diff --git a/src/engine/renderer/Material.cpp b/src/engine/renderer/Material.cpp index ba85e96441..124cf2b6fa 100644 --- a/src/engine/renderer/Material.cpp +++ b/src/engine/renderer/Material.cpp @@ -419,11 +419,10 @@ static void UpdateSurfaceDataLightMapping( uint32_t* materials, Material& materi // bind u_HeightMap if ( pStage->enableReliefMapping ) { - float depthScale = RB_EvalExpression( &pStage->depthScaleExp, r_reliefDepthScale->value ); - depthScale *= shader->reliefDepthScale; + float scale = RB_EvalExpression( &pStage->depthScaleExp, r_reliefDepthScale->value ); - gl_lightMappingShaderMaterial->SetUniform_ReliefDepthScale( depthScale ); - gl_lightMappingShaderMaterial->SetUniform_ReliefOffsetBias( shader->reliefOffsetBias ); + gl_lightMappingShaderMaterial->SetUniform_ReliefDepthScale( pStage->heightScale * scale ); + gl_lightMappingShaderMaterial->SetUniform_ReliefOffsetBias( pStage->heightOffset ); // FIXME: if there is both, embedded heightmap in normalmap is used instead of standalone heightmap if ( !pStage->hasHeightMapInNormalMap ) { @@ -620,11 +619,10 @@ static void UpdateSurfaceDataReflection( uint32_t* materials, Material& material // bind u_HeightMap u_depthScale u_reliefOffsetBias if ( pStage->enableReliefMapping ) { - float depthScale = RB_EvalExpression( &pStage->depthScaleExp, r_reliefDepthScale->value ); - float reliefDepthScale = shader->reliefDepthScale; - depthScale *= reliefDepthScale == 0 ? 1 : reliefDepthScale; - gl_reflectionShaderMaterial->SetUniform_ReliefDepthScale( depthScale ); - gl_reflectionShaderMaterial->SetUniform_ReliefOffsetBias( shader->reliefOffsetBias ); + float scale = RB_EvalExpression( &pStage->depthScaleExp, r_reliefDepthScale->value ); + + gl_reflectionShaderMaterial->SetUniform_ReliefDepthScale( pStage->heightScale * scale ); + gl_reflectionShaderMaterial->SetUniform_ReliefOffsetBias( pStage->heightOffset ); // FIXME: if there is both, embedded heightmap in normalmap is used instead of standalone heightmap if ( !pStage->hasHeightMapInNormalMap ) { @@ -772,13 +770,9 @@ static void UpdateSurfaceDataLiquid( uint32_t* materials, Material& material, dr // bind u_HeightMap u_depthScale u_reliefOffsetBias if ( pStage->enableReliefMapping ) { - float depthScale; - float reliefDepthScale; + float scale = RB_EvalExpression( &pStage->depthScaleExp, r_reliefDepthScale->value ); - depthScale = RB_EvalExpression( &pStage->depthScaleExp, r_reliefDepthScale->value ); - reliefDepthScale = tess.surfaceShader->reliefDepthScale; - depthScale *= reliefDepthScale == 0 ? 1 : reliefDepthScale; - gl_liquidShaderMaterial->SetUniform_ReliefDepthScale( depthScale ); + gl_liquidShaderMaterial->SetUniform_ReliefDepthScale( pStage->heightScale * scale ); gl_liquidShaderMaterial->SetUniform_ReliefOffsetBias( tess.surfaceShader->reliefOffsetBias ); // FIXME: if there is both, embedded heightmap in normalmap is used instead of standalone heightmap diff --git a/src/engine/renderer/tr_local.h b/src/engine/renderer/tr_local.h index 4283777e67..a006153e60 100644 --- a/src/engine/renderer/tr_local.h +++ b/src/engine/renderer/tr_local.h @@ -1180,6 +1180,9 @@ enum class dynamicLightRenderer_t { LEGACY, TILED }; expression_t fogDensityExp; + float heightScale; + float heightOffset; + expression_t depthScaleExp; expression_t deformMagnitudeExp; diff --git a/src/engine/renderer/tr_shade.cpp b/src/engine/renderer/tr_shade.cpp index 11f2eed0d2..e71745b603 100644 --- a/src/engine/renderer/tr_shade.cpp +++ b/src/engine/renderer/tr_shade.cpp @@ -1240,11 +1240,10 @@ void Render_lightMapping( shaderStage_t *pStage ) // bind u_HeightMap if ( pStage->enableReliefMapping ) { - float depthScale = RB_EvalExpression( &pStage->depthScaleExp, r_reliefDepthScale->value ); - depthScale *= tess.surfaceShader->reliefDepthScale; + float scale = RB_EvalExpression( &pStage->depthScaleExp, r_reliefDepthScale->value ); - gl_lightMappingShader->SetUniform_ReliefDepthScale( depthScale ); - gl_lightMappingShader->SetUniform_ReliefOffsetBias( tess.surfaceShader->reliefOffsetBias ); + gl_lightMappingShader->SetUniform_ReliefDepthScale( pStage->heightScale * scale ); + gl_lightMappingShader->SetUniform_ReliefOffsetBias( pStage->heightOffset ); // FIXME: if there is both, embedded heightmap in normalmap is used instead of standalone heightmap if ( !pStage->hasHeightMapInNormalMap ) @@ -1561,11 +1560,10 @@ static void Render_forwardLighting_DBS_omni( shaderStage_t *pStage, // bind u_HeightMap if ( pStage->enableReliefMapping ) { - float depthScale = RB_EvalExpression( &pStage->depthScaleExp, r_reliefDepthScale->value ); - depthScale *= tess.surfaceShader->reliefDepthScale; + float scale = RB_EvalExpression( &pStage->depthScaleExp, r_reliefDepthScale->value ); - gl_forwardLightingShader_omniXYZ->SetUniform_ReliefDepthScale( depthScale ); - gl_forwardLightingShader_omniXYZ->SetUniform_ReliefOffsetBias( tess.surfaceShader->reliefOffsetBias ); + gl_forwardLightingShader_omniXYZ->SetUniform_ReliefDepthScale( pStage->heightScale * scale ); + gl_forwardLightingShader_omniXYZ->SetUniform_ReliefOffsetBias( pStage->heightOffset ); // FIXME: if there is both, embedded heightmap in normalmap is used instead of standalone heightmap if ( !pStage->hasHeightMapInNormalMap ) @@ -1739,11 +1737,10 @@ static void Render_forwardLighting_DBS_proj( shaderStage_t *pStage, // bind u_HeightMap if ( pStage->enableReliefMapping ) { - float depthScale = RB_EvalExpression( &pStage->depthScaleExp, r_reliefDepthScale->value ); - depthScale *= tess.surfaceShader->reliefDepthScale; + float scale = RB_EvalExpression( &pStage->depthScaleExp, r_reliefDepthScale->value ); - gl_forwardLightingShader_projXYZ->SetUniform_ReliefDepthScale( depthScale ); - gl_forwardLightingShader_projXYZ->SetUniform_ReliefOffsetBias( tess.surfaceShader->reliefOffsetBias ); + gl_forwardLightingShader_projXYZ->SetUniform_ReliefDepthScale( pStage->heightScale * scale ); + gl_forwardLightingShader_projXYZ->SetUniform_ReliefOffsetBias( pStage->heightOffset ); // FIXME: if there is both, embedded heightmap in normalmap is used instead of standalone heightmap if ( !pStage->hasHeightMapInNormalMap ) @@ -1918,11 +1915,10 @@ static void Render_forwardLighting_DBS_directional( shaderStage_t *pStage, trRef // bind u_HeightMap if ( pStage->enableReliefMapping ) { - float depthScale = RB_EvalExpression( &pStage->depthScaleExp, r_reliefDepthScale->value ); - depthScale *= tess.surfaceShader->reliefDepthScale; + float scale = RB_EvalExpression( &pStage->depthScaleExp, r_reliefDepthScale->value ); - gl_forwardLightingShader_directionalSun->SetUniform_ReliefDepthScale( depthScale ); - gl_forwardLightingShader_directionalSun->SetUniform_ReliefOffsetBias( tess.surfaceShader->reliefOffsetBias ); + gl_forwardLightingShader_directionalSun->SetUniform_ReliefDepthScale( pStage->heightScale * scale ); + gl_forwardLightingShader_directionalSun->SetUniform_ReliefOffsetBias( pStage->heightOffset ); // FIXME: if there is both, embedded heightmap in normalmap is used instead of standalone heightmap if ( !pStage->hasHeightMapInNormalMap ) @@ -2152,11 +2148,10 @@ void Render_reflection_CB( shaderStage_t *pStage ) // bind u_HeightMap u_depthScale u_reliefOffsetBias if ( pStage->enableReliefMapping ) { - float depthScale = RB_EvalExpression( &pStage->depthScaleExp, r_reliefDepthScale->value ); - depthScale *= tess.surfaceShader->reliefDepthScale; + float scale = RB_EvalExpression( &pStage->depthScaleExp, r_reliefDepthScale->value ); - gl_reflectionShader->SetUniform_ReliefDepthScale( depthScale ); - gl_reflectionShader->SetUniform_ReliefOffsetBias( tess.surfaceShader->reliefOffsetBias ); + gl_reflectionShader->SetUniform_ReliefDepthScale( pStage->heightScale * scale ); + gl_reflectionShader->SetUniform_ReliefOffsetBias( pStage->heightOffset ); // FIXME: if there is both, embedded heightmap in normalmap is used instead of standalone heightmap if ( !pStage->hasHeightMapInNormalMap ) @@ -2432,11 +2427,10 @@ void Render_liquid( shaderStage_t *pStage ) // bind u_HeightMap u_depthScale u_reliefOffsetBias if ( pStage->enableReliefMapping ) { - float depthScale = RB_EvalExpression( &pStage->depthScaleExp, r_reliefDepthScale->value ); - depthScale *= tess.surfaceShader->reliefDepthScale; + float scale = RB_EvalExpression( &pStage->depthScaleExp, r_reliefDepthScale->value ); - gl_liquidShader->SetUniform_ReliefDepthScale( depthScale ); - gl_liquidShader->SetUniform_ReliefOffsetBias( tess.surfaceShader->reliefOffsetBias ); + gl_liquidShader->SetUniform_ReliefDepthScale( pStage->heightScale * scale ); + gl_liquidShader->SetUniform_ReliefOffsetBias( pStage->heightOffset ); // FIXME: if there is both, embedded heightmap in normalmap is used instead of standalone heightmap if ( !pStage->hasHeightMapInNormalMap ) diff --git a/src/engine/renderer/tr_shader.cpp b/src/engine/renderer/tr_shader.cpp index 2732c518cb..3ad3116ac1 100644 --- a/src/engine/renderer/tr_shader.cpp +++ b/src/engine/renderer/tr_shader.cpp @@ -81,6 +81,12 @@ Cvar::Cvar r_dpBlend("r_dpBlend", "Enable DarkPlaces blend compatibility, static Cvar::Cvar r_portalDefaultRange( "r_portalDefaultRange", "Default portal range", Cvar::NONE, 1024); +struct reliefBias_t { + float origin; + float divisor; + float offset; +}; + /* ================ return a hash value for the filename @@ -2004,6 +2010,8 @@ static bool ParseStage( shaderStage_t *stage, const char **text ) char buffer[ 1024 ] = ""; bool loadMap = false; + reliefBias_t reliefBias = { 0.0f, 1.0f, 0.0f }; + while ( true ) { token = COM_ParseExt2( text, true ); @@ -3199,6 +3207,63 @@ static bool ParseStage( shaderStage_t *stage, const char **text ) { ParseExpression( text, &stage->fogDensityExp ); } + else if ( !Q_stricmp( token, "heightScale" ) ) + { + token = COM_ParseExt2( text, false ); + + if ( !token[ 0 ] ) + { + Log::Warn("missing heightScale parm in shader '%s'", shader.name ); + } + + stage->heightScale = atof( token ); + } + else if ( !Q_stricmp( token, "heightBiasType" ) ) + { + token = COM_ParseExt2( text, false ); + + if ( !token[ 0 ] ) + { + Log::Warn("missing heightOffsetType parm in shader '%s'", shader.name ); + } + + if ( !Q_stricmp( token, "bias" ) ) + { + // Use default values. + } + else if ( !Q_stricmp( token, "match" ) ) + { + reliefBias.origin = 1.0f; + reliefBias.divisor = 1.0f; + } + else if ( !Q_stricmp( token, "match8" ) ) + { + reliefBias.origin = 1.0f; + reliefBias.divisor = 255.0f; + } + else if ( !Q_stricmp( token, "match16" ) ) + { + reliefBias.origin = 1.0f; + reliefBias.divisor = 65535.0f; + } + else + { + Log::Warn("invalid parm for heightOffsetType keyword in shader '%s'", shader.name ); + SkipRestOfLine( text ); + continue; + } + } + else if ( !Q_stricmp( token, "heightOffset" ) ) + { + token = COM_ParseExt2( text, false ); + + if ( !token[ 0 ] ) + { + Log::Warn("missing heightOffset parm in shader '%s'", shader.name ); + } + + reliefBias.offset = atof( token ); + } // depthScale else if ( !Q_stricmp( token, "depthScale" ) ) { @@ -3217,6 +3282,8 @@ static bool ParseStage( shaderStage_t *stage, const char **text ) } } + stage->heightOffset = reliefBias.origin - reliefBias.offset / reliefBias.divisor; + // parsing succeeded stage->active = true; @@ -4330,28 +4397,26 @@ static bool ParseShader( const char *_text ) } // dpoffsetmapping - 2 match8 65 - float off; - float div; + reliefBias_t reliefBias = { 0.0f, 1.0f, 0.0f }; if ( !Q_stricmp( token, "bias" ) ) { - off = 0.0f; - div = 1.0f; + // Use default values. } else if ( !Q_stricmp( token, "match" ) ) { - off = 1.0f; - div = 1.0f; + reliefBias.origin = 1.0f; + reliefBias.divisor = 1.0f; } else if ( !Q_stricmp( token, "match8" ) ) { - off = 1.0f; - div = 255.0f; + reliefBias.origin = 1.0f; + reliefBias.divisor = 255.0f; } else if ( !Q_stricmp( token, "match16" ) ) { - off = 1.0f; - div = 65535.0f; + reliefBias.origin = 1.0f; + reliefBias.divisor = 65535.0f; } else { @@ -4368,8 +4433,8 @@ static bool ParseShader( const char *_text ) continue; } - float bias = atof( token ); - shader.reliefOffsetBias = off - bias / div; + reliefBias.offset = atof( token ); + shader.reliefOffsetBias = reliefBias.origin - reliefBias.offset / reliefBias.divisor; continue; } // entityMergable, allowing sprite surfaces from multiple entities @@ -5336,6 +5401,21 @@ static void FinishStages() stage->normalScale[ 2 ] *= stage->normalFormat[ 2 ]; } } + + // Set heightmap scale and offset; + { + if ( stage->heightScale == 0.0f ) + { + // This defaults to 1 if unset. + stage->heightScale = shader.reliefDepthScale; + } + + if ( stage->heightOffset == 0.0f ) + { + // This defaults to 0 if unset. + stage->heightOffset = shader.reliefOffsetBias; + } + } } GroupActiveStages();