From e93becbad6efae33cb37ec1c2156add32f605f03 Mon Sep 17 00:00:00 2001 From: slipher Date: Fri, 17 Oct 2025 22:06:44 -0500 Subject: [PATCH] r_forceBlendRegime --- src/engine/renderer/gl_shader.h | 12 +++---- src/engine/renderer/glsl_source/common.glsl | 6 ++-- src/engine/renderer/tr_bsp.cpp | 37 ++++++++++++++------- src/engine/renderer/tr_init.cpp | 5 +++ src/engine/renderer/tr_local.h | 3 +- 5 files changed, 41 insertions(+), 22 deletions(-) diff --git a/src/engine/renderer/gl_shader.h b/src/engine/renderer/gl_shader.h index 0f857de57c..a8f234ddf6 100644 --- a/src/engine/renderer/gl_shader.h +++ b/src/engine/renderer/gl_shader.h @@ -2630,10 +2630,7 @@ class u_ColorModulateColorGen_Uint : ALPHA_ONE = 2, ALPHA_MINUS_ONE = 3, // <-- Insert new bits there. - LIGHTFACTOR_BIT0 = 28, - LIGHTFACTOR_BIT1 = 29, - LIGHTFACTOR_BIT2 = 30, - LIGHTFACTOR_BIT3 = 31, + LIGHTFACTOR_BIT0 = 11, // There should be not bit higher than the light factor. }; @@ -2647,8 +2644,11 @@ class u_ColorModulateColorGen_Uint : << Util::ordinal( ColorModulate_Bit::ALPHA_ONE ); colorModulate_Uint |= ( colorModulation.alphaGen == -1.0f ) << Util::ordinal( ColorModulate_Bit::ALPHA_MINUS_ONE ); - colorModulate_Uint |= uint32_t( colorModulation.lightFactor ) - << Util::ordinal( ColorModulate_Bit::LIGHTFACTOR_BIT0 ); + + // Light factor unit is 128 / ( 1 << 21 ) + // needs to go up to pow( 8, 2.2 ) = 97.006 + uint32_t lightFactorBits = lrintf( colorModulation.lightFactor * 16384.0f ); + colorModulate_Uint |= lightFactorBits << Util::ordinal( ColorModulate_Bit::LIGHTFACTOR_BIT0 ); this->SetValue( colorModulate_Uint ); } diff --git a/src/engine/renderer/glsl_source/common.glsl b/src/engine/renderer/glsl_source/common.glsl index 141f632261..d8829b7772 100644 --- a/src/engine/renderer/glsl_source/common.glsl +++ b/src/engine/renderer/glsl_source/common.glsl @@ -68,8 +68,8 @@ colorMod << 0: color * 1 colorMod << 1: color * ( -1 ) colorMod << 2: alpha * 1 colorMod << 3: alpha * ( -1 ) -colorMod << 4-27: available for future usage -colorMod << 28-31: lightFactor +colorMod << 4-10: available for future usage +colorMod << 11-31: lightFactor colorMod float format: @@ -98,7 +98,7 @@ vec4 ColorModulateToColor( const in colorModulatePack colorMod ) float ColorModulateToLightFactor( const in colorModulatePack colorMod ) { #if defined(HAVE_EXT_gpu_shader4) - return float( colorMod >> 28u ); + return float( colorMod >> 11u ) * ( 1.0 / 16384 ); #else return colorMod.g; #endif diff --git a/src/engine/renderer/tr_bsp.cpp b/src/engine/renderer/tr_bsp.cpp index 29cb4bb626..8e13184ebf 100644 --- a/src/engine/renderer/tr_bsp.cpp +++ b/src/engine/renderer/tr_bsp.cpp @@ -486,7 +486,7 @@ static void R_LoadLightmaps( lump_t *l, const char *bspName ) int lightMapBits = IF_LIGHTMAP | IF_NOPICMIP; int deluxeMapBits = IF_NORMALMAP | IF_NOPICMIP; - if ( tr.worldLinearizeLightMap ) + if ( tr.worldLinearizeTexture ) { lightMapBits |= IF_SRGB; } @@ -3969,15 +3969,18 @@ void R_LoadEntities( lump_t *l, std::string &externalEntities ) tr.worldLinearizeLightMap = true; } - if ( sRGBcolor && sRGBtex ) - { - Log::Debug( "Map features lights computed with linear colors and textures." ); - tr.worldLinearizeTexture = true; - } - else if ( sRGBcolor != sRGBtex ) + if ( !r_forceBlendRegime.Get() ) { - Log::Warn( "Map features lights computed with a mix of linear and non-linear colors or textures, acting like both colors and textures were linear when lights were computed." ); - tr.worldLinearizeTexture = true; + if ( sRGBcolor && sRGBtex ) + { + Log::Debug( "Map features lights computed with linear colors and textures." ); + tr.worldLinearizeTexture = true; + } + else if ( sRGBcolor != sRGBtex ) + { + Log::Warn( "Map features lights computed with a mix of linear and non-linear colors or textures, acting like both colors and textures were linear when lights were computed." ); + tr.worldLinearizeTexture = true; + } } continue; @@ -4659,12 +4662,23 @@ static void SetWorldLight() { /* Set GLSL overbright parameters if the lighting mode is not fullbright. */ if ( tr.lightMode != lightMode_t::FULLBRIGHT ) { + float factor = float( 1 << tr.overbrightBits ); + + if ( tr.worldLinearizeLightMap && !tr.worldLinearizeTexture ) + { + factor = powf( factor, 1.0f / 2.2f ); + } + else if ( !tr.worldLinearizeLightMap && tr.worldLinearizeTexture ) + { + factor = powf( factor, 2.2f ); + } + if ( r_overbrightQ3.Get() ) { // light factor is applied to entire color buffer; identityLight can be used to cancel it - tr.identityLight = 1.0f / float( 1 << tr.overbrightBits ); + tr.identityLight = 1.0f / factor; } else { // light factor is applied wherever a precomputed light is sampled - tr.mapLightFactor = float( 1 << tr.overbrightBits ); + tr.mapLightFactor = factor; } } } @@ -4779,7 +4793,6 @@ void RE_LoadWorldMap( const char *name ) tr.overbrightBits = std::min( tr.mapOverBrightBits, r_overbrightBits.Get() ); // set by RE_LoadWorldMap tr.mapLightFactor = 1.0f; // set by RE_LoadWorldMap tr.identityLight = 1.0f; // set by RE_LoadWorldMap - tr.worldLinearizeTexture = false; tr.worldLinearizeLightMap = false; s_worldData = {}; diff --git a/src/engine/renderer/tr_init.cpp b/src/engine/renderer/tr_init.cpp index 8d496d1b47..5d10fca142 100644 --- a/src/engine/renderer/tr_init.cpp +++ b/src/engine/renderer/tr_init.cpp @@ -97,6 +97,8 @@ Cvar::Cvar r_rendererAPI( "r_rendererAPI", "Renderer API: 0: OpenGL, 1: Vul Cvar::Cvar r_overbrightQ3("r_overbrightQ3", "brighten entire color buffer like Quake 3 (incompatible with newer assets)", Cvar::NONE, false); Cvar::Cvar r_overbrightIgnoreMapSettings("r_overbrightIgnoreMapSettings", "force usage of r_overbrightDefaultClamp / r_overbrightDefaultExponent, ignoring worldspawn", Cvar::NONE, false); + Cvar::Range> r_forceBlendRegime( + "r_forceBlendRegime", "override map settings to use: 1 = naive blending, 2 = linear blending", Cvar::NONE, 0, 0, 2); Cvar::Range> r_lightMode("r_lightMode", "lighting mode: 0: fullbright (cheat), 1: vertex light, 2: grid light (cheat), 3: light map", Cvar::NONE, Util::ordinal(lightMode_t::MAP), Util::ordinal(lightMode_t::FULLBRIGHT), Util::ordinal(lightMode_t::MAP)); Cvar::Cvar r_colorGrading( "r_colorGrading", "Use color grading", Cvar::NONE, true ); static Cvar::Range> r_readonlyDepthBuffer( @@ -1374,6 +1376,9 @@ ScreenshotCmd screenshotPNGRegistration("screenshotPNG", ssFormat_t::SSF_PNG, "p return false; } + Cvar::Latch( r_forceBlendRegime ); + tr.worldLinearizeTexture = r_forceBlendRegime.Get() == 2; + tr.lightMode = lightMode_t( r_lightMode.Get() ); if ( !Com_AreCheatsAllowed() ) diff --git a/src/engine/renderer/tr_local.h b/src/engine/renderer/tr_local.h index 68328fde7d..289e8b6c76 100644 --- a/src/engine/renderer/tr_local.h +++ b/src/engine/renderer/tr_local.h @@ -2428,7 +2428,7 @@ enum bool worldLightMapping; bool worldDeluxeMapping; bool worldHDR_RGBE; - bool worldLinearizeTexture; + bool worldLinearizeTexture; // this determines whether linear or naive blending is used bool worldLinearizeLightMap; floatProcessor_t convertFloatFromSRGB; @@ -2644,6 +2644,7 @@ enum extern Cvar::Range> r_overbrightBits; extern Cvar::Cvar r_overbrightQ3; extern Cvar::Cvar r_overbrightIgnoreMapSettings; + extern Cvar::Range> r_forceBlendRegime; extern Cvar::Range> r_lightMode; extern Cvar::Cvar r_colorGrading; extern Cvar::Cvar r_preferBindlessTextures;