# Transforming 3d point for depth testing

I have a ray and its direction is (o,d). Multiply it by the model matrix to rotate the model.

o = uCamera.xyz, d = GenRay();
o = vec3(uModel * vec4(o,1));
d = vec3(uModel * vec4(d,0));


Then beam, RayMarchLeaf(o, d, t, color, normal); where get the position vec3 t of the collision of the beam. (in model coordinates). Then traslate t to world coordinates :

t = vec3(inverse(uModel) * vec4(t,1)); // map to world pos;


ok, we have a 3d camera coordinate and a point. For Depth value, we can use length(uCamera.xyz - t), but this is not accurate. My camera is moving and rotating in 3d space.
How to accurate calculate depth value to store in texture?

• yes, I need a perpendicular, for more accurate calculations Aug 29, 2022 at 14:14

There is no direct correct answer to this as each engine's depth texture is packed differently. And also differ depending on the math behind it.

But as a broad answer is instead to unpack the depth value back to 3d, you can calculate the distance from there. To do this, you could multiply the depth value with the inverse View*Projection ( ClipspaceToWorldSpace ).

Here is an example code on how I rebuild the 3d position in the unity engine.

float2 uv = i.vPosition.xy / _ScreenParams.xy;
GBufferOutput gBuffer = UnpackGBuffer( uv );

float z = tex2D( _CameraDepthTexture, uv);
float linearZ = Linear01Depth( z );
float w = linearZ * _ProjectionParams.z;
float x = uv.x * 2.0 - 1.0;
float y = uv.y * 2.0 - 1.0;
float4 vProjectedPos = float4( x, y, z, 1.0 );
float4 vPositionVS = mul( mProjectionToView, vProjectedPos );
vPositionVS.xyz *= w;

float4 vWorldPosition = mul( mViewToWorld, float4( vPositionVS.xyz, 1.0 ) );


Where: UV = is the screen position coordinates. Z = depth value on texture.

It might not be the best solution in the world, but it does the trick! I hope this helps!

• Thanks for the answer, I have pure c++/gsl. But it is necessary to calculate the opposite, from the 3d position of the world to depth value. Aug 30, 2022 at 18:18

What i need - just multiply world coordinate by the product of view and projection matrices then do perspective divide.

mat4 viewproj = uProjection * uView; //calculate viewproj
vec4 clip_space_coord = viewproj * t; //do transform
//perspectice division (done automatically by the hardware between
//vertex and fragment shader stages, so you don't actually need to do this
//if you do this in a vertex shader and then continue to the fragment)
clip_space_coord = clip_space_coord / clip_space_coord.w; // perspective devide;