I’m trying to render a mesh with variable opacity.
However, I don’t want to see the triangles of my mesh that are behind other ones. Instead, the transparent front ones should knock those out.
Is there a way to do this in three?
three.js draws faces of a Mesh in the order given by the BufferGeometry index, so I think your options would be:
- (A) if the mesh isn’t too dense, sort the indices and set
.depthWrite = true, .depthTest = true
on the material to discard fragments behind triangles that have already been drawn - (B) if the mesh will be rendered in a solid transparent color (not shaded/lit/textured/…) so you don’t care which triangle is drawn, as long as no overlap is shown, consider using the stencil buffer to prevent >1 draw per pixel regardless of depth
- (C) if the mesh is mostly convex and manifold or “water tight”, just
material.side = THREE.FrontSide
would be enough
Finally, if performance and complexity are of little concern, I’ve occasionally seen people implement depth peeling with three.js, but this isn’t a feature built into the library at this time.
Thank you! That is very helpful
Finally, if performance and complexity are of little concern, I’ve occasionally seen people implement depth peeling with three.js, but this isn’t a feature built into the library at this time.
The cheaper, per-object version of depth peeling would just be implementing a depth prepass, which I think should be reasonably cheap as long as you’re not doing it with a ton of objects. Here’s an explanation and example:
Fundamentally it works like so:
- Draw the mesh once with just depth (discarded color) so the depth buffer is populated.
- Draw the mesh again with depthTest set to
EqualDepth
.
This adds a second draw call but with the fragment shader completely skipped. And compared to proper depth peeling this won’t require any full screen passes.
edit: A depth peeling demo I’d put together is also available in this repo. And another survey of other transparency techniques is available in this post.
Another approach worth considering (if it hasn’t already been mentioned), is to draw the whole mesh at full opacity, then “knock it back” with simple transparent mesh the same color as the background that surrounds the model to obscure it completely. This can be simple to set up and relatively cheap to render, and likely matches what most people imagine will happen when a model “fades out”.
The obscuring mesh can also be made to knock back the model to “alpha” (compatible with any background color) using custom blending settings.
Dang, that’s genius. I love it.