mirror of
https://github.com/luanti-org/luanti.git
synced 2025-06-27 16:36:03 +00:00
Add API to control shadow intensity from the game/mod (#11944)
* Also Disable shadows when sun/moon is hidden. Fixes #11972.
This commit is contained in:
parent
8d55702d13
commit
0f25fa7af6
24 changed files with 375 additions and 169 deletions
|
@ -16,6 +16,7 @@ uniform float animationTimer;
|
|||
uniform float f_textureresolution;
|
||||
uniform mat4 m_ShadowViewProj;
|
||||
uniform float f_shadowfar;
|
||||
uniform float f_shadow_strength;
|
||||
varying float normalOffsetScale;
|
||||
varying float adj_shadow_strength;
|
||||
varying float cosLight;
|
||||
|
@ -483,55 +484,57 @@ void main(void)
|
|||
vec4 col = vec4(color.rgb * varColor.rgb, 1.0);
|
||||
|
||||
#ifdef ENABLE_DYNAMIC_SHADOWS
|
||||
float shadow_int = 0.0;
|
||||
vec3 shadow_color = vec3(0.0, 0.0, 0.0);
|
||||
vec3 posLightSpace = getLightSpacePosition();
|
||||
if (f_shadow_strength > 0.0) {
|
||||
float shadow_int = 0.0;
|
||||
vec3 shadow_color = vec3(0.0, 0.0, 0.0);
|
||||
vec3 posLightSpace = getLightSpacePosition();
|
||||
|
||||
float distance_rate = (1 - pow(clamp(2.0 * length(posLightSpace.xy - 0.5),0.0,1.0), 20.0));
|
||||
float f_adj_shadow_strength = max(adj_shadow_strength-mtsmoothstep(0.9,1.1, posLightSpace.z ),0.0);
|
||||
float distance_rate = (1 - pow(clamp(2.0 * length(posLightSpace.xy - 0.5),0.0,1.0), 20.0));
|
||||
float f_adj_shadow_strength = max(adj_shadow_strength-mtsmoothstep(0.9,1.1, posLightSpace.z ),0.0);
|
||||
|
||||
if (distance_rate > 1e-7) {
|
||||
|
||||
if (distance_rate > 1e-7) {
|
||||
|
||||
#ifdef COLORED_SHADOWS
|
||||
vec4 visibility;
|
||||
if (cosLight > 0.0)
|
||||
visibility = getShadowColor(ShadowMapSampler, posLightSpace.xy, posLightSpace.z);
|
||||
else
|
||||
visibility = vec4(1.0, 0.0, 0.0, 0.0);
|
||||
shadow_int = visibility.r;
|
||||
shadow_color = visibility.gba;
|
||||
vec4 visibility;
|
||||
if (cosLight > 0.0)
|
||||
visibility = getShadowColor(ShadowMapSampler, posLightSpace.xy, posLightSpace.z);
|
||||
else
|
||||
visibility = vec4(1.0, 0.0, 0.0, 0.0);
|
||||
shadow_int = visibility.r;
|
||||
shadow_color = visibility.gba;
|
||||
#else
|
||||
if (cosLight > 0.0)
|
||||
shadow_int = getShadow(ShadowMapSampler, posLightSpace.xy, posLightSpace.z);
|
||||
else
|
||||
shadow_int = 1.0;
|
||||
if (cosLight > 0.0)
|
||||
shadow_int = getShadow(ShadowMapSampler, posLightSpace.xy, posLightSpace.z);
|
||||
else
|
||||
shadow_int = 1.0;
|
||||
#endif
|
||||
shadow_int *= distance_rate;
|
||||
shadow_int = clamp(shadow_int, 0.0, 1.0);
|
||||
shadow_int *= distance_rate;
|
||||
shadow_int = clamp(shadow_int, 0.0, 1.0);
|
||||
|
||||
}
|
||||
|
||||
// turns out that nightRatio falls off much faster than
|
||||
// actual brightness of artificial light in relation to natual light.
|
||||
// Power ratio was measured on torches in MTG (brightness = 14).
|
||||
float adjusted_night_ratio = pow(max(0.0, nightRatio), 0.6);
|
||||
|
||||
// Apply self-shadowing when light falls at a narrow angle to the surface
|
||||
// Cosine of the cut-off angle.
|
||||
const float self_shadow_cutoff_cosine = 0.035;
|
||||
if (f_normal_length != 0 && cosLight < self_shadow_cutoff_cosine) {
|
||||
shadow_int = max(shadow_int, 1 - clamp(cosLight, 0.0, self_shadow_cutoff_cosine)/self_shadow_cutoff_cosine);
|
||||
shadow_color = mix(vec3(0.0), shadow_color, min(cosLight, self_shadow_cutoff_cosine)/self_shadow_cutoff_cosine);
|
||||
}
|
||||
|
||||
shadow_int *= f_adj_shadow_strength;
|
||||
|
||||
// calculate fragment color from components:
|
||||
col.rgb =
|
||||
adjusted_night_ratio * col.rgb + // artificial light
|
||||
(1.0 - adjusted_night_ratio) * ( // natural light
|
||||
col.rgb * (1.0 - shadow_int * (1.0 - shadow_color)) + // filtered texture color
|
||||
dayLight * shadow_color * shadow_int); // reflected filtered sunlight/moonlight
|
||||
}
|
||||
|
||||
// turns out that nightRatio falls off much faster than
|
||||
// actual brightness of artificial light in relation to natual light.
|
||||
// Power ratio was measured on torches in MTG (brightness = 14).
|
||||
float adjusted_night_ratio = pow(max(0.0, nightRatio), 0.6);
|
||||
|
||||
// Apply self-shadowing when light falls at a narrow angle to the surface
|
||||
// Cosine of the cut-off angle.
|
||||
const float self_shadow_cutoff_cosine = 0.035;
|
||||
if (f_normal_length != 0 && cosLight < self_shadow_cutoff_cosine) {
|
||||
shadow_int = max(shadow_int, 1 - clamp(cosLight, 0.0, self_shadow_cutoff_cosine)/self_shadow_cutoff_cosine);
|
||||
shadow_color = mix(vec3(0.0), shadow_color, min(cosLight, self_shadow_cutoff_cosine)/self_shadow_cutoff_cosine);
|
||||
}
|
||||
|
||||
shadow_int *= f_adj_shadow_strength;
|
||||
|
||||
// calculate fragment color from components:
|
||||
col.rgb =
|
||||
adjusted_night_ratio * col.rgb + // artificial light
|
||||
(1.0 - adjusted_night_ratio) * ( // natural light
|
||||
col.rgb * (1.0 - shadow_int * (1.0 - shadow_color)) + // filtered texture color
|
||||
dayLight * shadow_color * shadow_int); // reflected filtered sunlight/moonlight
|
||||
#endif
|
||||
|
||||
#if ENABLE_TONE_MAPPING
|
||||
|
|
|
@ -195,34 +195,35 @@ void main(void)
|
|||
varColor = clamp(color, 0.0, 1.0);
|
||||
|
||||
#ifdef ENABLE_DYNAMIC_SHADOWS
|
||||
vec3 nNormal = normalize(vNormal);
|
||||
cosLight = dot(nNormal, -v_LightDirection);
|
||||
|
||||
// Calculate normal offset scale based on the texel size adjusted for
|
||||
// curvature of the SM texture. This code must be change together with
|
||||
// getPerspectiveFactor or any light-space transformation.
|
||||
vec3 eyeToVertex = worldPosition - eyePosition + cameraOffset;
|
||||
// Distance from the vertex to the player
|
||||
float distanceToPlayer = length(eyeToVertex - v_LightDirection * dot(eyeToVertex, v_LightDirection)) / f_shadowfar;
|
||||
// perspective factor estimation according to the
|
||||
float perspectiveFactor = distanceToPlayer * bias0 + bias1;
|
||||
float texelSize = f_shadowfar * perspectiveFactor * perspectiveFactor /
|
||||
(f_textureresolution * bias1 - perspectiveFactor * bias0);
|
||||
float slopeScale = clamp(pow(1.0 - cosLight*cosLight, 0.5), 0.0, 1.0);
|
||||
normalOffsetScale = texelSize * slopeScale;
|
||||
if (f_shadow_strength > 0.0) {
|
||||
vec3 nNormal = normalize(vNormal);
|
||||
cosLight = dot(nNormal, -v_LightDirection);
|
||||
|
||||
// Calculate normal offset scale based on the texel size adjusted for
|
||||
// curvature of the SM texture. This code must be change together with
|
||||
// getPerspectiveFactor or any light-space transformation.
|
||||
vec3 eyeToVertex = worldPosition - eyePosition + cameraOffset;
|
||||
// Distance from the vertex to the player
|
||||
float distanceToPlayer = length(eyeToVertex - v_LightDirection * dot(eyeToVertex, v_LightDirection)) / f_shadowfar;
|
||||
// perspective factor estimation according to the
|
||||
float perspectiveFactor = distanceToPlayer * bias0 + bias1;
|
||||
float texelSize = f_shadowfar * perspectiveFactor * perspectiveFactor /
|
||||
(f_textureresolution * bias1 - perspectiveFactor * bias0);
|
||||
float slopeScale = clamp(pow(1.0 - cosLight*cosLight, 0.5), 0.0, 1.0);
|
||||
normalOffsetScale = texelSize * slopeScale;
|
||||
|
||||
if (f_timeofday < 0.2) {
|
||||
adj_shadow_strength = f_shadow_strength * 0.5 *
|
||||
(1.0 - mtsmoothstep(0.18, 0.2, f_timeofday));
|
||||
} else if (f_timeofday >= 0.8) {
|
||||
adj_shadow_strength = f_shadow_strength * 0.5 *
|
||||
mtsmoothstep(0.8, 0.83, f_timeofday);
|
||||
} else {
|
||||
adj_shadow_strength = f_shadow_strength *
|
||||
mtsmoothstep(0.20, 0.25, f_timeofday) *
|
||||
(1.0 - mtsmoothstep(0.7, 0.8, f_timeofday));
|
||||
if (f_timeofday < 0.2) {
|
||||
adj_shadow_strength = f_shadow_strength * 0.5 *
|
||||
(1.0 - mtsmoothstep(0.18, 0.2, f_timeofday));
|
||||
} else if (f_timeofday >= 0.8) {
|
||||
adj_shadow_strength = f_shadow_strength * 0.5 *
|
||||
mtsmoothstep(0.8, 0.83, f_timeofday);
|
||||
} else {
|
||||
adj_shadow_strength = f_shadow_strength *
|
||||
mtsmoothstep(0.20, 0.25, f_timeofday) *
|
||||
(1.0 - mtsmoothstep(0.7, 0.8, f_timeofday));
|
||||
}
|
||||
f_normal_length = length(vNormal);
|
||||
}
|
||||
f_normal_length = length(vNormal);
|
||||
#endif
|
||||
|
||||
}
|
||||
|
|
|
@ -34,6 +34,8 @@ const float fogShadingParameter = 1.0 / (1.0 - fogStart);
|
|||
uniform float f_textureresolution;
|
||||
uniform mat4 m_ShadowViewProj;
|
||||
uniform float f_shadowfar;
|
||||
uniform float f_timeofday;
|
||||
uniform float f_shadow_strength;
|
||||
varying float normalOffsetScale;
|
||||
varying float adj_shadow_strength;
|
||||
varying float cosLight;
|
||||
|
@ -470,55 +472,57 @@ void main(void)
|
|||
col.rgb *= vIDiff;
|
||||
|
||||
#ifdef ENABLE_DYNAMIC_SHADOWS
|
||||
float shadow_int = 0.0;
|
||||
vec3 shadow_color = vec3(0.0, 0.0, 0.0);
|
||||
vec3 posLightSpace = getLightSpacePosition();
|
||||
if (f_shadow_strength > 0.0) {
|
||||
float shadow_int = 0.0;
|
||||
vec3 shadow_color = vec3(0.0, 0.0, 0.0);
|
||||
vec3 posLightSpace = getLightSpacePosition();
|
||||
|
||||
float distance_rate = (1 - pow(clamp(2.0 * length(posLightSpace.xy - 0.5),0.0,1.0), 20.0));
|
||||
float f_adj_shadow_strength = max(adj_shadow_strength-mtsmoothstep(0.9,1.1, posLightSpace.z ),0.0);
|
||||
float distance_rate = (1 - pow(clamp(2.0 * length(posLightSpace.xy - 0.5),0.0,1.0), 20.0));
|
||||
float f_adj_shadow_strength = max(adj_shadow_strength-mtsmoothstep(0.9,1.1, posLightSpace.z ),0.0);
|
||||
|
||||
if (distance_rate > 1e-7) {
|
||||
if (distance_rate > 1e-7) {
|
||||
|
||||
#ifdef COLORED_SHADOWS
|
||||
vec4 visibility;
|
||||
if (cosLight > 0.0)
|
||||
visibility = getShadowColor(ShadowMapSampler, posLightSpace.xy, posLightSpace.z);
|
||||
else
|
||||
visibility = vec4(1.0, 0.0, 0.0, 0.0);
|
||||
shadow_int = visibility.r;
|
||||
shadow_color = visibility.gba;
|
||||
vec4 visibility;
|
||||
if (cosLight > 0.0)
|
||||
visibility = getShadowColor(ShadowMapSampler, posLightSpace.xy, posLightSpace.z);
|
||||
else
|
||||
visibility = vec4(1.0, 0.0, 0.0, 0.0);
|
||||
shadow_int = visibility.r;
|
||||
shadow_color = visibility.gba;
|
||||
#else
|
||||
if (cosLight > 0.0)
|
||||
shadow_int = getShadow(ShadowMapSampler, posLightSpace.xy, posLightSpace.z);
|
||||
else
|
||||
shadow_int = 1.0;
|
||||
if (cosLight > 0.0)
|
||||
shadow_int = getShadow(ShadowMapSampler, posLightSpace.xy, posLightSpace.z);
|
||||
else
|
||||
shadow_int = 1.0;
|
||||
#endif
|
||||
shadow_int *= distance_rate;
|
||||
shadow_int = clamp(shadow_int, 0.0, 1.0);
|
||||
shadow_int *= distance_rate;
|
||||
shadow_int = clamp(shadow_int, 0.0, 1.0);
|
||||
|
||||
}
|
||||
|
||||
// turns out that nightRatio falls off much faster than
|
||||
// actual brightness of artificial light in relation to natual light.
|
||||
// Power ratio was measured on torches in MTG (brightness = 14).
|
||||
float adjusted_night_ratio = pow(max(0.0, nightRatio), 0.6);
|
||||
|
||||
// cosine of the normal-to-light angle when
|
||||
// we start to apply self-shadowing
|
||||
const float self_shadow_cutoff_cosine = 0.14;
|
||||
if (f_normal_length != 0 && cosLight < self_shadow_cutoff_cosine) {
|
||||
shadow_int = max(shadow_int, 1 - clamp(cosLight, 0.0, self_shadow_cutoff_cosine)/self_shadow_cutoff_cosine);
|
||||
shadow_color = mix(vec3(0.0), shadow_color, min(cosLight, self_shadow_cutoff_cosine)/self_shadow_cutoff_cosine);
|
||||
}
|
||||
|
||||
shadow_int *= f_adj_shadow_strength;
|
||||
|
||||
// calculate fragment color from components:
|
||||
col.rgb =
|
||||
adjusted_night_ratio * col.rgb + // artificial light
|
||||
(1.0 - adjusted_night_ratio) * ( // natural light
|
||||
col.rgb * (1.0 - shadow_int * (1.0 - shadow_color)) + // filtered texture color
|
||||
dayLight * shadow_color * shadow_int); // reflected filtered sunlight/moonlight
|
||||
}
|
||||
|
||||
// turns out that nightRatio falls off much faster than
|
||||
// actual brightness of artificial light in relation to natual light.
|
||||
// Power ratio was measured on torches in MTG (brightness = 14).
|
||||
float adjusted_night_ratio = pow(max(0.0, nightRatio), 0.6);
|
||||
|
||||
// cosine of the normal-to-light angle when
|
||||
// we start to apply self-shadowing
|
||||
const float self_shadow_cutoff_cosine = 0.14;
|
||||
if (f_normal_length != 0 && cosLight < self_shadow_cutoff_cosine) {
|
||||
shadow_int = max(shadow_int, 1 - clamp(cosLight, 0.0, self_shadow_cutoff_cosine)/self_shadow_cutoff_cosine);
|
||||
shadow_color = mix(vec3(0.0), shadow_color, min(cosLight, self_shadow_cutoff_cosine)/self_shadow_cutoff_cosine);
|
||||
}
|
||||
|
||||
shadow_int *= f_adj_shadow_strength;
|
||||
|
||||
// calculate fragment color from components:
|
||||
col.rgb =
|
||||
adjusted_night_ratio * col.rgb + // artificial light
|
||||
(1.0 - adjusted_night_ratio) * ( // natural light
|
||||
col.rgb * (1.0 - shadow_int * (1.0 - shadow_color)) + // filtered texture color
|
||||
dayLight * shadow_color * shadow_int); // reflected filtered sunlight/moonlight
|
||||
#endif
|
||||
|
||||
#if ENABLE_TONE_MAPPING
|
||||
|
|
|
@ -105,33 +105,35 @@ void main(void)
|
|||
|
||||
|
||||
#ifdef ENABLE_DYNAMIC_SHADOWS
|
||||
vec3 nNormal = normalize(vNormal);
|
||||
cosLight = dot(nNormal, -v_LightDirection);
|
||||
if (f_shadow_strength > 0.0) {
|
||||
vec3 nNormal = normalize(vNormal);
|
||||
cosLight = dot(nNormal, -v_LightDirection);
|
||||
|
||||
// Calculate normal offset scale based on the texel size adjusted for
|
||||
// curvature of the SM texture. This code must be change together with
|
||||
// getPerspectiveFactor or any light-space transformation.
|
||||
vec3 eyeToVertex = worldPosition - eyePosition + cameraOffset;
|
||||
// Distance from the vertex to the player
|
||||
float distanceToPlayer = length(eyeToVertex - v_LightDirection * dot(eyeToVertex, v_LightDirection)) / f_shadowfar;
|
||||
// perspective factor estimation according to the
|
||||
float perspectiveFactor = distanceToPlayer * bias0 + bias1;
|
||||
float texelSize = f_shadowfar * perspectiveFactor * perspectiveFactor /
|
||||
(f_textureresolution * bias1 - perspectiveFactor * bias0);
|
||||
float slopeScale = clamp(pow(1.0 - cosLight*cosLight, 0.5), 0.0, 1.0);
|
||||
normalOffsetScale = texelSize * slopeScale;
|
||||
|
||||
if (f_timeofday < 0.2) {
|
||||
adj_shadow_strength = f_shadow_strength * 0.5 *
|
||||
(1.0 - mtsmoothstep(0.18, 0.2, f_timeofday));
|
||||
} else if (f_timeofday >= 0.8) {
|
||||
adj_shadow_strength = f_shadow_strength * 0.5 *
|
||||
mtsmoothstep(0.8, 0.83, f_timeofday);
|
||||
} else {
|
||||
adj_shadow_strength = f_shadow_strength *
|
||||
mtsmoothstep(0.20, 0.25, f_timeofday) *
|
||||
(1.0 - mtsmoothstep(0.7, 0.8, f_timeofday));
|
||||
// Calculate normal offset scale based on the texel size adjusted for
|
||||
// curvature of the SM texture. This code must be change together with
|
||||
// getPerspectiveFactor or any light-space transformation.
|
||||
vec3 eyeToVertex = worldPosition - eyePosition + cameraOffset;
|
||||
// Distance from the vertex to the player
|
||||
float distanceToPlayer = length(eyeToVertex - v_LightDirection * dot(eyeToVertex, v_LightDirection)) / f_shadowfar;
|
||||
// perspective factor estimation according to the
|
||||
float perspectiveFactor = distanceToPlayer * bias0 + bias1;
|
||||
float texelSize = f_shadowfar * perspectiveFactor * perspectiveFactor /
|
||||
(f_textureresolution * bias1 - perspectiveFactor * bias0);
|
||||
float slopeScale = clamp(pow(1.0 - cosLight*cosLight, 0.5), 0.0, 1.0);
|
||||
normalOffsetScale = texelSize * slopeScale;
|
||||
|
||||
if (f_timeofday < 0.2) {
|
||||
adj_shadow_strength = f_shadow_strength * 0.5 *
|
||||
(1.0 - mtsmoothstep(0.18, 0.2, f_timeofday));
|
||||
} else if (f_timeofday >= 0.8) {
|
||||
adj_shadow_strength = f_shadow_strength * 0.5 *
|
||||
mtsmoothstep(0.8, 0.83, f_timeofday);
|
||||
} else {
|
||||
adj_shadow_strength = f_shadow_strength *
|
||||
mtsmoothstep(0.20, 0.25, f_timeofday) *
|
||||
(1.0 - mtsmoothstep(0.7, 0.8, f_timeofday));
|
||||
}
|
||||
f_normal_length = length(vNormal);
|
||||
}
|
||||
f_normal_length = length(vNormal);
|
||||
#endif
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue