Can objects be hidden behind other transparent objects? - three.js

I have created a transparent floor from a PlaneGeometry. But the requirement is that other objects will rise up from beneath that plane. They must not be visible until they are above the floor.
Is it possible to hide those objects despite being behind something with transparency?

You could use a local clipping plane, so these objects will only be visible above the plane.
See this three.js example: https://threejs.org/examples/?q=clipping#webgl_clipping
Important parts:
// plane on ground/floor level
var clippingPlane = new THREE.Plane(new THREE.Vector3(0, 1, 0), 0);
// material of objects that will rise up
var material = new THREE.MeshPhongMaterial({
color: 0x80ee10,
clippingPlanes: [ clippingPlane ]
clipShadows: true
});

Related

How to draw open end curve shapes in Threejs

I am drawing curves/polygons by using ExtrudeBufferGeometry.
Usually it always has closed ends.
For example:
My target is to draw similar shapes but open ended like
Note that my target is not "LINES" or "Planes". It must have extrude and I just want continuous points keep combining with angle (angle can be any floating point value in radian)
Your solution lies in the ExtrudeGeometry documentation, where it states:
When creating a Mesh with this geometry, if you'd like to have a separate material used for its face and its extruded sides, you can use an array of materials. The first material will be applied to the face; the second material will be applied to the sides.
So when generating the mesh, just pass 2 materials, the first one with visible: false so it doesn't get rendered.
const geometry = new THREE.ExtrudeGeometry( shape, extrudeSettings );
const materialFace = new THREE.MeshBasicMaterial( { visible: false } );
const materialSide = new THREE.MeshBasicMaterial( { color: 0x00ff00 } );
const mesh = new THREE.Mesh( geometry, [materialFace, materialSide] ) ;

FlatShading on colored custom geometry

As soon as I push my own vertices to a geometry, the geometry is a solid color, instead of having colored shadows.
Applying this code to a THREE.PlaneGeometry called mesh gives the following shading:
var light = new THREE.DirectionalLight(0xffffff, 1);
light.castShadow = true;
light.shadowDarkness = 0.5;
// ..
THREE.MeshLambertMaterial({ color: 0x66e6b0, shading: THREE.FlatShading });
// ...
mesh.receiveShadow = true;
mesh.castShadow = true;
However, when I apply the same code to a THREE.Geometry() with custom vertices and faces, the geometry is solid black. How can I give the custom geometry the same shading as the plane geometry?
I can use THREE.MeshBasicMaterial but then there are no longer shadows on the faces.
Using vertexColors: THREE.FaceColors and coloring each face still gives all black.
A THREE.AmbientLight gives color but then there are no shadows on the faces.
Here is a fiddle of randomly generated faces that are all the same color. Instead, I would like them to have different shadows because they are different angles (as in the above image).
It is not the shadows that would produce an effect like that but a z-coordinate. In your jsfiddle all your triangles are on the xy-plane so they all have the same normal. So their lighting would be the same. So if you make the call like this:
geometry.vertices.push(new THREE.Vector3(Math.random() * 100, Math.random() * 100, Math.random() * 100));
and also light.castShadow = false; because it does not contribute to anything then you will get the variation that you want.
This problem of a geometry appearing all black will occur when any initial coordinate of a vertex appended to the geometry has an undefined value.
Even if the geometry is displayed, animates, and no errors are thrown, if an initial coordinate of a THREE.Vector3 is undefined, THREE.MeshLambertMaterial shading will not work.
This problem is demonstrated in the fiddle, where the use of undefined_variable prevents colored shading, and just yields a solid color.
To handle this, initialize all vertices to arbitrary values i.e. new THREE.Vector3(0, 0, 0) and then use the values of variables in animate().

three.js: Using BufferGeometry with circles (or other shapes)

would it be possible to use bufferedgeometry filled with circles or other shapes? by circles i mean filled circles
i have tried drawing a circle via a series of "Line"s, but of course it wans't a filled circle, i have also tried using a ParticleCloud with pngs that looked like circles, but then the performance wouldn't be as good as native meshed circle i guess.
the closest i got to is when i drew a circle via a series of multiple "Mesh" objects but it is very cumbersome.
does BufferGeometry even support such thing?
In three.js there is CircleBufferGeometry
var geometry = new THREE.CircleBufferGeometry( 5, 32 );
var material = new THREE.MeshBasicMaterial( { color: 0xffff00 } );
var circle = new THREE.Mesh( geometry, material );
scene.add( circle );

