summaryrefslogtreecommitdiffstats
path: root/servers/visual/rasterizer_rd/rasterizer_scene_rd.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'servers/visual/rasterizer_rd/rasterizer_scene_rd.cpp')
-rw-r--r--servers/visual/rasterizer_rd/rasterizer_scene_rd.cpp203
1 files changed, 189 insertions, 14 deletions
diff --git a/servers/visual/rasterizer_rd/rasterizer_scene_rd.cpp b/servers/visual/rasterizer_rd/rasterizer_scene_rd.cpp
index c9f3f696eb..41acd05a30 100644
--- a/servers/visual/rasterizer_rd/rasterizer_scene_rd.cpp
+++ b/servers/visual/rasterizer_rd/rasterizer_scene_rd.cpp
@@ -347,6 +347,30 @@ RID RasterizerSceneRD::sky_get_radiance_texture_rd(RID p_sky) const {
return sky->radiance;
}
+RID RasterizerSceneRD::sky_get_radiance_uniform_set_rd(RID p_sky, RID p_shader, int p_set) const {
+ Sky *sky = sky_owner.getornull(p_sky);
+ ERR_FAIL_COND_V(!sky, RID());
+
+ if (sky->uniform_set.is_null() || !RD::get_singleton()->uniform_set_is_valid(sky->uniform_set)) {
+
+ sky->uniform_set = RID();
+ if (sky->radiance.is_valid()) {
+ Vector<RD::Uniform> uniforms;
+ {
+ RD::Uniform u;
+ u.type = RD::UNIFORM_TYPE_TEXTURE;
+ u.binding = 0;
+ u.ids.push_back(sky->radiance);
+ uniforms.push_back(u);
+ }
+
+ sky->uniform_set = RD::get_singleton()->uniform_set_create(uniforms, p_shader, p_set);
+ }
+ }
+
+ return sky->uniform_set;
+}
+
RID RasterizerSceneRD::environment_create() {
return environment_owner.make_rid(Environent());
@@ -387,7 +411,7 @@ void RasterizerSceneRD::environment_set_canvas_max_layer(RID p_env, int p_max_la
ERR_FAIL_COND(!env);
env->canvas_max_layer = p_max_layer;
}
-void RasterizerSceneRD::environment_set_ambient_light(RID p_env, const Color &p_color, VS::EnvironmentAmbientSource p_ambient, float p_energy, float p_sky_contribution, VS::EnvironmentReflectionSource p_reflection_source) {
+void RasterizerSceneRD::environment_set_ambient_light(RID p_env, const Color &p_color, VS::EnvironmentAmbientSource p_ambient, float p_energy, float p_sky_contribution, VS::EnvironmentReflectionSource p_reflection_source, const Color &p_ao_color) {
Environent *env = environment_owner.getornull(p_env);
ERR_FAIL_COND(!env);
env->ambient_light = p_color;
@@ -395,6 +419,7 @@ void RasterizerSceneRD::environment_set_ambient_light(RID p_env, const Color &p_
env->ambient_light_energy = p_energy;
env->ambient_sky_contribution = p_sky_contribution;
env->reflection_source = p_reflection_source;
+ env->ao_color = p_ao_color;
}
VS::EnvironmentBG RasterizerSceneRD::environment_get_background(RID p_env) const {
@@ -458,6 +483,12 @@ VS::EnvironmentReflectionSource RasterizerSceneRD::environment_get_reflection_so
return env->reflection_source;
}
+Color RasterizerSceneRD::environment_get_ao_color(RID p_env) const {
+ Environent *env = environment_owner.getornull(p_env);
+ ERR_FAIL_COND_V(!env, Color());
+ return env->ao_color;
+}
+
void RasterizerSceneRD::environment_set_tonemap(RID p_env, VS::EnvironmentToneMapper p_tone_mapper, float p_exposure, float p_white, bool p_auto_exposure, float p_min_luminance, float p_max_luminance, float p_auto_exp_speed, float p_auto_exp_scale) {
Environent *env = environment_owner.getornull(p_env);
ERR_FAIL_COND(!env);
@@ -491,6 +522,50 @@ void RasterizerSceneRD::environment_set_glow(RID p_env, bool p_enable, int p_lev
env->glow_bicubic_upscale = p_bicubic_upscale;
}
+void RasterizerSceneRD::environment_set_ssao(RID p_env, bool p_enable, float p_radius, float p_intensity, float p_bias, float p_light_affect, float p_ao_channel_affect, VS::EnvironmentSSAOBlur p_blur, float p_bilateral_sharpness) {
+
+ Environent *env = environment_owner.getornull(p_env);
+ ERR_FAIL_COND(!env);
+
+ env->ssao_enabled = p_enable;
+ env->ssao_radius = p_radius;
+ env->ssao_intensity = p_intensity;
+ env->ssao_bias = p_bias;
+ env->ssao_direct_light_affect = p_light_affect;
+ env->ssao_ao_channel_affect = p_ao_channel_affect;
+ env->ssao_blur = p_blur;
+}
+
+void RasterizerSceneRD::environment_set_ssao_quality(VS::EnvironmentSSAOQuality p_quality, bool p_half_size) {
+ ssao_quality = p_quality;
+ ssao_half_size = p_half_size;
+}
+
+bool RasterizerSceneRD::environment_is_ssao_enabled(RID p_env) const {
+
+ Environent *env = environment_owner.getornull(p_env);
+ ERR_FAIL_COND_V(!env, false);
+ return env->ssao_enabled;
+}
+
+float RasterizerSceneRD::environment_get_ssao_ao_affect(RID p_env) const {
+ Environent *env = environment_owner.getornull(p_env);
+ ERR_FAIL_COND_V(!env, false);
+ return env->ssao_ao_channel_affect;
+}
+float RasterizerSceneRD::environment_get_ssao_light_affect(RID p_env) const {
+ Environent *env = environment_owner.getornull(p_env);
+ ERR_FAIL_COND_V(!env, false);
+ return env->ssao_direct_light_affect;
+}
+
+bool RasterizerSceneRD::environment_is_ssr_enabled(RID p_env) const {
+
+ Environent *env = environment_owner.getornull(p_env);
+ ERR_FAIL_COND_V(!env, false);
+ return false;
+}
+
bool RasterizerSceneRD::is_environment(RID p_env) const {
return environment_owner.owns(p_env);
}
@@ -1065,6 +1140,8 @@ void RasterizerSceneRD::directional_shadow_atlas_set_size(int p_size) {
fb.push_back(directional_shadow.depth);
directional_shadow.fb = RD::get_singleton()->framebuffer_create(fb);
}
+
+ _base_uniforms_changed();
}
void RasterizerSceneRD::set_directional_shadow_count(int p_count) {
@@ -1725,8 +1802,9 @@ void RasterizerSceneRD::gi_probe_update(RID p_probe, bool p_update_light_instanc
}
gi_probe->last_probe_data_version = data_version;
- gi_probe_slots_dirty = true;
p_update_light_instances = true; //just in case
+
+ _base_uniforms_changed();
}
// UDPDATE TIME
@@ -2183,14 +2261,6 @@ const Vector<RID> &RasterizerSceneRD::gi_probe_get_slots() const {
return gi_probe_slots;
}
-bool RasterizerSceneRD::gi_probe_slots_are_dirty() const {
- return gi_probe_slots_dirty;
-}
-
-void RasterizerSceneRD::gi_probe_slots_make_not_dirty() {
- gi_probe_slots_dirty = false;
-}
-
RasterizerSceneRD::GIProbeQuality RasterizerSceneRD::gi_probe_get_quality() const {
return gi_probe_quality;
}
@@ -2323,6 +2393,91 @@ void RasterizerSceneRD::_free_render_buffer_data(RenderBuffers *rb) {
RD::get_singleton()->free(rb->luminance.current);
rb->luminance.current = RID();
}
+
+ if (rb->ssao.ao[0].is_valid()) {
+ RD::get_singleton()->free(rb->ssao.depth);
+ RD::get_singleton()->free(rb->ssao.ao[0]);
+ if (rb->ssao.ao[1].is_valid()) {
+ RD::get_singleton()->free(rb->ssao.ao[1]);
+ }
+ if (rb->ssao.ao_full.is_valid()) {
+ RD::get_singleton()->free(rb->ssao.ao_full);
+ }
+
+ rb->ssao.depth = RID();
+ rb->ssao.ao[0] = RID();
+ rb->ssao.ao[1] = RID();
+ rb->ssao.ao_full = RID();
+ rb->ssao.depth_slices.clear();
+ }
+}
+
+void RasterizerSceneRD::_process_ssao(RID p_render_buffers, RID p_environment, RID p_normal_buffer, const CameraMatrix &p_projection) {
+
+ RenderBuffers *rb = render_buffers_owner.getornull(p_render_buffers);
+ ERR_FAIL_COND(!rb);
+
+ Environent *env = environment_owner.getornull(p_environment);
+ ERR_FAIL_COND(!env);
+
+ if (rb->ssao.ao[0].is_valid() && rb->ssao.ao_full.is_valid() != ssao_half_size) {
+ RD::get_singleton()->free(rb->ssao.depth);
+ RD::get_singleton()->free(rb->ssao.ao[0]);
+ if (rb->ssao.ao[1].is_valid()) {
+ RD::get_singleton()->free(rb->ssao.ao[1]);
+ }
+ if (rb->ssao.ao_full.is_valid()) {
+ RD::get_singleton()->free(rb->ssao.ao_full);
+ }
+
+ rb->ssao.depth = RID();
+ rb->ssao.ao[0] = RID();
+ rb->ssao.ao[1] = RID();
+ rb->ssao.ao_full = RID();
+ rb->ssao.depth_slices.clear();
+ }
+
+ if (!rb->ssao.ao[0].is_valid()) {
+ //allocate depth slices
+
+ {
+ RD::TextureFormat tf;
+ tf.format = RD::DATA_FORMAT_R32_SFLOAT;
+ tf.width = rb->width / 2;
+ tf.height = rb->height / 2;
+ tf.mipmaps = Image::get_image_required_mipmaps(tf.width, tf.height, Image::FORMAT_RF) + 1;
+ tf.usage_bits = RD::TEXTURE_USAGE_SAMPLING_BIT | RD::TEXTURE_USAGE_STORAGE_BIT;
+ rb->ssao.depth = RD::get_singleton()->texture_create(tf, RD::TextureView());
+ for (uint32_t i = 0; i < tf.mipmaps; i++) {
+ RID slice = RD::get_singleton()->texture_create_shared_from_slice(RD::TextureView(), rb->ssao.depth, 0, i);
+ rb->ssao.depth_slices.push_back(slice);
+ }
+ }
+
+ {
+ RD::TextureFormat tf;
+ tf.format = RD::DATA_FORMAT_R8_UNORM;
+ tf.width = ssao_half_size ? rb->width / 2 : rb->width;
+ tf.height = ssao_half_size ? rb->height / 2 : rb->height;
+ tf.usage_bits = RD::TEXTURE_USAGE_SAMPLING_BIT | RD::TEXTURE_USAGE_STORAGE_BIT;
+ rb->ssao.ao[0] = RD::get_singleton()->texture_create(tf, RD::TextureView());
+ rb->ssao.ao[1] = RD::get_singleton()->texture_create(tf, RD::TextureView());
+ }
+
+ if (ssao_half_size) {
+ //upsample texture
+ RD::TextureFormat tf;
+ tf.format = RD::DATA_FORMAT_R8_UNORM;
+ tf.width = rb->width;
+ tf.height = rb->height;
+ tf.usage_bits = RD::TEXTURE_USAGE_SAMPLING_BIT | RD::TEXTURE_USAGE_STORAGE_BIT;
+ rb->ssao.ao_full = RD::get_singleton()->texture_create(tf, RD::TextureView());
+ }
+
+ _render_buffers_uniform_set_changed(p_render_buffers);
+ }
+
+ storage->get_effects()->generate_ssao(rb->depth_texture, p_normal_buffer, Size2i(rb->width, rb->height), rb->ssao.depth, rb->ssao.depth_slices, rb->ssao.ao[0], rb->ssao.ao_full.is_valid(), rb->ssao.ao[1], rb->ssao.ao_full, env->ssao_intensity, env->ssao_radius, env->ssao_bias, p_projection, ssao_quality, env->ssao_blur, env->ssao_blur_edge_sharpness);
}
void RasterizerSceneRD::_render_buffers_post_process_and_tonemap(RID p_render_buffers, RID p_environment, RID p_camera_effects, const CameraMatrix &p_projection) {
@@ -2340,6 +2495,7 @@ void RasterizerSceneRD::_render_buffers_post_process_and_tonemap(RID p_render_bu
if (rb->blur[0].texture.is_null()) {
_allocate_blur_textures(rb);
+ _render_buffers_uniform_set_changed(p_render_buffers);
}
float bokeh_size = camfx->dof_blur_amount * 64.0;
@@ -2350,6 +2506,7 @@ void RasterizerSceneRD::_render_buffers_post_process_and_tonemap(RID p_render_bu
if (rb->luminance.current.is_null()) {
_allocate_luminance_textures(rb);
+ _render_buffers_uniform_set_changed(p_render_buffers);
}
bool set_immediate = env->auto_exposure_version != rb->auto_exposure_version;
@@ -2372,6 +2529,7 @@ void RasterizerSceneRD::_render_buffers_post_process_and_tonemap(RID p_render_bu
if (rb->blur[0].texture.is_null()) {
_allocate_blur_textures(rb);
+ _render_buffers_uniform_set_changed(p_render_buffers);
}
for (int i = 0; i < VS::MAX_GLOW_LEVELS; i++) {
@@ -2456,7 +2614,7 @@ void RasterizerSceneRD::_render_buffers_debug_draw(RID p_render_buffers, RID p_s
RID shadow_atlas_texture = shadow_atlas_get_texture(p_shadow_atlas);
Size2 rtsize = storage->render_target_get_size(rb->render_target);
- effects->copy_to_rect(shadow_atlas_texture, storage->render_target_get_rd_framebuffer(rb->render_target), Rect2(Vector2(), rtsize / 2));
+ effects->copy_to_rect(shadow_atlas_texture, storage->render_target_get_rd_framebuffer(rb->render_target), Rect2(Vector2(), rtsize / 2), false, true);
}
}
@@ -2465,7 +2623,7 @@ void RasterizerSceneRD::_render_buffers_debug_draw(RID p_render_buffers, RID p_s
RID shadow_atlas_texture = directional_shadow_get_texture();
Size2 rtsize = storage->render_target_get_size(rb->render_target);
- effects->copy_to_rect(shadow_atlas_texture, storage->render_target_get_rd_framebuffer(rb->render_target), Rect2(Vector2(), rtsize / 2));
+ effects->copy_to_rect(shadow_atlas_texture, storage->render_target_get_rd_framebuffer(rb->render_target), Rect2(Vector2(), rtsize / 2), false, true);
}
}
@@ -2473,19 +2631,34 @@ void RasterizerSceneRD::_render_buffers_debug_draw(RID p_render_buffers, RID p_s
if (rb->luminance.current.is_valid()) {
Size2 rtsize = storage->render_target_get_size(rb->render_target);
- effects->copy_to_rect(rb->luminance.current, storage->render_target_get_rd_framebuffer(rb->render_target), Rect2(Vector2(), rtsize / 8));
+ effects->copy_to_rect(rb->luminance.current, storage->render_target_get_rd_framebuffer(rb->render_target), Rect2(Vector2(), rtsize / 8), false, true);
}
}
+
+ if (debug_draw == VS::VIEWPORT_DEBUG_DRAW_SSAO && rb->ssao.ao[0].is_valid()) {
+ Size2 rtsize = storage->render_target_get_size(rb->render_target);
+ RID ao_buf = rb->ssao.ao_full.is_valid() ? rb->ssao.ao_full : rb->ssao.ao[0];
+ effects->copy_to_rect(ao_buf, storage->render_target_get_rd_framebuffer(rb->render_target), Rect2(Vector2(), rtsize), false, true);
+ }
}
RID RasterizerSceneRD::render_buffers_get_back_buffer_texture(RID p_render_buffers) {
RenderBuffers *rb = render_buffers_owner.getornull(p_render_buffers);
ERR_FAIL_COND_V(!rb, RID());
- ERR_FAIL_COND_V(!rb->blur[0].texture.is_valid(), RID()); //should have been created for some reason?
+ if (!rb->blur[0].texture.is_valid()) {
+ return RID(); //not valid at the moment
+ }
return rb->blur[0].texture;
}
+RID RasterizerSceneRD::render_buffers_get_ao_texture(RID p_render_buffers) {
+ RenderBuffers *rb = render_buffers_owner.getornull(p_render_buffers);
+ ERR_FAIL_COND_V(!rb, RID());
+
+ return rb->ssao.ao_full.is_valid() ? rb->ssao.ao_full : rb->ssao.ao[0];
+}
+
void RasterizerSceneRD::render_buffers_configure(RID p_render_buffers, RID p_render_target, int p_width, int p_height, VS::ViewportMSAA p_msaa) {
RenderBuffers *rb = render_buffers_owner.getornull(p_render_buffers);
@@ -2516,6 +2689,7 @@ void RasterizerSceneRD::render_buffers_configure(RID p_render_buffers, RID p_ren
}
rb->data->configure(rb->texture, rb->depth_texture, p_width, p_height, p_msaa);
+ _render_buffers_uniform_set_changed(p_render_buffers);
}
int RasterizerSceneRD::get_roughness_layers() const {
@@ -2921,6 +3095,7 @@ RasterizerSceneRD::RasterizerSceneRD(RasterizerStorageRD *p_storage) {
camera_effects_set_dof_blur_bokeh_shape(VS::DOFBokehShape(int(GLOBAL_GET("rendering/quality/filters/depth_of_field_bokeh_shape"))));
camera_effects_set_dof_blur_quality(VS::DOFBlurQuality(int(GLOBAL_GET("rendering/quality/filters/depth_of_field_bokeh_quality"))), GLOBAL_GET("rendering/quality/filters/depth_of_field_use_jitter"));
+ environment_set_ssao_quality(VS::EnvironmentSSAOQuality(int(GLOBAL_GET("rendering/quality/ssao/quality"))), GLOBAL_GET("rendering/quality/ssao/half_size"));
}
RasterizerSceneRD::~RasterizerSceneRD() {