Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Stepped update of directional shadow maps #76291

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions doc/classes/ProjectSettings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -2177,6 +2177,9 @@
<member name="rendering/lights_and_shadows/directional_shadow/soft_shadow_filter_quality.mobile" type="int" setter="" getter="" default="0">
Lower-end override for [member rendering/lights_and_shadows/directional_shadow/soft_shadow_filter_quality] on mobile devices, due to performance concerns or driver support.
</member>
<member name="rendering/lights_and_shadows/directional_shadow/step_cascades" type="int" setter="" getter="" default="0">
Sets the default cascade step mode applied to our viewports.
</member>
<member name="rendering/lights_and_shadows/positional_shadow/atlas_16_bits" type="bool" setter="" getter="" default="true">
Use 16 bits for shadow depth map. Enabling this results in shadows having less precision and may result in shadow acne, but can lead to performance improvements on some devices.
</member>
Expand Down
27 changes: 27 additions & 0 deletions doc/classes/RenderingServer.xml
Original file line number Diff line number Diff line change
Expand Up @@ -3195,6 +3195,13 @@
Once finished with your RID, you will want to free the RID using the RenderingServer's [method free_rid] static method.
</description>
</method>
<method name="viewport_get_cascade_mode" qualifiers="const">
<return type="int" enum="RenderingServer.ViewportCascadeMode" />
<param index="0" name="viewport" type="RID" />
<description>
Obtain the cascade step mode for a given viewport.
</description>
</method>
<method name="viewport_get_measured_render_time_cpu" qualifiers="const">
<return type="float" />
<param index="0" name="viewport" type="RID" />
Expand Down Expand Up @@ -3266,6 +3273,14 @@
Sets the transformation of a viewport's canvas.
</description>
</method>
<method name="viewport_set_cascade_mode">
<return type="void" />
<param index="0" name="viewport" type="RID" />
<param index="1" name="mode" type="int" enum="RenderingServer.ViewportCascadeMode" />
<description>
Sets the cascade step mode of a viewport. See [enum ViewportCascadeMode] for options.
</description>
</method>
<method name="viewport_set_clear_mode">
<return type="void" />
<param index="0" name="viewport" type="RID" />
Expand Down Expand Up @@ -4354,6 +4369,18 @@
<constant name="VIEWPORT_VRS_MAX" value="3" enum="ViewportVRSMode">
Represents the size of the [enum ViewportVRSMode] enum.
</constant>
<constant name="VIEWPORT_CASCADE_ALL" value="0" enum="ViewportCascadeMode">
All directional shadow map cascades are updated each frame.
</constant>
<constant name="VIEWPORT_CASCADE_TWOSTEP" value="1" enum="ViewportCascadeMode">
Cascades 1 and 2 are updated each frame, 3 and 4 alternate between frames.
</constant>
<constant name="VIEWPORT_CASCADE_FOURSTEP" value="2" enum="ViewportCascadeMode">
Cascades are updated in the following repeating sequence: 1 + 2, 1 + 3, 1 + 2, 1 + 4.
</constant>
<constant name="VIEWPORT_CASCADE_MAX" value="3" enum="ViewportCascadeMode">
Representes the size of the [enum ViewportCascadeMode] enum.
</constant>
<constant name="SKY_MODE_AUTOMATIC" value="0" enum="SkyMode">
</constant>
<constant name="SKY_MODE_QUALITY" value="1" enum="SkyMode">
Expand Down
15 changes: 15 additions & 0 deletions doc/classes/Viewport.xml
Original file line number Diff line number Diff line change
Expand Up @@ -238,6 +238,9 @@
<member name="debug_draw" type="int" setter="set_debug_draw" getter="get_debug_draw" enum="Viewport.DebugDraw" default="0">
The overlay mode for test rendered geometry in debug purposes.
</member>
<member name="directional_shadow_atlas_cascade_mode" type="int" setter="set_cascade_mode" getter="get_cascade_mode" enum="Viewport.CascadeMode" default="0">
The directinal shadow map cascade mode. See [enum CascadeMode] for options.
</member>
<member name="disable_3d" type="bool" setter="set_disable_3d" getter="is_3d_disabled" default="false">
Disable 3D rendering (but keep 2D rendering).
</member>
Expand Down Expand Up @@ -582,5 +585,17 @@
<constant name="VRS_MAX" value="3" enum="VRSMode">
Represents the size of the [enum VRSMode] enum.
</constant>
<constant name="CASCADE_ALL" value="0" enum="CascadeMode">
All directional shadow map cascades are updated each frame.
</constant>
<constant name="CASCADE_TWOSTEP" value="1" enum="CascadeMode">
Cascades 1 and 2 are updated each frame, 3 and 4 alternate between frames.
</constant>
<constant name="CASCADE_FOURSTEP" value="2" enum="CascadeMode">
Cascades are updated in the following repeating sequence: 1 + 2, 1 + 3, 1 + 2, 1 + 4.
</constant>
<constant name="CASCADE_MAX" value="3" enum="CascadeMode">
Representes the size of the [enum CascadeMode] enum.
</constant>
</constants>
</class>
2 changes: 1 addition & 1 deletion drivers/gles3/rasterizer_scene_gles3.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1696,7 +1696,7 @@ void RasterizerSceneGLES3::_setup_lights(const RenderDataGLES3 *p_render_data, b
glBindBuffer(GL_UNIFORM_BUFFER, 0);
}

