【问题标题】:three.js - canvas texture on tube geometry for ipadthree.js - ipad 管几何上的画布纹理
【发布时间】:2012-11-25 21:20:33
【问题描述】:

我有一个管几何的 3D 模型。生产端有18000个坐标。我每 9 个坐标取一次,以便实际绘制 9000 个坐标来构建管几何图形。我只能使用CanvasRenderer

现在当我在WebGLRenderer 中使用vertexColors: THREE.VertexColors 时,模型在每个面上显示不同的颜色。当我将其更改为CanvasRenderer 时,模型仅变为白色。即使我更改vertexColors: THREE.FaceColors,结果也是一样的。

请在下面找到 jsfiddle 的链接和我以前的链接,其中 mrdoob 向 CanvasRenderer 添加了对 material.vertexColors = THREE.FaceColors 的支持。

support for vertex color in canvas rendering

tube in canvas rendering

请在图片下方找到根据值应用颜色。

如图所示,每个坐标有 12 个不同角度的 12 个值。所以我创建了一个半径段为 12 的管。然后我将这些值存储到 JSON 文件中,但由于有 18000 个点,文件变得很重。即使我正在绘制 2000 个点,也需要花费太多时间。对于 2000 个段,每个段有 12 个面,管上有 24000 个面。

请在下面找到根据参数值应用颜色的编程逻辑。

// 获取 res 值并应用颜色 变量 lblSeg=0;变量 pntId;变量 d=0; var faceLength=tube.faces.length; var degree = ['30', '60', '90', '120', '150', '180', '210', '240', '270', '300', '330' ]; var faces = tube.faces;变量度Cntr = 0; var degreeProp; //console.log(faces); 变量 res30=0,res60=0,res90=0,res120=0,res150=0,res180=0,res210=0,res240=0,res270=0,res300=0,res330=0; 变量资源;变量 resDegree; var pnt=0;

                // fetching json data of resistivity values at different degree as                                                          //shown in the image
        var result = getResValue(); 


        for(var k=0; k<faceLength; k++){
            resDegree = degrees[degreeCntr];
            degreeProp = "r"+resDegree;

            res = result.resistivity[pnt][degreeProp];
            objects.push(result.resistivity[pnt]);              

            f = faces[k];               

            color = new THREE.Color( 0xffffff );

            if(res<5){                      
                color.setRGB( 197/255, 217/255, 241/255);
            }

            else if(res>=5 && res<50){                                                                          
                color.setRGB( 141/255, 180/255, 226/255);
            }

            else if(res>=50 && res<100){                                
                color.setRGB( 83/255, 141/255, 213/255);
            }

            else if(res>=100 && res<200){                               
                color.setRGB( 22, 54, 92);
            }

            else if(res>=200 && res<300){                           
                color.setRGB( 15/255,36/255,62/255);
            }

            else if(res>=300 && res<400){                               
                color.setRGB( 220/255, 230/255, 241/255);
            }

            else if(res>=400 && res<700){                               
                color.setRGB( 184/255, 204/255, 228/255);
            }

            else if(res>=700 && res<1200){                              
                color.setRGB( 149/255, 179/255, 215/255);
            }

            else if(res>=1200 && res<1500){                             
                color.setRGB( 54/255, 96/255, 146/255);
            }

            else if(res>=1700 && res<1800){                             
                color.setRGB( 36/255, 84/255, 98/255);
            }

            else if(res>1900){                              
                color.setRGB( 128/255, 128/255, 128/255);
            }

            for(var j=0;j<4;j++)
            {                   
                tube.vertices.push(f.centroid);
                vertexIndex = f[ faceIndices[ j ] ];    
                p = tube.vertices[ vertexIndex ];                   
                f.vertexColors[ j ] = color;                    
            }

            degreeCntr++;
            if(degreeCntr==10){
                degreeCntr=0;
            }
            if(k%12==0 && k!=0){
                pnt++;                  
            }
        }

这个逻辑需要太多时间来渲染模型,模型变得太重,我们无法执行其他操作。 Android 上的 FPS 下降 2-3 FPS。实际上我必须在 iPad 上渲染这个模型,所以只能使用画布渲染器。

