Can someone explain why
screenPos = ComputeScreenPos(vpos).z and sceneZ = Linear01Depth(tex2Dproj(_CameraDepthTexture, UNITY_PROJ_COORD(IN.screenPos)).r) has very different values?
In first case objects which closer to camera are lighter in second case they are darker, but farther objects are lighter??))
Trying sceneZ - screenPos.z but result always depends of camera position…I need constant value…
For Unity 5.5 they implemented an inverted depth buffer for DX11, which means things close to the camera are at “1.0”, and far way is “0.0” in projection space. ComputeScreenPos() is taking that inverted projection space position (vpos) and calculating the values to get 0.0 - 1.0 x and y when doing screenPos.xy / screenPos.w, but it leaves the z mostly alone so it might still be inverted.
Linear01Depth() returns a 0.0 to 1.0 with 0.0 near the camera and 1.0 far away. I believe you want to use COMPUTE_DEPTH_01 to get a value that matches the output of Linear01Depth();
// screenPos should be a float4
o.screenPos = ComputeScreenPos(vpos);
o.screenPos.z = COMPUTE_DEPTH_01;
I’ve aplyed this code:
o.screenPos.z = COMPUTE_DEPTH_01; //in vertex
half sceneZ = Linear01Depth(tex2Dproj(_CameraDepthTexture, UNITY_PROJ_COORD(IN.screenPos)).r);
half4 edgeBlendFactors = sceneZ - IN.screenPos.z; //in surf
And… still no have result…
BUT, I’ve found decision in Water4
half depth = SAMPLE_DEPTH_TEXTURE_PROJ(_CameraDepthTexture, UNITY_PROJ_COORD(IN.screenPos));
depth = LinearEyeDepth(depth);
half4 edgeBlendFactors = depth - IN.screenPos.w;
It’s a pity, that I don’t understand why it working) What description for SAMPLE_DEPTH_TEXTURE_PROJ, and why we use IN.screenPos.w instead z…But it working precisely how i want))
However I have once more trouble with depth buffer. I’m multiplying edgeBlendFactors.y and some coefficient (f.e edgeBlendFactors.y*= 0.5) whith idea that coastline detection was more smooth. The less this coefficient, the more darker pixels near camera…(o.Albedo = edgeBlendFactors.y)
coeff = 0.5
coef = 0.1
Is any way to hide this problem?
I want to bind _SinTime whith this coefficent for realisation flux and reflux by changing Alpha.
I would suggest looking at how particles do this. It doesn’t use 01 depth, but rather linear depth which should work better for your needs.
edit: On further thought this might not help. The real problem is likely because as the water plane gets further away the view angle makes the distance longer between the surface and the ground below a further distance. You can adjusting the factor by the view direction vs surface normal (or just world up for simplicity).
yes, I’ve tried to use particles shaders, the same result.
You mean something like this?
float3 normViewDIr = normalize(i.viewDir);
float dotprod = dot(normViewDIr, float3(0, 1, 0));
o.Albedo = (fade + factor);
in this variant i’ve got something like
this is inverted dot result, it look like circle unlike on line how on screens from prev post))
SAMPLE_DEPTH_TEXTURE_PROJ is simply tex2Dproj on most platforms. And view-space z (scene depth) usually equals clip-space w. It depends on projection matrix but it is true for the typical ones.
screenPos.w = viewPos.z = depth
Just look at projection matrix to understand why. For example, this is DirectX projection matrix:
viewPos is a row vector (DirectX way), so clipPos is computed like this:
clipPos = viewPos * projectionMatrix
clipPos.w is computed as a dot product of viewPos and 4th column of the proj matrix:
clipPos.w = viewPos.x * 0 + viewPos.y * 0 + viewPos.z * 1 + viewPos.w * 0 = viewPos.z
clipPos.w = viewPos.z
So, screenPos.w is simply scene depth and you can compare it to linearized depth from depth buffer.
I believe you want to divide the factor by the dot product, not add to it. Technically your original (with out the dot product modification) is what happens in real life though, just the falloff is non-linear so its not as noticeable. You could try using an exponential fall off and your original shader, or that and the dot product.
Michal_
Thank you. This is useful information. Sometimes is hard to find simple explanation for some unity and cg features))
bgolus
At first I’ve had dividing but i was disappointed by this result (on screen), so I replaced it to adding))
you mean that I should do this?
float fade = saturate (_InvFade * (sceneZ-partZ)); // _InvFade = 0.31
o.Albedo = fade * fade * fade * fade * fade; )))
What that I see after this)