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 (which traces back to FitzQuake, in which it is attributed to LadyHavoc, Darkplaces author) to exactly calculate whether the light hits the surface, so we don't wrongly enable lighting on a surface by an increased radius.
This commit is contained in:
parent
a955d1e957
commit
b5cb0b9f10
3 changed files with 50 additions and 19 deletions
|
@ -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 );
|
||||
|
||||
|
@ -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
|
||||
|
|
|
@ -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()
|
||||
|
||||
|
@ -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 );
|
||||
|
|
|
@ -99,48 +99,76 @@ 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: the fix was taken from JoeQuake, which traces back to FitzQuake,
|
||||
// which attributes it to LadyHavoc (Darkplaces author)
|
||||
// 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] );
|
||||
|
|
Loading…
Add table
Reference in a new issue