Skip to content

Commit

Permalink
Don't use reflective specular for dynamic lights
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
slipher committed Nov 9, 2024
1 parent 68bf1ee commit de6c5d7
Show file tree
Hide file tree
Showing 3 changed files with 21 additions and 56 deletions.
61 changes: 17 additions & 44 deletions src/engine/renderer/glsl_source/computeLight_fp.glsl
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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 );

Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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;
Expand All @@ -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;
Expand All @@ -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++;
}
}
Expand Down
10 changes: 3 additions & 7 deletions src/engine/renderer/glsl_source/lightMapping_fp.glsl
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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.
Expand Down
6 changes: 1 addition & 5 deletions src/engine/renderer/glsl_source/liquid_fp.glsl
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down

0 comments on commit de6c5d7

Please sign in to comment.