Skip to content

Commit 99bcb38

Browse files
committed
Add r_forceBlendRegime: force linear/naive blending
Add the cvar r_forceBlendRegime which if set to 1 forces naive blending even on a linear lighting map, or if set to 2 forces linear blending on a non-linear map. Overbright factors are adjusted to produce a result as similar as possible to the map's "native" mode, assuming tone mapping is disabled. Correctly displaying a linear rgbGen or linear colormap is not implemented. Anyway there is already a console warning that should fire in this scenario.
1 parent 0552293 commit 99bcb38

5 files changed

Lines changed: 47 additions & 24 deletions

File tree

src/engine/renderer/gl_shader.h

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2666,10 +2666,7 @@ class u_ColorModulateColorGen_Uint :
26662666
ALPHA_ONE = 2,
26672667
ALPHA_MINUS_ONE = 3,
26682668
// <-- Insert new bits there.
2669-
LIGHTFACTOR_BIT0 = 28,
2670-
LIGHTFACTOR_BIT1 = 29,
2671-
LIGHTFACTOR_BIT2 = 30,
2672-
LIGHTFACTOR_BIT3 = 31,
2669+
LIGHTFACTOR_BIT0 = 11,
26732670
// There should be not bit higher than the light factor.
26742671
};
26752672

@@ -2683,8 +2680,11 @@ class u_ColorModulateColorGen_Uint :
26832680
<< Util::ordinal( ColorModulate_Bit::ALPHA_ONE );
26842681
colorModulate_Uint |= ( colorModulation.alphaGen == -1.0f )
26852682
<< Util::ordinal( ColorModulate_Bit::ALPHA_MINUS_ONE );
2686-
colorModulate_Uint |= uint32_t( colorModulation.lightFactor )
2687-
<< Util::ordinal( ColorModulate_Bit::LIGHTFACTOR_BIT0 );
2683+
2684+
// Light factor unit is 128 / ( 1 << 21 )
2685+
// needs to go up to pow( 8, 2.2 ) = 97.006
2686+
uint32_t lightFactorBits = lrintf( colorModulation.lightFactor * 16384.0f );
2687+
colorModulate_Uint |= lightFactorBits << Util::ordinal( ColorModulate_Bit::LIGHTFACTOR_BIT0 );
26882688

26892689
this->SetValue( colorModulate_Uint );
26902690
}