zbuffer problems using 2D planes in THREE.JS

I am composing 2D planes with textures. I have 3 levels.
A background plane at z=0,
black shapes for conections at z=0.1 and
small planes with textures at z=0.2
the problem is that when I move the camera planes seems to change z position.
Planes are drawn in incorrect Z, it depend on the position of the camera. Moving the camera it changes again and looks very ugly.
Maybe I need to activate some ZBuffer property for correct drawing
WebGL init is like this and planes are exactly the same (only Z coord change)
renderer = new THREE.WebGLRenderer();
renderer.setSize(window.innerWidth, window.innerHeight);
renderer._microCache = new MicroCache(); //cache de imagenes
renderer.setClearColor(0xeeeeee, 1);
document.body.appendChild(renderer.domElement);
// add directional light source
var directionalLight = new THREE.DirectionalLight(0xffffff, 1);
directionalLight.position.set(1, 1, 1300).normalize();
scene.add(directionalLight);
//background plane
plane = new THREE.Mesh(new THREE.PlaneGeometry(200000, 200000, 1, 1), new THREE.MeshLambertMaterial({ color: 0xffffff, opacity: planeOpacity, transparent: true }););
plane.position.z = 0;
scene.add(plane);
Other planes are exactly the same but greater Z position
Help please!
Thanks!
Palomo
The thing you're seing is probably z-fighting. Internally, depth is represented by integer in GPU so there is only fixed number of distinct z-s between camera's near and far planes. The solution is to either move your planes apart or narrow camera's near-far range down.

Inconsistent alpha channel in three.js

I'm building an educational tool using planes, extruded splines, and cylinder geometries. Planes have a texture map and the rest are either basic or Lambert materials.
Texture map on planes in the only map and it does have an alpha
channel.
Texture map has been tested as .GIF and .PNG
All objects have "transparent: true"
renderer = new THREE.WebGLRenderer( {antialias:true} );
NOTE: this is the exact same problem listed at the following link. It has not been solved and my Rep isn't high enough to comment.
in three.js, alpha channel works inconsistently
As mmaclaurin noted, it could be a change based in draw order and camera location. I am using THREE.TrackballControls and limiting camera movement to two axes.
Adding or removing the BasicMaterial for wireframe does not change the issue.
Thank you for your time reading this and any help you can offer!
Example of plane object:
var T4map = new THREE.ImageUtils.loadTexture( 'medium_T4.png' );
var T4Material = new THREE.MeshBasicMaterial( { opacity: .96, transparent:true, map: T4map } );
var T4Geometry = new THREE.PlaneGeometry(810, 699, 10, 10);
var T4 = new THREE.Mesh(T4Geometry, T4Material);
T4.position.y = -CNspacing;
T4.doubleSided = true;
scene.add(T4);
Example of extruded spline geometry where problem is most noticeable:
var mesh = THREE.SceneUtils.createMultiMaterialObject( geometry, [
new THREE.MeshLambertMaterial( { color: 0xaaff00, opacity: 0.5, transparent: true } ),
mesh.position.set( x, y, z );
mesh.scale.set( s, s, s );
parent.add( mesh );
Try to play around with depthTest. Usually this would help:
new THREE.MeshBasicMaterial( { side:THREE.BackSide,map:texture,transparency:true, opacity:0.9, depthWrite: false, depthTest: false });
There are many other questions related to your subject, for ex.: transparent bug
Was just going to comment but its too long:
Objects that are marked with transparent = true, are painters sorted based on their centroid, and drawn back to front so that the transparency layers mostly correctly. Make sure your mesh.geometries have proper computeBoundingBox() and computeBoundingSphere() applied to them before adding them... if that doesn't fix your problem, then try using material.alphaTest = 0.5 on your materials.. this works well for things that are mostly on/off alpha.. like masks... but if you have smooth gradations of transparency from 0 to 1 in your textures, you may see fringes where the alpha test threshholding happens.

Resources