summaryrefslogtreecommitdiffstats
path: root/servers/rendering
diff options
context:
space:
mode:
Diffstat (limited to 'servers/rendering')
-rw-r--r--servers/rendering/dummy/rasterizer_scene_dummy.h8
-rw-r--r--servers/rendering/renderer_canvas_cull.cpp6
-rw-r--r--servers/rendering/renderer_rd/environment/gi.h2
-rw-r--r--servers/rendering/renderer_rd/forward_clustered/render_forward_clustered.cpp128
-rw-r--r--servers/rendering/renderer_rd/forward_clustered/render_forward_clustered.h14
-rw-r--r--servers/rendering/renderer_rd/forward_mobile/render_forward_mobile.cpp44
-rw-r--r--servers/rendering/renderer_rd/framebuffer_cache_rd.cpp23
-rw-r--r--servers/rendering/renderer_rd/framebuffer_cache_rd.h6
-rw-r--r--servers/rendering/renderer_rd/renderer_scene_render_rd.cpp74
-rw-r--r--servers/rendering/renderer_rd/renderer_scene_render_rd.h52
-rw-r--r--servers/rendering/renderer_rd/storage_rd/light_storage.h2
-rw-r--r--servers/rendering/renderer_rd/storage_rd/render_data_rd.cpp50
-rw-r--r--servers/rendering/renderer_rd/storage_rd/render_data_rd.h97
-rw-r--r--servers/rendering/renderer_rd/storage_rd/render_scene_buffers_rd.compat.inc66
-rw-r--r--servers/rendering/renderer_rd/storage_rd/render_scene_buffers_rd.cpp15
-rw-r--r--servers/rendering/renderer_rd/storage_rd/render_scene_buffers_rd.h76
-rw-r--r--servers/rendering/renderer_rd/storage_rd/render_scene_data_rd.cpp29
-rw-r--r--servers/rendering/renderer_rd/storage_rd/render_scene_data_rd.h16
-rw-r--r--servers/rendering/renderer_rd/uniform_set_cache_rd.cpp17
-rw-r--r--servers/rendering/renderer_rd/uniform_set_cache_rd.h6
-rw-r--r--servers/rendering/renderer_scene_cull.cpp39
-rw-r--r--servers/rendering/renderer_scene_cull.h29
-rw-r--r--servers/rendering/renderer_scene_render.cpp58
-rw-r--r--servers/rendering/renderer_scene_render.h25
-rw-r--r--servers/rendering/rendering_device_binds.h2
-rw-r--r--servers/rendering/rendering_method.h23
-rw-r--r--servers/rendering/rendering_server_default.h19
-rw-r--r--servers/rendering/storage/compositor_storage.cpp160
-rw-r--r--servers/rendering/storage/compositor_storage.h98
-rw-r--r--servers/rendering/storage/environment_storage.cpp19
-rw-r--r--servers/rendering/storage/environment_storage.h9
-rw-r--r--servers/rendering/storage/render_data.cpp69
-rw-r--r--servers/rendering/storage/render_data.h70
-rw-r--r--servers/rendering/storage/render_scene_data.cpp88
-rw-r--r--servers/rendering/storage/render_scene_data.h82
35 files changed, 1388 insertions, 133 deletions
diff --git a/servers/rendering/dummy/rasterizer_scene_dummy.h b/servers/rendering/dummy/rasterizer_scene_dummy.h
index fdf8df7587..083493003f 100644
--- a/servers/rendering/dummy/rasterizer_scene_dummy.h
+++ b/servers/rendering/dummy/rasterizer_scene_dummy.h
@@ -145,7 +145,7 @@ public:
void voxel_gi_set_quality(RS::VoxelGIQuality) override {}
- void render_scene(const Ref<RenderSceneBuffers> &p_render_buffers, const CameraData *p_camera_data, const CameraData *p_prev_camera_data, const PagedArray<RenderGeometryInstance *> &p_instances, const PagedArray<RID> &p_lights, const PagedArray<RID> &p_reflection_probes, const PagedArray<RID> &p_voxel_gi_instances, const PagedArray<RID> &p_decals, const PagedArray<RID> &p_lightmaps, const PagedArray<RID> &p_fog_volumes, RID p_environment, RID p_camera_attributes, RID p_shadow_atlas, RID p_occluder_debug_tex, RID p_reflection_atlas, RID p_reflection_probe, int p_reflection_probe_pass, float p_screen_mesh_lod_threshold, const RenderShadowData *p_render_shadows, int p_render_shadow_count, const RenderSDFGIData *p_render_sdfgi_regions, int p_render_sdfgi_region_count, const RenderSDFGIUpdateData *p_sdfgi_update_data = nullptr, RenderingMethod::RenderInfo *r_info = nullptr) override {}
+ void render_scene(const Ref<RenderSceneBuffers> &p_render_buffers, const CameraData *p_camera_data, const CameraData *p_prev_camera_data, const PagedArray<RenderGeometryInstance *> &p_instances, const PagedArray<RID> &p_lights, const PagedArray<RID> &p_reflection_probes, const PagedArray<RID> &p_voxel_gi_instances, const PagedArray<RID> &p_decals, const PagedArray<RID> &p_lightmaps, const PagedArray<RID> &p_fog_volumes, RID p_environment, RID p_camera_attributes, RID p_compositor, RID p_shadow_atlas, RID p_occluder_debug_tex, RID p_reflection_atlas, RID p_reflection_probe, int p_reflection_probe_pass, float p_screen_mesh_lod_threshold, const RenderShadowData *p_render_shadows, int p_render_shadow_count, const RenderSDFGIData *p_render_sdfgi_regions, int p_render_sdfgi_region_count, const RenderSDFGIUpdateData *p_sdfgi_update_data = nullptr, RenderingMethod::RenderInfo *r_info = nullptr) override {}
void render_material(const Transform3D &p_cam_transform, const Projection &p_cam_projection, bool p_cam_orthogonal, const PagedArray<RenderGeometryInstance *> &p_instances, RID p_framebuffer, const Rect2i &p_region) override {}
void render_particle_collider_heightfield(RID p_collider, const Transform3D &p_transform, const PagedArray<RenderGeometryInstance *> &p_instances) override {}
@@ -168,6 +168,12 @@ public:
if (is_environment(p_rid)) {
environment_free(p_rid);
return true;
+ } else if (is_compositor(p_rid)) {
+ compositor_free(p_rid);
+ return true;
+ } else if (is_compositor_effect(p_rid)) {
+ compositor_effect_free(p_rid);
+ return true;
} else if (RSG::camera_attributes->owns_camera_attributes(p_rid)) {
RSG::camera_attributes->camera_attributes_free(p_rid);
return true;
diff --git a/servers/rendering/renderer_canvas_cull.cpp b/servers/rendering/renderer_canvas_cull.cpp
index 94355f2c5f..65fcdb9751 100644
--- a/servers/rendering/renderer_canvas_cull.cpp
+++ b/servers/rendering/renderer_canvas_cull.cpp
@@ -311,12 +311,14 @@ void RendererCanvasCull::_cull_canvas_item(Item *p_canvas_item, const Transform2
child_item_count = ci->ysort_children_count + 1;
child_items = (Item **)alloca(child_item_count * sizeof(Item *));
+ ci->ysort_xform = ci->xform.affine_inverse();
+ ci->ysort_pos = Vector2();
+ ci->ysort_modulate = Color(1, 1, 1, 1);
+ ci->ysort_index = 0;
ci->ysort_parent_abs_z_index = parent_z;
child_items[0] = ci;
int i = 1;
_collect_ysort_children(ci, Transform2D(), p_material_owner, Color(1, 1, 1, 1), child_items, i, p_z);
- ci->ysort_xform = ci->xform.affine_inverse();
- ci->ysort_modulate = Color(1, 1, 1, 1);
SortArray<Item *, ItemPtrSort> sorter;
sorter.sort(child_items, child_item_count);
diff --git a/servers/rendering/renderer_rd/environment/gi.h b/servers/rendering/renderer_rd/environment/gi.h
index 011493f1f6..6169d386b5 100644
--- a/servers/rendering/renderer_rd/environment/gi.h
+++ b/servers/rendering/renderer_rd/environment/gi.h
@@ -56,7 +56,7 @@
#define RB_TEX_REFLECTION SNAME("reflection")
// Forward declare RenderDataRD and RendererSceneRenderRD so we can pass it into some of our methods, these classes are pretty tightly bound
-struct RenderDataRD;
+class RenderDataRD;
class RendererSceneRenderRD;
namespace RendererRD {
diff --git a/servers/rendering/renderer_rd/forward_clustered/render_forward_clustered.cpp b/servers/rendering/renderer_rd/forward_clustered/render_forward_clustered.cpp
index c454d35d28..fa6e78750b 100644
--- a/servers/rendering/renderer_rd/forward_clustered/render_forward_clustered.cpp
+++ b/servers/rendering/renderer_rd/forward_clustered/render_forward_clustered.cpp
@@ -67,7 +67,7 @@ void RenderForwardClustered::RenderBufferDataForwardClustered::ensure_specular()
void RenderForwardClustered::RenderBufferDataForwardClustered::ensure_normal_roughness_texture() {
ERR_FAIL_NULL(render_buffers);
- if (!render_buffers->has_texture(RB_SCOPE_FORWARD_CLUSTERED, RB_TEX_ROUGHNESS)) {
+ if (!render_buffers->has_texture(RB_SCOPE_FORWARD_CLUSTERED, RB_TEX_NORMAL_ROUGHNESS)) {
RD::DataFormat format = RD::DATA_FORMAT_R8G8B8A8_UNORM;
uint32_t usage_bits = RD::TEXTURE_USAGE_SAMPLING_BIT | RD::TEXTURE_USAGE_STORAGE_BIT;
@@ -77,11 +77,11 @@ void RenderForwardClustered::RenderBufferDataForwardClustered::ensure_normal_rou
usage_bits |= RD::TEXTURE_USAGE_COLOR_ATTACHMENT_BIT;
}
- render_buffers->create_texture(RB_SCOPE_FORWARD_CLUSTERED, RB_TEX_ROUGHNESS, format, usage_bits);
+ render_buffers->create_texture(RB_SCOPE_FORWARD_CLUSTERED, RB_TEX_NORMAL_ROUGHNESS, format, usage_bits);
if (render_buffers->get_msaa_3d() != RS::VIEWPORT_MSAA_DISABLED) {
usage_bits = RD::TEXTURE_USAGE_COLOR_ATTACHMENT_BIT | RD::TEXTURE_USAGE_CAN_COPY_FROM_BIT | RD::TEXTURE_USAGE_SAMPLING_BIT;
- render_buffers->create_texture(RB_SCOPE_FORWARD_CLUSTERED, RB_TEX_ROUGHNESS_MSAA, format, usage_bits, render_buffers->get_texture_samples());
+ render_buffers->create_texture(RB_SCOPE_FORWARD_CLUSTERED, RB_TEX_NORMAL_ROUGHNESS_MSAA, format, usage_bits, render_buffers->get_texture_samples());
}
}
}
@@ -214,7 +214,7 @@ RID RenderForwardClustered::RenderBufferDataForwardClustered::get_depth_fb(Depth
case DEPTH_FB_ROUGHNESS: {
ensure_normal_roughness_texture();
- RID normal_roughness_buffer = render_buffers->get_texture(RB_SCOPE_FORWARD_CLUSTERED, use_msaa ? RB_TEX_ROUGHNESS_MSAA : RB_TEX_ROUGHNESS);
+ RID normal_roughness_buffer = render_buffers->get_texture(RB_SCOPE_FORWARD_CLUSTERED, use_msaa ? RB_TEX_NORMAL_ROUGHNESS_MSAA : RB_TEX_NORMAL_ROUGHNESS);
return FramebufferCacheRD::get_singleton()->get_cache_multiview(render_buffers->get_view_count(), depth, normal_roughness_buffer);
} break;
@@ -222,7 +222,7 @@ RID RenderForwardClustered::RenderBufferDataForwardClustered::get_depth_fb(Depth
ensure_normal_roughness_texture();
ensure_voxelgi();
- RID normal_roughness_buffer = render_buffers->get_texture(RB_SCOPE_FORWARD_CLUSTERED, use_msaa ? RB_TEX_ROUGHNESS_MSAA : RB_TEX_ROUGHNESS);
+ RID normal_roughness_buffer = render_buffers->get_texture(RB_SCOPE_FORWARD_CLUSTERED, use_msaa ? RB_TEX_NORMAL_ROUGHNESS_MSAA : RB_TEX_NORMAL_ROUGHNESS);
RID voxelgi_buffer = render_buffers->get_texture(RB_SCOPE_FORWARD_CLUSTERED, use_msaa ? RB_TEX_VOXEL_GI_MSAA : RB_TEX_VOXEL_GI);
return FramebufferCacheRD::get_singleton()->get_cache_multiview(render_buffers->get_view_count(), depth, normal_roughness_buffer, voxelgi_buffer);
@@ -1578,6 +1578,11 @@ void RenderForwardClustered::_render_scene(RenderDataRD *p_render_data, const Co
RENDER_TIMESTAMP("Prepare 3D Scene");
+ // get info about our rendering effects
+ bool ce_needs_motion_vectors = _compositor_effects_has_flag(p_render_data, RS::COMPOSITOR_EFFECT_FLAG_NEEDS_MOTION_VECTORS);
+ bool ce_needs_normal_roughness = _compositor_effects_has_flag(p_render_data, RS::COMPOSITOR_EFFECT_FLAG_NEEDS_ROUGHNESS);
+ bool ce_needs_separate_specular = _compositor_effects_has_flag(p_render_data, RS::COMPOSITOR_EFFECT_FLAG_NEEDS_SEPARATE_SPECULAR);
+
// sdfgi first
_update_sdfgi(p_render_data);
@@ -1632,6 +1637,8 @@ void RenderForwardClustered::_render_scene(RenderDataRD *p_render_data, const Co
bool motion_vectors_required;
if (using_debug_mvs) {
motion_vectors_required = true;
+ } else if (ce_needs_motion_vectors) {
+ motion_vectors_required = true;
} else if (!is_reflection_probe && using_taa) {
motion_vectors_required = true;
} else if (!is_reflection_probe && using_fsr2) {
@@ -1738,10 +1745,11 @@ void RenderForwardClustered::_render_scene(RenderDataRD *p_render_data, const Co
if (using_voxelgi) {
depth_pass_mode = PASS_MODE_DEPTH_NORMAL_ROUGHNESS_VOXEL_GI;
} else if (p_render_data->environment.is_valid()) {
- if (environment_get_ssr_enabled(p_render_data->environment) ||
- environment_get_sdfgi_enabled(p_render_data->environment) ||
+ if (using_ssr ||
+ using_sdfgi ||
environment_get_ssao_enabled(p_render_data->environment) ||
using_ssil ||
+ ce_needs_normal_roughness ||
get_debug_draw_mode() == RS::VIEWPORT_DEBUG_DRAW_NORMAL_BUFFER ||
scene_state.used_normal_texture) {
depth_pass_mode = PASS_MODE_DEPTH_NORMAL_ROUGHNESS;
@@ -1770,7 +1778,7 @@ void RenderForwardClustered::_render_scene(RenderDataRD *p_render_data, const Co
bool using_sss = rb_data.is_valid() && !is_reflection_probe && scene_state.used_sss && ss_effects->sss_get_quality() != RS::SUB_SURFACE_SCATTERING_QUALITY_DISABLED;
- if (using_sss && !using_separate_specular) {
+ if ((using_sss || ce_needs_separate_specular) && !using_separate_specular) {
using_separate_specular = true;
color_pass_flags |= COLOR_PASS_FLAG_SEPARATE_SPECULAR;
color_framebuffer = rb_data->get_color_pass_fb(color_pass_flags);
@@ -1880,6 +1888,17 @@ void RenderForwardClustered::_render_scene(RenderDataRD *p_render_data, const Co
clear_color = p_default_bg_color;
}
+ RS::ViewportMSAA msaa = rb->get_msaa_3d();
+ bool use_msaa = msaa != RS::VIEWPORT_MSAA_DISABLED;
+
+ bool ce_pre_opaque_resolved_color = use_msaa && _compositor_effects_has_flag(p_render_data, RS::COMPOSITOR_EFFECT_FLAG_ACCESS_RESOLVED_COLOR, RS::COMPOSITOR_EFFECT_CALLBACK_TYPE_PRE_OPAQUE);
+ bool ce_post_opaque_resolved_color = use_msaa && _compositor_effects_has_flag(p_render_data, RS::COMPOSITOR_EFFECT_FLAG_ACCESS_RESOLVED_COLOR, RS::COMPOSITOR_EFFECT_CALLBACK_TYPE_POST_OPAQUE);
+ bool ce_pre_transparent_resolved_color = use_msaa && _compositor_effects_has_flag(p_render_data, RS::COMPOSITOR_EFFECT_FLAG_ACCESS_RESOLVED_COLOR, RS::COMPOSITOR_EFFECT_CALLBACK_TYPE_PRE_TRANSPARENT);
+
+ bool ce_pre_opaque_resolved_depth = use_msaa && _compositor_effects_has_flag(p_render_data, RS::COMPOSITOR_EFFECT_FLAG_ACCESS_RESOLVED_DEPTH, RS::COMPOSITOR_EFFECT_CALLBACK_TYPE_PRE_OPAQUE);
+ bool ce_post_opaque_resolved_depth = use_msaa && _compositor_effects_has_flag(p_render_data, RS::COMPOSITOR_EFFECT_FLAG_ACCESS_RESOLVED_DEPTH, RS::COMPOSITOR_EFFECT_CALLBACK_TYPE_POST_OPAQUE);
+ bool ce_pre_transparent_resolved_depth = use_msaa && _compositor_effects_has_flag(p_render_data, RS::COMPOSITOR_EFFECT_FLAG_ACCESS_RESOLVED_DEPTH, RS::COMPOSITOR_EFFECT_CALLBACK_TYPE_PRE_TRANSPARENT);
+
bool debug_voxelgis = get_debug_draw_mode() == RS::VIEWPORT_DEBUG_DRAW_VOXEL_GI_ALBEDO || get_debug_draw_mode() == RS::VIEWPORT_DEBUG_DRAW_VOXEL_GI_LIGHTING || get_debug_draw_mode() == RS::VIEWPORT_DEBUG_DRAW_VOXEL_GI_EMISSION;
bool debug_sdfgi_probes = get_debug_draw_mode() == RS::VIEWPORT_DEBUG_DRAW_SDFGI_PROBES;
bool depth_pre_pass = bool(GLOBAL_GET("rendering/driver/depth_prepass/enable")) && depth_framebuffer.is_valid();
@@ -1892,8 +1911,8 @@ void RenderForwardClustered::_render_scene(RenderDataRD *p_render_data, const Co
}
bool using_ssao = depth_pre_pass && !is_reflection_probe && p_render_data->environment.is_valid() && environment_get_ssao_enabled(p_render_data->environment);
- if (depth_pre_pass) { //depth pre pass
+ if (depth_pre_pass) { //depth pre pass
bool needs_pre_resolve = _needs_post_prepass_render(p_render_data, using_sdfgi || using_voxelgi);
if (needs_pre_resolve) {
RENDER_TIMESTAMP("GI + Render Depth Pre-Pass (Parallel)");
@@ -1912,28 +1931,42 @@ void RenderForwardClustered::_render_scene(RenderDataRD *p_render_data, const Co
RID rp_uniform_set = _setup_render_pass_uniform_set(RENDER_LIST_OPAQUE, nullptr, RID(), samplers);
- bool finish_depth = using_ssao || using_ssil || using_sdfgi || using_voxelgi;
+ bool finish_depth = using_ssao || using_ssil || using_sdfgi || using_voxelgi || ce_pre_opaque_resolved_depth || ce_post_opaque_resolved_depth;
RenderListParameters render_list_params(render_list[RENDER_LIST_OPAQUE].elements.ptr(), render_list[RENDER_LIST_OPAQUE].element_info.ptr(), render_list[RENDER_LIST_OPAQUE].elements.size(), reverse_cull, depth_pass_mode, 0, rb_data.is_null(), p_render_data->directional_light_soft_shadows, rp_uniform_set, get_debug_draw_mode() == RS::VIEWPORT_DEBUG_DRAW_WIREFRAME, Vector2(), p_render_data->scene_data->lod_distance_multiplier, p_render_data->scene_data->screen_mesh_lod_threshold, p_render_data->scene_data->view_count, 0, spec_constant_base_flags);
_render_list_with_draw_list(&render_list_params, depth_framebuffer, needs_pre_resolve ? RD::INITIAL_ACTION_LOAD : RD::INITIAL_ACTION_CLEAR, RD::FINAL_ACTION_STORE, needs_pre_resolve ? RD::INITIAL_ACTION_LOAD : RD::INITIAL_ACTION_CLEAR, RD::FINAL_ACTION_STORE, needs_pre_resolve ? Vector<Color>() : depth_pass_clear);
RD::get_singleton()->draw_command_end_label();
- if (rb->get_msaa_3d() != RS::VIEWPORT_MSAA_DISABLED) {
+ if (use_msaa) {
RENDER_TIMESTAMP("Resolve Depth Pre-Pass (MSAA)");
RD::get_singleton()->draw_command_begin_label("Resolve Depth Pre-Pass (MSAA)");
if (depth_pass_mode == PASS_MODE_DEPTH_NORMAL_ROUGHNESS || depth_pass_mode == PASS_MODE_DEPTH_NORMAL_ROUGHNESS_VOXEL_GI) {
for (uint32_t v = 0; v < rb->get_view_count(); v++) {
- resolve_effects->resolve_gi(rb->get_depth_msaa(v), rb_data->get_normal_roughness_msaa(v), using_voxelgi ? rb_data->get_voxelgi_msaa(v) : RID(), rb->get_depth_texture(v), rb_data->get_normal_roughness(v), using_voxelgi ? rb_data->get_voxelgi(v) : RID(), rb->get_internal_size(), texture_multisamples[rb->get_msaa_3d()]);
+ resolve_effects->resolve_gi(rb->get_depth_msaa(v), rb_data->get_normal_roughness_msaa(v), using_voxelgi ? rb_data->get_voxelgi_msaa(v) : RID(), rb->get_depth_texture(v), rb_data->get_normal_roughness(v), using_voxelgi ? rb_data->get_voxelgi(v) : RID(), rb->get_internal_size(), texture_multisamples[msaa]);
}
} else if (finish_depth) {
for (uint32_t v = 0; v < rb->get_view_count(); v++) {
- resolve_effects->resolve_depth(rb->get_depth_msaa(v), rb->get_depth_texture(v), rb->get_internal_size(), texture_multisamples[rb->get_msaa_3d()]);
+ resolve_effects->resolve_depth(rb->get_depth_msaa(v), rb->get_depth_texture(v), rb->get_internal_size(), texture_multisamples[msaa]);
}
}
RD::get_singleton()->draw_command_end_label();
}
}
+ {
+ if (ce_pre_opaque_resolved_color) {
+ // We haven't rendered color data yet so...
+ WARN_PRINT_ONCE("Pre opaque rendering effects can't access resolved color buffers.");
+ }
+
+ if (ce_pre_opaque_resolved_depth && !depth_pre_pass) {
+ // We haven't rendered depth data yet so...
+ WARN_PRINT_ONCE("Pre opaque rendering effects can't access resolved depth buffers.");
+ }
+
+ _process_compositor_effects(RS::COMPOSITOR_EFFECT_CALLBACK_TYPE_PRE_OPAQUE, p_render_data);
+ }
+
RID normal_roughness_views[RendererSceneRender::MAX_RENDER_VIEWS];
if (rb_data.is_valid() && rb_data->has_normal_roughness()) {
for (uint32_t v = 0; v < rb->get_view_count(); v++) {
@@ -1955,8 +1988,6 @@ void RenderForwardClustered::_render_scene(RenderDataRD *p_render_data, const Co
RENDER_TIMESTAMP("Render Opaque Pass");
RID rp_uniform_set = _setup_render_pass_uniform_set(RENDER_LIST_OPAQUE, p_render_data, radiance_texture, samplers, true);
- bool can_continue_color = !scene_state.used_screen_texture && !using_ssr && !using_sss;
- bool can_continue_depth = !(scene_state.used_depth_texture || scene_state.used_normal_texture) && !using_ssr && !using_sss;
{
bool render_motion_pass = !render_list[RENDER_LIST_MOTION].elements.is_empty();
@@ -2006,6 +2037,22 @@ void RenderForwardClustered::_render_scene(RenderDataRD *p_render_data, const Co
}
}
+ {
+ if (ce_post_opaque_resolved_color) {
+ for (uint32_t v = 0; v < rb->get_view_count(); v++) {
+ RD::get_singleton()->texture_resolve_multisample(rb->get_color_msaa(v), rb->get_internal_texture(v));
+ }
+ }
+
+ if (ce_post_opaque_resolved_depth) {
+ for (uint32_t v = 0; v < rb->get_view_count(); v++) {
+ resolve_effects->resolve_depth(rb->get_depth_msaa(v), rb->get_depth_texture(v), rb->get_internal_size(), texture_multisamples[msaa]);
+ }
+ }
+
+ _process_compositor_effects(RS::COMPOSITOR_EFFECT_CALLBACK_TYPE_POST_OPAQUE, p_render_data);
+ }
+
if (debug_voxelgis) {
Projection dc;
dc.set_depth_correction(true);
@@ -2040,11 +2087,11 @@ void RenderForwardClustered::_render_scene(RenderDataRD *p_render_data, const Co
RD::get_singleton()->draw_list_end();
RD::get_singleton()->draw_command_end_label();
}
- if (rb->get_msaa_3d() != RS::VIEWPORT_MSAA_DISABLED) {
+
+ if (use_msaa) {
RENDER_TIMESTAMP("Resolve MSAA");
- if (!can_continue_color) {
- // Handle views individual, might want to look at rewriting our resolve to do both layers in one pass.
+ if (scene_state.used_screen_texture || using_separate_specular || ce_pre_transparent_resolved_color) {
for (uint32_t v = 0; v < rb->get_view_count(); v++) {
RD::get_singleton()->texture_resolve_multisample(rb->get_color_msaa(v), rb->get_internal_texture(v));
}
@@ -2055,13 +2102,18 @@ void RenderForwardClustered::_render_scene(RenderDataRD *p_render_data, const Co
}
}
- if (!can_continue_depth) {
+ if (scene_state.used_depth_texture || scene_state.used_normal_texture || using_separate_specular || ce_needs_normal_roughness || ce_pre_transparent_resolved_depth) {
for (uint32_t v = 0; v < rb->get_view_count(); v++) {
- resolve_effects->resolve_depth(rb->get_depth_msaa(v), rb->get_depth_texture(v), rb->get_internal_size(), texture_multisamples[rb->get_msaa_3d()]);
+ resolve_effects->resolve_depth(rb->get_depth_msaa(v), rb->get_depth_texture(v), rb->get_internal_size(), texture_multisamples[msaa]);
}
}
}
+ {
+ // Don't need to check for depth or color resolve here, we've already triggered it.
+ _process_compositor_effects(RS::COMPOSITOR_EFFECT_CALLBACK_TYPE_POST_SKY, p_render_data);
+ }
+
if (using_separate_specular) {
if (using_sss) {
RENDER_TIMESTAMP("Sub-Surface Scattering");
@@ -2077,12 +2129,12 @@ void RenderForwardClustered::_render_scene(RenderDataRD *p_render_data, const Co
for (uint32_t v = 0; v < p_render_data->scene_data->view_count; v++) {
specular_views[v] = rb_data->get_specular(v);
}
- _process_ssr(rb, color_only_framebuffer, normal_roughness_views, rb_data->get_specular(), specular_views, p_render_data->environment, p_render_data->scene_data->view_projection, p_render_data->scene_data->view_eye_offset, rb->get_msaa_3d() == RS::VIEWPORT_MSAA_DISABLED);
+ _process_ssr(rb, color_only_framebuffer, normal_roughness_views, rb_data->get_specular(), specular_views, p_render_data->environment, p_render_data->scene_data->view_projection, p_render_data->scene_data->view_eye_offset, !use_msaa);
RD::get_singleton()->draw_command_end_label();
} else {
//just mix specular back
RENDER_TIMESTAMP("Merge Specular");
- copy_effects->merge_specular(color_only_framebuffer, rb_data->get_specular(), rb->get_msaa_3d() == RS::VIEWPORT_MSAA_DISABLED ? RID() : rb->get_internal_texture(), RID(), p_render_data->scene_data->view_count);
+ copy_effects->merge_specular(color_only_framebuffer, rb_data->get_specular(), !use_msaa ? RID() : rb->get_internal_texture(), RID(), p_render_data->scene_data->view_count);
}
}
@@ -2116,6 +2168,28 @@ void RenderForwardClustered::_render_scene(RenderDataRD *p_render_data, const Co
_render_buffers_copy_depth_texture(p_render_data);
}
+ {
+ if (using_separate_specular) {
+ // Our specular will be combined back in (and effects, subsurface scattering and/or ssr applied),
+ // so if we've requested this, we need another copy.
+ // Fairly unlikely scenario though.
+
+ if (ce_pre_transparent_resolved_color) {
+ for (uint32_t v = 0; v < rb->get_view_count(); v++) {
+ RD::get_singleton()->texture_resolve_multisample(rb->get_color_msaa(v), rb->get_internal_texture(v));
+ }
+ }
+
+ if (ce_pre_transparent_resolved_depth) {
+ for (uint32_t v = 0; v < rb->get_view_count(); v++) {
+ resolve_effects->resolve_depth(rb->get_depth_msaa(v), rb->get_depth_texture(v), rb->get_internal_size(), texture_multisamples[msaa]);
+ }
+ }
+ }
+
+ _process_compositor_effects(RS::COMPOSITOR_EFFECT_CALLBACK_TYPE_PRE_TRANSPARENT, p_render_data);
+ }
+
RENDER_TIMESTAMP("Render 3D Transparent Pass");
RD::get_singleton()->draw_command_begin_label("Render 3D Transparent Pass");
@@ -2142,11 +2216,11 @@ void RenderForwardClustered::_render_scene(RenderDataRD *p_render_data, const Co
RD::get_singleton()->draw_command_begin_label("Resolve");
- if (rb_data.is_valid() && rb->get_msaa_3d() != RS::VIEWPORT_MSAA_DISABLED) {
- bool resolve_velocity_buffer = (using_taa || using_fsr2) && rb->has_velocity_buffer(true);
+ if (rb_data.is_valid() && use_msaa) {
+ bool resolve_velocity_buffer = (using_taa || using_fsr2 || ce_needs_motion_vectors) && rb->has_velocity_buffer(true);
for (uint32_t v = 0; v < rb->get_view_count(); v++) {
RD::get_singleton()->texture_resolve_multisample(rb->get_color_msaa(v), rb->get_internal_texture(v));
- resolve_effects->resolve_depth(rb->get_depth_msaa(v), rb->get_depth_texture(v), rb->get_internal_size(), texture_multisamples[rb->get_msaa_3d()]);
+ resolve_effects->resolve_depth(rb->get_depth_msaa(v), rb->get_depth_texture(v), rb->get_internal_size(), texture_multisamples[msaa]);
if (resolve_velocity_buffer) {
RD::get_singleton()->texture_resolve_multisample(rb->get_velocity_buffer(true, v), rb->get_velocity_buffer(false, v));
@@ -2156,6 +2230,10 @@ void RenderForwardClustered::_render_scene(RenderDataRD *p_render_data, const Co
RD::get_singleton()->draw_command_end_label();
+ {
+ _process_compositor_effects(RS::COMPOSITOR_EFFECT_CALLBACK_TYPE_POST_TRANSPARENT, p_render_data);
+ }
+
RD::get_singleton()->draw_command_begin_label("Copy framebuffer for SSIL");
if (using_ssil) {
RENDER_TIMESTAMP("Copy Final Framebuffer (SSIL)");
diff --git a/servers/rendering/renderer_rd/forward_clustered/render_forward_clustered.h b/servers/rendering/renderer_rd/forward_clustered/render_forward_clustered.h
index 51fd0aaffb..12af8822b4 100644
--- a/servers/rendering/renderer_rd/forward_clustered/render_forward_clustered.h
+++ b/servers/rendering/renderer_rd/forward_clustered/render_forward_clustered.h
@@ -48,8 +48,8 @@
#define RB_TEX_SPECULAR SNAME("specular")
#define RB_TEX_SPECULAR_MSAA SNAME("specular_msaa")
-#define RB_TEX_ROUGHNESS SNAME("normal_roughnesss")
-#define RB_TEX_ROUGHNESS_MSAA SNAME("normal_roughnesss_msaa")
+#define RB_TEX_NORMAL_ROUGHNESS SNAME("normal_roughness")
+#define RB_TEX_NORMAL_ROUGHNESS_MSAA SNAME("normal_roughness_msaa")
#define RB_TEX_VOXEL_GI SNAME("voxel_gi")
#define RB_TEX_VOXEL_GI_MSAA SNAME("voxel_gi_msaa")
@@ -131,11 +131,11 @@ class RenderForwardClustered : public RendererSceneRenderRD {
RID get_specular_msaa(uint32_t p_layer) { return render_buffers->get_texture_slice(RB_SCOPE_FORWARD_CLUSTERED, RB_TEX_SPECULAR_MSAA, p_layer, 0); }
void ensure_normal_roughness_texture();
- bool has_normal_roughness() const { return render_buffers->has_texture(RB_SCOPE_FORWARD_CLUSTERED, RB_TEX_ROUGHNESS); }
- RID get_normal_roughness() const { return render_buffers->get_texture(RB_SCOPE_FORWARD_CLUSTERED, RB_TEX_ROUGHNESS); }
- RID get_normal_roughness(uint32_t p_layer) { return render_buffers->get_texture_slice(RB_SCOPE_FORWARD_CLUSTERED, RB_TEX_ROUGHNESS, p_layer, 0); }
- RID get_normal_roughness_msaa() const { return render_buffers->get_texture(RB_SCOPE_FORWARD_CLUSTERED, RB_TEX_ROUGHNESS_MSAA); }
- RID get_normal_roughness_msaa(uint32_t p_layer) { return render_buffers->get_texture_slice(RB_SCOPE_FORWARD_CLUSTERED, RB_TEX_ROUGHNESS_MSAA, p_layer, 0); }
+ bool has_normal_roughness() const { return render_buffers->has_texture(RB_SCOPE_FORWARD_CLUSTERED, RB_TEX_NORMAL_ROUGHNESS); }
+ RID get_normal_roughness() const { return render_buffers->get_texture(RB_SCOPE_FORWARD_CLUSTERED, RB_TEX_NORMAL_ROUGHNESS); }
+ RID get_normal_roughness(uint32_t p_layer) { return render_buffers->get_texture_slice(RB_SCOPE_FORWARD_CLUSTERED, RB_TEX_NORMAL_ROUGHNESS, p_layer, 0); }
+ RID get_normal_roughness_msaa() const { return render_buffers->get_texture(RB_SCOPE_FORWARD_CLUSTERED, RB_TEX_NORMAL_ROUGHNESS_MSAA); }
+ RID get_normal_roughness_msaa(uint32_t p_layer) { return render_buffers->get_texture_slice(RB_SCOPE_FORWARD_CLUSTERED, RB_TEX_NORMAL_ROUGHNESS_MSAA, p_layer, 0); }
void ensure_voxelgi();
bool has_voxelgi() const { return render_buffers->has_texture(RB_SCOPE_FORWARD_CLUSTERED, RB_TEX_VOXEL_GI); }
diff --git a/servers/rendering/renderer_rd/forward_mobile/render_forward_mobile.cpp b/servers/rendering/renderer_rd/forward_mobile/render_forward_mobile.cpp
index fd81430983..ac93aca6bb 100644
--- a/servers/rendering/renderer_rd/forward_mobile/render_forward_mobile.cpp
+++ b/servers/rendering/renderer_rd/forward_mobile/render_forward_mobile.cpp
@@ -669,6 +669,8 @@ void RenderForwardMobile::_render_scene(RenderDataRD *p_render_data, const Color
// check if we need motion vectors
if (get_debug_draw_mode() == RS::VIEWPORT_DEBUG_DRAW_MOTION_VECTORS) {
p_render_data->scene_data->calculate_motion_vectors = true;
+ } else if (_compositor_effects_has_flag(p_render_data, RS::COMPOSITOR_EFFECT_FLAG_NEEDS_MOTION_VECTORS)) {
+ p_render_data->scene_data->calculate_motion_vectors = true;
} else if (render target has velocity override) { // TODO
p_render_data->scene_data->calculate_motion_vectors = true;
} else {
@@ -694,6 +696,34 @@ void RenderForwardMobile::_render_scene(RenderDataRD *p_render_data, const Color
bool using_subpass_post_process = true; // If true: we can do our post processing in a subpass
RendererRD::MaterialStorage::Samplers samplers;
+ RS::ViewportMSAA msaa = rb->get_msaa_3d();
+ bool use_msaa = msaa != RS::VIEWPORT_MSAA_DISABLED;
+
+ bool ce_has_post_opaque = _has_compositor_effect(RS::COMPOSITOR_EFFECT_CALLBACK_TYPE_POST_OPAQUE, p_render_data);
+ bool ce_has_pre_transparent = _has_compositor_effect(RS::COMPOSITOR_EFFECT_CALLBACK_TYPE_PRE_TRANSPARENT, p_render_data);
+ bool ce_has_post_transparent = _has_compositor_effect(RS::COMPOSITOR_EFFECT_CALLBACK_TYPE_POST_TRANSPARENT, p_render_data);
+
+ if (ce_has_post_opaque) {
+ // As we're doing opaque and sky in subpasses we don't support this *yet*
+ WARN_PRINT_ONCE("Post opaque rendering effect callback is not supported in the mobile renderer");
+ }
+
+ // Using RenderingEffects limits our ability to do subpasses..
+ if (ce_has_pre_transparent) {
+ merge_transparent_pass = false;
+ using_subpass_post_process = false;
+ }
+ if (ce_has_post_transparent) {
+ using_subpass_post_process = false;
+ }
+
+ if (use_msaa && _compositor_effects_has_flag(p_render_data, RS::COMPOSITOR_EFFECT_FLAG_ACCESS_RESOLVED_DEPTH, RS::COMPOSITOR_EFFECT_CALLBACK_TYPE_ANY)) {
+ // We'll be able to do this when we finish PR #78598
+ WARN_PRINT_ONCE("Depth buffer resolve for rendering effect callback is not supported in the mobile renderer");
+ }
+
+ // We don't need to check resolve color flag, it will be resolved for transparent passes regardless.
+
bool using_shadows = true;
if (p_render_data->reflection_probe.is_valid()) {
@@ -881,6 +911,9 @@ void RenderForwardMobile::_render_scene(RenderDataRD *p_render_data, const Color
clear_color = p_default_bg_color;
}
+ // We don't have access to any rendered buffers but we may be able to effect mesh data...
+ _process_compositor_effects(RS::COMPOSITOR_EFFECT_CALLBACK_TYPE_PRE_OPAQUE, p_render_data);
+
_pre_opaque_render(p_render_data);
uint32_t spec_constant_base_flags = 0;
@@ -942,7 +975,7 @@ void RenderForwardMobile::_render_scene(RenderDataRD *p_render_data, const Color
c.push_back(cc); // Our render buffer.
if (rb_data.is_valid()) {
- if (p_render_data->render_buffers->get_msaa_3d() != RS::VIEWPORT_MSAA_DISABLED) {
+ if (use_msaa) {
c.push_back(clear_color.srgb_to_linear() * inverse_luminance_multiplier); // Our resolve buffer.
}
if (using_subpass_post_process) {
@@ -985,6 +1018,11 @@ void RenderForwardMobile::_render_scene(RenderDataRD *p_render_data, const Color
RD::get_singleton()->draw_command_end_label(); // Draw Sky
}
+ // rendering effects
+ if (ce_has_pre_transparent) {
+ _process_compositor_effects(RS::COMPOSITOR_EFFECT_CALLBACK_TYPE_PRE_TRANSPARENT, p_render_data);
+ }
+
if (merge_transparent_pass) {
if (render_list[RENDER_LIST_ALPHA].element_info.size() > 0) {
// transparent pass
@@ -1055,6 +1093,10 @@ void RenderForwardMobile::_render_scene(RenderDataRD *p_render_data, const Color
if (rb_data.is_valid() && !using_subpass_post_process) {
RD::get_singleton()->draw_command_begin_label("Post process pass");
+ if (ce_has_post_transparent) {
+ _process_compositor_effects(RS::COMPOSITOR_EFFECT_CALLBACK_TYPE_POST_TRANSPARENT, p_render_data);
+ }
+
// If we need extra effects we do this in its own pass
RENDER_TIMESTAMP("Tonemap");
diff --git a/servers/rendering/renderer_rd/framebuffer_cache_rd.cpp b/servers/rendering/renderer_rd/framebuffer_cache_rd.cpp
index 71b8136245..ec037b71fa 100644
--- a/servers/rendering/renderer_rd/framebuffer_cache_rd.cpp
+++ b/servers/rendering/renderer_rd/framebuffer_cache_rd.cpp
@@ -32,6 +32,10 @@
FramebufferCacheRD *FramebufferCacheRD::singleton = nullptr;
+void FramebufferCacheRD::_bind_methods() {
+ ClassDB::bind_static_method("FramebufferCacheRD", D_METHOD("get_cache_multipass", "textures", "passes", "views"), &FramebufferCacheRD::get_cache_multipass_array);
+}
+
void FramebufferCacheRD::_invalidate(Cache *p_cache) {
if (p_cache->prev) {
p_cache->prev->next = p_cache->next;
@@ -52,6 +56,25 @@ void FramebufferCacheRD::_framebuffer_invalidation_callback(void *p_userdata) {
singleton->_invalidate(reinterpret_cast<Cache *>(p_userdata));
}
+RID FramebufferCacheRD::get_cache_multipass_array(const TypedArray<RID> &p_textures, const TypedArray<RDFramebufferPass> &p_passes, uint32_t p_views) {
+ Vector<RID> textures;
+ Vector<RD::FramebufferPass> passes;
+
+ for (int i = 0; i < p_textures.size(); i++) {
+ RID texture = p_textures[i];
+ textures.push_back(texture); // store even if NULL
+ }
+
+ for (int i = 0; i < p_passes.size(); i++) {
+ Ref<RDFramebufferPass> pass = p_passes[i];
+ if (pass.is_valid()) {
+ passes.push_back(pass->base);
+ }
+ }
+
+ return FramebufferCacheRD::get_singleton()->get_cache_multipass(textures, passes, p_views);
+}
+
FramebufferCacheRD::FramebufferCacheRD() {
ERR_FAIL_COND(singleton != nullptr);
singleton = this;
diff --git a/servers/rendering/renderer_rd/framebuffer_cache_rd.h b/servers/rendering/renderer_rd/framebuffer_cache_rd.h
index cae95ccce0..abb2a5808d 100644
--- a/servers/rendering/renderer_rd/framebuffer_cache_rd.h
+++ b/servers/rendering/renderer_rd/framebuffer_cache_rd.h
@@ -34,6 +34,7 @@
#include "core/templates/local_vector.h"
#include "core/templates/paged_allocator.h"
#include "servers/rendering/rendering_device.h"
+#include "servers/rendering/rendering_device_binds.h"
class FramebufferCacheRD : public Object {
GDCLASS(FramebufferCacheRD, Object)
@@ -195,6 +196,9 @@ class FramebufferCacheRD : public Object {
return rid;
}
+private:
+ static void _bind_methods();
+
public:
template <typename... Args>
RID get_cache(Args... args) {
@@ -301,6 +305,8 @@ public:
return _allocate_from_data(p_views, h, table_idx, p_textures, p_passes);
}
+ static RID get_cache_multipass_array(const TypedArray<RID> &p_textures, const TypedArray<RDFramebufferPass> &p_passes, uint32_t p_views = 1);
+
static FramebufferCacheRD *get_singleton() { return singleton; }
FramebufferCacheRD();
diff --git a/servers/rendering/renderer_rd/renderer_scene_render_rd.cpp b/servers/rendering/renderer_rd/renderer_scene_render_rd.cpp
index 35c0bdd595..62ecec3991 100644
--- a/servers/rendering/renderer_rd/renderer_scene_render_rd.cpp
+++ b/servers/rendering/renderer_rd/renderer_scene_render_rd.cpp
@@ -249,6 +249,73 @@ Ref<RenderSceneBuffers> RendererSceneRenderRD::render_buffers_create() {
return rb;
}
+bool RendererSceneRenderRD::_compositor_effects_has_flag(const RenderDataRD *p_render_data, RS::CompositorEffectFlags p_flag, RS::CompositorEffectCallbackType p_callback_type) {
+ RendererCompositorStorage *comp_storage = RendererCompositorStorage::get_singleton();
+
+ if (p_render_data->compositor.is_null()) {
+ return false;
+ }
+
+ if (p_render_data->reflection_probe.is_valid()) {
+ return false;
+ }
+
+ ERR_FAIL_COND_V(!comp_storage->is_compositor(p_render_data->compositor), false);
+ Vector<RID> re_rids = comp_storage->compositor_get_compositor_effects(p_render_data->compositor, p_callback_type, true);
+
+ for (RID rid : re_rids) {
+ if (comp_storage->compositor_effect_get_flag(rid, p_flag)) {
+ return true;
+ }
+ }
+
+ return false;
+}
+
+bool RendererSceneRenderRD::_has_compositor_effect(RS::CompositorEffectCallbackType p_callback_type, const RenderDataRD *p_render_data) {
+ RendererCompositorStorage *comp_storage = RendererCompositorStorage::get_singleton();
+
+ if (p_render_data->compositor.is_null()) {
+ return false;
+ }
+
+ if (p_render_data->reflection_probe.is_valid()) {
+ return false;
+ }
+
+ ERR_FAIL_COND_V(!comp_storage->is_compositor(p_render_data->compositor), false);
+
+ Vector<RID> effects = comp_storage->compositor_get_compositor_effects(p_render_data->compositor, p_callback_type, true);
+
+ return effects.size() > 0;
+}
+
+void RendererSceneRenderRD::_process_compositor_effects(RS::CompositorEffectCallbackType p_callback_type, const RenderDataRD *p_render_data) {
+ RendererCompositorStorage *comp_storage = RendererCompositorStorage::get_singleton();
+
+ if (p_render_data->compositor.is_null()) {
+ return;
+ }
+
+ if (p_render_data->reflection_probe.is_valid()) {
+ return;
+ }
+
+ ERR_FAIL_COND(!comp_storage->is_compositor(p_render_data->compositor));
+
+ Vector<RID> re_rids = comp_storage->compositor_get_compositor_effects(p_render_data->compositor, p_callback_type, true);
+
+ for (RID rid : re_rids) {
+ Array arr;
+ Callable callback = comp_storage->compositor_effect_get_callback(rid);
+
+ arr.push_back(p_callback_type);
+ arr.push_back(p_render_data);
+
+ callback.callv(arr);
+ }
+}
+
void RendererSceneRenderRD::_render_buffers_copy_screen_texture(const RenderDataRD *p_render_data) {
Ref<RenderSceneBuffersRD> rb = p_render_data->render_buffers;
ERR_FAIL_COND(rb.is_null());
@@ -987,7 +1054,7 @@ void RendererSceneRenderRD::_post_prepass_render(RenderDataRD *p_render_data, bo
}
}
-void RendererSceneRenderRD::render_scene(const Ref<RenderSceneBuffers> &p_render_buffers, const CameraData *p_camera_data, const CameraData *p_prev_camera_data, const PagedArray<RenderGeometryInstance *> &p_instances, const PagedArray<RID> &p_lights, const PagedArray<RID> &p_reflection_probes, const PagedArray<RID> &p_voxel_gi_instances, const PagedArray<RID> &p_decals, const PagedArray<RID> &p_lightmaps, const PagedArray<RID> &p_fog_volumes, RID p_environment, RID p_camera_attributes, RID p_shadow_atlas, RID p_occluder_debug_tex, RID p_reflection_atlas, RID p_reflection_probe, int p_reflection_probe_pass, float p_screen_mesh_lod_threshold, const RenderShadowData *p_render_shadows, int p_render_shadow_count, const RenderSDFGIData *p_render_sdfgi_regions, int p_render_sdfgi_region_count, const RenderSDFGIUpdateData *p_sdfgi_update_data, RenderingMethod::RenderInfo *r_render_info) {
+void RendererSceneRenderRD::render_scene(const Ref<RenderSceneBuffers> &p_render_buffers, const CameraData *p_camera_data, const CameraData *p_prev_camera_data, const PagedArray<RenderGeometryInstance *> &p_instances, const PagedArray<RID> &p_lights, const PagedArray<RID> &p_reflection_probes, const PagedArray<RID> &p_voxel_gi_instances, const PagedArray<RID> &p_decals, const PagedArray<RID> &p_lightmaps, const PagedArray<RID> &p_fog_volumes, RID p_environment, RID p_camera_attributes, RID p_compositor, RID p_shadow_atlas, RID p_occluder_debug_tex, RID p_reflection_atlas, RID p_reflection_probe, int p_reflection_probe_pass, float p_screen_mesh_lod_threshold, const RenderShadowData *p_render_shadows, int p_render_shadow_count, const RenderSDFGIData *p_render_sdfgi_regions, int p_render_sdfgi_region_count, const RenderSDFGIUpdateData *p_sdfgi_update_data, RenderingMethod::RenderInfo *r_render_info) {
RendererRD::LightStorage *light_storage = RendererRD::LightStorage::get_singleton();
RendererRD::TextureStorage *texture_storage = RendererRD::TextureStorage::get_singleton();
@@ -1067,6 +1134,7 @@ void RendererSceneRenderRD::render_scene(const Ref<RenderSceneBuffers> &p_render
render_data.lightmaps = &p_lightmaps;
render_data.fog_volumes = &p_fog_volumes;
render_data.environment = p_environment;
+ render_data.compositor = p_compositor;
render_data.camera_attributes = p_camera_attributes;
render_data.shadow_atlas = p_shadow_atlas;
render_data.occluder_debug_tex = p_occluder_debug_tex;
@@ -1128,6 +1196,10 @@ void RendererSceneRenderRD::render_particle_collider_heightfield(RID p_collider,
bool RendererSceneRenderRD::free(RID p_rid) {
if (is_environment(p_rid)) {
environment_free(p_rid);
+ } else if (is_compositor(p_rid)) {
+ compositor_free(p_rid);
+ } else if (is_compositor_effect(p_rid)) {
+ compositor_effect_free(p_rid);
} else if (RSG::camera_attributes->owns_camera_attributes(p_rid)) {
RSG::camera_attributes->camera_attributes_free(p_rid);
} else if (gi.voxel_gi_instance_owns(p_rid)) {
diff --git a/servers/rendering/renderer_rd/renderer_scene_render_rd.h b/servers/rendering/renderer_rd/renderer_scene_render_rd.h
index 4811ae3b44..5c5f11aba6 100644
--- a/servers/rendering/renderer_rd/renderer_scene_render_rd.h
+++ b/servers/rendering/renderer_rd/renderer_scene_render_rd.h
@@ -47,58 +47,13 @@
#include "servers/rendering/renderer_rd/environment/sky.h"
#include "servers/rendering/renderer_rd/framebuffer_cache_rd.h"
#include "servers/rendering/renderer_rd/storage_rd/light_storage.h"
+#include "servers/rendering/renderer_rd/storage_rd/render_data_rd.h"
#include "servers/rendering/renderer_rd/storage_rd/render_scene_buffers_rd.h"
#include "servers/rendering/renderer_rd/storage_rd/render_scene_data_rd.h"
#include "servers/rendering/renderer_scene_render.h"
#include "servers/rendering/rendering_device.h"
#include "servers/rendering/rendering_method.h"
-// For RenderDataRD, possibly inherited from RefCounted and add proper getters for our implementation classes
-
-struct RenderDataRD {
- Ref<RenderSceneBuffersRD> render_buffers;
- RenderSceneDataRD *scene_data;
-
- const PagedArray<RenderGeometryInstance *> *instances = nullptr;
- const PagedArray<RID> *lights = nullptr;
- const PagedArray<RID> *reflection_probes = nullptr;
- const PagedArray<RID> *voxel_gi_instances = nullptr;
- const PagedArray<RID> *decals = nullptr;
- const PagedArray<RID> *lightmaps = nullptr;
- const PagedArray<RID> *fog_volumes = nullptr;
- RID environment;
- RID camera_attributes;
- RID shadow_atlas;
- RID occluder_debug_tex;
- RID reflection_atlas;
- RID reflection_probe;
- int reflection_probe_pass = 0;
-
- RID cluster_buffer;
- uint32_t cluster_size = 0;
- uint32_t cluster_max_elements = 0;
-
- uint32_t directional_light_count = 0;
- bool directional_light_soft_shadows = false;
-
- RenderingMethod::RenderInfo *render_info = nullptr;
-
- /* Shadow data */
- const RendererSceneRender::RenderShadowData *render_shadows = nullptr;
- int render_shadow_count = 0;
-
- LocalVector<int> cube_shadows;
- LocalVector<int> shadows;
- LocalVector<int> directional_shadows;
-
- /* GI info */
- const RendererSceneRender::RenderSDFGIData *render_sdfgi_regions = nullptr;
- int render_sdfgi_region_count = 0;
- const RendererSceneRender::RenderSDFGIUpdateData *sdfgi_update_data = nullptr;
-
- uint32_t voxel_gi_count = 0;
-};
-
class RendererSceneRenderRD : public RendererSceneRender {
friend RendererRD::SkyRD;
friend RendererRD::GI;
@@ -145,6 +100,9 @@ protected:
bool _needs_post_prepass_render(RenderDataRD *p_render_data, bool p_use_gi);
void _post_prepass_render(RenderDataRD *p_render_data, bool p_use_gi);
+ bool _compositor_effects_has_flag(const RenderDataRD *p_render_data, RS::CompositorEffectFlags p_flag, RS::CompositorEffectCallbackType p_callback_type = RS::COMPOSITOR_EFFECT_CALLBACK_TYPE_ANY);
+ bool _has_compositor_effect(RS::CompositorEffectCallbackType p_callback_type, const RenderDataRD *p_render_data);
+ void _process_compositor_effects(RS::CompositorEffectCallbackType p_callback_type, const RenderDataRD *p_render_data);
void _render_buffers_copy_screen_texture(const RenderDataRD *p_render_data);
void _render_buffers_copy_depth_texture(const RenderDataRD *p_render_data);
void _render_buffers_post_process_and_tonemap(const RenderDataRD *p_render_data);
@@ -280,7 +238,7 @@ public:
virtual void base_uniforms_changed() = 0;
- virtual void render_scene(const Ref<RenderSceneBuffers> &p_render_buffers, const CameraData *p_camera_data, const CameraData *p_prev_camera_data, const PagedArray<RenderGeometryInstance *> &p_instances, const PagedArray<RID> &p_lights, const PagedArray<RID> &p_reflection_probes, const PagedArray<RID> &p_voxel_gi_instances, const PagedArray<RID> &p_decals, const PagedArray<RID> &p_lightmaps, const PagedArray<RID> &p_fog_volumes, RID p_environment, RID p_camera_attributes, RID p_shadow_atlas, RID p_occluder_debug_tex, RID p_reflection_atlas, RID p_reflection_probe, int p_reflection_probe_pass, float p_screen_mesh_lod_threshold, const RenderShadowData *p_render_shadows, int p_render_shadow_count, const RenderSDFGIData *p_render_sdfgi_regions, int p_render_sdfgi_region_count, const RenderSDFGIUpdateData *p_sdfgi_update_data = nullptr, RenderingMethod::RenderInfo *r_render_info = nullptr) override;
+ virtual void render_scene(const Ref<RenderSceneBuffers> &p_render_buffers, const CameraData *p_camera_data, const CameraData *p_prev_camera_data, const PagedArray<RenderGeometryInstance *> &p_instances, const PagedArray<RID> &p_lights, const PagedArray<RID> &p_reflection_probes, const PagedArray<RID> &p_voxel_gi_instances, const PagedArray<RID> &p_decals, const PagedArray<RID> &p_lightmaps, const PagedArray<RID> &p_fog_volumes, RID p_environment, RID p_camera_attributes, RID p_compositor, RID p_shadow_atlas, RID p_occluder_debug_tex, RID p_reflection_atlas, RID p_reflection_probe, int p_reflection_probe_pass, float p_screen_mesh_lod_threshold, const RenderShadowData *p_render_shadows, int p_render_shadow_count, const RenderSDFGIData *p_render_sdfgi_regions, int p_render_sdfgi_region_count, const RenderSDFGIUpdateData *p_sdfgi_update_data = nullptr, RenderingMethod::RenderInfo *r_render_info = nullptr) override;
virtual void render_material(const Transform3D &p_cam_transform, const Projection &p_cam_projection, bool p_cam_orthogonal, const PagedArray<RenderGeometryInstance *> &p_instances, RID p_framebuffer, const Rect2i &p_region) override;
diff --git a/servers/rendering/renderer_rd/storage_rd/light_storage.h b/servers/rendering/renderer_rd/storage_rd/light_storage.h
index 45226ec47c..b3d27cc6ed 100644
--- a/servers/rendering/renderer_rd/storage_rd/light_storage.h
+++ b/servers/rendering/renderer_rd/storage_rd/light_storage.h
@@ -43,7 +43,7 @@
#include "servers/rendering/storage/light_storage.h"
#include "servers/rendering/storage/utilities.h"
-struct RenderDataRD;
+class RenderDataRD;
namespace RendererRD {
diff --git a/servers/rendering/renderer_rd/storage_rd/render_data_rd.cpp b/servers/rendering/renderer_rd/storage_rd/render_data_rd.cpp
new file mode 100644
index 0000000000..ac4fbba75b
--- /dev/null
+++ b/servers/rendering/renderer_rd/storage_rd/render_data_rd.cpp
@@ -0,0 +1,50 @@
+/**************************************************************************/
+/* render_data_rd.cpp */
+/**************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* https://godotengine.org */
+/**************************************************************************/
+/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */
+/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */
+/* */
+/* Permission is hereby granted, free of charge, to any person obtaining */
+/* a copy of this software and associated documentation files (the */
+/* "Software"), to deal in the Software without restriction, including */
+/* without limitation the rights to use, copy, modify, merge, publish, */
+/* distribute, sublicense, and/or sell copies of the Software, and to */
+/* permit persons to whom the Software is furnished to do so, subject to */
+/* the following conditions: */
+/* */
+/* The above copyright notice and this permission notice shall be */
+/* included in all copies or substantial portions of the Software. */
+/* */
+/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
+/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
+/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. */
+/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
+/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
+/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
+/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
+/**************************************************************************/
+
+#include "render_data_rd.h"
+
+void RenderDataRD::_bind_methods() {
+}
+
+Ref<RenderSceneBuffers> RenderDataRD::get_render_scene_buffers() const {
+ return render_buffers;
+}
+
+RenderSceneData *RenderDataRD::get_render_scene_data() const {
+ return scene_data;
+}
+
+RID RenderDataRD::get_environment() const {
+ return environment;
+}
+
+RID RenderDataRD::get_camera_attributes() const {
+ return camera_attributes;
+}
diff --git a/servers/rendering/renderer_rd/storage_rd/render_data_rd.h b/servers/rendering/renderer_rd/storage_rd/render_data_rd.h
new file mode 100644
index 0000000000..2f61899a18
--- /dev/null
+++ b/servers/rendering/renderer_rd/storage_rd/render_data_rd.h
@@ -0,0 +1,97 @@
+/**************************************************************************/
+/* render_data_rd.h */
+/**************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* https://godotengine.org */
+/**************************************************************************/
+/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */
+/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */
+/* */
+/* Permission is hereby granted, free of charge, to any person obtaining */
+/* a copy of this software and associated documentation files (the */
+/* "Software"), to deal in the Software without restriction, including */
+/* without limitation the rights to use, copy, modify, merge, publish, */
+/* distribute, sublicense, and/or sell copies of the Software, and to */
+/* permit persons to whom the Software is furnished to do so, subject to */
+/* the following conditions: */
+/* */
+/* The above copyright notice and this permission notice shall be */
+/* included in all copies or substantial portions of the Software. */
+/* */
+/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
+/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
+/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. */
+/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
+/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
+/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
+/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
+/**************************************************************************/
+
+#ifndef RENDER_DATA_RD_H
+#define RENDER_DATA_RD_H
+
+#include "servers/rendering/renderer_rd/storage_rd/render_scene_buffers_rd.h"
+#include "servers/rendering/renderer_rd/storage_rd/render_scene_data_rd.h"
+#include "servers/rendering/storage/render_data.h"
+
+class RenderDataRD : public RenderData {
+ GDCLASS(RenderDataRD, RenderData);
+
+protected:
+ static void _bind_methods();
+
+public:
+ // Access methods to expose data externally
+ virtual Ref<RenderSceneBuffers> get_render_scene_buffers() const override;
+ virtual RenderSceneData *get_render_scene_data() const override;
+
+ virtual RID get_environment() const override;
+ virtual RID get_camera_attributes() const override;
+
+ // Members are publicly accessible within the render engine.
+ Ref<RenderSceneBuffersRD> render_buffers;
+ RenderSceneDataRD *scene_data = nullptr;
+
+ const PagedArray<RenderGeometryInstance *> *instances = nullptr;
+ const PagedArray<RID> *lights = nullptr;
+ const PagedArray<RID> *reflection_probes = nullptr;
+ const PagedArray<RID> *voxel_gi_instances = nullptr;
+ const PagedArray<RID> *decals = nullptr;
+ const PagedArray<RID> *lightmaps = nullptr;
+ const PagedArray<RID> *fog_volumes = nullptr;
+ RID environment;
+ RID camera_attributes;
+ RID compositor;
+ RID shadow_atlas;
+ RID occluder_debug_tex;
+ RID reflection_atlas;
+ RID reflection_probe;
+ int reflection_probe_pass = 0;
+
+ RID cluster_buffer;
+ uint32_t cluster_size = 0;
+ uint32_t cluster_max_elements = 0;
+
+ uint32_t directional_light_count = 0;
+ bool directional_light_soft_shadows = false;
+
+ RenderingMethod::RenderInfo *render_info = nullptr;
+
+ /* Shadow data */
+ const RendererSceneRender::RenderShadowData *render_shadows = nullptr;
+ int render_shadow_count = 0;
+
+ LocalVector<int> cube_shadows;
+ LocalVector<int> shadows;
+ LocalVector<int> directional_shadows;
+
+ /* GI info */
+ const RendererSceneRender::RenderSDFGIData *render_sdfgi_regions = nullptr;
+ int render_sdfgi_region_count = 0;
+ const RendererSceneRender::RenderSDFGIUpdateData *sdfgi_update_data = nullptr;
+
+ uint32_t voxel_gi_count = 0;
+};
+
+#endif // RENDER_DATA_RD_H
diff --git a/servers/rendering/renderer_rd/storage_rd/render_scene_buffers_rd.compat.inc b/servers/rendering/renderer_rd/storage_rd/render_scene_buffers_rd.compat.inc
new file mode 100644
index 0000000000..75b9ee2da7
--- /dev/null
+++ b/servers/rendering/renderer_rd/storage_rd/render_scene_buffers_rd.compat.inc
@@ -0,0 +1,66 @@
+/**************************************************************************/
+/* render_scene_buffers_rd.compat.inc */
+/**************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* https://godotengine.org */
+/**************************************************************************/
+/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */
+/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */
+/* */
+/* Permission is hereby granted, free of charge, to any person obtaining */
+/* a copy of this software and associated documentation files (the */
+/* "Software"), to deal in the Software without restriction, including */
+/* without limitation the rights to use, copy, modify, merge, publish, */
+/* distribute, sublicense, and/or sell copies of the Software, and to */
+/* permit persons to whom the Software is furnished to do so, subject to */
+/* the following conditions: */
+/* */
+/* The above copyright notice and this permission notice shall be */
+/* included in all copies or substantial portions of the Software. */
+/* */
+/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
+/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
+/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. */
+/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
+/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
+/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
+/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
+/**************************************************************************/
+
+#ifndef DISABLE_DEPRECATED
+
+RID RenderSceneBuffersRD::_get_color_texture_compat_80214() {
+ return _get_color_texture(msaa_3d != RS::VIEWPORT_MSAA_DISABLED);
+}
+
+RID RenderSceneBuffersRD::_get_color_layer_compat_80214(const uint32_t p_layer) {
+ return _get_color_layer(p_layer, msaa_3d != RS::VIEWPORT_MSAA_DISABLED);
+}
+
+RID RenderSceneBuffersRD::_get_depth_texture_compat_80214() {
+ return _get_depth_texture(msaa_3d != RS::VIEWPORT_MSAA_DISABLED);
+}
+
+RID RenderSceneBuffersRD::_get_depth_layer_compat_80214(const uint32_t p_layer) {
+ return _get_depth_layer(p_layer, msaa_3d != RS::VIEWPORT_MSAA_DISABLED);
+}
+
+RID RenderSceneBuffersRD::_get_velocity_texture_compat_80214() {
+ return _get_velocity_texture(msaa_3d != RS::VIEWPORT_MSAA_DISABLED);
+}
+
+RID RenderSceneBuffersRD::_get_velocity_layer_compat_80214(const uint32_t p_layer) {
+ return _get_velocity_layer(p_layer, msaa_3d != RS::VIEWPORT_MSAA_DISABLED);
+}
+
+void RenderSceneBuffersRD::_bind_compatibility_methods() {
+ ClassDB::bind_compatibility_method(D_METHOD("get_color_texture"), &RenderSceneBuffersRD::_get_color_texture_compat_80214);
+ ClassDB::bind_compatibility_method(D_METHOD("get_color_layer", "layer"), &RenderSceneBuffersRD::_get_color_layer_compat_80214);
+ ClassDB::bind_compatibility_method(D_METHOD("get_depth_texture"), &RenderSceneBuffersRD::_get_depth_texture_compat_80214);
+ ClassDB::bind_compatibility_method(D_METHOD("get_depth_layer", "layer"), &RenderSceneBuffersRD::_get_depth_layer_compat_80214);
+ ClassDB::bind_compatibility_method(D_METHOD("get_velocity_texture"), &RenderSceneBuffersRD::_get_velocity_texture_compat_80214);
+ ClassDB::bind_compatibility_method(D_METHOD("get_velocity_layer", "layer"), &RenderSceneBuffersRD::_get_velocity_layer_compat_80214);
+}
+
+#endif // DISABLE_DEPRECATED
diff --git a/servers/rendering/renderer_rd/storage_rd/render_scene_buffers_rd.cpp b/servers/rendering/renderer_rd/storage_rd/render_scene_buffers_rd.cpp
index c338dd0377..8dc74820e2 100644
--- a/servers/rendering/renderer_rd/storage_rd/render_scene_buffers_rd.cpp
+++ b/servers/rendering/renderer_rd/storage_rd/render_scene_buffers_rd.cpp
@@ -29,6 +29,8 @@
/**************************************************************************/
#include "render_scene_buffers_rd.h"
+#include "render_scene_buffers_rd.compat.inc"
+
#include "core/config/project_settings.h"
#include "servers/rendering/renderer_rd/renderer_scene_render_rd.h"
#include "servers/rendering/renderer_rd/storage_rd/texture_storage.h"
@@ -57,17 +59,18 @@ void RenderSceneBuffersRD::_bind_methods() {
ClassDB::bind_method(D_METHOD("clear_context", "context"), &RenderSceneBuffersRD::clear_context);
// Access to some core buffers so users don't need to know their names.
- ClassDB::bind_method(D_METHOD("get_color_texture"), &RenderSceneBuffersRD::_get_color_texture);
- ClassDB::bind_method(D_METHOD("get_color_layer", "layer"), &RenderSceneBuffersRD::_get_color_layer);
- ClassDB::bind_method(D_METHOD("get_depth_texture"), &RenderSceneBuffersRD::_get_depth_texture);
- ClassDB::bind_method(D_METHOD("get_depth_layer", "layer"), &RenderSceneBuffersRD::_get_depth_layer);
- ClassDB::bind_method(D_METHOD("get_velocity_texture"), &RenderSceneBuffersRD::_get_velocity_texture);
- ClassDB::bind_method(D_METHOD("get_velocity_layer", "layer"), &RenderSceneBuffersRD::_get_velocity_layer);
+ ClassDB::bind_method(D_METHOD("get_color_texture", "msaa"), &RenderSceneBuffersRD::_get_color_texture, DEFVAL(false));
+ ClassDB::bind_method(D_METHOD("get_color_layer", "layer", "msaa"), &RenderSceneBuffersRD::_get_color_layer, DEFVAL(false));
+ ClassDB::bind_method(D_METHOD("get_depth_texture", "msaa"), &RenderSceneBuffersRD::_get_depth_texture, DEFVAL(false));
+ ClassDB::bind_method(D_METHOD("get_depth_layer", "layer", "msaa"), &RenderSceneBuffersRD::_get_depth_layer, DEFVAL(false));
+ ClassDB::bind_method(D_METHOD("get_velocity_texture", "msaa"), &RenderSceneBuffersRD::_get_velocity_texture, DEFVAL(false));
+ ClassDB::bind_method(D_METHOD("get_velocity_layer", "layer", "msaa"), &RenderSceneBuffersRD::_get_velocity_layer, DEFVAL(false));
// Expose a few properties we're likely to use externally
ClassDB::bind_method(D_METHOD("get_render_target"), &RenderSceneBuffersRD::get_render_target);
ClassDB::bind_method(D_METHOD("get_view_count"), &RenderSceneBuffersRD::get_view_count);
ClassDB::bind_method(D_METHOD("get_internal_size"), &RenderSceneBuffersRD::get_internal_size);
+ ClassDB::bind_method(D_METHOD("get_msaa_3d"), &RenderSceneBuffersRD::get_msaa_3d);
ClassDB::bind_method(D_METHOD("get_use_taa"), &RenderSceneBuffersRD::get_use_taa);
}
diff --git a/servers/rendering/renderer_rd/storage_rd/render_scene_buffers_rd.h b/servers/rendering/renderer_rd/storage_rd/render_scene_buffers_rd.h
index 5b8a74de83..c885ad52d1 100644
--- a/servers/rendering/renderer_rd/storage_rd/render_scene_buffers_rd.h
+++ b/servers/rendering/renderer_rd/storage_rd/render_scene_buffers_rd.h
@@ -305,20 +305,25 @@ public:
return samplers;
}
+private:
////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Our classDB doesn't support calling our normal exposed functions
-private:
RID _create_texture_from_format(const StringName &p_context, const StringName &p_texture_name, const Ref<RDTextureFormat> &p_texture_format, const Ref<RDTextureView> &p_view = Ref<RDTextureView>(), bool p_unique = true);
RID _create_texture_view(const StringName &p_context, const StringName &p_texture_name, const StringName &p_view_name, const Ref<RDTextureView> p_view = Ref<RDTextureView>());
Ref<RDTextureFormat> _get_texture_format(const StringName &p_context, const StringName &p_texture_name) const;
RID _get_texture_slice_view(const StringName &p_context, const StringName &p_texture_name, const uint32_t p_layer, const uint32_t p_mipmap, const uint32_t p_layers = 1, const uint32_t p_mipmaps = 1, const Ref<RDTextureView> p_view = Ref<RDTextureView>());
- // For color and depth as exposed to extensions, we return the buffer that we're rendering into.
- // Resolving happens after effects etc. are run.
- RID _get_color_texture() {
- if (msaa_3d != RS::VIEWPORT_MSAA_DISABLED && has_texture(RB_SCOPE_BUFFERS, RB_TEX_COLOR_MSAA)) {
- return get_texture(RB_SCOPE_BUFFERS, RB_TEX_COLOR_MSAA);
+ // For color and depth as exposed to extensions:
+ // - we need separately named functions to access the layer,
+ // - we don't output an error for missing buffers but just return an empty RID.
+ RID _get_color_texture(bool p_msaa = false) {
+ if (p_msaa) {
+ if (has_texture(RB_SCOPE_BUFFERS, RB_TEX_COLOR_MSAA)) {
+ return get_texture(RB_SCOPE_BUFFERS, RB_TEX_COLOR_MSAA);
+ } else {
+ return RID();
+ }
} else if (has_internal_texture()) {
return get_internal_texture();
} else {
@@ -326,9 +331,13 @@ private:
}
}
- RID _get_color_layer(const uint32_t p_layer) {
- if (msaa_3d != RS::VIEWPORT_MSAA_DISABLED && has_texture(RB_SCOPE_BUFFERS, RB_TEX_COLOR_MSAA)) {
- return get_texture_slice(RB_SCOPE_BUFFERS, RB_TEX_COLOR_MSAA, p_layer, 0);
+ RID _get_color_layer(const uint32_t p_layer, bool p_msaa = false) {
+ if (p_msaa) {
+ if (has_texture(RB_SCOPE_BUFFERS, RB_TEX_COLOR_MSAA)) {
+ return get_texture_slice(RB_SCOPE_BUFFERS, RB_TEX_COLOR_MSAA, p_layer, 0);
+ } else {
+ return RID();
+ }
} else if (has_internal_texture()) {
return get_internal_texture(p_layer);
} else {
@@ -336,9 +345,13 @@ private:
}
}
- RID _get_depth_texture() {
- if (msaa_3d != RS::VIEWPORT_MSAA_DISABLED && has_texture(RB_SCOPE_BUFFERS, RB_TEX_DEPTH_MSAA)) {
- return get_texture(RB_SCOPE_BUFFERS, RB_TEX_DEPTH_MSAA);
+ RID _get_depth_texture(bool p_msaa = false) {
+ if (p_msaa) {
+ if (has_texture(RB_SCOPE_BUFFERS, RB_TEX_DEPTH_MSAA)) {
+ return get_texture(RB_SCOPE_BUFFERS, RB_TEX_DEPTH_MSAA);
+ } else {
+ return RID();
+ }
} else if (has_depth_texture()) {
return get_depth_texture();
} else {
@@ -346,9 +359,13 @@ private:
}
}
- RID _get_depth_layer(const uint32_t p_layer) {
- if (msaa_3d != RS::VIEWPORT_MSAA_DISABLED && has_texture(RB_SCOPE_BUFFERS, RB_TEX_DEPTH_MSAA)) {
- return get_texture_slice(RB_SCOPE_BUFFERS, RB_TEX_DEPTH_MSAA, p_layer, 0);
+ RID _get_depth_layer(const uint32_t p_layer, bool p_msaa = false) {
+ if (p_msaa) {
+ if (has_texture(RB_SCOPE_BUFFERS, RB_TEX_DEPTH_MSAA)) {
+ return get_texture_slice(RB_SCOPE_BUFFERS, RB_TEX_DEPTH_MSAA, p_layer, 0);
+ } else {
+ return RID();
+ }
} else if (has_depth_texture()) {
return get_depth_texture(p_layer);
} else {
@@ -356,26 +373,35 @@ private:
}
}
- RID _get_velocity_texture() {
- if (msaa_3d != RS::VIEWPORT_MSAA_DISABLED && has_velocity_buffer(true)) {
- return get_velocity_buffer(true);
- } else if (has_velocity_buffer(false)) {
- return get_velocity_buffer(false);
+ RID _get_velocity_texture(bool p_msaa = false) {
+ if (has_velocity_buffer(p_msaa)) {
+ return get_velocity_buffer(p_msaa);
} else {
return RID();
}
}
- RID _get_velocity_layer(const uint32_t p_layer) {
- if (msaa_3d != RS::VIEWPORT_MSAA_DISABLED && has_velocity_buffer(true)) {
- return get_velocity_buffer(true, p_layer);
- } else if (has_velocity_buffer(false)) {
- return get_velocity_buffer(false, p_layer);
+ RID _get_velocity_layer(const uint32_t p_layer, bool p_msaa = false) {
+ if (has_velocity_buffer(p_msaa)) {
+ return get_velocity_buffer(p_msaa, p_layer);
} else {
return RID();
}
}
+#ifndef DISABLE_DEPRECATED
+
+ RID _get_color_texture_compat_80214();
+ RID _get_color_layer_compat_80214(const uint32_t p_layer);
+ RID _get_depth_texture_compat_80214();
+ RID _get_depth_layer_compat_80214(const uint32_t p_layer);
+ RID _get_velocity_texture_compat_80214();
+ RID _get_velocity_layer_compat_80214(const uint32_t p_layer);
+
+ static void _bind_compatibility_methods();
+
+#endif // DISABLE_DEPRECATED
+
////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Everything after this needs to be re-evaluated, this is all old implementation
public:
diff --git a/servers/rendering/renderer_rd/storage_rd/render_scene_data_rd.cpp b/servers/rendering/renderer_rd/storage_rd/render_scene_data_rd.cpp
index 86f0f5acf2..dc1e64ddcc 100644
--- a/servers/rendering/renderer_rd/storage_rd/render_scene_data_rd.cpp
+++ b/servers/rendering/renderer_rd/storage_rd/render_scene_data_rd.cpp
@@ -34,6 +34,33 @@
#include "servers/rendering/renderer_rd/storage_rd/texture_storage.h"
#include "servers/rendering/rendering_server_default.h"
+void RenderSceneDataRD::_bind_methods() {
+}
+
+Transform3D RenderSceneDataRD::get_cam_transform() const {
+ return cam_transform;
+}
+
+Projection RenderSceneDataRD::get_cam_projection() const {
+ return cam_projection;
+}
+
+uint32_t RenderSceneDataRD::get_view_count() const {
+ return view_count;
+}
+
+Vector3 RenderSceneDataRD::get_view_eye_offset(uint32_t p_view) const {
+ ERR_FAIL_UNSIGNED_INDEX_V(p_view, view_count, Vector3());
+
+ return view_eye_offset[p_view];
+}
+
+Projection RenderSceneDataRD::get_view_projection(uint32_t p_view) const {
+ ERR_FAIL_UNSIGNED_INDEX_V(p_view, view_count, Projection());
+
+ return view_projection[p_view];
+}
+
RID RenderSceneDataRD::create_uniform_buffer() {
return RD::get_singleton()->uniform_buffer_create(sizeof(UBODATA));
}
@@ -262,6 +289,6 @@ void RenderSceneDataRD::update_ubo(RID p_uniform_buffer, RS::ViewportDebugDraw p
RD::get_singleton()->buffer_update(uniform_buffer, 0, sizeof(UBODATA), &ubo);
}
-RID RenderSceneDataRD::get_uniform_buffer() {
+RID RenderSceneDataRD::get_uniform_buffer() const {
return uniform_buffer;
}
diff --git a/servers/rendering/renderer_rd/storage_rd/render_scene_data_rd.h b/servers/rendering/renderer_rd/storage_rd/render_scene_data_rd.h
index 9453966a86..f6785942ed 100644
--- a/servers/rendering/renderer_rd/storage_rd/render_scene_data_rd.h
+++ b/servers/rendering/renderer_rd/storage_rd/render_scene_data_rd.h
@@ -34,11 +34,14 @@
#include "render_scene_buffers_rd.h"
#include "servers/rendering/renderer_scene_render.h"
#include "servers/rendering/rendering_device.h"
+#include "servers/rendering/storage/render_scene_data.h"
// This is a container for data related to rendering a single frame of a viewport where we load this data into a UBO
// that can be used by the main scene shader but also by various effects.
-class RenderSceneDataRD {
+class RenderSceneDataRD : public RenderSceneData {
+ GDCLASS(RenderSceneDataRD, RenderSceneData);
+
public:
bool calculate_motion_vectors = false;
@@ -79,11 +82,20 @@ public:
float time;
float time_step;
+ virtual Transform3D get_cam_transform() const override;
+ virtual Projection get_cam_projection() const override;
+
+ virtual uint32_t get_view_count() const override;
+ virtual Vector3 get_view_eye_offset(uint32_t p_view) const override;
+ virtual Projection get_view_projection(uint32_t p_view) const override;
+
RID create_uniform_buffer();
void update_ubo(RID p_uniform_buffer, RS::ViewportDebugDraw p_debug_mode, RID p_env, RID p_reflection_probe_instance, RID p_camera_attributes, bool p_flip_y, bool p_pancake_shadows, const Size2i &p_screen_size, const Color &p_default_bg_color, float p_luminance_multiplier, bool p_opaque_render_buffers, bool p_apply_alpha_multiplier);
- RID get_uniform_buffer();
+ virtual RID get_uniform_buffer() const override;
private:
+ static void _bind_methods();
+
RID uniform_buffer; // loaded into this uniform buffer (supplied externally)
// This struct is loaded into Set 1 - Binding 0, populated at start of rendering a frame, must match with shader code
diff --git a/servers/rendering/renderer_rd/uniform_set_cache_rd.cpp b/servers/rendering/renderer_rd/uniform_set_cache_rd.cpp
index 1f67d5e258..bcd8e78a71 100644
--- a/servers/rendering/renderer_rd/uniform_set_cache_rd.cpp
+++ b/servers/rendering/renderer_rd/uniform_set_cache_rd.cpp
@@ -32,6 +32,23 @@
UniformSetCacheRD *UniformSetCacheRD::singleton = nullptr;
+void UniformSetCacheRD::_bind_methods() {
+ ClassDB::bind_static_method("UniformSetCacheRD", D_METHOD("get_cache", "shader", "set", "uniforms"), &UniformSetCacheRD::get_cache_array);
+}
+
+RID UniformSetCacheRD::get_cache_array(RID p_shader, uint32_t p_set, const TypedArray<RDUniform> &p_uniforms) {
+ Vector<RD::Uniform> uniforms;
+
+ for (int i = 0; i < p_uniforms.size(); i++) {
+ Ref<RDUniform> uniform = p_uniforms[i];
+ if (uniform.is_valid()) {
+ uniforms.push_back(uniform->base);
+ }
+ }
+
+ return UniformSetCacheRD::get_singleton()->get_cache_vec(p_shader, p_set, uniforms);
+}
+
void UniformSetCacheRD::_invalidate(Cache *p_cache) {
if (p_cache->prev) {
p_cache->prev->next = p_cache->next;
diff --git a/servers/rendering/renderer_rd/uniform_set_cache_rd.h b/servers/rendering/renderer_rd/uniform_set_cache_rd.h
index 50243e715d..c3b95f5f93 100644
--- a/servers/rendering/renderer_rd/uniform_set_cache_rd.h
+++ b/servers/rendering/renderer_rd/uniform_set_cache_rd.h
@@ -34,6 +34,7 @@
#include "core/templates/local_vector.h"
#include "core/templates/paged_allocator.h"
#include "servers/rendering/rendering_device.h"
+#include "servers/rendering/rendering_device_binds.h"
class UniformSetCacheRD : public Object {
GDCLASS(UniformSetCacheRD, Object)
@@ -151,6 +152,9 @@ class UniformSetCacheRD : public Object {
return rid;
}
+private:
+ static void _bind_methods();
+
public:
template <typename... Args>
RID get_cache(RID p_shader, uint32_t p_set, Args... args) {
@@ -214,6 +218,8 @@ public:
return _allocate_from_uniforms(p_shader, p_set, h, table_idx, p_uniforms);
}
+ static RID get_cache_array(RID p_shader, uint32_t p_set, const TypedArray<RDUniform> &p_uniforms);
+
static UniformSetCacheRD *get_singleton() { return singleton; }
UniformSetCacheRD();
diff --git a/servers/rendering/renderer_scene_cull.cpp b/servers/rendering/renderer_scene_cull.cpp
index b8f14bb611..59d70958f1 100644
--- a/servers/rendering/renderer_scene_cull.cpp
+++ b/servers/rendering/renderer_scene_cull.cpp
@@ -115,6 +115,12 @@ void RendererSceneCull::camera_set_camera_attributes(RID p_camera, RID p_attribu
camera->attributes = p_attributes;
}
+void RendererSceneCull::camera_set_compositor(RID p_camera, RID p_compositor) {
+ Camera *camera = camera_owner.get_or_null(p_camera);
+ ERR_FAIL_NULL(camera);
+ camera->compositor = p_compositor;
+}
+
void RendererSceneCull::camera_set_use_vertical_aspect(RID p_camera, bool p_enable) {
Camera *camera = camera_owner.get_or_null(p_camera);
ERR_FAIL_NULL(camera);
@@ -401,6 +407,12 @@ void RendererSceneCull::scenario_set_camera_attributes(RID p_scenario, RID p_cam
scenario->camera_attributes = p_camera_attributes;
}
+void RendererSceneCull::scenario_set_compositor(RID p_scenario, RID p_compositor) {
+ Scenario *scenario = scenario_owner.get_or_null(p_scenario);
+ ERR_FAIL_NULL(scenario);
+ scenario->compositor = p_compositor;
+}
+
void RendererSceneCull::scenario_set_fallback_environment(RID p_scenario, RID p_environment) {
Scenario *scenario = scenario_owner.get_or_null(p_scenario);
ERR_FAIL_NULL(scenario);
@@ -2623,12 +2635,13 @@ void RendererSceneCull::render_camera(const Ref<RenderSceneBuffers> &p_render_bu
}
RID environment = _render_get_environment(p_camera, p_scenario);
+ RID compositor = _render_get_compositor(p_camera, p_scenario);
RENDER_TIMESTAMP("Update Occlusion Buffer")
// For now just cull on the first camera
RendererSceneOcclusionCull::get_singleton()->buffer_update(p_viewport, camera_data.main_transform, camera_data.main_projection, camera_data.is_orthogonal);
- _render_scene(&camera_data, p_render_buffers, environment, camera->attributes, camera->visible_layers, p_scenario, p_viewport, p_shadow_atlas, RID(), -1, p_screen_mesh_lod_threshold, true, r_render_info);
+ _render_scene(&camera_data, p_render_buffers, environment, camera->attributes, compositor, camera->visible_layers, p_scenario, p_viewport, p_shadow_atlas, RID(), -1, p_screen_mesh_lod_threshold, true, r_render_info);
#endif
}
@@ -3008,7 +3021,7 @@ void RendererSceneCull::_scene_cull(CullData &cull_data, InstanceCullResult &cul
}
}
-void RendererSceneCull::_render_scene(const RendererSceneRender::CameraData *p_camera_data, const Ref<RenderSceneBuffers> &p_render_buffers, RID p_environment, RID p_force_camera_attributes, uint32_t p_visible_layers, RID p_scenario, RID p_viewport, RID p_shadow_atlas, RID p_reflection_probe, int p_reflection_probe_pass, float p_screen_mesh_lod_threshold, bool p_using_shadows, RenderingMethod::RenderInfo *r_render_info) {
+void RendererSceneCull::_render_scene(const RendererSceneRender::CameraData *p_camera_data, const Ref<RenderSceneBuffers> &p_render_buffers, RID p_environment, RID p_force_camera_attributes, RID p_compositor, uint32_t p_visible_layers, RID p_scenario, RID p_viewport, RID p_shadow_atlas, RID p_reflection_probe, int p_reflection_probe_pass, float p_screen_mesh_lod_threshold, bool p_using_shadows, RenderingMethod::RenderInfo *r_render_info) {
Instance *render_reflection_probe = instance_owner.get_or_null(p_reflection_probe); //if null, not rendering to it
// Prepare the light - camera volume culling system.
@@ -3378,6 +3391,7 @@ void RendererSceneCull::_render_scene(const RendererSceneRender::CameraData *p_c
} else {
camera_attributes = scenario->camera_attributes;
}
+
/* PROCESS GEOMETRY AND DRAW SCENE */
RID occluders_tex;
@@ -3388,7 +3402,7 @@ void RendererSceneCull::_render_scene(const RendererSceneRender::CameraData *p_c
}
RENDER_TIMESTAMP("Render 3D Scene");
- scene_render->render_scene(p_render_buffers, p_camera_data, prev_camera_data, scene_cull_result.geometry_instances, scene_cull_result.light_instances, scene_cull_result.reflections, scene_cull_result.voxel_gi_instances, scene_cull_result.decals, scene_cull_result.lightmaps, scene_cull_result.fog_volumes, p_environment, camera_attributes, p_shadow_atlas, occluders_tex, p_reflection_probe.is_valid() ? RID() : scenario->reflection_atlas, p_reflection_probe, p_reflection_probe_pass, p_screen_mesh_lod_threshold, render_shadow_data, max_shadows_used, render_sdfgi_data, cull.sdfgi.region_count, &sdfgi_update_data, r_render_info);
+ scene_render->render_scene(p_render_buffers, p_camera_data, prev_camera_data, scene_cull_result.geometry_instances, scene_cull_result.light_instances, scene_cull_result.reflections, scene_cull_result.voxel_gi_instances, scene_cull_result.decals, scene_cull_result.lightmaps, scene_cull_result.fog_volumes, p_environment, camera_attributes, p_compositor, p_shadow_atlas, occluders_tex, p_reflection_probe.is_valid() ? RID() : scenario->reflection_atlas, p_reflection_probe, p_reflection_probe_pass, p_screen_mesh_lod_threshold, render_shadow_data, max_shadows_used, render_sdfgi_data, cull.sdfgi.region_count, &sdfgi_update_data, r_render_info);
if (p_viewport.is_valid()) {
RSG::viewport->viewport_set_prev_camera_data(p_viewport, p_camera_data);
@@ -3425,6 +3439,20 @@ RID RendererSceneCull::_render_get_environment(RID p_camera, RID p_scenario) {
return RID();
}
+RID RendererSceneCull::_render_get_compositor(RID p_camera, RID p_scenario) {
+ Camera *camera = camera_owner.get_or_null(p_camera);
+ if (camera && scene_render->is_compositor(camera->compositor)) {
+ return camera->compositor;
+ }
+
+ Scenario *scenario = scenario_owner.get_or_null(p_scenario);
+ if (scenario && scene_render->is_compositor(scenario->compositor)) {
+ return scenario->compositor;
+ }
+
+ return RID();
+}
+
void RendererSceneCull::render_empty_scene(const Ref<RenderSceneBuffers> &p_render_buffers, RID p_scenario, RID p_shadow_atlas) {
#ifndef _3D_DISABLED
Scenario *scenario = scenario_owner.get_or_null(p_scenario);
@@ -3435,12 +3463,13 @@ void RendererSceneCull::render_empty_scene(const Ref<RenderSceneBuffers> &p_rend
} else {
environment = scenario->fallback_environment;
}
+ RID compositor = scenario->compositor;
RENDER_TIMESTAMP("Render Empty 3D Scene");
RendererSceneRender::CameraData camera_data;
camera_data.set_camera(Transform3D(), Projection(), true, false);
- scene_render->render_scene(p_render_buffers, &camera_data, &camera_data, PagedArray<RenderGeometryInstance *>(), PagedArray<RID>(), PagedArray<RID>(), PagedArray<RID>(), PagedArray<RID>(), PagedArray<RID>(), PagedArray<RID>(), environment, RID(), p_shadow_atlas, RID(), scenario->reflection_atlas, RID(), 0, 0, nullptr, 0, nullptr, 0, nullptr);
+ scene_render->render_scene(p_render_buffers, &camera_data, &camera_data, PagedArray<RenderGeometryInstance *>(), PagedArray<RID>(), PagedArray<RID>(), PagedArray<RID>(), PagedArray<RID>(), PagedArray<RID>(), PagedArray<RID>(), environment, RID(), compositor, p_shadow_atlas, RID(), scenario->reflection_atlas, RID(), 0, 0, nullptr, 0, nullptr, 0, nullptr);
#endif
}
@@ -3514,7 +3543,7 @@ bool RendererSceneCull::_render_reflection_probe_step(Instance *p_instance, int
camera_data.set_camera(xform, cm, false, false);
Ref<RenderSceneBuffers> render_buffers = RSG::light_storage->reflection_probe_atlas_get_render_buffers(scenario->reflection_atlas);
- _render_scene(&camera_data, render_buffers, environment, RID(), RSG::light_storage->reflection_probe_get_cull_mask(p_instance->base), p_instance->scenario->self, RID(), shadow_atlas, reflection_probe->instance, p_step, mesh_lod_threshold, use_shadows);
+ _render_scene(&camera_data, render_buffers, environment, RID(), RID(), RSG::light_storage->reflection_probe_get_cull_mask(p_instance->base), p_instance->scenario->self, RID(), shadow_atlas, reflection_probe->instance, p_step, mesh_lod_threshold, use_shadows);
} else {
//do roughness postprocess step until it believes it's done
diff --git a/servers/rendering/renderer_scene_cull.h b/servers/rendering/renderer_scene_cull.h
index f48902a4ef..86090aa416 100644
--- a/servers/rendering/renderer_scene_cull.h
+++ b/servers/rendering/renderer_scene_cull.h
@@ -80,6 +80,7 @@ public:
bool vaspect;
RID env;
RID attributes;
+ RID compositor;
Transform3D transform;
@@ -107,6 +108,7 @@ public:
virtual void camera_set_cull_mask(RID p_camera, uint32_t p_layers);
virtual void camera_set_environment(RID p_camera, RID p_env);
virtual void camera_set_camera_attributes(RID p_camera, RID p_attributes);
+ virtual void camera_set_compositor(RID p_camera, RID p_compositor);
virtual void camera_set_use_vertical_aspect(RID p_camera, bool p_enable);
virtual bool is_camera(RID p_camera) const;
@@ -324,6 +326,7 @@ public:
RID environment;
RID fallback_environment;
RID camera_attributes;
+ RID compositor;
RID reflection_probe_shadow_atlas;
RID reflection_atlas;
uint64_t used_viewport_visibility_bits;
@@ -359,6 +362,7 @@ public:
virtual void scenario_set_environment(RID p_scenario, RID p_environment);
virtual void scenario_set_camera_attributes(RID p_scenario, RID p_attributes);
virtual void scenario_set_fallback_environment(RID p_scenario, RID p_environment);
+ virtual void scenario_set_compositor(RID p_scenario, RID p_compositor);
virtual void scenario_set_reflection_atlas_size(RID p_scenario, int p_reflection_size, int p_reflection_count);
virtual bool is_scenario(RID p_scenario) const;
virtual RID scenario_get_environment(RID p_scenario);
@@ -1065,6 +1069,7 @@ public:
_FORCE_INLINE_ bool _light_instance_update_shadow(Instance *p_instance, const Transform3D p_cam_transform, const Projection &p_cam_projection, bool p_cam_orthogonal, bool p_cam_vaspect, RID p_shadow_atlas, Scenario *p_scenario, float p_scren_mesh_lod_threshold, uint32_t p_visible_layers = 0xFFFFFF);
RID _render_get_environment(RID p_camera, RID p_scenario);
+ RID _render_get_compositor(RID p_camera, RID p_scenario);
struct Cull {
struct Shadow {
@@ -1134,7 +1139,7 @@ public:
_FORCE_INLINE_ bool _visibility_parent_check(const CullData &p_cull_data, const InstanceData &p_instance_data);
bool _render_reflection_probe_step(Instance *p_instance, int p_step);
- void _render_scene(const RendererSceneRender::CameraData *p_camera_data, const Ref<RenderSceneBuffers> &p_render_buffers, RID p_environment, RID p_force_camera_attributes, uint32_t p_visible_layers, RID p_scenario, RID p_viewport, RID p_shadow_atlas, RID p_reflection_probe, int p_reflection_probe_pass, float p_screen_mesh_lod_threshold, bool p_using_shadows = true, RenderInfo *r_render_info = nullptr);
+ void _render_scene(const RendererSceneRender::CameraData *p_camera_data, const Ref<RenderSceneBuffers> &p_render_buffers, RID p_environment, RID p_force_camera_attributes, RID p_compositor, uint32_t p_visible_layers, RID p_scenario, RID p_viewport, RID p_shadow_atlas, RID p_reflection_probe, int p_reflection_probe_pass, float p_screen_mesh_lod_threshold, bool p_using_shadows = true, RenderInfo *r_render_info = nullptr);
void render_empty_scene(const Ref<RenderSceneBuffers> &p_render_buffers, RID p_scenario, RID p_shadow_atlas);
void render_camera(const Ref<RenderSceneBuffers> &p_render_buffers, RID p_camera, RID p_scenario, RID p_viewport, Size2 p_viewport_size, uint32_t p_jitter_phase_count, float p_screen_mesh_lod_threshold, RID p_shadow_atlas, Ref<XRInterface> &p_xr_interface, RenderingMethod::RenderInfo *r_render_info = nullptr);
@@ -1167,6 +1172,28 @@ public:
PASS2(sky_set_material, RID, RID)
PASS4R(Ref<Image>, sky_bake_panorama, RID, float, bool, const Size2i &)
+ // Compositor effect
+
+ PASS0R(RID, compositor_effect_allocate)
+ PASS1(compositor_effect_initialize, RID)
+
+ PASS1RC(bool, is_compositor_effect, RID)
+
+ PASS2(compositor_effect_set_enabled, RID, bool)
+ PASS3(compositor_effect_set_callback, RID, RS::CompositorEffectCallbackType, const Callable &)
+ PASS3(compositor_effect_set_flag, RID, RS::CompositorEffectFlags, bool)
+
+ // Compositor
+
+ PASS0R(RID, compositor_allocate)
+ PASS1(compositor_initialize, RID)
+
+ PASS1RC(bool, is_compositor, RID)
+
+ PASS2(compositor_set_compositor_effects, RID, const TypedArray<RID> &)
+
+ // Environment
+
PASS0R(RID, environment_allocate)
PASS1(environment_initialize, RID)
diff --git a/servers/rendering/renderer_scene_render.cpp b/servers/rendering/renderer_scene_render.cpp
index 95eb29a891..76c779900f 100644
--- a/servers/rendering/renderer_scene_render.cpp
+++ b/servers/rendering/renderer_scene_render.cpp
@@ -186,6 +186,64 @@ void RendererSceneRender::CameraData::set_multiview_camera(uint32_t p_view_count
}
}
+/* Compositor effect API */
+
+RID RendererSceneRender::compositor_effect_allocate() {
+ return compositor_storage.compositor_effect_allocate();
+}
+
+void RendererSceneRender::compositor_effect_initialize(RID p_rid) {
+ compositor_storage.compositor_effect_initialize(p_rid);
+}
+
+void RendererSceneRender::compositor_effect_free(RID p_rid) {
+ compositor_storage.compositor_effect_free(p_rid);
+}
+
+bool RendererSceneRender::is_compositor_effect(RID p_effect) const {
+ return compositor_storage.is_compositor_effect(p_effect);
+}
+
+void RendererSceneRender::compositor_effect_set_enabled(RID p_effect, bool p_enabled) {
+ compositor_storage.compositor_effect_set_enabled(p_effect, p_enabled);
+}
+
+void RendererSceneRender::compositor_effect_set_callback(RID p_effect, RS::CompositorEffectCallbackType p_callback_type, const Callable &p_callback) {
+ compositor_storage.compositor_effect_set_callback(p_effect, p_callback_type, p_callback);
+}
+
+void RendererSceneRender::compositor_effect_set_flag(RID p_effect, RS::CompositorEffectFlags p_flag, bool p_set) {
+ compositor_storage.compositor_effect_set_flag(p_effect, p_flag, p_set);
+}
+
+/* Compositor API */
+
+RID RendererSceneRender::compositor_allocate() {
+ return compositor_storage.compositor_allocate();
+}
+
+void RendererSceneRender::compositor_initialize(RID p_rid) {
+ compositor_storage.compositor_initialize(p_rid);
+}
+
+void RendererSceneRender::compositor_free(RID p_rid) {
+ compositor_storage.compositor_free(p_rid);
+}
+
+bool RendererSceneRender::is_compositor(RID p_rid) const {
+ return compositor_storage.is_compositor(p_rid);
+}
+
+void RendererSceneRender::compositor_set_compositor_effects(RID p_compositor, const TypedArray<RID> &p_effects) {
+ Vector<RID> rids;
+ for (int i = 0; i < p_effects.size(); i++) {
+ RID rid = p_effects[i];
+ rids.push_back(rid);
+ }
+
+ compositor_storage.compositor_set_compositor_effects(p_compositor, rids);
+}
+
/* Environment API */
RID RendererSceneRender::environment_allocate() {
diff --git a/servers/rendering/renderer_scene_render.h b/servers/rendering/renderer_scene_render.h
index c6e2c23e91..719efa4df2 100644
--- a/servers/rendering/renderer_scene_render.h
+++ b/servers/rendering/renderer_scene_render.h
@@ -35,6 +35,7 @@
#include "core/templates/paged_array.h"
#include "servers/rendering/renderer_geometry_instance.h"
#include "servers/rendering/rendering_method.h"
+#include "servers/rendering/storage/compositor_storage.h"
#include "servers/rendering/storage/environment_storage.h"
#include "storage/render_scene_buffers.h"
#include "storage/utilities.h"
@@ -42,6 +43,7 @@
class RendererSceneRender {
private:
RendererEnvironmentStorage environment_storage;
+ RendererCompositorStorage compositor_storage;
public:
enum {
@@ -73,6 +75,27 @@ public:
virtual void sky_set_material(RID p_sky, RID p_material) = 0;
virtual Ref<Image> sky_bake_panorama(RID p_sky, float p_energy, bool p_bake_irradiance, const Size2i &p_size) = 0;
+ /* COMPOSITOR EFFECT API */
+
+ RID compositor_effect_allocate();
+ void compositor_effect_initialize(RID p_rid);
+ void compositor_effect_free(RID p_rid);
+
+ bool is_compositor_effect(RID p_compositor) const;
+ void compositor_effect_set_enabled(RID p_compositor, bool p_enabled);
+ void compositor_effect_set_callback(RID p_compositor, RS::CompositorEffectCallbackType p_callback_type, const Callable &p_callback);
+ void compositor_effect_set_flag(RID p_compositor, RS::CompositorEffectFlags p_flag, bool p_set);
+
+ /* COMPOSITOR API */
+
+ RID compositor_allocate();
+ void compositor_initialize(RID p_rid);
+ void compositor_free(RID p_rid);
+
+ bool is_compositor(RID p_compositor) const;
+
+ void compositor_set_compositor_effects(RID p_compositor, const TypedArray<RID> &p_effects);
+
/* ENVIRONMENT API */
RID environment_allocate();
@@ -289,7 +312,7 @@ public:
void set_multiview_camera(uint32_t p_view_count, const Transform3D *p_transforms, const Projection *p_projections, bool p_is_orthogonal, bool p_vaspect);
};
- virtual void render_scene(const Ref<RenderSceneBuffers> &p_render_buffers, const CameraData *p_camera_data, const CameraData *p_prev_camera_data, const PagedArray<RenderGeometryInstance *> &p_instances, const PagedArray<RID> &p_lights, const PagedArray<RID> &p_reflection_probes, const PagedArray<RID> &p_voxel_gi_instances, const PagedArray<RID> &p_decals, const PagedArray<RID> &p_lightmaps, const PagedArray<RID> &p_fog_volumes, RID p_environment, RID p_camera_attributes, RID p_shadow_atlas, RID p_occluder_debug_tex, RID p_reflection_atlas, RID p_reflection_probe, int p_reflection_probe_pass, float p_screen_mesh_lod_threshold, const RenderShadowData *p_render_shadows, int p_render_shadow_count, const RenderSDFGIData *p_render_sdfgi_regions, int p_render_sdfgi_region_count, const RenderSDFGIUpdateData *p_sdfgi_update_data = nullptr, RenderingMethod::RenderInfo *r_render_info = nullptr) = 0;
+ virtual void render_scene(const Ref<RenderSceneBuffers> &p_render_buffers, const CameraData *p_camera_data, const CameraData *p_prev_camera_data, const PagedArray<RenderGeometryInstance *> &p_instances, const PagedArray<RID> &p_lights, const PagedArray<RID> &p_reflection_probes, const PagedArray<RID> &p_voxel_gi_instances, const PagedArray<RID> &p_decals, const PagedArray<RID> &p_lightmaps, const PagedArray<RID> &p_fog_volumes, RID p_environment, RID p_camera_attributes, RID p_compositor, RID p_shadow_atlas, RID p_occluder_debug_tex, RID p_reflection_atlas, RID p_reflection_probe, int p_reflection_probe_pass, float p_screen_mesh_lod_threshold, const RenderShadowData *p_render_shadows, int p_render_shadow_count, const RenderSDFGIData *p_render_sdfgi_regions, int p_render_sdfgi_region_count, const RenderSDFGIUpdateData *p_sdfgi_update_data = nullptr, RenderingMethod::RenderInfo *r_render_info = nullptr) = 0;
virtual void render_material(const Transform3D &p_cam_transform, const Projection &p_cam_projection, bool p_cam_orthogonal, const PagedArray<RenderGeometryInstance *> &p_instances, RID p_framebuffer, const Rect2i &p_region) = 0;
virtual void render_particle_collider_heightfield(RID p_collider, const Transform3D &p_transform, const PagedArray<RenderGeometryInstance *> &p_instances) = 0;
diff --git a/servers/rendering/rendering_device_binds.h b/servers/rendering/rendering_device_binds.h
index 5f21207579..4d9b565080 100644
--- a/servers/rendering/rendering_device_binds.h
+++ b/servers/rendering/rendering_device_binds.h
@@ -134,6 +134,7 @@ protected:
class RDFramebufferPass : public RefCounted {
GDCLASS(RDFramebufferPass, RefCounted)
friend class RenderingDevice;
+ friend class FramebufferCacheRD;
RD::FramebufferPass base;
@@ -443,6 +444,7 @@ protected:
class RDUniform : public RefCounted {
GDCLASS(RDUniform, RefCounted)
friend class RenderingDevice;
+ friend class UniformSetCacheRD;
RD::Uniform base;
public:
diff --git a/servers/rendering/rendering_method.h b/servers/rendering/rendering_method.h
index be14a50eec..4569846752 100644
--- a/servers/rendering/rendering_method.h
+++ b/servers/rendering/rendering_method.h
@@ -47,6 +47,7 @@ public:
virtual void camera_set_cull_mask(RID p_camera, uint32_t p_layers) = 0;
virtual void camera_set_environment(RID p_camera, RID p_env) = 0;
virtual void camera_set_camera_attributes(RID p_camera, RID p_attributes) = 0;
+ virtual void camera_set_compositor(RID p_camera, RID p_compositor) = 0;
virtual void camera_set_use_vertical_aspect(RID p_camera, bool p_enable) = 0;
virtual bool is_camera(RID p_camera) const = 0;
@@ -60,6 +61,7 @@ public:
virtual void scenario_set_environment(RID p_scenario, RID p_environment) = 0;
virtual void scenario_set_camera_attributes(RID p_scenario, RID p_attributes) = 0;
virtual void scenario_set_fallback_environment(RID p_scenario, RID p_environment) = 0;
+ virtual void scenario_set_compositor(RID p_scenario, RID p_compositor) = 0;
virtual void scenario_set_reflection_atlas_size(RID p_scenario, int p_reflection_size, int p_reflection_count) = 0;
virtual bool is_scenario(RID p_scenario) const = 0;
virtual RID scenario_get_environment(RID p_scenario) = 0;
@@ -117,6 +119,27 @@ public:
virtual void sky_set_material(RID p_sky, RID p_material) = 0;
virtual Ref<Image> sky_bake_panorama(RID p_sky, float p_energy, bool p_bake_irradiance, const Size2i &p_size) = 0;
+ /* COMPOSITOR EFFECT API */
+
+ virtual RID compositor_effect_allocate() = 0;
+ virtual void compositor_effect_initialize(RID p_rid) = 0;
+
+ virtual bool is_compositor_effect(RID p_compositor) const = 0;
+
+ virtual void compositor_effect_set_enabled(RID p_compositor, bool p_enabled) = 0;
+
+ virtual void compositor_effect_set_callback(RID p_compositor, RS::CompositorEffectCallbackType p_callback_type, const Callable &p_callback) = 0;
+ virtual void compositor_effect_set_flag(RID p_compositor, RS::CompositorEffectFlags p_flag, bool p_set) = 0;
+
+ /* COMPOSITOR API */
+
+ virtual RID compositor_allocate() = 0;
+ virtual void compositor_initialize(RID p_rid) = 0;
+
+ virtual bool is_compositor(RID p_compositor) const = 0;
+
+ virtual void compositor_set_compositor_effects(RID p_env, const TypedArray<RID> &p_effects) = 0;
+
/* ENVIRONMENT API */
virtual RID environment_allocate() = 0;
diff --git a/servers/rendering/rendering_server_default.h b/servers/rendering/rendering_server_default.h
index c218007a78..17622ba311 100644
--- a/servers/rendering/rendering_server_default.h
+++ b/servers/rendering/rendering_server_default.h
@@ -591,6 +591,7 @@ public:
FUNC2(camera_set_cull_mask, RID, uint32_t)
FUNC2(camera_set_environment, RID, RID)
FUNC2(camera_set_camera_attributes, RID, RID)
+ FUNC2(camera_set_compositor, RID, RID)
FUNC2(camera_set_use_vertical_aspect, RID, bool)
/* OCCLUDER */
@@ -676,7 +677,7 @@ public:
FUNC2(viewport_set_vrs_mode, RID, ViewportVRSMode)
FUNC2(viewport_set_vrs_texture, RID, RID)
- /* ENVIRONMENT API */
+ /* COMPOSITOR EFFECT */
#undef server_name
#undef ServerName
@@ -684,6 +685,19 @@ public:
#define ServerName RenderingMethod
#define server_name RSG::scene
+ FUNCRIDSPLIT(compositor_effect)
+ FUNC2(compositor_effect_set_enabled, RID, bool)
+ FUNC3(compositor_effect_set_callback, RID, CompositorEffectCallbackType, const Callable &)
+ FUNC3(compositor_effect_set_flag, RID, CompositorEffectFlags, bool)
+
+ /* COMPOSITOR */
+
+ FUNC2(compositor_set_compositor_effects, RID, const TypedArray<RID> &)
+
+ FUNCRIDSPLIT(compositor)
+
+ /* ENVIRONMENT API */
+
FUNC1(voxel_gi_set_quality, VoxelGIQuality)
/* SKY API */
@@ -694,6 +708,8 @@ public:
FUNC2(sky_set_material, RID, RID)
FUNC4R(Ref<Image>, sky_bake_panorama, RID, float, bool, const Size2i &)
+ /* ENVIRONMENT */
+
FUNCRIDSPLIT(environment)
FUNC2(environment_set_background, RID, EnvironmentBG)
@@ -779,6 +795,7 @@ public:
FUNC2(scenario_set_environment, RID, RID)
FUNC2(scenario_set_camera_attributes, RID, RID)
FUNC2(scenario_set_fallback_environment, RID, RID)
+ FUNC2(scenario_set_compositor, RID, RID)
/* INSTANCING API */
FUNCRIDSPLIT(instance)
diff --git a/servers/rendering/storage/compositor_storage.cpp b/servers/rendering/storage/compositor_storage.cpp
new file mode 100644
index 0000000000..d9a70a093d
--- /dev/null
+++ b/servers/rendering/storage/compositor_storage.cpp
@@ -0,0 +1,160 @@
+/**************************************************************************/
+/* compositor_storage.cpp */
+/**************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* https://godotengine.org */
+/**************************************************************************/
+/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */
+/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */
+/* */
+/* Permission is hereby granted, free of charge, to any person obtaining */
+/* a copy of this software and associated documentation files (the */
+/* "Software"), to deal in the Software without restriction, including */
+/* without limitation the rights to use, copy, modify, merge, publish, */
+/* distribute, sublicense, and/or sell copies of the Software, and to */
+/* permit persons to whom the Software is furnished to do so, subject to */
+/* the following conditions: */
+/* */
+/* The above copyright notice and this permission notice shall be */
+/* included in all copies or substantial portions of the Software. */
+/* */
+/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
+/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
+/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. */
+/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
+/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
+/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
+/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
+/**************************************************************************/
+
+#include "compositor_storage.h"
+
+// Storage
+
+RendererCompositorStorage *RendererCompositorStorage::singleton = nullptr;
+
+RendererCompositorStorage::RendererCompositorStorage() {
+ singleton = this;
+}
+
+RendererCompositorStorage::~RendererCompositorStorage() {
+ singleton = nullptr;
+}
+
+// Compositor effect
+
+RID RendererCompositorStorage::compositor_effect_allocate() {
+ return compositor_effects_owner.allocate_rid();
+}
+
+void RendererCompositorStorage::compositor_effect_initialize(RID p_rid) {
+ compositor_effects_owner.initialize_rid(p_rid, CompositorEffect());
+}
+
+void RendererCompositorStorage::compositor_effect_free(RID p_rid) {
+ // TODO remove this RID from any compositor that uses it.
+
+ compositor_effects_owner.free(p_rid);
+}
+
+void RendererCompositorStorage::compositor_effect_set_callback(RID p_effect, RS::CompositorEffectCallbackType p_callback_type, const Callable &p_callback) {
+ CompositorEffect *effect = compositor_effects_owner.get_or_null(p_effect);
+ ERR_FAIL_NULL(effect);
+
+ effect->callback_type = p_callback_type;
+ effect->callback = p_callback;
+}
+
+void RendererCompositorStorage::compositor_effect_set_enabled(RID p_effect, bool p_enabled) {
+ CompositorEffect *effect = compositor_effects_owner.get_or_null(p_effect);
+ ERR_FAIL_NULL(effect);
+
+ effect->is_enabled = p_enabled;
+}
+
+bool RendererCompositorStorage::compositor_effect_get_enabled(RID p_effect) const {
+ CompositorEffect *effect = compositor_effects_owner.get_or_null(p_effect);
+ ERR_FAIL_NULL_V(effect, false);
+
+ return effect->is_enabled;
+}
+
+RS::CompositorEffectCallbackType RendererCompositorStorage::compositor_effect_get_callback_type(RID p_effect) const {
+ CompositorEffect *effect = compositor_effects_owner.get_or_null(p_effect);
+ ERR_FAIL_NULL_V(effect, RS::COMPOSITOR_EFFECT_CALLBACK_TYPE_MAX);
+
+ return effect->callback_type;
+}
+
+Callable RendererCompositorStorage::compositor_effect_get_callback(RID p_effect) const {
+ CompositorEffect *effect = compositor_effects_owner.get_or_null(p_effect);
+ ERR_FAIL_NULL_V(effect, Callable());
+
+ return effect->callback;
+}
+
+void RendererCompositorStorage::compositor_effect_set_flag(RID p_effect, RS::CompositorEffectFlags p_flag, bool p_set) {
+ CompositorEffect *effect = compositor_effects_owner.get_or_null(p_effect);
+ ERR_FAIL_NULL(effect);
+
+ if (p_set) {
+ effect->flags.set_flag(p_flag);
+ } else {
+ effect->flags.clear_flag(p_flag);
+ }
+}
+
+bool RendererCompositorStorage::compositor_effect_get_flag(RID p_effect, RS::CompositorEffectFlags p_flag) const {
+ CompositorEffect *effect = compositor_effects_owner.get_or_null(p_effect);
+ ERR_FAIL_NULL_V(effect, false);
+
+ return effect->flags.has_flag(p_flag);
+}
+
+// Compositor
+
+RID RendererCompositorStorage::compositor_allocate() {
+ return compositor_owner.allocate_rid();
+}
+
+void RendererCompositorStorage::compositor_initialize(RID p_rid) {
+ compositor_owner.initialize_rid(p_rid, Compositor());
+}
+
+void RendererCompositorStorage::compositor_free(RID p_rid) {
+ compositor_owner.free(p_rid);
+}
+
+// compositor effects
+
+void RendererCompositorStorage::compositor_set_compositor_effects(RID p_compositor, const Vector<RID> &p_effects) {
+ Compositor *compositor = compositor_owner.get_or_null(p_compositor);
+ ERR_FAIL_NULL(compositor);
+
+ compositor->compositor_effects.clear();
+ for (const RID &effect : p_effects) {
+ if (is_compositor_effect(effect)) {
+ compositor->compositor_effects.push_back(effect);
+ }
+ }
+}
+
+Vector<RID> RendererCompositorStorage::compositor_get_compositor_effects(RID p_compositor, RS::CompositorEffectCallbackType p_callback_type, bool p_enabled_only) const {
+ Compositor *compositor = compositor_owner.get_or_null(p_compositor);
+ ERR_FAIL_NULL_V(compositor, Vector<RID>());
+
+ if (p_enabled_only || p_callback_type != RS::COMPOSITOR_EFFECT_CALLBACK_TYPE_ANY) {
+ Vector<RID> effects;
+
+ for (RID rid : compositor->compositor_effects) {
+ if ((!p_enabled_only || compositor_effect_get_enabled(rid)) && (p_callback_type == RS::COMPOSITOR_EFFECT_CALLBACK_TYPE_ANY || compositor_effect_get_callback_type(rid) == p_callback_type)) {
+ effects.push_back(rid);
+ }
+ }
+
+ return effects;
+ } else {
+ return compositor->compositor_effects;
+ }
+}
diff --git a/servers/rendering/storage/compositor_storage.h b/servers/rendering/storage/compositor_storage.h
new file mode 100644
index 0000000000..0d6942e27f
--- /dev/null
+++ b/servers/rendering/storage/compositor_storage.h
@@ -0,0 +1,98 @@
+/**************************************************************************/
+/* compositor_storage.h */
+/**************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* https://godotengine.org */
+/**************************************************************************/
+/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */
+/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */
+/* */
+/* Permission is hereby granted, free of charge, to any person obtaining */
+/* a copy of this software and associated documentation files (the */
+/* "Software"), to deal in the Software without restriction, including */
+/* without limitation the rights to use, copy, modify, merge, publish, */
+/* distribute, sublicense, and/or sell copies of the Software, and to */
+/* permit persons to whom the Software is furnished to do so, subject to */
+/* the following conditions: */
+/* */
+/* The above copyright notice and this permission notice shall be */
+/* included in all copies or substantial portions of the Software. */
+/* */
+/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
+/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
+/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. */
+/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
+/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
+/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
+/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
+/**************************************************************************/
+
+#ifndef COMPOSITOR_STORAGE_H
+#define COMPOSITOR_STORAGE_H
+
+#include "core/templates/rid_owner.h"
+#include "servers/rendering_server.h"
+
+class RendererCompositorStorage {
+private:
+ static RendererCompositorStorage *singleton;
+
+ // Compositor effect
+ struct CompositorEffect {
+ bool is_enabled = true;
+ RS::CompositorEffectCallbackType callback_type;
+ Callable callback;
+
+ BitField<RS::CompositorEffectFlags> flags;
+ };
+
+ mutable RID_Owner<CompositorEffect, true> compositor_effects_owner;
+
+ // Compositor
+ struct Compositor {
+ // Compositor effects
+ Vector<RID> compositor_effects;
+ };
+
+ mutable RID_Owner<Compositor, true> compositor_owner;
+
+public:
+ static RendererCompositorStorage *get_singleton() { return singleton; }
+
+ RendererCompositorStorage();
+ virtual ~RendererCompositorStorage();
+
+ // Compositor effect
+ RID compositor_effect_allocate();
+ void compositor_effect_initialize(RID p_rid);
+ void compositor_effect_free(RID p_rid);
+
+ bool is_compositor_effect(RID p_effect) const {
+ return compositor_effects_owner.owns(p_effect);
+ }
+
+ void compositor_effect_set_enabled(RID p_effect, bool p_enabled);
+ bool compositor_effect_get_enabled(RID p_effect) const;
+
+ void compositor_effect_set_callback(RID p_effect, RS::CompositorEffectCallbackType p_callback_type, const Callable &p_callback);
+ RS::CompositorEffectCallbackType compositor_effect_get_callback_type(RID p_effect) const;
+ Callable compositor_effect_get_callback(RID p_effect) const;
+
+ void compositor_effect_set_flag(RID p_effect, RS::CompositorEffectFlags p_flag, bool p_set);
+ bool compositor_effect_get_flag(RID p_effect, RS::CompositorEffectFlags p_flag) const;
+
+ // Compositor
+ RID compositor_allocate();
+ void compositor_initialize(RID p_rid);
+ void compositor_free(RID p_rid);
+
+ bool is_compositor(RID p_compositor) const {
+ return compositor_owner.owns(p_compositor);
+ }
+
+ void compositor_set_compositor_effects(RID p_compositor, const Vector<RID> &p_effects);
+ Vector<RID> compositor_get_compositor_effects(RID p_compositor, RS::CompositorEffectCallbackType p_callback_type = RS::COMPOSITOR_EFFECT_CALLBACK_TYPE_ANY, bool p_enabled_only = true) const;
+};
+
+#endif // COMPOSITOR_STORAGE_H
diff --git a/servers/rendering/storage/environment_storage.cpp b/servers/rendering/storage/environment_storage.cpp
index ec26e36509..7b75a12a19 100644
--- a/servers/rendering/storage/environment_storage.cpp
+++ b/servers/rendering/storage/environment_storage.cpp
@@ -30,6 +30,20 @@
#include "environment_storage.h"
+// Storage
+
+RendererEnvironmentStorage *RendererEnvironmentStorage::singleton = nullptr;
+
+RendererEnvironmentStorage::RendererEnvironmentStorage() {
+ singleton = this;
+}
+
+RendererEnvironmentStorage::~RendererEnvironmentStorage() {
+ singleton = nullptr;
+}
+
+// Environment
+
RID RendererEnvironmentStorage::environment_allocate() {
return environment_owner.allocate_rid();
}
@@ -417,11 +431,6 @@ void RendererEnvironmentStorage::environment_set_glow(RID p_env, bool p_enable,
Environment *env = environment_owner.get_or_null(p_env);
ERR_FAIL_NULL(env);
ERR_FAIL_COND_MSG(p_levels.size() != 7, "Size of array of glow levels must be 7");
-#ifdef DEBUG_ENABLED
- if (OS::get_singleton()->get_current_rendering_method() == "gl_compatibility" && p_enable) {
- WARN_PRINT_ONCE_ED("Glow is not supported when using the GL Compatibility backend yet. Support will be added in a future release.");
- }
-#endif
env->glow_enabled = p_enable;
env->glow_levels = p_levels;
env->glow_intensity = p_intensity;
diff --git a/servers/rendering/storage/environment_storage.h b/servers/rendering/storage/environment_storage.h
index c077e093da..9f78808ff7 100644
--- a/servers/rendering/storage/environment_storage.h
+++ b/servers/rendering/storage/environment_storage.h
@@ -36,6 +36,9 @@
class RendererEnvironmentStorage {
private:
+ static RendererEnvironmentStorage *singleton;
+
+ // Environment
struct Environment {
// Note, we capture and store all environment parameters received from Godot here.
// Not all renderers support all effects and should just ignore the bits they don't support.
@@ -155,6 +158,12 @@ private:
mutable RID_Owner<Environment, true> environment_owner;
public:
+ static RendererEnvironmentStorage *get_singleton() { return singleton; }
+
+ RendererEnvironmentStorage();
+ virtual ~RendererEnvironmentStorage();
+
+ // Environment
RID environment_allocate();
void environment_initialize(RID p_rid);
void environment_free(RID p_rid);
diff --git a/servers/rendering/storage/render_data.cpp b/servers/rendering/storage/render_data.cpp
new file mode 100644
index 0000000000..fa00a5c672
--- /dev/null
+++ b/servers/rendering/storage/render_data.cpp
@@ -0,0 +1,69 @@
+/**************************************************************************/
+/* render_data.cpp */
+/**************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* https://godotengine.org */
+/**************************************************************************/
+/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */
+/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */
+/* */
+/* Permission is hereby granted, free of charge, to any person obtaining */
+/* a copy of this software and associated documentation files (the */
+/* "Software"), to deal in the Software without restriction, including */
+/* without limitation the rights to use, copy, modify, merge, publish, */
+/* distribute, sublicense, and/or sell copies of the Software, and to */
+/* permit persons to whom the Software is furnished to do so, subject to */
+/* the following conditions: */
+/* */
+/* The above copyright notice and this permission notice shall be */
+/* included in all copies or substantial portions of the Software. */
+/* */
+/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
+/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
+/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. */
+/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
+/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
+/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
+/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
+/**************************************************************************/
+
+#include "render_data.h"
+
+void RenderData::_bind_methods() {
+ ClassDB::bind_method(D_METHOD("get_render_scene_buffers"), &RenderData::get_render_scene_buffers);
+ ClassDB::bind_method(D_METHOD("get_render_scene_data"), &RenderData::get_render_scene_data);
+ ClassDB::bind_method(D_METHOD("get_environment"), &RenderData::get_environment);
+ ClassDB::bind_method(D_METHOD("get_camera_attributes"), &RenderData::get_camera_attributes);
+}
+
+void RenderDataExtension::_bind_methods() {
+ GDVIRTUAL_BIND(_get_render_scene_buffers);
+ GDVIRTUAL_BIND(_get_render_scene_data)
+ GDVIRTUAL_BIND(_get_environment)
+ GDVIRTUAL_BIND(_get_camera_attributes)
+}
+
+Ref<RenderSceneBuffers> RenderDataExtension::get_render_scene_buffers() const {
+ Ref<RenderSceneBuffers> ret;
+ GDVIRTUAL_CALL(_get_render_scene_buffers, ret);
+ return ret;
+}
+
+RenderSceneData *RenderDataExtension::get_render_scene_data() const {
+ RenderSceneData *ret = nullptr;
+ GDVIRTUAL_CALL(_get_render_scene_data, ret);
+ return ret;
+}
+
+RID RenderDataExtension::get_environment() const {
+ RID ret;
+ GDVIRTUAL_CALL(_get_environment, ret);
+ return ret;
+}
+
+RID RenderDataExtension::get_camera_attributes() const {
+ RID ret;
+ GDVIRTUAL_CALL(_get_camera_attributes, ret);
+ return ret;
+}
diff --git a/servers/rendering/storage/render_data.h b/servers/rendering/storage/render_data.h
new file mode 100644
index 0000000000..36aa6db784
--- /dev/null
+++ b/servers/rendering/storage/render_data.h
@@ -0,0 +1,70 @@
+/**************************************************************************/
+/* render_data.h */
+/**************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* https://godotengine.org */
+/**************************************************************************/
+/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */
+/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */
+/* */
+/* Permission is hereby granted, free of charge, to any person obtaining */
+/* a copy of this software and associated documentation files (the */
+/* "Software"), to deal in the Software without restriction, including */
+/* without limitation the rights to use, copy, modify, merge, publish, */
+/* distribute, sublicense, and/or sell copies of the Software, and to */
+/* permit persons to whom the Software is furnished to do so, subject to */
+/* the following conditions: */
+/* */
+/* The above copyright notice and this permission notice shall be */
+/* included in all copies or substantial portions of the Software. */
+/* */
+/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
+/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
+/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. */
+/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
+/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
+/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
+/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
+/**************************************************************************/
+
+#ifndef RENDER_DATA_H
+#define RENDER_DATA_H
+
+#include "core/object/object.h"
+#include "render_scene_buffers.h"
+#include "render_scene_data.h"
+
+class RenderData : public Object {
+ GDCLASS(RenderData, Object);
+
+protected:
+ static void _bind_methods();
+
+public:
+ virtual Ref<RenderSceneBuffers> get_render_scene_buffers() const = 0;
+ virtual RenderSceneData *get_render_scene_data() const = 0;
+
+ virtual RID get_environment() const = 0;
+ virtual RID get_camera_attributes() const = 0;
+};
+
+class RenderDataExtension : public RenderData {
+ GDCLASS(RenderDataExtension, RenderData);
+
+protected:
+ static void _bind_methods();
+
+ virtual Ref<RenderSceneBuffers> get_render_scene_buffers() const override;
+ virtual RenderSceneData *get_render_scene_data() const override;
+
+ virtual RID get_environment() const override;
+ virtual RID get_camera_attributes() const override;
+
+ GDVIRTUAL0RC(Ref<RenderSceneBuffers>, _get_render_scene_buffers)
+ GDVIRTUAL0RC(RenderSceneData *, _get_render_scene_data)
+ GDVIRTUAL0RC(RID, _get_environment)
+ GDVIRTUAL0RC(RID, _get_camera_attributes)
+};
+
+#endif // RENDER_DATA_H
diff --git a/servers/rendering/storage/render_scene_data.cpp b/servers/rendering/storage/render_scene_data.cpp
new file mode 100644
index 0000000000..a1d8f524b4
--- /dev/null
+++ b/servers/rendering/storage/render_scene_data.cpp
@@ -0,0 +1,88 @@
+/**************************************************************************/
+/* render_scene_data.cpp */
+/**************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* https://godotengine.org */
+/**************************************************************************/
+/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */
+/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */
+/* */
+/* Permission is hereby granted, free of charge, to any person obtaining */
+/* a copy of this software and associated documentation files (the */
+/* "Software"), to deal in the Software without restriction, including */
+/* without limitation the rights to use, copy, modify, merge, publish, */
+/* distribute, sublicense, and/or sell copies of the Software, and to */
+/* permit persons to whom the Software is furnished to do so, subject to */
+/* the following conditions: */
+/* */
+/* The above copyright notice and this permission notice shall be */
+/* included in all copies or substantial portions of the Software. */
+/* */
+/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
+/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
+/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. */
+/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
+/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
+/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
+/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
+/**************************************************************************/
+
+#include "render_scene_data.h"
+
+void RenderSceneData::_bind_methods() {
+ ClassDB::bind_method(D_METHOD("get_cam_transform"), &RenderSceneData::get_cam_transform);
+ ClassDB::bind_method(D_METHOD("get_cam_projection"), &RenderSceneData::get_cam_projection);
+
+ ClassDB::bind_method(D_METHOD("get_view_count"), &RenderSceneData::get_view_count);
+ ClassDB::bind_method(D_METHOD("get_view_eye_offset", "view"), &RenderSceneData::get_view_eye_offset);
+ ClassDB::bind_method(D_METHOD("get_view_projection", "view"), &RenderSceneData::get_view_projection);
+
+ ClassDB::bind_method(D_METHOD("get_uniform_buffer"), &RenderSceneData::get_uniform_buffer);
+}
+
+void RenderSceneDataExtension::_bind_methods() {
+ GDVIRTUAL_BIND(_get_cam_transform);
+ GDVIRTUAL_BIND(_get_cam_projection);
+ GDVIRTUAL_BIND(_get_view_count);
+ GDVIRTUAL_BIND(_get_view_eye_offset, "view");
+ GDVIRTUAL_BIND(_get_view_projection, "view");
+
+ GDVIRTUAL_BIND(_get_uniform_buffer);
+}
+
+Transform3D RenderSceneDataExtension::get_cam_transform() const {
+ Transform3D ret;
+ GDVIRTUAL_CALL(_get_cam_transform, ret);
+ return ret;
+}
+
+Projection RenderSceneDataExtension::get_cam_projection() const {
+ Projection ret;
+ GDVIRTUAL_CALL(_get_cam_projection, ret);
+ return ret;
+}
+
+uint32_t RenderSceneDataExtension::get_view_count() const {
+ uint32_t ret = 0;
+ GDVIRTUAL_CALL(_get_view_count, ret);
+ return ret;
+}
+
+Vector3 RenderSceneDataExtension::get_view_eye_offset(uint32_t p_view) const {
+ Vector3 ret;
+ GDVIRTUAL_CALL(_get_view_eye_offset, p_view, ret);
+ return ret;
+}
+
+Projection RenderSceneDataExtension::get_view_projection(uint32_t p_view) const {
+ Projection ret;
+ GDVIRTUAL_CALL(_get_view_projection, p_view, ret);
+ return ret;
+}
+
+RID RenderSceneDataExtension::get_uniform_buffer() const {
+ RID ret;
+ GDVIRTUAL_CALL(_get_uniform_buffer, ret);
+ return ret;
+}
diff --git a/servers/rendering/storage/render_scene_data.h b/servers/rendering/storage/render_scene_data.h
new file mode 100644
index 0000000000..6a00cecc96
--- /dev/null
+++ b/servers/rendering/storage/render_scene_data.h
@@ -0,0 +1,82 @@
+/**************************************************************************/
+/* render_scene_data.h */
+/**************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* https://godotengine.org */
+/**************************************************************************/
+/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */
+/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */
+/* */
+/* Permission is hereby granted, free of charge, to any person obtaining */
+/* a copy of this software and associated documentation files (the */
+/* "Software"), to deal in the Software without restriction, including */
+/* without limitation the rights to use, copy, modify, merge, publish, */
+/* distribute, sublicense, and/or sell copies of the Software, and to */
+/* permit persons to whom the Software is furnished to do so, subject to */
+/* the following conditions: */
+/* */
+/* The above copyright notice and this permission notice shall be */
+/* included in all copies or substantial portions of the Software. */
+/* */
+/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
+/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
+/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. */
+/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
+/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
+/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
+/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
+/**************************************************************************/
+
+#ifndef RENDER_SCENE_DATA_H
+#define RENDER_SCENE_DATA_H
+
+#include "core/object/class_db.h"
+#include "core/object/gdvirtual.gen.inc"
+#include "core/object/object.h"
+#include "core/object/script_language.h"
+
+class RenderSceneData : public Object {
+ GDCLASS(RenderSceneData, Object);
+
+protected:
+ static void _bind_methods();
+
+public:
+ virtual Transform3D get_cam_transform() const = 0;
+ virtual Projection get_cam_projection() const = 0;
+
+ virtual uint32_t get_view_count() const = 0;
+ virtual Vector3 get_view_eye_offset(uint32_t p_view) const = 0;
+ virtual Projection get_view_projection(uint32_t p_view) const = 0;
+
+ virtual RID get_uniform_buffer() const = 0;
+};
+
+class RenderSceneDataExtension : public RenderSceneData {
+ GDCLASS(RenderSceneDataExtension, RenderSceneData);
+
+protected:
+ static void _bind_methods();
+
+public:
+ virtual Transform3D get_cam_transform() const override;
+ virtual Projection get_cam_projection() const override;
+
+ virtual uint32_t get_view_count() const override;
+ virtual Vector3 get_view_eye_offset(uint32_t p_view) const override;
+ virtual Projection get_view_projection(uint32_t p_view) const override;
+
+ virtual RID get_uniform_buffer() const override;
+
+ GDVIRTUAL0RC(Transform3D, _get_cam_transform)
+ GDVIRTUAL0RC(Projection, _get_cam_projection)
+
+ GDVIRTUAL0RC(uint32_t, _get_view_count)
+ GDVIRTUAL1RC(Vector3, _get_view_eye_offset, uint32_t)
+ GDVIRTUAL1RC(Projection, _get_view_projection, uint32_t)
+
+ GDVIRTUAL0RC(RID, _get_uniform_buffer)
+};
+
+#endif // RENDER_SCENE_DATA_H