Hi everybody~
I have some trouble with depth render, I need your help
Question 1: why force32bitsFloat effect a lots?
In this PG, force32bitsFloat is set true: https://playground.babylonjs.com/#PZ4PJR#9
In this PG, force32bitsFloat is set false: https://playground.babylonjs.com/#PZ4PJR#10
force32bitsFloat seems not only effect the precious of depth but also sth else?
Question 2: how to convert linear depth to nonLinearDepth? or how to get screenSpace world Position from linear depth?(https://playground.babylonjs.com/#PZ4PJR#13)
In vertex shader:
gl_Position = viewProjection * finalWorld * vec4(positionUpdated, 1.0);
vDepthMetric = ((gl_Position.z + minZ) / (minZ+maxZ));
In fragment Shader:
#ifdef NONLINEARDEPTH
depth=gl_FragCoord.z
#else
depth=vDepthMetric
#endif
gl_FragCoord.xyz = gl_Position.xyz/gl_Position.w;
gl_FragCoord.w = 1/gl_Position.w;
… I always write shader in localSpace and worldSpace. I’m not clearly understand calculation from view space to fragCoord
There are simply not enough precision in a 16 bits float when using a non linear z.
Using a linear z does help:
This PG is using a linear depth renderer in 16 bits float mode.
Derivation of the formula for the linear case:
- See Mathematics of the depth metric when generating shadow maps and rendering with shadows | Babylon.js Documentation =>
zpersp (=zclip) = c * z + d
=>zndc = c + d / z
as we dividezclip
byw
to getzndc
andw = z
(because the last column of the projection matrix is (0 0 1 0)). - To get rid of z in the above equation, we note that
zndc = zclip / z
and replacez
byzclip / zndc
. You end up withzndc = c / (1 - d / zclip)
, withc = projection[2].z
andd = projection[3].z
.
In the PG c
and d
are negated because you are setting the scene in right handed mode (the derivation above is for a left handed mode).
2 Likes
Thank you