Depth buffer with orthographic camera?

Discussion in 'Shaders' started by pixpusher2, Sep 18, 2015.

1. pixpusher2

Joined:
Oct 30, 2013
Posts:
117
I came across this cool shader effect (shader code inside the link). The depth buffer fading effect works well on perspective camera, but not with orthographic camera mode I'm using.

Is there an alternative way to recreate the Y-depth effect on the ortho camera? I couldn't find anything on Google but I may be using the wrong keywords.

Any ideas or keywords to search for would help. Thanks!

2. Gambit-MSplitz

Joined:
May 16, 2015
Posts:
1,194
Why this happens:
Perspective cameras show objects larger up close and smaller as they get farther away. Because of this, you get a closer look at objects close to the camera, so you want better depth quality on them. For this reason, you have logarithmic depth, which gives better accuracy up-close at the cost of lower depth-quality farther away from the camera. (Nobody will notice those 2 pixels z-fighting in the distance anyway)

Orthographic cameras use linear depth because you can see object just the same no matter how far away they are from the camera, so there's no reason to have better accuracy on closer objects.

With logarithmic depth, you end up using depth values 0 through 0.7 in just the first 10% of the frustum and distribute the rest throughout the remaining 90% of the frustum. Linear depth goes from 0 to 1 linearly. (Let me know if you'd like me to explain any of this better)

How to fix it:
Line 39 of that shader is:
Code (CSharp):
1. float depth = Linear01Depth (tex2Dproj(_CameraDepthTexture, UNITY_PROJ_COORD(i.projPos)).r);
"Linear01Depth" converts logarythmic depth into linear depth, but you already have linear depth on an orthographic camera, so just remove that function call. The result should be this:
Code (CSharp):
1. float depth = tex2Dproj(_CameraDepthTexture, UNITY_PROJ_COORD(i.projPos)).r;

I have not tested this. Let me know how it goes!

chingwa likes this.
3. pixpusher2

Joined:
Oct 30, 2013
Posts:
117
Thanks for the explanation Gambit_MSplitz! I get what you mean.

I've tested the changes, but the result remains the same for ortho camera (the effect no longer works in perspective camera though, as expected). The ortho camera depth buffer seems to be either 0 or 1, but nothing in between?

I'll try fiddling with it more. Thanks!

Update:
Lowering the ortho camera's Clipping Planes to between 0.2 and 3.5 helped somewhat (no effect on the sphere though), but now the scene objects clip really badly. Any ideas? Or should I just drop it?

with LinearEyeDepth

without LinearEyeDepth

Update 2:
Getting close! Made some code changes to make it work with normal Clipping Planes value of 0.01 to 1000.
Code (CSharp):
1. float sceneZ = tex2Dproj(_CameraDepthTexture, UNITY_PROJ_COORD(i.projPos)).r * 40; //multiply with value
2.
3. float partZ = i.projPos.y; //changed to Y-axis

There's still an issue of the effect being more apparent when object is at the bottom of the screen. Will try to figure this out...

Last edited: Sep 19, 2015
4. pixpusher2

Joined:
Oct 30, 2013
Posts:
117
I did a hackish fix to reduce the Z-axis fading on ortho camera. I'll just consider this solved unless there's a better solution.

Code (CSharp):
1. //Highlights intersections with other objects
3. {
4.     Properties
5.     {
6.         _RegularColor("Main Color", Color) = (1, 1, 1, .5) //Color when not intersecting
7.         _HighlightColor("Highlight Color", Color) = (1, 1, 1, .5) //Color when intersecting
8.         _HighlightThresholdMax("Highlight Threshold Max", Float) = 1 //Max difference for intersections
9.         _ZBias("Highlight Z Bias", Float) = 2.5    //Balance out the Z-axis fading
10.     }
12.     {
13.         Tags { "Queue" = "Transparent" "RenderType"="Transparent"  }
14.         Pass
15.         {
16.             Blend SrcAlpha OneMinusSrcAlpha
17.             ZWrite Off
18.             Cull Off
19.             CGPROGRAM
20.             #pragma target 3.0
21.             #pragma vertex vert
22.             #pragma fragment frag
23.             #include "UnityCG.cginc"
24.             uniform sampler2D _CameraDepthTexture; //Depth Texture
25.             uniform float4 _RegularColor;
26.             uniform float4 _HighlightColor;
27.             uniform float _HighlightThresholdMax;
28.             uniform float _ZBias;
29.             struct v2f
30.             {
31.                 float4 pos : SV_POSITION;
32.                 float4 projPos : TEXCOORD1; //Screen position of pos
33.             };
34.             v2f vert(appdata_base v)
35.             {
36.                 v2f o;
37.                 o.pos = mul(UNITY_MATRIX_MVP, v.vertex);
38.                 o.projPos = ComputeScreenPos(o.pos);
39.                 return o;
40.             }
41.             half4 frag(v2f i) : COLOR
42.             {
43.                 float4 finalColor = _RegularColor;
44.                 //Get the distance to the camera from the depth buffer for this point
45.                 float sceneZ = tex2Dproj(_CameraDepthTexture, UNITY_PROJ_COORD(i.projPos)).r * 400;
46.
47.                 //Actual distance to the camera
48.                 float partY = i.projPos.y + (i.projPos.y/_ZBias);
49.
50.                 //If the two are similar, then there is an object intersecting with our object
51.                 float diff = (abs(sceneZ - partY)) / _HighlightThresholdMax;
52.                 if (diff <= 1)
53.                 {
54.                     finalColor = lerp(_HighlightColor, _RegularColor, diff);
55.                 }
56.
57.                 half4 c;
58.                 c.r = finalColor.r;
59.                 c.g = finalColor.g;
60.                 c.b = finalColor.b;
61.                 c.a = finalColor.a;
62.                 return c;
63.             }
64.             ENDCG
65.         }
66.     }
67.     FallBack "VertexLit"
68. }

5. Gambit-MSplitz

Joined:
May 16, 2015
Posts:
1,194
So in your "update 2" you say the effect is darker towards the bottom of the screen.. that's because you have your camera at an angle so the objects at the bottom of the screen are closer to the camera.

I could be wrong, but it seems the only problem you have now is the rate at which you fade from pink to transparent. Since the falloff is not linear, I think something in the calculation is still expecting you to use a perspective camera.

This is just a wild guess, but try changing:
Code (CSharp):
1. float depth = tex2Dproj(_CameraDepthTexture, UNITY_PROJ_COORD(i.projPos)).r;
to
Code (CSharp):
1. float depth = tex2D(_CameraDepthTexture, (i.projPos)).r;

6. pixpusher2

Joined:
Oct 30, 2013
Posts:
117
Thanks for helping out though!

Just realized the effect gets messed up whenever you have different Clipping Planes values, so I guess the shader is a bit finicky.

7. Gambit-MSplitz

Joined:
May 16, 2015
Posts:
1,194
Well that makes sense, the depth value 0 to 1 tells you how far between the near and far plane you are where 0 is the near plane and 1 is the far plane.

pixpusher2 likes this.
8. JamhammerDev

Joined:
Jul 11, 2015
Posts:
5
It's been a number of years, but would anyone have any ideas or insight into this? Trying to wrap my head around shaderforge and the above comments is leading me nowhere!

9. Gambit-MSplitz

Joined:
May 16, 2015
Posts:
1,194
Sorry for the non-answer, but Shaderforge isn't supported in Unity 2017 or later, so you may want to consider switching to Amplify shader editor or the built-in shader graph.

If you must have an answer, you may want to start your own thread to get new eyes on the question, or ask in the shader forge forums.