From de6c5d70e8f28fd73c2b78836fe62c602f4e51a3 Mon Sep 17 00:00:00 2001 From: slipher Date: Thu, 7 Nov 2024 01:49:44 -0600 Subject: [PATCH] Don't use reflective specular for dynamic lights It's wrong because in the reflection cubemaps, the world geometry is already pre-multiplied with the world lighting. For example if the location were completely dark but you added a static light, the specular reflection of the light should appear (but wouldn't previously). Fixes #1358. --- .../renderer/glsl_source/computeLight_fp.glsl | 61 ++++++------------- .../renderer/glsl_source/lightMapping_fp.glsl | 10 +-- .../renderer/glsl_source/liquid_fp.glsl | 6 +- 3 files changed, 21 insertions(+), 56 deletions(-) diff --git a/src/engine/renderer/glsl_source/computeLight_fp.glsl b/src/engine/renderer/glsl_source/computeLight_fp.glsl index 59e238b708..d9e8eb76b6 100644 --- a/src/engine/renderer/glsl_source/computeLight_fp.glsl +++ b/src/engine/renderer/glsl_source/computeLight_fp.glsl @@ -32,9 +32,19 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA #endif #if defined(USE_REFLECTIVE_SPECULAR) - uniform samplerCube u_EnvironmentMap0; - uniform samplerCube u_EnvironmentMap1; - uniform float u_EnvironmentInterpolation; +uniform samplerCube u_EnvironmentMap0; +uniform samplerCube u_EnvironmentMap1; +uniform float u_EnvironmentInterpolation; + +// Only the RGB components are meaningful +// FIXME: using reflective specular will always globally decrease the scene brightness +// because we're multiplying with something that can only be less than 1. +vec4 EnvironmentalSpecularFactor( vec3 viewDir, vec3 normal ) +{ + vec4 envColor0 = textureCube(u_EnvironmentMap0, reflect( -viewDir, normal ) ); + vec4 envColor1 = textureCube(u_EnvironmentMap1, reflect( -viewDir, normal ) ); + return mix( envColor0, envColor1, u_EnvironmentInterpolation ); +} #endif // USE_REFLECTIVE_SPECULAR // lighting helper functions @@ -59,15 +69,9 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA #endif #if defined(USE_DELUXE_MAPPING) || defined(USE_GRID_DELUXE_MAPPING) || (defined(r_realtimeLighting) && r_realtimeLightingRenderer == 1) -#if defined(USE_REFLECTIVE_SPECULAR) -void computeDeluxeLight( vec3 lightDir, vec3 normal, vec3 viewDir, vec3 lightColor, - vec4 diffuseColor, vec4 materialColor, - inout vec4 color, in samplerCube u_EnvironmentMap0, in samplerCube u_EnvironmentMap1 ) -#else // !USE_REFLECTIVE_SPECULAR void computeDeluxeLight( vec3 lightDir, vec3 normal, vec3 viewDir, vec3 lightColor, vec4 diffuseColor, vec4 materialColor, inout vec4 color ) -#endif // !USE_REFLECTIVE_SPECULAR { vec3 H = normalize( lightDir + viewDir ); @@ -122,15 +126,6 @@ void computeDeluxeLight( vec3 lightDir, vec3 normal, vec3 viewDir, vec3 lightCol color.a = mix( diffuseColor.a, 1.0, FexpNV ); #else // !USE_PHYSICAL_MAPPING - - #if defined(USE_REFLECTIVE_SPECULAR) - // not implemented for PBR yet - vec4 envColor0 = textureCube(u_EnvironmentMap0, reflect( -viewDir, normal ) ); - vec4 envColor1 = textureCube(u_EnvironmentMap1, reflect( -viewDir, normal ) ); - - materialColor.rgb *= mix( envColor0, envColor1, u_EnvironmentInterpolation ).rgb; - #endif // USE_REFLECTIVE_SPECULAR - color.rgb += lightColor.rgb * NdotL * diffuseColor.rgb; #if defined(r_specularMapping) color.rgb += computeSpecularity(lightColor.rgb, materialColor, NdotH); @@ -164,13 +159,8 @@ layout(std140) uniform u_Lights { uniform int u_numLights; -#if defined(USE_REFLECTIVE_SPECULAR) -void computeDynamicLight( uint idx, vec3 P, vec3 normal, vec3 viewDir, vec4 diffuse, - vec4 material, inout vec4 color, in samplerCube u_EnvironmentMap0, in samplerCube u_EnvironmentMap1 ) -#else // !USE_REFLECTIVE_SPECULAR void computeDynamicLight( uint idx, vec3 P, vec3 normal, vec3 viewDir, vec4 diffuse, vec4 material, inout vec4 color ) -#endif // !USE_REFLECTIVE_SPECULAR { Light light = GetLight( idx ); vec3 L; @@ -202,15 +192,9 @@ void computeDynamicLight( uint idx, vec3 P, vec3 normal, vec3 viewDir, vec4 diff attenuation = 1.0; } - #if defined(USE_REFLECTIVE_SPECULAR) - computeDeluxeLight( L, normal, viewDir, - attenuation * attenuation * light.color, - diffuse, material, color, u_EnvironmentMap0, u_EnvironmentMap1 ); - #else // !USE_REFLECTIVE_SPECULAR - computeDeluxeLight( L, normal, viewDir, - attenuation * attenuation * light.color, - diffuse, material, color ); - #endif // !USE_REFLECTIVE_SPECULAR + computeDeluxeLight( + L, normal, viewDir, attenuation * attenuation * light.color, + diffuse, material, color ); } const int lightsPerLayer = 16; @@ -230,14 +214,8 @@ uint nextIdx( in uint count, in idxs_t idxs ) { return ( idxs[count / 4] >> ( 8 * ( count % 4 ) ) ) & 0xFFu; } -#if defined(USE_REFLECTIVE_SPECULAR) -void computeDynamicLights( vec3 P, vec3 normal, vec3 viewDir, vec4 diffuse, vec4 material, - inout vec4 color, in usampler3D u_LightTiles, - in samplerCube u_EnvironmentMap0, in samplerCube u_EnvironmentMap1 ) -#else // !USE_REFLECTIVE_SPECULAR void computeDynamicLights( vec3 P, vec3 normal, vec3 viewDir, vec4 diffuse, vec4 material, inout vec4 color, in usampler3D u_LightTiles ) -#endif // !USE_REFLECTIVE_SPECULAR { if( u_numLights == 0 ) { return; @@ -259,13 +237,8 @@ void computeDynamicLights( vec3 P, vec3 normal, vec3 viewDir, vec4 diffuse, vec4 /* Light IDs are stored relative to the layer Subtract 1 because 0 means there's no light */ idx = ( idx - 1 ) * NUM_LIGHT_LAYERS + layer; - - #if defined(USE_REFLECTIVE_SPECULAR) - computeDynamicLight( idx, P, normal, viewDir, diffuse, material, color, u_EnvironmentMap0, u_EnvironmentMap1 ); - #else // !USE_REFLECTIVE_SPECULAR - computeDynamicLight( idx, P, normal, viewDir, diffuse, material, color ); - #endif // !USE_REFLECTIVE_SPECULAR + computeDynamicLight( idx, P, normal, viewDir, diffuse, material, color ); lightCount++; } } diff --git a/src/engine/renderer/glsl_source/lightMapping_fp.glsl b/src/engine/renderer/glsl_source/lightMapping_fp.glsl index 0bd5a3d128..8ec26659e4 100644 --- a/src/engine/renderer/glsl_source/lightMapping_fp.glsl +++ b/src/engine/renderer/glsl_source/lightMapping_fp.glsl @@ -184,7 +184,8 @@ void main() // Blend static light. #if defined(USE_DELUXE_MAPPING) || defined(USE_GRID_DELUXE_MAPPING) #if defined(USE_REFLECTIVE_SPECULAR) - computeDeluxeLight(lightDir, normal, viewDir, lightColor, diffuse, material, color, u_EnvironmentMap0, u_EnvironmentMap1); + vec4 modifiedSpecular = material * EnvironmentalSpecularFactor(viewDir, normal); + computeDeluxeLight(lightDir, normal, viewDir, lightColor, diffuse, modifiedSpecular, color); #else // !USE_REFLECTIVE_SPECULAR computeDeluxeLight(lightDir, normal, viewDir, lightColor, diffuse, material, color); #endif // !USE_REFLECTIVE_SPECULAR @@ -194,12 +195,7 @@ void main() // Blend dynamic lights. #if defined(r_realtimeLighting) && r_realtimeLightingRenderer == 1 - #if defined(USE_REFLECTIVE_SPECULAR) - computeDynamicLights(var_Position, normal, viewDir, diffuse, material, color, u_LightTiles, - u_EnvironmentMap0, u_EnvironmentMap1); - #else // !USE_REFLECTIVE_SPECULAR - computeDynamicLights(var_Position, normal, viewDir, diffuse, material, color, u_LightTiles); - #endif // !USE_REFLECTIVE_SPECULAR + computeDynamicLights(var_Position, normal, viewDir, diffuse, material, color, u_LightTiles); #endif // Add Rim Lighting to highlight the edges on model entities. diff --git a/src/engine/renderer/glsl_source/liquid_fp.glsl b/src/engine/renderer/glsl_source/liquid_fp.glsl index a9fab99766..42f7b62298 100644 --- a/src/engine/renderer/glsl_source/liquid_fp.glsl +++ b/src/engine/renderer/glsl_source/liquid_fp.glsl @@ -145,11 +145,7 @@ void main() // compute the specular term #if defined(USE_DELUXE_MAPPING) || defined(USE_GRID_DELUXE_MAPPING) - #if defined(USE_REFLECTIVE_SPECULAR) - computeDeluxeLight(lightDir, normal, viewDir, lightColor, diffuse, reflectColor, color, u_EnvironmentMap0, u_EnvironmentMap1); - #else // !USE_REFLECTIVE_SPECULAR - computeDeluxeLight(lightDir, normal, viewDir, lightColor, diffuse, reflectColor, color); - #endif // !USE_REFLECTIVE_SPECULAR + computeDeluxeLight(lightDir, normal, viewDir, lightColor, diffuse, reflectColor, color); #else // !USE_DELUXE_MAPPING && !USE_GRID_DELUXE_MAPPING computeLight(lightColor, diffuse, color); #endif // !USE_DELUXE_MAPPING && !USE_GRID_DELUXE_MAPPING