ShaderMaterial: make it hide itself

Hi folks,

I’m looking for clues on how to hide self parts of a mesh with a transparent shaderMaterial.

Here is a fiddle
The two sphere geometries are merged using BufferGeometryUtils.mergeBufferGeometries, and I want to hide the parts of this single geometry that are behind another part of the same geometry.

Current result :

What I want to achieve :

Actually there is something I don’t fully grasp about transparent materials : how come three.js is able to draw parts of a mesh with a transparent material several times on the same pixel ? Is the fragment shader executed several times ?

Basically how to only draw the closest face ?

Unfortunately, you have picked a use case which is very hard to solve with default transparency implementations, see: Cannot see glass transparency on GLTF 3D model · Issue #13889 · mrdoob/three.js · GitHub

You would need a technique called Order-independent transparency (OIT) to render such setups correct. three.js does not support OIT so far.

Well, each face of the geometry has to be rendered. However, the order of rendered primitives is not necessarily correct which produces typical self-transparency artifacts. OIT can solve those.


@Mugen87 I believe in this OIT case would render the overlapping section of both spheres rather than just rendering the closest face as transparent like the second image.

@felixmariotto You can use a depth prepass approach to render transparent objects like you have shown in your second image. See this other forum post for an example of the implementation and how it works:

The gist of it is that the transparent object is first rendered to depth only with out writing to color first. Then the transparent material is rendered and because depth has already been written to only the closest pixels will be rendered.

I’ve submitted PR #20673 to enable this more easily with a material flag because transparency artifacts are a common problem and this is a performant approach that I think improves things quite a bit.


@gkjohnson thank you so much, this is exactly what I need ! I’ve tweeked your exemple to adapt it to my use case, here is what it looks like :

To be more specific than in my original message, my exact use case is a double mesh, one with a front face material and one with a back face material, and both would hide parts of themselves in the background, but let other meshes in the background through… A bit convoluted and not easy to explain sorry…

@Mugen87 thanks for pointing me to this issue, it was an interesting read. pailhead depth peel exemple at the end is interesting, although it looks expensive.

Oh, it seems I misunderstood @felixmariotto initial post.

Nevertheless, OIT approaches will provide the best solution for transparency/transmission. This is another interesting post with a stunning live demo: Intent to implement/contribute Enterprise PBR improvements · Issue #16977 · mrdoob/three.js · GitHub

1 Like