Hi everyone! I’m using this shader to display zbuffer:
the result is always solid white color. No matter, if I apply is directly to the object, or to the camera as replacement shader. And changing camera near/far values helps not.
Ah, actually I was wrong. Making near clip plane 2, and far clip plane 50, I can see some difference. When I take print-screen, object pixel values ara ranging grom 200 to 255. I know that perspective buffer is non-linear, but is that really that hard to utilize full 0-255 range using it?
Honestly, keeping near plane like 5 and far like 10 is insane =)
there are a few threads on that, I think Aras posted on them explaining it a bit more detailed than this one line
Also the depth buffer is not 1 byte, but 3 / 4 byte depending on the hardware (24 or 32bit depth buffer) so I’m not sure if you really want to swizzle it to trash with .xxxx
I’ve searched all forums before this, maybe I’ve missed that thread. I’ll try searching by Aras user name now. The only hint I’ve got so far is that I have to use “LinearEyeDepth” somehow.
Hmm, my bad I do not understand what is actually going on in this line “i.Z.xxxx;”
But I can guess, that this assigment
o.Z = oPos.zzz;
sets same 1 byte value to Z
and later on
same byte value is used here
i.Z.xxxx;
But if I want to utilize more then 1 byte value, I guess I can’t use printscreen, will have to think of a way to save it to file firstly
The depth buffer doesn’t really figure into this, because you’re not reading from it and you already know the eye depth. The issue is just that you’re passing an arbitrary depth as a colour. This means that any fragment further than 1 unit away from the camera will be white, regardless of the far clipping plane.
What you want to do is normalize the depth value according to your camera’s depth range. Unity provides projection parameters if you declare the variable, so you don’t have to set up any more properties:
Shader "Depth Me Proper" {
SubShader {
Pass {
Fog { Mode Off }
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
// Unity-provided projection parameters:
// x = 1 or -1 (-1 if projection is flipped)
// y = near plane
// z = far plane
// w = 1/far plane
uniform float4 _ProjectionParams;
struct v2f {
float4 pos : POSITION;
float Z : TEXCOORD0;
};
v2f vert (float4 vertex : POSITION) {
v2f o;
float4 oPos = mul(UNITY_MATRIX_MVP, vertex);
o.pos = oPos;
o.Z = oPos.z/(_ProjectionParams.z - _ProjectionParams.y);
return o;
}
half4 frag( v2f i ) : COLOR {
return i.Z.xxxx;
}
ENDCG
}
}
}
I should mention that you and dreamora’s understanding of swizzling seems to be a bit confused. Swizzling is for selecting specific elements in Cg vector types. It does not move individual bytes in a single value. Sampling a texture always returns a four-component value, so swizzling is necessary in the case of a depth texture, which only populates the first component:
float depth = tex2D(_CameraDepthTexture, uv).x;
Swizzling (or “smearing”) a value using .xxxx just copies that value four times into a vector. You don’t have to worry about messing up your numbers with swizzling unless you’re packing values into multiple elements with some special format, such as with the En/DecodeFloat functions in UnityCG.cginc.
But I was definitely misslead on what is to be found in there from COLOR and comparable vectors where using .aaaa or just 4 times the same would mess up the return as it destroys 3 of 4 bytes in the resulting new color / vector.