From fe30922250c6b0949b1bd6b29bb377939cce8f5b 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 | 14 ++++---- src/engine/renderer/glsl_source/common.glsl | 8 ++--- src/engine/renderer/tr_bsp.cpp | 37 ++++++++++++++------- src/engine/renderer/tr_init.cpp | 5 +++ src/engine/renderer/tr_local.h | 3 +- 5 files changed, 43 insertions(+), 24 deletions(-) diff --git a/src/engine/renderer/gl_shader.h b/src/engine/renderer/gl_shader.h index ec6faee19a..18fd06a38b 100644 --- a/src/engine/renderer/gl_shader.h +++ b/src/engine/renderer/gl_shader.h @@ -2861,11 +2861,8 @@ class u_ColorModulateColorGen_Uint : ALPHA_MINUS_ONE = 3, ALPHA_ADD_ONE = 4, // <-- Insert new bits there. - IS_LIGHT_STYLE = 27, - LIGHTFACTOR_BIT0 = 28, - LIGHTFACTOR_BIT1 = 29, - LIGHTFACTOR_BIT2 = 30, - LIGHTFACTOR_BIT3 = 31, + IS_LIGHT_STYLE = 10, + LIGHTFACTOR_BIT0 = 11, // There should be not bit higher than the light factor. }; @@ -2883,8 +2880,11 @@ class u_ColorModulateColorGen_Uint : << Util::ordinal( ColorModulate_Bit::ALPHA_ADD_ONE ); colorModulate_Uint |= colorModulation.useVertexLightFactor << Util::ordinal( ColorModulate_Bit::IS_LIGHT_STYLE ); - 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 1c7013a74d..7fa1ece0ef 100644 --- a/src/engine/renderer/glsl_source/common.glsl +++ b/src/engine/renderer/glsl_source/common.glsl @@ -69,9 +69,9 @@ colorMod << 1: color * ( -1 ) colorMod << 2: alpha * 1 colorMod << 3: alpha * ( -1 ) colorMod << 4: alpha = 1 -colorMod << 5-26: available for future usage -colorMod << 27: color += lightFactor -colorMod << 28-31: lightFactor +colorMod << 5-9: available for future usage +colorMod << 10: color += lightFactor +colorMod << 11-31: lightFactor colorMod float format: @@ -123,7 +123,7 @@ ModBits_t ColorModulateToBits( 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 abs( colorMod.g ); #endif diff --git a/src/engine/renderer/tr_bsp.cpp b/src/engine/renderer/tr_bsp.cpp index 7da251d6b0..c0435ba231 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; } @@ -3917,15 +3917,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; @@ -4631,12 +4634,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; } } } @@ -4693,7 +4707,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 e2db9fe8f9..fc6e0a0077 100644 --- a/src/engine/renderer/tr_init.cpp +++ b/src/engine/renderer/tr_init.cpp @@ -96,6 +96,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( @@ -1343,6 +1345,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 a6cfc3d47e..d1882c1738 100644 --- a/src/engine/renderer/tr_local.h +++ b/src/engine/renderer/tr_local.h @@ -2430,7 +2430,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; @@ -2646,6 +2646,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;