Skip to content

Commit

Permalink
ref: gl: add r_dlight_virtual_radius. It potentially fixes ugly dligh…
Browse files Browse the repository at this point in the history
…t cut off on largely scaled textures (or at least allows to tune it)

It also adds a fix found in JoeQuake to exactly calculate whether the light
hits the surface, so we don't wrongly enable lighting on a surface by an
increased radius.
  • Loading branch information
a1batross committed Feb 7, 2025
1 parent f4a5b13 commit a42102f
Show file tree
Hide file tree
Showing 3 changed files with 49 additions and 19 deletions.
3 changes: 2 additions & 1 deletion ref/gl/gl_local.h
Original file line number Diff line number Diff line change
Expand Up @@ -388,7 +388,7 @@ void R_TextureReplacementReport( const char *modelname, int gl_texturenum, const
void CL_RunLightStyles( lightstyle_t *ls );
void R_PushDlights( void );
void R_GetLightSpot( vec3_t lightspot );
void R_MarkLights( dlight_t *light, int bit, mnode_t *node );
void R_MarkLights( const dlight_t *light, int bit, const mnode_t *node );
colorVec R_LightVec( const vec3_t start, const vec3_t end, vec3_t lightspot, vec3_t lightvec );
colorVec R_LightPoint( const vec3_t p0 );

Expand Down Expand Up @@ -812,6 +812,7 @@ extern convar_t r_ripple;
extern convar_t r_ripple_updatetime;
extern convar_t r_ripple_spawntime;
extern convar_t r_large_lightmaps;
extern convar_t r_dlight_virtual_radius;

//
// engine shared convars
Expand Down
2 changes: 2 additions & 0 deletions ref/gl/gl_opengl.c
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ CVAR_DEFINE_AUTO( r_ripple, "0", FCVAR_GLCONFIG, "enable software-like water tex
CVAR_DEFINE_AUTO( r_ripple_updatetime, "0.05", FCVAR_GLCONFIG, "how fast ripple simulation is" );
CVAR_DEFINE_AUTO( r_ripple_spawntime, "0.1", FCVAR_GLCONFIG, "how fast new ripples spawn" );
CVAR_DEFINE_AUTO( r_large_lightmaps, "0", FCVAR_GLCONFIG|FCVAR_LATCH, "enable larger lightmap atlas textures (might break custom renderer mods)" );
CVAR_DEFINE_AUTO( r_dlight_virtual_radius, "3", FCVAR_GLCONFIG, "increase dlight radius virtually by this amount, should help against ugly cut off dlights on highly scaled textures" );

DEFINE_ENGINE_SHARED_CVAR_LIST()

Expand Down Expand Up @@ -1155,6 +1156,7 @@ static void GL_InitCommands( void )
gEngfuncs.Cvar_RegisterVariable( &r_vbo_overbrightmode );
gEngfuncs.Cvar_RegisterVariable( &r_vbo_detail );
gEngfuncs.Cvar_RegisterVariable( &r_large_lightmaps );
gEngfuncs.Cvar_RegisterVariable( &r_dlight_virtual_radius );

gEngfuncs.Cvar_RegisterVariable( &gl_extensions );
gEngfuncs.Cvar_RegisterVariable( &gl_texture_nearest );
Expand Down
63 changes: 45 additions & 18 deletions ref/gl/gl_rlight.c
Original file line number Diff line number Diff line change
Expand Up @@ -99,48 +99,75 @@ void CL_RunLightStyles( lightstyle_t *ls )
R_MarkLights
=============
*/
void R_MarkLights( dlight_t *light, int bit, mnode_t *node )
void R_MarkLights( const dlight_t *light, int bit, const mnode_t *node )
{
float dist;
msurface_t *surf;
int i;
const float virtual_radius = light->radius * Q_max( 1.0f, r_dlight_virtual_radius.value );
const float maxdist = light->radius * light->radius;
float dist;
int i;
mnode_t *children[2];
int firstsurface, numsurfaces;

start:

if( !node || node->contents < 0 )
return;

dist = PlaneDiff( light->origin, node->plane );

node_children( children, node, RI.currentmodel );
firstsurface = node_firstsurface( node, RI.currentmodel );
numsurfaces = node_numsurfaces( node, RI.currentmodel );

if( dist > light->radius )
if( dist > virtual_radius )
{
R_MarkLights( light, bit, children[0] );
return;
node = children[0];
goto start;
}
if( dist < -light->radius )

if( dist < -virtual_radius )
{
R_MarkLights( light, bit, children[1] );
return;
node = children[1];
goto start;
}

// mark the polygons
surf = RI.currentmodel->surfaces + firstsurface;
firstsurface = node_firstsurface( node, RI.currentmodel );
numsurfaces = node_numsurfaces( node, RI.currentmodel );

for( i = 0; i < numsurfaces; i++, surf++ )
for( i = 0; i < numsurfaces; i++ )
{
if( !BoundsAndSphereIntersect( surf->info->mins, surf->info->maxs, light->origin, light->radius ))
continue; // no intersection
vec3_t impact;
float s, t, l;
msurface_t *surf = &RI.currentmodel->surfaces[firstsurface + i];
const mextrasurf_t *info = surf->info;

if( surf->plane->type < 3 )
{
VectorCopy( light->origin, impact );
impact[surf->plane->type] -= dist;
}
else VectorMA( light->origin, -dist, surf->plane->normal, impact );

// a1ba: taken from JoeQuake, but it's probably originated in FitzQuake
// clamp center of light to corner and check brightness
l = DotProduct( impact, info->lmvecs[0] ) + info->lmvecs[0][3] - info->lightmapmins[0];
s = l + 0.5;
s = bound( 0, s, info->lightextents[0] );
s = l - s;

l = DotProduct( impact, info->lmvecs[1] ) + info->lmvecs[1][3] - info->lightmapmins[1];
t = l + 0.5;
t = bound( 0, t, info->lightextents[1] );
t = l - t;

if( s * s + t * t + dist * dist >= maxdist )
continue;

if( surf->dlightframe != tr.dlightframecount )
{
surf->dlightbits = 0;
surf->dlightbits = bit;
surf->dlightframe = tr.dlightframecount;
}
surf->dlightbits |= bit;
else surf->dlightbits |= bit;
}

R_MarkLights( light, bit, children[0] );
Expand Down

0 comments on commit a42102f

Please sign in to comment.