I am overlaying an NRRD file with a transparent gltf model. However, I noticed that at certain angles, the gltf model turns dark and at other angles it looks transparent as I want.
Here is a transparent gltf duck model overlaid with the NRRD model from top view and side view:
But when I look at it from the opposite side or different side view angle , it appears darker:
At first I thought it was because of my lights, but I am using hemisphere light which should light up all the areas:
const hemiLight = new THREE.HemisphereLight( 0xffffff, 0xffffff);
hemiLight.position.set( 0, 100, -100 );
scene.add( hemiLight );
But this does not seem to help. How can I make the duck look transparent from all viewing angles?
I would suggest trying both
.depthWrite = false and
.depthWrite = true on any materials where you have set
.transparent = true. If the original glTF file used alpha blending transparency then GLTFLoader will set
.depthWrite = false automatically, but if you’re modifying materials later you’d need to do it yourself.
Note that transparent objects are sorted by the center of their bounding box, and rendering is very sensitive to sort order. Since you appear to have two interlocking transparent objects centered at the same point here, there’s little the renderer can do to ensure that triangles are rendered in the expected order, this is a very error-prone situation.
What about certain transparent parts in the gltf model suddenly appearing and disappearing as I rotate around the model? A gltf model with multiple parts inside sometimes pop up in the view and then disappear.
This is also related to sorting. The issue is common with interlocking transparent parts. Disabling depthWrite can help a bit, but there is no universal solution with alpha blending. There might be case-specific workarounds depending on specifically what you’re trying do display, for example: Material: Add .alphaHash and .alphaHashScale by donmccurdy · Pull Request #24271 · mrdoob/three.js · GitHub
The transparency looks exactly what I want from one side which is the nrrd object is seen at all times and the gltf is transparently shown. But the opposite side always gives the wrong effect which is the transparent model does not let the nrrd model be seen through it. Is there a solution to take the effect that I get on one side and transfer it to the opposite viewing angle?
You’ll need to think about this in terms of render order. Transparent objects must be sorted back-to-front to render correctly. Sometimes this requires sorting individual triangles. Sometimes it isn’t possible to get a perfect sort when triangles or objects interlock. If it looks wrong from a particular viewing angle, you may need to do something to force a particular render order, or to separate interlocking parts of objects. There is no one-size solution here, so I can only give general suggestions in response to the screenshots above and my guess at what you might be seeing.
Thanks, that does make sense to me now why I get my above results. From one side it is rendering from back to front with the expected transparency effect. But if I move my camera to the opposite side, I am now looking at the back which prevents me from seeing the front show through the transparent model.
So how can I manipulate the rendering order in Three Js?
If the centers of the objects’ bounding boxes are in the same location, the easiest way to change the render order is to shift the objects very slightly. three.js sorts by the bbox center, by default.
Alternatively you can disable default object sorting (
renderer.sortObjects = false) and specify a specific order for the objects with
object.renderOrder = order.
In cases where a single object is occluding itself you can sort triangles be reordering
geometry.index, but this shouldn’t be necessary if one object is occluding another object.