I have a scene with camera facing billboards drawn with depth write off so they appear on top of other objects. I would like to draw each sprite so that any obscured pixels are drawn with a very low opacity. So that obscured portions of each sprite are visible but very faint.

Could anyone point me in the direction of a solution? I am using Threejs but I imagine the solution will be shader (glsl) based. I already have the depth texture for the scene available.

Diagram showing desired effect

Sketchfab implements this with its annotations, which is the effect I would like to acheive.

Sketchfab example of desired effect

New contributor
Snicklefritz is a new contributor to this site. Take care in asking for clarification, commenting, and answering. Check out our Code of Conduct.
up vote 1 down vote accepted

Use the depth texture you mentioned, comparing it to the fragment's current depth to apply an alpha factor to your color. Remember to enable blending on the host. You can also upload the color texture and apply a more controlled blending on the shader.

The shader code involved would look like this:

#version 430 core

out vec4 finalColor;

...

in vec2 screenUV;

...

uniform sampler2D depthTexture;

...

void main()
{
    float texDepth = texture(depthTexture, screenUV).r;
    float alpha = texDepth < gl_FragDepth? 0.5 : 1.0;

    ...

    finalColor = vec4(..., alpha);

}
  • Okay thank you this has given me a good start as I did not know about gl_FragDepth. The part I am struggling with now is transforming the sprite UVs to screen UVs in order to sample the right part of the depthTexture. Any thoughts? – Snicklefritz Nov 8 at 11:03
  • @Snicklefritz To get the screen UVs, upload the screen size as uniform vec2. Then, divide gl_FragCoord.xy by the screen size and you will have them. You might have to flip the y coordinate as 1 - y – Nadir Nov 8 at 11:21
  • thank you for the sanity check as that's what I am doing. Still not getting the right result though. – Snicklefritz Nov 8 at 11:46
  • All sorted now, the problem was that my depth texture size was wrong, I have supersampling as a PP step so the size I was giving was wrong. I wish I could just use textureSize() in shader but it's not supported with the WebGL version Threejs uses. Thank you for your help. – Snicklefritz Nov 8 at 15:24
  • @Snicklefritz Great! I believe it is better not to be supported, its a performance killer :) – Nadir Nov 8 at 15:28

Your Answer

Snicklefritz is a new contributor. Be nice, and check out our Code of Conduct.
 

By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

Not the answer you're looking for? Browse other questions tagged or ask your own question.