From bc864d8537d95d8c912c6f286f6eec1caa5307f8 Mon Sep 17 00:00:00 2001 From: Thomas Debesse Date: Sat, 14 Dec 2019 18:11:54 +0100 Subject: [PATCH 1/2] renderer: add per-stage heightMap keyword also make USE_HEIGHTMAP_IN_NORMALMAP a macro, obsoletes #189 About the collapse code collapsing heightmap stage while heightmap is a pre-colapsed stage attribute: > @slipher: The commit message says the heightmap is a per-stage attribute, but this looks like it's in a stage by itself? > @illwieckz: The dpMaterial DarkPlaces compatibility layer is not yet ported to the pre-collapsed stage code and I'm using Xonotic assets to test this feature, hence the temporary requirement to collapse a standalone heightmap stage. There is no keyword available to mapper to use the standalone heightmap stage, only the per-stage attribute, so there is no chance a mapper uses the standalone heightmap stage by mistake and we can drop it one day. https://github.com/DaemonEngine/Daemon/pull/252#pullrequestreview-336919745 --- src/engine/renderer/gl_shader.cpp | 25 ++- src/engine/renderer/gl_shader.h | 57 +++--- .../glsl_source/reliefMapping_fp.glsl | 64 ++++--- src/engine/renderer/tr_image.cpp | 2 +- src/engine/renderer/tr_local.h | 4 +- src/engine/renderer/tr_shade.cpp | 165 +++++++++++++++--- src/engine/renderer/tr_shader.cpp | 59 ++++++- 7 files changed, 288 insertions(+), 88 deletions(-) diff --git a/src/engine/renderer/gl_shader.cpp b/src/engine/renderer/gl_shader.cpp index 00256673ed..05ea5c89f4 100644 --- a/src/engine/renderer/gl_shader.cpp +++ b/src/engine/renderer/gl_shader.cpp @@ -1466,12 +1466,12 @@ GLShader_lightMapping::GLShader_lightMapping( GLShaderManager *manager ) : u_ModelViewProjectionMatrix( this ), u_ParallaxDepthScale( this ), u_ParallaxOffsetBias( this ), - u_HeightMapInNormalMap( this ), u_NormalScale( this ), u_numLights( this ), u_Lights( this ), GLDeformStage( this ), GLCompileMacro_USE_DELUXE_MAPPING( this ), + GLCompileMacro_USE_HEIGHTMAP_IN_NORMALMAP( this ), GLCompileMacro_USE_PARALLAX_MAPPING( this ), GLCompileMacro_USE_PHYSICAL_SHADING( this ) { @@ -1503,6 +1503,7 @@ void GLShader_lightMapping::SetShaderProgramUniforms( shaderProgram_t *shaderPro if( !glConfig2.uniformBufferObjectAvailable ) { glUniform1i( glGetUniformLocation( shaderProgram->program, "u_Lights" ), 9 ); } + glUniform1i( glGetUniformLocation( shaderProgram->program, "u_HeightMap" ), 15 ); } GLShader_vertexLighting_DBS_entity::GLShader_vertexLighting_DBS_entity( GLShaderManager *manager ) : @@ -1517,7 +1518,6 @@ GLShader_vertexLighting_DBS_entity::GLShader_vertexLighting_DBS_entity( GLShader u_VertexInterpolation( this ), u_ParallaxDepthScale( this ), u_ParallaxOffsetBias( this ), - u_HeightMapInNormalMap( this ), u_NormalScale( this ), u_EnvironmentInterpolation( this ), u_LightGridOrigin( this ), @@ -1527,6 +1527,7 @@ GLShader_vertexLighting_DBS_entity::GLShader_vertexLighting_DBS_entity( GLShader GLDeformStage( this ), GLCompileMacro_USE_VERTEX_SKINNING( this ), GLCompileMacro_USE_VERTEX_ANIMATION( this ), + GLCompileMacro_USE_HEIGHTMAP_IN_NORMALMAP( this ), GLCompileMacro_USE_PARALLAX_MAPPING( this ), GLCompileMacro_USE_REFLECTIVE_SPECULAR( this ), GLCompileMacro_USE_PHYSICAL_SHADING( this ) @@ -1561,6 +1562,7 @@ void GLShader_vertexLighting_DBS_entity::SetShaderProgramUniforms( shaderProgram if( !glConfig2.uniformBufferObjectAvailable ) { glUniform1i( glGetUniformLocation( shaderProgram->program, "u_Lights" ), 9 ); } + glUniform1i( glGetUniformLocation( shaderProgram->program, "u_HeightMap" ), 15 ); } GLShader_vertexLighting_DBS_world::GLShader_vertexLighting_DBS_world( GLShaderManager *manager ) : @@ -1578,7 +1580,6 @@ GLShader_vertexLighting_DBS_world::GLShader_vertexLighting_DBS_world( GLShaderMa u_ModelViewProjectionMatrix( this ), u_ParallaxDepthScale( this ), u_ParallaxOffsetBias( this ), - u_HeightMapInNormalMap( this ), u_NormalScale( this ), u_LightWrapAround( this ), u_LightGridOrigin( this ), @@ -1586,6 +1587,7 @@ GLShader_vertexLighting_DBS_world::GLShader_vertexLighting_DBS_world( GLShaderMa u_numLights( this ), u_Lights( this ), GLDeformStage( this ), + GLCompileMacro_USE_HEIGHTMAP_IN_NORMALMAP( this ), GLCompileMacro_USE_PARALLAX_MAPPING( this ), GLCompileMacro_USE_PHYSICAL_SHADING( this ) { @@ -1616,6 +1618,7 @@ void GLShader_vertexLighting_DBS_world::SetShaderProgramUniforms( shaderProgram_ if( !glConfig2.uniformBufferObjectAvailable ) { glUniform1i( glGetUniformLocation( shaderProgram->program, "u_Lights" ), 9 ); } + glUniform1i( glGetUniformLocation( shaderProgram->program, "u_HeightMap" ), 15 ); } GLShader_forwardLighting_omniXYZ::GLShader_forwardLighting_omniXYZ( GLShaderManager *manager ): @@ -1640,11 +1643,11 @@ GLShader_forwardLighting_omniXYZ::GLShader_forwardLighting_omniXYZ( GLShaderMana u_VertexInterpolation( this ), u_ParallaxDepthScale( this ), u_ParallaxOffsetBias( this ), - u_HeightMapInNormalMap( this ), u_NormalScale( this ), GLDeformStage( this ), GLCompileMacro_USE_VERTEX_SKINNING( this ), GLCompileMacro_USE_VERTEX_ANIMATION( this ), + GLCompileMacro_USE_HEIGHTMAP_IN_NORMALMAP( this ), GLCompileMacro_USE_PARALLAX_MAPPING( this ), GLCompileMacro_USE_SHADOWING( this ) { @@ -1674,6 +1677,7 @@ void GLShader_forwardLighting_omniXYZ::SetShaderProgramUniforms( shaderProgram_t glUniform1i( glGetUniformLocation( shaderProgram->program, "u_ShadowMap" ), 5 ); glUniform1i( glGetUniformLocation( shaderProgram->program, "u_RandomMap" ), 6 ); glUniform1i( glGetUniformLocation( shaderProgram->program, "u_ShadowClipMap" ), 7 ); + glUniform1i( glGetUniformLocation( shaderProgram->program, "u_HeightMap" ), 15 ); } GLShader_forwardLighting_projXYZ::GLShader_forwardLighting_projXYZ( GLShaderManager *manager ): @@ -1699,11 +1703,11 @@ GLShader_forwardLighting_projXYZ::GLShader_forwardLighting_projXYZ( GLShaderMana u_VertexInterpolation( this ), u_ParallaxDepthScale( this ), u_ParallaxOffsetBias( this ), - u_HeightMapInNormalMap( this ), u_NormalScale( this ), GLDeformStage( this ), GLCompileMacro_USE_VERTEX_SKINNING( this ), GLCompileMacro_USE_VERTEX_ANIMATION( this ), + GLCompileMacro_USE_HEIGHTMAP_IN_NORMALMAP( this ), GLCompileMacro_USE_PARALLAX_MAPPING( this ), GLCompileMacro_USE_SHADOWING( this ) { @@ -1734,6 +1738,7 @@ void GLShader_forwardLighting_projXYZ::SetShaderProgramUniforms( shaderProgram_t glUniform1i( glGetUniformLocation( shaderProgram->program, "u_ShadowMap0" ), 5 ); glUniform1i( glGetUniformLocation( shaderProgram->program, "u_RandomMap" ), 6 ); glUniform1i( glGetUniformLocation( shaderProgram->program, "u_ShadowClipMap0" ), 7 ); + glUniform1i( glGetUniformLocation( shaderProgram->program, "u_HeightMap" ), 15 ); } GLShader_forwardLighting_directionalSun::GLShader_forwardLighting_directionalSun( GLShaderManager *manager ): @@ -1761,11 +1766,11 @@ GLShader_forwardLighting_directionalSun::GLShader_forwardLighting_directionalSun u_VertexInterpolation( this ), u_ParallaxDepthScale( this ), u_ParallaxOffsetBias( this ), - u_HeightMapInNormalMap( this ), u_NormalScale( this ), GLDeformStage( this ), GLCompileMacro_USE_VERTEX_SKINNING( this ), GLCompileMacro_USE_VERTEX_ANIMATION( this ), + GLCompileMacro_USE_HEIGHTMAP_IN_NORMALMAP( this ), GLCompileMacro_USE_PARALLAX_MAPPING( this ), GLCompileMacro_USE_SHADOWING( this ) { @@ -1803,6 +1808,7 @@ void GLShader_forwardLighting_directionalSun::SetShaderProgramUniforms( shaderPr glUniform1i( glGetUniformLocation( shaderProgram->program, "u_ShadowClipMap2" ), 12 ); glUniform1i( glGetUniformLocation( shaderProgram->program, "u_ShadowClipMap3" ), 13 ); glUniform1i( glGetUniformLocation( shaderProgram->program, "u_ShadowClipMap4" ), 14 ); + glUniform1i( glGetUniformLocation( shaderProgram->program, "u_HeightMap" ), 15 ); } GLShader_shadowFill::GLShader_shadowFill( GLShaderManager *manager ) : @@ -1843,12 +1849,12 @@ GLShader_reflection::GLShader_reflection( GLShaderManager *manager ): u_Bones( this ), u_ParallaxDepthScale( this ), u_ParallaxOffsetBias( this ), - u_HeightMapInNormalMap( this ), u_NormalScale( this ), u_VertexInterpolation( this ), GLDeformStage( this ), GLCompileMacro_USE_VERTEX_SKINNING( this ), GLCompileMacro_USE_VERTEX_ANIMATION( this ), + GLCompileMacro_USE_HEIGHTMAP_IN_NORMALMAP( this ), GLCompileMacro_USE_PARALLAX_MAPPING( this ) { } @@ -1871,6 +1877,7 @@ void GLShader_reflection::SetShaderProgramUniforms( shaderProgram_t *shaderProgr { glUniform1i( glGetUniformLocation( shaderProgram->program, "u_ColorMap" ), 0 ); glUniform1i( glGetUniformLocation( shaderProgram->program, "u_NormalMap" ), 1 ); + glUniform1i( glGetUniformLocation( shaderProgram->program, "u_HeightMap" ), 15 ); } GLShader_skybox::GLShader_skybox( GLShaderManager *manager ) : @@ -1969,6 +1976,7 @@ void GLShader_heatHaze::SetShaderProgramUniforms( shaderProgram_t *shaderProgram { glUniform1i( glGetUniformLocation( shaderProgram->program, "u_NormalMap" ), 0 ); glUniform1i( glGetUniformLocation( shaderProgram->program, "u_CurrentMap" ), 1 ); + glUniform1i( glGetUniformLocation( shaderProgram->program, "u_HeightMap" ), 15 ); } GLShader_screen::GLShader_screen( GLShaderManager *manager ) : @@ -2108,13 +2116,13 @@ GLShader_liquid::GLShader_liquid( GLShaderManager *manager ) : u_FresnelBias( this ), u_ParallaxDepthScale( this ), u_ParallaxOffsetBias( this ), - u_HeightMapInNormalMap( this ), u_NormalScale( this ), u_FogDensity( this ), u_FogColor( this ), u_SpecularExponent( this ), u_LightGridOrigin( this ), u_LightGridScale( this ), + GLCompileMacro_USE_HEIGHTMAP_IN_NORMALMAP( this ), GLCompileMacro_USE_PARALLAX_MAPPING( this ) { } @@ -2132,6 +2140,7 @@ void GLShader_liquid::SetShaderProgramUniforms( shaderProgram_t *shaderProgram ) glUniform1i( glGetUniformLocation( shaderProgram->program, "u_NormalMap" ), 3 ); glUniform1i( glGetUniformLocation( shaderProgram->program, "u_LightGrid1" ), 6 ); glUniform1i( glGetUniformLocation( shaderProgram->program, "u_LightGrid2" ), 7 ); + glUniform1i( glGetUniformLocation( shaderProgram->program, "u_HeightMap" ), 15 ); } GLShader_volumetricFog::GLShader_volumetricFog( GLShaderManager *manager ) : diff --git a/src/engine/renderer/gl_shader.h b/src/engine/renderer/gl_shader.h index 6d0c449c8a..cec1be8f65 100644 --- a/src/engine/renderer/gl_shader.h +++ b/src/engine/renderer/gl_shader.h @@ -784,6 +784,7 @@ class GLCompileMacro USE_TCGEN_ENVIRONMENT, USE_TCGEN_LIGHTMAP, USE_DELUXE_MAPPING, + USE_HEIGHTMAP_IN_NORMALMAP, USE_PARALLAX_MAPPING, USE_REFLECTIVE_SPECULAR, USE_SHADOWING, @@ -1009,6 +1010,31 @@ class GLCompileMacro_USE_DELUXE_MAPPING : } }; +class GLCompileMacro_USE_HEIGHTMAP_IN_NORMALMAP : + GLCompileMacro +{ +public: + GLCompileMacro_USE_HEIGHTMAP_IN_NORMALMAP( GLShader *shader ) : + GLCompileMacro( shader ) + { + } + + const char *GetName() const + { + return "USE_HEIGHTMAP_IN_NORMALMAP"; + } + + EGLCompileMacro GetType() const + { + return EGLCompileMacro::USE_HEIGHTMAP_IN_NORMALMAP; + } + + void SetHeightMapInNormalMap( bool enable ) + { + SetMacro( enable ); + } +}; + class GLCompileMacro_USE_PARALLAX_MAPPING : GLCompileMacro { @@ -1766,21 +1792,6 @@ class u_ParallaxOffsetBias : } }; -class u_HeightMapInNormalMap : - GLUniform1i -{ -public: - u_HeightMapInNormalMap( GLShader *shader ) : - GLUniform1i( shader, "u_HeightMapInNormalMap" ) - { - } - - void SetUniform_HeightMapInNormalMap( int value ) - { - this->SetValue( value ); - } -}; - class u_EnvironmentInterpolation : GLUniform1f { @@ -2146,12 +2157,12 @@ class GLShader_lightMapping : public u_ModelViewProjectionMatrix, public u_ParallaxDepthScale, public u_ParallaxOffsetBias, - public u_HeightMapInNormalMap, public u_NormalScale, public u_numLights, public u_Lights, public GLDeformStage, public GLCompileMacro_USE_DELUXE_MAPPING, + public GLCompileMacro_USE_HEIGHTMAP_IN_NORMALMAP, public GLCompileMacro_USE_PARALLAX_MAPPING, public GLCompileMacro_USE_PHYSICAL_SHADING { @@ -2175,7 +2186,6 @@ class GLShader_vertexLighting_DBS_entity : public u_VertexInterpolation, public u_ParallaxDepthScale, public u_ParallaxOffsetBias, - public u_HeightMapInNormalMap, public u_NormalScale, public u_EnvironmentInterpolation, public u_LightGridOrigin, @@ -2185,6 +2195,7 @@ class GLShader_vertexLighting_DBS_entity : public GLDeformStage, public GLCompileMacro_USE_VERTEX_SKINNING, public GLCompileMacro_USE_VERTEX_ANIMATION, + public GLCompileMacro_USE_HEIGHTMAP_IN_NORMALMAP, public GLCompileMacro_USE_PARALLAX_MAPPING, public GLCompileMacro_USE_REFLECTIVE_SPECULAR, public GLCompileMacro_USE_PHYSICAL_SHADING @@ -2209,7 +2220,6 @@ class GLShader_vertexLighting_DBS_world : public u_ModelViewProjectionMatrix, public u_ParallaxDepthScale, public u_ParallaxOffsetBias, - public u_HeightMapInNormalMap, public u_NormalScale, public u_LightWrapAround, public u_LightGridOrigin, @@ -2217,6 +2227,7 @@ class GLShader_vertexLighting_DBS_world : public u_numLights, public u_Lights, public GLDeformStage, + public GLCompileMacro_USE_HEIGHTMAP_IN_NORMALMAP, public GLCompileMacro_USE_PARALLAX_MAPPING, public GLCompileMacro_USE_PHYSICAL_SHADING { @@ -2250,11 +2261,11 @@ class GLShader_forwardLighting_omniXYZ : public u_VertexInterpolation, public u_ParallaxDepthScale, public u_ParallaxOffsetBias, - public u_HeightMapInNormalMap, public u_NormalScale, public GLDeformStage, public GLCompileMacro_USE_VERTEX_SKINNING, public GLCompileMacro_USE_VERTEX_ANIMATION, + public GLCompileMacro_USE_HEIGHTMAP_IN_NORMALMAP, public GLCompileMacro_USE_PARALLAX_MAPPING, public GLCompileMacro_USE_SHADOWING //, { @@ -2289,11 +2300,11 @@ class GLShader_forwardLighting_projXYZ : public u_VertexInterpolation, public u_ParallaxDepthScale, public u_ParallaxOffsetBias, - public u_HeightMapInNormalMap, public u_NormalScale, public GLDeformStage, public GLCompileMacro_USE_VERTEX_SKINNING, public GLCompileMacro_USE_VERTEX_ANIMATION, + public GLCompileMacro_USE_HEIGHTMAP_IN_NORMALMAP, public GLCompileMacro_USE_PARALLAX_MAPPING, public GLCompileMacro_USE_SHADOWING //, { @@ -2330,11 +2341,11 @@ class GLShader_forwardLighting_directionalSun : public u_VertexInterpolation, public u_ParallaxDepthScale, public u_ParallaxOffsetBias, - public u_HeightMapInNormalMap, public u_NormalScale, public GLDeformStage, public GLCompileMacro_USE_VERTEX_SKINNING, public GLCompileMacro_USE_VERTEX_ANIMATION, + public GLCompileMacro_USE_HEIGHTMAP_IN_NORMALMAP, public GLCompileMacro_USE_PARALLAX_MAPPING, public GLCompileMacro_USE_SHADOWING //, { @@ -2378,12 +2389,12 @@ class GLShader_reflection : public u_Bones, public u_ParallaxDepthScale, public u_ParallaxOffsetBias, - public u_HeightMapInNormalMap, public u_NormalScale, public u_VertexInterpolation, public GLDeformStage, public GLCompileMacro_USE_VERTEX_SKINNING, public GLCompileMacro_USE_VERTEX_ANIMATION, + public GLCompileMacro_USE_HEIGHTMAP_IN_NORMALMAP, public GLCompileMacro_USE_PARALLAX_MAPPING { public: @@ -2584,13 +2595,13 @@ class GLShader_liquid : public u_FresnelBias, public u_ParallaxDepthScale, public u_ParallaxOffsetBias, - public u_HeightMapInNormalMap, public u_NormalScale, public u_FogDensity, public u_FogColor, public u_SpecularExponent, public u_LightGridOrigin, public u_LightGridScale, + public GLCompileMacro_USE_HEIGHTMAP_IN_NORMALMAP, public GLCompileMacro_USE_PARALLAX_MAPPING { public: diff --git a/src/engine/renderer/glsl_source/reliefMapping_fp.glsl b/src/engine/renderer/glsl_source/reliefMapping_fp.glsl index 64950ee3d4..7bab1122f1 100644 --- a/src/engine/renderer/glsl_source/reliefMapping_fp.glsl +++ b/src/engine/renderer/glsl_source/reliefMapping_fp.glsl @@ -21,16 +21,13 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ // reliefMapping_fp.glsl - Relief mapping helper functions -#if defined(r_normalMapping) || defined(USE_PARALLAX_MAPPING) -uniform sampler2D u_NormalMap; -uniform int u_HeightMapInNormalMap; -#endif // r_normalMapping || USE_PARALLAX_MAPPING - #if defined(r_normalMapping) -uniform vec3 u_NormalScale; +uniform sampler2D u_NormalMap; +uniform vec3 u_NormalScale; #endif // r_normalMapping #if defined(USE_PARALLAX_MAPPING) +uniform sampler2D u_HeightMap; uniform float u_ParallaxDepthScale; uniform float u_ParallaxOffsetBias; #endif // USE_PARALLAX_MAPPING @@ -41,27 +38,24 @@ vec3 NormalInTangentSpace(vec2 texNormal) vec3 normal; #if defined(r_normalMapping) - if (u_HeightMapInNormalMap == 0) - { - // the Capcom trick abusing alpha channel of DXT1/5 formats to encode normal map - // https://github.com/DaemonEngine/Daemon/issues/183#issuecomment-473691252 - // - // the algorithm also works with normal maps in rgb format without alpha channel - // but we still must be sure there is no height map in alpha channel hence the test - // - // crunch -dxn seems to produce such files, since alpha channel is abused such format - // is unsuitable to embed height map, then height map must be distributed as loose file - normal = texture2D(u_NormalMap, texNormal).rga; - normal.x *= normal.z; - normal.xy = 2.0 * normal.xy - 1.0; - normal.z = sqrt(1.0 - dot(normal.xy, normal.xy)); - } - else - { - // alpha channel contains the height map so do not try to restore the normal map from it - normal = texture2D(u_NormalMap, texNormal).rgb; - normal = 2.0 * normal - 1.0; - } +#if defined(USE_HEIGHTMAP_IN_NORMALMAP) + // alpha channel contains the height map so do not try to reconstruct normal map from it + normal = texture2D(u_NormalMap, texNormal).rgb; + normal = 2.0 * normal - 1.0; +#else // !USE_HEIGHTMAP_IN_NORMALMAP + // the Capcom trick abusing alpha channel of DXT1/5 formats to encode normal map + // https://github.com/DaemonEngine/Daemon/issues/183#issuecomment-473691252 + // + // the algorithm also works with normal maps in rgb format without alpha channel + // but we still must be sure there is no height map in alpha channel hence the test + // + // crunch -dxn seems to produce such files, since alpha channel is abused such format + // is unsuitable to embed height map, then height map must be distributed as loose file + normal = texture2D(u_NormalMap, texNormal).rga; + normal.x *= normal.z; + normal.xy = 2.0 * normal.xy - 1.0; + normal.z = sqrt(1.0 - dot(normal.xy, normal.xy)); +#endif // !USE_HEIGHTMAP_IN_NORMALMAP // HACK: 0 normal Z channel can't be good if (u_NormalScale.z != 0) @@ -116,7 +110,13 @@ vec2 ParallaxTexOffset(vec2 rayStartTexCoords, vec3 viewDir, mat3 tangentToWorld { currentDepth += currentSize; - float heightMapDepth = topDepth - texture2D(u_NormalMap, rayStartTexCoords + displacement * currentDepth).a; +#if defined(USE_HEIGHTMAP_IN_NORMALMAP) + float depth = texture2D(u_HeightMap, rayStartTexCoords + displacement * currentDepth).a; +#else // !USE_HEIGHTMAP_IN_NORMALMAP + float depth = texture2D(u_HeightMap, rayStartTexCoords + displacement * currentDepth).g; +#endif // !USE_HEIGHTMAP_IN_NORMALMAP + + float heightMapDepth = topDepth - depth; if(bestDepth > 0.996) // if no depth found yet { @@ -134,7 +134,13 @@ vec2 ParallaxTexOffset(vec2 rayStartTexCoords, vec3 viewDir, mat3 tangentToWorld { currentSize *= 0.5; - float heightMapDepth = topDepth - texture2D(u_NormalMap, rayStartTexCoords + displacement * currentDepth).a; +#if defined(USE_HEIGHTMAP_IN_NORMALMAP) + float depth = texture2D(u_HeightMap, rayStartTexCoords + displacement * currentDepth).a; +#else // !USE_HEIGHTMAP_IN_NORMALMAP + float depth = texture2D(u_HeightMap, rayStartTexCoords + displacement * currentDepth).g; +#endif // !USE_HEIGHTMAP_IN_NORMALMAP + + float heightMapDepth = topDepth - depth; if(currentDepth >= heightMapDepth) { diff --git a/src/engine/renderer/tr_image.cpp b/src/engine/renderer/tr_image.cpp index 67e238cccb..47d8281f62 100644 --- a/src/engine/renderer/tr_image.cpp +++ b/src/engine/renderer/tr_image.cpp @@ -1346,7 +1346,7 @@ void R_UploadImage( const byte **dataArray, int numLayers, int numMips, case GL_RGBA32UI: case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT: case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT: - image->bits |= IF_DISPLACEMAP; + image->bits |= IF_HEIGHTMAP; } } diff --git a/src/engine/renderer/tr_local.h b/src/engine/renderer/tr_local.h index 0f86265bcb..b1ff2ca605 100644 --- a/src/engine/renderer/tr_local.h +++ b/src/engine/renderer/tr_local.h @@ -527,7 +527,7 @@ static inline void halfToFloat( const f16vec4_t in, vec4_t out ) IF_RGBA16 = BIT( 14 ), IF_RGBE = BIT( 15 ), IF_ALPHATEST = BIT( 16 ), - IF_DISPLACEMAP = BIT( 17 ), + IF_HEIGHTMAP = BIT( 17 ), IF_NOLIGHTSCALE = BIT( 18 ), IF_BC1 = BIT( 19 ), IF_BC2 = BIT( 20 ), @@ -1006,6 +1006,7 @@ static inline void halfToFloat( const f16vec4_t in, vec4_t out ) TB_DIFFUSEMAP = TB_COLORMAP, TB_REFLECTIONMAP = TB_COLORMAP, TB_NORMALMAP, + TB_HEIGHTMAP, TB_MATERIALMAP, TB_PHYSICALMAP = TB_MATERIALMAP, TB_SPECULARMAP = TB_MATERIALMAP, @@ -1033,6 +1034,7 @@ static inline void halfToFloat( const f16vec4_t in, vec4_t out ) ST_GLOWMAP, ST_DIFFUSEMAP, ST_NORMALMAP, + ST_HEIGHTMAP, ST_PHYSICALMAP, ST_SPECULARMAP, ST_REFLECTIONMAP, // cubeMap based reflection diff --git a/src/engine/renderer/tr_shade.cpp b/src/engine/renderer/tr_shade.cpp index d020deea91..1971d780fd 100644 --- a/src/engine/renderer/tr_shade.cpp +++ b/src/engine/renderer/tr_shade.cpp @@ -745,6 +745,7 @@ static void Render_vertexLighting_DBS_entity( int stage ) GL_State( stateBits ); bool hasNormalMap = pStage->bundle[ TB_NORMALMAP ].image[ 0 ] != nullptr; + bool hasHeightMap = pStage->bundle[ TB_HEIGHTMAP ].image[ 0 ] != nullptr; bool hasMaterialMap = pStage->bundle[ TB_MATERIALMAP ].image[ 0 ] != nullptr; bool hasGlowMap = pStage->bundle[ TB_GLOWMAP ].image[ 0 ] != nullptr; @@ -752,7 +753,7 @@ static void Render_vertexLighting_DBS_entity( int stage ) bool isMaterialPhysical = pStage->collapseType == collapseType_t::COLLAPSE_lighting_PBR; bool normalMapping = r_normalMapping->integer && hasNormalMap; - bool parallaxMapping = r_parallaxMapping->integer && !tess.surfaceShader->noParallax && hasHeightMapInNormalMap; + bool parallaxMapping = r_parallaxMapping->integer && !tess.surfaceShader->noParallax && ( hasHeightMap || hasHeightMapInNormalMap ); bool physicalMapping = r_physicalMapping->integer && hasMaterialMap && isMaterialPhysical; bool specularMapping = r_specularMapping->integer && hasMaterialMap && !isMaterialPhysical; bool glowMapping = r_glowMapping->integer && hasGlowMap; @@ -765,6 +766,8 @@ static void Render_vertexLighting_DBS_entity( int stage ) GL_BindToTMU( 8, tr.lighttileRenderImage ); + gl_vertexLightingShader_DBS_entity->SetHeightMapInNormalMap( hasHeightMapInNormalMap ); + gl_vertexLightingShader_DBS_entity->SetParallaxMapping( parallaxMapping ); gl_vertexLightingShader_DBS_entity->SetReflectiveSpecular( normalMapping && tr.cubeHashTable != nullptr ); @@ -816,6 +819,7 @@ static void Render_vertexLighting_DBS_entity( int stage ) // u_DeformGen gl_vertexLightingShader_DBS_entity->SetUniform_Time( backEnd.refdef.floatTime - backEnd.currentEntity->e.shaderTime ); + // bind u_HeightMap if ( parallaxMapping ) { float depthScale; @@ -826,14 +830,23 @@ static void Render_vertexLighting_DBS_entity( int stage ) depthScale *= parallaxDepthScale == 0 ? 1 : parallaxDepthScale; gl_vertexLightingShader_DBS_entity->SetUniform_ParallaxDepthScale( depthScale ); gl_vertexLightingShader_DBS_entity->SetUniform_ParallaxOffsetBias( tess.surfaceShader->parallaxOffsetBias ); - gl_vertexLightingShader_DBS_entity->SetUniform_HeightMapInNormalMap( hasHeightMapInNormalMap ); + + // FIXME: if there is both, embedded heightmap in normalmap is used instead of standalone heightmap + if ( hasHeightMapInNormalMap ) + { + GL_BindToTMU( 15, pStage->bundle[ TB_NORMALMAP ].image[ 0 ] ); + } + else + { + GL_BindToTMU( 15, pStage->bundle[ TB_HEIGHTMAP ].image[ 0 ] ); + } } // bind u_DiffuseMap GL_BindToTMU( 0, pStage->bundle[ TB_DIFFUSEMAP ].image[ 0 ] ); gl_vertexLightingShader_DBS_entity->SetUniform_TextureMatrix( tess.svars.texMatrices[ TB_DIFFUSEMAP ] ); - if ( normalMapping || hasHeightMapInNormalMap ) + if ( normalMapping ) { // bind u_NormalMap GL_BindToTMU( 1, pStage->bundle[ TB_NORMALMAP ].image[ 0 ] ); @@ -983,6 +996,7 @@ static void Render_vertexLighting_DBS_world( int stage ) stateBits = pStage->stateBits; bool hasNormalMap = pStage->bundle[ TB_NORMALMAP ].image[ 0 ] != nullptr; + bool hasHeightMap = pStage->bundle[ TB_HEIGHTMAP ].image[ 0 ] != nullptr; bool hasMaterialMap = pStage->bundle[ TB_MATERIALMAP ].image[ 0 ] != nullptr; bool hasGlowMap = pStage->bundle[ TB_GLOWMAP ].image[ 0 ] != nullptr; @@ -990,7 +1004,7 @@ static void Render_vertexLighting_DBS_world( int stage ) bool isMaterialPhysical = pStage->collapseType == collapseType_t::COLLAPSE_lighting_PBR; bool normalMapping = r_normalMapping->integer && hasNormalMap; - bool parallaxMapping = r_parallaxMapping->integer && !tess.surfaceShader->noParallax && hasHeightMapInNormalMap; + bool parallaxMapping = r_parallaxMapping->integer && !tess.surfaceShader->noParallax && ( hasHeightMap || hasHeightMapInNormalMap ); bool physicalMapping = r_physicalMapping->integer && hasMaterialMap && isMaterialPhysical; bool specularMapping = r_specularMapping->integer && hasMaterialMap && !isMaterialPhysical; bool glowMapping = r_glowMapping->integer && hasGlowMap; @@ -998,6 +1012,8 @@ static void Render_vertexLighting_DBS_world( int stage ) // choose right shader program ---------------------------------- GL_BindToTMU( 8, tr.lighttileRenderImage ); + gl_vertexLightingShader_DBS_world->SetHeightMapInNormalMap( hasHeightMapInNormalMap ); + gl_vertexLightingShader_DBS_world->SetParallaxMapping( parallaxMapping ); tess.vboVertexSprite = false; @@ -1068,6 +1084,8 @@ static void Render_vertexLighting_DBS_world( int stage ) gl_vertexLightingShader_DBS_world->SetUniform_ModelViewProjectionMatrix( glState.modelViewProjectionMatrix[ glState.stackIndex ] ); gl_vertexLightingShader_DBS_world->SetUniform_AlphaTest( pStage->stateBits ); + + // bind u_HeightMap if ( parallaxMapping ) { float depthScale; @@ -1078,7 +1096,16 @@ static void Render_vertexLighting_DBS_world( int stage ) depthScale *= parallaxDepthScale == 0 ? 1 : parallaxDepthScale; gl_vertexLightingShader_DBS_world->SetUniform_ParallaxDepthScale( depthScale ); gl_vertexLightingShader_DBS_world->SetUniform_ParallaxOffsetBias( tess.surfaceShader->parallaxOffsetBias ); - gl_vertexLightingShader_DBS_world->SetUniform_HeightMapInNormalMap( hasHeightMapInNormalMap ); + + // FIXME: if there is both, embedded heightmap in normalmap is used instead of standalone heightmap + if ( hasHeightMapInNormalMap ) + { + GL_BindToTMU( 15, pStage->bundle[ TB_NORMALMAP ].image[ 0 ] ); + } + else + { + GL_BindToTMU( 15, pStage->bundle[ TB_HEIGHTMAP ].image[ 0 ] ); + } } if( tr.world ) { @@ -1090,7 +1117,7 @@ static void Render_vertexLighting_DBS_world( int stage ) GL_BindToTMU( 0, pStage->bundle[ TB_DIFFUSEMAP ].image[ 0 ] ); gl_vertexLightingShader_DBS_world->SetUniform_TextureMatrix( tess.svars.texMatrices[ TB_DIFFUSEMAP ] ); - if ( normalMapping || hasHeightMapInNormalMap ) + if ( normalMapping ) { // bind u_NormalMap GL_BindToTMU( 1, pStage->bundle[ TB_NORMALMAP ].image[ 0 ] ); @@ -1188,6 +1215,7 @@ static void Render_lightMapping( int stage ) GL_State( stateBits ); bool hasNormalMap = pStage->bundle[ TB_NORMALMAP ].image[ 0 ] != nullptr; + bool hasHeightMap = pStage->bundle[ TB_HEIGHTMAP ].image[ 0 ] != nullptr; bool hasMaterialMap = pStage->bundle[ TB_MATERIALMAP ].image[ 0 ] != nullptr; bool hasGlowMap = pStage->bundle[ TB_GLOWMAP ].image[ 0 ] != nullptr; @@ -1196,7 +1224,7 @@ static void Render_lightMapping( int stage ) bool normalMapping = r_normalMapping->integer && hasNormalMap; bool deluxeMapping = r_deluxeMapping->integer && tr.worldDeluxeMapping && normalMapping; - bool parallaxMapping = r_parallaxMapping->integer && !tess.surfaceShader->noParallax && hasHeightMapInNormalMap; + bool parallaxMapping = r_parallaxMapping->integer && !tess.surfaceShader->noParallax && ( hasHeightMap || hasHeightMapInNormalMap ); bool physicalMapping = r_physicalMapping->integer && hasMaterialMap && isMaterialPhysical; bool specularMapping = r_specularMapping->integer && hasMaterialMap && !isMaterialPhysical; bool glowMapping = r_glowMapping->integer && hasGlowMap; @@ -1210,6 +1238,8 @@ static void Render_lightMapping( int stage ) gl_lightMappingShader->SetDeluxeMapping( deluxeMapping ); + gl_lightMappingShader->SetHeightMapInNormalMap( hasHeightMapInNormalMap ); + gl_lightMappingShader->SetParallaxMapping( parallaxMapping ); tess.vboVertexSprite = false; @@ -1246,6 +1276,7 @@ static void Render_lightMapping( int stage ) // u_Color gl_lightMappingShader->SetUniform_Color( tess.svars.color ); + // bind u_HeightMap if ( parallaxMapping ) { float depthScale; @@ -1256,7 +1287,16 @@ static void Render_lightMapping( int stage ) depthScale *= parallaxDepthScale == 0 ? 1 : parallaxDepthScale; gl_lightMappingShader->SetUniform_ParallaxDepthScale( depthScale ); gl_lightMappingShader->SetUniform_ParallaxOffsetBias( tess.surfaceShader->parallaxOffsetBias ); - gl_lightMappingShader->SetUniform_HeightMapInNormalMap( hasHeightMapInNormalMap ); + + // FIXME: if there is both, embedded heightmap in normalmap is used instead of standalone heightmap + if ( hasHeightMapInNormalMap ) + { + GL_BindToTMU( 15, pStage->bundle[ TB_NORMALMAP ].image[ 0 ] ); + } + else + { + GL_BindToTMU( 15, pStage->bundle[ TB_HEIGHTMAP ].image[ 0 ] ); + } } // bind u_DiffuseMap @@ -1272,7 +1312,7 @@ static void Render_lightMapping( int stage ) } // bind u_NormalMap - if ( normalMapping || hasHeightMapInNormalMap ) + if ( normalMapping ) { GL_BindToTMU( 1, pStage->bundle[ TB_NORMALMAP ].image[ 0 ] ); @@ -1496,13 +1536,14 @@ static void Render_forwardLighting_DBS_omni( shaderStage_t *pStage, GLimp_LogComment( "--- Render_forwardLighting_DBS_omni ---\n" ); bool hasNormalMap = pStage->bundle[ TB_NORMALMAP ].image[ 0 ] != nullptr; + bool hasHeightMap = pStage->bundle[ TB_HEIGHTMAP ].image[ 0 ] != nullptr; bool hasMaterialMap = pStage->bundle[ TB_MATERIALMAP ].image[ 0 ] != nullptr; bool hasHeightMapInNormalMap = pStage->heightMapInNormalMap && hasNormalMap; bool isMaterialPhysical = pStage->collapseType == collapseType_t::COLLAPSE_lighting_PBR; bool normalMapping = r_normalMapping->integer && hasNormalMap; - bool parallaxMapping = r_parallaxMapping->integer && !tess.surfaceShader->noParallax && hasHeightMapInNormalMap; + bool parallaxMapping = r_parallaxMapping->integer && !tess.surfaceShader->noParallax && ( hasHeightMap || hasHeightMapInNormalMap ); // physical mapping is not implemented bool specularMapping = r_specularMapping->integer && hasMaterialMap && !isMaterialPhysical; // glow mapping is not implemented @@ -1513,6 +1554,8 @@ static void Render_forwardLighting_DBS_omni( shaderStage_t *pStage, gl_forwardLightingShader_omniXYZ->SetVertexSkinning( glConfig2.vboVertexSkinningAvailable && tess.vboVertexSkinning ); gl_forwardLightingShader_omniXYZ->SetVertexAnimation( glState.vertexAttribsInterpolation > 0 ); + gl_forwardLightingShader_omniXYZ->SetHeightMapInNormalMap( hasHeightMapInNormalMap ); + gl_forwardLightingShader_omniXYZ->SetParallaxMapping( parallaxMapping ); gl_forwardLightingShader_omniXYZ->SetShadowing( shadowCompare ); @@ -1555,6 +1598,7 @@ static void Render_forwardLighting_DBS_omni( shaderStage_t *pStage, gl_forwardLightingShader_omniXYZ->SetUniform_AlphaTest( pStage->stateBits ); + // bind u_HeightMap if ( parallaxMapping ) { float depthScale; @@ -1565,7 +1609,16 @@ static void Render_forwardLighting_DBS_omni( shaderStage_t *pStage, depthScale *= parallaxDepthScale == 0 ? 1 : parallaxDepthScale; gl_forwardLightingShader_omniXYZ->SetUniform_ParallaxDepthScale( depthScale ); gl_forwardLightingShader_omniXYZ->SetUniform_ParallaxOffsetBias( tess.surfaceShader->parallaxOffsetBias ); - gl_forwardLightingShader_omniXYZ->SetUniform_HeightMapInNormalMap( hasHeightMapInNormalMap ); + + // FIXME: if there is both, embedded heightmap in normalmap is used instead of standalone heightmap + if ( hasHeightMapInNormalMap ) + { + GL_BindToTMU( 15, pStage->bundle[ TB_NORMALMAP ].image[ 0 ] ); + } + else + { + GL_BindToTMU( 15, pStage->bundle[ TB_HEIGHTMAP ].image[ 0 ] ); + } } // set uniforms @@ -1624,7 +1677,7 @@ static void Render_forwardLighting_DBS_omni( shaderStage_t *pStage, GL_BindToTMU( 0, pStage->bundle[ TB_DIFFUSEMAP ].image[ 0 ] ); gl_forwardLightingShader_omniXYZ->SetUniform_TextureMatrix( tess.svars.texMatrices[ TB_DIFFUSEMAP ] ); - if ( normalMapping || hasHeightMapInNormalMap ) + if ( normalMapping ) { // bind u_NormalMap GL_BindToTMU( 1, pStage->bundle[ TB_NORMALMAP ].image[ 0 ] ); @@ -1694,13 +1747,14 @@ static void Render_forwardLighting_DBS_proj( shaderStage_t *pStage, GLimp_LogComment( "--- Render_forwardLighting_DBS_proj ---\n" ); bool hasNormalMap = pStage->bundle[ TB_NORMALMAP ].image[ 0 ] != nullptr; + bool hasHeightMap = pStage->bundle[ TB_HEIGHTMAP ].image[ 0 ] != nullptr; bool hasMaterialMap = pStage->bundle[ TB_MATERIALMAP ].image[ 0 ] != nullptr; bool hasHeightMapInNormalMap = pStage->heightMapInNormalMap && hasNormalMap; bool isMaterialPhysical = pStage->collapseType == collapseType_t::COLLAPSE_lighting_PBR; bool normalMapping = r_normalMapping->integer && hasNormalMap; - bool parallaxMapping = r_parallaxMapping->integer && !tess.surfaceShader->noParallax && hasHeightMapInNormalMap; + bool parallaxMapping = r_parallaxMapping->integer && !tess.surfaceShader->noParallax && ( hasHeightMap || hasHeightMapInNormalMap ); // physical mapping is not implemented bool specularMapping = r_specularMapping->integer && hasMaterialMap && !isMaterialPhysical; @@ -1710,6 +1764,8 @@ static void Render_forwardLighting_DBS_proj( shaderStage_t *pStage, gl_forwardLightingShader_projXYZ->SetVertexSkinning( glConfig2.vboVertexSkinningAvailable && tess.vboVertexSkinning ); gl_forwardLightingShader_projXYZ->SetVertexAnimation( glState.vertexAttribsInterpolation > 0 ); + gl_forwardLightingShader_projXYZ->SetHeightMapInNormalMap( hasHeightMapInNormalMap ); + gl_forwardLightingShader_projXYZ->SetParallaxMapping( parallaxMapping ); gl_forwardLightingShader_projXYZ->SetShadowing( shadowCompare ); @@ -1752,6 +1808,7 @@ static void Render_forwardLighting_DBS_proj( shaderStage_t *pStage, gl_forwardLightingShader_projXYZ->SetUniform_AlphaTest( pStage->stateBits ); + // bind u_HeightMap if ( parallaxMapping ) { float depthScale; @@ -1762,7 +1819,16 @@ static void Render_forwardLighting_DBS_proj( shaderStage_t *pStage, depthScale *= parallaxDepthScale == 0 ? 1 : parallaxDepthScale; gl_forwardLightingShader_projXYZ->SetUniform_ParallaxDepthScale( depthScale ); gl_forwardLightingShader_projXYZ->SetUniform_ParallaxOffsetBias( tess.surfaceShader->parallaxOffsetBias ); - gl_forwardLightingShader_projXYZ->SetUniform_HeightMapInNormalMap( hasHeightMapInNormalMap ); + + // FIXME: if there is both, embedded heightmap in normalmap is used instead of standalone heightmap + if ( hasHeightMapInNormalMap ) + { + GL_BindToTMU( 15, pStage->bundle[ TB_NORMALMAP ].image[ 0 ] ); + } + else + { + GL_BindToTMU( 15, pStage->bundle[ TB_HEIGHTMAP ].image[ 0 ] ); + } } // set uniforms @@ -1822,7 +1888,7 @@ static void Render_forwardLighting_DBS_proj( shaderStage_t *pStage, GL_BindToTMU( 0, pStage->bundle[ TB_DIFFUSEMAP ].image[ 0 ] ); gl_forwardLightingShader_projXYZ->SetUniform_TextureMatrix( tess.svars.texMatrices[ TB_DIFFUSEMAP ] ); - if ( normalMapping || hasHeightMapInNormalMap ) + if ( normalMapping ) { // bind u_NormalMap GL_BindToTMU( 1, pStage->bundle[ TB_NORMALMAP ].image[ 0 ] ); @@ -1890,13 +1956,14 @@ static void Render_forwardLighting_DBS_directional( shaderStage_t *pStage, trRef GLimp_LogComment( "--- Render_forwardLighting_DBS_directional ---\n" ); bool hasNormalMap = pStage->bundle[ TB_NORMALMAP ].image[ 0 ] != nullptr; + bool hasHeightMap = pStage->bundle[ TB_HEIGHTMAP ].image[ 0 ] != nullptr; bool hasMaterialMap = pStage->bundle[ TB_MATERIALMAP ].image[ 0 ] != nullptr; bool hasHeightMapInNormalMap = pStage->heightMapInNormalMap && hasNormalMap; bool isMaterialPhysical = pStage->collapseType == collapseType_t::COLLAPSE_lighting_PBR; bool normalMapping = r_normalMapping->integer && hasNormalMap; - bool parallaxMapping = r_parallaxMapping->integer && !tess.surfaceShader->noParallax && hasHeightMapInNormalMap; + bool parallaxMapping = r_parallaxMapping->integer && !tess.surfaceShader->noParallax && ( hasHeightMap || hasHeightMapInNormalMap ); // physical mapping is not implemented bool specularMapping = r_specularMapping->integer && hasMaterialMap && !isMaterialPhysical; @@ -1906,6 +1973,8 @@ static void Render_forwardLighting_DBS_directional( shaderStage_t *pStage, trRef gl_forwardLightingShader_directionalSun->SetVertexSkinning( glConfig2.vboVertexSkinningAvailable && tess.vboVertexSkinning ); gl_forwardLightingShader_directionalSun->SetVertexAnimation( glState.vertexAttribsInterpolation > 0 ); + gl_forwardLightingShader_directionalSun->SetHeightMapInNormalMap( hasHeightMapInNormalMap ); + gl_forwardLightingShader_directionalSun->SetParallaxMapping( parallaxMapping ); gl_forwardLightingShader_directionalSun->SetShadowing( shadowCompare ); @@ -1948,6 +2017,7 @@ static void Render_forwardLighting_DBS_directional( shaderStage_t *pStage, trRef gl_forwardLightingShader_directionalSun->SetUniform_AlphaTest( pStage->stateBits ); + // bind u_HeightMap if ( parallaxMapping ) { float depthScale; @@ -1958,7 +2028,16 @@ static void Render_forwardLighting_DBS_directional( shaderStage_t *pStage, trRef depthScale *= parallaxDepthScale == 0 ? 1 : parallaxDepthScale; gl_forwardLightingShader_directionalSun->SetUniform_ParallaxDepthScale( depthScale ); gl_forwardLightingShader_directionalSun->SetUniform_ParallaxOffsetBias( tess.surfaceShader->parallaxOffsetBias ); - gl_forwardLightingShader_directionalSun->SetUniform_HeightMapInNormalMap( hasHeightMapInNormalMap ); + + // FIXME: if there is both, embedded heightmap in normalmap is used instead of standalone heightmap + if ( hasHeightMapInNormalMap ) + { + GL_BindToTMU( 15, pStage->bundle[ TB_NORMALMAP ].image[ 0 ] ); + } + else + { + GL_BindToTMU( 15, pStage->bundle[ TB_HEIGHTMAP ].image[ 0 ] ); + } } // set uniforms @@ -2022,7 +2101,7 @@ static void Render_forwardLighting_DBS_directional( shaderStage_t *pStage, trRef GL_BindToTMU( 0, pStage->bundle[ TB_DIFFUSEMAP ].image[ 0 ] ); gl_forwardLightingShader_directionalSun->SetUniform_TextureMatrix( tess.svars.texMatrices[ TB_DIFFUSEMAP ] ); - if ( normalMapping || hasHeightMapInNormalMap ) + if ( normalMapping ) { // bind u_NormalMap GL_BindToTMU( 1, pStage->bundle[ TB_NORMALMAP ].image[ 0 ] ); @@ -2100,13 +2179,16 @@ static void Render_reflection_CB( int stage ) GL_State( pStage->stateBits ); bool hasNormalMap = pStage->bundle[ TB_NORMALMAP ].image[ 0 ] != nullptr; + bool hasHeightMap = pStage->bundle[ TB_HEIGHTMAP ].image[ 0 ] != nullptr; bool hasHeightMapInNormalMap = pStage->heightMapInNormalMap && hasNormalMap; bool normalMapping = r_normalMapping->integer && hasNormalMap; - bool parallaxMapping = r_parallaxMapping->integer && !tess.surfaceShader->noParallax && hasHeightMapInNormalMap; + bool parallaxMapping = r_parallaxMapping->integer && !tess.surfaceShader->noParallax && ( hasHeightMap || hasHeightMapInNormalMap ); // choose right shader program ---------------------------------- + gl_reflectionShader->SetHeightMapInNormalMap( hasHeightMapInNormalMap ); + gl_reflectionShader->SetParallaxMapping( parallaxMapping ); gl_reflectionShader->SetVertexSkinning( glConfig2.vboVertexSkinningAvailable && tess.vboVertexSkinning ); @@ -2144,7 +2226,7 @@ static void Render_reflection_CB( int stage ) GL_BindNearestCubeMap( backEnd.viewParms.orientation.origin ); } - if ( normalMapping || hasHeightMapInNormalMap ) + if ( normalMapping ) { // bind u_NormalMap GL_BindToTMU( 1, pStage->bundle[ TB_NORMALMAP ].image[ 0 ] ); @@ -2162,7 +2244,7 @@ static void Render_reflection_CB( int stage ) gl_reflectionShader->SetUniform_TextureMatrix( tess.svars.texMatrices[ TB_NORMALMAP ] ); - // bind u_depthScale u_parallaxOffsetBias + // bind u_HeightMap u_depthScale u_parallaxOffsetBias if ( parallaxMapping ) { float depthScale; @@ -2173,7 +2255,16 @@ static void Render_reflection_CB( int stage ) depthScale *= parallaxDepthScale == 0 ? 1 : parallaxDepthScale; gl_reflectionShader->SetUniform_ParallaxDepthScale( depthScale ); gl_reflectionShader->SetUniform_ParallaxOffsetBias( tess.surfaceShader->parallaxOffsetBias ); - gl_reflectionShader->SetUniform_HeightMapInNormalMap( hasHeightMapInNormalMap ); + + // FIXME: if there is both, embedded heightmap in normalmap is used instead of standalone heightmap + if ( hasHeightMapInNormalMap ) + { + GL_BindToTMU( 15, pStage->bundle[ TB_NORMALMAP ].image[ 0 ] ); + } + else + { + GL_BindToTMU( 15, pStage->bundle[ TB_HEIGHTMAP ].image[ 0 ] ); + } } vec3_t normalScale; @@ -2386,11 +2477,12 @@ static void Render_liquid( int stage ) GLimp_LogComment( "--- Render_liquid ---\n" ); bool hasNormalMap = pStage->bundle[ TB_COLORMAP ].image[ 0 ] != nullptr; + bool hasHeightMap = pStage->bundle[ TB_HEIGHTMAP ].image[ 0 ] != nullptr; bool hasHeightMapInNormalMap = pStage->heightMapInNormalMap && hasNormalMap; bool normalMapping = r_normalMapping->integer && hasNormalMap; - bool parallaxMapping = r_parallaxMapping->integer && !tess.surfaceShader->noParallax && hasHeightMapInNormalMap; + bool parallaxMapping = r_parallaxMapping->integer && !tess.surfaceShader->noParallax && ( hasHeightMap || hasHeightMapInNormalMap ); // specular component is computed by shader // physical mapping is not implemented bool specularMapping = r_specularMapping->integer; @@ -2399,6 +2491,8 @@ static void Render_liquid( int stage ) GL_State( pStage->stateBits & ~( GLS_SRCBLEND_BITS | GLS_DSTBLEND_BITS | GLS_DEPTHMASK_TRUE ) ); // choose right shader program + gl_liquidShader->SetHeightMapInNormalMap( hasHeightMapInNormalMap ); + gl_liquidShader->SetParallaxMapping( parallaxMapping ); // enable shader, set arrays @@ -2441,7 +2535,30 @@ static void Render_liquid( int stage ) // depth texture GL_BindToTMU( 2, tr.currentDepthImage ); - if ( normalMapping || hasHeightMapInNormalMap ) + // bind u_HeightMap u_depthScale u_parallaxOffsetBias + if ( parallaxMapping ) + { + float depthScale; + float parallaxDepthScale; + + depthScale = RB_EvalExpression( &pStage->depthScaleExp, r_parallaxDepthScale->value ); + parallaxDepthScale = tess.surfaceShader->parallaxDepthScale; + depthScale *= parallaxDepthScale == 0 ? 1 : parallaxDepthScale; + gl_liquidShader->SetUniform_ParallaxDepthScale( depthScale ); + gl_liquidShader->SetUniform_ParallaxOffsetBias( tess.surfaceShader->parallaxOffsetBias ); + + // FIXME: if there is both, embedded heightmap in normalmap is used instead of standalone heightmap + if ( hasHeightMapInNormalMap ) + { + GL_BindToTMU( 15, pStage->bundle[ TB_COLORMAP ].image[ 0 ] ); + } + else + { + GL_BindToTMU( 15, pStage->bundle[ TB_HEIGHTMAP ].image[ 0 ] ); + } + } + + if ( normalMapping ) { // bind u_NormalMap GL_BindToTMU( 3, pStage->bundle[ TB_COLORMAP ].image[ 0 ] ); diff --git a/src/engine/renderer/tr_shader.cpp b/src/engine/renderer/tr_shader.cpp index 48f72865d1..c9182d71aa 100644 --- a/src/engine/renderer/tr_shader.cpp +++ b/src/engine/renderer/tr_shader.cpp @@ -1464,7 +1464,7 @@ static bool LoadMap( shaderStage_t *stage, const char *buffer, const int bundleI // tell renderer to enable parallax mapping since an heightmap is found // also tell renderer to not abuse normalmap alpha channel because it's an heightmap // https://github.com/DaemonEngine/Daemon/issues/183#issuecomment-473691252 - if ( stage->bundle[ bundleIndex ].image[ 0 ]->bits & IF_DISPLACEMAP ) + if ( stage->bundle[ bundleIndex ].image[ 0 ]->bits & IF_HEIGHTMAP ) { if ( stage->bundle[ bundleIndex ].image[ 0 ]->bits & IF_NORMALMAP ) { @@ -1635,6 +1635,21 @@ static void ParseNormalMap( shaderStage_t *stage, const char **text, const int b } } +static void ParseHeightMap( shaderStage_t *stage, const char **text, const int bundleIndex = TB_HEIGHTMAP ) +{ + char buffer[ 1024 ] = ""; + + stage->active = true; + stage->type = stageType_t::ST_HEIGHTMAP; + stage->rgbGen = colorGen_t::CGEN_IDENTITY; + stage->stateBits = GLS_DEFAULT; + + if ( ParseMap( text, buffer, sizeof( buffer ) ) ) + { + LoadMap( stage, buffer, bundleIndex ); + } +} + static void ParseSpecularMap( shaderStage_t *stage, const char **text, const int bundleIndex = TB_SPECULARMAP ) { char buffer[ 1024 ] = ""; @@ -1743,8 +1758,11 @@ struct extraMapParser_t static const extraMapParser_t extraMapParsers[] = { - // currently uses the collapse code path + // FIXME: dpMaterial Darkplaces compatibility layer still uses the collapse code path + // https://github.com/DaemonEngine/Daemon/pull/252#pullrequestreview-336919745 + { "norm", "normal map", ParseNormalMap, TB_COLORMAP, }, + { "bump", "height map", ParseHeightMap, TB_COLORMAP, }, { "gloss", "specular map", ParseSpecularMap, TB_COLORMAP, }, { "glow", "glow map", ParseGlowMap, TB_COLORMAP, }, { "luma", "glow map", ParseGlowMap, TB_COLORMAP, }, @@ -1827,6 +1845,15 @@ static bool ParseStage( shaderStage_t *stage, const char **text ) stage->heightMapInNormalMap = true; ParseNormalMap( stage, text ); } + else if ( !Q_stricmp( token, "heightMap" ) ) + { + if ( stage->collapseType == collapseType_t::COLLAPSE_none ) + { + stage->collapseType = collapseType_t::COLLAPSE_generic; + } + + ParseHeightMap( stage, text ); + } else if ( !Q_stricmp( token, "specularMap" ) ) { if ( stage->collapseType == collapseType_t::COLLAPSE_reflection_CB ) @@ -4350,8 +4377,16 @@ static void CollapseStages() return; } + // FIXME: heightStage is only used by dpMaterial Darkplaces compatibility layer + // that still uses to-be-collapsed standalone stages, + // this code will be dead when the dpMaterial feature + // will be ported to the pre-collapsed stage layout + // and this heightMap collapsing code would have to be deleted: + // https://github.com/DaemonEngine/Daemon/pull/252#pullrequestreview-336919745 + int diffuseStage = -1; int normalStage = -1; + int heightStage = -1; int specularStage = -1; int physicalStage = -1; int reflectionStage = -1; @@ -4402,6 +4437,17 @@ static void CollapseStages() normalStage = i; } } + else if ( stages[ i ].type == stageType_t::ST_HEIGHTMAP ) + { + if ( heightStage != -1 ) + { + Log::Warn( "more than one height map stage in shader '%s'", shader.name ); + } + else + { + heightStage = i; + } + } else if ( stages[ i ].type == stageType_t::ST_SPECULARMAP ) { if ( specularStage != -1 ) @@ -4492,6 +4538,7 @@ static void CollapseStages() if ( diffuseStage != -1 && ( specularStage != -1 || normalStage != -1 + || heightStage != -1 || physicalStage != -1 || lightStage != -1 || glowStage != -1 ) ) @@ -4533,6 +4580,14 @@ static void CollapseStages() stages[ normalStage ].active = false; } + if ( heightStage != -1 ) + { + // merge with diffuse stage + stages[ diffuseStage ].bundle[ TB_HEIGHTMAP ] = stages[ heightStage ].bundle[ TB_COLORMAP ]; + // disable since it's merged + stages[ heightStage ].active = false; + } + if ( specularStage != -1 ) { // merge with diffuse stage From f45f3ec7fe14e1a2a3e557faf9248f77086a1116 Mon Sep 17 00:00:00 2001 From: Thomas Debesse Date: Sat, 28 Dec 2019 23:06:33 +0100 Subject: [PATCH 2/2] renderer: do not bind normalmap with heightmap as heightmap --- .../glsl_source/reliefMapping_fp.glsl | 11 +- src/engine/renderer/tr_shade.cpp | 150 +++++++++--------- 2 files changed, 80 insertions(+), 81 deletions(-) diff --git a/src/engine/renderer/glsl_source/reliefMapping_fp.glsl b/src/engine/renderer/glsl_source/reliefMapping_fp.glsl index 7bab1122f1..a12e825890 100644 --- a/src/engine/renderer/glsl_source/reliefMapping_fp.glsl +++ b/src/engine/renderer/glsl_source/reliefMapping_fp.glsl @@ -21,13 +21,18 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ // reliefMapping_fp.glsl - Relief mapping helper functions -#if defined(r_normalMapping) +#if defined(r_normalMapping) || defined(USE_HEIGHTMAP_IN_NORMALMAP) uniform sampler2D u_NormalMap; +#endif // r_normalMapping || USE_HEIGHTMAP_IN_NORMALMAP + +#if defined(r_normalMapping) uniform vec3 u_NormalScale; #endif // r_normalMapping #if defined(USE_PARALLAX_MAPPING) +#if !defined(USE_HEIGHTMAP_IN_NORMALMAP) uniform sampler2D u_HeightMap; +#endif // !USE_HEIGHTMAP_IN_NORMALMAP uniform float u_ParallaxDepthScale; uniform float u_ParallaxOffsetBias; #endif // USE_PARALLAX_MAPPING @@ -111,7 +116,7 @@ vec2 ParallaxTexOffset(vec2 rayStartTexCoords, vec3 viewDir, mat3 tangentToWorld currentDepth += currentSize; #if defined(USE_HEIGHTMAP_IN_NORMALMAP) - float depth = texture2D(u_HeightMap, rayStartTexCoords + displacement * currentDepth).a; + float depth = texture2D(u_NormalMap, rayStartTexCoords + displacement * currentDepth).a; #else // !USE_HEIGHTMAP_IN_NORMALMAP float depth = texture2D(u_HeightMap, rayStartTexCoords + displacement * currentDepth).g; #endif // !USE_HEIGHTMAP_IN_NORMALMAP @@ -135,7 +140,7 @@ vec2 ParallaxTexOffset(vec2 rayStartTexCoords, vec3 viewDir, mat3 tangentToWorld currentSize *= 0.5; #if defined(USE_HEIGHTMAP_IN_NORMALMAP) - float depth = texture2D(u_HeightMap, rayStartTexCoords + displacement * currentDepth).a; + float depth = texture2D(u_NormalMap, rayStartTexCoords + displacement * currentDepth).a; #else // !USE_HEIGHTMAP_IN_NORMALMAP float depth = texture2D(u_HeightMap, rayStartTexCoords + displacement * currentDepth).g; #endif // !USE_HEIGHTMAP_IN_NORMALMAP diff --git a/src/engine/renderer/tr_shade.cpp b/src/engine/renderer/tr_shade.cpp index 1971d780fd..00f4370a9f 100644 --- a/src/engine/renderer/tr_shade.cpp +++ b/src/engine/renderer/tr_shade.cpp @@ -832,11 +832,7 @@ static void Render_vertexLighting_DBS_entity( int stage ) gl_vertexLightingShader_DBS_entity->SetUniform_ParallaxOffsetBias( tess.surfaceShader->parallaxOffsetBias ); // FIXME: if there is both, embedded heightmap in normalmap is used instead of standalone heightmap - if ( hasHeightMapInNormalMap ) - { - GL_BindToTMU( 15, pStage->bundle[ TB_NORMALMAP ].image[ 0 ] ); - } - else + if ( !hasHeightMapInNormalMap ) { GL_BindToTMU( 15, pStage->bundle[ TB_HEIGHTMAP ].image[ 0 ] ); } @@ -846,21 +842,24 @@ static void Render_vertexLighting_DBS_entity( int stage ) GL_BindToTMU( 0, pStage->bundle[ TB_DIFFUSEMAP ].image[ 0 ] ); gl_vertexLightingShader_DBS_entity->SetUniform_TextureMatrix( tess.svars.texMatrices[ TB_DIFFUSEMAP ] ); - if ( normalMapping ) + if ( normalMapping || ( parallaxMapping && hasHeightMapInNormalMap ) ) { // bind u_NormalMap GL_BindToTMU( 1, pStage->bundle[ TB_NORMALMAP ].image[ 0 ] ); + } + else + { + GL_BindToTMU( 1, tr.flatImage ); + } + if ( normalMapping ) + { vec3_t normalScale; SetNormalScale( pStage, normalScale ); // bind u_NormalScale gl_vertexLightingShader_DBS_entity->SetUniform_NormalScale( normalScale ); } - else - { - GL_BindToTMU( 1, tr.flatImage ); - } if ( physicalMapping || specularMapping ) { @@ -1098,11 +1097,7 @@ static void Render_vertexLighting_DBS_world( int stage ) gl_vertexLightingShader_DBS_world->SetUniform_ParallaxOffsetBias( tess.surfaceShader->parallaxOffsetBias ); // FIXME: if there is both, embedded heightmap in normalmap is used instead of standalone heightmap - if ( hasHeightMapInNormalMap ) - { - GL_BindToTMU( 15, pStage->bundle[ TB_NORMALMAP ].image[ 0 ] ); - } - else + if ( !hasHeightMapInNormalMap ) { GL_BindToTMU( 15, pStage->bundle[ TB_HEIGHTMAP ].image[ 0 ] ); } @@ -1117,21 +1112,24 @@ static void Render_vertexLighting_DBS_world( int stage ) GL_BindToTMU( 0, pStage->bundle[ TB_DIFFUSEMAP ].image[ 0 ] ); gl_vertexLightingShader_DBS_world->SetUniform_TextureMatrix( tess.svars.texMatrices[ TB_DIFFUSEMAP ] ); - if ( normalMapping ) + if ( normalMapping || ( parallaxMapping && hasHeightMapInNormalMap ) ) { // bind u_NormalMap GL_BindToTMU( 1, pStage->bundle[ TB_NORMALMAP ].image[ 0 ] ); + } + else + { + GL_BindToTMU( 1, tr.flatImage ); + } + if ( normalMapping ) + { vec3_t normalScale; SetNormalScale( pStage, normalScale ); // bind u_NormalScale gl_vertexLightingShader_DBS_world->SetUniform_NormalScale( normalScale ); } - else - { - GL_BindToTMU( 1, tr.flatImage ); - } if ( physicalMapping || specularMapping ) { @@ -1289,11 +1287,7 @@ static void Render_lightMapping( int stage ) gl_lightMappingShader->SetUniform_ParallaxOffsetBias( tess.surfaceShader->parallaxOffsetBias ); // FIXME: if there is both, embedded heightmap in normalmap is used instead of standalone heightmap - if ( hasHeightMapInNormalMap ) - { - GL_BindToTMU( 15, pStage->bundle[ TB_NORMALMAP ].image[ 0 ] ); - } - else + if ( !hasHeightMapInNormalMap ) { GL_BindToTMU( 15, pStage->bundle[ TB_HEIGHTMAP ].image[ 0 ] ); } @@ -1312,20 +1306,24 @@ static void Render_lightMapping( int stage ) } // bind u_NormalMap - if ( normalMapping ) + if ( normalMapping || ( parallaxMapping && hasHeightMapInNormalMap ) ) { GL_BindToTMU( 1, pStage->bundle[ TB_NORMALMAP ].image[ 0 ] ); + } + else + { + GL_BindToTMU( 1, tr.flatImage ); + } + // bind u_NormalMap + if ( normalMapping ) + { vec3_t normalScale; SetNormalScale( pStage, normalScale ); // bind u_NormalScale gl_lightMappingShader->SetUniform_NormalScale( normalScale ); } - else - { - GL_BindToTMU( 1, tr.flatImage ); - } if ( physicalMapping || specularMapping ) { @@ -1611,11 +1609,7 @@ static void Render_forwardLighting_DBS_omni( shaderStage_t *pStage, gl_forwardLightingShader_omniXYZ->SetUniform_ParallaxOffsetBias( tess.surfaceShader->parallaxOffsetBias ); // FIXME: if there is both, embedded heightmap in normalmap is used instead of standalone heightmap - if ( hasHeightMapInNormalMap ) - { - GL_BindToTMU( 15, pStage->bundle[ TB_NORMALMAP ].image[ 0 ] ); - } - else + if ( !hasHeightMapInNormalMap ) { GL_BindToTMU( 15, pStage->bundle[ TB_HEIGHTMAP ].image[ 0 ] ); } @@ -1677,21 +1671,24 @@ static void Render_forwardLighting_DBS_omni( shaderStage_t *pStage, GL_BindToTMU( 0, pStage->bundle[ TB_DIFFUSEMAP ].image[ 0 ] ); gl_forwardLightingShader_omniXYZ->SetUniform_TextureMatrix( tess.svars.texMatrices[ TB_DIFFUSEMAP ] ); - if ( normalMapping ) + if ( normalMapping || ( parallaxMapping && hasHeightMapInNormalMap ) ) { // bind u_NormalMap GL_BindToTMU( 1, pStage->bundle[ TB_NORMALMAP ].image[ 0 ] ); + } + else + { + GL_BindToTMU( 1, tr.flatImage ); + } + if ( normalMapping ) + { vec3_t normalScale; SetNormalScale( pStage, normalScale ); // bind u_NormalScale gl_forwardLightingShader_omniXYZ->SetUniform_NormalScale( normalScale ); } - else - { - GL_BindToTMU( 1, tr.flatImage ); - } // physical mapping is not implemented if ( specularMapping ) @@ -1821,11 +1818,7 @@ static void Render_forwardLighting_DBS_proj( shaderStage_t *pStage, gl_forwardLightingShader_projXYZ->SetUniform_ParallaxOffsetBias( tess.surfaceShader->parallaxOffsetBias ); // FIXME: if there is both, embedded heightmap in normalmap is used instead of standalone heightmap - if ( hasHeightMapInNormalMap ) - { - GL_BindToTMU( 15, pStage->bundle[ TB_NORMALMAP ].image[ 0 ] ); - } - else + if ( !hasHeightMapInNormalMap ) { GL_BindToTMU( 15, pStage->bundle[ TB_HEIGHTMAP ].image[ 0 ] ); } @@ -1888,21 +1881,24 @@ static void Render_forwardLighting_DBS_proj( shaderStage_t *pStage, GL_BindToTMU( 0, pStage->bundle[ TB_DIFFUSEMAP ].image[ 0 ] ); gl_forwardLightingShader_projXYZ->SetUniform_TextureMatrix( tess.svars.texMatrices[ TB_DIFFUSEMAP ] ); - if ( normalMapping ) + if ( normalMapping || ( parallaxMapping && hasHeightMapInNormalMap ) ) { // bind u_NormalMap GL_BindToTMU( 1, pStage->bundle[ TB_NORMALMAP ].image[ 0 ] ); + } + else + { + GL_BindToTMU( 1, tr.flatImage ); + } + if ( normalMapping ) + { vec3_t normalScale; SetNormalScale( pStage, normalScale ); // bind u_NormalScale gl_forwardLightingShader_projXYZ->SetUniform_NormalScale( normalScale ); } - else - { - GL_BindToTMU( 1, tr.flatImage ); - } // physical mapping is not implemented if ( specularMapping ) @@ -2030,11 +2026,7 @@ static void Render_forwardLighting_DBS_directional( shaderStage_t *pStage, trRef gl_forwardLightingShader_directionalSun->SetUniform_ParallaxOffsetBias( tess.surfaceShader->parallaxOffsetBias ); // FIXME: if there is both, embedded heightmap in normalmap is used instead of standalone heightmap - if ( hasHeightMapInNormalMap ) - { - GL_BindToTMU( 15, pStage->bundle[ TB_NORMALMAP ].image[ 0 ] ); - } - else + if ( !hasHeightMapInNormalMap ) { GL_BindToTMU( 15, pStage->bundle[ TB_HEIGHTMAP ].image[ 0 ] ); } @@ -2105,17 +2097,20 @@ static void Render_forwardLighting_DBS_directional( shaderStage_t *pStage, trRef { // bind u_NormalMap GL_BindToTMU( 1, pStage->bundle[ TB_NORMALMAP ].image[ 0 ] ); + } + else + { + GL_BindToTMU( 1, tr.flatImage ); + } + if ( normalMapping ) + { vec3_t normalScale; SetNormalScale( pStage, normalScale ); // bind u_NormalScale gl_forwardLightingShader_directionalSun->SetUniform_NormalScale( normalScale ); } - else - { - GL_BindToTMU( 1, tr.flatImage ); - } // physical mapping is not implemented if ( specularMapping ) @@ -2226,21 +2221,24 @@ static void Render_reflection_CB( int stage ) GL_BindNearestCubeMap( backEnd.viewParms.orientation.origin ); } - if ( normalMapping ) + if ( normalMapping || ( parallaxMapping && hasHeightMapInNormalMap ) ) { // bind u_NormalMap GL_BindToTMU( 1, pStage->bundle[ TB_NORMALMAP ].image[ 0 ] ); + } + else + { + GL_BindToTMU( 1, tr.flatImage ); + } + if ( normalMapping ) + { vec3_t normalScale; SetNormalScale( pStage, normalScale ); // bind u_NormalScale gl_reflectionShader->SetUniform_NormalScale( normalScale ); } - else - { - GL_BindToTMU( 1, tr.flatImage ); - } gl_reflectionShader->SetUniform_TextureMatrix( tess.svars.texMatrices[ TB_NORMALMAP ] ); @@ -2257,11 +2255,7 @@ static void Render_reflection_CB( int stage ) gl_reflectionShader->SetUniform_ParallaxOffsetBias( tess.surfaceShader->parallaxOffsetBias ); // FIXME: if there is both, embedded heightmap in normalmap is used instead of standalone heightmap - if ( hasHeightMapInNormalMap ) - { - GL_BindToTMU( 15, pStage->bundle[ TB_NORMALMAP ].image[ 0 ] ); - } - else + if ( !hasHeightMapInNormalMap ) { GL_BindToTMU( 15, pStage->bundle[ TB_HEIGHTMAP ].image[ 0 ] ); } @@ -2548,21 +2542,25 @@ static void Render_liquid( int stage ) gl_liquidShader->SetUniform_ParallaxOffsetBias( tess.surfaceShader->parallaxOffsetBias ); // FIXME: if there is both, embedded heightmap in normalmap is used instead of standalone heightmap - if ( hasHeightMapInNormalMap ) - { - GL_BindToTMU( 15, pStage->bundle[ TB_COLORMAP ].image[ 0 ] ); - } + if ( !hasHeightMapInNormalMap ) else { GL_BindToTMU( 15, pStage->bundle[ TB_HEIGHTMAP ].image[ 0 ] ); } } - if ( normalMapping ) + if ( normalMapping || ( parallaxMapping && hasHeightMapInNormalMap ) ) { // bind u_NormalMap GL_BindToTMU( 3, pStage->bundle[ TB_COLORMAP ].image[ 0 ] ); + } + else + { + GL_BindToTMU( 3, tr.flatImage ); + } + if ( normalMapping ) + { vec3_t normalScale; // FIXME: NormalIntensity default was 0.5 SetNormalScale( pStage, normalScale ); @@ -2570,10 +2568,6 @@ static void Render_liquid( int stage ) // bind u_NormalScale gl_liquidShader->SetUniform_NormalScale( normalScale ); } - else - { - GL_BindToTMU( 3, tr.flatImage ); - } gl_liquidShader->SetUniform_TextureMatrix( tess.svars.texMatrices[ TB_COLORMAP ] );