那么,如何让这个模型更轻,在 iPad 上加载和流畅运行?还有其他方法可以在每张脸上涂上颜色吗?如果可以将画布贴图作为纹理应用以使模型更轻,那么如何根据值构建具有所有颜色的贴图?

更新: 将库版本更改为 r53、vertexColors: THREE.FaceColorsface.color.setRGB( Math.random(), Math.random(), Math.random()) 后,模型在画布渲染中显示每个面的随机颜色。

所以现在的问题是根据要求应用颜色(通过画布地图或任何可行的解决方案)并使模型更轻以在 iPad 上顺利加载。

【问题讨论】:

  • 小提琴正在运行 r.50。变化是 r.52。此外,如果您一次提出一个问题,您将获得更多帮助,并保持您的示例简单。这个问题只会让读者目瞪口呆。
  • 好的,我将其更改为 r.52。我的问题是关于画布地图的,所以我解释了整个场景,因为最终我只能在画布上渲染模型。
  • 如何从github下载旧版three.js?因为最新版本是 r53。我可以从标签中选择它,但它没有显示下载 r52 包的选项。 - @WestLangley
  • 设置“无库”并自己包含。 jsfiddle.net/RnFqz/21.
  • 这里是一张带有面部颜色和画布的:jsfiddle.net/RnFqz/22

标签: javascript json ipad html5-canvas three.js


【解决方案1】:

我相信这会给你带来更好的性能+如果你能想出一些自动计算每个角度偏移的颜色的方法,你可以直接设置十六进制颜色:

for ( var i = 0; i < tube.faces.length; i ++ ) {

    tube.faces[ i ].color.setHex( Math.random() * 0xffffff );

}

正如我在上一条消息 - three.js - text next to line 中向您解释的那样,如果您尝试渲染这么多面,使用画布纹理只会增加您的 fps 负载。

如果你真的想在画布渲染器上渲染 24,000 个面,并且仍然希望它在 iPad 上显示良好 - 你疯了!))

这是我目前能想到的唯一解决方案:

1) 将您的管子设置为仅 1 段。

2) 创建 12 个画布元素(对于每个半径段),其宽度等于您的管长度(请参阅上面的链接)。

3) 现在想象一下,您将在每个画布内创建 2000 个片段。因此,您将画布长度除以 2000,并为该除法的每一部分设置计算颜色!!! (就像 Stats() FPS 条显示它的条一样,但您将让每个条具有不同的颜色)。

4) 然后,您只需将彩色条画布纹理应用于 12 个半径段中的每一个,就可以开始了!!

这样,您只会获得初始页面加载(计算 24,000 个彩色条),并且您的整个管道只有 12 个面!!!

现在,我知道你的下一个问题是:我将如何挑选我的面孔来显示我的带有标签文本的线条?

嗯,很简单!只需获取当前人脸(12 个中的 1 个)选择位置坐标并将它们转换回您的 JSON,就像处理 24,000 个人脸一样;)

希望有帮助!

【讨论】:

  • 感谢如此出色的高性能逻辑。我已经开始在画布重新渲染上更改为 r.53、segment=1 和 12 个面。但是当我与管子交互时,它会突然消失并再次出现。可能是什么原因 ? -@Alex Under
  • “创建 12 个画布元素(每个半径段),宽度等于管长。” - 我如何找到管的长度。你能详细解释一下这一步吗?-@Alex Under
  • 请提供一些示例(JSFiddle?),说明您正在消失的情况。现在,对于管子长度 - 为什么不自己设置,让管子在场景中看起来不错(就像它已经做到的那样?),然后你就会得到你的画布宽度;)
  • 你能解释一下你的逻辑on this tube吗?- @Alex Under
  • jsfiddle.net/RnFqz/29 - 这是一条可行的路。我在我的方法中发现了一些问题。 1)您将无法仅处理 12 个面(因为画布渲染器)。 2)您可能无法使用路径中的管几何形状。我认为最好的方法是以 30 度角组合 12 个平面。这样你就可以操纵他们的纹理贴图,但不是现在这样。所以看看,告诉我你的想法。
猜你喜欢
  • 1970-01-01
  • 2013-02-23
  • 2015-06-29
  • 2014-09-26
  • 2013-11-28
  • 2020-05-30
  • 2013-09-22
  • 1970-01-01
  • 2021-09-01
相关资源
最近更新 更多