src/engine/renderer/glsl_source/common.glsl

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -68,8 +68,8 @@ colorMod << 0: color * 1
6868
colorMod << 1: color * ( -1 )
6969
colorMod << 2: alpha * 1
7070
colorMod << 3: alpha * ( -1 )
71-
colorMod << 4-27: available for future usage
72-
colorMod << 28-31: lightFactor
71+
colorMod << 4-10: available for future usage
72+
colorMod << 11-31: lightFactor
7373
7474
colorMod float format:
7575
@@ -98,7 +98,7 @@ vec4 ColorModulateToColor( const in colorModulatePack colorMod )
9898
float ColorModulateToLightFactor( const in colorModulatePack colorMod )
9999
{
100100
#if defined(HAVE_EXT_gpu_shader4)
101-
return float( colorMod >> 28u );
101+
return float( colorMod >> 11u ) * ( 1.0 / 16384 );
102102
#else
103103
return colorMod.g;
104104
#endif

src/engine/renderer/tr_bsp.cpp

Lines changed: 26 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ static byte *fileBase;
4444

4545
static void R_LinearizeLightingColorBytes( byte* bytes )
4646
{
47-
if ( !tr.worldLinearizeLightMap )
47+
if ( !tr.worldLinearizeTexture )
4848
{
4949
return;
5050
}
@@ -486,7 +486,7 @@ static void R_LoadLightmaps( lump_t *l, const char *bspName )
486486
int lightMapBits = IF_LIGHTMAP | IF_NOPICMIP;
487487
int deluxeMapBits = IF_NORMALMAP | IF_NOPICMIP;
488488

489-
if ( tr.worldLinearizeLightMap )
489+
if ( tr.worldLinearizeTexture )
490490
{
491491
lightMapBits |= IF_SRGB;
492492
}
@@ -3969,15 +3969,18 @@ void R_LoadEntities( lump_t *l, std::string &externalEntities )
39693969
tr.worldLinearizeLightMap = true;
39703970
}
39713971

3972-
if ( sRGBcolor && sRGBtex )
3973-
{
3974-
Log::Debug( "Map features lights computed with linear colors and textures." );
3975-
tr.worldLinearizeTexture = true;
3976-
}
3977-
else if ( sRGBcolor != sRGBtex )
3972+
if ( !r_forceBlendRegime.Get() )
39783973
{
3979-
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." );
3980-
tr.worldLinearizeTexture = true;
3974+
if ( sRGBcolor && sRGBtex )
3975+
{
3976+
Log::Debug( "Map features lights computed with linear colors and textures." );
3977+
tr.worldLinearizeTexture = true;
3978+
}
3979+
else if ( sRGBcolor != sRGBtex )
3980+
{
3981+
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." );
3982+
tr.worldLinearizeTexture = true;
3983+
}
39813984
}
39823985

39833986
continue;
@@ -4659,12 +4662,23 @@ static void SetWorldLight() {
46594662

46604663
/* Set GLSL overbright parameters if the lighting mode is not fullbright. */
46614664
if ( tr.lightMode != lightMode_t::FULLBRIGHT ) {
4665+
float factor = float( 1 << tr.overbrightBits );
4666+
4667+
if ( tr.worldLinearizeLightMap && !tr.worldLinearizeTexture )
4668+
{
4669+
factor = powf( factor, 1.0f / 2.2f );
4670+
}
4671+
else if ( !tr.worldLinearizeLightMap && tr.worldLinearizeTexture )
4672+
{
4673+
factor = powf( factor, 2.2f );
4674+
}
4675+
46624676
if ( r_overbrightQ3.Get() ) {
46634677
// light factor is applied to entire color buffer; identityLight can be used to cancel it
4664-
tr.identityLight = 1.0f / float( 1 << tr.overbrightBits );
4678+
tr.identityLight = 1.0f / factor;
46654679
} else {
46664680
// light factor is applied wherever a precomputed light is sampled
4667-
tr.mapLightFactor = float( 1 << tr.overbrightBits );
4681+
tr.mapLightFactor = factor;
46684682
}
46694683
}
46704684
}
@@ -4779,7 +4793,6 @@ void RE_LoadWorldMap( const char *name )
47794793
tr.overbrightBits = std::min( tr.mapOverBrightBits, r_overbrightBits.Get() ); // set by RE_LoadWorldMap
47804794
tr.mapLightFactor = 1.0f; // set by RE_LoadWorldMap
47814795
tr.identityLight = 1.0f; // set by RE_LoadWorldMap
4782-
tr.worldLinearizeTexture = false;
47834796
tr.worldLinearizeLightMap = false;
47844797

47854798
s_worldData = {};

src/engine/renderer/tr_init.cpp

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -98,6 +98,12 @@ Cvar::Cvar<int> r_rendererAPI( "r_rendererAPI", "Renderer API: 0: OpenGL, 1: Vul
9898
Cvar::Cvar<bool> r_overbrightQ3("r_overbrightQ3", "brighten entire color buffer like Quake 3 (incompatible with newer assets)", Cvar::NONE, false);
9999

100100
Cvar::Cvar<bool> r_overbrightIgnoreMapSettings("r_overbrightIgnoreMapSettings", "force usage of r_overbrightDefaultClamp / r_overbrightDefaultExponent, ignoring worldspawn", Cvar::NONE, false);
101+
102+
// If you use this to compare results in different blend regimes you should disable tonemapping
103+
// since applying the tonemap curve to sRGB vs. linear values gives very different results
104+
Cvar::Range<Cvar::Cvar<int>> r_forceBlendRegime(
105+
"r_forceBlendRegime", "override map settings to use: 1 = naive blending, 2 = linear blending", Cvar::NONE, 0, 0, 2);
106+
101107
Cvar::Range<Cvar::Cvar<int>> 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));
102108
Cvar::Cvar<bool> r_colorGrading( "r_colorGrading", "Use color grading", Cvar::NONE, true );
103109
static Cvar::Range<Cvar::Cvar<int>> r_readonlyDepthBuffer(
@@ -1397,6 +1403,9 @@ ScreenshotCmd screenshotPNGRegistration("screenshotPNG", ssFormat_t::SSF_PNG, "p
13971403
return false;
13981404
}
13991405

1406+
Cvar::Latch( r_forceBlendRegime );
1407+
tr.worldLinearizeTexture = r_forceBlendRegime.Get() == 2;
1408+
14001409
tr.lightMode = lightMode_t( r_lightMode.Get() );
14011410

14021411
if ( !Com_AreCheatsAllowed() )

src/engine/renderer/tr_local.h

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2430,8 +2430,8 @@ enum
24302430
bool worldLightMapping;
24312431
bool worldDeluxeMapping;
24322432
bool worldHDR_RGBE;
2433-
bool worldLinearizeTexture;
2434-
bool worldLinearizeLightMap;
2433+
bool worldLinearizeTexture; // this determines whether linear or naive blending is used
2434+
bool worldLinearizeLightMap; // this is only used to decide the overbright behavior
24352435

24362436
floatProcessor_t convertFloatFromSRGB;
24372437
colorProcessor_t convertColorFromSRGB;
@@ -2648,6 +2648,7 @@ enum
26482648
extern Cvar::Range<Cvar::Cvar<int>> r_overbrightBits;
26492649
extern Cvar::Cvar<bool> r_overbrightQ3;
26502650
extern Cvar::Cvar<bool> r_overbrightIgnoreMapSettings;
2651+
extern Cvar::Range<Cvar::Cvar<int>> r_forceBlendRegime;
26512652
extern Cvar::Range<Cvar::Cvar<int>> r_lightMode;
26522653
extern Cvar::Cvar<bool> r_colorGrading;
26532654
extern Cvar::Cvar<bool> r_preferBindlessTextures;

0 commit comments

Comments
 (0)