I am currently trying to work out how to use depth textures but was hitting a road block.
I ended up searching the forums to see example code for how people do it. And see people using functions that i had no idea even existed and the docs don’t even mention.
For example i am doing this in my frag shader:
// depthSample at screen position
float4 depthSample = SAMPLE_DEPTH_TEXTURE_PROJ(_DepthTexture,IN.screenPos);
// depth from 0 to 1
float depth = LinearEyeDepth(depthSample);
But is this the right way to do it? I’ve seen other approaches as well.
SAMPLE_DEPTH_TEXTURE_PROJ is no where to be seen in the documentation. Is this deprecated ? Does it work on all platforms… i have no idea…
I’m using a surface shader if that matters here.
Is this the correct approach ? I am doing depth texture sampling for ocean rendering. If this is not the correct way - some guidance would be welcome.
That’s a perfectly fine way of doing it. In fact the use of that macro (along with the UNITY_DECLARE_DEPTH_TEXTURE(_CameraDepthTexture) was added to Unity shaders in part to help support more platforms. Specifically it helps for different VR modes which defines and accesses the depth texture in different ways.
Why are they not in the documentation? Because a lot of stuff isn’t in the documentation. The changes to the code has far and away outstripped Unity’s ability to document, and things keep changing so a few times by the time documentation ends up getting updated it’s already outdated.
Really, the only way to know what’s actually available is to read through the shader files yourself. There’s a lot of helper functions completely missed in the documentation, and a bunch of functions you might expect to exist that don’t.
Thanks for the reply, I still have a few more things i am not understanding from the results i am getting perhaps you can see where i might have gone wrong.
When i compare the depth differences between my frag’s COMPUTE_EYEDEPTH and the depth texture LinearEyeDepth() the values don’t seem to match what my math is doing.
float textureDepth = SAMPLE_DEPTH_TEXTURE_PROJ(_DepthTexture, IN.screenPos);
// will this give approximate world units distance from the camera ???
float depthDifference = LinearEyeDepth(textureDepth) - IN.screenPos.z;
// clamp difference in distance to maximum of 50 units
depthDifference = max(depthDifference,_MaxDepthVisibility);
//at 50 units deep opacity should == 0
//_MaxDepthVisibility = 50
float depth = 1 - ( depthDifference / _MaxDepthVisibility);
o.Albedo = float3(1,1,1) * _Color;
o.Alpha = depth;
From what i assumed, this should become more opaque the deep the object is under the water surface up to a maximum of 50 units - at which point its always 0 on the alpha.
Yet for me, the whole water surface is transparent so i seem to be getting a final depth of 1.
Everything looks fine from that code, though you mentioned you’re using a Surface Shader. The screenPos variable name is a special variable that the Surface Shader handles. It’s likely ignoring whatever values you’re setting in your custom vertex function, and I don’t believe the built in screenPos calculates the eye depth.
Another issue is that with shaders there isn’t a reliable way to produce automated documentation structures that can then simply be run through by someone and kept maintained reasonably, unlike with the C# stuff. It’s a more involved documentation process that also serves a much smaller userbase compared to the C# side, a userbase that usually will have to learn to be savvy enough to dig through shader includes anyway.
void vert (inout appdata v, out Input o)
{
UNITY_INITIALIZE_OUTPUT(Input, o);
o.screenPosition = ComputeScreenPos(UnityObjectToClipPos(v.vertex));
//o.screenPosition.z = -UnityObjectToViewPos( v.vertex ).z
COMPUTE_EYEDEPTH(o.screenPosition.z);
}
void surf (Input IN, inout SurfaceOutputStandard o)
{
float textureDepth = SAMPLE_DEPTH_TEXTURE_PROJ(_DepthTexture, IN.screenPosition);
// depth of texture sample from water fragment in world units [approximate]
float depthDifference = LinearEyeDepth(textureDepth) - IN.screenPosition.z;
// clamp difference in distance to maximum of 50 units
depthDifference = clamp(depthDifference,0,_MaxDepthVisibility);
//at 50 units deep opacity should == 1
//_MaxDepthVisibility = 50
float depth = saturate(depthDifference / _MaxDepthVisibility);
o.Albedo = float3(1,1,1) * _Color;
o.Alpha = depth;
}
For me i’m just getting a depth of 1 no matter what. That seems to imply to me that the depth difference is always 0…I must be missing something there?
Here is what it looks like in the engine:
Some extra info :
#pragma surface surf Standard vertex:vert alpha:blend
#pragma target 3.0