three.js-ipad的管几何图形上的画布纹理 [英] three.js - canvas texture on tube geometry for ipad

查看:146
本文介绍了three.js-ipad的管几何图形上的画布纹理的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个3D模型的管几何.生产方面有18000个坐标.我每隔9个坐标进行一次绘制,以便实际绘制9000个坐标来构建管的几何形状.我只需要使用CanvasRenderer.

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

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

在画布渲染中支持顶点颜色

画布渲染中的管

请在图像下方找到要根据值应用颜色的颜色.

如图所示,每个坐标有12个不同程度的12个值.因此,我创建了一个半径段为12的管.然后将这些值存储到JSON文件中,但是当有18000点时,该文件变得很重.即使我要绘制2000点,也要花费太多时间.对于2000个线段,每个线段有12个面,试管上有24000个面.

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

//获取res值&涂上颜色 var lblSeg = 0; var pntId; var d = 0; var faceLength = tube.faces.length; var degree = ['30','60','90','120','150','180','210','240','270','300','330']; var faces = tube.faces; var degreeCntr = 0; var degreeProp; //console.log(faces); var res30 = 0,res60 = 0,res90 = 0,res120 = 0,res150 = 0,res180 = 0,res210 = 0,res240 = 0,res270 = 0,res300 = 0,res330 = 0; var res; var 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上渲染此模型,因此只能使用canvas渲染器.

那么,如何使该模型更轻便地加载并在iPad上正常工作?还有其他方法可以在每张脸上应用颜色吗?如果可以应用画布贴图作为纹理,从而使模型更轻便,该如何使用基于值的所有颜色来构建贴图?

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

因此,现在的问题是根据要求(通过画布贴图或任何可行的解决方案)应用颜色,并使模型更轻巧,以将其平滑地加载到iPad上.

解决方案

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

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

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

}

正如我在上一条消息中向您解释的那样- three.js-发下一个文本行,使用画布纹理只会在尝试渲染这么多人脸时才会增加fps的负载.

如果您真的想在画布渲染器上渲染24,000个面,并且仍然希望它能在iPad上很好地显示–您就疯了!))

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

1)将电子管仅设置为1段.

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

3)现在,假设您要在每个画布中创建2000个细分.因此,您将画布长度除以2000,然后为该除法的每一部分设置计算出的颜色!!! (就像Stats()FPS栏显示它的栏一样,但是每个栏的颜色都会不同.

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

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

现在,我知道您的下一个问题将是:我将如何选择面部以显示带有标记文本的行?

嗯,非常简单!只需获取当前的面孔(共12张中的1张)来选择位置坐标,然后将其转换回JSON,就像处理24,000张面孔一样;)

希望有帮助!

I've a 3d model of a tube geometry. There are 18000 co-ordinates on production side. I am taking every 9th co-ordinate so that actually plotting 9000 co-ordinates to build a tube geometry. I've to use CanvasRenderer only.

Now when I use vertexColors: THREE.VertexColors in WebGLRenderer, the model displays different color on each face. When I change it to CanvasRenderer, the model turns into white color only. Even I change vertexColors: THREE.FaceColors, the result is same.

Please find below the link of jsfiddle and link of my previous where mrdoob added support for material.vertexColors = THREE.FaceColors to CanvasRenderer.

support for vertex color in canvas rendering

tube in canvas rendering

Please find below the image to apply colors based on values.

As shown in the image there are 12 values at 12 different degrees for every co-ordinate. So I've created a tube with radius segment of 12. Then I've stored these values into JSON file but as there 18000 points, the file becomes to heavy. Even though I am plotting 2000 points it takes too much time. For 2000 segments and each segment has 12 faces, there are 24000 faces on a tube.

Please find below the programming logic to apply color based on value of a parameter.

// get res values & apply color var lblSeg=0; var pntId; var d=0; var faceLength=tube.faces.length; var degrees = [ '30', '60', '90', '120', '150', '180', '210', '240', '270', '300', '330' ]; var faces = tube.faces; var degreeCntr=0; var degreeProp; //console.log(faces); var res30=0,res60=0,res90=0,res120=0,res150=0,res180=0,res210=0,res240=0,res270=0,res300=0,res330=0; var res; var 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++;                  
            }
        }

This logic takes too much time to render the model and the model becomes too heavy and we can't perform other operations. The FPS on android drops at 2-3 FPS. Actually I've to render this model on iPad so have to use canvas renderer only.

So, how do I make this model lighter to load and works smoothly on iPad ? and is there any other way to apply colors on every face ? If canvas map as texture can be applied to make the model lighter, how do I build that map with all the colors based on value ?

Update: After changing library version to r53, vertexColors: THREE.FaceColors and face.color.setRGB( Math.random(), Math.random(), Math.random()), the model displays random color for each face on canvas rendering.

So now the issue is applying colors as per requirements (either by canvas map or any feasible solution) and to make the model lighter to load it smoothly on iPad.

解决方案

I believe this will give you a little bit better performance + if you could come up with some automated method of calculating colors for each angle offset, that you could set hex color directly:

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

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

}

As I explained to you in the previous message - three.js - text next to line, using canvas textures will only increase load to you fps if you'll attempt to render so many faces.

If you really want to render 24,000 faces on canvas renderer and still hope that it gonna show up good on an iPad – you are out of your mind!))

Here is the only solution that I can think of for now:

1) Set your tube to only 1 segment.

2) Create 12 canvas elements (for every radius segment) with Width equal to your tube length (see my link above).

3) Now imagine that your 2000 segments you are going to create inside of each canvas. So, you divide your canvas length by 2000 and for every one of the portion of this division you set your calculated color!!! (Just like the Stats() FPS bar shows it’s bar, but you are going to have each bar different color).

4) Then you just apply your colored-bars-canvas-texture to each one of your 12 radius segments and you are good to go!!

This way you’ll only get initial page load (calculating 'em 24,000 colored-bars) and YOUR WHOLE TUBE ONLY GONNA BE 12 FACES!!!

Now, I know your next question is going to be: How I'll pick my faces to show my lines with tag text?

Well, very simple! Just take current face (1 of 12) pick position coordinates and translate them back to your JSON, just the same way you would do with 24,000 faces;)

Hope that helps!

这篇关于three.js-ipad的管几何图形上的画布纹理的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