From 7374b83c7e280e06cd6d80740afcd59a3b15f808 Mon Sep 17 00:00:00 2001 From: Thomas Debesse Date: Sun, 8 Dec 2019 03:13:04 +0100 Subject: [PATCH 1/4] renderer: implement per-stage normalScale keyword to scale and flip channels rename the old normalScale expression keyword as normalIntensity --- src/engine/renderer/gl_shader.cpp | 18 +-- src/engine/renderer/gl_shader.h | 36 +++--- .../renderer/glsl_source/liquid_fp.glsl | 4 +- .../glsl_source/reliefMapping_fp.glsl | 37 ++---- src/engine/renderer/tr_local.h | 8 +- src/engine/renderer/tr_shade.cpp | 41 ++++--- src/engine/renderer/tr_shader.cpp | 110 ++++++++++-------- 7 files changed, 129 insertions(+), 125 deletions(-) diff --git a/src/engine/renderer/gl_shader.cpp b/src/engine/renderer/gl_shader.cpp index 1fd83bfb98..dd1dae3f81 100644 --- a/src/engine/renderer/gl_shader.cpp +++ b/src/engine/renderer/gl_shader.cpp @@ -1468,7 +1468,7 @@ GLShader_lightMapping::GLShader_lightMapping( GLShaderManager *manager ) : u_ParallaxDepthScale( this ), u_ParallaxOffsetBias( this ), u_HeightMapInNormalMap( this ), - u_NormalFormat( this ), + u_NormalScale( this ), u_numLights( this ), u_Lights( this ), GLDeformStage( this ), @@ -1519,7 +1519,7 @@ GLShader_vertexLighting_DBS_entity::GLShader_vertexLighting_DBS_entity( GLShader u_ParallaxDepthScale( this ), u_ParallaxOffsetBias( this ), u_HeightMapInNormalMap( this ), - u_NormalFormat( this ), + u_NormalScale( this ), u_EnvironmentInterpolation( this ), u_LightGridOrigin( this ), u_LightGridScale( this ), @@ -1580,7 +1580,7 @@ GLShader_vertexLighting_DBS_world::GLShader_vertexLighting_DBS_world( GLShaderMa u_ParallaxDepthScale( this ), u_ParallaxOffsetBias( this ), u_HeightMapInNormalMap( this ), - u_NormalFormat( this ), + u_NormalScale( this ), u_LightWrapAround( this ), u_LightGridOrigin( this ), u_LightGridScale( this ), @@ -1642,7 +1642,7 @@ GLShader_forwardLighting_omniXYZ::GLShader_forwardLighting_omniXYZ( GLShaderMana u_ParallaxDepthScale( this ), u_ParallaxOffsetBias( this ), u_HeightMapInNormalMap( this ), - u_NormalFormat( this ), + u_NormalScale( this ), GLDeformStage( this ), GLCompileMacro_USE_VERTEX_SKINNING( this ), GLCompileMacro_USE_VERTEX_ANIMATION( this ), @@ -1701,7 +1701,7 @@ GLShader_forwardLighting_projXYZ::GLShader_forwardLighting_projXYZ( GLShaderMana u_ParallaxDepthScale( this ), u_ParallaxOffsetBias( this ), u_HeightMapInNormalMap( this ), - u_NormalFormat( this ), + u_NormalScale( this ), GLDeformStage( this ), GLCompileMacro_USE_VERTEX_SKINNING( this ), GLCompileMacro_USE_VERTEX_ANIMATION( this ), @@ -1763,7 +1763,7 @@ GLShader_forwardLighting_directionalSun::GLShader_forwardLighting_directionalSun u_ParallaxDepthScale( this ), u_ParallaxOffsetBias( this ), u_HeightMapInNormalMap( this ), - u_NormalFormat( this ), + u_NormalScale( this ), GLDeformStage( this ), GLCompileMacro_USE_VERTEX_SKINNING( this ), GLCompileMacro_USE_VERTEX_ANIMATION( this ), @@ -1845,8 +1845,8 @@ GLShader_reflection::GLShader_reflection( GLShaderManager *manager ): u_ParallaxDepthScale( this ), u_ParallaxOffsetBias( this ), u_HeightMapInNormalMap( this ), + u_NormalIntensity( this ), u_NormalScale( this ), - u_NormalFormat( this ), u_VertexInterpolation( this ), GLDeformStage( this ), GLCompileMacro_USE_VERTEX_SKINNING( this ), @@ -1948,7 +1948,7 @@ GLShader_heatHaze::GLShader_heatHaze( GLShaderManager *manager ) : u_ColorModulate( this ), u_Color( this ), u_Bones( this ), - u_NormalFormat( this ), + u_NormalScale( this ), u_VertexInterpolation( this ), GLDeformStage( this ), GLCompileMacro_USE_VERTEX_SKINNING( this ), @@ -2111,8 +2111,8 @@ GLShader_liquid::GLShader_liquid( GLShaderManager *manager ) : u_ParallaxDepthScale( this ), u_ParallaxOffsetBias( this ), u_HeightMapInNormalMap( this ), + u_NormalIntensity( this ), u_NormalScale( this ), - u_NormalFormat( this ), u_FogDensity( this ), u_FogColor( this ), u_SpecularExponent( this ), diff --git a/src/engine/renderer/gl_shader.h b/src/engine/renderer/gl_shader.h index 52f21834c7..ab317065b5 100644 --- a/src/engine/renderer/gl_shader.h +++ b/src/engine/renderer/gl_shader.h @@ -1510,31 +1510,31 @@ class u_FresnelBias : } }; -class u_NormalScale : +class u_NormalIntensity : GLUniform1f { public: - u_NormalScale( GLShader *shader ) : - GLUniform1f( shader, "u_NormalScale" ) + u_NormalIntensity( GLShader *shader ) : + GLUniform1f( shader, "u_NormalIntensity" ) { } - void SetUniform_NormalScale( float value ) + void SetUniform_NormalIntensity( float value ) { this->SetValue( value ); } }; -class u_NormalFormat : - GLUniform3f +class u_NormalScale : + GLUniform4f { public: - u_NormalFormat( GLShader *shader ) : - GLUniform3f( shader, "u_NormalFormat" ) + u_NormalScale( GLShader *shader ) : + GLUniform4f( shader, "u_NormalScale" ) { } - void SetUniform_NormalFormat( const vec3_t value ) + void SetUniform_NormalScale( const vec4_t value ) { this->SetValue( value ); } @@ -2162,7 +2162,7 @@ class GLShader_lightMapping : public u_ParallaxDepthScale, public u_ParallaxOffsetBias, public u_HeightMapInNormalMap, - public u_NormalFormat, + public u_NormalScale, public u_numLights, public u_Lights, public GLDeformStage, @@ -2191,7 +2191,7 @@ class GLShader_vertexLighting_DBS_entity : public u_ParallaxDepthScale, public u_ParallaxOffsetBias, public u_HeightMapInNormalMap, - public u_NormalFormat, + public u_NormalScale, public u_EnvironmentInterpolation, public u_LightGridOrigin, public u_LightGridScale, @@ -2225,7 +2225,7 @@ class GLShader_vertexLighting_DBS_world : public u_ParallaxDepthScale, public u_ParallaxOffsetBias, public u_HeightMapInNormalMap, - public u_NormalFormat, + public u_NormalScale, public u_LightWrapAround, public u_LightGridOrigin, public u_LightGridScale, @@ -2266,7 +2266,7 @@ class GLShader_forwardLighting_omniXYZ : public u_ParallaxDepthScale, public u_ParallaxOffsetBias, public u_HeightMapInNormalMap, - public u_NormalFormat, + public u_NormalScale, public GLDeformStage, public GLCompileMacro_USE_VERTEX_SKINNING, public GLCompileMacro_USE_VERTEX_ANIMATION, @@ -2305,7 +2305,7 @@ class GLShader_forwardLighting_projXYZ : public u_ParallaxDepthScale, public u_ParallaxOffsetBias, public u_HeightMapInNormalMap, - public u_NormalFormat, + public u_NormalScale, public GLDeformStage, public GLCompileMacro_USE_VERTEX_SKINNING, public GLCompileMacro_USE_VERTEX_ANIMATION, @@ -2346,7 +2346,7 @@ class GLShader_forwardLighting_directionalSun : public u_ParallaxDepthScale, public u_ParallaxOffsetBias, public u_HeightMapInNormalMap, - public u_NormalFormat, + public u_NormalScale, public GLDeformStage, public GLCompileMacro_USE_VERTEX_SKINNING, public GLCompileMacro_USE_VERTEX_ANIMATION, @@ -2394,8 +2394,8 @@ class GLShader_reflection : public u_ParallaxDepthScale, public u_ParallaxOffsetBias, public u_HeightMapInNormalMap, + public u_NormalIntensity, public u_NormalScale, - public u_NormalFormat, public u_VertexInterpolation, public GLDeformStage, public GLCompileMacro_USE_VERTEX_SKINNING, @@ -2472,7 +2472,7 @@ class GLShader_heatHaze : public u_ColorModulate, public u_Color, public u_Bones, - public u_NormalFormat, + public u_NormalScale, public u_VertexInterpolation, public GLDeformStage, public GLCompileMacro_USE_VERTEX_SKINNING, @@ -2601,8 +2601,8 @@ class GLShader_liquid : public u_ParallaxDepthScale, public u_ParallaxOffsetBias, public u_HeightMapInNormalMap, + public u_NormalIntensity, public u_NormalScale, - public u_NormalFormat, public u_FogDensity, public u_FogColor, public u_SpecularExponent, diff --git a/src/engine/renderer/glsl_source/liquid_fp.glsl b/src/engine/renderer/glsl_source/liquid_fp.glsl index af2ccfcc56..78ae3138c7 100644 --- a/src/engine/renderer/glsl_source/liquid_fp.glsl +++ b/src/engine/renderer/glsl_source/liquid_fp.glsl @@ -32,7 +32,7 @@ uniform float u_RefractionIndex; uniform float u_FresnelPower; uniform float u_FresnelScale; uniform float u_FresnelBias; -uniform float u_NormalScale; +uniform float u_NormalIntensity; uniform mat4 u_ModelMatrix; uniform mat4 u_UnprojectMatrix; uniform vec2 u_SpecularExponent; @@ -112,7 +112,7 @@ void main() float fresnel = clamp(u_FresnelBias + pow(1.0 - dot(viewDir, normal), u_FresnelPower) * u_FresnelScale, 0.0, 1.0); - texScreen += u_NormalScale * normal.xy; + texScreen += u_NormalIntensity * normal.xy; vec3 refractColor = texture2D(u_CurrentMap, texScreen).rgb; vec3 reflectColor = texture2D(u_PortalMap, texScreen).rgb; diff --git a/src/engine/renderer/glsl_source/reliefMapping_fp.glsl b/src/engine/renderer/glsl_source/reliefMapping_fp.glsl index be933061f1..700b2c2323 100644 --- a/src/engine/renderer/glsl_source/reliefMapping_fp.glsl +++ b/src/engine/renderer/glsl_source/reliefMapping_fp.glsl @@ -26,37 +26,16 @@ uniform sampler2D u_NormalMap; uniform int u_HeightMapInNormalMap; #endif // r_normalMapping || USE_PARALLAX_MAPPING +#if defined(r_normalMapping) +// HACK: fourth component tells renderer if normal scale is customized or not +uniform vec4 u_NormalScale; +#endif // r_normalMapping + #if defined(USE_PARALLAX_MAPPING) uniform float u_ParallaxDepthScale; uniform float u_ParallaxOffsetBias; #endif // USE_PARALLAX_MAPPING -#if defined(r_normalMapping) -uniform vec3 u_NormalFormat; - -vec3 normalFlip(vec3 normal) -{ - // undefined (zero) means default means 1.0 means do nothing - - if (u_NormalFormat.x < 0.0) - { - normal.x *= -1.0; - } - - if (u_NormalFormat.y < 0.0) - { - normal.y *= -1.0; - } - - if (u_NormalFormat.z < 0.0) - { - normal.z *= -1.0; - } - - return normal; -} -#endif // r_normalMapping - // compute normal in tangent space vec3 NormalInTangentSpace(vec2 texNormal) { @@ -85,7 +64,11 @@ vec3 NormalInTangentSpace(vec2 texNormal) normal = 2.0 * normal - 1.0; } - normal = normalFlip(normal); + // HACK: fourth component tells renderer if normal scale is customized or not + if (u_NormalScale.w != 0) + { + normal *= u_NormalScale.xyz; + } #if defined(r_NormalScale) normal.z *= r_NormalScale; diff --git a/src/engine/renderer/tr_local.h b/src/engine/renderer/tr_local.h index 69971a53c2..d496bef753 100644 --- a/src/engine/renderer/tr_local.h +++ b/src/engine/renderer/tr_local.h @@ -1121,7 +1121,11 @@ static inline void halfToFloat( const f16vec4_t in, vec4_t out ) expression_t fresnelScaleExp; expression_t fresnelBiasExp; - expression_t normalScaleExp; + // normalMap channel scale, negative value flips channel + // HACK: fourth component tells renderer if normal scale is customized or not + vec4_t normalScale; + + expression_t normalIntensityExp; expression_t etaExp; expression_t etaDeltaExp; @@ -1210,8 +1214,6 @@ static inline void halfToFloat( const f16vec4_t in, vec4_t out ) float parallaxOffsetBias; // offset the heightmap top relatively to the floor float parallaxDepthScale; // per-shader parallax depth scale - vec3_t normalFormat; // normalmap format (channel flip) - bool noShadows; bool fogLight; bool blendLight; diff --git a/src/engine/renderer/tr_shade.cpp b/src/engine/renderer/tr_shade.cpp index 92c9cfadc6..3b57cd3dc7 100644 --- a/src/engine/renderer/tr_shade.cpp +++ b/src/engine/renderer/tr_shade.cpp @@ -802,8 +802,8 @@ static void Render_vertexLighting_DBS_entity( int stage ) // bind u_NormalMap GL_BindToTMU( 1, pStage->bundle[ TB_NORMALMAP ].image[ 0 ] ); - // bind u_NormalFormat - gl_vertexLightingShader_DBS_entity->SetUniform_NormalFormat( tess.surfaceShader->normalFormat ); + // bind u_NormalScale + gl_vertexLightingShader_DBS_entity->SetUniform_NormalScale( pStage->normalScale ); } else { @@ -1049,8 +1049,8 @@ static void Render_vertexLighting_DBS_world( int stage ) // bind u_NormalMap GL_BindToTMU( 1, pStage->bundle[ TB_NORMALMAP ].image[ 0 ] ); - // bind u_NormalFormat - gl_vertexLightingShader_DBS_world->SetUniform_NormalFormat( tess.surfaceShader->normalFormat ); + // bind u_NormalScale + gl_vertexLightingShader_DBS_world->SetUniform_NormalScale( pStage->normalScale ); } else { @@ -1224,8 +1224,8 @@ static void Render_lightMapping( int stage ) { GL_BindToTMU( 1, pStage->bundle[ TB_NORMALMAP ].image[ 0 ] ); - // bind u_NormalFormat - gl_lightMappingShader->SetUniform_NormalFormat( tess.surfaceShader->normalFormat ); + // bind u_NormalScale + gl_lightMappingShader->SetUniform_NormalScale( pStage->normalScale ); } else { @@ -1566,8 +1566,8 @@ static void Render_forwardLighting_DBS_omni( shaderStage_t *diffuseStage, // bind u_NormalMap GL_BindToTMU( 1, diffuseStage->bundle[ TB_NORMALMAP ].image[ 0 ] ); - // bind u_NormalFormat - gl_forwardLightingShader_omniXYZ->SetUniform_NormalFormat( tess.surfaceShader->normalFormat ); + // bind u_NormalScale + gl_forwardLightingShader_omniXYZ->SetUniform_NormalScale( diffuseStage->normalScale ); } else { @@ -1753,8 +1753,8 @@ static void Render_forwardLighting_DBS_proj( shaderStage_t *diffuseStage, // bind u_NormalMap GL_BindToTMU( 1, diffuseStage->bundle[ TB_NORMALMAP ].image[ 0 ] ); - // bind u_NormalFormat - gl_forwardLightingShader_projXYZ->SetUniform_NormalFormat( tess.surfaceShader->normalFormat ); + // bind u_NormalScale + gl_forwardLightingShader_projXYZ->SetUniform_NormalScale( diffuseStage->normalScale ); } else { @@ -1942,8 +1942,8 @@ static void Render_forwardLighting_DBS_directional( shaderStage_t *diffuseStage, // bind u_NormalMap GL_BindToTMU( 1, diffuseStage->bundle[ TB_NORMALMAP ].image[ 0 ] ); - // bind u_NormalFormat - gl_forwardLightingShader_directionalSun->SetUniform_NormalFormat( tess.surfaceShader->normalFormat ); + // bind u_NormalScale + gl_forwardLightingShader_directionalSun->SetUniform_NormalScale( diffuseStage->normalScale ); } else { @@ -2078,8 +2078,8 @@ static void Render_reflection_CB( int stage ) gl_reflectionShader->SetUniform_HeightMapInNormalMap( pStage->heightMapInNormalMap ); } - // bind u_NormalFormat - gl_reflectionShader->SetUniform_NormalFormat( tess.surfaceShader->normalFormat ); + // bind u_NormalScale + gl_reflectionShader->SetUniform_NormalScale( pStage->normalScale ); gl_reflectionShader->SetRequiredVertexPointers(); @@ -2245,8 +2245,8 @@ static void Render_heatHaze( int stage ) gl_heatHazeShader->SetUniform_TextureMatrix( tess.svars.texMatrices[ TB_COLORMAP ] ); - // bind u_NormalFormat - gl_heatHazeShader->SetUniform_NormalFormat( tess.surfaceShader->normalFormat ); + // bind u_NormalScale + gl_heatHazeShader->SetUniform_NormalScale( pStage->normalScale ); } GL_BindToTMU( 1, tr.currentRenderImage[ backEnd.currentMainFBO ] ); @@ -2300,7 +2300,7 @@ static void Render_liquid( int stage ) gl_liquidShader->SetUniform_FresnelPower( RB_EvalExpression( &pStage->fresnelPowerExp, 2.0 ) ); gl_liquidShader->SetUniform_FresnelScale( RB_EvalExpression( &pStage->fresnelScaleExp, 1.0 ) ); gl_liquidShader->SetUniform_FresnelBias( RB_EvalExpression( &pStage->fresnelBiasExp, 0.05 ) ); - gl_liquidShader->SetUniform_NormalScale( RB_EvalExpression( &pStage->normalScaleExp, 0.05 ) ); + gl_liquidShader->SetUniform_NormalIntensity( RB_EvalExpression( &pStage->normalIntensityExp, 0.05 ) ); gl_liquidShader->SetUniform_FogDensity( fogDensity ); gl_liquidShader->SetUniform_FogColor( fogColor ); @@ -2328,8 +2328,11 @@ static void Render_liquid( int stage ) // bind u_NormalMap GL_BindToTMU( 3, pStage->bundle[ TB_COLORMAP ].image[ 0 ] ); - // bind u_NormalFormat - gl_liquidShader->SetUniform_NormalFormat( tess.surfaceShader->normalFormat ); + vec3_t normalScale = { 1, 1, 1 }; + SetNormalScale( pStage, normalScale ); + + // bind u_NormalScale + gl_liquidShader->SetUniform_NormalScale( pStage->normalScale ); } gl_liquidShader->SetUniform_TextureMatrix( tess.svars.texMatrices[ TB_COLORMAP ] ); diff --git a/src/engine/renderer/tr_shader.cpp b/src/engine/renderer/tr_shader.cpp index 2289605ac3..3e703653b8 100644 --- a/src/engine/renderer/tr_shader.cpp +++ b/src/engine/renderer/tr_shader.cpp @@ -2799,10 +2799,60 @@ static bool ParseStage( shaderStage_t *stage, const char **text ) { ParseExpression( text, &stage->fresnelBiasExp ); } - // normalScale + // normalScale + // + // for compatibility purpose, ioq3gl2 syntax is supported: + // normalScale + // + // scale normalMap channel, can flip channels with negative values + // + // expects OpenGL scale as default: 1 1 1 + // + // OpenGL format is described there: + // https://github.com/KhronosGroup/glTF/tree/2.0/specification/2.0#materialnormaltexture + // + // > The normal vector uses OpenGL conventions where +X is right, +Y is up, and +Z points toward the viewer. + // + // examples of scales: + // + // 1 1 1 OpenGL format (default) + // 1 -1 1 DirectX format with reverted green channel (reverted Y component) + // -1 1 1 weird other format with reverted red channel (reverted X component) + // 1 1 1.5 OpenGL format with an increased blue channel (larger Z componnent) else if ( !Q_stricmp( token, "normalScale" ) ) { - ParseExpression( text, &stage->normalScaleExp ); + for ( int i = 0; i < 3; i++ ) + { + token = COM_ParseExt2( text, false ); + + if ( token[ 0 ] == '\0' ) + { + if ( i == 2 ) + { + // ioq3gl2 only supports + // normalScale X Y + // having a fallback for missing Z component keeps compatibility + stage->normalScale[ 2 ] = 1; + // no need to hack the fourth component since previous loop did it + } + else + { + Log::Warn("missing normalScale parm in shader '%s'", shader.name ); + continue; + } + } + + stage->normalScale[ i ] = atof( token ); + // HACK: fourth component tells renderer if normal scale is customized or not + stage->normalScale[ 3 ] = 1; + } + SkipRestOfLine( text ); + continue; + } + // normalIntensity + else if ( !Q_stricmp( token, "normalIntensity" ) ) + { + ParseExpression( text, &stage->normalIntensityExp ); } // fogDensity else if ( !Q_stricmp( token, "fogDensity" ) ) @@ -3542,7 +3592,11 @@ static bool ParseShader( const char *_text ) if ( Q_stricmp( "norm", parser.suffix ) == 0 ) { // Xonotic uses -Y (DirectX) while this engine uses Y (OpenGL) - shader.normalFormat[ 1 ] = -1; + stages[ s ].normalScale[ 0 ] = 1; + stages[ s ].normalScale[ 1 ] = -1; + stages[ s ].normalScale[ 2 ] = 1; + // HACK: fourth component tells renderer if normal scale is customized or not + stages[ s ].normalScale[ 3 ] = 1; } s++; @@ -3758,50 +3812,6 @@ static bool ParseShader( const char *_text ) continue; } - // normalFormat - // - // expects OpenGL format as default - // - // OpenGL format is described there: - // https://github.com/KhronosGroup/glTF/tree/2.0/specification/2.0#materialnormaltexture - // - // > The normal vectors use OpenGL conventions where +X is right and +Y is up. - // > +Z points toward the viewer. - // - // example of formats: - // - // 1 1 1 OpenGL format (default) - // 1 -1 1 DirectX format with reverted green (Y) channel - // -1 1 1 weird other format with reverted red (X) channel - else if ( !Q_stricmp( token, "normalFormat" ) ) - { - for ( int i = 0; i < 3; i++ ) - { - token = COM_ParseExt2( text, false ); - - if ( token[ 0 ] == '\0' ) - { - Log::Warn("missing normalFormat parm in shader '%s'", shader.name ); - continue; - } - - if ( !Q_stricmp( token, "-1" ) ) - { - shader.normalFormat[ i ] = -1; - } - else if ( !Q_stricmp( token, "1" ) ) - { - // do nothing, that's the default - } - else - { - Log::Warn("unknown normalFormat parm '%s' in '%s'", token, shader.name ); - break; - } - } - SkipRestOfLine( text ); - continue; - } // parallax mapping else if ( !Q_stricmp( token, "parallax" ) || ( *r_dpMaterial && !Q_stricmp( token, "dpoffsetmapping" ) ) ) @@ -4509,6 +4519,12 @@ static void CollapseStages() { // merge with diffuse stage stages[ diffuseStage ].bundle[ TB_NORMALMAP ] = stages[ normalStage ].bundle[ TB_COLORMAP ]; + stages[ diffuseStage ].normalIntensityExp = stages[ normalStage ].normalIntensityExp; + stages[ diffuseStage ].normalScale[ 0 ] = stages[ normalStage ].normalScale[ 0 ]; + stages[ diffuseStage ].normalScale[ 1 ] = stages[ normalStage ].normalScale[ 1 ]; + stages[ diffuseStage ].normalScale[ 2 ] = stages[ normalStage ].normalScale[ 2 ]; + // HACK: fourth component tells renderer if normal scale is customized or not + stages[ diffuseStage ].normalScale[ 3 ] = stages[ normalStage ].normalScale[ 3 ]; stages[ diffuseStage ].heightMapInNormalMap = stages[ normalStage ].heightMapInNormalMap; // disable since it's merged stages[ normalStage ].active = false; From 3fdb97729623572e13d4a2baff50af4a7a6b3773 Mon Sep 17 00:00:00 2001 From: Thomas Debesse Date: Thu, 12 Dec 2019 09:36:01 +0100 Subject: [PATCH 2/4] renderer: enable normalIntensity and normalScale for any glsl with normal map no need to hack normalScale with a fourth channel to tell it's customized anymore --- src/engine/renderer/gl_shader.cpp | 2 - src/engine/renderer/gl_shader.h | 23 +------ .../renderer/glsl_source/liquid_fp.glsl | 8 ++- .../glsl_source/reliefMapping_fp.glsl | 9 ++- src/engine/renderer/tr_local.h | 4 +- src/engine/renderer/tr_shade.cpp | 64 ++++++++++++++++--- src/engine/renderer/tr_shader.cpp | 12 ++-- 7 files changed, 75 insertions(+), 47 deletions(-) diff --git a/src/engine/renderer/gl_shader.cpp b/src/engine/renderer/gl_shader.cpp index dd1dae3f81..f90e376334 100644 --- a/src/engine/renderer/gl_shader.cpp +++ b/src/engine/renderer/gl_shader.cpp @@ -1845,7 +1845,6 @@ GLShader_reflection::GLShader_reflection( GLShaderManager *manager ): u_ParallaxDepthScale( this ), u_ParallaxOffsetBias( this ), u_HeightMapInNormalMap( this ), - u_NormalIntensity( this ), u_NormalScale( this ), u_VertexInterpolation( this ), GLDeformStage( this ), @@ -2111,7 +2110,6 @@ GLShader_liquid::GLShader_liquid( GLShaderManager *manager ) : u_ParallaxDepthScale( this ), u_ParallaxOffsetBias( this ), u_HeightMapInNormalMap( this ), - u_NormalIntensity( this ), u_NormalScale( this ), u_FogDensity( this ), u_FogColor( this ), diff --git a/src/engine/renderer/gl_shader.h b/src/engine/renderer/gl_shader.h index ab317065b5..6d0c449c8a 100644 --- a/src/engine/renderer/gl_shader.h +++ b/src/engine/renderer/gl_shader.h @@ -1510,31 +1510,16 @@ class u_FresnelBias : } }; -class u_NormalIntensity : - GLUniform1f -{ -public: - u_NormalIntensity( GLShader *shader ) : - GLUniform1f( shader, "u_NormalIntensity" ) - { - } - - void SetUniform_NormalIntensity( float value ) - { - this->SetValue( value ); - } -}; - class u_NormalScale : - GLUniform4f + GLUniform3f { public: u_NormalScale( GLShader *shader ) : - GLUniform4f( shader, "u_NormalScale" ) + GLUniform3f( shader, "u_NormalScale" ) { } - void SetUniform_NormalScale( const vec4_t value ) + void SetUniform_NormalScale( const vec3_t value ) { this->SetValue( value ); } @@ -2394,7 +2379,6 @@ class GLShader_reflection : public u_ParallaxDepthScale, public u_ParallaxOffsetBias, public u_HeightMapInNormalMap, - public u_NormalIntensity, public u_NormalScale, public u_VertexInterpolation, public GLDeformStage, @@ -2601,7 +2585,6 @@ class GLShader_liquid : public u_ParallaxDepthScale, public u_ParallaxOffsetBias, public u_HeightMapInNormalMap, - public u_NormalIntensity, public u_NormalScale, public u_FogDensity, public u_FogColor, diff --git a/src/engine/renderer/glsl_source/liquid_fp.glsl b/src/engine/renderer/glsl_source/liquid_fp.glsl index 78ae3138c7..33f61974bb 100644 --- a/src/engine/renderer/glsl_source/liquid_fp.glsl +++ b/src/engine/renderer/glsl_source/liquid_fp.glsl @@ -32,7 +32,7 @@ uniform float u_RefractionIndex; uniform float u_FresnelPower; uniform float u_FresnelScale; uniform float u_FresnelBias; -uniform float u_NormalIntensity; +uniform float u_NormalScale; uniform mat4 u_ModelMatrix; uniform mat4 u_UnprojectMatrix; uniform vec2 u_SpecularExponent; @@ -112,7 +112,11 @@ void main() float fresnel = clamp(u_FresnelBias + pow(1.0 - dot(viewDir, normal), u_FresnelPower) * u_FresnelScale, 0.0, 1.0); - texScreen += u_NormalIntensity * normal.xy; + // HACK: 0 normal Z channel can't be good + if (u_NormalScale.z != 0) + { + texScreen *= u_NormalScale; + } vec3 refractColor = texture2D(u_CurrentMap, texScreen).rgb; vec3 reflectColor = texture2D(u_PortalMap, texScreen).rgb; diff --git a/src/engine/renderer/glsl_source/reliefMapping_fp.glsl b/src/engine/renderer/glsl_source/reliefMapping_fp.glsl index 700b2c2323..db8c355dc0 100644 --- a/src/engine/renderer/glsl_source/reliefMapping_fp.glsl +++ b/src/engine/renderer/glsl_source/reliefMapping_fp.glsl @@ -27,8 +27,7 @@ uniform int u_HeightMapInNormalMap; #endif // r_normalMapping || USE_PARALLAX_MAPPING #if defined(r_normalMapping) -// HACK: fourth component tells renderer if normal scale is customized or not -uniform vec4 u_NormalScale; +uniform vec3 u_NormalScale; #endif // r_normalMapping #if defined(USE_PARALLAX_MAPPING) @@ -64,10 +63,10 @@ vec3 NormalInTangentSpace(vec2 texNormal) normal = 2.0 * normal - 1.0; } - // HACK: fourth component tells renderer if normal scale is customized or not - if (u_NormalScale.w != 0) + // HACK: 0 normal Z channel can't be good + if (u_NormalScale.z != 0) { - normal *= u_NormalScale.xyz; + normal *= u_NormalScale; } #if defined(r_NormalScale) diff --git a/src/engine/renderer/tr_local.h b/src/engine/renderer/tr_local.h index d496bef753..a7edcdce7c 100644 --- a/src/engine/renderer/tr_local.h +++ b/src/engine/renderer/tr_local.h @@ -1122,8 +1122,8 @@ static inline void halfToFloat( const f16vec4_t in, vec4_t out ) expression_t fresnelBiasExp; // normalMap channel scale, negative value flips channel - // HACK: fourth component tells renderer if normal scale is customized or not - vec4_t normalScale; + bool hasNormalScale; + vec3_t normalScale; expression_t normalIntensityExp; diff --git a/src/engine/renderer/tr_shade.cpp b/src/engine/renderer/tr_shade.cpp index 3b57cd3dc7..9e82ff33ec 100644 --- a/src/engine/renderer/tr_shade.cpp +++ b/src/engine/renderer/tr_shade.cpp @@ -578,6 +578,28 @@ void Tess_Begin( void ( *stageIteratorFunc )(), } } +/* +============== +SetNormalScale +============== +*/ +void SetNormalScale( shaderStage_t *pStage, vec3_t normalScale) +{ + float normalIntensity; + + normalIntensity = RB_EvalExpression( &pStage->normalIntensityExp, 1 ); + + normalScale[ 0 ] *= normalIntensity; + normalScale[ 1 ] *= normalIntensity; + + if ( pStage->hasNormalScale ) + { + normalScale[ 0 ] *= pStage->normalScale[ 0 ]; + normalScale[ 1 ] *= pStage->normalScale[ 1 ]; + normalScale[ 2 ] *= pStage->normalScale[ 2 ]; + } +} + // *INDENT-ON* static void Render_generic( int stage ) @@ -802,8 +824,11 @@ static void Render_vertexLighting_DBS_entity( int stage ) // bind u_NormalMap GL_BindToTMU( 1, pStage->bundle[ TB_NORMALMAP ].image[ 0 ] ); + vec3_t normalScale = { 1, 1, 1 }; + SetNormalScale( pStage, normalScale ); + // bind u_NormalScale - gl_vertexLightingShader_DBS_entity->SetUniform_NormalScale( pStage->normalScale ); + gl_vertexLightingShader_DBS_entity->SetUniform_NormalScale( normalScale ); } else { @@ -1049,8 +1074,11 @@ static void Render_vertexLighting_DBS_world( int stage ) // bind u_NormalMap GL_BindToTMU( 1, pStage->bundle[ TB_NORMALMAP ].image[ 0 ] ); + vec3_t normalScale = { 1, 1, 1 }; + SetNormalScale( pStage, normalScale ); + // bind u_NormalScale - gl_vertexLightingShader_DBS_world->SetUniform_NormalScale( pStage->normalScale ); + gl_vertexLightingShader_DBS_world->SetUniform_NormalScale( normalScale ); } else { @@ -1224,8 +1252,11 @@ static void Render_lightMapping( int stage ) { GL_BindToTMU( 1, pStage->bundle[ TB_NORMALMAP ].image[ 0 ] ); + vec3_t normalScale = { 1, 1, 1 }; + SetNormalScale( pStage, normalScale ); + // bind u_NormalScale - gl_lightMappingShader->SetUniform_NormalScale( pStage->normalScale ); + gl_lightMappingShader->SetUniform_NormalScale( normalScale ); } else { @@ -1566,8 +1597,11 @@ static void Render_forwardLighting_DBS_omni( shaderStage_t *diffuseStage, // bind u_NormalMap GL_BindToTMU( 1, diffuseStage->bundle[ TB_NORMALMAP ].image[ 0 ] ); + vec3_t normalScale = { 1, 1, 1 }; + SetNormalScale( diffuseStage, normalScale ); + // bind u_NormalScale - gl_forwardLightingShader_omniXYZ->SetUniform_NormalScale( diffuseStage->normalScale ); + gl_forwardLightingShader_omniXYZ->SetUniform_NormalScale( normalScale ); } else { @@ -1753,8 +1787,11 @@ static void Render_forwardLighting_DBS_proj( shaderStage_t *diffuseStage, // bind u_NormalMap GL_BindToTMU( 1, diffuseStage->bundle[ TB_NORMALMAP ].image[ 0 ] ); + vec3_t normalScale = { 1, 1, 1 }; + SetNormalScale( diffuseStage, normalScale ); + // bind u_NormalScale - gl_forwardLightingShader_projXYZ->SetUniform_NormalScale( diffuseStage->normalScale ); + gl_forwardLightingShader_projXYZ->SetUniform_NormalScale( normalScale ); } else { @@ -1942,8 +1979,11 @@ static void Render_forwardLighting_DBS_directional( shaderStage_t *diffuseStage, // bind u_NormalMap GL_BindToTMU( 1, diffuseStage->bundle[ TB_NORMALMAP ].image[ 0 ] ); + vec3_t normalScale = { 1, 1, 1 }; + SetNormalScale( diffuseStage, normalScale ); + // bind u_NormalScale - gl_forwardLightingShader_directionalSun->SetUniform_NormalScale( diffuseStage->normalScale ); + gl_forwardLightingShader_directionalSun->SetUniform_NormalScale( normalScale ); } else { @@ -2078,8 +2118,11 @@ static void Render_reflection_CB( int stage ) gl_reflectionShader->SetUniform_HeightMapInNormalMap( pStage->heightMapInNormalMap ); } + vec3_t normalScale = { 1, 1, 1 }; + SetNormalScale( pStage, normalScale ); + // bind u_NormalScale - gl_reflectionShader->SetUniform_NormalScale( pStage->normalScale ); + gl_reflectionShader->SetUniform_NormalScale( normalScale ); gl_reflectionShader->SetRequiredVertexPointers(); @@ -2245,8 +2288,11 @@ static void Render_heatHaze( int stage ) gl_heatHazeShader->SetUniform_TextureMatrix( tess.svars.texMatrices[ TB_COLORMAP ] ); + vec3_t normalScale = { 1, 1, 1 }; + SetNormalScale( pStage, normalScale ); + // bind u_NormalScale - gl_heatHazeShader->SetUniform_NormalScale( pStage->normalScale ); + gl_heatHazeShader->SetUniform_NormalScale( normalScale ); } GL_BindToTMU( 1, tr.currentRenderImage[ backEnd.currentMainFBO ] ); @@ -2332,7 +2378,7 @@ static void Render_liquid( int stage ) SetNormalScale( pStage, normalScale ); // bind u_NormalScale - gl_liquidShader->SetUniform_NormalScale( pStage->normalScale ); + gl_liquidShader->SetUniform_NormalScale( normalScale ); } gl_liquidShader->SetUniform_TextureMatrix( tess.svars.texMatrices[ TB_COLORMAP ] ); diff --git a/src/engine/renderer/tr_shader.cpp b/src/engine/renderer/tr_shader.cpp index 3e703653b8..685aae1949 100644 --- a/src/engine/renderer/tr_shader.cpp +++ b/src/engine/renderer/tr_shader.cpp @@ -2833,7 +2833,8 @@ static bool ParseStage( shaderStage_t *stage, const char **text ) // normalScale X Y // having a fallback for missing Z component keeps compatibility stage->normalScale[ 2 ] = 1; - // no need to hack the fourth component since previous loop did it + // no need to set hasNormalScale since previous loop did it + // stage->hasNormalScale = true; } else { @@ -2843,8 +2844,7 @@ static bool ParseStage( shaderStage_t *stage, const char **text ) } stage->normalScale[ i ] = atof( token ); - // HACK: fourth component tells renderer if normal scale is customized or not - stage->normalScale[ 3 ] = 1; + stage->hasNormalScale = true; } SkipRestOfLine( text ); continue; @@ -3595,8 +3595,7 @@ static bool ParseShader( const char *_text ) stages[ s ].normalScale[ 0 ] = 1; stages[ s ].normalScale[ 1 ] = -1; stages[ s ].normalScale[ 2 ] = 1; - // HACK: fourth component tells renderer if normal scale is customized or not - stages[ s ].normalScale[ 3 ] = 1; + stages[ s ].hasNormalScale = true; } s++; @@ -4523,8 +4522,7 @@ static void CollapseStages() stages[ diffuseStage ].normalScale[ 0 ] = stages[ normalStage ].normalScale[ 0 ]; stages[ diffuseStage ].normalScale[ 1 ] = stages[ normalStage ].normalScale[ 1 ]; stages[ diffuseStage ].normalScale[ 2 ] = stages[ normalStage ].normalScale[ 2 ]; - // HACK: fourth component tells renderer if normal scale is customized or not - stages[ diffuseStage ].normalScale[ 3 ] = stages[ normalStage ].normalScale[ 3 ]; + stages[ diffuseStage ].hasNormalScale = stages[ normalStage ].hasNormalScale; stages[ diffuseStage ].heightMapInNormalMap = stages[ normalStage ].heightMapInNormalMap; // disable since it's merged stages[ normalStage ].active = false; From eda4c9dfb65aeddbacabf7688ed80d38692dd431 Mon Sep 17 00:00:00 2001 From: Thomas Debesse Date: Sun, 15 Dec 2019 06:29:22 +0100 Subject: [PATCH 3/4] renderer: remove glsl r_NormalScale define, leverage normalScale instead --- src/engine/renderer/gl_shader.cpp | 1 - src/engine/renderer/glsl_source/reliefMapping_fp.glsl | 4 ---- src/engine/renderer/tr_init.cpp | 2 +- src/engine/renderer/tr_shade.cpp | 9 +++++++++ 4 files changed, 10 insertions(+), 6 deletions(-) diff --git a/src/engine/renderer/gl_shader.cpp b/src/engine/renderer/gl_shader.cpp index f90e376334..00256673ed 100644 --- a/src/engine/renderer/gl_shader.cpp +++ b/src/engine/renderer/gl_shader.cpp @@ -699,7 +699,6 @@ std::string GLShaderManager::BuildGPUShaderText( Str::StringRef mainShaderNa AddDefine( env, "r_AmbientScale", r_ambientScale->value ); AddDefine( env, "r_SpecularScale", r_specularScale->value ); - AddDefine( env, "r_NormalScale", r_normalScale->value ); AddDefine( env, "r_zNear", r_znear->value ); AddDefine( env, "M_PI", static_cast( M_PI ) ); diff --git a/src/engine/renderer/glsl_source/reliefMapping_fp.glsl b/src/engine/renderer/glsl_source/reliefMapping_fp.glsl index db8c355dc0..64950ee3d4 100644 --- a/src/engine/renderer/glsl_source/reliefMapping_fp.glsl +++ b/src/engine/renderer/glsl_source/reliefMapping_fp.glsl @@ -68,10 +68,6 @@ vec3 NormalInTangentSpace(vec2 texNormal) { normal *= u_NormalScale; } - -#if defined(r_NormalScale) - normal.z *= r_NormalScale; -#endif #else // !r_normalMapping normal = vec3(0.5, 0.5, 1.0); #endif // !r_normalMapping diff --git a/src/engine/renderer/tr_init.cpp b/src/engine/renderer/tr_init.cpp index bafbfb6f1f..2bda7b081f 100644 --- a/src/engine/renderer/tr_init.cpp +++ b/src/engine/renderer/tr_init.cpp @@ -1196,7 +1196,7 @@ ScreenshotCmd screenshotPNGRegistration("screenshotPNG", ssFormat_t::SSF_PNG, "p r_specularScale = ri.Cvar_Get( "r_specularScale", "1.0", CVAR_CHEAT | CVAR_LATCH ); r_specularMapping = ri.Cvar_Get( "r_specularMapping", "1", CVAR_LATCH ); r_deluxeMapping = ri.Cvar_Get( "r_deluxeMapping", "1", CVAR_ARCHIVE ); - r_normalScale = ri.Cvar_Get( "r_normalScale", "1.0", CVAR_LATCH ); + r_normalScale = ri.Cvar_Get( "r_normalScale", "1.0", CVAR_ARCHIVE ); r_normalMapping = ri.Cvar_Get( "r_normalMapping", "1", CVAR_ARCHIVE ); r_highQualityNormalMapping = ri.Cvar_Get( "r_highQualityNormalMapping", "0", CVAR_LATCH ); r_parallaxDepthScale = ri.Cvar_Get( "r_parallaxDepthScale", "0.03", CVAR_CHEAT ); diff --git a/src/engine/renderer/tr_shade.cpp b/src/engine/renderer/tr_shade.cpp index 9e82ff33ec..d1af46b824 100644 --- a/src/engine/renderer/tr_shade.cpp +++ b/src/engine/renderer/tr_shade.cpp @@ -598,6 +598,15 @@ void SetNormalScale( shaderStage_t *pStage, vec3_t normalScale) normalScale[ 1 ] *= pStage->normalScale[ 1 ]; normalScale[ 2 ] *= pStage->normalScale[ 2 ]; } + + // NOTE: normalmap with zero Z component is wrong + // + // since glsl disables normalScale when Z is zero + // setting this to zero has side effect to reset + // per-stage normalScale + // + // there is no intention to keep this undefined feature + normalScale[ 2 ] *= r_normalScale->value; } // *INDENT-ON* From 927b640fb5d0d61f264f2a55ba4742bae544934f Mon Sep 17 00:00:00 2001 From: Thomas Debesse Date: Sun, 15 Dec 2019 07:40:05 +0100 Subject: [PATCH 4/4] tr_shade: refactor SetNormalScale a bit --- src/engine/renderer/tr_shade.cpp | 24 +++++++++++++----------- 1 file changed, 13 insertions(+), 11 deletions(-) diff --git a/src/engine/renderer/tr_shade.cpp b/src/engine/renderer/tr_shade.cpp index d1af46b824..fba53de79a 100644 --- a/src/engine/renderer/tr_shade.cpp +++ b/src/engine/renderer/tr_shade.cpp @@ -585,9 +585,11 @@ SetNormalScale */ void SetNormalScale( shaderStage_t *pStage, vec3_t normalScale) { - float normalIntensity; + float normalIntensity = RB_EvalExpression( &pStage->normalIntensityExp, 1 ); - normalIntensity = RB_EvalExpression( &pStage->normalIntensityExp, 1 ); + normalScale[ 0 ] = 1; + normalScale[ 1 ] = 1; + normalScale[ 2 ] = 1; normalScale[ 0 ] *= normalIntensity; normalScale[ 1 ] *= normalIntensity; @@ -833,7 +835,7 @@ static void Render_vertexLighting_DBS_entity( int stage ) // bind u_NormalMap GL_BindToTMU( 1, pStage->bundle[ TB_NORMALMAP ].image[ 0 ] ); - vec3_t normalScale = { 1, 1, 1 }; + vec3_t normalScale; SetNormalScale( pStage, normalScale ); // bind u_NormalScale @@ -1083,7 +1085,7 @@ static void Render_vertexLighting_DBS_world( int stage ) // bind u_NormalMap GL_BindToTMU( 1, pStage->bundle[ TB_NORMALMAP ].image[ 0 ] ); - vec3_t normalScale = { 1, 1, 1 }; + vec3_t normalScale; SetNormalScale( pStage, normalScale ); // bind u_NormalScale @@ -1261,7 +1263,7 @@ static void Render_lightMapping( int stage ) { GL_BindToTMU( 1, pStage->bundle[ TB_NORMALMAP ].image[ 0 ] ); - vec3_t normalScale = { 1, 1, 1 }; + vec3_t normalScale; SetNormalScale( pStage, normalScale ); // bind u_NormalScale @@ -1606,7 +1608,7 @@ static void Render_forwardLighting_DBS_omni( shaderStage_t *diffuseStage, // bind u_NormalMap GL_BindToTMU( 1, diffuseStage->bundle[ TB_NORMALMAP ].image[ 0 ] ); - vec3_t normalScale = { 1, 1, 1 }; + vec3_t normalScale; SetNormalScale( diffuseStage, normalScale ); // bind u_NormalScale @@ -1796,7 +1798,7 @@ static void Render_forwardLighting_DBS_proj( shaderStage_t *diffuseStage, // bind u_NormalMap GL_BindToTMU( 1, diffuseStage->bundle[ TB_NORMALMAP ].image[ 0 ] ); - vec3_t normalScale = { 1, 1, 1 }; + vec3_t normalScale; SetNormalScale( diffuseStage, normalScale ); // bind u_NormalScale @@ -1988,7 +1990,7 @@ static void Render_forwardLighting_DBS_directional( shaderStage_t *diffuseStage, // bind u_NormalMap GL_BindToTMU( 1, diffuseStage->bundle[ TB_NORMALMAP ].image[ 0 ] ); - vec3_t normalScale = { 1, 1, 1 }; + vec3_t normalScale; SetNormalScale( diffuseStage, normalScale ); // bind u_NormalScale @@ -2127,7 +2129,7 @@ static void Render_reflection_CB( int stage ) gl_reflectionShader->SetUniform_HeightMapInNormalMap( pStage->heightMapInNormalMap ); } - vec3_t normalScale = { 1, 1, 1 }; + vec3_t normalScale; SetNormalScale( pStage, normalScale ); // bind u_NormalScale @@ -2297,7 +2299,7 @@ static void Render_heatHaze( int stage ) gl_heatHazeShader->SetUniform_TextureMatrix( tess.svars.texMatrices[ TB_COLORMAP ] ); - vec3_t normalScale = { 1, 1, 1 }; + vec3_t normalScale; SetNormalScale( pStage, normalScale ); // bind u_NormalScale @@ -2383,7 +2385,7 @@ static void Render_liquid( int stage ) // bind u_NormalMap GL_BindToTMU( 3, pStage->bundle[ TB_COLORMAP ].image[ 0 ] ); - vec3_t normalScale = { 1, 1, 1 }; + vec3_t normalScale; SetNormalScale( pStage, normalScale ); // bind u_NormalScale