summaryrefslogtreecommitdiff
path: root/servers/rendering/renderer_rd
diff options
context:
space:
mode:
Diffstat (limited to 'servers/rendering/renderer_rd')
-rw-r--r--servers/rendering/renderer_rd/cluster_builder_rd.cpp2
-rw-r--r--servers/rendering/renderer_rd/cluster_builder_rd.h12
-rw-r--r--servers/rendering/renderer_rd/effects_rd.cpp122
-rw-r--r--servers/rendering/renderer_rd/effects_rd.h31
-rw-r--r--servers/rendering/renderer_rd/forward_clustered/render_forward_clustered.cpp252
-rw-r--r--servers/rendering/renderer_rd/forward_clustered/render_forward_clustered.h115
-rw-r--r--servers/rendering/renderer_rd/forward_clustered/scene_shader_forward_clustered.cpp137
-rw-r--r--servers/rendering/renderer_rd/forward_clustered/scene_shader_forward_clustered.h16
-rw-r--r--servers/rendering/renderer_rd/forward_mobile/render_forward_mobile.cpp147
-rw-r--r--servers/rendering/renderer_rd/forward_mobile/render_forward_mobile.h111
-rw-r--r--servers/rendering/renderer_rd/forward_mobile/scene_shader_forward_mobile.cpp177
-rw-r--r--servers/rendering/renderer_rd/forward_mobile/scene_shader_forward_mobile.h20
-rw-r--r--servers/rendering/renderer_rd/pipeline_cache_rd.cpp7
-rw-r--r--servers/rendering/renderer_rd/pipeline_cache_rd.h9
-rw-r--r--servers/rendering/renderer_rd/renderer_canvas_render_rd.cpp114
-rw-r--r--servers/rendering/renderer_rd/renderer_canvas_render_rd.h9
-rw-r--r--servers/rendering/renderer_rd/renderer_compositor_rd.cpp83
-rw-r--r--servers/rendering/renderer_rd/renderer_compositor_rd.h3
-rw-r--r--servers/rendering/renderer_rd/renderer_scene_gi_rd.cpp318
-rw-r--r--servers/rendering/renderer_rd/renderer_scene_gi_rd.h130
-rw-r--r--servers/rendering/renderer_rd/renderer_scene_render_rd.cpp227
-rw-r--r--servers/rendering/renderer_rd/renderer_scene_render_rd.h264
-rw-r--r--servers/rendering/renderer_rd/renderer_scene_sky_rd.cpp225
-rw-r--r--servers/rendering/renderer_rd/renderer_scene_sky_rd.h124
-rw-r--r--servers/rendering/renderer_rd/renderer_storage_rd.cpp871
-rw-r--r--servers/rendering/renderer_rd/renderer_storage_rd.h243
-rw-r--r--servers/rendering/renderer_rd/shader_compiler_rd.cpp1
-rw-r--r--servers/rendering/renderer_rd/shader_rd.cpp4
-rw-r--r--servers/rendering/renderer_rd/shaders/canvas.glsl2
-rw-r--r--servers/rendering/renderer_rd/shaders/gi.glsl93
-rw-r--r--servers/rendering/renderer_rd/shaders/resolve.glsl38
-rw-r--r--servers/rendering/renderer_rd/shaders/scene_forward_clustered.glsl497
-rw-r--r--servers/rendering/renderer_rd/shaders/scene_forward_clustered_inc.glsl23
-rw-r--r--servers/rendering/renderer_rd/shaders/scene_forward_gi_inc.glsl32
-rw-r--r--servers/rendering/renderer_rd/shaders/scene_forward_lights_inc.glsl51
-rw-r--r--servers/rendering/renderer_rd/shaders/scene_forward_mobile.glsl40
-rw-r--r--servers/rendering/renderer_rd/shaders/scene_forward_mobile_inc.glsl15
-rw-r--r--servers/rendering/renderer_rd/shaders/screen_space_reflection_scale.glsl15
-rw-r--r--servers/rendering/renderer_rd/shaders/sky.glsl31
-rw-r--r--servers/rendering/renderer_rd/shaders/tonemap.glsl35
-rw-r--r--servers/rendering/renderer_rd/shaders/volumetric_fog.glsl32
-rw-r--r--servers/rendering/renderer_rd/shaders/voxel_gi.glsl (renamed from servers/rendering/renderer_rd/shaders/giprobe.glsl)0
-rw-r--r--servers/rendering/renderer_rd/shaders/voxel_gi_debug.glsl (renamed from servers/rendering/renderer_rd/shaders/giprobe_debug.glsl)0
-rw-r--r--servers/rendering/renderer_rd/shaders/voxel_gi_sdf.glsl (renamed from servers/rendering/renderer_rd/shaders/giprobe_sdf.glsl)0
44 files changed, 2429 insertions, 2249 deletions
diff --git a/servers/rendering/renderer_rd/cluster_builder_rd.cpp b/servers/rendering/renderer_rd/cluster_builder_rd.cpp
index 2669a73014..b952ecbff0 100644
--- a/servers/rendering/renderer_rd/cluster_builder_rd.cpp
+++ b/servers/rendering/renderer_rd/cluster_builder_rd.cpp
@@ -374,7 +374,7 @@ void ClusterBuilderRD::setup(Size2i p_screen_size, uint32_t p_max_elements, RID
}
}
-void ClusterBuilderRD::begin(const Transform &p_view_transform, const CameraMatrix &p_cam_projection, bool p_flip_y) {
+void ClusterBuilderRD::begin(const Transform3D &p_view_transform, const CameraMatrix &p_cam_projection, bool p_flip_y) {
view_xform = p_view_transform.affine_inverse();
projection = p_cam_projection;
z_near = projection.get_z_near();
diff --git a/servers/rendering/renderer_rd/cluster_builder_rd.h b/servers/rendering/renderer_rd/cluster_builder_rd.h
index dc1707b534..ebb81abdad 100644
--- a/servers/rendering/renderer_rd/cluster_builder_rd.h
+++ b/servers/rendering/renderer_rd/cluster_builder_rd.h
@@ -167,7 +167,7 @@ private:
uint32_t render_element_count = 0;
uint32_t render_element_max = 0;
- Transform view_xform;
+ Transform3D view_xform;
CameraMatrix adjusted_projection;
CameraMatrix projection;
float z_far = 0;
@@ -220,9 +220,9 @@ private:
public:
void setup(Size2i p_screen_size, uint32_t p_max_elements, RID p_depth_buffer, RID p_depth_buffer_sampler, RID p_color_buffer);
- void begin(const Transform &p_view_transform, const CameraMatrix &p_cam_projection, bool p_flip_y);
+ void begin(const Transform3D &p_view_transform, const CameraMatrix &p_cam_projection, bool p_flip_y);
- _FORCE_INLINE_ void add_light(LightType p_type, const Transform &p_transform, float p_radius, float p_spot_aperture) {
+ _FORCE_INLINE_ void add_light(LightType p_type, const Transform3D &p_transform, float p_radius, float p_spot_aperture) {
if (p_type == LIGHT_TYPE_OMNI && cluster_count_by_type[ELEMENT_TYPE_OMNI_LIGHT] == max_elements_by_type) {
return; //max number elements reached
}
@@ -232,7 +232,7 @@ public:
RenderElementData &e = render_elements[render_element_count];
- Transform xform = view_xform * p_transform;
+ Transform3D xform = view_xform * p_transform;
float radius = xform.basis.get_uniform_scale();
if (radius > 0.98 || radius < 1.02) {
@@ -317,7 +317,7 @@ public:
render_element_count++;
}
- _FORCE_INLINE_ void add_box(BoxType p_box_type, const Transform &p_transform, const Vector3 &p_half_extents) {
+ _FORCE_INLINE_ void add_box(BoxType p_box_type, const Transform3D &p_transform, const Vector3 &p_half_extents) {
if (p_box_type == BOX_TYPE_DECAL && cluster_count_by_type[ELEMENT_TYPE_DECAL] == max_elements_by_type) {
return; //max number elements reached
}
@@ -326,7 +326,7 @@ public:
}
RenderElementData &e = render_elements[render_element_count];
- Transform xform = view_xform * p_transform;
+ Transform3D xform = view_xform * p_transform;
//extract scale and scale the matrix by it, makes things simpler
Vector3 scale = p_half_extents;
diff --git a/servers/rendering/renderer_rd/effects_rd.cpp b/servers/rendering/renderer_rd/effects_rd.cpp
index 563e08fdcb..5cf8895c8e 100644
--- a/servers/rendering/renderer_rd/effects_rd.cpp
+++ b/servers/rendering/renderer_rd/effects_rd.cpp
@@ -34,23 +34,9 @@
#include "core/math/math_defs.h"
#include "core/os/os.h"
+#include "servers/rendering/renderer_rd/renderer_compositor_rd.h"
#include "thirdparty/misc/cubemap_coeffs.h"
-static _FORCE_INLINE_ void store_transform_3x3(const Basis &p_basis, float *p_array) {
- p_array[0] = p_basis.elements[0][0];
- p_array[1] = p_basis.elements[1][0];
- p_array[2] = p_basis.elements[2][0];
- p_array[3] = 0;
- p_array[4] = p_basis.elements[0][1];
- p_array[5] = p_basis.elements[1][1];
- p_array[6] = p_basis.elements[2][1];
- p_array[7] = 0;
- p_array[8] = p_basis.elements[0][2];
- p_array[9] = p_basis.elements[1][2];
- p_array[10] = p_basis.elements[2][2];
- p_array[11] = 0;
-}
-
static _FORCE_INLINE_ void store_camera(const CameraMatrix &p_mtx, float *p_array) {
for (int i = 0; i < 4; i++) {
for (int j = 0; j < 4; j++) {
@@ -517,11 +503,10 @@ void EffectsRD::screen_space_reflection(RID p_diffuse, RID p_normal_roughness, R
if (p_roughness_quality != RS::ENV_SSR_ROUGNESS_QUALITY_DISABLED) {
RD::get_singleton()->compute_list_bind_uniform_set(compute_list, _get_compute_uniform_set_from_image_pair(p_output, p_blur_radius), 1);
- RD::get_singleton()->compute_list_bind_uniform_set(compute_list, _get_compute_uniform_set_from_texture_pair(p_metallic, p_normal_roughness), 3);
} else {
RD::get_singleton()->compute_list_bind_uniform_set(compute_list, _get_uniform_set_from_image(p_output), 1);
- RD::get_singleton()->compute_list_bind_uniform_set(compute_list, _get_compute_uniform_set_from_texture(p_metallic), 3);
}
+ RD::get_singleton()->compute_list_bind_uniform_set(compute_list, _get_compute_uniform_set_from_texture(p_metallic), 3);
RD::get_singleton()->compute_list_bind_uniform_set(compute_list, _get_uniform_set_from_image(p_scale_normal), 2);
RD::get_singleton()->compute_list_dispatch_threads(compute_list, p_screen_size.width, p_screen_size.height, 1);
@@ -732,6 +717,11 @@ void EffectsRD::tonemapper(RID p_source_color, RID p_dst_framebuffer, const Tone
tonemap.push_constant.pixel_size[0] = 1.0 / p_settings.texture_size.x;
tonemap.push_constant.pixel_size[1] = 1.0 / p_settings.texture_size.y;
+ if (p_settings.view_count > 1) {
+ // Use MULTIVIEW versions
+ mode += 4;
+ }
+
RD::DrawListID draw_list = RD::get_singleton()->draw_list_begin(p_dst_framebuffer, RD::INITIAL_ACTION_DROP, RD::FINAL_ACTION_READ, RD::INITIAL_ACTION_DROP, RD::FINAL_ACTION_DISCARD);
RD::get_singleton()->draw_list_bind_render_pipeline(draw_list, tonemap.pipelines[mode].get_render_pipeline(RD::INVALID_ID, RD::get_singleton()->framebuffer_get_format(p_dst_framebuffer)));
RD::get_singleton()->draw_list_bind_uniform_set(draw_list, _get_uniform_set_from_texture(p_source_color), 0);
@@ -934,10 +924,10 @@ void EffectsRD::bokeh_dof(RID p_base_texture, RID p_depth_texture, const Size2i
RD::get_singleton()->compute_list_end();
}
-void EffectsRD::gather_ssao(RD::ComputeListID p_compute_list, const Vector<RID> p_ao_slices, const SSAOSettings &p_settings, bool p_adaptive_base_pass) {
- RD::get_singleton()->compute_list_bind_uniform_set(p_compute_list, ssao.gather_uniform_set, 0);
+void EffectsRD::gather_ssao(RD::ComputeListID p_compute_list, const Vector<RID> p_ao_slices, const SSAOSettings &p_settings, bool p_adaptive_base_pass, RID p_gather_uniform_set, RID p_importance_map_uniform_set) {
+ RD::get_singleton()->compute_list_bind_uniform_set(p_compute_list, p_gather_uniform_set, 0);
if ((p_settings.quality == RS::ENV_SSAO_QUALITY_ULTRA) && !p_adaptive_base_pass) {
- RD::get_singleton()->compute_list_bind_uniform_set(p_compute_list, ssao.importance_map_uniform_set, 1);
+ RD::get_singleton()->compute_list_bind_uniform_set(p_compute_list, p_importance_map_uniform_set, 1);
}
for (int i = 0; i < 4; i++) {
@@ -960,7 +950,7 @@ void EffectsRD::gather_ssao(RD::ComputeListID p_compute_list, const Vector<RID>
RD::get_singleton()->compute_list_add_barrier(p_compute_list);
}
-void EffectsRD::generate_ssao(RID p_depth_buffer, RID p_normal_buffer, RID p_depth_mipmaps_texture, const Vector<RID> &p_depth_mipmaps, RID p_ao, const Vector<RID> p_ao_slices, RID p_ao_pong, const Vector<RID> p_ao_pong_slices, RID p_upscale_buffer, RID p_importance_map, RID p_importance_map_pong, const CameraMatrix &p_projection, const SSAOSettings &p_settings, bool p_invalidate_uniform_sets) {
+void EffectsRD::generate_ssao(RID p_depth_buffer, RID p_normal_buffer, RID p_depth_mipmaps_texture, const Vector<RID> &p_depth_mipmaps, RID p_ao, const Vector<RID> p_ao_slices, RID p_ao_pong, const Vector<RID> p_ao_pong_slices, RID p_upscale_buffer, RID p_importance_map, RID p_importance_map_pong, const CameraMatrix &p_projection, const SSAOSettings &p_settings, bool p_invalidate_uniform_sets, RID &r_downsample_uniform_set, RID &r_gather_uniform_set, RID &r_importance_map_uniform_set) {
RD::ComputeListID compute_list = RD::get_singleton()->compute_list_begin();
RD::get_singleton()->draw_command_begin_label("SSAO");
/* FIRST PASS */
@@ -990,7 +980,7 @@ void EffectsRD::generate_ssao(RID p_depth_buffer, RID p_normal_buffer, RID p_dep
u.ids.push_back(p_depth_mipmaps[3]);
uniforms.push_back(u);
}
- ssao.downsample_uniform_set = RD::get_singleton()->uniform_set_create(uniforms, ssao.downsample_shader.version_get_shader(ssao.downsample_shader_version, 2), 2);
+ r_downsample_uniform_set = RD::get_singleton()->uniform_set_create(uniforms, ssao.downsample_shader.version_get_shader(ssao.downsample_shader_version, 2), 2);
}
float depth_linearize_mul = -p_projection.matrix[3][2];
@@ -1025,7 +1015,7 @@ void EffectsRD::generate_ssao(RID p_depth_buffer, RID p_normal_buffer, RID p_dep
RD::get_singleton()->compute_list_bind_uniform_set(compute_list, _get_compute_uniform_set_from_texture(p_depth_buffer), 0);
RD::get_singleton()->compute_list_bind_uniform_set(compute_list, _get_uniform_set_from_image(p_depth_mipmaps[0]), 1);
if (p_settings.quality > RS::ENV_SSAO_QUALITY_MEDIUM) {
- RD::get_singleton()->compute_list_bind_uniform_set(compute_list, ssao.downsample_uniform_set, 2);
+ RD::get_singleton()->compute_list_bind_uniform_set(compute_list, r_downsample_uniform_set, 2);
}
RD::get_singleton()->compute_list_set_push_constant(compute_list, &ssao.downsample_push_constant, sizeof(SSAODownsamplePushConstant));
@@ -1109,7 +1099,7 @@ void EffectsRD::generate_ssao(RID p_depth_buffer, RID p_normal_buffer, RID p_dep
u.ids.push_back(ssao.gather_constants_buffer);
uniforms.push_back(u);
}
- ssao.gather_uniform_set = RD::get_singleton()->uniform_set_create(uniforms, ssao.gather_shader.version_get_shader(ssao.gather_shader_version, 0), 0);
+ r_gather_uniform_set = RD::get_singleton()->uniform_set_create(uniforms, ssao.gather_shader.version_get_shader(ssao.gather_shader_version, 0), 0);
}
if (p_invalidate_uniform_sets) {
@@ -1136,7 +1126,7 @@ void EffectsRD::generate_ssao(RID p_depth_buffer, RID p_normal_buffer, RID p_dep
u.ids.push_back(ssao.importance_map_load_counter);
uniforms.push_back(u);
}
- ssao.importance_map_uniform_set = RD::get_singleton()->uniform_set_create(uniforms, ssao.gather_shader.version_get_shader(ssao.gather_shader_version, 2), 1);
+ r_importance_map_uniform_set = RD::get_singleton()->uniform_set_create(uniforms, ssao.gather_shader.version_get_shader(ssao.gather_shader_version, 2), 1);
}
if (p_settings.quality == RS::ENV_SSAO_QUALITY_ULTRA) {
@@ -1147,7 +1137,7 @@ void EffectsRD::generate_ssao(RID p_depth_buffer, RID p_normal_buffer, RID p_dep
ssao.importance_map_push_constant.power = p_settings.power;
//base pass
RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, ssao.pipelines[SSAO_GATHER_BASE]);
- gather_ssao(compute_list, p_ao_pong_slices, p_settings, true);
+ gather_ssao(compute_list, p_ao_pong_slices, p_settings, true, r_gather_uniform_set, RID());
//generate importance map
RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, ssao.pipelines[SSAO_GENERATE_IMPORTANCE_MAP]);
@@ -1178,7 +1168,7 @@ void EffectsRD::generate_ssao(RID p_depth_buffer, RID p_normal_buffer, RID p_dep
RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, ssao.pipelines[SSAO_GATHER]);
}
- gather_ssao(compute_list, p_ao_slices, p_settings, false);
+ gather_ssao(compute_list, p_ao_slices, p_settings, false, r_gather_uniform_set, r_importance_map_uniform_set);
RD::get_singleton()->draw_command_end_label(); // Gather SSAO
}
@@ -1365,56 +1355,38 @@ void EffectsRD::cubemap_filter(RID p_source_cubemap, Vector<RID> p_dest_cubemap,
RD::get_singleton()->compute_list_end();
}
-void EffectsRD::render_sky(RD::DrawListID p_list, float p_time, RID p_fb, RID p_samplers, RID p_fog, PipelineCacheRD *p_pipeline, RID p_uniform_set, RID p_texture_set, const CameraMatrix &p_camera, const Basis &p_orientation, float p_multiplier, const Vector3 &p_position) {
- SkyPushConstant sky_push_constant;
-
- memset(&sky_push_constant, 0, sizeof(SkyPushConstant));
-
- sky_push_constant.proj[0] = p_camera.matrix[2][0];
- sky_push_constant.proj[1] = p_camera.matrix[0][0];
- sky_push_constant.proj[2] = p_camera.matrix[2][1];
- sky_push_constant.proj[3] = p_camera.matrix[1][1];
- sky_push_constant.position[0] = p_position.x;
- sky_push_constant.position[1] = p_position.y;
- sky_push_constant.position[2] = p_position.z;
- sky_push_constant.multiplier = p_multiplier;
- sky_push_constant.time = p_time;
- store_transform_3x3(p_orientation, sky_push_constant.orientation);
-
- RenderingDevice::FramebufferFormatID fb_format = RD::get_singleton()->framebuffer_get_format(p_fb);
-
- RD::DrawListID draw_list = p_list;
-
- RD::get_singleton()->draw_list_bind_render_pipeline(draw_list, p_pipeline->get_render_pipeline(RD::INVALID_ID, fb_format));
+void EffectsRD::resolve_gi(RID p_source_depth, RID p_source_normal_roughness, RID p_source_voxel_gi, RID p_dest_depth, RID p_dest_normal_roughness, RID p_dest_voxel_gi, Vector2i p_screen_size, int p_samples, uint32_t p_barrier) {
+ ResolvePushConstant push_constant;
+ push_constant.screen_size[0] = p_screen_size.x;
+ push_constant.screen_size[1] = p_screen_size.y;
+ push_constant.samples = p_samples;
- RD::get_singleton()->draw_list_bind_uniform_set(draw_list, p_samplers, 0);
- if (p_uniform_set.is_valid()) { //material may not have uniform set
- RD::get_singleton()->draw_list_bind_uniform_set(draw_list, p_uniform_set, 1);
+ RD::ComputeListID compute_list = RD::get_singleton()->compute_list_begin();
+ RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, resolve.pipelines[p_source_voxel_gi.is_valid() ? RESOLVE_MODE_GI_VOXEL_GI : RESOLVE_MODE_GI]);
+ RD::get_singleton()->compute_list_bind_uniform_set(compute_list, _get_compute_uniform_set_from_texture_pair(p_source_depth, p_source_normal_roughness), 0);
+ RD::get_singleton()->compute_list_bind_uniform_set(compute_list, _get_compute_uniform_set_from_image_pair(p_dest_depth, p_dest_normal_roughness), 1);
+ if (p_source_voxel_gi.is_valid()) {
+ RD::get_singleton()->compute_list_bind_uniform_set(compute_list, _get_compute_uniform_set_from_texture(p_source_voxel_gi), 2);
+ RD::get_singleton()->compute_list_bind_uniform_set(compute_list, _get_uniform_set_from_image(p_dest_voxel_gi), 3);
}
- RD::get_singleton()->draw_list_bind_uniform_set(draw_list, p_texture_set, 2);
- RD::get_singleton()->draw_list_bind_uniform_set(draw_list, p_fog, 3);
- RD::get_singleton()->draw_list_bind_index_array(draw_list, index_array);
+ RD::get_singleton()->compute_list_set_push_constant(compute_list, &push_constant, sizeof(ResolvePushConstant));
- RD::get_singleton()->draw_list_set_push_constant(draw_list, &sky_push_constant, sizeof(SkyPushConstant));
+ RD::get_singleton()->compute_list_dispatch_threads(compute_list, p_screen_size.x, p_screen_size.y, 1);
- RD::get_singleton()->draw_list_draw(draw_list, true);
+ RD::get_singleton()->compute_list_end(p_barrier);
}
-void EffectsRD::resolve_gi(RID p_source_depth, RID p_source_normal_roughness, RID p_source_giprobe, RID p_dest_depth, RID p_dest_normal_roughness, RID p_dest_giprobe, Vector2i p_screen_size, int p_samples, uint32_t p_barrier) {
+void EffectsRD::resolve_depth(RID p_source_depth, RID p_dest_depth, Vector2i p_screen_size, int p_samples, uint32_t p_barrier) {
ResolvePushConstant push_constant;
push_constant.screen_size[0] = p_screen_size.x;
push_constant.screen_size[1] = p_screen_size.y;
push_constant.samples = p_samples;
RD::ComputeListID compute_list = RD::get_singleton()->compute_list_begin();
- RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, resolve.pipelines[p_source_giprobe.is_valid() ? RESOLVE_MODE_GI_GIPROBE : RESOLVE_MODE_GI]);
- RD::get_singleton()->compute_list_bind_uniform_set(compute_list, _get_compute_uniform_set_from_texture_pair(p_source_depth, p_source_normal_roughness), 0);
- RD::get_singleton()->compute_list_bind_uniform_set(compute_list, _get_compute_uniform_set_from_image_pair(p_dest_depth, p_dest_normal_roughness), 1);
- if (p_source_giprobe.is_valid()) {
- RD::get_singleton()->compute_list_bind_uniform_set(compute_list, _get_compute_uniform_set_from_texture(p_source_giprobe), 2);
- RD::get_singleton()->compute_list_bind_uniform_set(compute_list, _get_uniform_set_from_image(p_dest_giprobe), 3);
- }
+ RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, resolve.pipelines[RESOLVE_MODE_DEPTH]);
+ RD::get_singleton()->compute_list_bind_uniform_set(compute_list, _get_compute_uniform_set_from_texture(p_source_depth), 0);
+ RD::get_singleton()->compute_list_bind_uniform_set(compute_list, _get_uniform_set_from_image(p_dest_depth), 1);
RD::get_singleton()->compute_list_set_push_constant(compute_list, &push_constant, sizeof(ResolvePushConstant));
@@ -1553,12 +1525,29 @@ EffectsRD::EffectsRD() {
tonemap_modes.push_back("\n#define USE_1D_LUT\n");
tonemap_modes.push_back("\n#define USE_GLOW_FILTER_BICUBIC\n#define USE_1D_LUT\n");
+ // multiview versions of our shaders
+ tonemap_modes.push_back("\n#define MULTIVIEW\n");
+ tonemap_modes.push_back("\n#define MULTIVIEW\n#define USE_GLOW_FILTER_BICUBIC\n");
+ tonemap_modes.push_back("\n#define MULTIVIEW\n#define USE_1D_LUT\n");
+ tonemap_modes.push_back("\n#define MULTIVIEW\n#define USE_GLOW_FILTER_BICUBIC\n#define USE_1D_LUT\n");
+
tonemap.shader.initialize(tonemap_modes);
+ if (!RendererCompositorRD::singleton->is_xr_enabled()) {
+ tonemap.shader.set_variant_enabled(TONEMAP_MODE_NORMAL_MULTIVIEW, false);
+ tonemap.shader.set_variant_enabled(TONEMAP_MODE_BICUBIC_GLOW_FILTER_MULTIVIEW, false);
+ tonemap.shader.set_variant_enabled(TONEMAP_MODE_1D_LUT_MULTIVIEW, false);
+ tonemap.shader.set_variant_enabled(TONEMAP_MODE_BICUBIC_GLOW_FILTER_1D_LUT_MULTIVIEW, false);
+ }
+
tonemap.shader_version = tonemap.shader.version_create();
for (int i = 0; i < TONEMAP_MODE_MAX; i++) {
- tonemap.pipelines[i].setup(tonemap.shader.version_get_shader(tonemap.shader_version, i), RD::RENDER_PRIMITIVE_TRIANGLES, RD::PipelineRasterizationState(), RD::PipelineMultisampleState(), RD::PipelineDepthStencilState(), RD::PipelineColorBlendState::create_disabled(), 0);
+ if (tonemap.shader.is_variant_enabled(i)) {
+ tonemap.pipelines[i].setup(tonemap.shader.version_get_shader(tonemap.shader_version, i), RD::RENDER_PRIMITIVE_TRIANGLES, RD::PipelineRasterizationState(), RD::PipelineMultisampleState(), RD::PipelineDepthStencilState(), RD::PipelineColorBlendState::create_disabled(), 0);
+ } else {
+ tonemap.pipelines[i].clear();
+ }
}
}
@@ -1907,7 +1896,8 @@ EffectsRD::EffectsRD() {
{
Vector<String> resolve_modes;
resolve_modes.push_back("\n#define MODE_RESOLVE_GI\n");
- resolve_modes.push_back("\n#define MODE_RESOLVE_GI\n#define GIPROBE_RESOLVE\n");
+ resolve_modes.push_back("\n#define MODE_RESOLVE_GI\n#define VOXEL_GI_RESOLVE\n");
+ resolve_modes.push_back("\n#define MODE_RESOLVE_DEPTH\n");
resolve.shader.initialize(resolve_modes);
diff --git a/servers/rendering/renderer_rd/effects_rd.h b/servers/rendering/renderer_rd/effects_rd.h
index 1ba25e301b..33d32f0c57 100644
--- a/servers/rendering/renderer_rd/effects_rd.h
+++ b/servers/rendering/renderer_rd/effects_rd.h
@@ -55,6 +55,7 @@
#include "servers/rendering/renderer_rd/shaders/ssao_interleave.glsl.gen.h"
#include "servers/rendering/renderer_rd/shaders/subsurface_scattering.glsl.gen.h"
#include "servers/rendering/renderer_rd/shaders/tonemap.glsl.gen.h"
+#include "servers/rendering/renderer_scene_render.h"
#include "servers/rendering_server.h"
@@ -170,6 +171,12 @@ class EffectsRD {
TONEMAP_MODE_BICUBIC_GLOW_FILTER,
TONEMAP_MODE_1D_LUT,
TONEMAP_MODE_BICUBIC_GLOW_FILTER_1D_LUT,
+
+ TONEMAP_MODE_NORMAL_MULTIVIEW,
+ TONEMAP_MODE_BICUBIC_GLOW_FILTER_MULTIVIEW,
+ TONEMAP_MODE_1D_LUT_MULTIVIEW,
+ TONEMAP_MODE_BICUBIC_GLOW_FILTER_1D_LUT_MULTIVIEW,
+
TONEMAP_MODE_MAX
};
@@ -378,12 +385,10 @@ class EffectsRD {
SSAODownsamplePushConstant downsample_push_constant;
SsaoDownsampleShaderRD downsample_shader;
RID downsample_shader_version;
- RID downsample_uniform_set;
SSAOGatherPushConstant gather_push_constant;
SsaoShaderRD gather_shader;
RID gather_shader_version;
- RID gather_uniform_set;
RID gather_constants_buffer;
bool gather_initialized = false;
@@ -391,7 +396,6 @@ class EffectsRD {
SsaoImportanceMapShaderRD importance_map_shader;
RID importance_map_shader_version;
RID importance_map_load_counter;
- RID importance_map_uniform_set;
RID counter_uniform_set;
SSAOBlurPushConstant blur_push_constant;
@@ -452,15 +456,6 @@ class EffectsRD {
} filter;
- struct SkyPushConstant {
- float orientation[12];
- float proj[4];
- float position[3];
- float multiplier;
- float time;
- float pad[3];
- };
-
enum SpecularMergeMode {
SPECULAR_MERGE_ADD,
SPECULAR_MERGE_SSR,
@@ -585,7 +580,8 @@ class EffectsRD {
enum ResolveMode {
RESOLVE_MODE_GI,
- RESOLVE_MODE_GI_GIPROBE,
+ RESOLVE_MODE_GI_VOXEL_GI,
+ RESOLVE_MODE_DEPTH,
RESOLVE_MODE_MAX
};
@@ -714,6 +710,7 @@ public:
bool use_fxaa = false;
bool use_debanding = false;
Vector2i texture_size;
+ uint32_t view_count = 1;
};
struct SSAOSettings {
@@ -738,19 +735,19 @@ public:
void tonemapper(RID p_source_color, RID p_dst_framebuffer, const TonemapSettings &p_settings);
- void gather_ssao(RD::ComputeListID p_compute_list, const Vector<RID> p_ao_slices, const SSAOSettings &p_settings, bool p_adaptive_base_pass);
- void generate_ssao(RID p_depth_buffer, RID p_normal_buffer, RID p_depth_mipmaps_texture, const Vector<RID> &depth_mipmaps, RID p_ao, const Vector<RID> p_ao_slices, RID p_ao_pong, const Vector<RID> p_ao_pong_slices, RID p_upscale_buffer, RID p_importance_map, RID p_importance_map_pong, const CameraMatrix &p_projection, const SSAOSettings &p_settings, bool p_invalidate_uniform_sets);
+ void gather_ssao(RD::ComputeListID p_compute_list, const Vector<RID> p_ao_slices, const SSAOSettings &p_settings, bool p_adaptive_base_pass, RID p_gather_uniform_set, RID p_importance_map_uniform_set);
+ void generate_ssao(RID p_depth_buffer, RID p_normal_buffer, RID p_depth_mipmaps_texture, const Vector<RID> &depth_mipmaps, RID p_ao, const Vector<RID> p_ao_slices, RID p_ao_pong, const Vector<RID> p_ao_pong_slices, RID p_upscale_buffer, RID p_importance_map, RID p_importance_map_pong, const CameraMatrix &p_projection, const SSAOSettings &p_settings, bool p_invalidate_uniform_sets, RID &r_downsample_uniform_set, RID &r_gather_uniform_set, RID &r_importance_map_uniform_set);
void roughness_limit(RID p_source_normal, RID p_roughness, const Size2i &p_size, float p_curve);
void cubemap_downsample(RID p_source_cubemap, RID p_dest_cubemap, const Size2i &p_size);
void cubemap_filter(RID p_source_cubemap, Vector<RID> p_dest_cubemap, bool p_use_array);
- void render_sky(RD::DrawListID p_list, float p_time, RID p_fb, RID p_samplers, RID p_fog, PipelineCacheRD *p_pipeline, RID p_uniform_set, RID p_texture_set, const CameraMatrix &p_camera, const Basis &p_orientation, float p_multiplier, const Vector3 &p_position);
void screen_space_reflection(RID p_diffuse, RID p_normal_roughness, RS::EnvironmentSSRRoughnessQuality p_roughness_quality, RID p_blur_radius, RID p_blur_radius2, RID p_metallic, const Color &p_metallic_mask, RID p_depth, RID p_scale_depth, RID p_scale_normal, RID p_output, RID p_output_blur, const Size2i &p_screen_size, int p_max_steps, float p_fade_in, float p_fade_out, float p_tolerance, const CameraMatrix &p_camera);
void merge_specular(RID p_dest_framebuffer, RID p_specular, RID p_base, RID p_reflection);
void sub_surface_scattering(RID p_diffuse, RID p_diffuse2, RID p_depth, const CameraMatrix &p_camera, const Size2i &p_screen_size, float p_scale, float p_depth_scale, RS::SubSurfaceScatteringQuality p_quality);
- void resolve_gi(RID p_source_depth, RID p_source_normal_roughness, RID p_source_giprobe, RID p_dest_depth, RID p_dest_normal_roughness, RID p_dest_giprobe, Vector2i p_screen_size, int p_samples, uint32_t p_barrier = RD::BARRIER_MASK_ALL);
+ void resolve_gi(RID p_source_depth, RID p_source_normal_roughness, RID p_source_voxel_gi, RID p_dest_depth, RID p_dest_normal_roughness, RID p_dest_voxel_gi, Vector2i p_screen_size, int p_samples, uint32_t p_barrier = RD::BARRIER_MASK_ALL);
+ void resolve_depth(RID p_source_depth, RID p_dest_depth, Vector2i p_screen_size, int p_samples, uint32_t p_barrier = RD::BARRIER_MASK_ALL);
void sort_buffer(RID p_uniform_set, int p_size);
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 16c6273ff6..22bfd03115 100644
--- a/servers/rendering/renderer_rd/forward_clustered/render_forward_clustered.cpp
+++ b/servers/rendering/renderer_rd/forward_clustered/render_forward_clustered.cpp
@@ -93,8 +93,8 @@ void RenderForwardClustered::RenderBufferDataForwardClustered::ensure_specular()
}
}
-void RenderForwardClustered::RenderBufferDataForwardClustered::ensure_giprobe() {
- if (!giprobe_buffer.is_valid()) {
+void RenderForwardClustered::RenderBufferDataForwardClustered::ensure_voxelgi() {
+ if (!voxelgi_buffer.is_valid()) {
RD::TextureFormat tf;
tf.format = RD::DATA_FORMAT_R8G8_UINT;
tf.width = width;
@@ -105,41 +105,41 @@ void RenderForwardClustered::RenderBufferDataForwardClustered::ensure_giprobe()
RD::TextureFormat tf_aa = tf;
tf_aa.usage_bits |= RD::TEXTURE_USAGE_COLOR_ATTACHMENT_BIT;
tf_aa.samples = texture_samples;
- giprobe_buffer_msaa = RD::get_singleton()->texture_create(tf_aa, RD::TextureView());
+ voxelgi_buffer_msaa = RD::get_singleton()->texture_create(tf_aa, RD::TextureView());
} else {
tf.usage_bits |= RD::TEXTURE_USAGE_COLOR_ATTACHMENT_BIT;
}
tf.usage_bits |= RD::TEXTURE_USAGE_STORAGE_BIT;
- giprobe_buffer = RD::get_singleton()->texture_create(tf, RD::TextureView());
+ voxelgi_buffer = RD::get_singleton()->texture_create(tf, RD::TextureView());
Vector<RID> fb;
if (msaa != RS::VIEWPORT_MSAA_DISABLED) {
fb.push_back(depth_msaa);
fb.push_back(normal_roughness_buffer_msaa);
- fb.push_back(giprobe_buffer_msaa);
+ fb.push_back(voxelgi_buffer_msaa);
} else {
fb.push_back(depth);
fb.push_back(normal_roughness_buffer);
- fb.push_back(giprobe_buffer);
+ fb.push_back(voxelgi_buffer);
}
- depth_normal_roughness_giprobe_fb = RD::get_singleton()->framebuffer_create(fb);
+ depth_normal_roughness_voxelgi_fb = RD::get_singleton()->framebuffer_create(fb);
}
}
void RenderForwardClustered::RenderBufferDataForwardClustered::clear() {
- if (giprobe_buffer != RID()) {
- RD::get_singleton()->free(giprobe_buffer);
- giprobe_buffer = RID();
+ if (voxelgi_buffer != RID()) {
+ RD::get_singleton()->free(voxelgi_buffer);
+ voxelgi_buffer = RID();
- if (giprobe_buffer_msaa.is_valid()) {
- RD::get_singleton()->free(giprobe_buffer_msaa);
- giprobe_buffer_msaa = RID();
+ if (voxelgi_buffer_msaa.is_valid()) {
+ RD::get_singleton()->free(voxelgi_buffer_msaa);
+ voxelgi_buffer_msaa = RID();
}
- depth_normal_roughness_giprobe_fb = RID();
+ depth_normal_roughness_voxelgi_fb = RID();
}
if (color_msaa.is_valid()) {
@@ -183,9 +183,11 @@ void RenderForwardClustered::RenderBufferDataForwardClustered::clear() {
}
}
-void RenderForwardClustered::RenderBufferDataForwardClustered::configure(RID p_color_buffer, RID p_depth_buffer, int p_width, int p_height, RS::ViewportMSAA p_msaa) {
+void RenderForwardClustered::RenderBufferDataForwardClustered::configure(RID p_color_buffer, RID p_depth_buffer, int p_width, int p_height, RS::ViewportMSAA p_msaa, uint32_t p_view_count) {
clear();
+ ERR_FAIL_COND_MSG(p_view_count != 1, "Multiple views is currently not supported in this renderer, please use the mobile renderer for VR support");
+
msaa = p_msaa;
width = p_width;
@@ -343,8 +345,20 @@ void RenderForwardClustered::_render_list_template(RenderingDevice::DrawListID p
mesh_surface = surf->surface_shadow;
} else {
- material_uniform_set = surf->material_uniform_set;
- shader = surf->shader;
+#ifdef DEBUG_ENABLED
+ if (unlikely(get_debug_draw_mode() == RS::VIEWPORT_DEBUG_DRAW_LIGHTING)) {
+ material_uniform_set = scene_shader.default_material_uniform_set;
+ shader = scene_shader.default_material_shader_ptr;
+ } else if (unlikely(get_debug_draw_mode() == RS::VIEWPORT_DEBUG_DRAW_OVERDRAW)) {
+ material_uniform_set = scene_shader.overdraw_material_uniform_set;
+ shader = scene_shader.overdraw_material_shader_ptr;
+ } else {
+#endif
+ material_uniform_set = surf->material_uniform_set;
+ shader = surf->shader;
+#ifdef DEBUG_ENABLED
+ }
+#endif
mesh_surface = surf->surface;
}
@@ -398,8 +412,8 @@ void RenderForwardClustered::_render_list_template(RenderingDevice::DrawListID p
case PASS_MODE_DEPTH_NORMAL_ROUGHNESS: {
shader_version = SceneShaderForwardClustered::SHADER_VERSION_DEPTH_PASS_WITH_NORMAL_AND_ROUGHNESS;
} break;
- case PASS_MODE_DEPTH_NORMAL_ROUGHNESS_GIPROBE: {
- shader_version = SceneShaderForwardClustered::SHADER_VERSION_DEPTH_PASS_WITH_NORMAL_AND_ROUGHNESS_AND_GIPROBE;
+ case PASS_MODE_DEPTH_NORMAL_ROUGHNESS_VOXEL_GI: {
+ shader_version = SceneShaderForwardClustered::SHADER_VERSION_DEPTH_PASS_WITH_NORMAL_AND_ROUGHNESS_AND_VOXEL_GI;
} break;
case PASS_MODE_DEPTH_MATERIAL: {
shader_version = SceneShaderForwardClustered::SHADER_VERSION_DEPTH_PASS_WITH_MATERIAL;
@@ -498,8 +512,8 @@ void RenderForwardClustered::_render_list(RenderingDevice::DrawListID p_draw_lis
case PASS_MODE_DEPTH_NORMAL_ROUGHNESS: {
_render_list_template<PASS_MODE_DEPTH_NORMAL_ROUGHNESS>(p_draw_list, p_framebuffer_Format, p_params, p_from_element, p_to_element);
} break;
- case PASS_MODE_DEPTH_NORMAL_ROUGHNESS_GIPROBE: {
- _render_list_template<PASS_MODE_DEPTH_NORMAL_ROUGHNESS_GIPROBE>(p_draw_list, p_framebuffer_Format, p_params, p_from_element, p_to_element);
+ case PASS_MODE_DEPTH_NORMAL_ROUGHNESS_VOXEL_GI: {
+ _render_list_template<PASS_MODE_DEPTH_NORMAL_ROUGHNESS_VOXEL_GI>(p_draw_list, p_framebuffer_Format, p_params, p_from_element, p_to_element);
} break;
case PASS_MODE_DEPTH_MATERIAL: {
_render_list_template<PASS_MODE_DEPTH_MATERIAL>(p_draw_list, p_framebuffer_Format, p_params, p_from_element, p_to_element);
@@ -799,13 +813,16 @@ void RenderForwardClustered::_update_instance_data_buffer(RenderListType p_rende
RD::get_singleton()->buffer_update(scene_state.instance_buffer[p_render_list], 0, sizeof(SceneState::InstanceData) * scene_state.instance_data[p_render_list].size(), scene_state.instance_data[p_render_list].ptr(), RD::BARRIER_MASK_RASTER);
}
}
-void RenderForwardClustered::_fill_instance_data(RenderListType p_render_list, uint32_t p_offset, int32_t p_max_elements, bool p_update_buffer) {
+void RenderForwardClustered::_fill_instance_data(RenderListType p_render_list, int *p_render_info, uint32_t p_offset, int32_t p_max_elements, bool p_update_buffer) {
RenderList *rl = &render_list[p_render_list];
uint32_t element_total = p_max_elements >= 0 ? uint32_t(p_max_elements) : rl->elements.size();
scene_state.instance_data[p_render_list].resize(p_offset + element_total);
rl->element_info.resize(p_offset + element_total);
+ if (p_render_info) {
+ p_render_info[RS::VIEWPORT_RENDER_INFO_OBJECTS_IN_FRAME] += element_total;
+ }
uint32_t repeats = 0;
GeometryInstanceSurfaceDataCache *prev_surface = nullptr;
for (uint32_t i = 0; i < element_total; i++) {
@@ -817,7 +834,7 @@ void RenderForwardClustered::_fill_instance_data(RenderListType p_render_list, u
if (inst->store_transform_cache) {
RendererStorageRD::store_transform(inst->transform, instance_data.transform);
} else {
- RendererStorageRD::store_transform(Transform(), instance_data.transform);
+ RendererStorageRD::store_transform(Transform3D(), instance_data.transform);
}
instance_data.flags = inst->flags_cache;
@@ -841,6 +858,9 @@ void RenderForwardClustered::_fill_instance_data(RenderListType p_render_list, u
}
}
repeats = 1;
+ if (p_render_info) {
+ p_render_info[RS::VIEWPORT_RENDER_INFO_DRAW_CALLS_IN_FRAME]++;
+ }
}
RenderElementInfo &element_info = rl->element_info[p_offset + i];
@@ -867,6 +887,11 @@ void RenderForwardClustered::_fill_instance_data(RenderListType p_render_list, u
}
}
+_FORCE_INLINE_ static uint32_t _indices_to_primitives(RS::PrimitiveType p_primitive, uint32_t p_indices) {
+ static const uint32_t divisor[RS::PRIMITIVE_MAX] = { 1, 2, 1, 3, 1 };
+ static const uint32_t subtractor[RS::PRIMITIVE_MAX] = { 0, 0, 1, 0, 1 };
+ return (p_indices - subtractor[p_primitive]) / divisor[p_primitive];
+}
void RenderForwardClustered::_fill_render_list(RenderListType p_render_list, const RenderDataRD *p_render_data, PassMode p_pass_mode, bool p_using_sdfgi, bool p_using_opaque_gi, bool p_append) {
if (p_render_list == RENDER_LIST_OPAQUE) {
scene_state.used_sss = false;
@@ -901,6 +926,9 @@ void RenderForwardClustered::_fill_render_list(RenderListType p_render_list, con
uint32_t flags = inst->base_flags; //fill flags if appropriate
+ if (inst->non_uniform_scale) {
+ flags |= INSTANCE_DATA_FLAGS_NON_UNIFORM_SCALE;
+ }
bool uses_lightmap = false;
bool uses_gi = false;
@@ -948,14 +976,14 @@ void RenderForwardClustered::_fill_render_list(RenderListType p_render_list, con
flags |= INSTANCE_DATA_FLAG_USE_GI_BUFFERS;
}
- if (inst->gi_probes[0].is_valid()) {
+ if (inst->voxel_gi_instances[0].is_valid()) {
uint32_t probe0_index = 0xFFFF;
uint32_t probe1_index = 0xFFFF;
- for (uint32_t j = 0; j < scene_state.giprobes_used; j++) {
- if (scene_state.giprobe_ids[j] == inst->gi_probes[0]) {
+ for (uint32_t j = 0; j < scene_state.voxelgis_used; j++) {
+ if (scene_state.voxelgi_ids[j] == inst->voxel_gi_instances[0]) {
probe0_index = j;
- } else if (scene_state.giprobe_ids[j] == inst->gi_probes[1]) {
+ } else if (scene_state.voxelgi_ids[j] == inst->voxel_gi_instances[1]) {
probe1_index = j;
}
}
@@ -966,7 +994,7 @@ void RenderForwardClustered::_fill_render_list(RenderListType p_render_list, con
}
inst->gi_offset_cache = probe0_index | (probe1_index << 16);
- flags |= INSTANCE_DATA_FLAG_USE_GIPROBE;
+ flags |= INSTANCE_DATA_FLAG_USE_VOXEL_GI;
uses_gi = true;
} else {
if (p_using_sdfgi && inst->can_sdfgi) {
@@ -1006,17 +1034,41 @@ void RenderForwardClustered::_fill_render_list(RenderListType p_render_list, con
distance = -distance_max;
}
- surf->sort.lod_index = storage->mesh_surface_get_lod(surf->surface, inst->lod_model_scale * inst->lod_bias, distance * p_render_data->lod_distance_multiplier, p_render_data->screen_lod_threshold);
+ uint32_t indices;
+ surf->sort.lod_index = storage->mesh_surface_get_lod(surf->surface, inst->lod_model_scale * inst->lod_bias, distance * p_render_data->lod_distance_multiplier, p_render_data->screen_lod_threshold, &indices);
+ if (p_render_data->render_info) {
+ indices = _indices_to_primitives(surf->primitive, indices);
+ if (p_render_list == RENDER_LIST_OPAQUE) { //opaque
+ p_render_data->render_info->info[RS::VIEWPORT_RENDER_INFO_TYPE_VISIBLE][RS::VIEWPORT_RENDER_INFO_PRIMITIVES_IN_FRAME] += indices;
+ } else if (p_render_list == RENDER_LIST_SECONDARY) { //shadow
+ p_render_data->render_info->info[RS::VIEWPORT_RENDER_INFO_TYPE_SHADOW][RS::VIEWPORT_RENDER_INFO_PRIMITIVES_IN_FRAME] += indices;
+ }
+ }
} else {
surf->sort.lod_index = 0;
+ if (p_render_data->render_info) {
+ uint32_t to_draw = storage->mesh_surface_get_vertices_drawn_count(surf->surface);
+ to_draw = _indices_to_primitives(surf->primitive, to_draw);
+ to_draw *= inst->instance_count;
+ if (p_render_list == RENDER_LIST_OPAQUE) { //opaque
+ p_render_data->render_info->info[RS::VIEWPORT_RENDER_INFO_TYPE_VISIBLE][RS::VIEWPORT_RENDER_INFO_PRIMITIVES_IN_FRAME] += storage->mesh_surface_get_vertices_drawn_count(surf->surface);
+ } else if (p_render_list == RENDER_LIST_SECONDARY) { //shadow
+ p_render_data->render_info->info[RS::VIEWPORT_RENDER_INFO_TYPE_SHADOW][RS::VIEWPORT_RENDER_INFO_PRIMITIVES_IN_FRAME] += storage->mesh_surface_get_vertices_drawn_count(surf->surface);
+ }
+ }
}
// ADD Element
if (p_pass_mode == PASS_MODE_COLOR) {
- if (surf->flags & (GeometryInstanceSurfaceDataCache::FLAG_PASS_DEPTH | GeometryInstanceSurfaceDataCache::FLAG_PASS_OPAQUE)) {
+#ifdef DEBUG_ENABLED
+ bool force_alpha = unlikely(get_debug_draw_mode() == RS::VIEWPORT_DEBUG_DRAW_OVERDRAW);
+#else
+ bool force_alpha = false;
+#endif
+ if (!force_alpha && (surf->flags & (GeometryInstanceSurfaceDataCache::FLAG_PASS_DEPTH | GeometryInstanceSurfaceDataCache::FLAG_PASS_OPAQUE))) {
rl->add_element(surf);
}
- if (surf->flags & GeometryInstanceSurfaceDataCache::FLAG_PASS_ALPHA) {
+ if (force_alpha || (surf->flags & GeometryInstanceSurfaceDataCache::FLAG_PASS_ALPHA)) {
render_list[RENDER_LIST_ALPHA].add_element(surf);
if (uses_gi) {
surf->sort.uses_forward_gi = 1;
@@ -1061,14 +1113,14 @@ void RenderForwardClustered::_fill_render_list(RenderListType p_render_list, con
}
}
-void RenderForwardClustered::_setup_giprobes(const PagedArray<RID> &p_giprobes) {
- scene_state.giprobes_used = MIN(p_giprobes.size(), uint32_t(MAX_GI_PROBES));
- for (uint32_t i = 0; i < scene_state.giprobes_used; i++) {
- scene_state.giprobe_ids[i] = p_giprobes[i];
+void RenderForwardClustered::_setup_voxelgis(const PagedArray<RID> &p_voxelgis) {
+ scene_state.voxelgis_used = MIN(p_voxelgis.size(), uint32_t(MAX_VOXEL_GI_INSTANCESS));
+ for (uint32_t i = 0; i < scene_state.voxelgis_used; i++) {
+ scene_state.voxelgi_ids[i] = p_voxelgis[i];
}
}
-void RenderForwardClustered::_setup_lightmaps(const PagedArray<RID> &p_lightmaps, const Transform &p_cam_transform) {
+void RenderForwardClustered::_setup_lightmaps(const PagedArray<RID> &p_lightmaps, const Transform3D &p_cam_transform) {
scene_state.lightmaps_used = 0;
for (int i = 0; i < (int)p_lightmaps.size(); i++) {
if (i >= (int)scene_state.max_lightmaps) {
@@ -1091,11 +1143,14 @@ void RenderForwardClustered::_setup_lightmaps(const PagedArray<RID> &p_lightmaps
}
void RenderForwardClustered::_render_scene(RenderDataRD *p_render_data, const Color &p_default_bg_color) {
+ ERR_FAIL_COND_MSG(p_render_data->view_count != 1, "Multiview is currently not supported in the clustered renderer. Please use the mobile renderer for VR.");
+
RenderBufferDataForwardClustered *render_buffer = nullptr;
if (p_render_data->render_buffers.is_valid()) {
render_buffer = (RenderBufferDataForwardClustered *)render_buffers_get_data(p_render_data->render_buffers);
}
RendererSceneEnvironmentRD *env = get_environment(p_render_data->environment);
+ static const int texture_multisamples[RS::VIEWPORT_MSAA_MAX] = { 1, 2, 4, 8, 16 };
//first of all, make a new render pass
//fill up ubo
@@ -1120,7 +1175,7 @@ void RenderForwardClustered::_render_scene(RenderDataRD *p_render_data, const Co
bool using_separate_specular = false;
bool using_ssr = false;
bool using_sdfgi = false;
- bool using_giprobe = false;
+ bool using_voxelgi = false;
bool reverse_cull = false;
if (render_buffer) {
@@ -1129,19 +1184,19 @@ void RenderForwardClustered::_render_scene(RenderDataRD *p_render_data, const Co
opaque_framebuffer = render_buffer->color_fb;
- if (p_render_data->gi_probes->size() > 0) {
- using_giprobe = true;
+ if (p_render_data->voxel_gi_instances->size() > 0) {
+ using_voxelgi = true;
}
- if (!p_render_data->environment.is_valid() && using_giprobe) {
- depth_pass_mode = PASS_MODE_DEPTH_NORMAL_ROUGHNESS_GIPROBE;
+ if (!p_render_data->environment.is_valid() && using_voxelgi) {
+ depth_pass_mode = PASS_MODE_DEPTH_NORMAL_ROUGHNESS_VOXEL_GI;
- } else if (p_render_data->environment.is_valid() && (environment_is_ssr_enabled(p_render_data->environment) || environment_is_sdfgi_enabled(p_render_data->environment) || using_giprobe)) {
+ } else if (p_render_data->environment.is_valid() && (environment_is_ssr_enabled(p_render_data->environment) || environment_is_sdfgi_enabled(p_render_data->environment) || using_voxelgi)) {
if (environment_is_sdfgi_enabled(p_render_data->environment)) {
- depth_pass_mode = using_giprobe ? PASS_MODE_DEPTH_NORMAL_ROUGHNESS_GIPROBE : PASS_MODE_DEPTH_NORMAL_ROUGHNESS; // also giprobe
+ depth_pass_mode = using_voxelgi ? PASS_MODE_DEPTH_NORMAL_ROUGHNESS_VOXEL_GI : PASS_MODE_DEPTH_NORMAL_ROUGHNESS; // also voxelgi
using_sdfgi = true;
} else {
- depth_pass_mode = using_giprobe ? PASS_MODE_DEPTH_NORMAL_ROUGHNESS_GIPROBE : PASS_MODE_DEPTH_NORMAL_ROUGHNESS;
+ depth_pass_mode = using_voxelgi ? PASS_MODE_DEPTH_NORMAL_ROUGHNESS_VOXEL_GI : PASS_MODE_DEPTH_NORMAL_ROUGHNESS;
}
if (environment_is_ssr_enabled(p_render_data->environment)) {
@@ -1164,10 +1219,10 @@ void RenderForwardClustered::_render_scene(RenderDataRD *p_render_data, const Co
depth_framebuffer = render_buffer->depth_normal_roughness_fb;
depth_pass_clear.push_back(Color(0.5, 0.5, 0.5, 0));
} break;
- case PASS_MODE_DEPTH_NORMAL_ROUGHNESS_GIPROBE: {
+ case PASS_MODE_DEPTH_NORMAL_ROUGHNESS_VOXEL_GI: {
_allocate_normal_roughness_texture(render_buffer);
- render_buffer->ensure_giprobe();
- depth_framebuffer = render_buffer->depth_normal_roughness_giprobe_fb;
+ render_buffer->ensure_voxelgi();
+ depth_framebuffer = render_buffer->depth_normal_roughness_voxelgi_fb;
depth_pass_clear.push_back(Color(0.5, 0.5, 0.5, 0));
depth_pass_clear.push_back(Color(0, 0, 0, 0));
} break;
@@ -1198,15 +1253,15 @@ void RenderForwardClustered::_render_scene(RenderDataRD *p_render_data, const Co
RD::get_singleton()->draw_command_begin_label("Render Setup");
_setup_lightmaps(*p_render_data->lightmaps, p_render_data->cam_transform);
- _setup_giprobes(*p_render_data->gi_probes);
+ _setup_voxelgis(*p_render_data->voxel_gi_instances);
_setup_environment(p_render_data, p_render_data->reflection_probe.is_valid(), screen_size, !p_render_data->reflection_probe.is_valid(), p_default_bg_color, false);
_update_render_base_uniform_set(); //may have changed due to the above (light buffer enlarged, as an example)
- _fill_render_list(RENDER_LIST_OPAQUE, p_render_data, PASS_MODE_COLOR, using_sdfgi, using_sdfgi || using_giprobe);
+ _fill_render_list(RENDER_LIST_OPAQUE, p_render_data, PASS_MODE_COLOR, using_sdfgi, using_sdfgi || using_voxelgi);
render_list[RENDER_LIST_OPAQUE].sort_by_key();
- render_list[RENDER_LIST_ALPHA].sort_by_depth();
- _fill_instance_data(RENDER_LIST_OPAQUE);
+ render_list[RENDER_LIST_ALPHA].sort_by_reverse_depth_and_priority();
+ _fill_instance_data(RENDER_LIST_OPAQUE, p_render_data->render_info ? p_render_data->render_info->info[RS::VIEWPORT_RENDER_INFO_TYPE_VISIBLE] : (int *)nullptr);
_fill_instance_data(RENDER_LIST_ALPHA);
RD::get_singleton()->draw_command_end_label();
@@ -1293,7 +1348,7 @@ void RenderForwardClustered::_render_scene(RenderDataRD *p_render_data, const Co
clear_color = p_default_bg_color;
}
- bool debug_giprobes = get_debug_draw_mode() == RS::VIEWPORT_DEBUG_DRAW_GI_PROBE_ALBEDO || get_debug_draw_mode() == RS::VIEWPORT_DEBUG_DRAW_GI_PROBE_LIGHTING || get_debug_draw_mode() == RS::VIEWPORT_DEBUG_DRAW_GI_PROBE_EMISSION;
+ 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 = depth_framebuffer.is_valid();
@@ -1301,7 +1356,7 @@ void RenderForwardClustered::_render_scene(RenderDataRD *p_render_data, const Co
bool continue_depth = false;
if (depth_pre_pass) { //depth pre pass
- bool needs_pre_resolve = _needs_post_prepass_render(p_render_data, using_sdfgi || using_giprobe);
+ 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)");
} else {
@@ -1312,34 +1367,33 @@ void RenderForwardClustered::_render_scene(RenderDataRD *p_render_data, const Co
RD::get_singleton()->draw_list_begin(depth_framebuffer, RD::INITIAL_ACTION_CLEAR, RD::FINAL_ACTION_CONTINUE, RD::INITIAL_ACTION_CLEAR, RD::FINAL_ACTION_CONTINUE, depth_pass_clear);
RD::get_singleton()->draw_list_end();
//start compute processes here, so they run at the same time as depth pre-pass
- _post_prepass_render(p_render_data, using_sdfgi || using_giprobe);
+ _post_prepass_render(p_render_data, using_sdfgi || using_voxelgi);
}
RD::get_singleton()->draw_command_begin_label("Render Depth Pre-Pass");
RID rp_uniform_set = _setup_render_pass_uniform_set(RENDER_LIST_OPAQUE, nullptr, RID());
- bool finish_depth = using_ssao || using_sdfgi || using_giprobe;
+ bool finish_depth = using_ssao || using_sdfgi || using_voxelgi;
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, render_buffer == nullptr, rp_uniform_set, get_debug_draw_mode() == RS::VIEWPORT_DEBUG_DRAW_WIREFRAME, Vector2(), p_render_data->lod_camera_plane, p_render_data->lod_distance_multiplier, p_render_data->screen_lod_threshold);
_render_list_with_threads(&render_list_params, depth_framebuffer, needs_pre_resolve ? RD::INITIAL_ACTION_CONTINUE : RD::INITIAL_ACTION_CLEAR, RD::FINAL_ACTION_READ, needs_pre_resolve ? RD::INITIAL_ACTION_CONTINUE : RD::INITIAL_ACTION_CLEAR, finish_depth ? RD::FINAL_ACTION_READ : RD::FINAL_ACTION_CONTINUE, needs_pre_resolve ? Vector<Color>() : depth_pass_clear);
RD::get_singleton()->draw_command_end_label();
if (needs_pre_resolve) {
- _pre_resolve_render(p_render_data, using_sdfgi || using_giprobe);
+ _pre_resolve_render(p_render_data, using_sdfgi || using_voxelgi);
}
if (render_buffer && render_buffer->msaa != RS::VIEWPORT_MSAA_DISABLED) {
RENDER_TIMESTAMP("Resolve Depth Pre-Pass");
RD::get_singleton()->draw_command_begin_label("Resolve Depth Pre-Pass");
- if (depth_pass_mode == PASS_MODE_DEPTH_NORMAL_ROUGHNESS || depth_pass_mode == PASS_MODE_DEPTH_NORMAL_ROUGHNESS_GIPROBE) {
+ if (depth_pass_mode == PASS_MODE_DEPTH_NORMAL_ROUGHNESS || depth_pass_mode == PASS_MODE_DEPTH_NORMAL_ROUGHNESS_VOXEL_GI) {
if (needs_pre_resolve) {
RD::get_singleton()->barrier(RD::BARRIER_MASK_RASTER, RD::BARRIER_MASK_COMPUTE);
}
- static int texture_samples[RS::VIEWPORT_MSAA_MAX] = { 1, 2, 4, 8, 16 };
- storage->get_effects()->resolve_gi(render_buffer->depth_msaa, render_buffer->normal_roughness_buffer_msaa, using_giprobe ? render_buffer->giprobe_buffer_msaa : RID(), render_buffer->depth, render_buffer->normal_roughness_buffer, using_giprobe ? render_buffer->giprobe_buffer : RID(), Vector2i(render_buffer->width, render_buffer->height), texture_samples[render_buffer->msaa]);
+ storage->get_effects()->resolve_gi(render_buffer->depth_msaa, render_buffer->normal_roughness_buffer_msaa, using_voxelgi ? render_buffer->voxelgi_buffer_msaa : RID(), render_buffer->depth, render_buffer->normal_roughness_buffer, using_voxelgi ? render_buffer->voxelgi_buffer : RID(), Vector2i(render_buffer->width, render_buffer->height), texture_multisamples[render_buffer->msaa]);
} else if (finish_depth) {
- RD::get_singleton()->texture_resolve_multisample(render_buffer->depth_msaa, render_buffer->depth);
+ storage->get_effects()->resolve_depth(render_buffer->depth_msaa, render_buffer->depth, Vector2i(render_buffer->width, render_buffer->height), texture_multisamples[render_buffer->msaa]);
}
RD::get_singleton()->draw_command_end_label();
}
@@ -1347,7 +1401,7 @@ void RenderForwardClustered::_render_scene(RenderDataRD *p_render_data, const Co
continue_depth = !finish_depth;
}
- _pre_opaque_render(p_render_data, using_ssao, using_sdfgi || using_giprobe, render_buffer ? render_buffer->normal_roughness_buffer : RID(), render_buffer ? render_buffer->giprobe_buffer : RID());
+ _pre_opaque_render(p_render_data, using_ssao, using_sdfgi || using_voxelgi, render_buffer ? render_buffer->normal_roughness_buffer : RID(), render_buffer ? render_buffer->voxelgi_buffer : RID());
RD::get_singleton()->draw_command_begin_label("Render Opaque Pass");
@@ -1363,8 +1417,8 @@ void RenderForwardClustered::_render_scene(RenderDataRD *p_render_data, const Co
bool can_continue_depth = !scene_state.used_depth_texture && !using_ssr && !using_sss;
{
- bool will_continue_color = (can_continue_color || draw_sky || draw_sky_fog_only || debug_giprobes || debug_sdfgi_probes);
- bool will_continue_depth = (can_continue_depth || draw_sky || draw_sky_fog_only || debug_giprobes || debug_sdfgi_probes);
+ bool will_continue_color = (can_continue_color || draw_sky || draw_sky_fog_only || debug_voxelgis || debug_sdfgi_probes);
+ bool will_continue_depth = (can_continue_depth || draw_sky || draw_sky_fog_only || debug_voxelgis || debug_sdfgi_probes);
//regular forward for now
Vector<Color> c;
@@ -1389,8 +1443,8 @@ void RenderForwardClustered::_render_scene(RenderDataRD *p_render_data, const Co
RD::get_singleton()->draw_command_end_label();
- if (debug_giprobes) {
- //debug giprobes
+ if (debug_voxelgis) {
+ //debug voxelgis
bool will_continue_color = (can_continue_color || draw_sky || draw_sky_fog_only);
bool will_continue_depth = (can_continue_depth || draw_sky || draw_sky_fog_only);
@@ -1398,16 +1452,16 @@ void RenderForwardClustered::_render_scene(RenderDataRD *p_render_data, const Co
dc.set_depth_correction(true);
CameraMatrix cm = (dc * p_render_data->cam_projection) * CameraMatrix(p_render_data->cam_transform.affine_inverse());
RD::DrawListID draw_list = RD::get_singleton()->draw_list_begin(opaque_framebuffer, RD::INITIAL_ACTION_CONTINUE, will_continue_color ? RD::FINAL_ACTION_CONTINUE : RD::FINAL_ACTION_READ, RD::INITIAL_ACTION_CONTINUE, will_continue_depth ? RD::FINAL_ACTION_CONTINUE : RD::FINAL_ACTION_READ);
- RD::get_singleton()->draw_command_begin_label("Debug GIProbes");
- for (int i = 0; i < (int)p_render_data->gi_probes->size(); i++) {
- gi.debug_giprobe((*p_render_data->gi_probes)[i], draw_list, opaque_framebuffer, cm, get_debug_draw_mode() == RS::VIEWPORT_DEBUG_DRAW_GI_PROBE_LIGHTING, get_debug_draw_mode() == RS::VIEWPORT_DEBUG_DRAW_GI_PROBE_EMISSION, 1.0);
+ RD::get_singleton()->draw_command_begin_label("Debug VoxelGIs");
+ for (int i = 0; i < (int)p_render_data->voxel_gi_instances->size(); i++) {
+ gi.debug_voxel_gi((*p_render_data->voxel_gi_instances)[i], draw_list, opaque_framebuffer, cm, get_debug_draw_mode() == RS::VIEWPORT_DEBUG_DRAW_VOXEL_GI_LIGHTING, get_debug_draw_mode() == RS::VIEWPORT_DEBUG_DRAW_VOXEL_GI_EMISSION, 1.0);
}
RD::get_singleton()->draw_command_end_label();
RD::get_singleton()->draw_list_end();
}
if (debug_sdfgi_probes) {
- //debug giprobes
+ //debug voxelgis
bool will_continue_color = (can_continue_color || draw_sky || draw_sky_fog_only);
bool will_continue_depth = (can_continue_depth || draw_sky || draw_sky_fog_only);
@@ -1431,7 +1485,7 @@ void RenderForwardClustered::_render_scene(RenderDataRD *p_render_data, const Co
projection = correction * p_render_data->cam_projection;
}
RD::get_singleton()->draw_command_begin_label("Draw Sky");
- sky.draw(env, can_continue_color, can_continue_depth, opaque_framebuffer, projection, p_render_data->cam_transform, time);
+ sky.draw(env, can_continue_color, can_continue_depth, opaque_framebuffer, 1, &projection, p_render_data->cam_transform, time);
RD::get_singleton()->draw_command_end_label();
}
@@ -1443,7 +1497,7 @@ void RenderForwardClustered::_render_scene(RenderDataRD *p_render_data, const Co
}
if (render_buffer && !can_continue_depth && render_buffer->msaa != RS::VIEWPORT_MSAA_DISABLED) {
- RD::get_singleton()->texture_resolve_multisample(render_buffer->depth_msaa, render_buffer->depth);
+ storage->get_effects()->resolve_depth(render_buffer->depth_msaa, render_buffer->depth, Vector2i(render_buffer->width, render_buffer->height), texture_multisamples[render_buffer->msaa]);
}
if (using_separate_specular) {
@@ -1498,7 +1552,8 @@ void RenderForwardClustered::_render_shadow_begin() {
render_list[RENDER_LIST_SECONDARY].clear();
scene_state.instance_data[RENDER_LIST_SECONDARY].clear();
}
-void RenderForwardClustered::_render_shadow_append(RID p_framebuffer, const PagedArray<GeometryInstance *> &p_instances, const CameraMatrix &p_projection, const Transform &p_transform, float p_zfar, float p_bias, float p_normal_bias, bool p_use_dp, bool p_use_dp_flip, bool p_use_pancake, const Plane &p_camera_plane, float p_lod_distance_multiplier, float p_screen_lod_threshold, const Rect2i &p_rect, bool p_flip_y, bool p_clear_region, bool p_begin, bool p_end) {
+
+void RenderForwardClustered::_render_shadow_append(RID p_framebuffer, const PagedArray<GeometryInstance *> &p_instances, const CameraMatrix &p_projection, const Transform3D &p_transform, float p_zfar, float p_bias, float p_normal_bias, bool p_use_dp, bool p_use_dp_flip, bool p_use_pancake, const Plane &p_camera_plane, float p_lod_distance_multiplier, float p_screen_lod_threshold, const Rect2i &p_rect, bool p_flip_y, bool p_clear_region, bool p_begin, bool p_end, RendererScene::RenderInfo *p_render_info) {
uint32_t shadow_pass_index = scene_state.shadow_passes.size();
SceneState::ShadowPass shadow_pass;
@@ -1513,6 +1568,7 @@ void RenderForwardClustered::_render_shadow_append(RID p_framebuffer, const Page
render_data.instances = &p_instances;
render_data.lod_camera_plane = p_camera_plane;
render_data.lod_distance_multiplier = p_lod_distance_multiplier;
+ render_data.render_info = p_render_info;
scene_state.ubo.dual_paraboloid_side = p_use_dp_flip ? -1 : 1;
@@ -1530,7 +1586,7 @@ void RenderForwardClustered::_render_shadow_append(RID p_framebuffer, const Page
_fill_render_list(RENDER_LIST_SECONDARY, &render_data, pass_mode, false, false, true);
uint32_t render_list_size = render_list[RENDER_LIST_SECONDARY].elements.size() - render_list_from;
render_list[RENDER_LIST_SECONDARY].sort_by_key_range(render_list_from, render_list_size);
- _fill_instance_data(RENDER_LIST_SECONDARY, render_list_from, render_list_size, false);
+ _fill_instance_data(RENDER_LIST_SECONDARY, p_render_info ? p_render_info->info[RS::VIEWPORT_RENDER_INFO_TYPE_SHADOW] : (int *)nullptr, render_list_from, render_list_size, false);
{
//regular forward for now
@@ -1585,7 +1641,7 @@ void RenderForwardClustered::_render_shadow_end(uint32_t p_barrier) {
RD::get_singleton()->draw_command_end_label();
}
-void RenderForwardClustered::_render_particle_collider_heightfield(RID p_fb, const Transform &p_cam_transform, const CameraMatrix &p_cam_projection, const PagedArray<GeometryInstance *> &p_instances) {
+void RenderForwardClustered::_render_particle_collider_heightfield(RID p_fb, const Transform3D &p_cam_transform, const CameraMatrix &p_cam_projection, const PagedArray<GeometryInstance *> &p_instances) {
RENDER_TIMESTAMP("Setup Render Collider Heightfield");
RD::get_singleton()->draw_command_begin_label("Render Collider Heightfield");
@@ -1622,7 +1678,7 @@ void RenderForwardClustered::_render_particle_collider_heightfield(RID p_fb, con
RD::get_singleton()->draw_command_end_label();
}
-void RenderForwardClustered::_render_material(const Transform &p_cam_transform, const CameraMatrix &p_cam_projection, bool p_cam_ortogonal, const PagedArray<GeometryInstance *> &p_instances, RID p_framebuffer, const Rect2i &p_region) {
+void RenderForwardClustered::_render_material(const Transform3D &p_cam_transform, const CameraMatrix &p_cam_projection, bool p_cam_ortogonal, const PagedArray<GeometryInstance *> &p_instances, RID p_framebuffer, const Rect2i &p_region) {
RENDER_TIMESTAMP("Setup Rendering Material");
RD::get_singleton()->draw_command_begin_label("Render Material");
@@ -1796,7 +1852,7 @@ void RenderForwardClustered::_render_sdfgi(RID p_render_buffers, const Vector3i
render_data.cam_projection.set_orthogonal(-h_size, h_size, -v_size, v_size, 0, d_size);
//print_line("pass: " + itos(i) + " cam hsize: " + rtos(h_size) + " vsize: " + rtos(v_size) + " dsize " + rtos(d_size));
- Transform to_bounds;
+ Transform3D to_bounds;
to_bounds.origin = p_bounds.position;
to_bounds.basis.scale(p_bounds.size);
@@ -2058,11 +2114,11 @@ RID RenderForwardClustered::_setup_render_pass_uniform_set(RenderListType p_rend
RD::Uniform u;
u.binding = 7;
u.uniform_type = RD::UNIFORM_TYPE_TEXTURE;
- u.ids.resize(MAX_GI_PROBES);
+ u.ids.resize(MAX_VOXEL_GI_INSTANCESS);
RID default_tex = storage->texture_rd_get_default(RendererStorageRD::DEFAULT_RD_TEXTURE_3D_WHITE);
- for (int i = 0; i < MAX_GI_PROBES; i++) {
- if (p_render_data && i < (int)p_render_data->gi_probes->size()) {
- RID tex = gi.gi_probe_instance_get_texture((*p_render_data->gi_probes)[i]);
+ for (int i = 0; i < MAX_VOXEL_GI_INSTANCESS; i++) {
+ if (p_render_data && i < (int)p_render_data->voxel_gi_instances->size()) {
+ RID tex = gi.voxel_gi_instance_get_texture((*p_render_data->voxel_gi_instances)[i]);
if (!tex.is_valid()) {
tex = default_tex;
}
@@ -2169,7 +2225,7 @@ RID RenderForwardClustered::_setup_render_pass_uniform_set(RenderListType p_rend
RD::Uniform u;
u.binding = 17;
u.uniform_type = RD::UNIFORM_TYPE_UNIFORM_BUFFER;
- u.ids.push_back(rb ? render_buffers_get_gi_probe_buffer(p_render_data->render_buffers) : render_buffers_get_default_gi_probe_buffer());
+ u.ids.push_back(rb ? render_buffers_get_voxel_gi_buffer(p_render_data->render_buffers) : render_buffers_get_default_voxel_gi_buffer());
uniforms.push_back(u);
}
{
@@ -2278,13 +2334,13 @@ RID RenderForwardClustered::_setup_sdfgi_render_pass_uniform_set(RID p_albedo_te
}
{
- // No GIProbes
+ // No VoxelGIs
RD::Uniform u;
u.binding = 7;
u.uniform_type = RD::UNIFORM_TYPE_TEXTURE;
- u.ids.resize(MAX_GI_PROBES);
+ u.ids.resize(MAX_VOXEL_GI_INSTANCESS);
RID default_tex = storage->texture_rd_get_default(RendererStorageRD::DEFAULT_RD_TEXTURE_3D_WHITE);
- for (int i = 0; i < MAX_GI_PROBES; i++) {
+ for (int i = 0; i < MAX_VOXEL_GI_INSTANCESS; i++) {
u.ids.write[i] = default_tex;
}
@@ -2589,6 +2645,8 @@ void RenderForwardClustered::_geometry_instance_update(GeometryInstance *p_geome
//Fill push constant
+ ginstance->base_flags = 0;
+
bool store_transform = true;
if (ginstance->data->base_type == RS::INSTANCE_MULTIMESH) {
@@ -2632,7 +2690,7 @@ void RenderForwardClustered::_geometry_instance_update(GeometryInstance *p_geome
ginstance->can_sdfgi = false;
if (!lightmap_instance_is_valid(ginstance->lightmap_instance)) {
- if (ginstance->gi_probes[0].is_null() && (ginstance->data->use_baked_light || ginstance->data->use_dynamic_gi)) {
+ if (ginstance->voxel_gi_instances[0].is_null() && (ginstance->data->use_baked_light || ginstance->data->use_dynamic_gi)) {
ginstance->can_sdfgi = true;
}
}
@@ -2719,7 +2777,7 @@ void RenderForwardClustered::geometry_instance_set_mesh_instance(GeometryInstanc
ginstance->mesh_instance = p_mesh_instance;
_geometry_instance_mark_dirty(ginstance);
}
-void RenderForwardClustered::geometry_instance_set_transform(GeometryInstance *p_geometry_instance, const Transform &p_transform, const AABB &p_aabb, const AABB &p_transformed_aabb) {
+void RenderForwardClustered::geometry_instance_set_transform(GeometryInstance *p_geometry_instance, const Transform3D &p_transform, const AABB &p_aabb, const AABB &p_transformed_aabb) {
GeometryInstanceForwardClustered *ginstance = static_cast<GeometryInstanceForwardClustered *>(p_geometry_instance);
ERR_FAIL_COND(!ginstance);
ginstance->transform = p_transform;
@@ -2732,6 +2790,7 @@ void RenderForwardClustered::geometry_instance_set_transform(GeometryInstance *p
float max_scale = MAX(model_scale_vec.x, MAX(model_scale_vec.y, model_scale_vec.z));
float min_scale = MIN(model_scale_vec.x, MIN(model_scale_vec.y, model_scale_vec.z));
+
ginstance->non_uniform_scale = max_scale >= 0.0 && (min_scale / max_scale) < 0.9;
ginstance->lod_model_scale = max_scale;
@@ -2815,7 +2874,7 @@ void RenderForwardClustered::geometry_instance_free(GeometryInstance *p_geometry
}
uint32_t RenderForwardClustered::geometry_instance_get_pair_mask() {
- return (1 << RS::INSTANCE_GI_PROBE);
+ return (1 << RS::INSTANCE_VOXEL_GI);
}
void RenderForwardClustered::geometry_instance_pair_light_instances(GeometryInstance *p_geometry_instance, const RID *p_light_instances, uint32_t p_light_instance_count) {
}
@@ -2824,30 +2883,31 @@ void RenderForwardClustered::geometry_instance_pair_reflection_probe_instances(G
void RenderForwardClustered::geometry_instance_pair_decal_instances(GeometryInstance *p_geometry_instance, const RID *p_decal_instances, uint32_t p_decal_instance_count) {
}
-Transform RenderForwardClustered::geometry_instance_get_transform(GeometryInstance *p_instance) {
+Transform3D RenderForwardClustered::geometry_instance_get_transform(GeometryInstance *p_instance) {
GeometryInstanceForwardClustered *ginstance = static_cast<GeometryInstanceForwardClustered *>(p_instance);
- ERR_FAIL_COND_V(!ginstance, Transform());
+ ERR_FAIL_COND_V(!ginstance, Transform3D());
return ginstance->transform;
}
+
AABB RenderForwardClustered::geometry_instance_get_aabb(GeometryInstance *p_instance) {
GeometryInstanceForwardClustered *ginstance = static_cast<GeometryInstanceForwardClustered *>(p_instance);
ERR_FAIL_COND_V(!ginstance, AABB());
return ginstance->data->aabb;
}
-void RenderForwardClustered::geometry_instance_pair_gi_probe_instances(GeometryInstance *p_geometry_instance, const RID *p_gi_probe_instances, uint32_t p_gi_probe_instance_count) {
+void RenderForwardClustered::geometry_instance_pair_voxel_gi_instances(GeometryInstance *p_geometry_instance, const RID *p_voxel_gi_instances, uint32_t p_voxel_gi_instance_count) {
GeometryInstanceForwardClustered *ginstance = static_cast<GeometryInstanceForwardClustered *>(p_geometry_instance);
ERR_FAIL_COND(!ginstance);
- if (p_gi_probe_instance_count > 0) {
- ginstance->gi_probes[0] = p_gi_probe_instances[0];
+ if (p_voxel_gi_instance_count > 0) {
+ ginstance->voxel_gi_instances[0] = p_voxel_gi_instances[0];
} else {
- ginstance->gi_probes[0] = RID();
+ ginstance->voxel_gi_instances[0] = RID();
}
- if (p_gi_probe_instance_count > 1) {
- ginstance->gi_probes[1] = p_gi_probe_instances[1];
+ if (p_voxel_gi_instance_count > 1) {
+ ginstance->voxel_gi_instances[1] = p_voxel_gi_instances[1];
} else {
- ginstance->gi_probes[1] = RID();
+ ginstance->voxel_gi_instances[1] = RID();
}
}
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 bed3c3b219..750c0167e7 100644
--- a/servers/rendering/renderer_rd/forward_clustered/render_forward_clustered.h
+++ b/servers/rendering/renderer_rd/forward_clustered/render_forward_clustered.h
@@ -52,9 +52,9 @@ class RenderForwardClustered : public RendererSceneRenderRD {
enum {
SDFGI_MAX_CASCADES = 8,
- MAX_GI_PROBES = 8,
+ MAX_VOXEL_GI_INSTANCESS = 8,
MAX_LIGHTMAPS = 8,
- MAX_GI_PROBES_PER_INSTANCE = 2,
+ MAX_VOXEL_GI_INSTANCESS_PER_INSTANCE = 2,
INSTANCE_DATA_BUFFER_MIN_SIZE = 4096
};
@@ -79,7 +79,7 @@ class RenderForwardClustered : public RendererSceneRenderRD {
RID depth;
RID specular;
RID normal_roughness_buffer;
- RID giprobe_buffer;
+ RID voxelgi_buffer;
RS::ViewportMSAA msaa;
RD::TextureSamples texture_samples;
@@ -89,11 +89,11 @@ class RenderForwardClustered : public RendererSceneRenderRD {
RID specular_msaa;
RID normal_roughness_buffer_msaa;
RID roughness_buffer_msaa;
- RID giprobe_buffer_msaa;
+ RID voxelgi_buffer_msaa;
RID depth_fb;
RID depth_normal_roughness_fb;
- RID depth_normal_roughness_giprobe_fb;
+ RID depth_normal_roughness_voxelgi_fb;
RID color_fb;
RID color_specular_fb;
RID specular_only_fb;
@@ -101,14 +101,14 @@ class RenderForwardClustered : public RendererSceneRenderRD {
RID render_sdfgi_uniform_set;
void ensure_specular();
- void ensure_giprobe();
+ void ensure_voxelgi();
void clear();
- virtual void configure(RID p_color_buffer, RID p_depth_buffer, int p_width, int p_height, RS::ViewportMSAA p_msaa);
+ virtual void configure(RID p_color_buffer, RID p_depth_buffer, int p_width, int p_height, RS::ViewportMSAA p_msaa, uint32_t p_view_count);
~RenderBufferDataForwardClustered();
};
- virtual RenderBufferData *_create_render_buffer_data();
+ virtual RenderBufferData *_create_render_buffer_data() override;
void _allocate_normal_roughness_texture(RenderBufferDataForwardClustered *rb);
RID render_base_uniform_set;
@@ -117,8 +117,8 @@ class RenderForwardClustered : public RendererSceneRenderRD {
uint64_t lightmap_texture_array_version = 0xFFFFFFFF;
- virtual void _base_uniforms_changed();
- virtual RID _render_buffers_get_normal_texture(RID p_render_buffers);
+ virtual void _base_uniforms_changed() override;
+ virtual RID _render_buffers_get_normal_texture(RID p_render_buffers) override;
void _update_render_base_uniform_set();
RID _setup_sdfgi_render_pass_uniform_set(RID p_albedo_texture, RID p_emission_texture, RID p_emission_aniso_texture, RID p_geom_facing_texture);
@@ -132,7 +132,7 @@ class RenderForwardClustered : public RendererSceneRenderRD {
PASS_MODE_SHADOW_DP,
PASS_MODE_DEPTH,
PASS_MODE_DEPTH_NORMAL_ROUGHNESS,
- PASS_MODE_DEPTH_NORMAL_ROUGHNESS_GIPROBE,
+ PASS_MODE_DEPTH_NORMAL_ROUGHNESS_VOXEL_GI,
PASS_MODE_DEPTH_MATERIAL,
PASS_MODE_SDF,
};
@@ -184,19 +184,19 @@ class RenderForwardClustered : public RendererSceneRenderRD {
};
enum {
+ INSTANCE_DATA_FLAGS_NON_UNIFORM_SCALE = 1 << 5,
INSTANCE_DATA_FLAG_USE_GI_BUFFERS = 1 << 6,
INSTANCE_DATA_FLAG_USE_SDFGI = 1 << 7,
INSTANCE_DATA_FLAG_USE_LIGHTMAP_CAPTURE = 1 << 8,
INSTANCE_DATA_FLAG_USE_LIGHTMAP = 1 << 9,
INSTANCE_DATA_FLAG_USE_SH_LIGHTMAP = 1 << 10,
- INSTANCE_DATA_FLAG_USE_GIPROBE = 1 << 11,
+ INSTANCE_DATA_FLAG_USE_VOXEL_GI = 1 << 11,
INSTANCE_DATA_FLAG_MULTIMESH = 1 << 12,
INSTANCE_DATA_FLAG_MULTIMESH_FORMAT_2D = 1 << 13,
INSTANCE_DATA_FLAG_MULTIMESH_HAS_COLOR = 1 << 14,
INSTANCE_DATA_FLAG_MULTIMESH_HAS_CUSTOM_DATA = 1 << 15,
INSTANCE_DATA_FLAGS_PARTICLE_TRAIL_SHIFT = 16,
INSTANCE_DATA_FLAGS_PARTICLE_TRAIL_MASK = 0xFF,
- INSTANCE_DATA_FLAGS_NON_UNIFORM_SCALE = 1 << 24,
};
struct SceneState {
@@ -204,7 +204,6 @@ class RenderForwardClustered : public RendererSceneRenderRD {
struct UBO {
float projection_matrix[16];
float inv_projection_matrix[16];
-
float camera_matrix[16];
float inv_camera_matrix[16];
@@ -318,8 +317,8 @@ class RenderForwardClustered : public RendererSceneRenderRD {
uint32_t max_lightmap_captures;
RID lightmap_capture_buffer;
- RID giprobe_ids[MAX_GI_PROBES];
- uint32_t giprobes_used = 0;
+ RID voxelgi_ids[MAX_VOXEL_GI_INSTANCESS];
+ uint32_t voxelgis_used = 0;
bool used_screen_texture = false;
bool used_normal_texture = false;
@@ -350,8 +349,8 @@ class RenderForwardClustered : public RendererSceneRenderRD {
static RenderForwardClustered *singleton;
void _setup_environment(const RenderDataRD *p_render_data, bool p_no_fog, const Size2i &p_screen_size, bool p_flip_y, const Color &p_default_bg_color, bool p_opaque_render_buffers = false, bool p_pancake_shadows = false, int p_index = 0);
- void _setup_giprobes(const PagedArray<RID> &p_giprobes);
- void _setup_lightmaps(const PagedArray<RID> &p_lightmaps, const Transform &p_cam_transform);
+ void _setup_voxelgis(const PagedArray<RID> &p_voxelgis);
+ void _setup_lightmaps(const PagedArray<RID> &p_lightmaps, const Transform3D &p_cam_transform);
struct RenderElementInfo {
uint32_t repeat : 22;
@@ -372,7 +371,7 @@ class RenderForwardClustered : public RendererSceneRenderRD {
uint32_t render_list_thread_threshold = 500;
void _update_instance_data_buffer(RenderListType p_render_list);
- void _fill_instance_data(RenderListType p_render_list, uint32_t p_offset = 0, int32_t p_max_elements = -1, bool p_update_buffer = true);
+ void _fill_instance_data(RenderListType p_render_list, int *p_render_info = nullptr, uint32_t p_offset = 0, int32_t p_max_elements = -1, bool p_update_buffer = true);
void _fill_render_list(RenderListType p_render_list, const RenderDataRD *p_render_data, PassMode p_pass_mode, bool p_using_sdfgi = false, bool p_using_opaque_gi = false, bool p_append = false);
Map<Size2i, RID> sdfgi_framebuffer_size_cache;
@@ -458,8 +457,8 @@ class RenderForwardClustered : public RendererSceneRenderRD {
bool can_sdfgi = false;
//used during setup
uint32_t base_flags = 0;
- Transform transform;
- RID gi_probes[MAX_GI_PROBES_PER_INSTANCE];
+ Transform3D transform;
+ RID voxel_gi_instances[MAX_VOXEL_GI_INSTANCESS_PER_INSTANCE];
RID lightmap_instance;
GeometryInstanceLightmapSH *lightmap_sh = nullptr;
GeometryInstanceSurfaceDataCache *surface_caches = nullptr;
@@ -552,7 +551,7 @@ class RenderForwardClustered : public RendererSceneRenderRD {
}
};
- void sort_by_reverse_depth_and_priority(bool p_alpha) { //used for alpha
+ void sort_by_reverse_depth_and_priority() { //used for alpha
SortArray<GeometryInstanceSurfaceDataCache *, SortByReverseDepthAndPriority> sorter;
sorter.sort(elements.ptr(), elements.size());
@@ -566,46 +565,46 @@ class RenderForwardClustered : public RendererSceneRenderRD {
RenderList render_list[RENDER_LIST_MAX];
protected:
- virtual void _render_scene(RenderDataRD *p_render_data, const Color &p_default_bg_color);
+ virtual void _render_scene(RenderDataRD *p_render_data, const Color &p_default_bg_color) override;
- virtual void _render_shadow_begin();
- virtual void _render_shadow_append(RID p_framebuffer, const PagedArray<GeometryInstance *> &p_instances, const CameraMatrix &p_projection, const Transform &p_transform, float p_zfar, float p_bias, float p_normal_bias, bool p_use_dp, bool p_use_dp_flip, bool p_use_pancake, const Plane &p_camera_plane = Plane(), float p_lod_distance_multiplier = 0.0, float p_screen_lod_threshold = 0.0, const Rect2i &p_rect = Rect2i(), bool p_flip_y = false, bool p_clear_region = true, bool p_begin = true, bool p_end = true);
- virtual void _render_shadow_process();
- virtual void _render_shadow_end(uint32_t p_barrier = RD::BARRIER_MASK_ALL);
+ virtual void _render_shadow_begin() override;
+ virtual void _render_shadow_append(RID p_framebuffer, const PagedArray<GeometryInstance *> &p_instances, const CameraMatrix &p_projection, const Transform3D &p_transform, float p_zfar, float p_bias, float p_normal_bias, bool p_use_dp, bool p_use_dp_flip, bool p_use_pancake, const Plane &p_camera_plane = Plane(), float p_lod_distance_multiplier = 0.0, float p_screen_lod_threshold = 0.0, const Rect2i &p_rect = Rect2i(), bool p_flip_y = false, bool p_clear_region = true, bool p_begin = true, bool p_end = true, RendererScene::RenderInfo *p_render_info = nullptr) override;
+ virtual void _render_shadow_process() override;
+ virtual void _render_shadow_end(uint32_t p_barrier = RD::BARRIER_MASK_ALL) override;
- virtual void _render_material(const Transform &p_cam_transform, const CameraMatrix &p_cam_projection, bool p_cam_ortogonal, const PagedArray<GeometryInstance *> &p_instances, RID p_framebuffer, const Rect2i &p_region);
- virtual void _render_uv2(const PagedArray<GeometryInstance *> &p_instances, RID p_framebuffer, const Rect2i &p_region);
- virtual void _render_sdfgi(RID p_render_buffers, const Vector3i &p_from, const Vector3i &p_size, const AABB &p_bounds, const PagedArray<GeometryInstance *> &p_instances, const RID &p_albedo_texture, const RID &p_emission_texture, const RID &p_emission_aniso_texture, const RID &p_geom_facing_texture);
- virtual void _render_particle_collider_heightfield(RID p_fb, const Transform &p_cam_transform, const CameraMatrix &p_cam_projection, const PagedArray<GeometryInstance *> &p_instances);
+ virtual void _render_material(const Transform3D &p_cam_transform, const CameraMatrix &p_cam_projection, bool p_cam_ortogonal, const PagedArray<GeometryInstance *> &p_instances, RID p_framebuffer, const Rect2i &p_region) override;
+ virtual void _render_uv2(const PagedArray<GeometryInstance *> &p_instances, RID p_framebuffer, const Rect2i &p_region) override;
+ virtual void _render_sdfgi(RID p_render_buffers, const Vector3i &p_from, const Vector3i &p_size, const AABB &p_bounds, const PagedArray<GeometryInstance *> &p_instances, const RID &p_albedo_texture, const RID &p_emission_texture, const RID &p_emission_aniso_texture, const RID &p_geom_facing_texture) override;
+ virtual void _render_particle_collider_heightfield(RID p_fb, const Transform3D &p_cam_transform, const CameraMatrix &p_cam_projection, const PagedArray<GeometryInstance *> &p_instances) override;
public:
- virtual GeometryInstance *geometry_instance_create(RID p_base);
- virtual void geometry_instance_set_skeleton(GeometryInstance *p_geometry_instance, RID p_skeleton);
- virtual void geometry_instance_set_material_override(GeometryInstance *p_geometry_instance, RID p_override);
- virtual void geometry_instance_set_surface_materials(GeometryInstance *p_geometry_instance, const Vector<RID> &p_materials);
- virtual void geometry_instance_set_mesh_instance(GeometryInstance *p_geometry_instance, RID p_mesh_instance);
- virtual void geometry_instance_set_transform(GeometryInstance *p_geometry_instance, const Transform &p_transform, const AABB &p_aabb, const AABB &p_transformed_aabb);
- virtual void geometry_instance_set_layer_mask(GeometryInstance *p_geometry_instance, uint32_t p_layer_mask);
- virtual void geometry_instance_set_lod_bias(GeometryInstance *p_geometry_instance, float p_lod_bias);
- virtual void geometry_instance_set_use_baked_light(GeometryInstance *p_geometry_instance, bool p_enable);
- virtual void geometry_instance_set_use_dynamic_gi(GeometryInstance *p_geometry_instance, bool p_enable);
- virtual void geometry_instance_set_use_lightmap(GeometryInstance *p_geometry_instance, RID p_lightmap_instance, const Rect2 &p_lightmap_uv_scale, int p_lightmap_slice_index);
- virtual void geometry_instance_set_lightmap_capture(GeometryInstance *p_geometry_instance, const Color *p_sh9);
- virtual void geometry_instance_set_instance_shader_parameters_offset(GeometryInstance *p_geometry_instance, int32_t p_offset);
- virtual void geometry_instance_set_cast_double_sided_shadows(GeometryInstance *p_geometry_instance, bool p_enable);
-
- virtual Transform geometry_instance_get_transform(GeometryInstance *p_instance);
- virtual AABB geometry_instance_get_aabb(GeometryInstance *p_instance);
-
- virtual void geometry_instance_free(GeometryInstance *p_geometry_instance);
-
- virtual uint32_t geometry_instance_get_pair_mask();
- virtual void geometry_instance_pair_light_instances(GeometryInstance *p_geometry_instance, const RID *p_light_instances, uint32_t p_light_instance_count);
- virtual void geometry_instance_pair_reflection_probe_instances(GeometryInstance *p_geometry_instance, const RID *p_reflection_probe_instances, uint32_t p_reflection_probe_instance_count);
- virtual void geometry_instance_pair_decal_instances(GeometryInstance *p_geometry_instance, const RID *p_decal_instances, uint32_t p_decal_instance_count);
- virtual void geometry_instance_pair_gi_probe_instances(GeometryInstance *p_geometry_instance, const RID *p_gi_probe_instances, uint32_t p_gi_probe_instance_count);
-
- virtual bool free(RID p_rid);
+ virtual GeometryInstance *geometry_instance_create(RID p_base) override;
+ virtual void geometry_instance_set_skeleton(GeometryInstance *p_geometry_instance, RID p_skeleton) override;
+ virtual void geometry_instance_set_material_override(GeometryInstance *p_geometry_instance, RID p_override) override;
+ virtual void geometry_instance_set_surface_materials(GeometryInstance *p_geometry_instance, const Vector<RID> &p_materials) override;
+ virtual void geometry_instance_set_mesh_instance(GeometryInstance *p_geometry_instance, RID p_mesh_instance) override;
+ virtual void geometry_instance_set_transform(GeometryInstance *p_geometry_instance, const Transform3D &p_transform, const AABB &p_aabb, const AABB &p_transformed_aabb) override;
+ virtual void geometry_instance_set_layer_mask(GeometryInstance *p_geometry_instance, uint32_t p_layer_mask) override;
+ virtual void geometry_instance_set_lod_bias(GeometryInstance *p_geometry_instance, float p_lod_bias) override;
+ virtual void geometry_instance_set_use_baked_light(GeometryInstance *p_geometry_instance, bool p_enable) override;
+ virtual void geometry_instance_set_use_dynamic_gi(GeometryInstance *p_geometry_instance, bool p_enable) override;
+ virtual void geometry_instance_set_use_lightmap(GeometryInstance *p_geometry_instance, RID p_lightmap_instance, const Rect2 &p_lightmap_uv_scale, int p_lightmap_slice_index) override;
+ virtual void geometry_instance_set_lightmap_capture(GeometryInstance *p_geometry_instance, const Color *p_sh9) override;
+ virtual void geometry_instance_set_instance_shader_parameters_offset(GeometryInstance *p_geometry_instance, int32_t p_offset) override;
+ virtual void geometry_instance_set_cast_double_sided_shadows(GeometryInstance *p_geometry_instance, bool p_enable) override;
+
+ virtual Transform3D geometry_instance_get_transform(GeometryInstance *p_instance) override;
+ virtual AABB geometry_instance_get_aabb(GeometryInstance *p_instance) override;
+
+ virtual void geometry_instance_free(GeometryInstance *p_geometry_instance) override;
+
+ virtual uint32_t geometry_instance_get_pair_mask() override;
+ virtual void geometry_instance_pair_light_instances(GeometryInstance *p_geometry_instance, const RID *p_light_instances, uint32_t p_light_instance_count) override;
+ virtual void geometry_instance_pair_reflection_probe_instances(GeometryInstance *p_geometry_instance, const RID *p_reflection_probe_instances, uint32_t p_reflection_probe_instance_count) override;
+ virtual void geometry_instance_pair_decal_instances(GeometryInstance *p_geometry_instance, const RID *p_decal_instances, uint32_t p_decal_instance_count) override;
+ virtual void geometry_instance_pair_voxel_gi_instances(GeometryInstance *p_geometry_instance, const RID *p_voxel_gi_instances, uint32_t p_voxel_gi_instance_count) override;
+
+ virtual bool free(RID p_rid) override;
RenderForwardClustered(RendererStorageRD *p_storage);
~RenderForwardClustered();
diff --git a/servers/rendering/renderer_rd/forward_clustered/scene_shader_forward_clustered.cpp b/servers/rendering/renderer_rd/forward_clustered/scene_shader_forward_clustered.cpp
index 5a26b5abbb..d39823a1a3 100644
--- a/servers/rendering/renderer_rd/forward_clustered/scene_shader_forward_clustered.cpp
+++ b/servers/rendering/renderer_rd/forward_clustered/scene_shader_forward_clustered.cpp
@@ -311,7 +311,7 @@ void SceneShaderForwardClustered::ShaderData::set_code(const String &p_code) {
//none, leave empty
} else if (k == SHADER_VERSION_DEPTH_PASS_WITH_NORMAL_AND_ROUGHNESS) {
blend_state = blend_state_depth_normal_roughness;
- } else if (k == SHADER_VERSION_DEPTH_PASS_WITH_NORMAL_AND_ROUGHNESS_AND_GIPROBE) {
+ } else if (k == SHADER_VERSION_DEPTH_PASS_WITH_NORMAL_AND_ROUGHNESS_AND_VOXEL_GI) {
blend_state = blend_state_depth_normal_roughness_giprobe;
} else if (k == SHADER_VERSION_DEPTH_PASS_WITH_MATERIAL) {
blend_state = RD::PipelineColorBlendState::create_disabled(5); //writes to normal and roughness in opaque way
@@ -320,8 +320,6 @@ void SceneShaderForwardClustered::ShaderData::set_code(const String &p_code) {
} else {
//specular write
blend_state = blend_state_opaque_specular;
- depth_stencil.enable_depth_test = false;
- depth_stencil.enable_depth_write = false;
}
}
@@ -437,94 +435,14 @@ void SceneShaderForwardClustered::MaterialData::set_next_pass(RID p_pass) {
next_pass = p_pass;
}
-void SceneShaderForwardClustered::MaterialData::update_parameters(const Map<StringName, Variant> &p_parameters, bool p_uniform_dirty, bool p_textures_dirty) {
+bool SceneShaderForwardClustered::MaterialData::update_parameters(const Map<StringName, Variant> &p_parameters, bool p_uniform_dirty, bool p_textures_dirty) {
SceneShaderForwardClustered *shader_singleton = (SceneShaderForwardClustered *)SceneShaderForwardClustered::singleton;
- if ((uint32_t)ubo_data.size() != shader_data->ubo_size) {
- p_uniform_dirty = true;
- if (uniform_buffer.is_valid()) {
- RD::get_singleton()->free(uniform_buffer);
- uniform_buffer = RID();
- }
-
- ubo_data.resize(shader_data->ubo_size);
- if (ubo_data.size()) {
- uniform_buffer = RD::get_singleton()->uniform_buffer_create(ubo_data.size());
- memset(ubo_data.ptrw(), 0, ubo_data.size()); //clear
- }
-
- //clear previous uniform set
- if (uniform_set.is_valid() && RD::get_singleton()->uniform_set_is_valid(uniform_set)) {
- RD::get_singleton()->free(uniform_set);
- uniform_set = RID();
- }
- }
-
- //check whether buffer changed
- if (p_uniform_dirty && ubo_data.size()) {
- update_uniform_buffer(shader_data->uniforms, shader_data->ubo_offsets.ptr(), p_parameters, ubo_data.ptrw(), ubo_data.size(), false);
- RD::get_singleton()->buffer_update(uniform_buffer, 0, ubo_data.size(), ubo_data.ptrw(), RD::BARRIER_MASK_RASTER);
- }
-
- uint32_t tex_uniform_count = shader_data->texture_uniforms.size();
-
- if ((uint32_t)texture_cache.size() != tex_uniform_count) {
- texture_cache.resize(tex_uniform_count);
- p_textures_dirty = true;
-
- //clear previous uniform set
- if (uniform_set.is_valid() && RD::get_singleton()->uniform_set_is_valid(uniform_set)) {
- RD::get_singleton()->free(uniform_set);
- uniform_set = RID();
- }
- }
-
- if (p_textures_dirty && tex_uniform_count) {
- update_textures(p_parameters, shader_data->default_texture_params, shader_data->texture_uniforms, texture_cache.ptrw(), true);
- }
-
- if (shader_data->ubo_size == 0 && shader_data->texture_uniforms.size() == 0) {
- // This material does not require an uniform set, so don't create it.
- return;
- }
-
- if (!p_textures_dirty && uniform_set.is_valid() && RD::get_singleton()->uniform_set_is_valid(uniform_set)) {
- //no reason to update uniform set, only UBO (or nothing) was needed to update
- return;
- }
-
- Vector<RD::Uniform> uniforms;
-
- {
- if (shader_data->ubo_size) {
- RD::Uniform u;
- u.uniform_type = RD::UNIFORM_TYPE_UNIFORM_BUFFER;
- u.binding = 0;
- u.ids.push_back(uniform_buffer);
- uniforms.push_back(u);
- }
-
- const RID *textures = texture_cache.ptrw();
- for (uint32_t i = 0; i < tex_uniform_count; i++) {
- RD::Uniform u;
- u.uniform_type = RD::UNIFORM_TYPE_TEXTURE;
- u.binding = 1 + i;
- u.ids.push_back(textures[i]);
- uniforms.push_back(u);
- }
- }
-
- uniform_set = RD::get_singleton()->uniform_set_create(uniforms, shader_singleton->shader.version_get_shader(shader_data->version, 0), RenderForwardClustered::MATERIAL_UNIFORM_SET);
+ return update_parameters_uniform_set(p_parameters, p_uniform_dirty, p_textures_dirty, shader_data->uniforms, shader_data->ubo_offsets.ptr(), shader_data->texture_uniforms, shader_data->default_texture_params, shader_data->ubo_size, uniform_set, shader_singleton->shader.version_get_shader(shader_data->version, 0), RenderForwardClustered::MATERIAL_UNIFORM_SET, RD::BARRIER_MASK_RASTER);
}
SceneShaderForwardClustered::MaterialData::~MaterialData() {
- if (uniform_set.is_valid() && RD::get_singleton()->uniform_set_is_valid(uniform_set)) {
- RD::get_singleton()->free(uniform_set);
- }
-
- if (uniform_buffer.is_valid()) {
- RD::get_singleton()->free(uniform_buffer);
- }
+ free_parameters_uniform_set(uniform_set);
}
RendererStorageRD::MaterialData *SceneShaderForwardClustered::_create_material_func(ShaderData *p_shader) {
@@ -546,11 +464,9 @@ SceneShaderForwardClustered::~SceneShaderForwardClustered() {
RD::get_singleton()->free(default_vec4_xform_buffer);
RD::get_singleton()->free(shadow_sampler);
- storage->free(wireframe_material_shader);
storage->free(overdraw_material_shader);
storage->free(default_shader);
- storage->free(wireframe_material);
storage->free(overdraw_material);
storage->free(default_material);
}
@@ -560,17 +476,18 @@ void SceneShaderForwardClustered::init(RendererStorageRD *p_storage, const Strin
{
Vector<String> shader_versions;
- shader_versions.push_back("\n#define MODE_RENDER_DEPTH\n");
- shader_versions.push_back("\n#define MODE_RENDER_DEPTH\n#define MODE_DUAL_PARABOLOID\n");
- shader_versions.push_back("\n#define MODE_RENDER_DEPTH\n#define MODE_RENDER_NORMAL_ROUGHNESS\n");
- shader_versions.push_back("\n#define MODE_RENDER_DEPTH\n#define MODE_RENDER_NORMAL_ROUGHNESS\n#define MODE_RENDER_GIPROBE\n");
- shader_versions.push_back("\n#define MODE_RENDER_DEPTH\n#define MODE_RENDER_MATERIAL\n");
- shader_versions.push_back("\n#define MODE_RENDER_DEPTH\n#define MODE_RENDER_SDF\n");
- shader_versions.push_back("");
- shader_versions.push_back("\n#define USE_FORWARD_GI\n");
- shader_versions.push_back("\n#define MODE_MULTIPLE_RENDER_TARGETS\n");
- shader_versions.push_back("\n#define USE_LIGHTMAP\n");
- shader_versions.push_back("\n#define MODE_MULTIPLE_RENDER_TARGETS\n#define USE_LIGHTMAP\n");
+ shader_versions.push_back("\n#define MODE_RENDER_DEPTH\n"); // SHADER_VERSION_DEPTH_PASS
+ shader_versions.push_back("\n#define MODE_RENDER_DEPTH\n#define MODE_DUAL_PARABOLOID\n"); // SHADER_VERSION_DEPTH_PASS_DP
+ shader_versions.push_back("\n#define MODE_RENDER_DEPTH\n#define MODE_RENDER_NORMAL_ROUGHNESS\n"); // SHADER_VERSION_DEPTH_PASS_WITH_NORMAL_AND_ROUGHNESS
+ shader_versions.push_back("\n#define MODE_RENDER_DEPTH\n#define MODE_RENDER_NORMAL_ROUGHNESS\n#define MODE_RENDER_VOXEL_GI\n"); // SHADER_VERSION_DEPTH_PASS_WITH_NORMAL_AND_ROUGHNESS_AND_GIPROBE
+ shader_versions.push_back("\n#define MODE_RENDER_DEPTH\n#define MODE_RENDER_MATERIAL\n"); // SHADER_VERSION_DEPTH_PASS_WITH_MATERIAL
+ shader_versions.push_back("\n#define MODE_RENDER_DEPTH\n#define MODE_RENDER_SDF\n"); // SHADER_VERSION_DEPTH_PASS_WITH_SDF
+ shader_versions.push_back(""); // SHADER_VERSION_COLOR_PASS
+ shader_versions.push_back("\n#define USE_FORWARD_GI\n"); // SHADER_VERSION_COLOR_PASS_WITH_FORWARD_GI
+ shader_versions.push_back("\n#define MODE_MULTIPLE_RENDER_TARGETS\n"); // SHADER_VERSION_COLOR_PASS_WITH_SEPARATE_SPECULAR
+ shader_versions.push_back("\n#define USE_LIGHTMAP\n"); // SHADER_VERSION_LIGHTMAP_COLOR_PASS
+ shader_versions.push_back("\n#define MODE_MULTIPLE_RENDER_TARGETS\n#define USE_LIGHTMAP\n"); // SHADER_VERSION_LIGHTMAP_COLOR_PASS_WITH_SEPARATE_SPECULAR
+
shader.initialize(shader_versions, p_defines);
}
@@ -632,7 +549,6 @@ void SceneShaderForwardClustered::init(RendererStorageRD *p_storage, const Strin
actions.renames["SSS_STRENGTH"] = "sss_strength";
actions.renames["SSS_TRANSMITTANCE_COLOR"] = "transmittance_color";
actions.renames["SSS_TRANSMITTANCE_DEPTH"] = "transmittance_depth";
- actions.renames["SSS_TRANSMITTANCE_CURVE"] = "transmittance_curve";
actions.renames["SSS_TRANSMITTANCE_BOOST"] = "transmittance_boost";
actions.renames["BACKLIGHT"] = "backlight";
actions.renames["AO"] = "ao";
@@ -656,6 +572,11 @@ void SceneShaderForwardClustered::init(RendererStorageRD *p_storage, const Strin
actions.renames["CUSTOM2"] = "custom2_attrib";
actions.renames["CUSTOM3"] = "custom3_attrib";
+ // not implemented but need these just in case code is in the shaders
+ actions.renames["VIEW_INDEX"] = "0";
+ actions.renames["VIEW_MONO_LEFT"] = "0";
+ actions.renames["VIEW_RIGHT"] = "1";
+
//for light
actions.renames["VIEW"] = "view";
actions.renames["LIGHT_COLOR"] = "light_color";
@@ -721,7 +642,6 @@ void SceneShaderForwardClustered::init(RendererStorageRD *p_storage, const Strin
actions.render_mode_defines["diffuse_burley"] = "#define DIFFUSE_BURLEY\n";
}
- actions.render_mode_defines["diffuse_oren_nayar"] = "#define DIFFUSE_OREN_NAYAR\n";
actions.render_mode_defines["diffuse_lambert_wrap"] = "#define DIFFUSE_LAMBERT_WRAP\n";
actions.render_mode_defines["diffuse_toon"] = "#define DIFFUSE_TOON\n";
@@ -770,22 +690,23 @@ void SceneShaderForwardClustered::init(RendererStorageRD *p_storage, const Strin
MaterialData *md = (MaterialData *)storage->material_get_data(default_material, RendererStorageRD::SHADER_TYPE_3D);
default_shader_rd = shader.version_get_shader(md->shader_data->version, SHADER_VERSION_COLOR_PASS);
default_shader_sdfgi_rd = shader.version_get_shader(md->shader_data->version, SHADER_VERSION_DEPTH_PASS_WITH_SDF);
+
+ default_material_shader_ptr = md->shader_data;
+ default_material_uniform_set = md->uniform_set;
}
{
overdraw_material_shader = storage->shader_allocate();
storage->shader_initialize(overdraw_material_shader);
- storage->shader_set_code(overdraw_material_shader, "shader_type spatial;\nrender_mode blend_add,unshaded;\n void fragment() { ALBEDO=vec3(0.4,0.8,0.8); ALPHA=0.2; }");
+ // Use relatively low opacity so that more "layers" of overlapping objects can be distinguished.
+ storage->shader_set_code(overdraw_material_shader, "shader_type spatial;\nrender_mode blend_add,unshaded;\n void fragment() { ALBEDO=vec3(0.4,0.8,0.8); ALPHA=0.1; }");
overdraw_material = storage->material_allocate();
storage->material_initialize(overdraw_material);
storage->material_set_shader(overdraw_material, overdraw_material_shader);
- wireframe_material_shader = storage->shader_allocate();
- storage->shader_initialize(wireframe_material_shader);
- storage->shader_set_code(wireframe_material_shader, "shader_type spatial;\nrender_mode wireframe,unshaded;\n void fragment() { ALBEDO=vec3(0.0,0.0,0.0); }");
- wireframe_material = storage->material_allocate();
- storage->material_initialize(wireframe_material);
- storage->material_set_shader(wireframe_material, wireframe_material_shader);
+ MaterialData *md = (MaterialData *)storage->material_get_data(overdraw_material, RendererStorageRD::SHADER_TYPE_3D);
+ overdraw_material_shader_ptr = md->shader_data;
+ overdraw_material_uniform_set = md->uniform_set;
}
{
diff --git a/servers/rendering/renderer_rd/forward_clustered/scene_shader_forward_clustered.h b/servers/rendering/renderer_rd/forward_clustered/scene_shader_forward_clustered.h
index 7c8879686b..810b1f3876 100644
--- a/servers/rendering/renderer_rd/forward_clustered/scene_shader_forward_clustered.h
+++ b/servers/rendering/renderer_rd/forward_clustered/scene_shader_forward_clustered.h
@@ -48,7 +48,7 @@ public:
SHADER_VERSION_DEPTH_PASS,
SHADER_VERSION_DEPTH_PASS_DP,
SHADER_VERSION_DEPTH_PASS_WITH_NORMAL_AND_ROUGHNESS,
- SHADER_VERSION_DEPTH_PASS_WITH_NORMAL_AND_ROUGHNESS_AND_GIPROBE,
+ SHADER_VERSION_DEPTH_PASS_WITH_NORMAL_AND_ROUGHNESS_AND_VOXEL_GI,
SHADER_VERSION_DEPTH_PASS_WITH_MATERIAL,
SHADER_VERSION_DEPTH_PASS_WITH_SDF,
SHADER_VERSION_COLOR_PASS,
@@ -56,6 +56,7 @@ public:
SHADER_VERSION_COLOR_PASS_WITH_SEPARATE_SPECULAR,
SHADER_VERSION_LIGHTMAP_COLOR_PASS,
SHADER_VERSION_LIGHTMAP_COLOR_PASS_WITH_SEPARATE_SPECULAR,
+
SHADER_VERSION_MAX
};
@@ -165,17 +166,14 @@ public:
struct MaterialData : public RendererStorageRD::MaterialData {
uint64_t last_frame;
ShaderData *shader_data;
- RID uniform_buffer;
RID uniform_set;
- Vector<RID> texture_cache;
- Vector<uint8_t> ubo_data;
uint64_t last_pass = 0;
uint32_t index = 0;
RID next_pass;
uint8_t priority;
virtual void set_render_priority(int p_priority);
virtual void set_next_pass(RID p_pass);
- virtual void update_parameters(const Map<StringName, Variant> &p_parameters, bool p_uniform_dirty, bool p_textures_dirty);
+ virtual bool update_parameters(const Map<StringName, Variant> &p_parameters, bool p_uniform_dirty, bool p_textures_dirty);
virtual ~MaterialData();
};
@@ -191,8 +189,6 @@ public:
RID default_material;
RID overdraw_material_shader;
RID overdraw_material;
- RID wireframe_material_shader;
- RID wireframe_material;
RID default_shader_rd;
RID default_shader_sdfgi_rd;
@@ -201,6 +197,12 @@ public:
RID shadow_sampler;
+ RID default_material_uniform_set;
+ ShaderData *default_material_shader_ptr = nullptr;
+
+ RID overdraw_material_uniform_set;
+ ShaderData *overdraw_material_shader_ptr = nullptr;
+
SceneShaderForwardClustered();
~SceneShaderForwardClustered();
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 4e93fa5333..7fbd6e23b0 100644
--- a/servers/rendering/renderer_rd/forward_mobile/render_forward_mobile.cpp
+++ b/servers/rendering/renderer_rd/forward_mobile/render_forward_mobile.cpp
@@ -53,13 +53,14 @@ void RenderForwardMobile::RenderBufferDataForwardMobile::clear() {
color_fb = RID();
}
-void RenderForwardMobile::RenderBufferDataForwardMobile::configure(RID p_color_buffer, RID p_depth_buffer, int p_width, int p_height, RS::ViewportMSAA p_msaa) {
+void RenderForwardMobile::RenderBufferDataForwardMobile::configure(RID p_color_buffer, RID p_depth_buffer, int p_width, int p_height, RS::ViewportMSAA p_msaa, uint32_t p_view_count) {
clear();
msaa = p_msaa;
width = p_width;
height = p_height;
+ view_count = p_view_count;
color = p_color_buffer;
depth = p_depth_buffer;
@@ -71,13 +72,18 @@ void RenderForwardMobile::RenderBufferDataForwardMobile::configure(RID p_color_b
fb.push_back(p_color_buffer);
fb.push_back(depth);
- color_fb = RD::get_singleton()->framebuffer_create(fb);
+ color_fb = RD::get_singleton()->framebuffer_create(fb, RenderingDevice::INVALID_ID, view_count);
} else {
RD::TextureFormat tf;
+ if (view_count > 1) {
+ tf.texture_type = RD::TEXTURE_TYPE_2D_ARRAY;
+ } else {
+ tf.texture_type = RD::TEXTURE_TYPE_2D;
+ }
tf.format = RD::DATA_FORMAT_R16G16B16A16_SFLOAT;
tf.width = p_width;
tf.height = p_height;
- tf.texture_type = RD::TEXTURE_TYPE_2D;
+ tf.array_layers = view_count; // create a layer for every view
tf.usage_bits = RD::TEXTURE_USAGE_COLOR_ATTACHMENT_BIT | RD::TEXTURE_USAGE_CAN_COPY_FROM_BIT | RD::TEXTURE_USAGE_SAMPLING_BIT;
RD::TextureSamples ts[RS::VIEWPORT_MSAA_MAX] = {
@@ -103,7 +109,7 @@ void RenderForwardMobile::RenderBufferDataForwardMobile::configure(RID p_color_b
fb.push_back(color_msaa);
fb.push_back(depth_msaa);
- color_fb = RD::get_singleton()->framebuffer_create(fb);
+ color_fb = RD::get_singleton()->framebuffer_create(fb, RenderingDevice::INVALID_ID, view_count);
}
}
}
@@ -226,11 +232,11 @@ RID RenderForwardMobile::_setup_render_pass_uniform_set(RenderListType p_render_
RD::Uniform u;
u.binding = 7;
u.uniform_type = RD::UNIFORM_TYPE_TEXTURE;
- u.ids.resize(MAX_GI_PROBES);
+ u.ids.resize(MAX_VOXEL_GI_INSTANCESS);
RID default_tex = storage->texture_rd_get_default(RendererStorageRD::DEFAULT_RD_TEXTURE_3D_WHITE);
- for (int i = 0; i < MAX_GI_PROBES; i++) {
- if (i < (int)p_gi_probes.size()) {
- RID tex = gi.gi_probe_instance_get_texture(p_gi_probes[i]);
+ for (int i = 0; i < MAX_VOXEL_GI_INSTANCESS; i++) {
+ if (i < (int)p_voxel_gi_instances.size()) {
+ RID tex = gi.voxel_gi_instance_get_texture(p_voxel_gi_instances[i]);
if (!tex.is_valid()) {
tex = default_tex;
}
@@ -283,7 +289,7 @@ RID RenderForwardMobile::_setup_render_pass_uniform_set(RenderListType p_render_
return render_pass_uniform_sets[p_index];
}
-void RenderForwardMobile::_setup_lightmaps(const PagedArray<RID> &p_lightmaps, const Transform &p_cam_transform) {
+void RenderForwardMobile::_setup_lightmaps(const PagedArray<RID> &p_lightmaps, const Transform3D &p_cam_transform) {
// This probably needs to change...
scene_state.lightmaps_used = 0;
for (int i = 0; i < (int)p_lightmaps.size(); i++) {
@@ -329,6 +335,11 @@ void RenderForwardMobile::_render_scene(RenderDataRD *p_render_data, const Color
bool using_ssr = false;
bool using_sss = false;
+ if (p_render_data->render_info) {
+ p_render_data->render_info->info[RS::VIEWPORT_RENDER_INFO_TYPE_VISIBLE][RS::VIEWPORT_RENDER_INFO_DRAW_CALLS_IN_FRAME] = p_render_data->instances->size();
+ p_render_data->render_info->info[RS::VIEWPORT_RENDER_INFO_TYPE_VISIBLE][RS::VIEWPORT_RENDER_INFO_OBJECTS_IN_FRAME] = p_render_data->instances->size();
+ }
+
if (render_buffer) {
// setup rendering to render buffer
screen_size.x = render_buffer->width;
@@ -363,7 +374,7 @@ void RenderForwardMobile::_render_scene(RenderDataRD *p_render_data, const Color
_fill_render_list(RENDER_LIST_OPAQUE, p_render_data, PASS_MODE_COLOR);
render_list[RENDER_LIST_OPAQUE].sort_by_key();
- render_list[RENDER_LIST_ALPHA].sort_by_depth();
+ render_list[RENDER_LIST_ALPHA].sort_by_reverse_depth_and_priority();
// we no longer use this...
_fill_instance_data(RENDER_LIST_OPAQUE);
@@ -479,7 +490,7 @@ void RenderForwardMobile::_render_scene(RenderDataRD *p_render_data, const Color
Vector<Color> c;
c.push_back(clear_color.to_linear());
- 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, PASS_MODE_COLOR, rp_uniform_set, get_debug_draw_mode() == RS::VIEWPORT_DEBUG_DRAW_WIREFRAME, Vector2(), p_render_data->lod_camera_plane, p_render_data->lod_distance_multiplier, p_render_data->screen_lod_threshold);
+ 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, PASS_MODE_COLOR, rp_uniform_set, get_debug_draw_mode() == RS::VIEWPORT_DEBUG_DRAW_WIREFRAME, Vector2(), p_render_data->lod_camera_plane, p_render_data->lod_distance_multiplier, p_render_data->screen_lod_threshold, p_render_data->view_count);
_render_list_with_threads(&render_list_params, opaque_framebuffer, keep_color ? RD::INITIAL_ACTION_KEEP : RD::INITIAL_ACTION_CLEAR, will_continue_color ? RD::FINAL_ACTION_CONTINUE : RD::FINAL_ACTION_READ, RD::INITIAL_ACTION_CLEAR, will_continue_depth ? RD::FINAL_ACTION_CONTINUE : RD::FINAL_ACTION_READ, c, 1.0, 0);
}
@@ -488,14 +499,16 @@ void RenderForwardMobile::_render_scene(RenderDataRD *p_render_data, const Color
if (draw_sky || draw_sky_fog_only) {
RENDER_TIMESTAMP("Render Sky");
- CameraMatrix projection = p_render_data->cam_projection;
+ RD::get_singleton()->draw_command_begin_label("Draw Sky");
+
if (p_render_data->reflection_probe.is_valid()) {
CameraMatrix correction;
correction.set_depth_correction(true);
- projection = correction * p_render_data->cam_projection;
+ CameraMatrix projection = correction * p_render_data->cam_projection;
+ sky.draw(env, can_continue_color, can_continue_depth, opaque_framebuffer, 1, &projection, p_render_data->cam_transform, time);
+ } else {
+ sky.draw(env, can_continue_color, can_continue_depth, opaque_framebuffer, p_render_data->view_count, p_render_data->view_projection, p_render_data->cam_transform, time);
}
- RD::get_singleton()->draw_command_begin_label("Draw Sky");
- sky.draw(env, can_continue_color, can_continue_depth, opaque_framebuffer, projection, p_render_data->cam_transform, time);
RD::get_singleton()->draw_command_end_label();
}
@@ -522,7 +535,7 @@ void RenderForwardMobile::_render_scene(RenderDataRD *p_render_data, const Color
_setup_environment(p_render_data, p_render_data->reflection_probe.is_valid(), screen_size, !p_render_data->reflection_probe.is_valid(), p_default_bg_color, false);
{
- RenderListParameters render_list_params(render_list[RENDER_LIST_ALPHA].elements.ptr(), render_list[RENDER_LIST_ALPHA].element_info.ptr(), render_list[RENDER_LIST_ALPHA].elements.size(), reverse_cull, PASS_MODE_COLOR, rp_uniform_set, get_debug_draw_mode() == RS::VIEWPORT_DEBUG_DRAW_WIREFRAME, Vector2(), p_render_data->lod_camera_plane, p_render_data->lod_distance_multiplier, p_render_data->screen_lod_threshold);
+ RenderListParameters render_list_params(render_list[RENDER_LIST_ALPHA].elements.ptr(), render_list[RENDER_LIST_ALPHA].element_info.ptr(), render_list[RENDER_LIST_ALPHA].elements.size(), reverse_cull, PASS_MODE_COLOR, rp_uniform_set, get_debug_draw_mode() == RS::VIEWPORT_DEBUG_DRAW_WIREFRAME, Vector2(), p_render_data->lod_camera_plane, p_render_data->lod_distance_multiplier, p_render_data->screen_lod_threshold, p_render_data->view_count);
_render_list_with_threads(&render_list_params, alpha_framebuffer, can_continue_color ? RD::INITIAL_ACTION_CONTINUE : RD::INITIAL_ACTION_KEEP, RD::FINAL_ACTION_READ, can_continue_depth ? RD::INITIAL_ACTION_CONTINUE : RD::INITIAL_ACTION_KEEP, RD::FINAL_ACTION_READ);
}
@@ -547,17 +560,23 @@ void RenderForwardMobile::_render_shadow_begin() {
render_list[RENDER_LIST_SECONDARY].clear();
}
-void RenderForwardMobile::_render_shadow_append(RID p_framebuffer, const PagedArray<GeometryInstance *> &p_instances, const CameraMatrix &p_projection, const Transform &p_transform, float p_zfar, float p_bias, float p_normal_bias, bool p_use_dp, bool p_use_dp_flip, bool p_use_pancake, const Plane &p_camera_plane, float p_lod_distance_multiplier, float p_screen_lod_threshold, const Rect2i &p_rect, bool p_flip_y, bool p_clear_region, bool p_begin, bool p_end) {
+void RenderForwardMobile::_render_shadow_append(RID p_framebuffer, const PagedArray<GeometryInstance *> &p_instances, const CameraMatrix &p_projection, const Transform3D &p_transform, float p_zfar, float p_bias, float p_normal_bias, bool p_use_dp, bool p_use_dp_flip, bool p_use_pancake, const Plane &p_camera_plane, float p_lod_distance_multiplier, float p_screen_lod_threshold, const Rect2i &p_rect, bool p_flip_y, bool p_clear_region, bool p_begin, bool p_end, RendererScene::RenderInfo *p_render_info) {
uint32_t shadow_pass_index = scene_state.shadow_passes.size();
SceneState::ShadowPass shadow_pass;
+ if (p_render_info) {
+ p_render_info->info[RS::VIEWPORT_RENDER_INFO_TYPE_SHADOW][RS::VIEWPORT_RENDER_INFO_DRAW_CALLS_IN_FRAME] = p_instances.size();
+ p_render_info->info[RS::VIEWPORT_RENDER_INFO_TYPE_SHADOW][RS::VIEWPORT_RENDER_INFO_OBJECTS_IN_FRAME] = p_instances.size();
+ }
RenderDataRD render_data;
render_data.cam_projection = p_projection;
render_data.cam_transform = p_transform;
+ render_data.view_projection[0] = p_projection;
render_data.z_near = 0.0;
render_data.z_far = p_zfar;
render_data.instances = &p_instances;
+ render_data.render_info = p_render_info;
render_data.lod_camera_plane = p_camera_plane;
render_data.lod_distance_multiplier = p_lod_distance_multiplier;
@@ -622,7 +641,7 @@ void RenderForwardMobile::_render_shadow_end(uint32_t p_barrier) {
for (uint32_t i = 0; i < scene_state.shadow_passes.size(); i++) {
SceneState::ShadowPass &shadow_pass = scene_state.shadow_passes[i];
- RenderListParameters render_list_parameters(render_list[RENDER_LIST_SECONDARY].elements.ptr() + shadow_pass.element_from, render_list[RENDER_LIST_SECONDARY].element_info.ptr() + shadow_pass.element_from, shadow_pass.element_count, shadow_pass.flip_cull, shadow_pass.pass_mode, shadow_pass.rp_uniform_set, false, Vector2(), shadow_pass.camera_plane, shadow_pass.lod_distance_multiplier, shadow_pass.screen_lod_threshold, shadow_pass.element_from, RD::BARRIER_MASK_NO_BARRIER);
+ RenderListParameters render_list_parameters(render_list[RENDER_LIST_SECONDARY].elements.ptr() + shadow_pass.element_from, render_list[RENDER_LIST_SECONDARY].element_info.ptr() + shadow_pass.element_from, shadow_pass.element_count, shadow_pass.flip_cull, shadow_pass.pass_mode, shadow_pass.rp_uniform_set, false, Vector2(), shadow_pass.camera_plane, shadow_pass.lod_distance_multiplier, shadow_pass.screen_lod_threshold, 1, shadow_pass.element_from, RD::BARRIER_MASK_NO_BARRIER);
_render_list_with_threads(&render_list_parameters, shadow_pass.framebuffer, RD::INITIAL_ACTION_DROP, RD::FINAL_ACTION_DISCARD, shadow_pass.initial_depth_action, shadow_pass.final_depth_action, Vector<Color>(), 1.0, 0, shadow_pass.rect);
}
@@ -634,7 +653,7 @@ void RenderForwardMobile::_render_shadow_end(uint32_t p_barrier) {
/* */
-void RenderForwardMobile::_render_material(const Transform &p_cam_transform, const CameraMatrix &p_cam_projection, bool p_cam_ortogonal, const PagedArray<GeometryInstance *> &p_instances, RID p_framebuffer, const Rect2i &p_region) {
+void RenderForwardMobile::_render_material(const Transform3D &p_cam_transform, const CameraMatrix &p_cam_projection, bool p_cam_ortogonal, const PagedArray<GeometryInstance *> &p_instances, RID p_framebuffer, const Rect2i &p_region) {
RENDER_TIMESTAMP("Setup Rendering Material");
RD::get_singleton()->draw_command_begin_label("Render Material");
@@ -647,6 +666,7 @@ void RenderForwardMobile::_render_material(const Transform &p_cam_transform, con
RenderDataRD render_data;
render_data.cam_projection = p_cam_projection;
render_data.cam_transform = p_cam_transform;
+ render_data.view_projection[0] = p_cam_projection;
render_data.instances = &p_instances;
_setup_environment(&render_data, true, Vector2(1, 1), false, Color());
@@ -746,7 +766,7 @@ void RenderForwardMobile::_render_sdfgi(RID p_render_buffers, const Vector3i &p_
// we don't do GI in low end..
}
-void RenderForwardMobile::_render_particle_collider_heightfield(RID p_fb, const Transform &p_cam_transform, const CameraMatrix &p_cam_projection, const PagedArray<GeometryInstance *> &p_instances) {
+void RenderForwardMobile::_render_particle_collider_heightfield(RID p_fb, const Transform3D &p_cam_transform, const CameraMatrix &p_cam_projection, const PagedArray<GeometryInstance *> &p_instances) {
RENDER_TIMESTAMP("Setup Render Collider Heightfield");
RD::get_singleton()->draw_command_begin_label("Render Collider Heightfield");
@@ -757,6 +777,7 @@ void RenderForwardMobile::_render_particle_collider_heightfield(RID p_fb, const
RenderDataRD render_data;
render_data.cam_projection = p_cam_projection;
render_data.cam_transform = p_cam_transform;
+ render_data.view_projection[0] = p_cam_projection;
render_data.z_near = 0.0;
render_data.z_far = p_cam_projection.get_z_far();
render_data.instances = &p_instances;
@@ -916,6 +937,12 @@ RID RenderForwardMobile::_render_buffers_get_normal_texture(RID p_render_buffers
return RID();
}
+_FORCE_INLINE_ static uint32_t _indices_to_primitives(RS::PrimitiveType p_primitive, uint32_t p_indices) {
+ static const uint32_t divisor[RS::PRIMITIVE_MAX] = { 1, 2, 1, 3, 1 };
+ static const uint32_t subtractor[RS::PRIMITIVE_MAX] = { 0, 0, 1, 0, 1 };
+ return (p_indices - subtractor[p_primitive]) / divisor[p_primitive];
+}
+
void RenderForwardMobile::_fill_render_list(RenderListType p_render_list, const RenderDataRD *p_render_data, PassMode p_pass_mode, bool p_append) {
if (p_render_list == RENDER_LIST_OPAQUE) {
scene_state.used_sss = false;
@@ -952,6 +979,10 @@ void RenderForwardMobile::_fill_render_list(RenderListType p_render_list, const
uint32_t flags = inst->base_flags; //fill flags if appropriate
+ if (inst->non_uniform_scale) {
+ flags |= INSTANCE_DATA_FLAGS_NON_UNIFORM_SCALE;
+ }
+
bool uses_lightmap = false;
// bool uses_gi = false;
@@ -1021,21 +1052,42 @@ void RenderForwardMobile::_fill_render_list(RenderListType p_render_list, const
distance = -distance_max;
}
- surf->lod_index = storage->mesh_surface_get_lod(surf->surface, inst->lod_model_scale * inst->lod_bias, distance * p_render_data->lod_distance_multiplier, p_render_data->screen_lod_threshold);
+ uint32_t indices;
+ surf->lod_index = storage->mesh_surface_get_lod(surf->surface, inst->lod_model_scale * inst->lod_bias, distance * p_render_data->lod_distance_multiplier, p_render_data->screen_lod_threshold, &indices);
+ if (p_render_data->render_info) {
+ indices = _indices_to_primitives(surf->primitive, indices);
+ if (p_render_list == RENDER_LIST_OPAQUE) { //opaque
+ p_render_data->render_info->info[RS::VIEWPORT_RENDER_INFO_TYPE_VISIBLE][RS::VIEWPORT_RENDER_INFO_PRIMITIVES_IN_FRAME] += indices;
+ } else if (p_render_list == RENDER_LIST_SECONDARY) { //shadow
+ p_render_data->render_info->info[RS::VIEWPORT_RENDER_INFO_TYPE_SHADOW][RS::VIEWPORT_RENDER_INFO_PRIMITIVES_IN_FRAME] += indices;
+ }
+ }
} else {
surf->lod_index = 0;
+ if (p_render_data->render_info) {
+ uint32_t to_draw = storage->mesh_surface_get_vertices_drawn_count(surf->surface);
+ to_draw = _indices_to_primitives(surf->primitive, to_draw);
+ to_draw *= inst->instance_count;
+ if (p_render_list == RENDER_LIST_OPAQUE) { //opaque
+ p_render_data->render_info->info[RS::VIEWPORT_RENDER_INFO_TYPE_VISIBLE][RS::VIEWPORT_RENDER_INFO_PRIMITIVES_IN_FRAME] += storage->mesh_surface_get_vertices_drawn_count(surf->surface);
+ } else if (p_render_list == RENDER_LIST_SECONDARY) { //shadow
+ p_render_data->render_info->info[RS::VIEWPORT_RENDER_INFO_TYPE_SHADOW][RS::VIEWPORT_RENDER_INFO_PRIMITIVES_IN_FRAME] += storage->mesh_surface_get_vertices_drawn_count(surf->surface);
+ }
+ }
}
// ADD Element
if (p_pass_mode == PASS_MODE_COLOR) {
- if (surf->flags & (GeometryInstanceSurfaceDataCache::FLAG_PASS_DEPTH | GeometryInstanceSurfaceDataCache::FLAG_PASS_OPAQUE)) {
+#ifdef DEBUG_ENABLED
+ bool force_alpha = unlikely(get_debug_draw_mode() == RS::VIEWPORT_DEBUG_DRAW_OVERDRAW);
+#else
+ bool force_alpha = false;
+#endif
+ if (!force_alpha && (surf->flags & (GeometryInstanceSurfaceDataCache::FLAG_PASS_DEPTH | GeometryInstanceSurfaceDataCache::FLAG_PASS_OPAQUE))) {
rl->add_element(surf);
}
- if (surf->flags & GeometryInstanceSurfaceDataCache::FLAG_PASS_ALPHA) {
+ if (force_alpha || (surf->flags & GeometryInstanceSurfaceDataCache::FLAG_PASS_ALPHA)) {
render_list[RENDER_LIST_ALPHA].add_element(surf);
- // if (uses_gi) {
- // surf->sort.uses_forward_gi = 1;
- // }
}
if (uses_lightmap) {
@@ -1089,6 +1141,12 @@ void RenderForwardMobile::_setup_environment(const RenderDataRD *p_render_data,
RendererStorageRD::store_transform(p_render_data->cam_transform, scene_state.ubo.camera_matrix);
RendererStorageRD::store_transform(p_render_data->cam_transform.affine_inverse(), scene_state.ubo.inv_camera_matrix);
+ for (uint32_t v = 0; v < p_render_data->view_count; v++) {
+ projection = correction * p_render_data->view_projection[v];
+ RendererStorageRD::store_camera(projection, scene_state.ubo.projection_matrix_view[v]);
+ RendererStorageRD::store_camera(projection.inverse(), scene_state.ubo.inv_projection_matrix_view[v]);
+ }
+
scene_state.ubo.z_far = p_render_data->z_far;
scene_state.ubo.z_near = p_render_data->z_near;
@@ -1364,7 +1422,7 @@ void RenderForwardMobile::_render_list_template(RenderingDevice::DrawListID p_dr
if (inst->store_transform_cache) {
RendererStorageRD::store_transform(inst->transform, push_constant.transform);
} else {
- RendererStorageRD::store_transform(Transform(), push_constant.transform);
+ RendererStorageRD::store_transform(Transform3D(), push_constant.transform);
}
push_constant.flags = inst->flags_cache;
@@ -1395,8 +1453,20 @@ void RenderForwardMobile::_render_list_template(RenderingDevice::DrawListID p_dr
mesh_surface = surf->surface_shadow;
} else {
- material_uniform_set = surf->material_uniform_set;
- shader = surf->shader;
+#ifdef DEBUG_ENABLED
+ if (unlikely(get_debug_draw_mode() == RS::VIEWPORT_DEBUG_DRAW_LIGHTING)) {
+ material_uniform_set = scene_shader.default_material_uniform_set;
+ shader = scene_shader.default_material_shader_ptr;
+ } else if (unlikely(get_debug_draw_mode() == RS::VIEWPORT_DEBUG_DRAW_OVERDRAW)) {
+ material_uniform_set = scene_shader.overdraw_material_uniform_set;
+ shader = scene_shader.overdraw_material_shader_ptr;
+ } else {
+#endif
+ material_uniform_set = surf->material_uniform_set;
+ shader = surf->shader;
+#ifdef DEBUG_ENABLED
+ }
+#endif
mesh_surface = surf->surface;
}
@@ -1426,18 +1496,20 @@ void RenderForwardMobile::_render_list_template(RenderingDevice::DrawListID p_dr
case PASS_MODE_COLOR:
case PASS_MODE_COLOR_TRANSPARENT: {
if (element_info.uses_lightmap) {
- shader_version = SceneShaderForwardMobile::SHADER_VERSION_LIGHTMAP_COLOR_PASS;
+ shader_version = p_params->view_count > 1 ? SceneShaderForwardMobile::SHADER_VERSION_LIGHTMAP_COLOR_PASS_MULTIVIEW : SceneShaderForwardMobile::SHADER_VERSION_LIGHTMAP_COLOR_PASS;
} else {
- shader_version = SceneShaderForwardMobile::SHADER_VERSION_COLOR_PASS;
+ shader_version = p_params->view_count > 1 ? SceneShaderForwardMobile::SHADER_VERSION_COLOR_PASS_MULTIVIEW : SceneShaderForwardMobile::SHADER_VERSION_COLOR_PASS;
}
} break;
case PASS_MODE_SHADOW: {
- shader_version = SceneShaderForwardMobile::SHADER_VERSION_SHADOW_PASS;
+ shader_version = p_params->view_count > 1 ? SceneShaderForwardMobile::SHADER_VERSION_SHADOW_PASS_MULTIVIEW : SceneShaderForwardMobile::SHADER_VERSION_SHADOW_PASS;
} break;
case PASS_MODE_SHADOW_DP: {
- shader_version = SceneShaderForwardMobile::SHADER_VERSION_DEPTH_PASS_DP;
+ ERR_FAIL_COND_MSG(p_params->view_count > 1, "Multiview not supported for shadow DP pass");
+ shader_version = SceneShaderForwardMobile::SHADER_VERSION_SHADOW_PASS_DP;
} break;
case PASS_MODE_DEPTH_MATERIAL: {
+ ERR_FAIL_COND_MSG(p_params->view_count > 1, "Multiview not supported for material pass");
shader_version = SceneShaderForwardMobile::SHADER_VERSION_DEPTH_PASS_WITH_MATERIAL;
} break;
}
@@ -1557,7 +1629,7 @@ void RenderForwardMobile::geometry_instance_set_mesh_instance(GeometryInstance *
_geometry_instance_mark_dirty(ginstance);
}
-void RenderForwardMobile::geometry_instance_set_transform(GeometryInstance *p_geometry_instance, const Transform &p_transform, const AABB &p_aabb, const AABB &p_transformed_aabb) {
+void RenderForwardMobile::geometry_instance_set_transform(GeometryInstance *p_geometry_instance, const Transform3D &p_transform, const AABB &p_aabb, const AABB &p_transformed_aabb) {
GeometryInstanceForwardMobile *ginstance = static_cast<GeometryInstanceForwardMobile *>(p_geometry_instance);
ERR_FAIL_COND(!ginstance);
ginstance->transform = p_transform;
@@ -1645,9 +1717,9 @@ void RenderForwardMobile::geometry_instance_set_cast_double_sided_shadows(Geomet
_geometry_instance_mark_dirty(ginstance);
}
-Transform RenderForwardMobile::geometry_instance_get_transform(GeometryInstance *p_instance) {
+Transform3D RenderForwardMobile::geometry_instance_get_transform(GeometryInstance *p_instance) {
GeometryInstanceForwardMobile *ginstance = static_cast<GeometryInstanceForwardMobile *>(p_instance);
- ERR_FAIL_COND_V(!ginstance, Transform());
+ ERR_FAIL_COND_V(!ginstance, Transform3D());
return ginstance->transform;
}
@@ -1725,7 +1797,7 @@ void RenderForwardMobile::geometry_instance_pair_decal_instances(GeometryInstanc
}
}
-void RenderForwardMobile::geometry_instance_pair_gi_probe_instances(GeometryInstance *p_geometry_instance, const RID *p_gi_probe_instances, uint32_t p_gi_probe_instance_count) {
+void RenderForwardMobile::geometry_instance_pair_voxel_gi_instances(GeometryInstance *p_geometry_instance, const RID *p_voxel_gi_instances, uint32_t p_voxel_gi_instance_count) {
// We do not have this here!
}
@@ -1976,6 +2048,7 @@ void RenderForwardMobile::_geometry_instance_update(GeometryInstance *p_geometry
//Fill push constant
bool store_transform = true;
+ ginstance->base_flags = 0;
if (ginstance->data->base_type == RS::INSTANCE_MULTIMESH) {
ginstance->base_flags |= INSTANCE_DATA_FLAG_MULTIMESH;
diff --git a/servers/rendering/renderer_rd/forward_mobile/render_forward_mobile.h b/servers/rendering/renderer_rd/forward_mobile/render_forward_mobile.h
index bf911319f2..f40f713c03 100644
--- a/servers/rendering/renderer_rd/forward_mobile/render_forward_mobile.h
+++ b/servers/rendering/renderer_rd/forward_mobile/render_forward_mobile.h
@@ -85,14 +85,15 @@ protected:
RID color_fb;
int width, height;
+ uint32_t view_count;
void clear();
- virtual void configure(RID p_color_buffer, RID p_depth_buffer, int p_width, int p_height, RS::ViewportMSAA p_msaa);
+ virtual void configure(RID p_color_buffer, RID p_depth_buffer, int p_width, int p_height, RS::ViewportMSAA p_msaa, uint32_t p_view_count);
~RenderBufferDataForwardMobile();
};
- virtual RenderBufferData *_create_render_buffer_data();
+ virtual RenderBufferData *_create_render_buffer_data() override;
/* Rendering */
@@ -104,7 +105,7 @@ protected:
PASS_MODE_SHADOW_DP,
// PASS_MODE_DEPTH,
// PASS_MODE_DEPTH_NORMAL_ROUGHNESS,
- // PASS_MODE_DEPTH_NORMAL_ROUGHNESS_GIPROBE,
+ // PASS_MODE_DEPTH_NORMAL_ROUGHNESS_VOXEL_GI,
PASS_MODE_DEPTH_MATERIAL,
// PASS_MODE_SDF,
};
@@ -120,6 +121,7 @@ protected:
bool reverse_cull = false;
PassMode pass_mode = PASS_MODE_COLOR;
// bool no_gi = false;
+ uint32_t view_count = 1;
RID render_pass_uniform_set;
bool force_wireframe = false;
Vector2 uv_offset;
@@ -130,13 +132,14 @@ protected:
uint32_t element_offset = 0;
uint32_t barrier = RD::BARRIER_MASK_ALL;
- RenderListParameters(GeometryInstanceSurfaceDataCache **p_elements, RenderElementInfo *p_element_info, int p_element_count, bool p_reverse_cull, PassMode p_pass_mode, RID p_render_pass_uniform_set, bool p_force_wireframe = false, const Vector2 &p_uv_offset = Vector2(), const Plane &p_lod_plane = Plane(), float p_lod_distance_multiplier = 0.0, float p_screen_lod_threshold = 0.0, uint32_t p_element_offset = 0, uint32_t p_barrier = RD::BARRIER_MASK_ALL) {
+ RenderListParameters(GeometryInstanceSurfaceDataCache **p_elements, RenderElementInfo *p_element_info, int p_element_count, bool p_reverse_cull, PassMode p_pass_mode, RID p_render_pass_uniform_set, bool p_force_wireframe = false, const Vector2 &p_uv_offset = Vector2(), const Plane &p_lod_plane = Plane(), float p_lod_distance_multiplier = 0.0, float p_screen_lod_threshold = 0.0, uint32_t p_view_count = 1, uint32_t p_element_offset = 0, uint32_t p_barrier = RD::BARRIER_MASK_ALL) {
elements = p_elements;
element_info = p_element_info;
element_count = p_element_count;
reverse_cull = p_reverse_cull;
pass_mode = p_pass_mode;
// no_gi = p_no_gi;
+ view_count = p_view_count;
render_pass_uniform_set = p_render_pass_uniform_set;
force_wireframe = p_force_wireframe;
uv_offset = p_uv_offset;
@@ -149,23 +152,23 @@ protected:
};
RID _setup_render_pass_uniform_set(RenderListType p_render_list, const RenderDataRD *p_render_data, RID p_radiance_texture, bool p_use_directional_shadow_atlas = false, int p_index = 0);
- virtual void _render_scene(RenderDataRD *p_render_data, const Color &p_default_bg_color);
+ virtual void _render_scene(RenderDataRD *p_render_data, const Color &p_default_bg_color) override;
- virtual void _render_shadow_begin();
- virtual void _render_shadow_append(RID p_framebuffer, const PagedArray<GeometryInstance *> &p_instances, const CameraMatrix &p_projection, const Transform &p_transform, float p_zfar, float p_bias, float p_normal_bias, bool p_use_dp, bool p_use_dp_flip, bool p_use_pancake, const Plane &p_camera_plane = Plane(), float p_lod_distance_multiplier = 0.0, float p_screen_lod_threshold = 0.0, const Rect2i &p_rect = Rect2i(), bool p_flip_y = false, bool p_clear_region = true, bool p_begin = true, bool p_end = true);
- virtual void _render_shadow_process();
- virtual void _render_shadow_end(uint32_t p_barrier = RD::BARRIER_MASK_ALL);
+ virtual void _render_shadow_begin() override;
+ virtual void _render_shadow_append(RID p_framebuffer, const PagedArray<GeometryInstance *> &p_instances, const CameraMatrix &p_projection, const Transform3D &p_transform, float p_zfar, float p_bias, float p_normal_bias, bool p_use_dp, bool p_use_dp_flip, bool p_use_pancake, const Plane &p_camera_plane = Plane(), float p_lod_distance_multiplier = 0.0, float p_screen_lod_threshold = 0.0, const Rect2i &p_rect = Rect2i(), bool p_flip_y = false, bool p_clear_region = true, bool p_begin = true, bool p_end = true, RendererScene::RenderInfo *p_render_info = nullptr) override;
+ virtual void _render_shadow_process() override;
+ virtual void _render_shadow_end(uint32_t p_barrier = RD::BARRIER_MASK_ALL) override;
- virtual void _render_material(const Transform &p_cam_transform, const CameraMatrix &p_cam_projection, bool p_cam_ortogonal, const PagedArray<GeometryInstance *> &p_instances, RID p_framebuffer, const Rect2i &p_region);
- virtual void _render_uv2(const PagedArray<GeometryInstance *> &p_instances, RID p_framebuffer, const Rect2i &p_region);
- virtual void _render_sdfgi(RID p_render_buffers, const Vector3i &p_from, const Vector3i &p_size, const AABB &p_bounds, const PagedArray<GeometryInstance *> &p_instances, const RID &p_albedo_texture, const RID &p_emission_texture, const RID &p_emission_aniso_texture, const RID &p_geom_facing_texture);
- virtual void _render_particle_collider_heightfield(RID p_fb, const Transform &p_cam_transform, const CameraMatrix &p_cam_projection, const PagedArray<GeometryInstance *> &p_instances);
+ virtual void _render_material(const Transform3D &p_cam_transform, const CameraMatrix &p_cam_projection, bool p_cam_ortogonal, const PagedArray<GeometryInstance *> &p_instances, RID p_framebuffer, const Rect2i &p_region) override;
+ virtual void _render_uv2(const PagedArray<GeometryInstance *> &p_instances, RID p_framebuffer, const Rect2i &p_region) override;
+ virtual void _render_sdfgi(RID p_render_buffers, const Vector3i &p_from, const Vector3i &p_size, const AABB &p_bounds, const PagedArray<GeometryInstance *> &p_instances, const RID &p_albedo_texture, const RID &p_emission_texture, const RID &p_emission_aniso_texture, const RID &p_geom_facing_texture) override;
+ virtual void _render_particle_collider_heightfield(RID p_fb, const Transform3D &p_cam_transform, const CameraMatrix &p_cam_projection, const PagedArray<GeometryInstance *> &p_instances) override;
uint64_t lightmap_texture_array_version = 0xFFFFFFFF;
- virtual void _base_uniforms_changed();
+ virtual void _base_uniforms_changed() override;
void _update_render_base_uniform_set();
- virtual RID _render_buffers_get_normal_texture(RID p_render_buffers);
+ virtual RID _render_buffers_get_normal_texture(RID p_render_buffers) override;
void _fill_render_list(RenderListType p_render_list, const RenderDataRD *p_render_data, PassMode p_pass_mode, bool p_append = false);
void _fill_instance_data(RenderListType p_render_list, uint32_t p_offset = 0, int32_t p_max_elements = -1, bool p_update_buffer = true);
@@ -174,7 +177,7 @@ protected:
static RenderForwardMobile *singleton;
void _setup_environment(const RenderDataRD *p_render_data, bool p_no_fog, const Size2i &p_screen_size, bool p_flip_y, const Color &p_default_bg_color, bool p_opaque_render_buffers = false, bool p_pancake_shadows = false, int p_index = 0);
- void _setup_lightmaps(const PagedArray<RID> &p_lightmaps, const Transform &p_cam_transform);
+ void _setup_lightmaps(const PagedArray<RID> &p_lightmaps, const Transform3D &p_cam_transform);
RID render_base_uniform_set;
LocalVector<RID> render_pass_uniform_sets;
@@ -196,10 +199,12 @@ protected:
struct UBO {
float projection_matrix[16];
float inv_projection_matrix[16];
-
float camera_matrix[16];
float inv_camera_matrix[16];
+ float projection_matrix_view[RendererSceneRender::MAX_RENDER_VIEWS][16];
+ float inv_projection_matrix_view[RendererSceneRender::MAX_RENDER_VIEWS][16];
+
float viewport_size[2];
float screen_pixel_size[2];
@@ -351,7 +356,7 @@ protected:
}
};
- void sort_by_reverse_depth_and_priority(bool p_alpha) { //used for alpha
+ void sort_by_reverse_depth_and_priority() { //used for alpha
SortArray<GeometryInstanceSurfaceDataCache *, SortByReverseDepthAndPriority> sorter;
sorter.sort(elements.ptr(), elements.size());
@@ -385,19 +390,19 @@ protected:
// check which ones of these apply, probably all except GI and SDFGI
enum {
+ INSTANCE_DATA_FLAGS_NON_UNIFORM_SCALE = 1 << 5,
INSTANCE_DATA_FLAG_USE_GI_BUFFERS = 1 << 6,
INSTANCE_DATA_FLAG_USE_SDFGI = 1 << 7,
INSTANCE_DATA_FLAG_USE_LIGHTMAP_CAPTURE = 1 << 8,
INSTANCE_DATA_FLAG_USE_LIGHTMAP = 1 << 9,
INSTANCE_DATA_FLAG_USE_SH_LIGHTMAP = 1 << 10,
- INSTANCE_DATA_FLAG_USE_GIPROBE = 1 << 11,
+ INSTANCE_DATA_FLAG_USE_VOXEL_GI = 1 << 11,
INSTANCE_DATA_FLAG_MULTIMESH = 1 << 12,
INSTANCE_DATA_FLAG_MULTIMESH_FORMAT_2D = 1 << 13,
INSTANCE_DATA_FLAG_MULTIMESH_HAS_COLOR = 1 << 14,
INSTANCE_DATA_FLAG_MULTIMESH_HAS_CUSTOM_DATA = 1 << 15,
INSTANCE_DATA_FLAGS_PARTICLE_TRAIL_SHIFT = 16,
INSTANCE_DATA_FLAGS_PARTICLE_TRAIL_MASK = 0xFF,
- INSTANCE_DATA_FLAGS_NON_UNIFORM_SCALE = 1 << 24,
};
struct GeometryInstanceLightmapSH {
@@ -489,7 +494,7 @@ protected:
RID transforms_uniform_set;
float depth = 0;
bool mirror = false;
- Transform transform;
+ Transform3D transform;
bool store_transform_cache = true; // if true we copy our transform into our PushConstant, if false we use our transforms UBO and clear our PushConstants transform
bool non_uniform_scale = false;
AABB transformed_aabb; //needed for LOD
@@ -563,38 +568,38 @@ public:
void _geometry_instance_update(GeometryInstance *p_geometry_instance);
void _update_dirty_geometry_instances();
- virtual GeometryInstance *geometry_instance_create(RID p_base);
- virtual void geometry_instance_set_skeleton(GeometryInstance *p_geometry_instance, RID p_skeleton);
- virtual void geometry_instance_set_material_override(GeometryInstance *p_geometry_instance, RID p_override);
- virtual void geometry_instance_set_surface_materials(GeometryInstance *p_geometry_instance, const Vector<RID> &p_materials);
- virtual void geometry_instance_set_mesh_instance(GeometryInstance *p_geometry_instance, RID p_mesh_instance);
- virtual void geometry_instance_set_transform(GeometryInstance *p_geometry_instance, const Transform &p_transform, const AABB &p_aabb, const AABB &p_transformed_aabb);
- virtual void geometry_instance_set_layer_mask(GeometryInstance *p_geometry_instance, uint32_t p_layer_mask);
- virtual void geometry_instance_set_lod_bias(GeometryInstance *p_geometry_instance, float p_lod_bias);
- virtual void geometry_instance_set_use_baked_light(GeometryInstance *p_geometry_instance, bool p_enable);
- virtual void geometry_instance_set_use_dynamic_gi(GeometryInstance *p_geometry_instance, bool p_enable);
- virtual void geometry_instance_set_use_lightmap(GeometryInstance *p_geometry_instance, RID p_lightmap_instance, const Rect2 &p_lightmap_uv_scale, int p_lightmap_slice_index);
- virtual void geometry_instance_set_lightmap_capture(GeometryInstance *p_geometry_instance, const Color *p_sh9);
- virtual void geometry_instance_set_instance_shader_parameters_offset(GeometryInstance *p_geometry_instance, int32_t p_offset);
- virtual void geometry_instance_set_cast_double_sided_shadows(GeometryInstance *p_geometry_instance, bool p_enable);
-
- virtual Transform geometry_instance_get_transform(GeometryInstance *p_instance);
- virtual AABB geometry_instance_get_aabb(GeometryInstance *p_instance);
-
- virtual void geometry_instance_free(GeometryInstance *p_geometry_instance);
-
- virtual uint32_t geometry_instance_get_pair_mask();
- virtual void geometry_instance_pair_light_instances(GeometryInstance *p_geometry_instance, const RID *p_light_instances, uint32_t p_light_instance_count);
- virtual void geometry_instance_pair_reflection_probe_instances(GeometryInstance *p_geometry_instance, const RID *p_reflection_probe_instances, uint32_t p_reflection_probe_instance_count);
- virtual void geometry_instance_pair_decal_instances(GeometryInstance *p_geometry_instance, const RID *p_decal_instances, uint32_t p_decal_instance_count);
- virtual void geometry_instance_pair_gi_probe_instances(GeometryInstance *p_geometry_instance, const RID *p_gi_probe_instances, uint32_t p_gi_probe_instance_count);
-
- virtual bool free(RID p_rid);
-
- virtual bool is_dynamic_gi_supported() const;
- virtual bool is_clustered_enabled() const;
- virtual bool is_volumetric_supported() const;
- virtual uint32_t get_max_elements() const;
+ virtual GeometryInstance *geometry_instance_create(RID p_base) override;
+ virtual void geometry_instance_set_skeleton(GeometryInstance *p_geometry_instance, RID p_skeleton) override;
+ virtual void geometry_instance_set_material_override(GeometryInstance *p_geometry_instance, RID p_override) override;
+ virtual void geometry_instance_set_surface_materials(GeometryInstance *p_geometry_instance, const Vector<RID> &p_materials) override;
+ virtual void geometry_instance_set_mesh_instance(GeometryInstance *p_geometry_instance, RID p_mesh_instance) override;
+ virtual void geometry_instance_set_transform(GeometryInstance *p_geometry_instance, const Transform3D &p_transform, const AABB &p_aabb, const AABB &p_transformed_aabb) override;
+ virtual void geometry_instance_set_layer_mask(GeometryInstance *p_geometry_instance, uint32_t p_layer_mask) override;
+ virtual void geometry_instance_set_lod_bias(GeometryInstance *p_geometry_instance, float p_lod_bias) override;
+ virtual void geometry_instance_set_use_baked_light(GeometryInstance *p_geometry_instance, bool p_enable) override;
+ virtual void geometry_instance_set_use_dynamic_gi(GeometryInstance *p_geometry_instance, bool p_enable) override;
+ virtual void geometry_instance_set_use_lightmap(GeometryInstance *p_geometry_instance, RID p_lightmap_instance, const Rect2 &p_lightmap_uv_scale, int p_lightmap_slice_index) override;
+ virtual void geometry_instance_set_lightmap_capture(GeometryInstance *p_geometry_instance, const Color *p_sh9) override;
+ virtual void geometry_instance_set_instance_shader_parameters_offset(GeometryInstance *p_geometry_instance, int32_t p_offset) override;
+ virtual void geometry_instance_set_cast_double_sided_shadows(GeometryInstance *p_geometry_instance, bool p_enable) override;
+
+ virtual Transform3D geometry_instance_get_transform(GeometryInstance *p_instance) override;
+ virtual AABB geometry_instance_get_aabb(GeometryInstance *p_instance) override;
+
+ virtual void geometry_instance_free(GeometryInstance *p_geometry_instance) override;
+
+ virtual uint32_t geometry_instance_get_pair_mask() override;
+ virtual void geometry_instance_pair_light_instances(GeometryInstance *p_geometry_instance, const RID *p_light_instances, uint32_t p_light_instance_count) override;
+ virtual void geometry_instance_pair_reflection_probe_instances(GeometryInstance *p_geometry_instance, const RID *p_reflection_probe_instances, uint32_t p_reflection_probe_instance_count) override;
+ virtual void geometry_instance_pair_decal_instances(GeometryInstance *p_geometry_instance, const RID *p_decal_instances, uint32_t p_decal_instance_count) override;
+ virtual void geometry_instance_pair_voxel_gi_instances(GeometryInstance *p_geometry_instance, const RID *p_voxel_gi_instances, uint32_t p_voxel_gi_instance_count) override;
+
+ virtual bool free(RID p_rid) override;
+
+ virtual bool is_dynamic_gi_supported() const override;
+ virtual bool is_clustered_enabled() const override;
+ virtual bool is_volumetric_supported() const override;
+ virtual uint32_t get_max_elements() const override;
RenderForwardMobile(RendererStorageRD *p_storage);
~RenderForwardMobile();
diff --git a/servers/rendering/renderer_rd/forward_mobile/scene_shader_forward_mobile.cpp b/servers/rendering/renderer_rd/forward_mobile/scene_shader_forward_mobile.cpp
index 883273c8a5..7709c8aadc 100644
--- a/servers/rendering/renderer_rd/forward_mobile/scene_shader_forward_mobile.cpp
+++ b/servers/rendering/renderer_rd/forward_mobile/scene_shader_forward_mobile.cpp
@@ -32,6 +32,7 @@
#include "core/config/project_settings.h"
#include "core/math/math_defs.h"
#include "render_forward_mobile.h"
+#include "servers/rendering/renderer_rd/renderer_compositor_rd.h"
using namespace RendererSceneRenderImplementation;
@@ -291,12 +292,12 @@ void SceneShaderForwardMobile::ShaderData::set_code(const String &p_code) {
multisample_state.enable_alpha_to_one = true;
}
- if (k == SHADER_VERSION_COLOR_PASS || k == SHADER_VERSION_LIGHTMAP_COLOR_PASS) {
+ if (k == SHADER_VERSION_COLOR_PASS || k == SHADER_VERSION_COLOR_PASS_MULTIVIEW || k == SHADER_VERSION_LIGHTMAP_COLOR_PASS || k == SHADER_VERSION_LIGHTMAP_COLOR_PASS_MULTIVIEW) {
blend_state = blend_state_blend;
if (depth_draw == DEPTH_DRAW_OPAQUE) {
depth_stencil.enable_depth_write = false; //alpha does not draw depth
}
- } else if (k == SHADER_VERSION_SHADOW_PASS || k == SHADER_VERSION_DEPTH_PASS_DP) {
+ } else if (k == SHADER_VERSION_SHADOW_PASS || k == SHADER_VERSION_SHADOW_PASS_MULTIVIEW || k == SHADER_VERSION_SHADOW_PASS_DP) {
//none, blend state contains nothing
} else if (k == SHADER_VERSION_DEPTH_PASS_WITH_MATERIAL) {
blend_state = RD::PipelineColorBlendState::create_disabled(5); //writes to normal and roughness in opaque way
@@ -304,57 +305,16 @@ void SceneShaderForwardMobile::ShaderData::set_code(const String &p_code) {
pipelines[i][j][k].clear();
continue; // do not use this version (will error if using it is attempted)
}
-
- /*
- if (k == SHADER_VERSION_COLOR_PASS || k == SHADER_VERSION_COLOR_PASS_WITH_FORWARD_GI || k == SHADER_VERSION_LIGHTMAP_COLOR_PASS) {
- blend_state = blend_state_blend;
- if (depth_draw == DEPTH_DRAW_OPAQUE) {
- depth_stencil.enable_depth_write = false; //alpha does not draw depth
- }
- } else if (uses_depth_pre_pass && (k == SHADER_VERSION_DEPTH_PASS || k == SHADER_VERSION_DEPTH_PASS_DP || k == SHADER_VERSION_DEPTH_PASS_WITH_NORMAL_AND_ROUGHNESS || k == SHADER_VERSION_DEPTH_PASS_WITH_MATERIAL)) {
- if (k == SHADER_VERSION_DEPTH_PASS || k == SHADER_VERSION_DEPTH_PASS_DP) {
- //none, blend state contains nothing
- } else if (k == SHADER_VERSION_DEPTH_PASS_WITH_MATERIAL) {
- blend_state = RD::PipelineColorBlendState::create_disabled(5); //writes to normal and roughness in opaque way
- } else {
- blend_state = blend_state_opaque; //writes to normal and roughness in opaque way
- }
- } else {
- pipelines[i][j][k].clear();
- continue; // do not use this version (will error if using it is attempted)
- }
- */
} else {
- if (k == SHADER_VERSION_COLOR_PASS || k == SHADER_VERSION_LIGHTMAP_COLOR_PASS) {
+ if (k == SHADER_VERSION_COLOR_PASS || k == SHADER_VERSION_COLOR_PASS_MULTIVIEW || k == SHADER_VERSION_LIGHTMAP_COLOR_PASS || k == SHADER_VERSION_LIGHTMAP_COLOR_PASS_MULTIVIEW) {
blend_state = blend_state_opaque;
- } else if (k == SHADER_VERSION_SHADOW_PASS || k == SHADER_VERSION_DEPTH_PASS_DP) {
+ } else if (k == SHADER_VERSION_SHADOW_PASS || k == SHADER_VERSION_SHADOW_PASS_MULTIVIEW || k == SHADER_VERSION_SHADOW_PASS_DP) {
//none, leave empty
} else if (k == SHADER_VERSION_DEPTH_PASS_WITH_MATERIAL) {
blend_state = RD::PipelineColorBlendState::create_disabled(5); //writes to normal and roughness in opaque way
} else {
// ???
}
-
- /*
- if (k == SHADER_VERSION_COLOR_PASS || k == SHADER_VERSION_COLOR_PASS_WITH_FORWARD_GI || k == SHADER_VERSION_LIGHTMAP_COLOR_PASS) {
- blend_state = blend_state_opaque;
- } else if (k == SHADER_VERSION_DEPTH_PASS || k == SHADER_VERSION_DEPTH_PASS_DP) {
- //none, leave empty
- } else if (k == SHADER_VERSION_DEPTH_PASS_WITH_NORMAL_AND_ROUGHNESS) {
- blend_state = blend_state_depth_normal_roughness;
- } else if (k == SHADER_VERSION_DEPTH_PASS_WITH_NORMAL_AND_ROUGHNESS_AND_GIPROBE) {
- blend_state = blend_state_depth_normal_roughness_giprobe;
- } else if (k == SHADER_VERSION_DEPTH_PASS_WITH_MATERIAL) {
- blend_state = RD::PipelineColorBlendState::create_disabled(5); //writes to normal and roughness in opaque way
- } else if (k == SHADER_VERSION_DEPTH_PASS_WITH_SDF) {
- blend_state = RD::PipelineColorBlendState(); //no color targets for SDF
- } else {
- //specular write
- blend_state = blend_state_opaque_specular;
- depth_stencil.enable_depth_test = false;
- depth_stencil.enable_depth_write = false;
- }
- */
}
RID shader_variant = shader_singleton->shader.version_get_shader(version, k);
@@ -469,94 +429,14 @@ void SceneShaderForwardMobile::MaterialData::set_next_pass(RID p_pass) {
next_pass = p_pass;
}
-void SceneShaderForwardMobile::MaterialData::update_parameters(const Map<StringName, Variant> &p_parameters, bool p_uniform_dirty, bool p_textures_dirty) {
+bool SceneShaderForwardMobile::MaterialData::update_parameters(const Map<StringName, Variant> &p_parameters, bool p_uniform_dirty, bool p_textures_dirty) {
SceneShaderForwardMobile *shader_singleton = (SceneShaderForwardMobile *)SceneShaderForwardMobile::singleton;
- if ((uint32_t)ubo_data.size() != shader_data->ubo_size) {
- p_uniform_dirty = true;
- if (uniform_buffer.is_valid()) {
- RD::get_singleton()->free(uniform_buffer);
- uniform_buffer = RID();
- }
-
- ubo_data.resize(shader_data->ubo_size);
- if (ubo_data.size()) {
- uniform_buffer = RD::get_singleton()->uniform_buffer_create(ubo_data.size());
- memset(ubo_data.ptrw(), 0, ubo_data.size()); //clear
- }
-
- //clear previous uniform set
- if (uniform_set.is_valid() && RD::get_singleton()->uniform_set_is_valid(uniform_set)) {
- RD::get_singleton()->free(uniform_set);
- uniform_set = RID();
- }
- }
-
- //check whether buffer changed
- if (p_uniform_dirty && ubo_data.size()) {
- update_uniform_buffer(shader_data->uniforms, shader_data->ubo_offsets.ptr(), p_parameters, ubo_data.ptrw(), ubo_data.size(), false);
- RD::get_singleton()->buffer_update(uniform_buffer, 0, ubo_data.size(), ubo_data.ptrw(), RD::BARRIER_MASK_RASTER);
- }
-
- uint32_t tex_uniform_count = shader_data->texture_uniforms.size();
-
- if ((uint32_t)texture_cache.size() != tex_uniform_count) {
- texture_cache.resize(tex_uniform_count);
- p_textures_dirty = true;
-
- //clear previous uniform set
- if (uniform_set.is_valid() && RD::get_singleton()->uniform_set_is_valid(uniform_set)) {
- RD::get_singleton()->free(uniform_set);
- uniform_set = RID();
- }
- }
-
- if (p_textures_dirty && tex_uniform_count) {
- update_textures(p_parameters, shader_data->default_texture_params, shader_data->texture_uniforms, texture_cache.ptrw(), true);
- }
-
- if (shader_data->ubo_size == 0 && shader_data->texture_uniforms.size() == 0) {
- // This material does not require an uniform set, so don't create it.
- return;
- }
-
- if (!p_textures_dirty && uniform_set.is_valid() && RD::get_singleton()->uniform_set_is_valid(uniform_set)) {
- //no reason to update uniform set, only UBO (or nothing) was needed to update
- return;
- }
-
- Vector<RD::Uniform> uniforms;
-
- {
- if (shader_data->ubo_size) {
- RD::Uniform u;
- u.uniform_type = RD::UNIFORM_TYPE_UNIFORM_BUFFER;
- u.binding = 0;
- u.ids.push_back(uniform_buffer);
- uniforms.push_back(u);
- }
-
- const RID *textures = texture_cache.ptrw();
- for (uint32_t i = 0; i < tex_uniform_count; i++) {
- RD::Uniform u;
- u.uniform_type = RD::UNIFORM_TYPE_TEXTURE;
- u.binding = 1 + i;
- u.ids.push_back(textures[i]);
- uniforms.push_back(u);
- }
- }
-
- uniform_set = RD::get_singleton()->uniform_set_create(uniforms, shader_singleton->shader.version_get_shader(shader_data->version, 0), RenderForwardMobile::MATERIAL_UNIFORM_SET);
+ return update_parameters_uniform_set(p_parameters, p_uniform_dirty, p_textures_dirty, shader_data->uniforms, shader_data->ubo_offsets.ptr(), shader_data->texture_uniforms, shader_data->default_texture_params, shader_data->ubo_size, uniform_set, shader_singleton->shader.version_get_shader(shader_data->version, 0), RenderForwardMobile::MATERIAL_UNIFORM_SET, RD::BARRIER_MASK_RASTER);
}
SceneShaderForwardMobile::MaterialData::~MaterialData() {
- if (uniform_set.is_valid() && RD::get_singleton()->uniform_set_is_valid(uniform_set)) {
- RD::get_singleton()->free(uniform_set);
- }
-
- if (uniform_buffer.is_valid()) {
- RD::get_singleton()->free(uniform_buffer);
- }
+ free_parameters_uniform_set(uniform_set);
}
RendererStorageRD::MaterialData *SceneShaderForwardMobile::_create_material_func(ShaderData *p_shader) {
@@ -585,10 +465,22 @@ void SceneShaderForwardMobile::init(RendererStorageRD *p_storage, const String p
Vector<String> shader_versions;
shader_versions.push_back(""); // SHADER_VERSION_COLOR_PASS
shader_versions.push_back("\n#define USE_LIGHTMAP\n"); // SHADER_VERSION_LIGHTMAP_COLOR_PASS
- shader_versions.push_back("\n#define MODE_RENDER_DEPTH\n"); // !BAS! SHADER_VERSION_SHADOW_PASS, should probably change this to MODE_RENDER_SHADOW because we don't have a depth pass here...
- shader_versions.push_back("\n#define MODE_RENDER_DEPTH\n#define MODE_DUAL_PARABOLOID\n"); // SHADER_VERSION_DEPTH_PASS_DP (maybe rename to SHADER_VERSION_SHADOW_PASS_DP?)
+ shader_versions.push_back("\n#define MODE_RENDER_DEPTH\n"); // SHADER_VERSION_SHADOW_PASS, should probably change this to MODE_RENDER_SHADOW because we don't have a depth pass here...
+ shader_versions.push_back("\n#define MODE_RENDER_DEPTH\n#define MODE_DUAL_PARABOLOID\n"); // SHADER_VERSION_SHADOW_PASS_DP
shader_versions.push_back("\n#define MODE_RENDER_DEPTH\n#define MODE_RENDER_MATERIAL\n"); // SHADER_VERSION_DEPTH_PASS_WITH_MATERIAL
+
+ // multiview versions of our shaders
+ shader_versions.push_back("\n#define USE_MULTIVIEW\n"); // SHADER_VERSION_COLOR_PASS_MULTIVIEW
+ shader_versions.push_back("\n#define USE_MULTIVIEW\n#define USE_LIGHTMAP\n"); // SHADER_VERSION_LIGHTMAP_COLOR_PASS_MULTIVIEW
+ shader_versions.push_back("\n#define USE_MULTIVIEW\n#define MODE_RENDER_DEPTH\n"); // SHADER_VERSION_SHADOW_PASS_MULTIVIEW
+
shader.initialize(shader_versions, p_defines);
+
+ if (!RendererCompositorRD::singleton->is_xr_enabled()) {
+ shader.set_variant_enabled(SHADER_VERSION_COLOR_PASS_MULTIVIEW, false);
+ shader.set_variant_enabled(SHADER_VERSION_LIGHTMAP_COLOR_PASS_MULTIVIEW, false);
+ shader.set_variant_enabled(SHADER_VERSION_SHADOW_PASS_MULTIVIEW, false);
+ }
}
storage->shader_set_data_request_function(RendererStorageRD::SHADER_TYPE_3D, _create_shader_funcs);
@@ -603,7 +495,7 @@ void SceneShaderForwardMobile::init(RendererStorageRD *p_storage, const String p
actions.renames["INV_CAMERA_MATRIX"] = "scene_data.inv_camera_matrix";
actions.renames["CAMERA_MATRIX"] = "scene_data.camera_matrix";
actions.renames["PROJECTION_MATRIX"] = "projection_matrix";
- actions.renames["INV_PROJECTION_MATRIX"] = "scene_data.inv_projection_matrix";
+ actions.renames["INV_PROJECTION_MATRIX"] = "inv_projection_matrix";
actions.renames["MODELVIEW_MATRIX"] = "modelview";
actions.renames["MODELVIEW_NORMAL_MATRIX"] = "modelview_normal";
@@ -649,7 +541,6 @@ void SceneShaderForwardMobile::init(RendererStorageRD *p_storage, const String p
actions.renames["SSS_STRENGTH"] = "sss_strength";
actions.renames["SSS_TRANSMITTANCE_COLOR"] = "transmittance_color";
actions.renames["SSS_TRANSMITTANCE_DEPTH"] = "transmittance_depth";
- actions.renames["SSS_TRANSMITTANCE_CURVE"] = "transmittance_curve";
actions.renames["SSS_TRANSMITTANCE_BOOST"] = "transmittance_boost";
actions.renames["BACKLIGHT"] = "backlight";
actions.renames["AO"] = "ao";
@@ -673,6 +564,10 @@ void SceneShaderForwardMobile::init(RendererStorageRD *p_storage, const String p
actions.renames["CUSTOM2"] = "custom2_attrib";
actions.renames["CUSTOM3"] = "custom3_attrib";
+ actions.renames["VIEW_INDEX"] = "ViewIndex";
+ actions.renames["VIEW_MONO_LEFT"] = "0";
+ actions.renames["VIEW_RIGHT"] = "1";
+
//for light
actions.renames["VIEW"] = "view";
actions.renames["LIGHT_COLOR"] = "light_color";
@@ -737,7 +632,6 @@ void SceneShaderForwardMobile::init(RendererStorageRD *p_storage, const String p
actions.render_mode_defines["diffuse_burley"] = "#define DIFFUSE_BURLEY\n";
}
- actions.render_mode_defines["diffuse_oren_nayar"] = "#define DIFFUSE_OREN_NAYAR\n";
actions.render_mode_defines["diffuse_lambert_wrap"] = "#define DIFFUSE_LAMBERT_WRAP\n";
actions.render_mode_defines["diffuse_toon"] = "#define DIFFUSE_TOON\n";
@@ -784,22 +678,23 @@ void SceneShaderForwardMobile::init(RendererStorageRD *p_storage, const String p
MaterialData *md = (MaterialData *)storage->material_get_data(default_material, RendererStorageRD::SHADER_TYPE_3D);
default_shader_rd = shader.version_get_shader(md->shader_data->version, SHADER_VERSION_COLOR_PASS);
+
+ default_material_shader_ptr = md->shader_data;
+ default_material_uniform_set = md->uniform_set;
}
{
overdraw_material_shader = storage->shader_allocate();
storage->shader_initialize(overdraw_material_shader);
- storage->shader_set_code(overdraw_material_shader, "shader_type spatial;\nrender_mode blend_add,unshaded;\n void fragment() { ALBEDO=vec3(0.4,0.8,0.8); ALPHA=0.2; }");
+ // Use relatively low opacity so that more "layers" of overlapping objects can be distinguished.
+ storage->shader_set_code(overdraw_material_shader, "shader_type spatial;\nrender_mode blend_add,unshaded;\n void fragment() { ALBEDO=vec3(0.4,0.8,0.8); ALPHA=0.1; }");
overdraw_material = storage->material_allocate();
storage->material_initialize(overdraw_material);
storage->material_set_shader(overdraw_material, overdraw_material_shader);
- wireframe_material_shader = storage->shader_allocate();
- storage->shader_initialize(wireframe_material_shader);
- storage->shader_set_code(wireframe_material_shader, "shader_type spatial;\nrender_mode wireframe,unshaded;\n void fragment() { ALBEDO=vec3(0.0,0.0,0.0); }");
- wireframe_material = storage->material_allocate();
- storage->material_initialize(wireframe_material);
- storage->material_set_shader(wireframe_material, wireframe_material_shader);
+ MaterialData *md = (MaterialData *)storage->material_get_data(overdraw_material, RendererStorageRD::SHADER_TYPE_3D);
+ overdraw_material_shader_ptr = md->shader_data;
+ overdraw_material_uniform_set = md->uniform_set;
}
{
@@ -827,11 +722,9 @@ SceneShaderForwardMobile::~SceneShaderForwardMobile() {
RD::get_singleton()->free(default_vec4_xform_buffer);
RD::get_singleton()->free(shadow_sampler);
- storage->free(wireframe_material_shader);
storage->free(overdraw_material_shader);
storage->free(default_shader);
- storage->free(wireframe_material);
storage->free(overdraw_material);
storage->free(default_material);
}
diff --git a/servers/rendering/renderer_rd/forward_mobile/scene_shader_forward_mobile.h b/servers/rendering/renderer_rd/forward_mobile/scene_shader_forward_mobile.h
index 1517197d25..5c9e35fd0d 100644
--- a/servers/rendering/renderer_rd/forward_mobile/scene_shader_forward_mobile.h
+++ b/servers/rendering/renderer_rd/forward_mobile/scene_shader_forward_mobile.h
@@ -47,8 +47,13 @@ public:
SHADER_VERSION_COLOR_PASS,
SHADER_VERSION_LIGHTMAP_COLOR_PASS,
SHADER_VERSION_SHADOW_PASS,
- SHADER_VERSION_DEPTH_PASS_DP,
+ SHADER_VERSION_SHADOW_PASS_DP,
SHADER_VERSION_DEPTH_PASS_WITH_MATERIAL,
+
+ SHADER_VERSION_COLOR_PASS_MULTIVIEW,
+ SHADER_VERSION_LIGHTMAP_COLOR_PASS_MULTIVIEW,
+ SHADER_VERSION_SHADOW_PASS_MULTIVIEW,
+
SHADER_VERSION_MAX
};
@@ -158,17 +163,14 @@ public:
struct MaterialData : public RendererStorageRD::MaterialData {
uint64_t last_frame;
ShaderData *shader_data;
- RID uniform_buffer;
RID uniform_set;
- Vector<RID> texture_cache;
- Vector<uint8_t> ubo_data;
uint64_t last_pass = 0;
uint32_t index = 0;
RID next_pass;
uint8_t priority;
virtual void set_render_priority(int p_priority);
virtual void set_next_pass(RID p_pass);
- virtual void update_parameters(const Map<StringName, Variant> &p_parameters, bool p_uniform_dirty, bool p_textures_dirty);
+ virtual bool update_parameters(const Map<StringName, Variant> &p_parameters, bool p_uniform_dirty, bool p_textures_dirty);
virtual ~MaterialData();
};
@@ -184,8 +186,6 @@ public:
RID default_material;
RID overdraw_material_shader;
RID overdraw_material;
- RID wireframe_material_shader;
- RID wireframe_material;
RID default_shader_rd;
RID default_vec4_xform_buffer;
@@ -193,6 +193,12 @@ public:
RID shadow_sampler;
+ RID default_material_uniform_set;
+ ShaderData *default_material_shader_ptr = nullptr;
+
+ RID overdraw_material_uniform_set;
+ ShaderData *overdraw_material_shader_ptr = nullptr;
+
SceneShaderForwardMobile();
~SceneShaderForwardMobile();
diff --git a/servers/rendering/renderer_rd/pipeline_cache_rd.cpp b/servers/rendering/renderer_rd/pipeline_cache_rd.cpp
index b2b919c40e..22888ddbe5 100644
--- a/servers/rendering/renderer_rd/pipeline_cache_rd.cpp
+++ b/servers/rendering/renderer_rd/pipeline_cache_rd.cpp
@@ -31,20 +31,21 @@
#include "pipeline_cache_rd.h"
#include "core/os/memory.h"
-RID PipelineCacheRD::_generate_version(RD::VertexFormatID p_vertex_format_id, RD::FramebufferFormatID p_framebuffer_format_id, bool p_wireframe) {
+RID PipelineCacheRD::_generate_version(RD::VertexFormatID p_vertex_format_id, RD::FramebufferFormatID p_framebuffer_format_id, bool p_wireframe, uint32_t p_render_pass) {
RD::PipelineMultisampleState multisample_state_version = multisample_state;
- multisample_state_version.sample_count = RD::get_singleton()->framebuffer_format_get_texture_samples(p_framebuffer_format_id);
+ multisample_state_version.sample_count = RD::get_singleton()->framebuffer_format_get_texture_samples(p_framebuffer_format_id, p_render_pass);
RD::PipelineRasterizationState raster_state_version = rasterization_state;
raster_state_version.wireframe = p_wireframe;
- RID pipeline = RD::get_singleton()->render_pipeline_create(shader, p_framebuffer_format_id, p_vertex_format_id, render_primitive, raster_state_version, multisample_state_version, depth_stencil_state, blend_state, dynamic_state_flags);
+ RID pipeline = RD::get_singleton()->render_pipeline_create(shader, p_framebuffer_format_id, p_vertex_format_id, render_primitive, raster_state_version, multisample_state_version, depth_stencil_state, blend_state, dynamic_state_flags, p_render_pass);
ERR_FAIL_COND_V(pipeline.is_null(), RID());
versions = (Version *)memrealloc(versions, sizeof(Version) * (version_count + 1));
versions[version_count].framebuffer_id = p_framebuffer_format_id;
versions[version_count].vertex_id = p_vertex_format_id;
versions[version_count].wireframe = p_wireframe;
versions[version_count].pipeline = pipeline;
+ versions[version_count].render_pass = p_render_pass;
version_count++;
return pipeline;
}
diff --git a/servers/rendering/renderer_rd/pipeline_cache_rd.h b/servers/rendering/renderer_rd/pipeline_cache_rd.h
index b1c8f21ecc..387a8a038f 100644
--- a/servers/rendering/renderer_rd/pipeline_cache_rd.h
+++ b/servers/rendering/renderer_rd/pipeline_cache_rd.h
@@ -50,6 +50,7 @@ class PipelineCacheRD {
struct Version {
RD::VertexFormatID vertex_id;
RD::FramebufferFormatID framebuffer_id;
+ uint32_t render_pass;
bool wireframe;
RID pipeline;
};
@@ -57,7 +58,7 @@ class PipelineCacheRD {
Version *versions;
uint32_t version_count;
- RID _generate_version(RD::VertexFormatID p_vertex_format_id, RD::FramebufferFormatID p_framebuffer_format_id, bool p_wireframe);
+ RID _generate_version(RD::VertexFormatID p_vertex_format_id, RD::FramebufferFormatID p_framebuffer_format_id, bool p_wireframe, uint32_t p_render_pass);
void _clear();
@@ -65,7 +66,7 @@ public:
void setup(RID p_shader, RD::RenderPrimitive p_primitive, const RD::PipelineRasterizationState &p_rasterization_state, RD::PipelineMultisampleState p_multisample, const RD::PipelineDepthStencilState &p_depth_stencil_state, const RD::PipelineColorBlendState &p_blend_state, int p_dynamic_state_flags = 0);
void update_shader(RID p_shader);
- _FORCE_INLINE_ RID get_render_pipeline(RD::VertexFormatID p_vertex_format_id, RD::FramebufferFormatID p_framebuffer_format_id, bool p_wireframe = false) {
+ _FORCE_INLINE_ RID get_render_pipeline(RD::VertexFormatID p_vertex_format_id, RD::FramebufferFormatID p_framebuffer_format_id, bool p_wireframe = false, uint32_t p_render_pass = 0) {
#ifdef DEBUG_ENABLED
ERR_FAIL_COND_V_MSG(shader.is_null(), RID(),
"Attempted to use an unused shader variant (shader is null),");
@@ -74,13 +75,13 @@ public:
spin_lock.lock();
RID result;
for (uint32_t i = 0; i < version_count; i++) {
- if (versions[i].vertex_id == p_vertex_format_id && versions[i].framebuffer_id == p_framebuffer_format_id && versions[i].wireframe == p_wireframe) {
+ if (versions[i].vertex_id == p_vertex_format_id && versions[i].framebuffer_id == p_framebuffer_format_id && versions[i].wireframe == p_wireframe && versions[i].render_pass == p_render_pass) {
result = versions[i].pipeline;
spin_lock.unlock();
return result;
}
}
- result = _generate_version(p_vertex_format_id, p_framebuffer_format_id, p_wireframe);
+ result = _generate_version(p_vertex_format_id, p_framebuffer_format_id, p_wireframe, p_render_pass);
spin_lock.unlock();
return result;
}
diff --git a/servers/rendering/renderer_rd/renderer_canvas_render_rd.cpp b/servers/rendering/renderer_rd/renderer_canvas_render_rd.cpp
index 70c1705bff..1e3dbe69a3 100644
--- a/servers/rendering/renderer_rd/renderer_canvas_render_rd.cpp
+++ b/servers/rendering/renderer_rd/renderer_canvas_render_rd.cpp
@@ -76,7 +76,7 @@ void RendererCanvasRenderRD::_update_transform_2d_to_mat2x3(const Transform2D &p
p_mat2x3[5] = p_transform.elements[2][1];
}
-void RendererCanvasRenderRD::_update_transform_to_mat4(const Transform &p_transform, float *p_mat4) {
+void RendererCanvasRenderRD::_update_transform_to_mat4(const Transform3D &p_transform, float *p_mat4) {
p_mat4[0] = p_transform.basis.elements[0][0];
p_mat4[1] = p_transform.basis.elements[1][0];
p_mat4[2] = p_transform.basis.elements[2][0];
@@ -408,6 +408,7 @@ void RendererCanvasRenderRD::_render_item(RD::DrawListID p_draw_list, RID p_rend
PushConstant push_constant;
Transform2D base_transform = p_canvas_transform_inverse * p_item->final_transform;
+ Transform2D draw_transform;
_update_transform_2d_to_mat2x3(base_transform, push_constant.world);
Color base_color = p_item->final_modulate;
@@ -464,8 +465,15 @@ void RendererCanvasRenderRD::_render_item(RD::DrawListID p_draw_list, RID p_rend
RID last_texture;
Size2 texpixel_size;
+ bool skipping = false;
+
const Item::Command *c = p_item->commands;
while (c) {
+ if (skipping && c->type != Item::Command::TYPE_ANIMATION_SLICE) {
+ c = c->next;
+ continue;
+ }
+
push_constant.flags = base_flags | (push_constant.flags & (FLAGS_DEFAULT_NORMAL_MAP_USED | FLAGS_DEFAULT_SPECULAR_MAP_USED)); //reset on each command for sanity, keep canvastexture binding config
switch (c->type) {
@@ -724,7 +732,7 @@ void RendererCanvasRenderRD::_render_item(RD::DrawListID p_draw_list, RID p_rend
mesh_instance = m->mesh_instance;
texture = m->texture;
modulate = m->modulate;
- _update_transform_2d_to_mat2x3(base_transform * m->transform, push_constant.world);
+ _update_transform_2d_to_mat2x3(base_transform * draw_transform * m->transform, push_constant.world);
} else if (c->type == Item::Command::TYPE_MULTIMESH) {
const Item::CommandMultiMesh *mm = static_cast<const Item::CommandMultiMesh *>(c);
RID multimesh = mm->multimesh;
@@ -857,10 +865,10 @@ void RendererCanvasRenderRD::_render_item(RD::DrawListID p_draw_list, RID p_rend
for (int j = 0; j < 6; j++) {
push_constant.world[j] = world_backup[j];
}
-
} break;
case Item::Command::TYPE_TRANSFORM: {
const Item::CommandTransform *transform = static_cast<const Item::CommandTransform *>(c);
+ draw_transform = transform->xform;
_update_transform_2d_to_mat2x3(base_transform * transform->xform, push_constant.world);
} break;
@@ -879,6 +887,14 @@ void RendererCanvasRenderRD::_render_item(RD::DrawListID p_draw_list, RID p_rend
}
} break;
+ case Item::Command::TYPE_ANIMATION_SLICE: {
+ const Item::CommandAnimationSlice *as = static_cast<const Item::CommandAnimationSlice *>(c);
+ double current_time = RendererCompositorRD::singleton->get_total_time();
+ double local_time = Math::fposmod(current_time - as->offset, as->animation_length);
+ skipping = !(local_time >= as->slice_begin && local_time < as->slice_end);
+
+ RenderingServerDefault::redraw_request(); // animation visible means redraw request
+ } break;
}
c = c->next;
@@ -1250,7 +1266,7 @@ void RendererCanvasRenderRD::canvas_render_items(RID p_to_render_target, Item *p
Size2i ssize = storage->render_target_get_size(p_to_render_target);
- Transform screen_transform;
+ Transform3D screen_transform;
screen_transform.translate(-(ssize.width / 2.0f), -(ssize.height / 2.0f), 0.0f);
screen_transform.scale(Vector3(2.0f / ssize.width, 2.0f / ssize.height, 1.0f));
_update_transform_to_mat4(screen_transform, state_buffer.screen_transform);
@@ -1539,7 +1555,7 @@ void RendererCanvasRenderRD::light_update_shadow(RID p_rid, int p_shadow_index,
}
Vector3 cam_target = Basis(Vector3(0, 0, Math_TAU * ((i + 3) / 4.0))).xform(Vector3(0, 1, 0));
- projection = projection * CameraMatrix(Transform().looking_at(cam_target, Vector3(0, 0, -1)).affine_inverse());
+ projection = projection * CameraMatrix(Transform3D().looking_at(cam_target, Vector3(0, 0, -1)).affine_inverse());
ShadowRenderPushConstant push_constant;
for (int y = 0; y < 4; y++) {
@@ -1617,7 +1633,7 @@ void RendererCanvasRenderRD::light_update_directional_shadow(RID p_rid, int p_sh
CameraMatrix projection;
projection.set_orthogonal(-half_size, half_size, -0.5, 0.5, 0.0, distance);
- projection = projection * CameraMatrix(Transform().looking_at(Vector3(0, 1, 0), Vector3(0, 0, -1)).affine_inverse());
+ projection = projection * CameraMatrix(Transform3D().looking_at(Vector3(0, 1, 0), Vector3(0, 0, -1)).affine_inverse());
ShadowRenderPushConstant push_constant;
for (int y = 0; y < 4; y++) {
@@ -2185,94 +2201,14 @@ RendererStorageRD::ShaderData *RendererCanvasRenderRD::_create_shader_func() {
return shader_data;
}
-void RendererCanvasRenderRD::MaterialData::update_parameters(const Map<StringName, Variant> &p_parameters, bool p_uniform_dirty, bool p_textures_dirty) {
+bool RendererCanvasRenderRD::MaterialData::update_parameters(const Map<StringName, Variant> &p_parameters, bool p_uniform_dirty, bool p_textures_dirty) {
RendererCanvasRenderRD *canvas_singleton = (RendererCanvasRenderRD *)RendererCanvasRender::singleton;
- if ((uint32_t)ubo_data.size() != shader_data->ubo_size) {
- p_uniform_dirty = true;
- if (uniform_buffer.is_valid()) {
- RD::get_singleton()->free(uniform_buffer);
- uniform_buffer = RID();
- }
-
- ubo_data.resize(shader_data->ubo_size);
- if (ubo_data.size()) {
- uniform_buffer = RD::get_singleton()->uniform_buffer_create(ubo_data.size());
- memset(ubo_data.ptrw(), 0, ubo_data.size()); //clear
- }
-
- //clear previous uniform set
- if (uniform_set.is_valid() && RD::get_singleton()->uniform_set_is_valid(uniform_set)) {
- RD::get_singleton()->free(uniform_set);
- uniform_set = RID();
- }
- }
-
- //check whether buffer changed
- if (p_uniform_dirty && ubo_data.size()) {
- update_uniform_buffer(shader_data->uniforms, shader_data->ubo_offsets.ptr(), p_parameters, ubo_data.ptrw(), ubo_data.size(), false);
- RD::get_singleton()->buffer_update(uniform_buffer, 0, ubo_data.size(), ubo_data.ptrw());
- }
-
- uint32_t tex_uniform_count = shader_data->texture_uniforms.size();
-
- if ((uint32_t)texture_cache.size() != tex_uniform_count) {
- texture_cache.resize(tex_uniform_count);
- p_textures_dirty = true;
-
- //clear previous uniform set
- if (uniform_set.is_valid() && RD::get_singleton()->uniform_set_is_valid(uniform_set)) {
- RD::get_singleton()->free(uniform_set);
- uniform_set = RID();
- }
- }
-
- if (p_textures_dirty && tex_uniform_count) {
- update_textures(p_parameters, shader_data->default_texture_params, shader_data->texture_uniforms, texture_cache.ptrw(), false);
- }
-
- if (shader_data->ubo_size == 0) {
- // This material does not require an uniform set, so don't create it.
- return;
- }
-
- if (!p_textures_dirty && uniform_set.is_valid() && RD::get_singleton()->uniform_set_is_valid(uniform_set)) {
- //no reason to update uniform set, only UBO (or nothing) was needed to update
- return;
- }
-
- Vector<RD::Uniform> uniforms;
-
- {
- if (shader_data->ubo_size) {
- RD::Uniform u;
- u.uniform_type = RD::UNIFORM_TYPE_UNIFORM_BUFFER;
- u.binding = 0;
- u.ids.push_back(uniform_buffer);
- uniforms.push_back(u);
- }
-
- const RID *textures = texture_cache.ptrw();
- for (uint32_t i = 0; i < tex_uniform_count; i++) {
- RD::Uniform u;
- u.uniform_type = RD::UNIFORM_TYPE_TEXTURE;
- u.binding = 1 + i;
- u.ids.push_back(textures[i]);
- uniforms.push_back(u);
- }
- }
-
- uniform_set = RD::get_singleton()->uniform_set_create(uniforms, canvas_singleton->shader.canvas_shader.version_get_shader(shader_data->version, 0), MATERIAL_UNIFORM_SET);
+ return update_parameters_uniform_set(p_parameters, p_uniform_dirty, p_textures_dirty, shader_data->uniforms, shader_data->ubo_offsets.ptr(), shader_data->texture_uniforms, shader_data->default_texture_params, shader_data->ubo_size, uniform_set, canvas_singleton->shader.canvas_shader.version_get_shader(shader_data->version, 0), MATERIAL_UNIFORM_SET);
}
RendererCanvasRenderRD::MaterialData::~MaterialData() {
- if (uniform_set.is_valid() && RD::get_singleton()->uniform_set_is_valid(uniform_set)) {
- RD::get_singleton()->free(uniform_set);
- }
-
- if (uniform_buffer.is_valid()) {
- RD::get_singleton()->free(uniform_buffer);
- }
+ free_parameters_uniform_set(uniform_set);
}
RendererStorageRD::MaterialData *RendererCanvasRenderRD::_create_material_func(ShaderData *p_shader) {
diff --git a/servers/rendering/renderer_rd/renderer_canvas_render_rd.h b/servers/rendering/renderer_rd/renderer_canvas_render_rd.h
index 890a4e3649..7c4f62832c 100644
--- a/servers/rendering/renderer_rd/renderer_canvas_render_rd.h
+++ b/servers/rendering/renderer_rd/renderer_canvas_render_rd.h
@@ -201,14 +201,11 @@ class RendererCanvasRenderRD : public RendererCanvasRender {
struct MaterialData : public RendererStorageRD::MaterialData {
uint64_t last_frame;
ShaderData *shader_data;
- RID uniform_buffer;
RID uniform_set;
- Vector<RID> texture_cache;
- Vector<uint8_t> ubo_data;
virtual void set_render_priority(int p_priority) {}
virtual void set_next_pass(RID p_pass) {}
- virtual void update_parameters(const Map<StringName, Variant> &p_parameters, bool p_uniform_dirty, bool p_textures_dirty);
+ virtual bool update_parameters(const Map<StringName, Variant> &p_parameters, bool p_uniform_dirty, bool p_textures_dirty);
virtual ~MaterialData();
};
@@ -433,7 +430,7 @@ class RendererCanvasRenderRD : public RendererCanvasRender {
_FORCE_INLINE_ void _update_transform_2d_to_mat2x3(const Transform2D &p_transform, float *p_mat2x3);
_FORCE_INLINE_ void _update_transform_2d_to_mat4(const Transform2D &p_transform, float *p_mat4);
- _FORCE_INLINE_ void _update_transform_to_mat4(const Transform &p_transform, float *p_mat4);
+ _FORCE_INLINE_ void _update_transform_to_mat4(const Transform3D &p_transform, float *p_mat4);
void _update_shadow_atlas();
@@ -457,8 +454,6 @@ public:
void canvas_debug_viewport_shadows(Light *p_lights_with_shadow) {}
- void draw_window_margins(int *p_margins, RID *p_margin_textures) {}
-
virtual void set_shadow_texture_size(int p_size);
void set_time(double p_time);
diff --git a/servers/rendering/renderer_rd/renderer_compositor_rd.cpp b/servers/rendering/renderer_rd/renderer_compositor_rd.cpp
index 1337d36762..a8f086b0f9 100644
--- a/servers/rendering/renderer_rd/renderer_compositor_rd.cpp
+++ b/servers/rendering/renderer_rd/renderer_compositor_rd.cpp
@@ -31,7 +31,7 @@
#include "renderer_compositor_rd.h"
#include "core/config/project_settings.h"
-#include "core/os/dir_access.h"
+#include "core/io/dir_access.h"
void RendererCompositorRD::prepare_for_blitting_render_targets() {
RD::get_singleton()->prepare_screen_for_drawing();
@@ -60,8 +60,7 @@ void RendererCompositorRD::blit_render_targets_to_screen(DisplayServer::WindowID
}
Size2 screen_size(RD::get_singleton()->screen_get_width(p_screen), RD::get_singleton()->screen_get_height(p_screen));
- BlitMode mode = p_render_targets[i].lens_distortion.apply ? BLIT_MODE_LENS : p_render_targets[i].multi_view.use_layer ? BLIT_MODE_USE_LAYER :
- BLIT_MODE_NORMAL;
+ BlitMode mode = p_render_targets[i].lens_distortion.apply ? BLIT_MODE_LENS : (p_render_targets[i].multi_view.use_layer ? BLIT_MODE_USE_LAYER : BLIT_MODE_NORMAL);
RD::get_singleton()->draw_list_bind_render_pipeline(draw_list, blit.pipelines[mode]);
RD::get_singleton()->draw_list_bind_index_array(draw_list, blit.array);
RD::get_singleton()->draw_list_bind_uniform_set(draw_list, render_target_descriptors[rd_texture], 0);
@@ -111,13 +110,14 @@ void RendererCompositorRD::initialize() {
blit_modes.push_back("\n");
blit_modes.push_back("\n#define USE_LAYER\n");
blit_modes.push_back("\n#define USE_LAYER\n#define APPLY_LENS_DISTORTION\n");
+ blit_modes.push_back("\n");
blit.shader.initialize(blit_modes);
blit.shader_version = blit.shader.version_create();
for (int i = 0; i < BLIT_MODE_MAX; i++) {
- blit.pipelines[i] = RD::get_singleton()->render_pipeline_create(blit.shader.version_get_shader(blit.shader_version, i), RD::get_singleton()->screen_get_framebuffer_format(), RD::INVALID_ID, RD::RENDER_PRIMITIVE_TRIANGLES, RD::PipelineRasterizationState(), RD::PipelineMultisampleState(), RD::PipelineDepthStencilState(), RenderingDevice::PipelineColorBlendState::create_disabled(), 0);
+ blit.pipelines[i] = RD::get_singleton()->render_pipeline_create(blit.shader.version_get_shader(blit.shader_version, i), RD::get_singleton()->screen_get_framebuffer_format(), RD::INVALID_ID, RD::RENDER_PRIMITIVE_TRIANGLES, RD::PipelineRasterizationState(), RD::PipelineMultisampleState(), RD::PipelineDepthStencilState(), i == BLIT_MODE_NORMAL_ALPHA ? RenderingDevice::PipelineColorBlendState::create_blend() : RenderingDevice::PipelineColorBlendState::create_disabled(), 0);
}
//create index array for copy shader
@@ -153,6 +153,81 @@ void RendererCompositorRD::finalize() {
RD::get_singleton()->free(blit.sampler);
}
+void RendererCompositorRD::set_boot_image(const Ref<Image> &p_image, const Color &p_color, bool p_scale, bool p_use_filter) {
+ RD::get_singleton()->prepare_screen_for_drawing();
+
+ RID texture = storage->texture_allocate();
+ storage->texture_2d_initialize(texture, p_image);
+ RID rd_texture = storage->texture_get_rd_texture(texture);
+
+ RID uset;
+ {
+ Vector<RD::Uniform> uniforms;
+ RD::Uniform u;
+ u.uniform_type = RD::UNIFORM_TYPE_SAMPLER_WITH_TEXTURE;
+ u.binding = 0;
+ u.ids.push_back(blit.sampler);
+ u.ids.push_back(rd_texture);
+ uniforms.push_back(u);
+ uset = RD::get_singleton()->uniform_set_create(uniforms, blit.shader.version_get_shader(blit.shader_version, BLIT_MODE_NORMAL), 0);
+ }
+
+ Size2 window_size = DisplayServer::get_singleton()->window_get_size();
+ print_line("window size: " + window_size);
+
+ Rect2 imgrect(0, 0, p_image->get_width(), p_image->get_height());
+ Rect2 screenrect;
+ if (p_scale) {
+ if (window_size.width > window_size.height) {
+ //scale horizontally
+ screenrect.size.y = window_size.height;
+ screenrect.size.x = imgrect.size.x * window_size.height / imgrect.size.y;
+ screenrect.position.x = (window_size.width - screenrect.size.x) / 2;
+
+ } else {
+ //scale vertically
+ screenrect.size.x = window_size.width;
+ screenrect.size.y = imgrect.size.y * window_size.width / imgrect.size.x;
+ screenrect.position.y = (window_size.height - screenrect.size.y) / 2;
+ }
+ } else {
+ screenrect = imgrect;
+ screenrect.position += ((Size2(window_size.width, window_size.height) - screenrect.size) / 2.0).floor();
+ }
+
+ screenrect.position /= window_size;
+ screenrect.size /= window_size;
+
+ RD::DrawListID draw_list = RD::get_singleton()->draw_list_begin_for_screen(DisplayServer::MAIN_WINDOW_ID, p_color);
+
+ RD::get_singleton()->draw_list_bind_render_pipeline(draw_list, blit.pipelines[BLIT_MODE_NORMAL_ALPHA]);
+ RD::get_singleton()->draw_list_bind_index_array(draw_list, blit.array);
+ RD::get_singleton()->draw_list_bind_uniform_set(draw_list, uset, 0);
+
+ blit.push_constant.rect[0] = screenrect.position.x;
+ blit.push_constant.rect[1] = screenrect.position.y;
+ blit.push_constant.rect[2] = screenrect.size.width;
+ blit.push_constant.rect[3] = screenrect.size.height;
+ blit.push_constant.layer = 0;
+ blit.push_constant.eye_center[0] = 0;
+ blit.push_constant.eye_center[1] = 0;
+ blit.push_constant.k1 = 0;
+ blit.push_constant.k2 = 0;
+ blit.push_constant.upscale = 1.0;
+ blit.push_constant.aspect_ratio = 1.0;
+
+ print_line("rect: " + screenrect);
+
+ RD::get_singleton()->draw_list_set_push_constant(draw_list, &blit.push_constant, sizeof(BlitPushConstant));
+ RD::get_singleton()->draw_list_draw(draw_list, true);
+
+ RD::get_singleton()->draw_list_end();
+
+ RD::get_singleton()->swap_buffers();
+
+ RD::get_singleton()->free(texture);
+}
+
RendererCompositorRD *RendererCompositorRD::singleton = nullptr;
RendererCompositorRD::RendererCompositorRD() {
diff --git a/servers/rendering/renderer_rd/renderer_compositor_rd.h b/servers/rendering/renderer_rd/renderer_compositor_rd.h
index 7a78322051..15b3b77ed9 100644
--- a/servers/rendering/renderer_rd/renderer_compositor_rd.h
+++ b/servers/rendering/renderer_rd/renderer_compositor_rd.h
@@ -50,6 +50,7 @@ protected:
BLIT_MODE_NORMAL,
BLIT_MODE_USE_LAYER,
BLIT_MODE_LENS,
+ BLIT_MODE_NORMAL_ALPHA,
BLIT_MODE_MAX
};
@@ -88,7 +89,7 @@ public:
RendererCanvasRender *get_canvas() { return canvas; }
RendererSceneRender *get_scene() { return scene; }
- void set_boot_image(const Ref<Image> &p_image, const Color &p_color, bool p_scale, bool p_use_filter) {}
+ void set_boot_image(const Ref<Image> &p_image, const Color &p_color, bool p_scale, bool p_use_filter);
void initialize();
void begin_frame(double frame_step);
diff --git a/servers/rendering/renderer_rd/renderer_scene_gi_rd.cpp b/servers/rendering/renderer_rd/renderer_scene_gi_rd.cpp
index b289b17fad..98d08f68e8 100644
--- a/servers/rendering/renderer_rd/renderer_scene_gi_rd.cpp
+++ b/servers/rendering/renderer_rd/renderer_scene_gi_rd.cpp
@@ -1099,7 +1099,7 @@ void RendererSceneGIRD::SDFGI::update_cascades() {
RD::get_singleton()->buffer_update(cascades_ubo, 0, sizeof(SDFGI::Cascade::UBO) * SDFGI::MAX_CASCADES, cascade_data, RD::BARRIER_MASK_COMPUTE);
}
-void RendererSceneGIRD::SDFGI::debug_draw(const CameraMatrix &p_projection, const Transform &p_transform, int p_width, int p_height, RID p_render_target, RID p_texture) {
+void RendererSceneGIRD::SDFGI::debug_draw(const CameraMatrix &p_projection, const Transform3D &p_transform, int p_width, int p_height, RID p_render_target, RID p_texture) {
if (!debug_uniform_set.is_valid() || !RD::get_singleton()->uniform_set_is_valid(debug_uniform_set)) {
Vector<RD::Uniform> uniforms;
{
@@ -1367,7 +1367,7 @@ void RendererSceneGIRD::SDFGI::debug_probes(RD::DrawListID p_draw_list, RID p_fr
}
}
-void RendererSceneGIRD::SDFGI::pre_process_gi(const Transform &p_transform, RenderDataRD *p_render_data, RendererSceneRenderRD *p_scene_render) {
+void RendererSceneGIRD::SDFGI::pre_process_gi(const Transform3D &p_transform, RenderDataRD *p_render_data, RendererSceneRenderRD *p_scene_render) {
/* Update general SDFGI Buffer */
SDFGIData sdfgi_data;
@@ -1862,7 +1862,7 @@ void RendererSceneGIRD::SDFGI::render_region(RID p_render_buffers, int p_region,
#if 0
Vector<uint8_t> data = RD::get_singleton()->texture_get_data(cascades[cascade].sdf, 0);
Ref<Image> img;
- img.instance();
+ img.instantiate();
for (uint32_t i = 0; i < cascade_size; i++) {
Vector<uint8_t> subarr = data.subarray(128 * 128 * i, 128 * 128 * (i + 1) - 1);
img->create(cascade_size, cascade_size, false, Image::FORMAT_L8, subarr);
@@ -1875,7 +1875,7 @@ void RendererSceneGIRD::SDFGI::render_region(RID p_render_buffers, int p_region,
#if 0
Vector<uint8_t> data = RD::get_singleton()->texture_get_data(render_albedo, 0);
Ref<Image> img;
- img.instance();
+ img.instantiate();
for (uint32_t i = 0; i < cascade_size; i++) {
Vector<uint8_t> subarr = data.subarray(128 * 128 * i * 2, 128 * 128 * (i + 1) * 2 - 1);
img->createcascade_size, cascade_size, false, Image::FORMAT_RGB565, subarr);
@@ -2012,10 +2012,10 @@ void RendererSceneGIRD::SDFGI::render_static_lights(RID p_render_buffers, uint32
}
////////////////////////////////////////////////////////////////////////////////
-// GIProbeInstance
+// VoxelGIInstance
-void RendererSceneGIRD::GIProbeInstance::update(bool p_update_light_instances, const Vector<RID> &p_light_instances, const PagedArray<RendererSceneRender::GeometryInstance *> &p_dynamic_objects, RendererSceneRenderRD *p_scene_render) {
- uint32_t data_version = storage->gi_probe_get_data_version(probe);
+void RendererSceneGIRD::VoxelGIInstance::update(bool p_update_light_instances, const Vector<RID> &p_light_instances, const PagedArray<RendererSceneRender::GeometryInstance *> &p_dynamic_objects, RendererSceneRenderRD *p_scene_render) {
+ uint32_t data_version = storage->voxel_gi_get_data_version(probe);
// (RE)CREATE IF NEEDED
@@ -2034,11 +2034,11 @@ void RendererSceneGIRD::GIProbeInstance::update(bool p_update_light_instances, c
dynamic_maps.clear();
- Vector3i octree_size = storage->gi_probe_get_octree_size(probe);
+ Vector3i octree_size = storage->voxel_gi_get_octree_size(probe);
if (octree_size != Vector3i()) {
//can create a 3D texture
- Vector<int> levels = storage->gi_probe_get_level_counts(probe);
+ Vector<int> levels = storage->voxel_gi_get_level_counts(probe);
RD::TextureFormat tf;
tf.format = RD::DATA_FORMAT_R8G8B8A8_UNORM;
@@ -2064,7 +2064,7 @@ void RendererSceneGIRD::GIProbeInstance::update(bool p_update_light_instances, c
}
for (int i = 0; i < levels.size(); i++) {
- GIProbeInstance::Mipmap mipmap;
+ VoxelGIInstance::Mipmap mipmap;
mipmap.texture = RD::get_singleton()->texture_create_shared_from_slice(RD::TextureView(), texture, 0, i, RD::TEXTURE_SLICE_3D);
mipmap.level = levels.size() - i - 1;
mipmap.cell_offset = 0;
@@ -2078,14 +2078,14 @@ void RendererSceneGIRD::GIProbeInstance::update(bool p_update_light_instances, c
RD::Uniform u;
u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER;
u.binding = 1;
- u.ids.push_back(storage->gi_probe_get_octree_buffer(probe));
+ u.ids.push_back(storage->voxel_gi_get_octree_buffer(probe));
uniforms.push_back(u);
}
{
RD::Uniform u;
u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER;
u.binding = 2;
- u.ids.push_back(storage->gi_probe_get_data_buffer(probe));
+ u.ids.push_back(storage->voxel_gi_get_data_buffer(probe));
uniforms.push_back(u);
}
@@ -2100,7 +2100,7 @@ void RendererSceneGIRD::GIProbeInstance::update(bool p_update_light_instances, c
RD::Uniform u;
u.uniform_type = RD::UNIFORM_TYPE_TEXTURE;
u.binding = 9;
- u.ids.push_back(storage->gi_probe_get_sdf_texture(probe));
+ u.ids.push_back(storage->voxel_gi_get_sdf_texture(probe));
uniforms.push_back(u);
}
{
@@ -2118,11 +2118,11 @@ void RendererSceneGIRD::GIProbeInstance::update(bool p_update_light_instances, c
RD::Uniform u;
u.uniform_type = RD::UNIFORM_TYPE_UNIFORM_BUFFER;
u.binding = 3;
- u.ids.push_back(gi->gi_probe_lights_uniform);
+ u.ids.push_back(gi->voxel_gi_lights_uniform);
copy_uniforms.push_back(u);
}
- mipmap.uniform_set = RD::get_singleton()->uniform_set_create(copy_uniforms, gi->giprobe_lighting_shader_version_shaders[GI_PROBE_SHADER_VERSION_COMPUTE_LIGHT], 0);
+ mipmap.uniform_set = RD::get_singleton()->uniform_set_create(copy_uniforms, gi->voxel_gi_lighting_shader_version_shaders[VOXEL_GI_SHADER_VERSION_COMPUTE_LIGHT], 0);
copy_uniforms = uniforms; //restore
@@ -2133,9 +2133,9 @@ void RendererSceneGIRD::GIProbeInstance::update(bool p_update_light_instances, c
u.ids.push_back(texture);
copy_uniforms.push_back(u);
}
- mipmap.second_bounce_uniform_set = RD::get_singleton()->uniform_set_create(copy_uniforms, gi->giprobe_lighting_shader_version_shaders[GI_PROBE_SHADER_VERSION_COMPUTE_SECOND_BOUNCE], 0);
+ mipmap.second_bounce_uniform_set = RD::get_singleton()->uniform_set_create(copy_uniforms, gi->voxel_gi_lighting_shader_version_shaders[VOXEL_GI_SHADER_VERSION_COMPUTE_SECOND_BOUNCE], 0);
} else {
- mipmap.uniform_set = RD::get_singleton()->uniform_set_create(copy_uniforms, gi->giprobe_lighting_shader_version_shaders[GI_PROBE_SHADER_VERSION_COMPUTE_MIPMAP], 0);
+ mipmap.uniform_set = RD::get_singleton()->uniform_set_create(copy_uniforms, gi->voxel_gi_lighting_shader_version_shaders[VOXEL_GI_SHADER_VERSION_COMPUTE_MIPMAP], 0);
}
}
@@ -2147,7 +2147,7 @@ void RendererSceneGIRD::GIProbeInstance::update(bool p_update_light_instances, c
uniforms.push_back(u);
}
- mipmap.write_uniform_set = RD::get_singleton()->uniform_set_create(uniforms, gi->giprobe_lighting_shader_version_shaders[GI_PROBE_SHADER_VERSION_WRITE_TEXTURE], 0);
+ mipmap.write_uniform_set = RD::get_singleton()->uniform_set_create(uniforms, gi->voxel_gi_lighting_shader_version_shaders[VOXEL_GI_SHADER_VERSION_WRITE_TEXTURE], 0);
mipmaps.push_back(mipmap);
}
@@ -2158,7 +2158,7 @@ void RendererSceneGIRD::GIProbeInstance::update(bool p_update_light_instances, c
int mipmap_index = 0;
while (mipmap_index < mipmaps.size()) {
- GIProbeInstance::DynamicMap dmap;
+ VoxelGIInstance::DynamicMap dmap;
if (oversample > 0) {
dmap.size = dynamic_map_size * (1 << oversample);
@@ -2217,7 +2217,7 @@ void RendererSceneGIRD::GIProbeInstance::update(bool p_update_light_instances, c
RD::Uniform u;
u.uniform_type = RD::UNIFORM_TYPE_UNIFORM_BUFFER;
u.binding = 3;
- u.ids.push_back(gi->gi_probe_lights_uniform);
+ u.ids.push_back(gi->voxel_gi_lights_uniform);
uniforms.push_back(u);
}
@@ -2253,7 +2253,7 @@ void RendererSceneGIRD::GIProbeInstance::update(bool p_update_light_instances, c
RD::Uniform u;
u.uniform_type = RD::UNIFORM_TYPE_TEXTURE;
u.binding = 9;
- u.ids.push_back(storage->gi_probe_get_sdf_texture(probe));
+ u.ids.push_back(storage->voxel_gi_get_sdf_texture(probe));
uniforms.push_back(u);
}
{
@@ -2278,7 +2278,7 @@ void RendererSceneGIRD::GIProbeInstance::update(bool p_update_light_instances, c
uniforms.push_back(u);
}
- dmap.uniform_set = RD::get_singleton()->uniform_set_create(uniforms, gi->giprobe_lighting_shader_version_shaders[GI_PROBE_SHADER_VERSION_DYNAMIC_OBJECT_LIGHTING], 0);
+ dmap.uniform_set = RD::get_singleton()->uniform_set_create(uniforms, gi->voxel_gi_lighting_shader_version_shaders[VOXEL_GI_SHADER_VERSION_DYNAMIC_OBJECT_LIGHTING], 0);
}
} else {
bool plot = dmap.mipmap >= 0;
@@ -2322,7 +2322,7 @@ void RendererSceneGIRD::GIProbeInstance::update(bool p_update_light_instances, c
RD::Uniform u;
u.uniform_type = RD::UNIFORM_TYPE_TEXTURE;
u.binding = 9;
- u.ids.push_back(storage->gi_probe_get_sdf_texture(probe));
+ u.ids.push_back(storage->voxel_gi_get_sdf_texture(probe));
uniforms.push_back(u);
}
{
@@ -2345,7 +2345,7 @@ void RendererSceneGIRD::GIProbeInstance::update(bool p_update_light_instances, c
dmap.uniform_set = RD::get_singleton()->uniform_set_create(
uniforms,
- gi->giprobe_lighting_shader_version_shaders[(write && plot) ? GI_PROBE_SHADER_VERSION_DYNAMIC_SHRINK_WRITE_PLOT : (write ? GI_PROBE_SHADER_VERSION_DYNAMIC_SHRINK_WRITE : GI_PROBE_SHADER_VERSION_DYNAMIC_SHRINK_PLOT)],
+ gi->voxel_gi_lighting_shader_version_shaders[(write && plot) ? VOXEL_GI_SHADER_VERSION_DYNAMIC_SHRINK_WRITE_PLOT : (write ? VOXEL_GI_SHADER_VERSION_DYNAMIC_SHRINK_WRITE : VOXEL_GI_SHADER_VERSION_DYNAMIC_SHRINK_PLOT)],
0);
}
@@ -2370,15 +2370,15 @@ void RendererSceneGIRD::GIProbeInstance::update(bool p_update_light_instances, c
uint32_t light_count = 0;
if (p_update_light_instances || p_dynamic_objects.size() > 0) {
- light_count = MIN(gi->gi_probe_max_lights, (uint32_t)p_light_instances.size());
+ light_count = MIN(gi->voxel_gi_max_lights, (uint32_t)p_light_instances.size());
{
- Transform to_cell = storage->gi_probe_get_to_cell_xform(probe);
- Transform to_probe_xform = (transform * to_cell.affine_inverse()).affine_inverse();
+ Transform3D to_cell = storage->voxel_gi_get_to_cell_xform(probe);
+ Transform3D to_probe_xform = (transform * to_cell.affine_inverse()).affine_inverse();
//update lights
for (uint32_t i = 0; i < light_count; i++) {
- GIProbeLight &l = gi->gi_probe_lights[i];
+ VoxelGILight &l = gi->voxel_gi_lights[i];
RID light_instance = p_light_instances[i];
RID light = p_scene_render->light_instance_get_base_light(light_instance);
@@ -2399,7 +2399,7 @@ void RendererSceneGIRD::GIProbeInstance::update(bool p_update_light_instances, c
l.cos_spot_angle = Math::cos(Math::deg2rad(storage->light_get_param(light, RS::LIGHT_PARAM_SPOT_ANGLE)));
l.inv_spot_attenuation = 1.0f / storage->light_get_param(light, RS::LIGHT_PARAM_SPOT_ATTENUATION);
- Transform xform = p_scene_render->light_instance_get_base_transform(light_instance);
+ Transform3D xform = p_scene_render->light_instance_get_base_transform(light_instance);
Vector3 pos = to_probe_xform.xform(xform.origin);
Vector3 dir = to_probe_xform.basis.xform(-xform.basis.get_axis(2)).normalized();
@@ -2415,7 +2415,7 @@ void RendererSceneGIRD::GIProbeInstance::update(bool p_update_light_instances, c
l.has_shadow = storage->light_has_shadow(light);
}
- RD::get_singleton()->buffer_update(gi->gi_probe_lights_uniform, 0, sizeof(GIProbeLight) * light_count, gi->gi_probe_lights);
+ RD::get_singleton()->buffer_update(gi->voxel_gi_lights_uniform, 0, sizeof(VoxelGILight) * light_count, gi->voxel_gi_lights);
}
}
@@ -2424,17 +2424,17 @@ void RendererSceneGIRD::GIProbeInstance::update(bool p_update_light_instances, c
if (mipmaps.size()) {
//can update mipmaps
- Vector3i probe_size = storage->gi_probe_get_octree_size(probe);
+ Vector3i probe_size = storage->voxel_gi_get_octree_size(probe);
- GIProbePushConstant push_constant;
+ VoxelGIPushConstant push_constant;
push_constant.limits[0] = probe_size.x;
push_constant.limits[1] = probe_size.y;
push_constant.limits[2] = probe_size.z;
push_constant.stack_size = mipmaps.size();
push_constant.emission_scale = 1.0;
- push_constant.propagation = storage->gi_probe_get_propagation(probe);
- push_constant.dynamic_range = storage->gi_probe_get_dynamic_range(probe);
+ push_constant.propagation = storage->voxel_gi_get_propagation(probe);
+ push_constant.dynamic_range = storage->voxel_gi_get_dynamic_range(probe);
push_constant.light_count = light_count;
push_constant.aniso_strength = 0;
@@ -2446,7 +2446,7 @@ void RendererSceneGIRD::GIProbeInstance::update(bool p_update_light_instances, c
int passes;
if (p_update_light_instances) {
- passes = storage->gi_probe_is_using_two_bounces(probe) ? 2 : 1;
+ passes = storage->voxel_gi_is_using_two_bounces(probe) ? 2 : 1;
} else {
passes = 1; //only re-blitting is necessary
}
@@ -2457,9 +2457,9 @@ void RendererSceneGIRD::GIProbeInstance::update(bool p_update_light_instances, c
if (p_update_light_instances) {
for (int i = 0; i < mipmaps.size(); i++) {
if (i == 0) {
- RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, gi->giprobe_lighting_shader_version_pipelines[pass == 0 ? GI_PROBE_SHADER_VERSION_COMPUTE_LIGHT : GI_PROBE_SHADER_VERSION_COMPUTE_SECOND_BOUNCE]);
+ RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, gi->voxel_gi_lighting_shader_version_pipelines[pass == 0 ? VOXEL_GI_SHADER_VERSION_COMPUTE_LIGHT : VOXEL_GI_SHADER_VERSION_COMPUTE_SECOND_BOUNCE]);
} else if (i == 1) {
- RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, gi->giprobe_lighting_shader_version_pipelines[GI_PROBE_SHADER_VERSION_COMPUTE_MIPMAP]);
+ RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, gi->voxel_gi_lighting_shader_version_pipelines[VOXEL_GI_SHADER_VERSION_COMPUTE_MIPMAP]);
}
if (pass == 1 || i > 0) {
@@ -2477,7 +2477,7 @@ void RendererSceneGIRD::GIProbeInstance::update(bool p_update_light_instances, c
int wg_todo = (mipmaps[i].cell_count - 1) / wg_size + 1;
while (wg_todo) {
int wg_count = MIN(wg_todo, wg_limit_x);
- RD::get_singleton()->compute_list_set_push_constant(compute_list, &push_constant, sizeof(GIProbePushConstant));
+ RD::get_singleton()->compute_list_set_push_constant(compute_list, &push_constant, sizeof(VoxelGIPushConstant));
RD::get_singleton()->compute_list_dispatch(compute_list, wg_count, 1, 1);
wg_todo -= wg_count;
push_constant.cell_offset += wg_count * wg_size;
@@ -2487,7 +2487,7 @@ void RendererSceneGIRD::GIProbeInstance::update(bool p_update_light_instances, c
RD::get_singleton()->compute_list_add_barrier(compute_list); //wait til previous step is done
}
- RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, gi->giprobe_lighting_shader_version_pipelines[GI_PROBE_SHADER_VERSION_WRITE_TEXTURE]);
+ RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, gi->voxel_gi_lighting_shader_version_pipelines[VOXEL_GI_SHADER_VERSION_WRITE_TEXTURE]);
for (int i = 0; i < mipmaps.size(); i++) {
RD::get_singleton()->compute_list_bind_uniform_set(compute_list, mipmaps[i].write_uniform_set, 0);
@@ -2498,7 +2498,7 @@ void RendererSceneGIRD::GIProbeInstance::update(bool p_update_light_instances, c
int wg_todo = (mipmaps[i].cell_count - 1) / wg_size + 1;
while (wg_todo) {
int wg_count = MIN(wg_todo, wg_limit_x);
- RD::get_singleton()->compute_list_set_push_constant(compute_list, &push_constant, sizeof(GIProbePushConstant));
+ RD::get_singleton()->compute_list_set_push_constant(compute_list, &push_constant, sizeof(VoxelGIPushConstant));
RD::get_singleton()->compute_list_dispatch(compute_list, wg_count, 1, 1);
wg_todo -= wg_count;
push_constant.cell_offset += wg_count * wg_size;
@@ -2513,15 +2513,15 @@ void RendererSceneGIRD::GIProbeInstance::update(bool p_update_light_instances, c
has_dynamic_object_data = false; //clear until dynamic object data is used again
if (p_dynamic_objects.size() && dynamic_maps.size()) {
- Vector3i octree_size = storage->gi_probe_get_octree_size(probe);
+ Vector3i octree_size = storage->voxel_gi_get_octree_size(probe);
int multiplier = dynamic_maps[0].size / MAX(MAX(octree_size.x, octree_size.y), octree_size.z);
- Transform oversample_scale;
+ Transform3D oversample_scale;
oversample_scale.basis.scale(Vector3(multiplier, multiplier, multiplier));
- Transform to_cell = oversample_scale * storage->gi_probe_get_to_cell_xform(probe);
- Transform to_world_xform = transform * to_cell.affine_inverse();
- Transform to_probe_xform = to_world_xform.affine_inverse();
+ Transform3D to_cell = oversample_scale * storage->voxel_gi_get_to_cell_xform(probe);
+ Transform3D to_world_xform = transform * to_cell.affine_inverse();
+ Transform3D to_probe_xform = to_world_xform.affine_inverse();
AABB probe_aabb(Vector3(), octree_size);
@@ -2529,7 +2529,7 @@ void RendererSceneGIRD::GIProbeInstance::update(bool p_update_light_instances, c
for (int i = 0; i < (int)p_dynamic_objects.size(); i++) {
RendererSceneRender::GeometryInstance *instance = p_dynamic_objects[i];
- //transform aabb to giprobe
+ //transform aabb to voxel_gi
AABB aabb = (to_probe_xform * p_scene_render->geometry_instance_get_transform(instance)).xform(p_scene_render->geometry_instance_get_aabb(instance));
//this needs to wrap to grid resolution to avoid jitter
@@ -2576,7 +2576,7 @@ void RendererSceneGIRD::GIProbeInstance::update(bool p_update_light_instances, c
Vector3 up_dir = render_up[j];
Vector3 center = aabb.position + aabb.size * 0.5;
- Transform xform;
+ Transform3D xform;
xform.set_look_at(center - aabb.size * 0.5 * render_dir, center, up_dir);
Vector3 x_dir = xform.basis.get_axis(0).abs();
@@ -2601,8 +2601,8 @@ void RendererSceneGIRD::GIProbeInstance::update(bool p_update_light_instances, c
p_scene_render->_render_material(to_world_xform * xform, cm, true, p_scene_render->cull_argument, dynamic_maps[0].fb, Rect2i(Vector2i(), rect.size));
- GIProbeDynamicPushConstant push_constant;
- memset(&push_constant, 0, sizeof(GIProbeDynamicPushConstant));
+ VoxelGIDynamicPushConstant push_constant;
+ memset(&push_constant, 0, sizeof(VoxelGIDynamicPushConstant));
push_constant.limits[0] = octree_size.x;
push_constant.limits[1] = octree_size.y;
push_constant.limits[2] = octree_size.z;
@@ -2619,7 +2619,7 @@ void RendererSceneGIRD::GIProbeInstance::update(bool p_update_light_instances, c
push_constant.z_base = xform.origin[z_axis];
push_constant.z_sign = (z_flip ? -1.0 : 1.0);
push_constant.pos_multiplier = float(1.0) / multiplier;
- push_constant.dynamic_range = storage->gi_probe_get_dynamic_range(probe);
+ push_constant.dynamic_range = storage->voxel_gi_get_dynamic_range(probe);
push_constant.flip_x = x_flip;
push_constant.flip_y = y_flip;
push_constant.rect_pos[0] = rect.position[0];
@@ -2631,16 +2631,16 @@ void RendererSceneGIRD::GIProbeInstance::update(bool p_update_light_instances, c
push_constant.prev_rect_size[0] = 0;
push_constant.prev_rect_size[1] = 0;
push_constant.on_mipmap = false;
- push_constant.propagation = storage->gi_probe_get_propagation(probe);
+ push_constant.propagation = storage->voxel_gi_get_propagation(probe);
push_constant.pad[0] = 0;
push_constant.pad[1] = 0;
push_constant.pad[2] = 0;
//process lighting
RD::ComputeListID compute_list = RD::get_singleton()->compute_list_begin();
- RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, gi->giprobe_lighting_shader_version_pipelines[GI_PROBE_SHADER_VERSION_DYNAMIC_OBJECT_LIGHTING]);
+ RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, gi->voxel_gi_lighting_shader_version_pipelines[VOXEL_GI_SHADER_VERSION_DYNAMIC_OBJECT_LIGHTING]);
RD::get_singleton()->compute_list_bind_uniform_set(compute_list, dynamic_maps[0].uniform_set, 0);
- RD::get_singleton()->compute_list_set_push_constant(compute_list, &push_constant, sizeof(GIProbeDynamicPushConstant));
+ RD::get_singleton()->compute_list_set_push_constant(compute_list, &push_constant, sizeof(VoxelGIDynamicPushConstant));
RD::get_singleton()->compute_list_dispatch(compute_list, (rect.size.x - 1) / 8 + 1, (rect.size.y - 1) / 8 + 1, 1);
//print_line("rect: " + itos(i) + ": " + rect);
@@ -2695,14 +2695,14 @@ void RendererSceneGIRD::GIProbeInstance::update(bool p_update_light_instances, c
RD::get_singleton()->compute_list_add_barrier(compute_list);
if (dynamic_maps[k].mipmap < 0) {
- RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, gi->giprobe_lighting_shader_version_pipelines[GI_PROBE_SHADER_VERSION_DYNAMIC_SHRINK_WRITE]);
+ RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, gi->voxel_gi_lighting_shader_version_pipelines[VOXEL_GI_SHADER_VERSION_DYNAMIC_SHRINK_WRITE]);
} else if (k < dynamic_maps.size() - 1) {
- RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, gi->giprobe_lighting_shader_version_pipelines[GI_PROBE_SHADER_VERSION_DYNAMIC_SHRINK_WRITE_PLOT]);
+ RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, gi->voxel_gi_lighting_shader_version_pipelines[VOXEL_GI_SHADER_VERSION_DYNAMIC_SHRINK_WRITE_PLOT]);
} else {
- RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, gi->giprobe_lighting_shader_version_pipelines[GI_PROBE_SHADER_VERSION_DYNAMIC_SHRINK_PLOT]);
+ RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, gi->voxel_gi_lighting_shader_version_pipelines[VOXEL_GI_SHADER_VERSION_DYNAMIC_SHRINK_PLOT]);
}
RD::get_singleton()->compute_list_bind_uniform_set(compute_list, dynamic_maps[k].uniform_set, 0);
- RD::get_singleton()->compute_list_set_push_constant(compute_list, &push_constant, sizeof(GIProbeDynamicPushConstant));
+ RD::get_singleton()->compute_list_set_push_constant(compute_list, &push_constant, sizeof(VoxelGIDynamicPushConstant));
RD::get_singleton()->compute_list_dispatch(compute_list, (rect.size.x - 1) / 8 + 1, (rect.size.y - 1) / 8 + 1, 1);
}
@@ -2713,22 +2713,22 @@ void RendererSceneGIRD::GIProbeInstance::update(bool p_update_light_instances, c
has_dynamic_object_data = true; //clear until dynamic object data is used again
}
- last_probe_version = storage->gi_probe_get_version(probe);
+ last_probe_version = storage->voxel_gi_get_version(probe);
}
-void RendererSceneGIRD::GIProbeInstance::debug(RD::DrawListID p_draw_list, RID p_framebuffer, const CameraMatrix &p_camera_with_transform, bool p_lighting, bool p_emission, float p_alpha) {
+void RendererSceneGIRD::VoxelGIInstance::debug(RD::DrawListID p_draw_list, RID p_framebuffer, const CameraMatrix &p_camera_with_transform, bool p_lighting, bool p_emission, float p_alpha) {
if (mipmaps.size() == 0) {
return;
}
- CameraMatrix cam_transform = (p_camera_with_transform * CameraMatrix(transform)) * CameraMatrix(storage->gi_probe_get_to_cell_xform(probe).affine_inverse());
+ CameraMatrix cam_transform = (p_camera_with_transform * CameraMatrix(transform)) * CameraMatrix(storage->voxel_gi_get_to_cell_xform(probe).affine_inverse());
int level = 0;
- Vector3i octree_size = storage->gi_probe_get_octree_size(probe);
+ Vector3i octree_size = storage->voxel_gi_get_octree_size(probe);
- GIProbeDebugPushConstant push_constant;
+ VoxelGIDebugPushConstant push_constant;
push_constant.alpha = p_alpha;
- push_constant.dynamic_range = storage->gi_probe_get_dynamic_range(probe);
+ push_constant.dynamic_range = storage->voxel_gi_get_dynamic_range(probe);
push_constant.cell_offset = mipmaps[level].cell_offset;
push_constant.level = level;
@@ -2743,15 +2743,15 @@ void RendererSceneGIRD::GIProbeInstance::debug(RD::DrawListID p_draw_list, RID p
}
}
- if (gi->giprobe_debug_uniform_set.is_valid()) {
- RD::get_singleton()->free(gi->giprobe_debug_uniform_set);
+ if (gi->voxel_gi_debug_uniform_set.is_valid()) {
+ RD::get_singleton()->free(gi->voxel_gi_debug_uniform_set);
}
Vector<RD::Uniform> uniforms;
{
RD::Uniform u;
u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER;
u.binding = 1;
- u.ids.push_back(storage->gi_probe_get_data_buffer(probe));
+ u.ids.push_back(storage->voxel_gi_get_data_buffer(probe));
uniforms.push_back(u);
}
{
@@ -2776,19 +2776,19 @@ void RendererSceneGIRD::GIProbeInstance::debug(RD::DrawListID p_draw_list, RID p
cell_count = mipmaps[level].cell_count;
}
- gi->giprobe_debug_uniform_set = RD::get_singleton()->uniform_set_create(uniforms, gi->giprobe_debug_shader_version_shaders[0], 0);
+ gi->voxel_gi_debug_uniform_set = RD::get_singleton()->uniform_set_create(uniforms, gi->voxel_gi_debug_shader_version_shaders[0], 0);
- int giprobe_debug_pipeline = GI_PROBE_DEBUG_COLOR;
+ int voxel_gi_debug_pipeline = VOXEL_GI_DEBUG_COLOR;
if (p_emission) {
- giprobe_debug_pipeline = GI_PROBE_DEBUG_EMISSION;
+ voxel_gi_debug_pipeline = VOXEL_GI_DEBUG_EMISSION;
} else if (p_lighting) {
- giprobe_debug_pipeline = has_dynamic_object_data ? GI_PROBE_DEBUG_LIGHT_FULL : GI_PROBE_DEBUG_LIGHT;
+ voxel_gi_debug_pipeline = has_dynamic_object_data ? VOXEL_GI_DEBUG_LIGHT_FULL : VOXEL_GI_DEBUG_LIGHT;
}
RD::get_singleton()->draw_list_bind_render_pipeline(
p_draw_list,
- gi->giprobe_debug_shader_version_pipelines[giprobe_debug_pipeline].get_render_pipeline(RD::INVALID_ID, RD::get_singleton()->framebuffer_get_format(p_framebuffer)));
- RD::get_singleton()->draw_list_bind_uniform_set(p_draw_list, gi->giprobe_debug_uniform_set, 0);
- RD::get_singleton()->draw_list_set_push_constant(p_draw_list, &push_constant, sizeof(GIProbeDebugPushConstant));
+ gi->voxel_gi_debug_shader_version_pipelines[voxel_gi_debug_pipeline].get_render_pipeline(RD::INVALID_ID, RD::get_singleton()->framebuffer_get_format(p_framebuffer)));
+ RD::get_singleton()->draw_list_bind_uniform_set(p_draw_list, gi->voxel_gi_debug_uniform_set, 0);
+ RD::get_singleton()->draw_list_set_push_constant(p_draw_list, &push_constant, sizeof(VoxelGIDebugPushConstant));
RD::get_singleton()->draw_list_draw(p_draw_list, false, cell_count, 36);
}
@@ -2812,13 +2812,13 @@ void RendererSceneGIRD::init(RendererStorageRD *p_storage, RendererSceneSkyRD *p
{
//kinda complicated to compute the amount of slots, we try to use as many as we can
- gi_probe_max_lights = 32;
+ voxel_gi_max_lights = 32;
- gi_probe_lights = memnew_arr(GIProbeLight, gi_probe_max_lights);
- gi_probe_lights_uniform = RD::get_singleton()->uniform_buffer_create(gi_probe_max_lights * sizeof(GIProbeLight));
- gi_probe_quality = RS::GIProbeQuality(CLAMP(int(GLOBAL_GET("rendering/global_illumination/gi_probes/quality")), 0, 1));
+ voxel_gi_lights = memnew_arr(VoxelGILight, voxel_gi_max_lights);
+ voxel_gi_lights_uniform = RD::get_singleton()->uniform_buffer_create(voxel_gi_max_lights * sizeof(VoxelGILight));
+ voxel_gi_quality = RS::VoxelGIQuality(CLAMP(int(GLOBAL_GET("rendering/global_illumination/voxel_gi/quality")), 0, 1));
- String defines = "\n#define MAX_LIGHTS " + itos(gi_probe_max_lights) + "\n";
+ String defines = "\n#define MAX_LIGHTS " + itos(voxel_gi_max_lights) + "\n";
Vector<String> versions;
versions.push_back("\n#define MODE_COMPUTE_LIGHT\n");
@@ -2830,11 +2830,11 @@ void RendererSceneGIRD::init(RendererStorageRD *p_storage, RendererSceneSkyRD *p
versions.push_back("\n#define MODE_DYNAMIC\n#define MODE_DYNAMIC_SHRINK\n#define MODE_DYNAMIC_SHRINK_PLOT\n");
versions.push_back("\n#define MODE_DYNAMIC\n#define MODE_DYNAMIC_SHRINK\n#define MODE_DYNAMIC_SHRINK_PLOT\n#define MODE_DYNAMIC_SHRINK_WRITE\n");
- giprobe_shader.initialize(versions, defines);
- giprobe_lighting_shader_version = giprobe_shader.version_create();
- for (int i = 0; i < GI_PROBE_SHADER_VERSION_MAX; i++) {
- giprobe_lighting_shader_version_shaders[i] = giprobe_shader.version_get_shader(giprobe_lighting_shader_version, i);
- giprobe_lighting_shader_version_pipelines[i] = RD::get_singleton()->compute_pipeline_create(giprobe_lighting_shader_version_shaders[i]);
+ voxel_gi_shader.initialize(versions, defines);
+ voxel_gi_lighting_shader_version = voxel_gi_shader.version_create();
+ for (int i = 0; i < VOXEL_GI_SHADER_VERSION_MAX; i++) {
+ voxel_gi_lighting_shader_version_shaders[i] = voxel_gi_shader.version_get_shader(voxel_gi_lighting_shader_version, i);
+ voxel_gi_lighting_shader_version_pipelines[i] = RD::get_singleton()->compute_pipeline_create(voxel_gi_lighting_shader_version_shaders[i]);
}
}
@@ -2846,10 +2846,10 @@ void RendererSceneGIRD::init(RendererStorageRD *p_storage, RendererSceneSkyRD *p
versions.push_back("\n#define MODE_DEBUG_EMISSION\n");
versions.push_back("\n#define MODE_DEBUG_LIGHT\n#define MODE_DEBUG_LIGHT_FULL\n");
- giprobe_debug_shader.initialize(versions, defines);
- giprobe_debug_shader_version = giprobe_debug_shader.version_create();
- for (int i = 0; i < GI_PROBE_DEBUG_MAX; i++) {
- giprobe_debug_shader_version_shaders[i] = giprobe_debug_shader.version_get_shader(giprobe_debug_shader_version, i);
+ voxel_gi_debug_shader.initialize(versions, defines);
+ voxel_gi_debug_shader_version = voxel_gi_debug_shader.version_create();
+ for (int i = 0; i < VOXEL_GI_DEBUG_MAX; i++) {
+ voxel_gi_debug_shader_version_shaders[i] = voxel_gi_debug_shader.version_get_shader(voxel_gi_debug_shader_version, i);
RD::PipelineRasterizationState rs;
rs.cull_mode = RD::POLYGON_CULL_FRONT;
@@ -2858,7 +2858,7 @@ void RendererSceneGIRD::init(RendererStorageRD *p_storage, RendererSceneSkyRD *p
ds.enable_depth_write = true;
ds.depth_compare_operator = RD::COMPARE_OP_LESS_OR_EQUAL;
- giprobe_debug_shader_version_pipelines[i].setup(giprobe_debug_shader_version_shaders[i], RD::RENDER_PRIMITIVE_TRIANGLES, rs, RD::PipelineMultisampleState(), ds, RD::PipelineColorBlendState::create_disabled(), 0);
+ voxel_gi_debug_shader_version_pipelines[i].setup(voxel_gi_debug_shader_version_shaders[i], RD::RENDER_PRIMITIVE_TRIANGLES, rs, RD::PipelineMultisampleState(), ds, RD::PipelineColorBlendState::create_disabled(), 0);
}
}
@@ -2944,12 +2944,12 @@ void RendererSceneGIRD::init(RendererStorageRD *p_storage, RendererSceneSkyRD *p
//calculate tables
String defines = "\n#define SDFGI_OCT_SIZE " + itos(SDFGI::LIGHTPROBE_OCT_SIZE) + "\n";
Vector<String> gi_modes;
- gi_modes.push_back("\n#define USE_GIPROBES\n");
+ gi_modes.push_back("\n#define USE_VOXEL_GI_INSTANCES\n");
gi_modes.push_back("\n#define USE_SDFGI\n");
- gi_modes.push_back("\n#define USE_SDFGI\n\n#define USE_GIPROBES\n");
- gi_modes.push_back("\n#define MODE_HALF_RES\n#define USE_GIPROBES\n");
+ gi_modes.push_back("\n#define USE_SDFGI\n\n#define USE_VOXEL_GI_INSTANCES\n");
+ gi_modes.push_back("\n#define MODE_HALF_RES\n#define USE_VOXEL_GI_INSTANCES\n");
gi_modes.push_back("\n#define MODE_HALF_RES\n#define USE_SDFGI\n");
- gi_modes.push_back("\n#define MODE_HALF_RES\n#define USE_SDFGI\n\n#define USE_GIPROBES\n");
+ gi_modes.push_back("\n#define MODE_HALF_RES\n#define USE_SDFGI\n\n#define USE_VOXEL_GI_INSTANCES\n");
shader.initialize(gi_modes, defines);
shader_version = shader.version_create();
@@ -2991,17 +2991,17 @@ void RendererSceneGIRD::init(RendererStorageRD *p_storage, RendererSceneSkyRD *p
}
}
}
- default_giprobe_buffer = RD::get_singleton()->uniform_buffer_create(sizeof(GIProbeData) * MAX_GIPROBES);
+ default_voxel_gi_buffer = RD::get_singleton()->uniform_buffer_create(sizeof(VoxelGIData) * MAX_VOXEL_GI_INSTANCES);
half_resolution = GLOBAL_GET("rendering/global_illumination/gi/use_half_resolution");
}
void RendererSceneGIRD::free() {
- RD::get_singleton()->free(default_giprobe_buffer);
- RD::get_singleton()->free(gi_probe_lights_uniform);
+ RD::get_singleton()->free(default_voxel_gi_buffer);
+ RD::get_singleton()->free(voxel_gi_lights_uniform);
RD::get_singleton()->free(sdfgi_ubo);
- giprobe_debug_shader.version_free(giprobe_debug_shader_version);
- giprobe_shader.version_free(giprobe_lighting_shader_version);
+ voxel_gi_debug_shader.version_free(voxel_gi_debug_shader_version);
+ voxel_gi_shader.version_free(voxel_gi_lighting_shader_version);
shader.version_free(shader_version);
sdfgi_shader.debug_probes.version_free(sdfgi_shader.debug_probes_shader);
sdfgi_shader.debug.version_free(sdfgi_shader.debug_shader);
@@ -3009,7 +3009,7 @@ void RendererSceneGIRD::free() {
sdfgi_shader.integrate.version_free(sdfgi_shader.integrate_shader);
sdfgi_shader.preprocess.version_free(sdfgi_shader.preprocess_shader);
- memdelete_arr(gi_probe_lights);
+ memdelete_arr(voxel_gi_lights);
}
RendererSceneGIRD::SDFGI *RendererSceneGIRD::create_sdfgi(RendererSceneEnvironmentRD *p_env, const Vector3 &p_world_position, uint32_t p_requested_history_size) {
@@ -3020,36 +3020,34 @@ RendererSceneGIRD::SDFGI *RendererSceneGIRD::create_sdfgi(RendererSceneEnvironme
return sdfgi;
}
-void RendererSceneGIRD::setup_giprobes(RID p_render_buffers, const Transform &p_transform, const PagedArray<RID> &p_gi_probes, uint32_t &r_gi_probes_used, RendererSceneRenderRD *p_scene_render) {
- r_gi_probes_used = 0;
+void RendererSceneGIRD::setup_voxel_gi_instances(RID p_render_buffers, const Transform3D &p_transform, const PagedArray<RID> &p_voxel_gi_instances, uint32_t &r_voxel_gi_instances_used, RendererSceneRenderRD *p_scene_render) {
+ r_voxel_gi_instances_used = 0;
// feels a little dirty to use our container this way but....
RendererSceneRenderRD::RenderBuffers *rb = p_scene_render->render_buffers_owner.getornull(p_render_buffers);
ERR_FAIL_COND(rb == nullptr);
- RID gi_probe_buffer = p_scene_render->render_buffers_get_gi_probe_buffer(p_render_buffers);
+ RID voxel_gi_buffer = p_scene_render->render_buffers_get_voxel_gi_buffer(p_render_buffers);
- RD::get_singleton()->draw_command_begin_label("GIProbes Setup");
+ VoxelGIData voxel_gi_data[MAX_VOXEL_GI_INSTANCES];
- GIProbeData gi_probe_data[MAX_GIPROBES];
+ bool voxel_gi_instances_changed = false;
- bool giprobes_changed = false;
-
- Transform to_camera;
+ Transform3D to_camera;
to_camera.origin = p_transform.origin; //only translation, make local
- for (int i = 0; i < MAX_GIPROBES; i++) {
+ for (int i = 0; i < MAX_VOXEL_GI_INSTANCES; i++) {
RID texture;
- if (i < (int)p_gi_probes.size()) {
- GIProbeInstance *gipi = get_probe_instance(p_gi_probes[i]);
+ if (i < (int)p_voxel_gi_instances.size()) {
+ VoxelGIInstance *gipi = get_probe_instance(p_voxel_gi_instances[i]);
if (gipi) {
texture = gipi->texture;
- GIProbeData &gipd = gi_probe_data[i];
+ VoxelGIData &gipd = voxel_gi_data[i];
RID base_probe = gipi->probe;
- Transform to_cell = storage->gi_probe_get_to_cell_xform(gipi->probe) * gipi->transform.affine_inverse() * to_camera;
+ Transform3D to_cell = storage->voxel_gi_get_to_cell_xform(gipi->probe) * gipi->transform.affine_inverse() * to_camera;
gipd.xform[0] = to_cell.basis.elements[0][0];
gipd.xform[1] = to_cell.basis.elements[1][0];
@@ -3068,36 +3066,33 @@ void RendererSceneGIRD::setup_giprobes(RID p_render_buffers, const Transform &p_
gipd.xform[14] = to_cell.origin.z;
gipd.xform[15] = 1;
- Vector3 bounds = storage->gi_probe_get_octree_size(base_probe);
+ Vector3 bounds = storage->voxel_gi_get_octree_size(base_probe);
gipd.bounds[0] = bounds.x;
gipd.bounds[1] = bounds.y;
gipd.bounds[2] = bounds.z;
- gipd.dynamic_range = storage->gi_probe_get_dynamic_range(base_probe) * storage->gi_probe_get_energy(base_probe);
- gipd.bias = storage->gi_probe_get_bias(base_probe);
- gipd.normal_bias = storage->gi_probe_get_normal_bias(base_probe);
- gipd.blend_ambient = !storage->gi_probe_is_interior(base_probe);
- gipd.anisotropy_strength = 0;
- gipd.ao = storage->gi_probe_get_ao(base_probe);
- gipd.ao_size = Math::pow(storage->gi_probe_get_ao_size(base_probe), 4.0f);
+ gipd.dynamic_range = storage->voxel_gi_get_dynamic_range(base_probe) * storage->voxel_gi_get_energy(base_probe);
+ gipd.bias = storage->voxel_gi_get_bias(base_probe);
+ gipd.normal_bias = storage->voxel_gi_get_normal_bias(base_probe);
+ gipd.blend_ambient = !storage->voxel_gi_is_interior(base_probe);
gipd.mipmaps = gipi->mipmaps.size();
}
- r_gi_probes_used++;
+ r_voxel_gi_instances_used++;
}
if (texture == RID()) {
texture = storage->texture_rd_get_default(RendererStorageRD::DEFAULT_RD_TEXTURE_3D_WHITE);
}
- if (texture != rb->gi.giprobe_textures[i]) {
- giprobes_changed = true;
- rb->gi.giprobe_textures[i] = texture;
+ if (texture != rb->gi.voxel_gi_textures[i]) {
+ voxel_gi_instances_changed = true;
+ rb->gi.voxel_gi_textures[i] = texture;
}
}
- if (giprobes_changed) {
+ if (voxel_gi_instances_changed) {
if (RD::get_singleton()->uniform_set_is_valid(rb->gi.uniform_set)) {
RD::get_singleton()->free(rb->gi.uniform_set);
}
@@ -3112,14 +3107,16 @@ void RendererSceneGIRD::setup_giprobes(RID p_render_buffers, const Transform &p_
}
}
- if (p_gi_probes.size() > 0) {
- RD::get_singleton()->buffer_update(gi_probe_buffer, 0, sizeof(GIProbeData) * MIN((uint64_t)MAX_GIPROBES, p_gi_probes.size()), gi_probe_data, RD::BARRIER_MASK_COMPUTE);
- }
+ if (p_voxel_gi_instances.size() > 0) {
+ RD::get_singleton()->draw_command_begin_label("VoxelGIs Setup");
- RD::get_singleton()->draw_command_end_label();
+ RD::get_singleton()->buffer_update(voxel_gi_buffer, 0, sizeof(VoxelGIData) * MIN((uint64_t)MAX_VOXEL_GI_INSTANCES, p_voxel_gi_instances.size()), voxel_gi_data, RD::BARRIER_MASK_COMPUTE);
+
+ RD::get_singleton()->draw_command_end_label();
+ }
}
-void RendererSceneGIRD::process_gi(RID p_render_buffers, RID p_normal_roughness_buffer, RID p_gi_probe_buffer, RID p_environment, const CameraMatrix &p_projection, const Transform &p_transform, const PagedArray<RID> &p_gi_probes, RendererSceneRenderRD *p_scene_render) {
+void RendererSceneGIRD::process_gi(RID p_render_buffers, RID p_normal_roughness_buffer, RID p_voxel_gi_buffer, RID p_environment, const CameraMatrix &p_projection, const Transform3D &p_transform, const PagedArray<RID> &p_voxel_gi_instances, RendererSceneRenderRD *p_scene_render) {
RD::get_singleton()->draw_command_begin_label("GI Render");
RendererSceneRenderRD::RenderBuffers *rb = p_scene_render->render_buffers_owner.getornull(p_render_buffers);
@@ -3157,11 +3154,11 @@ void RendererSceneGIRD::process_gi(RID p_render_buffers, RID p_normal_roughness_
push_constant.proj_info[1] = -2.0f / (rb->height * p_projection.matrix[1][1]);
push_constant.proj_info[2] = (1.0f - p_projection.matrix[0][2]) / p_projection.matrix[0][0];
push_constant.proj_info[3] = (1.0f + p_projection.matrix[1][2]) / p_projection.matrix[1][1];
- push_constant.max_giprobes = MIN((uint64_t)MAX_GIPROBES, p_gi_probes.size());
- push_constant.high_quality_vct = gi_probe_quality == RS::GI_PROBE_QUALITY_HIGH;
+ push_constant.max_voxel_gi_instances = MIN((uint64_t)MAX_VOXEL_GI_INSTANCES, p_voxel_gi_instances.size());
+ push_constant.high_quality_vct = voxel_gi_quality == RS::VOXEL_GI_QUALITY_HIGH;
bool use_sdfgi = rb->sdfgi != nullptr;
- bool use_giprobes = push_constant.max_giprobes > 0;
+ bool use_voxel_gi_instances = push_constant.max_voxel_gi_instances > 0;
if (env) {
push_constant.ao_color[0] = env->ao_color.r;
@@ -3311,7 +3308,7 @@ void RendererSceneGIRD::process_gi(RID p_render_buffers, RID p_normal_roughness_
RD::Uniform u;
u.uniform_type = RD::UNIFORM_TYPE_TEXTURE;
u.binding = 14;
- RID buffer = p_gi_probe_buffer.is_valid() ? p_gi_probe_buffer : storage->texture_rd_get_default(RendererStorageRD::DEFAULT_RD_TEXTURE_BLACK);
+ RID buffer = p_voxel_gi_buffer.is_valid() ? p_voxel_gi_buffer : storage->texture_rd_get_default(RendererStorageRD::DEFAULT_RD_TEXTURE_BLACK);
u.ids.push_back(buffer);
uniforms.push_back(u);
}
@@ -3326,15 +3323,15 @@ void RendererSceneGIRD::process_gi(RID p_render_buffers, RID p_normal_roughness_
RD::Uniform u;
u.uniform_type = RD::UNIFORM_TYPE_UNIFORM_BUFFER;
u.binding = 16;
- u.ids.push_back(rb->gi.giprobe_buffer);
+ u.ids.push_back(rb->gi.voxel_gi_buffer);
uniforms.push_back(u);
}
{
RD::Uniform u;
u.uniform_type = RD::UNIFORM_TYPE_TEXTURE;
u.binding = 17;
- for (int i = 0; i < MAX_GIPROBES; i++) {
- u.ids.push_back(rb->gi.giprobe_textures[i]);
+ for (int i = 0; i < MAX_VOXEL_GI_INSTANCES; i++) {
+ u.ids.push_back(rb->gi.voxel_gi_textures[i]);
}
uniforms.push_back(u);
}
@@ -3345,10 +3342,11 @@ void RendererSceneGIRD::process_gi(RID p_render_buffers, RID p_normal_roughness_
Mode mode;
if (rb->gi.using_half_size_gi) {
- mode = (use_sdfgi && use_giprobes) ? MODE_HALF_RES_COMBINED : (use_sdfgi ? MODE_HALF_RES_SDFGI : MODE_HALF_RES_GIPROBE);
+ mode = (use_sdfgi && use_voxel_gi_instances) ? MODE_HALF_RES_COMBINED : (use_sdfgi ? MODE_HALF_RES_SDFGI : MODE_HALF_RES_VOXEL_GI);
} else {
- mode = (use_sdfgi && use_giprobes) ? MODE_COMBINED : (use_sdfgi ? MODE_SDFGI : MODE_GIPROBE);
+ mode = (use_sdfgi && use_voxel_gi_instances) ? MODE_COMBINED : (use_sdfgi ? MODE_SDFGI : MODE_VOXEL_GI);
}
+
RD::ComputeListID compute_list = RD::get_singleton()->compute_list_begin(true);
RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, pipelines[mode]);
RD::get_singleton()->compute_list_bind_uniform_set(compute_list, rb->gi.uniform_set, 0);
@@ -3364,39 +3362,39 @@ void RendererSceneGIRD::process_gi(RID p_render_buffers, RID p_normal_roughness_
RD::get_singleton()->draw_command_end_label();
}
-RID RendererSceneGIRD::gi_probe_instance_create(RID p_base) {
- GIProbeInstance gi_probe;
- gi_probe.gi = this;
- gi_probe.storage = storage;
- gi_probe.probe = p_base;
- RID rid = gi_probe_instance_owner.make_rid(gi_probe);
+RID RendererSceneGIRD::voxel_gi_instance_create(RID p_base) {
+ VoxelGIInstance voxel_gi;
+ voxel_gi.gi = this;
+ voxel_gi.storage = storage;
+ voxel_gi.probe = p_base;
+ RID rid = voxel_gi_instance_owner.make_rid(voxel_gi);
return rid;
}
-void RendererSceneGIRD::gi_probe_instance_set_transform_to_data(RID p_probe, const Transform &p_xform) {
- GIProbeInstance *gi_probe = get_probe_instance(p_probe);
- ERR_FAIL_COND(!gi_probe);
+void RendererSceneGIRD::voxel_gi_instance_set_transform_to_data(RID p_probe, const Transform3D &p_xform) {
+ VoxelGIInstance *voxel_gi = get_probe_instance(p_probe);
+ ERR_FAIL_COND(!voxel_gi);
- gi_probe->transform = p_xform;
+ voxel_gi->transform = p_xform;
}
-bool RendererSceneGIRD::gi_probe_needs_update(RID p_probe) const {
- GIProbeInstance *gi_probe = get_probe_instance(p_probe);
- ERR_FAIL_COND_V(!gi_probe, false);
+bool RendererSceneGIRD::voxel_gi_needs_update(RID p_probe) const {
+ VoxelGIInstance *voxel_gi = get_probe_instance(p_probe);
+ ERR_FAIL_COND_V(!voxel_gi, false);
- return gi_probe->last_probe_version != storage->gi_probe_get_version(gi_probe->probe);
+ return voxel_gi->last_probe_version != storage->voxel_gi_get_version(voxel_gi->probe);
}
-void RendererSceneGIRD::gi_probe_update(RID p_probe, bool p_update_light_instances, const Vector<RID> &p_light_instances, const PagedArray<RendererSceneRender::GeometryInstance *> &p_dynamic_objects, RendererSceneRenderRD *p_scene_render) {
- GIProbeInstance *gi_probe = get_probe_instance(p_probe);
- ERR_FAIL_COND(!gi_probe);
+void RendererSceneGIRD::voxel_gi_update(RID p_probe, bool p_update_light_instances, const Vector<RID> &p_light_instances, const PagedArray<RendererSceneRender::GeometryInstance *> &p_dynamic_objects, RendererSceneRenderRD *p_scene_render) {
+ VoxelGIInstance *voxel_gi = get_probe_instance(p_probe);
+ ERR_FAIL_COND(!voxel_gi);
- gi_probe->update(p_update_light_instances, p_light_instances, p_dynamic_objects, p_scene_render);
+ voxel_gi->update(p_update_light_instances, p_light_instances, p_dynamic_objects, p_scene_render);
}
-void RendererSceneGIRD::debug_giprobe(RID p_gi_probe, RD::DrawListID p_draw_list, RID p_framebuffer, const CameraMatrix &p_camera_with_transform, bool p_lighting, bool p_emission, float p_alpha) {
- GIProbeInstance *gi_probe = gi_probe_instance_owner.getornull(p_gi_probe);
- ERR_FAIL_COND(!gi_probe);
+void RendererSceneGIRD::debug_voxel_gi(RID p_voxel_gi, RD::DrawListID p_draw_list, RID p_framebuffer, const CameraMatrix &p_camera_with_transform, bool p_lighting, bool p_emission, float p_alpha) {
+ VoxelGIInstance *voxel_gi = voxel_gi_instance_owner.getornull(p_voxel_gi);
+ ERR_FAIL_COND(!voxel_gi);
- gi_probe->debug(p_draw_list, p_framebuffer, p_camera_with_transform, p_lighting, p_emission, p_alpha);
+ voxel_gi->debug(p_draw_list, p_framebuffer, p_camera_with_transform, p_lighting, p_emission, p_alpha);
}
diff --git a/servers/rendering/renderer_rd/renderer_scene_gi_rd.h b/servers/rendering/renderer_rd/renderer_scene_gi_rd.h
index 59f5f374d1..128bf09063 100644
--- a/servers/rendering/renderer_rd/renderer_scene_gi_rd.h
+++ b/servers/rendering/renderer_rd/renderer_scene_gi_rd.h
@@ -38,13 +38,13 @@
#include "servers/rendering/renderer_rd/renderer_scene_sky_rd.h"
#include "servers/rendering/renderer_rd/renderer_storage_rd.h"
#include "servers/rendering/renderer_rd/shaders/gi.glsl.gen.h"
-#include "servers/rendering/renderer_rd/shaders/giprobe.glsl.gen.h"
-#include "servers/rendering/renderer_rd/shaders/giprobe_debug.glsl.gen.h"
#include "servers/rendering/renderer_rd/shaders/sdfgi_debug.glsl.gen.h"
#include "servers/rendering/renderer_rd/shaders/sdfgi_debug_probes.glsl.gen.h"
#include "servers/rendering/renderer_rd/shaders/sdfgi_direct_light.glsl.gen.h"
#include "servers/rendering/renderer_rd/shaders/sdfgi_integrate.glsl.gen.h"
#include "servers/rendering/renderer_rd/shaders/sdfgi_preprocess.glsl.gen.h"
+#include "servers/rendering/renderer_rd/shaders/voxel_gi.glsl.gen.h"
+#include "servers/rendering/renderer_rd/shaders/voxel_gi_debug.glsl.gen.h"
#include "servers/rendering/renderer_scene_render.h"
#include "servers/rendering/rendering_device.h"
@@ -56,9 +56,9 @@ class RendererSceneGIRD {
private:
RendererStorageRD *storage;
- /* GIPROBE INSTANCE */
+ /* VOXEL_GI INSTANCE */
- struct GIProbeLight {
+ struct VoxelGILight {
uint32_t type;
float energy;
float radius;
@@ -74,7 +74,7 @@ private:
uint32_t has_shadow;
};
- struct GIProbePushConstant {
+ struct VoxelGIPushConstant {
int32_t limits[3];
uint32_t stack_size;
@@ -89,7 +89,7 @@ private:
uint32_t pad;
};
- struct GIProbeDynamicPushConstant {
+ struct VoxelGIDynamicPushConstant {
int32_t limits[3];
uint32_t light_count;
int32_t x_dir[3];
@@ -110,36 +110,36 @@ private:
float pad[3];
};
- GIProbeLight *gi_probe_lights;
- uint32_t gi_probe_max_lights;
- RID gi_probe_lights_uniform;
+ VoxelGILight *voxel_gi_lights;
+ uint32_t voxel_gi_max_lights;
+ RID voxel_gi_lights_uniform;
enum {
- GI_PROBE_SHADER_VERSION_COMPUTE_LIGHT,
- GI_PROBE_SHADER_VERSION_COMPUTE_SECOND_BOUNCE,
- GI_PROBE_SHADER_VERSION_COMPUTE_MIPMAP,
- GI_PROBE_SHADER_VERSION_WRITE_TEXTURE,
- GI_PROBE_SHADER_VERSION_DYNAMIC_OBJECT_LIGHTING,
- GI_PROBE_SHADER_VERSION_DYNAMIC_SHRINK_WRITE,
- GI_PROBE_SHADER_VERSION_DYNAMIC_SHRINK_PLOT,
- GI_PROBE_SHADER_VERSION_DYNAMIC_SHRINK_WRITE_PLOT,
- GI_PROBE_SHADER_VERSION_MAX
+ VOXEL_GI_SHADER_VERSION_COMPUTE_LIGHT,
+ VOXEL_GI_SHADER_VERSION_COMPUTE_SECOND_BOUNCE,
+ VOXEL_GI_SHADER_VERSION_COMPUTE_MIPMAP,
+ VOXEL_GI_SHADER_VERSION_WRITE_TEXTURE,
+ VOXEL_GI_SHADER_VERSION_DYNAMIC_OBJECT_LIGHTING,
+ VOXEL_GI_SHADER_VERSION_DYNAMIC_SHRINK_WRITE,
+ VOXEL_GI_SHADER_VERSION_DYNAMIC_SHRINK_PLOT,
+ VOXEL_GI_SHADER_VERSION_DYNAMIC_SHRINK_WRITE_PLOT,
+ VOXEL_GI_SHADER_VERSION_MAX
};
- GiprobeShaderRD giprobe_shader;
- RID giprobe_lighting_shader_version;
- RID giprobe_lighting_shader_version_shaders[GI_PROBE_SHADER_VERSION_MAX];
- RID giprobe_lighting_shader_version_pipelines[GI_PROBE_SHADER_VERSION_MAX];
+ VoxelGiShaderRD voxel_gi_shader;
+ RID voxel_gi_lighting_shader_version;
+ RID voxel_gi_lighting_shader_version_shaders[VOXEL_GI_SHADER_VERSION_MAX];
+ RID voxel_gi_lighting_shader_version_pipelines[VOXEL_GI_SHADER_VERSION_MAX];
enum {
- GI_PROBE_DEBUG_COLOR,
- GI_PROBE_DEBUG_LIGHT,
- GI_PROBE_DEBUG_EMISSION,
- GI_PROBE_DEBUG_LIGHT_FULL,
- GI_PROBE_DEBUG_MAX
+ VOXEL_GI_DEBUG_COLOR,
+ VOXEL_GI_DEBUG_LIGHT,
+ VOXEL_GI_DEBUG_EMISSION,
+ VOXEL_GI_DEBUG_LIGHT_FULL,
+ VOXEL_GI_DEBUG_MAX
};
- struct GIProbeDebugPushConstant {
+ struct VoxelGIDebugPushConstant {
float projection[16];
uint32_t cell_offset;
float dynamic_range;
@@ -149,11 +149,11 @@ private:
uint32_t pad;
};
- GiprobeDebugShaderRD giprobe_debug_shader;
- RID giprobe_debug_shader_version;
- RID giprobe_debug_shader_version_shaders[GI_PROBE_DEBUG_MAX];
- PipelineCacheRD giprobe_debug_shader_version_pipelines[GI_PROBE_DEBUG_MAX];
- RID giprobe_debug_uniform_set;
+ VoxelGiDebugShaderRD voxel_gi_debug_shader;
+ RID voxel_gi_debug_shader_version;
+ RID voxel_gi_debug_shader_version_shaders[VOXEL_GI_DEBUG_MAX];
+ PipelineCacheRD voxel_gi_debug_shader_version_pipelines[VOXEL_GI_DEBUG_MAX];
+ RID voxel_gi_debug_uniform_set;
/* SDFGI */
@@ -326,11 +326,11 @@ private:
} sdfgi_shader;
public:
- /* GIPROBE INSTANCE */
+ /* VOXEL_GI INSTANCE */
- //@TODO GIProbeInstance is still directly used in the render code, we'll address this when we refactor the render code itself.
+ //@TODO VoxelGIInstance is still directly used in the render code, we'll address this when we refactor the render code itself.
- struct GIProbeInstance {
+ struct VoxelGIInstance {
// access to our containers
RendererStorageRD *storage;
RendererSceneGIRD *gi;
@@ -374,25 +374,25 @@ public:
bool has_dynamic_object_data = false;
- Transform transform;
+ Transform3D transform;
void update(bool p_update_light_instances, const Vector<RID> &p_light_instances, const PagedArray<RendererSceneRender::GeometryInstance *> &p_dynamic_objects, RendererSceneRenderRD *p_scene_render);
void debug(RD::DrawListID p_draw_list, RID p_framebuffer, const CameraMatrix &p_camera_with_transform, bool p_lighting, bool p_emission, float p_alpha);
};
- mutable RID_Owner<GIProbeInstance> gi_probe_instance_owner;
+ mutable RID_Owner<VoxelGIInstance> voxel_gi_instance_owner;
- _FORCE_INLINE_ GIProbeInstance *get_probe_instance(RID p_probe) const {
- return gi_probe_instance_owner.getornull(p_probe);
+ _FORCE_INLINE_ VoxelGIInstance *get_probe_instance(RID p_probe) const {
+ return voxel_gi_instance_owner.getornull(p_probe);
};
- _FORCE_INLINE_ RID gi_probe_instance_get_texture(RID p_probe) {
- GIProbeInstance *gi_probe = get_probe_instance(p_probe);
- ERR_FAIL_COND_V(!gi_probe, RID());
- return gi_probe->texture;
+ _FORCE_INLINE_ RID voxel_gi_instance_get_texture(RID p_probe) {
+ VoxelGIInstance *voxel_gi = get_probe_instance(p_probe);
+ ERR_FAIL_COND_V(!voxel_gi, RID());
+ return voxel_gi->texture;
};
- RS::GIProbeQuality gi_probe_quality = RS::GI_PROBE_QUALITY_HIGH;
+ RS::VoxelGIQuality voxel_gi_quality = RS::VOXEL_GI_QUALITY_HIGH;
/* SDFGI */
@@ -527,10 +527,10 @@ public:
int get_pending_region_data(int p_region, Vector3i &r_local_offset, Vector3i &r_local_size, AABB &r_bounds) const;
void update_cascades();
- void debug_draw(const CameraMatrix &p_projection, const Transform &p_transform, int p_width, int p_height, RID p_render_target, RID p_texture);
+ void debug_draw(const CameraMatrix &p_projection, const Transform3D &p_transform, int p_width, int p_height, RID p_render_target, RID p_texture);
void debug_probes(RD::DrawListID p_draw_list, RID p_framebuffer, const CameraMatrix &p_camera_with_transform);
- void pre_process_gi(const Transform &p_transform, RenderDataRD *p_render_data, RendererSceneRenderRD *p_scene_render);
+ void pre_process_gi(const Transform3D &p_transform, RenderDataRD *p_render_data, RendererSceneRenderRD *p_scene_render);
void render_region(RID p_render_buffers, int p_region, const PagedArray<RendererSceneRender::GeometryInstance *> &p_instances, RendererSceneRenderRD *p_scene_render);
void render_static_lights(RID p_render_buffers, uint32_t p_cascade_count, const uint32_t *p_cascade_indices, const PagedArray<RID> *p_positional_light_cull_result, RendererSceneRenderRD *p_scene_render);
};
@@ -551,13 +551,13 @@ public:
/* GI */
enum {
- MAX_GIPROBES = 8
+ MAX_VOXEL_GI_INSTANCES = 8
};
// Struct for use in render buffer
struct RenderBuffersGI {
- RID giprobe_textures[MAX_GIPROBES];
- RID giprobe_buffer;
+ RID voxel_gi_textures[MAX_VOXEL_GI_INSTANCES];
+ RID voxel_gi_buffer;
RID full_buffer;
RID full_dispatch;
@@ -601,7 +601,7 @@ public:
ProbeCascadeData cascades[SDFGI::MAX_CASCADES];
};
- struct GIProbeData {
+ struct VoxelGIData {
float xform[16];
float bounds[3];
float dynamic_range;
@@ -611,9 +611,9 @@ public:
uint32_t blend_ambient;
uint32_t texture_slot;
- float anisotropy_strength;
- float ao;
- float ao_size;
+ uint32_t pad0;
+ uint32_t pad1;
+ uint32_t pad2;
uint32_t mipmaps;
};
@@ -624,7 +624,7 @@ public:
float proj_info[4];
float ao_color[3];
- uint32_t max_giprobes;
+ uint32_t max_voxel_gi_instances;
uint32_t high_quality_vct;
uint32_t orthogonal;
@@ -635,16 +635,16 @@ public:
RID sdfgi_ubo;
enum Mode {
- MODE_GIPROBE,
+ MODE_VOXEL_GI,
MODE_SDFGI,
MODE_COMBINED,
- MODE_HALF_RES_GIPROBE,
+ MODE_HALF_RES_VOXEL_GI,
MODE_HALF_RES_SDFGI,
MODE_HALF_RES_COMBINED,
MODE_MAX
};
- RID default_giprobe_buffer;
+ RID default_voxel_gi_buffer;
bool half_resolution = false;
GiShaderRD shader;
@@ -659,14 +659,14 @@ public:
SDFGI *create_sdfgi(RendererSceneEnvironmentRD *p_env, const Vector3 &p_world_position, uint32_t p_requested_history_size);
- void setup_giprobes(RID p_render_buffers, const Transform &p_transform, const PagedArray<RID> &p_gi_probes, uint32_t &r_gi_probes_used, RendererSceneRenderRD *p_scene_render);
- void process_gi(RID p_render_buffers, RID p_normal_roughness_buffer, RID p_gi_probe_buffer, RID p_environment, const CameraMatrix &p_projection, const Transform &p_transform, const PagedArray<RID> &p_gi_probes, RendererSceneRenderRD *p_scene_render);
+ void setup_voxel_gi_instances(RID p_render_buffers, const Transform3D &p_transform, const PagedArray<RID> &p_voxel_gi_instances, uint32_t &r_voxel_gi_instances_used, RendererSceneRenderRD *p_scene_render);
+ void process_gi(RID p_render_buffers, RID p_normal_roughness_buffer, RID p_voxel_gi_buffer, RID p_environment, const CameraMatrix &p_projection, const Transform3D &p_transform, const PagedArray<RID> &p_voxel_gi_instances, RendererSceneRenderRD *p_scene_render);
- RID gi_probe_instance_create(RID p_base);
- void gi_probe_instance_set_transform_to_data(RID p_probe, const Transform &p_xform);
- bool gi_probe_needs_update(RID p_probe) const;
- void gi_probe_update(RID p_probe, bool p_update_light_instances, const Vector<RID> &p_light_instances, const PagedArray<RendererSceneRender::GeometryInstance *> &p_dynamic_objects, RendererSceneRenderRD *p_scene_render);
- void debug_giprobe(RID p_gi_probe, RD::DrawListID p_draw_list, RID p_framebuffer, const CameraMatrix &p_camera_with_transform, bool p_lighting, bool p_emission, float p_alpha);
+ RID voxel_gi_instance_create(RID p_base);
+ void voxel_gi_instance_set_transform_to_data(RID p_probe, const Transform3D &p_xform);
+ bool voxel_gi_needs_update(RID p_probe) const;
+ void voxel_gi_update(RID p_probe, bool p_update_light_instances, const Vector<RID> &p_light_instances, const PagedArray<RendererSceneRender::GeometryInstance *> &p_dynamic_objects, RendererSceneRenderRD *p_scene_render);
+ void debug_voxel_gi(RID p_voxel_gi, RD::DrawListID p_draw_list, RID p_framebuffer, const CameraMatrix &p_camera_with_transform, bool p_lighting, bool p_emission, float p_alpha);
};
#endif /* !RENDERING_SERVER_SCENE_GI_RD_H */
diff --git a/servers/rendering/renderer_rd/renderer_scene_render_rd.cpp b/servers/rendering/renderer_rd/renderer_scene_render_rd.cpp
index 1f01de1333..a70514e9e5 100644
--- a/servers/rendering/renderer_rd/renderer_scene_render_rd.cpp
+++ b/servers/rendering/renderer_rd/renderer_scene_render_rd.cpp
@@ -486,7 +486,7 @@ Ref<Image> RendererSceneRenderRD::environment_bake_panorama(RID p_env, bool p_ba
color.b *= env->bg_energy;
Ref<Image> ret;
- ret.instance();
+ ret.instantiate();
ret->create(p_size.width, p_size.height, false, Image::FORMAT_RGBAF);
for (int i = 0; i < p_size.width; i++) {
for (int j = 0; j < p_size.height; j++) {
@@ -570,7 +570,7 @@ RID RendererSceneRenderRD::reflection_probe_instance_create(RID p_probe) {
return reflection_probe_instance_owner.make_rid(rpi);
}
-void RendererSceneRenderRD::reflection_probe_instance_set_transform(RID p_instance, const Transform &p_transform) {
+void RendererSceneRenderRD::reflection_probe_instance_set_transform(RID p_instance, const Transform3D &p_transform) {
ReflectionProbeInstance *rpi = reflection_probe_instance_owner.getornull(p_instance);
ERR_FAIL_COND(!rpi);
@@ -709,6 +709,10 @@ bool RendererSceneRenderRD::reflection_probe_instance_begin_render(RID p_instanc
}
}
+ if (rpi->atlas_index != -1) { // should we fail if this is still -1 ?
+ atlas->reflections.write[rpi->atlas_index].owner = p_instance;
+ }
+
rpi->atlas = p_reflection_atlas;
rpi->rendering = true;
rpi->dirty = false;
@@ -1233,7 +1237,7 @@ RID RendererSceneRenderRD::light_instance_create(RID p_light) {
return li;
}
-void RendererSceneRenderRD::light_instance_set_transform(RID p_light_instance, const Transform &p_transform) {
+void RendererSceneRenderRD::light_instance_set_transform(RID p_light_instance, const Transform3D &p_transform) {
LightInstance *light_instance = light_instance_owner.getornull(p_light_instance);
ERR_FAIL_COND(!light_instance);
@@ -1247,7 +1251,7 @@ void RendererSceneRenderRD::light_instance_set_aabb(RID p_light_instance, const
light_instance->aabb = p_aabb;
}
-void RendererSceneRenderRD::light_instance_set_shadow_transform(RID p_light_instance, const CameraMatrix &p_projection, const Transform &p_transform, float p_far, float p_split, int p_pass, float p_shadow_texel_size, float p_bias_scale, float p_range_begin, const Vector2 &p_uv_scale) {
+void RendererSceneRenderRD::light_instance_set_shadow_transform(RID p_light_instance, const CameraMatrix &p_projection, const Transform3D &p_transform, float p_far, float p_split, int p_pass, float p_shadow_texel_size, float p_bias_scale, float p_range_begin, const Vector2 &p_uv_scale) {
LightInstance *light_instance = light_instance_owner.getornull(p_light_instance);
ERR_FAIL_COND(!light_instance);
@@ -1305,7 +1309,7 @@ RID RendererSceneRenderRD::decal_instance_create(RID p_decal) {
return decal_instance_owner.make_rid(di);
}
-void RendererSceneRenderRD::decal_instance_set_transform(RID p_decal, const Transform &p_transform) {
+void RendererSceneRenderRD::decal_instance_set_transform(RID p_decal, const Transform3D &p_transform) {
DecalInstance *di = decal_instance_owner.getornull(p_decal);
ERR_FAIL_COND(!di);
di->transform = p_transform;
@@ -1318,7 +1322,7 @@ RID RendererSceneRenderRD::lightmap_instance_create(RID p_lightmap) {
li.lightmap = p_lightmap;
return lightmap_instance_owner.make_rid(li);
}
-void RendererSceneRenderRD::lightmap_instance_set_transform(RID p_lightmap, const Transform &p_transform) {
+void RendererSceneRenderRD::lightmap_instance_set_transform(RID p_lightmap, const Transform3D &p_transform) {
LightmapInstance *li = lightmap_instance_owner.getornull(p_lightmap);
ERR_FAIL_COND(!li);
li->transform = p_transform;
@@ -1326,28 +1330,28 @@ void RendererSceneRenderRD::lightmap_instance_set_transform(RID p_lightmap, cons
/////////////////////////////////
-RID RendererSceneRenderRD::gi_probe_instance_create(RID p_base) {
- return gi.gi_probe_instance_create(p_base);
+RID RendererSceneRenderRD::voxel_gi_instance_create(RID p_base) {
+ return gi.voxel_gi_instance_create(p_base);
}
-void RendererSceneRenderRD::gi_probe_instance_set_transform_to_data(RID p_probe, const Transform &p_xform) {
- gi.gi_probe_instance_set_transform_to_data(p_probe, p_xform);
+void RendererSceneRenderRD::voxel_gi_instance_set_transform_to_data(RID p_probe, const Transform3D &p_xform) {
+ gi.voxel_gi_instance_set_transform_to_data(p_probe, p_xform);
}
-bool RendererSceneRenderRD::gi_probe_needs_update(RID p_probe) const {
+bool RendererSceneRenderRD::voxel_gi_needs_update(RID p_probe) const {
if (!is_dynamic_gi_supported()) {
return false;
}
- return gi.gi_probe_needs_update(p_probe);
+ return gi.voxel_gi_needs_update(p_probe);
}
-void RendererSceneRenderRD::gi_probe_update(RID p_probe, bool p_update_light_instances, const Vector<RID> &p_light_instances, const PagedArray<GeometryInstance *> &p_dynamic_objects) {
+void RendererSceneRenderRD::voxel_gi_update(RID p_probe, bool p_update_light_instances, const Vector<RID> &p_light_instances, const PagedArray<GeometryInstance *> &p_dynamic_objects) {
if (!is_dynamic_gi_supported()) {
return;
}
- gi.gi_probe_update(p_probe, p_update_light_instances, p_light_instances, p_dynamic_objects, this);
+ gi.voxel_gi_update(p_probe, p_update_light_instances, p_light_instances, p_dynamic_objects, this);
}
void RendererSceneRenderRD::_debug_sdfgi_probes(RID p_render_buffers, RD::DrawListID p_draw_list, RID p_framebuffer, const CameraMatrix &p_camera_with_transform) {
@@ -1728,7 +1732,7 @@ void RendererSceneRenderRD::_process_ssao(RID p_render_buffers, RID p_environmen
settings.half_screen_size = Size2i(buffer_width, buffer_height);
settings.quarter_screen_size = Size2i(half_width, half_height);
- storage->get_effects()->generate_ssao(rb->depth_texture, p_normal_buffer, rb->ssao.depth, rb->ssao.depth_slices, rb->ssao.ao_deinterleaved, rb->ssao.ao_deinterleaved_slices, rb->ssao.ao_pong, rb->ssao.ao_pong_slices, rb->ssao.ao_final, rb->ssao.importance_map[0], rb->ssao.importance_map[1], p_projection, settings, uniform_sets_are_invalid);
+ storage->get_effects()->generate_ssao(rb->depth_texture, p_normal_buffer, rb->ssao.depth, rb->ssao.depth_slices, rb->ssao.ao_deinterleaved, rb->ssao.ao_deinterleaved_slices, rb->ssao.ao_pong, rb->ssao.ao_pong_slices, rb->ssao.ao_final, rb->ssao.importance_map[0], rb->ssao.importance_map[1], p_projection, settings, uniform_sets_are_invalid, rb->ssao.downsample_uniform_set, rb->ssao.gather_uniform_set, rb->ssao.importance_map_uniform_set);
}
void RendererSceneRenderRD::_render_buffers_post_process_and_tonemap(const RenderDataRD *p_render_data) {
@@ -1857,6 +1861,8 @@ void RendererSceneRenderRD::_render_buffers_post_process_and_tonemap(const Rende
}
}
+ tonemap.view_count = p_render_data->view_count;
+
storage->get_effects()->tonemapper(rb->texture, storage->render_target_get_rd_framebuffer(rb->render_target), tonemap);
}
@@ -1959,17 +1965,17 @@ RID RendererSceneRenderRD::render_buffers_get_ao_texture(RID p_render_buffers) {
return rb->ssao.ao_final;
}
-RID RendererSceneRenderRD::render_buffers_get_gi_probe_buffer(RID p_render_buffers) {
+RID RendererSceneRenderRD::render_buffers_get_voxel_gi_buffer(RID p_render_buffers) {
RenderBuffers *rb = render_buffers_owner.getornull(p_render_buffers);
ERR_FAIL_COND_V(!rb, RID());
- if (rb->gi.giprobe_buffer.is_null()) {
- rb->gi.giprobe_buffer = RD::get_singleton()->uniform_buffer_create(sizeof(RendererSceneGIRD::GIProbeData) * RendererSceneGIRD::MAX_GIPROBES);
+ if (rb->gi.voxel_gi_buffer.is_null()) {
+ rb->gi.voxel_gi_buffer = RD::get_singleton()->uniform_buffer_create(sizeof(RendererSceneGIRD::VoxelGIData) * RendererSceneGIRD::MAX_VOXEL_GI_INSTANCES);
}
- return rb->gi.giprobe_buffer;
+ return rb->gi.voxel_gi_buffer;
}
-RID RendererSceneRenderRD::render_buffers_get_default_gi_probe_buffer() {
- return gi.default_giprobe_buffer;
+RID RendererSceneRenderRD::render_buffers_get_default_voxel_gi_buffer() {
+ return gi.default_voxel_gi_buffer;
}
RID RendererSceneRenderRD::render_buffers_get_gi_ambient_texture(RID p_render_buffers) {
@@ -2112,7 +2118,9 @@ float RendererSceneRenderRD::render_buffers_get_volumetric_fog_detail_spread(RID
return rb->volumetric_fog->spread;
}
-void RendererSceneRenderRD::render_buffers_configure(RID p_render_buffers, RID p_render_target, int p_width, int p_height, RS::ViewportMSAA p_msaa, RenderingServer::ViewportScreenSpaceAA p_screen_space_aa, bool p_use_debanding) {
+void RendererSceneRenderRD::render_buffers_configure(RID p_render_buffers, RID p_render_target, int p_width, int p_height, RS::ViewportMSAA p_msaa, RenderingServer::ViewportScreenSpaceAA p_screen_space_aa, bool p_use_debanding, uint32_t p_view_count) {
+ ERR_FAIL_COND_MSG(p_view_count == 0, "Must have atleast 1 view");
+
RenderBuffers *rb = render_buffers_owner.getornull(p_render_buffers);
rb->width = p_width;
rb->height = p_height;
@@ -2120,6 +2128,7 @@ void RendererSceneRenderRD::render_buffers_configure(RID p_render_buffers, RID p
rb->msaa = p_msaa;
rb->screen_space_aa = p_screen_space_aa;
rb->use_debanding = p_use_debanding;
+ rb->view_count = p_view_count;
if (is_clustered_enabled()) {
if (rb->cluster_builder == nullptr) {
@@ -2132,9 +2141,13 @@ void RendererSceneRenderRD::render_buffers_configure(RID p_render_buffers, RID p
{
RD::TextureFormat tf;
+ if (rb->view_count > 1) {
+ tf.texture_type = RD::TEXTURE_TYPE_2D_ARRAY;
+ }
tf.format = RD::DATA_FORMAT_R16G16B16A16_SFLOAT;
tf.width = rb->width;
tf.height = rb->height;
+ tf.array_layers = rb->view_count; // create a layer for every view
tf.usage_bits = RD::TEXTURE_USAGE_SAMPLING_BIT | RD::TEXTURE_USAGE_STORAGE_BIT;
if (rb->msaa != RS::VIEWPORT_MSAA_DISABLED) {
tf.usage_bits |= RD::TEXTURE_USAGE_CAN_COPY_TO_BIT | RD::TEXTURE_USAGE_STORAGE_BIT;
@@ -2147,6 +2160,9 @@ void RendererSceneRenderRD::render_buffers_configure(RID p_render_buffers, RID p
{
RD::TextureFormat tf;
+ if (rb->view_count > 1) {
+ tf.texture_type = RD::TEXTURE_TYPE_2D_ARRAY;
+ }
if (rb->msaa == RS::VIEWPORT_MSAA_DISABLED) {
tf.format = RD::get_singleton()->texture_is_format_supported_for_usage(RD::DATA_FORMAT_D24_UNORM_S8_UINT, RD::TEXTURE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT) ? RD::DATA_FORMAT_D24_UNORM_S8_UINT : RD::DATA_FORMAT_D32_SFLOAT_S8_UINT;
} else {
@@ -2156,6 +2172,7 @@ void RendererSceneRenderRD::render_buffers_configure(RID p_render_buffers, RID p
tf.width = p_width;
tf.height = p_height;
tf.usage_bits = RD::TEXTURE_USAGE_SAMPLING_BIT;
+ tf.array_layers = rb->view_count; // create a layer for every view
if (rb->msaa != RS::VIEWPORT_MSAA_DISABLED) {
tf.usage_bits |= RD::TEXTURE_USAGE_CAN_COPY_TO_BIT | RD::TEXTURE_USAGE_STORAGE_BIT;
@@ -2166,7 +2183,7 @@ void RendererSceneRenderRD::render_buffers_configure(RID p_render_buffers, RID p
rb->depth_texture = RD::get_singleton()->texture_create(tf, RD::TextureView());
}
- rb->data->configure(rb->texture, rb->depth_texture, p_width, p_height, p_msaa);
+ rb->data->configure(rb->texture, rb->depth_texture, p_width, p_height, p_msaa, p_view_count);
if (is_clustered_enabled()) {
rb->cluster_builder->setup(Size2i(p_width, p_height), max_cluster_elements, rb->depth_texture, storage->sampler_rd_get_default(RS::CANVAS_ITEM_TEXTURE_FILTER_NEAREST, RS::CANVAS_ITEM_TEXTURE_REPEAT_DISABLED), rb->texture);
@@ -2284,7 +2301,7 @@ RendererSceneRenderRD::RenderBufferData *RendererSceneRenderRD::render_buffers_g
return rb->data;
}
-void RendererSceneRenderRD::_setup_reflections(const PagedArray<RID> &p_reflections, const Transform &p_camera_inverse_transform, RID p_environment) {
+void RendererSceneRenderRD::_setup_reflections(const PagedArray<RID> &p_reflections, const Transform3D &p_camera_inverse_transform, RID p_environment) {
cluster.reflection_count = 0;
for (uint32_t i = 0; i < (uint32_t)p_reflections.size(); i++) {
@@ -2344,8 +2361,8 @@ void RendererSceneRenderRD::_setup_reflections(const PagedArray<RID> &p_reflecti
reflection_ubo.ambient[1] = ambient_linear.g * interior_ambient_energy;
reflection_ubo.ambient[2] = ambient_linear.b * interior_ambient_energy;
- Transform transform = rpi->transform;
- Transform proj = (p_camera_inverse_transform * transform).inverse();
+ Transform3D transform = rpi->transform;
+ Transform3D proj = (p_camera_inverse_transform * transform).inverse();
RendererStorageRD::store_transform(proj, reflection_ubo.local_matrix);
if (current_cluster_builder != nullptr) {
@@ -2360,8 +2377,8 @@ void RendererSceneRenderRD::_setup_reflections(const PagedArray<RID> &p_reflecti
}
}
-void RendererSceneRenderRD::_setup_lights(const PagedArray<RID> &p_lights, const Transform &p_camera_transform, RID p_shadow_atlas, bool p_using_shadows, uint32_t &r_directional_light_count, uint32_t &r_positional_light_count) {
- Transform inverse_transform = p_camera_transform.affine_inverse();
+void RendererSceneRenderRD::_setup_lights(const PagedArray<RID> &p_lights, const Transform3D &p_camera_transform, RID p_shadow_atlas, bool p_using_shadows, uint32_t &r_directional_light_count, uint32_t &r_positional_light_count) {
+ Transform3D inverse_transform = p_camera_transform.affine_inverse();
r_directional_light_count = 0;
r_positional_light_count = 0;
@@ -2387,7 +2404,7 @@ void RendererSceneRenderRD::_setup_lights(const PagedArray<RID> &p_lights, const
// Copy to SkyDirectionalLightData
if (r_directional_light_count < sky.sky_scene_state.max_directional_lights) {
RendererSceneSkyRD::SkyDirectionalLightData &sky_light_data = sky.sky_scene_state.directional_lights[r_directional_light_count];
- Transform light_transform = li->transform;
+ Transform3D light_transform = li->transform;
Vector3 world_direction = light_transform.basis.xform(Vector3(0, 0, 1)).normalized();
sky_light_data.direction[0] = world_direction.x;
@@ -2423,7 +2440,7 @@ void RendererSceneRenderRD::_setup_lights(const PagedArray<RID> &p_lights, const
Cluster::DirectionalLightData &light_data = cluster.directional_lights[r_directional_light_count];
- Transform light_transform = li->transform;
+ Transform3D light_transform = li->transform;
Vector3 direction = inverse_transform.basis.xform(light_transform.basis.xform(Vector3(0, 0, 1))).normalized();
@@ -2513,7 +2530,7 @@ void RendererSceneRenderRD::_setup_lights(const PagedArray<RID> &p_lights, const
CameraMatrix rectm;
rectm.set_light_atlas_rect(atlas_rect);
- Transform modelview = (inverse_transform * li->shadow_transform[j].transform).inverse();
+ Transform3D modelview = (inverse_transform * li->shadow_transform[j].transform).inverse();
CameraMatrix shadow_mtx = rectm * bias * matrix * modelview;
light_data.shadow_split_offsets[j] = split;
@@ -2609,7 +2626,7 @@ void RendererSceneRenderRD::_setup_lights(const PagedArray<RID> &p_lights, const
LightInstance *li = (i < cluster.omni_light_count) ? cluster.omni_light_sort[index].instance : cluster.spot_light_sort[index].instance;
RID base = li->light;
- Transform light_transform = li->transform;
+ Transform3D light_transform = li->transform;
float sign = storage->light_is_negative(base) ? -1 : 1;
Color linear_col = storage->light_get_color(base).to_linear();
@@ -2709,7 +2726,7 @@ void RendererSceneRenderRD::_setup_lights(const PagedArray<RID> &p_lights, const
if (type == RS::LIGHT_OMNI) {
light_data.atlas_rect[3] *= 0.5; //one paraboloid on top of another
- Transform proj = (inverse_transform * light_transform).inverse();
+ Transform3D proj = (inverse_transform * light_transform).inverse();
RendererStorageRD::store_transform(proj, light_data.shadow_matrix);
@@ -2721,7 +2738,7 @@ void RendererSceneRenderRD::_setup_lights(const PagedArray<RID> &p_lights, const
}
} else if (type == RS::LIGHT_SPOT) {
- Transform modelview = (inverse_transform * light_transform).inverse();
+ Transform3D modelview = (inverse_transform * light_transform).inverse();
CameraMatrix bias;
bias.set_light_bias();
@@ -2765,8 +2782,8 @@ void RendererSceneRenderRD::_setup_lights(const PagedArray<RID> &p_lights, const
}
}
-void RendererSceneRenderRD::_setup_decals(const PagedArray<RID> &p_decals, const Transform &p_camera_inverse_xform) {
- Transform uv_xform;
+void RendererSceneRenderRD::_setup_decals(const PagedArray<RID> &p_decals, const Transform3D &p_camera_inverse_xform) {
+ Transform3D uv_xform;
uv_xform.basis.scale(Vector3(2.0, 1.0, 2.0));
uv_xform.origin = Vector3(-1.0, 0.0, -1.0);
@@ -2785,7 +2802,7 @@ void RendererSceneRenderRD::_setup_decals(const PagedArray<RID> &p_decals, const
}
RID decal = di->decal;
- Transform xform = di->transform;
+ Transform3D xform = di->transform;
real_t distance = -p_camera_inverse_xform.xform(xform.origin).z;
@@ -2817,7 +2834,7 @@ void RendererSceneRenderRD::_setup_decals(const PagedArray<RID> &p_decals, const
di->render_index = i;
di->cull_mask = storage->decal_get_cull_mask(decal);
- Transform xform = di->transform;
+ Transform3D xform = di->transform;
float fade = 1.0;
if (storage->decal_is_distance_fade_enabled(decal)) {
@@ -2834,9 +2851,9 @@ void RendererSceneRenderRD::_setup_decals(const PagedArray<RID> &p_decals, const
Vector3 decal_extents = storage->decal_get_extents(decal);
- Transform scale_xform;
+ Transform3D scale_xform;
scale_xform.basis.scale(Vector3(decal_extents.x, decal_extents.y, decal_extents.z));
- Transform to_decal_xform = (p_camera_inverse_xform * di->transform * scale_xform * uv_xform).affine_inverse();
+ Transform3D to_decal_xform = (p_camera_inverse_xform * di->transform * scale_xform * uv_xform).affine_inverse();
RendererStorageRD::store_transform(to_decal_xform, dd.xform);
Vector3 normal = xform.basis.get_axis(Vector3::AXIS_Y).normalized();
@@ -3066,7 +3083,7 @@ void RendererSceneRenderRD::_volumetric_fog_erase(RenderBuffers *rb) {
rb->volumetric_fog = nullptr;
}
-void RendererSceneRenderRD::_update_volumetric_fog(RID p_render_buffers, RID p_environment, const CameraMatrix &p_cam_projection, const Transform &p_cam_transform, RID p_shadow_atlas, int p_directional_light_count, bool p_use_directional_shadows, int p_positional_light_count, int p_gi_probe_count) {
+void RendererSceneRenderRD::_update_volumetric_fog(RID p_render_buffers, RID p_environment, const CameraMatrix &p_cam_projection, const Transform3D &p_cam_transform, RID p_shadow_atlas, int p_directional_light_count, bool p_use_directional_shadows, int p_positional_light_count, int p_voxel_gi_count) {
ERR_FAIL_COND(!is_clustered_enabled()); // can't use volumetric fog without clustered
RenderBuffers *rb = render_buffers_owner.getornull(p_render_buffers);
ERR_FAIL_COND(!rb);
@@ -3228,7 +3245,7 @@ void RendererSceneRenderRD::_update_volumetric_fog(RID p_render_buffers, RID p_e
RD::Uniform u;
u.uniform_type = RD::UNIFORM_TYPE_UNIFORM_BUFFER;
u.binding = 11;
- u.ids.push_back(render_buffers_get_gi_probe_buffer(p_render_buffers));
+ u.ids.push_back(render_buffers_get_voxel_gi_buffer(p_render_buffers));
uniforms.push_back(u);
}
@@ -3236,8 +3253,8 @@ void RendererSceneRenderRD::_update_volumetric_fog(RID p_render_buffers, RID p_e
RD::Uniform u;
u.uniform_type = RD::UNIFORM_TYPE_TEXTURE;
u.binding = 12;
- for (int i = 0; i < RendererSceneGIRD::MAX_GIPROBES; i++) {
- u.ids.push_back(rb->gi.giprobe_textures[i]);
+ for (int i = 0; i < RendererSceneGIRD::MAX_VOXEL_GI_INSTANCES; i++) {
+ u.ids.push_back(rb->gi.voxel_gi_textures[i]);
}
uniforms.push_back(u);
}
@@ -3362,10 +3379,10 @@ void RendererSceneRenderRD::_update_volumetric_fog(RID p_render_buffers, RID p_e
params.cam_rotation[10] = p_cam_transform.basis[2][2];
params.cam_rotation[11] = 0;
params.filter_axis = 0;
- params.max_gi_probes = env->volumetric_fog_gi_inject > 0.001 ? p_gi_probe_count : 0;
+ params.max_voxel_gi_instances = env->volumetric_fog_gi_inject > 0.001 ? p_voxel_gi_count : 0;
params.temporal_frame = RSG::rasterizer->get_frame_number() % VolumetricFog::MAX_TEMPORAL_FRAMES;
- Transform to_prev_cam_view = rb->volumetric_fog->prev_cam_transform.affine_inverse() * p_cam_transform;
+ Transform3D to_prev_cam_view = rb->volumetric_fog->prev_cam_transform.affine_inverse() * p_cam_transform;
storage->store_transform(to_prev_cam_view, params.to_prev_view);
params.use_temporal_reprojection = env->volumetric_fog_temporal_reprojection;
@@ -3492,17 +3509,15 @@ void RendererSceneRenderRD::_pre_resolve_render(RenderDataRD *p_render_data, boo
}
}
-void RendererSceneRenderRD::_pre_opaque_render(RenderDataRD *p_render_data, bool p_use_ssao, bool p_use_gi, RID p_normal_roughness_buffer, RID p_gi_probe_buffer) {
+void RendererSceneRenderRD::_pre_opaque_render(RenderDataRD *p_render_data, bool p_use_ssao, bool p_use_gi, RID p_normal_roughness_buffer, RID p_voxel_gi_buffer) {
// Render shadows while GI is rendering, due to how barriers are handled, this should happen at the same time
if (p_render_data->render_buffers.is_valid() && p_use_gi) {
RenderBuffers *rb = render_buffers_owner.getornull(p_render_data->render_buffers);
ERR_FAIL_COND(rb == nullptr);
- if (rb->sdfgi == nullptr) {
- return;
+ if (rb->sdfgi != nullptr) {
+ rb->sdfgi->store_probes();
}
-
- rb->sdfgi->store_probes();
}
render_state.cube_shadows.clear();
@@ -3511,7 +3526,6 @@ void RendererSceneRenderRD::_pre_opaque_render(RenderDataRD *p_render_data, bool
Plane camera_plane(p_render_data->cam_transform.origin, -p_render_data->cam_transform.basis.get_axis(Vector3::AXIS_Z));
float lod_distance_multiplier = p_render_data->cam_projection.get_lod_multiplier();
-
{
for (int i = 0; i < render_state.render_shadow_count; i++) {
LightInstance *li = light_instance_owner.getornull(render_state.render_shadows[i].light);
@@ -3527,7 +3541,7 @@ void RendererSceneRenderRD::_pre_opaque_render(RenderDataRD *p_render_data, bool
//cube shadows are rendered in their own way
for (uint32_t i = 0; i < render_state.cube_shadows.size(); i++) {
- _render_shadow_pass(render_state.render_shadows[render_state.cube_shadows[i]].light, p_render_data->shadow_atlas, render_state.render_shadows[render_state.cube_shadows[i]].pass, render_state.render_shadows[render_state.cube_shadows[i]].instances, camera_plane, lod_distance_multiplier, p_render_data->screen_lod_threshold, true, true, true);
+ _render_shadow_pass(render_state.render_shadows[render_state.cube_shadows[i]].light, p_render_data->shadow_atlas, render_state.render_shadows[render_state.cube_shadows[i]].pass, render_state.render_shadows[render_state.cube_shadows[i]].instances, camera_plane, lod_distance_multiplier, p_render_data->screen_lod_threshold, true, true, true, p_render_data->render_info);
}
if (render_state.directional_shadows.size()) {
@@ -3557,11 +3571,11 @@ void RendererSceneRenderRD::_pre_opaque_render(RenderDataRD *p_render_data, bool
//render directional shadows
for (uint32_t i = 0; i < render_state.directional_shadows.size(); i++) {
- _render_shadow_pass(render_state.render_shadows[render_state.directional_shadows[i]].light, p_render_data->shadow_atlas, render_state.render_shadows[render_state.directional_shadows[i]].pass, render_state.render_shadows[render_state.directional_shadows[i]].instances, camera_plane, lod_distance_multiplier, p_render_data->screen_lod_threshold, false, i == render_state.directional_shadows.size() - 1, false);
+ _render_shadow_pass(render_state.render_shadows[render_state.directional_shadows[i]].light, p_render_data->shadow_atlas, render_state.render_shadows[render_state.directional_shadows[i]].pass, render_state.render_shadows[render_state.directional_shadows[i]].instances, camera_plane, lod_distance_multiplier, p_render_data->screen_lod_threshold, false, i == render_state.directional_shadows.size() - 1, false, p_render_data->render_info);
}
//render positional shadows
for (uint32_t i = 0; i < render_state.shadows.size(); i++) {
- _render_shadow_pass(render_state.render_shadows[render_state.shadows[i]].light, p_render_data->shadow_atlas, render_state.render_shadows[render_state.shadows[i]].pass, render_state.render_shadows[render_state.shadows[i]].instances, camera_plane, lod_distance_multiplier, p_render_data->screen_lod_threshold, i == 0, i == render_state.shadows.size() - 1, true);
+ _render_shadow_pass(render_state.render_shadows[render_state.shadows[i]].light, p_render_data->shadow_atlas, render_state.render_shadows[render_state.shadows[i]].pass, render_state.render_shadows[render_state.shadows[i]].instances, camera_plane, lod_distance_multiplier, p_render_data->screen_lod_threshold, i == 0, i == render_state.shadows.size() - 1, true, p_render_data->render_info);
}
_render_shadow_process();
@@ -3569,7 +3583,7 @@ void RendererSceneRenderRD::_pre_opaque_render(RenderDataRD *p_render_data, bool
//start GI
if (render_gi) {
- gi.process_gi(p_render_data->render_buffers, p_normal_roughness_buffer, p_gi_probe_buffer, p_render_data->environment, p_render_data->cam_projection, p_render_data->cam_transform, *p_render_data->gi_probes, this);
+ gi.process_gi(p_render_data->render_buffers, p_normal_roughness_buffer, p_voxel_gi_buffer, p_render_data->environment, p_render_data->cam_projection, p_render_data->cam_transform, *p_render_data->voxel_gi_instances, this);
}
//Do shadow rendering (in parallel with GI)
@@ -3625,12 +3639,12 @@ void RendererSceneRenderRD::_pre_opaque_render(RenderDataRD *p_render_data, bool
}
}
if (is_volumetric_supported()) {
- _update_volumetric_fog(p_render_data->render_buffers, p_render_data->environment, p_render_data->cam_projection, p_render_data->cam_transform, p_render_data->shadow_atlas, directional_light_count, directional_shadows, positional_light_count, render_state.gi_probe_count);
+ _update_volumetric_fog(p_render_data->render_buffers, p_render_data->environment, p_render_data->cam_projection, p_render_data->cam_transform, p_render_data->shadow_atlas, directional_light_count, directional_shadows, positional_light_count, render_state.voxel_gi_count);
}
}
}
-void RendererSceneRenderRD::render_scene(RID p_render_buffers, const Transform &p_cam_transform, const CameraMatrix &p_cam_projection, bool p_cam_ortogonal, const PagedArray<GeometryInstance *> &p_instances, const PagedArray<RID> &p_lights, const PagedArray<RID> &p_reflection_probes, const PagedArray<RID> &p_gi_probes, const PagedArray<RID> &p_decals, const PagedArray<RID> &p_lightmaps, RID p_environment, RID p_camera_effects, 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_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) {
+void RendererSceneRenderRD::render_scene(RID p_render_buffers, const CameraData *p_camera_data, const PagedArray<GeometryInstance *> &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, RID p_environment, RID p_camera_effects, 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_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, RendererScene::RenderInfo *r_render_info) {
// getting this here now so we can direct call a bunch of things more easily
RenderBuffers *rb = nullptr;
if (p_render_buffers.is_valid()) {
@@ -3643,16 +3657,24 @@ void RendererSceneRenderRD::render_scene(RID p_render_buffers, const Transform &
{
render_data.render_buffers = p_render_buffers;
- render_data.cam_transform = p_cam_transform;
- render_data.cam_projection = p_cam_projection;
- render_data.cam_ortogonal = p_cam_projection.is_orthogonal(); // !BAS! Shouldn't this be p_cam_ortogonal ?
- render_data.z_near = p_cam_projection.get_z_near();
- render_data.z_far = p_cam_projection.get_z_far();
+ // Our first camera is used by default
+ render_data.cam_transform = p_camera_data->main_transform;
+ render_data.cam_projection = p_camera_data->main_projection;
+ render_data.view_projection[0] = p_camera_data->main_projection;
+ render_data.cam_ortogonal = p_camera_data->is_ortogonal;
+
+ render_data.view_count = p_camera_data->view_count;
+ for (uint32_t v = 0; v < p_camera_data->view_count; v++) {
+ render_data.view_projection[v] = p_camera_data->view_projection[v];
+ }
+
+ render_data.z_near = p_camera_data->main_projection.get_z_near();
+ render_data.z_far = p_camera_data->main_projection.get_z_far();
render_data.instances = &p_instances;
render_data.lights = &p_lights;
render_data.reflection_probes = &p_reflection_probes;
- render_data.gi_probes = &p_gi_probes;
+ render_data.voxel_gi_instances = &p_voxel_gi_instances;
render_data.decals = &p_decals;
render_data.lightmaps = &p_lightmaps;
render_data.environment = p_environment;
@@ -3662,8 +3684,9 @@ void RendererSceneRenderRD::render_scene(RID p_render_buffers, const Transform &
render_data.reflection_probe = p_reflection_probe;
render_data.reflection_probe_pass = p_reflection_probe_pass;
- render_data.lod_distance_multiplier = p_cam_projection.get_lod_multiplier();
- render_data.lod_camera_plane = Plane(p_cam_transform.get_origin(), -p_cam_transform.basis.get_axis(Vector3::AXIS_Z));
+ // this should be the same for all cameras..
+ render_data.lod_distance_multiplier = p_camera_data->main_projection.get_lod_multiplier();
+ render_data.lod_camera_plane = Plane(p_camera_data->main_transform.get_origin(), -p_camera_data->main_transform.basis.get_axis(Vector3::AXIS_Z));
if (get_debug_draw_mode() == RS::VIEWPORT_DEBUG_DRAW_DISABLE_LOD) {
render_data.screen_lod_threshold = 0.0;
@@ -3676,6 +3699,7 @@ void RendererSceneRenderRD::render_scene(RID p_render_buffers, const Transform &
render_state.render_sdfgi_regions = p_render_sdfgi_regions;
render_state.render_sdfgi_region_count = p_render_sdfgi_region_count;
render_state.sdfgi_update_data = p_sdfgi_update_data;
+ render_data.render_info = r_render_info;
}
PagedArray<RID> empty;
@@ -3683,7 +3707,7 @@ void RendererSceneRenderRD::render_scene(RID p_render_buffers, const Transform &
if (get_debug_draw_mode() == RS::VIEWPORT_DEBUG_DRAW_UNSHADED) {
render_data.lights = &empty;
render_data.reflection_probes = &empty;
- render_data.gi_probes = &empty;
+ render_data.voxel_gi_instances = &empty;
}
//sdfgi first
@@ -3703,12 +3727,12 @@ void RendererSceneRenderRD::render_scene(RID p_render_buffers, const Transform &
clear_color = storage->get_default_clear_color();
}
- //assign render indices to giprobes
+ //assign render indices to voxel_gi_instances
if (is_dynamic_gi_supported()) {
- for (uint32_t i = 0; i < (uint32_t)p_gi_probes.size(); i++) {
- RendererSceneGIRD::GIProbeInstance *giprobe_inst = gi.gi_probe_instance_owner.getornull(p_gi_probes[i]);
- if (giprobe_inst) {
- giprobe_inst->render_index = i;
+ for (uint32_t i = 0; i < (uint32_t)p_voxel_gi_instances.size(); i++) {
+ RendererSceneGIRD::VoxelGIInstance *voxel_gi_inst = gi.voxel_gi_instance_owner.getornull(p_voxel_gi_instances[i]);
+ if (voxel_gi_inst) {
+ voxel_gi_inst->render_index = i;
}
}
}
@@ -3730,17 +3754,16 @@ void RendererSceneRenderRD::render_scene(RID p_render_buffers, const Transform &
current_cluster_builder = nullptr;
}
- if (rb != nullptr && rb->sdfgi != nullptr) {
- rb->sdfgi->update_cascades();
-
- rb->sdfgi->pre_process_gi(p_cam_transform, &render_data, this);
- }
+ render_state.voxel_gi_count = 0;
- render_state.gi_probe_count = 0;
- if (rb != nullptr && rb->sdfgi != nullptr) {
- gi.setup_giprobes(render_data.render_buffers, render_data.cam_transform, *render_data.gi_probes, render_state.gi_probe_count, this);
+ if (rb != nullptr) {
+ if (rb->sdfgi) {
+ rb->sdfgi->update_cascades();
+ rb->sdfgi->pre_process_gi(render_data.cam_transform, &render_data, this);
+ rb->sdfgi->update_light();
+ }
- rb->sdfgi->update_light();
+ gi.setup_voxel_gi_instances(render_data.render_buffers, render_data.cam_transform, *render_data.voxel_gi_instances, render_state.voxel_gi_count, this);
}
render_state.depth_prepass_used = false;
@@ -3782,12 +3805,12 @@ void RendererSceneRenderRD::render_scene(RID p_render_buffers, const Transform &
_render_buffers_post_process_and_tonemap(&render_data);
_render_buffers_debug_draw(p_render_buffers, p_shadow_atlas, p_occluder_debug_tex);
if (debug_draw == RS::VIEWPORT_DEBUG_DRAW_SDFGI && rb != nullptr && rb->sdfgi != nullptr) {
- rb->sdfgi->debug_draw(p_cam_projection, p_cam_transform, rb->width, rb->height, rb->render_target, rb->texture);
+ rb->sdfgi->debug_draw(render_data.cam_projection, render_data.cam_transform, rb->width, rb->height, rb->render_target, rb->texture);
}
}
}
-void RendererSceneRenderRD::_render_shadow_pass(RID p_light, RID p_shadow_atlas, int p_pass, const PagedArray<GeometryInstance *> &p_instances, const Plane &p_camera_plane, float p_lod_distance_multiplier, float p_screen_lod_threshold, bool p_open_pass, bool p_close_pass, bool p_clear_region) {
+void RendererSceneRenderRD::_render_shadow_pass(RID p_light, RID p_shadow_atlas, int p_pass, const PagedArray<GeometryInstance *> &p_instances, const Plane &p_camera_plane, float p_lod_distance_multiplier, float p_screen_lod_threshold, bool p_open_pass, bool p_close_pass, bool p_clear_region, RendererScene::RenderInfo *p_render_info) {
LightInstance *light_instance = light_instance_owner.getornull(p_light);
ERR_FAIL_COND(!light_instance);
@@ -3808,7 +3831,7 @@ void RendererSceneRenderRD::_render_shadow_pass(RID p_light, RID p_shadow_atlas,
bool flip_y = false;
CameraMatrix light_projection;
- Transform light_transform;
+ Transform3D light_transform;
if (storage->light_get_type(light_instance->light) == RS::LIGHT_DIRECTIONAL) {
//set pssm stuff
@@ -3933,7 +3956,7 @@ void RendererSceneRenderRD::_render_shadow_pass(RID p_light, RID p_shadow_atlas,
if (render_cubemap) {
//rendering to cubemap
- _render_shadow_append(render_fb, p_instances, light_projection, light_transform, zfar, 0, 0, false, false, use_pancake, p_camera_plane, p_lod_distance_multiplier, p_screen_lod_threshold, Rect2(), false, true, true, true);
+ _render_shadow_append(render_fb, p_instances, light_projection, light_transform, zfar, 0, 0, false, false, use_pancake, p_camera_plane, p_lod_distance_multiplier, p_screen_lod_threshold, Rect2(), false, true, true, true, p_render_info);
if (finalize_cubemap) {
_render_shadow_process();
_render_shadow_end();
@@ -3954,15 +3977,15 @@ void RendererSceneRenderRD::_render_shadow_pass(RID p_light, RID p_shadow_atlas,
} else {
//render shadow
- _render_shadow_append(render_fb, p_instances, light_projection, light_transform, zfar, 0, 0, using_dual_paraboloid, using_dual_paraboloid_flip, use_pancake, p_camera_plane, p_lod_distance_multiplier, p_screen_lod_threshold, atlas_rect, flip_y, p_clear_region, p_open_pass, p_close_pass);
+ _render_shadow_append(render_fb, p_instances, light_projection, light_transform, zfar, 0, 0, using_dual_paraboloid, using_dual_paraboloid_flip, use_pancake, p_camera_plane, p_lod_distance_multiplier, p_screen_lod_threshold, atlas_rect, flip_y, p_clear_region, p_open_pass, p_close_pass, p_render_info);
}
}
-void RendererSceneRenderRD::render_material(const Transform &p_cam_transform, const CameraMatrix &p_cam_projection, bool p_cam_ortogonal, const PagedArray<GeometryInstance *> &p_instances, RID p_framebuffer, const Rect2i &p_region) {
+void RendererSceneRenderRD::render_material(const Transform3D &p_cam_transform, const CameraMatrix &p_cam_projection, bool p_cam_ortogonal, const PagedArray<GeometryInstance *> &p_instances, RID p_framebuffer, const Rect2i &p_region) {
_render_material(p_cam_transform, p_cam_projection, p_cam_ortogonal, p_instances, p_framebuffer, p_region);
}
-void RendererSceneRenderRD::render_particle_collider_heightfield(RID p_collider, const Transform &p_transform, const PagedArray<GeometryInstance *> &p_instances) {
+void RendererSceneRenderRD::render_particle_collider_heightfield(RID p_collider, const Transform3D &p_transform, const PagedArray<GeometryInstance *> &p_instances) {
ERR_FAIL_COND(!storage->particles_collision_is_heightfield(p_collider));
Vector3 extents = storage->particles_collision_get_extents(p_collider) * p_transform.basis.get_scale();
CameraMatrix cm;
@@ -3971,7 +3994,7 @@ void RendererSceneRenderRD::render_particle_collider_heightfield(RID p_collider,
Vector3 cam_pos = p_transform.origin;
cam_pos.y += extents.y;
- Transform cam_xform;
+ Transform3D cam_xform;
cam_xform.set_look_at(cam_pos, cam_pos - p_transform.basis.get_axis(Vector3::AXIS_Y), -p_transform.basis.get_axis(Vector3::AXIS_Z).normalized());
RID fb = storage->particles_collision_get_heightfield_framebuffer(p_collider);
@@ -4018,19 +4041,19 @@ bool RendererSceneRenderRD::free(RID p_rid) {
decal_instance_owner.free(p_rid);
} else if (lightmap_instance_owner.owns(p_rid)) {
lightmap_instance_owner.free(p_rid);
- } else if (gi.gi_probe_instance_owner.owns(p_rid)) {
- RendererSceneGIRD::GIProbeInstance *gi_probe = gi.gi_probe_instance_owner.getornull(p_rid);
- if (gi_probe->texture.is_valid()) {
- RD::get_singleton()->free(gi_probe->texture);
- RD::get_singleton()->free(gi_probe->write_buffer);
+ } else if (gi.voxel_gi_instance_owner.owns(p_rid)) {
+ RendererSceneGIRD::VoxelGIInstance *voxel_gi = gi.voxel_gi_instance_owner.getornull(p_rid);
+ if (voxel_gi->texture.is_valid()) {
+ RD::get_singleton()->free(voxel_gi->texture);
+ RD::get_singleton()->free(voxel_gi->write_buffer);
}
- for (int i = 0; i < gi_probe->dynamic_maps.size(); i++) {
- RD::get_singleton()->free(gi_probe->dynamic_maps[i].texture);
- RD::get_singleton()->free(gi_probe->dynamic_maps[i].depth);
+ for (int i = 0; i < voxel_gi->dynamic_maps.size(); i++) {
+ RD::get_singleton()->free(voxel_gi->dynamic_maps[i].texture);
+ RD::get_singleton()->free(voxel_gi->dynamic_maps[i].depth);
}
- gi.gi_probe_instance_owner.free(p_rid);
+ gi.voxel_gi_instance_owner.free(p_rid);
} else if (sky.sky_owner.owns(p_rid)) {
sky.update_dirty_skys();
sky.free_sky(p_rid);
@@ -4153,7 +4176,7 @@ TypedArray<Image> RendererSceneRenderRD::bake_render_uv2(RID p_base, const Vecto
{
PackedByteArray data = RD::get_singleton()->texture_get_data(albedo_alpha_tex, 0);
Ref<Image> img;
- img.instance();
+ img.instantiate();
img->create(p_image_size.width, p_image_size.height, false, Image::FORMAT_RGBA8, data);
RD::get_singleton()->free(albedo_alpha_tex);
ret.push_back(img);
@@ -4162,7 +4185,7 @@ TypedArray<Image> RendererSceneRenderRD::bake_render_uv2(RID p_base, const Vecto
{
PackedByteArray data = RD::get_singleton()->texture_get_data(normal_tex, 0);
Ref<Image> img;
- img.instance();
+ img.instantiate();
img->create(p_image_size.width, p_image_size.height, false, Image::FORMAT_RGBA8, data);
RD::get_singleton()->free(normal_tex);
ret.push_back(img);
@@ -4171,7 +4194,7 @@ TypedArray<Image> RendererSceneRenderRD::bake_render_uv2(RID p_base, const Vecto
{
PackedByteArray data = RD::get_singleton()->texture_get_data(orm_tex, 0);
Ref<Image> img;
- img.instance();
+ img.instantiate();
img->create(p_image_size.width, p_image_size.height, false, Image::FORMAT_RGBA8, data);
RD::get_singleton()->free(orm_tex);
ret.push_back(img);
@@ -4180,7 +4203,7 @@ TypedArray<Image> RendererSceneRenderRD::bake_render_uv2(RID p_base, const Vecto
{
PackedByteArray data = RD::get_singleton()->texture_get_data(emission_tex, 0);
Ref<Image> img;
- img.instance();
+ img.instantiate();
img->create(p_image_size.width, p_image_size.height, false, Image::FORMAT_RGBAH, data);
RD::get_singleton()->free(emission_tex);
ret.push_back(img);
diff --git a/servers/rendering/renderer_rd/renderer_scene_render_rd.h b/servers/rendering/renderer_rd/renderer_scene_render_rd.h
index 1f82ae6dec..be3d3551c7 100644
--- a/servers/rendering/renderer_rd/renderer_scene_render_rd.h
+++ b/servers/rendering/renderer_rd/renderer_scene_render_rd.h
@@ -40,23 +40,28 @@
#include "servers/rendering/renderer_rd/renderer_scene_sky_rd.h"
#include "servers/rendering/renderer_rd/renderer_storage_rd.h"
#include "servers/rendering/renderer_rd/shaders/volumetric_fog.glsl.gen.h"
+#include "servers/rendering/renderer_scene.h"
#include "servers/rendering/renderer_scene_render.h"
#include "servers/rendering/rendering_device.h"
struct RenderDataRD {
RID render_buffers = RID();
- Transform cam_transform = Transform();
+ Transform3D cam_transform = Transform3D();
CameraMatrix cam_projection = CameraMatrix();
bool cam_ortogonal = false;
+ // For stereo rendering
+ uint32_t view_count = 1;
+ CameraMatrix view_projection[RendererSceneRender::MAX_RENDER_VIEWS];
+
float z_near = 0.0;
float z_far = 0.0;
const PagedArray<RendererSceneRender::GeometryInstance *> *instances = nullptr;
const PagedArray<RID> *lights = nullptr;
const PagedArray<RID> *reflection_probes = nullptr;
- const PagedArray<RID> *gi_probes = nullptr;
+ const PagedArray<RID> *voxel_gi_instances = nullptr;
const PagedArray<RID> *decals = nullptr;
const PagedArray<RID> *lightmaps = nullptr;
RID environment = RID();
@@ -75,6 +80,8 @@ struct RenderDataRD {
uint32_t cluster_max_elements = 0;
uint32_t directional_light_count = 0;
+
+ RendererScene::RenderInfo *render_info = nullptr;
};
class RendererSceneRenderRD : public RendererSceneRender {
@@ -87,26 +94,26 @@ protected:
double time_step = 0;
struct RenderBufferData {
- virtual void configure(RID p_color_buffer, RID p_depth_buffer, int p_width, int p_height, RS::ViewportMSAA p_msaa) = 0;
+ virtual void configure(RID p_color_buffer, RID p_depth_buffer, int p_width, int p_height, RS::ViewportMSAA p_msaa, uint32_t p_view_count) = 0;
virtual ~RenderBufferData() {}
};
virtual RenderBufferData *_create_render_buffer_data() = 0;
- void _setup_lights(const PagedArray<RID> &p_lights, const Transform &p_camera_transform, RID p_shadow_atlas, bool p_using_shadows, uint32_t &r_directional_light_count, uint32_t &r_positional_light_count);
- void _setup_decals(const PagedArray<RID> &p_decals, const Transform &p_camera_inverse_xform);
- void _setup_reflections(const PagedArray<RID> &p_reflections, const Transform &p_camera_inverse_transform, RID p_environment);
+ void _setup_lights(const PagedArray<RID> &p_lights, const Transform3D &p_camera_transform, RID p_shadow_atlas, bool p_using_shadows, uint32_t &r_directional_light_count, uint32_t &r_positional_light_count);
+ void _setup_decals(const PagedArray<RID> &p_decals, const Transform3D &p_camera_inverse_xform);
+ void _setup_reflections(const PagedArray<RID> &p_reflections, const Transform3D &p_camera_inverse_transform, RID p_environment);
virtual void _render_scene(RenderDataRD *p_render_data, const Color &p_default_color) = 0;
virtual void _render_shadow_begin() = 0;
- virtual void _render_shadow_append(RID p_framebuffer, const PagedArray<GeometryInstance *> &p_instances, const CameraMatrix &p_projection, const Transform &p_transform, float p_zfar, float p_bias, float p_normal_bias, bool p_use_dp, bool p_use_dp_flip, bool p_use_pancake, const Plane &p_camera_plane = Plane(), float p_lod_distance_multiplier = 0.0, float p_screen_lod_threshold = 0.0, const Rect2i &p_rect = Rect2i(), bool p_flip_y = false, bool p_clear_region = true, bool p_begin = true, bool p_end = true) = 0;
+ virtual void _render_shadow_append(RID p_framebuffer, const PagedArray<GeometryInstance *> &p_instances, const CameraMatrix &p_projection, const Transform3D &p_transform, float p_zfar, float p_bias, float p_normal_bias, bool p_use_dp, bool p_use_dp_flip, bool p_use_pancake, const Plane &p_camera_plane = Plane(), float p_lod_distance_multiplier = 0.0, float p_screen_lod_threshold = 0.0, const Rect2i &p_rect = Rect2i(), bool p_flip_y = false, bool p_clear_region = true, bool p_begin = true, bool p_end = true, RendererScene::RenderInfo *p_render_info = nullptr) = 0;
virtual void _render_shadow_process() = 0;
virtual void _render_shadow_end(uint32_t p_barrier = RD::BARRIER_MASK_ALL) = 0;
- virtual void _render_material(const Transform &p_cam_transform, const CameraMatrix &p_cam_projection, bool p_cam_ortogonal, const PagedArray<GeometryInstance *> &p_instances, RID p_framebuffer, const Rect2i &p_region) = 0;
+ virtual void _render_material(const Transform3D &p_cam_transform, const CameraMatrix &p_cam_projection, bool p_cam_ortogonal, const PagedArray<GeometryInstance *> &p_instances, RID p_framebuffer, const Rect2i &p_region) = 0;
virtual void _render_uv2(const PagedArray<GeometryInstance *> &p_instances, RID p_framebuffer, const Rect2i &p_region) = 0;
virtual void _render_sdfgi(RID p_render_buffers, const Vector3i &p_from, const Vector3i &p_size, const AABB &p_bounds, const PagedArray<GeometryInstance *> &p_instances, const RID &p_albedo_texture, const RID &p_emission_texture, const RID &p_emission_aniso_texture, const RID &p_geom_facing_texture) = 0;
- virtual void _render_particle_collider_heightfield(RID p_fb, const Transform &p_cam_transform, const CameraMatrix &p_cam_projection, const PagedArray<GeometryInstance *> &p_instances) = 0;
+ virtual void _render_particle_collider_heightfield(RID p_fb, const Transform3D &p_cam_transform, const CameraMatrix &p_cam_projection, const PagedArray<GeometryInstance *> &p_instances) = 0;
void _debug_sdfgi_probes(RID p_render_buffers, RD::DrawListID p_draw_list, RID p_framebuffer, const CameraMatrix &p_camera_with_transform);
@@ -123,7 +130,7 @@ protected:
void _post_prepass_render(RenderDataRD *p_render_data, bool p_use_gi);
void _pre_resolve_render(RenderDataRD *p_render_data, bool p_use_gi);
- void _pre_opaque_render(RenderDataRD *p_render_data, bool p_use_ssao, bool p_use_gi, RID p_normal_roughness_buffer, RID p_gi_probe_buffer);
+ void _pre_opaque_render(RenderDataRD *p_render_data, bool p_use_ssao, bool p_use_gi, RID p_normal_roughness_buffer, RID p_voxel_gi_buffer);
// needed for a single argument calls (material and uv2)
PagedArrayPool<GeometryInstance *> cull_argument_pool;
@@ -184,7 +191,7 @@ private:
uint32_t render_index = 0;
uint32_t cull_mask = 0;
- Transform transform;
+ Transform3D transform;
};
mutable RID_Owner<ReflectionProbeInstance> reflection_probe_instance_owner;
@@ -193,7 +200,7 @@ private:
struct DecalInstance {
RID decal;
- Transform transform;
+ Transform3D transform;
uint32_t render_index;
uint32_t cull_mask;
};
@@ -204,7 +211,7 @@ private:
struct LightmapInstance {
RID lightmap;
- Transform transform;
+ Transform3D transform;
};
mutable RID_Owner<LightmapInstance> lightmap_instance_owner;
@@ -312,7 +319,7 @@ private:
struct LightInstance {
struct ShadowTransform {
CameraMatrix camera;
- Transform transform;
+ Transform3D transform;
float farplane;
float split;
float bias_scale;
@@ -329,7 +336,7 @@ private:
AABB aabb;
RID self;
RID light;
- Transform transform;
+ Transform3D transform;
Vector3 light_vector;
Vector3 spot_vector;
@@ -411,6 +418,7 @@ private:
RS::ViewportMSAA msaa = RS::VIEWPORT_MSAA_DISABLED;
RS::ViewportScreenSpaceAA screen_space_aa = RS::VIEWPORT_SCREEN_SPACE_AA_DISABLED;
bool use_debanding = false;
+ uint32_t view_count = 1;
RID render_target;
@@ -454,6 +462,10 @@ private:
Vector<RID> ao_pong_slices;
RID ao_final;
RID importance_map[2];
+
+ RID downsample_uniform_set;
+ RID gather_uniform_set;
+ RID importance_map_uniform_set;
} ssao;
struct SSR {
@@ -631,7 +643,7 @@ private:
int render_sdfgi_region_count = 0;
const RendererSceneRender::RenderSDFGIUpdateData *sdfgi_update_data = nullptr;
- uint32_t gi_probe_count = 0;
+ uint32_t voxel_gi_count = 0;
LocalVector<int> cube_shadows;
LocalVector<int> shadows;
@@ -663,7 +675,7 @@ private:
int last_shadow_filter = -1;
- Transform prev_cam_transform;
+ Transform3D prev_cam_transform;
};
enum {
@@ -692,7 +704,7 @@ private:
float detail_spread;
float gi_inject;
- uint32_t max_gi_probes;
+ uint32_t max_voxel_gi_instances;
uint32_t cluster_type_size;
float screen_size[2];
@@ -721,7 +733,7 @@ private:
bool volumetric_fog_filter_active = true;
void _volumetric_fog_erase(RenderBuffers *rb);
- void _update_volumetric_fog(RID p_render_buffers, RID p_environment, const CameraMatrix &p_cam_projection, const Transform &p_cam_transform, RID p_shadow_atlas, int p_directional_light_count, bool p_use_directional_shadows, int p_positional_light_count, int p_gi_probe_count);
+ void _update_volumetric_fog(RID p_render_buffers, RID p_environment, const CameraMatrix &p_cam_projection, const Transform3D &p_cam_transform, RID p_shadow_atlas, int p_directional_light_count, bool p_use_directional_shadows, int p_positional_light_count, int p_voxel_gi_count);
RID shadow_sampler;
@@ -737,18 +749,18 @@ private:
uint32_t max_cluster_elements = 512;
- void _render_shadow_pass(RID p_light, RID p_shadow_atlas, int p_pass, const PagedArray<GeometryInstance *> &p_instances, const Plane &p_camera_plane = Plane(), float p_lod_distance_multiplier = 0, float p_screen_lod_threshold = 0.0, bool p_open_pass = true, bool p_close_pass = true, bool p_clear_region = true);
+ void _render_shadow_pass(RID p_light, RID p_shadow_atlas, int p_pass, const PagedArray<GeometryInstance *> &p_instances, const Plane &p_camera_plane = Plane(), float p_lod_distance_multiplier = 0, float p_screen_lod_threshold = 0.0, bool p_open_pass = true, bool p_close_pass = true, bool p_clear_region = true, RendererScene::RenderInfo *p_render_info = nullptr);
public:
- virtual Transform geometry_instance_get_transform(GeometryInstance *p_instance) = 0;
+ virtual Transform3D geometry_instance_get_transform(GeometryInstance *p_instance) = 0;
virtual AABB geometry_instance_get_aabb(GeometryInstance *p_instance) = 0;
/* SHADOW ATLAS API */
- RID shadow_atlas_create();
- void shadow_atlas_set_size(RID p_atlas, int p_size, bool p_16_bits = false);
- void shadow_atlas_set_quadrant_subdivision(RID p_atlas, int p_quadrant, int p_subdivision);
- bool shadow_atlas_update_light(RID p_atlas, RID p_light_intance, float p_coverage, uint64_t p_light_version);
+ virtual RID shadow_atlas_create() override;
+ virtual void shadow_atlas_set_size(RID p_atlas, int p_size, bool p_16_bits = false) override;
+ virtual void shadow_atlas_set_quadrant_subdivision(RID p_atlas, int p_quadrant, int p_subdivision) override;
+ virtual bool shadow_atlas_update_light(RID p_atlas, RID p_light_intance, float p_coverage, uint64_t p_light_version) override;
_FORCE_INLINE_ bool shadow_atlas_owns_light_instance(RID p_atlas, RID p_light_intance) {
ShadowAtlas *atlas = shadow_atlas_owner.getornull(p_atlas);
ERR_FAIL_COND_V(!atlas, false);
@@ -767,9 +779,9 @@ public:
return Size2(atlas->size, atlas->size);
}
- void directional_shadow_atlas_set_size(int p_size, bool p_16_bits = false);
- int get_directional_light_shadow_size(RID p_light_intance);
- void set_directional_shadow_count(int p_count);
+ virtual void directional_shadow_atlas_set_size(int p_size, bool p_16_bits = false) override;
+ virtual int get_directional_light_shadow_size(RID p_light_intance) override;
+ virtual void set_directional_shadow_count(int p_count) override;
_FORCE_INLINE_ RID directional_shadow_get_texture() {
return directional_shadow.depth;
@@ -781,43 +793,43 @@ public:
/* SDFGI UPDATE */
- virtual void sdfgi_update(RID p_render_buffers, RID p_environment, const Vector3 &p_world_position);
- virtual int sdfgi_get_pending_region_count(RID p_render_buffers) const;
- virtual AABB sdfgi_get_pending_region_bounds(RID p_render_buffers, int p_region) const;
- virtual uint32_t sdfgi_get_pending_region_cascade(RID p_render_buffers, int p_region) const;
+ virtual void sdfgi_update(RID p_render_buffers, RID p_environment, const Vector3 &p_world_position) override;
+ virtual int sdfgi_get_pending_region_count(RID p_render_buffers) const override;
+ virtual AABB sdfgi_get_pending_region_bounds(RID p_render_buffers, int p_region) const override;
+ virtual uint32_t sdfgi_get_pending_region_cascade(RID p_render_buffers, int p_region) const override;
RID sdfgi_get_ubo() const { return gi.sdfgi_ubo; }
/* SKY API */
- virtual RID sky_allocate();
- virtual void sky_initialize(RID p_rid);
+ virtual RID sky_allocate() override;
+ virtual void sky_initialize(RID p_rid) override;
- void sky_set_radiance_size(RID p_sky, int p_radiance_size);
- void sky_set_mode(RID p_sky, RS::SkyMode p_mode);
- void sky_set_material(RID p_sky, RID p_material);
- Ref<Image> sky_bake_panorama(RID p_sky, float p_energy, bool p_bake_irradiance, const Size2i &p_size);
+ virtual void sky_set_radiance_size(RID p_sky, int p_radiance_size) override;
+ virtual void sky_set_mode(RID p_sky, RS::SkyMode p_mode) override;
+ virtual void sky_set_material(RID p_sky, RID p_material) override;
+ virtual Ref<Image> sky_bake_panorama(RID p_sky, float p_energy, bool p_bake_irradiance, const Size2i &p_size) override;
/* ENVIRONMENT API */
- virtual RID environment_allocate();
- virtual void environment_initialize(RID p_rid);
+ virtual RID environment_allocate() override;
+ virtual void environment_initialize(RID p_rid) override;
- void environment_set_background(RID p_env, RS::EnvironmentBG p_bg);
- void environment_set_sky(RID p_env, RID p_sky);
- void environment_set_sky_custom_fov(RID p_env, float p_scale);
- void environment_set_sky_orientation(RID p_env, const Basis &p_orientation);
- void environment_set_bg_color(RID p_env, const Color &p_color);
- void environment_set_bg_energy(RID p_env, float p_energy);
- void environment_set_canvas_max_layer(RID p_env, int p_max_layer);
- void environment_set_ambient_light(RID p_env, const Color &p_color, RS::EnvironmentAmbientSource p_ambient = RS::ENV_AMBIENT_SOURCE_BG, float p_energy = 1.0, float p_sky_contribution = 0.0, RS::EnvironmentReflectionSource p_reflection_source = RS::ENV_REFLECTION_SOURCE_BG, const Color &p_ao_color = Color());
+ virtual void environment_set_background(RID p_env, RS::EnvironmentBG p_bg) override;
+ virtual void environment_set_sky(RID p_env, RID p_sky) override;
+ virtual void environment_set_sky_custom_fov(RID p_env, float p_scale) override;
+ virtual void environment_set_sky_orientation(RID p_env, const Basis &p_orientation) override;
+ virtual void environment_set_bg_color(RID p_env, const Color &p_color) override;
+ virtual void environment_set_bg_energy(RID p_env, float p_energy) override;
+ virtual void environment_set_canvas_max_layer(RID p_env, int p_max_layer) override;
+ virtual void environment_set_ambient_light(RID p_env, const Color &p_color, RS::EnvironmentAmbientSource p_ambient = RS::ENV_AMBIENT_SOURCE_BG, float p_energy = 1.0, float p_sky_contribution = 0.0, RS::EnvironmentReflectionSource p_reflection_source = RS::ENV_REFLECTION_SOURCE_BG, const Color &p_ao_color = Color()) override;
- RS::EnvironmentBG environment_get_background(RID p_env) const;
+ virtual RS::EnvironmentBG environment_get_background(RID p_env) const override;
RID environment_get_sky(RID p_env) const;
float environment_get_sky_custom_fov(RID p_env) const;
Basis environment_get_sky_orientation(RID p_env) const;
Color environment_get_bg_color(RID p_env) const;
float environment_get_bg_energy(RID p_env) const;
- int environment_get_canvas_max_layer(RID p_env) const;
+ virtual int environment_get_canvas_max_layer(RID p_env) const override;
Color environment_get_ambient_light_color(RID p_env) const;
RS::EnvironmentAmbientSource environment_get_ambient_source(RID p_env) const;
float environment_get_ambient_light_energy(RID p_env) const;
@@ -825,13 +837,13 @@ public:
RS::EnvironmentReflectionSource environment_get_reflection_source(RID p_env) const;
Color environment_get_ao_color(RID p_env) const;
- bool is_environment(RID p_env) const;
+ virtual bool is_environment(RID p_env) const override;
- void environment_set_glow(RID p_env, bool p_enable, Vector<float> p_levels, float p_intensity, float p_strength, float p_mix, float p_bloom_threshold, RS::EnvironmentGlowBlendMode p_blend_mode, float p_hdr_bleed_threshold, float p_hdr_bleed_scale, float p_hdr_luminance_cap);
- void environment_glow_set_use_bicubic_upscale(bool p_enable);
- void environment_glow_set_use_high_quality(bool p_enable);
+ virtual void environment_set_glow(RID p_env, bool p_enable, Vector<float> p_levels, float p_intensity, float p_strength, float p_mix, float p_bloom_threshold, RS::EnvironmentGlowBlendMode p_blend_mode, float p_hdr_bleed_threshold, float p_hdr_bleed_scale, float p_hdr_luminance_cap) override;
+ virtual void environment_glow_set_use_bicubic_upscale(bool p_enable) override;
+ virtual void environment_glow_set_use_high_quality(bool p_enable) override;
- void environment_set_fog(RID p_env, bool p_enable, const Color &p_light_color, float p_light_energy, float p_sun_scatter, float p_density, float p_height, float p_height_density, float p_aerial_perspective);
+ virtual void environment_set_fog(RID p_env, bool p_enable, const Color &p_light_color, float p_light_energy, float p_sun_scatter, float p_density, float p_height, float p_height_density, float p_aerial_perspective) override;
bool environment_is_fog_enabled(RID p_env) const;
Color environment_get_fog_light_color(RID p_env) const;
float environment_get_fog_light_energy(RID p_env) const;
@@ -841,54 +853,54 @@ public:
float environment_get_fog_height_density(RID p_env) const;
float environment_get_fog_aerial_perspective(RID p_env) const;
- void environment_set_volumetric_fog(RID p_env, bool p_enable, float p_density, const Color &p_light, float p_light_energy, float p_length, float p_detail_spread, float p_gi_inject, bool p_temporal_reprojection, float p_temporal_reprojection_amount);
+ virtual void environment_set_volumetric_fog(RID p_env, bool p_enable, float p_density, const Color &p_light, float p_light_energy, float p_length, float p_detail_spread, float p_gi_inject, bool p_temporal_reprojection, float p_temporal_reprojection_amount) override;
- virtual void environment_set_volumetric_fog_volume_size(int p_size, int p_depth);
- virtual void environment_set_volumetric_fog_filter_active(bool p_enable);
+ virtual void environment_set_volumetric_fog_volume_size(int p_size, int p_depth) override;
+ virtual void environment_set_volumetric_fog_filter_active(bool p_enable) override;
- void environment_set_ssr(RID p_env, bool p_enable, int p_max_steps, float p_fade_int, float p_fade_out, float p_depth_tolerance);
- void environment_set_ssao(RID p_env, bool p_enable, float p_radius, float p_intensity, float p_power, float p_detail, float p_horizon, float p_sharpness, float p_light_affect, float p_ao_channel_affect);
- void environment_set_ssao_quality(RS::EnvironmentSSAOQuality p_quality, bool p_half_size, float p_adaptive_target, int p_blur_passes, float p_fadeout_from, float p_fadeout_to);
+ virtual void environment_set_ssr(RID p_env, bool p_enable, int p_max_steps, float p_fade_int, float p_fade_out, float p_depth_tolerance) override;
+ virtual void environment_set_ssao(RID p_env, bool p_enable, float p_radius, float p_intensity, float p_power, float p_detail, float p_horizon, float p_sharpness, float p_light_affect, float p_ao_channel_affect) override;
+ virtual void environment_set_ssao_quality(RS::EnvironmentSSAOQuality p_quality, bool p_half_size, float p_adaptive_target, int p_blur_passes, float p_fadeout_from, float p_fadeout_to) override;
bool environment_is_ssao_enabled(RID p_env) const;
float environment_get_ssao_ao_affect(RID p_env) const;
float environment_get_ssao_light_affect(RID p_env) const;
bool environment_is_ssr_enabled(RID p_env) const;
bool environment_is_sdfgi_enabled(RID p_env) const;
- virtual void environment_set_sdfgi(RID p_env, bool p_enable, RS::EnvironmentSDFGICascades p_cascades, float p_min_cell_size, RS::EnvironmentSDFGIYScale p_y_scale, bool p_use_occlusion, float p_bounce_feedback, bool p_read_sky, float p_energy, float p_normal_bias, float p_probe_bias);
- virtual void environment_set_sdfgi_ray_count(RS::EnvironmentSDFGIRayCount p_ray_count);
- virtual void environment_set_sdfgi_frames_to_converge(RS::EnvironmentSDFGIFramesToConverge p_frames);
- virtual void environment_set_sdfgi_frames_to_update_light(RS::EnvironmentSDFGIFramesToUpdateLight p_update);
+ virtual void environment_set_sdfgi(RID p_env, bool p_enable, RS::EnvironmentSDFGICascades p_cascades, float p_min_cell_size, RS::EnvironmentSDFGIYScale p_y_scale, bool p_use_occlusion, float p_bounce_feedback, bool p_read_sky, float p_energy, float p_normal_bias, float p_probe_bias) override;
+ virtual void environment_set_sdfgi_ray_count(RS::EnvironmentSDFGIRayCount p_ray_count) override;
+ virtual void environment_set_sdfgi_frames_to_converge(RS::EnvironmentSDFGIFramesToConverge p_frames) override;
+ virtual void environment_set_sdfgi_frames_to_update_light(RS::EnvironmentSDFGIFramesToUpdateLight p_update) override;
- void environment_set_ssr_roughness_quality(RS::EnvironmentSSRRoughnessQuality p_quality);
+ virtual void environment_set_ssr_roughness_quality(RS::EnvironmentSSRRoughnessQuality p_quality) override;
RS::EnvironmentSSRRoughnessQuality environment_get_ssr_roughness_quality() const;
- void environment_set_tonemap(RID p_env, RS::EnvironmentToneMapper p_tone_mapper, float p_exposure, float p_white, bool p_auto_exposure, float p_min_luminance, float p_max_luminance, float p_auto_exp_speed, float p_auto_exp_scale);
- void environment_set_adjustment(RID p_env, bool p_enable, float p_brightness, float p_contrast, float p_saturation, bool p_use_1d_color_correction, RID p_color_correction);
+ virtual void environment_set_tonemap(RID p_env, RS::EnvironmentToneMapper p_tone_mapper, float p_exposure, float p_white, bool p_auto_exposure, float p_min_luminance, float p_max_luminance, float p_auto_exp_speed, float p_auto_exp_scale) override;
+ virtual void environment_set_adjustment(RID p_env, bool p_enable, float p_brightness, float p_contrast, float p_saturation, bool p_use_1d_color_correction, RID p_color_correction) override;
- virtual Ref<Image> environment_bake_panorama(RID p_env, bool p_bake_irradiance, const Size2i &p_size);
+ virtual Ref<Image> environment_bake_panorama(RID p_env, bool p_bake_irradiance, const Size2i &p_size) override;
- virtual RID camera_effects_allocate();
- virtual void camera_effects_initialize(RID p_rid);
+ virtual RID camera_effects_allocate() override;
+ virtual void camera_effects_initialize(RID p_rid) override;
- virtual void camera_effects_set_dof_blur_quality(RS::DOFBlurQuality p_quality, bool p_use_jitter);
- virtual void camera_effects_set_dof_blur_bokeh_shape(RS::DOFBokehShape p_shape);
+ virtual void camera_effects_set_dof_blur_quality(RS::DOFBlurQuality p_quality, bool p_use_jitter) override;
+ virtual void camera_effects_set_dof_blur_bokeh_shape(RS::DOFBokehShape p_shape) override;
- virtual void camera_effects_set_dof_blur(RID p_camera_effects, bool p_far_enable, float p_far_distance, float p_far_transition, bool p_near_enable, float p_near_distance, float p_near_transition, float p_amount);
- virtual void camera_effects_set_custom_exposure(RID p_camera_effects, bool p_enable, float p_exposure);
+ virtual void camera_effects_set_dof_blur(RID p_camera_effects, bool p_far_enable, float p_far_distance, float p_far_transition, bool p_near_enable, float p_near_distance, float p_near_transition, float p_amount) override;
+ virtual void camera_effects_set_custom_exposure(RID p_camera_effects, bool p_enable, float p_exposure) override;
- RID light_instance_create(RID p_light);
- void light_instance_set_transform(RID p_light_instance, const Transform &p_transform);
- void light_instance_set_aabb(RID p_light_instance, const AABB &p_aabb);
- void light_instance_set_shadow_transform(RID p_light_instance, const CameraMatrix &p_projection, const Transform &p_transform, float p_far, float p_split, int p_pass, float p_shadow_texel_size, float p_bias_scale = 1.0, float p_range_begin = 0, const Vector2 &p_uv_scale = Vector2());
- void light_instance_mark_visible(RID p_light_instance);
+ virtual RID light_instance_create(RID p_light) override;
+ virtual void light_instance_set_transform(RID p_light_instance, const Transform3D &p_transform) override;
+ virtual void light_instance_set_aabb(RID p_light_instance, const AABB &p_aabb) override;
+ virtual void light_instance_set_shadow_transform(RID p_light_instance, const CameraMatrix &p_projection, const Transform3D &p_transform, float p_far, float p_split, int p_pass, float p_shadow_texel_size, float p_bias_scale = 1.0, float p_range_begin = 0, const Vector2 &p_uv_scale = Vector2()) override;
+ virtual void light_instance_mark_visible(RID p_light_instance) override;
_FORCE_INLINE_ RID light_instance_get_base_light(RID p_light_instance) {
LightInstance *li = light_instance_owner.getornull(p_light_instance);
return li->light;
}
- _FORCE_INLINE_ Transform light_instance_get_base_transform(RID p_light_instance) {
+ _FORCE_INLINE_ Transform3D light_instance_get_base_transform(RID p_light_instance) {
LightInstance *li = light_instance_owner.getornull(p_light_instance);
return li->transform;
}
@@ -945,7 +957,7 @@ public:
return float(1.0) / shadow_size;
}
- _FORCE_INLINE_ Transform
+ _FORCE_INLINE_ Transform3D
light_instance_get_shadow_transform(RID p_light_instance, int p_index) {
LightInstance *li = light_instance_owner.getornull(p_light_instance);
return li->shadow_transform[p_index].transform;
@@ -1008,9 +1020,9 @@ public:
return li->light_type;
}
- virtual RID reflection_atlas_create();
- virtual void reflection_atlas_set_size(RID p_ref_atlas, int p_reflection_size, int p_reflection_count);
- virtual int reflection_atlas_get_size(RID p_ref_atlas) const;
+ virtual RID reflection_atlas_create() override;
+ virtual void reflection_atlas_set_size(RID p_ref_atlas, int p_reflection_size, int p_reflection_count) override;
+ virtual int reflection_atlas_get_size(RID p_ref_atlas) const override;
_FORCE_INLINE_ RID reflection_atlas_get_texture(RID p_ref_atlas) {
ReflectionAtlas *atlas = reflection_atlas_owner.getornull(p_ref_atlas);
@@ -1018,13 +1030,13 @@ public:
return atlas->reflection;
}
- virtual RID reflection_probe_instance_create(RID p_probe);
- virtual void reflection_probe_instance_set_transform(RID p_instance, const Transform &p_transform);
- virtual void reflection_probe_release_atlas_index(RID p_instance);
- virtual bool reflection_probe_instance_needs_redraw(RID p_instance);
- virtual bool reflection_probe_instance_has_reflection(RID p_instance);
- virtual bool reflection_probe_instance_begin_render(RID p_instance, RID p_reflection_atlas);
- virtual bool reflection_probe_instance_postprocess_step(RID p_instance);
+ virtual RID reflection_probe_instance_create(RID p_probe) override;
+ virtual void reflection_probe_instance_set_transform(RID p_instance, const Transform3D &p_transform) override;
+ virtual void reflection_probe_release_atlas_index(RID p_instance) override;
+ virtual bool reflection_probe_instance_needs_redraw(RID p_instance) override;
+ virtual bool reflection_probe_instance_has_reflection(RID p_instance) override;
+ virtual bool reflection_probe_instance_begin_render(RID p_instance, RID p_reflection_atlas) override;
+ virtual bool reflection_probe_instance_postprocess_step(RID p_instance) override;
uint32_t reflection_probe_instance_get_resolution(RID p_instance);
RID reflection_probe_instance_get_framebuffer(RID p_instance, int p_index);
@@ -1063,9 +1075,9 @@ public:
return rpi->last_pass;
}
- _FORCE_INLINE_ Transform reflection_probe_instance_get_transform(RID p_instance) {
+ _FORCE_INLINE_ Transform3D reflection_probe_instance_get_transform(RID p_instance) {
ReflectionProbeInstance *rpi = reflection_probe_instance_owner.getornull(p_instance);
- ERR_FAIL_COND_V(!rpi, Transform());
+ ERR_FAIL_COND_V(!rpi, Transform3D());
return rpi->transform;
}
@@ -1077,21 +1089,21 @@ public:
return rpi->atlas_index;
}
- virtual RID decal_instance_create(RID p_decal);
- virtual void decal_instance_set_transform(RID p_decal, const Transform &p_transform);
+ virtual RID decal_instance_create(RID p_decal) override;
+ virtual void decal_instance_set_transform(RID p_decal, const Transform3D &p_transform) override;
_FORCE_INLINE_ RID decal_instance_get_base(RID p_decal) const {
DecalInstance *decal = decal_instance_owner.getornull(p_decal);
return decal->decal;
}
- _FORCE_INLINE_ Transform decal_instance_get_transform(RID p_decal) const {
+ _FORCE_INLINE_ Transform3D decal_instance_get_transform(RID p_decal) const {
DecalInstance *decal = decal_instance_owner.getornull(p_decal);
return decal->transform;
}
- virtual RID lightmap_instance_create(RID p_lightmap);
- virtual void lightmap_instance_set_transform(RID p_lightmap, const Transform &p_transform);
+ virtual RID lightmap_instance_create(RID p_lightmap) override;
+ virtual void lightmap_instance_set_transform(RID p_lightmap, const Transform3D &p_transform) override;
_FORCE_INLINE_ bool lightmap_instance_is_valid(RID p_lightmap_instance) {
return lightmap_instance_owner.getornull(p_lightmap_instance) != nullptr;
}
@@ -1100,7 +1112,7 @@ public:
LightmapInstance *li = lightmap_instance_owner.getornull(p_lightmap_instance);
return li->lightmap;
}
- _FORCE_INLINE_ Transform lightmap_instance_get_transform(RID p_lightmap_instance) {
+ _FORCE_INLINE_ Transform3D lightmap_instance_get_transform(RID p_lightmap_instance) {
LightmapInstance *li = lightmap_instance_owner.getornull(p_lightmap_instance);
return li->transform;
}
@@ -1109,22 +1121,22 @@ public:
/* gi light probes */
- RID gi_probe_instance_create(RID p_base);
- void gi_probe_instance_set_transform_to_data(RID p_probe, const Transform &p_xform);
- bool gi_probe_needs_update(RID p_probe) const;
- void gi_probe_update(RID p_probe, bool p_update_light_instances, const Vector<RID> &p_light_instances, const PagedArray<RendererSceneRender::GeometryInstance *> &p_dynamic_objects);
- void gi_probe_set_quality(RS::GIProbeQuality p_quality) { gi.gi_probe_quality = p_quality; }
+ virtual RID voxel_gi_instance_create(RID p_base) override;
+ virtual void voxel_gi_instance_set_transform_to_data(RID p_probe, const Transform3D &p_xform) override;
+ virtual bool voxel_gi_needs_update(RID p_probe) const override;
+ virtual void voxel_gi_update(RID p_probe, bool p_update_light_instances, const Vector<RID> &p_light_instances, const PagedArray<RendererSceneRender::GeometryInstance *> &p_dynamic_objects) override;
+ virtual void voxel_gi_set_quality(RS::VoxelGIQuality p_quality) override { gi.voxel_gi_quality = p_quality; }
/* render buffers */
- RID render_buffers_create();
- void render_buffers_configure(RID p_render_buffers, RID p_render_target, int p_width, int p_height, RS::ViewportMSAA p_msaa, RS::ViewportScreenSpaceAA p_screen_space_aa, bool p_use_debanding);
- void gi_set_use_half_resolution(bool p_enable);
+ virtual RID render_buffers_create() override;
+ virtual void render_buffers_configure(RID p_render_buffers, RID p_render_target, int p_width, int p_height, RS::ViewportMSAA p_msaa, RS::ViewportScreenSpaceAA p_screen_space_aa, bool p_use_debanding, uint32_t p_view_count) override;
+ virtual void gi_set_use_half_resolution(bool p_enable) override;
RID render_buffers_get_ao_texture(RID p_render_buffers);
RID render_buffers_get_back_buffer_texture(RID p_render_buffers);
- RID render_buffers_get_gi_probe_buffer(RID p_render_buffers);
- RID render_buffers_get_default_gi_probe_buffer();
+ RID render_buffers_get_voxel_gi_buffer(RID p_render_buffers);
+ RID render_buffers_get_default_voxel_gi_buffer();
RID render_buffers_get_gi_ambient_texture(RID p_render_buffers);
RID render_buffers_get_gi_reflection_texture(RID p_render_buffers);
@@ -1147,30 +1159,30 @@ public:
float render_buffers_get_volumetric_fog_end(RID p_render_buffers);
float render_buffers_get_volumetric_fog_detail_spread(RID p_render_buffers);
- void render_scene(RID p_render_buffers, const Transform &p_cam_transform, const CameraMatrix &p_cam_projection, bool p_cam_ortogonal, const PagedArray<GeometryInstance *> &p_instances, const PagedArray<RID> &p_lights, const PagedArray<RID> &p_reflection_probes, const PagedArray<RID> &p_gi_probes, const PagedArray<RID> &p_decals, const PagedArray<RID> &p_lightmaps, RID p_environment, RID p_camera_effects, 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_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);
+ virtual void render_scene(RID p_render_buffers, const CameraData *p_camera_data, const PagedArray<GeometryInstance *> &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, RID p_environment, RID p_camera_effects, 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_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, RendererScene::RenderInfo *r_render_info = nullptr) override;
- void render_material(const Transform &p_cam_transform, const CameraMatrix &p_cam_projection, bool p_cam_ortogonal, const PagedArray<GeometryInstance *> &p_instances, RID p_framebuffer, const Rect2i &p_region);
+ virtual void render_material(const Transform3D &p_cam_transform, const CameraMatrix &p_cam_projection, bool p_cam_ortogonal, const PagedArray<GeometryInstance *> &p_instances, RID p_framebuffer, const Rect2i &p_region) override;
- void render_particle_collider_heightfield(RID p_collider, const Transform &p_transform, const PagedArray<GeometryInstance *> &p_instances);
+ virtual void render_particle_collider_heightfield(RID p_collider, const Transform3D &p_transform, const PagedArray<GeometryInstance *> &p_instances) override;
- virtual void set_scene_pass(uint64_t p_pass) {
+ virtual void set_scene_pass(uint64_t p_pass) override {
scene_pass = p_pass;
}
_FORCE_INLINE_ uint64_t get_scene_pass() {
return scene_pass;
}
- virtual void screen_space_roughness_limiter_set_active(bool p_enable, float p_amount, float p_limit);
- virtual bool screen_space_roughness_limiter_is_active() const;
+ virtual void screen_space_roughness_limiter_set_active(bool p_enable, float p_amount, float p_limit) override;
+ virtual bool screen_space_roughness_limiter_is_active() const override;
virtual float screen_space_roughness_limiter_get_amount() const;
virtual float screen_space_roughness_limiter_get_limit() const;
- virtual void sub_surface_scattering_set_quality(RS::SubSurfaceScatteringQuality p_quality);
+ virtual void sub_surface_scattering_set_quality(RS::SubSurfaceScatteringQuality p_quality) override;
RS::SubSurfaceScatteringQuality sub_surface_scattering_get_quality() const;
- virtual void sub_surface_scattering_set_scale(float p_scale, float p_depth_scale);
+ virtual void sub_surface_scattering_set_scale(float p_scale, float p_depth_scale) override;
- virtual void shadows_quality_set(RS::ShadowQuality p_quality);
- virtual void directional_shadow_quality_set(RS::ShadowQuality p_quality);
+ virtual void shadows_quality_set(RS::ShadowQuality p_quality) override;
+ virtual void directional_shadow_quality_set(RS::ShadowQuality p_quality) override;
_FORCE_INLINE_ RS::ShadowQuality shadows_quality_get() const { return shadows_quality; }
_FORCE_INLINE_ RS::ShadowQuality directional_shadow_quality_get() const { return directional_shadow_quality; }
_FORCE_INLINE_ float shadows_quality_radius_get() const { return shadows_quality_radius; }
@@ -1189,18 +1201,18 @@ public:
int get_roughness_layers() const;
bool is_using_radiance_cubemap_array() const;
- virtual TypedArray<Image> bake_render_uv2(RID p_base, const Vector<RID> &p_material_overrides, const Size2i &p_image_size);
+ virtual TypedArray<Image> bake_render_uv2(RID p_base, const Vector<RID> &p_material_overrides, const Size2i &p_image_size) override;
- virtual bool free(RID p_rid);
+ virtual bool free(RID p_rid) override;
- virtual void update();
+ virtual void update() override;
- virtual void set_debug_draw_mode(RS::ViewportDebugDraw p_debug_draw);
+ virtual void set_debug_draw_mode(RS::ViewportDebugDraw p_debug_draw) override;
_FORCE_INLINE_ RS::ViewportDebugDraw get_debug_draw_mode() const {
return debug_draw;
}
- void set_time(double p_time, double p_step);
+ virtual void set_time(double p_time, double p_step) override;
RID get_reflection_probe_buffer();
RID get_omni_light_buffer();
@@ -1209,7 +1221,7 @@ public:
RID get_decal_buffer();
int get_max_directional_lights() const;
- void sdfgi_set_debug_probe_select(const Vector3 &p_position, const Vector3 &p_dir);
+ virtual void sdfgi_set_debug_probe_select(const Vector3 &p_position, const Vector3 &p_dir) override;
virtual bool is_dynamic_gi_supported() const;
virtual bool is_clustered_enabled() const;
diff --git a/servers/rendering/renderer_rd/renderer_scene_sky_rd.cpp b/servers/rendering/renderer_rd/renderer_scene_sky_rd.cpp
index 966a1c6815..e701219617 100644
--- a/servers/rendering/renderer_rd/renderer_scene_sky_rd.cpp
+++ b/servers/rendering/renderer_rd/renderer_scene_sky_rd.cpp
@@ -32,6 +32,7 @@
#include "core/config/project_settings.h"
#include "core/math/math_defs.h"
#include "renderer_scene_render_rd.h"
+#include "servers/rendering/renderer_rd/renderer_compositor_rd.h"
#include "servers/rendering/rendering_server_default.h"
////////////////////////////////////////////////////////////////////////////////
@@ -126,8 +127,12 @@ void RendererSceneSkyRD::SkyShaderData::set_code(const String &p_code) {
depth_stencil_state.enable_depth_test = true;
depth_stencil_state.depth_compare_operator = RD::COMPARE_OP_LESS_OR_EQUAL;
- RID shader_variant = scene_singleton->sky.sky_shader.shader.version_get_shader(version, i);
- pipelines[i].setup(shader_variant, RD::RENDER_PRIMITIVE_TRIANGLES, RD::PipelineRasterizationState(), RD::PipelineMultisampleState(), depth_stencil_state, RD::PipelineColorBlendState::create_disabled(), 0);
+ if (scene_singleton->sky.sky_shader.shader.is_variant_enabled(i)) {
+ RID shader_variant = scene_singleton->sky.sky_shader.shader.version_get_shader(version, i);
+ pipelines[i].setup(shader_variant, RD::RENDER_PRIMITIVE_TRIANGLES, RD::PipelineRasterizationState(), RD::PipelineMultisampleState(), depth_stencil_state, RD::PipelineColorBlendState::create_disabled(), 0);
+ } else {
+ pipelines[i].clear();
+ }
}
valid = true;
@@ -225,96 +230,73 @@ RendererSceneSkyRD::SkyShaderData::~SkyShaderData() {
////////////////////////////////////////////////////////////////////////////////
// Sky material
-void RendererSceneSkyRD::SkyMaterialData::update_parameters(const Map<StringName, Variant> &p_parameters, bool p_uniform_dirty, bool p_textures_dirty) {
+bool RendererSceneSkyRD::SkyMaterialData::update_parameters(const Map<StringName, Variant> &p_parameters, bool p_uniform_dirty, bool p_textures_dirty) {
RendererSceneRenderRD *scene_singleton = (RendererSceneRenderRD *)RendererSceneRenderRD::singleton;
uniform_set_updated = true;
- if ((uint32_t)ubo_data.size() != shader_data->ubo_size) {
- p_uniform_dirty = true;
- if (uniform_buffer.is_valid()) {
- RD::get_singleton()->free(uniform_buffer);
- uniform_buffer = RID();
- }
-
- ubo_data.resize(shader_data->ubo_size);
- if (ubo_data.size()) {
- uniform_buffer = RD::get_singleton()->uniform_buffer_create(ubo_data.size());
- memset(ubo_data.ptrw(), 0, ubo_data.size()); //clear
- }
-
- //clear previous uniform set
- if (uniform_set.is_valid() && RD::get_singleton()->uniform_set_is_valid(uniform_set)) {
- RD::get_singleton()->free(uniform_set);
- uniform_set = RID();
- }
- }
-
- //check whether buffer changed
- if (p_uniform_dirty && ubo_data.size()) {
- update_uniform_buffer(shader_data->uniforms, shader_data->ubo_offsets.ptr(), p_parameters, ubo_data.ptrw(), ubo_data.size(), false);
- RD::get_singleton()->buffer_update(uniform_buffer, 0, ubo_data.size(), ubo_data.ptrw());
- }
+ return update_parameters_uniform_set(p_parameters, p_uniform_dirty, p_textures_dirty, shader_data->uniforms, shader_data->ubo_offsets.ptr(), shader_data->texture_uniforms, shader_data->default_texture_params, shader_data->ubo_size, uniform_set, scene_singleton->sky.sky_shader.shader.version_get_shader(shader_data->version, 0), SKY_SET_MATERIAL);
+}
- uint32_t tex_uniform_count = shader_data->texture_uniforms.size();
+RendererSceneSkyRD::SkyMaterialData::~SkyMaterialData() {
+ free_parameters_uniform_set(uniform_set);
+}
- if ((uint32_t)texture_cache.size() != tex_uniform_count) {
- texture_cache.resize(tex_uniform_count);
- p_textures_dirty = true;
+////////////////////////////////////////////////////////////////////////////////
+// Render sky
+
+static _FORCE_INLINE_ void store_transform_3x3(const Basis &p_basis, float *p_array) {
+ p_array[0] = p_basis.elements[0][0];
+ p_array[1] = p_basis.elements[1][0];
+ p_array[2] = p_basis.elements[2][0];
+ p_array[3] = 0;
+ p_array[4] = p_basis.elements[0][1];
+ p_array[5] = p_basis.elements[1][1];
+ p_array[6] = p_basis.elements[2][1];
+ p_array[7] = 0;
+ p_array[8] = p_basis.elements[0][2];
+ p_array[9] = p_basis.elements[1][2];
+ p_array[10] = p_basis.elements[2][2];
+ p_array[11] = 0;
+}
- //clear previous uniform set
- if (uniform_set.is_valid() && RD::get_singleton()->uniform_set_is_valid(uniform_set)) {
- RD::get_singleton()->free(uniform_set);
- uniform_set = RID();
- }
- }
+void RendererSceneSkyRD::_render_sky(RD::DrawListID p_list, float p_time, RID p_fb, PipelineCacheRD *p_pipeline, RID p_uniform_set, RID p_texture_set, uint32_t p_view_count, const CameraMatrix *p_projections, const Basis &p_orientation, float p_multiplier, const Vector3 &p_position) {
+ SkyPushConstant sky_push_constant;
- if (p_textures_dirty && tex_uniform_count) {
- update_textures(p_parameters, shader_data->default_texture_params, shader_data->texture_uniforms, texture_cache.ptrw(), true);
- }
+ memset(&sky_push_constant, 0, sizeof(SkyPushConstant));
- if (shader_data->ubo_size == 0 && shader_data->texture_uniforms.size() == 0) {
- // This material does not require an uniform set, so don't create it.
- return;
+ for (uint32_t v = 0; v < p_view_count; v++) {
+ // We only need key components of our projection matrix
+ sky_push_constant.projections[v][0] = p_projections[v].matrix[2][0];
+ sky_push_constant.projections[v][1] = p_projections[v].matrix[0][0];
+ sky_push_constant.projections[v][2] = p_projections[v].matrix[2][1];
+ sky_push_constant.projections[v][3] = p_projections[v].matrix[1][1];
}
+ sky_push_constant.position[0] = p_position.x;
+ sky_push_constant.position[1] = p_position.y;
+ sky_push_constant.position[2] = p_position.z;
+ sky_push_constant.multiplier = p_multiplier;
+ sky_push_constant.time = p_time;
+ store_transform_3x3(p_orientation, sky_push_constant.orientation);
- if (!p_textures_dirty && uniform_set.is_valid() && RD::get_singleton()->uniform_set_is_valid(uniform_set)) {
- //no reason to update uniform set, only UBO (or nothing) was needed to update
- return;
- }
+ RenderingDevice::FramebufferFormatID fb_format = RD::get_singleton()->framebuffer_get_format(p_fb);
- Vector<RD::Uniform> uniforms;
+ RD::DrawListID draw_list = p_list;
- {
- if (shader_data->ubo_size) {
- RD::Uniform u;
- u.uniform_type = RD::UNIFORM_TYPE_UNIFORM_BUFFER;
- u.binding = 0;
- u.ids.push_back(uniform_buffer);
- uniforms.push_back(u);
- }
+ RD::get_singleton()->draw_list_bind_render_pipeline(draw_list, p_pipeline->get_render_pipeline(RD::INVALID_ID, fb_format));
- const RID *textures = texture_cache.ptrw();
- for (uint32_t i = 0; i < tex_uniform_count; i++) {
- RD::Uniform u;
- u.uniform_type = RD::UNIFORM_TYPE_TEXTURE;
- u.binding = 1 + i;
- u.ids.push_back(textures[i]);
- uniforms.push_back(u);
- }
+ RD::get_singleton()->draw_list_bind_uniform_set(draw_list, sky_scene_state.uniform_set, 0);
+ if (p_uniform_set.is_valid()) { //material may not have uniform set
+ RD::get_singleton()->draw_list_bind_uniform_set(draw_list, p_uniform_set, 1);
}
+ RD::get_singleton()->draw_list_bind_uniform_set(draw_list, p_texture_set, 2);
+ RD::get_singleton()->draw_list_bind_uniform_set(draw_list, sky_scene_state.fog_uniform_set, 3);
- uniform_set = RD::get_singleton()->uniform_set_create(uniforms, scene_singleton->sky.sky_shader.shader.version_get_shader(shader_data->version, 0), SKY_SET_MATERIAL);
-}
+ RD::get_singleton()->draw_list_bind_index_array(draw_list, index_array);
-RendererSceneSkyRD::SkyMaterialData::~SkyMaterialData() {
- if (uniform_set.is_valid() && RD::get_singleton()->uniform_set_is_valid(uniform_set)) {
- RD::get_singleton()->free(uniform_set);
- }
+ RD::get_singleton()->draw_list_set_push_constant(draw_list, &sky_push_constant, sizeof(SkyPushConstant));
- if (uniform_buffer.is_valid()) {
- RD::get_singleton()->free(uniform_buffer);
- }
+ RD::get_singleton()->draw_list_draw(draw_list, true);
}
////////////////////////////////////////////////////////////////////////////////
@@ -623,7 +605,7 @@ Ref<Image> RendererSceneSkyRD::Sky::bake_panorama(RendererStorageRD *p_storage,
RD::get_singleton()->free(rad_tex);
Ref<Image> img;
- img.instance();
+ img.instantiate();
img->create(p_size.width, p_size.height, false, Image::FORMAT_RGBAF, data);
for (int i = 0; i < p_size.width; i++) {
for (int j = 0; j < p_size.height; j++) {
@@ -694,7 +676,18 @@ void RendererSceneSkyRD::init(RendererStorageRD *p_storage) {
sky_modes.push_back("\n#define USE_CUBEMAP_PASS\n"); // Cubemap
sky_modes.push_back("\n#define USE_CUBEMAP_PASS\n#define USE_HALF_RES_PASS\n"); // Half Res Cubemap
sky_modes.push_back("\n#define USE_CUBEMAP_PASS\n#define USE_QUARTER_RES_PASS\n"); // Quarter res Cubemap
+
+ sky_modes.push_back("\n#define USE_MULTIVIEW\n"); // Full size multiview
+ sky_modes.push_back("\n#define USE_HALF_RES_PASS\n#define USE_MULTIVIEW\n"); // Half Res multiview
+ sky_modes.push_back("\n#define USE_QUARTER_RES_PASS\n#define USE_MULTIVIEW\n"); // Quarter res multiview
+
sky_shader.shader.initialize(sky_modes, defines);
+
+ if (!RendererCompositorRD::singleton->is_xr_enabled()) {
+ sky_shader.shader.set_variant_enabled(SKY_VERSION_BACKGROUND_MULTIVIEW, false);
+ sky_shader.shader.set_variant_enabled(SKY_VERSION_HALF_RES_MULTIVIEW, false);
+ sky_shader.shader.set_variant_enabled(SKY_VERSION_QUARTER_RES_MULTIVIEW, false);
+ }
}
// register our shader funds
@@ -876,9 +869,44 @@ void RendererSceneSkyRD::init(RendererStorageRD *p_storage) {
sky_scene_state.fog_only_texture_uniform_set = RD::get_singleton()->uniform_set_create(uniforms, sky_shader.default_shader_rd, SKY_SET_TEXTURES);
}
+
+ { //create index array for copy shaders
+ Vector<uint8_t> pv;
+ pv.resize(6 * 4);
+ {
+ uint8_t *w = pv.ptrw();
+ int *p32 = (int *)w;
+ p32[0] = 0;
+ p32[1] = 1;
+ p32[2] = 2;
+ p32[3] = 0;
+ p32[4] = 2;
+ p32[5] = 3;
+ }
+ index_buffer = RD::get_singleton()->index_buffer_create(6, RenderingDevice::INDEX_BUFFER_FORMAT_UINT32, pv);
+ index_array = RD::get_singleton()->index_array_create(index_buffer, 0, 6);
+ }
+}
+
+RendererSceneSkyRD::~RendererSceneSkyRD() {
+ // TODO cleanup anything created in init...
+
+ if (RD::get_singleton()->uniform_set_is_valid(sky_scene_state.uniform_set)) {
+ RD::get_singleton()->free(sky_scene_state.uniform_set);
+ }
+
+ if (RD::get_singleton()->uniform_set_is_valid(sky_scene_state.default_fog_uniform_set)) {
+ RD::get_singleton()->free(sky_scene_state.default_fog_uniform_set);
+ }
+
+ if (RD::get_singleton()->uniform_set_is_valid(sky_scene_state.fog_only_texture_uniform_set)) {
+ RD::get_singleton()->free(sky_scene_state.fog_only_texture_uniform_set);
+ }
+
+ RD::get_singleton()->free(index_buffer); //array gets freed as dependency
}
-void RendererSceneSkyRD::setup(RendererSceneEnvironmentRD *p_env, RID p_render_buffers, const CameraMatrix &p_projection, const Transform &p_transform, const Size2i p_screen_size, RendererSceneRenderRD *p_scene_render) {
+void RendererSceneSkyRD::setup(RendererSceneEnvironmentRD *p_env, RID p_render_buffers, const CameraMatrix &p_projection, const Transform3D &p_transform, const Size2i p_screen_size, RendererSceneRenderRD *p_scene_render) {
ERR_FAIL_COND(!p_env); // I guess without an environment we also can't have a sky...
SkyMaterialData *material = nullptr;
@@ -1048,7 +1076,7 @@ void RendererSceneSkyRD::setup(RendererSceneEnvironmentRD *p_env, RID p_render_b
RD::get_singleton()->buffer_update(sky_scene_state.uniform_buffer, 0, sizeof(SkySceneState::UBO), &sky_scene_state.ubo);
}
-void RendererSceneSkyRD::update(RendererSceneEnvironmentRD *p_env, const CameraMatrix &p_projection, const Transform &p_transform, double p_time) {
+void RendererSceneSkyRD::update(RendererSceneEnvironmentRD *p_env, const CameraMatrix &p_projection, const Transform3D &p_transform, double p_time) {
ERR_FAIL_COND(!p_env);
Sky *sky = get_sky(p_env->sky);
@@ -1135,12 +1163,12 @@ void RendererSceneSkyRD::update(RendererSceneEnvironmentRD *p_env, const CameraM
RD::DrawListID cubemap_draw_list;
for (int i = 0; i < 6; i++) {
- Transform local_view;
+ Transform3D local_view;
local_view.set_look_at(Vector3(0, 0, 0), view_normals[i], view_up[i]);
RID texture_uniform_set = sky->get_textures(storage, SKY_TEXTURE_SET_CUBEMAP_QUARTER_RES, sky_shader.default_shader_rd);
cubemap_draw_list = RD::get_singleton()->draw_list_begin(sky->reflection.layers[0].mipmaps[2].framebuffers[i], RD::INITIAL_ACTION_KEEP, RD::FINAL_ACTION_READ, RD::INITIAL_ACTION_KEEP, RD::FINAL_ACTION_DISCARD);
- storage->get_effects()->render_sky(cubemap_draw_list, p_time, sky->reflection.layers[0].mipmaps[2].framebuffers[i], sky_scene_state.uniform_set, sky_scene_state.fog_uniform_set, pipeline, material->uniform_set, texture_uniform_set, cm, local_view.basis, multiplier, p_transform.origin);
+ _render_sky(cubemap_draw_list, p_time, sky->reflection.layers[0].mipmaps[2].framebuffers[i], pipeline, material->uniform_set, texture_uniform_set, 1, &cm, local_view.basis, multiplier, p_transform.origin);
RD::get_singleton()->draw_list_end();
}
}
@@ -1153,12 +1181,12 @@ void RendererSceneSkyRD::update(RendererSceneEnvironmentRD *p_env, const CameraM
RD::DrawListID cubemap_draw_list;
for (int i = 0; i < 6; i++) {
- Transform local_view;
+ Transform3D local_view;
local_view.set_look_at(Vector3(0, 0, 0), view_normals[i], view_up[i]);
RID texture_uniform_set = sky->get_textures(storage, SKY_TEXTURE_SET_CUBEMAP_HALF_RES, sky_shader.default_shader_rd);
cubemap_draw_list = RD::get_singleton()->draw_list_begin(sky->reflection.layers[0].mipmaps[1].framebuffers[i], RD::INITIAL_ACTION_KEEP, RD::FINAL_ACTION_READ, RD::INITIAL_ACTION_KEEP, RD::FINAL_ACTION_DISCARD);
- storage->get_effects()->render_sky(cubemap_draw_list, p_time, sky->reflection.layers[0].mipmaps[1].framebuffers[i], sky_scene_state.uniform_set, sky_scene_state.fog_uniform_set, pipeline, material->uniform_set, texture_uniform_set, cm, local_view.basis, multiplier, p_transform.origin);
+ _render_sky(cubemap_draw_list, p_time, sky->reflection.layers[0].mipmaps[1].framebuffers[i], pipeline, material->uniform_set, texture_uniform_set, 1, &cm, local_view.basis, multiplier, p_transform.origin);
RD::get_singleton()->draw_list_end();
}
}
@@ -1167,12 +1195,12 @@ void RendererSceneSkyRD::update(RendererSceneEnvironmentRD *p_env, const CameraM
PipelineCacheRD *pipeline = &shader_data->pipelines[SKY_VERSION_CUBEMAP];
for (int i = 0; i < 6; i++) {
- Transform local_view;
+ Transform3D local_view;
local_view.set_look_at(Vector3(0, 0, 0), view_normals[i], view_up[i]);
RID texture_uniform_set = sky->get_textures(storage, SKY_TEXTURE_SET_CUBEMAP, sky_shader.default_shader_rd);
cubemap_draw_list = RD::get_singleton()->draw_list_begin(sky->reflection.layers[0].mipmaps[0].framebuffers[i], RD::INITIAL_ACTION_KEEP, RD::FINAL_ACTION_READ, RD::INITIAL_ACTION_KEEP, RD::FINAL_ACTION_DISCARD);
- storage->get_effects()->render_sky(cubemap_draw_list, p_time, sky->reflection.layers[0].mipmaps[0].framebuffers[i], sky_scene_state.uniform_set, sky_scene_state.fog_uniform_set, pipeline, material->uniform_set, texture_uniform_set, cm, local_view.basis, multiplier, p_transform.origin);
+ _render_sky(cubemap_draw_list, p_time, sky->reflection.layers[0].mipmaps[0].framebuffers[i], pipeline, material->uniform_set, texture_uniform_set, 1, &cm, local_view.basis, multiplier, p_transform.origin);
RD::get_singleton()->draw_list_end();
}
@@ -1213,9 +1241,12 @@ void RendererSceneSkyRD::update(RendererSceneEnvironmentRD *p_env, const CameraM
}
}
-void RendererSceneSkyRD::draw(RendererSceneEnvironmentRD *p_env, bool p_can_continue_color, bool p_can_continue_depth, RID p_fb, const CameraMatrix &p_projection, const Transform &p_transform, double p_time) {
+void RendererSceneSkyRD::draw(RendererSceneEnvironmentRD *p_env, bool p_can_continue_color, bool p_can_continue_depth, RID p_fb, uint32_t p_view_count, const CameraMatrix *p_projections, const Transform3D &p_transform, double p_time) {
ERR_FAIL_COND(!p_env);
+ ERR_FAIL_COND(p_view_count == 0);
+ ERR_FAIL_COND(p_view_count > RendererSceneRender::MAX_RENDER_VIEWS);
+
Sky *sky = get_sky(p_env->sky);
ERR_FAIL_COND(!sky);
@@ -1257,24 +1288,28 @@ void RendererSceneSkyRD::draw(RendererSceneEnvironmentRD *p_env, bool p_can_cont
float multiplier = p_env->bg_energy;
float custom_fov = p_env->sky_custom_fov;
+
// Camera
CameraMatrix camera;
+ uint32_t view_count = p_view_count;
+ const CameraMatrix *projections = p_projections;
if (custom_fov) {
- float near_plane = p_projection.get_z_near();
- float far_plane = p_projection.get_z_far();
- float aspect = p_projection.get_aspect();
+ // With custom fov we don't support stereo...
+ float near_plane = p_projections[0].get_z_near();
+ float far_plane = p_projections[0].get_z_far();
+ float aspect = p_projections[0].get_aspect();
camera.set_perspective(custom_fov, aspect, near_plane, far_plane);
- } else {
- camera = p_projection;
+ view_count = 1;
+ projections = &camera;
}
sky_transform = p_transform.basis * sky_transform;
if (shader_data->uses_quarter_res) {
- PipelineCacheRD *pipeline = &shader_data->pipelines[SKY_VERSION_QUARTER_RES];
+ PipelineCacheRD *pipeline = &shader_data->pipelines[view_count > 1 ? SKY_VERSION_QUARTER_RES_MULTIVIEW : SKY_VERSION_QUARTER_RES];
RID texture_uniform_set = sky->get_textures(storage, SKY_TEXTURE_SET_QUARTER_RES, sky_shader.default_shader_rd);
@@ -1282,12 +1317,12 @@ void RendererSceneSkyRD::draw(RendererSceneEnvironmentRD *p_env, bool p_can_cont
clear_colors.push_back(Color(0.0, 0.0, 0.0));
RD::DrawListID draw_list = RD::get_singleton()->draw_list_begin(sky->quarter_res_framebuffer, RD::INITIAL_ACTION_CLEAR, RD::FINAL_ACTION_READ, RD::INITIAL_ACTION_CLEAR, RD::FINAL_ACTION_DISCARD, clear_colors);
- storage->get_effects()->render_sky(draw_list, p_time, sky->quarter_res_framebuffer, sky_scene_state.uniform_set, sky_scene_state.fog_uniform_set, pipeline, material->uniform_set, texture_uniform_set, camera, sky_transform, multiplier, p_transform.origin);
+ _render_sky(draw_list, p_time, sky->quarter_res_framebuffer, pipeline, material->uniform_set, texture_uniform_set, view_count, projections, sky_transform, multiplier, p_transform.origin);
RD::get_singleton()->draw_list_end();
}
if (shader_data->uses_half_res) {
- PipelineCacheRD *pipeline = &shader_data->pipelines[SKY_VERSION_HALF_RES];
+ PipelineCacheRD *pipeline = &shader_data->pipelines[view_count > 1 ? SKY_VERSION_HALF_RES_MULTIVIEW : SKY_VERSION_HALF_RES];
RID texture_uniform_set = sky->get_textures(storage, SKY_TEXTURE_SET_HALF_RES, sky_shader.default_shader_rd);
@@ -1295,11 +1330,11 @@ void RendererSceneSkyRD::draw(RendererSceneEnvironmentRD *p_env, bool p_can_cont
clear_colors.push_back(Color(0.0, 0.0, 0.0));
RD::DrawListID draw_list = RD::get_singleton()->draw_list_begin(sky->half_res_framebuffer, RD::INITIAL_ACTION_CLEAR, RD::FINAL_ACTION_READ, RD::INITIAL_ACTION_CLEAR, RD::FINAL_ACTION_DISCARD, clear_colors);
- storage->get_effects()->render_sky(draw_list, p_time, sky->half_res_framebuffer, sky_scene_state.uniform_set, sky_scene_state.fog_uniform_set, pipeline, material->uniform_set, texture_uniform_set, camera, sky_transform, multiplier, p_transform.origin);
+ _render_sky(draw_list, p_time, sky->half_res_framebuffer, pipeline, material->uniform_set, texture_uniform_set, view_count, projections, sky_transform, multiplier, p_transform.origin);
RD::get_singleton()->draw_list_end();
}
- PipelineCacheRD *pipeline = &shader_data->pipelines[SKY_VERSION_BACKGROUND];
+ PipelineCacheRD *pipeline = &shader_data->pipelines[view_count > 1 ? SKY_VERSION_BACKGROUND_MULTIVIEW : SKY_VERSION_BACKGROUND];
RID texture_uniform_set;
if (sky) {
@@ -1309,7 +1344,7 @@ void RendererSceneSkyRD::draw(RendererSceneEnvironmentRD *p_env, bool p_can_cont
}
RD::DrawListID draw_list = RD::get_singleton()->draw_list_begin(p_fb, RD::INITIAL_ACTION_CONTINUE, p_can_continue_color ? RD::FINAL_ACTION_CONTINUE : RD::FINAL_ACTION_READ, RD::INITIAL_ACTION_CONTINUE, p_can_continue_depth ? RD::FINAL_ACTION_CONTINUE : RD::FINAL_ACTION_READ);
- storage->get_effects()->render_sky(draw_list, p_time, p_fb, sky_scene_state.uniform_set, sky_scene_state.fog_uniform_set, pipeline, material->uniform_set, texture_uniform_set, camera, sky_transform, multiplier, p_transform.origin);
+ _render_sky(draw_list, p_time, p_fb, pipeline, material->uniform_set, texture_uniform_set, view_count, projections, sky_transform, multiplier, p_transform.origin);
RD::get_singleton()->draw_list_end();
}
diff --git a/servers/rendering/renderer_rd/renderer_scene_sky_rd.h b/servers/rendering/renderer_rd/renderer_scene_sky_rd.h
index 73390a586b..4f852e55a7 100644
--- a/servers/rendering/renderer_rd/renderer_scene_sky_rd.h
+++ b/servers/rendering/renderer_rd/renderer_scene_sky_rd.h
@@ -43,9 +43,6 @@
class RendererSceneRenderRD;
class RendererSceneSkyRD {
-private:
- RendererStorageRD *storage;
-
public:
enum SkySet {
SKY_SET_UNIFORMS,
@@ -55,6 +52,22 @@ public:
SKY_SET_MAX
};
+ // Skys need less info from Directional Lights than the normal shaders
+ struct SkyDirectionalLightData {
+ float direction[3];
+ float energy;
+ float color[3];
+ float size;
+ uint32_t enabled;
+ uint32_t pad[3];
+ };
+
+private:
+ RendererStorageRD *storage;
+
+ RID index_buffer;
+ RID index_array;
+
enum SkyTextureSetVersion {
SKY_TEXTURE_SET_BACKGROUND,
SKY_TEXTURE_SET_HALF_RES,
@@ -72,19 +85,61 @@ public:
SKY_VERSION_CUBEMAP,
SKY_VERSION_CUBEMAP_HALF_RES,
SKY_VERSION_CUBEMAP_QUARTER_RES,
+
+ SKY_VERSION_BACKGROUND_MULTIVIEW,
+ SKY_VERSION_HALF_RES_MULTIVIEW,
+ SKY_VERSION_QUARTER_RES_MULTIVIEW,
+
SKY_VERSION_MAX
};
- // Skys need less info from Directional Lights than the normal shaders
- struct SkyDirectionalLightData {
- float direction[3];
- float energy;
- float color[3];
- float size;
- uint32_t enabled;
- uint32_t pad[3];
+ struct SkyPushConstant {
+ float orientation[12]; // 48 - 48
+ float projections[RendererSceneRender::MAX_RENDER_VIEWS][4]; // 2 x 16 - 80
+ float position[3]; // 12 - 92
+ float multiplier; // 4 - 96
+ float time; // 4 - 100
+ float pad[3]; // 12 - 112 // Using pad to align on 16 bytes
+ // 128 is the max size of a push constant. We can replace "pad" but we can't add any more.
};
+ struct SkyShaderData : public RendererStorageRD::ShaderData {
+ bool valid;
+ RID version;
+
+ PipelineCacheRD pipelines[SKY_VERSION_MAX];
+ Map<StringName, ShaderLanguage::ShaderNode::Uniform> uniforms;
+ Vector<ShaderCompilerRD::GeneratedCode::Texture> texture_uniforms;
+
+ Vector<uint32_t> ubo_offsets;
+ uint32_t ubo_size;
+
+ String path;
+ String code;
+ Map<StringName, RID> default_texture_params;
+
+ bool uses_time;
+ bool uses_position;
+ bool uses_half_res;
+ bool uses_quarter_res;
+ bool uses_light;
+
+ virtual void set_code(const String &p_Code);
+ virtual void set_default_texture_param(const StringName &p_name, RID p_texture);
+ virtual void get_param_list(List<PropertyInfo> *p_param_list) const;
+ virtual void get_instance_param_list(List<RendererStorage::InstanceShaderParam> *p_param_list) const;
+ virtual bool is_param_texture(const StringName &p_param) const;
+ virtual bool is_animated() const;
+ virtual bool casts_shadows() const;
+ virtual Variant get_default_parameter(const StringName &p_parameter) const;
+ virtual RS::ShaderNativeSourceCode get_native_source_code() const;
+ SkyShaderData();
+ virtual ~SkyShaderData();
+ };
+
+ void _render_sky(RD::DrawListID p_list, float p_time, RID p_fb, PipelineCacheRD *p_pipeline, RID p_uniform_set, RID p_texture_set, uint32_t p_view_count, const CameraMatrix *p_projections, const Basis &p_orientation, float p_multiplier, const Vector3 &p_position);
+
+public:
struct SkySceneState {
struct UBO {
uint32_t volumetric_fog_enabled;
@@ -155,40 +210,6 @@ public:
void update_reflection_mipmaps(RendererStorageRD *p_storage, int p_start, int p_end);
};
- struct SkyShaderData : public RendererStorageRD::ShaderData {
- bool valid;
- RID version;
-
- PipelineCacheRD pipelines[SKY_VERSION_MAX];
- Map<StringName, ShaderLanguage::ShaderNode::Uniform> uniforms;
- Vector<ShaderCompilerRD::GeneratedCode::Texture> texture_uniforms;
-
- Vector<uint32_t> ubo_offsets;
- uint32_t ubo_size;
-
- String path;
- String code;
- Map<StringName, RID> default_texture_params;
-
- bool uses_time;
- bool uses_position;
- bool uses_half_res;
- bool uses_quarter_res;
- bool uses_light;
-
- virtual void set_code(const String &p_Code);
- virtual void set_default_texture_param(const StringName &p_name, RID p_texture);
- virtual void get_param_list(List<PropertyInfo> *p_param_list) const;
- virtual void get_instance_param_list(List<RendererStorage::InstanceShaderParam> *p_param_list) const;
- virtual bool is_param_texture(const StringName &p_param) const;
- virtual bool is_animated() const;
- virtual bool casts_shadows() const;
- virtual Variant get_default_parameter(const StringName &p_parameter) const;
- virtual RS::ShaderNativeSourceCode get_native_source_code() const;
- SkyShaderData();
- virtual ~SkyShaderData();
- };
-
/* Sky shader */
struct SkyShader {
@@ -203,15 +224,12 @@ public:
struct SkyMaterialData : public RendererStorageRD::MaterialData {
uint64_t last_frame;
SkyShaderData *shader_data;
- RID uniform_buffer;
RID uniform_set;
- Vector<RID> texture_cache;
- Vector<uint8_t> ubo_data;
bool uniform_set_updated;
virtual void set_render_priority(int p_priority) {}
virtual void set_next_pass(RID p_pass) {}
- virtual void update_parameters(const Map<StringName, Variant> &p_parameters, bool p_uniform_dirty, bool p_textures_dirty);
+ virtual bool update_parameters(const Map<StringName, Variant> &p_parameters, bool p_uniform_dirty, bool p_textures_dirty);
virtual ~SkyMaterialData();
};
@@ -265,12 +283,12 @@ public:
static RendererStorageRD::MaterialData *_create_sky_material_funcs(RendererStorageRD::ShaderData *p_shader);
RendererSceneSkyRD();
-
void init(RendererStorageRD *p_storage);
+ ~RendererSceneSkyRD();
- void setup(RendererSceneEnvironmentRD *p_env, RID p_render_buffers, const CameraMatrix &p_projection, const Transform &p_transform, const Size2i p_screen_size, RendererSceneRenderRD *p_scene_render);
- void update(RendererSceneEnvironmentRD *p_env, const CameraMatrix &p_projection, const Transform &p_transform, double p_time);
- void draw(RendererSceneEnvironmentRD *p_env, bool p_can_continue_color, bool p_can_continue_depth, RID p_fb, const CameraMatrix &p_projection, const Transform &p_transform, double p_time);
+ void setup(RendererSceneEnvironmentRD *p_env, RID p_render_buffers, const CameraMatrix &p_projection, const Transform3D &p_transform, const Size2i p_screen_size, RendererSceneRenderRD *p_scene_render);
+ void update(RendererSceneEnvironmentRD *p_env, const CameraMatrix &p_projection, const Transform3D &p_transform, double p_time);
+ void draw(RendererSceneEnvironmentRD *p_env, bool p_can_continue_color, bool p_can_continue_depth, RID p_fb, uint32_t p_view_count, const CameraMatrix *p_projections, const Transform3D &p_transform, double p_time);
void invalidate_sky(Sky *p_sky);
void update_dirty_skys();
diff --git a/servers/rendering/renderer_rd/renderer_storage_rd.cpp b/servers/rendering/renderer_rd/renderer_storage_rd.cpp
index 7a26e40c0a..6738f499bd 100644
--- a/servers/rendering/renderer_rd/renderer_storage_rd.cpp
+++ b/servers/rendering/renderer_rd/renderer_storage_rd.cpp
@@ -35,6 +35,7 @@
#include "core/io/resource_loader.h"
#include "core/math/math_defs.h"
#include "renderer_compositor_rd.h"
+#include "servers/rendering/rendering_server_globals.h"
#include "servers/rendering/shader_language.h"
bool RendererStorageRD::can_create_resources_async() const {
@@ -883,10 +884,6 @@ void RendererStorageRD::_texture_2d_update(RID p_texture, const Ref<Image> &p_im
RD::get_singleton()->texture_update(tex->rd_texture, p_layer, validated->get_data());
}
-void RendererStorageRD::texture_2d_update_immediate(RID p_texture, const Ref<Image> &p_image, int p_layer) {
- _texture_2d_update(p_texture, p_image, p_layer, true);
-}
-
void RendererStorageRD::texture_2d_update(RID p_texture, const Ref<Image> &p_image, int p_layer) {
_texture_2d_update(p_texture, p_image, p_layer, false);
}
@@ -972,7 +969,7 @@ void RendererStorageRD::texture_2d_placeholder_initialize(RID p_texture) {
//this could be better optimized to reuse an existing image , done this way
//for now to get it working
Ref<Image> image;
- image.instance();
+ image.instantiate();
image->create(4, 4, false, Image::FORMAT_RGBA8);
for (int i = 0; i < 4; i++) {
@@ -988,7 +985,7 @@ void RendererStorageRD::texture_2d_layered_placeholder_initialize(RID p_texture,
//this could be better optimized to reuse an existing image , done this way
//for now to get it working
Ref<Image> image;
- image.instance();
+ image.instantiate();
image->create(4, 4, false, Image::FORMAT_RGBA8);
for (int i = 0; i < 4; i++) {
@@ -1014,7 +1011,7 @@ void RendererStorageRD::texture_3d_placeholder_initialize(RID p_texture) {
//this could be better optimized to reuse an existing image , done this way
//for now to get it working
Ref<Image> image;
- image.instance();
+ image.instantiate();
image->create(4, 4, false, Image::FORMAT_RGBA8);
for (int i = 0; i < 4; i++) {
@@ -1044,7 +1041,7 @@ Ref<Image> RendererStorageRD::texture_2d_get(RID p_texture) const {
Vector<uint8_t> data = RD::get_singleton()->texture_get_data(tex->rd_texture, 0);
ERR_FAIL_COND_V(data.size() == 0, Ref<Image>());
Ref<Image> image;
- image.instance();
+ image.instantiate();
image->create(tex->width, tex->height, tex->mipmaps > 1, tex->validated_format, data);
ERR_FAIL_COND_V(image->is_empty(), Ref<Image>());
if (tex->format != tex->validated_format) {
@@ -1067,7 +1064,7 @@ Ref<Image> RendererStorageRD::texture_2d_layer_get(RID p_texture, int p_layer) c
Vector<uint8_t> data = RD::get_singleton()->texture_get_data(tex->rd_texture, p_layer);
ERR_FAIL_COND_V(data.size() == 0, Ref<Image>());
Ref<Image> image;
- image.instance();
+ image.instantiate();
image->create(tex->width, tex->height, tex->mipmaps > 1, tex->validated_format, data);
ERR_FAIL_COND_V(image->is_empty(), Ref<Image>());
if (tex->format != tex->validated_format) {
@@ -1095,7 +1092,7 @@ Vector<Ref<Image>> RendererStorageRD::texture_3d_get(RID p_texture) const {
Vector<uint8_t> sub_region = all_data.subarray(bs.offset, bs.offset + bs.buffer_size - 1);
Ref<Image> img;
- img.instance();
+ img.instantiate();
img->create(bs.size.width, bs.size.height, false, tex->validated_format, sub_region);
ERR_FAIL_COND_V(img->is_empty(), Vector<Ref<Image>>());
if (tex->format != tex->validated_format) {
@@ -1234,7 +1231,7 @@ RID RendererStorageRD::canvas_texture_allocate() {
return canvas_texture_owner.allocate_rid();
}
void RendererStorageRD::canvas_texture_initialize(RID p_rid) {
- canvas_texture_owner.initialize_rid(p_rid, memnew(CanvasTexture));
+ canvas_texture_owner.initialize_rid(p_rid);
}
void RendererStorageRD::canvas_texture_set_channel(RID p_canvas_texture, RS::CanvasTextureChannel p_channel, RID p_texture) {
@@ -1440,8 +1437,10 @@ void RendererStorageRD::shader_set_code(RID p_shader, const String &p_code) {
material->shader_type = new_type;
}
- for (Map<StringName, RID>::Element *E = shader->default_texture_parameter.front(); E; E = E->next()) {
- shader->data->set_default_texture_param(E->key(), E->get());
+ if (shader->data) {
+ for (Map<StringName, RID>::Element *E = shader->default_texture_parameter.front(); E; E = E->next()) {
+ shader->data->set_default_texture_param(E->key(), E->get());
+ }
}
}
@@ -1527,27 +1526,18 @@ RID RendererStorageRD::material_allocate() {
return material_owner.allocate_rid();
}
void RendererStorageRD::material_initialize(RID p_rid) {
- Material material;
- material.data = nullptr;
- material.shader = nullptr;
- material.shader_type = SHADER_TYPE_MAX;
- material.update_next = nullptr;
- material.update_requested = false;
- material.uniform_dirty = false;
- material.texture_dirty = false;
- material.priority = 0;
- material.self = p_rid;
- material_owner.initialize_rid(p_rid, material);
+ material_owner.initialize_rid(p_rid);
+ Material *material = material_owner.getornull(p_rid);
+ material->self = p_rid;
}
void RendererStorageRD::_material_queue_update(Material *material, bool p_uniform, bool p_texture) {
- if (material->update_requested) {
+ if (material->update_element.in_list()) {
return;
}
- material->update_next = material_update_list;
- material_update_list = material;
- material->update_requested = true;
+ material_update_list.add(&material->update_element);
+
material->uniform_dirty = material->uniform_dirty || p_uniform;
material->texture_dirty = material->texture_dirty || p_texture;
}
@@ -1602,6 +1592,7 @@ void RendererStorageRD::material_set_param(RID p_material, const StringName &p_p
if (p_value.get_type() == Variant::NIL) {
material->params.erase(p_param);
} else {
+ ERR_FAIL_COND(p_value.get_type() == Variant::OBJECT); //object not allowed
material->params[p_param] = p_value;
}
@@ -1878,8 +1869,8 @@ _FORCE_INLINE_ static void _fill_std140_variant_ubo_value(ShaderLanguage::DataTy
gui[1] = v.position.y;
gui[2] = v.size.x;
gui[3] = v.size.y;
- } else if (value.get_type() == Variant::QUAT) {
- Quat v = value;
+ } else if (value.get_type() == Variant::QUATERNION) {
+ Quaternion v = value;
gui[0] = v.x;
gui[1] = v.y;
@@ -1926,7 +1917,7 @@ _FORCE_INLINE_ static void _fill_std140_variant_ubo_value(ShaderLanguage::DataTy
gui[11] = 0;
} break;
case ShaderLanguage::TYPE_MAT4: {
- Transform v = value;
+ Transform3D v = value;
float *gui = (float *)data;
gui[0] = v.basis.elements[0][0];
@@ -2233,6 +2224,10 @@ RendererStorageRD::MaterialData::~MaterialData() {
//unregister material from those using global textures
rs->global_variables.materials_using_texture.erase(global_texture_E);
}
+
+ if (uniform_buffer.is_valid()) {
+ RD::get_singleton()->free(uniform_buffer);
+ }
}
void RendererStorageRD::MaterialData::update_textures(const Map<StringName, Variant> &p_parameters, const Map<StringName, RID> &p_default_textures, const Vector<ShaderCompilerRD::GeneratedCode::Texture> &p_texture_uniforms, RID *p_textures, bool p_use_linear_color) {
@@ -2382,6 +2377,105 @@ void RendererStorageRD::MaterialData::update_textures(const Map<StringName, Vari
}
}
+void RendererStorageRD::MaterialData::free_parameters_uniform_set(RID p_uniform_set) {
+ if (p_uniform_set.is_valid() && RD::get_singleton()->uniform_set_is_valid(p_uniform_set)) {
+ RD::get_singleton()->uniform_set_set_invalidation_callback(p_uniform_set, nullptr, nullptr);
+ RD::get_singleton()->free(p_uniform_set);
+ }
+}
+
+bool RendererStorageRD::MaterialData::update_parameters_uniform_set(const Map<StringName, Variant> &p_parameters, bool p_uniform_dirty, bool p_textures_dirty, const Map<StringName, ShaderLanguage::ShaderNode::Uniform> &p_uniforms, const uint32_t *p_uniform_offsets, const Vector<ShaderCompilerRD::GeneratedCode::Texture> &p_texture_uniforms, const Map<StringName, RID> &p_default_texture_params, uint32_t p_ubo_size, RID &uniform_set, RID p_shader, uint32_t p_shader_uniform_set, uint32_t p_barrier) {
+ if ((uint32_t)ubo_data.size() != p_ubo_size) {
+ p_uniform_dirty = true;
+ if (uniform_buffer.is_valid()) {
+ RD::get_singleton()->free(uniform_buffer);
+ uniform_buffer = RID();
+ }
+
+ ubo_data.resize(p_ubo_size);
+ if (ubo_data.size()) {
+ uniform_buffer = RD::get_singleton()->uniform_buffer_create(ubo_data.size());
+ memset(ubo_data.ptrw(), 0, ubo_data.size()); //clear
+ }
+
+ //clear previous uniform set
+ if (uniform_set.is_valid() && RD::get_singleton()->uniform_set_is_valid(uniform_set)) {
+ RD::get_singleton()->uniform_set_set_invalidation_callback(uniform_set, nullptr, nullptr);
+ RD::get_singleton()->free(uniform_set);
+ uniform_set = RID();
+ }
+ }
+
+ //check whether buffer changed
+ if (p_uniform_dirty && ubo_data.size()) {
+ update_uniform_buffer(p_uniforms, p_uniform_offsets, p_parameters, ubo_data.ptrw(), ubo_data.size(), false);
+ RD::get_singleton()->buffer_update(uniform_buffer, 0, ubo_data.size(), ubo_data.ptrw(), p_barrier);
+ }
+
+ uint32_t tex_uniform_count = p_texture_uniforms.size();
+
+ if ((uint32_t)texture_cache.size() != tex_uniform_count || p_textures_dirty) {
+ texture_cache.resize(tex_uniform_count);
+ p_textures_dirty = true;
+
+ //clear previous uniform set
+ if (uniform_set.is_valid() && RD::get_singleton()->uniform_set_is_valid(uniform_set)) {
+ RD::get_singleton()->uniform_set_set_invalidation_callback(uniform_set, nullptr, nullptr);
+ RD::get_singleton()->free(uniform_set);
+ uniform_set = RID();
+ }
+ }
+
+ if (p_textures_dirty && tex_uniform_count) {
+ update_textures(p_parameters, p_default_texture_params, p_texture_uniforms, texture_cache.ptrw(), true);
+ }
+
+ if (p_ubo_size == 0 && p_texture_uniforms.size() == 0) {
+ // This material does not require an uniform set, so don't create it.
+ return false;
+ }
+
+ if (!p_textures_dirty && uniform_set.is_valid() && RD::get_singleton()->uniform_set_is_valid(uniform_set)) {
+ //no reason to update uniform set, only UBO (or nothing) was needed to update
+ return false;
+ }
+
+ Vector<RD::Uniform> uniforms;
+
+ {
+ if (p_ubo_size) {
+ RD::Uniform u;
+ u.uniform_type = RD::UNIFORM_TYPE_UNIFORM_BUFFER;
+ u.binding = 0;
+ u.ids.push_back(uniform_buffer);
+ uniforms.push_back(u);
+ }
+
+ const RID *textures = texture_cache.ptrw();
+ for (uint32_t i = 0; i < tex_uniform_count; i++) {
+ RD::Uniform u;
+ u.uniform_type = RD::UNIFORM_TYPE_TEXTURE;
+ u.binding = 1 + i;
+ u.ids.push_back(textures[i]);
+ uniforms.push_back(u);
+ }
+ }
+
+ uniform_set = RD::get_singleton()->uniform_set_create(uniforms, p_shader, p_shader_uniform_set);
+
+ RD::get_singleton()->uniform_set_set_invalidation_callback(uniform_set, _material_uniform_set_erased, &self);
+
+ return true;
+}
+
+void RendererStorageRD::_material_uniform_set_erased(const RID &p_set, void *p_material) {
+ RID rid = *(RID *)p_material;
+ Material *material = base_singleton->material_owner.getornull(rid);
+ if (material) {
+ material->dependency.changed_notify(DEPENDENCY_CHANGED_MATERIAL);
+ }
+}
+
void RendererStorageRD::material_force_update_textures(RID p_material, ShaderType p_shader_type) {
Material *material = material_owner.getornull(p_material);
if (material->shader_type != p_shader_type) {
@@ -2393,20 +2487,23 @@ void RendererStorageRD::material_force_update_textures(RID p_material, ShaderTyp
}
void RendererStorageRD::_update_queued_materials() {
- Material *material = material_update_list;
- while (material) {
- Material *next = material->update_next;
+ while (material_update_list.first()) {
+ Material *material = material_update_list.first()->self();
+ bool uniforms_changed = false;
if (material->data) {
- material->data->update_parameters(material->params, material->uniform_dirty, material->texture_dirty);
+ uniforms_changed = material->data->update_parameters(material->params, material->uniform_dirty, material->texture_dirty);
}
- material->update_requested = false;
material->texture_dirty = false;
material->uniform_dirty = false;
- material->update_next = nullptr;
- material = next;
+
+ material_update_list.remove(&material->update_element);
+
+ if (uniforms_changed) {
+ //some implementations such as 3D renderer cache the matreial uniform set, so update is required
+ material->dependency.changed_notify(DEPENDENCY_CHANGED_MATERIAL);
+ }
}
- material_update_list = nullptr;
}
/* MESH API */
@@ -2461,7 +2558,7 @@ void RendererStorageRD::mesh_add_surface(RID p_mesh, const RS::SurfaceData &p_su
} break;
case RS::ARRAY_COLOR: {
- attrib_stride += sizeof(int16_t) * 4;
+ attrib_stride += sizeof(uint32_t);
} break;
case RS::ARRAY_TEX_UV: {
attrib_stride += sizeof(float) * 2;
@@ -2549,6 +2646,7 @@ void RendererStorageRD::mesh_add_surface(RID p_mesh, const RS::SurfaceData &p_su
s->lods[i].index_buffer = RD::get_singleton()->index_buffer_create(indices, is_index_16 ? RD::INDEX_BUFFER_FORMAT_UINT16 : RD::INDEX_BUFFER_FORMAT_UINT32, p_surface.lods[i].index_data);
s->lods[i].index_array = RD::get_singleton()->index_array_create(s->lods[i].index_buffer, 0, indices);
s->lods[i].edge_length = p_surface.lods[i].edge_length;
+ s->lods[i].index_count = indices;
}
}
}
@@ -2653,7 +2751,7 @@ RS::BlendShapeMode RendererStorageRD::mesh_get_blend_shape_mode(RID p_mesh) cons
return mesh->blend_shape_mode;
}
-void RendererStorageRD::mesh_surface_update_region(RID p_mesh, int p_surface, int p_offset, const Vector<uint8_t> &p_data) {
+void RendererStorageRD::mesh_surface_update_vertex_region(RID p_mesh, int p_surface, int p_offset, const Vector<uint8_t> &p_data) {
Mesh *mesh = mesh_owner.getornull(p_mesh);
ERR_FAIL_COND(!mesh);
ERR_FAIL_UNSIGNED_INDEX((uint32_t)p_surface, mesh->surface_count);
@@ -2664,6 +2762,30 @@ void RendererStorageRD::mesh_surface_update_region(RID p_mesh, int p_surface, in
RD::get_singleton()->buffer_update(mesh->surfaces[p_surface]->vertex_buffer, p_offset, data_size, r);
}
+void RendererStorageRD::mesh_surface_update_attribute_region(RID p_mesh, int p_surface, int p_offset, const Vector<uint8_t> &p_data) {
+ Mesh *mesh = mesh_owner.getornull(p_mesh);
+ ERR_FAIL_COND(!mesh);
+ ERR_FAIL_UNSIGNED_INDEX((uint32_t)p_surface, mesh->surface_count);
+ ERR_FAIL_COND(p_data.size() == 0);
+ ERR_FAIL_COND(mesh->surfaces[p_surface]->attribute_buffer.is_null());
+ uint64_t data_size = p_data.size();
+ const uint8_t *r = p_data.ptr();
+
+ RD::get_singleton()->buffer_update(mesh->surfaces[p_surface]->attribute_buffer, p_offset, data_size, r);
+}
+
+void RendererStorageRD::mesh_surface_update_skin_region(RID p_mesh, int p_surface, int p_offset, const Vector<uint8_t> &p_data) {
+ Mesh *mesh = mesh_owner.getornull(p_mesh);
+ ERR_FAIL_COND(!mesh);
+ ERR_FAIL_UNSIGNED_INDEX((uint32_t)p_surface, mesh->surface_count);
+ ERR_FAIL_COND(p_data.size() == 0);
+ ERR_FAIL_COND(mesh->surfaces[p_surface]->skin_buffer.is_null());
+ uint64_t data_size = p_data.size();
+ const uint8_t *r = p_data.ptr();
+
+ RD::get_singleton()->buffer_update(mesh->surfaces[p_surface]->skin_buffer, p_offset, data_size, r);
+}
+
void RendererStorageRD::mesh_surface_set_material(RID p_mesh, int p_surface, RID p_material) {
Mesh *mesh = mesh_owner.getornull(p_mesh);
ERR_FAIL_COND(!mesh);
@@ -2776,7 +2898,7 @@ AABB RendererStorageRD::mesh_get_aabb(RID p_mesh, RID p_skeleton) {
const float *dataptr = baseptr + j * 8;
- Transform mtx;
+ Transform3D mtx;
mtx.basis.elements[0].x = dataptr[0];
mtx.basis.elements[1].x = dataptr[1];
@@ -2803,7 +2925,7 @@ AABB RendererStorageRD::mesh_get_aabb(RID p_mesh, RID p_skeleton) {
const float *dataptr = baseptr + j * 12;
- Transform mtx;
+ Transform3D mtx;
mtx.basis.elements[0][0] = dataptr[0];
mtx.basis.elements[0][1] = dataptr[1];
@@ -2932,7 +3054,8 @@ RID RendererStorageRD::mesh_instance_create(RID p_base) {
Mesh *mesh = mesh_owner.getornull(p_base);
ERR_FAIL_COND_V(!mesh, RID());
- MeshInstance *mi = memnew(MeshInstance);
+ RID rid = mesh_instance_owner.make_rid();
+ MeshInstance *mi = mesh_instance_owner.getornull(rid);
mi->mesh = mesh;
@@ -2944,7 +3067,7 @@ RID RendererStorageRD::mesh_instance_create(RID p_base) {
mi->dirty = true;
- return mesh_instance_owner.make_rid(mi);
+ return rid;
}
void RendererStorageRD::mesh_instance_set_skeleton(RID p_mesh_instance, RID p_skeleton) {
MeshInstance *mi = mesh_instance_owner.getornull(p_mesh_instance);
@@ -3231,8 +3354,8 @@ void RendererStorageRD::_mesh_surface_generate_version_for_input_mask(Mesh::Surf
case RS::ARRAY_COLOR: {
vd.offset = attribute_stride;
- vd.format = RD::DATA_FORMAT_R16G16B16A16_SFLOAT;
- attribute_stride += sizeof(int16_t) * 4;
+ vd.format = RD::DATA_FORMAT_R8G8B8A8_UNORM;
+ attribute_stride += sizeof(int8_t) * 4;
buffer = s->attribute_buffer;
} break;
case RS::ARRAY_TEX_UV: {
@@ -3478,7 +3601,7 @@ void RendererStorageRD::_multimesh_re_create_aabb(MultiMesh *multimesh, const fl
AABB mesh_aabb = mesh_get_aabb(multimesh->mesh);
for (int i = 0; i < p_instances; i++) {
const float *data = p_data + multimesh->stride_cache * i;
- Transform t;
+ Transform3D t;
if (multimesh->xform_format == RS::MULTIMESH_TRANSFORM_3D) {
t.basis.elements[0][0] = data[0];
@@ -3514,7 +3637,7 @@ void RendererStorageRD::_multimesh_re_create_aabb(MultiMesh *multimesh, const fl
multimesh->aabb = aabb;
}
-void RendererStorageRD::multimesh_instance_set_transform(RID p_multimesh, int p_index, const Transform &p_transform) {
+void RendererStorageRD::multimesh_instance_set_transform(RID p_multimesh, int p_index, const Transform3D &p_transform) {
MultiMesh *multimesh = multimesh_owner.getornull(p_multimesh);
ERR_FAIL_COND(!multimesh);
ERR_FAIL_INDEX(p_index, multimesh->instances);
@@ -3621,15 +3744,15 @@ RID RendererStorageRD::multimesh_get_mesh(RID p_multimesh) const {
return multimesh->mesh;
}
-Transform RendererStorageRD::multimesh_instance_get_transform(RID p_multimesh, int p_index) const {
+Transform3D RendererStorageRD::multimesh_instance_get_transform(RID p_multimesh, int p_index) const {
MultiMesh *multimesh = multimesh_owner.getornull(p_multimesh);
- ERR_FAIL_COND_V(!multimesh, Transform());
- ERR_FAIL_INDEX_V(p_index, multimesh->instances, Transform());
- ERR_FAIL_COND_V(multimesh->xform_format != RS::MULTIMESH_TRANSFORM_3D, Transform());
+ ERR_FAIL_COND_V(!multimesh, Transform3D());
+ ERR_FAIL_INDEX_V(p_index, multimesh->instances, Transform3D());
+ ERR_FAIL_COND_V(multimesh->xform_format != RS::MULTIMESH_TRANSFORM_3D, Transform3D());
_multimesh_make_local(multimesh);
- Transform t;
+ Transform3D t;
{
const float *r = multimesh->data_cache.ptr();
@@ -3823,7 +3946,7 @@ void RendererStorageRD::_update_dirty_multimeshes() {
if (multimesh->data_cache_used_dirty_regions) {
uint32_t data_cache_dirty_region_count = (multimesh->instances - 1) / MULTIMESH_DIRTY_REGION_SIZE + 1;
- uint32_t visible_region_count = (visible_instances - 1) / MULTIMESH_DIRTY_REGION_SIZE + 1;
+ uint32_t visible_region_count = visible_instances == 0 ? 0 : (visible_instances - 1) / MULTIMESH_DIRTY_REGION_SIZE + 1;
uint32_t region_size = multimesh->stride_cache * MULTIMESH_DIRTY_REGION_SIZE * sizeof(float);
@@ -3894,6 +4017,7 @@ void RendererStorageRD::particles_set_emitting(RID p_particles, bool p_emitting)
}
bool RendererStorageRD::particles_get_emitting(RID p_particles) {
+ ERR_FAIL_COND_V_MSG(RSG::threaded, false, "This function should never be used with threaded rendering, as it stalls the renderer.");
Particles *particles = particles_owner.getornull(p_particles);
ERR_FAIL_COND_V(!particles, false);
@@ -4065,7 +4189,7 @@ void RendererStorageRD::particles_set_trails(RID p_particles, bool p_enable, flo
particles->dependency.changed_notify(DEPENDENCY_CHANGED_PARTICLES);
}
-void RendererStorageRD::particles_set_trail_bind_poses(RID p_particles, const Vector<Transform> &p_bind_poses) {
+void RendererStorageRD::particles_set_trail_bind_poses(RID p_particles, const Vector<Transform3D> &p_bind_poses) {
Particles *particles = particles_owner.getornull(p_particles);
ERR_FAIL_COND(!particles);
if (particles->trail_bind_pose_buffer.is_valid() && particles->trail_bind_poses.size() != p_bind_poses.size()) {
@@ -4161,7 +4285,7 @@ void RendererStorageRD::particles_set_subemitter(RID p_particles, RID p_subemitt
}
}
-void RendererStorageRD::particles_emit(RID p_particles, const Transform &p_transform, const Vector3 &p_velocity, const Color &p_color, const Color &p_custom, uint32_t p_emit_flags) {
+void RendererStorageRD::particles_emit(RID p_particles, const Transform3D &p_transform, const Vector3 &p_velocity, const Color &p_color, const Color &p_custom, uint32_t p_emit_flags) {
Particles *particles = particles_owner.getornull(p_particles);
ERR_FAIL_COND(!particles);
ERR_FAIL_COND(particles->amount == 0);
@@ -4216,6 +4340,10 @@ void RendererStorageRD::particles_request_process(RID p_particles) {
}
AABB RendererStorageRD::particles_get_current_aabb(RID p_particles) {
+ if (RSG::threaded) {
+ WARN_PRINT_ONCE("Calling this function with threaded rendering enabled stalls the renderer, use with care.");
+ }
+
const Particles *particles = particles_owner.getornull(p_particles);
ERR_FAIL_COND_V(!particles, AABB());
@@ -4229,7 +4357,7 @@ AABB RendererStorageRD::particles_get_current_aabb(RID p_particles) {
Vector<uint8_t> buffer = RD::get_singleton()->buffer_get_data(particles->particle_buffer);
- Transform inv = particles->emission_transform.affine_inverse();
+ Transform3D inv = particles->emission_transform.affine_inverse();
AABB aabb;
if (buffer.size()) {
@@ -4272,7 +4400,7 @@ AABB RendererStorageRD::particles_get_aabb(RID p_particles) const {
return particles->custom_aabb;
}
-void RendererStorageRD::particles_set_emission_transform(RID p_particles, const Transform &p_transform) {
+void RendererStorageRD::particles_set_emission_transform(RID p_particles, const Transform3D &p_transform) {
Particles *particles = particles_owner.getornull(p_particles);
ERR_FAIL_COND(!particles);
@@ -4396,7 +4524,7 @@ void RendererStorageRD::_particles_process(Particles *p_particles, float p_delta
frame_params.randomness = p_particles->randomness;
if (p_particles->use_local_coords) {
- store_transform(Transform(), frame_params.emission_transform);
+ store_transform(Transform3D(), frame_params.emission_transform);
} else {
store_transform(p_particles->emission_transform, frame_params.emission_transform);
}
@@ -4416,7 +4544,7 @@ void RendererStorageRD::_particles_process(Particles *p_particles, float p_delta
RID collision_3d_textures[ParticlesFrameParams::MAX_3D_TEXTURES];
RID collision_heightmap_texture;
- Transform to_particles;
+ Transform3D to_particles;
if (p_particles->use_local_coords) {
to_particles = p_particles->emission_transform.affine_inverse();
}
@@ -4473,7 +4601,7 @@ void RendererStorageRD::_particles_process(Particles *p_particles, float p_delta
ParticlesCollision *pc = particles_collision_owner.getornull(pci->collision);
ERR_CONTINUE(!pc);
- Transform to_collider = pci->transform;
+ Transform3D to_collider = pci->transform;
if (p_particles->use_local_coords) {
to_collider = to_particles * to_collider;
}
@@ -5100,6 +5228,7 @@ void RendererStorageRD::update_particles() {
}
bool RendererStorageRD::particles_is_inactive(RID p_particles) const {
+ ERR_FAIL_COND_V_MSG(RSG::threaded, false, "This function should never be used with threaded rendering, as it stalls the renderer.");
const Particles *particles = particles_owner.getornull(p_particles);
ERR_FAIL_COND_V(!particles, false);
return !particles->emitting && particles->inactive;
@@ -5250,94 +5379,14 @@ RendererStorageRD::ShaderData *RendererStorageRD::_create_particles_shader_func(
return shader_data;
}
-void RendererStorageRD::ParticlesMaterialData::update_parameters(const Map<StringName, Variant> &p_parameters, bool p_uniform_dirty, bool p_textures_dirty) {
+bool RendererStorageRD::ParticlesMaterialData::update_parameters(const Map<StringName, Variant> &p_parameters, bool p_uniform_dirty, bool p_textures_dirty) {
uniform_set_updated = true;
- if ((uint32_t)ubo_data.size() != shader_data->ubo_size) {
- p_uniform_dirty = true;
- if (uniform_buffer.is_valid()) {
- RD::get_singleton()->free(uniform_buffer);
- uniform_buffer = RID();
- }
-
- ubo_data.resize(shader_data->ubo_size);
- if (ubo_data.size()) {
- uniform_buffer = RD::get_singleton()->uniform_buffer_create(ubo_data.size());
- memset(ubo_data.ptrw(), 0, ubo_data.size()); //clear
- }
-
- //clear previous uniform set
- if (uniform_set.is_valid() && RD::get_singleton()->uniform_set_is_valid(uniform_set)) {
- RD::get_singleton()->free(uniform_set);
- uniform_set = RID();
- }
- }
-
- //check whether buffer changed
- if (p_uniform_dirty && ubo_data.size()) {
- update_uniform_buffer(shader_data->uniforms, shader_data->ubo_offsets.ptr(), p_parameters, ubo_data.ptrw(), ubo_data.size(), false);
- RD::get_singleton()->buffer_update(uniform_buffer, 0, ubo_data.size(), ubo_data.ptrw());
- }
-
- uint32_t tex_uniform_count = shader_data->texture_uniforms.size();
-
- if ((uint32_t)texture_cache.size() != tex_uniform_count) {
- texture_cache.resize(tex_uniform_count);
- p_textures_dirty = true;
-
- //clear previous uniform set
- if (uniform_set.is_valid() && RD::get_singleton()->uniform_set_is_valid(uniform_set)) {
- RD::get_singleton()->free(uniform_set);
- uniform_set = RID();
- }
- }
-
- if (p_textures_dirty && tex_uniform_count) {
- update_textures(p_parameters, shader_data->default_texture_params, shader_data->texture_uniforms, texture_cache.ptrw(), true);
- }
-
- if (shader_data->ubo_size == 0 && shader_data->texture_uniforms.size() == 0) {
- // This material does not require an uniform set, so don't create it.
- return;
- }
-
- if (!p_textures_dirty && uniform_set.is_valid() && RD::get_singleton()->uniform_set_is_valid(uniform_set)) {
- //no reason to update uniform set, only UBO (or nothing) was needed to update
- return;
- }
-
- Vector<RD::Uniform> uniforms;
-
- {
- if (shader_data->ubo_size) {
- RD::Uniform u;
- u.uniform_type = RD::UNIFORM_TYPE_UNIFORM_BUFFER;
- u.binding = 0;
- u.ids.push_back(uniform_buffer);
- uniforms.push_back(u);
- }
-
- const RID *textures = texture_cache.ptrw();
- for (uint32_t i = 0; i < tex_uniform_count; i++) {
- RD::Uniform u;
- u.uniform_type = RD::UNIFORM_TYPE_TEXTURE;
- u.binding = 1 + i;
- u.ids.push_back(textures[i]);
- uniforms.push_back(u);
- }
- }
-
- uniform_set = RD::get_singleton()->uniform_set_create(uniforms, base_singleton->particles_shader.shader.version_get_shader(shader_data->version, 0), 3);
+ return update_parameters_uniform_set(p_parameters, p_uniform_dirty, p_textures_dirty, shader_data->uniforms, shader_data->ubo_offsets.ptr(), shader_data->texture_uniforms, shader_data->default_texture_params, shader_data->ubo_size, uniform_set, base_singleton->particles_shader.shader.version_get_shader(shader_data->version, 0), 3);
}
RendererStorageRD::ParticlesMaterialData::~ParticlesMaterialData() {
- if (uniform_set.is_valid() && RD::get_singleton()->uniform_set_is_valid(uniform_set)) {
- RD::get_singleton()->free(uniform_set);
- }
-
- if (uniform_buffer.is_valid()) {
- RD::get_singleton()->free(uniform_buffer);
- }
+ free_parameters_uniform_set(uniform_set);
}
RendererStorageRD::MaterialData *RendererStorageRD::_create_particles_material_func(ParticlesShaderData *p_shader) {
@@ -5522,7 +5571,7 @@ RID RendererStorageRD::particles_collision_instance_create(RID p_collision) {
pci.collision = p_collision;
return particles_collision_instance_owner.make_rid(pci);
}
-void RendererStorageRD::particles_collision_instance_set_transform(RID p_collision_instance, const Transform &p_transform) {
+void RendererStorageRD::particles_collision_instance_set_transform(RID p_collision_instance, const Transform3D &p_transform) {
ParticlesCollisionInstance *pci = particles_collision_instance_owner.getornull(p_collision_instance);
ERR_FAIL_COND(!pci);
pci->transform = p_transform;
@@ -5533,6 +5582,59 @@ void RendererStorageRD::particles_collision_instance_set_active(RID p_collision_
pci->active = p_active;
}
+/* VISIBILITY NOTIFIER */
+
+RID RendererStorageRD::visibility_notifier_allocate() {
+ return visibility_notifier_owner.allocate_rid();
+}
+void RendererStorageRD::visibility_notifier_initialize(RID p_notifier) {
+ visibility_notifier_owner.initialize_rid(p_notifier, VisibilityNotifier());
+}
+void RendererStorageRD::visibility_notifier_set_aabb(RID p_notifier, const AABB &p_aabb) {
+ VisibilityNotifier *vn = visibility_notifier_owner.getornull(p_notifier);
+ ERR_FAIL_COND(!vn);
+ vn->aabb = p_aabb;
+ vn->dependency.changed_notify(DEPENDENCY_CHANGED_AABB);
+}
+void RendererStorageRD::visibility_notifier_set_callbacks(RID p_notifier, const Callable &p_enter_callbable, const Callable &p_exit_callable) {
+ VisibilityNotifier *vn = visibility_notifier_owner.getornull(p_notifier);
+ ERR_FAIL_COND(!vn);
+ vn->enter_callback = p_enter_callbable;
+ vn->exit_callback = p_exit_callable;
+}
+
+AABB RendererStorageRD::visibility_notifier_get_aabb(RID p_notifier) const {
+ const VisibilityNotifier *vn = visibility_notifier_owner.getornull(p_notifier);
+ ERR_FAIL_COND_V(!vn, AABB());
+ return vn->aabb;
+}
+void RendererStorageRD::visibility_notifier_call(RID p_notifier, bool p_enter, bool p_deferred) {
+ VisibilityNotifier *vn = visibility_notifier_owner.getornull(p_notifier);
+ ERR_FAIL_COND(!vn);
+
+ if (p_enter) {
+ if (!vn->enter_callback.is_null()) {
+ if (p_deferred) {
+ vn->enter_callback.call_deferred(nullptr, 0);
+ } else {
+ Variant r;
+ Callable::CallError ce;
+ vn->enter_callback.call(nullptr, 0, r, ce);
+ }
+ }
+ } else {
+ if (!vn->exit_callback.is_null()) {
+ if (p_deferred) {
+ vn->exit_callback.call_deferred(nullptr, 0);
+ } else {
+ Variant r;
+ Callable::CallError ce;
+ vn->exit_callback.call(nullptr, 0, r, ce);
+ }
+ }
+ }
+}
+
/* SKELETON API */
RID RendererStorageRD::skeleton_allocate() {
@@ -5600,7 +5702,7 @@ int RendererStorageRD::skeleton_get_bone_count(RID p_skeleton) const {
return skeleton->size;
}
-void RendererStorageRD::skeleton_bone_set_transform(RID p_skeleton, int p_bone, const Transform &p_transform) {
+void RendererStorageRD::skeleton_bone_set_transform(RID p_skeleton, int p_bone, const Transform3D &p_transform) {
Skeleton *skeleton = skeleton_owner.getornull(p_skeleton);
ERR_FAIL_COND(!skeleton);
@@ -5625,16 +5727,16 @@ void RendererStorageRD::skeleton_bone_set_transform(RID p_skeleton, int p_bone,
_skeleton_make_dirty(skeleton);
}
-Transform RendererStorageRD::skeleton_bone_get_transform(RID p_skeleton, int p_bone) const {
+Transform3D RendererStorageRD::skeleton_bone_get_transform(RID p_skeleton, int p_bone) const {
Skeleton *skeleton = skeleton_owner.getornull(p_skeleton);
- ERR_FAIL_COND_V(!skeleton, Transform());
- ERR_FAIL_INDEX_V(p_bone, skeleton->size, Transform());
- ERR_FAIL_COND_V(skeleton->use_2d, Transform());
+ ERR_FAIL_COND_V(!skeleton, Transform3D());
+ ERR_FAIL_INDEX_V(p_bone, skeleton->size, Transform3D());
+ ERR_FAIL_COND_V(skeleton->use_2d, Transform3D());
const float *dataptr = skeleton->data.ptr() + p_bone * 12;
- Transform t;
+ Transform3D t;
t.basis.elements[0][0] = dataptr[0];
t.basis.elements[0][1] = dataptr[1];
@@ -5948,20 +6050,6 @@ RS::LightDirectionalShadowMode RendererStorageRD::light_directional_get_shadow_m
return light->directional_shadow_mode;
}
-void RendererStorageRD::light_directional_set_shadow_depth_range_mode(RID p_light, RS::LightDirectionalShadowDepthRangeMode p_range_mode) {
- Light *light = light_owner.getornull(p_light);
- ERR_FAIL_COND(!light);
-
- light->directional_range_mode = p_range_mode;
-}
-
-RS::LightDirectionalShadowDepthRangeMode RendererStorageRD::light_directional_get_shadow_depth_range_mode(RID p_light) const {
- const Light *light = light_owner.getornull(p_light);
- ERR_FAIL_COND_V(!light, RS::LIGHT_DIRECTIONAL_SHADOW_DEPTH_RANGE_STABLE);
-
- return light->directional_range_mode;
-}
-
uint32_t RendererStorageRD::light_get_max_sdfgi_cascade(RID p_light) {
const Light *light = light_owner.getornull(p_light);
ERR_FAIL_COND_V(!light, 0);
@@ -6324,36 +6412,36 @@ AABB RendererStorageRD::decal_get_aabb(RID p_decal) const {
return AABB(-decal->extents, decal->extents * 2.0);
}
-RID RendererStorageRD::gi_probe_allocate() {
- return gi_probe_owner.allocate_rid();
+RID RendererStorageRD::voxel_gi_allocate() {
+ return voxel_gi_owner.allocate_rid();
}
-void RendererStorageRD::gi_probe_initialize(RID p_gi_probe) {
- gi_probe_owner.initialize_rid(p_gi_probe, GIProbe());
+void RendererStorageRD::voxel_gi_initialize(RID p_voxel_gi) {
+ voxel_gi_owner.initialize_rid(p_voxel_gi, VoxelGI());
}
-void RendererStorageRD::gi_probe_allocate_data(RID p_gi_probe, const Transform &p_to_cell_xform, const AABB &p_aabb, const Vector3i &p_octree_size, const Vector<uint8_t> &p_octree_cells, const Vector<uint8_t> &p_data_cells, const Vector<uint8_t> &p_distance_field, const Vector<int> &p_level_counts) {
- GIProbe *gi_probe = gi_probe_owner.getornull(p_gi_probe);
- ERR_FAIL_COND(!gi_probe);
+void RendererStorageRD::voxel_gi_allocate_data(RID p_voxel_gi, const Transform3D &p_to_cell_xform, const AABB &p_aabb, const Vector3i &p_octree_size, const Vector<uint8_t> &p_octree_cells, const Vector<uint8_t> &p_data_cells, const Vector<uint8_t> &p_distance_field, const Vector<int> &p_level_counts) {
+ VoxelGI *voxel_gi = voxel_gi_owner.getornull(p_voxel_gi);
+ ERR_FAIL_COND(!voxel_gi);
- if (gi_probe->octree_buffer.is_valid()) {
- RD::get_singleton()->free(gi_probe->octree_buffer);
- RD::get_singleton()->free(gi_probe->data_buffer);
- if (gi_probe->sdf_texture.is_valid()) {
- RD::get_singleton()->free(gi_probe->sdf_texture);
+ if (voxel_gi->octree_buffer.is_valid()) {
+ RD::get_singleton()->free(voxel_gi->octree_buffer);
+ RD::get_singleton()->free(voxel_gi->data_buffer);
+ if (voxel_gi->sdf_texture.is_valid()) {
+ RD::get_singleton()->free(voxel_gi->sdf_texture);
}
- gi_probe->sdf_texture = RID();
- gi_probe->octree_buffer = RID();
- gi_probe->data_buffer = RID();
- gi_probe->octree_buffer_size = 0;
- gi_probe->data_buffer_size = 0;
- gi_probe->cell_count = 0;
+ voxel_gi->sdf_texture = RID();
+ voxel_gi->octree_buffer = RID();
+ voxel_gi->data_buffer = RID();
+ voxel_gi->octree_buffer_size = 0;
+ voxel_gi->data_buffer_size = 0;
+ voxel_gi->cell_count = 0;
}
- gi_probe->to_cell_xform = p_to_cell_xform;
- gi_probe->bounds = p_aabb;
- gi_probe->octree_size = p_octree_size;
- gi_probe->level_counts = p_level_counts;
+ voxel_gi->to_cell_xform = p_to_cell_xform;
+ voxel_gi->bounds = p_aabb;
+ voxel_gi->octree_size = p_octree_size;
+ voxel_gi->level_counts = p_level_counts;
if (p_octree_cells.size()) {
ERR_FAIL_COND(p_octree_cells.size() % 32 != 0); //cells size must be a multiple of 32
@@ -6362,42 +6450,42 @@ void RendererStorageRD::gi_probe_allocate_data(RID p_gi_probe, const Transform &
ERR_FAIL_COND(p_data_cells.size() != (int)cell_count * 16); //see that data size matches
- gi_probe->cell_count = cell_count;
- gi_probe->octree_buffer = RD::get_singleton()->storage_buffer_create(p_octree_cells.size(), p_octree_cells);
- gi_probe->octree_buffer_size = p_octree_cells.size();
- gi_probe->data_buffer = RD::get_singleton()->storage_buffer_create(p_data_cells.size(), p_data_cells);
- gi_probe->data_buffer_size = p_data_cells.size();
+ voxel_gi->cell_count = cell_count;
+ voxel_gi->octree_buffer = RD::get_singleton()->storage_buffer_create(p_octree_cells.size(), p_octree_cells);
+ voxel_gi->octree_buffer_size = p_octree_cells.size();
+ voxel_gi->data_buffer = RD::get_singleton()->storage_buffer_create(p_data_cells.size(), p_data_cells);
+ voxel_gi->data_buffer_size = p_data_cells.size();
if (p_distance_field.size()) {
RD::TextureFormat tf;
tf.format = RD::DATA_FORMAT_R8_UNORM;
- tf.width = gi_probe->octree_size.x;
- tf.height = gi_probe->octree_size.y;
- tf.depth = gi_probe->octree_size.z;
+ tf.width = voxel_gi->octree_size.x;
+ tf.height = voxel_gi->octree_size.y;
+ tf.depth = voxel_gi->octree_size.z;
tf.texture_type = RD::TEXTURE_TYPE_3D;
tf.usage_bits = RD::TEXTURE_USAGE_SAMPLING_BIT | RD::TEXTURE_USAGE_CAN_UPDATE_BIT | RD::TEXTURE_USAGE_CAN_COPY_FROM_BIT;
Vector<Vector<uint8_t>> s;
s.push_back(p_distance_field);
- gi_probe->sdf_texture = RD::get_singleton()->texture_create(tf, RD::TextureView(), s);
+ voxel_gi->sdf_texture = RD::get_singleton()->texture_create(tf, RD::TextureView(), s);
}
#if 0
{
RD::TextureFormat tf;
tf.format = RD::DATA_FORMAT_R8_UNORM;
- tf.width = gi_probe->octree_size.x;
- tf.height = gi_probe->octree_size.y;
- tf.depth = gi_probe->octree_size.z;
+ tf.width = voxel_gi->octree_size.x;
+ tf.height = voxel_gi->octree_size.y;
+ tf.depth = voxel_gi->octree_size.z;
tf.type = RD::TEXTURE_TYPE_3D;
tf.usage_bits = RD::TEXTURE_USAGE_SAMPLING_BIT | RD::TEXTURE_USAGE_STORAGE_BIT | RD::TEXTURE_USAGE_CAN_COPY_TO_BIT;
tf.shareable_formats.push_back(RD::DATA_FORMAT_R8_UNORM);
tf.shareable_formats.push_back(RD::DATA_FORMAT_R8_UINT);
- gi_probe->sdf_texture = RD::get_singleton()->texture_create(tf, RD::TextureView());
+ voxel_gi->sdf_texture = RD::get_singleton()->texture_create(tf, RD::TextureView());
}
RID shared_tex;
{
RD::TextureView tv;
tv.format_override = RD::DATA_FORMAT_R8_UINT;
- shared_tex = RD::get_singleton()->texture_create_shared(tv, gi_probe->sdf_texture);
+ shared_tex = RD::get_singleton()->texture_create_shared(tv, voxel_gi->sdf_texture);
}
//update SDF texture
Vector<RD::Uniform> uniforms;
@@ -6405,14 +6493,14 @@ void RendererStorageRD::gi_probe_allocate_data(RID p_gi_probe, const Transform &
RD::Uniform u;
u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER;
u.binding = 1;
- u.ids.push_back(gi_probe->octree_buffer);
+ u.ids.push_back(voxel_gi->octree_buffer);
uniforms.push_back(u);
}
{
RD::Uniform u;
u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER;
u.binding = 2;
- u.ids.push_back(gi_probe->data_buffer);
+ u.ids.push_back(voxel_gi->data_buffer);
uniforms.push_back(u);
}
{
@@ -6423,24 +6511,24 @@ void RendererStorageRD::gi_probe_allocate_data(RID p_gi_probe, const Transform &
uniforms.push_back(u);
}
- RID uniform_set = RD::get_singleton()->uniform_set_create(uniforms, giprobe_sdf_shader_version_shader, 0);
+ RID uniform_set = RD::get_singleton()->uniform_set_create(uniforms, voxel_gi_sdf_shader_version_shader, 0);
{
uint32_t push_constant[4] = { 0, 0, 0, 0 };
- for (int i = 0; i < gi_probe->level_counts.size() - 1; i++) {
- push_constant[0] += gi_probe->level_counts[i];
+ for (int i = 0; i < voxel_gi->level_counts.size() - 1; i++) {
+ push_constant[0] += voxel_gi->level_counts[i];
}
- push_constant[1] = push_constant[0] + gi_probe->level_counts[gi_probe->level_counts.size() - 1];
+ push_constant[1] = push_constant[0] + voxel_gi->level_counts[voxel_gi->level_counts.size() - 1];
print_line("offset: " + itos(push_constant[0]));
print_line("size: " + itos(push_constant[1]));
//create SDF
RD::ComputeListID compute_list = RD::get_singleton()->compute_list_begin();
- RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, giprobe_sdf_shader_pipeline);
+ RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, voxel_gi_sdf_shader_pipeline);
RD::get_singleton()->compute_list_bind_uniform_set(compute_list, uniform_set, 0);
RD::get_singleton()->compute_list_set_push_constant(compute_list, push_constant, sizeof(uint32_t) * 4);
- RD::get_singleton()->compute_list_dispatch(compute_list, gi_probe->octree_size.x / 4, gi_probe->octree_size.y / 4, gi_probe->octree_size.z / 4);
+ RD::get_singleton()->compute_list_dispatch(compute_list, voxel_gi->octree_size.x / 4, voxel_gi->octree_size.y / 4, voxel_gi->octree_size.z / 4);
RD::get_singleton()->compute_list_end();
}
@@ -6450,232 +6538,206 @@ void RendererStorageRD::gi_probe_allocate_data(RID p_gi_probe, const Transform &
#endif
}
- gi_probe->version++;
- gi_probe->data_version++;
+ voxel_gi->version++;
+ voxel_gi->data_version++;
- gi_probe->dependency.changed_notify(DEPENDENCY_CHANGED_AABB);
+ voxel_gi->dependency.changed_notify(DEPENDENCY_CHANGED_AABB);
}
-AABB RendererStorageRD::gi_probe_get_bounds(RID p_gi_probe) const {
- GIProbe *gi_probe = gi_probe_owner.getornull(p_gi_probe);
- ERR_FAIL_COND_V(!gi_probe, AABB());
+AABB RendererStorageRD::voxel_gi_get_bounds(RID p_voxel_gi) const {
+ VoxelGI *voxel_gi = voxel_gi_owner.getornull(p_voxel_gi);
+ ERR_FAIL_COND_V(!voxel_gi, AABB());
- return gi_probe->bounds;
+ return voxel_gi->bounds;
}
-Vector3i RendererStorageRD::gi_probe_get_octree_size(RID p_gi_probe) const {
- GIProbe *gi_probe = gi_probe_owner.getornull(p_gi_probe);
- ERR_FAIL_COND_V(!gi_probe, Vector3i());
- return gi_probe->octree_size;
+Vector3i RendererStorageRD::voxel_gi_get_octree_size(RID p_voxel_gi) const {
+ VoxelGI *voxel_gi = voxel_gi_owner.getornull(p_voxel_gi);
+ ERR_FAIL_COND_V(!voxel_gi, Vector3i());
+ return voxel_gi->octree_size;
}
-Vector<uint8_t> RendererStorageRD::gi_probe_get_octree_cells(RID p_gi_probe) const {
- GIProbe *gi_probe = gi_probe_owner.getornull(p_gi_probe);
- ERR_FAIL_COND_V(!gi_probe, Vector<uint8_t>());
+Vector<uint8_t> RendererStorageRD::voxel_gi_get_octree_cells(RID p_voxel_gi) const {
+ VoxelGI *voxel_gi = voxel_gi_owner.getornull(p_voxel_gi);
+ ERR_FAIL_COND_V(!voxel_gi, Vector<uint8_t>());
- if (gi_probe->octree_buffer.is_valid()) {
- return RD::get_singleton()->buffer_get_data(gi_probe->octree_buffer);
+ if (voxel_gi->octree_buffer.is_valid()) {
+ return RD::get_singleton()->buffer_get_data(voxel_gi->octree_buffer);
}
return Vector<uint8_t>();
}
-Vector<uint8_t> RendererStorageRD::gi_probe_get_data_cells(RID p_gi_probe) const {
- GIProbe *gi_probe = gi_probe_owner.getornull(p_gi_probe);
- ERR_FAIL_COND_V(!gi_probe, Vector<uint8_t>());
+Vector<uint8_t> RendererStorageRD::voxel_gi_get_data_cells(RID p_voxel_gi) const {
+ VoxelGI *voxel_gi = voxel_gi_owner.getornull(p_voxel_gi);
+ ERR_FAIL_COND_V(!voxel_gi, Vector<uint8_t>());
- if (gi_probe->data_buffer.is_valid()) {
- return RD::get_singleton()->buffer_get_data(gi_probe->data_buffer);
+ if (voxel_gi->data_buffer.is_valid()) {
+ return RD::get_singleton()->buffer_get_data(voxel_gi->data_buffer);
}
return Vector<uint8_t>();
}
-Vector<uint8_t> RendererStorageRD::gi_probe_get_distance_field(RID p_gi_probe) const {
- GIProbe *gi_probe = gi_probe_owner.getornull(p_gi_probe);
- ERR_FAIL_COND_V(!gi_probe, Vector<uint8_t>());
+Vector<uint8_t> RendererStorageRD::voxel_gi_get_distance_field(RID p_voxel_gi) const {
+ VoxelGI *voxel_gi = voxel_gi_owner.getornull(p_voxel_gi);
+ ERR_FAIL_COND_V(!voxel_gi, Vector<uint8_t>());
- if (gi_probe->data_buffer.is_valid()) {
- return RD::get_singleton()->texture_get_data(gi_probe->sdf_texture, 0);
+ if (voxel_gi->data_buffer.is_valid()) {
+ return RD::get_singleton()->texture_get_data(voxel_gi->sdf_texture, 0);
}
return Vector<uint8_t>();
}
-Vector<int> RendererStorageRD::gi_probe_get_level_counts(RID p_gi_probe) const {
- GIProbe *gi_probe = gi_probe_owner.getornull(p_gi_probe);
- ERR_FAIL_COND_V(!gi_probe, Vector<int>());
+Vector<int> RendererStorageRD::voxel_gi_get_level_counts(RID p_voxel_gi) const {
+ VoxelGI *voxel_gi = voxel_gi_owner.getornull(p_voxel_gi);
+ ERR_FAIL_COND_V(!voxel_gi, Vector<int>());
- return gi_probe->level_counts;
+ return voxel_gi->level_counts;
}
-Transform RendererStorageRD::gi_probe_get_to_cell_xform(RID p_gi_probe) const {
- GIProbe *gi_probe = gi_probe_owner.getornull(p_gi_probe);
- ERR_FAIL_COND_V(!gi_probe, Transform());
+Transform3D RendererStorageRD::voxel_gi_get_to_cell_xform(RID p_voxel_gi) const {
+ VoxelGI *voxel_gi = voxel_gi_owner.getornull(p_voxel_gi);
+ ERR_FAIL_COND_V(!voxel_gi, Transform3D());
- return gi_probe->to_cell_xform;
+ return voxel_gi->to_cell_xform;
}
-void RendererStorageRD::gi_probe_set_dynamic_range(RID p_gi_probe, float p_range) {
- GIProbe *gi_probe = gi_probe_owner.getornull(p_gi_probe);
- ERR_FAIL_COND(!gi_probe);
+void RendererStorageRD::voxel_gi_set_dynamic_range(RID p_voxel_gi, float p_range) {
+ VoxelGI *voxel_gi = voxel_gi_owner.getornull(p_voxel_gi);
+ ERR_FAIL_COND(!voxel_gi);
- gi_probe->dynamic_range = p_range;
- gi_probe->version++;
+ voxel_gi->dynamic_range = p_range;
+ voxel_gi->version++;
}
-float RendererStorageRD::gi_probe_get_dynamic_range(RID p_gi_probe) const {
- GIProbe *gi_probe = gi_probe_owner.getornull(p_gi_probe);
- ERR_FAIL_COND_V(!gi_probe, 0);
+float RendererStorageRD::voxel_gi_get_dynamic_range(RID p_voxel_gi) const {
+ VoxelGI *voxel_gi = voxel_gi_owner.getornull(p_voxel_gi);
+ ERR_FAIL_COND_V(!voxel_gi, 0);
- return gi_probe->dynamic_range;
+ return voxel_gi->dynamic_range;
}
-void RendererStorageRD::gi_probe_set_propagation(RID p_gi_probe, float p_range) {
- GIProbe *gi_probe = gi_probe_owner.getornull(p_gi_probe);
- ERR_FAIL_COND(!gi_probe);
+void RendererStorageRD::voxel_gi_set_propagation(RID p_voxel_gi, float p_range) {
+ VoxelGI *voxel_gi = voxel_gi_owner.getornull(p_voxel_gi);
+ ERR_FAIL_COND(!voxel_gi);
- gi_probe->propagation = p_range;
- gi_probe->version++;
+ voxel_gi->propagation = p_range;
+ voxel_gi->version++;
}
-float RendererStorageRD::gi_probe_get_propagation(RID p_gi_probe) const {
- GIProbe *gi_probe = gi_probe_owner.getornull(p_gi_probe);
- ERR_FAIL_COND_V(!gi_probe, 0);
- return gi_probe->propagation;
+float RendererStorageRD::voxel_gi_get_propagation(RID p_voxel_gi) const {
+ VoxelGI *voxel_gi = voxel_gi_owner.getornull(p_voxel_gi);
+ ERR_FAIL_COND_V(!voxel_gi, 0);
+ return voxel_gi->propagation;
}
-void RendererStorageRD::gi_probe_set_energy(RID p_gi_probe, float p_energy) {
- GIProbe *gi_probe = gi_probe_owner.getornull(p_gi_probe);
- ERR_FAIL_COND(!gi_probe);
+void RendererStorageRD::voxel_gi_set_energy(RID p_voxel_gi, float p_energy) {
+ VoxelGI *voxel_gi = voxel_gi_owner.getornull(p_voxel_gi);
+ ERR_FAIL_COND(!voxel_gi);
- gi_probe->energy = p_energy;
+ voxel_gi->energy = p_energy;
}
-float RendererStorageRD::gi_probe_get_energy(RID p_gi_probe) const {
- GIProbe *gi_probe = gi_probe_owner.getornull(p_gi_probe);
- ERR_FAIL_COND_V(!gi_probe, 0);
- return gi_probe->energy;
+float RendererStorageRD::voxel_gi_get_energy(RID p_voxel_gi) const {
+ VoxelGI *voxel_gi = voxel_gi_owner.getornull(p_voxel_gi);
+ ERR_FAIL_COND_V(!voxel_gi, 0);
+ return voxel_gi->energy;
}
-void RendererStorageRD::gi_probe_set_ao(RID p_gi_probe, float p_ao) {
- GIProbe *gi_probe = gi_probe_owner.getornull(p_gi_probe);
- ERR_FAIL_COND(!gi_probe);
+void RendererStorageRD::voxel_gi_set_bias(RID p_voxel_gi, float p_bias) {
+ VoxelGI *voxel_gi = voxel_gi_owner.getornull(p_voxel_gi);
+ ERR_FAIL_COND(!voxel_gi);
- gi_probe->ao = p_ao;
+ voxel_gi->bias = p_bias;
}
-float RendererStorageRD::gi_probe_get_ao(RID p_gi_probe) const {
- GIProbe *gi_probe = gi_probe_owner.getornull(p_gi_probe);
- ERR_FAIL_COND_V(!gi_probe, 0);
- return gi_probe->ao;
+float RendererStorageRD::voxel_gi_get_bias(RID p_voxel_gi) const {
+ VoxelGI *voxel_gi = voxel_gi_owner.getornull(p_voxel_gi);
+ ERR_FAIL_COND_V(!voxel_gi, 0);
+ return voxel_gi->bias;
}
-void RendererStorageRD::gi_probe_set_ao_size(RID p_gi_probe, float p_strength) {
- GIProbe *gi_probe = gi_probe_owner.getornull(p_gi_probe);
- ERR_FAIL_COND(!gi_probe);
+void RendererStorageRD::voxel_gi_set_normal_bias(RID p_voxel_gi, float p_normal_bias) {
+ VoxelGI *voxel_gi = voxel_gi_owner.getornull(p_voxel_gi);
+ ERR_FAIL_COND(!voxel_gi);
- gi_probe->ao_size = p_strength;
+ voxel_gi->normal_bias = p_normal_bias;
}
-float RendererStorageRD::gi_probe_get_ao_size(RID p_gi_probe) const {
- GIProbe *gi_probe = gi_probe_owner.getornull(p_gi_probe);
- ERR_FAIL_COND_V(!gi_probe, 0);
- return gi_probe->ao_size;
+float RendererStorageRD::voxel_gi_get_normal_bias(RID p_voxel_gi) const {
+ VoxelGI *voxel_gi = voxel_gi_owner.getornull(p_voxel_gi);
+ ERR_FAIL_COND_V(!voxel_gi, 0);
+ return voxel_gi->normal_bias;
}
-void RendererStorageRD::gi_probe_set_bias(RID p_gi_probe, float p_bias) {
- GIProbe *gi_probe = gi_probe_owner.getornull(p_gi_probe);
- ERR_FAIL_COND(!gi_probe);
+void RendererStorageRD::voxel_gi_set_anisotropy_strength(RID p_voxel_gi, float p_strength) {
+ VoxelGI *voxel_gi = voxel_gi_owner.getornull(p_voxel_gi);
+ ERR_FAIL_COND(!voxel_gi);
- gi_probe->bias = p_bias;
+ voxel_gi->anisotropy_strength = p_strength;
}
-float RendererStorageRD::gi_probe_get_bias(RID p_gi_probe) const {
- GIProbe *gi_probe = gi_probe_owner.getornull(p_gi_probe);
- ERR_FAIL_COND_V(!gi_probe, 0);
- return gi_probe->bias;
+float RendererStorageRD::voxel_gi_get_anisotropy_strength(RID p_voxel_gi) const {
+ VoxelGI *voxel_gi = voxel_gi_owner.getornull(p_voxel_gi);
+ ERR_FAIL_COND_V(!voxel_gi, 0);
+ return voxel_gi->anisotropy_strength;
}
-void RendererStorageRD::gi_probe_set_normal_bias(RID p_gi_probe, float p_normal_bias) {
- GIProbe *gi_probe = gi_probe_owner.getornull(p_gi_probe);
- ERR_FAIL_COND(!gi_probe);
-
- gi_probe->normal_bias = p_normal_bias;
-}
+void RendererStorageRD::voxel_gi_set_interior(RID p_voxel_gi, bool p_enable) {
+ VoxelGI *voxel_gi = voxel_gi_owner.getornull(p_voxel_gi);
+ ERR_FAIL_COND(!voxel_gi);
-float RendererStorageRD::gi_probe_get_normal_bias(RID p_gi_probe) const {
- GIProbe *gi_probe = gi_probe_owner.getornull(p_gi_probe);
- ERR_FAIL_COND_V(!gi_probe, 0);
- return gi_probe->normal_bias;
+ voxel_gi->interior = p_enable;
}
-void RendererStorageRD::gi_probe_set_anisotropy_strength(RID p_gi_probe, float p_strength) {
- GIProbe *gi_probe = gi_probe_owner.getornull(p_gi_probe);
- ERR_FAIL_COND(!gi_probe);
+void RendererStorageRD::voxel_gi_set_use_two_bounces(RID p_voxel_gi, bool p_enable) {
+ VoxelGI *voxel_gi = voxel_gi_owner.getornull(p_voxel_gi);
+ ERR_FAIL_COND(!voxel_gi);
- gi_probe->anisotropy_strength = p_strength;
+ voxel_gi->use_two_bounces = p_enable;
+ voxel_gi->version++;
}
-float RendererStorageRD::gi_probe_get_anisotropy_strength(RID p_gi_probe) const {
- GIProbe *gi_probe = gi_probe_owner.getornull(p_gi_probe);
- ERR_FAIL_COND_V(!gi_probe, 0);
- return gi_probe->anisotropy_strength;
+bool RendererStorageRD::voxel_gi_is_using_two_bounces(RID p_voxel_gi) const {
+ VoxelGI *voxel_gi = voxel_gi_owner.getornull(p_voxel_gi);
+ ERR_FAIL_COND_V(!voxel_gi, false);
+ return voxel_gi->use_two_bounces;
}
-void RendererStorageRD::gi_probe_set_interior(RID p_gi_probe, bool p_enable) {
- GIProbe *gi_probe = gi_probe_owner.getornull(p_gi_probe);
- ERR_FAIL_COND(!gi_probe);
-
- gi_probe->interior = p_enable;
+bool RendererStorageRD::voxel_gi_is_interior(RID p_voxel_gi) const {
+ VoxelGI *voxel_gi = voxel_gi_owner.getornull(p_voxel_gi);
+ ERR_FAIL_COND_V(!voxel_gi, 0);
+ return voxel_gi->interior;
}
-void RendererStorageRD::gi_probe_set_use_two_bounces(RID p_gi_probe, bool p_enable) {
- GIProbe *gi_probe = gi_probe_owner.getornull(p_gi_probe);
- ERR_FAIL_COND(!gi_probe);
-
- gi_probe->use_two_bounces = p_enable;
- gi_probe->version++;
+uint32_t RendererStorageRD::voxel_gi_get_version(RID p_voxel_gi) {
+ VoxelGI *voxel_gi = voxel_gi_owner.getornull(p_voxel_gi);
+ ERR_FAIL_COND_V(!voxel_gi, 0);
+ return voxel_gi->version;
}
-bool RendererStorageRD::gi_probe_is_using_two_bounces(RID p_gi_probe) const {
- GIProbe *gi_probe = gi_probe_owner.getornull(p_gi_probe);
- ERR_FAIL_COND_V(!gi_probe, false);
- return gi_probe->use_two_bounces;
+uint32_t RendererStorageRD::voxel_gi_get_data_version(RID p_voxel_gi) {
+ VoxelGI *voxel_gi = voxel_gi_owner.getornull(p_voxel_gi);
+ ERR_FAIL_COND_V(!voxel_gi, 0);
+ return voxel_gi->data_version;
}
-bool RendererStorageRD::gi_probe_is_interior(RID p_gi_probe) const {
- GIProbe *gi_probe = gi_probe_owner.getornull(p_gi_probe);
- ERR_FAIL_COND_V(!gi_probe, 0);
- return gi_probe->interior;
+RID RendererStorageRD::voxel_gi_get_octree_buffer(RID p_voxel_gi) const {
+ VoxelGI *voxel_gi = voxel_gi_owner.getornull(p_voxel_gi);
+ ERR_FAIL_COND_V(!voxel_gi, RID());
+ return voxel_gi->octree_buffer;
}
-uint32_t RendererStorageRD::gi_probe_get_version(RID p_gi_probe) {
- GIProbe *gi_probe = gi_probe_owner.getornull(p_gi_probe);
- ERR_FAIL_COND_V(!gi_probe, 0);
- return gi_probe->version;
+RID RendererStorageRD::voxel_gi_get_data_buffer(RID p_voxel_gi) const {
+ VoxelGI *voxel_gi = voxel_gi_owner.getornull(p_voxel_gi);
+ ERR_FAIL_COND_V(!voxel_gi, RID());
+ return voxel_gi->data_buffer;
}
-uint32_t RendererStorageRD::gi_probe_get_data_version(RID p_gi_probe) {
- GIProbe *gi_probe = gi_probe_owner.getornull(p_gi_probe);
- ERR_FAIL_COND_V(!gi_probe, 0);
- return gi_probe->data_version;
-}
+RID RendererStorageRD::voxel_gi_get_sdf_texture(RID p_voxel_gi) {
+ VoxelGI *voxel_gi = voxel_gi_owner.getornull(p_voxel_gi);
+ ERR_FAIL_COND_V(!voxel_gi, RID());
-RID RendererStorageRD::gi_probe_get_octree_buffer(RID p_gi_probe) const {
- GIProbe *gi_probe = gi_probe_owner.getornull(p_gi_probe);
- ERR_FAIL_COND_V(!gi_probe, RID());
- return gi_probe->octree_buffer;
-}
-
-RID RendererStorageRD::gi_probe_get_data_buffer(RID p_gi_probe) const {
- GIProbe *gi_probe = gi_probe_owner.getornull(p_gi_probe);
- ERR_FAIL_COND_V(!gi_probe, RID());
- return gi_probe->data_buffer;
-}
-
-RID RendererStorageRD::gi_probe_get_sdf_texture(RID p_gi_probe) {
- GIProbe *gi_probe = gi_probe_owner.getornull(p_gi_probe);
- ERR_FAIL_COND_V(!gi_probe, RID());
-
- return gi_probe->sdf_texture;
+ return voxel_gi->sdf_texture;
}
/* LIGHTMAP API */
@@ -6911,9 +6973,13 @@ void RendererStorageRD::_update_render_target(RenderTarget *rt) {
rd_format.width = rt->size.width;
rd_format.height = rt->size.height;
rd_format.depth = 1;
- rd_format.array_layers = 1;
+ rd_format.array_layers = rt->view_count; // for stereo we create two (or more) layers, need to see if we can make fallback work like this too if we don't have multiview
rd_format.mipmaps = 1;
- rd_format.texture_type = RD::TEXTURE_TYPE_2D;
+ if (rd_format.array_layers > 1) { // why are we not using rt->texture_type ??
+ rd_format.texture_type = RD::TEXTURE_TYPE_2D_ARRAY;
+ } else {
+ rd_format.texture_type = RD::TEXTURE_TYPE_2D;
+ }
rd_format.samples = RD::TEXTURE_SAMPLES_1;
rd_format.usage_bits = RD::TEXTURE_USAGE_SAMPLING_BIT | RD::TEXTURE_USAGE_COLOR_ATTACHMENT_BIT | RD::TEXTURE_USAGE_CAN_COPY_FROM_BIT;
rd_format.shareable_formats.push_back(rt->color_format);
@@ -6925,7 +6991,7 @@ void RendererStorageRD::_update_render_target(RenderTarget *rt) {
Vector<RID> fb_textures;
fb_textures.push_back(rt->color);
- rt->framebuffer = RD::get_singleton()->framebuffer_create(fb_textures);
+ rt->framebuffer = RD::get_singleton()->framebuffer_create(fb_textures, RenderingDevice::INVALID_ID, rt->view_count);
if (rt->framebuffer.is_null()) {
_clear_render_target(rt);
ERR_FAIL_COND(rt->framebuffer.is_null());
@@ -7039,12 +7105,15 @@ void RendererStorageRD::render_target_set_position(RID p_render_target, int p_x,
//unused for this render target
}
-void RendererStorageRD::render_target_set_size(RID p_render_target, int p_width, int p_height) {
+void RendererStorageRD::render_target_set_size(RID p_render_target, int p_width, int p_height, uint32_t p_view_count) {
RenderTarget *rt = render_target_owner.getornull(p_render_target);
ERR_FAIL_COND(!rt);
- rt->size.x = p_width;
- rt->size.y = p_height;
- _update_render_target(rt);
+ if (rt->size.x != p_width || rt->size.y != p_height || rt->view_count != p_view_count) {
+ rt->size.x = p_width;
+ rt->size.y = p_height;
+ rt->view_count = p_view_count;
+ _update_render_target(rt);
+ }
}
RID RendererStorageRD::render_target_get_texture(RID p_render_target) {
@@ -7566,8 +7635,8 @@ void RendererStorageRD::base_update_dependency(RID p_base, DependencyTracker *p_
} else if (decal_owner.owns(p_base)) {
Decal *decal = decal_owner.getornull(p_base);
p_instance->update_dependency(&decal->dependency);
- } else if (gi_probe_owner.owns(p_base)) {
- GIProbe *gip = gi_probe_owner.getornull(p_base);
+ } else if (voxel_gi_owner.owns(p_base)) {
+ VoxelGI *gip = voxel_gi_owner.getornull(p_base);
p_instance->update_dependency(&gip->dependency);
} else if (lightmap_owner.owns(p_base)) {
Lightmap *lm = lightmap_owner.getornull(p_base);
@@ -7581,6 +7650,9 @@ void RendererStorageRD::base_update_dependency(RID p_base, DependencyTracker *p_
} else if (particles_collision_owner.owns(p_base)) {
ParticlesCollision *pc = particles_collision_owner.getornull(p_base);
p_instance->update_dependency(&pc->dependency);
+ } else if (visibility_notifier_owner.owns(p_base)) {
+ VisibilityNotifier *vn = visibility_notifier_owner.getornull(p_base);
+ p_instance->update_dependency(&vn->dependency);
}
}
@@ -7604,8 +7676,8 @@ RS::InstanceType RendererStorageRD::get_base_type(RID p_rid) const {
if (decal_owner.owns(p_rid)) {
return RS::INSTANCE_DECAL;
}
- if (gi_probe_owner.owns(p_rid)) {
- return RS::INSTANCE_GI_PROBE;
+ if (voxel_gi_owner.owns(p_rid)) {
+ return RS::INSTANCE_VOXEL_GI;
}
if (light_owner.owns(p_rid)) {
return RS::INSTANCE_LIGHT;
@@ -7619,6 +7691,9 @@ RS::InstanceType RendererStorageRD::get_base_type(RID p_rid) const {
if (particles_collision_owner.owns(p_rid)) {
return RS::INSTANCE_PARTICLES_COLLISION;
}
+ if (visibility_notifier_owner.owns(p_rid)) {
+ return RS::INSTANCE_VISIBLITY_NOTIFIER;
+ }
return RS::INSTANCE_NONE;
}
@@ -8129,7 +8204,7 @@ void RendererStorageRD::_global_variable_store_in_buffer(int32_t p_index, RS::Gl
} break;
case RS::GLOBAL_VAR_TYPE_TRANSFORM: {
GlobalVariables::Value *bv = &global_variables.buffer_values[p_index];
- Transform v = p_value;
+ Transform3D v = p_value;
bv[0].x = v.basis.elements[0][0];
bv[0].y = v.basis.elements[1][0];
bv[0].z = v.basis.elements[2][0];
@@ -8265,6 +8340,9 @@ void RendererStorageRD::global_variable_set_override(const StringName &p_name, c
if (!global_variables.variables.has(p_name)) {
return; //variable may not exist
}
+
+ ERR_FAIL_COND(p_value.get_type() == Variant::OBJECT);
+
GlobalVariables::Variable &gv = global_variables.variables[p_name];
gv.override = p_value;
@@ -8552,6 +8630,7 @@ bool RendererStorageRD::free(RID p_rid) {
if (texture_owner.owns(p_rid)) {
Texture *t = texture_owner.getornull(p_rid);
+ ERR_FAIL_COND_V(!t, false);
ERR_FAIL_COND_V(t->is_render_target, false);
if (RD::get_singleton()->texture_is_valid(t->rd_texture_srgb)) {
@@ -8588,8 +8667,6 @@ bool RendererStorageRD::free(RID p_rid) {
texture_owner.free(p_rid);
} else if (canvas_texture_owner.owns(p_rid)) {
- CanvasTexture *ct = canvas_texture_owner.getornull(p_rid);
- memdelete(ct);
canvas_texture_owner.free(p_rid);
} else if (shader_owner.owns(p_rid)) {
Shader *shader = shader_owner.getornull(p_rid);
@@ -8605,9 +8682,6 @@ bool RendererStorageRD::free(RID p_rid) {
} else if (material_owner.owns(p_rid)) {
Material *material = material_owner.getornull(p_rid);
- if (material->update_requested) {
- _update_queued_materials();
- }
material_set_shader(p_rid, RID()); //clean up shader
material->dependency.deleted_notify(p_rid);
@@ -8635,7 +8709,6 @@ bool RendererStorageRD::free(RID p_rid) {
mi->I = nullptr;
mesh_instance_owner.free(p_rid);
- memdelete(mi);
} else if (multimesh_owner.owns(p_rid)) {
_update_dirty_multimeshes();
@@ -8662,11 +8735,11 @@ bool RendererStorageRD::free(RID p_rid) {
}
decal->dependency.deleted_notify(p_rid);
decal_owner.free(p_rid);
- } else if (gi_probe_owner.owns(p_rid)) {
- gi_probe_allocate_data(p_rid, Transform(), AABB(), Vector3i(), Vector<uint8_t>(), Vector<uint8_t>(), Vector<uint8_t>(), Vector<int>()); //deallocate
- GIProbe *gi_probe = gi_probe_owner.getornull(p_rid);
- gi_probe->dependency.deleted_notify(p_rid);
- gi_probe_owner.free(p_rid);
+ } else if (voxel_gi_owner.owns(p_rid)) {
+ voxel_gi_allocate_data(p_rid, Transform3D(), AABB(), Vector3i(), Vector<uint8_t>(), Vector<uint8_t>(), Vector<uint8_t>(), Vector<int>()); //deallocate
+ VoxelGI *voxel_gi = voxel_gi_owner.getornull(p_rid);
+ voxel_gi->dependency.deleted_notify(p_rid);
+ voxel_gi_owner.free(p_rid);
} else if (lightmap_owner.owns(p_rid)) {
lightmap_set_textures(p_rid, RID(), false);
Lightmap *lightmap = lightmap_owner.getornull(p_rid);
@@ -8694,6 +8767,10 @@ bool RendererStorageRD::free(RID p_rid) {
}
particles_collision->dependency.deleted_notify(p_rid);
particles_collision_owner.free(p_rid);
+ } else if (visibility_notifier_owner.owns(p_rid)) {
+ VisibilityNotifier *vn = visibility_notifier_owner.getornull(p_rid);
+ vn->dependency.deleted_notify(p_rid);
+ visibility_notifier_owner.free(p_rid);
} else if (particles_collision_instance_owner.owns(p_rid)) {
particles_collision_instance_owner.free(p_rid);
} else if (render_target_owner.owns(p_rid)) {
@@ -8747,6 +8824,29 @@ String RendererStorageRD::get_captured_timestamp_name(uint32_t p_index) const {
return RD::get_singleton()->get_captured_timestamp_name(p_index);
}
+void RendererStorageRD::update_memory_info() {
+ texture_mem_cache = RenderingDevice::get_singleton()->get_memory_usage(RenderingDevice::MEMORY_TEXTURES);
+ buffer_mem_cache = RenderingDevice::get_singleton()->get_memory_usage(RenderingDevice::MEMORY_BUFFERS);
+ total_mem_cache = RenderingDevice::get_singleton()->get_memory_usage(RenderingDevice::MEMORY_TOTAL);
+}
+uint64_t RendererStorageRD::get_rendering_info(RS::RenderingInfo p_info) {
+ if (p_info == RS::RENDERING_INFO_TEXTURE_MEM_USED) {
+ return texture_mem_cache;
+ } else if (p_info == RS::RENDERING_INFO_BUFFER_MEM_USED) {
+ return buffer_mem_cache;
+ } else if (p_info == RS::RENDERING_INFO_VIDEO_MEM_USED) {
+ return total_mem_cache;
+ }
+ return 0;
+}
+
+String RendererStorageRD::get_video_adapter_name() const {
+ return RenderingDevice::get_singleton()->get_device_name();
+}
+String RendererStorageRD::get_video_adapter_vendor() const {
+ return RenderingDevice::get_singleton()->get_device_vendor_name();
+}
+
RendererStorageRD *RendererStorageRD::base_singleton = nullptr;
RendererStorageRD::RendererStorageRD() {
@@ -8767,7 +8867,6 @@ RendererStorageRD::RendererStorageRD() {
memset(global_variables.buffer_dirty_regions, 0, sizeof(bool) * global_variables.buffer_size / GlobalVariables::BUFFER_DIRTY_REGION_SIZE);
global_variables.buffer = RD::get_singleton()->storage_buffer_create(sizeof(GlobalVariables::Value) * global_variables.buffer_size);
- material_update_list = nullptr;
{ //create default textures
RD::TextureFormat tformat;
@@ -9181,10 +9280,10 @@ RendererStorageRD::RendererStorageRD() {
{
Vector<String> sdf_versions;
sdf_versions.push_back(""); //one only
- giprobe_sdf_shader.initialize(sdf_versions);
- giprobe_sdf_shader_version = giprobe_sdf_shader.version_create();
- giprobe_sdf_shader_version_shader = giprobe_sdf_shader.version_get_shader(giprobe_sdf_shader_version, 0);
- giprobe_sdf_shader_pipeline = RD::get_singleton()->compute_pipeline_create(giprobe_sdf_shader_version_shader);
+ voxel_gi_sdf_shader.initialize(sdf_versions);
+ voxel_gi_sdf_shader_version = voxel_gi_sdf_shader.version_create();
+ voxel_gi_sdf_shader_version_shader = voxel_gi_sdf_shader.version_get_shader(voxel_gi_sdf_shader_version, 0);
+ voxel_gi_sdf_shader_pipeline = RD::get_singleton()->compute_pipeline_create(voxel_gi_sdf_shader_version_shader);
}
using_lightmap_array = true; // high end
@@ -9400,7 +9499,7 @@ RendererStorageRD::~RendererStorageRD() {
RD::get_singleton()->free(mesh_default_rd_buffers[i]);
}
- giprobe_sdf_shader.version_free(giprobe_sdf_shader_version);
+ voxel_gi_sdf_shader.version_free(voxel_gi_sdf_shader_version);
particles_shader.copy_shader.version_free(particles_shader.copy_shader_version);
rt_sdf.shader.version_free(rt_sdf.shader_version);
diff --git a/servers/rendering/renderer_rd/renderer_storage_rd.h b/servers/rendering/renderer_rd/renderer_storage_rd.h
index 67fbeb3008..1a33569c33 100644
--- a/servers/rendering/renderer_rd/renderer_storage_rd.h
+++ b/servers/rendering/renderer_rd/renderer_storage_rd.h
@@ -38,15 +38,15 @@
#include "servers/rendering/renderer_rd/effects_rd.h"
#include "servers/rendering/renderer_rd/shader_compiler_rd.h"
#include "servers/rendering/renderer_rd/shaders/canvas_sdf.glsl.gen.h"
-#include "servers/rendering/renderer_rd/shaders/giprobe_sdf.glsl.gen.h"
#include "servers/rendering/renderer_rd/shaders/particles.glsl.gen.h"
#include "servers/rendering/renderer_rd/shaders/particles_copy.glsl.gen.h"
#include "servers/rendering/renderer_rd/shaders/skeleton.glsl.gen.h"
+#include "servers/rendering/renderer_rd/shaders/voxel_gi_sdf.glsl.gen.h"
#include "servers/rendering/renderer_scene_render.h"
#include "servers/rendering/rendering_device.h"
class RendererStorageRD : public RendererStorage {
public:
- static _FORCE_INLINE_ void store_transform(const Transform &p_mtx, float *p_array) {
+ static _FORCE_INLINE_ void store_transform(const Transform3D &p_mtx, float *p_array) {
p_array[0] = p_mtx.basis.elements[0][0];
p_array[1] = p_mtx.basis.elements[1][0];
p_array[2] = p_mtx.basis.elements[2][0];
@@ -95,7 +95,7 @@ public:
p_array[11] = 0;
}
- static _FORCE_INLINE_ void store_transform_transposed_3x4(const Transform &p_mtx, float *p_array) {
+ static _FORCE_INLINE_ void store_transform_transposed_3x4(const Transform3D &p_mtx, float *p_array) {
p_array[0] = p_mtx.basis.elements[0][0];
p_array[1] = p_mtx.basis.elements[0][1];
p_array[2] = p_mtx.basis.elements[0][2];
@@ -155,9 +155,13 @@ public:
virtual void set_render_priority(int p_priority) = 0;
virtual void set_next_pass(RID p_pass) = 0;
- virtual void update_parameters(const Map<StringName, Variant> &p_parameters, bool p_uniform_dirty, bool p_textures_dirty) = 0;
+ virtual bool update_parameters(const Map<StringName, Variant> &p_parameters, bool p_uniform_dirty, bool p_textures_dirty) = 0;
virtual ~MaterialData();
+ //to be used internally by update_parameters, in the most common configuration of material parameters
+ bool update_parameters_uniform_set(const Map<StringName, Variant> &p_parameters, bool p_uniform_dirty, bool p_textures_dirty, const Map<StringName, ShaderLanguage::ShaderNode::Uniform> &p_uniforms, const uint32_t *p_uniform_offsets, const Vector<ShaderCompilerRD::GeneratedCode::Texture> &p_texture_uniforms, const Map<StringName, RID> &p_default_texture_params, uint32_t p_ubo_size, RID &uniform_set, RID p_shader, uint32_t p_shader_uniform_set, uint32_t p_barrier = RD::BARRIER_MASK_ALL);
+ void free_parameters_uniform_set(RID p_uniform_set);
+
private:
friend class RendererStorageRD;
RID self;
@@ -165,8 +169,14 @@ public:
List<RID>::Element *global_texture_E = nullptr;
uint64_t global_textures_pass = 0;
Map<StringName, uint64_t> used_global_textures;
+
+ //internally by update_parameters_uniform_set
+ Vector<uint8_t> ubo_data;
+ RID uniform_buffer;
+ Vector<RID> texture_cache;
};
typedef MaterialData *(*MaterialDataRequestFunction)(ShaderData *);
+ static void _material_uniform_set_erased(const RID &p_set, void *p_material);
enum DefaultRDTexture {
DEFAULT_RD_TEXTURE_WHITE,
@@ -221,7 +231,7 @@ private:
~CanvasTexture();
};
- RID_PtrOwner<CanvasTexture, true> canvas_texture_owner;
+ RID_Owner<CanvasTexture, true> canvas_texture_owner;
/* TEXTURE API */
struct Texture {
@@ -373,25 +383,28 @@ private:
struct Material {
RID self;
- MaterialData *data;
- Shader *shader;
+ MaterialData *data = nullptr;
+ Shader *shader = nullptr;
//shortcut to shader data and type
- ShaderType shader_type;
+ ShaderType shader_type = SHADER_TYPE_MAX;
uint32_t shader_id = 0;
- bool update_requested;
- bool uniform_dirty;
- bool texture_dirty;
- Material *update_next;
+ bool uniform_dirty = false;
+ bool texture_dirty = false;
Map<StringName, Variant> params;
- int32_t priority;
+ int32_t priority = 0;
RID next_pass;
+ SelfList<Material> update_element;
+
Dependency dependency;
+
+ Material() :
+ update_element(this) {}
};
MaterialDataRequestFunction material_data_request_func[SHADER_TYPE_MAX];
mutable RID_Owner<Material, true> material_owner;
- Material *material_update_list;
+ SelfList<Material>::List material_update_list;
void _material_queue_update(Material *material, bool p_uniform, bool p_texture);
void _update_queued_materials();
@@ -434,6 +447,7 @@ private:
struct LOD {
float edge_length = 0.0;
+ uint32_t index_count = 0;
RID index_buffer;
RID index_array;
};
@@ -513,7 +527,7 @@ private:
void _mesh_instance_clear(MeshInstance *mi);
void _mesh_instance_add_surface(MeshInstance *mi, Mesh *mesh, uint32_t p_surface);
- mutable RID_PtrOwner<MeshInstance> mesh_instance_owner;
+ mutable RID_Owner<MeshInstance> mesh_instance_owner;
SelfList<MeshInstance>::List dirty_mesh_instance_weights;
SelfList<MeshInstance>::List dirty_mesh_instance_arrays;
@@ -726,7 +740,7 @@ private:
RS::ParticlesDrawOrder draw_order = RS::PARTICLES_DRAW_ORDER_INDEX;
Vector<RID> draw_passes;
- Vector<Transform> trail_bind_poses;
+ Vector<Transform3D> trail_bind_poses;
bool trail_bind_poses_dirty = false;
RID trail_bind_pose_buffer;
RID trail_bind_pose_uniform_set;
@@ -771,7 +785,7 @@ private:
bool force_sub_emit = false;
- Transform emission_transform;
+ Transform3D emission_transform;
Vector<uint8_t> emission_buffer_data;
@@ -894,17 +908,14 @@ private:
}
struct ParticlesMaterialData : public MaterialData {
- uint64_t last_frame;
- ParticlesShaderData *shader_data;
- RID uniform_buffer;
+ uint64_t last_frame = 0;
+ ParticlesShaderData *shader_data = nullptr;
RID uniform_set;
- Vector<RID> texture_cache;
- Vector<uint8_t> ubo_data;
- bool uniform_set_updated;
+ bool uniform_set_updated = false;
virtual void set_render_priority(int p_priority) {}
virtual void set_next_pass(RID p_pass) {}
- virtual void update_parameters(const Map<StringName, Variant> &p_parameters, bool p_uniform_dirty, bool p_textures_dirty);
+ virtual bool update_parameters(const Map<StringName, Variant> &p_parameters, bool p_uniform_dirty, bool p_textures_dirty);
virtual ~ParticlesMaterialData();
};
@@ -941,12 +952,23 @@ private:
struct ParticlesCollisionInstance {
RID collision;
- Transform transform;
+ Transform3D transform;
bool active = false;
};
mutable RID_Owner<ParticlesCollisionInstance> particles_collision_instance_owner;
+ /* visibility_notifier */
+
+ struct VisibilityNotifier {
+ AABB aabb;
+ Callable enter_callback;
+ Callable exit_callback;
+ Dependency dependency;
+ };
+
+ mutable RID_Owner<VisibilityNotifier> visibility_notifier_owner;
+
/* Skeleton */
struct Skeleton {
@@ -991,7 +1013,6 @@ private:
uint32_t cull_mask = 0xFFFFFFFF;
RS::LightOmniShadowMode omni_shadow_mode = RS::LIGHT_OMNI_SHADOW_DUAL_PARABOLOID;
RS::LightDirectionalShadowMode directional_shadow_mode = RS::LIGHT_DIRECTIONAL_SHADOW_ORTHOGONAL;
- RS::LightDirectionalShadowDepthRangeMode directional_range_mode = RS::LIGHT_DIRECTIONAL_SHADOW_DEPTH_RANGE_STABLE;
bool directional_blend_splits = false;
bool directional_sky_only = false;
uint64_t version = 0;
@@ -1045,9 +1066,9 @@ private:
mutable RID_Owner<Decal, true> decal_owner;
- /* GI PROBE */
+ /* VOXEL GI */
- struct GIProbe {
+ struct VoxelGI {
RID octree_buffer;
RID data_buffer;
RID sdf_texture;
@@ -1059,14 +1080,12 @@ private:
int cell_count = 0;
- Transform to_cell_xform;
+ Transform3D to_cell_xform;
AABB bounds;
Vector3i octree_size;
float dynamic_range = 4.0;
float energy = 1.0;
- float ao = 0.0;
- float ao_size = 0.5;
float bias = 1.4;
float normal_bias = 0.0;
float propagation = 0.7;
@@ -1081,12 +1100,12 @@ private:
Dependency dependency;
};
- GiprobeSdfShaderRD giprobe_sdf_shader;
- RID giprobe_sdf_shader_version;
- RID giprobe_sdf_shader_version_shader;
- RID giprobe_sdf_shader_pipeline;
+ VoxelGiSdfShaderRD voxel_gi_sdf_shader;
+ RID voxel_gi_sdf_shader_version;
+ RID voxel_gi_sdf_shader_version_shader;
+ RID voxel_gi_sdf_shader_pipeline;
- mutable RID_Owner<GIProbe, true> gi_probe_owner;
+ mutable RID_Owner<VoxelGI, true> voxel_gi_owner;
/* REFLECTION PROBE */
@@ -1125,6 +1144,7 @@ private:
struct RenderTarget {
Size2i size;
+ uint32_t view_count;
RID framebuffer;
RID color;
@@ -1286,7 +1306,6 @@ public:
virtual void _texture_2d_update(RID p_texture, const Ref<Image> &p_image, int p_layer, bool p_immediate);
- virtual void texture_2d_update_immediate(RID p_texture, const Ref<Image> &p_image, int p_layer = 0); //mostly used for video and streaming
virtual void texture_2d_update(RID p_texture, const Ref<Image> &p_image, int p_layer = 0);
virtual void texture_3d_update(RID p_texture, const Vector<Ref<Image>> &p_data);
virtual void texture_proxy_update(RID p_texture, RID p_proxy_to);
@@ -1445,7 +1464,9 @@ public:
virtual void mesh_set_blend_shape_mode(RID p_mesh, RS::BlendShapeMode p_mode);
virtual RS::BlendShapeMode mesh_get_blend_shape_mode(RID p_mesh) const;
- virtual void mesh_surface_update_region(RID p_mesh, int p_surface, int p_offset, const Vector<uint8_t> &p_data);
+ virtual void mesh_surface_update_vertex_region(RID p_mesh, int p_surface, int p_offset, const Vector<uint8_t> &p_data);
+ virtual void mesh_surface_update_attribute_region(RID p_mesh, int p_surface, int p_offset, const Vector<uint8_t> &p_data);
+ virtual void mesh_surface_update_skin_region(RID p_mesh, int p_surface, int p_offset, const Vector<uint8_t> &p_data);
virtual void mesh_surface_set_material(RID p_mesh, int p_surface, RID p_material);
virtual RID mesh_surface_get_material(RID p_mesh, int p_surface) const;
@@ -1514,10 +1535,18 @@ public:
return s->lod_count > 0;
}
- _FORCE_INLINE_ uint32_t mesh_surface_get_lod(void *p_surface, float p_model_scale, float p_distance_threshold, float p_lod_threshold) const {
+ _FORCE_INLINE_ uint32_t mesh_surface_get_vertices_drawn_count(void *p_surface) const {
+ Mesh::Surface *s = reinterpret_cast<Mesh::Surface *>(p_surface);
+ return s->index_count ? s->index_count : s->vertex_count;
+ }
+
+ _FORCE_INLINE_ uint32_t mesh_surface_get_lod(void *p_surface, float p_model_scale, float p_distance_threshold, float p_lod_threshold, uint32_t *r_index_count = nullptr) const {
Mesh::Surface *s = reinterpret_cast<Mesh::Surface *>(p_surface);
int32_t current_lod = -1;
+ if (r_index_count) {
+ *r_index_count = s->index_count;
+ }
for (uint32_t i = 0; i < s->lod_count; i++) {
float screen_size = s->lods[i].edge_length * p_model_scale / p_distance_threshold;
if (screen_size > p_lod_threshold) {
@@ -1528,6 +1557,9 @@ public:
if (current_lod == -1) {
return 0;
} else {
+ if (r_index_count) {
+ *r_index_count = s->lods[current_lod].index_count;
+ }
return current_lod + 1;
}
}
@@ -1661,14 +1693,14 @@ public:
int multimesh_get_instance_count(RID p_multimesh) const;
void multimesh_set_mesh(RID p_multimesh, RID p_mesh);
- void multimesh_instance_set_transform(RID p_multimesh, int p_index, const Transform &p_transform);
+ void multimesh_instance_set_transform(RID p_multimesh, int p_index, const Transform3D &p_transform);
void multimesh_instance_set_transform_2d(RID p_multimesh, int p_index, const Transform2D &p_transform);
void multimesh_instance_set_color(RID p_multimesh, int p_index, const Color &p_color);
void multimesh_instance_set_custom_data(RID p_multimesh, int p_index, const Color &p_color);
RID multimesh_get_mesh(RID p_multimesh) const;
- Transform multimesh_instance_get_transform(RID p_multimesh, int p_index) const;
+ Transform3D multimesh_instance_get_transform(RID p_multimesh, int p_index) const;
Transform2D multimesh_instance_get_transform_2d(RID p_multimesh, int p_index) const;
Color multimesh_instance_get_color(RID p_multimesh, int p_index) const;
Color multimesh_instance_get_custom_data(RID p_multimesh, int p_index) const;
@@ -1734,24 +1766,6 @@ public:
return multimesh->uniform_set_2d;
}
- /* IMMEDIATE API */
-
- RID immediate_allocate() { return RID(); }
- void immediate_initialize(RID p_immediate) {}
-
- virtual void immediate_begin(RID p_immediate, RS::PrimitiveType p_rimitive, RID p_texture = RID()) {}
- virtual void immediate_vertex(RID p_immediate, const Vector3 &p_vertex) {}
- virtual void immediate_normal(RID p_immediate, const Vector3 &p_normal) {}
- virtual void immediate_tangent(RID p_immediate, const Plane &p_tangent) {}
- virtual void immediate_color(RID p_immediate, const Color &p_color) {}
- virtual void immediate_uv(RID p_immediate, const Vector2 &tex_uv) {}
- virtual void immediate_uv2(RID p_immediate, const Vector2 &tex_uv) {}
- virtual void immediate_end(RID p_immediate) {}
- virtual void immediate_clear(RID p_immediate) {}
- virtual void immediate_set_material(RID p_immediate, RID p_material) {}
- virtual RID immediate_get_material(RID p_immediate) const { return RID(); }
- virtual AABB immediate_get_aabb(RID p_immediate) const { return AABB(); }
-
/* SKELETON API */
RID skeleton_allocate();
@@ -1759,10 +1773,10 @@ public:
void skeleton_allocate_data(RID p_skeleton, int p_bones, bool p_2d_skeleton = false);
void skeleton_set_base_transform_2d(RID p_skeleton, const Transform2D &p_base_transform);
- void skeleton_set_world_transform(RID p_skeleton, bool p_enable, const Transform &p_world_transform);
+ void skeleton_set_world_transform(RID p_skeleton, bool p_enable, const Transform3D &p_world_transform);
int skeleton_get_bone_count(RID p_skeleton) const;
- void skeleton_bone_set_transform(RID p_skeleton, int p_bone, const Transform &p_transform);
- Transform skeleton_bone_get_transform(RID p_skeleton, int p_bone) const;
+ void skeleton_bone_set_transform(RID p_skeleton, int p_bone, const Transform3D &p_transform);
+ Transform3D skeleton_bone_get_transform(RID p_skeleton, int p_bone) const;
void skeleton_bone_set_transform_2d(RID p_skeleton, int p_bone, const Transform2D &p_transform);
Transform2D skeleton_bone_get_transform_2d(RID p_skeleton, int p_bone) const;
@@ -1820,8 +1834,6 @@ public:
bool light_directional_get_blend_splits(RID p_light) const;
void light_directional_set_sky_only(RID p_light, bool p_sky_only);
bool light_directional_is_sky_only(RID p_light) const;
- void light_directional_set_shadow_depth_range_mode(RID p_light, RS::LightDirectionalShadowDepthRangeMode p_range_mode);
- RS::LightDirectionalShadowDepthRangeMode light_directional_get_shadow_depth_range_mode(RID p_light) const;
RS::LightDirectionalShadowMode light_directional_get_shadow_mode(RID p_light);
RS::LightOmniShadowMode light_omni_get_shadow_mode(RID p_light);
@@ -2019,59 +2031,53 @@ public:
virtual AABB decal_get_aabb(RID p_decal) const;
- /* GI PROBE API */
-
- RID gi_probe_allocate();
- void gi_probe_initialize(RID p_gi_probe);
-
- void gi_probe_allocate_data(RID p_gi_probe, const Transform &p_to_cell_xform, const AABB &p_aabb, const Vector3i &p_octree_size, const Vector<uint8_t> &p_octree_cells, const Vector<uint8_t> &p_data_cells, const Vector<uint8_t> &p_distance_field, const Vector<int> &p_level_counts);
+ /* VOXEL GI API */
- AABB gi_probe_get_bounds(RID p_gi_probe) const;
- Vector3i gi_probe_get_octree_size(RID p_gi_probe) const;
- Vector<uint8_t> gi_probe_get_octree_cells(RID p_gi_probe) const;
- Vector<uint8_t> gi_probe_get_data_cells(RID p_gi_probe) const;
- Vector<uint8_t> gi_probe_get_distance_field(RID p_gi_probe) const;
+ RID voxel_gi_allocate();
+ void voxel_gi_initialize(RID p_voxel_gi);
- Vector<int> gi_probe_get_level_counts(RID p_gi_probe) const;
- Transform gi_probe_get_to_cell_xform(RID p_gi_probe) const;
+ void voxel_gi_allocate_data(RID p_voxel_gi, const Transform3D &p_to_cell_xform, const AABB &p_aabb, const Vector3i &p_octree_size, const Vector<uint8_t> &p_octree_cells, const Vector<uint8_t> &p_data_cells, const Vector<uint8_t> &p_distance_field, const Vector<int> &p_level_counts);
- void gi_probe_set_dynamic_range(RID p_gi_probe, float p_range);
- float gi_probe_get_dynamic_range(RID p_gi_probe) const;
+ AABB voxel_gi_get_bounds(RID p_voxel_gi) const;
+ Vector3i voxel_gi_get_octree_size(RID p_voxel_gi) const;
+ Vector<uint8_t> voxel_gi_get_octree_cells(RID p_voxel_gi) const;
+ Vector<uint8_t> voxel_gi_get_data_cells(RID p_voxel_gi) const;
+ Vector<uint8_t> voxel_gi_get_distance_field(RID p_voxel_gi) const;
- void gi_probe_set_propagation(RID p_gi_probe, float p_range);
- float gi_probe_get_propagation(RID p_gi_probe) const;
+ Vector<int> voxel_gi_get_level_counts(RID p_voxel_gi) const;
+ Transform3D voxel_gi_get_to_cell_xform(RID p_voxel_gi) const;
- void gi_probe_set_energy(RID p_gi_probe, float p_energy);
- float gi_probe_get_energy(RID p_gi_probe) const;
+ void voxel_gi_set_dynamic_range(RID p_voxel_gi, float p_range);
+ float voxel_gi_get_dynamic_range(RID p_voxel_gi) const;
- void gi_probe_set_ao(RID p_gi_probe, float p_ao);
- float gi_probe_get_ao(RID p_gi_probe) const;
+ void voxel_gi_set_propagation(RID p_voxel_gi, float p_range);
+ float voxel_gi_get_propagation(RID p_voxel_gi) const;
- void gi_probe_set_ao_size(RID p_gi_probe, float p_strength);
- float gi_probe_get_ao_size(RID p_gi_probe) const;
+ void voxel_gi_set_energy(RID p_voxel_gi, float p_energy);
+ float voxel_gi_get_energy(RID p_voxel_gi) const;
- void gi_probe_set_bias(RID p_gi_probe, float p_bias);
- float gi_probe_get_bias(RID p_gi_probe) const;
+ void voxel_gi_set_bias(RID p_voxel_gi, float p_bias);
+ float voxel_gi_get_bias(RID p_voxel_gi) const;
- void gi_probe_set_normal_bias(RID p_gi_probe, float p_range);
- float gi_probe_get_normal_bias(RID p_gi_probe) const;
+ void voxel_gi_set_normal_bias(RID p_voxel_gi, float p_range);
+ float voxel_gi_get_normal_bias(RID p_voxel_gi) const;
- void gi_probe_set_interior(RID p_gi_probe, bool p_enable);
- bool gi_probe_is_interior(RID p_gi_probe) const;
+ void voxel_gi_set_interior(RID p_voxel_gi, bool p_enable);
+ bool voxel_gi_is_interior(RID p_voxel_gi) const;
- void gi_probe_set_use_two_bounces(RID p_gi_probe, bool p_enable);
- bool gi_probe_is_using_two_bounces(RID p_gi_probe) const;
+ void voxel_gi_set_use_two_bounces(RID p_voxel_gi, bool p_enable);
+ bool voxel_gi_is_using_two_bounces(RID p_voxel_gi) const;
- void gi_probe_set_anisotropy_strength(RID p_gi_probe, float p_strength);
- float gi_probe_get_anisotropy_strength(RID p_gi_probe) const;
+ void voxel_gi_set_anisotropy_strength(RID p_voxel_gi, float p_strength);
+ float voxel_gi_get_anisotropy_strength(RID p_voxel_gi) const;
- uint32_t gi_probe_get_version(RID p_probe);
- uint32_t gi_probe_get_data_version(RID p_probe);
+ uint32_t voxel_gi_get_version(RID p_probe);
+ uint32_t voxel_gi_get_data_version(RID p_probe);
- RID gi_probe_get_octree_buffer(RID p_gi_probe) const;
- RID gi_probe_get_data_buffer(RID p_gi_probe) const;
+ RID voxel_gi_get_octree_buffer(RID p_voxel_gi) const;
+ RID voxel_gi_get_data_buffer(RID p_voxel_gi) const;
- RID gi_probe_get_sdf_texture(RID p_gi_probe);
+ RID voxel_gi_get_sdf_texture(RID p_voxel_gi);
/* LIGHTMAP CAPTURE */
@@ -2147,10 +2153,10 @@ public:
void particles_set_transform_align(RID p_particles, RS::ParticlesTransformAlign p_transform_align);
void particles_set_trails(RID p_particles, bool p_enable, float p_length);
- void particles_set_trail_bind_poses(RID p_particles, const Vector<Transform> &p_bind_poses);
+ void particles_set_trail_bind_poses(RID p_particles, const Vector<Transform3D> &p_bind_poses);
void particles_restart(RID p_particles);
- void particles_emit(RID p_particles, const Transform &p_transform, const Vector3 &p_velocity, const Color &p_color, const Color &p_custom, uint32_t p_emit_flags);
+ void particles_emit(RID p_particles, const Transform3D &p_transform, const Vector3 &p_velocity, const Color &p_color, const Color &p_custom, uint32_t p_emit_flags);
void particles_set_subemitter(RID p_particles, RID p_subemitter_particles);
@@ -2163,7 +2169,7 @@ public:
AABB particles_get_current_aabb(RID p_particles);
AABB particles_get_aabb(RID p_particles) const;
- void particles_set_emission_transform(RID p_particles, const Transform &p_transform);
+ void particles_set_emission_transform(RID p_particles, const Transform3D &p_transform);
bool particles_get_emitting(RID p_particles);
int particles_get_draw_passes(RID p_particles) const;
@@ -2252,9 +2258,17 @@ public:
virtual bool particles_collision_is_heightfield(RID p_particles_collision) const;
RID particles_collision_get_heightfield_framebuffer(RID p_particles_collision) const;
+ virtual RID visibility_notifier_allocate();
+ virtual void visibility_notifier_initialize(RID p_notifier);
+ virtual void visibility_notifier_set_aabb(RID p_notifier, const AABB &p_aabb);
+ virtual void visibility_notifier_set_callbacks(RID p_notifier, const Callable &p_enter_callbable, const Callable &p_exit_callable);
+
+ virtual AABB visibility_notifier_get_aabb(RID p_notifier) const;
+ virtual void visibility_notifier_call(RID p_notifier, bool p_enter, bool p_deferred);
+
//used from 2D and 3D
virtual RID particles_collision_instance_create(RID p_collision);
- virtual void particles_collision_instance_set_transform(RID p_collision_instance, const Transform &p_transform);
+ virtual void particles_collision_instance_set_transform(RID p_collision_instance, const Transform3D &p_transform);
virtual void particles_collision_instance_set_active(RID p_collision_instance, bool p_active);
/* GLOBAL VARIABLES API */
@@ -2282,7 +2296,7 @@ public:
RID render_target_create();
void render_target_set_position(RID p_render_target, int p_x, int p_y);
- void render_target_set_size(RID p_render_target, int p_width, int p_height);
+ void render_target_set_size(RID p_render_target, int p_width, int p_height, uint32_t p_view_count);
RID render_target_get_texture(RID p_render_target);
void render_target_set_external_texture(RID p_render_target, unsigned int p_texture_id);
void render_target_set_flag(RID p_render_target, RenderTargetFlags p_flag, bool p_value);
@@ -2330,13 +2344,16 @@ public:
void set_debug_generate_wireframes(bool p_generate) {}
- void render_info_begin_capture() {}
- void render_info_end_capture() {}
- int get_captured_render_info(RS::RenderInfo p_info) { return 0; }
+ //keep cached since it can be called form any thread
+ uint64_t texture_mem_cache = 0;
+ uint64_t buffer_mem_cache = 0;
+ uint64_t total_mem_cache = 0;
+
+ virtual void update_memory_info();
+ virtual uint64_t get_rendering_info(RS::RenderingInfo p_info);
- uint64_t get_render_info(RS::RenderInfo p_info) { return 0; }
- String get_video_adapter_name() const { return String(); }
- String get_video_adapter_vendor() const { return String(); }
+ String get_video_adapter_name() const;
+ String get_video_adapter_vendor() const;
virtual void capture_timestamps_begin();
virtual void capture_timestamp(const String &p_name);
diff --git a/servers/rendering/renderer_rd/shader_compiler_rd.cpp b/servers/rendering/renderer_rd/shader_compiler_rd.cpp
index 7deedb80c3..b347197289 100644
--- a/servers/rendering/renderer_rd/shader_compiler_rd.cpp
+++ b/servers/rendering/renderer_rd/shader_compiler_rd.cpp
@@ -1504,7 +1504,6 @@ ShaderCompilerRD::ShaderCompilerRD() {
actions[RS::SHADER_SPATIAL].render_mode_defines["diffuse_burley"] = "#define DIFFUSE_BURLEY\n";
}
- actions[RS::SHADER_SPATIAL].render_mode_defines["diffuse_oren_nayar"] = "#define DIFFUSE_OREN_NAYAR\n";
actions[RS::SHADER_SPATIAL].render_mode_defines["diffuse_lambert_wrap"] = "#define DIFFUSE_LAMBERT_WRAP\n";
actions[RS::SHADER_SPATIAL].render_mode_defines["diffuse_toon"] = "#define DIFFUSE_TOON\n";
diff --git a/servers/rendering/renderer_rd/shader_rd.cpp b/servers/rendering/renderer_rd/shader_rd.cpp
index 6f29ff42bc..27305cc938 100644
--- a/servers/rendering/renderer_rd/shader_rd.cpp
+++ b/servers/rendering/renderer_rd/shader_rd.cpp
@@ -31,8 +31,8 @@
#include "shader_rd.h"
#include "core/io/compression.h"
-#include "core/os/dir_access.h"
-#include "core/os/file_access.h"
+#include "core/io/dir_access.h"
+#include "core/io/file_access.h"
#include "renderer_compositor_rd.h"
#include "servers/rendering/rendering_device.h"
#include "thirdparty/misc/smolv.h"
diff --git a/servers/rendering/renderer_rd/shaders/canvas.glsl b/servers/rendering/renderer_rd/shaders/canvas.glsl
index 2186bd174b..a443bcdcb8 100644
--- a/servers/rendering/renderer_rd/shaders/canvas.glsl
+++ b/servers/rendering/renderer_rd/shaders/canvas.glsl
@@ -65,7 +65,7 @@ void main() {
#elif defined(USE_ATTRIBUTES)
vec2 vertex = vertex_attrib;
- vec4 color = color_attrib;
+ vec4 color = color_attrib * draw_data.modulation;
vec2 uv = uv_attrib;
uvec4 bones = bone_attrib;
diff --git a/servers/rendering/renderer_rd/shaders/gi.glsl b/servers/rendering/renderer_rd/shaders/gi.glsl
index bfd5c4c88d..60c881881d 100644
--- a/servers/rendering/renderer_rd/shaders/gi.glsl
+++ b/servers/rendering/renderer_rd/shaders/gi.glsl
@@ -35,7 +35,7 @@ layout(set = 0, binding = 11) uniform texture2DArray lightprobe_texture;
layout(set = 0, binding = 12) uniform texture2D depth_buffer;
layout(set = 0, binding = 13) uniform texture2D normal_roughness_buffer;
-layout(set = 0, binding = 14) uniform utexture2D giprobe_buffer;
+layout(set = 0, binding = 14) uniform utexture2D voxel_gi_buffer;
layout(set = 0, binding = 15, std140) uniform SDFGI {
vec3 grid_size;
@@ -65,9 +65,9 @@ layout(set = 0, binding = 15, std140) uniform SDFGI {
}
sdfgi;
-#define MAX_GI_PROBES 8
+#define MAX_VOXEL_GI_INSTANCES 8
-struct GIProbeData {
+struct VoxelGIData {
mat4 xform;
vec3 bounds;
float dynamic_range;
@@ -77,18 +77,18 @@ struct GIProbeData {
bool blend_ambient;
uint texture_slot;
- float anisotropy_strength;
- float ambient_occlusion;
- float ambient_occlusion_size;
+ uint pad0;
+ uint pad1;
+ uint pad2;
uint mipmaps;
};
-layout(set = 0, binding = 16, std140) uniform GIProbes {
- GIProbeData data[MAX_GI_PROBES];
+layout(set = 0, binding = 16, std140) uniform VoxelGIs {
+ VoxelGIData data[MAX_VOXEL_GI_INSTANCES];
}
-gi_probes;
+voxel_gi_instances;
-layout(set = 0, binding = 17) uniform texture3D gi_probe_textures[MAX_GI_PROBES];
+layout(set = 0, binding = 17) uniform texture3D voxel_gi_textures[MAX_VOXEL_GI_INSTANCES];
layout(push_constant, binding = 0, std430) uniform Params {
ivec2 screen_size;
@@ -98,7 +98,7 @@ layout(push_constant, binding = 0, std430) uniform Params {
vec4 proj_info;
vec3 ao_color;
- uint max_giprobes;
+ uint max_voxel_gi_instances;
bool high_quality_vct;
bool orthogonal;
@@ -155,7 +155,7 @@ vec3 reconstruct_position(ivec2 screen_pos) {
return pos;
}
-void sdfgi_probe_process(uint cascade, vec3 cascade_pos, vec3 cam_pos, vec3 cam_normal, vec3 cam_specular_normal, float roughness, out vec3 diffuse_light, out vec3 specular_light) {
+void sdfvoxel_gi_process(uint cascade, vec3 cascade_pos, vec3 cam_pos, vec3 cam_normal, vec3 cam_specular_normal, float roughness, out vec3 diffuse_light, out vec3 specular_light) {
cascade_pos += cam_normal * sdfgi.normal_bias;
vec3 base_pos = floor(cascade_pos);
@@ -293,7 +293,7 @@ void sdfgi_process(vec3 vertex, vec3 normal, vec3 reflection, float roughness, o
float blend;
vec3 diffuse, specular;
- sdfgi_probe_process(cascade, cascade_pos, cam_pos, cam_normal, reflection, roughness, diffuse, specular);
+ sdfvoxel_gi_process(cascade, cascade_pos, cam_pos, cam_normal, reflection, roughness, diffuse, specular);
{
//process blend
@@ -323,7 +323,7 @@ void sdfgi_process(vec3 vertex, vec3 normal, vec3 reflection, float roughness, o
} else {
vec3 diffuse2, specular2;
cascade_pos = (cam_pos - sdfgi.cascades[cascade + 1].position) * sdfgi.cascades[cascade + 1].to_probe;
- sdfgi_probe_process(cascade + 1, cascade_pos, cam_pos, cam_normal, reflection, roughness, diffuse2, specular2);
+ sdfvoxel_gi_process(cascade + 1, cascade_pos, cam_pos, cam_normal, reflection, roughness, diffuse2, specular2);
diffuse = mix(diffuse, diffuse2, blend);
specular = mix(specular, specular2, blend);
}
@@ -494,26 +494,26 @@ vec4 voxel_cone_trace_45_degrees(texture3D probe, vec3 cell_size, vec3 pos, vec3
return color;
}
-void gi_probe_compute(uint index, vec3 position, vec3 normal, vec3 ref_vec, mat3 normal_xform, float roughness, inout vec4 out_spec, inout vec4 out_diff, inout float out_blend) {
- position = (gi_probes.data[index].xform * vec4(position, 1.0)).xyz;
- ref_vec = normalize((gi_probes.data[index].xform * vec4(ref_vec, 0.0)).xyz);
- normal = normalize((gi_probes.data[index].xform * vec4(normal, 0.0)).xyz);
+void voxel_gi_compute(uint index, vec3 position, vec3 normal, vec3 ref_vec, mat3 normal_xform, float roughness, inout vec4 out_spec, inout vec4 out_diff, inout float out_blend) {
+ position = (voxel_gi_instances.data[index].xform * vec4(position, 1.0)).xyz;
+ ref_vec = normalize((voxel_gi_instances.data[index].xform * vec4(ref_vec, 0.0)).xyz);
+ normal = normalize((voxel_gi_instances.data[index].xform * vec4(normal, 0.0)).xyz);
- position += normal * gi_probes.data[index].normal_bias;
+ position += normal * voxel_gi_instances.data[index].normal_bias;
//this causes corrupted pixels, i have no idea why..
- if (any(bvec2(any(lessThan(position, vec3(0.0))), any(greaterThan(position, gi_probes.data[index].bounds))))) {
+ if (any(bvec2(any(lessThan(position, vec3(0.0))), any(greaterThan(position, voxel_gi_instances.data[index].bounds))))) {
return;
}
- mat3 dir_xform = mat3(gi_probes.data[index].xform) * normal_xform;
+ mat3 dir_xform = mat3(voxel_gi_instances.data[index].xform) * normal_xform;
- vec3 blendv = abs(position / gi_probes.data[index].bounds * 2.0 - 1.0);
+ vec3 blendv = abs(position / voxel_gi_instances.data[index].bounds * 2.0 - 1.0);
float blend = clamp(1.0 - max(blendv.x, max(blendv.y, blendv.z)), 0.0, 1.0);
//float blend=1.0;
- float max_distance = length(gi_probes.data[index].bounds);
- vec3 cell_size = 1.0 / gi_probes.data[index].bounds;
+ float max_distance = length(voxel_gi_instances.data[index].bounds);
+ vec3 cell_size = 1.0 / voxel_gi_instances.data[index].bounds;
//irradiance
@@ -534,7 +534,7 @@ void gi_probe_compute(uint index, vec3 position, vec3 normal, vec3 ref_vec, mat3
for (uint i = 0; i < cone_dir_count; i++) {
vec3 dir = normalize(dir_xform * cone_dirs[i]);
- light += cone_weights[i] * voxel_cone_trace(gi_probe_textures[index], cell_size, position, dir, cone_angle_tan, max_distance, gi_probes.data[index].bias);
+ light += cone_weights[i] * voxel_cone_trace(voxel_gi_textures[index], cell_size, position, dir, cone_angle_tan, max_distance, voxel_gi_instances.data[index].bias);
}
} else {
const uint cone_dir_count = 4;
@@ -547,42 +547,21 @@ void gi_probe_compute(uint index, vec3 position, vec3 normal, vec3 ref_vec, mat3
float cone_weights[cone_dir_count] = float[](0.25, 0.25, 0.25, 0.25);
for (int i = 0; i < cone_dir_count; i++) {
vec3 dir = normalize(dir_xform * cone_dirs[i]);
- light += cone_weights[i] * voxel_cone_trace_45_degrees(gi_probe_textures[index], cell_size, position, dir, max_distance, gi_probes.data[index].bias);
+ light += cone_weights[i] * voxel_cone_trace_45_degrees(voxel_gi_textures[index], cell_size, position, dir, max_distance, voxel_gi_instances.data[index].bias);
}
}
- if (gi_probes.data[index].ambient_occlusion > 0.001) {
- float size = 1.0 + gi_probes.data[index].ambient_occlusion_size * 7.0;
-
- float taps, blend;
- blend = modf(size, taps);
- float ao = 0.0;
- for (float i = 1.0; i <= taps; i++) {
- vec3 ofs = (position + normal * (i * 0.5 + 1.0)) * cell_size;
- ao += textureLod(sampler3D(gi_probe_textures[index], linear_sampler_with_mipmaps), ofs, i - 1.0).a * i;
- }
-
- if (blend > 0.001) {
- vec3 ofs = (position + normal * ((taps + 1.0) * 0.5 + 1.0)) * cell_size;
- ao += textureLod(sampler3D(gi_probe_textures[index], linear_sampler_with_mipmaps), ofs, taps).a * (taps + 1.0) * blend;
- }
-
- ao = 1.0 - min(1.0, ao);
-
- light.rgb = mix(params.ao_color, light.rgb, mix(1.0, ao, gi_probes.data[index].ambient_occlusion));
- }
-
- light.rgb *= gi_probes.data[index].dynamic_range;
- if (!gi_probes.data[index].blend_ambient) {
+ light.rgb *= voxel_gi_instances.data[index].dynamic_range;
+ if (!voxel_gi_instances.data[index].blend_ambient) {
light.a = 1.0;
}
out_diff += light * blend;
//radiance
- vec4 irr_light = voxel_cone_trace(gi_probe_textures[index], cell_size, position, ref_vec, tan(roughness * 0.5 * M_PI * 0.99), max_distance, gi_probes.data[index].bias);
- irr_light.rgb *= gi_probes.data[index].dynamic_range;
- if (!gi_probes.data[index].blend_ambient) {
+ vec4 irr_light = voxel_cone_trace(voxel_gi_textures[index], cell_size, position, ref_vec, tan(roughness * 0.5 * M_PI * 0.99), max_distance, voxel_gi_instances.data[index].bias);
+ irr_light.rgb *= voxel_gi_instances.data[index].dynamic_range;
+ if (!voxel_gi_instances.data[index].blend_ambient) {
irr_light.a = 1.0;
}
@@ -614,9 +593,9 @@ void process_gi(ivec2 pos, vec3 vertex, inout vec4 ambient_light, inout vec4 ref
sdfgi_process(vertex, normal, reflection, roughness, ambient_light, reflection_light);
#endif
-#ifdef USE_GIPROBES
+#ifdef USE_VOXEL_GI_INSTANCES
{
- uvec2 giprobe_tex = texelFetch(usampler2D(giprobe_buffer, linear_sampler), pos, 0).rg;
+ uvec2 voxel_gi_tex = texelFetch(usampler2D(voxel_gi_buffer, linear_sampler), pos, 0).rg;
roughness *= roughness;
//find arbitrary tangent and bitangent, then build a matrix
vec3 v0 = abs(normal.z) < 0.999 ? vec3(0.0, 0.0, 1.0) : vec3(0.0, 1.0, 0.0);
@@ -628,9 +607,9 @@ void process_gi(ivec2 pos, vec3 vertex, inout vec4 ambient_light, inout vec4 ref
vec4 spec_accum = vec4(0.0);
float blend_accum = 0.0;
- for (uint i = 0; i < params.max_giprobes; i++) {
- if (any(equal(uvec2(i), giprobe_tex))) {
- gi_probe_compute(i, vertex, normal, reflection, normal_mat, roughness, spec_accum, amb_accum, blend_accum);
+ for (uint i = 0; i < params.max_voxel_gi_instances; i++) {
+ if (any(equal(uvec2(i), voxel_gi_tex))) {
+ voxel_gi_compute(i, vertex, normal, reflection, normal_mat, roughness, spec_accum, amb_accum, blend_accum);
}
}
if (blend_accum > 0.0) {
diff --git a/servers/rendering/renderer_rd/shaders/resolve.glsl b/servers/rendering/renderer_rd/shaders/resolve.glsl
index 2286a26485..fecf812a8c 100644
--- a/servers/rendering/renderer_rd/shaders/resolve.glsl
+++ b/servers/rendering/renderer_rd/shaders/resolve.glsl
@@ -6,6 +6,11 @@
layout(local_size_x = 8, local_size_y = 8, local_size_z = 1) in;
+#ifdef MODE_RESOLVE_DEPTH
+layout(set = 0, binding = 0) uniform sampler2DMS source_depth;
+layout(r32f, set = 1, binding = 0) uniform restrict writeonly image2D dest_depth;
+#endif
+
#ifdef MODE_RESOLVE_GI
layout(set = 0, binding = 0) uniform sampler2DMS source_depth;
layout(set = 0, binding = 1) uniform sampler2DMS source_normal_roughness;
@@ -13,9 +18,9 @@ layout(set = 0, binding = 1) uniform sampler2DMS source_normal_roughness;
layout(r32f, set = 1, binding = 0) uniform restrict writeonly image2D dest_depth;
layout(rgba8, set = 1, binding = 1) uniform restrict writeonly image2D dest_normal_roughness;
-#ifdef GIPROBE_RESOLVE
-layout(set = 2, binding = 0) uniform usampler2DMS source_giprobe;
-layout(rg8ui, set = 3, binding = 0) uniform restrict writeonly uimage2D dest_giprobe;
+#ifdef VOXEL_GI_RESOLVE
+layout(set = 2, binding = 0) uniform usampler2DMS source_voxel_gi;
+layout(rg8ui, set = 3, binding = 0) uniform restrict writeonly uimage2D dest_voxel_gi;
#endif
#endif
@@ -34,12 +39,23 @@ void main() {
return;
}
+#ifdef MODE_RESOLVE_DEPTH
+
+ float depth_avg = 0.0;
+ for (int i = 0; i < params.sample_count; i++) {
+ depth_avg += texelFetch(source_depth, pos, i).r;
+ }
+ depth_avg /= float(params.sample_count);
+ imageStore(dest_depth, pos, vec4(depth_avg));
+
+#endif
+
#ifdef MODE_RESOLVE_GI
float best_depth = 1e20;
vec4 best_normal_roughness = vec4(0.0);
-#ifdef GIPROBE_RESOLVE
- uvec2 best_giprobe;
+#ifdef VOXEL_GI_RESOLVE
+ uvec2 best_voxel_gi;
#endif
#if 0
@@ -50,8 +66,8 @@ void main() {
best_depth = depth;
best_normal_roughness = texelFetch(source_normal_roughness,pos,i);
-#ifdef GIPROBE_RESOLVE
- best_giprobe = texelFetch(source_giprobe,pos,i).rg;
+#ifdef VOXEL_GI_RESOLVE
+ best_voxel_gi = texelFetch(source_voxel_gi,pos,i).rg;
#endif
}
}
@@ -204,16 +220,16 @@ void main() {
#endif
best_depth = texelFetch(source_depth, pos, best_index).r;
best_normal_roughness = texelFetch(source_normal_roughness, pos, best_index);
-#ifdef GIPROBE_RESOLVE
- best_giprobe = texelFetch(source_giprobe, pos, best_index).rg;
+#ifdef VOXEL_GI_RESOLVE
+ best_voxel_gi = texelFetch(source_voxel_gi, pos, best_index).rg;
#endif
#endif
imageStore(dest_depth, pos, vec4(best_depth));
imageStore(dest_normal_roughness, pos, vec4(best_normal_roughness));
-#ifdef GIPROBE_RESOLVE
- imageStore(dest_giprobe, pos, uvec4(best_giprobe, 0, 0));
+#ifdef VOXEL_GI_RESOLVE
+ imageStore(dest_voxel_gi, pos, uvec4(best_voxel_gi, 0, 0));
#endif
#endif
diff --git a/servers/rendering/renderer_rd/shaders/scene_forward_clustered.glsl b/servers/rendering/renderer_rd/shaders/scene_forward_clustered.glsl
index e09b8f15be..74d5af5cb6 100644
--- a/servers/rendering/renderer_rd/shaders/scene_forward_clustered.glsl
+++ b/servers/rendering/renderer_rd/shaders/scene_forward_clustered.glsl
@@ -426,8 +426,8 @@ layout(location = 4) out float depth_output_buffer;
#ifdef MODE_RENDER_NORMAL_ROUGHNESS
layout(location = 0) out vec4 normal_roughness_output_buffer;
-#ifdef MODE_RENDER_GIPROBE
-layout(location = 1) out uvec2 giprobe_buffer;
+#ifdef MODE_RENDER_VOXEL_GI
+layout(location = 1) out uvec2 voxel_gi_buffer;
#endif
#endif //MODE_RENDER_NORMAL
@@ -547,9 +547,8 @@ void main() {
vec3 view = -normalize(vertex_interp);
vec3 albedo = vec3(1.0);
vec3 backlight = vec3(0.0);
- vec4 transmittance_color = vec4(0.0);
+ vec4 transmittance_color = vec4(0.0, 0.0, 0.0, 1.0);
float transmittance_depth = 0.0;
- float transmittance_curve = 1.0;
float transmittance_boost = 0.0;
float metallic = 0.0;
float specular = 0.5;
@@ -634,12 +633,8 @@ void main() {
}
#ifdef LIGHT_TRANSMITTANCE_USED
-#ifdef SSS_MODE_SKIN
- transmittance_color.a = sss_strength;
-#else
transmittance_color.a *= sss_strength;
#endif
-#endif
#ifndef USE_SHADOW_TO_OPACITY
@@ -850,7 +845,7 @@ void main() {
if (scene_data.roughness_limiter_enabled) {
//http://www.jp.square-enix.com/tech/library/pdf/ImprovedGeometricSpecularAA.pdf
float roughness2 = roughness * roughness;
- vec3 dndu = dFdx(normal), dndv = dFdx(normal);
+ vec3 dndu = dFdx(normal), dndv = dFdy(normal);
float variance = scene_data.roughness_limiter_amount * (dot(dndu, dndu) + dot(dndv, dndv));
float kernelRoughness2 = min(2.0 * variance, scene_data.roughness_limiter_limit); //limit effect
float filteredRoughness2 = min(1.0, roughness2 + kernelRoughness2);
@@ -904,7 +899,7 @@ void main() {
}
#endif // USE_LIGHTMAP
#if defined(CUSTOM_IRRADIANCE_USED)
- ambient_light = mix(specular_light, custom_irradiance.rgb, custom_irradiance.a);
+ ambient_light = mix(ambient_light, custom_irradiance.rgb, custom_irradiance.a);
#endif
#endif //!defined(MODE_RENDER_DEPTH) && !defined(MODE_UNSHADED)
@@ -1042,7 +1037,7 @@ void main() {
}
}
- if (bool(instances.data[instance_index].flags & INSTANCE_FLAGS_USE_GIPROBE)) { // process giprobes
+ if (bool(instances.data[instance_index].flags & INSTANCE_FLAGS_USE_VOXEL_GI)) { // process voxel_gi_instances
uint index1 = instances.data[instance_index].gi_offset & 0xFFFF;
vec3 ref_vec = normalize(reflect(normalize(vertex), normal));
@@ -1054,12 +1049,12 @@ void main() {
vec4 amb_accum = vec4(0.0);
vec4 spec_accum = vec4(0.0);
- gi_probe_compute(index1, vertex, normal, ref_vec, normal_mat, roughness * roughness, ambient_light, specular_light, spec_accum, amb_accum);
+ voxel_gi_compute(index1, vertex, normal, ref_vec, normal_mat, roughness * roughness, ambient_light, specular_light, spec_accum, amb_accum);
uint index2 = instances.data[instance_index].gi_offset >> 16;
if (index2 != 0xFFFF) {
- gi_probe_compute(index2, vertex, normal, ref_vec, normal_mat, roughness * roughness, ambient_light, specular_light, spec_accum, amb_accum);
+ voxel_gi_compute(index2, vertex, normal, ref_vec, normal_mat, roughness * roughness, ambient_light, specular_light, spec_accum, amb_accum);
}
if (amb_accum.a > 0.0) {
@@ -1423,57 +1418,18 @@ void main() {
BIAS_FUNC(v, 0)
pssm_coord = (directional_lights.data[i].shadow_matrix1 * v);
-#ifdef LIGHT_TRANSMITTANCE_USED
- {
- vec4 trans_vertex = vec4(vertex - normalize(normal_interp) * directional_lights.data[i].shadow_transmittance_bias.x, 1.0);
- vec4 trans_coord = directional_lights.data[i].shadow_matrix1 * trans_vertex;
- trans_coord /= trans_coord.w;
-
- float shadow_z = textureLod(sampler2D(directional_shadow_atlas, material_samplers[SAMPLER_LINEAR_CLAMP]), trans_coord.xy, 0.0).r;
- shadow_z *= directional_lights.data[i].shadow_transmittance_z_scale.x;
- float z = trans_coord.z * directional_lights.data[i].shadow_transmittance_z_scale.x;
-
- transmittance_z = z - shadow_z;
- }
-#endif
} else if (depth_z < directional_lights.data[i].shadow_split_offsets.y) {
vec4 v = vec4(vertex, 1.0);
BIAS_FUNC(v, 1)
pssm_coord = (directional_lights.data[i].shadow_matrix2 * v);
-#ifdef LIGHT_TRANSMITTANCE_USED
- {
- vec4 trans_vertex = vec4(vertex - normalize(normal_interp) * directional_lights.data[i].shadow_transmittance_bias.y, 1.0);
- vec4 trans_coord = directional_lights.data[i].shadow_matrix2 * trans_vertex;
- trans_coord /= trans_coord.w;
-
- float shadow_z = textureLod(sampler2D(directional_shadow_atlas, material_samplers[SAMPLER_LINEAR_CLAMP]), trans_coord.xy, 0.0).r;
- shadow_z *= directional_lights.data[i].shadow_transmittance_z_scale.y;
- float z = trans_coord.z * directional_lights.data[i].shadow_transmittance_z_scale.y;
-
- transmittance_z = z - shadow_z;
- }
-#endif
} else if (depth_z < directional_lights.data[i].shadow_split_offsets.z) {
vec4 v = vec4(vertex, 1.0);
BIAS_FUNC(v, 2)
pssm_coord = (directional_lights.data[i].shadow_matrix3 * v);
-#ifdef LIGHT_TRANSMITTANCE_USED
- {
- vec4 trans_vertex = vec4(vertex - normalize(normal_interp) * directional_lights.data[i].shadow_transmittance_bias.z, 1.0);
- vec4 trans_coord = directional_lights.data[i].shadow_matrix3 * trans_vertex;
- trans_coord /= trans_coord.w;
-
- float shadow_z = textureLod(sampler2D(directional_shadow_atlas, material_samplers[SAMPLER_LINEAR_CLAMP]), trans_coord.xy, 0.0).r;
- shadow_z *= directional_lights.data[i].shadow_transmittance_z_scale.z;
- float z = trans_coord.z * directional_lights.data[i].shadow_transmittance_z_scale.z;
-
- transmittance_z = z - shadow_z;
- }
-#endif
} else {
vec4 v = vec4(vertex, 1.0);
@@ -1481,19 +1437,6 @@ void main() {
BIAS_FUNC(v, 3)
pssm_coord = (directional_lights.data[i].shadow_matrix4 * v);
-#ifdef LIGHT_TRANSMITTANCE_USED
- {
- vec4 trans_vertex = vec4(vertex - normalize(normal_interp) * directional_lights.data[i].shadow_transmittance_bias.w, 1.0);
- vec4 trans_coord = directional_lights.data[i].shadow_matrix4 * trans_vertex;
- trans_coord /= trans_coord.w;
-
- float shadow_z = textureLod(sampler2D(directional_shadow_atlas, material_samplers[SAMPLER_LINEAR_CLAMP]), trans_coord.xy, 0.0).r;
- shadow_z *= directional_lights.data[i].shadow_transmittance_z_scale.w;
- float z = trans_coord.z * directional_lights.data[i].shadow_transmittance_z_scale.w;
-
- transmittance_z = z - shadow_z;
- }
-#endif
}
pssm_coord /= pssm_coord.w;
@@ -1562,8 +1505,8 @@ void main() {
trans_coord /= trans_coord.w;
float shadow_z = textureLod(sampler2D(directional_shadow_atlas, material_samplers[SAMPLER_LINEAR_CLAMP]), trans_coord.xy, 0.0).r;
- shadow_z *= directional_lights.data[i].shadow_transmittance_z_scale.x;
- float z = trans_coord.z * directional_lights.data[i].shadow_transmittance_z_scale.x;
+ shadow_z *= directional_lights.data[i].shadow_z_range.x;
+ float z = trans_coord.z * directional_lights.data[i].shadow_z_range.x;
transmittance_z = z - shadow_z;
} else if (depth_z < directional_lights.data[i].shadow_split_offsets.y) {
@@ -1572,8 +1515,8 @@ void main() {
trans_coord /= trans_coord.w;
float shadow_z = textureLod(sampler2D(directional_shadow_atlas, material_samplers[SAMPLER_LINEAR_CLAMP]), trans_coord.xy, 0.0).r;
- shadow_z *= directional_lights.data[i].shadow_transmittance_z_scale.y;
- float z = trans_coord.z * directional_lights.data[i].shadow_transmittance_z_scale.y;
+ shadow_z *= directional_lights.data[i].shadow_z_range.y;
+ float z = trans_coord.z * directional_lights.data[i].shadow_z_range.y;
transmittance_z = z - shadow_z;
} else if (depth_z < directional_lights.data[i].shadow_split_offsets.z) {
@@ -1582,8 +1525,8 @@ void main() {
trans_coord /= trans_coord.w;
float shadow_z = textureLod(sampler2D(directional_shadow_atlas, material_samplers[SAMPLER_LINEAR_CLAMP]), trans_coord.xy, 0.0).r;
- shadow_z *= directional_lights.data[i].shadow_transmittance_z_scale.z;
- float z = trans_coord.z * directional_lights.data[i].shadow_transmittance_z_scale.z;
+ shadow_z *= directional_lights.data[i].shadow_z_range.z;
+ float z = trans_coord.z * directional_lights.data[i].shadow_z_range.z;
transmittance_z = z - shadow_z;
@@ -1593,221 +1536,219 @@ void main() {
trans_coord /= trans_coord.w;
float shadow_z = textureLod(sampler2D(directional_shadow_atlas, material_samplers[SAMPLER_LINEAR_CLAMP]), trans_coord.xy, 0.0).r;
- shadow_z *= directional_lights.data[i].shadow_transmittance_z_scale.w;
- float z = trans_coord.z * directional_lights.data[i].shadow_transmittance_z_scale.w;
+ shadow_z *= directional_lights.data[i].shadow_z_range.w;
+ float z = trans_coord.z * directional_lights.data[i].shadow_z_range.w;
transmittance_z = z - shadow_z;
}
+ }
#endif
- float shadow = 1.0;
+ float shadow = 1.0;
- if (i < 4) {
- shadow = float(shadow0 >> (i * 8) & 0xFF) / 255.0;
- } else {
- shadow = float(shadow1 >> ((i - 4) * 8) & 0xFF) / 255.0;
- }
+ if (i < 4) {
+ shadow = float(shadow0 >> (i * 8) & 0xFF) / 255.0;
+ } else {
+ shadow = float(shadow1 >> ((i - 4) * 8) & 0xFF) / 255.0;
+ }
- blur_shadow(shadow);
+ blur_shadow(shadow);
- light_compute(normal, directional_lights.data[i].direction, normalize(view), directional_lights.data[i].color * directional_lights.data[i].energy, shadow, f0, orms, 1.0,
+ light_compute(normal, directional_lights.data[i].direction, normalize(view), directional_lights.data[i].color * directional_lights.data[i].energy, shadow, f0, orms, 1.0,
#ifdef LIGHT_BACKLIGHT_USED
- backlight,
+ backlight,
#endif
#ifdef LIGHT_TRANSMITTANCE_USED
- transmittance_color,
- transmittance_depth,
- transmittance_curve,
- transmittance_boost,
- transmittance_z,
+ transmittance_color,
+ transmittance_depth,
+ transmittance_boost,
+ transmittance_z,
#endif
#ifdef LIGHT_RIM_USED
- rim, rim_tint, albedo,
+ rim, rim_tint, albedo,
#endif
#ifdef LIGHT_CLEARCOAT_USED
- clearcoat, clearcoat_gloss,
+ clearcoat, clearcoat_gloss,
#endif
#ifdef LIGHT_ANISOTROPY_USED
- binormal, tangent, anisotropy,
+ binormal, tangent, anisotropy,
#endif
#ifdef USE_SOFT_SHADOW
- directional_lights.data[i].size,
+ directional_lights.data[i].size,
#endif
#ifdef USE_SHADOW_TO_OPACITY
- alpha,
+ alpha,
#endif
- diffuse_light,
- specular_light);
- }
+ diffuse_light,
+ specular_light);
}
+ }
- { //omni lights
+ { //omni lights
- uint cluster_omni_offset = cluster_offset;
+ uint cluster_omni_offset = cluster_offset;
- uint item_min;
- uint item_max;
- uint item_from;
- uint item_to;
+ uint item_min;
+ uint item_max;
+ uint item_from;
+ uint item_to;
- cluster_get_item_range(cluster_omni_offset + scene_data.max_cluster_element_count_div_32 + cluster_z, item_min, item_max, item_from, item_to);
+ cluster_get_item_range(cluster_omni_offset + scene_data.max_cluster_element_count_div_32 + cluster_z, item_min, item_max, item_from, item_to);
#ifdef USE_SUBGROUPS
- item_from = subgroupBroadcastFirst(subgroupMin(item_from));
- item_to = subgroupBroadcastFirst(subgroupMax(item_to));
+ item_from = subgroupBroadcastFirst(subgroupMin(item_from));
+ item_to = subgroupBroadcastFirst(subgroupMax(item_to));
#endif
- for (uint i = item_from; i < item_to; i++) {
- uint mask = cluster_buffer.data[cluster_omni_offset + i];
- mask &= cluster_get_range_clip_mask(i, item_min, item_max);
+ for (uint i = item_from; i < item_to; i++) {
+ uint mask = cluster_buffer.data[cluster_omni_offset + i];
+ mask &= cluster_get_range_clip_mask(i, item_min, item_max);
#ifdef USE_SUBGROUPS
- uint merged_mask = subgroupBroadcastFirst(subgroupOr(mask));
+ uint merged_mask = subgroupBroadcastFirst(subgroupOr(mask));
#else
uint merged_mask = mask;
#endif
- while (merged_mask != 0) {
- uint bit = findMSB(merged_mask);
- merged_mask &= ~(1 << bit);
+ while (merged_mask != 0) {
+ uint bit = findMSB(merged_mask);
+ merged_mask &= ~(1 << bit);
#ifdef USE_SUBGROUPS
- if (((1 << bit) & mask) == 0) { //do not process if not originally here
- continue;
- }
+ if (((1 << bit) & mask) == 0) { //do not process if not originally here
+ continue;
+ }
#endif
- uint light_index = 32 * i + bit;
+ uint light_index = 32 * i + bit;
- if (!bool(omni_lights.data[light_index].mask & instances.data[instance_index].layer_mask)) {
- continue; //not masked
- }
+ if (!bool(omni_lights.data[light_index].mask & instances.data[instance_index].layer_mask)) {
+ continue; //not masked
+ }
- if (omni_lights.data[light_index].bake_mode == LIGHT_BAKE_STATIC && bool(instances.data[instance_index].flags & INSTANCE_FLAGS_USE_LIGHTMAP)) {
- continue; // Statically baked light and object uses lightmap, skip
- }
+ if (omni_lights.data[light_index].bake_mode == LIGHT_BAKE_STATIC && bool(instances.data[instance_index].flags & INSTANCE_FLAGS_USE_LIGHTMAP)) {
+ continue; // Statically baked light and object uses lightmap, skip
+ }
- float shadow = light_process_omni_shadow(light_index, vertex, view);
+ float shadow = light_process_omni_shadow(light_index, vertex, view);
- shadow = blur_shadow(shadow);
+ shadow = blur_shadow(shadow);
- light_process_omni(light_index, vertex, view, normal, vertex_ddx, vertex_ddy, f0, orms, shadow,
+ light_process_omni(light_index, vertex, view, normal, vertex_ddx, vertex_ddy, f0, orms, shadow,
#ifdef LIGHT_BACKLIGHT_USED
- backlight,
+ backlight,
#endif
#ifdef LIGHT_TRANSMITTANCE_USED
- transmittance_color,
- transmittance_depth,
- transmittance_curve,
- transmittance_boost,
+ transmittance_color,
+ transmittance_depth,
+ transmittance_boost,
#endif
#ifdef LIGHT_RIM_USED
- rim,
- rim_tint,
- albedo,
+ rim,
+ rim_tint,
+ albedo,
#endif
#ifdef LIGHT_CLEARCOAT_USED
- clearcoat, clearcoat_gloss,
+ clearcoat, clearcoat_gloss,
#endif
#ifdef LIGHT_ANISOTROPY_USED
- tangent, binormal, anisotropy,
+ tangent, binormal, anisotropy,
#endif
#ifdef USE_SHADOW_TO_OPACITY
- alpha,
+ alpha,
#endif
- diffuse_light, specular_light);
- }
+ diffuse_light, specular_light);
}
}
+ }
- { //spot lights
+ { //spot lights
- uint cluster_spot_offset = cluster_offset + scene_data.cluster_type_size;
+ uint cluster_spot_offset = cluster_offset + scene_data.cluster_type_size;
- uint item_min;
- uint item_max;
- uint item_from;
- uint item_to;
+ uint item_min;
+ uint item_max;
+ uint item_from;
+ uint item_to;
- cluster_get_item_range(cluster_spot_offset + scene_data.max_cluster_element_count_div_32 + cluster_z, item_min, item_max, item_from, item_to);
+ cluster_get_item_range(cluster_spot_offset + scene_data.max_cluster_element_count_div_32 + cluster_z, item_min, item_max, item_from, item_to);
#ifdef USE_SUBGROUPS
- item_from = subgroupBroadcastFirst(subgroupMin(item_from));
- item_to = subgroupBroadcastFirst(subgroupMax(item_to));
+ item_from = subgroupBroadcastFirst(subgroupMin(item_from));
+ item_to = subgroupBroadcastFirst(subgroupMax(item_to));
#endif
- for (uint i = item_from; i < item_to; i++) {
- uint mask = cluster_buffer.data[cluster_spot_offset + i];
- mask &= cluster_get_range_clip_mask(i, item_min, item_max);
+ for (uint i = item_from; i < item_to; i++) {
+ uint mask = cluster_buffer.data[cluster_spot_offset + i];
+ mask &= cluster_get_range_clip_mask(i, item_min, item_max);
#ifdef USE_SUBGROUPS
- uint merged_mask = subgroupBroadcastFirst(subgroupOr(mask));
+ uint merged_mask = subgroupBroadcastFirst(subgroupOr(mask));
#else
uint merged_mask = mask;
#endif
- while (merged_mask != 0) {
- uint bit = findMSB(merged_mask);
- merged_mask &= ~(1 << bit);
+ while (merged_mask != 0) {
+ uint bit = findMSB(merged_mask);
+ merged_mask &= ~(1 << bit);
#ifdef USE_SUBGROUPS
- if (((1 << bit) & mask) == 0) { //do not process if not originally here
- continue;
- }
+ if (((1 << bit) & mask) == 0) { //do not process if not originally here
+ continue;
+ }
#endif
- uint light_index = 32 * i + bit;
+ uint light_index = 32 * i + bit;
- if (!bool(spot_lights.data[light_index].mask & instances.data[instance_index].layer_mask)) {
- continue; //not masked
- }
+ if (!bool(spot_lights.data[light_index].mask & instances.data[instance_index].layer_mask)) {
+ continue; //not masked
+ }
- if (spot_lights.data[light_index].bake_mode == LIGHT_BAKE_STATIC && bool(instances.data[instance_index].flags & INSTANCE_FLAGS_USE_LIGHTMAP)) {
- continue; // Statically baked light and object uses lightmap, skip
- }
+ if (spot_lights.data[light_index].bake_mode == LIGHT_BAKE_STATIC && bool(instances.data[instance_index].flags & INSTANCE_FLAGS_USE_LIGHTMAP)) {
+ continue; // Statically baked light and object uses lightmap, skip
+ }
- float shadow = light_process_spot_shadow(light_index, vertex, view);
+ float shadow = light_process_spot_shadow(light_index, vertex, view);
- shadow = blur_shadow(shadow);
+ shadow = blur_shadow(shadow);
- light_process_spot(light_index, vertex, view, normal, vertex_ddx, vertex_ddy, f0, orms, shadow,
+ light_process_spot(light_index, vertex, view, normal, vertex_ddx, vertex_ddy, f0, orms, shadow,
#ifdef LIGHT_BACKLIGHT_USED
- backlight,
+ backlight,
#endif
#ifdef LIGHT_TRANSMITTANCE_USED
- transmittance_color,
- transmittance_depth,
- transmittance_curve,
- transmittance_boost,
+ transmittance_color,
+ transmittance_depth,
+ transmittance_boost,
#endif
#ifdef LIGHT_RIM_USED
- rim,
- rim_tint,
- albedo,
+ rim,
+ rim_tint,
+ albedo,
#endif
#ifdef LIGHT_CLEARCOAT_USED
- clearcoat, clearcoat_gloss,
+ clearcoat, clearcoat_gloss,
#endif
#ifdef LIGHT_ANISOTROPY_USED
- tangent, binormal, anisotropy,
+ tangent, binormal, anisotropy,
#endif
#ifdef USE_SHADOW_TO_OPACITY
- alpha,
+ alpha,
#endif
- diffuse_light, specular_light);
- }
+ diffuse_light, specular_light);
}
}
+ }
#ifdef USE_SHADOW_TO_OPACITY
- alpha = min(alpha, clamp(length(ambient_light), 0.0, 1.0));
+ alpha = min(alpha, clamp(length(ambient_light), 0.0, 1.0));
#if defined(ALPHA_SCISSOR_USED)
- if (alpha < alpha_scissor) {
- discard;
- }
+ if (alpha < alpha_scissor) {
+ discard;
+ }
#endif // ALPHA_SCISSOR_USED
#ifdef USE_OPAQUE_PREPASS
- if (alpha < opaque_prepass_threshold) {
- discard;
- }
+ if (alpha < opaque_prepass_threshold) {
+ discard;
+ }
#endif // USE_OPAQUE_PREPASS
@@ -1819,126 +1760,126 @@ void main() {
#ifdef MODE_RENDER_SDF
- {
- vec3 local_pos = (scene_data.sdf_to_bounds * vec4(vertex, 1.0)).xyz;
- ivec3 grid_pos = scene_data.sdf_offset + ivec3(local_pos * vec3(scene_data.sdf_size));
-
- uint albedo16 = 0x1; //solid flag
- albedo16 |= clamp(uint(albedo.r * 31.0), 0, 31) << 11;
- albedo16 |= clamp(uint(albedo.g * 31.0), 0, 31) << 6;
- albedo16 |= clamp(uint(albedo.b * 31.0), 0, 31) << 1;
-
- imageStore(albedo_volume_grid, grid_pos, uvec4(albedo16));
-
- uint facing_bits = 0;
- const vec3 aniso_dir[6] = vec3[](
- vec3(1, 0, 0),
- vec3(0, 1, 0),
- vec3(0, 0, 1),
- vec3(-1, 0, 0),
- vec3(0, -1, 0),
- vec3(0, 0, -1));
-
- vec3 cam_normal = mat3(scene_data.camera_matrix) * normalize(normal_interp);
-
- float closest_dist = -1e20;
-
- for (uint i = 0; i < 6; i++) {
- float d = dot(cam_normal, aniso_dir[i]);
- if (d > closest_dist) {
- closest_dist = d;
- facing_bits = (1 << i);
- }
+ {
+ vec3 local_pos = (scene_data.sdf_to_bounds * vec4(vertex, 1.0)).xyz;
+ ivec3 grid_pos = scene_data.sdf_offset + ivec3(local_pos * vec3(scene_data.sdf_size));
+
+ uint albedo16 = 0x1; //solid flag
+ albedo16 |= clamp(uint(albedo.r * 31.0), 0, 31) << 11;
+ albedo16 |= clamp(uint(albedo.g * 31.0), 0, 31) << 6;
+ albedo16 |= clamp(uint(albedo.b * 31.0), 0, 31) << 1;
+
+ imageStore(albedo_volume_grid, grid_pos, uvec4(albedo16));
+
+ uint facing_bits = 0;
+ const vec3 aniso_dir[6] = vec3[](
+ vec3(1, 0, 0),
+ vec3(0, 1, 0),
+ vec3(0, 0, 1),
+ vec3(-1, 0, 0),
+ vec3(0, -1, 0),
+ vec3(0, 0, -1));
+
+ vec3 cam_normal = mat3(scene_data.camera_matrix) * normalize(normal_interp);
+
+ float closest_dist = -1e20;
+
+ for (uint i = 0; i < 6; i++) {
+ float d = dot(cam_normal, aniso_dir[i]);
+ if (d > closest_dist) {
+ closest_dist = d;
+ facing_bits = (1 << i);
}
+ }
- imageAtomicOr(geom_facing_grid, grid_pos, facing_bits); //store facing bits
+ imageAtomicOr(geom_facing_grid, grid_pos, facing_bits); //store facing bits
- if (length(emission) > 0.001) {
- float lumas[6];
- vec3 light_total = vec3(0);
+ if (length(emission) > 0.001) {
+ float lumas[6];
+ vec3 light_total = vec3(0);
- for (int i = 0; i < 6; i++) {
- float strength = max(0.0, dot(cam_normal, aniso_dir[i]));
- vec3 light = emission * strength;
- light_total += light;
- lumas[i] = max(light.r, max(light.g, light.b));
- }
+ for (int i = 0; i < 6; i++) {
+ float strength = max(0.0, dot(cam_normal, aniso_dir[i]));
+ vec3 light = emission * strength;
+ light_total += light;
+ lumas[i] = max(light.r, max(light.g, light.b));
+ }
- float luma_total = max(light_total.r, max(light_total.g, light_total.b));
+ float luma_total = max(light_total.r, max(light_total.g, light_total.b));
- uint light_aniso = 0;
+ uint light_aniso = 0;
- for (int i = 0; i < 6; i++) {
- light_aniso |= min(31, uint((lumas[i] / luma_total) * 31.0)) << (i * 5);
- }
+ for (int i = 0; i < 6; i++) {
+ light_aniso |= min(31, uint((lumas[i] / luma_total) * 31.0)) << (i * 5);
+ }
- //compress to RGBE9995 to save space
+ //compress to RGBE9995 to save space
- const float pow2to9 = 512.0f;
- const float B = 15.0f;
- const float N = 9.0f;
- const float LN2 = 0.6931471805599453094172321215;
+ const float pow2to9 = 512.0f;
+ const float B = 15.0f;
+ const float N = 9.0f;
+ const float LN2 = 0.6931471805599453094172321215;
- float cRed = clamp(light_total.r, 0.0, 65408.0);
- float cGreen = clamp(light_total.g, 0.0, 65408.0);
- float cBlue = clamp(light_total.b, 0.0, 65408.0);
+ float cRed = clamp(light_total.r, 0.0, 65408.0);
+ float cGreen = clamp(light_total.g, 0.0, 65408.0);
+ float cBlue = clamp(light_total.b, 0.0, 65408.0);
- float cMax = max(cRed, max(cGreen, cBlue));
+ float cMax = max(cRed, max(cGreen, cBlue));
- float expp = max(-B - 1.0f, floor(log(cMax) / LN2)) + 1.0f + B;
+ float expp = max(-B - 1.0f, floor(log(cMax) / LN2)) + 1.0f + B;
- float sMax = floor((cMax / pow(2.0f, expp - B - N)) + 0.5f);
+ float sMax = floor((cMax / pow(2.0f, expp - B - N)) + 0.5f);
- float exps = expp + 1.0f;
+ float exps = expp + 1.0f;
- if (0.0 <= sMax && sMax < pow2to9) {
- exps = expp;
- }
+ if (0.0 <= sMax && sMax < pow2to9) {
+ exps = expp;
+ }
- float sRed = floor((cRed / pow(2.0f, exps - B - N)) + 0.5f);
- float sGreen = floor((cGreen / pow(2.0f, exps - B - N)) + 0.5f);
- float sBlue = floor((cBlue / pow(2.0f, exps - B - N)) + 0.5f);
- //store as 8985 to have 2 extra neighbour bits
- uint light_rgbe = ((uint(sRed) & 0x1FF) >> 1) | ((uint(sGreen) & 0x1FF) << 8) | (((uint(sBlue) & 0x1FF) >> 1) << 17) | ((uint(exps) & 0x1F) << 25);
+ float sRed = floor((cRed / pow(2.0f, exps - B - N)) + 0.5f);
+ float sGreen = floor((cGreen / pow(2.0f, exps - B - N)) + 0.5f);
+ float sBlue = floor((cBlue / pow(2.0f, exps - B - N)) + 0.5f);
+ //store as 8985 to have 2 extra neighbour bits
+ uint light_rgbe = ((uint(sRed) & 0x1FF) >> 1) | ((uint(sGreen) & 0x1FF) << 8) | (((uint(sBlue) & 0x1FF) >> 1) << 17) | ((uint(exps) & 0x1F) << 25);
- imageStore(emission_grid, grid_pos, uvec4(light_rgbe));
- imageStore(emission_aniso_grid, grid_pos, uvec4(light_aniso));
- }
+ imageStore(emission_grid, grid_pos, uvec4(light_rgbe));
+ imageStore(emission_aniso_grid, grid_pos, uvec4(light_aniso));
}
+ }
#endif
#ifdef MODE_RENDER_MATERIAL
- albedo_output_buffer.rgb = albedo;
- albedo_output_buffer.a = alpha;
+ albedo_output_buffer.rgb = albedo;
+ albedo_output_buffer.a = alpha;
- normal_output_buffer.rgb = normal * 0.5 + 0.5;
- normal_output_buffer.a = 0.0;
- depth_output_buffer.r = -vertex.z;
+ normal_output_buffer.rgb = normal * 0.5 + 0.5;
+ normal_output_buffer.a = 0.0;
+ depth_output_buffer.r = -vertex.z;
- orm_output_buffer.r = ao;
- orm_output_buffer.g = roughness;
- orm_output_buffer.b = metallic;
- orm_output_buffer.a = sss_strength;
+ orm_output_buffer.r = ao;
+ orm_output_buffer.g = roughness;
+ orm_output_buffer.b = metallic;
+ orm_output_buffer.a = sss_strength;
- emission_output_buffer.rgb = emission;
- emission_output_buffer.a = 0.0;
+ emission_output_buffer.rgb = emission;
+ emission_output_buffer.a = 0.0;
#endif
#ifdef MODE_RENDER_NORMAL_ROUGHNESS
- normal_roughness_output_buffer = vec4(normal * 0.5 + 0.5, roughness);
-
-#ifdef MODE_RENDER_GIPROBE
- if (bool(instances.data[instance_index].flags & INSTANCE_FLAGS_USE_GIPROBE)) { // process giprobes
- uint index1 = instances.data[instance_index].gi_offset & 0xFFFF;
- uint index2 = instances.data[instance_index].gi_offset >> 16;
- giprobe_buffer.x = index1 & 0xFF;
- giprobe_buffer.y = index2 & 0xFF;
- } else {
- giprobe_buffer.x = 0xFF;
- giprobe_buffer.y = 0xFF;
- }
+ normal_roughness_output_buffer = vec4(normal * 0.5 + 0.5, roughness);
+
+#ifdef MODE_RENDER_VOXEL_GI
+ if (bool(instances.data[instance_index].flags & INSTANCE_FLAGS_USE_VOXEL_GI)) { // process voxel_gi_instances
+ uint index1 = instances.data[instance_index].gi_offset & 0xFFFF;
+ uint index2 = instances.data[instance_index].gi_offset >> 16;
+ voxel_gi_buffer.x = index1 & 0xFF;
+ voxel_gi_buffer.y = index2 & 0xFF;
+ } else {
+ voxel_gi_buffer.x = 0xFF;
+ voxel_gi_buffer.y = 0xFF;
+ }
#endif
#endif //MODE_RENDER_NORMAL_ROUGHNESS
@@ -1996,4 +1937,4 @@ void main() {
#endif //MODE_MULTIPLE_RENDER_TARGETS
#endif //MODE_RENDER_DEPTH
- }
+}
diff --git a/servers/rendering/renderer_rd/shaders/scene_forward_clustered_inc.glsl b/servers/rendering/renderer_rd/shaders/scene_forward_clustered_inc.glsl
index ca75d6300e..6599a42bab 100644
--- a/servers/rendering/renderer_rd/shaders/scene_forward_clustered_inc.glsl
+++ b/servers/rendering/renderer_rd/shaders/scene_forward_clustered_inc.glsl
@@ -1,7 +1,7 @@
#define M_PI 3.14159265359
#define ROUGHNESS_MAX_LOD 5
-#define MAX_GI_PROBES 8
+#define MAX_VOXEL_GI_INSTANCES 8
#if defined(has_GL_KHR_shader_subgroup_ballot) && defined(has_GL_KHR_shader_subgroup_arithmetic)
@@ -15,7 +15,7 @@
#include "cluster_data_inc.glsl"
#include "decal_data_inc.glsl"
-#if !defined(MODE_RENDER_DEPTH) || defined(MODE_RENDER_MATERIAL) || defined(MODE_RENDER_SDF) || defined(MODE_RENDER_NORMAL_ROUGHNESS) || defined(MODE_RENDER_GIPROBE) || defined(TANGENT_USED) || defined(NORMAL_MAP_USED)
+#if !defined(MODE_RENDER_DEPTH) || defined(MODE_RENDER_MATERIAL) || defined(MODE_RENDER_SDF) || defined(MODE_RENDER_NORMAL_ROUGHNESS) || defined(MODE_RENDER_VOXEL_GI) || defined(TANGENT_USED) || defined(NORMAL_MAP_USED)
#ifndef NORMAL_USED
#define NORMAL_USED
#endif
@@ -52,12 +52,13 @@ layout(set = 0, binding = 1) uniform sampler material_samplers[12];
layout(set = 0, binding = 2) uniform sampler shadow_sampler;
+#define INSTANCE_FLAGS_NON_UNIFORM_SCALE (1 << 5)
#define INSTANCE_FLAGS_USE_GI_BUFFERS (1 << 6)
#define INSTANCE_FLAGS_USE_SDFGI (1 << 7)
#define INSTANCE_FLAGS_USE_LIGHTMAP_CAPTURE (1 << 8)
#define INSTANCE_FLAGS_USE_LIGHTMAP (1 << 9)
#define INSTANCE_FLAGS_USE_SH_LIGHTMAP (1 << 10)
-#define INSTANCE_FLAGS_USE_GIPROBE (1 << 11)
+#define INSTANCE_FLAGS_USE_VOXEL_GI (1 << 11)
#define INSTANCE_FLAGS_MULTIMESH (1 << 12)
#define INSTANCE_FLAGS_MULTIMESH_FORMAT_2D (1 << 13)
#define INSTANCE_FLAGS_MULTIMESH_HAS_COLOR (1 << 14)
@@ -66,8 +67,6 @@ layout(set = 0, binding = 2) uniform sampler shadow_sampler;
//3 bits of stride
#define INSTANCE_FLAGS_PARTICLE_TRAIL_MASK 0xFF
-#define INSTANCE_FLAGS_NON_UNIFORM_SCALE (1 << 24)
-
layout(set = 0, binding = 3, std430) restrict readonly buffer OmniLights {
LightData data[];
}
@@ -122,7 +121,7 @@ layout(set = 0, binding = 12, std430) restrict readonly buffer GlobalVariableDat
}
global_variables;
-struct SDFGIProbeCascadeData {
+struct SDFVoxelGICascadeData {
vec3 position;
float to_probe;
ivec3 probe_world_offset;
@@ -153,7 +152,7 @@ layout(set = 0, binding = 13, std140) uniform SDFGI {
vec3 cascade_probe_size;
uint pad5;
- SDFGIProbeCascadeData cascades[SDFGI_MAX_CASCADES];
+ SDFVoxelGICascadeData cascades[SDFGI_MAX_CASCADES];
}
sdfgi;
@@ -275,7 +274,7 @@ layout(set = 1, binding = 5) uniform texture2D directional_shadow_atlas;
layout(set = 1, binding = 6) uniform texture2DArray lightmap_textures[MAX_LIGHTMAP_TEXTURES];
-layout(set = 1, binding = 7) uniform texture3D gi_probe_textures[MAX_GI_PROBES];
+layout(set = 1, binding = 7) uniform texture3D voxel_gi_textures[MAX_VOXEL_GI_INSTANCES];
layout(set = 1, binding = 8, std430) buffer restrict readonly ClusterBuffer {
uint data[];
@@ -306,7 +305,7 @@ layout(set = 1, binding = 14) uniform texture2D reflection_buffer;
layout(set = 1, binding = 15) uniform texture2DArray sdfgi_lightprobe_texture;
layout(set = 1, binding = 16) uniform texture3D sdfgi_occlusion_cascades;
-struct GIProbeData {
+struct VoxelGIData {
mat4 xform;
vec3 bounds;
float dynamic_range;
@@ -322,10 +321,10 @@ struct GIProbeData {
uint mipmaps;
};
-layout(set = 1, binding = 17, std140) uniform GIProbes {
- GIProbeData data[MAX_GI_PROBES];
+layout(set = 1, binding = 17, std140) uniform VoxelGIs {
+ VoxelGIData data[MAX_VOXEL_GI_INSTANCES];
}
-gi_probes;
+voxel_gi_instances;
layout(set = 1, binding = 18) uniform texture3D volumetric_fog_texture;
diff --git a/servers/rendering/renderer_rd/shaders/scene_forward_gi_inc.glsl b/servers/rendering/renderer_rd/shaders/scene_forward_gi_inc.glsl
index b41f16cbe7..c88bd0a14b 100644
--- a/servers/rendering/renderer_rd/shaders/scene_forward_gi_inc.glsl
+++ b/servers/rendering/renderer_rd/shaders/scene_forward_gi_inc.glsl
@@ -48,24 +48,24 @@ vec4 voxel_cone_trace_45_degrees(texture3D probe, vec3 cell_size, vec3 pos, vec3
return color;
}
-void gi_probe_compute(uint index, vec3 position, vec3 normal, vec3 ref_vec, mat3 normal_xform, float roughness, vec3 ambient, vec3 environment, inout vec4 out_spec, inout vec4 out_diff) {
- position = (gi_probes.data[index].xform * vec4(position, 1.0)).xyz;
- ref_vec = normalize((gi_probes.data[index].xform * vec4(ref_vec, 0.0)).xyz);
- normal = normalize((gi_probes.data[index].xform * vec4(normal, 0.0)).xyz);
+void voxel_gi_compute(uint index, vec3 position, vec3 normal, vec3 ref_vec, mat3 normal_xform, float roughness, vec3 ambient, vec3 environment, inout vec4 out_spec, inout vec4 out_diff) {
+ position = (voxel_gi_instances.data[index].xform * vec4(position, 1.0)).xyz;
+ ref_vec = normalize((voxel_gi_instances.data[index].xform * vec4(ref_vec, 0.0)).xyz);
+ normal = normalize((voxel_gi_instances.data[index].xform * vec4(normal, 0.0)).xyz);
- position += normal * gi_probes.data[index].normal_bias;
+ position += normal * voxel_gi_instances.data[index].normal_bias;
//this causes corrupted pixels, i have no idea why..
- if (any(bvec2(any(lessThan(position, vec3(0.0))), any(greaterThan(position, gi_probes.data[index].bounds))))) {
+ if (any(bvec2(any(lessThan(position, vec3(0.0))), any(greaterThan(position, voxel_gi_instances.data[index].bounds))))) {
return;
}
- vec3 blendv = abs(position / gi_probes.data[index].bounds * 2.0 - 1.0);
+ vec3 blendv = abs(position / voxel_gi_instances.data[index].bounds * 2.0 - 1.0);
float blend = clamp(1.0 - max(blendv.x, max(blendv.y, blendv.z)), 0.0, 1.0);
//float blend=1.0;
- float max_distance = length(gi_probes.data[index].bounds);
- vec3 cell_size = 1.0 / gi_probes.data[index].bounds;
+ float max_distance = length(voxel_gi_instances.data[index].bounds);
+ vec3 cell_size = 1.0 / voxel_gi_instances.data[index].bounds;
//radiance
@@ -83,26 +83,26 @@ void gi_probe_compute(uint index, vec3 position, vec3 normal, vec3 ref_vec, mat3
vec3 light = vec3(0.0);
for (int i = 0; i < MAX_CONE_DIRS; i++) {
- vec3 dir = normalize((gi_probes.data[index].xform * vec4(normal_xform * cone_dirs[i], 0.0)).xyz);
+ vec3 dir = normalize((voxel_gi_instances.data[index].xform * vec4(normal_xform * cone_dirs[i], 0.0)).xyz);
- vec4 cone_light = voxel_cone_trace_45_degrees(gi_probe_textures[index], cell_size, position, dir, cone_angle_tan, max_distance, gi_probes.data[index].bias);
+ vec4 cone_light = voxel_cone_trace_45_degrees(voxel_gi_textures[index], cell_size, position, dir, cone_angle_tan, max_distance, voxel_gi_instances.data[index].bias);
- if (gi_probes.data[index].blend_ambient) {
+ if (voxel_gi_instances.data[index].blend_ambient) {
cone_light.rgb = mix(ambient, cone_light.rgb, min(1.0, cone_light.a / 0.95));
}
light += cone_weights[i] * cone_light.rgb;
}
- light *= gi_probes.data[index].dynamic_range;
+ light *= voxel_gi_instances.data[index].dynamic_range;
out_diff += vec4(light * blend, blend);
//irradiance
- vec4 irr_light = voxel_cone_trace(gi_probe_textures[index], cell_size, position, ref_vec, tan(roughness * 0.5 * M_PI * 0.99), max_distance, gi_probes.data[index].bias);
- if (gi_probes.data[index].blend_ambient) {
+ vec4 irr_light = voxel_cone_trace(voxel_gi_textures[index], cell_size, position, ref_vec, tan(roughness * 0.5 * M_PI * 0.99), max_distance, voxel_gi_instances.data[index].bias);
+ if (voxel_gi_instances.data[index].blend_ambient) {
irr_light.rgb = mix(environment, irr_light.rgb, min(1.0, irr_light.a / 0.95));
}
- irr_light.rgb *= gi_probes.data[index].dynamic_range;
+ irr_light.rgb *= voxel_gi_instances.data[index].dynamic_range;
//irr_light=vec3(0.0);
out_spec += vec4(irr_light.rgb * blend, blend);
diff --git a/servers/rendering/renderer_rd/shaders/scene_forward_lights_inc.glsl b/servers/rendering/renderer_rd/shaders/scene_forward_lights_inc.glsl
index 32a86cb166..b6e89acb46 100644
--- a/servers/rendering/renderer_rd/shaders/scene_forward_lights_inc.glsl
+++ b/servers/rendering/renderer_rd/shaders/scene_forward_lights_inc.glsl
@@ -80,7 +80,6 @@ void light_compute(vec3 N, vec3 L, vec3 V, vec3 light_color, float attenuation,
#ifdef LIGHT_TRANSMITTANCE_USED
vec4 transmittance_color,
float transmittance_depth,
- float transmittance_curve,
float transmittance_boost,
float transmittance_z,
#endif
@@ -144,12 +143,7 @@ void light_compute(vec3 N, vec3 L, vec3 V, vec3 light_color, float attenuation,
float metallic = unpackUnorm4x8(orms).z;
if (metallic < 1.0) {
float roughness = unpackUnorm4x8(orms).y;
-
-#if defined(DIFFUSE_OREN_NAYAR)
- vec3 diffuse_brdf_NL;
-#else
float diffuse_brdf_NL; // BRDF times N.L for calculating diffuse radiance
-#endif
#if defined(DIFFUSE_LAMBERT_WRAP)
// energy conserving lambert wrap shader
@@ -194,9 +188,8 @@ void light_compute(vec3 N, vec3 L, vec3 V, vec3 light_color, float attenuation,
#ifdef LIGHT_TRANSMITTANCE_USED
-#ifdef SSS_MODE_SKIN
-
{
+#ifdef SSS_MODE_SKIN
float scale = 8.25 / transmittance_depth;
float d = scale * abs(transmittance_z);
float dd = -d * d;
@@ -208,19 +201,15 @@ void light_compute(vec3 N, vec3 L, vec3 V, vec3 light_color, float attenuation,
vec3(0.078, 0.0, 0.0) * exp(dd / 7.41);
diffuse_light += profile * transmittance_color.a * light_color * clamp(transmittance_boost - NdotL, 0.0, 1.0) * (1.0 / M_PI);
- }
#else
- if (transmittance_depth > 0.0) {
- float fade = clamp(abs(transmittance_z / transmittance_depth), 0.0, 1.0);
-
- fade = pow(max(0.0, 1.0 - fade), transmittance_curve);
- fade *= clamp(transmittance_boost - NdotL, 0.0, 1.0);
-
- diffuse_light += transmittance_color.rgb * light_color * (1.0 / M_PI) * transmittance_color.a * fade;
+ float scale = 8.25 / transmittance_depth;
+ float d = scale * abs(transmittance_z);
+ float dd = -d * d;
+ diffuse_light += exp(dd) * transmittance_color.rgb * transmittance_color.a * light_color * clamp(transmittance_boost - NdotL, 0.0, 1.0) * (1.0 / M_PI);
+#endif
}
-
-#endif //SSS_MODE_SKIN
+#else
#endif //LIGHT_TRANSMITTANCE_USED
}
@@ -243,7 +232,11 @@ void light_compute(vec3 N, vec3 L, vec3 V, vec3 light_color, float attenuation,
#elif defined(SPECULAR_PHONG)
vec3 R = normalize(-reflect(L, N));
+#ifdef USE_SOFT_SHADOWS
float cRdotV = clamp(A + dot(R, V), 0.0, 1.0);
+#else
+ float cRdotV = clamp(dot(R, V), 0.0, 1.0);
+#endif
float shininess = exp2(15.0 * (1.0 - roughness) + 1.0) * 0.25;
float phong = pow(cRdotV, shininess);
phong *= (shininess + 8.0) * (1.0 / (8.0 * M_PI));
@@ -578,7 +571,6 @@ void light_process_omni(uint idx, vec3 vertex, vec3 eye_vec, vec3 normal, vec3 v
#ifdef LIGHT_TRANSMITTANCE_USED
vec4 transmittance_color,
float transmittance_depth,
- float transmittance_curve,
float transmittance_boost,
#endif
#ifdef LIGHT_RIM_USED
@@ -618,20 +610,22 @@ void light_process_omni(uint idx, vec3 vertex, vec3 eye_vec, vec3 normal, vec3 v
//redo shadowmapping, but shrink the model a bit to avoid arctifacts
vec4 splane = (omni_lights.data[idx].shadow_matrix * vec4(vertex - normalize(normal_interp) * omni_lights.data[idx].transmittance_bias, 1.0));
- shadow_len = length(splane.xyz);
- splane = normalize(splane.xyz);
+ float shadow_len = length(splane.xyz);
+ splane.xyz = normalize(splane.xyz);
if (splane.z >= 0.0) {
splane.z += 1.0;
-
+ clamp_rect.y += clamp_rect.w;
} else {
splane.z = 1.0 - splane.z;
}
splane.xy /= splane.z;
+
splane.xy = splane.xy * 0.5 + 0.5;
splane.z = shadow_len * omni_lights.data[idx].inv_radius;
splane.xy = clamp_rect.xy + splane.xy * clamp_rect.zw;
+ // splane.xy = clamp(splane.xy,clamp_rect.xy + scene_data.shadow_atlas_pixel_size,clamp_rect.xy + clamp_rect.zw - scene_data.shadow_atlas_pixel_size );
splane.w = 1.0; //needed? i think it should be 1 already
float shadow_z = textureLod(sampler2D(shadow_atlas, material_samplers[SAMPLER_LINEAR_CLAMP]), splane.xy, 0.0).r;
@@ -705,7 +699,6 @@ void light_process_omni(uint idx, vec3 vertex, vec3 eye_vec, vec3 normal, vec3 v
#ifdef LIGHT_TRANSMITTANCE_USED
transmittance_color,
transmittance_depth,
- transmittance_curve,
transmittance_boost,
transmittance_z,
#endif
@@ -830,7 +823,6 @@ void light_process_spot(uint idx, vec3 vertex, vec3 eye_vec, vec3 normal, vec3 v
#ifdef LIGHT_TRANSMITTANCE_USED
vec4 transmittance_color,
float transmittance_depth,
- float transmittance_curve,
float transmittance_boost,
#endif
#ifdef LIGHT_RIM_USED
@@ -877,13 +869,17 @@ void light_process_spot(uint idx, vec3 vertex, vec3 eye_vec, vec3 normal, vec3 v
float transmittance_z = transmittance_depth;
transmittance_color.a *= light_attenuation;
{
- splane = (spot_lights.data[idx].shadow_matrix * vec4(vertex - normalize(normal_interp) * spot_lights.data[idx].transmittance_bias, 1.0));
+ vec4 splane = (spot_lights.data[idx].shadow_matrix * vec4(vertex - normalize(normal_interp) * spot_lights.data[idx].transmittance_bias, 1.0));
splane /= splane.w;
splane.xy = splane.xy * spot_lights.data[idx].atlas_rect.zw + spot_lights.data[idx].atlas_rect.xy;
float shadow_z = textureLod(sampler2D(shadow_atlas, material_samplers[SAMPLER_LINEAR_CLAMP]), splane.xy, 0.0).r;
- //reconstruct depth
- shadow_z /= spot_lights.data[idx].inv_radius;
+
+ shadow_z = shadow_z * 2.0 - 1.0;
+ float z_far = 1.0 / spot_lights.data[idx].inv_radius;
+ float z_near = 0.01;
+ shadow_z = 2.0 * z_near * z_far / (z_far + z_near - shadow_z * (z_far - z_near));
+
//distance to light plane
float z = dot(spot_dir, -light_rel_vec);
transmittance_z = z - shadow_z;
@@ -899,7 +895,6 @@ void light_process_spot(uint idx, vec3 vertex, vec3 eye_vec, vec3 normal, vec3 v
#ifdef LIGHT_TRANSMITTANCE_USED
transmittance_color,
transmittance_depth,
- transmittance_curve,
transmittance_boost,
transmittance_z,
#endif
diff --git a/servers/rendering/renderer_rd/shaders/scene_forward_mobile.glsl b/servers/rendering/renderer_rd/shaders/scene_forward_mobile.glsl
index d488c99b6d..1bc17e140f 100644
--- a/servers/rendering/renderer_rd/shaders/scene_forward_mobile.glsl
+++ b/servers/rendering/renderer_rd/shaders/scene_forward_mobile.glsl
@@ -96,6 +96,18 @@ layout(location = 8) out float dp_clip;
#endif
+#ifdef USE_MULTIVIEW
+#ifdef has_VK_KHR_multiview
+#define ViewIndex gl_ViewIndex
+#else
+// !BAS! This needs to become an input once we implement our fallback!
+#define ViewIndex 0
+#endif
+#else
+// Set to zero, not supported in non stereo
+#define ViewIndex 0
+#endif //USE_MULTIVIEW
+
invariant gl_Position;
#GLOBALS
@@ -234,7 +246,13 @@ void main() {
vec4 position;
#endif
+#ifdef USE_MULTIVIEW
+ mat4 projection_matrix = scene_data.projection_matrix_view[ViewIndex];
+ mat4 inv_projection_matrix = scene_data.inv_projection_matrix_view[ViewIndex];
+#else
mat4 projection_matrix = scene_data.projection_matrix;
+ mat4 inv_projection_matrix = scene_data.inv_projection_matrix;
+#endif //USE_MULTIVIEW
//using world coordinates
#if !defined(SKIP_TRANSFORM_USED) && defined(VERTEX_WORLD_COORDS_USED)
@@ -386,10 +404,26 @@ layout(location = 8) in float dp_clip;
#endif
+#ifdef USE_MULTIVIEW
+#ifdef has_VK_KHR_multiview
+#define ViewIndex gl_ViewIndex
+#else
+// !BAS! This needs to become an input once we implement our fallback!
+#define ViewIndex 0
+#endif
+#else
+// Set to zero, not supported in non stereo
+#define ViewIndex 0
+#endif //USE_MULTIVIEW
+
//defines to keep compatibility with vertex
#define world_matrix draw_call.transform
+#ifdef USE_MULTIVIEW
+#define projection_matrix scene_data.projection_matrix_view[ViewIndex]
+#else
#define projection_matrix scene_data.projection_matrix
+#endif
#if defined(ENABLE_SSS) && defined(ENABLE_TRANSMITTANCE)
//both required for transmittance to be enabled
@@ -509,7 +543,6 @@ void main() {
vec3 backlight = vec3(0.0);
vec4 transmittance_color = vec4(0.0);
float transmittance_depth = 0.0;
- float transmittance_curve = 1.0;
float transmittance_boost = 0.0;
float metallic = 0.0;
float specular = 0.5;
@@ -761,7 +794,7 @@ void main() {
if (scene_data.roughness_limiter_enabled) {
//http://www.jp.square-enix.com/tech/library/pdf/ImprovedGeometricSpecularAA.pdf
float roughness2 = roughness * roughness;
- vec3 dndu = dFdx(normal), dndv = dFdx(normal);
+ vec3 dndu = dFdx(normal), dndv = dFdy(normal);
float variance = scene_data.roughness_limiter_amount * (dot(dndu, dndu) + dot(dndv, dndv));
float kernelRoughness2 = min(2.0 * variance, scene_data.roughness_limiter_limit); //limit effect
float filteredRoughness2 = min(1.0, roughness2 + kernelRoughness2);
@@ -1259,7 +1292,6 @@ void main() {
#ifdef LIGHT_TRANSMITTANCE_USED
transmittance_color,
transmittance_depth,
- transmittance_curve,
transmittance_boost,
transmittance_z,
#endif
@@ -1310,7 +1342,6 @@ void main() {
#ifdef LIGHT_TRANSMITTANCE_USED
transmittance_color,
transmittance_depth,
- transmittance_curve,
transmittance_boost,
#endif
*/
@@ -1359,7 +1390,6 @@ void main() {
#ifdef LIGHT_TRANSMITTANCE_USED
transmittance_color,
transmittance_depth,
- transmittance_curve,
transmittance_boost,
#endif
*/
diff --git a/servers/rendering/renderer_rd/shaders/scene_forward_mobile_inc.glsl b/servers/rendering/renderer_rd/shaders/scene_forward_mobile_inc.glsl
index 0156b58574..d4ebcbeec4 100644
--- a/servers/rendering/renderer_rd/shaders/scene_forward_mobile_inc.glsl
+++ b/servers/rendering/renderer_rd/shaders/scene_forward_mobile_inc.glsl
@@ -1,4 +1,9 @@
#define M_PI 3.14159265359
+#define MAX_VIEWS 2
+
+#if defined(USE_MULTIVIEW) && defined(has_VK_KHR_multiview)
+#extension GL_EXT_multiview : enable
+#endif
#include "decal_data_inc.glsl"
@@ -46,12 +51,13 @@ layout(set = 0, binding = 1) uniform sampler material_samplers[12];
layout(set = 0, binding = 2) uniform sampler shadow_sampler;
+#define INSTANCE_FLAGS_NON_UNIFORM_SCALE (1 << 5)
#define INSTANCE_FLAGS_USE_GI_BUFFERS (1 << 6)
#define INSTANCE_FLAGS_USE_SDFGI (1 << 7)
#define INSTANCE_FLAGS_USE_LIGHTMAP_CAPTURE (1 << 8)
#define INSTANCE_FLAGS_USE_LIGHTMAP (1 << 9)
#define INSTANCE_FLAGS_USE_SH_LIGHTMAP (1 << 10)
-#define INSTANCE_FLAGS_USE_GIPROBE (1 << 11)
+#define INSTANCE_FLAGS_USE_VOXEL_GI (1 << 11)
#define INSTANCE_FLAGS_MULTIMESH (1 << 12)
#define INSTANCE_FLAGS_MULTIMESH_FORMAT_2D (1 << 13)
#define INSTANCE_FLAGS_MULTIMESH_HAS_COLOR (1 << 14)
@@ -60,8 +66,6 @@ layout(set = 0, binding = 2) uniform sampler shadow_sampler;
//3 bits of stride
#define INSTANCE_FLAGS_PARTICLE_TRAIL_MASK 0xFF
-#define INSTANCE_FLAGS_NON_UNIFORM_SCALE (1 << 24)
-
layout(set = 0, binding = 3, std430) restrict readonly buffer OmniLights {
LightData data[];
}
@@ -121,10 +125,13 @@ global_variables;
layout(set = 1, binding = 0, std140) uniform SceneData {
mat4 projection_matrix;
mat4 inv_projection_matrix;
-
mat4 camera_matrix;
mat4 inv_camera_matrix;
+ // only used for multiview
+ mat4 projection_matrix_view[MAX_VIEWS];
+ mat4 inv_projection_matrix_view[MAX_VIEWS];
+
vec2 viewport_size;
vec2 screen_pixel_size;
diff --git a/servers/rendering/renderer_rd/shaders/screen_space_reflection_scale.glsl b/servers/rendering/renderer_rd/shaders/screen_space_reflection_scale.glsl
index 7e06516d90..2328effe7b 100644
--- a/servers/rendering/renderer_rd/shaders/screen_space_reflection_scale.glsl
+++ b/servers/rendering/renderer_rd/shaders/screen_space_reflection_scale.glsl
@@ -36,12 +36,12 @@ void main() {
float divisor = 0.0;
vec4 color;
float depth;
- vec3 normal;
+ vec4 normal;
if (params.filtered) {
color = vec4(0.0);
depth = 0.0;
- normal = vec3(0.0);
+ normal = vec4(0.0);
for (int i = 0; i < 4; i++) {
ivec2 ofs = ssC << 1;
@@ -53,7 +53,9 @@ void main() {
}
color += texelFetch(source_ssr, ofs, 0);
float d = texelFetch(source_depth, ofs, 0).r;
- normal += texelFetch(source_normal, ofs, 0).xyz * 2.0 - 1.0;
+ vec4 nr = texelFetch(source_normal, ofs, 0);
+ normal.xyz += nr.xyz * 2.0 - 1.0;
+ normal.w += nr.w;
d = d * 2.0 - 1.0;
if (params.orthogonal) {
@@ -66,11 +68,12 @@ void main() {
color /= 4.0;
depth /= 4.0;
- normal = normalize(normal / 4.0) * 0.5 + 0.5;
+ normal.xyz = normalize(normal.xyz / 4.0) * 0.5 + 0.5;
+ normal.w /= 4.0;
} else {
color = texelFetch(source_ssr, ssC << 1, 0);
depth = texelFetch(source_depth, ssC << 1, 0).r;
- normal = texelFetch(source_normal, ssC << 1, 0).xyz;
+ normal = texelFetch(source_normal, ssC << 1, 0);
depth = depth * 2.0 - 1.0;
if (params.orthogonal) {
@@ -83,5 +86,5 @@ void main() {
imageStore(dest_ssr, ssC, color);
imageStore(dest_depth, ssC, vec4(depth));
- imageStore(dest_normal, ssC, vec4(normal, 0.0));
+ imageStore(dest_normal, ssC, normal);
}
diff --git a/servers/rendering/renderer_rd/shaders/sky.glsl b/servers/rendering/renderer_rd/shaders/sky.glsl
index 9924da37d5..41c6325bc5 100644
--- a/servers/rendering/renderer_rd/shaders/sky.glsl
+++ b/servers/rendering/renderer_rd/shaders/sky.glsl
@@ -4,11 +4,17 @@
#VERSION_DEFINES
+#define MAX_VIEWS 2
+
+#if defined(USE_MULTIVIEW) && defined(has_VK_KHR_multiview)
+#extension GL_EXT_multiview : enable
+#endif
+
layout(location = 0) out vec2 uv_interp;
layout(push_constant, binding = 1, std430) uniform Params {
mat3 orientation;
- vec4 proj;
+ vec4 projections[MAX_VIEWS];
vec4 position_multiplier;
float time;
}
@@ -26,15 +32,29 @@ void main() {
#VERSION_DEFINES
+#ifdef USE_MULTIVIEW
+#ifdef has_VK_KHR_multiview
+#extension GL_EXT_multiview : enable
+#define ViewIndex gl_ViewIndex
+#else // has_VK_KHR_multiview
+// !BAS! This needs to become an input once we implement our fallback!
+#define ViewIndex 0
+#endif // has_VK_KHR_multiview
+#else // USE_MULTIVIEW
+// Set to zero, not supported in non stereo
+#define ViewIndex 0
+#endif //USE_MULTIVIEW
+
#define M_PI 3.14159265359
+#define MAX_VIEWS 2
layout(location = 0) in vec2 uv_interp;
layout(push_constant, binding = 1, std430) uniform Params {
mat3 orientation;
- vec4 proj;
+ vec4 projections[MAX_VIEWS];
vec4 position_multiplier;
- float time; //TODO consider adding vec2 screen res, and float radiance size
+ float time;
}
params;
@@ -85,7 +105,6 @@ struct DirectionalLightData {
layout(set = 0, binding = 3, std140) uniform DirectionalLights {
DirectionalLightData data[MAX_DIRECTIONAL_LIGHT_DATA_STRUCTS];
}
-
directional_lights;
#ifdef MATERIAL_UNIFORMS_USED
@@ -154,8 +173,8 @@ vec4 fog_process(vec3 view, vec3 sky_color) {
void main() {
vec3 cube_normal;
cube_normal.z = -1.0;
- cube_normal.x = (cube_normal.z * (-uv_interp.x - params.proj.x)) / params.proj.y;
- cube_normal.y = -(cube_normal.z * (-uv_interp.y - params.proj.z)) / params.proj.w;
+ cube_normal.x = (cube_normal.z * (-uv_interp.x - params.projections[ViewIndex].x)) / params.projections[ViewIndex].y;
+ cube_normal.y = -(cube_normal.z * (-uv_interp.y - params.projections[ViewIndex].z)) / params.projections[ViewIndex].w;
cube_normal = mat3(params.orientation) * cube_normal;
cube_normal.z = -cube_normal.z;
cube_normal = normalize(cube_normal);
diff --git a/servers/rendering/renderer_rd/shaders/tonemap.glsl b/servers/rendering/renderer_rd/shaders/tonemap.glsl
index 86b4da6b08..23f83b3b9c 100644
--- a/servers/rendering/renderer_rd/shaders/tonemap.glsl
+++ b/servers/rendering/renderer_rd/shaders/tonemap.glsl
@@ -4,6 +4,12 @@
#VERSION_DEFINES
+#ifdef MULTIVIEW
+#ifdef has_VK_KHR_multiview
+#extension GL_EXT_multiview : enable
+#endif
+#endif
+
layout(location = 0) out vec2 uv_interp;
void main() {
@@ -18,9 +24,22 @@ void main() {
#VERSION_DEFINES
+#ifdef MULTIVIEW
+#ifdef has_VK_KHR_multiview
+#extension GL_EXT_multiview : enable
+#define ViewIndex gl_ViewIndex
+#else // has_VK_KHR_multiview
+#define ViewIndex 0
+#endif // has_VK_KHR_multiview
+#endif //MULTIVIEW
+
layout(location = 0) in vec2 uv_interp;
+#ifdef MULTIVIEW
+layout(set = 0, binding = 0) uniform sampler2DArray source_color;
+#else
layout(set = 0, binding = 0) uniform sampler2D source_color;
+#endif
layout(set = 1, binding = 0) uniform sampler2D source_auto_exposure;
layout(set = 2, binding = 0) uniform sampler2D source_glow;
#ifdef USE_1D_LUT
@@ -277,10 +296,17 @@ vec3 do_fxaa(vec3 color, float exposure, vec2 uv_interp) {
const float FXAA_REDUCE_MUL = (1.0 / 8.0);
const float FXAA_SPAN_MAX = 8.0;
+#ifdef MULTIVIEW
+ vec3 rgbNW = textureLod(source_color, vec3(uv_interp + vec2(-1.0, -1.0) * params.pixel_size, ViewIndex), 0.0).xyz * exposure;
+ vec3 rgbNE = textureLod(source_color, vec3(uv_interp + vec2(1.0, -1.0) * params.pixel_size, ViewIndex), 0.0).xyz * exposure;
+ vec3 rgbSW = textureLod(source_color, vec3(uv_interp + vec2(-1.0, 1.0) * params.pixel_size, ViewIndex), 0.0).xyz * exposure;
+ vec3 rgbSE = textureLod(source_color, vec3(uv_interp + vec2(1.0, 1.0) * params.pixel_size, ViewIndex), 0.0).xyz * exposure;
+#else
vec3 rgbNW = textureLod(source_color, uv_interp + vec2(-1.0, -1.0) * params.pixel_size, 0.0).xyz * exposure;
vec3 rgbNE = textureLod(source_color, uv_interp + vec2(1.0, -1.0) * params.pixel_size, 0.0).xyz * exposure;
vec3 rgbSW = textureLod(source_color, uv_interp + vec2(-1.0, 1.0) * params.pixel_size, 0.0).xyz * exposure;
vec3 rgbSE = textureLod(source_color, uv_interp + vec2(1.0, 1.0) * params.pixel_size, 0.0).xyz * exposure;
+#endif
vec3 rgbM = color;
vec3 luma = vec3(0.299, 0.587, 0.114);
float lumaNW = dot(rgbNW, luma);
@@ -305,8 +331,13 @@ vec3 do_fxaa(vec3 color, float exposure, vec2 uv_interp) {
dir * rcpDirMin)) *
params.pixel_size;
+#ifdef MULTIVIEW
+ vec3 rgbA = 0.5 * exposure * (textureLod(source_color, vec3(uv_interp + dir * (1.0 / 3.0 - 0.5), ViewIndex), 0.0).xyz + textureLod(source_color, vec3(uv_interp + dir * (2.0 / 3.0 - 0.5), ViewIndex), 0.0).xyz);
+ vec3 rgbB = rgbA * 0.5 + 0.25 * exposure * (textureLod(source_color, vec3(uv_interp + dir * -0.5, ViewIndex), 0.0).xyz + textureLod(source_color, vec3(uv_interp + dir * 0.5, ViewIndex), 0.0).xyz);
+#else
vec3 rgbA = 0.5 * exposure * (textureLod(source_color, uv_interp + dir * (1.0 / 3.0 - 0.5), 0.0).xyz + textureLod(source_color, uv_interp + dir * (2.0 / 3.0 - 0.5), 0.0).xyz);
vec3 rgbB = rgbA * 0.5 + 0.25 * exposure * (textureLod(source_color, uv_interp + dir * -0.5, 0.0).xyz + textureLod(source_color, uv_interp + dir * 0.5, 0.0).xyz);
+#endif
float lumaB = dot(rgbB, luma);
if ((lumaB < lumaMin) || (lumaB > lumaMax)) {
@@ -329,7 +360,11 @@ vec3 screen_space_dither(vec2 frag_coord) {
}
void main() {
+#ifdef MULTIVIEW
+ vec3 color = textureLod(source_color, vec3(uv_interp, ViewIndex), 0.0f).rgb;
+#else
vec3 color = textureLod(source_color, uv_interp, 0.0f).rgb;
+#endif
// Exposure
diff --git a/servers/rendering/renderer_rd/shaders/volumetric_fog.glsl b/servers/rendering/renderer_rd/shaders/volumetric_fog.glsl
index c793b6ebe1..f2010222e5 100644
--- a/servers/rendering/renderer_rd/shaders/volumetric_fog.glsl
+++ b/servers/rendering/renderer_rd/shaders/volumetric_fog.glsl
@@ -72,9 +72,9 @@ layout(rgba16f, set = 0, binding = 9) uniform restrict writeonly image3D dest_ma
layout(set = 0, binding = 10) uniform sampler shadow_sampler;
-#define MAX_GI_PROBES 8
+#define MAX_VOXEL_GI_INSTANCES 8
-struct GIProbeData {
+struct VoxelGIData {
mat4 xform;
vec3 bounds;
float dynamic_range;
@@ -90,12 +90,12 @@ struct GIProbeData {
uint mipmaps;
};
-layout(set = 0, binding = 11, std140) uniform GIProbes {
- GIProbeData data[MAX_GI_PROBES];
+layout(set = 0, binding = 11, std140) uniform VoxelGIs {
+ VoxelGIData data[MAX_VOXEL_GI_INSTANCES];
}
-gi_probes;
+voxel_gi_instances;
-layout(set = 0, binding = 12) uniform texture3D gi_probe_textures[MAX_GI_PROBES];
+layout(set = 0, binding = 12) uniform texture3D voxel_gi_textures[MAX_VOXEL_GI_INSTANCES];
layout(set = 0, binding = 13) uniform sampler linear_sampler_with_mipmaps;
@@ -104,7 +104,7 @@ layout(set = 0, binding = 13) uniform sampler linear_sampler_with_mipmaps;
// SDFGI Integration on set 1
#define SDFGI_MAX_CASCADES 8
-struct SDFGIProbeCascadeData {
+struct SDFVoxelGICascadeData {
vec3 position;
float to_probe;
ivec3 probe_world_offset;
@@ -135,7 +135,7 @@ layout(set = 1, binding = 0, std140) uniform SDFGI {
vec3 cascade_probe_size;
uint pad5;
- SDFGIProbeCascadeData cascades[SDFGI_MAX_CASCADES];
+ SDFVoxelGICascadeData cascades[SDFGI_MAX_CASCADES];
}
sdfgi;
@@ -162,7 +162,7 @@ layout(set = 0, binding = 14, std140) uniform Params {
float detail_spread;
float gi_inject;
- uint max_gi_probes;
+ uint max_voxel_gi_instances;
uint cluster_type_size;
vec2 screen_size;
@@ -533,21 +533,21 @@ void main() {
vec3 world_pos = mat3(params.cam_rotation) * view_pos;
- for (uint i = 0; i < params.max_gi_probes; i++) {
- vec3 position = (gi_probes.data[i].xform * vec4(world_pos, 1.0)).xyz;
+ for (uint i = 0; i < params.max_voxel_gi_instances; i++) {
+ vec3 position = (voxel_gi_instances.data[i].xform * vec4(world_pos, 1.0)).xyz;
//this causes corrupted pixels, i have no idea why..
- if (all(bvec2(all(greaterThanEqual(position, vec3(0.0))), all(lessThan(position, gi_probes.data[i].bounds))))) {
- position /= gi_probes.data[i].bounds;
+ if (all(bvec2(all(greaterThanEqual(position, vec3(0.0))), all(lessThan(position, voxel_gi_instances.data[i].bounds))))) {
+ position /= voxel_gi_instances.data[i].bounds;
vec4 light = vec4(0.0);
- for (uint j = 0; j < gi_probes.data[i].mipmaps; j++) {
- vec4 slight = textureLod(sampler3D(gi_probe_textures[i], linear_sampler_with_mipmaps), position, float(j));
+ for (uint j = 0; j < voxel_gi_instances.data[i].mipmaps; j++) {
+ vec4 slight = textureLod(sampler3D(voxel_gi_textures[i], linear_sampler_with_mipmaps), position, float(j));
float a = (1.0 - light.a);
light += a * slight;
}
- light.rgb *= gi_probes.data[i].dynamic_range * params.gi_inject;
+ light.rgb *= voxel_gi_instances.data[i].dynamic_range * params.gi_inject;
total_light += light.rgb;
}
diff --git a/servers/rendering/renderer_rd/shaders/giprobe.glsl b/servers/rendering/renderer_rd/shaders/voxel_gi.glsl
index 49a493cdc7..49a493cdc7 100644
--- a/servers/rendering/renderer_rd/shaders/giprobe.glsl
+++ b/servers/rendering/renderer_rd/shaders/voxel_gi.glsl
diff --git a/servers/rendering/renderer_rd/shaders/giprobe_debug.glsl b/servers/rendering/renderer_rd/shaders/voxel_gi_debug.glsl
index 7d4d72967a..7d4d72967a 100644
--- a/servers/rendering/renderer_rd/shaders/giprobe_debug.glsl
+++ b/servers/rendering/renderer_rd/shaders/voxel_gi_debug.glsl
diff --git a/servers/rendering/renderer_rd/shaders/giprobe_sdf.glsl b/servers/rendering/renderer_rd/shaders/voxel_gi_sdf.glsl
index e20b3f680d..e20b3f680d 100644
--- a/servers/rendering/renderer_rd/shaders/giprobe_sdf.glsl
+++ b/servers/rendering/renderer_rd/shaders/voxel_gi_sdf.glsl