I'm developing a glow effect, having this test scene: I have a secondary Camera rendering to a Target texture, only objects on `Glow` layer: Now I want to cull fragments covered by Eiffel Tower. Of course I don't want to draw all the 1M Eiffel Tower triangles again here. The idea is to reuse the depth texture of the Main Camera (I can get a sample from it using http://docs.unity3d.com/ScriptReference/DepthTextureMode.Depth.html): But I can't see how to cull fragments in the secondary camera shader. The shader code is bare simple, my question is how to use _CameraDepthTexture in my shader: Code (CSharp): Shader "eppz!/Glow/Camera" { Properties { _MainColor ("Main Color", Color) = (1,1,1,1) _GlowColor ("Glow Color", Color) = (1,1,1,1) } SubShader { Pass { CGPROGRAM #pragma vertex vert #pragma fragment frag fixed4 _MainColor; fixed4 _GlowColor; sampler2D_CameraDepthTexture; float4 vert(float4 v:POSITION) : SV_POSITION { // Sample from depth texture. // Compare to current vertex depth (But how?). // Discard fragment if Z-culled. return mul (UNITY_MATRIX_MVP, v); } fixed4 frag() : COLOR { // Sample here at least, then output black pixel if fragment is Z-culled. return _GlowColor; } ENDCG } } }
Turned out that the best is to use GLSL, as it has `gl_FragCoord` showing me the exact fragment position (this is not entrely the same as I would calculated a z position from vertex position and projection). Here is the lovely pass: Draws only 2 sphere and a cube, but culled by the Eiffel Tower in the front. Full composite with glow, overlay, and some more geometry: The glow camera only draws the glowing objects before blur (see bottom right), but in the shader they are culled with scene depth buffer. Shader goes like: Code (CSharp): Shader "eppz!/Glow/Camera (GLSL)" { Properties { _GlowColor ("Glow Color", Color) = (1,1,1,1) } SubShader { Pass { GLSLPROGRAM uniform vec4 _GlowColor; uniform vec4 _ScreenParams; uniform sampler2D _CameraDepthTexture; varying vec2 v_textureCoordinates; #ifdef VERTEX void main() { gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex; v_textureCoordinates = gl_MultiTexCoord0.xy; } #endif #ifdef FRAGMENT void main() { vec2 fragmentScreenCoordinates = vec2(gl_FragCoord.x / _ScreenParams.x, gl_FragCoord.y / _ScreenParams.y); float sceneDepthSample = texture2D(_CameraDepthTexture, fragmentScreenCoordinates).x; bool culled = (sceneDepthSample < gl_FragCoord.z); // Output. gl_FragColor = (culled) ? vec4(0.0, 0.0, 0.0, 1.0) : _GlowColor; } #endif ENDGLSL } Actually a manual Z-test.