I'm rendering geometry in the usual way to a target with a depth texture, then in a post-processing shader pass running an implicit surface ray tracer, comparing the ray-tracer depth value to the saved depth texture to discard fragments behind the existing rendered geometry. The depth comparison isn't right. It looks correct for an orthographic camera, but is slightly off for a perspective camera. I don't have a small working snippet, but here is the relevant code in case my math mistake jumps out at anyone:
Setting the uniforms:
const graphModelViewMatrix = new Matrix4().multiplyMatrices(
this.camera.matrixWorldInverse,
this.world.matrixWorld // coordinate system of the 1st pass geometry
);
const graphNormalMatrix = new Matrix3().getNormalMatrix(modelViewMatrix);
In the post-processing fragment shader:
uniform highp sampler2D depth;
uniform float cameraNear; // this.camera.near
uniform float cameraFar; // this.camera.far
uniform mat4 cameraProjection; // this.camera.projectionMatrix
uniform mat4 graphModelViewMatrix; //
uniform mat3 graphNormalMatrix;
// ... ray-tracing runs for this fragment, finding a point at vec3 p
vec4 pNDC = graphModelViewMatrix * vec4(p, 1.);
float z = (cameraProjection * pNDC).w;
float zDepth = (z - cameraNear) / (cameraFar - cameraNear);
float d = texture2D(depth, vUv).x;
if (zDepth < d) { // set the fragment color for p
Or, more fundamentally, when reading a value from a depth texture, how do I convert that back to a z value in the coordinate system which wrote it?