From 7f7983806f14d6e64fb96f6f35397f12db99a519 Mon Sep 17 00:00:00 2001 From: slipher Date: Fri, 1 Aug 2025 17:25:45 -0500 Subject: [PATCH 1/5] Warn when loading non-2D shaders before map Since the necessity of sRGB conversions is not known. --- src/engine/client/cl_main.cpp | 2 +- src/engine/client/client.h | 2 +- src/engine/renderer/tr_shader.cpp | 5 +++++ 3 files changed, 7 insertions(+), 2 deletions(-) diff --git a/src/engine/client/cl_main.cpp b/src/engine/client/cl_main.cpp index 037dec1f87..59c7cc8a61 100644 --- a/src/engine/client/cl_main.cpp +++ b/src/engine/client/cl_main.cpp @@ -2139,7 +2139,7 @@ bool CL_InitRenderer() FS_FCloseFile( f ); } - cls.whiteShader = re.RegisterShader( "white", RSF_NOMIP ); + cls.whiteShader = re.RegisterShader( "white", RSF_NOMIP | RSF_2D ); g_console_field_width = cls.windowConfig.vidWidth / SMALLCHAR_WIDTH - 2; g_consoleField.SetWidth(g_console_field_width); diff --git a/src/engine/client/client.h b/src/engine/client/client.h index 3c64e4e7cc..7b78deb055 100644 --- a/src/engine/client/client.h +++ b/src/engine/client/client.h @@ -316,7 +316,7 @@ struct clientStatic_t // rendering info WindowConfig windowConfig; qhandle_t charSetShader; - qhandle_t whiteShader; + qhandle_t whiteShader; // used for console drawing bool useLegacyConsoleFont; bool useLegacyConsoleFace; fontInfo_t *consoleFont; diff --git a/src/engine/renderer/tr_shader.cpp b/src/engine/renderer/tr_shader.cpp index 647eae66c6..7606f46007 100644 --- a/src/engine/renderer/tr_shader.cpp +++ b/src/engine/renderer/tr_shader.cpp @@ -6050,6 +6050,11 @@ shader_t *R_FindShader( const char *name, int flags ) // going to have to upload an image R_SyncRenderThread(); + if ( !( flags & RSF_2D ) && !tr.worldMapLoaded ) + { + Log::Warn( "non-2D shader '%s' registered before map colorspace is known, assuming naive blending", name ); + } + ClearGlobalShader(); Q_strncpyz( shader.name, strippedName, sizeof( shader.name ) ); From 3764166783204f031e250301a8b9718996b25f34 Mon Sep 17 00:00:00 2001 From: slipher Date: Fri, 1 Aug 2025 18:16:44 -0500 Subject: [PATCH 2/5] Implement stage-level colorspace shader keyword Allows making conditional stages that depend on whether naive or linear blending is used. --- src/engine/renderer/tr_shader.cpp | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/src/engine/renderer/tr_shader.cpp b/src/engine/renderer/tr_shader.cpp index 7606f46007..27f98e71c1 100644 --- a/src/engine/renderer/tr_shader.cpp +++ b/src/engine/renderer/tr_shader.cpp @@ -2009,6 +2009,7 @@ static bool ParseStage( shaderStage_t *stage, const char **text ) filterType_t filterType; char buffer[ 1024 ] = ""; bool loadMap = false; + bool blendRegimeMatch = true; while ( true ) { @@ -2844,6 +2845,23 @@ static bool ParseStage( shaderStage_t *stage, const char **text ) continue; } } + // disable the stage if the renderer's blending mode does not match the specified mode + else if ( !Q_stricmp( token, "ifBlendRegime" ) ) + { + token = COM_ParseExt2( text, false ); + if ( !Q_stricmp( token, "naive" ) ) + { + blendRegimeMatch = !tr.worldLinearizeTexture; + } + else if ( !Q_stricmp( token, "linear" ) ) + { + blendRegimeMatch = tr.worldLinearizeTexture; + } + else + { + Log::Warn( "unknown parameter'%s' for ifBlendRegime in shader '%s'", token, shader.name ); + } + } // alpha else if ( !Q_stricmp( token, "alpha" ) ) { @@ -3222,6 +3240,11 @@ static bool ParseStage( shaderStage_t *stage, const char **text ) } } + if ( !blendRegimeMatch ) + { + return true; // parsing succeeded, but not active + } + // parsing succeeded stage->active = true; From 9dcdce2518786288205b2a88e0a6095d933c5034 Mon Sep 17 00:00:00 2001 From: slipher Date: Wed, 22 Oct 2025 00:05:14 -0500 Subject: [PATCH 3/5] Revert "Implement stage-level colorspace shader keyword" This reverts commit 3764166783204f031e250301a8b9718996b25f34. --- src/engine/renderer/tr_shader.cpp | 23 ----------------------- 1 file changed, 23 deletions(-) diff --git a/src/engine/renderer/tr_shader.cpp b/src/engine/renderer/tr_shader.cpp index 27f98e71c1..7606f46007 100644 --- a/src/engine/renderer/tr_shader.cpp +++ b/src/engine/renderer/tr_shader.cpp @@ -2009,7 +2009,6 @@ static bool ParseStage( shaderStage_t *stage, const char **text ) filterType_t filterType; char buffer[ 1024 ] = ""; bool loadMap = false; - bool blendRegimeMatch = true; while ( true ) { @@ -2845,23 +2844,6 @@ static bool ParseStage( shaderStage_t *stage, const char **text ) continue; } } - // disable the stage if the renderer's blending mode does not match the specified mode - else if ( !Q_stricmp( token, "ifBlendRegime" ) ) - { - token = COM_ParseExt2( text, false ); - if ( !Q_stricmp( token, "naive" ) ) - { - blendRegimeMatch = !tr.worldLinearizeTexture; - } - else if ( !Q_stricmp( token, "linear" ) ) - { - blendRegimeMatch = tr.worldLinearizeTexture; - } - else - { - Log::Warn( "unknown parameter'%s' for ifBlendRegime in shader '%s'", token, shader.name ); - } - } // alpha else if ( !Q_stricmp( token, "alpha" ) ) { @@ -3240,11 +3222,6 @@ static bool ParseStage( shaderStage_t *stage, const char **text ) } } - if ( !blendRegimeMatch ) - { - return true; // parsing succeeded, but not active - } - // parsing succeeded stage->active = true; From 5343c4ccaf8600871c935285168248e631883071 Mon Sep 17 00:00:00 2001 From: slipher Date: Wed, 22 Oct 2025 15:03:48 -0500 Subject: [PATCH 4/5] Add linearBlending/naiveBlending to expression_t --- src/engine/renderer/tr_local.h | 2 ++ src/engine/renderer/tr_shade_calc.cpp | 10 ++++++++++ src/engine/renderer/tr_shader.cpp | 4 ++++ 3 files changed, 16 insertions(+) diff --git a/src/engine/renderer/tr_local.h b/src/engine/renderer/tr_local.h index a6cfc3d47e..9db8d277be 100644 --- a/src/engine/renderer/tr_local.h +++ b/src/engine/renderer/tr_local.h @@ -745,6 +745,8 @@ enum class ssaoMode { OP_GLOBAL5, OP_GLOBAL6, OP_GLOBAL7, + OP_NAIVE_BLENDING, + OP_LINEAR_BLENDING, OP_FRAGMENTSHADERS, OP_FRAMEBUFFEROBJECTS, OP_SOUND, diff --git a/src/engine/renderer/tr_shade_calc.cpp b/src/engine/renderer/tr_shade_calc.cpp index 48a4cf0dc2..c72be78fb2 100644 --- a/src/engine/renderer/tr_shade_calc.cpp +++ b/src/engine/renderer/tr_shade_calc.cpp @@ -176,6 +176,14 @@ static float GetOpValue( const expOperation_t *op ) value = 1.0; break; + case opcode_t::OP_NAIVE_BLENDING: + value = float( !tr.worldLinearizeTexture ); + break; + + case opcode_t::OP_LINEAR_BLENDING: + value = float( tr.worldLinearizeTexture ); + break; + case opcode_t::OP_FRAGMENTSHADERS: value = 1.0; break; @@ -272,6 +280,8 @@ static float EvalExpression( const expression_t *exp, float defaultValue ) case opcode_t::OP_GLOBAL5: case opcode_t::OP_GLOBAL6: case opcode_t::OP_GLOBAL7: + case opcode_t::OP_NAIVE_BLENDING: + case opcode_t::OP_LINEAR_BLENDING: case opcode_t::OP_FRAGMENTSHADERS: case opcode_t::OP_FRAMEBUFFEROBJECTS: case opcode_t::OP_SOUND: diff --git a/src/engine/renderer/tr_shader.cpp b/src/engine/renderer/tr_shader.cpp index 7606f46007..3c9152bcb0 100644 --- a/src/engine/renderer/tr_shader.cpp +++ b/src/engine/renderer/tr_shader.cpp @@ -275,6 +275,8 @@ const opstring_t opStrings[] = { {"global5", opcode_t::OP_GLOBAL5}, {"global6", opcode_t::OP_GLOBAL6}, {"global7", opcode_t::OP_GLOBAL7}, + {"naiveBlending", opcode_t::OP_NAIVE_BLENDING}, + {"linearBlending", opcode_t::OP_LINEAR_BLENDING}, {"fragmentShaders", opcode_t::OP_FRAGMENTSHADERS}, {"frameBufferObjects", opcode_t::OP_FRAMEBUFFEROBJECTS}, {"sound", opcode_t::OP_SOUND}, @@ -358,6 +360,8 @@ static bool IsOperand( opcode_t oc ) case opcode_t::OP_GLOBAL5: case opcode_t::OP_GLOBAL6: case opcode_t::OP_GLOBAL7: + case opcode_t::OP_NAIVE_BLENDING: + case opcode_t::OP_LINEAR_BLENDING: case opcode_t::OP_FRAGMENTSHADERS: case opcode_t::OP_FRAMEBUFFEROBJECTS: case opcode_t::OP_SOUND: From 0e3539b46ed9b80dbbb938a7e07f76bf9870bebb Mon Sep 17 00:00:00 2001 From: slipher Date: Sun, 26 Oct 2025 03:36:31 -0500 Subject: [PATCH 5/5] Add ifStatic shader keyword The stage-level shader option ifStatic evaluates an expression at load time and disables the stage if the expression evaluates to a falsey float value. --- src/engine/renderer/tr_shader.cpp | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/src/engine/renderer/tr_shader.cpp b/src/engine/renderer/tr_shader.cpp index 3c9152bcb0..7cfdd741ed 100644 --- a/src/engine/renderer/tr_shader.cpp +++ b/src/engine/renderer/tr_shader.cpp @@ -2013,6 +2013,7 @@ static bool ParseStage( shaderStage_t *stage, const char **text ) filterType_t filterType; char buffer[ 1024 ] = ""; bool loadMap = false; + bool staticEnabled = true; while ( true ) { @@ -2033,6 +2034,12 @@ static bool ParseStage( shaderStage_t *stage, const char **text ) { ParseExpression( text, &stage->ifExp ); } + else if ( !Q_stricmp( token, "ifStatic" ) ) + { + expression_t expr; + ParseExpression( text, &expr ); + staticEnabled = !!RB_EvalExpression( &expr, 1.0f ); + } // map else if ( !Q_stricmp( token, "map" ) ) { @@ -3226,6 +3233,12 @@ static bool ParseStage( shaderStage_t *stage, const char **text ) } } + if ( !staticEnabled ) + { + // parsing succeeded, but stage disabled + return true; + } + // parsing succeeded stage->active = true;