|
@@ -1276,14 +1276,26 @@ void RendererSceneRenderRD::sdfgi_update_probes(RID p_render_buffers, RID p_envi
|
|
|
push_constant.multibounce = rb->sdfgi->uses_multibounce;
|
|
|
push_constant.y_mult = rb->sdfgi->y_mult;
|
|
|
|
|
|
- push_constant.process_offset = 0;
|
|
|
- push_constant.process_increment = 1;
|
|
|
-
|
|
|
for (uint32_t i = 0; i < rb->sdfgi->cascades.size(); i++) {
|
|
|
SDFGI::Cascade &cascade = rb->sdfgi->cascades[i];
|
|
|
push_constant.light_count = cascade_light_count[i];
|
|
|
push_constant.cascade = i;
|
|
|
|
|
|
+ if (rb->sdfgi->cascades[i].all_dynamic_lights_dirty || sdfgi_frames_to_update_light == RS::ENV_SDFGI_UPDATE_LIGHT_IN_1_FRAME) {
|
|
|
+ push_constant.process_offset = 0;
|
|
|
+ push_constant.process_increment = 1;
|
|
|
+ } else {
|
|
|
+ static uint32_t frames_to_update_table[RS::ENV_SDFGI_UPDATE_LIGHT_MAX] = {
|
|
|
+ 1, 2, 4, 8, 16
|
|
|
+ };
|
|
|
+
|
|
|
+ uint32_t frames_to_update = frames_to_update_table[sdfgi_frames_to_update_light];
|
|
|
+
|
|
|
+ push_constant.process_offset = RSG::rasterizer->get_frame_number() % frames_to_update;
|
|
|
+ push_constant.process_increment = frames_to_update;
|
|
|
+ }
|
|
|
+ rb->sdfgi->cascades[i].all_dynamic_lights_dirty = false;
|
|
|
+
|
|
|
RD::get_singleton()->compute_list_bind_uniform_set(compute_list, cascade.sdf_direct_light_uniform_set, 0);
|
|
|
RD::get_singleton()->compute_list_set_push_constant(compute_list, &push_constant, sizeof(SDGIShader::DirectLightPushConstant));
|
|
|
RD::get_singleton()->compute_list_dispatch_indirect(compute_list, cascade.solid_cell_dispatch_buffer, 0);
|
|
@@ -1301,7 +1313,7 @@ void RendererSceneRenderRD::sdfgi_update_probes(RID p_render_buffers, RID p_envi
|
|
|
push_constant.probe_axis_size = rb->sdfgi->probe_axis_count;
|
|
|
push_constant.history_index = rb->sdfgi->render_pass % rb->sdfgi->history_size;
|
|
|
push_constant.history_size = rb->sdfgi->history_size;
|
|
|
- static const uint32_t ray_count[RS::ENV_SDFGI_RAY_COUNT_MAX] = { 8, 16, 32, 64, 96, 128 };
|
|
|
+ static const uint32_t ray_count[RS::ENV_SDFGI_RAY_COUNT_MAX] = { 4, 8, 16, 32, 64, 96, 128 };
|
|
|
push_constant.ray_count = ray_count[sdfgi_ray_count];
|
|
|
push_constant.ray_bias = rb->sdfgi->probe_bias;
|
|
|
push_constant.image_size[0] = rb->sdfgi->probe_axis_count * rb->sdfgi->probe_axis_count;
|
|
@@ -1492,13 +1504,35 @@ void RendererSceneRenderRD::_setup_giprobes(RID p_render_buffers, const Transfor
|
|
|
}
|
|
|
}
|
|
|
|
|
|
-void RendererSceneRenderRD::_process_gi(RID p_render_buffers, RID p_normal_roughness_buffer, RID p_ambient_buffer, RID p_reflection_buffer, RID p_gi_probe_buffer, RID p_environment, const CameraMatrix &p_projection, const Transform &p_transform, const PagedArray<RID> &p_gi_probes) {
|
|
|
+void RendererSceneRenderRD::_process_gi(RID p_render_buffers, RID p_normal_roughness_buffer, RID p_gi_probe_buffer, RID p_environment, const CameraMatrix &p_projection, const Transform &p_transform, const PagedArray<RID> &p_gi_probes) {
|
|
|
RENDER_TIMESTAMP("Render GI");
|
|
|
|
|
|
RenderBuffers *rb = render_buffers_owner.getornull(p_render_buffers);
|
|
|
ERR_FAIL_COND(rb == nullptr);
|
|
|
Environment *env = environment_owner.getornull(p_environment);
|
|
|
|
|
|
+ if (rb->ambient_buffer.is_null() || rb->using_half_size_gi != gi.half_resolution) {
|
|
|
+ if (rb->ambient_buffer.is_valid()) {
|
|
|
+ RD::get_singleton()->free(rb->ambient_buffer);
|
|
|
+ RD::get_singleton()->free(rb->reflection_buffer);
|
|
|
+ }
|
|
|
+
|
|
|
+ RD::TextureFormat tf;
|
|
|
+ tf.format = RD::DATA_FORMAT_R16G16B16A16_SFLOAT;
|
|
|
+ tf.width = rb->width;
|
|
|
+ tf.height = rb->height;
|
|
|
+ if (gi.half_resolution) {
|
|
|
+ tf.width >>= 1;
|
|
|
+ tf.height >>= 1;
|
|
|
+ }
|
|
|
+ tf.usage_bits = RD::TEXTURE_USAGE_SAMPLING_BIT | RD::TEXTURE_USAGE_STORAGE_BIT;
|
|
|
+ rb->reflection_buffer = RD::get_singleton()->texture_create(tf, RD::TextureView());
|
|
|
+ rb->ambient_buffer = RD::get_singleton()->texture_create(tf, RD::TextureView());
|
|
|
+ rb->using_half_size_gi = gi.half_resolution;
|
|
|
+
|
|
|
+ _render_buffers_uniform_set_changed(p_render_buffers);
|
|
|
+ }
|
|
|
+
|
|
|
GI::PushConstant push_constant;
|
|
|
|
|
|
push_constant.screen_size[0] = rb->width;
|
|
@@ -1693,7 +1727,7 @@ void RendererSceneRenderRD::_process_gi(RID p_render_buffers, RID p_normal_rough
|
|
|
RD::Uniform u;
|
|
|
u.uniform_type = RD::UNIFORM_TYPE_IMAGE;
|
|
|
u.binding = 9;
|
|
|
- u.ids.push_back(p_ambient_buffer);
|
|
|
+ u.ids.push_back(rb->ambient_buffer);
|
|
|
uniforms.push_back(u);
|
|
|
}
|
|
|
|
|
@@ -1701,7 +1735,7 @@ void RendererSceneRenderRD::_process_gi(RID p_render_buffers, RID p_normal_rough
|
|
|
RD::Uniform u;
|
|
|
u.uniform_type = RD::UNIFORM_TYPE_IMAGE;
|
|
|
u.binding = 10;
|
|
|
- u.ids.push_back(p_reflection_buffer);
|
|
|
+ u.ids.push_back(rb->reflection_buffer);
|
|
|
uniforms.push_back(u);
|
|
|
}
|
|
|
|
|
@@ -1765,12 +1799,23 @@ void RendererSceneRenderRD::_process_gi(RID p_render_buffers, RID p_normal_rough
|
|
|
rb->gi_uniform_set = RD::get_singleton()->uniform_set_create(uniforms, gi.shader.version_get_shader(gi.shader_version, 0), 0);
|
|
|
}
|
|
|
|
|
|
- GI::Mode mode = (use_sdfgi && use_giprobes) ? GI::MODE_COMBINED : (use_sdfgi ? GI::MODE_SDFGI : GI::MODE_GIPROBE);
|
|
|
+ GI::Mode mode;
|
|
|
+
|
|
|
+ if (rb->using_half_size_gi) {
|
|
|
+ mode = (use_sdfgi && use_giprobes) ? GI::MODE_HALF_RES_COMBINED : (use_sdfgi ? GI::MODE_HALF_RES_SDFGI : GI::MODE_HALF_RES_GIPROBE);
|
|
|
+ } else {
|
|
|
+ mode = (use_sdfgi && use_giprobes) ? GI::MODE_COMBINED : (use_sdfgi ? GI::MODE_SDFGI : GI::MODE_GIPROBE);
|
|
|
+ }
|
|
|
RD::ComputeListID compute_list = RD::get_singleton()->compute_list_begin();
|
|
|
RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, gi.pipelines[mode]);
|
|
|
RD::get_singleton()->compute_list_bind_uniform_set(compute_list, rb->gi_uniform_set, 0);
|
|
|
RD::get_singleton()->compute_list_set_push_constant(compute_list, &push_constant, sizeof(GI::PushConstant));
|
|
|
- RD::get_singleton()->compute_list_dispatch_threads(compute_list, rb->width, rb->height, 1, 8, 8, 1);
|
|
|
+
|
|
|
+ if (rb->using_half_size_gi) {
|
|
|
+ RD::get_singleton()->compute_list_dispatch_threads(compute_list, rb->width >> 1, rb->height >> 1, 1, 8, 8, 1);
|
|
|
+ } else {
|
|
|
+ RD::get_singleton()->compute_list_dispatch_threads(compute_list, rb->width, rb->height, 1, 8, 8, 1);
|
|
|
+ }
|
|
|
RD::get_singleton()->compute_list_end();
|
|
|
}
|
|
|
|
|
@@ -3105,6 +3150,9 @@ void RendererSceneRenderRD::environment_set_sdfgi_ray_count(RS::EnvironmentSDFGI
|
|
|
void RendererSceneRenderRD::environment_set_sdfgi_frames_to_converge(RS::EnvironmentSDFGIFramesToConverge p_frames) {
|
|
|
sdfgi_frames_to_converge = p_frames;
|
|
|
}
|
|
|
+void RendererSceneRenderRD::environment_set_sdfgi_frames_to_update_light(RS::EnvironmentSDFGIFramesToUpdateLight p_update) {
|
|
|
+ sdfgi_frames_to_update_light = p_update;
|
|
|
+}
|
|
|
|
|
|
void RendererSceneRenderRD::environment_set_ssr(RID p_env, bool p_enable, int p_max_steps, float p_fade_int, float p_fade_out, float p_depth_tolerance) {
|
|
|
Environment *env = environment_owner.getornull(p_env);
|
|
@@ -3516,13 +3564,28 @@ RID RendererSceneRenderRD::shadow_atlas_create() {
|
|
|
return shadow_atlas_owner.make_rid(ShadowAtlas());
|
|
|
}
|
|
|
|
|
|
-void RendererSceneRenderRD::shadow_atlas_set_size(RID p_atlas, int p_size) {
|
|
|
+void RendererSceneRenderRD::_update_shadow_atlas(ShadowAtlas *shadow_atlas) {
|
|
|
+ if (shadow_atlas->size > 0 && shadow_atlas->depth.is_null()) {
|
|
|
+ RD::TextureFormat tf;
|
|
|
+ tf.format = shadow_atlas->use_16_bits ? RD::DATA_FORMAT_D16_UNORM : RD::DATA_FORMAT_D32_SFLOAT;
|
|
|
+ tf.width = shadow_atlas->size;
|
|
|
+ tf.height = shadow_atlas->size;
|
|
|
+ tf.usage_bits = RD::TEXTURE_USAGE_SAMPLING_BIT | RD::TEXTURE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT;
|
|
|
+
|
|
|
+ shadow_atlas->depth = RD::get_singleton()->texture_create(tf, RD::TextureView());
|
|
|
+ Vector<RID> fb_tex;
|
|
|
+ fb_tex.push_back(shadow_atlas->depth);
|
|
|
+ shadow_atlas->fb = RD::get_singleton()->framebuffer_create(fb_tex);
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+void RendererSceneRenderRD::shadow_atlas_set_size(RID p_atlas, int p_size, bool p_16_bits) {
|
|
|
ShadowAtlas *shadow_atlas = shadow_atlas_owner.getornull(p_atlas);
|
|
|
ERR_FAIL_COND(!shadow_atlas);
|
|
|
ERR_FAIL_COND(p_size < 0);
|
|
|
p_size = next_power_of_2(p_size);
|
|
|
|
|
|
- if (p_size == shadow_atlas->size) {
|
|
|
+ if (p_size == shadow_atlas->size && p_16_bits == shadow_atlas->use_16_bits) {
|
|
|
return;
|
|
|
}
|
|
|
|
|
@@ -3549,16 +3612,7 @@ void RendererSceneRenderRD::shadow_atlas_set_size(RID p_atlas, int p_size) {
|
|
|
shadow_atlas->shadow_owners.clear();
|
|
|
|
|
|
shadow_atlas->size = p_size;
|
|
|
-
|
|
|
- if (shadow_atlas->size) {
|
|
|
- RD::TextureFormat tf;
|
|
|
- tf.format = RD::DATA_FORMAT_R32_SFLOAT;
|
|
|
- tf.width = shadow_atlas->size;
|
|
|
- tf.height = shadow_atlas->size;
|
|
|
- tf.usage_bits = RD::TEXTURE_USAGE_SAMPLING_BIT | RD::TEXTURE_USAGE_STORAGE_BIT;
|
|
|
-
|
|
|
- shadow_atlas->depth = RD::get_singleton()->texture_create(tf, RD::TextureView());
|
|
|
- }
|
|
|
+ shadow_atlas->use_16_bits = p_size;
|
|
|
}
|
|
|
|
|
|
void RendererSceneRenderRD::shadow_atlas_set_quadrant_subdivision(RID p_atlas, int p_quadrant, int p_subdivision) {
|
|
@@ -3813,10 +3867,24 @@ bool RendererSceneRenderRD::shadow_atlas_update_light(RID p_atlas, RID p_light_i
|
|
|
return false;
|
|
|
}
|
|
|
|
|
|
-void RendererSceneRenderRD::directional_shadow_atlas_set_size(int p_size) {
|
|
|
+void RendererSceneRenderRD::_update_directional_shadow_atlas() {
|
|
|
+ if (directional_shadow.depth.is_null() && directional_shadow.size > 0) {
|
|
|
+ RD::TextureFormat tf;
|
|
|
+ tf.format = directional_shadow.use_16_bits ? RD::DATA_FORMAT_D16_UNORM : RD::DATA_FORMAT_D32_SFLOAT;
|
|
|
+ tf.width = directional_shadow.size;
|
|
|
+ tf.height = directional_shadow.size;
|
|
|
+ tf.usage_bits = RD::TEXTURE_USAGE_SAMPLING_BIT | RD::TEXTURE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT;
|
|
|
+
|
|
|
+ directional_shadow.depth = RD::get_singleton()->texture_create(tf, RD::TextureView());
|
|
|
+ Vector<RID> fb_tex;
|
|
|
+ fb_tex.push_back(directional_shadow.depth);
|
|
|
+ directional_shadow.fb = RD::get_singleton()->framebuffer_create(fb_tex);
|
|
|
+ }
|
|
|
+}
|
|
|
+void RendererSceneRenderRD::directional_shadow_atlas_set_size(int p_size, bool p_16_bits) {
|
|
|
p_size = nearest_power_of_2_templated(p_size);
|
|
|
|
|
|
- if (directional_shadow.size == p_size) {
|
|
|
+ if (directional_shadow.size == p_size && directional_shadow.use_16_bits == p_16_bits) {
|
|
|
return;
|
|
|
}
|
|
|
|
|
@@ -3826,19 +3894,8 @@ void RendererSceneRenderRD::directional_shadow_atlas_set_size(int p_size) {
|
|
|
RD::get_singleton()->free(directional_shadow.depth);
|
|
|
_clear_shadow_shrink_stages(directional_shadow.shrink_stages);
|
|
|
directional_shadow.depth = RID();
|
|
|
+ _base_uniforms_changed();
|
|
|
}
|
|
|
-
|
|
|
- if (p_size > 0) {
|
|
|
- RD::TextureFormat tf;
|
|
|
- tf.format = RD::DATA_FORMAT_R32_SFLOAT;
|
|
|
- tf.width = p_size;
|
|
|
- tf.height = p_size;
|
|
|
- tf.usage_bits = RD::TEXTURE_USAGE_SAMPLING_BIT | RD::TEXTURE_USAGE_STORAGE_BIT;
|
|
|
-
|
|
|
- directional_shadow.depth = RD::get_singleton()->texture_create(tf, RD::TextureView());
|
|
|
- }
|
|
|
-
|
|
|
- _base_uniforms_changed();
|
|
|
}
|
|
|
|
|
|
void RendererSceneRenderRD::set_directional_shadow_count(int p_count) {
|
|
@@ -4008,29 +4065,6 @@ RendererSceneRenderRD::ShadowCubemap *RendererSceneRenderRD::_get_shadow_cubemap
|
|
|
return &shadow_cubemaps[p_size];
|
|
|
}
|
|
|
|
|
|
-RendererSceneRenderRD::ShadowMap *RendererSceneRenderRD::_get_shadow_map(const Size2i &p_size) {
|
|
|
- if (!shadow_maps.has(p_size)) {
|
|
|
- ShadowMap sm;
|
|
|
- {
|
|
|
- RD::TextureFormat tf;
|
|
|
- tf.format = RD::get_singleton()->texture_is_format_supported_for_usage(RD::DATA_FORMAT_D32_SFLOAT, RD::TEXTURE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT) ? RD::DATA_FORMAT_D32_SFLOAT : RD::DATA_FORMAT_X8_D24_UNORM_PACK32;
|
|
|
- tf.width = p_size.width;
|
|
|
- tf.height = p_size.height;
|
|
|
- tf.usage_bits = RD::TEXTURE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT | RD::TEXTURE_USAGE_SAMPLING_BIT;
|
|
|
-
|
|
|
- sm.depth = RD::get_singleton()->texture_create(tf, RD::TextureView());
|
|
|
- }
|
|
|
-
|
|
|
- Vector<RID> fbtex;
|
|
|
- fbtex.push_back(sm.depth);
|
|
|
- sm.fb = RD::get_singleton()->framebuffer_create(fbtex);
|
|
|
-
|
|
|
- shadow_maps[p_size] = sm;
|
|
|
- }
|
|
|
-
|
|
|
- return &shadow_maps[p_size];
|
|
|
-}
|
|
|
-
|
|
|
//////////////////////////
|
|
|
|
|
|
RID RendererSceneRenderRD::decal_instance_create(RID p_decal) {
|
|
@@ -5159,6 +5193,13 @@ void RendererSceneRenderRD::_free_render_buffer_data(RenderBuffers *rb) {
|
|
|
RD::get_singleton()->free(rb->ssr.normal_scaled);
|
|
|
rb->ssr.normal_scaled = RID();
|
|
|
}
|
|
|
+
|
|
|
+ if (rb->ambient_buffer.is_valid()) {
|
|
|
+ RD::get_singleton()->free(rb->ambient_buffer);
|
|
|
+ RD::get_singleton()->free(rb->reflection_buffer);
|
|
|
+ rb->ambient_buffer = RID();
|
|
|
+ rb->reflection_buffer = RID();
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
void RendererSceneRenderRD::_process_sss(RID p_render_buffers, const CameraMatrix &p_camera) {
|
|
@@ -5558,10 +5599,10 @@ void RendererSceneRenderRD::_render_buffers_debug_draw(RID p_render_buffers, RID
|
|
|
effects->copy_to_fb_rect(_render_buffers_get_normal_texture(p_render_buffers), storage->render_target_get_rd_framebuffer(rb->render_target), Rect2(Vector2(), rtsize), false, false);
|
|
|
}
|
|
|
|
|
|
- if (debug_draw == RS::VIEWPORT_DEBUG_DRAW_GI_BUFFER && _render_buffers_get_ambient_texture(p_render_buffers).is_valid()) {
|
|
|
+ if (debug_draw == RS::VIEWPORT_DEBUG_DRAW_GI_BUFFER && rb->ambient_buffer.is_valid()) {
|
|
|
Size2 rtsize = storage->render_target_get_size(rb->render_target);
|
|
|
- RID ambient_texture = _render_buffers_get_ambient_texture(p_render_buffers);
|
|
|
- RID reflection_texture = _render_buffers_get_reflection_texture(p_render_buffers);
|
|
|
+ RID ambient_texture = rb->ambient_buffer;
|
|
|
+ RID reflection_texture = rb->reflection_buffer;
|
|
|
effects->copy_to_fb_rect(ambient_texture, storage->render_target_get_rd_framebuffer(rb->render_target), Rect2(Vector2(), rtsize), false, false, false, true, reflection_texture);
|
|
|
}
|
|
|
}
|
|
@@ -5753,6 +5794,17 @@ RID RendererSceneRenderRD::render_buffers_get_default_gi_probe_buffer() {
|
|
|
return default_giprobe_buffer;
|
|
|
}
|
|
|
|
|
|
+RID RendererSceneRenderRD::render_buffers_get_gi_ambient_texture(RID p_render_buffers) {
|
|
|
+ RenderBuffers *rb = render_buffers_owner.getornull(p_render_buffers);
|
|
|
+ ERR_FAIL_COND_V(!rb, RID());
|
|
|
+ return rb->ambient_buffer;
|
|
|
+}
|
|
|
+RID RendererSceneRenderRD::render_buffers_get_gi_reflection_texture(RID p_render_buffers) {
|
|
|
+ RenderBuffers *rb = render_buffers_owner.getornull(p_render_buffers);
|
|
|
+ ERR_FAIL_COND_V(!rb, RID());
|
|
|
+ return rb->reflection_buffer;
|
|
|
+}
|
|
|
+
|
|
|
uint32_t RendererSceneRenderRD::render_buffers_get_sdfgi_cascade_count(RID p_render_buffers) const {
|
|
|
const RenderBuffers *rb = render_buffers_owner.getornull(p_render_buffers);
|
|
|
ERR_FAIL_COND_V(!rb, 0);
|
|
@@ -5939,6 +5991,10 @@ void RendererSceneRenderRD::render_buffers_configure(RID p_render_buffers, RID p
|
|
|
rb->cluster_builder->setup(Size2i(p_width, p_height), max_cluster_elements, rb->depth_texture, storage->sampler_rd_get_default(RS::CANVAS_ITEM_TEXTURE_FILTER_NEAREST, RS::CANVAS_ITEM_TEXTURE_REPEAT_DISABLED), rb->texture);
|
|
|
}
|
|
|
|
|
|
+void RendererSceneRenderRD::gi_set_use_half_resolution(bool p_enable) {
|
|
|
+ gi.half_resolution = p_enable;
|
|
|
+}
|
|
|
+
|
|
|
void RendererSceneRenderRD::sub_surface_scattering_set_quality(RS::SubSurfaceScatteringQuality p_quality) {
|
|
|
sss_quality = p_quality;
|
|
|
}
|
|
@@ -7386,26 +7442,31 @@ void RendererSceneRenderRD::render_shadow(RID p_light, RID p_shadow_atlas, int p
|
|
|
ERR_FAIL_COND(!light_instance);
|
|
|
|
|
|
Rect2i atlas_rect;
|
|
|
- RID atlas_texture;
|
|
|
+ uint32_t atlas_size;
|
|
|
+ RID atlas_fb;
|
|
|
|
|
|
bool using_dual_paraboloid = false;
|
|
|
bool using_dual_paraboloid_flip = false;
|
|
|
- float znear = 0;
|
|
|
- float zfar = 0;
|
|
|
RID render_fb;
|
|
|
RID render_texture;
|
|
|
- float bias = 0;
|
|
|
- float normal_bias = 0;
|
|
|
+ float zfar;
|
|
|
|
|
|
bool use_pancake = false;
|
|
|
- bool use_linear_depth = false;
|
|
|
bool render_cubemap = false;
|
|
|
bool finalize_cubemap = false;
|
|
|
|
|
|
+ bool flip_y = false;
|
|
|
+
|
|
|
CameraMatrix light_projection;
|
|
|
Transform light_transform;
|
|
|
|
|
|
+ bool clear_region = true;
|
|
|
+ bool begin_texture = true;
|
|
|
+ bool end_texture = true;
|
|
|
+
|
|
|
if (storage->light_get_type(light_instance->light) == RS::LIGHT_DIRECTIONAL) {
|
|
|
+ _update_directional_shadow_atlas();
|
|
|
+
|
|
|
//set pssm stuff
|
|
|
if (light_instance->last_scene_shadow_pass != scene_pass) {
|
|
|
light_instance->directional_rect = _get_directional_shadow_rect(directional_shadow.size, directional_shadow.light_count, directional_shadow.current_light);
|
|
@@ -7422,6 +7483,7 @@ void RendererSceneRenderRD::render_shadow(RID p_light, RID p_shadow_atlas, int p
|
|
|
atlas_rect.size.width = light_instance->directional_rect.size.x;
|
|
|
atlas_rect.size.height = light_instance->directional_rect.size.y;
|
|
|
|
|
|
+ int pass_count = 1;
|
|
|
if (storage->light_directional_get_shadow_mode(light_instance->light) == RS::LIGHT_DIRECTIONAL_SHADOW_PARALLEL_4_SPLITS) {
|
|
|
atlas_rect.size.width /= 2;
|
|
|
atlas_rect.size.height /= 2;
|
|
@@ -7434,7 +7496,7 @@ void RendererSceneRenderRD::render_shadow(RID p_light, RID p_shadow_atlas, int p
|
|
|
atlas_rect.position.x += atlas_rect.size.width;
|
|
|
atlas_rect.position.y += atlas_rect.size.height;
|
|
|
}
|
|
|
-
|
|
|
+ pass_count = 4;
|
|
|
} else if (storage->light_directional_get_shadow_mode(light_instance->light) == RS::LIGHT_DIRECTIONAL_SHADOW_PARALLEL_2_SPLITS) {
|
|
|
atlas_rect.size.height /= 2;
|
|
|
|
|
@@ -7442,6 +7504,7 @@ void RendererSceneRenderRD::render_shadow(RID p_light, RID p_shadow_atlas, int p
|
|
|
} else {
|
|
|
atlas_rect.position.y += atlas_rect.size.height;
|
|
|
}
|
|
|
+ pass_count = 2;
|
|
|
}
|
|
|
|
|
|
light_instance->shadow_transform[p_pass].atlas_rect = atlas_rect;
|
|
@@ -7449,15 +7512,15 @@ void RendererSceneRenderRD::render_shadow(RID p_light, RID p_shadow_atlas, int p
|
|
|
light_instance->shadow_transform[p_pass].atlas_rect.position /= directional_shadow.size;
|
|
|
light_instance->shadow_transform[p_pass].atlas_rect.size /= directional_shadow.size;
|
|
|
|
|
|
- float bias_mult = light_instance->shadow_transform[p_pass].bias_scale;
|
|
|
zfar = storage->light_get_param(light_instance->light, RS::LIGHT_PARAM_RANGE);
|
|
|
- bias = storage->light_get_param(light_instance->light, RS::LIGHT_PARAM_SHADOW_BIAS) * bias_mult;
|
|
|
- normal_bias = storage->light_get_param(light_instance->light, RS::LIGHT_PARAM_SHADOW_NORMAL_BIAS) * bias_mult;
|
|
|
|
|
|
- ShadowMap *shadow_map = _get_shadow_map(atlas_rect.size);
|
|
|
- render_fb = shadow_map->fb;
|
|
|
- render_texture = shadow_map->depth;
|
|
|
- atlas_texture = directional_shadow.depth;
|
|
|
+ render_fb = directional_shadow.fb;
|
|
|
+ render_texture = RID();
|
|
|
+ flip_y = true;
|
|
|
+
|
|
|
+ clear_region = false;
|
|
|
+ begin_texture = (directional_shadow.current_light == 1) && (p_pass == 0); //light is 1-index because it was incremented above
|
|
|
+ end_texture = (directional_shadow.current_light == directional_shadow.light_count) && (p_pass == pass_count - 1);
|
|
|
|
|
|
} else {
|
|
|
//set from shadow atlas
|
|
@@ -7466,6 +7529,8 @@ void RendererSceneRenderRD::render_shadow(RID p_light, RID p_shadow_atlas, int p
|
|
|
ERR_FAIL_COND(!shadow_atlas);
|
|
|
ERR_FAIL_COND(!shadow_atlas->shadow_owners.has(p_light));
|
|
|
|
|
|
+ _update_shadow_atlas(shadow_atlas);
|
|
|
+
|
|
|
uint32_t key = shadow_atlas->shadow_owners[p_light];
|
|
|
|
|
|
uint32_t quadrant = (key >> ShadowAtlas::QUADRANT_SHIFT) & 0x3;
|
|
@@ -7484,11 +7549,8 @@ void RendererSceneRenderRD::render_shadow(RID p_light, RID p_shadow_atlas, int p
|
|
|
|
|
|
atlas_rect.size.width = shadow_size;
|
|
|
atlas_rect.size.height = shadow_size;
|
|
|
- atlas_texture = shadow_atlas->depth;
|
|
|
|
|
|
zfar = storage->light_get_param(light_instance->light, RS::LIGHT_PARAM_RANGE);
|
|
|
- bias = storage->light_get_param(light_instance->light, RS::LIGHT_PARAM_SHADOW_BIAS);
|
|
|
- normal_bias = storage->light_get_param(light_instance->light, RS::LIGHT_PARAM_SHADOW_NORMAL_BIAS);
|
|
|
|
|
|
if (storage->light_get_type(light_instance->light) == RS::LIGHT_OMNI) {
|
|
|
if (storage->light_omni_get_shadow_mode(light_instance->light) == RS::LIGHT_OMNI_SHADOW_CUBE) {
|
|
@@ -7501,6 +7563,10 @@ void RendererSceneRenderRD::render_shadow(RID p_light, RID p_shadow_atlas, int p
|
|
|
light_transform = light_instance->shadow_transform[0].transform;
|
|
|
render_cubemap = true;
|
|
|
finalize_cubemap = p_pass == 5;
|
|
|
+ atlas_fb = shadow_atlas->fb;
|
|
|
+
|
|
|
+ atlas_size = shadow_atlas->size;
|
|
|
+ clear_region = false;
|
|
|
|
|
|
} else {
|
|
|
light_projection = light_instance->shadow_transform[0].camera;
|
|
@@ -7511,22 +7577,17 @@ void RendererSceneRenderRD::render_shadow(RID p_light, RID p_shadow_atlas, int p
|
|
|
|
|
|
using_dual_paraboloid = true;
|
|
|
using_dual_paraboloid_flip = p_pass == 1;
|
|
|
-
|
|
|
- ShadowMap *shadow_map = _get_shadow_map(atlas_rect.size);
|
|
|
- render_fb = shadow_map->fb;
|
|
|
- render_texture = shadow_map->depth;
|
|
|
+ render_fb = shadow_atlas->fb;
|
|
|
+ flip_y = true;
|
|
|
}
|
|
|
|
|
|
} else if (storage->light_get_type(light_instance->light) == RS::LIGHT_SPOT) {
|
|
|
light_projection = light_instance->shadow_transform[0].camera;
|
|
|
light_transform = light_instance->shadow_transform[0].transform;
|
|
|
|
|
|
- ShadowMap *shadow_map = _get_shadow_map(atlas_rect.size);
|
|
|
- render_fb = shadow_map->fb;
|
|
|
- render_texture = shadow_map->depth;
|
|
|
+ render_fb = shadow_atlas->fb;
|
|
|
|
|
|
- znear = light_instance->shadow_transform[0].camera.get_z_near();
|
|
|
- use_linear_depth = true;
|
|
|
+ flip_y = true;
|
|
|
}
|
|
|
}
|
|
|
|
|
@@ -7535,25 +7596,19 @@ void RendererSceneRenderRD::render_shadow(RID p_light, RID p_shadow_atlas, int p
|
|
|
_render_shadow(render_fb, p_instances, light_projection, light_transform, zfar, 0, 0, false, false, use_pancake, p_camera_plane, p_lod_distance_multiplier, p_screen_lod_threshold);
|
|
|
if (finalize_cubemap) {
|
|
|
//reblit
|
|
|
- atlas_rect.size.height /= 2;
|
|
|
- storage->get_effects()->copy_cubemap_to_dp(render_texture, atlas_texture, atlas_rect, light_projection.get_z_near(), light_projection.get_z_far(), 0.0, false);
|
|
|
- atlas_rect.position.y += atlas_rect.size.height;
|
|
|
- storage->get_effects()->copy_cubemap_to_dp(render_texture, atlas_texture, atlas_rect, light_projection.get_z_near(), light_projection.get_z_far(), 0.0, true);
|
|
|
+ Rect2 atlas_rect_norm = atlas_rect;
|
|
|
+ atlas_rect_norm.position.x /= float(atlas_size);
|
|
|
+ atlas_rect_norm.position.y /= float(atlas_size);
|
|
|
+ atlas_rect_norm.size.x /= float(atlas_size);
|
|
|
+ atlas_rect_norm.size.y /= float(atlas_size);
|
|
|
+ atlas_rect_norm.size.height /= 2;
|
|
|
+ storage->get_effects()->copy_cubemap_to_dp(render_texture, atlas_fb, atlas_rect_norm, light_projection.get_z_near(), light_projection.get_z_far(), false);
|
|
|
+ atlas_rect_norm.position.y += atlas_rect_norm.size.height;
|
|
|
+ storage->get_effects()->copy_cubemap_to_dp(render_texture, atlas_fb, atlas_rect_norm, light_projection.get_z_near(), light_projection.get_z_far(), true);
|
|
|
}
|
|
|
} else {
|
|
|
//render shadow
|
|
|
-
|
|
|
- _render_shadow(render_fb, p_instances, light_projection, light_transform, zfar, bias, normal_bias, using_dual_paraboloid, using_dual_paraboloid_flip, use_pancake, p_camera_plane, p_lod_distance_multiplier, p_screen_lod_threshold);
|
|
|
-
|
|
|
- //copy to atlas
|
|
|
- if (use_linear_depth) {
|
|
|
- storage->get_effects()->copy_depth_to_rect_and_linearize(render_texture, atlas_texture, atlas_rect, true, znear, zfar);
|
|
|
- } else {
|
|
|
- storage->get_effects()->copy_depth_to_rect(render_texture, atlas_texture, atlas_rect, true);
|
|
|
- }
|
|
|
-
|
|
|
- //does not work from depth to color
|
|
|
- //RD::get_singleton()->texture_copy(render_texture, atlas_texture, Vector3(0, 0, 0), Vector3(atlas_rect.position.x, atlas_rect.position.y, 0), Vector3(atlas_rect.size.x, atlas_rect.size.y, 1), 0, 0, 0, 0, true);
|
|
|
+ _render_shadow(render_fb, p_instances, light_projection, light_transform, zfar, 0, 0, using_dual_paraboloid, using_dual_paraboloid_flip, use_pancake, p_camera_plane, p_lod_distance_multiplier, p_screen_lod_threshold, atlas_rect, flip_y, clear_region, begin_texture, end_texture);
|
|
|
}
|
|
|
}
|
|
|
|
|
@@ -7609,6 +7664,9 @@ void RendererSceneRenderRD::render_sdfgi(RID p_render_buffers, int p_region, con
|
|
|
push_constant.scroll[1] = 0;
|
|
|
push_constant.scroll[2] = 0;
|
|
|
}
|
|
|
+
|
|
|
+ rb->sdfgi->cascades[cascade].all_dynamic_lights_dirty = true;
|
|
|
+
|
|
|
push_constant.grid_size = rb->sdfgi->cascade_size;
|
|
|
push_constant.cascade = cascade;
|
|
|
|
|
@@ -7684,6 +7742,23 @@ void RendererSceneRenderRD::render_sdfgi(RID p_render_buffers, int p_region, con
|
|
|
RD::get_singleton()->compute_list_bind_uniform_set(compute_list, sdfgi_shader.integrate_default_sky_uniform_set, 1);
|
|
|
RD::get_singleton()->compute_list_set_push_constant(compute_list, &ipush_constant, sizeof(SDGIShader::IntegratePushConstant));
|
|
|
RD::get_singleton()->compute_list_dispatch_threads(compute_list, rb->sdfgi->probe_axis_count * rb->sdfgi->probe_axis_count, rb->sdfgi->probe_axis_count, 1, 8, 8, 1);
|
|
|
+
|
|
|
+ RD::get_singleton()->compute_list_add_barrier(compute_list);
|
|
|
+
|
|
|
+ if (rb->sdfgi->uses_multibounce) {
|
|
|
+ //multibounce requires this to be stored so direct light can read from it
|
|
|
+
|
|
|
+ RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, sdfgi_shader.integrate_pipeline[SDGIShader::INTEGRATE_MODE_STORE]);
|
|
|
+
|
|
|
+ //convert to octahedral to store
|
|
|
+ ipush_constant.image_size[0] *= SDFGI::LIGHTPROBE_OCT_SIZE;
|
|
|
+ ipush_constant.image_size[1] *= SDFGI::LIGHTPROBE_OCT_SIZE;
|
|
|
+
|
|
|
+ RD::get_singleton()->compute_list_bind_uniform_set(compute_list, rb->sdfgi->cascades[cascade].integrate_uniform_set, 0);
|
|
|
+ RD::get_singleton()->compute_list_bind_uniform_set(compute_list, sdfgi_shader.integrate_default_sky_uniform_set, 1);
|
|
|
+ RD::get_singleton()->compute_list_set_push_constant(compute_list, &ipush_constant, sizeof(SDGIShader::IntegratePushConstant));
|
|
|
+ RD::get_singleton()->compute_list_dispatch_threads(compute_list, rb->sdfgi->probe_axis_count * rb->sdfgi->probe_axis_count * SDFGI::LIGHTPROBE_OCT_SIZE, rb->sdfgi->probe_axis_count * SDFGI::LIGHTPROBE_OCT_SIZE, 1, 8, 8, 1);
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
//ok finally barrier
|
|
@@ -7922,25 +7997,8 @@ void RendererSceneRenderRD::render_sdfgi_static_lights(RID p_render_buffers, uin
|
|
|
|
|
|
_sdfgi_update_cascades(p_render_buffers); //need cascades updated for this
|
|
|
|
|
|
- RD::ComputeListID compute_list = RD::get_singleton()->compute_list_begin();
|
|
|
-
|
|
|
- RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, sdfgi_shader.direct_light_pipeline[SDGIShader::DIRECT_LIGHT_MODE_STATIC]);
|
|
|
-
|
|
|
- SDGIShader::DirectLightPushConstant dl_push_constant;
|
|
|
-
|
|
|
- dl_push_constant.grid_size[0] = rb->sdfgi->cascade_size;
|
|
|
- dl_push_constant.grid_size[1] = rb->sdfgi->cascade_size;
|
|
|
- dl_push_constant.grid_size[2] = rb->sdfgi->cascade_size;
|
|
|
- dl_push_constant.max_cascades = rb->sdfgi->cascades.size();
|
|
|
- dl_push_constant.probe_axis_size = rb->sdfgi->probe_axis_count;
|
|
|
- dl_push_constant.multibounce = false; // this is static light, do not multibounce yet
|
|
|
- dl_push_constant.y_mult = rb->sdfgi->y_mult;
|
|
|
-
|
|
|
- //all must be processed
|
|
|
- dl_push_constant.process_offset = 0;
|
|
|
- dl_push_constant.process_increment = 1;
|
|
|
-
|
|
|
SDGIShader::Light lights[SDFGI::MAX_STATIC_LIGHTS];
|
|
|
+ uint32_t light_count[SDFGI::MAX_STATIC_LIGHTS];
|
|
|
|
|
|
for (uint32_t i = 0; i < p_cascade_count; i++) {
|
|
|
ERR_CONTINUE(p_cascade_indices[i] >= rb->sdfgi->cascades.size());
|
|
@@ -8005,9 +8063,36 @@ void RendererSceneRenderRD::render_sdfgi_static_lights(RID p_render_buffers, uin
|
|
|
if (idx > 0) {
|
|
|
RD::get_singleton()->buffer_update(cc.lights_buffer, 0, idx * sizeof(SDGIShader::Light), lights, true);
|
|
|
}
|
|
|
- dl_push_constant.light_count = idx;
|
|
|
+
|
|
|
+ light_count[i] = idx;
|
|
|
}
|
|
|
+ }
|
|
|
|
|
|
+ /* Static Lights */
|
|
|
+ RD::ComputeListID compute_list = RD::get_singleton()->compute_list_begin();
|
|
|
+
|
|
|
+ RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, sdfgi_shader.direct_light_pipeline[SDGIShader::DIRECT_LIGHT_MODE_STATIC]);
|
|
|
+
|
|
|
+ SDGIShader::DirectLightPushConstant dl_push_constant;
|
|
|
+
|
|
|
+ dl_push_constant.grid_size[0] = rb->sdfgi->cascade_size;
|
|
|
+ dl_push_constant.grid_size[1] = rb->sdfgi->cascade_size;
|
|
|
+ dl_push_constant.grid_size[2] = rb->sdfgi->cascade_size;
|
|
|
+ dl_push_constant.max_cascades = rb->sdfgi->cascades.size();
|
|
|
+ dl_push_constant.probe_axis_size = rb->sdfgi->probe_axis_count;
|
|
|
+ dl_push_constant.multibounce = false; // this is static light, do not multibounce yet
|
|
|
+ dl_push_constant.y_mult = rb->sdfgi->y_mult;
|
|
|
+
|
|
|
+ //all must be processed
|
|
|
+ dl_push_constant.process_offset = 0;
|
|
|
+ dl_push_constant.process_increment = 1;
|
|
|
+
|
|
|
+ for (uint32_t i = 0; i < p_cascade_count; i++) {
|
|
|
+ ERR_CONTINUE(p_cascade_indices[i] >= rb->sdfgi->cascades.size());
|
|
|
+
|
|
|
+ SDFGI::Cascade &cc = rb->sdfgi->cascades[p_cascade_indices[i]];
|
|
|
+
|
|
|
+ dl_push_constant.light_count = light_count[i];
|
|
|
dl_push_constant.cascade = p_cascade_indices[i];
|
|
|
|
|
|
if (dl_push_constant.light_count > 0) {
|
|
@@ -8299,7 +8384,13 @@ RendererSceneRenderRD::RendererSceneRenderRD(RendererStorageRD *p_storage) {
|
|
|
roughness_layers = GLOBAL_GET("rendering/quality/reflections/roughness_layers");
|
|
|
sky_ggx_samples_quality = GLOBAL_GET("rendering/quality/reflections/ggx_samples");
|
|
|
sky_use_cubemap_array = GLOBAL_GET("rendering/quality/reflections/texture_array_reflections");
|
|
|
- // sky_use_cubemap_array = false;
|
|
|
+
|
|
|
+ sdfgi_ray_count = RS::EnvironmentSDFGIRayCount(CLAMP(int32_t(GLOBAL_GET("rendering/sdfgi/probe_ray_count")), 0, int32_t(RS::ENV_SDFGI_RAY_COUNT_MAX - 1)));
|
|
|
+ sdfgi_frames_to_converge = RS::EnvironmentSDFGIFramesToConverge(CLAMP(int32_t(GLOBAL_GET("rendering/sdfgi/frames_to_converge")), 0, int32_t(RS::ENV_SDFGI_CONVERGE_MAX - 1)));
|
|
|
+ sdfgi_frames_to_update_light = RS::EnvironmentSDFGIFramesToUpdateLight(CLAMP(int32_t(GLOBAL_GET("rendering/sdfgi/frames_to_update_lights")), 0, int32_t(RS::ENV_SDFGI_UPDATE_LIGHT_MAX - 1)));
|
|
|
+
|
|
|
+ directional_shadow.size = GLOBAL_GET("rendering/quality/directional_shadow/size");
|
|
|
+ directional_shadow.use_16_bits = GLOBAL_GET("rendering/quality/directional_shadow/16_bits");
|
|
|
|
|
|
uint32_t textures_per_stage = RD::get_singleton()->limit_get(RD::LIMIT_MAX_TEXTURES_PER_SHADER_STAGE);
|
|
|
|
|
@@ -8632,9 +8723,12 @@ RendererSceneRenderRD::RendererSceneRenderRD(RendererStorageRD *p_storage) {
|
|
|
//calculate tables
|
|
|
String defines = "\n#define SDFGI_OCT_SIZE " + itos(SDFGI::LIGHTPROBE_OCT_SIZE) + "\n";
|
|
|
Vector<String> gi_modes;
|
|
|
- gi_modes.push_back("\n#define USE_GIPROBE\n");
|
|
|
+ gi_modes.push_back("\n#define USE_GIPROBES\n");
|
|
|
gi_modes.push_back("\n#define USE_SDFGI\n");
|
|
|
- gi_modes.push_back("\n#define USE_SDFGI\n\n#define USE_GIPROBE\n");
|
|
|
+ gi_modes.push_back("\n#define USE_SDFGI\n\n#define USE_GIPROBES\n");
|
|
|
+ gi_modes.push_back("\n#define MODE_HALF_RES\n#define USE_GIPROBES\n");
|
|
|
+ gi_modes.push_back("\n#define MODE_HALF_RES\n#define USE_SDFGI\n");
|
|
|
+ gi_modes.push_back("\n#define MODE_HALF_RES\n#define USE_SDFGI\n\n#define USE_GIPROBES\n");
|
|
|
|
|
|
gi.shader.initialize(gi_modes, defines);
|
|
|
gi.shader_version = gi.shader.version_create();
|
|
@@ -8766,12 +8860,11 @@ RendererSceneRenderRD::RendererSceneRenderRD(RendererStorageRD *p_storage) {
|
|
|
environment_set_volumetric_fog_positional_shadow_shrink_size(GLOBAL_GET("rendering/volumetric_fog/positional_shadow_shrink"));
|
|
|
|
|
|
cull_argument.set_page_pool(&cull_argument_pool);
|
|
|
+
|
|
|
+ gi.half_resolution = GLOBAL_GET("rendering/quality/gi/use_half_resolution");
|
|
|
}
|
|
|
|
|
|
RendererSceneRenderRD::~RendererSceneRenderRD() {
|
|
|
- for (Map<Vector2i, ShadowMap>::Element *E = shadow_maps.front(); E; E = E->next()) {
|
|
|
- RD::get_singleton()->free(E->get().depth);
|
|
|
- }
|
|
|
for (Map<int, ShadowCubemap>::Element *E = shadow_cubemaps.front(); E; E = E->next()) {
|
|
|
RD::get_singleton()->free(E->get().cubemap);
|
|
|
}
|