summaryrefslogtreecommitdiff
path: root/servers
diff options
context:
space:
mode:
Diffstat (limited to 'servers')
-rw-r--r--servers/rendering/rasterizer_rd/rasterizer_effects_rd.cpp354
-rw-r--r--servers/rendering/rasterizer_rd/rasterizer_effects_rd.h135
-rw-r--r--servers/rendering/rasterizer_rd/rasterizer_scene_rd.cpp62
-rw-r--r--servers/rendering/rasterizer_rd/rasterizer_scene_rd.h2
-rw-r--r--servers/rendering/rasterizer_rd/rasterizer_storage_rd.cpp38
-rw-r--r--servers/rendering/rasterizer_rd/rasterizer_storage_rd.h5
-rw-r--r--servers/rendering/rasterizer_rd/shaders/SCsub5
-rw-r--r--servers/rendering/rasterizer_rd/shaders/blur.glsl301
-rw-r--r--servers/rendering/rasterizer_rd/shaders/blur_inc.glsl35
-rw-r--r--servers/rendering/rasterizer_rd/shaders/copy.glsl239
-rw-r--r--servers/rendering/rasterizer_rd/shaders/copy_to_fb.glsl68
-rw-r--r--servers/rendering/rasterizer_rd/shaders/cube_to_dp.glsl72
-rw-r--r--servers/rendering/rendering_device.h1
13 files changed, 647 insertions, 670 deletions
diff --git a/servers/rendering/rasterizer_rd/rasterizer_effects_rd.cpp b/servers/rendering/rasterizer_rd/rasterizer_effects_rd.cpp
index 79b1686232..973b422b14 100644
--- a/servers/rendering/rasterizer_rd/rasterizer_effects_rd.cpp
+++ b/servers/rendering/rasterizer_rd/rasterizer_effects_rd.cpp
@@ -99,7 +99,7 @@ RID RasterizerEffectsRD::_get_uniform_set_from_texture(RID p_texture, bool p_use
u.ids.push_back(p_texture);
uniforms.push_back(u);
//any thing with the same configuration (one texture in binding 0 for set 0), is good
- RID uniform_set = RD::get_singleton()->uniform_set_create(uniforms, blur.shader.version_get_shader(blur.shader_version, 0), 0);
+ RID uniform_set = RD::get_singleton()->uniform_set_create(uniforms, tonemap.shader.version_get_shader(tonemap.shader_version, 0), 0);
texture_to_uniform_set_cache[p_texture] = uniform_set;
@@ -204,154 +204,199 @@ RID RasterizerEffectsRD::_get_compute_uniform_set_from_image_pair(RID p_texture1
return uniform_set;
}
-void RasterizerEffectsRD::copy_to_rect_and_linearize(RID p_source_rd_texture, RID p_dest_framebuffer, const Rect2 &p_rect, bool p_flip_y, float p_z_near, float p_z_far) {
+void RasterizerEffectsRD::copy_to_fb_rect(RID p_source_rd_texture, RID p_dest_framebuffer, const Rect2i &p_rect, bool p_flip_y, bool p_force_luminance) {
+ zeromem(&copy_to_fb.push_constant, sizeof(CopyToFbPushConstant));
- zeromem(&blur.push_constant, sizeof(BlurPushConstant));
if (p_flip_y) {
- blur.push_constant.flags |= BLUR_FLAG_FLIP_Y;
+ copy_to_fb.push_constant.flip_y = true;
+ }
+ if (p_force_luminance) {
+ copy_to_fb.push_constant.force_luminance = true;
}
-
- blur.push_constant.camera_z_near = p_z_near;
- blur.push_constant.camera_z_far = p_z_far;
RD::DrawListID draw_list = RD::get_singleton()->draw_list_begin(p_dest_framebuffer, RD::INITIAL_ACTION_KEEP, RD::FINAL_ACTION_READ, RD::INITIAL_ACTION_KEEP, RD::FINAL_ACTION_DISCARD, Vector<Color>(), 1.0, 0, p_rect);
- RD::get_singleton()->draw_list_bind_render_pipeline(draw_list, blur.pipelines[BLUR_MODE_LINEARIZE_DEPTH].get_render_pipeline(RD::INVALID_ID, RD::get_singleton()->framebuffer_get_format(p_dest_framebuffer)));
+ RD::get_singleton()->draw_list_bind_render_pipeline(draw_list, copy_to_fb.pipeline.get_render_pipeline(RD::INVALID_ID, RD::get_singleton()->framebuffer_get_format(p_dest_framebuffer)));
RD::get_singleton()->draw_list_bind_uniform_set(draw_list, _get_uniform_set_from_texture(p_source_rd_texture), 0);
RD::get_singleton()->draw_list_bind_index_array(draw_list, index_array);
- RD::get_singleton()->draw_list_set_push_constant(draw_list, &blur.push_constant, sizeof(BlurPushConstant));
+ RD::get_singleton()->draw_list_set_push_constant(draw_list, &copy_to_fb.push_constant, sizeof(CopyToFbPushConstant));
RD::get_singleton()->draw_list_draw(draw_list, true);
RD::get_singleton()->draw_list_end();
}
-void RasterizerEffectsRD::copy_to_rect(RID p_source_rd_texture, RID p_dest_framebuffer, const Rect2 &p_rect, bool p_flip_y, bool p_force_luminance) {
+void RasterizerEffectsRD::copy_to_rect(RID p_source_rd_texture, RID p_dest_texture, const Rect2i &p_rect, bool p_flip_y, bool p_force_luminance, bool p_all_source, bool p_8_bit_dst) {
- zeromem(&blur.push_constant, sizeof(BlurPushConstant));
+ zeromem(&copy.push_constant, sizeof(CopyPushConstant));
if (p_flip_y) {
- blur.push_constant.flags |= BLUR_FLAG_FLIP_Y;
+ copy.push_constant.flags |= COPY_FLAG_FLIP_Y;
}
+
if (p_force_luminance) {
- blur.push_constant.flags |= BLUR_COPY_FORCE_LUMINANCE;
+ copy.push_constant.flags |= COPY_FLAG_FORCE_LUMINANCE;
}
- RD::DrawListID draw_list = RD::get_singleton()->draw_list_begin(p_dest_framebuffer, RD::INITIAL_ACTION_KEEP, RD::FINAL_ACTION_READ, RD::INITIAL_ACTION_KEEP, RD::FINAL_ACTION_DISCARD, Vector<Color>(), 1.0, 0, p_rect);
- RD::get_singleton()->draw_list_bind_render_pipeline(draw_list, blur.pipelines[BLUR_MODE_SIMPLY_COPY].get_render_pipeline(RD::INVALID_ID, RD::get_singleton()->framebuffer_get_format(p_dest_framebuffer)));
- RD::get_singleton()->draw_list_bind_uniform_set(draw_list, _get_uniform_set_from_texture(p_source_rd_texture), 0);
- RD::get_singleton()->draw_list_bind_index_array(draw_list, index_array);
- RD::get_singleton()->draw_list_set_push_constant(draw_list, &blur.push_constant, sizeof(BlurPushConstant));
- RD::get_singleton()->draw_list_draw(draw_list, true);
- RD::get_singleton()->draw_list_end();
+ if (p_all_source) {
+ copy.push_constant.flags |= COPY_FLAG_ALL_SOURCE;
+ }
+
+ copy.push_constant.section[0] = 0;
+ copy.push_constant.section[1] = 0;
+ copy.push_constant.section[2] = p_rect.size.width;
+ copy.push_constant.section[3] = p_rect.size.height;
+ copy.push_constant.target[0] = p_rect.position.x;
+ copy.push_constant.target[1] = p_rect.position.y;
+
+ int32_t x_groups = (p_rect.size.width - 1) / 8 + 1;
+ int32_t y_groups = (p_rect.size.height - 1) / 8 + 1;
+
+ RD::ComputeListID compute_list = RD::get_singleton()->compute_list_begin();
+ RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, copy.pipelines[p_8_bit_dst ? COPY_MODE_SIMPLY_COPY_8BIT : COPY_MODE_SIMPLY_COPY]);
+ RD::get_singleton()->compute_list_bind_uniform_set(compute_list, _get_compute_uniform_set_from_texture(p_source_rd_texture), 0);
+ RD::get_singleton()->compute_list_bind_uniform_set(compute_list, _get_uniform_set_from_image(p_dest_texture), 3);
+ RD::get_singleton()->compute_list_set_push_constant(compute_list, &copy.push_constant, sizeof(CopyPushConstant));
+ RD::get_singleton()->compute_list_dispatch(compute_list, x_groups, y_groups, 1);
+ RD::get_singleton()->compute_list_end();
}
-void RasterizerEffectsRD::region_copy(RID p_source_rd_texture, RID p_dest_framebuffer, const Rect2 &p_region) {
+void RasterizerEffectsRD::copy_depth_to_rect_and_linearize(RID p_source_rd_texture, RID p_dest_texture, const Rect2i &p_rect, bool p_flip_y, float p_z_near, float p_z_far) {
+
+ zeromem(&copy.push_constant, sizeof(CopyPushConstant));
+ if (p_flip_y) {
+ copy.push_constant.flags |= COPY_FLAG_FLIP_Y;
+ }
+
+ copy.push_constant.section[0] = 0;
+ copy.push_constant.section[1] = 0;
+ copy.push_constant.section[2] = p_rect.size.width;
+ copy.push_constant.section[3] = p_rect.size.height;
+ copy.push_constant.target[0] = p_rect.position.x;
+ copy.push_constant.target[1] = p_rect.position.y;
+ copy.push_constant.camera_z_far = p_z_far;
+ copy.push_constant.camera_z_near = p_z_near;
+
+ int32_t x_groups = (p_rect.size.width - 1) / 8 + 1;
+ int32_t y_groups = (p_rect.size.height - 1) / 8 + 1;
+
+ RD::ComputeListID compute_list = RD::get_singleton()->compute_list_begin();
+ RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, copy.pipelines[COPY_MODE_LINEARIZE_DEPTH]);
+ RD::get_singleton()->compute_list_bind_uniform_set(compute_list, _get_compute_uniform_set_from_texture(p_source_rd_texture), 0);
+ RD::get_singleton()->compute_list_bind_uniform_set(compute_list, _get_uniform_set_from_image(p_dest_texture), 3);
+ RD::get_singleton()->compute_list_set_push_constant(compute_list, &copy.push_constant, sizeof(CopyPushConstant));
+ RD::get_singleton()->compute_list_dispatch(compute_list, x_groups, y_groups, 1);
+ RD::get_singleton()->compute_list_end();
+}
- zeromem(&blur.push_constant, sizeof(BlurPushConstant));
+void RasterizerEffectsRD::copy_depth_to_rect(RID p_source_rd_texture, RID p_dest_texture, const Rect2i &p_rect, bool p_flip_y) {
- if (p_region != Rect2()) {
- blur.push_constant.flags = BLUR_FLAG_USE_BLUR_SECTION;
- blur.push_constant.section[0] = p_region.position.x;
- blur.push_constant.section[1] = p_region.position.y;
- blur.push_constant.section[2] = p_region.size.width;
- blur.push_constant.section[3] = p_region.size.height;
+ zeromem(&copy.push_constant, sizeof(CopyPushConstant));
+ if (p_flip_y) {
+ copy.push_constant.flags |= COPY_FLAG_FLIP_Y;
}
- RD::DrawListID draw_list = RD::get_singleton()->draw_list_begin(p_dest_framebuffer, RD::INITIAL_ACTION_KEEP, RD::FINAL_ACTION_READ, RD::INITIAL_ACTION_KEEP, RD::FINAL_ACTION_DISCARD);
- RD::get_singleton()->draw_list_bind_render_pipeline(draw_list, blur.pipelines[BLUR_MODE_SIMPLY_COPY].get_render_pipeline(RD::INVALID_ID, RD::get_singleton()->framebuffer_get_format(p_dest_framebuffer)));
- RD::get_singleton()->draw_list_bind_uniform_set(draw_list, _get_uniform_set_from_texture(p_source_rd_texture), 0);
- RD::get_singleton()->draw_list_bind_index_array(draw_list, index_array);
- RD::get_singleton()->draw_list_set_push_constant(draw_list, &blur.push_constant, sizeof(BlurPushConstant));
- RD::get_singleton()->draw_list_draw(draw_list, true);
- RD::get_singleton()->draw_list_end();
+ copy.push_constant.section[0] = 0;
+ copy.push_constant.section[1] = 0;
+ copy.push_constant.section[2] = p_rect.size.width;
+ copy.push_constant.section[3] = p_rect.size.height;
+ copy.push_constant.target[0] = p_rect.position.x;
+ copy.push_constant.target[1] = p_rect.position.y;
+
+ int32_t x_groups = (p_rect.size.width - 1) / 8 + 1;
+ int32_t y_groups = (p_rect.size.height - 1) / 8 + 1;
+
+ RD::ComputeListID compute_list = RD::get_singleton()->compute_list_begin();
+ RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, copy.pipelines[COPY_MODE_SIMPLY_COPY_DEPTH]);
+ RD::get_singleton()->compute_list_bind_uniform_set(compute_list, _get_compute_uniform_set_from_texture(p_source_rd_texture), 0);
+ RD::get_singleton()->compute_list_bind_uniform_set(compute_list, _get_uniform_set_from_image(p_dest_texture), 3);
+ RD::get_singleton()->compute_list_set_push_constant(compute_list, &copy.push_constant, sizeof(CopyPushConstant));
+ RD::get_singleton()->compute_list_dispatch(compute_list, x_groups, y_groups, 1);
+ RD::get_singleton()->compute_list_end();
}
-void RasterizerEffectsRD::gaussian_blur(RID p_source_rd_texture, RID p_framebuffer_half, RID p_rd_texture_half, RID p_dest_framebuffer, const Vector2 &p_pixel_size, const Rect2 &p_region) {
+void RasterizerEffectsRD::gaussian_blur(RID p_source_rd_texture, RID p_texture, RID p_back_texture, const Rect2i &p_region, bool p_8bit_dst) {
- zeromem(&blur.push_constant, sizeof(BlurPushConstant));
+ zeromem(&copy.push_constant, sizeof(CopyPushConstant));
uint32_t base_flags = 0;
- if (p_region != Rect2()) {
- base_flags = BLUR_FLAG_USE_BLUR_SECTION;
- blur.push_constant.section[0] = p_region.position.x;
- blur.push_constant.section[1] = p_region.position.y;
- blur.push_constant.section[2] = p_region.size.width;
- blur.push_constant.section[3] = p_region.size.height;
- }
-
- blur.push_constant.pixel_size[0] = p_pixel_size.x;
- blur.push_constant.pixel_size[1] = p_pixel_size.y;
+ copy.push_constant.section[0] = p_region.position.x;
+ copy.push_constant.section[1] = p_region.position.y;
+ copy.push_constant.section[2] = p_region.size.width;
+ copy.push_constant.section[3] = p_region.size.height;
+ int32_t x_groups = (p_region.size.width - 1) / 8 + 1;
+ int32_t y_groups = (p_region.size.height - 1) / 8 + 1;
//HORIZONTAL
- RD::DrawListID draw_list = RD::get_singleton()->draw_list_begin(p_framebuffer_half, RD::INITIAL_ACTION_KEEP, RD::FINAL_ACTION_READ, RD::INITIAL_ACTION_KEEP, RD::FINAL_ACTION_DISCARD);
- RD::get_singleton()->draw_list_bind_render_pipeline(draw_list, blur.pipelines[BLUR_MODE_GAUSSIAN_BLUR].get_render_pipeline(RD::INVALID_ID, RD::get_singleton()->framebuffer_get_format(p_framebuffer_half)));
- RD::get_singleton()->draw_list_bind_uniform_set(draw_list, _get_uniform_set_from_texture(p_source_rd_texture), 0);
- RD::get_singleton()->draw_list_bind_index_array(draw_list, index_array);
+ RD::DrawListID compute_list = RD::get_singleton()->compute_list_begin();
+ RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, copy.pipelines[p_8bit_dst ? COPY_MODE_GAUSSIAN_COPY_8BIT : COPY_MODE_GAUSSIAN_COPY]);
+ RD::get_singleton()->compute_list_bind_uniform_set(compute_list, _get_compute_uniform_set_from_texture(p_source_rd_texture), 0);
+ RD::get_singleton()->compute_list_bind_uniform_set(compute_list, _get_uniform_set_from_image(p_back_texture), 0);
- blur.push_constant.flags = base_flags | BLUR_FLAG_HORIZONTAL;
- RD::get_singleton()->draw_list_set_push_constant(draw_list, &blur.push_constant, sizeof(BlurPushConstant));
+ copy.push_constant.flags = base_flags | COPY_FLAG_HORIZONTAL;
+ RD::get_singleton()->compute_list_set_push_constant(compute_list, &copy.push_constant, sizeof(CopyPushConstant));
- RD::get_singleton()->draw_list_draw(draw_list, true);
- RD::get_singleton()->draw_list_end();
+ RD::get_singleton()->compute_list_dispatch(compute_list, x_groups, y_groups, 1);
+
+ RD::get_singleton()->compute_list_add_barrier(compute_list);
//VERTICAL
- draw_list = RD::get_singleton()->draw_list_begin(p_dest_framebuffer, RD::INITIAL_ACTION_KEEP, RD::FINAL_ACTION_READ, RD::INITIAL_ACTION_KEEP, RD::FINAL_ACTION_DISCARD);
- RD::get_singleton()->draw_list_bind_render_pipeline(draw_list, blur.pipelines[BLUR_MODE_GAUSSIAN_BLUR].get_render_pipeline(RD::INVALID_ID, RD::get_singleton()->framebuffer_get_format(p_dest_framebuffer)));
- RD::get_singleton()->draw_list_bind_uniform_set(draw_list, _get_uniform_set_from_texture(p_rd_texture_half), 0);
- RD::get_singleton()->draw_list_bind_index_array(draw_list, index_array);
+ RD::get_singleton()->compute_list_bind_uniform_set(compute_list, _get_compute_uniform_set_from_texture(p_back_texture), 0);
+ RD::get_singleton()->compute_list_bind_uniform_set(compute_list, _get_uniform_set_from_image(p_texture), 0);
- blur.push_constant.flags = base_flags;
- RD::get_singleton()->draw_list_set_push_constant(draw_list, &blur.push_constant, sizeof(BlurPushConstant));
+ copy.push_constant.flags = base_flags;
+ RD::get_singleton()->compute_list_set_push_constant(compute_list, &copy.push_constant, sizeof(CopyPushConstant));
- RD::get_singleton()->draw_list_draw(draw_list, true);
- RD::get_singleton()->draw_list_end();
+ RD::get_singleton()->compute_list_dispatch(compute_list, x_groups, y_groups, 1);
+ RD::get_singleton()->compute_list_end();
}
-void RasterizerEffectsRD::gaussian_glow(RID p_source_rd_texture, RID p_framebuffer_half, RID p_rd_texture_half, RID p_dest_framebuffer, const Vector2 &p_pixel_size, float p_strength, bool p_first_pass, float p_luminance_cap, float p_exposure, float p_bloom, float p_hdr_bleed_treshold, float p_hdr_bleed_scale, RID p_auto_exposure, float p_auto_exposure_grey) {
+void RasterizerEffectsRD::gaussian_glow(RID p_source_rd_texture, RID p_texture, RID p_back_texture, const Size2i &p_size, float p_strength, bool p_first_pass, float p_luminance_cap, float p_exposure, float p_bloom, float p_hdr_bleed_treshold, float p_hdr_bleed_scale, RID p_auto_exposure, float p_auto_exposure_grey) {
- zeromem(&blur.push_constant, sizeof(BlurPushConstant));
+ zeromem(&copy.push_constant, sizeof(CopyPushConstant));
- BlurMode blur_mode = p_first_pass && p_auto_exposure.is_valid() ? BLUR_MODE_GAUSSIAN_GLOW_AUTO_EXPOSURE : BLUR_MODE_GAUSSIAN_GLOW;
+ CopyMode copy_mode = p_first_pass && p_auto_exposure.is_valid() ? COPY_MODE_GAUSSIAN_GLOW_AUTO_EXPOSURE : COPY_MODE_GAUSSIAN_GLOW;
uint32_t base_flags = 0;
- blur.push_constant.pixel_size[0] = p_pixel_size.x;
- blur.push_constant.pixel_size[1] = p_pixel_size.y;
+ int32_t x_groups = (p_size.width - 1) / 8 + 1;
+ int32_t y_groups = (p_size.height - 1) / 8 + 1;
- blur.push_constant.glow_strength = p_strength;
- blur.push_constant.glow_bloom = p_bloom;
- blur.push_constant.glow_hdr_threshold = p_hdr_bleed_treshold;
- blur.push_constant.glow_hdr_scale = p_hdr_bleed_scale;
- blur.push_constant.glow_exposure = p_exposure;
- blur.push_constant.glow_white = 0; //actually unused
- blur.push_constant.glow_luminance_cap = p_luminance_cap;
+ copy.push_constant.section[2] = p_size.x;
+ copy.push_constant.section[3] = p_size.y;
- blur.push_constant.glow_auto_exposure_grey = p_auto_exposure_grey; //unused also
+ copy.push_constant.glow_strength = p_strength;
+ copy.push_constant.glow_bloom = p_bloom;
+ copy.push_constant.glow_hdr_threshold = p_hdr_bleed_treshold;
+ copy.push_constant.glow_hdr_scale = p_hdr_bleed_scale;
+ copy.push_constant.glow_exposure = p_exposure;
+ copy.push_constant.glow_white = 0; //actually unused
+ copy.push_constant.glow_luminance_cap = p_luminance_cap;
+
+ copy.push_constant.glow_auto_exposure_grey = p_auto_exposure_grey; //unused also
//HORIZONTAL
- RD::DrawListID draw_list = RD::get_singleton()->draw_list_begin(p_framebuffer_half, RD::INITIAL_ACTION_KEEP, RD::FINAL_ACTION_READ, RD::INITIAL_ACTION_KEEP, RD::FINAL_ACTION_DISCARD);
- RD::get_singleton()->draw_list_bind_render_pipeline(draw_list, blur.pipelines[blur_mode].get_render_pipeline(RD::INVALID_ID, RD::get_singleton()->framebuffer_get_format(p_framebuffer_half)));
- RD::get_singleton()->draw_list_bind_uniform_set(draw_list, _get_uniform_set_from_texture(p_source_rd_texture), 0);
+ RD::ComputeListID compute_list = RD::get_singleton()->compute_list_begin();
+ RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, copy.pipelines[copy_mode]);
+ RD::get_singleton()->compute_list_bind_uniform_set(compute_list, _get_compute_uniform_set_from_texture(p_source_rd_texture), 0);
+ RD::get_singleton()->compute_list_bind_uniform_set(compute_list, _get_uniform_set_from_image(p_back_texture), 3);
if (p_auto_exposure.is_valid() && p_first_pass) {
- RD::get_singleton()->draw_list_bind_uniform_set(draw_list, _get_uniform_set_from_texture(p_auto_exposure), 1);
+ RD::get_singleton()->compute_list_bind_uniform_set(compute_list, _get_compute_uniform_set_from_texture(p_auto_exposure), 1);
}
- RD::get_singleton()->draw_list_bind_index_array(draw_list, index_array);
- blur.push_constant.flags = base_flags | BLUR_FLAG_HORIZONTAL | (p_first_pass ? BLUR_FLAG_GLOW_FIRST_PASS : 0);
- RD::get_singleton()->draw_list_set_push_constant(draw_list, &blur.push_constant, sizeof(BlurPushConstant));
+ copy.push_constant.flags = base_flags | COPY_FLAG_HORIZONTAL | (p_first_pass ? COPY_FLAG_GLOW_FIRST_PASS : 0);
+ RD::get_singleton()->compute_list_set_push_constant(compute_list, &copy.push_constant, sizeof(CopyPushConstant));
- RD::get_singleton()->draw_list_draw(draw_list, true);
- RD::get_singleton()->draw_list_end();
+ RD::get_singleton()->compute_list_dispatch(compute_list, x_groups, y_groups, 1);
+ RD::get_singleton()->compute_list_add_barrier(compute_list);
- blur_mode = BLUR_MODE_GAUSSIAN_GLOW;
+ copy_mode = COPY_MODE_GAUSSIAN_GLOW;
//VERTICAL
- draw_list = RD::get_singleton()->draw_list_begin(p_dest_framebuffer, RD::INITIAL_ACTION_KEEP, RD::FINAL_ACTION_READ, RD::INITIAL_ACTION_KEEP, RD::FINAL_ACTION_DISCARD);
- RD::get_singleton()->draw_list_bind_render_pipeline(draw_list, blur.pipelines[blur_mode].get_render_pipeline(RD::INVALID_ID, RD::get_singleton()->framebuffer_get_format(p_dest_framebuffer)));
- RD::get_singleton()->draw_list_bind_uniform_set(draw_list, _get_uniform_set_from_texture(p_rd_texture_half), 0);
- RD::get_singleton()->draw_list_bind_index_array(draw_list, index_array);
+ RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, copy.pipelines[copy_mode]);
+ RD::get_singleton()->compute_list_bind_uniform_set(compute_list, _get_compute_uniform_set_from_texture(p_back_texture), 0);
+ RD::get_singleton()->compute_list_bind_uniform_set(compute_list, _get_uniform_set_from_image(p_texture), 3);
- blur.push_constant.flags = base_flags;
- RD::get_singleton()->draw_list_set_push_constant(draw_list, &blur.push_constant, sizeof(BlurPushConstant));
+ copy.push_constant.flags = base_flags;
+ RD::get_singleton()->compute_list_set_push_constant(compute_list, &copy.push_constant, sizeof(CopyPushConstant));
- RD::get_singleton()->draw_list_draw(draw_list, true);
- RD::get_singleton()->draw_list_end();
+ RD::get_singleton()->compute_list_dispatch(compute_list, x_groups, y_groups, 1);
+ RD::get_singleton()->compute_list_end();
}
void RasterizerEffectsRD::screen_space_reflection(RID p_diffuse, RID p_normal, RenderingServer::EnvironmentSSRRoughnessQuality p_roughness_quality, RID p_roughness, RID p_blur_radius, RID p_blur_radius2, RID p_metallic, const Color &p_metallic_mask, RID p_depth, RID p_scale_depth, RID p_scale_normal, RID p_output, RID p_output_blur, const Size2i &p_screen_size, int p_max_steps, float p_fade_in, float p_fade_out, float p_tolerance, const CameraMatrix &p_camera) {
@@ -560,37 +605,49 @@ void RasterizerEffectsRD::merge_specular(RID p_dest_framebuffer, RID p_specular,
RD::get_singleton()->draw_list_end();
}
-void RasterizerEffectsRD::make_mipmap(RID p_source_rd_texture, RID p_dest_framebuffer, const Vector2 &p_pixel_size) {
+void RasterizerEffectsRD::make_mipmap(RID p_source_rd_texture, RID p_dest_texture, const Size2i &p_size) {
- zeromem(&blur.push_constant, sizeof(BlurPushConstant));
+ zeromem(&copy.push_constant, sizeof(CopyPushConstant));
- blur.push_constant.pixel_size[0] = p_pixel_size.x;
- blur.push_constant.pixel_size[1] = p_pixel_size.y;
+ copy.push_constant.section[0] = 0;
+ copy.push_constant.section[1] = 0;
+ copy.push_constant.section[2] = p_size.width;
+ copy.push_constant.section[3] = p_size.height;
- RD::DrawListID draw_list = RD::get_singleton()->draw_list_begin(p_dest_framebuffer, RD::INITIAL_ACTION_KEEP, RD::FINAL_ACTION_READ, RD::INITIAL_ACTION_KEEP, RD::FINAL_ACTION_DISCARD);
- RD::get_singleton()->draw_list_bind_render_pipeline(draw_list, blur.pipelines[BLUR_MODE_MIPMAP].get_render_pipeline(RD::INVALID_ID, RD::get_singleton()->framebuffer_get_format(p_dest_framebuffer)));
- RD::get_singleton()->draw_list_bind_uniform_set(draw_list, _get_uniform_set_from_texture(p_source_rd_texture), 0);
- RD::get_singleton()->draw_list_bind_index_array(draw_list, index_array);
- RD::get_singleton()->draw_list_set_push_constant(draw_list, &blur.push_constant, sizeof(BlurPushConstant));
- RD::get_singleton()->draw_list_draw(draw_list, true);
- RD::get_singleton()->draw_list_end();
+ int32_t x_groups = (p_size.width - 1) / 8 + 1;
+ int32_t y_groups = (p_size.height - 1) / 8 + 1;
+
+ RD::ComputeListID compute_list = RD::get_singleton()->compute_list_begin();
+ RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, copy.pipelines[COPY_MODE_MIPMAP]);
+ RD::get_singleton()->compute_list_bind_uniform_set(compute_list, _get_compute_uniform_set_from_texture(p_source_rd_texture), 0);
+ RD::get_singleton()->compute_list_bind_uniform_set(compute_list, _get_uniform_set_from_image(p_dest_texture), 3);
+ RD::get_singleton()->compute_list_set_push_constant(compute_list, &copy.push_constant, sizeof(CopyPushConstant));
+ RD::get_singleton()->compute_list_dispatch(compute_list, x_groups, y_groups, 1);
+ RD::get_singleton()->compute_list_end();
}
-void RasterizerEffectsRD::copy_cubemap_to_dp(RID p_source_rd_texture, RID p_dest_framebuffer, const Rect2 &p_rect, float p_z_near, float p_z_far, float p_bias, bool p_dp_flip) {
+void RasterizerEffectsRD::copy_cubemap_to_dp(RID p_source_rd_texture, RID p_dest_texture, const Rect2i &p_rect, float p_z_near, float p_z_far, float p_bias, bool p_dp_flip) {
CopyToDPPushConstant push_constant;
+ push_constant.screen_size[0] = p_rect.size.x;
+ push_constant.screen_size[1] = p_rect.size.y;
+ push_constant.dest_offset[0] = p_rect.position.x;
+ push_constant.dest_offset[1] = p_rect.position.y;
push_constant.bias = p_bias;
push_constant.z_far = p_z_far;
push_constant.z_near = p_z_near;
push_constant.z_flip = p_dp_flip;
- RD::DrawListID draw_list = RD::get_singleton()->draw_list_begin(p_dest_framebuffer, RD::INITIAL_ACTION_KEEP, RD::FINAL_ACTION_READ, RD::INITIAL_ACTION_KEEP, RD::FINAL_ACTION_DISCARD, Vector<Color>(), 1.0, 0, p_rect);
- RD::get_singleton()->draw_list_bind_render_pipeline(draw_list, copy.pipelines[COPY_MODE_CUBE_TO_DP].get_render_pipeline(RD::INVALID_ID, RD::get_singleton()->framebuffer_get_format(p_dest_framebuffer)));
- RD::get_singleton()->draw_list_bind_uniform_set(draw_list, _get_uniform_set_from_texture(p_source_rd_texture), 0);
- RD::get_singleton()->draw_list_bind_index_array(draw_list, index_array);
- RD::get_singleton()->draw_list_set_push_constant(draw_list, &push_constant, sizeof(CopyToDPPushConstant));
- RD::get_singleton()->draw_list_draw(draw_list, true);
- RD::get_singleton()->draw_list_end();
+ int32_t x_groups = (p_rect.size.width - 1) / 8 + 1;
+ int32_t y_groups = (p_rect.size.height - 1) / 8 + 1;
+
+ RD::ComputeListID compute_list = RD::get_singleton()->compute_list_begin();
+ RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, cube_to_dp.pipeline);
+ RD::get_singleton()->compute_list_bind_uniform_set(compute_list, _get_compute_uniform_set_from_texture(p_source_rd_texture), 0);
+ RD::get_singleton()->compute_list_bind_uniform_set(compute_list, _get_uniform_set_from_image(p_dest_texture), 1);
+ RD::get_singleton()->compute_list_set_push_constant(compute_list, &push_constant, sizeof(CopyToDPPushConstant));
+ RD::get_singleton()->compute_list_dispatch(compute_list, x_groups, y_groups, 1);
+ RD::get_singleton()->compute_list_end();
}
void RasterizerEffectsRD::tonemapper(RID p_source_color, RID p_dst_framebuffer, const TonemapSettings &p_settings) {
@@ -619,7 +676,7 @@ void RasterizerEffectsRD::tonemapper(RID p_source_color, RID p_dst_framebuffer,
tonemap.push_constant.use_color_correction = p_settings.use_color_correction;
- RD::DrawListID draw_list = RD::get_singleton()->draw_list_begin(p_dst_framebuffer, RD::INITIAL_ACTION_KEEP, RD::FINAL_ACTION_READ, RD::INITIAL_ACTION_KEEP, RD::FINAL_ACTION_DISCARD);
+ RD::DrawListID draw_list = RD::get_singleton()->draw_list_begin(p_dst_framebuffer, RD::INITIAL_ACTION_DROP, RD::FINAL_ACTION_READ, RD::INITIAL_ACTION_DROP, RD::FINAL_ACTION_DISCARD);
RD::get_singleton()->draw_list_bind_render_pipeline(draw_list, tonemap.pipelines[mode].get_render_pipeline(RD::INVALID_ID, RD::get_singleton()->framebuffer_get_format(p_dst_framebuffer)));
RD::get_singleton()->draw_list_bind_uniform_set(draw_list, _get_uniform_set_from_texture(p_source_color), 0);
RD::get_singleton()->draw_list_bind_uniform_set(draw_list, _get_uniform_set_from_texture(p_settings.exposure_texture), 1);
@@ -1129,33 +1186,38 @@ void RasterizerEffectsRD::render_sky(RD::DrawListID p_list, float p_time, RID p_
RasterizerEffectsRD::RasterizerEffectsRD() {
- { // Initialize blur
- Vector<String> blur_modes;
- blur_modes.push_back("\n#define MODE_GAUSSIAN_BLUR\n");
- blur_modes.push_back("\n#define MODE_GAUSSIAN_GLOW\n");
- blur_modes.push_back("\n#define MODE_GAUSSIAN_GLOW\n#define GLOW_USE_AUTO_EXPOSURE\n");
- blur_modes.push_back("\n#define MODE_DOF_NEAR_BLUR\n#define DOF_QUALITY_LOW\n");
- blur_modes.push_back("\n#define MODE_DOF_NEAR_BLUR\n#define DOF_QUALITY_MEDIUM\n");
- blur_modes.push_back("\n#define MODE_DOF_NEAR_BLUR\n#define DOF_QUALITY_HIGH\n");
- blur_modes.push_back("\n#define MODE_DOF_NEAR_BLUR\n#define DOF_QUALITY_LOW\n#define DOF_NEAR_BLUR_MERGE\n");
- blur_modes.push_back("\n#define MODE_DOF_NEAR_BLUR\n#define DOF_QUALITY_MEDIUM\n#define DOF_NEAR_BLUR_MERGE\n");
- blur_modes.push_back("\n#define MODE_DOF_NEAR_BLUR\n#define DOF_QUALITY_HIGH\n#define DOF_NEAR_BLUR_MERGE\n");
- blur_modes.push_back("\n#define MODE_DOF_FAR_BLUR\n#define DOF_QUALITY_LOW\n");
- blur_modes.push_back("\n#define MODE_DOF_FAR_BLUR\n#define DOF_QUALITY_MEDIUM\n");
- blur_modes.push_back("\n#define MODE_DOF_FAR_BLUR\n#define DOF_QUALITY_HIGH\n");
- blur_modes.push_back("\n#define MODE_SSAO_MERGE\n");
- blur_modes.push_back("\n#define MODE_SIMPLE_COPY\n");
- blur_modes.push_back("\n#define MODE_MIPMAP\n");
- blur_modes.push_back("\n#define MODE_LINEARIZE_DEPTH_COPY\n");
-
- blur.shader.initialize(blur_modes);
- zeromem(&blur.push_constant, sizeof(BlurPushConstant));
- blur.shader_version = blur.shader.version_create();
-
- for (int i = 0; i < BLUR_MODE_MAX; i++) {
- blur.pipelines[i].setup(blur.shader.version_get_shader(blur.shader_version, i), RD::RENDER_PRIMITIVE_TRIANGLES, RD::PipelineRasterizationState(), RD::PipelineMultisampleState(), RD::PipelineDepthStencilState(), RD::PipelineColorBlendState::create_disabled(), 0);
+ { // Initialize copy
+ Vector<String> copy_modes;
+ copy_modes.push_back("\n#define MODE_GAUSSIAN_BLUR\n");
+ copy_modes.push_back("\n#define MODE_GAUSSIAN_BLUR\n#define DST_IMAGE_8BIT\n");
+ copy_modes.push_back("\n#define MODE_GAUSSIAN_GLOW\n");
+ copy_modes.push_back("\n#define MODE_GAUSSIAN_GLOW\n#define GLOW_USE_AUTO_EXPOSURE\n");
+ copy_modes.push_back("\n#define MODE_SIMPLE_COPY\n");
+ copy_modes.push_back("\n#define MODE_SIMPLE_COPY\n#define DST_IMAGE_8BIT\n");
+ copy_modes.push_back("\n#define MODE_SIMPLE_COPY_DEPTH\n");
+ copy_modes.push_back("\n#define MODE_MIPMAP\n");
+ copy_modes.push_back("\n#define MODE_LINEARIZE_DEPTH_COPY\n");
+
+ copy.shader.initialize(copy_modes);
+ zeromem(&copy.push_constant, sizeof(CopyPushConstant));
+ copy.shader_version = copy.shader.version_create();
+
+ for (int i = 0; i < COPY_MODE_MAX; i++) {
+ copy.pipelines[i] = RD::get_singleton()->compute_pipeline_create(copy.shader.version_get_shader(copy.shader_version, i));
}
}
+ {
+ Vector<String> copy_modes;
+ copy_modes.push_back("\n");
+
+ copy_to_fb.shader.initialize(copy_modes);
+
+ copy_to_fb.shader_version = copy_to_fb.shader.version_create();
+
+ //use additive
+
+ copy_to_fb.pipeline.setup(copy_to_fb.shader.version_get_shader(copy_to_fb.shader_version, 0), RD::RENDER_PRIMITIVE_TRIANGLES, RD::PipelineRasterizationState(), RD::PipelineMultisampleState(), RD::PipelineDepthStencilState(), RD::PipelineColorBlendState::create_disabled(), 0);
+ }
{
// Initialize roughness
@@ -1202,15 +1264,13 @@ RasterizerEffectsRD::RasterizerEffectsRD() {
{
// Initialize copier
Vector<String> copy_modes;
- copy_modes.push_back("\n#define MODE_CUBE_TO_DP\n");
+ copy_modes.push_back("\n");
- copy.shader.initialize(copy_modes);
+ cube_to_dp.shader.initialize(copy_modes);
- copy.shader_version = copy.shader.version_create();
+ cube_to_dp.shader_version = cube_to_dp.shader.version_create();
- for (int i = 0; i < COPY_MODE_MAX; i++) {
- copy.pipelines[i].setup(copy.shader.version_get_shader(copy.shader_version, i), RD::RENDER_PRIMITIVE_TRIANGLES, RD::PipelineRasterizationState(), RD::PipelineMultisampleState(), RD::PipelineDepthStencilState(), RD::PipelineColorBlendState::create_disabled(), 0);
- }
+ cube_to_dp.pipeline = RD::get_singleton()->compute_pipeline_create(cube_to_dp.shader.version_get_shader(cube_to_dp.shader_version, 0));
}
{
@@ -1482,9 +1542,9 @@ RasterizerEffectsRD::~RasterizerEffectsRD() {
RD::get_singleton()->free(index_buffer); //array gets freed as dependency
RD::get_singleton()->free(filter.coefficient_buffer);
- blur.shader.version_free(blur.shader_version);
- bokeh.shader.version_free(bokeh.shader_version);
copy.shader.version_free(copy.shader_version);
+ bokeh.shader.version_free(bokeh.shader_version);
+ cube_to_dp.shader.version_free(cube_to_dp.shader_version);
cubemap_downsampler.shader.version_free(cubemap_downsampler.shader_version);
filter.shader.version_free(filter.shader_version);
luminance_reduce.shader.version_free(luminance_reduce.shader_version);
diff --git a/servers/rendering/rasterizer_rd/rasterizer_effects_rd.h b/servers/rendering/rasterizer_rd/rasterizer_effects_rd.h
index c0c62eb0be..64e16a58a6 100644
--- a/servers/rendering/rasterizer_rd/rasterizer_effects_rd.h
+++ b/servers/rendering/rasterizer_rd/rasterizer_effects_rd.h
@@ -33,9 +33,10 @@
#include "core/math/camera_matrix.h"
#include "servers/rendering/rasterizer_rd/render_pipeline_vertex_format_cache_rd.h"
-#include "servers/rendering/rasterizer_rd/shaders/blur.glsl.gen.h"
#include "servers/rendering/rasterizer_rd/shaders/bokeh_dof.glsl.gen.h"
#include "servers/rendering/rasterizer_rd/shaders/copy.glsl.gen.h"
+#include "servers/rendering/rasterizer_rd/shaders/copy_to_fb.glsl.gen.h"
+#include "servers/rendering/rasterizer_rd/shaders/cube_to_dp.glsl.gen.h"
#include "servers/rendering/rasterizer_rd/shaders/cubemap_downsampler.glsl.gen.h"
#include "servers/rendering/rasterizer_rd/shaders/cubemap_filter.glsl.gen.h"
#include "servers/rendering/rasterizer_rd/shaders/cubemap_roughness.glsl.gen.h"
@@ -55,71 +56,78 @@
class RasterizerEffectsRD {
- enum BlurMode {
- BLUR_MODE_GAUSSIAN_BLUR,
- BLUR_MODE_GAUSSIAN_GLOW,
- BLUR_MODE_GAUSSIAN_GLOW_AUTO_EXPOSURE,
- BLUR_MODE_DOF_NEAR_LOW,
- BLUR_MODE_DOF_NEAR_MEDIUM,
- BLUR_MODE_DOF_NEAR_HIGH,
- BLUR_MODE_DOF_NEAR_MERGE_LOW,
- BLUR_MODE_DOF_NEAR_MERGE_MEDIUM,
- BLUR_MODE_DOF_NEAR_MERGE_HIGH,
- BLUR_MODE_DOF_FAR_LOW,
- BLUR_MODE_DOF_FAR_MEDIUM,
- BLUR_MODE_DOF_FAR_HIGH,
- BLUR_MODE_SSAO_MERGE,
- BLUR_MODE_SIMPLY_COPY,
- BLUR_MODE_MIPMAP,
- BLUR_MODE_LINEARIZE_DEPTH,
- BLUR_MODE_MAX,
+ enum CopyMode {
+ COPY_MODE_GAUSSIAN_COPY,
+ COPY_MODE_GAUSSIAN_COPY_8BIT,
+ COPY_MODE_GAUSSIAN_GLOW,
+ COPY_MODE_GAUSSIAN_GLOW_AUTO_EXPOSURE,
+ COPY_MODE_SIMPLY_COPY,
+ COPY_MODE_SIMPLY_COPY_8BIT,
+ COPY_MODE_SIMPLY_COPY_DEPTH,
+ COPY_MODE_MIPMAP,
+ COPY_MODE_LINEARIZE_DEPTH,
+ COPY_MODE_MAX,
};
enum {
- BLUR_FLAG_HORIZONTAL = (1 << 0),
- BLUR_FLAG_USE_BLUR_SECTION = (1 << 1),
- BLUR_FLAG_USE_ORTHOGONAL_PROJECTION = (1 << 2),
- BLUR_FLAG_DOF_NEAR_FIRST_TAP = (1 << 3),
- BLUR_FLAG_GLOW_FIRST_PASS = (1 << 4),
- BLUR_FLAG_FLIP_Y = (1 << 5),
- BLUR_COPY_FORCE_LUMINANCE = (1 << 6)
+ COPY_FLAG_HORIZONTAL = (1 << 0),
+ COPY_FLAG_USE_COPY_SECTION = (1 << 1),
+ COPY_FLAG_USE_ORTHOGONAL_PROJECTION = (1 << 2),
+ COPY_FLAG_DOF_NEAR_FIRST_TAP = (1 << 3),
+ COPY_FLAG_GLOW_FIRST_PASS = (1 << 4),
+ COPY_FLAG_FLIP_Y = (1 << 5),
+ COPY_FLAG_FORCE_LUMINANCE = (1 << 6),
+ COPY_FLAG_ALL_SOURCE = (1 << 7)
};
- struct BlurPushConstant {
- float section[4];
- float pixel_size[2];
+ struct CopyPushConstant {
+
+ int32_t section[4];
+ int32_t target[2];
uint32_t flags;
uint32_t pad;
- //glow
+ // Glow.
float glow_strength;
float glow_bloom;
float glow_hdr_threshold;
float glow_hdr_scale;
+
float glow_exposure;
float glow_white;
float glow_luminance_cap;
float glow_auto_exposure_grey;
- //dof
- float dof_begin;
- float dof_end;
- float dof_radius;
- float dof_pad;
-
- float dof_dir[2];
+ // DOF.
float camera_z_far;
float camera_z_near;
+ uint32_t pad2[2];
+ };
+
+ struct Copy {
+ CopyPushConstant push_constant;
+ CopyShaderRD shader;
+ RID shader_version;
+ RID pipelines[COPY_MODE_MAX];
+
+ } copy;
+
+ struct CopyToFbPushConstant {
- float ssao_color[4];
+ float section[4];
+ float pixel_size[2];
+ uint32_t flip_y;
+ uint32_t use_section;
+ uint32_t force_luminance;
+ uint32_t pad[3];
};
- struct Blur {
- BlurPushConstant push_constant;
- BlurShaderRD shader;
+ struct CopyToFb {
+ CopyToFbPushConstant push_constant;
+ CopyToFbShaderRD shader;
RID shader_version;
- RenderPipelineVertexFormatCacheRD pipelines[BLUR_MODE_MAX];
+ RenderPipelineVertexFormatCacheRD pipeline;
- } blur;
+ } copy_to_fb;
struct CubemapRoughnessPushConstant {
uint32_t face_id;
@@ -164,8 +172,11 @@ class RasterizerEffectsRD {
float auto_exposure_grey;
};
+ /* tonemap actually writes to a framebuffer, which is
+ * better to do using the raster pipeline rather than
+ * comptute, as that framebuffer might be in different formats
+ */
struct Tonemap {
-
TonemapPushConstant push_constant;
TonemapShaderRD shader;
RID shader_version;
@@ -196,23 +207,20 @@ class RasterizerEffectsRD {
} luminance_reduce;
struct CopyToDPPushConstant {
+ int32_t screen_size[2];
+ int32_t dest_offset[2];
float bias;
float z_far;
float z_near;
uint32_t z_flip;
};
- enum CopyMode {
- COPY_MODE_CUBE_TO_DP,
- COPY_MODE_MAX
- };
-
- struct Copy {
+ struct CoptToDP {
- CopyShaderRD shader;
+ CubeToDpShaderRD shader;
RID shader_version;
- RenderPipelineVertexFormatCacheRD pipelines[COPY_MODE_MAX];
- } copy;
+ RID pipeline;
+ } cube_to_dp;
struct BokehPushConstant {
uint32_t size[2];
@@ -392,6 +400,10 @@ class RasterizerEffectsRD {
SPECULAR_MERGE_MAX
};
+ /* Specular merge must be done using raster, rather than compute
+ * because it must continue the existing color buffer
+ */
+
struct SpecularMerge {
SpecularMergeShaderRD shader;
@@ -537,17 +549,16 @@ class RasterizerEffectsRD {
RID _get_compute_uniform_set_from_image_pair(RID p_texture, RID p_texture2);
public:
- //TODO must re-do most of the shaders in compute
-
- void region_copy(RID p_source_rd_texture, RID p_dest_framebuffer, const Rect2 &p_region);
- void copy_to_rect(RID p_source_rd_texture, RID p_dest_framebuffer, const Rect2 &p_rect, bool p_flip_y = false, bool p_force_luminance = false);
- void copy_to_rect_and_linearize(RID p_source_rd_texture, RID p_dest_framebuffer, const Rect2 &p_rect, bool p_flip_y, float p_z_near, float p_z_far);
- void gaussian_blur(RID p_source_rd_texture, RID p_framebuffer_half, RID p_rd_texture_half, RID p_dest_framebuffer, const Vector2 &p_pixel_size, const Rect2 &p_region);
- void gaussian_glow(RID p_source_rd_texture, RID p_framebuffer_half, RID p_rd_texture_half, RID p_dest_framebuffer, const Vector2 &p_pixel_size, float p_strength = 1.0, bool p_first_pass = false, float p_luminance_cap = 16.0, float p_exposure = 1.0, float p_bloom = 0.0, float p_hdr_bleed_treshold = 1.0, float p_hdr_bleed_scale = 1.0, RID p_auto_exposure = RID(), float p_auto_exposure_grey = 1.0);
+ void copy_to_fb_rect(RID p_source_rd_texture, RID p_dest_framebuffer, const Rect2i &p_rect, bool p_flip_y = false, bool p_force_luminance = false);
+ void copy_to_rect(RID p_source_rd_texture, RID p_dest_texture, const Rect2i &p_rect, bool p_flip_y = false, bool p_force_luminance = false, bool p_all_source = false, bool p_8_bit_dst = false);
+ void copy_depth_to_rect(RID p_source_rd_texture, RID p_dest_framebuffer, const Rect2i &p_rect, bool p_flip_y = false);
+ void copy_depth_to_rect_and_linearize(RID p_source_rd_texture, RID p_dest_texture, const Rect2i &p_rect, bool p_flip_y, float p_z_near, float p_z_far);
+ void gaussian_blur(RID p_source_rd_texture, RID p_texture, RID p_back_texture, const Rect2i &p_region, bool p_8bit_dst = false);
+ void gaussian_glow(RID p_source_rd_texture, RID p_texture, RID p_back_texture, const Size2i &p_size, float p_strength = 1.0, bool p_first_pass = false, float p_luminance_cap = 16.0, float p_exposure = 1.0, float p_bloom = 0.0, float p_hdr_bleed_treshold = 1.0, float p_hdr_bleed_scale = 1.0, RID p_auto_exposure = RID(), float p_auto_exposure_grey = 1.0);
void cubemap_roughness(RID p_source_rd_texture, RID p_dest_framebuffer, uint32_t p_face_id, uint32_t p_sample_count, float p_roughness, float p_size);
- void make_mipmap(RID p_source_rd_texture, RID p_framebuffer_half, const Vector2 &p_pixel_size);
- void copy_cubemap_to_dp(RID p_source_rd_texture, RID p_dest_framebuffer, const Rect2 &p_rect, float p_z_near, float p_z_far, float p_bias, bool p_dp_flip);
+ void make_mipmap(RID p_source_rd_texture, RID p_dest_texture, const Size2i &p_size);
+ void copy_cubemap_to_dp(RID p_source_rd_texture, RID p_dest_texture, const Rect2i &p_rect, float p_z_near, float p_z_far, float p_bias, bool p_dp_flip);
void luminance_reduction(RID p_source_texture, const Size2i p_source_size, const Vector<RID> p_reduce, RID p_prev_luminance, float p_min_luminance, float p_max_luminance, float p_adjust, bool p_set = false);
void bokeh_dof(RID p_base_texture, RID p_depth_texture, const Size2i &p_base_texture_size, RID p_secondary_texture, RID p_bokeh_texture1, RID p_bokeh_texture2, bool p_dof_far, float p_dof_far_begin, float p_dof_far_size, bool p_dof_near, float p_dof_near_begin, float p_dof_near_size, float p_bokeh_size, RS::DOFBokehShape p_bokeh_shape, RS::DOFBlurQuality p_quality, bool p_use_jitter, float p_cam_znear, float p_cam_zfar, bool p_cam_orthogonal);
diff --git a/servers/rendering/rasterizer_rd/rasterizer_scene_rd.cpp b/servers/rendering/rasterizer_rd/rasterizer_scene_rd.cpp
index a0bbf8bd43..2426eb7ebe 100644
--- a/servers/rendering/rasterizer_rd/rasterizer_scene_rd.cpp
+++ b/servers/rendering/rasterizer_rd/rasterizer_scene_rd.cpp
@@ -181,10 +181,9 @@ void RasterizerSceneRD::_update_reflection_mipmaps(ReflectionData &rd) {
for (int j = 0; j < rd.layers[i].mipmaps.size() - 1; j++) {
for (int k = 0; k < 6; k++) {
RID view = rd.layers[i].mipmaps[j].views[k];
- RID fb = rd.layers[i].mipmaps[j + 1].framebuffers[k];
- Vector2 size = rd.layers[i].mipmaps[j].size;
- size = Vector2(1.0 / size.x, 1.0 / size.y);
- storage->get_effects()->make_mipmap(view, fb, size);
+ RID texture = rd.layers[i].mipmaps[j + 1].views[k];
+ Size2i size = rd.layers[i].mipmaps[j + 1].size;
+ storage->get_effects()->make_mipmap(view, texture, size);
}
}
}
@@ -1599,7 +1598,6 @@ void RasterizerSceneRD::shadow_atlas_set_size(RID p_atlas, int p_size) {
if (shadow_atlas->depth.is_valid()) {
RD::get_singleton()->free(shadow_atlas->depth);
shadow_atlas->depth = RID();
- shadow_atlas->fb = RID();
}
for (int i = 0; i < 4; i++) {
//clear subdivisions
@@ -1625,13 +1623,9 @@ void RasterizerSceneRD::shadow_atlas_set_size(RID p_atlas, int p_size) {
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_COLOR_ATTACHMENT_BIT;
+ tf.usage_bits = RD::TEXTURE_USAGE_SAMPLING_BIT | RD::TEXTURE_USAGE_STORAGE_BIT;
shadow_atlas->depth = RD::get_singleton()->texture_create(tf, RD::TextureView());
-
- Vector<RID> fb;
- fb.push_back(shadow_atlas->depth);
- shadow_atlas->fb = RD::get_singleton()->framebuffer_create(fb);
}
}
@@ -1901,7 +1895,6 @@ void RasterizerSceneRD::directional_shadow_atlas_set_size(int p_size) {
if (directional_shadow.depth.is_valid()) {
RD::get_singleton()->free(directional_shadow.depth);
directional_shadow.depth = RID();
- directional_shadow.fb = RID();
}
if (p_size > 0) {
@@ -1910,12 +1903,9 @@ void RasterizerSceneRD::directional_shadow_atlas_set_size(int p_size) {
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_COLOR_ATTACHMENT_BIT;
+ tf.usage_bits = RD::TEXTURE_USAGE_SAMPLING_BIT | RD::TEXTURE_USAGE_STORAGE_BIT;
directional_shadow.depth = RD::get_singleton()->texture_create(tf, RD::TextureView());
- Vector<RID> fb;
- fb.push_back(directional_shadow.depth);
- directional_shadow.fb = RD::get_singleton()->framebuffer_create(fb);
}
_base_uniforms_changed();
@@ -3062,7 +3052,7 @@ void RasterizerSceneRD::_allocate_blur_textures(RenderBuffers *rb) {
tf.width = rb->width;
tf.height = rb->height;
tf.type = RD::TEXTURE_TYPE_2D;
- tf.usage_bits = RD::TEXTURE_USAGE_COLOR_ATTACHMENT_BIT | RD::TEXTURE_USAGE_STORAGE_BIT | RD::TEXTURE_USAGE_SAMPLING_BIT | RD::TEXTURE_USAGE_CAN_COPY_TO_BIT;
+ tf.usage_bits = RD::TEXTURE_USAGE_STORAGE_BIT | RD::TEXTURE_USAGE_SAMPLING_BIT | RD::TEXTURE_USAGE_CAN_COPY_TO_BIT;
tf.mipmaps = mipmaps_required;
rb->blur[0].texture = RD::get_singleton()->texture_create(tf, RD::TextureView());
@@ -3079,11 +3069,6 @@ void RasterizerSceneRD::_allocate_blur_textures(RenderBuffers *rb) {
RenderBuffers::Blur::Mipmap mm;
mm.texture = RD::get_singleton()->texture_create_shared_from_slice(RD::TextureView(), rb->blur[0].texture, 0, i);
- {
- Vector<RID> fbs;
- fbs.push_back(mm.texture);
- mm.framebuffer = RD::get_singleton()->framebuffer_create(fbs);
- }
mm.width = base_width;
mm.height = base_height;
@@ -3093,11 +3078,6 @@ void RasterizerSceneRD::_allocate_blur_textures(RenderBuffers *rb) {
if (i > 0) {
mm.texture = RD::get_singleton()->texture_create_shared_from_slice(RD::TextureView(), rb->blur[1].texture, 0, i - 1);
- {
- Vector<RID> fbs;
- fbs.push_back(mm.texture);
- mm.framebuffer = RD::get_singleton()->framebuffer_create(fbs);
- }
rb->blur[1].mipmaps.push_back(mm);
}
@@ -3424,9 +3404,9 @@ void RasterizerSceneRD::_render_buffers_post_process_and_tonemap(RID p_render_bu
if (env->auto_exposure && rb->luminance.current.is_valid()) {
luminance_texture = rb->luminance.current;
}
- storage->get_effects()->gaussian_glow(rb->texture, rb->blur[0].mipmaps[i + 1].framebuffer, rb->blur[0].mipmaps[i + 1].texture, rb->blur[1].mipmaps[i].framebuffer, Vector2(1.0 / vp_w, 1.0 / vp_h), env->glow_strength, true, env->glow_hdr_luminance_cap, env->exposure, env->glow_bloom, env->glow_hdr_bleed_threshold, env->glow_hdr_bleed_scale, luminance_texture, env->auto_exp_scale);
+ storage->get_effects()->gaussian_glow(rb->texture, rb->blur[0].mipmaps[i + 1].texture, rb->blur[1].mipmaps[i].texture, Size2i(vp_w, vp_h), env->glow_strength, true, env->glow_hdr_luminance_cap, env->exposure, env->glow_bloom, env->glow_hdr_bleed_threshold, env->glow_hdr_bleed_scale, luminance_texture, env->auto_exp_scale);
} else {
- storage->get_effects()->gaussian_glow(rb->blur[1].mipmaps[i - 1].texture, rb->blur[0].mipmaps[i + 1].framebuffer, rb->blur[0].mipmaps[i + 1].texture, rb->blur[1].mipmaps[i].framebuffer, Vector2(1.0 / vp_w, 1.0 / vp_h), env->glow_strength);
+ storage->get_effects()->gaussian_glow(rb->blur[1].mipmaps[i - 1].texture, rb->blur[0].mipmaps[i + 1].texture, rb->blur[1].mipmaps[i].texture, Size2i(vp_w, vp_h), env->glow_strength);
}
}
}
@@ -3482,7 +3462,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), false, true);
+ effects->copy_to_fb_rect(shadow_atlas_texture, storage->render_target_get_rd_framebuffer(rb->render_target), Rect2i(Vector2(), rtsize / 2), false, true);
}
}
@@ -3491,7 +3471,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), false, true);
+ effects->copy_to_fb_rect(shadow_atlas_texture, storage->render_target_get_rd_framebuffer(rb->render_target), Rect2i(Vector2(), rtsize / 2), false, true);
}
}
@@ -3499,24 +3479,24 @@ 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), false, true);
+ effects->copy_to_fb_rect(rb->luminance.current, storage->render_target_get_rd_framebuffer(rb->render_target), Rect2(Vector2(), rtsize / 8), false, true);
}
}
if (debug_draw == RS::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);
+ effects->copy_to_fb_rect(ao_buf, storage->render_target_get_rd_framebuffer(rb->render_target), Rect2(Vector2(), rtsize), false, true);
}
if (debug_draw == RS::VIEWPORT_DEBUG_DRAW_ROUGHNESS_LIMITER && _render_buffers_get_roughness_texture(p_render_buffers).is_valid()) {
Size2 rtsize = storage->render_target_get_size(rb->render_target);
- effects->copy_to_rect(_render_buffers_get_roughness_texture(p_render_buffers), storage->render_target_get_rd_framebuffer(rb->render_target), Rect2(Vector2(), rtsize), false, true);
+ effects->copy_to_fb_rect(_render_buffers_get_roughness_texture(p_render_buffers), storage->render_target_get_rd_framebuffer(rb->render_target), Rect2(Vector2(), rtsize), false, true);
}
if (debug_draw == RS::VIEWPORT_DEBUG_DRAW_NORMAL_BUFFER && _render_buffers_get_normal_texture(p_render_buffers).is_valid()) {
Size2 rtsize = storage->render_target_get_size(rb->render_target);
- effects->copy_to_rect(_render_buffers_get_normal_texture(p_render_buffers), storage->render_target_get_rd_framebuffer(rb->render_target), Rect2(Vector2(), rtsize));
+ 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);
}
}
@@ -3628,7 +3608,7 @@ void RasterizerSceneRD::render_shadow(RID p_light, RID p_shadow_atlas, int p_pas
ERR_FAIL_COND(!light_instance);
Rect2i atlas_rect;
- RID atlas_fb;
+ RID atlas_texture;
bool using_dual_paraboloid = false;
bool using_dual_paraboloid_flip = false;
@@ -3702,7 +3682,7 @@ void RasterizerSceneRD::render_shadow(RID p_light, RID p_shadow_atlas, int p_pas
ShadowMap *shadow_map = _get_shadow_map(atlas_rect.size);
render_fb = shadow_map->fb;
render_texture = shadow_map->depth;
- atlas_fb = directional_shadow.fb;
+ atlas_texture = directional_shadow.depth;
} else {
//set from shadow atlas
@@ -3729,7 +3709,7 @@ void RasterizerSceneRD::render_shadow(RID p_light, RID p_shadow_atlas, int p_pas
atlas_rect.size.width = shadow_size;
atlas_rect.size.height = shadow_size;
- atlas_fb = shadow_atlas->fb;
+ 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);
@@ -3785,9 +3765,9 @@ void RasterizerSceneRD::render_shadow(RID p_light, RID p_shadow_atlas, int p_pas
if (finalize_cubemap) {
//reblit
atlas_rect.size.height /= 2;
- storage->get_effects()->copy_cubemap_to_dp(render_texture, atlas_fb, atlas_rect, light_projection.get_z_near(), light_projection.get_z_far(), 0.0, false);
+ 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_fb, atlas_rect, light_projection.get_z_near(), light_projection.get_z_far(), 0.0, true);
+ 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);
}
} else {
//render shadow
@@ -3796,9 +3776,9 @@ void RasterizerSceneRD::render_shadow(RID p_light, RID p_shadow_atlas, int p_pas
//copy to atlas
if (use_linear_depth) {
- storage->get_effects()->copy_to_rect_and_linearize(render_texture, atlas_fb, atlas_rect, true, znear, zfar);
+ storage->get_effects()->copy_depth_to_rect_and_linearize(render_texture, atlas_texture, atlas_rect, true, znear, zfar);
} else {
- storage->get_effects()->copy_to_rect(render_texture, atlas_fb, atlas_rect, true);
+ storage->get_effects()->copy_depth_to_rect(render_texture, atlas_texture, atlas_rect, true);
}
//does not work from depth to color
diff --git a/servers/rendering/rasterizer_rd/rasterizer_scene_rd.h b/servers/rendering/rasterizer_rd/rasterizer_scene_rd.h
index 3478c05fb1..21c3c08d16 100644
--- a/servers/rendering/rasterizer_rd/rasterizer_scene_rd.h
+++ b/servers/rendering/rasterizer_rd/rasterizer_scene_rd.h
@@ -533,7 +533,6 @@ private:
struct DirectionalShadow {
RID depth;
- RID fb; //for copying
int light_count = 0;
int size = 0;
@@ -730,7 +729,6 @@ private:
struct Mipmap {
RID texture;
- RID framebuffer;
int width;
int height;
};
diff --git a/servers/rendering/rasterizer_rd/rasterizer_storage_rd.cpp b/servers/rendering/rasterizer_rd/rasterizer_storage_rd.cpp
index 0b26ec1be6..00dfdc612a 100644
--- a/servers/rendering/rasterizer_rd/rasterizer_storage_rd.cpp
+++ b/servers/rendering/rasterizer_rd/rasterizer_storage_rd.cpp
@@ -3914,7 +3914,6 @@ void RasterizerStorageRD::_clear_render_target(RenderTarget *rt) {
if (rt->backbuffer.is_valid()) {
RD::get_singleton()->free(rt->backbuffer);
rt->backbuffer = RID();
- rt->backbuffer_fb = RID();
for (int i = 0; i < rt->backbuffer_mipmaps.size(); i++) {
//just erase copies, since the rest are erased by dependency
RD::get_singleton()->free(rt->backbuffer_mipmaps[i].mipmap_copy);
@@ -4028,17 +4027,11 @@ void RasterizerStorageRD::_create_render_target_backbuffer(RenderTarget *rt) {
tf.width = rt->size.width;
tf.height = rt->size.height;
tf.type = RD::TEXTURE_TYPE_2D;
- tf.usage_bits = RD::TEXTURE_USAGE_COLOR_ATTACHMENT_BIT | RD::TEXTURE_USAGE_SAMPLING_BIT | RD::TEXTURE_USAGE_CAN_COPY_TO_BIT;
+ tf.usage_bits = RD::TEXTURE_USAGE_STORAGE_BIT | RD::TEXTURE_USAGE_SAMPLING_BIT | RD::TEXTURE_USAGE_CAN_COPY_TO_BIT;
tf.mipmaps = mipmaps_required;
rt->backbuffer = RD::get_singleton()->texture_create(tf, RD::TextureView());
-
- {
- Vector<RID> backbuffer_att;
- RID backbuffer_fb_tex = RD::get_singleton()->texture_create_shared_from_slice(RD::TextureView(), rt->backbuffer, 0, 0);
- backbuffer_att.push_back(backbuffer_fb_tex);
- rt->backbuffer_fb = RD::get_singleton()->framebuffer_create(backbuffer_att);
- }
+ rt->backbuffer_mipmap0 = RD::get_singleton()->texture_create_shared_from_slice(RD::TextureView(), rt->backbuffer, 0, 0);
//create mipmaps
for (uint32_t i = 1; i < mipmaps_required; i++) {
@@ -4046,9 +4039,6 @@ void RasterizerStorageRD::_create_render_target_backbuffer(RenderTarget *rt) {
RenderTarget::BackbufferMipmap mm;
{
mm.mipmap = RD::get_singleton()->texture_create_shared_from_slice(RD::TextureView(), rt->backbuffer, 0, i);
- Vector<RID> mm_fb_at;
- mm_fb_at.push_back(mm.mipmap);
- mm.mipmap_fb = RD::get_singleton()->framebuffer_create(mm_fb_at);
}
{
@@ -4060,9 +4050,6 @@ void RasterizerStorageRD::_create_render_target_backbuffer(RenderTarget *rt) {
mmtf.mipmaps = 1;
mm.mipmap_copy = RD::get_singleton()->texture_create(mmtf, RD::TextureView());
- Vector<RID> mm_fb_at;
- mm_fb_at.push_back(mm.mipmap_copy);
- mm.mipmap_copy_fb = RD::get_singleton()->framebuffer_create(mm_fb_at);
}
rt->backbuffer_mipmaps.push_back(mm);
@@ -4138,7 +4125,12 @@ RID RasterizerStorageRD::render_target_get_rd_framebuffer(RID p_render_target) {
return rt->framebuffer;
}
+RID RasterizerStorageRD::render_target_get_rd_texture(RID p_render_target) {
+ RenderTarget *rt = render_target_owner.getornull(p_render_target);
+ ERR_FAIL_COND_V(!rt, RID());
+ return rt->color;
+}
void RasterizerStorageRD::render_target_request_clear(RID p_render_target, const Color &p_clear_color) {
RenderTarget *rt = render_target_owner.getornull(p_render_target);
ERR_FAIL_COND(!rt);
@@ -4188,27 +4180,25 @@ void RasterizerStorageRD::render_target_copy_to_back_buffer(RID p_render_target,
}
Rect2i region = p_region;
- Rect2 blur_region;
if (region == Rect2i()) {
region.size = rt->size;
- } else {
- blur_region = region;
- blur_region.position /= rt->size;
- blur_region.size /= rt->size;
}
//single texture copy for backbuffer
- RD::get_singleton()->texture_copy(rt->color, rt->backbuffer, Vector3(region.position.x, region.position.y, 0), Vector3(region.position.x, region.position.y, 0), Vector3(region.size.x, region.size.y, 1), 0, 0, 0, 0, true);
+ RD::get_singleton()->texture_copy(rt->color, rt->backbuffer_mipmap0, Vector3(region.position.x, region.position.y, 0), Vector3(region.position.x, region.position.y, 0), Vector3(region.size.x, region.size.y, 1), 0, 0, 0, 0, true);
//effects.copy(rt->color, rt->backbuffer_fb, blur_region);
//then mipmap blur
RID prev_texture = rt->color; //use color, not backbuffer, as bb has mipmaps.
- Vector2 pixel_size = Vector2(1.0 / rt->size.width, 1.0 / rt->size.height);
for (int i = 0; i < rt->backbuffer_mipmaps.size(); i++) {
- pixel_size *= 2.0; //go halfway
+ region.position.x >>= 1;
+ region.position.y >>= 1;
+ region.size.x = MAX(1, region.size.x >> 1);
+ region.size.y = MAX(1, region.size.y >> 1);
+
const RenderTarget::BackbufferMipmap &mm = rt->backbuffer_mipmaps[i];
- effects.gaussian_blur(prev_texture, mm.mipmap_copy_fb, mm.mipmap_copy, mm.mipmap_fb, pixel_size, blur_region);
+ effects.gaussian_blur(prev_texture, mm.mipmap, mm.mipmap_copy, region, true);
prev_texture = mm.mipmap;
}
}
diff --git a/servers/rendering/rasterizer_rd/rasterizer_storage_rd.h b/servers/rendering/rasterizer_rd/rasterizer_storage_rd.h
index 7573a0d70c..29a45ca90e 100644
--- a/servers/rendering/rasterizer_rd/rasterizer_storage_rd.h
+++ b/servers/rendering/rasterizer_rd/rasterizer_storage_rd.h
@@ -463,13 +463,11 @@ private:
bool flags[RENDER_TARGET_FLAG_MAX];
RID backbuffer; //used for effects
- RID backbuffer_fb;
+ RID backbuffer_mipmap0;
struct BackbufferMipmap {
RID mipmap;
- RID mipmap_fb;
RID mipmap_copy;
- RID mipmap_copy_fb;
};
Vector<BackbufferMipmap> backbuffer_mipmaps;
@@ -1105,6 +1103,7 @@ public:
Size2 render_target_get_size(RID p_render_target);
RID render_target_get_rd_framebuffer(RID p_render_target);
+ RID render_target_get_rd_texture(RID p_render_target);
RS::InstanceType get_base_type(RID p_rid) const;
diff --git a/servers/rendering/rasterizer_rd/shaders/SCsub b/servers/rendering/rasterizer_rd/shaders/SCsub
index 04a43e3251..a454d144aa 100644
--- a/servers/rendering/rasterizer_rd/shaders/SCsub
+++ b/servers/rendering/rasterizer_rd/shaders/SCsub
@@ -5,14 +5,15 @@ Import("env")
if "RD_GLSL" in env["BUILDERS"]:
env.RD_GLSL("canvas.glsl")
env.RD_GLSL("canvas_occlusion.glsl")
- env.RD_GLSL("blur.glsl")
+ env.RD_GLSL("copy.glsl")
+ env.RD_GLSL("copy_to_fb.glsl")
env.RD_GLSL("cubemap_roughness.glsl")
env.RD_GLSL("cubemap_downsampler.glsl")
env.RD_GLSL("cubemap_filter.glsl")
env.RD_GLSL("scene_high_end.glsl")
env.RD_GLSL("sky.glsl")
env.RD_GLSL("tonemap.glsl")
- env.RD_GLSL("copy.glsl")
+ env.RD_GLSL("cube_to_dp.glsl")
env.RD_GLSL("giprobe.glsl")
env.RD_GLSL("giprobe_debug.glsl")
env.RD_GLSL("giprobe_sdf.glsl")
diff --git a/servers/rendering/rasterizer_rd/shaders/blur.glsl b/servers/rendering/rasterizer_rd/shaders/blur.glsl
deleted file mode 100644
index 5dfdc614a4..0000000000
--- a/servers/rendering/rasterizer_rd/shaders/blur.glsl
+++ /dev/null
@@ -1,301 +0,0 @@
-/* clang-format off */
-[vertex]
-
-#version 450
-
-VERSION_DEFINES
-
-#include "blur_inc.glsl"
-
-layout(location = 0) out vec2 uv_interp;
-/* clang-format on */
-
-void main() {
-
- vec2 base_arr[4] = vec2[](vec2(0.0, 0.0), vec2(0.0, 1.0), vec2(1.0, 1.0), vec2(1.0, 0.0));
- uv_interp = base_arr[gl_VertexIndex];
-
- if (bool(blur.flags & FLAG_USE_BLUR_SECTION)) {
- uv_interp = blur.section.xy + uv_interp * blur.section.zw;
- }
-
- gl_Position = vec4(uv_interp * 2.0 - 1.0, 0.0, 1.0);
-
- if (bool(blur.flags & FLAG_FLIP_Y)) {
- uv_interp.y = 1.0 - uv_interp.y;
- }
-}
-
-/* clang-format off */
-[fragment]
-
-#version 450
-
-VERSION_DEFINES
-
-#include "blur_inc.glsl"
-
-layout(location = 0) in vec2 uv_interp;
-/* clang-format on */
-
-layout(set = 0, binding = 0) uniform sampler2D source_color;
-
-#ifdef MODE_SSAO_MERGE
-layout(set = 1, binding = 0) uniform sampler2D source_ssao;
-#endif
-
-#ifdef GLOW_USE_AUTO_EXPOSURE
-layout(set = 1, binding = 0) uniform sampler2D source_auto_exposure;
-#endif
-
-layout(location = 0) out vec4 frag_color;
-
-//DOF
-#if defined(MODE_DOF_FAR_BLUR) || defined(MODE_DOF_NEAR_BLUR)
-
-layout(set = 1, binding = 0) uniform sampler2D dof_source_depth;
-
-#ifdef DOF_NEAR_BLUR_MERGE
-layout(set = 2, binding = 0) uniform sampler2D source_dof_original;
-#endif
-
-#ifdef DOF_QUALITY_LOW
-const int dof_kernel_size = 5;
-const int dof_kernel_from = 2;
-const float dof_kernel[5] = float[](0.153388, 0.221461, 0.250301, 0.221461, 0.153388);
-#endif
-
-#ifdef DOF_QUALITY_MEDIUM
-const int dof_kernel_size = 11;
-const int dof_kernel_from = 5;
-const float dof_kernel[11] = float[](0.055037, 0.072806, 0.090506, 0.105726, 0.116061, 0.119726, 0.116061, 0.105726, 0.090506, 0.072806, 0.055037);
-
-#endif
-
-#ifdef DOF_QUALITY_HIGH
-const int dof_kernel_size = 21;
-const int dof_kernel_from = 10;
-const float dof_kernel[21] = float[](0.028174, 0.032676, 0.037311, 0.041944, 0.046421, 0.050582, 0.054261, 0.057307, 0.059587, 0.060998, 0.061476, 0.060998, 0.059587, 0.057307, 0.054261, 0.050582, 0.046421, 0.041944, 0.037311, 0.032676, 0.028174);
-#endif
-
-#endif
-
-void main() {
-
-#ifdef MODE_MIPMAP
-
- vec2 pix_size = blur.pixel_size;
- vec4 color = texture(source_color, uv_interp + vec2(-0.5, -0.5) * pix_size);
- color += texture(source_color, uv_interp + vec2(0.5, -0.5) * pix_size);
- color += texture(source_color, uv_interp + vec2(0.5, 0.5) * pix_size);
- color += texture(source_color, uv_interp + vec2(-0.5, 0.5) * pix_size);
- frag_color = color / 4.0;
-
-#endif
-
-#ifdef MODE_GAUSSIAN_BLUR
-
- //Simpler blur uses SIGMA2 for the gaussian kernel for a stronger effect
-
- if (bool(blur.flags & FLAG_HORIZONTAL)) {
-
- vec2 pix_size = blur.pixel_size;
- pix_size *= 0.5; //reading from larger buffer, so use more samples
- vec4 color = texture(source_color, uv_interp + vec2(0.0, 0.0) * pix_size) * 0.214607;
- color += texture(source_color, uv_interp + vec2(1.0, 0.0) * pix_size) * 0.189879;
- color += texture(source_color, uv_interp + vec2(2.0, 0.0) * pix_size) * 0.131514;
- color += texture(source_color, uv_interp + vec2(3.0, 0.0) * pix_size) * 0.071303;
- color += texture(source_color, uv_interp + vec2(-1.0, 0.0) * pix_size) * 0.189879;
- color += texture(source_color, uv_interp + vec2(-2.0, 0.0) * pix_size) * 0.131514;
- color += texture(source_color, uv_interp + vec2(-3.0, 0.0) * pix_size) * 0.071303;
- frag_color = color;
- } else {
-
- vec2 pix_size = blur.pixel_size;
- vec4 color = texture(source_color, uv_interp + vec2(0.0, 0.0) * pix_size) * 0.38774;
- color += texture(source_color, uv_interp + vec2(0.0, 1.0) * pix_size) * 0.24477;
- color += texture(source_color, uv_interp + vec2(0.0, 2.0) * pix_size) * 0.06136;
- color += texture(source_color, uv_interp + vec2(0.0, -1.0) * pix_size) * 0.24477;
- color += texture(source_color, uv_interp + vec2(0.0, -2.0) * pix_size) * 0.06136;
- frag_color = color;
- }
-#endif
-
-#ifdef MODE_GAUSSIAN_GLOW
-
- //Glow uses larger sigma 1 for a more rounded blur effect
-
-#define GLOW_ADD(m_ofs, m_mult) \
- { \
- vec2 ofs = uv_interp + m_ofs * pix_size; \
- vec4 c = texture(source_color, ofs) * m_mult; \
- if (any(lessThan(ofs, vec2(0.0))) || any(greaterThan(ofs, vec2(1.0)))) { \
- c *= 0.0; \
- } \
- color += c; \
- }
-
- if (bool(blur.flags & FLAG_HORIZONTAL)) {
-
- vec2 pix_size = blur.pixel_size;
- pix_size *= 0.5; //reading from larger buffer, so use more samples
- vec4 color = texture(source_color, uv_interp + vec2(0.0, 0.0) * pix_size) * 0.174938;
- GLOW_ADD(vec2(1.0, 0.0), 0.165569);
- GLOW_ADD(vec2(2.0, 0.0), 0.140367);
- GLOW_ADD(vec2(3.0, 0.0), 0.106595);
- GLOW_ADD(vec2(-1.0, 0.0), 0.165569);
- GLOW_ADD(vec2(-2.0, 0.0), 0.140367);
- GLOW_ADD(vec2(-3.0, 0.0), 0.106595);
- color *= blur.glow_strength;
- frag_color = color;
- } else {
-
- vec2 pix_size = blur.pixel_size;
- vec4 color = texture(source_color, uv_interp + vec2(0.0, 0.0) * pix_size) * 0.288713;
- GLOW_ADD(vec2(0.0, 1.0), 0.233062);
- GLOW_ADD(vec2(0.0, 2.0), 0.122581);
- GLOW_ADD(vec2(0.0, -1.0), 0.233062);
- GLOW_ADD(vec2(0.0, -2.0), 0.122581);
- color *= blur.glow_strength;
- frag_color = color;
- }
-
-#undef GLOW_ADD
-
- if (bool(blur.flags & FLAG_GLOW_FIRST_PASS)) {
-#ifdef GLOW_USE_AUTO_EXPOSURE
-
- frag_color /= texelFetch(source_auto_exposure, ivec2(0, 0), 0).r / blur.glow_auto_exposure_grey;
-#endif
- frag_color *= blur.glow_exposure;
-
- float luminance = max(frag_color.r, max(frag_color.g, frag_color.b));
- float feedback = max(smoothstep(blur.glow_hdr_threshold, blur.glow_hdr_threshold + blur.glow_hdr_scale, luminance), blur.glow_bloom);
-
- frag_color = min(frag_color * feedback, vec4(blur.glow_luminance_cap));
- }
-
-#endif
-
-#ifdef MODE_DOF_FAR_BLUR
-
- vec4 color_accum = vec4(0.0);
-
- float depth = texture(dof_source_depth, uv_interp, 0.0).r;
- depth = depth * 2.0 - 1.0;
-
- if (bool(blur.flags & FLAG_USE_ORTHOGONAL_PROJECTION)) {
- depth = ((depth + (blur.camera_z_far + blur.camera_z_near) / (blur.camera_z_far - blur.camera_z_near)) * (blur.camera_z_far - blur.camera_z_near)) / 2.0;
- } else {
- depth = 2.0 * blur.camera_z_near * blur.camera_z_far / (blur.camera_z_far + blur.camera_z_near - depth * (blur.camera_z_far - blur.camera_z_near));
- }
-
- float amount = smoothstep(blur.dof_begin, blur.dof_end, depth);
- float k_accum = 0.0;
-
- for (int i = 0; i < dof_kernel_size; i++) {
-
- int int_ofs = i - dof_kernel_from;
- vec2 tap_uv = uv_interp + blur.dof_dir * float(int_ofs) * amount * blur.dof_radius;
-
- float tap_k = dof_kernel[i];
-
- float tap_depth = texture(dof_source_depth, tap_uv, 0.0).r;
- tap_depth = tap_depth * 2.0 - 1.0;
-
- if (bool(blur.flags & FLAG_USE_ORTHOGONAL_PROJECTION)) {
-
- tap_depth = ((tap_depth + (blur.camera_z_far + blur.camera_z_near) / (blur.camera_z_far - blur.camera_z_near)) * (blur.camera_z_far - blur.camera_z_near)) / 2.0;
- } else {
- tap_depth = 2.0 * blur.camera_z_near * blur.camera_z_far / (blur.camera_z_far + blur.camera_z_near - tap_depth * (blur.camera_z_far - blur.camera_z_near));
- }
-
- float tap_amount = mix(smoothstep(blur.dof_begin, blur.dof_end, tap_depth), 1.0, int_ofs == 0);
- tap_amount *= tap_amount * tap_amount; //prevent undesired glow effect
-
- vec4 tap_color = texture(source_color, tap_uv, 0.0) * tap_k;
-
- k_accum += tap_k * tap_amount;
- color_accum += tap_color * tap_amount;
- }
-
- if (k_accum > 0.0) {
- color_accum /= k_accum;
- }
-
- frag_color = color_accum; ///k_accum;
-
-#endif
-
-#ifdef MODE_DOF_NEAR_BLUR
-
- vec4 color_accum = vec4(0.0);
-
- float max_accum = 0.0;
-
- for (int i = 0; i < dof_kernel_size; i++) {
-
- int int_ofs = i - dof_kernel_from;
- vec2 tap_uv = uv_interp + blur.dof_dir * float(int_ofs) * blur.dof_radius;
- float ofs_influence = max(0.0, 1.0 - float(abs(int_ofs)) / float(dof_kernel_from));
-
- float tap_k = dof_kernel[i];
-
- vec4 tap_color = texture(source_color, tap_uv, 0.0);
-
- float tap_depth = texture(dof_source_depth, tap_uv, 0.0).r;
- tap_depth = tap_depth * 2.0 - 1.0;
- if (bool(blur.flags & FLAG_USE_ORTHOGONAL_PROJECTION)) {
-
- tap_depth = ((tap_depth + (blur.camera_z_far + blur.camera_z_near) / (blur.camera_z_far - blur.camera_z_near)) * (blur.camera_z_far - blur.camera_z_near)) / 2.0;
- } else {
- tap_depth = 2.0 * blur.camera_z_near * blur.camera_z_far / (blur.camera_z_far + blur.camera_z_near - tap_depth * (blur.camera_z_far - blur.camera_z_near));
- }
- float tap_amount = 1.0 - smoothstep(blur.dof_end, blur.dof_begin, tap_depth);
- tap_amount *= tap_amount * tap_amount; //prevent undesired glow effect
-
- if (bool(blur.flags & FLAG_DOF_NEAR_FIRST_TAP)) {
- tap_color.a = 1.0 - smoothstep(blur.dof_end, blur.dof_begin, tap_depth);
- }
-
- max_accum = max(max_accum, tap_amount * ofs_influence);
-
- color_accum += tap_color * tap_k;
- }
-
- color_accum.a = max(color_accum.a, sqrt(max_accum));
-
-#ifdef DOF_NEAR_BLUR_MERGE
- {
- vec4 original = texture(source_dof_original, uv_interp, 0.0);
- color_accum = mix(original, color_accum, color_accum.a);
- }
-#endif
-
- if (bool(blur.flags & FLAG_DOF_NEAR_FIRST_TAP)) {
- frag_color = color_accum;
- }
-#endif
-
-#ifdef MODE_SIMPLE_COPY
- vec4 color = texture(source_color, uv_interp, 0.0);
- if (bool(blur.flags & FLAG_COPY_FORCE_LUMINANCE)) {
- color.rgb = vec3(max(max(color.r, color.g), color.b));
- }
- frag_color = color;
-#endif
-
-#ifdef MODE_LINEARIZE_DEPTH_COPY
- float depth = texture(source_color, uv_interp, 0.0).r;
- depth = depth * 2.0 - 1.0;
- depth = 2.0 * blur.camera_z_near * blur.camera_z_far / (blur.camera_z_far + blur.camera_z_near - depth * (blur.camera_z_far - blur.camera_z_near));
- frag_color = vec4(depth / blur.camera_z_far);
-#endif
-
-#ifdef MODE_SSAO_MERGE
- vec4 color = texture(source_color, uv_interp, 0.0);
- float ssao = texture(source_ssao, uv_interp, 0.0).r;
- frag_color = vec4(mix(color.rgb, color.rgb * mix(blur.ssao_color.rgb, vec3(1.0), ssao), color.a), 1.0);
-
-#endif
-}
diff --git a/servers/rendering/rasterizer_rd/shaders/blur_inc.glsl b/servers/rendering/rasterizer_rd/shaders/blur_inc.glsl
deleted file mode 100644
index 33ba9de7bb..0000000000
--- a/servers/rendering/rasterizer_rd/shaders/blur_inc.glsl
+++ /dev/null
@@ -1,35 +0,0 @@
-#define FLAG_HORIZONTAL (1 << 0)
-#define FLAG_USE_BLUR_SECTION (1 << 1)
-#define FLAG_USE_ORTHOGONAL_PROJECTION (1 << 2)
-#define FLAG_DOF_NEAR_FIRST_TAP (1 << 3)
-#define FLAG_GLOW_FIRST_PASS (1 << 4)
-#define FLAG_FLIP_Y (1 << 5)
-#define FLAG_COPY_FORCE_LUMINANCE (1 << 6)
-
-layout(push_constant, binding = 1, std430) uniform Blur {
- vec4 section;
- vec2 pixel_size;
- uint flags;
- uint pad;
- // Glow.
- float glow_strength;
- float glow_bloom;
- float glow_hdr_threshold;
- float glow_hdr_scale;
- float glow_exposure;
- float glow_white;
- float glow_luminance_cap;
- float glow_auto_exposure_grey;
- // DOF.
- float dof_begin;
- float dof_end;
- float dof_radius;
- float dof_pad;
-
- vec2 dof_dir;
- float camera_z_far;
- float camera_z_near;
-
- vec4 ssao_color;
-}
-blur;
diff --git a/servers/rendering/rasterizer_rd/shaders/copy.glsl b/servers/rendering/rasterizer_rd/shaders/copy.glsl
index 2b541f2660..48c49ff7de 100644
--- a/servers/rendering/rasterizer_rd/shaders/copy.glsl
+++ b/servers/rendering/rasterizer_rd/shaders/copy.glsl
@@ -1,87 +1,220 @@
/* clang-format off */
-[vertex]
+[compute]
#version 450
VERSION_DEFINES
-layout(location = 0) out vec2 uv_interp;
+layout(local_size_x = 8, local_size_y = 8, local_size_z = 1) in;
/* clang-format on */
-void main() {
+#define FLAG_HORIZONTAL (1 << 0)
+#define FLAG_USE_BLUR_SECTION (1 << 1)
+#define FLAG_USE_ORTHOGONAL_PROJECTION (1 << 2)
+#define FLAG_DOF_NEAR_FIRST_TAP (1 << 3)
+#define FLAG_GLOW_FIRST_PASS (1 << 4)
+#define FLAG_FLIP_Y (1 << 5)
+#define FLAG_FORCE_LUMINANCE (1 << 6)
+#define FLAG_COPY_ALL_SOURCE (1 << 7)
+
+layout(push_constant, binding = 1, std430) uniform Params {
+ ivec4 section;
+ ivec2 target;
+ uint flags;
+ uint pad;
+ // Glow.
+ float glow_strength;
+ float glow_bloom;
+ float glow_hdr_threshold;
+ float glow_hdr_scale;
+
+ float glow_exposure;
+ float glow_white;
+ float glow_luminance_cap;
+ float glow_auto_exposure_grey;
+ // DOF.
+ float camera_z_far;
+ float camera_z_near;
+ uvec2 pad2;
+}
+params;
- vec2 base_arr[4] = vec2[](vec2(0.0, 0.0), vec2(0.0, 1.0), vec2(1.0, 1.0), vec2(1.0, 0.0));
- uv_interp = base_arr[gl_VertexIndex];
+layout(set = 0, binding = 0) uniform sampler2D source_color;
- gl_Position = vec4(uv_interp * 2.0 - 1.0, 0.0, 1.0);
-}
+#ifdef GLOW_USE_AUTO_EXPOSURE
+layout(set = 1, binding = 0) uniform sampler2D source_auto_exposure;
+#endif
-/* clang-format off */
-[fragment]
+#if defined(MODE_LINEARIZE_DEPTH_COPY) || defined(MODE_SIMPLE_COPY_DEPTH)
+layout(r32f, set = 3, binding = 0) uniform restrict writeonly image2D dest_buffer;
+#elif defined(DST_IMAGE_8BIT)
+layout(rgba8, set = 3, binding = 0) uniform restrict writeonly image2D dest_buffer;
+#else
+layout(rgba32f, set = 3, binding = 0) uniform restrict writeonly image2D dest_buffer;
+#endif
-#version 450
+void main() {
-VERSION_DEFINES
+ // Pixel being shaded
+ ivec2 pos = ivec2(gl_GlobalInvocationID.xy);
+ if (any(greaterThan(pos, params.section.zw))) { //too large, do nothing
+ return;
+ }
-layout(location = 0) in vec2 uv_interp;
-/* clang-format on */
+#ifdef MODE_MIPMAP
-#ifdef MODE_CUBE_TO_DP
+ ivec2 base_pos = (pos + params.section.xy) << 1;
+ vec4 color = texelFetch(source_color, base_pos, 0);
+ color += texelFetch(source_color, base_pos + ivec2(0, 1), 0);
+ color += texelFetch(source_color, base_pos + ivec2(1, 0), 0);
+ color += texelFetch(source_color, base_pos + ivec2(1, 1), 0);
+ color /= 4.0;
-layout(set = 0, binding = 0) uniform samplerCube source_cube;
+ imageStore(dest_buffer, pos + params.target, color);
+#endif
-layout(push_constant, binding = 0, std430) uniform Params {
- float bias;
- float z_far;
- float z_near;
- bool z_flip;
-}
-params;
+#ifdef MODE_GAUSSIAN_BLUR
+
+ //Simpler blur uses SIGMA2 for the gaussian kernel for a stronger effect
-layout(location = 0) out float depth_buffer;
+ if (bool(params.flags & FLAG_HORIZONTAL)) {
+
+ ivec2 base_pos = (pos + params.section.xy) << 1;
+ vec4 color = texelFetch(source_color, base_pos + ivec2(0, 0), 0) * 0.214607;
+ color += texelFetch(source_color, base_pos + ivec2(1, 0), 0) * 0.189879;
+ color += texelFetch(source_color, base_pos + ivec2(2, 0), 0) * 0.131514;
+ color += texelFetch(source_color, base_pos + ivec2(3, 0), 0) * 0.071303;
+ color += texelFetch(source_color, base_pos + ivec2(-1, 0), 0) * 0.189879;
+ color += texelFetch(source_color, base_pos + ivec2(-2, 0), 0) * 0.131514;
+ color += texelFetch(source_color, base_pos + ivec2(-3, 0), 0) * 0.071303;
+ imageStore(dest_buffer, pos + params.target, color);
+ } else {
+ ivec2 base_pos = (pos + params.section.xy);
+ vec4 color = texelFetch(source_color, base_pos + ivec2(0, 0), 0) * 0.38774;
+ color += texelFetch(source_color, base_pos + ivec2(0, 1), 0) * 0.24477;
+ color += texelFetch(source_color, base_pos + ivec2(0, 2), 0) * 0.06136;
+ color += texelFetch(source_color, base_pos + ivec2(0, -1), 0) * 0.24477;
+ color += texelFetch(source_color, base_pos + ivec2(0, -2), 0) * 0.06136;
+ imageStore(dest_buffer, pos + params.target, color);
+ }
#endif
-void main() {
+#ifdef MODE_GAUSSIAN_GLOW
-#ifdef MODE_CUBE_TO_DP
+ //Glow uses larger sigma 1 for a more rounded blur effect
- vec3 normal = vec3(uv_interp * 2.0 - 1.0, 0.0);
+#define GLOW_ADD(m_ofs, m_mult) \
+ { \
+ ivec2 ofs = base_pos + m_ofs; \
+ if (all(greaterThanEqual(ofs, section_begin)) && all(lessThan(ofs, section_end))) { \
+ color += texelFetch(source_color, ofs, 0) * m_mult; \
+ } \
+ }
- normal.z = 0.5 - 0.5 * ((normal.x * normal.x) + (normal.y * normal.y));
- normal = normalize(normal);
+ vec4 color = vec4(0.0);
- normal.y = -normal.y; //needs to be flipped to match projection matrix
- if (!params.z_flip) {
- normal.z = -normal.z;
+ if (bool(params.flags & FLAG_HORIZONTAL)) {
+
+ ivec2 base_pos = (pos + params.section.xy) << 1;
+ ivec2 section_begin = params.section.xy << 1;
+ ivec2 section_end = section_begin + (params.section.zw << 1);
+
+ GLOW_ADD(ivec2(0, 0), 0.174938);
+ GLOW_ADD(ivec2(1, 0), 0.165569);
+ GLOW_ADD(ivec2(2, 0), 0.140367);
+ GLOW_ADD(ivec2(3, 0), 0.106595);
+ GLOW_ADD(ivec2(-1, 0), 0.165569);
+ GLOW_ADD(ivec2(-2, 0), 0.140367);
+ GLOW_ADD(ivec2(-3, 0), 0.106595);
+ color *= params.glow_strength;
+ } else {
+
+ ivec2 base_pos = pos + params.section.xy;
+ ivec2 section_begin = params.section.xy;
+ ivec2 section_end = section_begin + params.section.zw;
+
+ GLOW_ADD(ivec2(0, 0), 0.288713);
+ GLOW_ADD(ivec2(0, 1), 0.233062);
+ GLOW_ADD(ivec2(0, 2), 0.122581);
+ GLOW_ADD(ivec2(0, -1), 0.233062);
+ GLOW_ADD(ivec2(0, -2), 0.122581);
+ color *= params.glow_strength;
}
- float depth = texture(source_cube, normal).r;
- depth_buffer = depth;
-
- // absolute values for direction cosines, bigger value equals closer to basis axis
- vec3 unorm = abs(normal);
-
- if ((unorm.x >= unorm.y) && (unorm.x >= unorm.z)) {
- // x code
- unorm = normal.x > 0.0 ? vec3(1.0, 0.0, 0.0) : vec3(-1.0, 0.0, 0.0);
- } else if ((unorm.y > unorm.x) && (unorm.y >= unorm.z)) {
- // y code
- unorm = normal.y > 0.0 ? vec3(0.0, 1.0, 0.0) : vec3(0.0, -1.0, 0.0);
- } else if ((unorm.z > unorm.x) && (unorm.z > unorm.y)) {
- // z code
- unorm = normal.z > 0.0 ? vec3(0.0, 0.0, 1.0) : vec3(0.0, 0.0, -1.0);
+#undef GLOW_ADD
+
+ if (bool(params.flags & FLAG_GLOW_FIRST_PASS)) {
+#ifdef GLOW_USE_AUTO_EXPOSURE
+
+ color /= texelFetch(source_auto_exposure, ivec2(0, 0), 0).r / params.glow_auto_exposure_grey;
+#endif
+ color *= params.glow_exposure;
+
+ float luminance = max(color.r, max(color.g, color.b));
+ float feedback = max(smoothstep(params.glow_hdr_threshold, params.glow_hdr_threshold + params.glow_hdr_scale, luminance), params.glow_bloom);
+
+ color = min(color * feedback, vec4(params.glow_luminance_cap));
+ }
+
+ imageStore(dest_buffer, pos + params.target, color);
+
+#endif
+
+#ifdef MODE_SIMPLE_COPY
+
+ vec4 color;
+ if (bool(params.flags & FLAG_COPY_ALL_SOURCE)) {
+ vec2 uv = vec2(pos) / vec2(params.section.zw);
+ if (bool(params.flags & FLAG_FLIP_Y)) {
+ uv.y = 1.0 - uv.y;
+ }
+ color = textureLod(source_color, uv, 0.0);
+
+ if (bool(params.flags & FLAG_FORCE_LUMINANCE)) {
+ color.rgb = vec3(max(max(color.r, color.g), color.b));
+ }
+ imageStore(dest_buffer, pos + params.target, color);
+
} else {
- // oh-no we messed up code
- // has to be
- unorm = vec3(1.0, 0.0, 0.0);
+ color = texelFetch(source_color, pos + params.section.xy, 0);
+
+ if (bool(params.flags & FLAG_FORCE_LUMINANCE)) {
+ color.rgb = vec3(max(max(color.r, color.g), color.b));
+ }
+
+ if (bool(params.flags & FLAG_FLIP_Y)) {
+ pos.y = params.section.w - pos.y - 1;
+ }
+
+ imageStore(dest_buffer, pos + params.target, color);
}
- float depth_fix = 1.0 / dot(normal, unorm);
+#endif
+
+#ifdef MODE_SIMPLE_COPY_DEPTH
+
+ vec4 color = texelFetch(source_color, pos + params.section.xy, 0);
+
+ if (bool(params.flags & FLAG_FLIP_Y)) {
+ pos.y = params.section.w - pos.y - 1;
+ }
- depth = 2.0 * depth - 1.0;
- float linear_depth = 2.0 * params.z_near * params.z_far / (params.z_far + params.z_near - depth * (params.z_far - params.z_near));
- depth_buffer = (linear_depth * depth_fix) / params.z_far;
+ imageStore(dest_buffer, pos + params.target, vec4(color.r));
+
+#endif
+
+#ifdef MODE_LINEARIZE_DEPTH_COPY
+
+ float depth = texelFetch(source_color, pos + params.section.xy, 0).r;
+ depth = depth * 2.0 - 1.0;
+ depth = 2.0 * params.camera_z_near * params.camera_z_far / (params.camera_z_far + params.camera_z_near - depth * (params.camera_z_far - params.camera_z_near));
+ vec4 color = vec4(depth / params.camera_z_far);
+
+ if (bool(params.flags & FLAG_FLIP_Y)) {
+ pos.y = params.section.w - pos.y - 1;
+ }
+ imageStore(dest_buffer, pos + params.target, color);
#endif
}
diff --git a/servers/rendering/rasterizer_rd/shaders/copy_to_fb.glsl b/servers/rendering/rasterizer_rd/shaders/copy_to_fb.glsl
new file mode 100644
index 0000000000..1f499cf372
--- /dev/null
+++ b/servers/rendering/rasterizer_rd/shaders/copy_to_fb.glsl
@@ -0,0 +1,68 @@
+/* clang-format off */
+[vertex]
+
+#version 450
+
+VERSION_DEFINES
+
+layout(location = 0) out vec2 uv_interp;
+/* clang-format on */
+
+layout(push_constant, binding = 1, std430) uniform Params {
+ vec4 section;
+ vec2 pixel_size;
+ bool flip_y;
+ bool use_section;
+ bool force_luminance;
+ uint pad[3];
+}
+params;
+
+void main() {
+
+ vec2 base_arr[4] = vec2[](vec2(0.0, 0.0), vec2(0.0, 1.0), vec2(1.0, 1.0), vec2(1.0, 0.0));
+ uv_interp = base_arr[gl_VertexIndex];
+
+ if (params.use_section) {
+ uv_interp = params.section.xy + uv_interp * params.section.zw;
+ }
+
+ gl_Position = vec4(uv_interp * 2.0 - 1.0, 0.0, 1.0);
+
+ if (params.flip_y) {
+ uv_interp.y = 1.0 - uv_interp.y;
+ }
+}
+
+/* clang-format off */
+[fragment]
+
+#version 450
+
+VERSION_DEFINES
+
+layout(push_constant, binding = 1, std430) uniform Params {
+ vec4 section;
+ vec2 pixel_size;
+ bool flip_y;
+ bool use_section;
+ bool force_luminance;
+ uint pad[3];
+} params;
+
+
+layout(location = 0) in vec2 uv_interp;
+/* clang-format on */
+
+layout(set = 0, binding = 0) uniform sampler2D source_color;
+
+layout(location = 0) out vec4 frag_color;
+
+void main() {
+
+ vec4 color = texture(source_color, uv_interp, 0.0);
+ if (params.force_luminance) {
+ color.rgb = vec3(max(max(color.r, color.g), color.b));
+ }
+ frag_color = color;
+}
diff --git a/servers/rendering/rasterizer_rd/shaders/cube_to_dp.glsl b/servers/rendering/rasterizer_rd/shaders/cube_to_dp.glsl
new file mode 100644
index 0000000000..02ebe1a53b
--- /dev/null
+++ b/servers/rendering/rasterizer_rd/shaders/cube_to_dp.glsl
@@ -0,0 +1,72 @@
+/* clang-format off */
+[compute]
+
+#version 450
+
+VERSION_DEFINES
+
+layout(local_size_x = 8, local_size_y = 8, local_size_z = 1) in;
+/* clang-format on */
+
+layout(set = 0, binding = 0) uniform samplerCube source_cube;
+
+layout(push_constant, binding = 1, std430) uniform Params {
+ ivec2 screen_size;
+ ivec2 offset;
+ float bias;
+ float z_far;
+ float z_near;
+ bool z_flip;
+}
+params;
+
+layout(r32f, set = 1, binding = 0) uniform restrict writeonly image2D depth_buffer;
+
+void main() {
+
+ ivec2 pos = ivec2(gl_GlobalInvocationID.xy);
+ if (any(greaterThan(pos, params.screen_size))) { //too large, do nothing
+ return;
+ }
+
+ vec2 pixel_size = 1.0 / vec2(params.screen_size);
+ vec2 uv = (vec2(pos) + 0.5) * pixel_size;
+
+ vec3 normal = vec3(uv * 2.0 - 1.0, 0.0);
+
+ normal.z = 0.5 - 0.5 * ((normal.x * normal.x) + (normal.y * normal.y));
+ normal = normalize(normal);
+
+ normal.y = -normal.y; //needs to be flipped to match projection matrix
+ if (!params.z_flip) {
+ normal.z = -normal.z;
+ }
+
+ float depth = texture(source_cube, normal).r;
+
+ // absolute values for direction cosines, bigger value equals closer to basis axis
+ vec3 unorm = abs(normal);
+
+ if ((unorm.x >= unorm.y) && (unorm.x >= unorm.z)) {
+ // x code
+ unorm = normal.x > 0.0 ? vec3(1.0, 0.0, 0.0) : vec3(-1.0, 0.0, 0.0);
+ } else if ((unorm.y > unorm.x) && (unorm.y >= unorm.z)) {
+ // y code
+ unorm = normal.y > 0.0 ? vec3(0.0, 1.0, 0.0) : vec3(0.0, -1.0, 0.0);
+ } else if ((unorm.z > unorm.x) && (unorm.z > unorm.y)) {
+ // z code
+ unorm = normal.z > 0.0 ? vec3(0.0, 0.0, 1.0) : vec3(0.0, 0.0, -1.0);
+ } else {
+ // oh-no we messed up code
+ // has to be
+ unorm = vec3(1.0, 0.0, 0.0);
+ }
+
+ float depth_fix = 1.0 / dot(normal, unorm);
+
+ depth = 2.0 * depth - 1.0;
+ float linear_depth = 2.0 * params.z_near * params.z_far / (params.z_far + params.z_near - depth * (params.z_far - params.z_near));
+ depth = (linear_depth * depth_fix) / params.z_far;
+
+ imageStore(depth_buffer, pos + params.offset, vec4(depth));
+}
diff --git a/servers/rendering/rendering_device.h b/servers/rendering/rendering_device.h
index a639ff3641..393bbc9f2f 100644
--- a/servers/rendering/rendering_device.h
+++ b/servers/rendering/rendering_device.h
@@ -908,6 +908,7 @@ public:
enum InitialAction {
INITIAL_ACTION_CLEAR, //start rendering and clear the framebuffer (supply params)
INITIAL_ACTION_KEEP, //start rendering, but keep attached color texture contents (depth will be cleared)
+ INITIAL_ACTION_DROP, //start rendering, ignore what is there, just write above it
INITIAL_ACTION_CONTINUE, //continue rendering (framebuffer must have been left in "continue" state as final action previously)
INITIAL_ACTION_MAX
};