Fix flare visibility in mirrors

Compute the flare's depth with the same projection used for the scene, then compare it to the depth we read.
This commit is contained in:
llbraughler 2025-10-06 19:51:16 -04:00 committed by Tim Angus
parent c891c337cb
commit b9262943a4

View File

@ -276,7 +276,8 @@ void RB_TestFlare( flare_t *f ) {
float depth; float depth;
qboolean visible; qboolean visible;
float fade; float fade;
float screenZ; float flareDepth;
FBO_t *oldFbo; FBO_t *oldFbo;
backEnd.pc.c_flareTests++; backEnd.pc.c_flareTests++;
@ -301,10 +302,22 @@ void RB_TestFlare( flare_t *f ) {
FBO_Bind(oldFbo); FBO_Bind(oldFbo);
} }
screenZ = backEnd.viewParms.projectionMatrix[14] / // Project flare origin with the CURRENT view (handles oblique near plane)
( ( 2*depth - 1 ) * backEnd.viewParms.projectionMatrix[11] - backEnd.viewParms.projectionMatrix[10] ); vec4_t eyePos, clipPos;
R_TransformModelToClip(f->origin,
backEnd.or.modelMatrix,
backEnd.viewParms.projectionMatrix,
eyePos, clipPos);
if (clipPos[3] <= 0.0f) {
visible = qfalse; // behind eye
} else {
// Treat near-equal depths as visible, tiny margin to avoid false occlusion from rounding
const float depthBias = 1e-5f; // ~256 / 2^24
visible = ( -f->eyeZ - -screenZ ) < 24; float clipDepth = clipPos[2] / clipPos[3]; // [-1,1]
flareDepth = clipDepth * 0.5f + 0.5f; // 0..1
visible = (flareDepth - depthBias) <= depth; // in front (with margin)
}
if ( visible ) { if ( visible ) {
if ( !f->visible ) { if ( !f->visible ) {
@ -555,7 +568,3 @@ void RB_RenderFlares (void) {
GL_SetModelviewMatrix(oldmodelview); GL_SetModelviewMatrix(oldmodelview);
} }