Three.js : Can i create mesh to replace lot of object - javascript

this is the link of my work : maison.whiteplay.fr
What i am trying to do is a 3D PacMan, but look at th code, i'm using mesh to build my level, except for bubbles (yellow circle), that you need to eat to win.
They are all different objects, but because they are a lot, it's lagging, can i use the same technologie (mesh i think) to the bubbles ? If yes, how ?
code:
var geometrySphere = new THREE.SphereGeometry( 5, 32, 32 );
var bille = function(x,z){
this.bille = new THREE.Mesh(
geometrySphere,
new THREE.MeshBasicMaterial( {color: 0xffff00} )
);
this.bille.position.x = (x-15.5)*100; this.bille.position.y = 100;
this.bille.position.z = (z-15.5)*100; scene.add(this.bille);
}
Thank your for reading, and if you have any suggestions about my code, don't hesistate :D

You can also reuse your material instead of making a new instance all the time:
var geometrySphere = new THREE.SphereGeometry( 5, 32, 32 );
var billeMaterial = new THREE.MeshBasicMaterial( {color: 0xffff00} );
var bille = function(x,z){
this.bille = new THREE.Mesh(
geometrySphere,
billeMaterial
);
this.bille.position.x = (x-15.5)*100; this.bille.position.y = 100;
this.bille.position.z = (z-15.5)*100; scene.add(this.bille);
}
Reusing materials has good influence on performance.
How do you duplicate your meshes/objects?

You're code is almost right.
In your specific case, with N equal balls, you must have N mesh but just one material.
In this way, if you want to colorize (just for example) only one ball, you have to apply it one new material, otherwise you will apply new color to all the balls.
In your case lagging may be due to the sphere construction.
You clearly copy and paste from the documentation without read it before.
var geometrySphere = new THREE.SphereGeometry( 5, 32, 32 );
Where, as explained in the documentation:
radius — sphere radius. Default is 50.
widthSegments — number of horizontal segments. Minimum value is 3, and the default is 8.
heightSegments — number of vertical segments. Minimum value is 2, and the default is 6.
32 * 32 is too much for your small-monocolor bubbles, doesn't have sense.
The higher are this values, the higher is the complexity for draw it for each frame.
I suggest you to create sphere with a minor number of vertical/horizontal segments (8*8 may be ok).
Take a look at this demo.

Related

Can't alter offset/repeat of texture used as alphaMap

demo:
https://dl.dropboxusercontent.com/u/123374/so-pages/20160601/index.html
the alphaTexture is having it's offset altered during each render. as a "map" property it changes, but as an "alphaMap" it does not change. the 2nd mesh's alphaMap
relevant code from demo link:
var colorTexture = new THREE.TextureLoader().load('blue.png')
, alphaTexture = new THREE.TextureLoader().load('alpha.png')
, offset = 0
, colorFill = new THREE.Mesh(
new THREE.Geometry(),
new THREE.MeshPhongMaterial({
map: colorTexture,
alphaMap: alphaTexture,
side: THREE.DoubleSide,
shading: THREE.FlatShading
})
)
function render() {
requestAnimationFrame(render)
offset += .01
alphaTexture.offset.x = Math.sin(offset)
renderer.render(scene, camera)
}
render()
expected:
the transparent part of the object would shift as the offset of the alphaTexture changes.
actual:
transparent part stays fixed on the material. However, if I edit the offset of the texture set to the map property (instead of alphaMap) it * is * able to shift, which seems like inconsistent behavior to me.
What you are seeing is a current "feature" of three.js: only one offset/repeat pair is allowed per mesh. mesh.map has priority.
For more info, see https://stackoverflow.com/a/14372235/1461008
This may be changed in the future to allow separate offset/repeat settings per texture or per material property.
three.js r.84
I tried commenting out the USE_ALPHAMAP with the latest version(82) but it didn't work. However, changing the vUv to vUv2 in the alpha_fragment chunk worked.
Jim

Duplicate points Three.js

