1
$\begingroup$

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

$\endgroup$
1
$\begingroup$

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);

}
$\endgroup$
  • $\begingroup$ 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? $\endgroup$ – Snicklefritz Nov 8 '18 at 11:03
  • $\begingroup$ @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 $\endgroup$ – Nadir Nov 8 '18 at 11:21
  • $\begingroup$ thank you for the sanity check as that's what I am doing. Still not getting the right result though. $\endgroup$ – Snicklefritz Nov 8 '18 at 11:46
  • $\begingroup$ 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. $\endgroup$ – Snicklefritz Nov 8 '18 at 15:24
  • $\begingroup$ @Snicklefritz Great! I believe it is better not to be supported, its a performance killer :) $\endgroup$ – Nadir Nov 8 '18 at 15:28

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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