Skip to content

Commit

Permalink
Add Soft Very Low shadow quality mode for 3D
Browse files Browse the repository at this point in the history
This can be used to improve 3D shadow rendering quality at little
performance cost. Unlike the existing Hard setting which is limited
to variable shadow blur only, it works with both fixed blur and
variable blur.
  • Loading branch information
Calinou committed Oct 21, 2021
1 parent 85a8939 commit e87ec8e
Show file tree
Hide file tree
Showing 6 changed files with 41 additions and 16 deletions.
8 changes: 6 additions & 2 deletions doc/classes/ProjectSettings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -1698,8 +1698,10 @@
<member name="rendering/shadows/directional_shadow/size.mobile" type="int" setter="" getter="" default="2048">
Lower-end override for [member rendering/shadows/directional_shadow/size] on mobile devices, due to performance concerns or driver support.
</member>
<member name="rendering/shadows/directional_shadow/soft_shadow_quality" type="int" setter="" getter="" default="2">
<member name="rendering/shadows/directional_shadow/soft_shadow_quality" type="int" setter="" getter="" default="3">
Quality setting for shadows cast by [DirectionalLight3D]s. Higher quality settings use more samples when reading from shadow maps and are thus slower. Low quality settings may result in shadows looking grainy.
[b]Note:[/b] The Soft Very Low setting will automatically multiply [i]constant[/i] shadow blur by 0.75x to reduce the amount of noise visible. This automatic blur change only affects the constant blur factor defined in [member Light3D.shadow_blur], not the variable blur performed by [DirectionalLight3D]s' [member Light3D.light_angular_distance].
[b]Note:[/b] The Soft High and Soft Ultra settings will automatically multiply [i]constant[/i] shadow blur by 1.5× and 2× respectively to make better use of the increased sample count. This increased blur also improves stability of dynamic object shadows.
</member>
<member name="rendering/shadows/directional_shadow/soft_shadow_quality.mobile" type="int" setter="" getter="" default="0">
Lower-end override for [member rendering/shadows/directional_shadow/soft_shadow_quality] on mobile devices, due to performance concerns or driver support.
Expand All @@ -1724,8 +1726,10 @@
<member name="rendering/shadows/shadow_atlas/size.mobile" type="int" setter="" getter="" default="2048">
Lower-end override for [member rendering/shadows/shadow_atlas/size] on mobile devices, due to performance concerns or driver support.
</member>
<member name="rendering/shadows/shadows/soft_shadow_quality" type="int" setter="" getter="" default="2">
<member name="rendering/shadows/shadows/soft_shadow_quality" type="int" setter="" getter="" default="3">
Quality setting for shadows cast by [OmniLight3D]s and [SpotLight3D]s. Higher quality settings use more samples when reading from shadow maps and are thus slower. Low quality settings may result in shadows looking grainy.
[b]Note:[/b] The Soft Very Low setting will automatically multiply [i]constant[/i] shadow blur by 0.75x to reduce the amount of noise visible. This automatic blur change only affects the constant blur factor defined in [member Light3D.shadow_blur], not the variable blur performed by [DirectionalLight3D]s' [member Light3D.light_angular_distance].
[b]Note:[/b] The Soft High and Soft Ultra settings will automatically multiply shadow blur by 1.5× and 2× respectively to make better use of the increased sample count. This increased blur also improves stability of dynamic object shadows.
</member>
<member name="rendering/shadows/shadows/soft_shadow_quality.mobile" type="int" setter="" getter="" default="0">
Lower-end override for [member rendering/shadows/shadows/soft_shadow_quality] on mobile devices, due to performance concerns or driver support.
Expand Down
19 changes: 14 additions & 5 deletions doc/classes/RenderingServer.xml
Original file line number Diff line number Diff line change
Expand Up @@ -3663,16 +3663,25 @@
Use 4 splits for shadow projection when using directional light.
</constant>
<constant name="SHADOW_QUALITY_HARD" value="0" enum="ShadowQuality">
Lowest shadow filtering quality (fastest). Soft shadows are not available with this quality setting, which means the [member Light3D.shadow_blur] property is ignored if [member Light3D.light_size] and [member Light3D.light_angular_distance] is [code]0.0[/code].
[b]Note:[/b] The variable shadow blur performed by [member Light3D.light_size] and [member Light3D.light_angular_distance] is still effective when using hard shadow filtering. In this case, [member Light3D.shadow_blur] [i]is[/i] taken into account. However, the results will not be blurred, instead the blur amount is treated as a maximum radius for the penumbra.
</constant>
<constant name="SHADOW_QUALITY_SOFT_LOW" value="1" enum="ShadowQuality">
<constant name="SHADOW_QUALITY_SOFT_VERY_LOW" value="1" enum="ShadowQuality">
Very low shadow filtering quality (faster). When using this quality setting, [member Light3D.shadow_blur] is automatically multiplied by 0.75× to avoid introducing too much noise. This division only applies to lights whose [member Light3D.light_size] or [member Light3D.light_angular_distance] is [code]0.0[/code]).
</constant>
<constant name="SHADOW_QUALITY_SOFT_MEDIUM" value="2" enum="ShadowQuality">
<constant name="SHADOW_QUALITY_SOFT_LOW" value="2" enum="ShadowQuality">
Low shadow filtering quality (fast).
</constant>
<constant name="SHADOW_QUALITY_SOFT_HIGH" value="3" enum="ShadowQuality">
<constant name="SHADOW_QUALITY_SOFT_MEDIUM" value="3" enum="ShadowQuality">
Medium low shadow filtering quality (average).
</constant>
<constant name="SHADOW_QUALITY_SOFT_ULTRA" value="4" enum="ShadowQuality">
<constant name="SHADOW_QUALITY_SOFT_HIGH" value="4" enum="ShadowQuality">
High low shadow filtering quality (slow). When using this quality setting, [member Light3D.shadow_blur] is automatically multiplied by 1.5× to better make use of the high sample count. This increased blur also improves the stability of dynamic object shadows. This multiplier only applies to lights whose [member Light3D.light_size] or [member Light3D.light_angular_distance] is [code]0.0[/code]).
</constant>
<constant name="SHADOW_QUALITY_MAX" value="5" enum="ShadowQuality">
<constant name="SHADOW_QUALITY_SOFT_ULTRA" value="5" enum="ShadowQuality">
Highest low shadow filtering quality (slowest). When using this quality setting, [member Light3D.shadow_blur] is automatically multiplied by 2× to better make use of the high sample count. This increased blur also improves the stability of dynamic object shadows. This multiplier only applies to lights whose [member Light3D.light_size] or [member Light3D.light_angular_distance] is [code]0.0[/code]).
</constant>
<constant name="SHADOW_QUALITY_MAX" value="6" enum="ShadowQuality">
</constant>
<constant name="REFLECTION_PROBE_UPDATE_ONCE" value="0" enum="ReflectionProbeUpdateMode">
Reflection probe will update reflections once and then stop.
Expand Down
14 changes: 12 additions & 2 deletions servers/rendering/renderer_rd/renderer_scene_render_rd.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2696,9 +2696,14 @@ void RendererSceneRenderRD::shadows_quality_set(RS::ShadowQuality p_quality) {
switch (shadows_quality) {
case RS::SHADOW_QUALITY_HARD: {
penumbra_shadow_samples = 4;
soft_shadow_samples = 1;
soft_shadow_samples = 0;
shadows_quality_radius = 1.0;
} break;
case RS::SHADOW_QUALITY_SOFT_VERY_LOW: {
penumbra_shadow_samples = 4;
soft_shadow_samples = 1;
shadows_quality_radius = 1.5;
} break;
case RS::SHADOW_QUALITY_SOFT_LOW: {
penumbra_shadow_samples = 8;
soft_shadow_samples = 4;
Expand Down Expand Up @@ -2738,9 +2743,14 @@ void RendererSceneRenderRD::directional_shadow_quality_set(RS::ShadowQuality p_q
switch (directional_shadow_quality) {
case RS::SHADOW_QUALITY_HARD: {
directional_penumbra_shadow_samples = 4;
directional_soft_shadow_samples = 1;
directional_soft_shadow_samples = 0;
directional_shadow_quality_radius = 1.0;
} break;
case RS::SHADOW_QUALITY_SOFT_VERY_LOW: {
directional_penumbra_shadow_samples = 4;
directional_soft_shadow_samples = 1;
directional_shadow_quality_radius = 1.5;
} break;
case RS::SHADOW_QUALITY_SOFT_LOW: {
directional_penumbra_shadow_samples = 8;
directional_soft_shadow_samples = 4;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -301,7 +301,7 @@ float sample_directional_pcf_shadow(texture2D shadow, vec2 shadow_pixel_size, ve
float depth = coord.z;

//if only one sample is taken, take it from the center
if (sc_directional_soft_shadow_samples == 1) {
if (sc_directional_soft_shadow_samples == 0) {
return textureProj(sampler2DShadow(shadow, shadow_sampler), vec4(pos, depth, 1.0));
}

Expand All @@ -327,7 +327,7 @@ float sample_pcf_shadow(texture2D shadow, vec2 shadow_pixel_size, vec3 coord) {
float depth = coord.z;

//if only one sample is taken, take it from the center
if (sc_soft_shadow_samples == 1) {
if (sc_soft_shadow_samples == 0) {
return textureProj(sampler2DShadow(shadow, shadow_sampler), vec4(pos, depth, 1.0));
}

Expand All @@ -350,7 +350,7 @@ float sample_pcf_shadow(texture2D shadow, vec2 shadow_pixel_size, vec3 coord) {

float sample_omni_pcf_shadow(texture2D shadow, float blur_scale, vec2 coord, vec4 uv_rect, vec2 flip_offset, float depth) {
//if only one sample is taken, take it from the center
if (sc_soft_shadow_samples == 1) {
if (sc_soft_shadow_samples == 0) {
vec2 pos = coord * 0.5 + 0.5;
pos = uv_rect.xy + pos * uv_rect.zw;
return textureProj(sampler2DShadow(shadow, shadow_sampler), vec4(pos, depth, 1.0));
Expand Down
9 changes: 5 additions & 4 deletions servers/rendering_server.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1942,6 +1942,7 @@ void RenderingServer::_bind_methods() {
ClassDB::bind_method(D_METHOD("directional_shadow_atlas_set_size", "size", "is_16bits"), &RenderingServer::directional_shadow_atlas_set_size);

BIND_ENUM_CONSTANT(SHADOW_QUALITY_HARD);
BIND_ENUM_CONSTANT(SHADOW_QUALITY_SOFT_VERY_LOW);
BIND_ENUM_CONSTANT(SHADOW_QUALITY_SOFT_LOW);
BIND_ENUM_CONSTANT(SHADOW_QUALITY_SOFT_MEDIUM);
BIND_ENUM_CONSTANT(SHADOW_QUALITY_SOFT_HIGH);
Expand Down Expand Up @@ -2793,14 +2794,14 @@ RenderingServer::RenderingServer() {
GLOBAL_DEF("rendering/shadows/directional_shadow/size", 4096);
GLOBAL_DEF("rendering/shadows/directional_shadow/size.mobile", 2048);
ProjectSettings::get_singleton()->set_custom_property_info("rendering/shadows/directional_shadow/size", PropertyInfo(Variant::INT, "rendering/shadows/directional_shadow/size", PROPERTY_HINT_RANGE, "256,16384"));
GLOBAL_DEF("rendering/shadows/directional_shadow/soft_shadow_quality", 2);
GLOBAL_DEF("rendering/shadows/directional_shadow/soft_shadow_quality", 3);
GLOBAL_DEF("rendering/shadows/directional_shadow/soft_shadow_quality.mobile", 0);
ProjectSettings::get_singleton()->set_custom_property_info("rendering/shadows/directional_shadow/soft_shadow_quality", PropertyInfo(Variant::INT, "rendering/shadows/directional_shadow/soft_shadow_quality", PROPERTY_HINT_ENUM, "Hard (Fastest),Soft Low (Fast),Soft Medium (Average),Soft High (Slow),Soft Ultra (Slowest)"));
ProjectSettings::get_singleton()->set_custom_property_info("rendering/shadows/directional_shadow/soft_shadow_quality", PropertyInfo(Variant::INT, "rendering/shadows/directional_shadow/soft_shadow_quality", PROPERTY_HINT_ENUM, "Hard (Fastest),Soft Very Low (Faster),Soft Low (Fast),Soft Medium (Average),Soft High (Slow),Soft Ultra (Slowest)"));
GLOBAL_DEF("rendering/shadows/directional_shadow/16_bits", true);

GLOBAL_DEF("rendering/shadows/shadows/soft_shadow_quality", 2);
GLOBAL_DEF("rendering/shadows/shadows/soft_shadow_quality", 3);
GLOBAL_DEF("rendering/shadows/shadows/soft_shadow_quality.mobile", 0);
ProjectSettings::get_singleton()->set_custom_property_info("rendering/shadows/shadows/soft_shadow_quality", PropertyInfo(Variant::INT, "rendering/shadows/shadows/soft_shadow_quality", PROPERTY_HINT_ENUM, "Hard (Fastest),Soft Low (Fast),Soft Medium (Average),Soft High (Slow),Soft Ultra (Slowest)"));
ProjectSettings::get_singleton()->set_custom_property_info("rendering/shadows/shadows/soft_shadow_quality", PropertyInfo(Variant::INT, "rendering/shadows/shadows/soft_shadow_quality", PROPERTY_HINT_ENUM, "Hard (Fastest),Soft Very Low (Faster),Soft Low (Fast),Soft Medium (Average),Soft High (Slow),Soft Ultra (Slowest)"));

GLOBAL_DEF("rendering/2d/shadow_atlas/size", 2048);

Expand Down
1 change: 1 addition & 0 deletions servers/rendering_server.h
Original file line number Diff line number Diff line change
Expand Up @@ -474,6 +474,7 @@ class RenderingServer : public Object {

enum ShadowQuality {
SHADOW_QUALITY_HARD,
SHADOW_QUALITY_SOFT_VERY_LOW,
SHADOW_QUALITY_SOFT_LOW,
SHADOW_QUALITY_SOFT_MEDIUM,
SHADOW_QUALITY_SOFT_HIGH,
Expand Down

0 comments on commit e87ec8e

Please sign in to comment.