diff --git a/src.cmake b/src.cmake index 11311e3ca8..68f6cddfd8 100644 --- a/src.cmake +++ b/src.cmake @@ -149,6 +149,7 @@ set(GLSLSOURCELIST ${ENGINE_DIR}/renderer/glsl_source/blurY_vp.glsl ${ENGINE_DIR}/renderer/glsl_source/cameraEffects_fp.glsl ${ENGINE_DIR}/renderer/glsl_source/cameraEffects_vp.glsl + ${ENGINE_DIR}/renderer/glsl_source/computeLight_fp.glsl ${ENGINE_DIR}/renderer/glsl_source/contrast_fp.glsl ${ENGINE_DIR}/renderer/glsl_source/contrast_vp.glsl ${ENGINE_DIR}/renderer/glsl_source/debugShadowMap_fp.glsl diff --git a/src/engine/renderer/gl_shader.cpp b/src/engine/renderer/gl_shader.cpp index bf62fd4d8f..080faee711 100644 --- a/src/engine/renderer/gl_shader.cpp +++ b/src/engine/renderer/gl_shader.cpp @@ -579,6 +579,21 @@ static std::string GenEngineConstants() { AddDefine( str, "r_showLightTiles", 1 ); } + if ( r_normalMapping->integer ) + { + AddDefine( str, "r_normalMapping", 1 ); + } + + if ( r_specularMapping->integer ) + { + AddDefine( str, "r_specularMapping", 1 ); + } + + if ( r_glowMapping->integer ) + { + AddDefine( str, "r_glowMapping", 1 ); + } + return str; } @@ -1449,6 +1464,7 @@ GLShader_lightMapping::GLShader_lightMapping( GLShaderManager *manager ) : u_numLights( this ), u_Lights( this ), GLDeformStage( this ), + GLCompileMacro_USE_DELUXE_MAPPING( this ), GLCompileMacro_USE_PARALLAX_MAPPING( this ), GLCompileMacro_USE_PHYSICAL_SHADING( this ) { @@ -1461,7 +1477,7 @@ void GLShader_lightMapping::BuildShaderVertexLibNames( std::string& vertexInline void GLShader_lightMapping::BuildShaderFragmentLibNames( std::string& fragmentInlines ) { - fragmentInlines += "reliefMapping"; + fragmentInlines += "computeLight reliefMapping"; } void GLShader_lightMapping::BuildShaderCompileMacros( std::string& /*compileMacros*/ ) @@ -1520,7 +1536,7 @@ void GLShader_vertexLighting_DBS_entity::BuildShaderVertexLibNames( std::string& void GLShader_vertexLighting_DBS_entity::BuildShaderFragmentLibNames( std::string& fragmentInlines ) { - fragmentInlines += "reliefMapping"; + fragmentInlines += "computeLight reliefMapping"; } void GLShader_vertexLighting_DBS_entity::BuildShaderCompileMacros( std::string& ) @@ -1580,7 +1596,7 @@ void GLShader_vertexLighting_DBS_world::BuildShaderVertexLibNames( std::string& } void GLShader_vertexLighting_DBS_world::BuildShaderFragmentLibNames( std::string& fragmentInlines ) { - fragmentInlines += "reliefMapping"; + fragmentInlines += "computeLight reliefMapping"; } void GLShader_vertexLighting_DBS_world::BuildShaderCompileMacros( std::string& ) @@ -1642,7 +1658,7 @@ void GLShader_forwardLighting_omniXYZ::BuildShaderVertexLibNames( std::string& v void GLShader_forwardLighting_omniXYZ::BuildShaderFragmentLibNames( std::string& fragmentInlines ) { - fragmentInlines += "reliefMapping"; + fragmentInlines += "computeLight reliefMapping"; } void GLShader_forwardLighting_omniXYZ::BuildShaderCompileMacros( std::string& /*compileMacros*/ ) @@ -1703,7 +1719,7 @@ void GLShader_forwardLighting_projXYZ::BuildShaderVertexLibNames( std::string& v void GLShader_forwardLighting_projXYZ::BuildShaderFragmentLibNames( std::string& fragmentInlines ) { - fragmentInlines += "reliefMapping"; + fragmentInlines += "computeLight reliefMapping"; } void GLShader_forwardLighting_projXYZ::BuildShaderCompileMacros( std::string& compileMacros ) @@ -1767,7 +1783,7 @@ void GLShader_forwardLighting_directionalSun::BuildShaderVertexLibNames( std::st void GLShader_forwardLighting_directionalSun::BuildShaderFragmentLibNames( std::string& fragmentInlines ) { - fragmentInlines += "reliefMapping"; + fragmentInlines += "computeLight reliefMapping"; } void GLShader_forwardLighting_directionalSun::BuildShaderCompileMacros( std::string& compileMacros ) @@ -2112,7 +2128,7 @@ GLShader_liquid::GLShader_liquid( GLShaderManager *manager ) : void GLShader_liquid::BuildShaderFragmentLibNames( std::string& fragmentInlines ) { - fragmentInlines += "reliefMapping"; + fragmentInlines += "computeLight reliefMapping"; } void GLShader_liquid::SetShaderProgramUniforms( shaderProgram_t *shaderProgram ) diff --git a/src/engine/renderer/gl_shader.h b/src/engine/renderer/gl_shader.h index 10f1fd41bb..ec2f79b182 100644 --- a/src/engine/renderer/gl_shader.h +++ b/src/engine/renderer/gl_shader.h @@ -783,6 +783,7 @@ class GLCompileMacro USE_VERTEX_SPRITE, USE_TCGEN_ENVIRONMENT, USE_TCGEN_LIGHTMAP, + USE_DELUXE_MAPPING, USE_PARALLAX_MAPPING, USE_REFLECTIVE_SPECULAR, USE_SHADOWING, @@ -983,6 +984,31 @@ class GLCompileMacro_USE_TCGEN_LIGHTMAP : } }; +class GLCompileMacro_USE_DELUXE_MAPPING : + GLCompileMacro +{ +public: + GLCompileMacro_USE_DELUXE_MAPPING( GLShader *shader ) : + GLCompileMacro( shader ) + { + } + + const char *GetName() const + { + return "USE_DELUXE_MAPPING"; + } + + EGLCompileMacro GetType() const + { + return EGLCompileMacro::USE_DELUXE_MAPPING; + } + + void SetDeluxeMapping( bool enable ) + { + SetMacro( enable ); + } +}; + class GLCompileMacro_USE_PARALLAX_MAPPING : GLCompileMacro { @@ -2201,6 +2227,7 @@ class GLShader_lightMapping : public u_numLights, public u_Lights, public GLDeformStage, + public GLCompileMacro_USE_DELUXE_MAPPING, public GLCompileMacro_USE_PARALLAX_MAPPING, public GLCompileMacro_USE_PHYSICAL_SHADING { diff --git a/src/engine/renderer/glsl_source/computeLight_fp.glsl b/src/engine/renderer/glsl_source/computeLight_fp.glsl new file mode 100644 index 0000000000..f4aa4e46e3 --- /dev/null +++ b/src/engine/renderer/glsl_source/computeLight_fp.glsl @@ -0,0 +1,202 @@ +/* +=========================================================================== +Copyright (C) 2009-2011 Robert Beckebans + +This file is part of XreaL source code. + +XreaL source code is free software; you can redistribute it +and/or modify it under the terms of the GNU General Public License as +published by the Free Software Foundation; either version 2 of the License, +or (at your option) any later version. + +XreaL source code is distributed in the hope that it will be +useful, but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with XreaL source code; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +=========================================================================== +*/ +// computeLight_fp.glsl - Light computing helper functions + +struct light { + vec4 center_radius; + vec4 color_type; + vec4 direction_angle; +}; + +#ifdef HAVE_ARB_uniform_buffer_object +layout(std140) uniform u_Lights { + light lights[ MAX_REF_LIGHTS ]; +}; +#define GetLight(idx, component) lights[idx].component +#else // !HAVE_ARB_uniform_buffer_object +uniform sampler2D u_Lights; +#define idxToTC( idx, w, h ) vec2( floor( ( idx * ( 1.0 / w ) ) + 0.5 ) * ( 1.0 / h ), \ + fract( ( idx + 0.5 ) * (1.0 / w ) ) ) +const struct GetLightOffsets { + int center_radius; + int color_type; + int direction_angle; +} getLightOffsets = GetLightOffsets(0, 1, 2); +#define GetLight(idx, component) texture2D( u_Lights, idxToTC(3 * idx + getLightOffsets.component, 64.0, float( 3 * MAX_REF_LIGHTS / 64 ) ) ) +#endif // HAVE_ARB_uniform_buffer_object + +uniform int u_numLights; + +uniform vec2 u_SpecularExponent; + +// lighting helper functions +void computeLight( vec3 lightDir, vec3 normal, vec3 eyeDir, vec3 lightColor, + vec4 diffuseColor, vec4 specularColor, + inout vec4 accumulator ) { + vec3 H = normalize( lightDir + eyeDir ); + float NdotH = clamp( dot( normal, H ), 0.0, 1.0 ); + +#if defined(USE_PHYSICAL_SHADING) + float metalness = specularColor.x; + float roughness = specularColor.y; + + float NdotV = clamp( dot( normal, eyeDir ), 0.0, 1.0); + float VdotH = clamp( dot( eyeDir, H ), 0.0, 1.0); + float NdotL = clamp( dot( normal, lightDir ), 0.0, 1.0 ); + + float alpha = roughness * roughness; + float k = 0.125 * (roughness + 1.0) * (roughness + 1.0); + + float D = alpha / ((NdotH * NdotH) * (alpha * alpha - 1.0) + 1.0); + D *= D; + + float FexpNH = pow(1.0 - NdotH, 5.0); + float FexpNV = pow(1.0 - NdotV, 5.0); + vec3 F = mix(vec3(0.04), diffuseColor.xyz, metalness); + F = F + (1.0 - F) * FexpNH; + + float G = NdotL / (NdotL * (1.0 - k) + k); + G *= NdotV / (NdotV * (1.0 - k) + k); + + accumulator.xyz += lightColor.xyz * (1.0 - metalness) * NdotL * diffuseColor.xyz; + accumulator.xyz += lightColor.xyz * vec3((D * F * G) / (4.0 * NdotV)); + accumulator.a = mix(diffuseColor.a, 1.0, FexpNV); +#else // !USE_PHYSICAL_SHADING + float NdotL = dot( normal, lightDir ); +#if defined(r_HalfLambertLighting) + // http://developer.valvesoftware.com/wiki/Half_Lambert + NdotL = NdotL * 0.5 + 0.5; + NdotL *= NdotL; +#elif defined(r_WrapAroundLighting) + NdotL = clamp( NdotL + r_WrapAroundLighting, 0.0, 1.0) / clamp(1.0 + r_WrapAroundLighting, 0.0, 1.0); +#else + NdotL = clamp( NdotL, 0.0, 1.0 ); +#endif + + accumulator.xyz += diffuseColor.xyz * lightColor.xyz * NdotL; +#if defined(r_specularMapping) + accumulator.xyz += specularColor.xyz * lightColor.xyz * pow( NdotH, u_SpecularExponent.x * specularColor.w + u_SpecularExponent.y) * r_SpecularScale; +#endif // r_specularMapping +#endif // USE_PHYSICAL_SHADING +} + +#if defined(TEXTURE_INTEGER) +const int lightsPerLayer = 16; +uniform usampler3D u_LightTiles; +#define idxs_t uvec4 +idxs_t fetchIdxs( in vec3 coords ) { + return texture3D( u_LightTiles, coords ); +} +int nextIdx( inout idxs_t idxs ) { + uvec4 tmp = ( idxs & uvec4( 3 ) ) * uvec4( 0x40, 0x10, 0x04, 0x01 ); + idxs = idxs >> 2; + return int( tmp.x + tmp.y + tmp.z + tmp.w ); +} +#else // !TEXTURE INTEGER +const int lightsPerLayer = 4; +uniform sampler3D u_LightTiles; +#define idxs_t vec4 +idxs_t fetchIdxs( in vec3 coords ) { + return texture3D( u_LightTiles, coords ) * 255.0; +} +int nextIdx( inout idxs_t idxs ) { + vec4 tmp = idxs; + idxs = floor(idxs * 0.25); + tmp -= 4.0 * idxs; + return int( dot( tmp, vec4( 64.0, 16.0, 4.0, 1.0 ) ) ); +} +#endif // TEXTURE_INTEGER + +const int numLayers = MAX_REF_LIGHTS / 256; + +void computeDLight( int idx, vec3 P, vec3 N, vec3 I, vec4 diffuse, + vec4 specular, inout vec4 color ) { + vec4 center_radius = GetLight( idx, center_radius ); + vec4 color_type = GetLight( idx, color_type ); + vec3 L; + float attenuation; + + if( color_type.w == 0.0 ) { + // point light + L = center_radius.xyz - P; + attenuation = 1.0 / (1.0 + 8.0 * length(L) / center_radius.w); + L = normalize(L); + } else if( color_type.w == 1.0 ) { + // spot light + vec4 direction_angle = GetLight( idx, direction_angle ); + L = center_radius.xyz - P; + attenuation = 1.0 / (1.0 + 8.0 * length(L) / center_radius.w); + L = normalize( L ); + + if( dot( L, direction_angle.xyz ) <= direction_angle.w ) { + attenuation = 0.0; + } + } else if( color_type.w == 2.0 ) { + // sun (directional) light + L = GetLight( idx, direction_angle ).xyz; + attenuation = 1.0; + } + computeLight( L, N, I, + attenuation * attenuation * color_type.xyz, + diffuse, specular, color ); +} + +void computeDLights( vec3 P, vec3 N, vec3 I, vec4 diffuse, vec4 specular, + inout vec4 color ) { + vec2 tile = floor( gl_FragCoord.xy * (1.0 / float( TILE_SIZE ) ) ) + 0.5; + vec3 tileScale = vec3( r_tileStep, 1.0/numLayers ); + +#if defined(r_showLightTiles) + float numLights = 0.0; +#endif + + for( int layer = 0; layer < numLayers; layer++ ) { + idxs_t idxs = fetchIdxs( tileScale * vec3( tile, float( layer ) + 0.5 ) ); + for( int i = 0; i < lightsPerLayer; i++ ) { + int idx = numLayers * nextIdx( idxs ) + layer; + + if( idx > u_numLights ) + { +#if defined(r_showLightTiles) + if (numLights > 0.0) + { + color = vec4(numLights/(lightsPerLayer*numLayers), numLights/(lightsPerLayer*numLayers), numLights/(lightsPerLayer*numLayers), 1.0); + } +#endif + return; + } + + computeDLight( idx, P, N, I, diffuse, specular, color ); + +#if defined(r_showLightTiles) + numLights++; +#endif + } + } + +#if defined(r_showLightTiles) + if (numLights > 0.0) + { + color = vec4(numLights/(lightsPerLayer*numLayers), numLights/(lightsPerLayer*numLayers), numLights/(lightsPerLayer*numLayers), 1.0); + } +#endif +} diff --git a/src/engine/renderer/glsl_source/forwardLighting_fp.glsl b/src/engine/renderer/glsl_source/forwardLighting_fp.glsl index 7121d7d036..223f5a9e9b 100644 --- a/src/engine/renderer/glsl_source/forwardLighting_fp.glsl +++ b/src/engine/renderer/glsl_source/forwardLighting_fp.glsl @@ -32,7 +32,6 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA #endif uniform sampler2D u_DiffuseMap; -uniform sampler2D u_NormalMap; uniform sampler2D u_SpecularMap; uniform sampler2D u_AttenuationMapXY; uniform sampler2D u_AttenuationMapZ; @@ -58,7 +57,6 @@ uniform samplerCube u_ShadowClipMap; uniform sampler2D u_RandomMap; // random normals - uniform vec3 u_ViewOrigin; #if defined(LIGHT_DIRECTIONAL) @@ -79,18 +77,15 @@ uniform float u_ShadowBlur; uniform mat4 u_ViewMatrix; -uniform float u_ParallaxDepthScale; -uniform float u_ParallaxOffsetBias; - IN(smooth) vec3 var_Position; -IN(smooth) vec4 var_TexDiffuse; -IN(smooth) vec4 var_TexNormal; +IN(smooth) vec2 var_TexDiffuse; +IN(smooth) vec2 var_TexNormal; IN(smooth) vec2 var_TexSpecular; IN(smooth) vec4 var_TexAttenuation; IN(smooth) vec4 var_Tangent; IN(smooth) vec4 var_Binormal; IN(smooth) vec4 var_Normal; -//IN(smooth) vec4 var_Color; +IN(smooth) vec4 var_Color; DECLARE_OUTPUT(vec4) @@ -157,7 +152,6 @@ Pr(X -mu >= k * sigma) <= 1 / ( 1 + k^2) */ #if defined(VSM) || defined(EVSM) - float linstep(float low, float high, float v) { return clamp((v - low)/(high - low), 0.0, 1.0); @@ -947,19 +941,19 @@ void main() vec3 L = normalize(u_LightOrigin - var_Position); #endif - vec2 texDiffuse = var_TexDiffuse.st; + vec2 texDiffuse = var_TexDiffuse; mat3 tangentToWorldMatrix = mat3(var_Tangent.xyz, var_Binormal.xyz, var_Normal.xyz); - vec2 texNormal = var_TexNormal.st; - vec2 texSpecular = var_TexSpecular.st; + vec2 texNormal = var_TexNormal; + vec2 texSpecular = var_TexSpecular; // compute view direction in world space vec3 viewDir = normalize(u_ViewOrigin - var_Position.xyz); #if defined(USE_PARALLAX_MAPPING) // compute texcoords offset from heightmap - vec2 texOffset = ParallaxTexOffset(u_NormalMap, texNormal, u_ParallaxDepthScale, u_ParallaxOffsetBias, viewDir, tangentToWorldMatrix); + vec2 texOffset = ParallaxTexOffset(texNormal, viewDir, tangentToWorldMatrix); texDiffuse += texOffset; texNormal += texOffset; @@ -970,7 +964,7 @@ void main() vec3 H = normalize(L + viewDir); // compute normal in world space from normal map - vec3 N = NormalInWorldSpace(u_NormalMap, texNormal, tangentToWorldMatrix); + vec3 N = NormalInWorldSpace(texNormal, tangentToWorldMatrix); // compute the light term #if defined(r_WrapAroundLighting) @@ -980,7 +974,7 @@ void main() #endif // compute the diffuse term - vec4 diffuse = texture2D(u_DiffuseMap, texDiffuse.st); + vec4 diffuse = texture2D(u_DiffuseMap, texDiffuse); if( abs(diffuse.a + u_AlphaThreshold) <= 1.0 ) { discard; @@ -988,9 +982,11 @@ void main() } diffuse.rgb *= u_LightColor * NL; +#if defined(r_specularMapping) // compute the specular term vec4 spec = texture2D(u_SpecularMap, texSpecular).rgba; vec3 specular = spec.rgb * u_LightColor * pow(clamp(dot(N, H), 0.0, 1.0), u_SpecularExponent.x * spec.a + u_SpecularExponent.y) * r_SpecularScale; +#endif // r_specularMapping // compute light attenuation #if defined(LIGHT_PROJ) @@ -1009,7 +1005,9 @@ void main() // compute final color vec4 color = diffuse; +#if defined(r_specularMapping) color.rgb += specular; +#endif // r_specularMapping #if !defined(LIGHT_DIRECTIONAL) color.rgb *= attenuationXY; @@ -1018,8 +1016,7 @@ void main() color.rgb *= abs(u_LightScale); color.rgb *= shadow; - color.r *= var_TexDiffuse.p; - color.gb *= var_TexNormal.pq; + color.rgb *= var_Color.rgb; if( u_LightScale < 0.0 ) { color.rgb = vec3( clamp(dot(color.rgb, vec3( 0.3333 ) ), 0.3, 0.7 ) ); diff --git a/src/engine/renderer/glsl_source/forwardLighting_vp.glsl b/src/engine/renderer/glsl_source/forwardLighting_vp.glsl index bf9c885db2..522de5f939 100644 --- a/src/engine/renderer/glsl_source/forwardLighting_vp.glsl +++ b/src/engine/renderer/glsl_source/forwardLighting_vp.glsl @@ -36,8 +36,8 @@ uniform mat4 u_ModelViewProjectionMatrix; uniform float u_Time; OUT(smooth) vec3 var_Position; -OUT(smooth) vec4 var_TexDiffuse; -OUT(smooth) vec4 var_TexNormal; +OUT(smooth) vec2 var_TexDiffuse; +OUT(smooth) vec2 var_TexNormal; OUT(smooth) vec2 var_TexSpecular; OUT(smooth) vec4 var_TexAttenuation; @@ -45,7 +45,8 @@ OUT(smooth) vec4 var_TexAttenuation; OUT(smooth) vec4 var_Tangent; OUT(smooth) vec4 var_Binormal; OUT(smooth) vec4 var_Normal; -//OUT(smooth) vec4 var_Color; // Tr3B - maximum vars reached + +OUT(smooth) vec4 var_Color; void DeformVertex( inout vec4 pos, inout vec3 normal, @@ -85,14 +86,13 @@ void main() var_TexAttenuation = u_LightAttenuationMatrix * position; // transform diffusemap texcoords - var_TexDiffuse.xy = (u_DiffuseTextureMatrix * vec4(texCoord, 0.0, 1.0)).st; + var_TexDiffuse = (u_DiffuseTextureMatrix * vec4(texCoord, 0.0, 1.0)).st; // transform normalmap texcoords - var_TexNormal.xy = (u_NormalTextureMatrix * vec4(texCoord, 0.0, 1.0)).st; + var_TexNormal = (u_NormalTextureMatrix * vec4(texCoord, 0.0, 1.0)).st; // transform specularmap texture coords var_TexSpecular = (u_SpecularTextureMatrix * vec4(texCoord, 0.0, 1.0)).st; - var_TexDiffuse.p = color.r; - var_TexNormal.pq = color.gb; + var_Color = color; } diff --git a/src/engine/renderer/glsl_source/heatHaze_fp.glsl b/src/engine/renderer/glsl_source/heatHaze_fp.glsl index 0bab406f93..72a694b9ae 100644 --- a/src/engine/renderer/glsl_source/heatHaze_fp.glsl +++ b/src/engine/renderer/glsl_source/heatHaze_fp.glsl @@ -22,7 +22,6 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA /* heatHaze_fp.glsl */ -uniform sampler2D u_NormalMap; uniform sampler2D u_CurrentMap; uniform float u_AlphaThreshold; @@ -36,7 +35,7 @@ void main() vec4 color; // compute normal in tangent space from normalmap - vec3 N = NormalInTangentSpace(u_NormalMap, var_TexNormal); + vec3 N = NormalInTangentSpace(var_TexNormal); // calculate the screen texcoord in the 0.0 to 1.0 range vec2 st = gl_FragCoord.st * r_FBufScale; diff --git a/src/engine/renderer/glsl_source/lightMapping_fp.glsl b/src/engine/renderer/glsl_source/lightMapping_fp.glsl index 621f229aa3..55648c7657 100644 --- a/src/engine/renderer/glsl_source/lightMapping_fp.glsl +++ b/src/engine/renderer/glsl_source/lightMapping_fp.glsl @@ -22,19 +22,18 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA /* lightMapping_fp.glsl */ uniform sampler2D u_DiffuseMap; -uniform sampler2D u_NormalMap; uniform sampler2D u_SpecularMap; uniform sampler2D u_GlowMap; uniform sampler2D u_LightMap; uniform sampler2D u_DeluxeMap; uniform float u_AlphaThreshold; uniform vec3 u_ViewOrigin; -uniform float u_ParallaxDepthScale; -uniform float u_ParallaxOffsetBias; IN(smooth) vec3 var_Position; -IN(smooth) vec4 var_TexDiffuseGlow; -IN(smooth) vec4 var_TexNormalSpecular; +IN(smooth) vec2 var_TexDiffuse; +IN(smooth) vec2 var_TexGlow; +IN(smooth) vec2 var_TexNormal; +IN(smooth) vec2 var_TexSpecular; IN(smooth) vec2 var_TexLight; IN(smooth) vec3 var_Tangent; @@ -50,16 +49,16 @@ void main() // compute view direction in world space vec3 viewDir = normalize(u_ViewOrigin - var_Position); - vec2 texDiffuse = var_TexDiffuseGlow.st; - vec2 texGlow = var_TexDiffuseGlow.pq; - vec2 texNormal = var_TexNormalSpecular.st; - vec2 texSpecular = var_TexNormalSpecular.pq; + vec2 texDiffuse = var_TexDiffuse; + vec2 texGlow = var_TexGlow; + vec2 texNormal = var_TexNormal; + vec2 texSpecular = var_TexSpecular; mat3 tangentToWorldMatrix = mat3(var_Tangent.xyz, var_Binormal.xyz, var_Normal.xyz); #if defined(USE_PARALLAX_MAPPING) // compute texcoords offset from heightmap - vec2 texOffset = ParallaxTexOffset(u_NormalMap, texNormal, u_ParallaxDepthScale, u_ParallaxOffsetBias, viewDir, tangentToWorldMatrix); + vec2 texOffset = ParallaxTexOffset(texNormal, viewDir, tangentToWorldMatrix); texDiffuse += texOffset; texGlow += texOffset; @@ -80,31 +79,37 @@ void main() vec4 specular = texture2D(u_SpecularMap, texSpecular); // compute normal in world space from normalmap - vec3 N = NormalInWorldSpace(u_NormalMap, texNormal, tangentToWorldMatrix); + vec3 N = NormalInWorldSpace(texNormal, tangentToWorldMatrix); // compute light color from world space lightmap vec3 lightColor = texture2D(u_LightMap, var_TexLight).xyz; vec4 color = vec4( 0.0, 0.0, 0.0, diffuse.a ); +#if defined(USE_DELUXE_MAPPING) // compute light direction in world space vec4 deluxe = texture2D(u_DeluxeMap, var_TexLight); - if( deluxe.w < 0.5 ) { - // normal/deluxe mapping is disabled - color.xyz += lightColor.xyz * diffuse.xyz; - } else { - vec3 L = 2.0 * deluxe.xyz - 1.0; - L = normalize(L); - - // divide by cosine term to restore original light color - lightColor /= clamp(dot(normalize(var_Normal), L), 0.004, 1.0); - - // compute final color - computeLight( L, N, viewDir, lightColor, diffuse, specular, color ); - } +#else // !USE_DELUXE_MAPPING + // normal/deluxe mapping is disabled + color.xyz += lightColor.xyz * diffuse.xyz; +#endif // USE_DELUXE_MAPPING + +#if defined(USE_DELUXE_MAPPING) + vec3 L = 2.0 * deluxe.xyz - 1.0; + L = normalize(L); + + // divide by cosine term to restore original light color + lightColor /= clamp(dot(normalize(var_Normal), L), 0.004, 1.0); + + // compute final color + computeLight( L, N, viewDir, lightColor, diffuse, specular, color ); +#endif // USE_DELUXE_MAPPING + computeDLights( var_Position, N, viewDir, diffuse, specular, color ); +#if defined(r_glowMapping) color.rgb += texture2D(u_GlowMap, texGlow).rgb; +#endif // r_glowMapping outputColor = color; diff --git a/src/engine/renderer/glsl_source/lightMapping_vp.glsl b/src/engine/renderer/glsl_source/lightMapping_vp.glsl index d44f5bad15..0c47765f78 100644 --- a/src/engine/renderer/glsl_source/lightMapping_vp.glsl +++ b/src/engine/renderer/glsl_source/lightMapping_vp.glsl @@ -35,8 +35,10 @@ uniform vec4 u_ColorModulate; uniform vec4 u_Color; OUT(smooth) vec3 var_Position; -OUT(smooth) vec4 var_TexDiffuseGlow; -OUT(smooth) vec4 var_TexNormalSpecular; +OUT(smooth) vec2 var_TexDiffuse; +OUT(smooth) vec2 var_TexGlow; +OUT(smooth) vec2 var_TexNormal; +OUT(smooth) vec2 var_TexSpecular; OUT(smooth) vec2 var_TexLight; OUT(smooth) vec3 var_Tangent; OUT(smooth) vec3 var_Binormal; @@ -70,16 +72,17 @@ void main() gl_Position = u_ModelViewProjectionMatrix * position; // transform diffusemap texcoords - var_TexDiffuseGlow.st = (u_DiffuseTextureMatrix * vec4(texCoord, 0.0, 1.0)).st; + var_TexDiffuse = (u_DiffuseTextureMatrix * vec4(texCoord, 0.0, 1.0)).st; var_TexLight = lmCoord; // transform normalmap texcoords - var_TexNormalSpecular.st = (u_NormalTextureMatrix * vec4(texCoord, 0.0, 1.0)).st; + var_TexNormal = (u_NormalTextureMatrix * vec4(texCoord, 0.0, 1.0)).st; // transform specularmap texcoords - var_TexNormalSpecular.pq = (u_SpecularTextureMatrix * vec4(texCoord, 0.0, 1.0)).st; + var_TexSpecular = (u_SpecularTextureMatrix * vec4(texCoord, 0.0, 1.0)).st; - var_TexDiffuseGlow.pq = (u_GlowTextureMatrix * vec4(texCoord, 0.0, 1.0)).st; + // transform glowmap texcoords + var_TexGlow = (u_GlowTextureMatrix * vec4(texCoord, 0.0, 1.0)).st; var_Position = position.xyz; diff --git a/src/engine/renderer/glsl_source/liquid_fp.glsl b/src/engine/renderer/glsl_source/liquid_fp.glsl index f096bbf549..ac7a190990 100644 --- a/src/engine/renderer/glsl_source/liquid_fp.glsl +++ b/src/engine/renderer/glsl_source/liquid_fp.glsl @@ -25,7 +25,6 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA uniform sampler2D u_CurrentMap; uniform sampler2D u_PortalMap; uniform sampler2D u_DepthMap; -uniform sampler2D u_NormalMap; uniform vec3 u_ViewOrigin; uniform float u_FogDensity; uniform vec3 u_FogColor; @@ -33,8 +32,6 @@ uniform float u_RefractionIndex; uniform float u_FresnelPower; uniform float u_FresnelScale; uniform float u_FresnelBias; -uniform float u_ParallaxDepthScale; -uniform float u_ParallaxOffsetBias; uniform float u_NormalScale; uniform mat4 u_ModelMatrix; uniform mat4 u_UnprojectMatrix; @@ -93,13 +90,13 @@ void main() // calculate the screen texcoord in the 0.0 to 1.0 range vec2 texScreen = gl_FragCoord.st * r_FBufScale; - vec2 texNormal = var_TexNormal.st; + vec2 texNormal = var_TexNormal; #if defined(USE_PARALLAX_MAPPING) // ray intersect in view direction // compute texcoords offset from heightmap - vec2 texOffset = ParallaxTexOffset(u_NormalMap, texNormal, u_ParallaxDepthScale, u_ParallaxOffsetBias, viewDir, tangentToWorldMatrix); + vec2 texOffset = ParallaxTexOffset(texNormal, viewDir, tangentToWorldMatrix); texScreen += texOffset; texNormal += texOffset; @@ -110,7 +107,7 @@ void main() vec3 N = normalize(var_Normal); // compute normal in world space from normalmap - vec3 N2 = NormalInWorldSpace(u_NormalMap, texNormal, tangentToWorldMatrix); + vec3 N2 = NormalInWorldSpace(texNormal, tangentToWorldMatrix); // compute fresnel term float fresnel = clamp(u_FresnelBias + pow(1.0 - dot(viewDir, N), u_FresnelPower) * @@ -158,9 +155,11 @@ void main() // compute the light term vec3 light = lgtCol * clamp(dot(N2, L), 0.0, 1.0); +#if defined(r_specularMapping) // compute the specular term vec3 specular = reflectColor * lgtCol * pow(clamp(dot(N2, H), 0.0, 1.0), u_SpecularExponent.x + u_SpecularExponent.y) * r_SpecularScale; color.rgb += specular; +#endif // r_specularMapping outputColor = color; } diff --git a/src/engine/renderer/glsl_source/reflection_CB_fp.glsl b/src/engine/renderer/glsl_source/reflection_CB_fp.glsl index 1ca855450b..dfc3ba285f 100644 --- a/src/engine/renderer/glsl_source/reflection_CB_fp.glsl +++ b/src/engine/renderer/glsl_source/reflection_CB_fp.glsl @@ -23,11 +23,8 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA /* reflection_CB_fp.glsl */ uniform samplerCube u_ColorMap; -uniform sampler2D u_NormalMap; uniform vec3 u_ViewOrigin; uniform mat4 u_ModelMatrix; -uniform float u_ParallaxDepthScale; -uniform float u_ParallaxOffsetBias; IN(smooth) vec3 var_Position; IN(smooth) vec2 var_TexNormal; @@ -48,13 +45,13 @@ void main() #if defined(USE_PARALLAX_MAPPING) // compute texcoords offset from heightmap - vec2 texOffset = ParallaxTexOffset(u_NormalMap, texNormal, u_ParallaxDepthScale, u_ParallaxOffsetBias, viewDir, tangentToWorldMatrix); + vec2 texOffset = ParallaxTexOffset(texNormal, viewDir, tangentToWorldMatrix); texNormal += texOffset; #endif // USE_PARALLAX_MAPPING // compute normal in tangent space from normal map - vec3 N = NormalInWorldSpace(u_NormalMap, texNormal, tangentToWorldMatrix); + vec3 N = NormalInWorldSpace(texNormal, tangentToWorldMatrix); // compute reflection ray vec3 R = reflect(viewDir, N); diff --git a/src/engine/renderer/glsl_source/reliefMapping_fp.glsl b/src/engine/renderer/glsl_source/reliefMapping_fp.glsl index dfe5dbbc8b..7fc478807c 100644 --- a/src/engine/renderer/glsl_source/reliefMapping_fp.glsl +++ b/src/engine/renderer/glsl_source/reliefMapping_fp.glsl @@ -19,188 +19,20 @@ along with XreaL source code; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA =========================================================================== */ -// reliefMapping_vp.glsl - Relief mapping helper functions +// reliefMapping_fp.glsl - Relief mapping helper functions +#if defined(r_normalMapping) || defined(USE_PARALLAX_MAPPING) +uniform sampler2D u_NormalMap; uniform int u_HeightMapInNormalMap; -uniform vec3 u_NormalFormat; - -struct light { - vec4 center_radius; - vec4 color_type; - vec4 direction_angle; -}; - -#ifdef HAVE_ARB_uniform_buffer_object -layout(std140) uniform u_Lights { - light lights[ MAX_REF_LIGHTS ]; -}; -#define GetLight(idx, component) lights[idx].component -#else -uniform sampler2D u_Lights; -#define idxToTC( idx, w, h ) vec2( floor( ( idx * ( 1.0 / w ) ) + 0.5 ) * ( 1.0 / h ), \ - fract( ( idx + 0.5 ) * (1.0 / w ) ) ) -const struct GetLightOffsets { - int center_radius; - int color_type; - int direction_angle; -} getLightOffsets = GetLightOffsets(0, 1, 2); -#define GetLight(idx, component) texture2D( u_Lights, idxToTC(3 * idx + getLightOffsets.component, 64.0, float( 3 * MAX_REF_LIGHTS / 64 ) ) ) -#endif - -uniform int u_numLights; - -uniform vec2 u_SpecularExponent; - -// lighting helper functions -void computeLight( vec3 lightDir, vec3 normal, vec3 eyeDir, vec3 lightColor, - vec4 diffuseColor, vec4 specularColor, - inout vec4 accumulator ) { - vec3 H = normalize( lightDir + eyeDir ); - float NdotH = clamp( dot( normal, H ), 0.0, 1.0 ); - -#if defined( USE_PHYSICAL_SHADING ) - float metalness = specularColor.x; - float roughness = specularColor.y; - - float NdotV = clamp( dot( normal, eyeDir ), 0.0, 1.0); - float VdotH = clamp( dot( eyeDir, H ), 0.0, 1.0); - float NdotL = clamp( dot( normal, lightDir ), 0.0, 1.0 ); - - float alpha = roughness * roughness; - float k = 0.125 * (roughness + 1.0) * (roughness + 1.0); - - float D = alpha / ((NdotH * NdotH) * (alpha * alpha - 1.0) + 1.0); - D *= D; - - float FexpNH = pow(1.0 - NdotH, 5.0); - float FexpNV = pow(1.0 - NdotV, 5.0); - vec3 F = mix(vec3(0.04), diffuseColor.xyz, metalness); - F = F + (1.0 - F) * FexpNH; - - float G = NdotL / (NdotL * (1.0 - k) + k); - G *= NdotV / (NdotV * (1.0 - k) + k); - - accumulator.xyz += lightColor.xyz * (1.0 - metalness) * NdotL * diffuseColor.xyz; - accumulator.xyz += lightColor.xyz * vec3((D * F * G) / (4.0 * NdotV)); - accumulator.a = mix(diffuseColor.a, 1.0, FexpNV); -#else - float NdotL = dot( normal, lightDir ); -#if defined(r_HalfLambertLighting) - // http://developer.valvesoftware.com/wiki/Half_Lambert - NdotL = NdotL * 0.5 + 0.5; - NdotL *= NdotL; -#elif defined(r_WrapAroundLighting) - NdotL = clamp( NdotL + r_WrapAroundLighting, 0.0, 1.0) / clamp(1.0 + r_WrapAroundLighting, 0.0, 1.0); -#else - NdotL = clamp( NdotL, 0.0, 1.0 ); -#endif - - accumulator.xyz += diffuseColor.xyz * lightColor.xyz * NdotL; - accumulator.xyz += specularColor.xyz * lightColor.xyz * pow( NdotH, u_SpecularExponent.x * specularColor.w + u_SpecularExponent.y) * r_SpecularScale; -#endif -} +#endif // r_normalMapping || USE_PARALLAX_MAPPING -#if defined( TEXTURE_INTEGER ) -const int lightsPerLayer = 16; -uniform usampler3D u_LightTiles; -#define idxs_t uvec4 -idxs_t fetchIdxs( in vec3 coords ) { - return texture3D( u_LightTiles, coords ); -} -int nextIdx( inout idxs_t idxs ) { - uvec4 tmp = ( idxs & uvec4( 3 ) ) * uvec4( 0x40, 0x10, 0x04, 0x01 ); - idxs = idxs >> 2; - return int( tmp.x + tmp.y + tmp.z + tmp.w ); -} -#else -const int lightsPerLayer = 4; -uniform sampler3D u_LightTiles; -#define idxs_t vec4 -idxs_t fetchIdxs( in vec3 coords ) { - return texture3D( u_LightTiles, coords ) * 255.0; -} -int nextIdx( inout idxs_t idxs ) { - vec4 tmp = idxs; - idxs = floor(idxs * 0.25); - tmp -= 4.0 * idxs; - return int( dot( tmp, vec4( 64.0, 16.0, 4.0, 1.0 ) ) ); -} -#endif - -const int numLayers = MAX_REF_LIGHTS / 256; - -void computeDLight( int idx, vec3 P, vec3 N, vec3 I, vec4 diffuse, - vec4 specular, inout vec4 color ) { - vec4 center_radius = GetLight( idx, center_radius ); - vec4 color_type = GetLight( idx, color_type ); - vec3 L; - float attenuation; - - if( color_type.w == 0.0 ) { - // point light - L = center_radius.xyz - P; - attenuation = 1.0 / (1.0 + 8.0 * length(L) / center_radius.w); - L = normalize(L); - } else if( color_type.w == 1.0 ) { - // spot light - vec4 direction_angle = GetLight( idx, direction_angle ); - L = center_radius.xyz - P; - attenuation = 1.0 / (1.0 + 8.0 * length(L) / center_radius.w); - L = normalize( L ); - - if( dot( L, direction_angle.xyz ) <= direction_angle.w ) { - attenuation = 0.0; - } - } else if( color_type.w == 2.0 ) { - // sun (directional) light - L = GetLight( idx, direction_angle ).xyz; - attenuation = 1.0; - } - computeLight( L, N, I, - attenuation * attenuation * color_type.xyz, - diffuse, specular, color ); -} - -void computeDLights( vec3 P, vec3 N, vec3 I, vec4 diffuse, vec4 specular, - inout vec4 color ) { - vec2 tile = floor( gl_FragCoord.xy * (1.0 / float( TILE_SIZE ) ) ) + 0.5; - vec3 tileScale = vec3( r_tileStep, 1.0/numLayers ); - -#if defined(r_showLightTiles) - float numLights = 0.0; -#endif - - for( int layer = 0; layer < numLayers; layer++ ) { - idxs_t idxs = fetchIdxs( tileScale * vec3( tile, float( layer ) + 0.5 ) ); - for( int i = 0; i < lightsPerLayer; i++ ) { - int idx = numLayers * nextIdx( idxs ) + layer; - - if( idx > u_numLights ) - { -#if defined(r_showLightTiles) - if (numLights > 0.0) - { - color = vec4(numLights/(lightsPerLayer*numLayers), numLights/(lightsPerLayer*numLayers), numLights/(lightsPerLayer*numLayers), 1.0); - } -#endif - return; - } - - computeDLight( idx, P, N, I, diffuse, specular, color ); +#if defined(USE_PARALLAX_MAPPING) +uniform float u_ParallaxDepthScale; +uniform float u_ParallaxOffsetBias; +#endif // USE_PARALLAX_MAPPING -#if defined(r_showLightTiles) - numLights++; -#endif - } - } - -#if defined(r_showLightTiles) - if (numLights > 0.0) - { - color = vec4(numLights/(lightsPerLayer*numLayers), numLights/(lightsPerLayer*numLayers), numLights/(lightsPerLayer*numLayers), 1.0); - } -#endif -} +#if defined(r_normalMapping) +uniform vec3 u_NormalFormat; vec3 normalFlip(vec3 normal) { @@ -223,11 +55,14 @@ vec3 normalFlip(vec3 normal) return normal; } +#endif // r_normalMapping // compute normal in tangent space -vec3 NormalInTangentSpace(sampler2D normalMap, vec2 texNormal) +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 @@ -238,7 +73,7 @@ vec3 NormalInTangentSpace(sampler2D normalMap, vec2 texNormal) // // 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(normalMap, texNormal).rga; + 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)); @@ -246,7 +81,7 @@ vec3 NormalInTangentSpace(sampler2D normalMap, vec2 texNormal) else { // alpha channel contains the height map so do not try to restore the normal map from it - normal = texture2D(normalMap, texNormal).rgb; + normal = texture2D(u_NormalMap, texNormal).rgb; normal = 2.0 * normal - 1.0; } @@ -256,14 +91,18 @@ vec3 NormalInTangentSpace(sampler2D normalMap, vec2 texNormal) normal.z *= r_NormalScale; #endif +#else // !r_normalMapping + normal = vec3(0.0, 0.0, 1.0); +#endif // r_normalMapping + return normal; } // compute normal in worldspace from normalmap -vec3 NormalInWorldSpace(sampler2D normalMap, vec2 texNormal, mat3 tangentToWorldMatrix) +vec3 NormalInWorldSpace(vec2 texNormal, mat3 tangentToWorldMatrix) { // compute normal in tangent space from normalmap - vec3 normal = NormalInTangentSpace(normalMap, texNormal); + vec3 normal = NormalInTangentSpace(texNormal); // transform normal into world space return normalize(tangentToWorldMatrix * normal); } @@ -273,18 +112,18 @@ vec3 NormalInWorldSpace(sampler2D normalMap, vec2 texNormal, mat3 tangentToWorld // most of the code doing somewhat the same is likely to be named // RayIntersectDisplaceMap in other id tech3-based engines // so please keep the comment above to enable cross-tree look-up -vec2 ParallaxTexOffset(sampler2D normalMap, vec2 rayStartTexCoords, float parallaxDepthScale, float parallaxOffsetBias, vec3 viewDir, mat3 tangentToWorldMatrix) +vec2 ParallaxTexOffset(vec2 rayStartTexCoords, vec3 viewDir, mat3 tangentToWorldMatrix) { // compute view direction in tangent space vec3 tangentViewDir = normalize(viewDir * tangentToWorldMatrix); - vec2 displacement = tangentViewDir.xy * -parallaxDepthScale / tangentViewDir.z; + vec2 displacement = tangentViewDir.xy * -u_ParallaxDepthScale / tangentViewDir.z; const int linearSearchSteps = 16; const int binarySearchSteps = 6; float depthStep = 1.0 / float(linearSearchSteps); - float topDepth = 1.0 - parallaxOffsetBias; + float topDepth = 1.0 - u_ParallaxOffsetBias; // current size of search window float currentSize = depthStep; @@ -300,7 +139,7 @@ vec2 ParallaxTexOffset(sampler2D normalMap, vec2 rayStartTexCoords, float parall { currentDepth += currentSize; - float heightMapDepth = topDepth - texture2D(normalMap, rayStartTexCoords + displacement * currentDepth).a; + float heightMapDepth = topDepth - texture2D(u_NormalMap, rayStartTexCoords + displacement * currentDepth).a; if(bestDepth > 0.996) // if no depth found yet { @@ -318,7 +157,7 @@ vec2 ParallaxTexOffset(sampler2D normalMap, vec2 rayStartTexCoords, float parall { currentSize *= 0.5; - float heightMapDepth = topDepth - texture2D(normalMap, rayStartTexCoords + displacement * currentDepth).a; + float heightMapDepth = topDepth - texture2D(u_NormalMap, rayStartTexCoords + displacement * currentDepth).a; if(currentDepth >= heightMapDepth) { @@ -331,4 +170,4 @@ vec2 ParallaxTexOffset(sampler2D normalMap, vec2 rayStartTexCoords, float parall return bestDepth * displacement; } -#endif +#endif // USE_PARALLAX_MAPPING diff --git a/src/engine/renderer/glsl_source/vertexLighting_DBS_entity_fp.glsl b/src/engine/renderer/glsl_source/vertexLighting_DBS_entity_fp.glsl index 1bc88639d5..bed8ba05ec 100644 --- a/src/engine/renderer/glsl_source/vertexLighting_DBS_entity_fp.glsl +++ b/src/engine/renderer/glsl_source/vertexLighting_DBS_entity_fp.glsl @@ -23,7 +23,6 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA /* vertexLighting_DBS_entity_fp.glsl */ uniform sampler2D u_DiffuseMap; -uniform sampler2D u_NormalMap; uniform sampler2D u_SpecularMap; uniform sampler2D u_GlowMap; @@ -33,8 +32,6 @@ uniform float u_EnvironmentInterpolation; uniform float u_AlphaThreshold; uniform vec3 u_ViewOrigin; -uniform float u_ParallaxDepthScale; -uniform float u_ParallaxOffsetBias; uniform sampler3D u_LightGrid1; uniform sampler3D u_LightGrid2; @@ -44,7 +41,8 @@ uniform vec3 u_LightGridScale; IN(smooth) vec3 var_Position; IN(smooth) vec2 var_TexDiffuse; IN(smooth) vec4 var_Color; -IN(smooth) vec4 var_TexNormalSpecular; +IN(smooth) vec2 var_TexNormal; +IN(smooth) vec2 var_TexSpecular; IN(smooth) vec3 var_Tangent; IN(smooth) vec3 var_Binormal; IN(smooth) vec2 var_TexGlow; @@ -85,17 +83,17 @@ void main() // compute view direction in world space vec3 viewDir = normalize(u_ViewOrigin - var_Position); - vec2 texDiffuse = var_TexDiffuse.st; + vec2 texDiffuse = var_TexDiffuse; vec2 texGlow = var_TexGlow; mat3 tangentToWorldMatrix = mat3(var_Tangent.xyz, var_Binormal.xyz, var_Normal.xyz); - vec2 texNormal = var_TexNormalSpecular.xy; - vec2 texSpecular = var_TexNormalSpecular.zw; + vec2 texNormal = var_TexNormal; + vec2 texSpecular = var_TexSpecular; #if defined(USE_PARALLAX_MAPPING) // compute texcoords offset from heightmap - vec2 texOffset = ParallaxTexOffset(u_NormalMap, texNormal, u_ParallaxDepthScale, u_ParallaxOffsetBias, viewDir, tangentToWorldMatrix); + vec2 texOffset = ParallaxTexOffset(texNormal, viewDir, tangentToWorldMatrix); texDiffuse += texOffset; texGlow += texOffset; @@ -104,7 +102,7 @@ void main() #endif // USE_PARALLAX_MAPPING // compute normal in world space from normalmap - vec3 N = NormalInWorldSpace(u_NormalMap, texNormal, tangentToWorldMatrix); + vec3 N = NormalInWorldSpace(texNormal, tangentToWorldMatrix); // compute the specular term #if defined(USE_REFLECTIVE_SPECULAR) @@ -147,7 +145,9 @@ void main() color.rgb += 0.7 * emission; #endif +#if defined(r_glowMapping) color.rgb += texture2D(u_GlowMap, texGlow).rgb; +#endif // r_glowMapping outputColor = color; diff --git a/src/engine/renderer/glsl_source/vertexLighting_DBS_entity_vp.glsl b/src/engine/renderer/glsl_source/vertexLighting_DBS_entity_vp.glsl index bdac6a85ba..089a5ce77b 100644 --- a/src/engine/renderer/glsl_source/vertexLighting_DBS_entity_vp.glsl +++ b/src/engine/renderer/glsl_source/vertexLighting_DBS_entity_vp.glsl @@ -34,7 +34,8 @@ uniform float u_Time; OUT(smooth) vec3 var_Position; OUT(smooth) vec2 var_TexDiffuse; OUT(smooth) vec4 var_Color; -OUT(smooth) vec4 var_TexNormalSpecular; +OUT(smooth) vec2 var_TexNormal; +OUT(smooth) vec2 var_TexSpecular; OUT(smooth) vec3 var_Tangent; OUT(smooth) vec3 var_Binormal; OUT(smooth) vec2 var_TexGlow; @@ -77,10 +78,11 @@ void main() var_Color = color; // transform normalmap texcoords - var_TexNormalSpecular.xy = (u_NormalTextureMatrix * vec4(texCoord, 0.0, 1.0)).st; + var_TexNormal = (u_NormalTextureMatrix * vec4(texCoord, 0.0, 1.0)).st; // transform specularmap texture coords - var_TexNormalSpecular.zw = (u_SpecularTextureMatrix * vec4(texCoord, 0.0, 1.0)).st; + var_TexSpecular = (u_SpecularTextureMatrix * vec4(texCoord, 0.0, 1.0)).st; + // transform glowmap texcoords var_TexGlow = (u_GlowTextureMatrix * vec4(texCoord, 0.0, 1.0)).st; } diff --git a/src/engine/renderer/glsl_source/vertexLighting_DBS_world_fp.glsl b/src/engine/renderer/glsl_source/vertexLighting_DBS_world_fp.glsl index 3bdc6cff77..4c284767b1 100644 --- a/src/engine/renderer/glsl_source/vertexLighting_DBS_world_fp.glsl +++ b/src/engine/renderer/glsl_source/vertexLighting_DBS_world_fp.glsl @@ -23,13 +23,10 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA /* vertexLighting_DBS_world_fp.glsl */ uniform sampler2D u_DiffuseMap; -uniform sampler2D u_NormalMap; uniform sampler2D u_SpecularMap; uniform sampler2D u_GlowMap; uniform float u_AlphaThreshold; -uniform float u_ParallaxDepthScale; -uniform float u_ParallaxOffsetBias; uniform float u_LightWrapAround; uniform sampler3D u_LightGrid1; @@ -40,10 +37,12 @@ uniform vec3 u_LightGridScale; uniform vec3 u_ViewOrigin; IN(smooth) vec3 var_Position; -IN(smooth) vec4 var_TexDiffuseGlow; +IN(smooth) vec2 var_TexDiffuse; +IN(smooth) vec2 var_TexGlow; IN(smooth) vec4 var_Color; -IN(smooth) vec4 var_TexNormalSpecular; +IN(smooth) vec2 var_TexNormal; +IN(smooth) vec2 var_TexSpecular; IN(smooth) vec3 var_Tangent; IN(smooth) vec3 var_Binormal; @@ -73,8 +72,8 @@ void ReadLightGrid(in vec3 pos, out vec3 lgtDir, void main() { - vec2 texDiffuse = var_TexDiffuseGlow.st; - vec2 texGlow = var_TexDiffuseGlow.pq; + vec2 texDiffuse = var_TexDiffuse; + vec2 texGlow = var_TexGlow; // compute view direction in world space vec3 viewDir = normalize(u_ViewOrigin - var_Position); @@ -85,12 +84,12 @@ void main() ReadLightGrid( (var_Position - u_LightGridOrigin) * u_LightGridScale, L, ambCol, dirCol); - vec2 texNormal = var_TexNormalSpecular.st; - vec2 texSpecular = var_TexNormalSpecular.pq; + vec2 texNormal = var_TexNormal; + vec2 texSpecular = var_TexSpecular; #if defined(USE_PARALLAX_MAPPING) // compute texcoords offset from heightmap - vec2 texOffset = ParallaxTexOffset(u_NormalMap, texNormal, u_ParallaxDepthScale, u_ParallaxOffsetBias, viewDir, tangentToWorldMatrix); + vec2 texOffset = ParallaxTexOffset(texNormal, viewDir, tangentToWorldMatrix); texDiffuse += texOffset; texGlow += texOffset; @@ -110,7 +109,7 @@ void main() vec4 specular = texture2D(u_SpecularMap, texSpecular); // compute normal in world space from normalmap - vec3 N = NormalInWorldSpace(u_NormalMap, texNormal, tangentToWorldMatrix); + vec3 N = NormalInWorldSpace(texNormal, tangentToWorldMatrix); // compute final color vec4 color = vec4( ambCol * diffuse.xyz, diffuse.a ); @@ -118,7 +117,9 @@ void main() computeDLights( var_Position, N, viewDir, diffuse, specular, color ); +#if defined(r_glowMapping) color.rgb += texture2D(u_GlowMap, texGlow).rgb; +#endif // r_glowMapping outputColor = color; } diff --git a/src/engine/renderer/glsl_source/vertexLighting_DBS_world_vp.glsl b/src/engine/renderer/glsl_source/vertexLighting_DBS_world_vp.glsl index 7aa792824f..92fb9b2020 100644 --- a/src/engine/renderer/glsl_source/vertexLighting_DBS_world_vp.glsl +++ b/src/engine/renderer/glsl_source/vertexLighting_DBS_world_vp.glsl @@ -34,10 +34,12 @@ uniform vec4 u_ColorModulate; uniform vec4 u_Color; OUT(smooth) vec3 var_Position; -OUT(smooth) vec4 var_TexDiffuseGlow; +OUT(smooth) vec2 var_TexDiffuse; +OUT(smooth) vec2 var_TexGlow; OUT(smooth) vec4 var_Color; -OUT(smooth) vec4 var_TexNormalSpecular; +OUT(smooth) vec2 var_TexNormal; +OUT(smooth) vec2 var_TexSpecular; OUT(smooth) vec3 var_Tangent; OUT(smooth) vec3 var_Binormal; @@ -73,21 +75,22 @@ void main() var_Position = position.xyz; // transform diffusemap texcoords - var_TexDiffuseGlow.st = (u_DiffuseTextureMatrix * vec4(texCoord, 0.0, 1.0)).st; + var_TexDiffuse = (u_DiffuseTextureMatrix * vec4(texCoord, 0.0, 1.0)).st; // assign color var_Color = color; // transform normalmap texcoords - var_TexNormalSpecular.st = (u_NormalTextureMatrix * vec4(texCoord, 0.0, 1.0)).st; + var_TexNormal = (u_NormalTextureMatrix * vec4(texCoord, 0.0, 1.0)).st; // transform specularmap texture coords - var_TexNormalSpecular.pq = (u_SpecularTextureMatrix * vec4(texCoord, 0.0, 1.0)).st; + var_TexSpecular = (u_SpecularTextureMatrix * vec4(texCoord, 0.0, 1.0)).st; var_Tangent = LB.tangent; var_Binormal = LB.binormal; var_Normal = LB.normal; - var_TexDiffuseGlow.pq = ( u_GlowTextureMatrix * vec4(texCoord, 0.0, 1.0) ).st; + // transform glowmap texture coords + var_TexGlow = ( u_GlowTextureMatrix * vec4(texCoord, 0.0, 1.0) ).st; } diff --git a/src/engine/renderer/shaders.cpp b/src/engine/renderer/shaders.cpp index 05db63795a..99527efbe8 100644 --- a/src/engine/renderer/shaders.cpp +++ b/src/engine/renderer/shaders.cpp @@ -19,6 +19,7 @@ #include "glsl/blurY_vp.h" #include "glsl/cameraEffects_fp.h" #include "glsl/cameraEffects_vp.h" +#include "glsl/computeLight_fp.h" #include "glsl/contrast_fp.h" #include "glsl/contrast_vp.h" #include "glsl/debugShadowMap_fp.h" @@ -75,6 +76,7 @@ std::unordered_map shadermap({ { "glsl/blurY_vp.glsl", std::string((char*)blurY_vp_glsl, blurY_vp_glsl_len) }, { "glsl/cameraEffects_fp.glsl", std::string((char*)cameraEffects_fp_glsl, cameraEffects_fp_glsl_len) }, { "glsl/cameraEffects_vp.glsl", std::string((char*)cameraEffects_vp_glsl, cameraEffects_vp_glsl_len) }, + { "glsl/computeLight_fp.glsl", std::string((char*)computeLight_fp_glsl, computeLight_fp_glsl_len) }, { "glsl/contrast_fp.glsl", std::string((char*)contrast_fp_glsl, contrast_fp_glsl_len) }, { "glsl/contrast_vp.glsl", std::string((char*)contrast_vp_glsl, contrast_vp_glsl_len) }, { "glsl/debugShadowMap_fp.glsl", std::string((char*)debugShadowMap_fp_glsl, debugShadowMap_fp_glsl_len) }, diff --git a/src/engine/renderer/tr_init.cpp b/src/engine/renderer/tr_init.cpp index 003f5fce1b..a904a8ccfa 100644 --- a/src/engine/renderer/tr_init.cpp +++ b/src/engine/renderer/tr_init.cpp @@ -158,12 +158,20 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA cvar_t *r_textureMode; cvar_t *r_offsetFactor; cvar_t *r_offsetUnits; - cvar_t *r_forceSpecular; + cvar_t *r_specularExponentMin; cvar_t *r_specularExponentMax; cvar_t *r_specularScale; + cvar_t *r_specularMapping; + cvar_t *r_deluxeMapping; cvar_t *r_normalScale; cvar_t *r_normalMapping; + cvar_t *r_highQualityNormalMapping; + cvar_t *r_parallaxDepthScale; + cvar_t *r_parallaxMapping; + cvar_t *r_glowMapping; + cvar_t *r_reflectionMapping; + cvar_t *r_wrapAroundLighting; cvar_t *r_halfLambertLighting; cvar_t *r_rimLighting; @@ -235,11 +243,7 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA cvar_t *r_vboDeformVertexes; cvar_t *r_mergeLeafSurfaces; - cvar_t *r_parallaxMapping; - cvar_t *r_parallaxDepthScale; - cvar_t *r_reflectionMapping; - cvar_t *r_highQualityNormalMapping; cvar_t *r_bloom; cvar_t *r_bloomBlur; cvar_t *r_bloomPasses; @@ -1076,7 +1080,6 @@ ScreenshotCmd screenshotPNGRegistration("screenshotPNG", ssFormat_t::SSF_PNG, "p r_customaspect = ri.Cvar_Get( "r_customaspect", "1", CVAR_LATCH ); r_simpleMipMaps = ri.Cvar_Get( "r_simpleMipMaps", "0", CVAR_LATCH ); r_subdivisions = ri.Cvar_Get( "r_subdivisions", "4", CVAR_LATCH ); - r_parallaxMapping = ri.Cvar_Get( "r_parallaxMapping", "0", 0 ); r_dynamicLightCastShadows = ri.Cvar_Get( "r_dynamicLightCastShadows", "1", 0 ); r_precomputedLighting = ri.Cvar_Get( "r_precomputedLighting", "1", CVAR_SHADER ); r_vertexLighting = ri.Cvar_Get( "r_vertexLighting", "0", CVAR_LATCH | CVAR_ARCHIVE ); @@ -1091,9 +1094,6 @@ ScreenshotCmd screenshotPNGRegistration("screenshotPNG", ssFormat_t::SSF_PNG, "p r_wolfFog = ri.Cvar_Get( "r_wolfFog", "1", CVAR_CHEAT ); r_noFog = ri.Cvar_Get( "r_noFog", "0", CVAR_CHEAT ); - r_reflectionMapping = ri.Cvar_Get( "r_reflectionMapping", "0", CVAR_CHEAT ); - r_highQualityNormalMapping = ri.Cvar_Get( "r_highQualityNormalMapping", "0", CVAR_LATCH ); - r_forceAmbient = ri.Cvar_Get( "r_forceAmbient", "0.125", CVAR_LATCH ); AssertCvarRange( r_forceAmbient, 0.0f, 0.3f, false ); @@ -1190,13 +1190,19 @@ ScreenshotCmd screenshotPNGRegistration("screenshotPNG", ssFormat_t::SSF_PNG, "p r_clear = ri.Cvar_Get( "r_clear", "0", CVAR_CHEAT ); r_offsetFactor = ri.Cvar_Get( "r_offsetFactor", "-1", CVAR_CHEAT ); r_offsetUnits = ri.Cvar_Get( "r_offsetUnits", "-2", CVAR_CHEAT ); - r_forceSpecular = ri.Cvar_Get( "r_forceSpecular", "0", CVAR_CHEAT ); + r_specularExponentMin = ri.Cvar_Get( "r_specularExponentMin", "0", CVAR_CHEAT ); r_specularExponentMax = ri.Cvar_Get( "r_specularExponentMax", "16", CVAR_CHEAT ); r_specularScale = ri.Cvar_Get( "r_specularScale", "1.0", CVAR_CHEAT | CVAR_SHADER ); + r_specularMapping = ri.Cvar_Get( "r_specularMapping", "1", CVAR_LATCH ); + r_deluxeMapping = ri.Cvar_Get( "r_deluxeMapping", "1", CVAR_ARCHIVE ); r_normalScale = ri.Cvar_Get( "r_normalScale", "1.0", CVAR_SHADER ); r_normalMapping = ri.Cvar_Get( "r_normalMapping", "1", CVAR_ARCHIVE ); + r_highQualityNormalMapping = ri.Cvar_Get( "r_highQualityNormalMapping", "0", CVAR_LATCH ); r_parallaxDepthScale = ri.Cvar_Get( "r_parallaxDepthScale", "0.03", CVAR_CHEAT ); + r_parallaxMapping = ri.Cvar_Get( "r_parallaxMapping", "0", 0 ); + r_glowMapping = ri.Cvar_Get( "r_glowMapping", "1", CVAR_LATCH ); + r_reflectionMapping = ri.Cvar_Get( "r_reflectionMapping", "0", CVAR_CHEAT ); r_wrapAroundLighting = ri.Cvar_Get( "r_wrapAroundLighting", "0.7", CVAR_CHEAT | CVAR_SHADER ); r_halfLambertLighting = ri.Cvar_Get( "r_halfLambertLighting", "1", CVAR_CHEAT | CVAR_SHADER ); diff --git a/src/engine/renderer/tr_local.h b/src/engine/renderer/tr_local.h index b198428c0c..702f23d072 100644 --- a/src/engine/renderer/tr_local.h +++ b/src/engine/renderer/tr_local.h @@ -2848,12 +2848,20 @@ static inline void halfToFloat( const f16vec4_t in, vec4_t out ) extern cvar_t *r_textureMode; extern cvar_t *r_offsetFactor; extern cvar_t *r_offsetUnits; - extern cvar_t *r_forceSpecular; + extern cvar_t *r_specularExponentMin; extern cvar_t *r_specularExponentMax; extern cvar_t *r_specularScale; + extern cvar_t *r_specularMapping; + extern cvar_t *r_deluxeMapping; extern cvar_t *r_normalScale; extern cvar_t *r_normalMapping; + extern cvar_t *r_highQualityNormalMapping; + extern cvar_t *r_parallaxDepthScale; + extern cvar_t *r_parallaxMapping; + extern cvar_t *r_glowMapping; + extern cvar_t *r_reflectionMapping; + extern cvar_t *r_wrapAroundLighting; extern cvar_t *r_halfLambertLighting; extern cvar_t *r_rimLighting; @@ -2962,11 +2970,6 @@ static inline void halfToFloat( const f16vec4_t in, vec4_t out ) extern cvar_t *r_vboDeformVertexes; extern cvar_t *r_mergeLeafSurfaces; - extern cvar_t *r_parallaxMapping; - extern cvar_t *r_parallaxDepthScale; - - extern cvar_t *r_reflectionMapping; - extern cvar_t *r_highQualityNormalMapping; extern cvar_t *r_bloom; extern cvar_t *r_bloomBlur; diff --git a/src/engine/renderer/tr_shade.cpp b/src/engine/renderer/tr_shade.cpp index 05ea9816c9..07a940e783 100644 --- a/src/engine/renderer/tr_shade.cpp +++ b/src/engine/renderer/tr_shade.cpp @@ -721,7 +721,10 @@ static void Render_vertexLighting_DBS_entity( int stage ) GL_State( stateBits ); bool normalMapping = r_normalMapping->integer && ( pStage->bundle[ TB_NORMALMAP ].image[ 0 ] != nullptr ); - bool glowMapping = ( pStage->bundle[ TB_GLOWMAP ].image[ 0 ] != nullptr ); + bool heightMapInNormalMap = tess.surfaceShader->heightMapInNormalMap && ( pStage->bundle[ TB_NORMALMAP ].image[ 0 ] != nullptr ); + bool parallaxMapping = r_parallaxMapping->integer && tess.surfaceShader->parallax && !tess.surfaceShader->noParallax && heightMapInNormalMap; + bool specularMapping = r_specularMapping->integer && ( pStage->bundle[ TB_SPECULARMAP ].image[ 0 ] ); + bool glowMapping = r_glowMapping->integer && ( pStage->bundle[ TB_GLOWMAP ].image[ 0 ] != nullptr ); bool materialMapping = hasMaterialMapping( tess.surfaceShader ); // choose right shader program ---------------------------------- @@ -732,7 +735,7 @@ static void Render_vertexLighting_DBS_entity( int stage ) GL_BindToTMU( 8, tr.lighttileRenderImage ); - gl_vertexLightingShader_DBS_entity->SetParallaxMapping( normalMapping && r_parallaxMapping->integer && tess.surfaceShader->parallax && !tess.surfaceShader->noParallax ); + gl_vertexLightingShader_DBS_entity->SetParallaxMapping( parallaxMapping ); gl_vertexLightingShader_DBS_entity->SetReflectiveSpecular( normalMapping && tr.cubeHashTable != nullptr ); @@ -783,7 +786,7 @@ static void Render_vertexLighting_DBS_entity( int stage ) // u_DeformGen gl_vertexLightingShader_DBS_entity->SetUniform_Time( backEnd.refdef.floatTime - backEnd.currentEntity->e.shaderTime ); - if ( r_parallaxMapping->integer && tess.surfaceShader->parallax && !tess.surfaceShader->noParallax ) + if ( parallaxMapping ) { float depthScale; float parallaxDepthScale; @@ -800,10 +803,13 @@ static void Render_vertexLighting_DBS_entity( int stage ) GL_BindToTMU( 0, pStage->bundle[ TB_DIFFUSEMAP ].image[ 0 ] ); gl_vertexLightingShader_DBS_entity->SetUniform_DiffuseTextureMatrix( tess.svars.texMatrices[ TB_DIFFUSEMAP ] ); - // bind u_NormalMap - if ( pStage->bundle[ TB_NORMALMAP ].image[ 0 ] ) + if ( normalMapping || heightMapInNormalMap ) { + // bind u_NormalMap GL_BindToTMU( 1, pStage->bundle[ TB_NORMALMAP ].image[ 0 ] ); + + // bind u_NormalFormat + gl_vertexLightingShader_DBS_entity->SetUniform_NormalFormat( tess.surfaceShader->normalFormat ); } else { @@ -812,13 +818,15 @@ static void Render_vertexLighting_DBS_entity( int stage ) gl_vertexLightingShader_DBS_entity->SetUniform_NormalTextureMatrix( tess.svars.texMatrices[ TB_NORMALMAP ] ); - // bind u_NormalFormat - gl_vertexLightingShader_DBS_entity->SetUniform_NormalFormat( tess.surfaceShader->normalFormat ); - - // bind u_SpecularMap - if ( pStage->bundle[ TB_SPECULARMAP ].image[ 0 ] ) + if ( specularMapping ) { + // bind u_SpecularMap GL_BindToTMU( 2, pStage->bundle[ TB_SPECULARMAP ].image[ 0 ] ); + + float minSpec = RB_EvalExpression( &pStage->specularExponentMin, r_specularExponentMin->value ); + float maxSpec = RB_EvalExpression( &pStage->specularExponentMax, r_specularExponentMax->value ); + + gl_vertexLightingShader_DBS_entity->SetUniform_SpecularExponent( minSpec, maxSpec ); } else { @@ -827,11 +835,6 @@ static void Render_vertexLighting_DBS_entity( int stage ) gl_vertexLightingShader_DBS_entity->SetUniform_SpecularTextureMatrix( tess.svars.texMatrices[ TB_SPECULARMAP ] ); - float minSpec = RB_EvalExpression( &pStage->specularExponentMin, r_specularExponentMin->value ); - float maxSpec = RB_EvalExpression( &pStage->specularExponentMax, r_specularExponentMax->value ); - - gl_vertexLightingShader_DBS_entity->SetUniform_SpecularExponent( minSpec, maxSpec ); - if ( tr.cubeHashTable != nullptr ) { cubemapProbe_t *cubeProbeNearest; @@ -952,12 +955,15 @@ static void Render_vertexLighting_DBS_world( int stage ) stateBits = pStage->stateBits; bool normalMapping = r_normalMapping->integer && ( pStage->bundle[ TB_NORMALMAP ].image[ 0 ] != nullptr ); - bool glowMapping = ( pStage->bundle[ TB_GLOWMAP ].image[ 0 ] != nullptr ); + bool heightMapInNormalMap = tess.surfaceShader->heightMapInNormalMap && ( pStage->bundle[ TB_NORMALMAP ].image[ 0 ] != nullptr ); + bool parallaxMapping = r_parallaxMapping->integer && tess.surfaceShader->parallax && !tess.surfaceShader->noParallax && heightMapInNormalMap; + bool specularMapping = r_specularMapping->integer && ( pStage->bundle[ TB_SPECULARMAP ].image[ 0 ] ); + bool glowMapping = r_glowMapping->integer && ( pStage->bundle[ TB_GLOWMAP ].image[ 0 ] != nullptr ); // choose right shader program ---------------------------------- GL_BindToTMU( 8, tr.lighttileRenderImage ); - gl_vertexLightingShader_DBS_world->SetParallaxMapping( normalMapping && r_parallaxMapping->integer && tess.surfaceShader->parallax && !tess.surfaceShader->noParallax ); + gl_vertexLightingShader_DBS_world->SetParallaxMapping( parallaxMapping ); tess.vboVertexSprite = false; @@ -1027,7 +1033,7 @@ 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 ); - if ( r_parallaxMapping->integer ) + if ( parallaxMapping ) { float depthScale; float parallaxDepthScale; @@ -1049,10 +1055,13 @@ static void Render_vertexLighting_DBS_world( int stage ) GL_BindToTMU( 0, pStage->bundle[ TB_DIFFUSEMAP ].image[ 0 ] ); gl_vertexLightingShader_DBS_world->SetUniform_DiffuseTextureMatrix( tess.svars.texMatrices[ TB_DIFFUSEMAP ] ); - // bind u_NormalMap - if ( pStage->bundle[ TB_NORMALMAP ].image[ 0 ] ) + if ( normalMapping || heightMapInNormalMap ) { + // bind u_NormalMap GL_BindToTMU( 1, pStage->bundle[ TB_NORMALMAP ].image[ 0 ] ); + + // bind u_NormalFormat + gl_vertexLightingShader_DBS_world->SetUniform_NormalFormat( tess.surfaceShader->normalFormat ); } else { @@ -1061,13 +1070,15 @@ static void Render_vertexLighting_DBS_world( int stage ) gl_vertexLightingShader_DBS_world->SetUniform_NormalTextureMatrix( tess.svars.texMatrices[ TB_NORMALMAP ] ); - // bind u_NormalFormat - gl_vertexLightingShader_DBS_world->SetUniform_NormalFormat( tess.surfaceShader->normalFormat ); - - // bind u_SpecularMap - if ( pStage->bundle[ TB_SPECULARMAP ].image[ 0 ] ) + if ( specularMapping ) { + // bind u_SpecularMap GL_BindToTMU( 2, pStage->bundle[ TB_SPECULARMAP ].image[ 0 ] ); + + float minSpec = RB_EvalExpression( &pStage->specularExponentMin, r_specularExponentMin->value ); + float maxSpec = RB_EvalExpression( &pStage->specularExponentMax, r_specularExponentMax->value ); + + gl_vertexLightingShader_DBS_world->SetUniform_SpecularExponent( minSpec, maxSpec ); } else { @@ -1076,11 +1087,6 @@ static void Render_vertexLighting_DBS_world( int stage ) gl_vertexLightingShader_DBS_world->SetUniform_SpecularTextureMatrix( tess.svars.texMatrices[ TB_SPECULARMAP ] ); - float minSpec = RB_EvalExpression( &pStage->specularExponentMin, r_specularExponentMin->value ); - float maxSpec = RB_EvalExpression( &pStage->specularExponentMax, r_specularExponentMax->value ); - - gl_vertexLightingShader_DBS_world->SetUniform_SpecularExponent( minSpec, maxSpec ); - if ( tr.lightGrid1Image && tr.lightGrid2Image ) { GL_BindToTMU( 6, tr.lightGrid1Image ); GL_BindToTMU( 7, tr.lightGrid2Image ); @@ -1110,7 +1116,6 @@ static void Render_lightMapping( int stage, bool asColorMap, bool normalMapping, uint32_t stateBits; colorGen_t rgbGen; alphaGen_t alphaGen; - bool glowMapping = false; GLimp_LogComment( "--- Render_lightMapping ---\n" ); @@ -1149,20 +1154,19 @@ static void Render_lightMapping( int stage, bool asColorMap, bool normalMapping, GL_State( stateBits ); - if ( pStage->bundle[ TB_NORMALMAP ].image[ 0 ] == nullptr ) - { - normalMapping = false; - } - - if ( pStage->bundle[ TB_GLOWMAP ].image[ 0 ] != nullptr ) - { - glowMapping = true; - } + bool deluxeMapping = r_deluxeMapping->integer && tr.worldDeluxeMapping; + normalMapping = normalMapping && deluxeMapping && ( pStage->bundle[ TB_NORMALMAP ].image[ 0 ] != nullptr ); + bool heightMapInNormalMap = tess.surfaceShader->heightMapInNormalMap && ( pStage->bundle[ TB_NORMALMAP ].image[ 0 ] != nullptr ); + bool parallaxMapping = r_parallaxMapping->integer && tess.surfaceShader->parallax && !tess.surfaceShader->noParallax && heightMapInNormalMap; + bool specularMapping = r_specularMapping->integer && ( pStage->bundle[ TB_SPECULARMAP ].image[ 0 ] ); + bool glowMapping = r_glowMapping->integer && ( pStage->bundle[ TB_GLOWMAP ].image[ 0 ] != nullptr ); // choose right shader program ---------------------------------- GL_BindToTMU( 8, tr.lighttileRenderImage ); - gl_lightMappingShader->SetParallaxMapping( normalMapping && r_parallaxMapping->integer && tess.surfaceShader->parallax && !tess.surfaceShader->noParallax ); + gl_lightMappingShader->SetDeluxeMapping( deluxeMapping ); + + gl_lightMappingShader->SetParallaxMapping( parallaxMapping ); tess.vboVertexSprite = false; @@ -1196,7 +1200,7 @@ static void Render_lightMapping( int stage, bool asColorMap, bool normalMapping, // u_Color gl_lightMappingShader->SetUniform_Color( tess.svars.color ); - if ( r_parallaxMapping->integer ) + if ( parallaxMapping ) { float depthScale; float parallaxDepthScale; @@ -1221,9 +1225,12 @@ static void Render_lightMapping( int stage, bool asColorMap, bool normalMapping, } // bind u_NormalMap - if ( normalMapping ) + if ( normalMapping || heightMapInNormalMap ) { GL_BindToTMU( 1, pStage->bundle[ TB_NORMALMAP ].image[ 0 ] ); + + // bind u_NormalFormat + gl_lightMappingShader->SetUniform_NormalFormat( tess.surfaceShader->normalFormat ); } else { @@ -1232,13 +1239,15 @@ static void Render_lightMapping( int stage, bool asColorMap, bool normalMapping, gl_lightMappingShader->SetUniform_NormalTextureMatrix( tess.svars.texMatrices[ TB_NORMALMAP ] ); - // bind u_NormalFormat - gl_lightMappingShader->SetUniform_NormalFormat( tess.surfaceShader->normalFormat ); - - // bind u_SpecularMap - if ( pStage->bundle[ TB_SPECULARMAP ].image[ 0 ] ) + if ( specularMapping ) { + // bind u_SpecularMap GL_BindToTMU( 2, pStage->bundle[ TB_SPECULARMAP ].image[ 0 ] ); + + 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 { @@ -1247,13 +1256,8 @@ static void Render_lightMapping( int stage, bool asColorMap, bool normalMapping, gl_lightMappingShader->SetUniform_SpecularTextureMatrix( tess.svars.texMatrices[ TB_SPECULARMAP ] ); - 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_DeluxeMap - if ( normalMapping ) + if ( deluxeMapping ) { BindDeluxeMap( 4 ); } @@ -1454,15 +1458,17 @@ static void Render_forwardLighting_DBS_omni( shaderStage_t *diffuseStage, GLimp_LogComment( "--- Render_forwardLighting_DBS_omni ---\n" ); bool normalMapping = r_normalMapping->integer && ( diffuseStage->bundle[ TB_NORMALMAP ].image[ 0 ] != nullptr ); - + bool heightMapInNormalMap = tess.surfaceShader->heightMapInNormalMap && ( diffuseStage->bundle[ TB_NORMALMAP ].image[ 0 ] != nullptr ); + bool parallaxMapping = r_parallaxMapping->integer && tess.surfaceShader->parallax && !tess.surfaceShader->noParallax && heightMapInNormalMap; + bool specularMapping = r_specularMapping->integer && ( diffuseStage->bundle[ TB_SPECULARMAP ].image[ 0 ] ); 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->SetParallaxMapping( normalMapping && r_parallaxMapping->integer && tess.surfaceShader->parallax && !tess.surfaceShader->noParallax ); - + gl_forwardLightingShader_omniXYZ->SetParallaxMapping( parallaxMapping ); + gl_forwardLightingShader_omniXYZ->SetShadowing( shadowCompare ); gl_forwardLightingShader_omniXYZ->BindProgram( diffuseStage->deformIndex ); @@ -1503,7 +1509,7 @@ static void Render_forwardLighting_DBS_omni( shaderStage_t *diffuseStage, gl_forwardLightingShader_omniXYZ->SetUniform_AlphaTest( diffuseStage->stateBits ); - if ( r_parallaxMapping->integer ) + if ( parallaxMapping ) { float depthScale; float parallaxDepthScale; @@ -1572,10 +1578,13 @@ static void Render_forwardLighting_DBS_omni( shaderStage_t *diffuseStage, GL_BindToTMU( 0, diffuseStage->bundle[ TB_DIFFUSEMAP ].image[ 0 ] ); gl_forwardLightingShader_omniXYZ->SetUniform_DiffuseTextureMatrix( tess.svars.texMatrices[ TB_DIFFUSEMAP ] ); - // bind u_NormalMap - if ( diffuseStage->bundle[ TB_NORMALMAP ].image[ 0 ] ) + if ( normalMapping || heightMapInNormalMap ) { + // bind u_NormalMap GL_BindToTMU( 1, diffuseStage->bundle[ TB_NORMALMAP ].image[ 0 ] ); + + // bind u_NormalFormat + gl_forwardLightingShader_omniXYZ->SetUniform_NormalFormat( tess.surfaceShader->normalFormat ); } else { @@ -1584,17 +1593,15 @@ static void Render_forwardLighting_DBS_omni( shaderStage_t *diffuseStage, gl_forwardLightingShader_omniXYZ->SetUniform_NormalTextureMatrix( tess.svars.texMatrices[ TB_NORMALMAP ] ); - // bind u_NormalFormat - gl_forwardLightingShader_omniXYZ->SetUniform_NormalFormat( tess.surfaceShader->normalFormat ); - - // bind u_SpecularMap - if ( r_forceSpecular->integer ) - { - GL_BindToTMU( 2, diffuseStage->bundle[ TB_DIFFUSEMAP ].image[ 0 ] ); - } - else if ( diffuseStage->bundle[ TB_SPECULARMAP ].image[ 0 ] ) + if ( specularMapping ) { + // bind u_SpecularMap GL_BindToTMU( 2, diffuseStage->bundle[ TB_SPECULARMAP ].image[ 0 ] ); + + float minSpec = RB_EvalExpression( &diffuseStage->specularExponentMin, r_specularExponentMin->value ); + float maxSpec = RB_EvalExpression( &diffuseStage->specularExponentMax, r_specularExponentMax->value ); + + gl_forwardLightingShader_omniXYZ->SetUniform_SpecularExponent( minSpec, maxSpec ); } else { @@ -1603,11 +1610,6 @@ static void Render_forwardLighting_DBS_omni( shaderStage_t *diffuseStage, gl_forwardLightingShader_omniXYZ->SetUniform_SpecularTextureMatrix( tess.svars.texMatrices[ TB_SPECULARMAP ] ); - float minSpec = RB_EvalExpression( &diffuseStage->specularExponentMin, r_specularExponentMin->value ); - float maxSpec = RB_EvalExpression( &diffuseStage->specularExponentMax, r_specularExponentMax->value ); - - gl_forwardLightingShader_omniXYZ->SetUniform_SpecularExponent( minSpec, maxSpec ); - // bind u_AttenuationMapXY GL_SelectTexture( 3 ); BindAnimatedImage( &attenuationXYStage->bundle[ TB_COLORMAP ] ); @@ -1646,15 +1648,17 @@ static void Render_forwardLighting_DBS_proj( shaderStage_t *diffuseStage, GLimp_LogComment( "--- Render_fowardLighting_DBS_proj ---\n" ); bool normalMapping = r_normalMapping->integer && ( diffuseStage->bundle[ TB_NORMALMAP ].image[ 0 ] != nullptr ); - + bool heightMapInNormalMap = tess.surfaceShader->heightMapInNormalMap && ( diffuseStage->bundle[ TB_NORMALMAP ].image[ 0 ] != nullptr ); + bool parallaxMapping = r_parallaxMapping->integer && tess.surfaceShader->parallax && !tess.surfaceShader->noParallax && heightMapInNormalMap; + bool specularMapping = r_specularMapping->integer && ( diffuseStage->bundle[ TB_SPECULARMAP ].image[ 0 ] ); 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->SetParallaxMapping( normalMapping && r_parallaxMapping->integer && tess.surfaceShader->parallax && !tess.surfaceShader->noParallax ); - + gl_forwardLightingShader_projXYZ->SetParallaxMapping( parallaxMapping ); + gl_forwardLightingShader_projXYZ->SetShadowing( shadowCompare ); gl_forwardLightingShader_projXYZ->BindProgram( diffuseStage->deformIndex ); @@ -1695,7 +1699,7 @@ static void Render_forwardLighting_DBS_proj( shaderStage_t *diffuseStage, gl_forwardLightingShader_projXYZ->SetUniform_AlphaTest( diffuseStage->stateBits ); - if ( r_parallaxMapping->integer ) + if ( parallaxMapping ) { float depthScale; float parallaxDepthScale; @@ -1765,10 +1769,13 @@ static void Render_forwardLighting_DBS_proj( shaderStage_t *diffuseStage, GL_BindToTMU( 0, diffuseStage->bundle[ TB_DIFFUSEMAP ].image[ 0 ] ); gl_forwardLightingShader_projXYZ->SetUniform_DiffuseTextureMatrix( tess.svars.texMatrices[ TB_DIFFUSEMAP ] ); - // bind u_NormalMap - if ( diffuseStage->bundle[ TB_NORMALMAP ].image[ 0 ] ) + if ( normalMapping || heightMapInNormalMap ) { + // bind u_NormalMap GL_BindToTMU( 1, diffuseStage->bundle[ TB_NORMALMAP ].image[ 0 ] ); + + // bind u_NormalFormat + gl_forwardLightingShader_projXYZ->SetUniform_NormalFormat( tess.surfaceShader->normalFormat ); } else { @@ -1777,17 +1784,15 @@ static void Render_forwardLighting_DBS_proj( shaderStage_t *diffuseStage, gl_forwardLightingShader_projXYZ->SetUniform_NormalTextureMatrix( tess.svars.texMatrices[ TB_NORMALMAP ] ); - // bind u_NormalFormat - gl_forwardLightingShader_projXYZ->SetUniform_NormalFormat( tess.surfaceShader->normalFormat ); - - // bind u_SpecularMap - if ( r_forceSpecular->integer ) - { - GL_BindToTMU( 2, diffuseStage->bundle[ TB_DIFFUSEMAP ].image[ 0 ] ); - } - else if ( diffuseStage->bundle[ TB_SPECULARMAP ].image[ 0 ] ) + if ( specularMapping ) { + // bind u_SpecularMap GL_BindToTMU( 2, diffuseStage->bundle[ TB_SPECULARMAP ].image[ 0 ] ); + + float minSpec = RB_EvalExpression( &diffuseStage->specularExponentMin, r_specularExponentMin->value ); + float maxSpec = RB_EvalExpression( &diffuseStage->specularExponentMax, r_specularExponentMax->value ); + + gl_forwardLightingShader_projXYZ->SetUniform_SpecularExponent( minSpec, maxSpec ); } else { @@ -1796,11 +1801,6 @@ static void Render_forwardLighting_DBS_proj( shaderStage_t *diffuseStage, gl_forwardLightingShader_projXYZ->SetUniform_SpecularTextureMatrix( tess.svars.texMatrices[ TB_SPECULARMAP ] ); - float minSpec = RB_EvalExpression( &diffuseStage->specularExponentMin, r_specularExponentMin->value ); - float maxSpec = RB_EvalExpression( &diffuseStage->specularExponentMax, r_specularExponentMax->value ); - - gl_forwardLightingShader_projXYZ->SetUniform_SpecularExponent( minSpec, maxSpec ); - // bind u_AttenuationMapXY GL_SelectTexture( 3 ); BindAnimatedImage( &attenuationXYStage->bundle[ TB_COLORMAP ] ); @@ -1837,14 +1837,16 @@ static void Render_forwardLighting_DBS_directional( shaderStage_t *diffuseStage, GLimp_LogComment( "--- Render_forwardLighting_DBS_directional ---\n" ); bool normalMapping = r_normalMapping->integer && ( diffuseStage->bundle[ TB_NORMALMAP ].image[ 0 ] != nullptr ); - + bool heightMapInNormalMap = tess.surfaceShader->heightMapInNormalMap && ( diffuseStage->bundle[ TB_NORMALMAP ].image[ 0 ] != nullptr ); + bool parallaxMapping = r_parallaxMapping->integer && tess.surfaceShader->parallax && !tess.surfaceShader->noParallax && heightMapInNormalMap; + bool specularMapping = r_specularMapping->integer && ( diffuseStage->bundle[ TB_SPECULARMAP ].image[ 0 ] ); 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->SetParallaxMapping( normalMapping && r_parallaxMapping->integer && tess.surfaceShader->parallax && !tess.surfaceShader->noParallax ); + gl_forwardLightingShader_directionalSun->SetParallaxMapping( parallaxMapping ); gl_forwardLightingShader_directionalSun->SetShadowing( shadowCompare ); @@ -1886,7 +1888,7 @@ static void Render_forwardLighting_DBS_directional( shaderStage_t *diffuseStage, gl_forwardLightingShader_directionalSun->SetUniform_AlphaTest( diffuseStage->stateBits ); - if ( r_parallaxMapping->integer ) + if ( parallaxMapping ) { float depthScale; float parallaxDepthScale; @@ -1960,10 +1962,13 @@ static void Render_forwardLighting_DBS_directional( shaderStage_t *diffuseStage, GL_BindToTMU( 0, diffuseStage->bundle[ TB_DIFFUSEMAP ].image[ 0 ] ); gl_forwardLightingShader_directionalSun->SetUniform_DiffuseTextureMatrix( tess.svars.texMatrices[ TB_DIFFUSEMAP ] ); - // bind u_NormalMap - if ( diffuseStage->bundle[ TB_NORMALMAP ].image[ 0 ] ) + if ( normalMapping || heightMapInNormalMap ) { + // bind u_NormalMap GL_BindToTMU( 1, diffuseStage->bundle[ TB_NORMALMAP ].image[ 0 ] ); + + // bind u_NormalFormat + gl_forwardLightingShader_directionalSun->SetUniform_NormalFormat( tess.surfaceShader->normalFormat ); } else { @@ -1972,17 +1977,15 @@ static void Render_forwardLighting_DBS_directional( shaderStage_t *diffuseStage, gl_forwardLightingShader_directionalSun->SetUniform_NormalTextureMatrix( tess.svars.texMatrices[ TB_NORMALMAP ] ); - // bind u_NormalFormat - gl_forwardLightingShader_directionalSun->SetUniform_NormalFormat( tess.surfaceShader->normalFormat ); - - // bind u_SpecularMap - if ( r_forceSpecular->integer ) - { - GL_BindToTMU( 2, diffuseStage->bundle[ TB_DIFFUSEMAP ].image[ 0 ] ); - } - else if ( diffuseStage->bundle[ TB_SPECULARMAP ].image[ 0 ] ) + if ( specularMapping ) { + // bind u_SpecularMap GL_BindToTMU( 2, diffuseStage->bundle[ TB_SPECULARMAP ].image[ 0 ] ); + + float minSpec = RB_EvalExpression( &diffuseStage->specularExponentMin, r_specularExponentMin->value ); + float maxSpec = RB_EvalExpression( &diffuseStage->specularExponentMax, r_specularExponentMax->value ); + + gl_forwardLightingShader_directionalSun->SetUniform_SpecularExponent( minSpec, maxSpec ); } else { @@ -1991,11 +1994,6 @@ static void Render_forwardLighting_DBS_directional( shaderStage_t *diffuseStage, gl_forwardLightingShader_directionalSun->SetUniform_SpecularTextureMatrix( tess.svars.texMatrices[ TB_SPECULARMAP ] ); - float minSpec = RB_EvalExpression( &diffuseStage->specularExponentMin, r_specularExponentMin->value ); - float maxSpec = RB_EvalExpression( &diffuseStage->specularExponentMax, r_specularExponentMax->value ); - - gl_forwardLightingShader_directionalSun->SetUniform_SpecularExponent( minSpec, maxSpec ); - // bind u_ShadowMap if ( shadowCompare ) { @@ -2042,7 +2040,13 @@ static void Render_reflection_CB( int stage ) GL_State( pStage->stateBits ); + bool normalMapping = r_normalMapping->integer && ( pStage->bundle[ TB_NORMALMAP ].image[ 0 ] != nullptr ); + bool heightMapInNormalMap = tess.surfaceShader->heightMapInNormalMap && ( pStage->bundle[ TB_NORMALMAP ].image[ 0 ] != nullptr ); + bool parallaxMapping = r_parallaxMapping->integer && tess.surfaceShader->parallax && !tess.surfaceShader->noParallax && heightMapInNormalMap; + // choose right shader program ---------------------------------- + gl_reflectionShader->SetParallaxMapping( parallaxMapping ); + gl_reflectionShader->SetVertexSkinning( glConfig2.vboVertexSkinningAvailable && tess.vboVertexSkinning ); gl_reflectionShader->SetVertexAnimation( glState.vertexAttribsInterpolation > 0 ); @@ -2050,8 +2054,6 @@ static void Render_reflection_CB( int stage ) // end choose right shader program ------------------------------ - gl_reflectionShader->SetParallaxMapping(r_parallaxMapping->integer && tess.surfaceShader->parallax && !tess.surfaceShader->noParallax); - gl_reflectionShader->SetUniform_ViewOrigin( backEnd.viewParms.orientation.origin ); // in world space gl_reflectionShader->SetUniform_ModelMatrix( backEnd.orientation.transformMatrix ); @@ -2080,9 +2082,9 @@ static void Render_reflection_CB( int stage ) GL_BindNearestCubeMap( backEnd.viewParms.orientation.origin ); } - // bind u_NormalMap - if ( pStage->bundle[ TB_NORMALMAP ].image[ 0 ] != nullptr ) + if ( normalMapping || heightMapInNormalMap ) { + // bind u_NormalMap GL_BindToTMU( 1, pStage->bundle[ TB_NORMALMAP ].image[ 0 ] ); } else { @@ -2092,7 +2094,7 @@ static void Render_reflection_CB( int stage ) gl_reflectionShader->SetUniform_NormalTextureMatrix( tess.svars.texMatrices[ TB_NORMALMAP ] ); // bind u_depthScale u_parallaxOffsetBias - if ( r_parallaxMapping->integer ) + if ( parallaxMapping ) { float depthScale; float parallaxDepthScale; @@ -2204,6 +2206,8 @@ static void Render_heatHaze( int stage ) GLimp_LogComment( "--- Render_heatHaze ---\n" ); + bool normalMapping = r_normalMapping->integer && ( pStage->bundle[ TB_COLORMAP ].image[ 0 ] != nullptr ); + // remove alpha test stateBits = pStage->stateBits; stateBits &= ~GLS_ATEST_BITS; @@ -2263,12 +2267,16 @@ static void Render_heatHaze( int stage ) // draw to background image R_BindFBO( tr.mainFBO[ 1 - backEnd.currentMainFBO ] ); - // bind u_NormalMap - GL_BindToTMU( 0, pStage->bundle[ TB_COLORMAP ].image[ 0 ] ); - gl_heatHazeShader->SetUniform_NormalTextureMatrix( tess.svars.texMatrices[ TB_COLORMAP ] ); + if ( normalMapping ) + { + // bind u_NormalMap + GL_BindToTMU( 0, pStage->bundle[ TB_COLORMAP ].image[ 0 ] ); - // bind u_NormalFormat - gl_heatHazeShader->SetUniform_NormalFormat( tess.surfaceShader->normalFormat ); + gl_heatHazeShader->SetUniform_NormalTextureMatrix( tess.svars.texMatrices[ TB_COLORMAP ] ); + + // bind u_NormalFormat + gl_heatHazeShader->SetUniform_NormalFormat( tess.surfaceShader->normalFormat ); + } GL_BindToTMU( 1, tr.currentRenderImage[ backEnd.currentMainFBO ] ); @@ -2295,11 +2303,16 @@ static void Render_liquid( int stage ) GLimp_LogComment( "--- Render_liquid ---\n" ); + bool normalMapping = r_normalMapping->integer && ( pStage->bundle[ TB_COLORMAP ].image[ 0 ] != nullptr ); + bool heightMapInNormalMap = tess.surfaceShader->heightMapInNormalMap && ( pStage->bundle[ TB_NORMALMAP ].image[ 0 ] != nullptr ); + bool parallaxMapping = r_parallaxMapping->integer && tess.surfaceShader->parallax && !tess.surfaceShader->noParallax && heightMapInNormalMap; + bool specularMapping = r_specularMapping->integer; // TODO: specular map? + // 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->SetParallaxMapping(r_parallaxMapping->integer && tess.surfaceShader->parallax && !tess.surfaceShader->noParallax); + gl_liquidShader->SetParallaxMapping( parallaxMapping ); // enable shader, set arrays gl_liquidShader->BindProgram( pStage->deformIndex ); @@ -2324,9 +2337,12 @@ static void Render_liquid( int stage ) gl_liquidShader->SetUniform_ModelMatrix( backEnd.orientation.transformMatrix ); gl_liquidShader->SetUniform_ModelViewProjectionMatrix( glState.modelViewProjectionMatrix[ glState.stackIndex ] ); - float specMin = RB_EvalExpression( &pStage->specularExponentMin, r_specularExponentMin->value ); - float specMax = RB_EvalExpression( &pStage->specularExponentMax, r_specularExponentMax->value ); - gl_liquidShader->SetUniform_SpecularExponent( specMin, specMax ); + if ( specularMapping ) + { + float specMin = RB_EvalExpression( &pStage->specularExponentMin, r_specularExponentMin->value ); + float specMax = RB_EvalExpression( &pStage->specularExponentMax, r_specularExponentMax->value ); + gl_liquidShader->SetUniform_SpecularExponent( specMin, specMax ); + } GL_BindToTMU( 0, tr.currentRenderImage[ backEnd.currentMainFBO ] ); @@ -2336,12 +2352,16 @@ static void Render_liquid( int stage ) // depth texture GL_BindToTMU( 2, tr.currentDepthImage ); - // bind u_NormalMap - GL_BindToTMU( 3, pStage->bundle[ TB_COLORMAP ].image[ 0 ] ); - gl_liquidShader->SetUniform_NormalTextureMatrix( tess.svars.texMatrices[ TB_COLORMAP ] ); + if ( normalMapping || heightMapInNormalMap ) + { + // bind u_NormalMap + GL_BindToTMU( 3, pStage->bundle[ TB_COLORMAP ].image[ 0 ] ); - // bind u_NormalFormat - gl_liquidShader->SetUniform_NormalFormat( tess.surfaceShader->normalFormat ); + // bind u_NormalFormat + gl_liquidShader->SetUniform_NormalFormat( tess.surfaceShader->normalFormat ); + } + + gl_liquidShader->SetUniform_NormalTextureMatrix( tess.svars.texMatrices[ TB_COLORMAP ] ); Tess_DrawElements();