diff --git a/src/engine/renderer/gl_shader.cpp b/src/engine/renderer/gl_shader.cpp index 0c4b21bd45..d37926ffdb 100644 --- a/src/engine/renderer/gl_shader.cpp +++ b/src/engine/renderer/gl_shader.cpp @@ -599,7 +599,7 @@ static std::string GenEngineConstants() { // Engine constants std::string str; - AddDefine( str, "r_AmbientScale", r_ambientScale->value ); + AddDefine( str, "r_AmbientScale", r_ambientScale.Get() ); AddDefine( str, "r_SpecularScale", r_specularScale->value ); AddDefine( str, "r_zNear", r_znear->value ); diff --git a/src/engine/renderer/tr_animation.cpp b/src/engine/renderer/tr_animation.cpp index 9e5fe88fd5..fd56eee833 100644 --- a/src/engine/renderer/tr_animation.cpp +++ b/src/engine/renderer/tr_animation.cpp @@ -679,12 +679,6 @@ void R_AddMD5Surfaces( trRefEntity_t *ent ) return; } - // set up lighting now that we know we aren't culled - if ( !personalModel || glConfig2.shadowMapping ) - { - R_SetupEntityLighting( &tr.refdef, ent, nullptr ); - } - // see if we are in a fog volume fogNum = R_FogWorldBox( ent->worldBounds ); diff --git a/src/engine/renderer/tr_bsp.cpp b/src/engine/renderer/tr_bsp.cpp index f366f28379..94ef1e982f 100644 --- a/src/engine/renderer/tr_bsp.cpp +++ b/src/engine/renderer/tr_bsp.cpp @@ -3955,7 +3955,7 @@ static void R_LoadFogs( lump_t *l, lump_t *brushesLump, lump_t *sidesLump ) Log::Debug("%i fog volumes loaded", s_worldData.numFogs ); } -static void R_SetDefaultLightGrid() +static void R_SetConstantColorLightGrid( const byte color[3] ) { world_t *w = &s_worldData; @@ -3983,9 +3983,9 @@ static void R_SetDefaultLightGrid() bspGridPoint2_t *gridPoint2 = (bspGridPoint2_t *) (gridPoint1 + w->numLightGridPoints); // default some white light from above - gridPoint1->color[ 0 ] = 64; - gridPoint1->color[ 1 ] = 64; - gridPoint1->color[ 2 ] = 64; + gridPoint1->color[ 0 ] = color[0]; + gridPoint1->color[ 1 ] = color[1]; + gridPoint1->color[ 2 ] = color[2]; gridPoint1->ambientPart = 128; gridPoint2->direction[ 0 ] = floatToSnorm8(0.0f); gridPoint2->direction[ 1 ] = floatToSnorm8(0.0f); @@ -4039,9 +4039,16 @@ void R_LoadLightGrid( lump_t *l ) vec3_t ambientColor, directedColor, direction; float scale; + if ( tr.ambientLightSet ) { + const byte color[3]{ floatToUnorm8( tr.ambientLight[0] ), floatToUnorm8( tr.ambientLight[1] ), + floatToUnorm8( tr.ambientLight[2] ) }; + R_SetConstantColorLightGrid( color ); + } + if ( !r_precomputedLighting->integer ) { - R_SetDefaultLightGrid(); + const byte color[3] { 64, 64, 64 }; + R_SetConstantColorLightGrid( color ); return; } @@ -4081,7 +4088,8 @@ void R_LoadLightGrid( lump_t *l ) { Log::Warn("light grid mismatch, default light grid used" ); - R_SetDefaultLightGrid(); + const byte color[3]{ 64, 64, 64 }; + R_SetConstantColorLightGrid( color ); return; } @@ -4116,6 +4124,12 @@ void R_LoadLightGrid( lump_t *l ) tmpDirected[ 2 ] = in->directed[ 2 ]; tmpDirected[ 3 ] = 255; + if ( tmpAmbient[0] < r_forceAmbient.Get() && + tmpAmbient[1] < r_forceAmbient.Get() && + tmpAmbient[2] < r_forceAmbient.Get() ) { + VectorSet( tmpAmbient, r_forceAmbient.Get(), r_forceAmbient.Get(), r_forceAmbient.Get() ); + } + if ( tr.legacyOverBrightClamping ) { R_ColorShiftLightingBytes( tmpAmbient ); @@ -4338,13 +4352,12 @@ void R_LoadEntities( lump_t *l, std::string &externalEntities ) // check for ambient color else if ( !Q_stricmp( keyname, "_color" ) || !Q_stricmp( keyname, "ambientColor" ) ) { - if ( r_forceAmbient->value <= 0 ) - { - sscanf( value, "%f %f %f", &tr.worldEntity.ambientLight[ 0 ], &tr.worldEntity.ambientLight[ 1 ], - &tr.worldEntity.ambientLight[ 2 ] ); + if ( r_forceAmbient.Get() == 0 ) { + sscanf( value, "%f %f %f", &tr.ambientLight[0], &tr.ambientLight[1], + &tr.ambientLight[2] ); - VectorCopy( tr.worldEntity.ambientLight, tr.worldEntity.ambientLight ); - VectorScale( tr.worldEntity.ambientLight, r_ambientScale->value, tr.worldEntity.ambientLight ); + VectorScale( tr.ambientLight, r_ambientScale.Get(), tr.ambientLight ); + tr.ambientLightSet = true; } } @@ -5048,11 +5061,6 @@ void RE_LoadWorldMap( const char *name ) VectorNormalize( tr.sunDirection ); - // set default ambient color - tr.worldEntity.ambientLight[ 0 ] = r_forceAmbient->value; - tr.worldEntity.ambientLight[ 1 ] = r_forceAmbient->value; - tr.worldEntity.ambientLight[ 2 ] = r_forceAmbient->value; - tr.worldMapLoaded = true; // load it diff --git a/src/engine/renderer/tr_init.cpp b/src/engine/renderer/tr_init.cpp index 543adc87c0..686592e4e0 100644 --- a/src/engine/renderer/tr_init.cpp +++ b/src/engine/renderer/tr_init.cpp @@ -216,8 +216,9 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA cvar_t *r_wolfFog; cvar_t *r_noFog; - cvar_t *r_forceAmbient; - cvar_t *r_ambientScale; + Cvar::Range> r_forceAmbient( "r_forceAmbient", "Minimal light amount in lightGrid", Cvar::NONE, + 0.125f, 0.0f, 0.3f ); + Cvar::Cvar r_ambientScale( "r_ambientScale", "Scale lightGrid produced by ambientColor keyword by this much", Cvar::CHEAT, 1.0 ); cvar_t *r_lightScale; cvar_t *r_debugSort; cvar_t *r_printShaders; @@ -1165,8 +1166,7 @@ ScreenshotCmd screenshotPNGRegistration("screenshotPNG", ssFormat_t::SSF_PNG, "p r_wolfFog = Cvar_Get( "r_wolfFog", "1", CVAR_CHEAT ); r_noFog = Cvar_Get( "r_noFog", "0", CVAR_CHEAT ); - r_forceAmbient = Cvar_Get( "r_forceAmbient", "0.125", CVAR_LATCH ); - AssertCvarRange( r_forceAmbient, 0.0f, 0.3f, false ); + Cvar::Latch( r_forceAmbient ); r_smp = Cvar_Get( "r_smp", "0", CVAR_LATCH ); @@ -1192,7 +1192,7 @@ ScreenshotCmd screenshotPNGRegistration("screenshotPNG", ssFormat_t::SSF_PNG, "p r_gamma = Cvar_Get( "r_gamma", "1.0", CVAR_ARCHIVE ); r_facePlaneCull = Cvar_Get( "r_facePlaneCull", "1", 0 ); - r_ambientScale = Cvar_Get( "r_ambientScale", "1.0", CVAR_CHEAT | CVAR_LATCH ); + Cvar::Latch( r_ambientScale ); r_lightScale = Cvar_Get( "r_lightScale", "2", CVAR_CHEAT ); r_vboFaces = Cvar_Get( "r_vboFaces", "1", CVAR_CHEAT ); diff --git a/src/engine/renderer/tr_light.cpp b/src/engine/renderer/tr_light.cpp index c134b3ea5f..c6fbaf27db 100644 --- a/src/engine/renderer/tr_light.cpp +++ b/src/engine/renderer/tr_light.cpp @@ -248,110 +248,18 @@ int R_LightForPoint( vec3_t point, vec3_t ambientLight, vec3_t directedLight, ve VectorNormalize( lightDir ); - if ( ambientLight[ 0 ] < r_forceAmbient->value && - ambientLight[ 1 ] < r_forceAmbient->value && - ambientLight[ 2 ] < r_forceAmbient->value ) + if ( ambientLight[ 0 ] < r_forceAmbient.Get() && + ambientLight[ 1 ] < r_forceAmbient.Get() && + ambientLight[ 2 ] < r_forceAmbient.Get() ) { - ambientLight[ 0 ] = r_forceAmbient->value; - ambientLight[ 1 ] = r_forceAmbient->value; - ambientLight[ 2 ] = r_forceAmbient->value; + ambientLight[ 0 ] = r_forceAmbient.Get(); + ambientLight[ 1 ] = r_forceAmbient.Get(); + ambientLight[ 2 ] = r_forceAmbient.Get(); } return true; } -/* -================= -R_SetupEntityLightingGrid -================= -*/ -static void R_SetupEntityLightingGrid( trRefEntity_t *ent, vec3_t forcedOrigin ) -{ - vec3_t lightOrigin; - - if ( forcedOrigin ) - { - VectorCopy( forcedOrigin, lightOrigin ); - } - else - { - if ( ent->e.renderfx & RF_LIGHTING_ORIGIN ) - { - // separate lightOrigins are needed so an object that is - // sinking into the ground can still be lit, and so - // multi-part models can be lit identically - VectorCopy( ent->e.lightingOrigin, lightOrigin ); - } - else - { - VectorCopy( ent->e.origin, lightOrigin ); - } - } - - R_LightForPoint( lightOrigin, ent->ambientLight, ent->directedLight, - ent->lightDir ); -} - -/* -================= -R_SetupEntityLighting - -Calculates all the lighting values that will be used -by the Calc_* functions -================= -*/ -void R_SetupEntityLighting( const trRefdef_t *refdef, trRefEntity_t *ent, vec3_t forcedOrigin ) -{ - // lighting calculations - if ( ent->lightingCalculated ) - { - return; - } - - ent->lightingCalculated = true; - - // if NOWORLDMODEL, only use dynamic lights (menu system, etc) - if ( !( refdef->rdflags & RDF_NOWORLDMODEL ) && tr.world - && tr.world->lightGridData1 && tr.world->lightGridData2 ) - { - R_SetupEntityLightingGrid( ent, forcedOrigin ); - } - else - { - /* Historically those values were multiplied by - tr.identityLight but tr.identityLight is always 1.0f - in Dæmon engine as the overbright bit implementation - is fully software. */ - - //% ent->ambientLight[0] = ent->ambientLight[1] = ent->ambientLight[2] = 150.0f; - //% ent->directedLight[0] = ent->directedLight[1] = ent->directedLight[2] = 150.0f; - //% VectorCopy( tr.sunDirection, ent->lightDir ); - ent->ambientLight[ 0 ] = 64.0f / 255.0f; - ent->ambientLight[ 1 ] = 64.0f / 255.0f; - ent->ambientLight[ 2 ] = 96.0f / 255.0f; - - ent->directedLight[ 0 ] = 255.0f / 255.0f; - ent->directedLight[ 1 ] = 232.0f / 255.0f; - ent->directedLight[ 2 ] = 224.0f / 255.0f; - - VectorSet( ent->lightDir, -1, 1, 1.25 ); - VectorNormalize( ent->lightDir ); - } - - if ( ( ent->e.renderfx & RF_MINLIGHT ) ) // && VectorLength(ent->ambientLight) <= 0) - { - /* Historically those values were multiplied by - tr.identityLight but tr.identityLight is always 1.0f - in Dæmon engine as the as the overbright bit - implementation is fully software. */ - - // give everything a minimum light add - ent->ambientLight[ 0 ] += 0.125f; - ent->ambientLight[ 1 ] += 0.125f; - ent->ambientLight[ 2 ] += 0.125f; - } -} - /* ================= R_SetupLightOrigin diff --git a/src/engine/renderer/tr_local.h b/src/engine/renderer/tr_local.h index 42988156a4..2a2d4637ef 100644 --- a/src/engine/renderer/tr_local.h +++ b/src/engine/renderer/tr_local.h @@ -465,10 +465,6 @@ enum class shaderProfilerRenderSubGroupsMode { // local float axisLength; // compensate for non-normalized axis - bool lightingCalculated; - vec3_t lightDir; // normalized direction towards light - vec3_t ambientLight; // color normalized to 0-1 - vec3_t directedLight; cullResult_t cull; vec3_t localBounds[ 2 ]; @@ -2755,6 +2751,9 @@ enum class shaderProfilerRenderSubGroupsMode { std::vector lightmaps; std::vector deluxemaps; + vec3_t ambientLight; + bool ambientLightSet = false; + image_t *lightGrid1Image; image_t *lightGrid2Image; @@ -2890,9 +2889,9 @@ enum class shaderProfilerRenderSubGroupsMode { extern cvar_t *r_wolfFog; extern cvar_t *r_noFog; - - extern cvar_t *r_forceAmbient; - extern cvar_t *r_ambientScale; + + extern Cvar::Range> r_forceAmbient; + extern Cvar::Cvar r_ambientScale; extern cvar_t *r_lightScale; extern Cvar::Cvar r_drawSky; // Controls whether sky should be drawn or cleared. @@ -3563,7 +3562,6 @@ inline bool checkGLErrors() */ void R_AddBrushModelInteractions( trRefEntity_t *ent, trRefLight_t *light, interactionType_t iaType ); - void R_SetupEntityLighting( const trRefdef_t *refdef, trRefEntity_t *ent, vec3_t forcedOrigin ); float R_InterpolateLightGrid( world_t *w, int from[3], int to[3], float *factors[3], vec3_t ambientLight, vec3_t directedLight, vec3_t lightDir ); diff --git a/src/engine/renderer/tr_mesh.cpp b/src/engine/renderer/tr_mesh.cpp index 3338777fc1..8aefcda50b 100644 --- a/src/engine/renderer/tr_mesh.cpp +++ b/src/engine/renderer/tr_mesh.cpp @@ -302,12 +302,6 @@ void R_AddMDVSurfaces( trRefEntity_t *ent ) return; } - // set up lighting now that we know we aren't culled - if ( !personalModel || glConfig2.shadowMapping ) - { - R_SetupEntityLighting( &tr.refdef, ent, nullptr ); - } - // see if we are in a fog volume fogNum = R_FogWorldBox( ent->worldBounds ); diff --git a/src/engine/renderer/tr_model_iqm.cpp b/src/engine/renderer/tr_model_iqm.cpp index 167bc98e40..c865571542 100644 --- a/src/engine/renderer/tr_model_iqm.cpp +++ b/src/engine/renderer/tr_model_iqm.cpp @@ -948,10 +948,8 @@ void R_AddIQMSurfaces( trRefEntity_t *ent ) { personalModel = (ent->e.renderfx & RF_THIRD_PERSON) && tr.viewParms.portalLevel == 0; - // // cull the entire model if merged bounding box of both frames // is outside the view frustum. - // R_CullIQM( ent ); // HACK: Never cull first-person models, due to issues with a certain model's bounds @@ -962,16 +960,7 @@ void R_AddIQMSurfaces( trRefEntity_t *ent ) { return; } - // - // set up lighting now that we know we aren't culled - // - if ( !personalModel || glConfig2.shadowMapping ) { - R_SetupEntityLighting( &tr.refdef, ent, nullptr ); - } - - // // see if we are in a fog volume - // fogNum = R_FogWorldBox( ent->worldBounds ); for ( i = 0 ; i < IQModel->num_surfaces ; i++ ) { diff --git a/src/engine/renderer/tr_scene.cpp b/src/engine/renderer/tr_scene.cpp index 2aa9d5cf6a..aa02565b4a 100644 --- a/src/engine/renderer/tr_scene.cpp +++ b/src/engine/renderer/tr_scene.cpp @@ -274,7 +274,6 @@ void RE_AddRefEntityToScene( const refEntity_t *ent ) } backEndData[ tr.smpFrame ]->entities[ r_numEntities ].e = *ent; - backEndData[ tr.smpFrame ]->entities[ r_numEntities ].lightingCalculated = false; r_numEntities++; } diff --git a/src/engine/renderer/tr_world.cpp b/src/engine/renderer/tr_world.cpp index 2f05042212..4ca207aec0 100644 --- a/src/engine/renderer/tr_world.cpp +++ b/src/engine/renderer/tr_world.cpp @@ -322,9 +322,6 @@ void R_AddBSPModelSurfaces( trRefEntity_t *ent ) return; } - // Tr3B: BSP inline models should always use vertex lighting - R_SetupEntityLighting( &tr.refdef, ent, boundsCenter ); - fogNum = R_FogWorldBox( ent->worldBounds ); for ( i = 0; i < bspModel->numSurfaces; i++ )