diff --git a/src/engine/renderer/tr_local.h b/src/engine/renderer/tr_local.h index 4acaba818f..c4a0fce349 100644 --- a/src/engine/renderer/tr_local.h +++ b/src/engine/renderer/tr_local.h @@ -1094,7 +1094,6 @@ static inline void halfToFloat( const f16vec4_t in, vec4_t out ) bool tcGen_Environment; bool tcGen_Lightmap; - bool heightMapInNormalMap; // material has normalmap suited for parallax mapping bool implicitLightmap; Color::Color32Bit constantColor; // for CGEN_CONST and AGEN_CONST @@ -1125,6 +1124,22 @@ static inline void halfToFloat( const f16vec4_t in, vec4_t out ) expression_t fresnelScaleExp; expression_t fresnelBiasExp; + // Available textures. + bool hasNormalMap; + bool hasHeightMap; + bool isHeightMapInNormalMap; + bool hasMaterialMap; + bool isMaterialPhysical; + bool hasGlowMap; + + // Available features. + bool enableNormalMapping; + bool enableDeluxeMapping; + bool enableParallaxMapping; + bool enablePhysicalMapping; + bool enableSpecularMapping; + bool enableGlowMapping; + // normalMap channel scale, negative value flips channel bool hasNormalScale; vec3_t normalScale; @@ -1212,7 +1227,6 @@ static inline void halfToFloat( const f16vec4_t in, vec4_t out ) fogPass_t fogPass; // draw a blended pass, possibly with depth test equals bool noFog; - bool heightMapInNormalMap; // material has normalmap suited for parallax mapping bool noParallax; // disable parallax for this material even if it's available float parallaxOffsetBias; // offset the heightmap top relatively to the floor float parallaxDepthScale; // per-shader parallax depth scale diff --git a/src/engine/renderer/tr_shade.cpp b/src/engine/renderer/tr_shade.cpp index 23d77b55a5..2a5cd483dc 100644 --- a/src/engine/renderer/tr_shade.cpp +++ b/src/engine/renderer/tr_shade.cpp @@ -744,33 +744,19 @@ 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; - - 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 && ( hasHeightMap || hasHeightMapInNormalMap ); - bool physicalMapping = r_physicalMapping->integer && hasMaterialMap && isMaterialPhysical; - bool specularMapping = r_specularMapping->integer && hasMaterialMap && !isMaterialPhysical; - bool glowMapping = r_glowMapping->integer && hasGlowMap; - // choose right shader program ---------------------------------- tess.vboVertexSprite = false; gl_vertexLightingShader_DBS_entity->SetVertexSkinning( glConfig2.vboVertexSkinningAvailable && tess.vboVertexSkinning ); gl_vertexLightingShader_DBS_entity->SetVertexAnimation( tess.vboVertexAnimation ); - gl_vertexLightingShader_DBS_entity->SetHeightMapInNormalMap( hasHeightMapInNormalMap ); + gl_vertexLightingShader_DBS_entity->SetHeightMapInNormalMap( pStage->isHeightMapInNormalMap ); - gl_vertexLightingShader_DBS_entity->SetParallaxMapping( parallaxMapping ); + gl_vertexLightingShader_DBS_entity->SetParallaxMapping( pStage->enableParallaxMapping ); - gl_vertexLightingShader_DBS_entity->SetReflectiveSpecular( normalMapping && tr.cubeHashTable != nullptr ); + gl_vertexLightingShader_DBS_entity->SetReflectiveSpecular( pStage->enableNormalMapping && tr.cubeHashTable != nullptr ); - gl_vertexLightingShader_DBS_entity->SetPhysicalShading( isMaterialPhysical ); + gl_vertexLightingShader_DBS_entity->SetPhysicalShading( pStage->isMaterialPhysical ); gl_vertexLightingShader_DBS_entity->BindProgram( pStage->deformIndex ); // end choose right shader program ------------------------------ @@ -818,7 +804,7 @@ static void Render_vertexLighting_DBS_entity( int stage ) gl_vertexLightingShader_DBS_entity->SetUniform_AlphaTest( pStage->stateBits ); // bind u_HeightMap - if ( parallaxMapping ) + if ( pStage->enableParallaxMapping ) { float depthScale; float parallaxDepthScale; @@ -830,7 +816,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 ) + if ( !pStage->isHeightMapInNormalMap ) { GL_BindToTMU( 15, pStage->bundle[ TB_HEIGHTMAP ].image[ 0 ] ); } @@ -840,42 +826,27 @@ 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 || ( parallaxMapping && hasHeightMapInNormalMap ) ) - { - // bind u_NormalMap - GL_BindToTMU( 1, pStage->bundle[ TB_NORMALMAP ].image[ 0 ] ); - } - else - { - GL_BindToTMU( 1, tr.flatImage ); - } - // bind u_NormalMap - if ( normalMapping ) + GL_BindToTMU( 1, pStage->bundle[ TB_NORMALMAP ].image[ 0 ] ); + + // bind u_NormalScale + if ( pStage->enableNormalMapping ) { vec3_t normalScale; SetNormalScale( pStage, normalScale ); - // bind u_NormalScale gl_vertexLightingShader_DBS_entity->SetUniform_NormalScale( normalScale ); } - if ( physicalMapping || specularMapping ) - { - // bind u_MaterialMap - GL_BindToTMU( 2, pStage->bundle[ TB_MATERIALMAP ].image[ 0 ] ); - - if ( specularMapping ) - { - float specExpMin = RB_EvalExpression( &pStage->specularExponentMin, r_specularExponentMin->value ); - float specExpMax = RB_EvalExpression( &pStage->specularExponentMax, r_specularExponentMax->value ); + // bind u_MaterialMap + GL_BindToTMU( 2, pStage->bundle[ TB_MATERIALMAP ].image[ 0 ] ); - gl_vertexLightingShader_DBS_entity->SetUniform_SpecularExponent( specExpMin, specExpMax ); - } - } - else + if ( pStage->enableSpecularMapping ) { - GL_BindToTMU( 2, tr.blackImage ); + float specExpMin = RB_EvalExpression( &pStage->specularExponentMin, r_specularExponentMin->value ); + float specExpMax = RB_EvalExpression( &pStage->specularExponentMax, r_specularExponentMax->value ); + + gl_vertexLightingShader_DBS_entity->SetUniform_SpecularExponent( specExpMin, specExpMax ); } if ( tr.cubeHashTable != nullptr ) @@ -976,12 +947,7 @@ static void Render_vertexLighting_DBS_entity( int stage ) } // bind u_GlowMap - if ( glowMapping ) - { - GL_BindToTMU( 5, pStage->bundle[ TB_GLOWMAP ].image[ 0 ] ); - } else { - GL_BindToTMU( 5, tr.blackImage ); - } + GL_BindToTMU( 5, pStage->bundle[ TB_GLOWMAP ].image[ 0 ] ); gl_vertexLightingShader_DBS_entity->SetRequiredVertexPointers(); @@ -1029,29 +995,15 @@ static void Render_vertexLighting_DBS_world( int stage ) break; } - 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; - - 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 && ( hasHeightMap || hasHeightMapInNormalMap ); - bool physicalMapping = r_physicalMapping->integer && hasMaterialMap && isMaterialPhysical; - bool specularMapping = r_specularMapping->integer && hasMaterialMap && !isMaterialPhysical; - bool glowMapping = r_glowMapping->integer && hasGlowMap; - // choose right shader program ---------------------------------- tess.vboVertexSprite = false; - gl_vertexLightingShader_DBS_world->SetHeightMapInNormalMap( hasHeightMapInNormalMap ); + gl_vertexLightingShader_DBS_world->SetHeightMapInNormalMap( pStage->isHeightMapInNormalMap ); - gl_vertexLightingShader_DBS_world->SetParallaxMapping( parallaxMapping ); + gl_vertexLightingShader_DBS_world->SetParallaxMapping( pStage->enableParallaxMapping ); - gl_vertexLightingShader_DBS_world->SetPhysicalShading( isMaterialPhysical ); + gl_vertexLightingShader_DBS_world->SetPhysicalShading( pStage->isMaterialPhysical ); gl_vertexLightingShader_DBS_world->BindProgram( pStage->deformIndex ); // end choose right shader program ------------------------------ @@ -1093,7 +1045,7 @@ static void Render_vertexLighting_DBS_world( int stage ) gl_vertexLightingShader_DBS_world->SetUniform_AlphaTest( pStage->stateBits ); // bind u_HeightMap - if ( parallaxMapping ) + if ( pStage->enableParallaxMapping ) { float depthScale; float parallaxDepthScale; @@ -1105,7 +1057,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 ) + if ( !pStage->isHeightMapInNormalMap ) { GL_BindToTMU( 15, pStage->bundle[ TB_HEIGHTMAP ].image[ 0 ] ); } @@ -1115,42 +1067,27 @@ 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 || ( parallaxMapping && hasHeightMapInNormalMap ) ) - { - // bind u_NormalMap - GL_BindToTMU( 1, pStage->bundle[ TB_NORMALMAP ].image[ 0 ] ); - } - else - { - GL_BindToTMU( 1, tr.flatImage ); - } - // bind u_NormalMap - if ( normalMapping ) + GL_BindToTMU( 1, pStage->bundle[ TB_NORMALMAP ].image[ 0 ] ); + + // bind u_NormalScale + if ( pStage->enableNormalMapping ) { vec3_t normalScale; SetNormalScale( pStage, normalScale ); - // bind u_NormalScale gl_vertexLightingShader_DBS_world->SetUniform_NormalScale( normalScale ); } - if ( physicalMapping || specularMapping ) - { - // bind u_MaterialMap - GL_BindToTMU( 2, pStage->bundle[ TB_MATERIALMAP ].image[ 0 ] ); - - if ( specularMapping ) - { - float specExpMin = RB_EvalExpression( &pStage->specularExponentMin, r_specularExponentMin->value ); - float specExpMax = RB_EvalExpression( &pStage->specularExponentMax, r_specularExponentMax->value ); + // bind u_MaterialMap + GL_BindToTMU( 2, pStage->bundle[ TB_MATERIALMAP ].image[ 0 ] ); - gl_vertexLightingShader_DBS_world->SetUniform_SpecularExponent( specExpMin, specExpMax ); - } - } - else + if ( pStage->enableSpecularMapping ) { - GL_BindToTMU( 2, tr.blackImage ); + float specExpMin = RB_EvalExpression( &pStage->specularExponentMin, r_specularExponentMin->value ); + float specExpMax = RB_EvalExpression( &pStage->specularExponentMax, r_specularExponentMax->value ); + + gl_vertexLightingShader_DBS_world->SetUniform_SpecularExponent( specExpMin, specExpMax ); } if( tr.world ) @@ -1167,12 +1104,7 @@ static void Render_vertexLighting_DBS_world( int stage ) } // bind u_GlowMap - if ( glowMapping ) - { - GL_BindToTMU( 5, pStage->bundle[ TB_GLOWMAP ].image[ 0 ] ); - } else { - GL_BindToTMU( 5, tr.blackImage ); - } + GL_BindToTMU( 5, pStage->bundle[ TB_GLOWMAP ].image[ 0 ] ); gl_vertexLightingShader_DBS_world->SetRequiredVertexPointers(); @@ -1225,20 +1157,7 @@ static void Render_lightMapping( int stage ) break; } - 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; - - bool hasHeightMapInNormalMap = pStage->heightMapInNormalMap && hasNormalMap; - bool isMaterialPhysical = pStage->collapseType == collapseType_t::COLLAPSE_lighting_PBR; - - bool normalMapping = r_normalMapping->integer && hasNormalMap; - bool deluxeMapping = r_deluxeMapping->integer && tr.worldDeluxeMapping && normalMapping; - 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; + bool enableDeluxeMapping = pStage->enableDeluxeMapping && tr.worldDeluxeMapping; bool noLightMap = !pStage->implicitLightmap && (tess.surfaceShader->surfaceFlags & SURF_NOLIGHTMAP) @@ -1247,13 +1166,13 @@ static void Render_lightMapping( int stage ) // choose right shader program ---------------------------------- tess.vboVertexSprite = false; - gl_lightMappingShader->SetDeluxeMapping( deluxeMapping ); + gl_lightMappingShader->SetDeluxeMapping( enableDeluxeMapping ); - gl_lightMappingShader->SetHeightMapInNormalMap( hasHeightMapInNormalMap ); + gl_lightMappingShader->SetHeightMapInNormalMap( pStage->isHeightMapInNormalMap ); - gl_lightMappingShader->SetParallaxMapping( parallaxMapping ); + gl_lightMappingShader->SetParallaxMapping( pStage->enableParallaxMapping ); - gl_lightMappingShader->SetPhysicalShading( isMaterialPhysical ); + gl_lightMappingShader->SetPhysicalShading( pStage->isMaterialPhysical ); gl_lightMappingShader->BindProgram( pStage->deformIndex ); // end choose right shader program ------------------------------ @@ -1292,7 +1211,7 @@ static void Render_lightMapping( int stage ) gl_lightMappingShader->SetUniform_AlphaTest( pStage->stateBits ); // bind u_HeightMap - if ( parallaxMapping ) + if ( pStage->enableParallaxMapping ) { float depthScale; float parallaxDepthScale; @@ -1304,7 +1223,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 ) + if ( !pStage->isHeightMapInNormalMap ) { GL_BindToTMU( 15, pStage->bundle[ TB_HEIGHTMAP ].image[ 0 ] ); } @@ -1322,49 +1241,34 @@ static void Render_lightMapping( int stage ) gl_lightMappingShader->SetUniform_TextureMatrix( tess.svars.texMatrices[ TB_DIFFUSEMAP ] ); } - if ( normalMapping || ( parallaxMapping && hasHeightMapInNormalMap ) ) - { - // bind u_NormalMap - GL_BindToTMU( 1, pStage->bundle[ TB_NORMALMAP ].image[ 0 ] ); - } - else - { - GL_BindToTMU( 1, tr.flatImage ); - } - // bind u_NormalMap - if ( normalMapping ) + GL_BindToTMU( 1, pStage->bundle[ TB_NORMALMAP ].image[ 0 ] ); + + // bind u_NormalScale + if ( pStage->enableNormalMapping ) { vec3_t normalScale; SetNormalScale( pStage, normalScale ); - // bind u_NormalScale gl_lightMappingShader->SetUniform_NormalScale( normalScale ); } - if ( physicalMapping || specularMapping ) - { - // bind u_MaterialMap - GL_BindToTMU( 2, pStage->bundle[ TB_MATERIALMAP ].image[ 0 ] ); + // bind u_MaterialMap + GL_BindToTMU( 2, pStage->bundle[ TB_MATERIALMAP ].image[ 0 ] ); - if ( specularMapping ) - { - float specExpMin = RB_EvalExpression( &pStage->specularExponentMin, r_specularExponentMin->value ); - float specExpMax = RB_EvalExpression( &pStage->specularExponentMax, r_specularExponentMax->value ); - - gl_lightMappingShader->SetUniform_SpecularExponent( specExpMin, specExpMax ); - } - } - else + if ( pStage->enableSpecularMapping ) { - GL_BindToTMU( 2, tr.blackImage ); + float specExpMin = RB_EvalExpression( &pStage->specularExponentMin, r_specularExponentMin->value ); + float specExpMax = RB_EvalExpression( &pStage->specularExponentMax, r_specularExponentMax->value ); + + gl_lightMappingShader->SetUniform_SpecularExponent( specExpMin, specExpMax ); } // bind u_LightMap BindLightMap( 3, noLightMap ); // bind u_DeluxeMap - if ( deluxeMapping ) + if ( enableDeluxeMapping ) { BindDeluxeMap( 4 ); } @@ -1374,12 +1278,7 @@ static void Render_lightMapping( int stage ) } // bind u_GlowMap - if ( glowMapping ) - { - GL_BindToTMU( 5, pStage->bundle[ TB_GLOWMAP ].image[ 0 ] ); - } else { - GL_BindToTMU( 5, tr.blackImage ); - } + GL_BindToTMU( 5, pStage->bundle[ TB_GLOWMAP ].image[ 0 ] ); gl_lightMappingShader->SetRequiredVertexPointers(); @@ -1550,28 +1449,15 @@ 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 && ( hasHeightMap || hasHeightMapInNormalMap ); - // physical mapping is not implemented - bool specularMapping = r_specularMapping->integer && hasMaterialMap && !isMaterialPhysical; - // glow mapping is not implemented - bool shadowCompare = ( r_shadows->integer >= Util::ordinal(shadowingMode_t::SHADOWING_ESM16) && !light->l.noShadows && light->shadowLOD >= 0 ); // choose right shader program ---------------------------------- gl_forwardLightingShader_omniXYZ->SetVertexSkinning( glConfig2.vboVertexSkinningAvailable && tess.vboVertexSkinning ); gl_forwardLightingShader_omniXYZ->SetVertexAnimation( glState.vertexAttribsInterpolation > 0 ); - gl_forwardLightingShader_omniXYZ->SetHeightMapInNormalMap( hasHeightMapInNormalMap ); + gl_forwardLightingShader_omniXYZ->SetHeightMapInNormalMap( pStage->isHeightMapInNormalMap ); - gl_forwardLightingShader_omniXYZ->SetParallaxMapping( parallaxMapping ); + gl_forwardLightingShader_omniXYZ->SetParallaxMapping( pStage->enableParallaxMapping ); gl_forwardLightingShader_omniXYZ->SetShadowing( shadowCompare ); @@ -1613,7 +1499,7 @@ static void Render_forwardLighting_DBS_omni( shaderStage_t *pStage, gl_forwardLightingShader_omniXYZ->SetUniform_AlphaTest( pStage->stateBits ); // bind u_HeightMap - if ( parallaxMapping ) + if ( pStage->enableParallaxMapping ) { float depthScale; float parallaxDepthScale; @@ -1625,7 +1511,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 ) + if ( !pStage->isHeightMapInNormalMap ) { GL_BindToTMU( 15, pStage->bundle[ TB_HEIGHTMAP ].image[ 0 ] ); } @@ -1687,40 +1573,29 @@ 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 || ( parallaxMapping && hasHeightMapInNormalMap ) ) - { - // bind u_NormalMap - GL_BindToTMU( 1, pStage->bundle[ TB_NORMALMAP ].image[ 0 ] ); - } - else - { - GL_BindToTMU( 1, tr.flatImage ); - } + // bind u_NormalMap + GL_BindToTMU( 1, pStage->bundle[ TB_NORMALMAP ].image[ 0 ] ); - if ( normalMapping ) + // bind u_NormalScale + if ( pStage->enableNormalMapping ) { vec3_t normalScale; SetNormalScale( pStage, normalScale ); - // bind u_NormalScale gl_forwardLightingShader_omniXYZ->SetUniform_NormalScale( normalScale ); } - // physical mapping is not implemented - if ( specularMapping ) - { - // bind u_MaterialMap - GL_BindToTMU( 2, pStage->bundle[ TB_MATERIALMAP ].image[ 0 ] ); + // bind u_MaterialMap + GL_BindToTMU( 2, pStage->bundle[ TB_MATERIALMAP ].image[ 0 ] ); + // FIXME: physical mapping is not implemented. + if ( pStage->enableSpecularMapping ) + { float minSpec = RB_EvalExpression( &pStage->specularExponentMin, r_specularExponentMin->value ); float maxSpec = RB_EvalExpression( &pStage->specularExponentMax, r_specularExponentMax->value ); gl_forwardLightingShader_omniXYZ->SetUniform_SpecularExponent( minSpec, maxSpec ); } - else - { - GL_BindToTMU( 2, tr.blackImage ); - } // bind u_AttenuationMapXY GL_SelectTexture( 3 ); @@ -1759,27 +1634,15 @@ 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 && ( hasHeightMap || hasHeightMapInNormalMap ); - // physical mapping is not implemented - bool specularMapping = r_specularMapping->integer && hasMaterialMap && !isMaterialPhysical; - bool shadowCompare = ( r_shadows->integer >= Util::ordinal(shadowingMode_t::SHADOWING_ESM16) && !light->l.noShadows && light->shadowLOD >= 0 ); // choose right shader program ---------------------------------- gl_forwardLightingShader_projXYZ->SetVertexSkinning( glConfig2.vboVertexSkinningAvailable && tess.vboVertexSkinning ); gl_forwardLightingShader_projXYZ->SetVertexAnimation( glState.vertexAttribsInterpolation > 0 ); - gl_forwardLightingShader_projXYZ->SetHeightMapInNormalMap( hasHeightMapInNormalMap ); + gl_forwardLightingShader_projXYZ->SetHeightMapInNormalMap( pStage->isHeightMapInNormalMap ); - gl_forwardLightingShader_projXYZ->SetParallaxMapping( parallaxMapping ); + gl_forwardLightingShader_projXYZ->SetParallaxMapping( pStage->enableParallaxMapping ); gl_forwardLightingShader_projXYZ->SetShadowing( shadowCompare ); @@ -1821,7 +1684,7 @@ static void Render_forwardLighting_DBS_proj( shaderStage_t *pStage, gl_forwardLightingShader_projXYZ->SetUniform_AlphaTest( pStage->stateBits ); // bind u_HeightMap - if ( parallaxMapping ) + if ( pStage->enableParallaxMapping ) { float depthScale; float parallaxDepthScale; @@ -1833,7 +1696,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 ) + if ( !pStage->isHeightMapInNormalMap ) { GL_BindToTMU( 15, pStage->bundle[ TB_HEIGHTMAP ].image[ 0 ] ); } @@ -1896,40 +1759,29 @@ 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 || ( parallaxMapping && hasHeightMapInNormalMap ) ) - { - // bind u_NormalMap - GL_BindToTMU( 1, pStage->bundle[ TB_NORMALMAP ].image[ 0 ] ); - } - else - { - GL_BindToTMU( 1, tr.flatImage ); - } + // bind u_NormalMap + GL_BindToTMU( 1, pStage->bundle[ TB_NORMALMAP ].image[ 0 ] ); - if ( normalMapping ) + // bind u_NormalScale + if ( pStage->enableNormalMapping ) { vec3_t normalScale; SetNormalScale( pStage, normalScale ); - // bind u_NormalScale gl_forwardLightingShader_projXYZ->SetUniform_NormalScale( normalScale ); } - // physical mapping is not implemented - if ( specularMapping ) - { - // bind u_MaterialMap - GL_BindToTMU( 2, pStage->bundle[ TB_MATERIALMAP ].image[ 0 ] ); + // bind u_MaterialMap + GL_BindToTMU( 2, pStage->bundle[ TB_MATERIALMAP ].image[ 0 ] ); + // FIXME: physical mapping is not implemented. + if ( pStage->enableSpecularMapping ) + { float minSpec = RB_EvalExpression( &pStage->specularExponentMin, r_specularExponentMin->value ); float maxSpec = RB_EvalExpression( &pStage->specularExponentMax, r_specularExponentMax->value ); gl_forwardLightingShader_projXYZ->SetUniform_SpecularExponent( minSpec, maxSpec ); } - else - { - GL_BindToTMU( 2, tr.blackImage ); - } // bind u_AttenuationMapXY GL_SelectTexture( 3 ); @@ -1966,27 +1818,15 @@ 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 && ( hasHeightMap || hasHeightMapInNormalMap ); - // physical mapping is not implemented - bool specularMapping = r_specularMapping->integer && hasMaterialMap && !isMaterialPhysical; - bool shadowCompare = ( r_shadows->integer >= Util::ordinal(shadowingMode_t::SHADOWING_ESM16) && !light->l.noShadows && light->shadowLOD >= 0 ); // choose right shader program ---------------------------------- gl_forwardLightingShader_directionalSun->SetVertexSkinning( glConfig2.vboVertexSkinningAvailable && tess.vboVertexSkinning ); gl_forwardLightingShader_directionalSun->SetVertexAnimation( glState.vertexAttribsInterpolation > 0 ); - gl_forwardLightingShader_directionalSun->SetHeightMapInNormalMap( hasHeightMapInNormalMap ); + gl_forwardLightingShader_directionalSun->SetHeightMapInNormalMap( pStage->isHeightMapInNormalMap ); - gl_forwardLightingShader_directionalSun->SetParallaxMapping( parallaxMapping ); + gl_forwardLightingShader_directionalSun->SetParallaxMapping( pStage->enableParallaxMapping ); gl_forwardLightingShader_directionalSun->SetShadowing( shadowCompare ); @@ -2028,7 +1868,7 @@ static void Render_forwardLighting_DBS_directional( shaderStage_t *pStage, trRef gl_forwardLightingShader_directionalSun->SetUniform_AlphaTest( pStage->stateBits ); // bind u_HeightMap - if ( parallaxMapping ) + if ( pStage->enableParallaxMapping ) { float depthScale; float parallaxDepthScale; @@ -2040,7 +1880,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 ) + if ( !pStage->isHeightMapInNormalMap ) { GL_BindToTMU( 15, pStage->bundle[ TB_HEIGHTMAP ].image[ 0 ] ); } @@ -2107,39 +1947,28 @@ 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 ) - { - // bind u_NormalMap - GL_BindToTMU( 1, pStage->bundle[ TB_NORMALMAP ].image[ 0 ] ); - } - else - { - GL_BindToTMU( 1, tr.flatImage ); - } + // bind u_NormalMap + GL_BindToTMU( 1, pStage->bundle[ TB_NORMALMAP ].image[ 0 ] ); - if ( normalMapping ) + // bind u_NormalScale + if ( pStage->enableNormalMapping ) { vec3_t normalScale; SetNormalScale( pStage, normalScale ); - // bind u_NormalScale gl_forwardLightingShader_directionalSun->SetUniform_NormalScale( normalScale ); } - // physical mapping is not implemented - if ( specularMapping ) - { - // bind u_MaterialMap - GL_BindToTMU( 2, pStage->bundle[ TB_MATERIALMAP ].image[ 0 ] ); + // bind u_MaterialMap + GL_BindToTMU( 2, pStage->bundle[ TB_MATERIALMAP ].image[ 0 ] ); + // FIXME: physical mapping is not implemented. + if ( pStage->enableSpecularMapping ) + { float minSpec = RB_EvalExpression( &pStage->specularExponentMin, r_specularExponentMin->value ); float maxSpec = RB_EvalExpression( &pStage->specularExponentMax, r_specularExponentMax->value ); gl_forwardLightingShader_directionalSun->SetUniform_SpecularExponent( minSpec, maxSpec ); } - else - { - GL_BindToTMU( 2, tr.blackImage ); - } // bind u_ShadowMap if ( shadowCompare ) @@ -2187,18 +2016,10 @@ 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 && ( hasHeightMap || hasHeightMapInNormalMap ); - // choose right shader program ---------------------------------- - gl_reflectionShader->SetHeightMapInNormalMap( hasHeightMapInNormalMap ); + gl_reflectionShader->SetHeightMapInNormalMap( pStage->isHeightMapInNormalMap ); - gl_reflectionShader->SetParallaxMapping( parallaxMapping ); + gl_reflectionShader->SetParallaxMapping( pStage->enableParallaxMapping ); gl_reflectionShader->SetVertexSkinning( glConfig2.vboVertexSkinningAvailable && tess.vboVertexSkinning ); gl_reflectionShader->SetVertexAnimation( glState.vertexAttribsInterpolation > 0 ); @@ -2234,29 +2055,22 @@ static void Render_reflection_CB( int stage ) GL_BindNearestCubeMap( backEnd.viewParms.orientation.origin ); } - if ( normalMapping || ( parallaxMapping && hasHeightMapInNormalMap ) ) - { - // bind u_NormalMap - GL_BindToTMU( 1, pStage->bundle[ TB_NORMALMAP ].image[ 0 ] ); - } - else - { - GL_BindToTMU( 1, tr.flatImage ); - } + // bind u_NormalMap + GL_BindToTMU( 1, pStage->bundle[ TB_NORMALMAP ].image[ 0 ] ); - if ( normalMapping ) + // bind u_NormalScale + if ( pStage->enableNormalMapping ) { vec3_t normalScale; SetNormalScale( pStage, normalScale ); - // bind u_NormalScale gl_reflectionShader->SetUniform_NormalScale( normalScale ); } gl_reflectionShader->SetUniform_TextureMatrix( tess.svars.texMatrices[ TB_NORMALMAP ] ); // bind u_HeightMap u_depthScale u_parallaxOffsetBias - if ( parallaxMapping ) + if ( pStage->enableParallaxMapping ) { float depthScale; float parallaxDepthScale; @@ -2268,7 +2082,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 ) + if ( !pStage->isHeightMapInNormalMap ) { GL_BindToTMU( 15, pStage->bundle[ TB_HEIGHTMAP ].image[ 0 ] ); } @@ -2370,10 +2184,6 @@ static void Render_heatHaze( int stage ) GLimp_LogComment( "--- Render_heatHaze ---\n" ); - bool hasNormalMap = pStage->bundle[ TB_COLORMAP ].image[ 0 ] != nullptr; - - bool normalMapping = r_normalMapping->integer && hasNormalMap; - // remove alpha test stateBits = pStage->stateBits; stateBits &= ~GLS_ATEST_BITS; @@ -2432,12 +2242,12 @@ static void Render_heatHaze( int stage ) // draw to background image R_BindFBO( tr.mainFBO[ 1 - backEnd.currentMainFBO ] ); - if ( normalMapping ) - { - // bind u_NormalMap - GL_BindToTMU( 0, pStage->bundle[ TB_COLORMAP ].image[ 0 ] ); + // bind u_NormalMap + GL_BindToTMU( 0, pStage->bundle[ TB_NORMALMAP ].image[ 0 ] ); - gl_heatHazeShader->SetUniform_TextureMatrix( tess.svars.texMatrices[ TB_COLORMAP ] ); + if ( pStage->enableNormalMapping ) + { + gl_heatHazeShader->SetUniform_TextureMatrix( tess.svars.texMatrices[ TB_NORMALMAP ] ); vec3_t normalScale; SetNormalScale( pStage, normalScale ); @@ -2445,10 +2255,6 @@ static void Render_heatHaze( int stage ) // bind u_NormalScale gl_heatHazeShader->SetUniform_NormalScale( normalScale ); } - else - { - GL_BindToTMU( 0, tr.flatImage ); - } // bind u_CurrentMap GL_BindToTMU( 1, tr.currentRenderImage[ backEnd.currentMainFBO ] ); @@ -2475,24 +2281,13 @@ 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 && ( hasHeightMap || hasHeightMapInNormalMap ); - // specular component is computed by shader - // physical mapping is not implemented - bool specularMapping = r_specularMapping->integer; - // Tr3B: don't allow blend effects GL_State( pStage->stateBits & ~( GLS_SRCBLEND_BITS | GLS_DSTBLEND_BITS | GLS_DEPTHMASK_TRUE ) ); // choose right shader program - gl_liquidShader->SetHeightMapInNormalMap( hasHeightMapInNormalMap ); + gl_liquidShader->SetHeightMapInNormalMap( pStage->isHeightMapInNormalMap ); - gl_liquidShader->SetParallaxMapping( parallaxMapping ); + gl_liquidShader->SetParallaxMapping( pStage->enableParallaxMapping ); // enable shader, set arrays gl_liquidShader->BindProgram( pStage->deformIndex ); @@ -2516,9 +2311,9 @@ static void Render_liquid( int stage ) gl_liquidShader->SetUniform_ModelMatrix( backEnd.orientation.transformMatrix ); gl_liquidShader->SetUniform_ModelViewProjectionMatrix( glState.modelViewProjectionMatrix[ glState.stackIndex ] ); - // specular component is computed by shader - // physical mapping is not implemented - if ( specularMapping ) + // NOTE: specular component is computed by shader. + // FIXME: physical mapping is not implemented. + if ( pStage->enableSpecularMapping ) { float specMin = RB_EvalExpression( &pStage->specularExponentMin, r_specularExponentMin->value ); float specMax = RB_EvalExpression( &pStage->specularExponentMax, r_specularExponentMax->value ); @@ -2535,7 +2330,7 @@ static void Render_liquid( int stage ) GL_BindToTMU( 2, tr.currentDepthImage ); // bind u_HeightMap u_depthScale u_parallaxOffsetBias - if ( parallaxMapping ) + if ( pStage->enableParallaxMapping ) { float depthScale; float parallaxDepthScale; @@ -2547,33 +2342,26 @@ 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 ) + if ( !pStage->isHeightMapInNormalMap ) { GL_BindToTMU( 15, pStage->bundle[ TB_HEIGHTMAP ].image[ 0 ] ); } } - if ( normalMapping || ( parallaxMapping && hasHeightMapInNormalMap ) ) - { - // bind u_NormalMap - GL_BindToTMU( 3, pStage->bundle[ TB_COLORMAP ].image[ 0 ] ); - } - else - { - GL_BindToTMU( 3, tr.flatImage ); - } + // bind u_NormalMap + GL_BindToTMU( 3, pStage->bundle[ TB_NORMALMAP ].image[ 0 ] ); - if ( normalMapping ) + // bind u_NormalScale + if ( pStage->enableNormalMapping ) { vec3_t normalScale; // FIXME: NormalIntensity default was 0.5 SetNormalScale( pStage, normalScale ); - // bind u_NormalScale gl_liquidShader->SetUniform_NormalScale( normalScale ); } - gl_liquidShader->SetUniform_TextureMatrix( tess.svars.texMatrices[ TB_COLORMAP ] ); + gl_liquidShader->SetUniform_TextureMatrix( tess.svars.texMatrices[ TB_NORMALMAP ] ); Tess_DrawElements(); diff --git a/src/engine/renderer/tr_shader.cpp b/src/engine/renderer/tr_shader.cpp index 53d40a1f7d..27df38813f 100644 --- a/src/engine/renderer/tr_shader.cpp +++ b/src/engine/renderer/tr_shader.cpp @@ -1481,7 +1481,7 @@ static bool LoadMap( shaderStage_t *stage, const char *buffer, const int bundleI && stage->bundle[ bundleIndex ].image[ 0 ]->bits & IF_ALPHA ) { Log::Debug("found heightmap embedded in normalmap '%s'", buffer); - stage->heightMapInNormalMap = true; + stage->isHeightMapInNormalMap = true; } return true; @@ -1909,7 +1909,7 @@ static bool ParseStage( shaderStage_t *stage, const char **text ) stage->collapseType = collapseType_t::COLLAPSE_generic; } - stage->heightMapInNormalMap = true; + stage->isHeightMapInNormalMap = true; ParseNormalMap( stage, text ); } else if ( !Q_stricmp( token, "heightMap" ) ) @@ -4422,6 +4422,18 @@ static void CollapseStages() for ( int i = 0; i < MAX_SHADER_STAGES; i++ ) { + /* Store hethaze and liquid normal map in normal map slot. + + NOTE: liquidMap may be entirely redesigned in the future + to be a variant of diffuseMap (hence supporting all others textures). + */ + if ( stages[ i ].type == stageType_t::ST_HEATHAZEMAP + || stages[ i ].type == stageType_t::ST_LIQUIDMAP ) + { + stages[ i ].bundle[ TB_NORMALMAP ] = stages[ i ].bundle[ TB_COLORMAP ]; + stages[ i ].bundle[ TB_COLORMAP ] = {}; + } + if ( lightStage != -1 && stages[ i ].collapseType != collapseType_t::COLLAPSE_none ) { if ( stages[ i ].dpMaterial ) @@ -4501,7 +4513,7 @@ static void CollapseStages() stages[ diffuseStage ].normalScale[ 1 ] = stages[ normalStage ].normalScale[ 1 ]; stages[ diffuseStage ].normalScale[ 2 ] = stages[ normalStage ].normalScale[ 2 ]; stages[ diffuseStage ].hasNormalScale = stages[ normalStage ].hasNormalScale; - stages[ diffuseStage ].heightMapInNormalMap = stages[ normalStage ].heightMapInNormalMap; + stages[ diffuseStage ].isHeightMapInNormalMap = stages[ normalStage ].isHeightMapInNormalMap; // disable since it's merged stages[ normalStage ].active = false; } @@ -4603,6 +4615,44 @@ static void CollapseStages() } shader.numStages = numActiveStages; + + // Do some precomputation. + for ( int s = 0; s < shader.numStages; s++ ) + { + shaderStage_t *stage = &stages[ s ]; + + // Available textures. + stage->hasNormalMap = stage->bundle[ TB_NORMALMAP ].image[ 0 ] != nullptr; + stage->hasHeightMap = stage->bundle[ TB_HEIGHTMAP ].image[ 0 ] != nullptr; + stage->isHeightMapInNormalMap = stage->isHeightMapInNormalMap && stage->hasNormalMap; + stage->hasMaterialMap = stage->bundle[ TB_MATERIALMAP ].image[ 0 ] != nullptr; + stage->hasGlowMap = stage->bundle[ TB_GLOWMAP ].image[ 0 ] != nullptr; + stage->isMaterialPhysical = stage->collapseType == collapseType_t::COLLAPSE_lighting_PBR; + + // Available features. + stage->enableNormalMapping = r_normalMapping->integer && stage->hasNormalMap; + stage->enableDeluxeMapping = r_deluxeMapping->integer && stage->hasNormalMap; + stage->enableParallaxMapping = r_parallaxMapping->integer && !shader.noParallax && ( stage->hasHeightMap || stage->isHeightMapInNormalMap ); + stage->enablePhysicalMapping = r_physicalMapping->integer && stage->hasMaterialMap && stage->isMaterialPhysical; + stage->enableSpecularMapping = r_specularMapping->integer && stage->hasMaterialMap && !stage->isMaterialPhysical; + stage->enableGlowMapping = r_glowMapping->integer && stage->hasGlowMap; + + // Bind fallback textures if required. + if ( !stage->enableNormalMapping && !( stage->enableParallaxMapping && stage->isHeightMapInNormalMap) ) + { + stage->bundle[ TB_NORMALMAP ].image[ 0 ] = tr.flatImage; + } + + if ( !stage->enablePhysicalMapping && !stage->enableSpecularMapping ) + { + stage->bundle[ TB_MATERIALMAP ].image[ 0 ] = tr.blackImage; + } + + if ( !stage->enableGlowMapping ) + { + stage->bundle[ TB_GLOWMAP ].image[ 0 ] = tr.blackImage; + } + } } // *INDENT-ON*