Skip to content

Commit 1e681c3

Browse files
committed
ref: gl: add r_dlight_virtual_radius. It potentially fixes ugly dlight 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.
1 parent a955d1e commit 1e681c3

File tree

3 files changed

+49
-19
lines changed

3 files changed

+49
-19
lines changed

ref/gl/gl_local.h

+2-1
Original file line numberDiff line numberDiff line change
@@ -388,7 +388,7 @@ void R_TextureReplacementReport( const char *modelname, int gl_texturenum, const
388388
void CL_RunLightStyles( lightstyle_t *ls );
389389
void R_PushDlights( void );
390390
void R_GetLightSpot( vec3_t lightspot );
391-
void R_MarkLights( dlight_t *light, int bit, mnode_t *node );
391+
void R_MarkLights( const dlight_t *light, int bit, const mnode_t *node );
392392
colorVec R_LightVec( const vec3_t start, const vec3_t end, vec3_t lightspot, vec3_t lightvec );
393393
colorVec R_LightPoint( const vec3_t p0 );
394394

@@ -812,6 +812,7 @@ extern convar_t r_ripple;
812812
extern convar_t r_ripple_updatetime;
813813
extern convar_t r_ripple_spawntime;
814814
extern convar_t r_large_lightmaps;
815+
extern convar_t r_dlight_virtual_radius;
815816

816817
//
817818
// engine shared convars

ref/gl/gl_opengl.c

+2
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ CVAR_DEFINE_AUTO( r_ripple, "0", FCVAR_GLCONFIG, "enable software-like water tex
3838
CVAR_DEFINE_AUTO( r_ripple_updatetime, "0.05", FCVAR_GLCONFIG, "how fast ripple simulation is" );
3939
CVAR_DEFINE_AUTO( r_ripple_spawntime, "0.1", FCVAR_GLCONFIG, "how fast new ripples spawn" );
4040
CVAR_DEFINE_AUTO( r_large_lightmaps, "0", FCVAR_GLCONFIG|FCVAR_LATCH, "enable larger lightmap atlas textures (might break custom renderer mods)" );
41+
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" );
4142

4243
DEFINE_ENGINE_SHARED_CVAR_LIST()
4344

@@ -1155,6 +1156,7 @@ static void GL_InitCommands( void )
11551156
gEngfuncs.Cvar_RegisterVariable( &r_vbo_overbrightmode );
11561157
gEngfuncs.Cvar_RegisterVariable( &r_vbo_detail );
11571158
gEngfuncs.Cvar_RegisterVariable( &r_large_lightmaps );
1159+
gEngfuncs.Cvar_RegisterVariable( &r_dlight_virtual_radius );
11581160

11591161
gEngfuncs.Cvar_RegisterVariable( &gl_extensions );
11601162
gEngfuncs.Cvar_RegisterVariable( &gl_texture_nearest );

ref/gl/gl_rlight.c

+45-18
Original file line numberDiff line numberDiff line change
@@ -99,48 +99,75 @@ void CL_RunLightStyles( lightstyle_t *ls )
9999
R_MarkLights
100100
=============
101101
*/
102-
void R_MarkLights( dlight_t *light, int bit, mnode_t *node )
102+
void R_MarkLights( const dlight_t *light, int bit, const mnode_t *node )
103103
{
104-
float dist;
105-
msurface_t *surf;
106-
int i;
104+
const float virtual_radius = light->radius * Q_max( 1.0f, r_dlight_virtual_radius.value );
105+
const float maxdist = light->radius * light->radius;
106+
float dist;
107+
int i;
107108
mnode_t *children[2];
108109
int firstsurface, numsurfaces;
109110

111+
start:
112+
110113
if( !node || node->contents < 0 )
111114
return;
112115

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

115118
node_children( children, node, RI.currentmodel );
116-
firstsurface = node_firstsurface( node, RI.currentmodel );
117-
numsurfaces = node_numsurfaces( node, RI.currentmodel );
118119

119-
if( dist > light->radius )
120+
if( dist > virtual_radius )
120121
{
121-
R_MarkLights( light, bit, children[0] );
122-
return;
122+
node = children[0];
123+
goto start;
123124
}
124-
if( dist < -light->radius )
125+
126+
if( dist < -virtual_radius )
125127
{
126-
R_MarkLights( light, bit, children[1] );
127-
return;
128+
node = children[1];
129+
goto start;
128130
}
129131

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

133-
for( i = 0; i < numsurfaces; i++, surf++ )
136+
for( i = 0; i < numsurfaces; i++ )
134137
{
135-
if( !BoundsAndSphereIntersect( surf->info->mins, surf->info->maxs, light->origin, light->radius ))
136-
continue; // no intersection
138+
vec3_t impact;
139+
float s, t, l;
140+
msurface_t *surf = &RI.currentmodel->surfaces[firstsurface + i];
141+
const mextrasurf_t *info = surf->info;
142+
143+
if( surf->plane->type < 3 )
144+
{
145+
VectorCopy( light->origin, impact );
146+
impact[surf->plane->type] -= dist;
147+
}
148+
else VectorMA( light->origin, -dist, surf->plane->normal, impact );
149+
150+
// a1ba: taken from JoeQuake, but it's probably originated in FitzQuake
151+
// clamp center of light to corner and check brightness
152+
l = DotProduct( impact, info->lmvecs[0] ) + info->lmvecs[0][3] - info->lightmapmins[0];
153+
s = l + 0.5;
154+
s = bound( 0, s, info->lightextents[0] );
155+
s = l - s;
156+
157+
l = DotProduct( impact, info->lmvecs[1] ) + info->lmvecs[1][3] - info->lightmapmins[1];
158+
t = l + 0.5;
159+
t = bound( 0, t, info->lightextents[1] );
160+
t = l - t;
161+
162+
if( s * s + t * t + dist * dist >= maxdist )
163+
continue;
137164

138165
if( surf->dlightframe != tr.dlightframecount )
139166
{
140-
surf->dlightbits = 0;
167+
surf->dlightbits = bit;
141168
surf->dlightframe = tr.dlightframecount;
142169
}
143-
surf->dlightbits |= bit;
170+
else surf->dlightbits |= bit;
144171
}
145172

146173
R_MarkLights( light, bit, children[0] );

0 commit comments

Comments
 (0)