void RasterizerSceneGLES3::render_scene(const Ref<RenderSceneBuffers> &p_render_buffers, const CameraData *p_camera_data, const CameraData *p_prev_camera_data, const PagedArray<RenderGeometryInstance *> &p_instances, const PagedArray<RID> &p_lights, const PagedArray<RID> &p_reflection_probes, const PagedArray<RID> &p_voxel_gi_instances, const PagedArray<RID> &p_decals, const PagedArray<RID> &p_lightmaps, const PagedArray<RID> &p_fog_volumes, RID p_environment, RID p_camera_attributes, RID p_shadow_atlas, RID p_occluder_debug_tex, RID p_reflection_atlas, RID p_reflection_probe, int p_reflection_probe_pass, float p_screen_mesh_lod_threshold, const RenderShadowData *p_render_shadows, int p_render_shadow_count, const RenderSDFGIData *p_render_sdfgi_regions, int p_render_sdfgi_region_count, const RenderSDFGIUpdateData *p_sdfgi_update_data, RenderingMethod::RenderInfo *r_render_info) {
void RasterizerSceneGLES3::render_scene(const Ref<RenderSceneBuffers> &p_render_buffers, const CameraData *p_camera_data, const CameraData *p_prev_camera_data, const PagedArray<RenderGeometryInstance *> &p_instances, const PagedArray<RID> &p_lights, const PagedArray<RID> &p_reflection_probes, const PagedArray<RID> &p_voxel_gi_instances, const PagedArray<RID> &p_decals, const PagedArray<RID> &p_lightmaps, const PagedArray<RID> &p_fog_volumes, RID p_environment, RID p_camera_attributes, RID p_shadow_atlas, RID p_occluder_debug_tex, RID p_viewport, RID p_reflection_atlas, RID p_reflection_probe, int p_reflection_probe_pass, float p_screen_mesh_lod_threshold, const RenderShadowData *p_render_shadows, int p_render_shadow_count, const RenderSDFGIData *p_render_sdfgi_regions, int p_render_sdfgi_region_count, const RenderSDFGIUpdateData *p_sdfgi_update_data, RenderingMethod::RenderInfo *r_render_info) {
GLES3::TextureStorage *texture_storage = GLES3::TextureStorage::get_singleton();
GLES3::Config *config = GLES3::Config::get_singleton();
RENDER_TIMESTAMP("Setup 3D Scene");
Expand Down
2 changes: 1 addition & 1 deletion drivers/gles3/rasterizer_scene_gles3.h
Original file line number Diff line number Diff line change
Expand Up @@ -646,7 +646,7 @@ class RasterizerSceneGLES3 : public RendererSceneRender {

void voxel_gi_set_quality(RS::VoxelGIQuality) override;

void render_scene(const Ref<RenderSceneBuffers> &p_render_buffers, const CameraData *p_camera_data, const CameraData *p_prev_camera_data, const PagedArray<RenderGeometryInstance *> &p_instances, const PagedArray<RID> &p_lights, const PagedArray<RID> &p_reflection_probes, const PagedArray<RID> &p_voxel_gi_instances, const PagedArray<RID> &p_decals, const PagedArray<RID> &p_lightmaps, const PagedArray<RID> &p_fog_volumes, RID p_environment, RID p_camera_attributes, RID p_shadow_atlas, RID p_occluder_debug_tex, RID p_reflection_atlas, RID p_reflection_probe, int p_reflection_probe_pass, float p_screen_mesh_lod_threshold, const RenderShadowData *p_render_shadows, int p_render_shadow_count, const RenderSDFGIData *p_render_sdfgi_regions, int p_render_sdfgi_region_count, const RenderSDFGIUpdateData *p_sdfgi_update_data = nullptr, RenderingMethod::RenderInfo *r_render_info = nullptr) override;
void render_scene(const Ref<RenderSceneBuffers> &p_render_buffers, const CameraData *p_camera_data, const CameraData *p_prev_camera_data, const PagedArray<RenderGeometryInstance *> &p_instances, const PagedArray<RID> &p_lights, const PagedArray<RID> &p_reflection_probes, const PagedArray<RID> &p_voxel_gi_instances, const PagedArray<RID> &p_decals, const PagedArray<RID> &p_lightmaps, const PagedArray<RID> &p_fog_volumes, RID p_environment, RID p_camera_attributes, RID p_shadow_atlas, RID p_occluder_debug_tex, RID p_viewport, RID p_reflection_atlas, RID p_reflection_probe, int p_reflection_probe_pass, float p_screen_mesh_lod_threshold, const RenderShadowData *p_render_shadows, int p_render_shadow_count, const RenderSDFGIData *p_render_sdfgi_regions, int p_render_sdfgi_region_count, const RenderSDFGIUpdateData *p_sdfgi_update_data = nullptr, RenderingMethod::RenderInfo *r_render_info = nullptr) override;
void render_material(const Transform3D &p_cam_transform, const Projection &p_cam_projection, bool p_cam_orthogonal, const PagedArray<RenderGeometryInstance *> &p_instances, RID p_framebuffer, const Rect2i &p_region) override;
void render_particle_collider_heightfield(RID p_collider, const Transform3D &p_transform, const PagedArray<RenderGeometryInstance *> &p_instances) override;

Expand Down
2 changes: 1 addition & 1 deletion drivers/gles3/storage/light_storage.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -374,7 +374,7 @@ void LightStorage::light_instance_set_aabb(RID p_light_instance, const AABB &p_a
light_instance->aabb = p_aabb;
}

void LightStorage::light_instance_set_shadow_transform(RID p_light_instance, const Projection &p_projection, const Transform3D &p_transform, float p_far, float p_split, int p_pass, float p_shadow_texel_size, float p_bias_scale, float p_range_begin, const Vector2 &p_uv_scale) {
void LightStorage::light_instance_set_shadow_transform(RID p_light_instance, const Projection &p_projection, const Transform3D &p_transform, float p_far, float p_split, int p_pass, float p_shadow_texel_size, float p_bias_scale, float p_range_begin, const Vector2 &p_uv_scale, RID p_viewport) {
}

void LightStorage::light_instance_mark_visible(RID p_light_instance) {
Expand Down
7 changes: 6 additions & 1 deletion drivers/gles3/storage/light_storage.h
Original file line number Diff line number Diff line change
Expand Up @@ -302,7 +302,7 @@ class LightStorage : public RendererLightStorage {

virtual void light_instance_set_transform(RID p_light_instance, const Transform3D &p_transform) override;
virtual void light_instance_set_aabb(RID p_light_instance, const AABB &p_aabb) override;
virtual void light_instance_set_shadow_transform(RID p_light_instance, const Projection &p_projection, const Transform3D &p_transform, float p_far, float p_split, int p_pass, float p_shadow_texel_size, float p_bias_scale = 1.0, float p_range_begin = 0, const Vector2 &p_uv_scale = Vector2()) override;
virtual void light_instance_set_shadow_transform(RID p_light_instance, const Projection &p_projection, const Transform3D &p_transform, float p_far, float p_split, int p_pass, float p_shadow_texel_size, float p_bias_scale = 1.0, float p_range_begin = 0, const Vector2 &p_uv_scale = Vector2(), RID p_viewport = RID()) override;
virtual void light_instance_mark_visible(RID p_light_instance) override;

_FORCE_INLINE_ RS::LightType light_instance_get_type(RID p_light_instance) {
Expand Down Expand Up @@ -423,6 +423,11 @@ class LightStorage : public RendererLightStorage {
virtual void directional_shadow_atlas_set_size(int p_size, bool p_16_bits = true) override;
virtual int get_directional_light_shadow_size(RID p_light_intance) override;
virtual void set_directional_shadow_count(int p_count) override;

virtual bool directional_shadow_get_needs_full_update(RID p_viewport) const override { return false; }
virtual void directional_shadow_set_needs_full_update(RID p_viewport, bool p_needs_update) override {}

virtual void cleanup_directional_shadow_viewport(RID p_viewport) override {}
};

} // namespace GLES3
Expand Down
3 changes: 3 additions & 0 deletions editor/editor_node.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -535,6 +535,9 @@ void EditorNode::_update_from_settings() {
Viewport::MSAA msaa = Viewport::MSAA(int(GLOBAL_GET("rendering/anti_aliasing/quality/msaa_2d")));
scene_root->set_msaa_2d(msaa);

Viewport::CascadeMode cascade_mode = Viewport::CascadeMode(int(GLOBAL_GET("rendering/lights_and_shadows/directional_shadow/step_cascades")));
scene_root->set_cascade_mode(cascade_mode);

float mesh_lod_threshold = GLOBAL_GET("rendering/mesh_lod/lod_change/threshold_pixels");
scene_root->set_mesh_lod_threshold(mesh_lod_threshold);

Expand Down
33 changes: 33 additions & 0 deletions scene/main/viewport.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3276,6 +3276,26 @@ Ref<Texture2D> Viewport::get_vrs_texture() const {
return vrs_texture;
}

void Viewport::set_cascade_mode(Viewport::CascadeMode p_cascade_mode) {
cascade_mode = p_cascade_mode;

switch (cascade_mode) {
case CASCADE_TWOSTEP: {
RS::get_singleton()->viewport_set_cascade_mode(viewport, RS::VIEWPORT_CASCADE_TWOSTEP);
} break;
case CASCADE_FOURSTEP: {
RS::get_singleton()->viewport_set_cascade_mode(viewport, RS::VIEWPORT_CASCADE_FOURSTEP);
} break;
default: {
RS::get_singleton()->viewport_set_cascade_mode(viewport, RS::VIEWPORT_CASCADE_ALL);
} break;
}
}

Viewport::CascadeMode Viewport::get_cascade_mode() const {
return cascade_mode;
}

DisplayServer::WindowID Viewport::get_window_id() const {
return DisplayServer::MAIN_WINDOW_ID;
}
Expand Down Expand Up @@ -3993,6 +4013,9 @@ void Viewport::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_vrs_texture", "texture"), &Viewport::set_vrs_texture);
ClassDB::bind_method(D_METHOD("get_vrs_texture"), &Viewport::get_vrs_texture);

ClassDB::bind_method(D_METHOD("set_cascade_mode", "mode"), &Viewport::set_cascade_mode);
ClassDB::bind_method(D_METHOD("get_cascade_mode"), &Viewport::get_cascade_mode);

ADD_PROPERTY(PropertyInfo(Variant::BOOL, "disable_3d"), "set_disable_3d", "is_3d_disabled");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "use_xr"), "set_use_xr", "is_using_xr");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "own_world_3d"), "set_use_own_world_3d", "is_using_own_world_3d");
Expand Down Expand Up @@ -4040,6 +4063,10 @@ void Viewport::_bind_methods() {
ADD_GROUP("SDF", "sdf_");
ADD_PROPERTY(PropertyInfo(Variant::INT, "sdf_oversize", PROPERTY_HINT_ENUM, "100%,120%,150%,200%"), "set_sdf_oversize", "get_sdf_oversize");
ADD_PROPERTY(PropertyInfo(Variant::INT, "sdf_scale", PROPERTY_HINT_ENUM, "100%,50%,25%"), "set_sdf_scale", "get_sdf_scale");
#ifndef _3D_DISABLED
ADD_GROUP("Directional Shadow Atlas", "directional_shadow_atlas_");
ADD_PROPERTY(PropertyInfo(Variant::INT, "directional_shadow_atlas_cascade_mode", PROPERTY_HINT_ENUM, "All (Slowest),Two step (Faster),Four step (Fastest)"), "set_cascade_mode", "get_cascade_mode");
#endif
ADD_GROUP("Positional Shadow Atlas", "positional_shadow_atlas_");
ADD_PROPERTY(PropertyInfo(Variant::INT, "positional_shadow_atlas_size"), "set_positional_shadow_atlas_size", "get_positional_shadow_atlas_size");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "positional_shadow_atlas_16_bits"), "set_positional_shadow_atlas_16_bits", "get_positional_shadow_atlas_16_bits");
Expand Down Expand Up @@ -4139,6 +4166,11 @@ void Viewport::_bind_methods() {
BIND_ENUM_CONSTANT(VRS_TEXTURE);
BIND_ENUM_CONSTANT(VRS_XR);
BIND_ENUM_CONSTANT(VRS_MAX);

BIND_ENUM_CONSTANT(CASCADE_ALL);
BIND_ENUM_CONSTANT(CASCADE_TWOSTEP);
BIND_ENUM_CONSTANT(CASCADE_FOURSTEP);
BIND_ENUM_CONSTANT(CASCADE_MAX);
}

void Viewport::_validate_property(PropertyInfo &p_property) const {
Expand Down Expand Up @@ -4187,6 +4219,7 @@ Viewport::Viewport() {
set_scaling_3d_scale(GLOBAL_GET("rendering/scaling_3d/scale"));
set_fsr_sharpness((float)GLOBAL_GET("rendering/scaling_3d/fsr_sharpness"));
set_texture_mipmap_bias((float)GLOBAL_GET("rendering/textures/default_filters/texture_mipmap_bias"));
set_cascade_mode(CascadeMode(int(GLOBAL_GET("rendering/lights_and_shadows/directional_shadow/step_cascades"))));
#endif // _3D_DISABLED

set_sdf_oversize(sdf_oversize); // Set to server.
Expand Down
16 changes: 16 additions & 0 deletions scene/main/viewport.h
Original file line number Diff line number Diff line change
Expand Up @@ -204,6 +204,13 @@ class Viewport : public Node {
VRS_MAX
};

enum CascadeMode {
CASCADE_ALL,
CASCADE_TWOSTEP,
CASCADE_FOURSTEP,
CASCADE_MAX
};

private:
friend class ViewportTexture;

Expand Down Expand Up @@ -348,6 +355,9 @@ class Viewport : public Node {
VRSMode vrs_mode = VRS_DISABLED;
Ref<Texture2D> vrs_texture;

// Directional shadow cascade
CascadeMode cascade_mode = CASCADE_ALL;

struct GUI {
// info used when this is a window

Expand Down Expand Up @@ -638,6 +648,11 @@ class Viewport : public Node {
void set_vrs_texture(Ref<Texture2D> p_texture);
Ref<Texture2D> get_vrs_texture() const;

// Directional shadow cascade

void set_cascade_mode(CascadeMode p_cascade_mode);
CascadeMode get_cascade_mode() const;

virtual DisplayServer::WindowID get_window_id() const = 0;

void set_embedding_subwindows(bool p_embed);
Expand Down Expand Up @@ -802,6 +817,7 @@ VARIANT_ENUM_CAST(Viewport::DebugDraw);
VARIANT_ENUM_CAST(Viewport::SDFScale);
VARIANT_ENUM_CAST(Viewport::SDFOversize);
VARIANT_ENUM_CAST(Viewport::VRSMode);
VARIANT_ENUM_CAST(Viewport::CascadeMode);
VARIANT_ENUM_CAST(SubViewport::ClearMode);
VARIANT_ENUM_CAST(Viewport::RenderInfo);
VARIANT_ENUM_CAST(Viewport::RenderInfoType);
Expand Down
2 changes: 1 addition & 1 deletion servers/rendering/dummy/rasterizer_scene_dummy.h
Original file line number Diff line number Diff line change
Expand Up @@ -145,7 +145,7 @@ class RasterizerSceneDummy : public RendererSceneRender {

void voxel_gi_set_quality(RS::VoxelGIQuality) override {}

void render_scene(const Ref<RenderSceneBuffers> &p_render_buffers, const CameraData *p_camera_data, const CameraData *p_prev_camera_data, const PagedArray<RenderGeometryInstance *> &p_instances, const PagedArray<RID> &p_lights, const PagedArray<RID> &p_reflection_probes, const PagedArray<RID> &p_voxel_gi_instances, const PagedArray<RID> &p_decals, const PagedArray<RID> &p_lightmaps, const PagedArray<RID> &p_fog_volumes, RID p_environment, RID p_camera_attributes, RID p_shadow_atlas, RID p_occluder_debug_tex, RID p_reflection_atlas, RID p_reflection_probe, int p_reflection_probe_pass, float p_screen_mesh_lod_threshold, const RenderShadowData *p_render_shadows, int p_render_shadow_count, const RenderSDFGIData *p_render_sdfgi_regions, int p_render_sdfgi_region_count, const RenderSDFGIUpdateData *p_sdfgi_update_data = nullptr, RenderingMethod::RenderInfo *r_info = nullptr) override {}
void render_scene(const Ref<RenderSceneBuffers> &p_render_buffers, const CameraData *p_camera_data, const CameraData *p_prev_camera_data, const PagedArray<RenderGeometryInstance *> &p_instances, const PagedArray<RID> &p_lights, const PagedArray<RID> &p_reflection_probes, const PagedArray<RID> &p_voxel_gi_instances, const PagedArray<RID> &p_decals, const PagedArray<RID> &p_lightmaps, const PagedArray<RID> &p_fog_volumes, RID p_environment, RID p_camera_attributes, RID p_shadow_atlas, RID p_occluder_debug_tex, RID p_viewport, RID p_reflection_atlas, RID p_reflection_probe, int p_reflection_probe_pass, float p_screen_mesh_lod_threshold, const RenderShadowData *p_render_shadows, int p_render_shadow_count, const RenderSDFGIData *p_render_sdfgi_regions, int p_render_sdfgi_region_count, const RenderSDFGIUpdateData *p_sdfgi_update_data = nullptr, RenderingMethod::RenderInfo *r_info = nullptr) override {}
void render_material(const Transform3D &p_cam_transform, const Projection &p_cam_projection, bool p_cam_orthogonal, const PagedArray<RenderGeometryInstance *> &p_instances, RID p_framebuffer, const Rect2i &p_region) override {}
void render_particle_collider_heightfield(RID p_collider, const Transform3D &p_transform, const PagedArray<RenderGeometryInstance *> &p_instances) override {}

Expand Down
Loading