0
\$\begingroup\$

I have a raymarching shader which computes the location of a hit on the scene in world space.

float3 worldPos = ... ;

I can verify that the world position is right, because the position of everything renders correctly, even in stereoscopic rendering.

Now I'm trying to convert this to clip space so that I can write the right value into the Z-buffer. I initially thought it would be like this:

float4 clipPos = mul(UNITY_MATRIX_VP, float4(worldPos, 1.0));
output.depth = clipPos.z / clipPos.w;

But this turns out to be completely wrong:

nope 1

What is the correct way to get the right Z value?

Investigation 1:

Tinkering with it a bit, I started trying random multiplication factors:

float4 clipPos = mul(UNITY_MATRIX_VP, float4(worldPos, 1.0));
output.depth = clipPos.z * 100 / clipPos.w;

This turns out to look exactly right in the editor:

nope 2

But it looks wrong in the game view. This, however, looks right in the game view:

float4 clipPos = mul(UNITY_MATRIX_VP, float4(worldPos, 1.0));
output.depth = clipPos.z * 96 / clipPos.w;

I assume that the difference is somehow due to the settings on the different cameras. So now I'm trying to figure out: what is the correct way to do this, to get the right value irrespective of the camera?

Investigation 2:

I'm trying to render this as the scene skybox.

If I render the same thing onto a cube, the generated depth values appear to be correct. Is there a different value in UNITY_MATRIX_VP when rendering the skybox, which results in the wrong result?

How far away is the skybox actually? Everyone just says "it's infinitely far", but that's nonsense - if it were really infinitely far, the world position of every point on the thing would be infinity, and transforming that to view space and clip space would also give infinity.

\$\endgroup\$
  • \$\begingroup\$ "Is there a different value in UNITY_MATRIX_VP when rendering the skybox" I think you're on the right track. When we say the skybox is infinitely far away, we mean it doesn't exhibit parallax as the camera moves. (Parallax decreases with distance: zero parallax = infinite distance) The portion of the skybox you see depends only on the direction you're looking, not on the position of the view point. That means it's often rendered with the translation component of the view matrix zero'd out. \$\endgroup\$ – DMGregory Jul 11 '18 at 11:33
  • \$\begingroup\$ @DMGregory From my experimentation, it seemed that the skybox was in object space [-0.5,-0.5]..[+0.5,+0.5]. My next idea was that maybe the world space would be up to the camera far plane, but it didn't quite work out - whether I set the far plane on the camera to 100 or 1000, the value 96 appeared to give the right rendering. So at the moment, the status of this little project is, produces the right rendering for all tested situations, but will probably break for somebody. :) The next investigation step is going to be to try and determine the matrix transforms. \$\endgroup\$ – Trejkaz Jul 12 '18 at 0:23

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.