diff --git a/src.cmake b/src.cmake index 48d50a2f41..9a322532dd 100644 --- a/src.cmake +++ b/src.cmake @@ -135,10 +135,6 @@ set(GLSLSOURCELIST ${ENGINE_DIR}/renderer/glsl_source/ssao_fp.glsl ${ENGINE_DIR}/renderer/glsl_source/ssao_vp.glsl ${ENGINE_DIR}/renderer/glsl_source/vertexAnimation_vp.glsl - ${ENGINE_DIR}/renderer/glsl_source/vertexLighting_DBS_entity_fp.glsl - ${ENGINE_DIR}/renderer/glsl_source/vertexLighting_DBS_entity_vp.glsl - ${ENGINE_DIR}/renderer/glsl_source/vertexLighting_DBS_world_fp.glsl - ${ENGINE_DIR}/renderer/glsl_source/vertexLighting_DBS_world_vp.glsl ${ENGINE_DIR}/renderer/glsl_source/vertexSimple_vp.glsl ${ENGINE_DIR}/renderer/glsl_source/vertexSkinning_vp.glsl ${ENGINE_DIR}/renderer/glsl_source/vertexSprite_vp.glsl diff --git a/src/engine/renderer/gl_shader.cpp b/src/engine/renderer/gl_shader.cpp index 13424bb199..6d61ae4407 100644 --- a/src/engine/renderer/gl_shader.cpp +++ b/src/engine/renderer/gl_shader.cpp @@ -37,8 +37,6 @@ ShaderKind shaderKind = ShaderKind::Unknown; GLShader_generic *gl_genericShader = nullptr; GLShader_lightMapping *gl_lightMappingShader = nullptr; -GLShader_vertexLighting_DBS_entity *gl_vertexLightingShader_DBS_entity = nullptr; -GLShader_vertexLighting_DBS_world *gl_vertexLightingShader_DBS_world = nullptr; GLShader_forwardLighting_omniXYZ *gl_forwardLightingShader_omniXYZ = nullptr; GLShader_forwardLighting_projXYZ *gl_forwardLightingShader_projXYZ = nullptr; GLShader_forwardLighting_directionalSun *gl_forwardLightingShader_directionalSun = nullptr; @@ -1470,62 +1468,14 @@ void GLShader_generic::SetShaderProgramUniforms( shaderProgram_t *shaderProgram } GLShader_lightMapping::GLShader_lightMapping( GLShaderManager *manager ) : - GLShader( "lightMapping", ATTR_POSITION | ATTR_TEXCOORD | ATTR_QTANGENT | ATTR_COLOR, manager ), + GLShader( "lightMapping", + ATTR_POSITION | ATTR_TEXCOORD | ATTR_QTANGENT | ATTR_COLOR, manager ), u_TextureMatrix( this ), u_SpecularExponent( this ), u_ColorModulate( this ), u_Color( this ), u_AlphaThreshold( this ), u_ViewOrigin( this ), - u_ModelViewProjectionMatrix( this ), - u_ParallaxDepthScale( this ), - u_ParallaxOffsetBias( this ), - u_NormalScale( this ), - u_numLights( this ), - u_Lights( this ), - GLDeformStage( this ), - GLCompileMacro_USE_DELUXE_MAPPING( this ), - GLCompileMacro_USE_HEIGHTMAP_IN_NORMALMAP( this ), - GLCompileMacro_USE_PARALLAX_MAPPING( this ), - GLCompileMacro_USE_PHYSICAL_SHADING( this ) -{ -} - -void GLShader_lightMapping::BuildShaderVertexLibNames( std::string& vertexInlines ) -{ - vertexInlines += "vertexSimple vertexSkinning vertexAnimation vertexSprite "; -} - -void GLShader_lightMapping::BuildShaderFragmentLibNames( std::string& fragmentInlines ) -{ - fragmentInlines += "computeLight reliefMapping"; -} - -void GLShader_lightMapping::BuildShaderCompileMacros( std::string& /*compileMacros*/ ) -{ -} - -void GLShader_lightMapping::SetShaderProgramUniforms( shaderProgram_t *shaderProgram ) -{ - glUniform1i( glGetUniformLocation( shaderProgram->program, "u_DiffuseMap" ), 0 ); - glUniform1i( glGetUniformLocation( shaderProgram->program, "u_NormalMap" ), 1 ); - glUniform1i( glGetUniformLocation( shaderProgram->program, "u_MaterialMap" ), 2 ); - glUniform1i( glGetUniformLocation( shaderProgram->program, "u_LightMap" ), 3 ); - glUniform1i( glGetUniformLocation( shaderProgram->program, "u_DeluxeMap" ), 4 ); - glUniform1i( glGetUniformLocation( shaderProgram->program, "u_GlowMap" ), 5 ); - glUniform1i( glGetUniformLocation( shaderProgram->program, "u_LightTiles" ), 8 ); - if( !glConfig2.uniformBufferObjectAvailable ) { - glUniform1i( glGetUniformLocation( shaderProgram->program, "u_Lights" ), 9 ); - } - glUniform1i( glGetUniformLocation( shaderProgram->program, "u_HeightMap" ), 15 ); -} - -GLShader_vertexLighting_DBS_entity::GLShader_vertexLighting_DBS_entity( GLShaderManager *manager ) : - GLShader( "vertexLighting_DBS_entity", ATTR_POSITION | ATTR_TEXCOORD | ATTR_QTANGENT, manager ), - u_TextureMatrix( this ), - u_SpecularExponent( this ), - u_AlphaThreshold( this ), - u_ViewOrigin( this ), u_ModelMatrix( this ), u_ModelViewProjectionMatrix( this ), u_Bones( this ), @@ -1534,13 +1484,17 @@ GLShader_vertexLighting_DBS_entity::GLShader_vertexLighting_DBS_entity( GLShader u_ParallaxOffsetBias( this ), u_NormalScale( this ), u_EnvironmentInterpolation( this ), + u_LightWrapAround( this ), u_LightGridOrigin( this ), u_LightGridScale( this ), u_numLights( this ), u_Lights( this ), GLDeformStage( this ), + GLCompileMacro_USE_BSP_SURFACE( this ), GLCompileMacro_USE_VERTEX_SKINNING( this ), GLCompileMacro_USE_VERTEX_ANIMATION( this ), + GLCompileMacro_USE_LIGHT_MAPPING( this ), + GLCompileMacro_USE_DELUXE_MAPPING( this ), GLCompileMacro_USE_HEIGHTMAP_IN_NORMALMAP( this ), GLCompileMacro_USE_PARALLAX_MAPPING( this ), GLCompileMacro_USE_REFLECTIVE_SPECULAR( this ), @@ -1548,91 +1502,35 @@ GLShader_vertexLighting_DBS_entity::GLShader_vertexLighting_DBS_entity( GLShader { } -void GLShader_vertexLighting_DBS_entity::BuildShaderVertexLibNames( std::string& vertexInlines ) -{ - vertexInlines += "vertexSimple vertexSkinning vertexAnimation "; -} - -void GLShader_vertexLighting_DBS_entity::BuildShaderFragmentLibNames( std::string& fragmentInlines ) -{ - fragmentInlines += "computeLight reliefMapping"; -} - -void GLShader_vertexLighting_DBS_entity::BuildShaderCompileMacros( std::string& ) -{ -} - -void GLShader_vertexLighting_DBS_entity::SetShaderProgramUniforms( shaderProgram_t *shaderProgram ) -{ - glUniform1i( glGetUniformLocation( shaderProgram->program, "u_DiffuseMap" ), 0 ); - glUniform1i( glGetUniformLocation( shaderProgram->program, "u_NormalMap" ), 1 ); - glUniform1i( glGetUniformLocation( shaderProgram->program, "u_MaterialMap" ), 2 ); - glUniform1i( glGetUniformLocation( shaderProgram->program, "u_EnvironmentMap0" ), 3 ); - glUniform1i( glGetUniformLocation( shaderProgram->program, "u_EnvironmentMap1" ), 4 ); - glUniform1i( glGetUniformLocation( shaderProgram->program, "u_GlowMap" ), 5 ); - glUniform1i( glGetUniformLocation( shaderProgram->program, "u_LightGrid1" ), 6 ); - glUniform1i( glGetUniformLocation( shaderProgram->program, "u_LightGrid2" ), 7 ); - glUniform1i( glGetUniformLocation( shaderProgram->program, "u_LightTiles" ), 8 ); - if( !glConfig2.uniformBufferObjectAvailable ) { - glUniform1i( glGetUniformLocation( shaderProgram->program, "u_Lights" ), 9 ); - } - glUniform1i( glGetUniformLocation( shaderProgram->program, "u_HeightMap" ), 15 ); -} - -GLShader_vertexLighting_DBS_world::GLShader_vertexLighting_DBS_world( GLShaderManager *manager ) : - GLShader( "vertexLighting_DBS_world", - ATTR_POSITION | ATTR_TEXCOORD | ATTR_QTANGENT | ATTR_COLOR, - manager - ), - u_TextureMatrix( this ), - u_SpecularExponent( this ), - u_ColorModulate( this ), - u_Color( this ), - u_AlphaThreshold( this ), - u_ViewOrigin( this ), - u_ModelMatrix( this ), - u_ModelViewProjectionMatrix( this ), - u_ParallaxDepthScale( this ), - u_ParallaxOffsetBias( this ), - u_NormalScale( this ), - u_LightWrapAround( this ), - u_LightGridOrigin( this ), - u_LightGridScale( this ), - u_numLights( this ), - u_Lights( this ), - GLDeformStage( this ), - GLCompileMacro_USE_HEIGHTMAP_IN_NORMALMAP( this ), - GLCompileMacro_USE_PARALLAX_MAPPING( this ), - GLCompileMacro_USE_PHYSICAL_SHADING( this ) -{ -} - -void GLShader_vertexLighting_DBS_world::BuildShaderVertexLibNames( std::string& vertexInlines ) +void GLShader_lightMapping::BuildShaderVertexLibNames( std::string& vertexInlines ) { vertexInlines += "vertexSimple vertexSkinning vertexAnimation vertexSprite "; } -void GLShader_vertexLighting_DBS_world::BuildShaderFragmentLibNames( std::string& fragmentInlines ) + +void GLShader_lightMapping::BuildShaderFragmentLibNames( std::string& fragmentInlines ) { fragmentInlines += "computeLight reliefMapping"; } -void GLShader_vertexLighting_DBS_world::BuildShaderCompileMacros( std::string& ) +void GLShader_lightMapping::BuildShaderCompileMacros( std::string& /*compileMacros*/ ) { } -void GLShader_vertexLighting_DBS_world::SetShaderProgramUniforms( shaderProgram_t *shaderProgram ) +void GLShader_lightMapping::SetShaderProgramUniforms( shaderProgram_t *shaderProgram ) { - glUniform1i( glGetUniformLocation( shaderProgram->program, "u_DiffuseMap" ), 0 ); - glUniform1i( glGetUniformLocation( shaderProgram->program, "u_NormalMap" ), 1 ); - glUniform1i( glGetUniformLocation( shaderProgram->program, "u_MaterialMap" ), 2 ); - glUniform1i( glGetUniformLocation( shaderProgram->program, "u_GlowMap" ), 5 ); - glUniform1i( glGetUniformLocation( shaderProgram->program, "u_LightGrid1" ), 6 ); - glUniform1i( glGetUniformLocation( shaderProgram->program, "u_LightGrid2" ), 7 ); - glUniform1i( glGetUniformLocation( shaderProgram->program, "u_LightTiles" ), 8 ); + glUniform1i( glGetUniformLocation( shaderProgram->program, "u_DiffuseMap" ), BIND_DIFFUSEMAP ); + glUniform1i( glGetUniformLocation( shaderProgram->program, "u_NormalMap" ), BIND_NORMALMAP ); + glUniform1i( glGetUniformLocation( shaderProgram->program, "u_HeightMap" ), BIND_HEIGHTMAP ); + glUniform1i( glGetUniformLocation( shaderProgram->program, "u_MaterialMap" ), BIND_MATERIALMAP ); + glUniform1i( glGetUniformLocation( shaderProgram->program, "u_LightMap" ), BIND_LIGHTMAP ); + glUniform1i( glGetUniformLocation( shaderProgram->program, "u_DeluxeMap" ), BIND_DELUXEMAP ); + glUniform1i( glGetUniformLocation( shaderProgram->program, "u_GlowMap" ), BIND_GLOWMAP ); + glUniform1i( glGetUniformLocation( shaderProgram->program, "u_EnvironmentMap0" ), BIND_ENVIRONMENTMAP0 ); + glUniform1i( glGetUniformLocation( shaderProgram->program, "u_EnvironmentMap1" ), BIND_ENVIRONMENTMAP1 ); + glUniform1i( glGetUniformLocation( shaderProgram->program, "u_LightTiles" ), BIND_LIGHTTILES ); if( !glConfig2.uniformBufferObjectAvailable ) { - glUniform1i( glGetUniformLocation( shaderProgram->program, "u_Lights" ), 9 ); + glUniform1i( glGetUniformLocation( shaderProgram->program, "u_Lights" ), BIND_LIGHTS ); } - glUniform1i( glGetUniformLocation( shaderProgram->program, "u_HeightMap" ), 15 ); } GLShader_forwardLighting_omniXYZ::GLShader_forwardLighting_omniXYZ( GLShaderManager *manager ): diff --git a/src/engine/renderer/gl_shader.h b/src/engine/renderer/gl_shader.h index 1f99f2e26e..427a81d2d8 100644 --- a/src/engine/renderer/gl_shader.h +++ b/src/engine/renderer/gl_shader.h @@ -778,11 +778,13 @@ class GLCompileMacro // It also works regardless of RTTI is enabled or not. enum EGLCompileMacro { + USE_BSP_SURFACE, USE_VERTEX_SKINNING, USE_VERTEX_ANIMATION, USE_VERTEX_SPRITE, USE_TCGEN_ENVIRONMENT, USE_TCGEN_LIGHTMAP, + USE_LIGHT_MAPPING, USE_DELUXE_MAPPING, USE_HEIGHTMAP_IN_NORMALMAP, USE_PARALLAX_MAPPING, @@ -837,6 +839,31 @@ class GLCompileMacro virtual ~GLCompileMacro() = default; }; +class GLCompileMacro_USE_BSP_SURFACE : + GLCompileMacro +{ +public: + GLCompileMacro_USE_BSP_SURFACE( GLShader *shader ) : + GLCompileMacro( shader ) + { + } + + const char *GetName() const + { + return "USE_BSP_SURFACE"; + } + + EGLCompileMacro GetType() const + { + return EGLCompileMacro::USE_BSP_SURFACE; + } + + void SetBspSurface( bool enable ) + { + SetMacro( enable ); + } +}; + class GLCompileMacro_USE_VERTEX_SKINNING : GLCompileMacro { @@ -985,6 +1012,31 @@ class GLCompileMacro_USE_TCGEN_LIGHTMAP : } }; +class GLCompileMacro_USE_LIGHT_MAPPING : + GLCompileMacro +{ +public: + GLCompileMacro_USE_LIGHT_MAPPING( GLShader *shader ) : + GLCompileMacro( shader ) + { + } + + const char *GetName() const + { + return "USE_LIGHT_MAPPING"; + } + + EGLCompileMacro GetType() const + { + return EGLCompileMacro::USE_LIGHT_MAPPING; + } + + void SetLightMapping( bool enable ) + { + SetMacro( enable ); + } +}; + class GLCompileMacro_USE_DELUXE_MAPPING : GLCompileMacro { @@ -2173,32 +2225,6 @@ class GLShader_lightMapping : public u_Color, public u_AlphaThreshold, public u_ViewOrigin, - public u_ModelViewProjectionMatrix, - public u_ParallaxDepthScale, - public u_ParallaxOffsetBias, - public u_NormalScale, - public u_numLights, - public u_Lights, - public GLDeformStage, - public GLCompileMacro_USE_DELUXE_MAPPING, - public GLCompileMacro_USE_HEIGHTMAP_IN_NORMALMAP, - public GLCompileMacro_USE_PARALLAX_MAPPING, - public GLCompileMacro_USE_PHYSICAL_SHADING -{ -public: - GLShader_lightMapping( GLShaderManager *manager ); - void BuildShaderVertexLibNames( std::string& vertexInlines ); - void BuildShaderFragmentLibNames( std::string& fragmentInlines ); - void BuildShaderCompileMacros( std::string& compileMacros ); - void SetShaderProgramUniforms( shaderProgram_t *shaderProgram ); -}; - -class GLShader_vertexLighting_DBS_entity : - public GLShader, - public u_TextureMatrix, - public u_SpecularExponent, - public u_AlphaThreshold, - public u_ViewOrigin, public u_ModelMatrix, public u_ModelViewProjectionMatrix, public u_Bones, @@ -2207,51 +2233,24 @@ class GLShader_vertexLighting_DBS_entity : public u_ParallaxOffsetBias, public u_NormalScale, public u_EnvironmentInterpolation, + public u_LightWrapAround, public u_LightGridOrigin, public u_LightGridScale, public u_numLights, public u_Lights, public GLDeformStage, + public GLCompileMacro_USE_BSP_SURFACE, public GLCompileMacro_USE_VERTEX_SKINNING, public GLCompileMacro_USE_VERTEX_ANIMATION, + public GLCompileMacro_USE_LIGHT_MAPPING, + public GLCompileMacro_USE_DELUXE_MAPPING, public GLCompileMacro_USE_HEIGHTMAP_IN_NORMALMAP, public GLCompileMacro_USE_PARALLAX_MAPPING, public GLCompileMacro_USE_REFLECTIVE_SPECULAR, public GLCompileMacro_USE_PHYSICAL_SHADING { public: - GLShader_vertexLighting_DBS_entity( GLShaderManager *manager ); - void BuildShaderVertexLibNames( std::string& vertexInlines ); - void BuildShaderFragmentLibNames( std::string& fragmentInlines ); - void BuildShaderCompileMacros( std::string& compileMacros ); - void SetShaderProgramUniforms( shaderProgram_t *shaderProgram ); -}; - -class GLShader_vertexLighting_DBS_world : - public GLShader, - public u_TextureMatrix, - public u_SpecularExponent, - public u_ColorModulate, - public u_Color, - public u_AlphaThreshold, - public u_ViewOrigin, - public u_ModelMatrix, - public u_ModelViewProjectionMatrix, - public u_ParallaxDepthScale, - public u_ParallaxOffsetBias, - public u_NormalScale, - public u_LightWrapAround, - public u_LightGridOrigin, - public u_LightGridScale, - public u_numLights, - public u_Lights, - public GLDeformStage, - public GLCompileMacro_USE_HEIGHTMAP_IN_NORMALMAP, - public GLCompileMacro_USE_PARALLAX_MAPPING, - public GLCompileMacro_USE_PHYSICAL_SHADING -{ -public: - GLShader_vertexLighting_DBS_world( GLShaderManager *manager ); + GLShader_lightMapping( GLShaderManager *manager ); void BuildShaderVertexLibNames( std::string& vertexInlines ); void BuildShaderFragmentLibNames( std::string& fragmentInlines ); void BuildShaderCompileMacros( std::string& compileMacros ); @@ -2705,8 +2704,6 @@ extern ShaderKind shaderKind; extern GLShader_generic *gl_genericShader; extern GLShader_lightMapping *gl_lightMappingShader; -extern GLShader_vertexLighting_DBS_entity *gl_vertexLightingShader_DBS_entity; -extern GLShader_vertexLighting_DBS_world *gl_vertexLightingShader_DBS_world; extern GLShader_forwardLighting_omniXYZ *gl_forwardLightingShader_omniXYZ; extern GLShader_forwardLighting_projXYZ *gl_forwardLightingShader_projXYZ; extern GLShader_forwardLighting_directionalSun *gl_forwardLightingShader_directionalSun; diff --git a/src/engine/renderer/glsl_source/lightMapping_fp.glsl b/src/engine/renderer/glsl_source/lightMapping_fp.glsl index 6e88b98054..69d6a871e8 100644 --- a/src/engine/renderer/glsl_source/lightMapping_fp.glsl +++ b/src/engine/renderer/glsl_source/lightMapping_fp.glsl @@ -26,111 +26,188 @@ uniform sampler2D u_DiffuseMap; uniform sampler2D u_MaterialMap; uniform sampler2D u_GlowMap; -uniform sampler2D u_LightMap; -uniform sampler2D u_DeluxeMap; - uniform float u_AlphaThreshold; uniform vec3 u_ViewOrigin; IN(smooth) vec3 var_Position; IN(smooth) vec2 var_TexCoords; -IN(smooth) vec2 var_TexLight; IN(smooth) vec4 var_Color; IN(smooth) vec3 var_Tangent; IN(smooth) vec3 var_Binormal; IN(smooth) vec3 var_Normal; +#if defined(USE_BSP_SURFACE) && defined(USE_LIGHT_MAPPING) && !defined(USE_DELUXE_MAPPING) +/* HACK: restore legacy behavior for bsp surface with lightmap +but no deluxemap, do not use the lightgrid to compute the light +direction, do not do normal mapping neither specular mapping +with static lights. +https://github.com/DaemonEngine/Daemon/issues/324 + +Comment out this line to enable lightgrid light direction with +lightmap light color when there is no deluxe map. +*/ + #define HACK_NO_BSP_GRID_LIGHTDIR +#endif + +#if defined(USE_LIGHT_MAPPING) + uniform sampler2D u_LightMap; +#else + uniform sampler3D u_LightMap; + #define u_LightGrid1 u_LightMap +#endif + +#if defined(USE_DELUXE_MAPPING) + uniform sampler2D u_DeluxeMap; +#else + uniform sampler3D u_DeluxeMap; + #define u_LightGrid2 u_DeluxeMap +#endif + +#if defined(USE_LIGHT_MAPPING) || defined(USE_DELUXE_MAPPING) + IN(smooth) vec2 var_TexLight; +#endif + +#if !defined(USE_LIGHT_MAPPING) || !defined(USE_DELUXE_MAPPING) + uniform vec3 u_LightGridOrigin; + uniform vec3 u_LightGridScale; +#endif + DECLARE_OUTPUT(vec4) -void main() +void main() { - // compute view direction in world space + // Compute view direction in world space. vec3 viewDir = normalize(u_ViewOrigin - var_Position); vec2 texCoords = var_TexCoords; 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(texCoords, viewDir, tangentToWorldMatrix); + #if defined(USE_PARALLAX_MAPPING) + // Compute texcoords offset from heightmap. + vec2 texOffset = ParallaxTexOffset(texCoords, viewDir, tangentToWorldMatrix); - texCoords += texOffset; -#endif // USE_PARALLAX_MAPPING + texCoords += texOffset; + #endif - // compute the diffuse term + // Compute the diffuse term. vec4 diffuse = texture2D(u_DiffuseMap, texCoords); - // vertex blend operation like: alphaGen vertex + // Apply vertex blend operation like: alphaGen vertex. diffuse *= var_Color; - if( abs(diffuse.a + u_AlphaThreshold) <= 1.0 ) + if(abs(diffuse.a + u_AlphaThreshold) <= 1.0) { discard; return; } - // compute normal in world space from normalmap + // Compute normal in world space from normalmap. vec3 normal = NormalInWorldSpace(texCoords, tangentToWorldMatrix); - // compute the material term + // Compute the material term. vec4 material = texture2D(u_MaterialMap, texCoords); - // compute light color from world space lightmap - vec3 lightColor = texture2D(u_LightMap, var_TexLight).rgb; - - // compute final color - 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); - vec3 lightDir = normalize(2.0 * deluxe.xyz - 1.0); - - // Lightmaps generated by q3map2 don't store the raw light value, but - // they store light premultiplied with the dot product of the light - // direction and surface normal. The line is just an attempt to reverse - // that and get the original light values. - // The lightmap stores the light in this way because for the diffuse - // lighting formula the outgoing light is equal to the incoming light - // multiplied by the above dot product multiplied by the surface albedo. - // So this premultiplication means that the diffuse lighting value can - // be calculated with a single multiply operation. - // But specular lighting and/or normal mapping formulas are more complex, - // and so you need the true light value to get correct lighting. - // Obviously the data is not good enough to recover the original color - // in all cases. The lower bound was an arbitrary chose factor to - // prevent too small divisors resulting in too bright lights. Increasing - // the value should reduce these artifacts. -- gimhael - // https://github.com/DaemonEngine/Daemon/issues/299#issuecomment-606186347 - - // divide by cosine term to restore original light color - lightColor /= clamp(dot(normalize(var_Normal), lightDir), 0.3, 1.0); - - computeLight(lightDir, normal, viewDir, lightColor, diffuse, material, color); -#else // !USE_DELUXE_MAPPING - // normal/deluxe mapping is disabled - color.rgb += lightColor.rgb * diffuse.rgb; -#endif // USE_DELUXE_MAPPING - - computeDLights( var_Position, normal, viewDir, diffuse, material, color ); - -#if defined(r_glowMapping) - color.rgb += texture2D(u_GlowMap, texCoords).rgb; -#endif // r_glowMapping + // Compute final color. + vec4 color; + color.a = diffuse.a; + + #if !defined(USE_LIGHT_MAPPING) || !defined(USE_DELUXE_MAPPING) + #if !defined(HACK_NO_BSP_GRID_LIGHTDIR) + // Compute light grid position. + vec3 lightGridPos = (var_Position - u_LightGridOrigin) * u_LightGridScale; + #endif + #endif + + #if defined(USE_DELUXE_MAPPING) + // Compute light direction in world space from deluxe map. + vec4 deluxe = texture2D(u_DeluxeMap, var_TexLight); + vec3 lightDir = normalize(2.0 * deluxe.xyz - 1.0); + #else + #if !defined(HACK_NO_BSP_GRID_LIGHTDIR) + // Compute light direction in world space from light grid. + vec4 texel = texture3D(u_LightGrid2, lightGridPos); + vec3 lightDir = normalize(texel.xyz - (128.0 / 255.0)); + #endif + #endif + + #if defined(USE_LIGHT_MAPPING) + // Compute light color from world space lightmap. + vec3 lightColor = texture2D(u_LightMap, var_TexLight).rgb; + + #if !defined(HACK_NO_BSP_GRID_LIGHTDIR) + color.rgb = vec3(0.0); + #else + color.rgb = lightColor.rgb * diffuse.rgb; + #endif + #else + // Compute light color from lightgrid. + vec3 ambientColor, lightColor; + ReadLightGrid(texture3D(u_LightGrid1, lightGridPos), ambientColor, lightColor); + + color.rgb = ambientColor * r_AmbientScale * diffuse.rgb; + #endif + + #if defined(USE_LIGHT_MAPPING) + /* Lightmaps generated by q3map2 don't store the raw light value, but + they store light premultiplied with the dot product of the light + direction and surface normal. The line is just an attempt to reverse + that and get the original light values. + + The lightmap stores the light in this way because for the diffuse + lighting formula the outgoing light is equal to the incoming light + multiplied by the above dot product multiplied by the surface albedo. + So this premultiplication means that the diffuse lighting value can + be calculated with a single multiply operation. + + But specular lighting and/or normal mapping formulas are more complex, + and so you need the true light value to get correct lighting. + Obviously the data is not good enough to recover the original color + in all cases. The lower bound was an arbitrary chose factor to + prevent too small divisors resulting in too bright lights. + + Increasing the value should reduce these artifacts. -- gimhael + https://github.com/DaemonEngine/Daemon/issues/299#issuecomment-606186347 + */ + + #if !defined(HACK_NO_BSP_GRID_LIGHTDIR) + // Divide by cosine term to restore original light color. + lightColor /= clamp(dot(normalize(var_Normal), lightDir), 0.3, 1.0); + #endif + #endif + + #if !defined(HACK_NO_BSP_GRID_LIGHTDIR) + // Blend static light. + computeLight(lightDir, normal, viewDir, lightColor, diffuse, material, color); + #endif + + // Blend dynamic lights. + computeDLights(var_Position, normal, viewDir, diffuse, material, color); + + // Add Rim Lighting to highlight the edges on model entities. + #if defined(r_RimLighting) && !defined(USE_BSP_SURFACE) && !defined(USE_LIGHT_MAPPING) + float rim = pow(1.0 - clamp(dot(normal, viewDir), 0.0, 1.0), r_RimExponent); + vec3 emission = ambientColor * rim * rim * 0.2; + color.rgb += 0.7 * emission; + #endif + + #if defined(r_glowMapping) + // Blend glow map. + color.rgb += texture2D(u_GlowMap, texCoords).rgb; + #endif outputColor = color; -// Debugging -#if defined(r_showLightMaps) - outputColor = texture2D(u_LightMap, var_TexLight); -#elif defined(r_showDeluxeMaps) - outputColor = texture2D(u_DeluxeMap, var_TexLight); -#elif defined(r_showNormalMaps) - // convert normal to [0,1] color space - normal = normal * 0.5 + 0.5; - outputColor = vec4(normal, 1.0); -#elif defined(r_showMaterialMaps) - outputColor = material; -#endif + // Debugging. + #if defined(r_showLightMaps) && defined(USE_LIGHT_MAPPING) + outputColor = texture2D(u_LightMap, var_TexLight); + #elif defined(r_showDeluxeMaps) && defined(USE_DELUXE_MAPPING) + outputColor = texture2D(u_DeluxeMap, var_TexLight); + #elif defined(r_showNormalMaps) + // Convert normal to [0,1] color space. + normal = normal * 0.5 + 0.5; + outputColor = vec4(normal, 1.0); + #elif defined(r_showMaterialMaps) + outputColor = material; + #endif } diff --git a/src/engine/renderer/glsl_source/lightMapping_vp.glsl b/src/engine/renderer/glsl_source/lightMapping_vp.glsl index 0f62cdbd81..ba6ae4a907 100644 --- a/src/engine/renderer/glsl_source/lightMapping_vp.glsl +++ b/src/engine/renderer/glsl_source/lightMapping_vp.glsl @@ -23,6 +23,11 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA /* lightMapping_vp.glsl */ uniform mat4 u_TextureMatrix; + +#if !defined(USE_BSP_SURFACE) + uniform mat4 u_ModelMatrix; +#endif + uniform mat4 u_ModelViewProjectionMatrix; uniform float u_Time; @@ -32,7 +37,10 @@ uniform vec4 u_Color; OUT(smooth) vec3 var_Position; OUT(smooth) vec2 var_TexCoords; -OUT(smooth) vec2 var_TexLight; + +#if defined(USE_LIGHT_MAPPING) || defined(USE_DELUXE_MAPPING) + OUT(smooth) vec2 var_TexLight; +#endif OUT(smooth) vec3 var_Tangent; OUT(smooth) vec3 var_Binormal; @@ -40,44 +48,46 @@ OUT(smooth) vec3 var_Normal; OUT(smooth) vec4 var_Color; -void DeformVertex( inout vec4 pos, - inout vec3 normal, - inout vec2 st, - inout vec4 color, - in float time); +void DeformVertex(inout vec4 pos, inout vec3 normal, inout vec2 st, inout vec4 color, in float time); void main() { localBasis LB; - vec4 position; + vec4 position, color; vec2 texCoord, lmCoord; - vec4 color; - VertexFetch( position, LB, color, texCoord, lmCoord ); + VertexFetch(position, LB, color, texCoord, lmCoord); color = color * u_ColorModulate + u_Color; - DeformVertex( position, - LB.normal, - texCoord, - color, - u_Time); + DeformVertex(position, LB.normal, texCoord, color, u_Time); // transform vertex position into homogenous clip-space gl_Position = u_ModelViewProjectionMatrix * position; - // assign vertex Position - var_Position = position.xyz; + #if defined(USE_BSP_SURFACE) + // assign vertex Position + var_Position = position.xyz; - var_Normal = LB.normal; - var_Tangent = LB.tangent; - var_Binormal = LB.binormal; + var_Tangent = LB.tangent; + var_Binormal = LB.binormal; + var_Normal = LB.normal; + #else + // transform position into world space + var_Position = (u_ModelMatrix * position).xyz; + + var_Tangent = (u_ModelMatrix * vec4(LB.tangent, 0.0)).xyz; + var_Binormal = (u_ModelMatrix * vec4(LB.binormal, 0.0)).xyz; + var_Normal = (u_ModelMatrix * vec4(LB.normal, 0.0)).xyz; + #endif + + #if defined(USE_LIGHT_MAPPING) || defined(USE_DELUXE_MAPPING) + var_TexLight = lmCoord; + #endif // transform diffusemap texcoords var_TexCoords = (u_TextureMatrix * vec4(texCoord, 0.0, 1.0)).st; - var_TexLight = lmCoord; - // assign color var_Color = color; } diff --git a/src/engine/renderer/glsl_source/vertexLighting_DBS_entity_fp.glsl b/src/engine/renderer/glsl_source/vertexLighting_DBS_entity_fp.glsl deleted file mode 100644 index e56d10f862..0000000000 --- a/src/engine/renderer/glsl_source/vertexLighting_DBS_entity_fp.glsl +++ /dev/null @@ -1,118 +0,0 @@ -/* -=========================================================================== -Copyright (C) 2006-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 -=========================================================================== -*/ - -/* vertexLighting_DBS_entity_fp.glsl */ - -uniform sampler2D u_DiffuseMap; -uniform sampler2D u_MaterialMap; -uniform sampler2D u_GlowMap; - -uniform float u_AlphaThreshold; -uniform vec3 u_ViewOrigin; - -uniform sampler3D u_LightGrid1; -uniform sampler3D u_LightGrid2; -uniform vec3 u_LightGridOrigin; -uniform vec3 u_LightGridScale; - -IN(smooth) vec3 var_Position; -IN(smooth) vec2 var_TexCoords; -IN(smooth) vec4 var_Color; -IN(smooth) vec3 var_Tangent; -IN(smooth) vec3 var_Binormal; -IN(smooth) vec3 var_Normal; - -DECLARE_OUTPUT(vec4) - -void main() -{ - // compute view direction in world space - vec3 viewDir = normalize(u_ViewOrigin - var_Position); - - vec2 texCoords = var_TexCoords; - - mat3 tangentToWorldMatrix = mat3(var_Tangent.xyz, var_Binormal.xyz, var_Normal.xyz); - - vec3 lightGridPos = (var_Position - u_LightGridOrigin) * u_LightGridScale; - - // compute light color from light grid - vec3 ambientColor, lightColor; - ReadLightGrid(texture3D(u_LightGrid1, lightGridPos), ambientColor, lightColor); - - // compute light direction in world space - vec4 texel = texture3D(u_LightGrid2, lightGridPos); - vec3 lightDir = normalize(texel.xyz - (128.0 / 255.0)); - -#if defined(USE_PARALLAX_MAPPING) - // compute texcoords offset from heightmap - vec2 texOffset = ParallaxTexOffset(texCoords, viewDir, tangentToWorldMatrix); - - texCoords += texOffset; -#endif // USE_PARALLAX_MAPPING - - // compute the diffuse term - vec4 diffuse = texture2D(u_DiffuseMap, texCoords); - - // vertex blend operation like: alphaGen vertex - diffuse *= var_Color; - - if( abs(diffuse.a + u_AlphaThreshold) <= 1.0 ) - { - discard; - return; - } - - // compute normal in world space from normalmap - vec3 normal = NormalInWorldSpace(texCoords, tangentToWorldMatrix); - - // compute the material term - vec4 material = texture2D(u_MaterialMap, texCoords); - - // compute final color - vec4 color = vec4(ambientColor * r_AmbientScale * diffuse.rgb, diffuse.a); - - computeLight(lightDir, normal, viewDir, lightColor, diffuse, material, color); - - computeDLights( var_Position, normal, viewDir, diffuse, material, color ); - -// add Rim Lighting to highlight the edges -#if defined(r_RimLighting) - float rim = pow(1.0 - clamp(dot(normal, viewDir), 0.0, 1.0), r_RimExponent); - vec3 emission = ambientColor * rim * rim * 0.2; - color.rgb += 0.7 * emission; -#endif - -#if defined(r_glowMapping) - color.rgb += texture2D(u_GlowMap, texCoords).rgb; -#endif // r_glowMapping - - outputColor = color; - -// Debugging -#if defined(r_showNormalMaps) - // convert normal to [0,1] color space - normal = normal * 0.5 + 0.5; - outputColor = vec4(normal, 1.0); -#elif defined(r_showMaterialMaps) - outputColor = material; -#endif -} diff --git a/src/engine/renderer/glsl_source/vertexLighting_DBS_entity_vp.glsl b/src/engine/renderer/glsl_source/vertexLighting_DBS_entity_vp.glsl deleted file mode 100644 index a210212c57..0000000000 --- a/src/engine/renderer/glsl_source/vertexLighting_DBS_entity_vp.glsl +++ /dev/null @@ -1,76 +0,0 @@ -/* -=========================================================================== -Copyright (C) 2006-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 -=========================================================================== -*/ - -/* vertexLighting_DBS_entity_vp.glsl */ - -uniform mat4 u_TextureMatrix; -uniform mat4 u_ModelMatrix; -uniform mat4 u_ModelViewProjectionMatrix; - -uniform float u_Time; - -OUT(smooth) vec3 var_Position; -OUT(smooth) vec2 var_TexCoords; - -OUT(smooth) vec3 var_Tangent; -OUT(smooth) vec3 var_Binormal; -OUT(smooth) vec3 var_Normal; - -OUT(smooth) vec4 var_Color; - -void DeformVertex( inout vec4 pos, - inout vec3 normal, - inout vec2 st, - inout vec4 color, - in float time); - -void main() -{ - localBasis LB; - vec4 position; - vec2 texCoord, lmCoord; - vec4 color; - - VertexFetch( position, LB, color, texCoord, lmCoord); - - DeformVertex( position, - LB.normal, - texCoord, - color, - u_Time); - - // transform vertex position into homogenous clip-space - gl_Position = u_ModelViewProjectionMatrix * position; - - // transform position into world space - var_Position = (u_ModelMatrix * position).xyz; - - var_Tangent = (u_ModelMatrix * vec4(LB.tangent, 0.0)).xyz; - var_Binormal = (u_ModelMatrix * vec4(LB.binormal, 0.0)).xyz; - var_Normal = (u_ModelMatrix * vec4(LB.normal, 0.0)).xyz; - - // transform diffusemap texcoords - var_TexCoords = (u_TextureMatrix * vec4(texCoord, 0.0, 1.0)).st; - - // assign color - var_Color = color; -} diff --git a/src/engine/renderer/glsl_source/vertexLighting_DBS_world_fp.glsl b/src/engine/renderer/glsl_source/vertexLighting_DBS_world_fp.glsl deleted file mode 100644 index 7edcf86d9c..0000000000 --- a/src/engine/renderer/glsl_source/vertexLighting_DBS_world_fp.glsl +++ /dev/null @@ -1,111 +0,0 @@ -/* -=========================================================================== -Copyright (C) 2008-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 -=========================================================================== -*/ - -/* vertexLighting_DBS_world_fp.glsl */ - -uniform sampler2D u_DiffuseMap; -uniform sampler2D u_MaterialMap; -uniform sampler2D u_GlowMap; - -uniform float u_AlphaThreshold; -uniform vec3 u_ViewOrigin; - -uniform sampler3D u_LightGrid1; -uniform sampler3D u_LightGrid2; -uniform vec3 u_LightGridOrigin; -uniform vec3 u_LightGridScale; - -IN(smooth) vec3 var_Position; -IN(smooth) vec2 var_TexCoords; -IN(smooth) vec4 var_Color; -IN(smooth) vec3 var_Tangent; -IN(smooth) vec3 var_Binormal; -IN(smooth) vec3 var_Normal; - -DECLARE_OUTPUT(vec4) - -void main() -{ - // compute view direction in world space - vec3 viewDir = normalize(u_ViewOrigin - var_Position); - - vec2 texCoords = var_TexCoords; - - mat3 tangentToWorldMatrix = mat3(var_Tangent.xyz, var_Binormal.xyz, var_Normal.xyz); - - vec3 lightGridPos = (var_Position - u_LightGridOrigin) * u_LightGridScale; - - // compute light color from light grid - vec3 ambientColor, lightColor; - ReadLightGrid(texture3D(u_LightGrid1, lightGridPos), ambientColor, lightColor); - - // compute light direction in world space - vec4 texel = texture3D(u_LightGrid2, lightGridPos); - vec3 lightDir = normalize(texel.xyz - (128.0 / 255.0)); - -#if defined(USE_PARALLAX_MAPPING) - // compute texcoords offset from heightmap - vec2 texOffset = ParallaxTexOffset(texCoords, viewDir, tangentToWorldMatrix); - - texCoords += texOffset; -#endif // USE_PARALLAX_MAPPING - - // compute the diffuse term - vec4 diffuse = texture2D(u_DiffuseMap, texCoords); - - // vertex blend operation like: alphaGen vertex - diffuse *= var_Color; - - if( abs(diffuse.a + u_AlphaThreshold) <= 1.0 ) - { - discard; - return; - } - - // compute normal in world space from normalmap - vec3 normal = NormalInWorldSpace(texCoords, tangentToWorldMatrix); - - // compute the material term - vec4 material = texture2D(u_MaterialMap, texCoords); - - // compute final color - vec4 color = vec4(ambientColor * r_AmbientScale * diffuse.rgb, diffuse.a); - - computeLight(lightDir, normal, viewDir, lightColor, diffuse, material, color); - - computeDLights( var_Position, normal, viewDir, diffuse, material, color ); - -#if defined(r_glowMapping) - color.rgb += texture2D(u_GlowMap, texCoords).rgb; -#endif // r_glowMapping - - outputColor = color; - -// Debugging -#if defined(r_showNormalMaps) - // convert normal to [0,1] color space - normal = normal * 0.5 + 0.5; - outputColor = vec4(normal, 1.0); -#elif defined(r_showMaterialMaps) - outputColor = material; -#endif -} diff --git a/src/engine/renderer/glsl_source/vertexLighting_DBS_world_vp.glsl b/src/engine/renderer/glsl_source/vertexLighting_DBS_world_vp.glsl deleted file mode 100644 index 2f210bbe2c..0000000000 --- a/src/engine/renderer/glsl_source/vertexLighting_DBS_world_vp.glsl +++ /dev/null @@ -1,80 +0,0 @@ -/* -=========================================================================== -Copyright (C) 2008-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 -=========================================================================== -*/ - -/* vertexLighting_DBS_world_vp.glsl */ - -uniform mat4 u_TextureMatrix; -uniform mat4 u_ModelViewProjectionMatrix; - -uniform float u_Time; - -uniform vec4 u_ColorModulate; -uniform vec4 u_Color; - -OUT(smooth) vec3 var_Position; -OUT(smooth) vec2 var_TexCoords; - -OUT(smooth) vec3 var_Tangent; -OUT(smooth) vec3 var_Binormal; -OUT(smooth) vec3 var_Normal; - -OUT(smooth) vec4 var_Color; - -void DeformVertex( inout vec4 pos, - inout vec3 normal, - inout vec2 st, - inout vec4 color, - in float time); - -void main() -{ - localBasis LB; - vec4 position; - vec2 texCoord, lmCoord; - vec4 color; - - VertexFetch( position, LB, color, texCoord, lmCoord ); - - color = color * u_ColorModulate + u_Color; - - DeformVertex( position, - LB.normal, - texCoord, - color, - u_Time); - - // transform vertex position into homogenous clip-space - gl_Position = u_ModelViewProjectionMatrix * position; - - // assign vertex Position for light grid sampling - var_Position = position.xyz; - - var_Normal = LB.normal; - var_Tangent = LB.tangent; - var_Binormal = LB.binormal; - - // transform diffusemap texcoords - var_TexCoords = (u_TextureMatrix * vec4(texCoord, 0.0, 1.0)).st; - - // assign color - var_Color = color; -} diff --git a/src/engine/renderer/shaders.cpp b/src/engine/renderer/shaders.cpp index 99527efbe8..f8de872555 100644 --- a/src/engine/renderer/shaders.cpp +++ b/src/engine/renderer/shaders.cpp @@ -4,10 +4,6 @@ #include "glsl/ssao_fp.h" #include "glsl/ssao_vp.h" #include "glsl/vertexAnimation_vp.h" -#include "glsl/vertexLighting_DBS_entity_fp.h" -#include "glsl/vertexLighting_DBS_entity_vp.h" -#include "glsl/vertexLighting_DBS_world_fp.h" -#include "glsl/vertexLighting_DBS_world_vp.h" #include "glsl/vertexSimple_vp.h" #include "glsl/vertexSkinning_vp.h" #include "glsl/vertexSprite_vp.h" @@ -129,10 +125,6 @@ std::unordered_map shadermap({ { "glsl/ssao_fp.glsl", std::string((char*)ssao_fp_glsl, ssao_fp_glsl_len) }, { "glsl/ssao_vp.glsl", std::string((char*)ssao_vp_glsl, ssao_vp_glsl_len) }, { "glsl/vertexAnimation_vp.glsl", std::string((char*)vertexAnimation_vp_glsl, vertexAnimation_vp_glsl_len) }, - { "glsl/vertexLighting_DBS_entity_fp.glsl", std::string((char*)vertexLighting_DBS_entity_fp_glsl, vertexLighting_DBS_entity_fp_glsl_len) }, - { "glsl/vertexLighting_DBS_entity_vp.glsl", std::string((char*)vertexLighting_DBS_entity_vp_glsl, vertexLighting_DBS_entity_vp_glsl_len) }, - { "glsl/vertexLighting_DBS_world_fp.glsl", std::string((char*)vertexLighting_DBS_world_fp_glsl, vertexLighting_DBS_world_fp_glsl_len) }, - { "glsl/vertexLighting_DBS_world_vp.glsl", std::string((char*)vertexLighting_DBS_world_vp_glsl, vertexLighting_DBS_world_vp_glsl_len) }, { "glsl/vertexSimple_vp.glsl", std::string((char*)vertexSimple_vp_glsl, vertexSimple_vp_glsl_len) }, { "glsl/vertexSkinning_vp.glsl", std::string((char*)vertexSkinning_vp_glsl, vertexSkinning_vp_glsl_len) }, { "glsl/vertexSprite_vp.glsl", std::string((char*)vertexSprite_vp_glsl, vertexSprite_vp_glsl_len) }, diff --git a/src/engine/renderer/tr_bsp.cpp b/src/engine/renderer/tr_bsp.cpp index e6b421cd83..9d0542b035 100644 --- a/src/engine/renderer/tr_bsp.cpp +++ b/src/engine/renderer/tr_bsp.cpp @@ -833,13 +833,13 @@ static void ParseFace( dsurface_t *ds, drawVert_t *verts, bspSurface_t *surf, in // get lightmap realLightmapNum = LittleLong( ds->lightmapNum ); - if ( r_vertexLighting->integer || !r_precomputedLighting->integer ) + if ( r_precomputedLighting->integer && ( !r_vertexLighting->integer || ( r_deluxeMapping->integer && tr.worldDeluxeMapping ) ) ) { - surf->lightmapNum = -1; + surf->lightmapNum = tr.fatLightmapSize ? 0 : realLightmapNum; } else { - surf->lightmapNum = tr.fatLightmapSize ? 0 : realLightmapNum; + surf->lightmapNum = -1; } if ( tr.worldDeluxeMapping && surf->lightmapNum >= 2 ) @@ -1041,13 +1041,13 @@ static void ParseMesh( dsurface_t *ds, drawVert_t *verts, bspSurface_t *surf ) // get lightmap realLightmapNum = LittleLong( ds->lightmapNum ); - if ( r_vertexLighting->integer || !r_precomputedLighting->integer ) + if ( r_precomputedLighting->integer && ( !r_vertexLighting->integer || ( r_deluxeMapping->integer && tr.worldDeluxeMapping ) ) ) { - surf->lightmapNum = -1; + surf->lightmapNum = tr.fatLightmapSize ? 0 : realLightmapNum; } else { - surf->lightmapNum = tr.fatLightmapSize ? 0 : realLightmapNum; + surf->lightmapNum = -1; } if ( tr.worldDeluxeMapping && surf->lightmapNum >= 2 ) diff --git a/src/engine/renderer/tr_local.h b/src/engine/renderer/tr_local.h index 1f8cd4aead..d65b208003 100644 --- a/src/engine/renderer/tr_local.h +++ b/src/engine/renderer/tr_local.h @@ -508,6 +508,21 @@ static inline void halfToFloat( const f16vec4_t in, vec4_t out ) vertexHash_t *next; }; + enum + { + BIND_DIFFUSEMAP, + BIND_NORMALMAP, + BIND_HEIGHTMAP, + BIND_MATERIALMAP, + BIND_LIGHTMAP, + BIND_DELUXEMAP, + BIND_GLOWMAP, + BIND_ENVIRONMENTMAP0, + BIND_ENVIRONMENTMAP1, + BIND_LIGHTTILES, + BIND_LIGHTS, + }; + enum { IF_NONE, diff --git a/src/engine/renderer/tr_shade.cpp b/src/engine/renderer/tr_shade.cpp index c2bcc7c6a9..77364486bc 100644 --- a/src/engine/renderer/tr_shade.cpp +++ b/src/engine/renderer/tr_shade.cpp @@ -42,14 +42,9 @@ static void GLSL_InitGPUShadersOrError() // single texture rendering gl_shaderManager.GenerateBuiltinHeaders(); + // single texture rendering gl_shaderManager.load( gl_genericShader ); - // simple vertex color shading for entities - gl_shaderManager.load( gl_vertexLightingShader_DBS_entity ); - - // simple vertex color shading for the world - gl_shaderManager.load( gl_vertexLightingShader_DBS_world ); - // standard light mapping gl_shaderManager.load( gl_lightMappingShader ); @@ -213,8 +208,6 @@ void GLSL_ShutdownGPUShaders() gl_shaderManager.freeAll(); gl_genericShader = nullptr; - gl_vertexLightingShader_DBS_entity = nullptr; - gl_vertexLightingShader_DBS_world = nullptr; gl_lightMappingShader = nullptr; gl_forwardLightingShader_omniXYZ = nullptr; gl_forwardLightingShader_projXYZ = nullptr; @@ -352,68 +345,6 @@ SURFACE SHADERS ALIGNED( 16, shaderCommands_t tess ); -/* -================= -BindLightMap -================= -*/ -static void BindLightMap( int tmu, bool noLightMap ) -{ - image_t *lightmap; - - if ( noLightMap ) - { - lightmap = nullptr; - } - else if ( tr.fatLightmap ) - { - lightmap = tr.fatLightmap; - } - else if ( tess.lightmapNum >= 0 && tess.lightmapNum < tr.lightmaps.currentElements ) - { - lightmap = ( image_t * ) Com_GrowListElement( &tr.lightmaps, tess.lightmapNum ); - } - else - { - lightmap = nullptr; - } - - if ( !tr.lightmaps.currentElements || !lightmap ) - { - GL_BindToTMU( tmu, tr.whiteImage ); - return; - } - - GL_BindToTMU( tmu, lightmap ); -} - -/* -================= -BindDeluxeMap -================= -*/ -static void BindDeluxeMap( int tmu ) -{ - image_t *deluxemap; - - if ( tess.lightmapNum >= 0 && tess.lightmapNum < tr.deluxemaps.currentElements ) - { - deluxemap = ( image_t * ) Com_GrowListElement( &tr.deluxemaps, tess.lightmapNum ); - } - else - { - deluxemap = nullptr; - } - - if ( !tr.deluxemaps.currentElements || !deluxemap ) - { - GL_BindToTMU( tmu, tr.blackImage ); - return; - } - - GL_BindToTMU( tmu, deluxemap ); -} - /* ================ DrawTris @@ -730,245 +661,86 @@ static void Render_generic( int stage ) GL_CheckErrors(); } -static void Render_vertexLighting_DBS_entity( int stage ) +/* +================= +GetLightMap +================= +*/ +static image_t* GetLightMap() { - vec3_t viewOrigin; - uint32_t stateBits; - shaderStage_t *pStage = tess.surfaceStages[ stage ]; - - GLimp_LogComment( "--- Render_vertexLighting_DBS_entity ---\n" ); - - stateBits = pStage->stateBits; - - GL_State( stateBits ); - - // 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( pStage->isHeightMapInNormalMap ); - - gl_vertexLightingShader_DBS_entity->SetParallaxMapping( pStage->enableParallaxMapping ); - - gl_vertexLightingShader_DBS_entity->SetReflectiveSpecular( pStage->enableNormalMapping && tr.cubeHashTable != nullptr ); - - gl_vertexLightingShader_DBS_entity->SetPhysicalShading( pStage->isMaterialPhysical ); - - gl_vertexLightingShader_DBS_entity->BindProgram( pStage->deformIndex ); - // end choose right shader program ------------------------------ - - // now we are ready to set the shader program uniforms - - // set uniforms - VectorCopy( backEnd.viewParms.orientation.origin, viewOrigin ); // in world space - - if ( glConfig2.vboVertexSkinningAvailable && tess.vboVertexSkinning ) + if ( !tr.lightmaps.currentElements ) { - gl_vertexLightingShader_DBS_entity->SetUniform_Bones( tess.numBones, tess.bones ); - } - - if( backEnd.refdef.numShaderLights > 0 ) { - gl_vertexLightingShader_DBS_entity->SetUniform_numLights( backEnd.refdef.numLights ); - if( glConfig2.uniformBufferObjectAvailable ) { - gl_vertexLightingShader_DBS_entity->SetUniformBlock_Lights( tr.dlightUBO ); - } else { - GL_BindToTMU( 9, tr.dlightImage ); - } + return tr.whiteImage; } - - // bind u_LightTiles - GL_BindToTMU( 8, tr.lighttileRenderImage ); - - // u_DeformGen - gl_vertexLightingShader_DBS_entity->SetUniform_Time( backEnd.refdef.floatTime - backEnd.currentEntity->e.shaderTime ); - - - // u_VertexInterpolation - if ( tess.vboVertexAnimation ) + else if ( tr.fatLightmap ) { - gl_vertexLightingShader_DBS_entity->SetUniform_VertexInterpolation( glState.vertexAttribsInterpolation ); + return tr.fatLightmap; } - - // u_ViewOrigin - gl_vertexLightingShader_DBS_entity->SetUniform_ViewOrigin( viewOrigin ); - - gl_vertexLightingShader_DBS_entity->SetUniform_ModelMatrix( backEnd.orientation.transformMatrix ); - - gl_vertexLightingShader_DBS_entity->SetUniform_ModelViewProjectionMatrix( glState.modelViewProjectionMatrix[ glState.stackIndex ] ); - - // u_AlphaTest - gl_vertexLightingShader_DBS_entity->SetUniform_AlphaTest( pStage->stateBits ); - - // bind u_HeightMap - if ( pStage->enableParallaxMapping ) + else if ( tess.lightmapNum >= 0 && tess.lightmapNum < tr.lightmaps.currentElements ) { - float depthScale; - float parallaxDepthScale; - - depthScale = RB_EvalExpression( &pStage->depthScaleExp, r_parallaxDepthScale->value ); - parallaxDepthScale = tess.surfaceShader->parallaxDepthScale; - depthScale *= parallaxDepthScale == 0 ? 1 : parallaxDepthScale; - gl_vertexLightingShader_DBS_entity->SetUniform_ParallaxDepthScale( depthScale ); - 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 ( !pStage->isHeightMapInNormalMap ) - { - GL_BindToTMU( 15, pStage->bundle[ TB_HEIGHTMAP ].image[ 0 ] ); - } + return ( image_t * ) Com_GrowListElement( &tr.lightmaps, tess.lightmapNum ); } - - // bind u_DiffuseMap - GL_BindToTMU( 0, pStage->bundle[ TB_DIFFUSEMAP ].image[ 0 ] ); - gl_vertexLightingShader_DBS_entity->SetUniform_TextureMatrix( tess.svars.texMatrices[ TB_DIFFUSEMAP ] ); - - // bind u_NormalMap - GL_BindToTMU( 1, pStage->bundle[ TB_NORMALMAP ].image[ 0 ] ); - - // bind u_NormalScale - if ( pStage->enableNormalMapping ) + else { - vec3_t normalScale; - SetNormalScale( pStage, normalScale ); - - gl_vertexLightingShader_DBS_entity->SetUniform_NormalScale( normalScale ); + return tr.whiteImage; } +} - // bind u_MaterialMap - GL_BindToTMU( 2, pStage->bundle[ TB_MATERIALMAP ].image[ 0 ] ); +/* +================= +GetDeluxeMap +================= +*/ +static image_t* GetDeluxeMap() +{ - if ( pStage->enableSpecularMapping ) + if ( !tr.deluxemaps.currentElements ) { - 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 ); + return tr.blackImage; } - - if ( tr.cubeHashTable != nullptr ) + else if ( tess.lightmapNum >= 0 && tess.lightmapNum < tr.deluxemaps.currentElements ) { - cubemapProbe_t *cubeProbeNearest; - cubemapProbe_t *cubeProbeSecondNearest; - - if ( backEnd.currentEntity && ( backEnd.currentEntity != &tr.worldEntity ) ) - { - R_FindTwoNearestCubeMaps( backEnd.currentEntity->e.origin, &cubeProbeNearest, &cubeProbeSecondNearest ); - } - else - { - // FIXME position - R_FindTwoNearestCubeMaps( backEnd.viewParms.orientation.origin, &cubeProbeNearest, &cubeProbeSecondNearest ); - } - - if ( cubeProbeNearest == nullptr && cubeProbeSecondNearest == nullptr ) - { - GLimp_LogComment( "cubeProbeNearest && cubeProbeSecondNearest == NULL\n" ); - - // bind u_EnvironmentMap0 - GL_BindToTMU( 3, tr.whiteCubeImage ); - - // bind u_EnvironmentMap1 - GL_BindToTMU( 4, tr.whiteCubeImage ); - } - else if ( cubeProbeNearest == nullptr ) - { - GLimp_LogComment( "cubeProbeNearest == NULL\n" ); - - // bind u_EnvironmentMap0 - GL_BindToTMU( 3, cubeProbeSecondNearest->cubemap ); - - // u_EnvironmentInterpolation - gl_vertexLightingShader_DBS_entity->SetUniform_EnvironmentInterpolation( 0.0 ); - } - else if ( cubeProbeSecondNearest == nullptr ) - { - GLimp_LogComment( "cubeProbeSecondNearest == NULL\n" ); - - // bind u_EnvironmentMap0 - GL_BindToTMU( 3, cubeProbeNearest->cubemap ); - - // bind u_EnvironmentMap1 - //GL_SelectTexture(4); - //GL_Bind(cubeProbeNearest->cubemap); - - // u_EnvironmentInterpolation - gl_vertexLightingShader_DBS_entity->SetUniform_EnvironmentInterpolation( 0.0 ); - } - else - { - float cubeProbeNearestDistance, cubeProbeSecondNearestDistance; - - if ( backEnd.currentEntity && ( backEnd.currentEntity != &tr.worldEntity ) ) - { - cubeProbeNearestDistance = Distance( backEnd.currentEntity->e.origin, cubeProbeNearest->origin ); - cubeProbeSecondNearestDistance = Distance( backEnd.currentEntity->e.origin, cubeProbeSecondNearest->origin ); - } - else - { - // FIXME position - cubeProbeNearestDistance = Distance( backEnd.viewParms.orientation.origin, cubeProbeNearest->origin ); - cubeProbeSecondNearestDistance = Distance( backEnd.viewParms.orientation.origin, cubeProbeSecondNearest->origin ); - } - - float interpolate = cubeProbeNearestDistance / ( cubeProbeNearestDistance + cubeProbeSecondNearestDistance ); - - if ( r_logFile->integer ) - { - GLimp_LogComment( va( "cubeProbeNearestDistance = %f, cubeProbeSecondNearestDistance = %f, interpolation = %f\n", - cubeProbeNearestDistance, cubeProbeSecondNearestDistance, interpolate ) ); - } - - // bind u_EnvironmentMap0 - GL_BindToTMU( 3, cubeProbeNearest->cubemap ); - - // bind u_EnvironmentMap1 - GL_BindToTMU( 4, cubeProbeSecondNearest->cubemap ); - - // u_EnvironmentInterpolation - gl_vertexLightingShader_DBS_entity->SetUniform_EnvironmentInterpolation( interpolate ); - } + return ( image_t * ) Com_GrowListElement( &tr.deluxemaps, tess.lightmapNum ); } - - if( tr.world ) + else { - gl_vertexLightingShader_DBS_entity->SetUniform_LightGridOrigin( tr.world->lightGridGLOrigin ); - gl_vertexLightingShader_DBS_entity->SetUniform_LightGridScale( tr.world->lightGridGLScale ); + return tr.blackImage; } +} - // bind u_LightGrid1 u_LightGrid2 - if ( tr.lightGrid1Image && tr.lightGrid2Image ) - { - GL_BindToTMU( 6, tr.lightGrid1Image ); - GL_BindToTMU( 7, tr.lightGrid2Image ); - } +static void Render_lightMapping( int stage ) +{ + GLimp_LogComment( "--- Render_lightMapping ---\n" ); - // bind u_GlowMap - GL_BindToTMU( 5, pStage->bundle[ TB_GLOWMAP ].image[ 0 ] ); + shaderStage_t *pStage = tess.surfaceStages[ stage ]; - gl_vertexLightingShader_DBS_entity->SetRequiredVertexPointers(); + bool enableLightMapping = !r_vertexLighting->integer \ + && tess.bspSurface \ + && tess.lightmapNum >= 0 && tess.lightmapNum <= tr.lightmaps.currentElements; - Tess_DrawElements(); + bool enableDeluxeMapping = pStage->enableDeluxeMapping \ + && tess.bspSurface \ + && tr.worldDeluxeMapping; - GL_CheckErrors(); -} + bool noLightMap = !pStage->implicitLightmap + && (tess.surfaceShader->surfaceFlags & SURF_NOLIGHTMAP) + && !(tess.numSurfaceStages > 0 && tess.surfaceStages[0]->rgbGen == colorGen_t::CGEN_VERTEX); -static void Render_vertexLighting_DBS_world( int stage ) -{ - vec3_t viewOrigin; - uint32_t stateBits; - colorGen_t colorGen; - alphaGen_t alphaGen; - shaderStage_t *pStage = tess.surfaceStages[ stage ]; + bool isWorldEntity = backEnd.currentEntity == &tr.worldEntity; - GLimp_LogComment( "--- Render_vertexLighting_DBS_world ---\n" ); + uint32_t stateBits = pStage->stateBits; - stateBits = pStage->stateBits; + if ( enableLightMapping && r_showLightMaps->integer ) + { + stateBits &= ~( GLS_SRCBLEND_BITS | GLS_DSTBLEND_BITS | GLS_ATEST_BITS ); + } GL_State( stateBits ); // u_ColorModulate + colorGen_t colorGen; + alphaGen_t alphaGen; + switch ( pStage->rgbGen ) { case colorGen_t::CGEN_VERTEX: @@ -993,176 +765,57 @@ static void Render_vertexLighting_DBS_world( int stage ) break; } - // choose right shader program ---------------------------------- - tess.vboVertexSprite = false; - - gl_vertexLightingShader_DBS_world->SetHeightMapInNormalMap( pStage->isHeightMapInNormalMap ); - - gl_vertexLightingShader_DBS_world->SetParallaxMapping( pStage->enableParallaxMapping ); - - - gl_vertexLightingShader_DBS_world->SetPhysicalShading( pStage->isMaterialPhysical ); - - gl_vertexLightingShader_DBS_world->BindProgram( pStage->deformIndex ); - // end choose right shader program ------------------------------ - - // now we are ready to set the shader program uniforms - - // set uniforms - VectorCopy( backEnd.orientation.viewOrigin, viewOrigin ); // in world space - - if( backEnd.refdef.numShaderLights > 0 ) { - gl_vertexLightingShader_DBS_world->SetUniform_numLights( backEnd.refdef.numLights ); - if( glConfig2.uniformBufferObjectAvailable ) { - gl_vertexLightingShader_DBS_world->SetUniformBlock_Lights( tr.dlightUBO ); - } else { - GL_BindToTMU( 9, tr.dlightImage ); - } - } - - // bind u_LightTiles - GL_BindToTMU( 8, tr.lighttileRenderImage ); - - // u_DeformGen - gl_vertexLightingShader_DBS_world->SetUniform_Time( backEnd.refdef.floatTime - backEnd.currentEntity->e.shaderTime ); - - // u_ColorModulate - gl_vertexLightingShader_DBS_world->SetUniform_ColorModulate( colorGen, alphaGen ); - - // u_Color - gl_vertexLightingShader_DBS_world->SetUniform_Color( tess.svars.color ); - - gl_vertexLightingShader_DBS_world->SetUniform_LightWrapAround( RB_EvalExpression( &pStage->wrapAroundLightingExp, 0 ) ); - - // u_ViewOrigin - gl_vertexLightingShader_DBS_world->SetUniform_ViewOrigin( viewOrigin ); - - gl_vertexLightingShader_DBS_world->SetUniform_ModelViewProjectionMatrix( glState.modelViewProjectionMatrix[ glState.stackIndex ] ); - - // u_AlphaTest - gl_vertexLightingShader_DBS_world->SetUniform_AlphaTest( pStage->stateBits ); + // u_LightMap, u_DeluxeMap + image_t *lightmap; + image_t *deluxemap; - // bind u_HeightMap - if ( pStage->enableParallaxMapping ) + if ( noLightMap ) { - float depthScale; - float parallaxDepthScale; - - depthScale = RB_EvalExpression( &pStage->depthScaleExp, r_parallaxDepthScale->value ); - parallaxDepthScale = tess.surfaceShader->parallaxDepthScale; - depthScale *= parallaxDepthScale == 0 ? 1 : parallaxDepthScale; - gl_vertexLightingShader_DBS_world->SetUniform_ParallaxDepthScale( depthScale ); - 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 ( !pStage->isHeightMapInNormalMap ) - { - GL_BindToTMU( 15, pStage->bundle[ TB_HEIGHTMAP ].image[ 0 ] ); - } + lightmap = tr.whiteImage; + enableLightMapping = true; } - - // bind u_DiffuseMap - GL_BindToTMU( 0, pStage->bundle[ TB_DIFFUSEMAP ].image[ 0 ] ); - gl_vertexLightingShader_DBS_world->SetUniform_TextureMatrix( tess.svars.texMatrices[ TB_DIFFUSEMAP ] ); - - // bind u_NormalMap - GL_BindToTMU( 1, pStage->bundle[ TB_NORMALMAP ].image[ 0 ] ); - - // bind u_NormalScale - if ( pStage->enableNormalMapping ) + else if ( enableLightMapping ) { - vec3_t normalScale; - SetNormalScale( pStage, normalScale ); - - gl_vertexLightingShader_DBS_world->SetUniform_NormalScale( normalScale ); + lightmap = GetLightMap(); } - - // bind u_MaterialMap - GL_BindToTMU( 2, pStage->bundle[ TB_MATERIALMAP ].image[ 0 ] ); - - if ( pStage->enableSpecularMapping ) + else if ( tr.lightGrid1Image ) { - 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 ); + // Store lightGrid1 as lightmap, + // the GLSL code will know to deal with it. + lightmap = tr.lightGrid1Image; } - - if( tr.world ) + else { - gl_vertexLightingShader_DBS_world->SetUniform_LightGridOrigin( tr.world->lightGridGLOrigin ); - gl_vertexLightingShader_DBS_world->SetUniform_LightGridScale( tr.world->lightGridGLScale ); + lightmap = tr.whiteImage; + enableLightMapping = true; } - // bind u_LightGrid1 u_LightGrid2 - if ( tr.lightGrid1Image && tr.lightGrid2Image ) + if ( enableDeluxeMapping ) { - GL_BindToTMU( 6, tr.lightGrid1Image ); - GL_BindToTMU( 7, tr.lightGrid2Image ); + deluxemap = GetDeluxeMap(); } - - // bind u_GlowMap - GL_BindToTMU( 5, pStage->bundle[ TB_GLOWMAP ].image[ 0 ] ); - - gl_vertexLightingShader_DBS_world->SetRequiredVertexPointers(); - - Tess_DrawElements(); - - GL_CheckErrors(); -} - -static void Render_lightMapping( int stage ) -{ - vec3_t viewOrigin; - uint32_t stateBits; - colorGen_t colorGen; - alphaGen_t alphaGen; - shaderStage_t *pStage = tess.surfaceStages[ stage ]; - - GLimp_LogComment( "--- Render_lightMapping ---\n" ); - - stateBits = pStage->stateBits; - - if ( r_showLightMaps->integer ) + else if ( tr.lightGrid2Image ) { - stateBits &= ~( GLS_SRCBLEND_BITS | GLS_DSTBLEND_BITS | GLS_ATEST_BITS ); + // Store lightGrid2 as deluxemap, + // the GLSL code will know to deal with it. + deluxemap = tr.lightGrid2Image; } - - GL_State( stateBits ); - - // u_ColorModulate - switch ( pStage->rgbGen ) + else { - case colorGen_t::CGEN_VERTEX: - case colorGen_t::CGEN_ONE_MINUS_VERTEX: - colorGen = pStage->rgbGen; - break; - - default: - colorGen = colorGen_t::CGEN_CONST; - break; + deluxemap = tr.blackImage; + enableDeluxeMapping = true; } - switch ( pStage->alphaGen ) - { - case alphaGen_t::AGEN_VERTEX: - case alphaGen_t::AGEN_ONE_MINUS_VERTEX: - alphaGen = pStage->alphaGen; - break; + // choose right shader program ---------------------------------- + tess.vboVertexSprite = false; - default: - alphaGen = alphaGen_t::AGEN_CONST; - break; - } + gl_lightMappingShader->SetVertexSkinning( glConfig2.vboVertexSkinningAvailable && tess.vboVertexSkinning ); - bool enableDeluxeMapping = pStage->enableDeluxeMapping && tr.worldDeluxeMapping; + gl_lightMappingShader->SetVertexAnimation( tess.vboVertexAnimation ); - bool noLightMap = !pStage->implicitLightmap - && (tess.surfaceShader->surfaceFlags & SURF_NOLIGHTMAP) - && !(tess.numSurfaceStages > 0 && tess.surfaceStages[0]->rgbGen == colorGen_t::CGEN_VERTEX); + gl_lightMappingShader->SetBspSurface( tess.bspSurface ); - // choose right shader program ---------------------------------- - tess.vboVertexSprite = false; + gl_lightMappingShader->SetLightMapping( enableLightMapping ); gl_lightMappingShader->SetDeluxeMapping( enableDeluxeMapping ); @@ -1170,27 +823,54 @@ static void Render_lightMapping( int stage ) gl_lightMappingShader->SetParallaxMapping( pStage->enableParallaxMapping ); + gl_lightMappingShader->SetReflectiveSpecular( pStage->enableNormalMapping && tr.cubeHashTable != nullptr ); + gl_lightMappingShader->SetPhysicalShading( pStage->isMaterialPhysical ); gl_lightMappingShader->BindProgram( pStage->deformIndex ); // end choose right shader program ------------------------------ // now we are ready to set the shader program uniforms + vec3_t viewOrigin; - // set uniforms - VectorCopy( backEnd.orientation.viewOrigin, viewOrigin ); // in world space + if ( tess.bspSurface ) + { + VectorCopy( backEnd.orientation.viewOrigin, viewOrigin ); // in world space + } + else + { + VectorCopy( backEnd.viewParms.orientation.origin, viewOrigin ); // in world space + + if ( glConfig2.vboVertexSkinningAvailable && tess.vboVertexSkinning ) + { + gl_lightMappingShader->SetUniform_Bones( tess.numBones, tess.bones ); + } + + // u_VertexInterpolation + if ( tess.vboVertexAnimation ) + { + gl_lightMappingShader->SetUniform_VertexInterpolation( glState.vertexAttribsInterpolation ); + } + + gl_lightMappingShader->SetUniform_ModelMatrix( backEnd.orientation.transformMatrix ); + } + + // u_ViewOrigin + gl_lightMappingShader->SetUniform_ViewOrigin( viewOrigin ); + + gl_lightMappingShader->SetUniform_ModelViewProjectionMatrix( glState.modelViewProjectionMatrix[ glState.stackIndex ] ); if( backEnd.refdef.numShaderLights > 0 ) { gl_lightMappingShader->SetUniform_numLights( backEnd.refdef.numLights ); if( glConfig2.uniformBufferObjectAvailable ) { gl_lightMappingShader->SetUniformBlock_Lights( tr.dlightUBO ); } else { - GL_BindToTMU( 9, tr.dlightImage ); + GL_BindToTMU( BIND_LIGHTS, tr.dlightImage ); } } // bind u_LightTiles - GL_BindToTMU( 8, tr.lighttileRenderImage ); + GL_BindToTMU( BIND_LIGHTTILES, tr.lighttileRenderImage ); // u_DeformGen gl_lightMappingShader->SetUniform_Time( backEnd.refdef.floatTime - backEnd.currentEntity->e.shaderTime ); @@ -1201,11 +881,12 @@ static void Render_lightMapping( int stage ) // u_Color gl_lightMappingShader->SetUniform_Color( tess.svars.color ); - // u_ViewOrigin - gl_lightMappingShader->SetUniform_ViewOrigin( viewOrigin ); - - gl_lightMappingShader->SetUniform_ModelViewProjectionMatrix( glState.modelViewProjectionMatrix[ glState.stackIndex ] ); + if ( tess.bspSurface && !enableLightMapping ) + { + gl_lightMappingShader->SetUniform_LightWrapAround( RB_EvalExpression( &pStage->wrapAroundLightingExp, 0 ) ); + } + // u_AlphaTest gl_lightMappingShader->SetUniform_AlphaTest( pStage->stateBits ); // bind u_HeightMap @@ -1223,24 +904,25 @@ static void Render_lightMapping( int stage ) // FIXME: if there is both, embedded heightmap in normalmap is used instead of standalone heightmap if ( !pStage->isHeightMapInNormalMap ) { - GL_BindToTMU( 15, pStage->bundle[ TB_HEIGHTMAP ].image[ 0 ] ); + GL_BindToTMU( BIND_HEIGHTMAP, pStage->bundle[ TB_HEIGHTMAP ].image[ 0 ] ); } } + // bind u_DiffuseMap if ( pStage->type == stageType_t::ST_LIGHTMAP ) { // standalone lightmap stage: paint shadows over a white texture - GL_BindToTMU( 0, tr.whiteImage ); + GL_BindToTMU( BIND_DIFFUSEMAP, tr.whiteImage ); } else { - // bind u_DiffuseMap - GL_BindToTMU( 0, pStage->bundle[ TB_DIFFUSEMAP ].image[ 0 ] ); + GL_BindToTMU( BIND_DIFFUSEMAP, pStage->bundle[ TB_DIFFUSEMAP ].image[ 0 ] ); + gl_lightMappingShader->SetUniform_TextureMatrix( tess.svars.texMatrices[ TB_DIFFUSEMAP ] ); } // bind u_NormalMap - GL_BindToTMU( 1, pStage->bundle[ TB_NORMALMAP ].image[ 0 ] ); + GL_BindToTMU( BIND_NORMALMAP, pStage->bundle[ TB_NORMALMAP ].image[ 0 ] ); // bind u_NormalScale if ( pStage->enableNormalMapping ) @@ -1252,7 +934,7 @@ static void Render_lightMapping( int stage ) } // bind u_MaterialMap - GL_BindToTMU( 2, pStage->bundle[ TB_MATERIALMAP ].image[ 0 ] ); + GL_BindToTMU( BIND_MATERIALMAP, pStage->bundle[ TB_MATERIALMAP ].image[ 0 ] ); if ( pStage->enableSpecularMapping ) { @@ -1262,21 +944,110 @@ static void Render_lightMapping( int stage ) gl_lightMappingShader->SetUniform_SpecularExponent( specExpMin, specExpMax ); } - // bind u_LightMap - BindLightMap( 3, noLightMap ); - - // bind u_DeluxeMap - if ( enableDeluxeMapping ) + // specular reflection + if ( tr.cubeHashTable != nullptr ) { - BindDeluxeMap( 4 ); + cubemapProbe_t *cubeProbeNearest; + cubemapProbe_t *cubeProbeSecondNearest; + + if ( backEnd.currentEntity && !isWorldEntity ) + { + R_FindTwoNearestCubeMaps( backEnd.currentEntity->e.origin, &cubeProbeNearest, &cubeProbeSecondNearest ); + } + else + { + // FIXME position + R_FindTwoNearestCubeMaps( backEnd.viewParms.orientation.origin, &cubeProbeNearest, &cubeProbeSecondNearest ); + } + + if ( cubeProbeNearest == nullptr && cubeProbeSecondNearest == nullptr ) + { + GLimp_LogComment( "cubeProbeNearest && cubeProbeSecondNearest == NULL\n" ); + + // bind u_EnvironmentMap0 + GL_BindToTMU( BIND_ENVIRONMENTMAP0, tr.whiteCubeImage ); + + // bind u_EnvironmentMap1 + GL_BindToTMU( BIND_ENVIRONMENTMAP1, tr.whiteCubeImage ); + } + else if ( cubeProbeNearest == nullptr ) + { + GLimp_LogComment( "cubeProbeNearest == NULL\n" ); + + // bind u_EnvironmentMap0 + GL_BindToTMU( BIND_ENVIRONMENTMAP0, cubeProbeSecondNearest->cubemap ); + + // u_EnvironmentInterpolation + gl_lightMappingShader->SetUniform_EnvironmentInterpolation( 0.0 ); + } + else if ( cubeProbeSecondNearest == nullptr ) + { + GLimp_LogComment( "cubeProbeSecondNearest == NULL\n" ); + + // bind u_EnvironmentMap0 + GL_BindToTMU( BIND_ENVIRONMENTMAP0, cubeProbeNearest->cubemap ); + + // bind u_EnvironmentMap1 + // GL_SelectTexture( BIND_ENVIRONMENTMAP1 ); + // GL_Bind( cubeProbeNearest->cubemap ); + + // u_EnvironmentInterpolation + gl_lightMappingShader->SetUniform_EnvironmentInterpolation( 0.0 ); + } + else + { + float cubeProbeNearestDistance, cubeProbeSecondNearestDistance; + + if ( backEnd.currentEntity && !isWorldEntity ) + { + cubeProbeNearestDistance = Distance( backEnd.currentEntity->e.origin, cubeProbeNearest->origin ); + cubeProbeSecondNearestDistance = Distance( backEnd.currentEntity->e.origin, cubeProbeSecondNearest->origin ); + } + else + { + // FIXME position + cubeProbeNearestDistance = Distance( backEnd.viewParms.orientation.origin, cubeProbeNearest->origin ); + cubeProbeSecondNearestDistance = Distance( backEnd.viewParms.orientation.origin, cubeProbeSecondNearest->origin ); + } + + float interpolate = cubeProbeNearestDistance / ( cubeProbeNearestDistance + cubeProbeSecondNearestDistance ); + + if ( r_logFile->integer ) + { + GLimp_LogComment( va( "cubeProbeNearestDistance = %f, cubeProbeSecondNearestDistance = %f, interpolation = %f\n", + cubeProbeNearestDistance, cubeProbeSecondNearestDistance, interpolate ) ); + } + + // bind u_EnvironmentMap0 + GL_BindToTMU( BIND_ENVIRONMENTMAP0, cubeProbeNearest->cubemap ); + + // bind u_EnvironmentMap1 + GL_BindToTMU( BIND_ENVIRONMENTMAP1, cubeProbeSecondNearest->cubemap ); + + // u_EnvironmentInterpolation + gl_lightMappingShader->SetUniform_EnvironmentInterpolation( interpolate ); + } } - else + + // bind u_LightGridOrigin and u_LightGridScale to compute light grid position + if ( !enableLightMapping || !enableDeluxeMapping ) { - GL_BindToTMU( 4, tr.blackImage ); + if( tr.world ) + { + gl_lightMappingShader->SetUniform_LightGridOrigin( tr.world->lightGridGLOrigin ); + gl_lightMappingShader->SetUniform_LightGridScale( tr.world->lightGridGLScale ); + } + // FIXME: else } + // bind u_LightMap + GL_BindToTMU( BIND_LIGHTMAP, lightmap ); + + // bind u_DeluxeMap + GL_BindToTMU( BIND_DELUXEMAP, deluxemap ); + // bind u_GlowMap - GL_BindToTMU( 5, pStage->bundle[ TB_GLOWMAP ].image[ 0 ] ); + GL_BindToTMU( BIND_GLOWMAP, pStage->bundle[ TB_GLOWMAP ].image[ 0 ] ); gl_lightMappingShader->SetRequiredVertexPointers(); @@ -2832,30 +2603,13 @@ void Tess_StageIteratorGeneric() case stageType_t::ST_COLLAPSE_lighting_PHONG: case stageType_t::ST_COLLAPSE_lighting_PBR: { + if ( r_precomputedLighting->integer || r_vertexLighting->integer ) { - if ( r_precomputedLighting->integer || r_vertexLighting->integer ) - { - - if ( tess.bspSurface ) - { - if ( !r_vertexLighting->integer && tess.lightmapNum >= 0 && tess.lightmapNum <= tr.lightmaps.currentElements ) - { - Render_lightMapping( stage ); - } - else - { - Render_vertexLighting_DBS_world( stage ); - } - } - else - { - Render_vertexLighting_DBS_entity( stage ); - } - } - else - { - Render_depthFill( stage ); - } + Render_lightMapping( stage ); + } + else + { + Render_depthFill( stage ); } break; }