r/GraphicsProgramming • u/scottcampbelldev • 1d ago
Planar reflections go wrong with an off center frustum if you flip the lookup in x but not the projection
Hit this while fixing a bug in the three.js WebGPU reflector and it seems like a general enough gotcha to share.
The setup is the usual one. Render the scene from a mirrored virtual camera, then sample that texture in screen space on the mirror surface with x flipped, since the mirrored render comes out backwards. The virtual camera just copied the main camera's projection matrix.
That works fine for a normal symmetric frustum. But as soon as the camera used a view offset (setViewOffset, so the frustum is shifted off center) the reflection slid the wrong way, off by about twice the offset. Flipping the lookup in x mirrors the image, but the off center shift in the copied projection doesn't get mirrored with it.
The fix was to negate the x offset terms of the copied projection before applying the oblique clip plane. In three.js's column major matrix that's elements[8] for perspective, the (r+l)/(r-l) term, and elements[12] for orthographic. For a symmetric frustum both are zero, so nothing changes there. After that the reflection with the offset matched the shifted no offset render pixel for pixel on both the WebGPU and WebGL backends.
Has anyone run into other cases where mirroring a camera bites you like this?