I am creating a line and added to the scene and shows well.
but when I try to create a mesh (using the same coordinates that I formed the line) I get errors that no duplicate points.
"Warning, unable to triangulate polygon!
Duplicate point 653.4789181355854: 204.0166729191409
Either or not infinite solutions!
Its finite solutions.
Either or not infinite solutions!
Too bad, not solutions. "
The strange thing about all this is that the coordinates are more than 4000 points, and I'm sure none of them is repeated. (I even checked in excel, and are only repeated the coordinates of start and end which I understand to be the same) .
what can I do?. no way that from the points of the line can create the mesh without me these errors appear ?. or what other steps should I follow?
for(var x in features.features){
materialLinea[x] = new THREE.LineBasicMaterial( { color: "#FFFFFF"} );
array_extrude[x]=new Array();
material[x] = new THREE.MeshBasicMaterial({
color: "#FF0000"
});
geometria[x] = new THREE.Geometry();
for(var s in features.features[x].geometry.coordinates[0]){
geometria[x].vertices.push(new THREE.Vector3(features.features[x].geometry.coordinates[0][s][0],features.features[x].geometry.coordinates[0][s][1],0))
array_extrude[x].push(new THREE.Vector3(features.features[x].geometry.coordinates[0][s][0],features.features[x].geometry.coordinates[0][s][1],0));
}
line[x] = new THREE.Line( geometria[x], materialLinea[x])
scene.add(line[x])
object3d[x] = new THREE.Shape( array_extrude[x] );
var extrusionSettings = {bevelEnabled: false,amount:10, };
figuraExtrude[x] = new THREE.ExtrudeGeometry( object3d[x], extrusionSettings );
municipios[x] = new THREE.Mesh( figuraExtrude[x], material[x] );
scene.add(municipios[x]);
}
You can merge vertices on your geometries
Geometry.mergeVertices()

three.js - Get all objects(meshes) in the area (3d cube)

I have a system of tubes. More precisely, I create a tubes from this code
tube_color - obviously, color of tube,
spline_points - huge number of THREE.Vector3 objects,
segments, radiusSegments are just numbers
var material = new THREE.MeshLambertMaterial( { color: tube_color, shading: THREE.SmoothShading } );
var spline = new THREE.SplineCurve3(spline_points);
var tube = new THREE.TubeGeometry(spline, segments, 10, radiusSegments, false, false);
var tubeMesh = new THREE.Mesh(tube, material);
scene.add(tubeMesh);
This code creates one particular mesh object in space. For each mesh I can have an array of Vector3's by using myMesh.geometry.vertices.
The problem is: I have the point in 3d space. Around this point I create Cube, which does intersect with tubes. For example, this cube can be created like this
var cube = new THREE.CubeGeometry(xSize,ySize,zSize, 5, 5, 5);
var material = new THREE.MeshBasicMaterial({
color: 0xff0000,
opacity: 1,
wireframe: true,
transparent: false
});
var selectionMesh = new THREE.Mesh(cube, material);
scene.add(selectionMesh);
Is it possible at least to find objects(meshes) that have intersection with by cubic area? I know that in scene object I have all meshes, and I can iterate over them, get vertices, iterate over them with a condition if there is at least one its point is in cubic area. But I believe... I hope there is a method/algorithm/magic much more simple then this...
As #WestLangley recommended the solution of this problem was to build octree.
octree=new THREE.Octree({
undeferred:false,
depthMax:Infinity,
objectsThreshold:8,
overlapPct:0.15
} );
and search it
var meshesSearch=octree.search( rayCaster.ray.origin, radiusSphere, true, rayCaster.ray.direction );
However, to have specific intersection we need to provide the recursive flag
raycaster.intersectOctreeObjects( objects, true )
I ended up with more complicated processing of my specific case however this was enough to solve the problem at that moment.

Three.js - Shape disappears on flip side

I've made a circle as follows:
material = new THREE.MeshBasicMaterial({ color: 0x00ff00 });
arcShape = new THREE.Shape();
arcShape.absarc( 0, 0, 20, 0, -Math.PI*2, true );
geometry = arcShape.makeGeometry();
circle = new THREE.Mesh(geometry, material);
scene.add(circle);
Like that, it is visible. But rotate it, and it disappears.
shadow.rotation.x = Math.PI / 2;
I've seen several other posts where this problem has not been solved. (So unless someone has a solution, I'll resort to making a flat cylinder instead. It's just a niggling problem).
I've set mesh.doubleSided = true and mesh.flipSided = false. I've also tried all 4 combinations of toggling the renderer's depthTest and the material's depthWrite properties.
Is there anything else I could try? If not, I'm guessing the code is sensitive to the order of some of my calls, in which case, I've had a long day so I'll stick with the cylinder!!
material.side = THREE.DoubleSide;

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!

Categories

Resources