简体   繁体   中英

three.js - canvas texture on tube geometry for ipad

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!

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM