summaryrefslogtreecommitdiff
path: root/servers/rendering
diff options
context:
space:
mode:
Diffstat (limited to 'servers/rendering')
-rw-r--r--servers/rendering/renderer_compositor.h17
-rw-r--r--servers/rendering/renderer_rd/forward_clustered/render_forward_clustered.cpp387
-rw-r--r--servers/rendering/renderer_rd/forward_clustered/render_forward_clustered.h8
-rw-r--r--servers/rendering/renderer_rd/forward_mobile/render_forward_mobile.cpp273
-rw-r--r--servers/rendering/renderer_rd/forward_mobile/render_forward_mobile.h8
-rw-r--r--servers/rendering/renderer_rd/renderer_compositor_rd.cpp95
-rw-r--r--servers/rendering/renderer_rd/renderer_compositor_rd.h35
-rw-r--r--servers/rendering/renderer_rd/renderer_scene_gi_rd.cpp2
-rw-r--r--servers/rendering/renderer_rd/renderer_scene_gi_rd.h5
-rw-r--r--servers/rendering/renderer_rd/renderer_scene_render_rd.cpp149
-rw-r--r--servers/rendering/renderer_rd/renderer_scene_render_rd.h74
-rw-r--r--servers/rendering/renderer_rd/shaders/blit.glsl95
12 files changed, 664 insertions, 484 deletions
diff --git a/servers/rendering/renderer_compositor.h b/servers/rendering/renderer_compositor.h
index 919ae2c6da..41aaba0f4c 100644
--- a/servers/rendering/renderer_compositor.h
+++ b/servers/rendering/renderer_compositor.h
@@ -59,7 +59,22 @@ public:
struct BlitToScreen {
RID render_target;
Rect2i rect;
- //lens distorted parameters for VR should go here
+
+ struct {
+ bool use_layer = false;
+ uint32_t layer = 0;
+ } multi_view;
+
+ struct {
+ //lens distorted parameters for VR
+ bool apply = false;
+ Vector2 eye_center;
+ float k1 = 0.0;
+ float k2 = 0.0;
+
+ float upscale = 1.0;
+ float aspect_ratio = 1.0;
+ } lens_distortion;
};
virtual void prepare_for_blitting_render_targets() = 0;
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 aadb7bac19..16c6273ff6 100644
--- a/servers/rendering/renderer_rd/forward_clustered/render_forward_clustered.cpp
+++ b/servers/rendering/renderer_rd/forward_clustered/render_forward_clustered.cpp
@@ -536,21 +536,21 @@ void RenderForwardClustered::_render_list_with_threads(RenderListParameters *p_p
}
}
-void RenderForwardClustered::_setup_environment(RID p_environment, RID p_render_buffers, const CameraMatrix &p_cam_projection, const Transform &p_cam_transform, RID p_reflection_probe, bool p_no_fog, const Size2i &p_screen_size, uint32_t p_cluster_size, uint32_t p_max_cluster_elements, RID p_shadow_atlas, bool p_flip_y, const Color &p_default_bg_color, float p_znear, float p_zfar, bool p_opaque_render_buffers, bool p_pancake_shadows, int p_index) {
- //CameraMatrix projection = p_cam_projection;
+void RenderForwardClustered::_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, bool p_pancake_shadows, int p_index) {
+ //CameraMatrix projection = p_render_data->cam_projection;
//projection.flip_y(); // Vulkan and modern APIs use Y-Down
CameraMatrix correction;
correction.set_depth_correction(p_flip_y);
- CameraMatrix projection = correction * p_cam_projection;
+ CameraMatrix projection = correction * p_render_data->cam_projection;
//store camera into ubo
RendererStorageRD::store_camera(projection, scene_state.ubo.projection_matrix);
RendererStorageRD::store_camera(projection.inverse(), scene_state.ubo.inv_projection_matrix);
- RendererStorageRD::store_transform(p_cam_transform, scene_state.ubo.camera_matrix);
- RendererStorageRD::store_transform(p_cam_transform.affine_inverse(), scene_state.ubo.inv_camera_matrix);
+ 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);
- scene_state.ubo.z_far = p_zfar;
- scene_state.ubo.z_near = p_znear;
+ scene_state.ubo.z_far = p_render_data->z_far;
+ scene_state.ubo.z_near = p_render_data->z_near;
scene_state.ubo.pancake_shadows = p_pancake_shadows;
@@ -568,17 +568,17 @@ void RenderForwardClustered::_setup_environment(RID p_environment, RID p_render_
scene_state.ubo.screen_pixel_size[0] = screen_pixel_size.x;
scene_state.ubo.screen_pixel_size[1] = screen_pixel_size.y;
- scene_state.ubo.cluster_shift = get_shift_from_power_of_2(p_cluster_size);
- scene_state.ubo.max_cluster_element_count_div_32 = p_max_cluster_elements / 32;
+ scene_state.ubo.cluster_shift = get_shift_from_power_of_2(p_render_data->cluster_size);
+ scene_state.ubo.max_cluster_element_count_div_32 = p_render_data->cluster_max_elements / 32;
{
- uint32_t cluster_screen_width = (p_screen_size.width - 1) / p_cluster_size + 1;
- uint32_t cluster_screen_height = (p_screen_size.height - 1) / p_cluster_size + 1;
+ uint32_t cluster_screen_width = (p_screen_size.width - 1) / p_render_data->cluster_size + 1;
+ uint32_t cluster_screen_height = (p_screen_size.height - 1) / p_render_data->cluster_size + 1;
scene_state.ubo.cluster_type_size = cluster_screen_width * cluster_screen_height * (scene_state.ubo.max_cluster_element_count_div_32 + 32);
scene_state.ubo.cluster_width = cluster_screen_width;
}
- if (p_shadow_atlas.is_valid()) {
- Vector2 sas = shadow_atlas_get_size(p_shadow_atlas);
+ if (p_render_data->shadow_atlas.is_valid()) {
+ Vector2 sas = shadow_atlas_get_size(p_render_data->shadow_atlas);
scene_state.ubo.shadow_atlas_pixel_size[0] = 1.0 / sas.x;
scene_state.ubo.shadow_atlas_pixel_size[1] = 1.0 / sas.y;
}
@@ -594,22 +594,22 @@ void RenderForwardClustered::_setup_environment(RID p_environment, RID p_render_
scene_state.ubo.volumetric_fog_enabled = false;
scene_state.ubo.fog_enabled = false;
- if (p_render_buffers.is_valid()) {
- RenderBufferDataForwardClustered *render_buffers = (RenderBufferDataForwardClustered *)render_buffers_get_data(p_render_buffers);
+ if (p_render_data->render_buffers.is_valid()) {
+ RenderBufferDataForwardClustered *render_buffers = (RenderBufferDataForwardClustered *)render_buffers_get_data(p_render_data->render_buffers);
if (render_buffers->msaa != RS::VIEWPORT_MSAA_DISABLED) {
scene_state.ubo.gi_upscale_for_msaa = true;
}
- if (render_buffers_has_volumetric_fog(p_render_buffers)) {
+ if (render_buffers_has_volumetric_fog(p_render_data->render_buffers)) {
scene_state.ubo.volumetric_fog_enabled = true;
- float fog_end = render_buffers_get_volumetric_fog_end(p_render_buffers);
+ float fog_end = render_buffers_get_volumetric_fog_end(p_render_data->render_buffers);
if (fog_end > 0.0) {
scene_state.ubo.volumetric_fog_inv_length = 1.0 / fog_end;
} else {
scene_state.ubo.volumetric_fog_inv_length = 1.0;
}
- float fog_detail_spread = render_buffers_get_volumetric_fog_detail_spread(p_render_buffers); //reverse lookup
+ float fog_detail_spread = render_buffers_get_volumetric_fog_detail_spread(p_render_data->render_buffers); //reverse lookup
if (fog_detail_spread > 0.0) {
scene_state.ubo.volumetric_fog_detail_spread = 1.0 / fog_detail_spread;
} else {
@@ -618,26 +618,26 @@ void RenderForwardClustered::_setup_environment(RID p_environment, RID p_render_
}
}
#if 0
- if (p_render_buffers.is_valid() && render_buffers_is_sdfgi_enabled(p_render_buffers)) {
- scene_state.ubo.sdfgi_cascade_count = render_buffers_get_sdfgi_cascade_count(p_render_buffers);
- scene_state.ubo.sdfgi_probe_axis_size = render_buffers_get_sdfgi_cascade_probe_count(p_render_buffers);
+ if (p_render_data->render_buffers.is_valid() && render_buffers_is_sdfgi_enabled(p_render_data->render_buffers)) {
+ scene_state.ubo.sdfgi_cascade_count = render_buffers_get_sdfgi_cascade_count(p_render_data->render_buffers);
+ scene_state.ubo.sdfgi_probe_axis_size = render_buffers_get_sdfgi_cascade_probe_count(p_render_data->render_buffers);
scene_state.ubo.sdfgi_cascade_probe_size[0] = scene_state.ubo.sdfgi_probe_axis_size - 1; //float version for performance
scene_state.ubo.sdfgi_cascade_probe_size[1] = scene_state.ubo.sdfgi_probe_axis_size - 1;
scene_state.ubo.sdfgi_cascade_probe_size[2] = scene_state.ubo.sdfgi_probe_axis_size - 1;
- float csize = render_buffers_get_sdfgi_cascade_size(p_render_buffers);
+ float csize = render_buffers_get_sdfgi_cascade_size(p_render_data->render_buffers);
scene_state.ubo.sdfgi_probe_to_uvw = 1.0 / float(scene_state.ubo.sdfgi_cascade_probe_size[0]);
float occ_bias = 0.0;
scene_state.ubo.sdfgi_occlusion_bias = occ_bias / csize;
- scene_state.ubo.sdfgi_use_occlusion = render_buffers_is_sdfgi_using_occlusion(p_render_buffers);
- scene_state.ubo.sdfgi_energy = render_buffers_get_sdfgi_energy(p_render_buffers);
+ scene_state.ubo.sdfgi_use_occlusion = render_buffers_is_sdfgi_using_occlusion(p_render_data->render_buffers);
+ scene_state.ubo.sdfgi_energy = render_buffers_get_sdfgi_energy(p_render_data->render_buffers);
float cascade_voxel_size = (csize / scene_state.ubo.sdfgi_cascade_probe_size[0]);
float occlusion_clamp = (cascade_voxel_size - 0.5) / cascade_voxel_size;
scene_state.ubo.sdfgi_occlusion_clamp[0] = occlusion_clamp;
scene_state.ubo.sdfgi_occlusion_clamp[1] = occlusion_clamp;
scene_state.ubo.sdfgi_occlusion_clamp[2] = occlusion_clamp;
- scene_state.ubo.sdfgi_normal_bias = (render_buffers_get_sdfgi_normal_bias(p_render_buffers) / csize) * scene_state.ubo.sdfgi_cascade_probe_size[0];
+ scene_state.ubo.sdfgi_normal_bias = (render_buffers_get_sdfgi_normal_bias(p_render_data->render_buffers) / csize) * scene_state.ubo.sdfgi_cascade_probe_size[0];
//vec2 tex_pixel_size = 1.0 / vec2(ivec2( (OCT_SIZE+2) * params.probe_axis_size * params.probe_axis_size, (OCT_SIZE+2) * params.probe_axis_size ) );
//vec3 probe_uv_offset = (ivec3(OCT_SIZE+2,OCT_SIZE+2,(OCT_SIZE+2) * params.probe_axis_size)) * tex_pixel_size.xyx;
@@ -658,14 +658,14 @@ void RenderForwardClustered::_setup_environment(RID p_environment, RID p_render_
for (uint32_t i = 0; i < scene_state.ubo.sdfgi_cascade_count; i++) {
SceneState::UBO::SDFGICascade &c = scene_state.ubo.sdfgi_cascades[i];
- Vector3 pos = render_buffers_get_sdfgi_cascade_offset(p_render_buffers, i);
- pos -= p_cam_transform.origin; //make pos local to camera, to reduce numerical error
+ Vector3 pos = render_buffers_get_sdfgi_cascade_offset(p_render_data->render_buffers, i);
+ pos -= p_render_data->cam_transform.origin; //make pos local to camera, to reduce numerical error
c.position[0] = pos.x;
c.position[1] = pos.y;
c.position[2] = pos.z;
- c.to_probe = 1.0 / render_buffers_get_sdfgi_cascade_probe_size(p_render_buffers, i);
+ c.to_probe = 1.0 / render_buffers_get_sdfgi_cascade_probe_size(p_render_data->render_buffers, i);
- Vector3i probe_ofs = render_buffers_get_sdfgi_cascade_probe_offset(p_render_buffers, i);
+ Vector3i probe_ofs = render_buffers_get_sdfgi_cascade_probe_offset(p_render_data->render_buffers, i);
c.probe_world_offset[0] = probe_ofs.x;
c.probe_world_offset[1] = probe_ofs.y;
c.probe_world_offset[2] = probe_ofs.z;
@@ -682,18 +682,18 @@ void RenderForwardClustered::_setup_environment(RID p_environment, RID p_render_
scene_state.ubo.use_reflection_cubemap = false;
scene_state.ubo.ssao_enabled = false;
- } else if (is_environment(p_environment)) {
- RS::EnvironmentBG env_bg = environment_get_background(p_environment);
- RS::EnvironmentAmbientSource ambient_src = environment_get_ambient_source(p_environment);
+ } else if (is_environment(p_render_data->environment)) {
+ RS::EnvironmentBG env_bg = environment_get_background(p_render_data->environment);
+ RS::EnvironmentAmbientSource ambient_src = environment_get_ambient_source(p_render_data->environment);
- float bg_energy = environment_get_bg_energy(p_environment);
+ float bg_energy = environment_get_bg_energy(p_render_data->environment);
scene_state.ubo.ambient_light_color_energy[3] = bg_energy;
- scene_state.ubo.ambient_color_sky_mix = environment_get_ambient_sky_contribution(p_environment);
+ scene_state.ubo.ambient_color_sky_mix = environment_get_ambient_sky_contribution(p_render_data->environment);
//ambient
if (ambient_src == RS::ENV_AMBIENT_SOURCE_BG && (env_bg == RS::ENV_BG_CLEAR_COLOR || env_bg == RS::ENV_BG_COLOR)) {
- Color color = env_bg == RS::ENV_BG_CLEAR_COLOR ? p_default_bg_color : environment_get_bg_color(p_environment);
+ Color color = env_bg == RS::ENV_BG_CLEAR_COLOR ? p_default_bg_color : environment_get_bg_color(p_render_data->environment);
color = color.to_linear();
scene_state.ubo.ambient_light_color_energy[0] = color.r * bg_energy;
@@ -702,15 +702,15 @@ void RenderForwardClustered::_setup_environment(RID p_environment, RID p_render_
scene_state.ubo.use_ambient_light = true;
scene_state.ubo.use_ambient_cubemap = false;
} else {
- float energy = environment_get_ambient_light_energy(p_environment);
- Color color = environment_get_ambient_light_color(p_environment);
+ float energy = environment_get_ambient_light_energy(p_render_data->environment);
+ Color color = environment_get_ambient_light_color(p_render_data->environment);
color = color.to_linear();
scene_state.ubo.ambient_light_color_energy[0] = color.r * energy;
scene_state.ubo.ambient_light_color_energy[1] = color.g * energy;
scene_state.ubo.ambient_light_color_energy[2] = color.b * energy;
- Basis sky_transform = environment_get_sky_orientation(p_environment);
- sky_transform = sky_transform.inverse() * p_cam_transform.basis;
+ Basis sky_transform = environment_get_sky_orientation(p_render_data->environment);
+ sky_transform = sky_transform.inverse() * p_render_data->cam_transform.basis;
RendererStorageRD::store_transform_3x3(sky_transform, scene_state.ubo.radiance_inverse_xform);
scene_state.ubo.use_ambient_cubemap = (ambient_src == RS::ENV_AMBIENT_SOURCE_BG && env_bg == RS::ENV_BG_SKY) || ambient_src == RS::ENV_AMBIENT_SOURCE_SKY;
@@ -718,43 +718,43 @@ void RenderForwardClustered::_setup_environment(RID p_environment, RID p_render_
}
//specular
- RS::EnvironmentReflectionSource ref_src = environment_get_reflection_source(p_environment);
+ RS::EnvironmentReflectionSource ref_src = environment_get_reflection_source(p_render_data->environment);
if ((ref_src == RS::ENV_REFLECTION_SOURCE_BG && env_bg == RS::ENV_BG_SKY) || ref_src == RS::ENV_REFLECTION_SOURCE_SKY) {
scene_state.ubo.use_reflection_cubemap = true;
} else {
scene_state.ubo.use_reflection_cubemap = false;
}
- scene_state.ubo.ssao_enabled = p_opaque_render_buffers && environment_is_ssao_enabled(p_environment);
- scene_state.ubo.ssao_ao_affect = environment_get_ssao_ao_affect(p_environment);
- scene_state.ubo.ssao_light_affect = environment_get_ssao_light_affect(p_environment);
+ scene_state.ubo.ssao_enabled = p_opaque_render_buffers && environment_is_ssao_enabled(p_render_data->environment);
+ scene_state.ubo.ssao_ao_affect = environment_get_ssao_ao_affect(p_render_data->environment);
+ scene_state.ubo.ssao_light_affect = environment_get_ssao_light_affect(p_render_data->environment);
- Color ao_color = environment_get_ao_color(p_environment).to_linear();
+ Color ao_color = environment_get_ao_color(p_render_data->environment).to_linear();
scene_state.ubo.ao_color[0] = ao_color.r;
scene_state.ubo.ao_color[1] = ao_color.g;
scene_state.ubo.ao_color[2] = ao_color.b;
scene_state.ubo.ao_color[3] = ao_color.a;
- scene_state.ubo.fog_enabled = environment_is_fog_enabled(p_environment);
- scene_state.ubo.fog_density = environment_get_fog_density(p_environment);
- scene_state.ubo.fog_height = environment_get_fog_height(p_environment);
- scene_state.ubo.fog_height_density = environment_get_fog_height_density(p_environment);
+ scene_state.ubo.fog_enabled = environment_is_fog_enabled(p_render_data->environment);
+ scene_state.ubo.fog_density = environment_get_fog_density(p_render_data->environment);
+ scene_state.ubo.fog_height = environment_get_fog_height(p_render_data->environment);
+ scene_state.ubo.fog_height_density = environment_get_fog_height_density(p_render_data->environment);
if (scene_state.ubo.fog_height_density >= 0.0001) {
scene_state.ubo.fog_height_density = 1.0 / scene_state.ubo.fog_height_density;
}
- scene_state.ubo.fog_aerial_perspective = environment_get_fog_aerial_perspective(p_environment);
+ scene_state.ubo.fog_aerial_perspective = environment_get_fog_aerial_perspective(p_render_data->environment);
- Color fog_color = environment_get_fog_light_color(p_environment).to_linear();
- float fog_energy = environment_get_fog_light_energy(p_environment);
+ Color fog_color = environment_get_fog_light_color(p_render_data->environment).to_linear();
+ float fog_energy = environment_get_fog_light_energy(p_render_data->environment);
scene_state.ubo.fog_light_color[0] = fog_color.r * fog_energy;
scene_state.ubo.fog_light_color[1] = fog_color.g * fog_energy;
scene_state.ubo.fog_light_color[2] = fog_color.b * fog_energy;
- scene_state.ubo.fog_sun_scatter = environment_get_fog_sun_scatter(p_environment);
+ scene_state.ubo.fog_sun_scatter = environment_get_fog_sun_scatter(p_render_data->environment);
} else {
- if (p_reflection_probe.is_valid() && storage->reflection_probe_is_interior(reflection_probe_instance_get_probe(p_reflection_probe))) {
+ if (p_render_data->reflection_probe.is_valid() && storage->reflection_probe_is_interior(reflection_probe_instance_get_probe(p_render_data->reflection_probe))) {
scene_state.ubo.use_ambient_light = false;
} else {
scene_state.ubo.use_ambient_light = true;
@@ -867,7 +867,7 @@ void RenderForwardClustered::_fill_instance_data(RenderListType p_render_list, u
}
}
-void RenderForwardClustered::_fill_render_list(RenderListType p_render_list, const PagedArray<GeometryInstance *> &p_instances, PassMode p_pass_mode, const CameraMatrix &p_cam_projection, const Transform &p_cam_transform, bool p_using_sdfgi, bool p_using_opaque_gi, const Plane &p_lod_plane, float p_lod_distance_multiplier, float p_screen_lod_threshold, bool p_append) {
+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;
scene_state.used_screen_texture = false;
@@ -876,9 +876,9 @@ void RenderForwardClustered::_fill_render_list(RenderListType p_render_list, con
}
uint32_t lightmap_captures_used = 0;
- Plane near_plane(p_cam_transform.origin, -p_cam_transform.basis.get_axis(Vector3::AXIS_Z));
- near_plane.d += p_cam_projection.get_z_near();
- float z_max = p_cam_projection.get_z_far() - p_cam_projection.get_z_near();
+ Plane near_plane(p_render_data->cam_transform.origin, -p_render_data->cam_transform.basis.get_axis(Vector3::AXIS_Z));
+ near_plane.d += p_render_data->cam_projection.get_z_near();
+ float z_max = p_render_data->cam_projection.get_z_far() - p_render_data->cam_projection.get_z_near();
RenderList *rl = &render_list[p_render_list];
_update_dirty_geometry_instances();
@@ -892,8 +892,8 @@ void RenderForwardClustered::_fill_render_list(RenderListType p_render_list, con
//fill list
- for (int i = 0; i < (int)p_instances.size(); i++) {
- GeometryInstanceForwardClustered *inst = static_cast<GeometryInstanceForwardClustered *>(p_instances[i]);
+ for (int i = 0; i < (int)p_render_data->instances->size(); i++) {
+ GeometryInstanceForwardClustered *inst = static_cast<GeometryInstanceForwardClustered *>((*p_render_data->instances)[i]);
Vector3 support_min = inst->transformed_aabb.get_support(-near_plane.normal);
inst->depth = near_plane.distance_to(support_min);
@@ -987,13 +987,13 @@ void RenderForwardClustered::_fill_render_list(RenderListType p_render_list, con
// LOD
- if (p_screen_lod_threshold > 0.0 && storage->mesh_surface_has_lod(surf->surface)) {
+ if (p_render_data->screen_lod_threshold > 0.0 && storage->mesh_surface_has_lod(surf->surface)) {
//lod
- Vector3 lod_support_min = inst->transformed_aabb.get_support(-p_lod_plane.normal);
- Vector3 lod_support_max = inst->transformed_aabb.get_support(p_lod_plane.normal);
+ Vector3 lod_support_min = inst->transformed_aabb.get_support(-p_render_data->lod_camera_plane.normal);
+ Vector3 lod_support_max = inst->transformed_aabb.get_support(p_render_data->lod_camera_plane.normal);
- float distance_min = p_lod_plane.distance_to(lod_support_min);
- float distance_max = p_lod_plane.distance_to(lod_support_max);
+ float distance_min = p_render_data->lod_camera_plane.distance_to(lod_support_min);
+ float distance_max = p_render_data->lod_camera_plane.distance_to(lod_support_max);
float distance = 0.0;
@@ -1006,7 +1006,7 @@ 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_lod_distance_multiplier, p_screen_lod_threshold);
+ 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);
} else {
surf->sort.lod_index = 0;
}
@@ -1090,28 +1090,21 @@ void RenderForwardClustered::_setup_lightmaps(const PagedArray<RID> &p_lightmaps
}
}
-void RenderForwardClustered::_render_scene(RID p_render_buffer, const Transform &p_cam_transform, const CameraMatrix &p_cam_projection, bool p_cam_ortogonal, const PagedArray<GeometryInstance *> &p_instances, const PagedArray<RID> &p_gi_probes, const PagedArray<RID> &p_lightmaps, RID p_environment, RID p_cluster_buffer, uint32_t p_cluster_size, uint32_t p_max_cluster_elements, RID p_camera_effects, RID p_shadow_atlas, RID p_reflection_atlas, RID p_reflection_probe, int p_reflection_probe_pass, const Color &p_default_bg_color, float p_screen_lod_threshold) {
+void RenderForwardClustered::_render_scene(RenderDataRD *p_render_data, const Color &p_default_bg_color) {
RenderBufferDataForwardClustered *render_buffer = nullptr;
- if (p_render_buffer.is_valid()) {
- render_buffer = (RenderBufferDataForwardClustered *)render_buffers_get_data(p_render_buffer);
+ 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_environment);
+ RendererSceneEnvironmentRD *env = get_environment(p_render_data->environment);
//first of all, make a new render pass
//fill up ubo
RENDER_TIMESTAMP("Setup 3D Scene");
- float lod_distance_multiplier = p_cam_projection.get_lod_multiplier();
- Plane lod_camera_plane(p_cam_transform.get_origin(), -p_cam_transform.basis.get_axis(Vector3::AXIS_Z));
-
- if (get_debug_draw_mode() == RS::VIEWPORT_DEBUG_DRAW_DISABLE_LOD) {
- p_screen_lod_threshold = 0.0;
- }
-
//scene_state.ubo.subsurface_scatter_width = subsurface_scatter_size;
- Vector2 vp_he = p_cam_projection.get_viewport_half_extents();
+ Vector2 vp_he = p_render_data->cam_projection.get_viewport_half_extents();
scene_state.ubo.viewport_size[0] = vp_he.x;
scene_state.ubo.viewport_size[1] = vp_he.y;
scene_state.ubo.directional_light_count = 0;
@@ -1136,29 +1129,29 @@ void RenderForwardClustered::_render_scene(RID p_render_buffer, const Transform
opaque_framebuffer = render_buffer->color_fb;
- if (p_gi_probes.size() > 0) {
+ if (p_render_data->gi_probes->size() > 0) {
using_giprobe = true;
}
- if (!p_environment.is_valid() && using_giprobe) {
+ if (!p_render_data->environment.is_valid() && using_giprobe) {
depth_pass_mode = PASS_MODE_DEPTH_NORMAL_ROUGHNESS_GIPROBE;
- } else if (p_environment.is_valid() && (environment_is_ssr_enabled(p_environment) || environment_is_sdfgi_enabled(p_environment) || using_giprobe)) {
- if (environment_is_sdfgi_enabled(p_environment)) {
+ } 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)) {
+ 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
using_sdfgi = true;
} else {
depth_pass_mode = using_giprobe ? PASS_MODE_DEPTH_NORMAL_ROUGHNESS_GIPROBE : PASS_MODE_DEPTH_NORMAL_ROUGHNESS;
}
- if (environment_is_ssr_enabled(p_environment)) {
+ if (environment_is_ssr_enabled(p_render_data->environment)) {
render_buffer->ensure_specular();
using_separate_specular = true;
using_ssr = true;
opaque_specular_framebuffer = render_buffer->color_specular_fb;
}
- } else if (p_environment.is_valid() && (environment_is_ssao_enabled(p_environment) || get_debug_draw_mode() == RS::VIEWPORT_DEBUG_DRAW_NORMAL_BUFFER)) {
+ } else if (p_render_data->environment.is_valid() && (environment_is_ssao_enabled(p_render_data->environment) || get_debug_draw_mode() == RS::VIEWPORT_DEBUG_DRAW_NORMAL_BUFFER)) {
depth_pass_mode = PASS_MODE_DEPTH_NORMAL_ROUGHNESS;
}
@@ -1183,17 +1176,18 @@ void RenderForwardClustered::_render_scene(RID p_render_buffer, const Transform
}
alpha_framebuffer = opaque_framebuffer;
- } else if (p_reflection_probe.is_valid()) {
- uint32_t resolution = reflection_probe_instance_get_resolution(p_reflection_probe);
+ } else if (p_render_data->reflection_probe.is_valid()) {
+ uint32_t resolution = reflection_probe_instance_get_resolution(p_render_data->reflection_probe);
screen_size.x = resolution;
screen_size.y = resolution;
- opaque_framebuffer = reflection_probe_instance_get_framebuffer(p_reflection_probe, p_reflection_probe_pass);
- depth_framebuffer = reflection_probe_instance_get_depth_framebuffer(p_reflection_probe, p_reflection_probe_pass);
+ opaque_framebuffer = reflection_probe_instance_get_framebuffer(p_render_data->reflection_probe, p_render_data->reflection_probe_pass);
+ depth_framebuffer = reflection_probe_instance_get_depth_framebuffer(p_render_data->reflection_probe, p_render_data->reflection_probe_pass);
alpha_framebuffer = opaque_framebuffer;
- if (storage->reflection_probe_is_interior(reflection_probe_instance_get_probe(p_reflection_probe))) {
- p_environment = RID(); //no environment on interiors
+ if (storage->reflection_probe_is_interior(reflection_probe_instance_get_probe(p_render_data->reflection_probe))) {
+ p_render_data->environment = RID(); //no environment on interiors
+ env = nullptr;
}
reverse_cull = true; // for some reason our views are inverted
@@ -1203,13 +1197,13 @@ void RenderForwardClustered::_render_scene(RID p_render_buffer, const Transform
RD::get_singleton()->draw_command_begin_label("Render Setup");
- _setup_lightmaps(p_lightmaps, p_cam_transform);
- _setup_giprobes(p_gi_probes);
- _setup_environment(p_environment, p_render_buffer, p_cam_projection, p_cam_transform, p_reflection_probe, p_reflection_probe.is_valid(), screen_size, p_cluster_size, p_max_cluster_elements, p_shadow_atlas, !p_reflection_probe.is_valid(), p_default_bg_color, p_cam_projection.get_z_near(), p_cam_projection.get_z_far(), false);
+ _setup_lightmaps(*p_render_data->lightmaps, p_render_data->cam_transform);
+ _setup_giprobes(*p_render_data->gi_probes);
+ _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_instances, PASS_MODE_COLOR, p_cam_projection, p_cam_transform, using_sdfgi, using_sdfgi || using_giprobe, lod_camera_plane, lod_distance_multiplier, p_screen_lod_threshold);
+ _fill_render_list(RENDER_LIST_OPAQUE, p_render_data, PASS_MODE_COLOR, using_sdfgi, using_sdfgi || using_giprobe);
render_list[RENDER_LIST_OPAQUE].sort_by_key();
render_list[RENDER_LIST_ALPHA].sort_by_depth();
_fill_instance_data(RENDER_LIST_OPAQUE);
@@ -1234,26 +1228,26 @@ void RenderForwardClustered::_render_scene(RID p_render_buffer, const Transform
if (get_debug_draw_mode() == RS::VIEWPORT_DEBUG_DRAW_OVERDRAW) {
clear_color = Color(0, 0, 0, 1); //in overdraw mode, BG should always be black
- } else if (is_environment(p_environment)) {
- RS::EnvironmentBG bg_mode = environment_get_background(p_environment);
- float bg_energy = environment_get_bg_energy(p_environment);
+ } else if (is_environment(p_render_data->environment)) {
+ RS::EnvironmentBG bg_mode = environment_get_background(p_render_data->environment);
+ float bg_energy = environment_get_bg_energy(p_render_data->environment);
switch (bg_mode) {
case RS::ENV_BG_CLEAR_COLOR: {
clear_color = p_default_bg_color;
clear_color.r *= bg_energy;
clear_color.g *= bg_energy;
clear_color.b *= bg_energy;
- if (render_buffers_has_volumetric_fog(p_render_buffer) || environment_is_fog_enabled(p_environment)) {
+ if (render_buffers_has_volumetric_fog(p_render_data->render_buffers) || environment_is_fog_enabled(p_render_data->environment)) {
draw_sky_fog_only = true;
storage->material_set_param(sky.sky_scene_state.fog_material, "clear_color", Variant(clear_color.to_linear()));
}
} break;
case RS::ENV_BG_COLOR: {
- clear_color = environment_get_bg_color(p_environment);
+ clear_color = environment_get_bg_color(p_render_data->environment);
clear_color.r *= bg_energy;
clear_color.g *= bg_energy;
clear_color.b *= bg_energy;
- if (render_buffers_has_volumetric_fog(p_render_buffer) || environment_is_fog_enabled(p_environment)) {
+ if (render_buffers_has_volumetric_fog(p_render_data->render_buffers) || environment_is_fog_enabled(p_render_data->environment)) {
draw_sky_fog_only = true;
storage->material_set_param(sky.sky_scene_state.fog_material, "clear_color", Variant(clear_color.to_linear()));
}
@@ -1273,21 +1267,21 @@ void RenderForwardClustered::_render_scene(RID p_render_buffer, const Transform
}
}
// setup sky if used for ambient, reflections, or background
- if (draw_sky || draw_sky_fog_only || environment_get_reflection_source(p_environment) == RS::ENV_REFLECTION_SOURCE_SKY || environment_get_ambient_source(p_environment) == RS::ENV_AMBIENT_SOURCE_SKY) {
+ if (draw_sky || draw_sky_fog_only || environment_get_reflection_source(p_render_data->environment) == RS::ENV_REFLECTION_SOURCE_SKY || environment_get_ambient_source(p_render_data->environment) == RS::ENV_AMBIENT_SOURCE_SKY) {
RENDER_TIMESTAMP("Setup Sky");
RD::get_singleton()->draw_command_begin_label("Setup Sky");
- CameraMatrix projection = p_cam_projection;
- if (p_reflection_probe.is_valid()) {
+ CameraMatrix projection = p_render_data->cam_projection;
+ if (p_render_data->reflection_probe.is_valid()) {
CameraMatrix correction;
correction.set_depth_correction(true);
- projection = correction * p_cam_projection;
+ projection = correction * p_render_data->cam_projection;
}
- sky.setup(env, p_render_buffer, projection, p_cam_transform, screen_size, this);
+ sky.setup(env, p_render_data->render_buffers, projection, p_render_data->cam_transform, screen_size, this);
RID sky_rid = env->sky;
if (sky_rid.is_valid()) {
- sky.update(env, projection, p_cam_transform, time);
+ sky.update(env, projection, p_render_data->cam_transform, time);
radiance_texture = sky.sky_get_radiance_texture_rd(sky_rid);
} else {
// do not try to draw sky if invalid
@@ -1303,11 +1297,11 @@ void RenderForwardClustered::_render_scene(RID p_render_buffer, const Transform
bool debug_sdfgi_probes = get_debug_draw_mode() == RS::VIEWPORT_DEBUG_DRAW_SDFGI_PROBES;
bool depth_pre_pass = depth_framebuffer.is_valid();
- bool using_ssao = depth_pre_pass && p_render_buffer.is_valid() && p_environment.is_valid() && environment_is_ssao_enabled(p_environment);
+ bool using_ssao = depth_pre_pass && p_render_data->render_buffers.is_valid() && p_render_data->environment.is_valid() && environment_is_ssao_enabled(p_render_data->environment);
bool continue_depth = false;
if (depth_pre_pass) { //depth pre pass
- bool needs_pre_resolve = _needs_post_prepass_render(using_sdfgi || using_giprobe);
+ bool needs_pre_resolve = _needs_post_prepass_render(p_render_data, using_sdfgi || using_giprobe);
if (needs_pre_resolve) {
RENDER_TIMESTAMP("GI + Render Depth Pre-Pass (parallel)");
} else {
@@ -1318,21 +1312,21 @@ void RenderForwardClustered::_render_scene(RID p_render_buffer, const Transform
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(using_sdfgi || using_giprobe);
+ _post_prepass_render(p_render_data, using_sdfgi || using_giprobe);
}
RD::get_singleton()->draw_command_begin_label("Render Depth Pre-Pass");
- RID rp_uniform_set = _setup_render_pass_uniform_set(RENDER_LIST_OPAQUE, RID(), RID(), RID(), RID(), RID(), PagedArray<RID>(), PagedArray<RID>());
+ RID rp_uniform_set = _setup_render_pass_uniform_set(RENDER_LIST_OPAQUE, nullptr, RID());
bool finish_depth = using_ssao || using_sdfgi || using_giprobe;
- 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(), lod_camera_plane, lod_distance_multiplier, p_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, 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(using_sdfgi || using_giprobe);
+ _pre_resolve_render(p_render_data, using_sdfgi || using_giprobe);
}
if (render_buffer && render_buffer->msaa != RS::VIEWPORT_MSAA_DISABLED) {
@@ -1353,17 +1347,17 @@ void RenderForwardClustered::_render_scene(RID p_render_buffer, const Transform
continue_depth = !finish_depth;
}
- _pre_opaque_render(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_giprobe, render_buffer ? render_buffer->normal_roughness_buffer : RID(), render_buffer ? render_buffer->giprobe_buffer : RID());
RD::get_singleton()->draw_command_begin_label("Render Opaque Pass");
- scene_state.ubo.directional_light_count = _get_render_state_directional_light_count();
+ scene_state.ubo.directional_light_count = p_render_data->directional_light_count;
- _setup_environment(p_environment, p_render_buffer, p_cam_projection, p_cam_transform, p_reflection_probe, p_reflection_probe.is_valid(), screen_size, p_cluster_size, p_max_cluster_elements, p_shadow_atlas, !p_reflection_probe.is_valid(), p_default_bg_color, p_cam_projection.get_z_near(), p_cam_projection.get_z_far(), p_render_buffer.is_valid());
+ _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, p_render_data->render_buffers.is_valid());
RENDER_TIMESTAMP("Render Opaque Pass");
- RID rp_uniform_set = _setup_render_pass_uniform_set(RENDER_LIST_OPAQUE, p_render_buffer, radiance_texture, p_shadow_atlas, p_reflection_atlas, p_cluster_buffer, p_gi_probes, p_lightmaps, true);
+ RID rp_uniform_set = _setup_render_pass_uniform_set(RENDER_LIST_OPAQUE, p_render_data, radiance_texture, true);
bool can_continue_color = !scene_state.used_screen_texture && !using_ssr && !using_sss;
bool can_continue_depth = !scene_state.used_depth_texture && !using_ssr && !using_sss;
@@ -1384,7 +1378,7 @@ void RenderForwardClustered::_render_scene(RID p_render_buffer, const Transform
}
RID framebuffer = using_separate_specular ? opaque_specular_framebuffer : opaque_framebuffer;
- 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, using_separate_specular ? PASS_MODE_COLOR_SPECULAR : PASS_MODE_COLOR, render_buffer == nullptr, rp_uniform_set, get_debug_draw_mode() == RS::VIEWPORT_DEBUG_DRAW_WIREFRAME, Vector2(), lod_camera_plane, lod_distance_multiplier, p_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, using_separate_specular ? PASS_MODE_COLOR_SPECULAR : PASS_MODE_COLOR, 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, framebuffer, keep_color ? RD::INITIAL_ACTION_KEEP : RD::INITIAL_ACTION_CLEAR, will_continue_color ? RD::FINAL_ACTION_CONTINUE : RD::FINAL_ACTION_READ, depth_pre_pass ? (continue_depth ? RD::INITIAL_ACTION_CONTINUE : RD::INITIAL_ACTION_KEEP) : RD::INITIAL_ACTION_CLEAR, will_continue_depth ? RD::FINAL_ACTION_CONTINUE : RD::FINAL_ACTION_READ, c, 1.0, 0);
if (will_continue_color && using_separate_specular) {
// close the specular framebuffer, as it's no longer used
@@ -1402,11 +1396,11 @@ void RenderForwardClustered::_render_scene(RID p_render_buffer, const Transform
CameraMatrix dc;
dc.set_depth_correction(true);
- CameraMatrix cm = (dc * p_cam_projection) * CameraMatrix(p_cam_transform.affine_inverse());
+ 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_gi_probes.size(); i++) {
- gi.debug_giprobe(p_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);
+ 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_end_label();
RD::get_singleton()->draw_list_end();
@@ -1419,10 +1413,10 @@ void RenderForwardClustered::_render_scene(RID p_render_buffer, const Transform
CameraMatrix dc;
dc.set_depth_correction(true);
- CameraMatrix cm = (dc * p_cam_projection) * CameraMatrix(p_cam_transform.affine_inverse());
+ 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 SDFGI");
- _debug_sdfgi_probes(p_render_buffer, draw_list, opaque_framebuffer, cm);
+ _debug_sdfgi_probes(p_render_data->render_buffers, draw_list, opaque_framebuffer, cm);
RD::get_singleton()->draw_command_end_label();
RD::get_singleton()->draw_list_end();
}
@@ -1430,14 +1424,14 @@ void RenderForwardClustered::_render_scene(RID p_render_buffer, const Transform
if (draw_sky || draw_sky_fog_only) {
RENDER_TIMESTAMP("Render Sky");
- CameraMatrix projection = p_cam_projection;
- if (p_reflection_probe.is_valid()) {
+ CameraMatrix projection = p_render_data->cam_projection;
+ if (p_render_data->reflection_probe.is_valid()) {
CameraMatrix correction;
correction.set_depth_correction(true);
- projection = correction * p_cam_projection;
+ 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_cam_transform, time);
+ 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();
}
@@ -1456,14 +1450,14 @@ void RenderForwardClustered::_render_scene(RID p_render_buffer, const Transform
if (using_sss) {
RENDER_TIMESTAMP("Sub Surface Scattering");
RD::get_singleton()->draw_command_begin_label("Process Sub Surface Scattering");
- _process_sss(p_render_buffer, p_cam_projection);
+ _process_sss(p_render_data->render_buffers, p_render_data->cam_projection);
RD::get_singleton()->draw_command_end_label();
}
if (using_ssr) {
RENDER_TIMESTAMP("Screen Space Reflection");
RD::get_singleton()->draw_command_begin_label("Process Screen Space Reflections");
- _process_ssr(p_render_buffer, render_buffer->color_fb, render_buffer->normal_roughness_buffer, render_buffer->specular, render_buffer->specular, Color(0, 0, 0, 1), p_environment, p_cam_projection, render_buffer->msaa == RS::VIEWPORT_MSAA_DISABLED);
+ _process_ssr(p_render_data->render_buffers, render_buffer->color_fb, render_buffer->normal_roughness_buffer, render_buffer->specular, render_buffer->specular, Color(0, 0, 0, 1), p_render_data->environment, p_render_data->cam_projection, render_buffer->msaa == RS::VIEWPORT_MSAA_DISABLED);
RD::get_singleton()->draw_command_end_label();
} else {
//just mix specular back
@@ -1476,12 +1470,12 @@ void RenderForwardClustered::_render_scene(RID p_render_buffer, const Transform
RD::get_singleton()->draw_command_begin_label("Render Transparent Pass");
- rp_uniform_set = _setup_render_pass_uniform_set(RENDER_LIST_ALPHA, p_render_buffer, radiance_texture, p_shadow_atlas, p_reflection_atlas, p_cluster_buffer, p_gi_probes, p_lightmaps, true);
+ rp_uniform_set = _setup_render_pass_uniform_set(RENDER_LIST_ALPHA, p_render_data, radiance_texture, true);
- _setup_environment(p_environment, p_render_buffer, p_cam_projection, p_cam_transform, p_reflection_probe, p_reflection_probe.is_valid(), screen_size, p_cluster_size, p_max_cluster_elements, p_shadow_atlas, !p_reflection_probe.is_valid(), p_default_bg_color, p_cam_projection.get_z_near(), p_cam_projection.get_z_far(), false);
+ _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(), false, PASS_MODE_COLOR, render_buffer == nullptr, rp_uniform_set, get_debug_draw_mode() == RS::VIEWPORT_DEBUG_DRAW_WIREFRAME, Vector2(), lod_camera_plane, lod_distance_multiplier, p_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(), false, PASS_MODE_COLOR, 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, 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);
}
@@ -1509,18 +1503,31 @@ void RenderForwardClustered::_render_shadow_append(RID p_framebuffer, const Page
SceneState::ShadowPass shadow_pass;
+ RenderDataRD render_data;
+ render_data.cam_projection = p_projection;
+ render_data.cam_transform = p_transform;
+ render_data.z_far = p_zfar;
+ render_data.z_near = 0.0;
+ render_data.cluster_size = 1;
+ render_data.cluster_max_elements = 32;
+ render_data.instances = &p_instances;
+ render_data.lod_camera_plane = p_camera_plane;
+ render_data.lod_distance_multiplier = p_lod_distance_multiplier;
+
scene_state.ubo.dual_paraboloid_side = p_use_dp_flip ? -1 : 1;
- _setup_environment(RID(), RID(), p_projection, p_transform, RID(), true, Vector2(1, 1), 1, 32, RID(), !p_flip_y, Color(), 0, p_zfar, false, p_use_pancake, shadow_pass_index);
+ _setup_environment(&render_data, true, Vector2(1, 1), !p_flip_y, Color(), false, p_use_pancake, shadow_pass_index);
if (get_debug_draw_mode() == RS::VIEWPORT_DEBUG_DRAW_DISABLE_LOD) {
- p_screen_lod_threshold = 0.0;
+ render_data.screen_lod_threshold = 0.0;
+ } else {
+ render_data.screen_lod_threshold = p_screen_lod_threshold;
}
PassMode pass_mode = p_use_dp ? PASS_MODE_SHADOW_DP : PASS_MODE_SHADOW;
uint32_t render_list_from = render_list[RENDER_LIST_SECONDARY].elements.size();
- _fill_render_list(RENDER_LIST_SECONDARY, p_instances, pass_mode, p_projection, p_transform, false, false, p_camera_plane, p_lod_distance_multiplier, p_screen_lod_threshold, true);
+ _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);
@@ -1539,8 +1546,8 @@ void RenderForwardClustered::_render_shadow_append(RID p_framebuffer, const Page
shadow_pass.rp_uniform_set = RID(); //will be filled later when instance buffer is complete
shadow_pass.camera_plane = p_camera_plane;
- shadow_pass.screen_lod_threshold = p_screen_lod_threshold;
- shadow_pass.lod_distance_multiplier = p_lod_distance_multiplier;
+ shadow_pass.screen_lod_threshold = render_data.screen_lod_threshold;
+ shadow_pass.lod_distance_multiplier = render_data.lod_distance_multiplier;
shadow_pass.framebuffer = p_framebuffer;
shadow_pass.initial_depth_action = p_begin ? (p_clear_region ? RD::INITIAL_ACTION_CLEAR_REGION : RD::INITIAL_ACTION_CLEAR) : (p_clear_region ? RD::INITIAL_ACTION_CLEAR_REGION_CONTINUE : RD::INITIAL_ACTION_CONTINUE);
@@ -1558,7 +1565,7 @@ void RenderForwardClustered::_render_shadow_process() {
for (uint32_t i = 0; i < scene_state.shadow_passes.size(); i++) {
//render passes need to be configured after instance buffer is done, since they need the latest version
SceneState::ShadowPass &shadow_pass = scene_state.shadow_passes[i];
- shadow_pass.rp_uniform_set = _setup_render_pass_uniform_set(RENDER_LIST_SECONDARY, RID(), RID(), RID(), RID(), RID(), PagedArray<RID>(), PagedArray<RID>(), false, i);
+ shadow_pass.rp_uniform_set = _setup_render_pass_uniform_set(RENDER_LIST_SECONDARY, nullptr, RID(), false, i);
}
RD::get_singleton()->draw_command_end_label();
@@ -1583,18 +1590,27 @@ void RenderForwardClustered::_render_particle_collider_heightfield(RID p_fb, con
RD::get_singleton()->draw_command_begin_label("Render Collider Heightfield");
+ RenderDataRD render_data;
+ render_data.cam_projection = p_cam_projection;
+ render_data.cam_transform = p_cam_transform;
+ render_data.z_near = 0.0;
+ render_data.z_far = p_cam_projection.get_z_far();
+ render_data.cluster_size = 1;
+ render_data.cluster_max_elements = 32;
+ render_data.instances = &p_instances;
+
_update_render_base_uniform_set();
scene_state.ubo.dual_paraboloid_side = 0;
- _setup_environment(RID(), RID(), p_cam_projection, p_cam_transform, RID(), true, Vector2(1, 1), 1, 32, RID(), true, Color(), 0, p_cam_projection.get_z_far(), false, false);
+ _setup_environment(&render_data, true, Vector2(1, 1), true, Color(), false, false);
PassMode pass_mode = PASS_MODE_SHADOW;
- _fill_render_list(RENDER_LIST_SECONDARY, p_instances, pass_mode, p_cam_projection, p_cam_transform);
+ _fill_render_list(RENDER_LIST_SECONDARY, &render_data, pass_mode);
render_list[RENDER_LIST_SECONDARY].sort_by_key();
_fill_instance_data(RENDER_LIST_SECONDARY);
- RID rp_uniform_set = _setup_render_pass_uniform_set(RENDER_LIST_SECONDARY, RID(), RID(), RID(), RID(), RID(), PagedArray<RID>(), PagedArray<RID>());
+ RID rp_uniform_set = _setup_render_pass_uniform_set(RENDER_LIST_SECONDARY, nullptr, RID());
RENDER_TIMESTAMP("Render Collider Heightfield");
@@ -1611,19 +1627,26 @@ void RenderForwardClustered::_render_material(const Transform &p_cam_transform,
RD::get_singleton()->draw_command_begin_label("Render Material");
+ RenderDataRD render_data;
+ render_data.cam_projection = p_cam_projection;
+ render_data.cam_transform = p_cam_transform;
+ render_data.cluster_size = 1;
+ render_data.cluster_max_elements = 32;
+ render_data.instances = &p_instances;
+
_update_render_base_uniform_set();
scene_state.ubo.dual_paraboloid_side = 0;
scene_state.ubo.material_uv2_mode = false;
- _setup_environment(RID(), RID(), p_cam_projection, p_cam_transform, RID(), true, Vector2(1, 1), 1, 32, RID(), false, Color(), 0, 0);
+ _setup_environment(&render_data, true, Vector2(1, 1), false, Color());
PassMode pass_mode = PASS_MODE_DEPTH_MATERIAL;
- _fill_render_list(RENDER_LIST_SECONDARY, p_instances, pass_mode, p_cam_projection, p_cam_transform);
+ _fill_render_list(RENDER_LIST_SECONDARY, &render_data, pass_mode);
render_list[RENDER_LIST_SECONDARY].sort_by_key();
_fill_instance_data(RENDER_LIST_SECONDARY);
- RID rp_uniform_set = _setup_render_pass_uniform_set(RENDER_LIST_SECONDARY, RID(), RID(), RID(), RID(), RID(), PagedArray<RID>(), PagedArray<RID>());
+ RID rp_uniform_set = _setup_render_pass_uniform_set(RENDER_LIST_SECONDARY, nullptr, RID());
RENDER_TIMESTAMP("Render Material");
@@ -1649,19 +1672,24 @@ void RenderForwardClustered::_render_uv2(const PagedArray<GeometryInstance *> &p
RD::get_singleton()->draw_command_begin_label("Render UV2");
+ RenderDataRD render_data;
+ render_data.cluster_size = 1;
+ render_data.cluster_max_elements = 32;
+ render_data.instances = &p_instances;
+
_update_render_base_uniform_set();
scene_state.ubo.dual_paraboloid_side = 0;
scene_state.ubo.material_uv2_mode = true;
- _setup_environment(RID(), RID(), CameraMatrix(), Transform(), RID(), true, Vector2(1, 1), 1, 32, RID(), false, Color(), 0, 0);
+ _setup_environment(&render_data, true, Vector2(1, 1), false, Color());
PassMode pass_mode = PASS_MODE_DEPTH_MATERIAL;
- _fill_render_list(RENDER_LIST_SECONDARY, p_instances, pass_mode, CameraMatrix(), Transform());
+ _fill_render_list(RENDER_LIST_SECONDARY, &render_data, pass_mode);
render_list[RENDER_LIST_SECONDARY].sort_by_key();
_fill_instance_data(RENDER_LIST_SECONDARY);
- RID rp_uniform_set = _setup_render_pass_uniform_set(RENDER_LIST_SECONDARY, RID(), RID(), RID(), RID(), RID(), PagedArray<RID>(), PagedArray<RID>());
+ RID rp_uniform_set = _setup_render_pass_uniform_set(RENDER_LIST_SECONDARY, nullptr, RID());
RENDER_TIMESTAMP("Render Material");
@@ -1712,13 +1740,18 @@ void RenderForwardClustered::_render_sdfgi(RID p_render_buffers, const Vector3i
RD::get_singleton()->draw_command_begin_label("Render SDFGI Voxel");
+ RenderDataRD render_data;
+ render_data.cluster_size = 1;
+ render_data.cluster_max_elements = 32;
+ render_data.instances = &p_instances;
+
_update_render_base_uniform_set();
RenderBufferDataForwardClustered *render_buffer = (RenderBufferDataForwardClustered *)render_buffers_get_data(p_render_buffers);
ERR_FAIL_COND(!render_buffer);
PassMode pass_mode = PASS_MODE_SDF;
- _fill_render_list(RENDER_LIST_SECONDARY, p_instances, pass_mode, CameraMatrix(), Transform());
+ _fill_render_list(RENDER_LIST_SECONDARY, &render_data, pass_mode);
render_list[RENDER_LIST_SECONDARY].sort_by_key();
_fill_instance_data(RENDER_LIST_SECONDARY);
@@ -1750,28 +1783,26 @@ void RenderForwardClustered::_render_sdfgi(RID p_render_buffers, const Vector3i
fb_size.x = p_size[right_axis];
fb_size.y = p_size[up_axis];
- Transform cam_xform;
- cam_xform.origin = center + axis * half_extents;
- cam_xform.basis.set_axis(0, right);
- cam_xform.basis.set_axis(1, up);
- cam_xform.basis.set_axis(2, axis);
+ render_data.cam_transform.origin = center + axis * half_extents;
+ render_data.cam_transform.basis.set_axis(0, right);
+ render_data.cam_transform.basis.set_axis(1, up);
+ render_data.cam_transform.basis.set_axis(2, axis);
- //print_line("pass: " + itos(i) + " xform " + cam_xform);
+ //print_line("pass: " + itos(i) + " xform " + render_data.cam_transform);
float h_size = half_extents[right_axis];
float v_size = half_extents[up_axis];
float d_size = half_extents[i] * 2.0;
- CameraMatrix camera_proj;
- camera_proj.set_orthogonal(-h_size, h_size, -v_size, v_size, 0, d_size);
+ 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;
to_bounds.origin = p_bounds.position;
to_bounds.basis.scale(p_bounds.size);
- RendererStorageRD::store_transform(to_bounds.affine_inverse() * cam_xform, scene_state.ubo.sdf_to_bounds);
+ RendererStorageRD::store_transform(to_bounds.affine_inverse() * render_data.cam_transform, scene_state.ubo.sdf_to_bounds);
- _setup_environment(RID(), RID(), camera_proj, cam_xform, RID(), true, Vector2(1, 1), 1, 32, RID(), false, Color(), 0, 0);
+ _setup_environment(&render_data, true, Vector2(1, 1), false, Color());
RID rp_uniform_set = _setup_sdfgi_render_pass_uniform_set(p_albedo_texture, p_emission_texture, p_emission_aniso_texture, p_geom_facing_texture);
@@ -1921,13 +1952,13 @@ void RenderForwardClustered::_update_render_base_uniform_set() {
}
}
-RID RenderForwardClustered::_setup_render_pass_uniform_set(RenderListType p_render_list, RID p_render_buffers, RID p_radiance_texture, RID p_shadow_atlas, RID p_reflection_atlas, RID p_cluster_buffer, const PagedArray<RID> &p_gi_probes, const PagedArray<RID> &p_lightmaps, bool p_use_directional_shadow_atlas, int p_index) {
+RID RenderForwardClustered::_setup_render_pass_uniform_set(RenderListType p_render_list, const RenderDataRD *p_render_data, RID p_radiance_texture, bool p_use_directional_shadow_atlas, int p_index) {
//there should always be enough uniform buffers for render passes, otherwise bugs
ERR_FAIL_INDEX_V(p_index, (int)scene_state.uniform_buffers.size(), RID());
RenderBufferDataForwardClustered *rb = nullptr;
- if (p_render_buffers.is_valid()) {
- rb = (RenderBufferDataForwardClustered *)render_buffers_get_data(p_render_buffers);
+ if (p_render_data && p_render_data->render_buffers.is_valid()) {
+ rb = (RenderBufferDataForwardClustered *)render_buffers_get_data(p_render_data->render_buffers);
}
//default render buffer and scene state uniform set
@@ -1967,7 +1998,7 @@ RID RenderForwardClustered::_setup_render_pass_uniform_set(RenderListType p_rend
}
{
- RID ref_texture = p_reflection_atlas.is_valid() ? reflection_atlas_get_texture(p_reflection_atlas) : RID();
+ RID ref_texture = (p_render_data && p_render_data->reflection_atlas.is_valid()) ? reflection_atlas_get_texture(p_render_data->reflection_atlas) : RID();
RD::Uniform u;
u.binding = 3;
u.uniform_type = RD::UNIFORM_TYPE_TEXTURE;
@@ -1984,8 +2015,8 @@ RID RenderForwardClustered::_setup_render_pass_uniform_set(RenderListType p_rend
u.binding = 4;
u.uniform_type = RD::UNIFORM_TYPE_TEXTURE;
RID texture;
- if (p_shadow_atlas.is_valid()) {
- texture = shadow_atlas_get_texture(p_shadow_atlas);
+ if (p_render_data && p_render_data->shadow_atlas.is_valid()) {
+ texture = shadow_atlas_get_texture(p_render_data->shadow_atlas);
}
if (!texture.is_valid()) {
texture = storage->texture_rd_get_default(RendererStorageRD::DEFAULT_RD_TEXTURE_WHITE);
@@ -2011,8 +2042,8 @@ RID RenderForwardClustered::_setup_render_pass_uniform_set(RenderListType p_rend
u.ids.resize(scene_state.max_lightmaps);
RID default_tex = storage->texture_rd_get_default(RendererStorageRD::DEFAULT_RD_TEXTURE_2D_ARRAY_WHITE);
for (uint32_t i = 0; i < scene_state.max_lightmaps; i++) {
- if (i < p_lightmaps.size()) {
- RID base = lightmap_instance_get_lightmap(p_lightmaps[i]);
+ if (p_render_data && i < p_render_data->lightmaps->size()) {
+ RID base = lightmap_instance_get_lightmap((*p_render_data->lightmaps)[i]);
RID texture = storage->lightmap_get_texture(base);
RID rd_texture = storage->texture_get_rd_texture(texture);
u.ids.write[i] = rd_texture;
@@ -2030,8 +2061,8 @@ RID RenderForwardClustered::_setup_render_pass_uniform_set(RenderListType p_rend
u.ids.resize(MAX_GI_PROBES);
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]);
+ 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]);
if (!tex.is_valid()) {
tex = default_tex;
}
@@ -2048,7 +2079,7 @@ RID RenderForwardClustered::_setup_render_pass_uniform_set(RenderListType p_rend
RD::Uniform u;
u.binding = 8;
u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER;
- RID cb = p_cluster_buffer.is_valid() ? p_cluster_buffer : scene_shader.default_vec4_xform_buffer;
+ RID cb = (p_render_data && p_render_data->cluster_buffer.is_valid()) ? p_render_data->cluster_buffer : scene_shader.default_vec4_xform_buffer;
u.ids.push_back(cb);
uniforms.push_back(u);
}
@@ -2065,7 +2096,7 @@ RID RenderForwardClustered::_setup_render_pass_uniform_set(RenderListType p_rend
RD::Uniform u;
u.binding = 10;
u.uniform_type = RD::UNIFORM_TYPE_TEXTURE;
- RID bbt = rb ? render_buffers_get_back_buffer_texture(p_render_buffers) : RID();
+ RID bbt = rb ? render_buffers_get_back_buffer_texture(p_render_data->render_buffers) : RID();
RID texture = bbt.is_valid() ? bbt : storage->texture_rd_get_default(RendererStorageRD::DEFAULT_RD_TEXTURE_BLACK);
u.ids.push_back(texture);
uniforms.push_back(u);
@@ -2085,7 +2116,7 @@ RID RenderForwardClustered::_setup_render_pass_uniform_set(RenderListType p_rend
RD::Uniform u;
u.binding = 12;
u.uniform_type = RD::UNIFORM_TYPE_TEXTURE;
- RID aot = rb ? render_buffers_get_ao_texture(p_render_buffers) : RID();
+ RID aot = rb ? render_buffers_get_ao_texture(p_render_data->render_buffers) : RID();
RID texture = aot.is_valid() ? aot : storage->texture_rd_get_default(RendererStorageRD::DEFAULT_RD_TEXTURE_BLACK);
u.ids.push_back(texture);
uniforms.push_back(u);
@@ -2095,7 +2126,7 @@ RID RenderForwardClustered::_setup_render_pass_uniform_set(RenderListType p_rend
RD::Uniform u;
u.binding = 13;
u.uniform_type = RD::UNIFORM_TYPE_TEXTURE;
- RID ambient_buffer = p_render_buffers.is_valid() ? render_buffers_get_gi_ambient_texture(p_render_buffers) : RID();
+ RID ambient_buffer = rb ? render_buffers_get_gi_ambient_texture(p_render_data->render_buffers) : RID();
RID texture = ambient_buffer.is_valid() ? ambient_buffer : storage->texture_rd_get_default(RendererStorageRD::DEFAULT_RD_TEXTURE_BLACK);
u.ids.push_back(texture);
uniforms.push_back(u);
@@ -2105,7 +2136,7 @@ RID RenderForwardClustered::_setup_render_pass_uniform_set(RenderListType p_rend
RD::Uniform u;
u.binding = 14;
u.uniform_type = RD::UNIFORM_TYPE_TEXTURE;
- RID reflection_buffer = p_render_buffers.is_valid() ? render_buffers_get_gi_reflection_texture(p_render_buffers) : RID();
+ RID reflection_buffer = rb ? render_buffers_get_gi_reflection_texture(p_render_data->render_buffers) : RID();
RID texture = reflection_buffer.is_valid() ? reflection_buffer : storage->texture_rd_get_default(RendererStorageRD::DEFAULT_RD_TEXTURE_BLACK);
u.ids.push_back(texture);
uniforms.push_back(u);
@@ -2115,8 +2146,8 @@ RID RenderForwardClustered::_setup_render_pass_uniform_set(RenderListType p_rend
u.binding = 15;
u.uniform_type = RD::UNIFORM_TYPE_TEXTURE;
RID t;
- if (rb && render_buffers_is_sdfgi_enabled(p_render_buffers)) {
- t = render_buffers_get_sdfgi_irradiance_probes(p_render_buffers);
+ if (rb && render_buffers_is_sdfgi_enabled(p_render_data->render_buffers)) {
+ t = render_buffers_get_sdfgi_irradiance_probes(p_render_data->render_buffers);
} else {
t = storage->texture_rd_get_default(RendererStorageRD::DEFAULT_RD_TEXTURE_2D_ARRAY_WHITE);
}
@@ -2127,8 +2158,8 @@ RID RenderForwardClustered::_setup_render_pass_uniform_set(RenderListType p_rend
RD::Uniform u;
u.binding = 16;
u.uniform_type = RD::UNIFORM_TYPE_TEXTURE;
- if (rb && render_buffers_is_sdfgi_enabled(p_render_buffers)) {
- u.ids.push_back(render_buffers_get_sdfgi_occlusion_texture(p_render_buffers));
+ if (rb && render_buffers_is_sdfgi_enabled(p_render_data->render_buffers)) {
+ u.ids.push_back(render_buffers_get_sdfgi_occlusion_texture(p_render_data->render_buffers));
} else {
u.ids.push_back(storage->texture_rd_get_default(RendererStorageRD::DEFAULT_RD_TEXTURE_3D_WHITE));
}
@@ -2138,7 +2169,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_buffers) : render_buffers_get_default_gi_probe_buffer());
+ u.ids.push_back(rb ? render_buffers_get_gi_probe_buffer(p_render_data->render_buffers) : render_buffers_get_default_gi_probe_buffer());
uniforms.push_back(u);
}
{
@@ -2146,8 +2177,8 @@ RID RenderForwardClustered::_setup_render_pass_uniform_set(RenderListType p_rend
u.binding = 18;
u.uniform_type = RD::UNIFORM_TYPE_TEXTURE;
RID vfog = RID();
- if (rb && render_buffers_has_volumetric_fog(p_render_buffers)) {
- vfog = render_buffers_get_volumetric_fog_texture(p_render_buffers);
+ if (rb && render_buffers_has_volumetric_fog(p_render_data->render_buffers)) {
+ vfog = render_buffers_get_volumetric_fog_texture(p_render_data->render_buffers);
if (vfog.is_null()) {
vfog = storage->texture_rd_get_default(RendererStorageRD::DEFAULT_RD_TEXTURE_3D_WHITE);
}
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 4b998a9e76..bed3c3b219 100644
--- a/servers/rendering/renderer_rd/forward_clustered/render_forward_clustered.h
+++ b/servers/rendering/renderer_rd/forward_clustered/render_forward_clustered.h
@@ -122,7 +122,7 @@ class RenderForwardClustered : public RendererSceneRenderRD {
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);
- RID _setup_render_pass_uniform_set(RenderListType p_render_list, RID p_render_buffers, RID p_radiance_texture, RID p_shadow_atlas, RID p_reflection_atlas, RID p_cluster_buffer, const PagedArray<RID> &p_gi_probes, const PagedArray<RID> &p_lightmaps, bool p_use_directional_shadow_atlas = false, int p_index = 0);
+ 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);
enum PassMode {
PASS_MODE_COLOR,
@@ -349,7 +349,7 @@ class RenderForwardClustered : public RendererSceneRenderRD {
static RenderForwardClustered *singleton;
- void _setup_environment(RID p_environment, RID p_render_buffers, const CameraMatrix &p_cam_projection, const Transform &p_cam_transform, RID p_reflection_probe, bool p_no_fog, const Size2i &p_screen_size, uint32_t p_cluster_size, uint32_t p_max_cluster_elements, RID p_shadow_atlas, bool p_flip_y, const Color &p_default_bg_color, float p_znear, float p_zfar, bool p_opaque_render_buffers = false, bool p_pancake_shadows = false, int p_index = 0);
+ 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);
@@ -373,7 +373,7 @@ class RenderForwardClustered : public RendererSceneRenderRD {
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_render_list(RenderListType p_render_list, const PagedArray<GeometryInstance *> &p_instances, PassMode p_pass_mode, const CameraMatrix &p_cam_projection, const Transform &p_cam_transform, bool p_using_sdfgi = false, bool p_using_opaque_gi = false, const Plane &p_lod_camera_plane = Plane(), float p_lod_distance_multiplier = 0.0, float p_screen_lod_threshold = 0.0, bool p_append = false);
+ 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;
@@ -566,7 +566,7 @@ class RenderForwardClustered : public RendererSceneRenderRD {
RenderList render_list[RENDER_LIST_MAX];
protected:
- virtual void _render_scene(RID p_render_buffer, const Transform &p_cam_transform, const CameraMatrix &p_cam_projection, bool p_cam_ortogonal, const PagedArray<GeometryInstance *> &p_instances, const PagedArray<RID> &p_gi_probes, const PagedArray<RID> &p_lightmaps, RID p_environment, RID p_cluster_buffer, uint32_t p_cluster_size, uint32_t p_max_cluster_elements, RID p_camera_effects, RID p_shadow_atlas, RID p_reflection_atlas, RID p_reflection_probe, int p_reflection_probe_pass, const Color &p_default_bg_color, float p_lod_threshold);
+ virtual void _render_scene(RenderDataRD *p_render_data, const Color &p_default_bg_color);
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);
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 041476adf3..4e93fa5333 100644
--- a/servers/rendering/renderer_rd/forward_mobile/render_forward_mobile.cpp
+++ b/servers/rendering/renderer_rd/forward_mobile/render_forward_mobile.cpp
@@ -125,13 +125,13 @@ bool RenderForwardMobile::free(RID p_rid) {
/* Render functions */
-RID RenderForwardMobile::_setup_render_pass_uniform_set(RenderListType p_render_list, RID p_render_buffers, RID p_radiance_texture, RID p_shadow_atlas, RID p_reflection_atlas, const PagedArray<RID> &p_lightmaps, bool p_use_directional_shadow_atlas, int p_index) {
+RID RenderForwardMobile::_setup_render_pass_uniform_set(RenderListType p_render_list, const RenderDataRD *p_render_data, RID p_radiance_texture, bool p_use_directional_shadow_atlas, int p_index) {
//there should always be enough uniform buffers for render passes, otherwise bugs
ERR_FAIL_INDEX_V(p_index, (int)scene_state.uniform_buffers.size(), RID());
RenderBufferDataForwardMobile *rb = nullptr;
- if (p_render_buffers.is_valid()) {
- rb = (RenderBufferDataForwardMobile *)render_buffers_get_data(p_render_buffers);
+ if (p_render_data && p_render_data->render_buffers.is_valid()) {
+ rb = (RenderBufferDataForwardMobile *)render_buffers_get_data(p_render_data->render_buffers);
}
// default render buffer and scene state uniform set
@@ -162,7 +162,7 @@ RID RenderForwardMobile::_setup_render_pass_uniform_set(RenderListType p_render_
}
{
- RID ref_texture = p_reflection_atlas.is_valid() ? reflection_atlas_get_texture(p_reflection_atlas) : RID();
+ RID ref_texture = (p_render_data && p_render_data->reflection_atlas.is_valid()) ? reflection_atlas_get_texture(p_render_data->reflection_atlas) : RID();
RD::Uniform u;
u.binding = 3;
u.uniform_type = RD::UNIFORM_TYPE_TEXTURE;
@@ -179,8 +179,8 @@ RID RenderForwardMobile::_setup_render_pass_uniform_set(RenderListType p_render_
u.binding = 4;
u.uniform_type = RD::UNIFORM_TYPE_TEXTURE;
RID texture;
- if (p_shadow_atlas.is_valid()) {
- texture = shadow_atlas_get_texture(p_shadow_atlas);
+ if (p_render_data && p_render_data->shadow_atlas.is_valid()) {
+ texture = shadow_atlas_get_texture(p_render_data->shadow_atlas);
}
if (!texture.is_valid()) {
texture = storage->texture_rd_get_default(RendererStorageRD::DEFAULT_RD_TEXTURE_WHITE);
@@ -208,8 +208,8 @@ RID RenderForwardMobile::_setup_render_pass_uniform_set(RenderListType p_render_
u.ids.resize(scene_state.max_lightmaps);
RID default_tex = storage->texture_rd_get_default(RendererStorageRD::DEFAULT_RD_TEXTURE_2D_ARRAY_WHITE);
for (uint32_t i = 0; i < scene_state.max_lightmaps; i++) {
- if (i < p_lightmaps.size()) {
- RID base = lightmap_instance_get_lightmap(p_lightmaps[i]);
+ if (p_render_data && i < p_render_data->lightmaps->size()) {
+ RID base = lightmap_instance_get_lightmap((*p_render_data->lightmaps)[i]);
RID texture = storage->lightmap_get_texture(base);
RID rd_texture = storage->texture_get_rd_texture(texture);
u.ids.write[i] = rd_texture;
@@ -265,7 +265,7 @@ RID RenderForwardMobile::_setup_render_pass_uniform_set(RenderListType p_render_
RD::Uniform u;
u.binding = 10;
u.uniform_type = RD::UNIFORM_TYPE_TEXTURE;
- RID bbt = rb ? render_buffers_get_back_buffer_texture(p_render_buffers) : RID();
+ RID bbt = rb ? render_buffers_get_back_buffer_texture(p_render_data->render_buffers) : RID();
RID texture = bbt.is_valid() ? bbt : storage->texture_rd_get_default(RendererStorageRD::DEFAULT_RD_TEXTURE_BLACK);
u.ids.push_back(texture);
uniforms.push_back(u);
@@ -306,29 +306,16 @@ void RenderForwardMobile::_setup_lightmaps(const PagedArray<RID> &p_lightmaps, c
}
}
-void RenderForwardMobile::_render_scene(RID p_render_buffer, const Transform &p_cam_transform, const CameraMatrix &p_cam_projection, bool p_cam_ortogonal, const PagedArray<GeometryInstance *> &p_instances, const PagedArray<RID> &p_gi_probes, const PagedArray<RID> &p_lightmaps, RID p_environment, RID p_cluster_buffer, uint32_t p_cluster_size, uint32_t p_cluster_max_elements, RID p_camera_effects, RID p_shadow_atlas, RID p_reflection_atlas, RID p_reflection_probe, int p_reflection_probe_pass, const Color &p_default_bg_color, float p_screen_lod_threshold) {
- // These are UNUSED here and will not have data parsed from RendererSceneRenderRD:
- // - p_gi_probes
- // - p_cluster_buffer
- // - p_cluster_size
- // - p_cluster_max_elements
-
+void RenderForwardMobile::_render_scene(RenderDataRD *p_render_data, const Color &p_default_bg_color) {
RenderBufferDataForwardMobile *render_buffer = nullptr;
- if (p_render_buffer.is_valid()) {
- render_buffer = (RenderBufferDataForwardMobile *)render_buffers_get_data(p_render_buffer);
+ if (p_render_data->render_buffers.is_valid()) {
+ render_buffer = (RenderBufferDataForwardMobile *)render_buffers_get_data(p_render_data->render_buffers);
}
- RendererSceneEnvironmentRD *env = get_environment(p_environment);
+ RendererSceneEnvironmentRD *env = get_environment(p_render_data->environment);
RENDER_TIMESTAMP("Setup 3D Scene");
- float lod_distance_multiplier = p_cam_projection.get_lod_multiplier();
- Plane lod_camera_plane(p_cam_transform.get_origin(), -p_cam_transform.basis.get_axis(Vector3::AXIS_Z));
-
- if (get_debug_draw_mode() == RS::VIEWPORT_DEBUG_DRAW_DISABLE_LOD) {
- p_screen_lod_threshold = 0.0;
- }
-
- Vector2 vp_he = p_cam_projection.get_viewport_half_extents();
+ Vector2 vp_he = p_render_data->cam_projection.get_viewport_half_extents();
scene_state.ubo.viewport_size[0] = vp_he.x;
scene_state.ubo.viewport_size[1] = vp_he.y;
scene_state.ubo.directional_light_count = 0;
@@ -349,16 +336,17 @@ void RenderForwardMobile::_render_scene(RID p_render_buffer, const Transform &p_
opaque_framebuffer = render_buffer->color_fb;
alpha_framebuffer = opaque_framebuffer;
- } else if (p_reflection_probe.is_valid()) {
- uint32_t resolution = reflection_probe_instance_get_resolution(p_reflection_probe);
+ } else if (p_render_data->reflection_probe.is_valid()) {
+ uint32_t resolution = reflection_probe_instance_get_resolution(p_render_data->reflection_probe);
screen_size.x = resolution;
screen_size.y = resolution;
- opaque_framebuffer = reflection_probe_instance_get_framebuffer(p_reflection_probe, p_reflection_probe_pass);
+ opaque_framebuffer = reflection_probe_instance_get_framebuffer(p_render_data->reflection_probe, p_render_data->reflection_probe_pass);
alpha_framebuffer = opaque_framebuffer;
- if (storage->reflection_probe_is_interior(reflection_probe_instance_get_probe(p_reflection_probe))) {
- p_environment = RID(); //no environment on interiors
+ if (storage->reflection_probe_is_interior(reflection_probe_instance_get_probe(p_render_data->reflection_probe))) {
+ p_render_data->environment = RID(); //no environment on interiors
+ env = nullptr;
}
reverse_cull = true;
@@ -368,12 +356,12 @@ void RenderForwardMobile::_render_scene(RID p_render_buffer, const Transform &p_
RD::get_singleton()->draw_command_begin_label("Render Setup");
- _setup_lightmaps(p_lightmaps, p_cam_transform);
- _setup_environment(p_environment, p_render_buffer, p_cam_projection, p_cam_transform, p_reflection_probe, p_reflection_probe.is_valid(), screen_size, p_shadow_atlas, !p_reflection_probe.is_valid(), p_default_bg_color, p_cam_projection.get_z_near(), p_cam_projection.get_z_far(), false);
+ _setup_lightmaps(*p_render_data->lightmaps, p_render_data->cam_transform);
+ _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_instances, PASS_MODE_COLOR, p_cam_projection, p_cam_transform, lod_camera_plane, lod_distance_multiplier, p_screen_lod_threshold);
+ _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();
@@ -395,9 +383,9 @@ void RenderForwardMobile::_render_scene(RID p_render_buffer, const Transform &p_
if (get_debug_draw_mode() == RS::VIEWPORT_DEBUG_DRAW_OVERDRAW) {
clear_color = Color(0, 0, 0, 1); //in overdraw mode, BG should always be black
- } else if (is_environment(p_environment)) {
- RS::EnvironmentBG bg_mode = environment_get_background(p_environment);
- float bg_energy = environment_get_bg_energy(p_environment);
+ } else if (is_environment(p_render_data->environment)) {
+ RS::EnvironmentBG bg_mode = environment_get_background(p_render_data->environment);
+ float bg_energy = environment_get_bg_energy(p_render_data->environment);
switch (bg_mode) {
case RS::ENV_BG_CLEAR_COLOR: {
clear_color = p_default_bg_color;
@@ -405,19 +393,19 @@ void RenderForwardMobile::_render_scene(RID p_render_buffer, const Transform &p_
clear_color.g *= bg_energy;
clear_color.b *= bg_energy;
/*
- if (render_buffers_has_volumetric_fog(p_render_buffer) || environment_is_fog_enabled(p_environment)) {
+ if (render_buffers_has_volumetric_fog(p_render_data->render_buffers) || environment_is_fog_enabled(p_render_data->environment)) {
draw_sky_fog_only = true;
storage->material_set_param(sky.sky_scene_state.fog_material, "clear_color", Variant(clear_color.to_linear()));
}
*/
} break;
case RS::ENV_BG_COLOR: {
- clear_color = environment_get_bg_color(p_environment);
+ clear_color = environment_get_bg_color(p_render_data->environment);
clear_color.r *= bg_energy;
clear_color.g *= bg_energy;
clear_color.b *= bg_energy;
/*
- if (render_buffers_has_volumetric_fog(p_render_buffer) || environment_is_fog_enabled(p_environment)) {
+ if (render_buffers_has_volumetric_fog(p_render_data->render_buffers) || environment_is_fog_enabled(p_render_data->environment)) {
draw_sky_fog_only = true;
storage->material_set_param(sky.sky_scene_state.fog_material, "clear_color", Variant(clear_color.to_linear()));
}
@@ -438,21 +426,21 @@ void RenderForwardMobile::_render_scene(RID p_render_buffer, const Transform &p_
}
}
// setup sky if used for ambient, reflections, or background
- if (draw_sky || draw_sky_fog_only || environment_get_reflection_source(p_environment) == RS::ENV_REFLECTION_SOURCE_SKY || environment_get_ambient_source(p_environment) == RS::ENV_AMBIENT_SOURCE_SKY) {
+ if (draw_sky || draw_sky_fog_only || environment_get_reflection_source(p_render_data->environment) == RS::ENV_REFLECTION_SOURCE_SKY || environment_get_ambient_source(p_render_data->environment) == RS::ENV_AMBIENT_SOURCE_SKY) {
RENDER_TIMESTAMP("Setup Sky");
RD::get_singleton()->draw_command_begin_label("Setup Sky");
- CameraMatrix projection = p_cam_projection;
- if (p_reflection_probe.is_valid()) {
+ CameraMatrix projection = p_render_data->cam_projection;
+ if (p_render_data->reflection_probe.is_valid()) {
CameraMatrix correction;
correction.set_depth_correction(true);
- projection = correction * p_cam_projection;
+ projection = correction * p_render_data->cam_projection;
}
- sky.setup(env, p_render_buffer, projection, p_cam_transform, screen_size, this);
+ sky.setup(env, p_render_data->render_buffers, projection, p_render_data->cam_transform, screen_size, this);
RID sky_rid = env->sky;
if (sky_rid.is_valid()) {
- sky.update(env, projection, p_cam_transform, time);
+ sky.update(env, projection, p_render_data->cam_transform, time);
radiance_texture = sky.sky_get_radiance_texture_rd(sky_rid);
} else {
// do not try to draw sky if invalid
@@ -468,17 +456,17 @@ void RenderForwardMobile::_render_scene(RID p_render_buffer, const Transform &p_
// !BAS! Look into this, seems most of the code in here related to clustered only, may want to move this code into ForwardClustered/RenderForwardMobile before calling it from here
// does trigger shadow map rendering so kinda important
- _pre_opaque_render(false, false, RID(), RID());
+ _pre_opaque_render(p_render_data, false, false, RID(), RID());
RD::get_singleton()->draw_command_begin_label("Render Opaque Pass");
- scene_state.ubo.directional_light_count = _get_render_state_directional_light_count();
+ scene_state.ubo.directional_light_count = p_render_data->directional_light_count;
- _setup_environment(p_environment, p_render_buffer, p_cam_projection, p_cam_transform, p_reflection_probe, p_reflection_probe.is_valid(), screen_size, p_shadow_atlas, !p_reflection_probe.is_valid(), p_default_bg_color, p_cam_projection.get_z_near(), p_cam_projection.get_z_far(), p_render_buffer.is_valid());
+ _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, p_render_data->render_buffers.is_valid());
RENDER_TIMESTAMP("Render Opaque Pass");
- RID rp_uniform_set = _setup_render_pass_uniform_set(RENDER_LIST_OPAQUE, p_render_buffer, radiance_texture, p_shadow_atlas, p_reflection_atlas, p_lightmaps, true);
+ RID rp_uniform_set = _setup_render_pass_uniform_set(RENDER_LIST_OPAQUE, p_render_data, radiance_texture, true);
bool can_continue_color = !scene_state.used_screen_texture && !using_ssr && !using_sss;
bool can_continue_depth = !scene_state.used_depth_texture && !using_ssr && !using_sss;
@@ -491,7 +479,7 @@ void RenderForwardMobile::_render_scene(RID p_render_buffer, const Transform &p_
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(), lod_camera_plane, lod_distance_multiplier, p_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);
_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);
}
@@ -500,14 +488,14 @@ void RenderForwardMobile::_render_scene(RID p_render_buffer, const Transform &p_
if (draw_sky || draw_sky_fog_only) {
RENDER_TIMESTAMP("Render Sky");
- CameraMatrix projection = p_cam_projection;
- if (p_reflection_probe.is_valid()) {
+ CameraMatrix projection = p_render_data->cam_projection;
+ if (p_render_data->reflection_probe.is_valid()) {
CameraMatrix correction;
correction.set_depth_correction(true);
- projection = correction * p_cam_projection;
+ 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_cam_transform, time);
+ 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();
}
@@ -529,12 +517,12 @@ void RenderForwardMobile::_render_scene(RID p_render_buffer, const Transform &p_
RD::get_singleton()->draw_command_begin_label("Render Transparent Pass");
- rp_uniform_set = _setup_render_pass_uniform_set(RENDER_LIST_ALPHA, p_render_buffer, radiance_texture, p_shadow_atlas, p_reflection_atlas, p_lightmaps, true);
+ rp_uniform_set = _setup_render_pass_uniform_set(RENDER_LIST_ALPHA, p_render_data, radiance_texture, true);
- _setup_environment(p_environment, p_render_buffer, p_cam_projection, p_cam_transform, p_reflection_probe, p_reflection_probe.is_valid(), screen_size, p_shadow_atlas, !p_reflection_probe.is_valid(), p_default_bg_color, p_cam_projection.get_z_near(), p_cam_projection.get_z_far(), false);
+ _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(), lod_camera_plane, lod_distance_multiplier, p_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);
_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);
}
@@ -564,18 +552,29 @@ void RenderForwardMobile::_render_shadow_append(RID p_framebuffer, const PagedAr
SceneState::ShadowPass shadow_pass;
+ RenderDataRD render_data;
+ render_data.cam_projection = p_projection;
+ render_data.cam_transform = p_transform;
+ render_data.z_near = 0.0;
+ render_data.z_far = p_zfar;
+ render_data.instances = &p_instances;
+ render_data.lod_camera_plane = p_camera_plane;
+ render_data.lod_distance_multiplier = p_lod_distance_multiplier;
+
scene_state.ubo.dual_paraboloid_side = p_use_dp_flip ? -1 : 1;
- _setup_environment(RID(), RID(), p_projection, p_transform, RID(), true, Vector2(1, 1), RID(), !p_flip_y, Color(), 0, p_zfar, false, p_use_pancake, shadow_pass_index);
+ _setup_environment(&render_data, true, Vector2(1, 1), !p_flip_y, Color(), false, p_use_pancake, shadow_pass_index);
if (get_debug_draw_mode() == RS::VIEWPORT_DEBUG_DRAW_DISABLE_LOD) {
- p_screen_lod_threshold = 0.0;
+ render_data.screen_lod_threshold = 0.0;
+ } else {
+ render_data.screen_lod_threshold = p_screen_lod_threshold;
}
PassMode pass_mode = p_use_dp ? PASS_MODE_SHADOW_DP : PASS_MODE_SHADOW;
uint32_t render_list_from = render_list[RENDER_LIST_SECONDARY].elements.size();
- _fill_render_list(RENDER_LIST_SECONDARY, p_instances, pass_mode, p_projection, p_transform, p_camera_plane, p_lod_distance_multiplier, p_screen_lod_threshold, true);
+ _fill_render_list(RENDER_LIST_SECONDARY, &render_data, pass_mode, 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);
@@ -594,8 +593,8 @@ void RenderForwardMobile::_render_shadow_append(RID p_framebuffer, const PagedAr
shadow_pass.rp_uniform_set = RID(); //will be filled later when instance buffer is complete
shadow_pass.camera_plane = p_camera_plane;
- shadow_pass.screen_lod_threshold = p_screen_lod_threshold;
- shadow_pass.lod_distance_multiplier = p_lod_distance_multiplier;
+ shadow_pass.screen_lod_threshold = render_data.screen_lod_threshold;
+ shadow_pass.lod_distance_multiplier = render_data.lod_distance_multiplier;
shadow_pass.framebuffer = p_framebuffer;
shadow_pass.initial_depth_action = p_begin ? (p_clear_region ? RD::INITIAL_ACTION_CLEAR_REGION : RD::INITIAL_ACTION_CLEAR) : (p_clear_region ? RD::INITIAL_ACTION_CLEAR_REGION_CONTINUE : RD::INITIAL_ACTION_CONTINUE);
@@ -612,7 +611,7 @@ void RenderForwardMobile::_render_shadow_process() {
for (uint32_t i = 0; i < scene_state.shadow_passes.size(); i++) {
//render passes need to be configured after instance buffer is done, since they need the latest version
SceneState::ShadowPass &shadow_pass = scene_state.shadow_passes[i];
- shadow_pass.rp_uniform_set = _setup_render_pass_uniform_set(RENDER_LIST_SECONDARY, RID(), RID(), RID(), RID(), PagedArray<RID>(), false, i);
+ shadow_pass.rp_uniform_set = _setup_render_pass_uniform_set(RENDER_LIST_SECONDARY, nullptr, RID(), false, i);
}
RD::get_singleton()->draw_command_end_label();
@@ -645,14 +644,19 @@ void RenderForwardMobile::_render_material(const Transform &p_cam_transform, con
scene_state.ubo.dual_paraboloid_side = 0;
scene_state.ubo.material_uv2_mode = false;
- _setup_environment(RID(), RID(), p_cam_projection, p_cam_transform, RID(), true, Vector2(1, 1), RID(), false, Color(), 0, 0);
+ RenderDataRD render_data;
+ render_data.cam_projection = p_cam_projection;
+ render_data.cam_transform = p_cam_transform;
+ render_data.instances = &p_instances;
+
+ _setup_environment(&render_data, true, Vector2(1, 1), false, Color());
PassMode pass_mode = PASS_MODE_DEPTH_MATERIAL;
- _fill_render_list(RENDER_LIST_SECONDARY, p_instances, pass_mode, p_cam_projection, p_cam_transform);
+ _fill_render_list(RENDER_LIST_SECONDARY, &render_data, pass_mode);
render_list[RENDER_LIST_SECONDARY].sort_by_key();
_fill_instance_data(RENDER_LIST_SECONDARY);
- RID rp_uniform_set = _setup_render_pass_uniform_set(RENDER_LIST_SECONDARY, RID(), RID(), RID(), RID(), PagedArray<RID>());
+ RID rp_uniform_set = _setup_render_pass_uniform_set(RENDER_LIST_SECONDARY, nullptr, RID());
RENDER_TIMESTAMP("Render Material");
@@ -683,14 +687,17 @@ void RenderForwardMobile::_render_uv2(const PagedArray<GeometryInstance *> &p_in
scene_state.ubo.dual_paraboloid_side = 0;
scene_state.ubo.material_uv2_mode = true;
- _setup_environment(RID(), RID(), CameraMatrix(), Transform(), RID(), true, Vector2(1, 1), RID(), false, Color(), 0, 0);
+ RenderDataRD render_data;
+ render_data.instances = &p_instances;
+
+ _setup_environment(&render_data, true, Vector2(1, 1), false, Color());
PassMode pass_mode = PASS_MODE_DEPTH_MATERIAL;
- _fill_render_list(RENDER_LIST_SECONDARY, p_instances, pass_mode, CameraMatrix(), Transform());
+ _fill_render_list(RENDER_LIST_SECONDARY, &render_data, pass_mode);
render_list[RENDER_LIST_SECONDARY].sort_by_key();
_fill_instance_data(RENDER_LIST_SECONDARY);
- RID rp_uniform_set = _setup_render_pass_uniform_set(RENDER_LIST_SECONDARY, RID(), RID(), RID(), RID(), PagedArray<RID>());
+ RID rp_uniform_set = _setup_render_pass_uniform_set(RENDER_LIST_SECONDARY, nullptr, RID());
RENDER_TIMESTAMP("Render Material");
@@ -747,15 +754,22 @@ void RenderForwardMobile::_render_particle_collider_heightfield(RID p_fb, const
_update_render_base_uniform_set();
scene_state.ubo.dual_paraboloid_side = 0;
- _setup_environment(RID(), RID(), p_cam_projection, p_cam_transform, RID(), true, Vector2(1, 1), RID(), true, Color(), 0, p_cam_projection.get_z_far(), false, false);
+ RenderDataRD render_data;
+ render_data.cam_projection = p_cam_projection;
+ render_data.cam_transform = p_cam_transform;
+ render_data.z_near = 0.0;
+ render_data.z_far = p_cam_projection.get_z_far();
+ render_data.instances = &p_instances;
+
+ _setup_environment(&render_data, true, Vector2(1, 1), true, Color(), false, false);
PassMode pass_mode = PASS_MODE_SHADOW;
- _fill_render_list(RENDER_LIST_SECONDARY, p_instances, pass_mode, p_cam_projection, p_cam_transform);
+ _fill_render_list(RENDER_LIST_SECONDARY, &render_data, pass_mode);
render_list[RENDER_LIST_SECONDARY].sort_by_key();
_fill_instance_data(RENDER_LIST_SECONDARY);
- RID rp_uniform_set = _setup_render_pass_uniform_set(RENDER_LIST_SECONDARY, RID(), RID(), RID(), RID(), PagedArray<RID>());
+ RID rp_uniform_set = _setup_render_pass_uniform_set(RENDER_LIST_SECONDARY, nullptr, RID());
RENDER_TIMESTAMP("Render Collider Heightfield");
@@ -902,7 +916,7 @@ RID RenderForwardMobile::_render_buffers_get_normal_texture(RID p_render_buffers
return RID();
}
-void RenderForwardMobile::_fill_render_list(RenderListType p_render_list, const PagedArray<GeometryInstance *> &p_instances, PassMode p_pass_mode, const CameraMatrix &p_cam_projection, const Transform &p_cam_transform, const Plane &p_lod_plane, float p_lod_distance_multiplier, float p_screen_lod_threshold, bool p_append) {
+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;
scene_state.used_screen_texture = false;
@@ -911,9 +925,9 @@ void RenderForwardMobile::_fill_render_list(RenderListType p_render_list, const
}
uint32_t lightmap_captures_used = 0;
- Plane near_plane(p_cam_transform.origin, -p_cam_transform.basis.get_axis(Vector3::AXIS_Z));
- near_plane.d += p_cam_projection.get_z_near();
- float z_max = p_cam_projection.get_z_far() - p_cam_projection.get_z_near();
+ Plane near_plane(p_render_data->cam_transform.origin, -p_render_data->cam_transform.basis.get_axis(Vector3::AXIS_Z));
+ near_plane.d += p_render_data->cam_projection.get_z_near();
+ float z_max = p_render_data->cam_projection.get_z_far() - p_render_data->cam_projection.get_z_near();
RenderList *rl = &render_list[p_render_list];
@@ -929,8 +943,8 @@ void RenderForwardMobile::_fill_render_list(RenderListType p_render_list, const
//fill list
- for (int i = 0; i < (int)p_instances.size(); i++) {
- GeometryInstanceForwardMobile *inst = static_cast<GeometryInstanceForwardMobile *>(p_instances[i]);
+ for (int i = 0; i < (int)p_render_data->instances->size(); i++) {
+ GeometryInstanceForwardMobile *inst = static_cast<GeometryInstanceForwardMobile *>((*p_render_data->instances)[i]);
Vector3 support_min = inst->transformed_aabb.get_support(-near_plane.normal);
inst->depth = near_plane.distance_to(support_min);
@@ -988,13 +1002,13 @@ void RenderForwardMobile::_fill_render_list(RenderListType p_render_list, const
// LOD
- if (p_screen_lod_threshold > 0.0 && storage->mesh_surface_has_lod(surf->surface)) {
+ if (p_render_data->screen_lod_threshold > 0.0 && storage->mesh_surface_has_lod(surf->surface)) {
//lod
- Vector3 lod_support_min = inst->transformed_aabb.get_support(-p_lod_plane.normal);
- Vector3 lod_support_max = inst->transformed_aabb.get_support(p_lod_plane.normal);
+ Vector3 lod_support_min = inst->transformed_aabb.get_support(-p_render_data->lod_camera_plane.normal);
+ Vector3 lod_support_max = inst->transformed_aabb.get_support(p_render_data->lod_camera_plane.normal);
- float distance_min = p_lod_plane.distance_to(lod_support_min);
- float distance_max = p_lod_plane.distance_to(lod_support_max);
+ float distance_min = p_render_data->lod_camera_plane.distance_to(lod_support_min);
+ float distance_max = p_render_data->lod_camera_plane.distance_to(lod_support_max);
float distance = 0.0;
@@ -1007,7 +1021,7 @@ 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_lod_distance_multiplier, p_screen_lod_threshold);
+ 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);
} else {
surf->lod_index = 0;
}
@@ -1058,25 +1072,25 @@ void RenderForwardMobile::_fill_render_list(RenderListType p_render_list, const
}
}
-void RenderForwardMobile::_setup_environment(RID p_environment, RID p_render_buffers, const CameraMatrix &p_cam_projection, const Transform &p_cam_transform, RID p_reflection_probe, bool p_no_fog, const Size2i &p_screen_size, RID p_shadow_atlas, bool p_flip_y, const Color &p_default_bg_color, float p_znear, float p_zfar, bool p_opaque_render_buffers, bool p_pancake_shadows, int p_index) {
+void RenderForwardMobile::_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, bool p_pancake_shadows, int p_index) {
//!BAS! need to go through this and find out what we don't need anymore
// This populates our UBO with main scene data that is pushed into set 1
- //CameraMatrix projection = p_cam_projection;
+ //CameraMatrix projection = p_render_data->cam_projection;
//projection.flip_y(); // Vulkan and modern APIs use Y-Down
CameraMatrix correction;
correction.set_depth_correction(p_flip_y);
- CameraMatrix projection = correction * p_cam_projection;
+ CameraMatrix projection = correction * p_render_data->cam_projection;
//store camera into ubo
RendererStorageRD::store_camera(projection, scene_state.ubo.projection_matrix);
RendererStorageRD::store_camera(projection.inverse(), scene_state.ubo.inv_projection_matrix);
- RendererStorageRD::store_transform(p_cam_transform, scene_state.ubo.camera_matrix);
- RendererStorageRD::store_transform(p_cam_transform.affine_inverse(), scene_state.ubo.inv_camera_matrix);
+ 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);
- scene_state.ubo.z_far = p_zfar;
- scene_state.ubo.z_near = p_znear;
+ scene_state.ubo.z_far = p_render_data->z_far;
+ scene_state.ubo.z_near = p_render_data->z_near;
scene_state.ubo.pancake_shadows = p_pancake_shadows;
@@ -1094,19 +1108,8 @@ void RenderForwardMobile::_setup_environment(RID p_environment, RID p_render_buf
scene_state.ubo.screen_pixel_size[0] = screen_pixel_size.x;
scene_state.ubo.screen_pixel_size[1] = screen_pixel_size.y;
- /*
- scene_state.ubo.cluster_shift = get_shift_from_power_of_2(p_cluster_size);
- scene_state.ubo.max_cluster_element_count_div_32 = p_max_cluster_elements / 32;
- {
- uint32_t cluster_screen_width = (p_screen_size.width - 1) / p_cluster_size + 1;
- uint32_t cluster_screen_height = (p_screen_size.height - 1) / p_cluster_size + 1;
- scene_state.ubo.cluster_type_size = cluster_screen_width * cluster_screen_height * (scene_state.ubo.max_cluster_element_count_div_32 + 32);
- scene_state.ubo.cluster_width = cluster_screen_width;
- }
- */
-
- if (p_shadow_atlas.is_valid()) {
- Vector2 sas = shadow_atlas_get_size(p_shadow_atlas);
+ if (p_render_data->shadow_atlas.is_valid()) {
+ Vector2 sas = shadow_atlas_get_size(p_render_data->shadow_atlas);
scene_state.ubo.shadow_atlas_pixel_size[0] = 1.0 / sas.x;
scene_state.ubo.shadow_atlas_pixel_size[1] = 1.0 / sas.y;
}
@@ -1124,22 +1127,22 @@ void RenderForwardMobile::_setup_environment(RID p_environment, RID p_render_buf
scene_state.ubo.volumetric_fog_enabled = false;
scene_state.ubo.fog_enabled = false;
- if (p_render_buffers.is_valid()) {
- RenderBufferDataForwardMobile *render_buffers = (RenderBufferDataForwardMobile *)render_buffers_get_data(p_render_buffers);
+ if (p_render_data->render_buffers.is_valid()) {
+ RenderBufferDataForwardMobile *render_buffers = (RenderBufferDataForwardMobile *)render_buffers_get_data(p_render_data->render_buffers);
if (render_buffers->msaa != RS::VIEWPORT_MSAA_DISABLED) {
scene_state.ubo.gi_upscale_for_msaa = true;
}
- if (render_buffers_has_volumetric_fog(p_render_buffers)) {
+ if (render_buffers_has_volumetric_fog(p_render_data->render_buffers)) {
scene_state.ubo.volumetric_fog_enabled = true;
- float fog_end = render_buffers_get_volumetric_fog_end(p_render_buffers);
+ float fog_end = render_buffers_get_volumetric_fog_end(p_render_data->render_buffers);
if (fog_end > 0.0) {
scene_state.ubo.volumetric_fog_inv_length = 1.0 / fog_end;
} else {
scene_state.ubo.volumetric_fog_inv_length = 1.0;
}
- float fog_detail_spread = render_buffers_get_volumetric_fog_detail_spread(p_render_buffers); //reverse lookup
+ float fog_detail_spread = render_buffers_get_volumetric_fog_detail_spread(p_render_data->render_buffers); //reverse lookup
if (fog_detail_spread > 0.0) {
scene_state.ubo.volumetric_fog_detail_spread = 1.0 / fog_detail_spread;
} else {
@@ -1160,18 +1163,18 @@ void RenderForwardMobile::_setup_environment(RID p_environment, RID p_render_buf
scene_state.ubo.use_reflection_cubemap = false;
scene_state.ubo.ssao_enabled = false;
- } else if (is_environment(p_environment)) {
- RS::EnvironmentBG env_bg = environment_get_background(p_environment);
- RS::EnvironmentAmbientSource ambient_src = environment_get_ambient_source(p_environment);
+ } else if (is_environment(p_render_data->environment)) {
+ RS::EnvironmentBG env_bg = environment_get_background(p_render_data->environment);
+ RS::EnvironmentAmbientSource ambient_src = environment_get_ambient_source(p_render_data->environment);
- float bg_energy = environment_get_bg_energy(p_environment);
+ float bg_energy = environment_get_bg_energy(p_render_data->environment);
scene_state.ubo.ambient_light_color_energy[3] = bg_energy;
- scene_state.ubo.ambient_color_sky_mix = environment_get_ambient_sky_contribution(p_environment);
+ scene_state.ubo.ambient_color_sky_mix = environment_get_ambient_sky_contribution(p_render_data->environment);
//ambient
if (ambient_src == RS::ENV_AMBIENT_SOURCE_BG && (env_bg == RS::ENV_BG_CLEAR_COLOR || env_bg == RS::ENV_BG_COLOR)) {
- Color color = env_bg == RS::ENV_BG_CLEAR_COLOR ? p_default_bg_color : environment_get_bg_color(p_environment);
+ Color color = env_bg == RS::ENV_BG_CLEAR_COLOR ? p_default_bg_color : environment_get_bg_color(p_render_data->environment);
color = color.to_linear();
scene_state.ubo.ambient_light_color_energy[0] = color.r * bg_energy;
@@ -1180,15 +1183,15 @@ void RenderForwardMobile::_setup_environment(RID p_environment, RID p_render_buf
scene_state.ubo.use_ambient_light = true;
scene_state.ubo.use_ambient_cubemap = false;
} else {
- float energy = environment_get_ambient_light_energy(p_environment);
- Color color = environment_get_ambient_light_color(p_environment);
+ float energy = environment_get_ambient_light_energy(p_render_data->environment);
+ Color color = environment_get_ambient_light_color(p_render_data->environment);
color = color.to_linear();
scene_state.ubo.ambient_light_color_energy[0] = color.r * energy;
scene_state.ubo.ambient_light_color_energy[1] = color.g * energy;
scene_state.ubo.ambient_light_color_energy[2] = color.b * energy;
- Basis sky_transform = environment_get_sky_orientation(p_environment);
- sky_transform = sky_transform.inverse() * p_cam_transform.basis;
+ Basis sky_transform = environment_get_sky_orientation(p_render_data->environment);
+ sky_transform = sky_transform.inverse() * p_render_data->cam_transform.basis;
RendererStorageRD::store_transform_3x3(sky_transform, scene_state.ubo.radiance_inverse_xform);
scene_state.ubo.use_ambient_cubemap = (ambient_src == RS::ENV_AMBIENT_SOURCE_BG && env_bg == RS::ENV_BG_SKY) || ambient_src == RS::ENV_AMBIENT_SOURCE_SKY;
@@ -1196,43 +1199,43 @@ void RenderForwardMobile::_setup_environment(RID p_environment, RID p_render_buf
}
//specular
- RS::EnvironmentReflectionSource ref_src = environment_get_reflection_source(p_environment);
+ RS::EnvironmentReflectionSource ref_src = environment_get_reflection_source(p_render_data->environment);
if ((ref_src == RS::ENV_REFLECTION_SOURCE_BG && env_bg == RS::ENV_BG_SKY) || ref_src == RS::ENV_REFLECTION_SOURCE_SKY) {
scene_state.ubo.use_reflection_cubemap = true;
} else {
scene_state.ubo.use_reflection_cubemap = false;
}
- scene_state.ubo.ssao_enabled = p_opaque_render_buffers && environment_is_ssao_enabled(p_environment);
- scene_state.ubo.ssao_ao_affect = environment_get_ssao_ao_affect(p_environment);
- scene_state.ubo.ssao_light_affect = environment_get_ssao_light_affect(p_environment);
+ scene_state.ubo.ssao_enabled = p_opaque_render_buffers && environment_is_ssao_enabled(p_render_data->environment);
+ scene_state.ubo.ssao_ao_affect = environment_get_ssao_ao_affect(p_render_data->environment);
+ scene_state.ubo.ssao_light_affect = environment_get_ssao_light_affect(p_render_data->environment);
- Color ao_color = environment_get_ao_color(p_environment).to_linear();
+ Color ao_color = environment_get_ao_color(p_render_data->environment).to_linear();
scene_state.ubo.ao_color[0] = ao_color.r;
scene_state.ubo.ao_color[1] = ao_color.g;
scene_state.ubo.ao_color[2] = ao_color.b;
scene_state.ubo.ao_color[3] = ao_color.a;
- scene_state.ubo.fog_enabled = environment_is_fog_enabled(p_environment);
- scene_state.ubo.fog_density = environment_get_fog_density(p_environment);
- scene_state.ubo.fog_height = environment_get_fog_height(p_environment);
- scene_state.ubo.fog_height_density = environment_get_fog_height_density(p_environment);
+ scene_state.ubo.fog_enabled = environment_is_fog_enabled(p_render_data->environment);
+ scene_state.ubo.fog_density = environment_get_fog_density(p_render_data->environment);
+ scene_state.ubo.fog_height = environment_get_fog_height(p_render_data->environment);
+ scene_state.ubo.fog_height_density = environment_get_fog_height_density(p_render_data->environment);
if (scene_state.ubo.fog_height_density >= 0.0001) {
scene_state.ubo.fog_height_density = 1.0 / scene_state.ubo.fog_height_density;
}
- scene_state.ubo.fog_aerial_perspective = environment_get_fog_aerial_perspective(p_environment);
+ scene_state.ubo.fog_aerial_perspective = environment_get_fog_aerial_perspective(p_render_data->environment);
- Color fog_color = environment_get_fog_light_color(p_environment).to_linear();
- float fog_energy = environment_get_fog_light_energy(p_environment);
+ Color fog_color = environment_get_fog_light_color(p_render_data->environment).to_linear();
+ float fog_energy = environment_get_fog_light_energy(p_render_data->environment);
scene_state.ubo.fog_light_color[0] = fog_color.r * fog_energy;
scene_state.ubo.fog_light_color[1] = fog_color.g * fog_energy;
scene_state.ubo.fog_light_color[2] = fog_color.b * fog_energy;
- scene_state.ubo.fog_sun_scatter = environment_get_fog_sun_scatter(p_environment);
+ scene_state.ubo.fog_sun_scatter = environment_get_fog_sun_scatter(p_render_data->environment);
} else {
- if (p_reflection_probe.is_valid() && storage->reflection_probe_is_interior(reflection_probe_instance_get_probe(p_reflection_probe))) {
+ if (p_render_data->reflection_probe.is_valid() && storage->reflection_probe_is_interior(reflection_probe_instance_get_probe(p_render_data->reflection_probe))) {
scene_state.ubo.use_ambient_light = false;
} else {
scene_state.ubo.use_ambient_light = true;
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 232ad0066b..bf911319f2 100644
--- a/servers/rendering/renderer_rd/forward_mobile/render_forward_mobile.h
+++ b/servers/rendering/renderer_rd/forward_mobile/render_forward_mobile.h
@@ -148,8 +148,8 @@ protected:
}
};
- RID _setup_render_pass_uniform_set(RenderListType p_render_list, RID p_render_buffers, RID p_radiance_texture, RID p_shadow_atlas, RID p_reflection_atlas, const PagedArray<RID> &p_lightmaps, bool p_use_directional_shadow_atlas = false, int p_index = 0);
- virtual void _render_scene(RID p_render_buffer, const Transform &p_cam_transform, const CameraMatrix &p_cam_projection, bool p_cam_ortogonal, const PagedArray<GeometryInstance *> &p_instances, const PagedArray<RID> &p_gi_probes, const PagedArray<RID> &p_lightmaps, RID p_environment, RID p_cluster_buffer, uint32_t p_cluster_size, uint32_t p_cluster_max_elements, RID p_camera_effects, RID p_shadow_atlas, RID p_reflection_atlas, RID p_reflection_probe, int p_reflection_probe_pass, const Color &p_default_bg_color, float p_screen_lod_threshold);
+ 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_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);
@@ -167,13 +167,13 @@ protected:
void _update_render_base_uniform_set();
virtual RID _render_buffers_get_normal_texture(RID p_render_buffers);
- void _fill_render_list(RenderListType p_render_list, const PagedArray<GeometryInstance *> &p_instances, PassMode p_pass_mode, const CameraMatrix &p_cam_projection, const Transform &p_cam_transform, const Plane &p_lod_camera_plane = Plane(), float p_lod_distance_multiplier = 0.0, float p_screen_lod_threshold = 0.0, bool p_append = false);
+ 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);
// void _update_instance_data_buffer(RenderListType p_render_list);
static RenderForwardMobile *singleton;
- void _setup_environment(RID p_environment, RID p_render_buffers, const CameraMatrix &p_cam_projection, const Transform &p_cam_transform, RID p_reflection_probe, bool p_no_fog, const Size2i &p_screen_size, RID p_shadow_atlas, bool p_flip_y, const Color &p_default_bg_color, float p_znear, float p_zfar, bool p_opaque_render_buffers = false, bool p_pancake_shadows = false, int p_index = 0);
+ 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);
RID render_base_uniform_set;
diff --git a/servers/rendering/renderer_rd/renderer_compositor_rd.cpp b/servers/rendering/renderer_rd/renderer_compositor_rd.cpp
index cb3e67e990..0012ba9c27 100644
--- a/servers/rendering/renderer_rd/renderer_compositor_rd.cpp
+++ b/servers/rendering/renderer_rd/renderer_compositor_rd.cpp
@@ -44,32 +44,40 @@ void RendererCompositorRD::blit_render_targets_to_screen(DisplayServer::WindowID
ERR_CONTINUE(texture.is_null());
RID rd_texture = storage->texture_get_rd_texture(texture);
ERR_CONTINUE(rd_texture.is_null());
+
if (!render_target_descriptors.has(rd_texture) || !RD::get_singleton()->uniform_set_is_valid(render_target_descriptors[rd_texture])) {
Vector<RD::Uniform> uniforms;
RD::Uniform u;
u.uniform_type = RD::UNIFORM_TYPE_SAMPLER_WITH_TEXTURE;
u.binding = 0;
- u.ids.push_back(copy_viewports_sampler);
+ u.ids.push_back(blit.sampler);
u.ids.push_back(rd_texture);
uniforms.push_back(u);
- RID uniform_set = RD::get_singleton()->uniform_set_create(uniforms, copy_viewports_rd_shader, 0);
+ RID uniform_set = RD::get_singleton()->uniform_set_create(uniforms, blit.shader.version_get_shader(blit.shader_version, BLIT_MODE_NORMAL), 0);
render_target_descriptors[rd_texture] = uniform_set;
}
Size2 screen_size(RD::get_singleton()->screen_get_width(p_screen), RD::get_singleton()->screen_get_height(p_screen));
-
- RD::get_singleton()->draw_list_bind_render_pipeline(draw_list, copy_viewports_rd_pipeline);
- RD::get_singleton()->draw_list_bind_index_array(draw_list, copy_viewports_rd_array);
+ 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);
- float push_constant[4] = {
- p_render_targets[i].rect.position.x / screen_size.width,
- p_render_targets[i].rect.position.y / screen_size.height,
- p_render_targets[i].rect.size.width / screen_size.width,
- p_render_targets[i].rect.size.height / screen_size.height,
- };
- RD::get_singleton()->draw_list_set_push_constant(draw_list, push_constant, 4 * sizeof(float));
+ blit.push_constant.rect[0] = p_render_targets[i].rect.position.x / screen_size.width;
+ blit.push_constant.rect[1] = p_render_targets[i].rect.position.y / screen_size.height;
+ blit.push_constant.rect[2] = p_render_targets[i].rect.size.width / screen_size.width;
+ blit.push_constant.rect[3] = p_render_targets[i].rect.size.height / screen_size.height;
+ blit.push_constant.layer = p_render_targets[i].multi_view.layer;
+ blit.push_constant.eye_center[0] = p_render_targets[i].lens_distortion.eye_center.x;
+ blit.push_constant.eye_center[1] = p_render_targets[i].lens_distortion.eye_center.y;
+ blit.push_constant.k1 = p_render_targets[i].lens_distortion.k1;
+ blit.push_constant.k2 = p_render_targets[i].lens_distortion.k2;
+ blit.push_constant.upscale = p_render_targets[i].lens_distortion.upscale;
+ blit.push_constant.aspect_ratio = p_render_targets[i].lens_distortion.aspect_ratio;
+
+ RD::get_singleton()->draw_list_set_push_constant(draw_list, &blit.push_constant, sizeof(BlitPushConstant));
RD::get_singleton()->draw_list_draw(draw_list, true);
}
@@ -96,40 +104,22 @@ void RendererCompositorRD::end_frame(bool p_swap_buffers) {
}
void RendererCompositorRD::initialize() {
- { //create framebuffer copy shader
- RenderingDevice::ShaderStageData vert;
- vert.shader_stage = RenderingDevice::SHADER_STAGE_VERTEX;
- vert.spir_v = RenderingDevice::get_singleton()->shader_compile_from_source(RenderingDevice::SHADER_STAGE_VERTEX,
- "#version 450\n"
- "layout(push_constant, binding = 0, std140) uniform Pos { vec4 dst_rect; } pos;\n"
- "layout(location =0) out vec2 uv;\n"
- "void main() { \n"
- " vec2 base_arr[4] = vec2[](vec2(0.0,0.0),vec2(0.0,1.0),vec2(1.0,1.0),vec2(1.0,0.0));\n"
- " uv = base_arr[gl_VertexIndex];\n"
- " vec2 vtx = pos.dst_rect.xy+uv*pos.dst_rect.zw;\n"
- " gl_Position = vec4(vtx * 2.0 - 1.0,0.0,1.0);\n"
- "}\n");
-
- RenderingDevice::ShaderStageData frag;
- frag.shader_stage = RenderingDevice::SHADER_STAGE_FRAGMENT;
- frag.spir_v = RenderingDevice::get_singleton()->shader_compile_from_source(RenderingDevice::SHADER_STAGE_FRAGMENT,
- "#version 450\n"
- "layout (location = 0) in vec2 uv;\n"
- "layout (location = 0) out vec4 color;\n"
- "layout (binding = 0) uniform sampler2D src_rt;\n"
- "void main() { color=texture(src_rt,uv); }\n");
-
- Vector<RenderingDevice::ShaderStageData> source;
- source.push_back(vert);
- source.push_back(frag);
- String error;
- copy_viewports_rd_shader = RD::get_singleton()->shader_create(source);
- if (!copy_viewports_rd_shader.is_valid()) {
- print_line("Failed compilation: " + error);
+ {
+ // Initialize blit
+ Vector<String> blit_modes;
+ 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.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);
}
- }
- { //create index array for copy shader
+ //create index array for copy shader
Vector<uint8_t> pv;
pv.resize(6 * 4);
{
@@ -142,15 +132,10 @@ void RendererCompositorRD::initialize() {
p32[4] = 2;
p32[5] = 3;
}
- copy_viewports_rd_index_buffer = RD::get_singleton()->index_buffer_create(6, RenderingDevice::INDEX_BUFFER_FORMAT_UINT32, pv);
- copy_viewports_rd_array = RD::get_singleton()->index_array_create(copy_viewports_rd_index_buffer, 0, 6);
- }
+ blit.index_buffer = RD::get_singleton()->index_buffer_create(6, RenderingDevice::INDEX_BUFFER_FORMAT_UINT32, pv);
+ blit.array = RD::get_singleton()->index_array_create(blit.index_buffer, 0, 6);
- { //pipeline
- copy_viewports_rd_pipeline = RD::get_singleton()->render_pipeline_create(copy_viewports_rd_shader, 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);
- }
- { // sampler
- copy_viewports_sampler = RD::get_singleton()->sampler_create(RD::SamplerState());
+ blit.sampler = RD::get_singleton()->sampler_create(RD::SamplerState());
}
}
@@ -162,9 +147,9 @@ void RendererCompositorRD::finalize() {
memdelete(storage);
//only need to erase these, the rest are erased by cascade
- RD::get_singleton()->free(copy_viewports_rd_index_buffer);
- RD::get_singleton()->free(copy_viewports_rd_shader);
- RD::get_singleton()->free(copy_viewports_sampler);
+ blit.shader.version_free(blit.shader_version);
+ RD::get_singleton()->free(blit.index_buffer);
+ RD::get_singleton()->free(blit.sampler);
}
RendererCompositorRD *RendererCompositorRD::singleton = nullptr;
diff --git a/servers/rendering/renderer_rd/renderer_compositor_rd.h b/servers/rendering/renderer_rd/renderer_compositor_rd.h
index b3865de2bf..52552f7ee3 100644
--- a/servers/rendering/renderer_rd/renderer_compositor_rd.h
+++ b/servers/rendering/renderer_rd/renderer_compositor_rd.h
@@ -38,6 +38,7 @@
#include "servers/rendering/renderer_rd/forward_mobile/render_forward_mobile.h"
#include "servers/rendering/renderer_rd/renderer_canvas_render_rd.h"
#include "servers/rendering/renderer_rd/renderer_storage_rd.h"
+#include "servers/rendering/renderer_rd/shaders/blit.glsl.gen.h"
class RendererCompositorRD : public RendererCompositor {
protected:
@@ -45,11 +46,35 @@ protected:
RendererStorageRD *storage;
RendererSceneRenderRD *scene;
- RID copy_viewports_rd_shader;
- RID copy_viewports_rd_pipeline;
- RID copy_viewports_rd_index_buffer;
- RID copy_viewports_rd_array;
- RID copy_viewports_sampler;
+ enum BlitMode {
+ BLIT_MODE_NORMAL,
+ BLIT_MODE_USE_LAYER,
+ BLIT_MODE_LENS,
+ BLIT_MODE_MAX
+ };
+
+ struct BlitPushConstant {
+ float rect[4];
+
+ float eye_center[2];
+ float k1;
+ float k2;
+
+ float upscale;
+ float aspect_ratio;
+ uint32_t layer;
+ uint32_t pad1;
+ };
+
+ struct Blit {
+ BlitPushConstant push_constant;
+ BlitShaderRD shader;
+ RID shader_version;
+ RID pipelines[BLIT_MODE_MAX];
+ RID index_buffer;
+ RID array;
+ RID sampler;
+ } blit;
Map<RID, RID> render_target_descriptors;
diff --git a/servers/rendering/renderer_rd/renderer_scene_gi_rd.cpp b/servers/rendering/renderer_rd/renderer_scene_gi_rd.cpp
index bc92e0b1ad..b289b17fad 100644
--- a/servers/rendering/renderer_rd/renderer_scene_gi_rd.cpp
+++ b/servers/rendering/renderer_rd/renderer_scene_gi_rd.cpp
@@ -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, RendererSceneRenderRD *p_scene_render) {
+void RendererSceneGIRD::SDFGI::pre_process_gi(const Transform &p_transform, RenderDataRD *p_render_data, RendererSceneRenderRD *p_scene_render) {
/* Update general SDFGI Buffer */
SDFGIData sdfgi_data;
diff --git a/servers/rendering/renderer_rd/renderer_scene_gi_rd.h b/servers/rendering/renderer_rd/renderer_scene_gi_rd.h
index df20011b23..59f5f374d1 100644
--- a/servers/rendering/renderer_rd/renderer_scene_gi_rd.h
+++ b/servers/rendering/renderer_rd/renderer_scene_gi_rd.h
@@ -48,7 +48,8 @@
#include "servers/rendering/renderer_scene_render.h"
#include "servers/rendering/rendering_device.h"
-// Forward declare RendererSceneRenderRD so we can pass it into some of our methods, these classes are pretty tightly bound
+// Forward declare RenderDataRD and RendererSceneRenderRD so we can pass it into some of our methods, these classes are pretty tightly bound
+struct RenderDataRD;
class RendererSceneRenderRD;
class RendererSceneGIRD {
@@ -529,7 +530,7 @@ public:
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_probes(RD::DrawListID p_draw_list, RID p_framebuffer, const CameraMatrix &p_camera_with_transform);
- void pre_process_gi(const Transform &p_transform, RendererSceneRenderRD *p_scene_render);
+ void pre_process_gi(const Transform &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);
};
diff --git a/servers/rendering/renderer_rd/renderer_scene_render_rd.cpp b/servers/rendering/renderer_rd/renderer_scene_render_rd.cpp
index d7a5d1211c..1f01de1333 100644
--- a/servers/rendering/renderer_rd/renderer_scene_render_rd.cpp
+++ b/servers/rendering/renderer_rd/renderer_scene_render_rd.cpp
@@ -1731,13 +1731,13 @@ void RendererSceneRenderRD::_process_ssao(RID p_render_buffers, RID p_environmen
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);
}
-void RendererSceneRenderRD::_render_buffers_post_process_and_tonemap(RID p_render_buffers, RID p_environment, RID p_camera_effects, const CameraMatrix &p_projection) {
- RenderBuffers *rb = render_buffers_owner.getornull(p_render_buffers);
+void RendererSceneRenderRD::_render_buffers_post_process_and_tonemap(const RenderDataRD *p_render_data) {
+ RenderBuffers *rb = render_buffers_owner.getornull(p_render_data->render_buffers);
ERR_FAIL_COND(!rb);
- RendererSceneEnvironmentRD *env = environment_owner.getornull(p_environment);
+ RendererSceneEnvironmentRD *env = environment_owner.getornull(p_render_data->environment);
//glow (if enabled)
- CameraEffects *camfx = camera_effects_owner.getornull(p_camera_effects);
+ CameraEffects *camfx = camera_effects_owner.getornull(p_render_data->camera_effects);
bool can_use_effects = rb->width >= 8 && rb->height >= 8;
@@ -1747,7 +1747,7 @@ void RendererSceneRenderRD::_render_buffers_post_process_and_tonemap(RID p_rende
}
float bokeh_size = camfx->dof_blur_amount * 64.0;
- storage->get_effects()->bokeh_dof(rb->texture, rb->depth_texture, Size2i(rb->width, rb->height), rb->blur[0].mipmaps[0].texture, rb->blur[1].mipmaps[0].texture, rb->blur[0].mipmaps[1].texture, camfx->dof_blur_far_enabled, camfx->dof_blur_far_distance, camfx->dof_blur_far_transition, camfx->dof_blur_near_enabled, camfx->dof_blur_near_distance, camfx->dof_blur_near_transition, bokeh_size, dof_blur_bokeh_shape, dof_blur_quality, dof_blur_use_jitter, p_projection.get_z_near(), p_projection.get_z_far(), p_projection.is_orthogonal());
+ storage->get_effects()->bokeh_dof(rb->texture, rb->depth_texture, Size2i(rb->width, rb->height), rb->blur[0].mipmaps[0].texture, rb->blur[1].mipmaps[0].texture, rb->blur[0].mipmaps[1].texture, camfx->dof_blur_far_enabled, camfx->dof_blur_far_distance, camfx->dof_blur_far_transition, camfx->dof_blur_near_enabled, camfx->dof_blur_near_distance, camfx->dof_blur_near_transition, bokeh_size, dof_blur_bokeh_shape, dof_blur_quality, dof_blur_use_jitter, p_render_data->z_near, p_render_data->z_far, p_render_data->cam_ortogonal);
}
if (can_use_effects && env && env->auto_exposure) {
@@ -3459,13 +3459,9 @@ void RendererSceneRenderRD::_update_volumetric_fog(RID p_render_buffers, RID p_e
rb->volumetric_fog->prev_cam_transform = p_cam_transform;
}
-uint32_t RendererSceneRenderRD::_get_render_state_directional_light_count() const {
- return render_state.directional_light_count;
-}
-
-bool RendererSceneRenderRD::_needs_post_prepass_render(bool p_use_gi) {
- if (render_state.render_buffers.is_valid()) {
- RenderBuffers *rb = render_buffers_owner.getornull(render_state.render_buffers);
+bool RendererSceneRenderRD::_needs_post_prepass_render(RenderDataRD *p_render_data, bool p_use_gi) {
+ if (p_render_data->render_buffers.is_valid()) {
+ RenderBuffers *rb = render_buffers_owner.getornull(p_render_data->render_buffers);
if (rb->sdfgi != nullptr) {
return true;
}
@@ -3473,34 +3469,34 @@ bool RendererSceneRenderRD::_needs_post_prepass_render(bool p_use_gi) {
return false;
}
-void RendererSceneRenderRD::_post_prepass_render(bool p_use_gi) {
- if (render_state.render_buffers.is_valid()) {
+void RendererSceneRenderRD::_post_prepass_render(RenderDataRD *p_render_data, bool p_use_gi) {
+ if (p_render_data->render_buffers.is_valid()) {
if (p_use_gi) {
- RenderBuffers *rb = render_buffers_owner.getornull(render_state.render_buffers);
+ RenderBuffers *rb = render_buffers_owner.getornull(p_render_data->render_buffers);
ERR_FAIL_COND(rb == nullptr);
if (rb->sdfgi == nullptr) {
return;
}
- RendererSceneEnvironmentRD *env = environment_owner.getornull(render_state.environment);
+ RendererSceneEnvironmentRD *env = environment_owner.getornull(p_render_data->environment);
rb->sdfgi->update_probes(env, sky.sky_owner.getornull(env->sky));
}
}
}
-void RendererSceneRenderRD::_pre_resolve_render(bool p_use_gi) {
- if (render_state.render_buffers.is_valid()) {
+void RendererSceneRenderRD::_pre_resolve_render(RenderDataRD *p_render_data, bool p_use_gi) {
+ if (p_render_data->render_buffers.is_valid()) {
if (p_use_gi) {
RD::get_singleton()->compute_list_end();
}
}
}
-void RendererSceneRenderRD::_pre_opaque_render(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_gi_probe_buffer) {
// Render shadows while GI is rendering, due to how barriers are handled, this should happen at the same time
- if (render_state.render_buffers.is_valid() && p_use_gi) {
- RenderBuffers *rb = render_buffers_owner.getornull(render_state.render_buffers);
+ 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;
@@ -3513,8 +3509,8 @@ void RendererSceneRenderRD::_pre_opaque_render(bool p_use_ssao, bool p_use_gi, R
render_state.shadows.clear();
render_state.directional_shadows.clear();
- Plane camera_plane(render_state.cam_transform.origin, -render_state.cam_transform.basis.get_axis(Vector3::AXIS_Z));
- float lod_distance_multiplier = render_state.cam_projection.get_lod_multiplier();
+ 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++) {
@@ -3531,7 +3527,7 @@ void RendererSceneRenderRD::_pre_opaque_render(bool p_use_ssao, bool p_use_gi, R
//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, render_state.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, render_state.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);
}
if (render_state.directional_shadows.size()) {
@@ -3545,7 +3541,7 @@ void RendererSceneRenderRD::_pre_opaque_render(bool p_use_ssao, bool p_use_gi, R
// Render GI
bool render_shadows = render_state.directional_shadows.size() || render_state.shadows.size();
- bool render_gi = render_state.render_buffers.is_valid() && p_use_gi;
+ bool render_gi = p_render_data->render_buffers.is_valid() && p_use_gi;
if (render_shadows && render_gi) {
RENDER_TIMESTAMP("Render GI + Render Shadows (parallel)");
@@ -3561,11 +3557,11 @@ void RendererSceneRenderRD::_pre_opaque_render(bool p_use_ssao, bool p_use_gi, R
//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, render_state.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, render_state.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);
}
//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, render_state.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, render_state.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);
}
_render_shadow_process();
@@ -3573,7 +3569,7 @@ void RendererSceneRenderRD::_pre_opaque_render(bool p_use_ssao, bool p_use_gi, R
//start GI
if (render_gi) {
- gi.process_gi(render_state.render_buffers, p_normal_roughness_buffer, p_gi_probe_buffer, render_state.environment, render_state.cam_projection, render_state.cam_transform, *render_state.gi_probes, this);
+ 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);
}
//Do shadow rendering (in parallel with GI)
@@ -3585,9 +3581,9 @@ void RendererSceneRenderRD::_pre_opaque_render(bool p_use_ssao, bool p_use_gi, R
RD::get_singleton()->compute_list_end(RD::BARRIER_MASK_NO_BARRIER); //use a later barrier
}
- if (render_state.render_buffers.is_valid()) {
+ if (p_render_data->render_buffers.is_valid()) {
if (p_use_ssao) {
- _process_ssao(render_state.render_buffers, render_state.environment, p_normal_roughness_buffer, render_state.cam_projection);
+ _process_ssao(p_render_data->render_buffers, p_render_data->environment, p_normal_roughness_buffer, p_render_data->cam_projection);
}
}
@@ -3595,32 +3591,32 @@ void RendererSceneRenderRD::_pre_opaque_render(bool p_use_ssao, bool p_use_gi, R
RD::get_singleton()->barrier(RD::BARRIER_MASK_ALL, RD::BARRIER_MASK_ALL);
if (current_cluster_builder) {
- current_cluster_builder->begin(render_state.cam_transform, render_state.cam_projection, !render_state.reflection_probe.is_valid());
+ current_cluster_builder->begin(p_render_data->cam_transform, p_render_data->cam_projection, !p_render_data->reflection_probe.is_valid());
}
bool using_shadows = true;
- if (render_state.reflection_probe.is_valid()) {
- if (!storage->reflection_probe_renders_shadows(reflection_probe_instance_get_probe(render_state.reflection_probe))) {
+ if (p_render_data->reflection_probe.is_valid()) {
+ if (!storage->reflection_probe_renders_shadows(reflection_probe_instance_get_probe(p_render_data->reflection_probe))) {
using_shadows = false;
}
} else {
//do not render reflections when rendering a reflection probe
- _setup_reflections(*render_state.reflection_probes, render_state.cam_transform.affine_inverse(), render_state.environment);
+ _setup_reflections(*p_render_data->reflection_probes, p_render_data->cam_transform.affine_inverse(), p_render_data->environment);
}
uint32_t directional_light_count = 0;
uint32_t positional_light_count = 0;
- _setup_lights(*render_state.lights, render_state.cam_transform, render_state.shadow_atlas, using_shadows, directional_light_count, positional_light_count);
- _setup_decals(*render_state.decals, render_state.cam_transform.affine_inverse());
+ _setup_lights(*p_render_data->lights, p_render_data->cam_transform, p_render_data->shadow_atlas, using_shadows, directional_light_count, positional_light_count);
+ _setup_decals(*p_render_data->decals, p_render_data->cam_transform.affine_inverse());
- render_state.directional_light_count = directional_light_count;
+ p_render_data->directional_light_count = directional_light_count;
if (current_cluster_builder) {
current_cluster_builder->bake_cluster();
}
- if (render_state.render_buffers.is_valid()) {
+ if (p_render_data->render_buffers.is_valid()) {
bool directional_shadows = false;
for (uint32_t i = 0; i < directional_light_count; i++) {
if (cluster.directional_lights[i].shadow_enabled) {
@@ -3629,7 +3625,7 @@ void RendererSceneRenderRD::_pre_opaque_render(bool p_use_ssao, bool p_use_gi, R
}
}
if (is_volumetric_supported()) {
- _update_volumetric_fog(render_state.render_buffers, render_state.environment, render_state.cam_projection, render_state.cam_transform, render_state.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.gi_probe_count);
}
}
}
@@ -3643,24 +3639,37 @@ void RendererSceneRenderRD::render_scene(RID p_render_buffers, const Transform &
}
//assign render data
+ RenderDataRD render_data;
{
- render_state.render_buffers = p_render_buffers;
- render_state.cam_transform = p_cam_transform;
- render_state.cam_projection = p_cam_projection;
- render_state.cam_ortogonal = p_cam_projection.is_orthogonal();
- render_state.instances = &p_instances;
- render_state.lights = &p_lights;
- render_state.reflection_probes = &p_reflection_probes;
- render_state.gi_probes = &p_gi_probes;
- render_state.decals = &p_decals;
- render_state.lightmaps = &p_lightmaps;
- render_state.environment = p_environment;
- render_state.camera_effects = p_camera_effects;
- render_state.shadow_atlas = p_shadow_atlas;
- render_state.reflection_atlas = p_reflection_atlas;
- render_state.reflection_probe = p_reflection_probe;
- render_state.reflection_probe_pass = p_reflection_probe_pass;
- render_state.screen_lod_threshold = p_screen_lod_threshold;
+ 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();
+
+ 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.decals = &p_decals;
+ render_data.lightmaps = &p_lightmaps;
+ render_data.environment = p_environment;
+ render_data.camera_effects = p_camera_effects;
+ render_data.shadow_atlas = p_shadow_atlas;
+ render_data.reflection_atlas = p_reflection_atlas;
+ 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));
+
+ if (get_debug_draw_mode() == RS::VIEWPORT_DEBUG_DRAW_DISABLE_LOD) {
+ render_data.screen_lod_threshold = 0.0;
+ } else {
+ render_data.screen_lod_threshold = p_screen_lod_threshold;
+ }
render_state.render_shadows = p_render_shadows;
render_state.render_shadow_count = p_render_shadow_count;
@@ -3672,9 +3681,9 @@ void RendererSceneRenderRD::render_scene(RID p_render_buffers, const Transform &
PagedArray<RID> empty;
if (get_debug_draw_mode() == RS::VIEWPORT_DEBUG_DRAW_UNSHADED) {
- render_state.lights = &empty;
- render_state.reflection_probes = &empty;
- render_state.gi_probes = &empty;
+ render_data.lights = &empty;
+ render_data.reflection_probes = &empty;
+ render_data.gi_probes = &empty;
}
//sdfgi first
@@ -3704,11 +3713,11 @@ void RendererSceneRenderRD::render_scene(RID p_render_buffers, const Transform &
}
}
- if (render_buffers_owner.owns(render_state.render_buffers)) {
- // render_state.render_buffers == p_render_buffers so we can use our already retrieved rb
+ if (render_buffers_owner.owns(render_data.render_buffers)) {
+ // render_data.render_buffers == p_render_buffers so we can use our already retrieved rb
current_cluster_builder = rb->cluster_builder;
- } else if (reflection_probe_instance_owner.owns(render_state.reflection_probe)) {
- ReflectionProbeInstance *rpi = reflection_probe_instance_owner.getornull(render_state.reflection_probe);
+ } else if (reflection_probe_instance_owner.owns(render_data.reflection_probe)) {
+ ReflectionProbeInstance *rpi = reflection_probe_instance_owner.getornull(render_data.reflection_probe);
ReflectionAtlas *ra = reflection_atlas_owner.getornull(rpi->atlas);
if (!ra) {
ERR_PRINT("reflection probe has no reflection atlas! Bug?");
@@ -3724,12 +3733,12 @@ void RendererSceneRenderRD::render_scene(RID p_render_buffers, const Transform &
if (rb != nullptr && rb->sdfgi != nullptr) {
rb->sdfgi->update_cascades();
- rb->sdfgi->pre_process_gi(p_cam_transform, this);
+ rb->sdfgi->pre_process_gi(p_cam_transform, &render_data, this);
}
render_state.gi_probe_count = 0;
if (rb != nullptr && rb->sdfgi != nullptr) {
- gi.setup_giprobes(render_state.render_buffers, render_state.cam_transform, *render_state.gi_probes, render_state.gi_probe_count, this);
+ gi.setup_giprobes(render_data.render_buffers, render_data.cam_transform, *render_data.gi_probes, render_state.gi_probe_count, this);
rb->sdfgi->update_light();
}
@@ -3737,11 +3746,13 @@ void RendererSceneRenderRD::render_scene(RID p_render_buffers, const Transform &
render_state.depth_prepass_used = false;
//calls _pre_opaque_render between depth pre-pass and opaque pass
if (current_cluster_builder != nullptr) {
- _render_scene(p_render_buffers, p_cam_transform, p_cam_projection, p_cam_ortogonal, p_instances, *render_state.gi_probes, p_lightmaps, p_environment, current_cluster_builder->get_cluster_buffer(), current_cluster_builder->get_cluster_size(), current_cluster_builder->get_max_cluster_elements(), p_camera_effects, p_shadow_atlas, p_reflection_atlas, p_reflection_probe, p_reflection_probe_pass, clear_color, p_screen_lod_threshold);
- } else {
- _render_scene(p_render_buffers, p_cam_transform, p_cam_projection, p_cam_ortogonal, p_instances, *render_state.gi_probes, p_lightmaps, p_environment, RID(), 0, 0, p_camera_effects, p_shadow_atlas, p_reflection_atlas, p_reflection_probe, p_reflection_probe_pass, clear_color, p_screen_lod_threshold);
+ render_data.cluster_buffer = current_cluster_builder->get_cluster_buffer();
+ render_data.cluster_size = current_cluster_builder->get_cluster_size();
+ render_data.cluster_max_elements = current_cluster_builder->get_max_cluster_elements();
}
+ _render_scene(&render_data, clear_color);
+
if (p_render_buffers.is_valid()) {
if (debug_draw == RS::VIEWPORT_DEBUG_DRAW_CLUSTER_OMNI_LIGHTS || debug_draw == RS::VIEWPORT_DEBUG_DRAW_CLUSTER_SPOT_LIGHTS || debug_draw == RS::VIEWPORT_DEBUG_DRAW_CLUSTER_DECALS || debug_draw == RS::VIEWPORT_DEBUG_DRAW_CLUSTER_REFLECTION_PROBES) {
ClusterBuilderRD::ElementType elem_type = ClusterBuilderRD::ELEMENT_TYPE_MAX;
@@ -3768,7 +3779,7 @@ void RendererSceneRenderRD::render_scene(RID p_render_buffers, const Transform &
RENDER_TIMESTAMP("Tonemap");
- _render_buffers_post_process_and_tonemap(p_render_buffers, p_environment, p_camera_effects, p_cam_projection);
+ _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);
diff --git a/servers/rendering/renderer_rd/renderer_scene_render_rd.h b/servers/rendering/renderer_rd/renderer_scene_render_rd.h
index 7600d6823e..1f82ae6dec 100644
--- a/servers/rendering/renderer_rd/renderer_scene_render_rd.h
+++ b/servers/rendering/renderer_rd/renderer_scene_render_rd.h
@@ -43,6 +43,40 @@
#include "servers/rendering/renderer_scene_render.h"
#include "servers/rendering/rendering_device.h"
+struct RenderDataRD {
+ RID render_buffers = RID();
+
+ Transform cam_transform = Transform();
+ CameraMatrix cam_projection = CameraMatrix();
+ bool cam_ortogonal = false;
+
+ 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> *decals = nullptr;
+ const PagedArray<RID> *lightmaps = nullptr;
+ RID environment = RID();
+ RID camera_effects = RID();
+ RID shadow_atlas = RID();
+ RID reflection_atlas = RID();
+ RID reflection_probe = RID();
+ int reflection_probe_pass = 0;
+
+ float lod_distance_multiplier = 0.0;
+ Plane lod_camera_plane = Plane();
+ float screen_lod_threshold = 0.0;
+
+ RID cluster_buffer = RID();
+ uint32_t cluster_size = 0;
+ uint32_t cluster_max_elements = 0;
+
+ uint32_t directional_light_count = 0;
+};
+
class RendererSceneRenderRD : public RendererSceneRender {
friend RendererSceneSkyRD;
friend RendererSceneGIRD;
@@ -62,7 +96,7 @@ protected:
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);
- virtual void _render_scene(RID p_render_buffer, const Transform &p_cam_transform, const CameraMatrix &p_cam_projection, bool p_cam_ortogonal, const PagedArray<GeometryInstance *> &p_instances, const PagedArray<RID> &p_gi_probes, const PagedArray<RID> &p_lightmaps, RID p_environment, RID p_cluster_buffer, uint32_t p_cluster_size, uint32_t p_cluster_max_elements, RID p_camera_effects, RID p_shadow_atlas, RID p_reflection_atlas, RID p_reflection_probe, int p_reflection_probe_pass, const Color &p_default_color, float p_screen_lod_threshold) = 0;
+ 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;
@@ -85,12 +119,11 @@ protected:
void _process_ssr(RID p_render_buffers, RID p_dest_framebuffer, RID p_normal_buffer, RID p_specular_buffer, RID p_metallic, const Color &p_metallic_mask, RID p_environment, const CameraMatrix &p_projection, bool p_use_additive);
void _process_sss(RID p_render_buffers, const CameraMatrix &p_camera);
- bool _needs_post_prepass_render(bool p_use_gi);
- void _post_prepass_render(bool p_use_gi);
- void _pre_resolve_render(bool p_use_gi);
+ bool _needs_post_prepass_render(RenderDataRD *p_render_data, bool p_use_gi);
+ void _post_prepass_render(RenderDataRD *p_render_data, bool p_use_gi);
+ void _pre_resolve_render(RenderDataRD *p_render_data, bool p_use_gi);
- void _pre_opaque_render(bool p_use_ssao, bool p_use_gi, RID p_normal_roughness_buffer, RID p_gi_probe_buffer);
- uint32_t _get_render_state_directional_light_count() const;
+ 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);
// needed for a single argument calls (material and uv2)
PagedArrayPool<GeometryInstance *> cull_argument_pool;
@@ -445,7 +478,7 @@ private:
void _allocate_luminance_textures(RenderBuffers *rb);
void _render_buffers_debug_draw(RID p_render_buffers, RID p_shadow_atlas, RID p_occlusion_buffer);
- void _render_buffers_post_process_and_tonemap(RID p_render_buffers, RID p_environment, RID p_camera_effects, const CameraMatrix &p_projection);
+ void _render_buffers_post_process_and_tonemap(const RenderDataRD *p_render_data);
/* Cluster */
@@ -592,38 +625,19 @@ private:
} cluster;
struct RenderState {
- RID render_buffers;
- Transform cam_transform;
- CameraMatrix cam_projection;
- bool cam_ortogonal = false;
- const PagedArray<GeometryInstance *> *instances = nullptr;
- const PagedArray<RID> *lights = nullptr;
- const PagedArray<RID> *reflection_probes = nullptr;
- const PagedArray<RID> *gi_probes = nullptr;
- const PagedArray<RID> *decals = nullptr;
- const PagedArray<RID> *lightmaps = nullptr;
- RID environment;
- RID camera_effects;
- RID shadow_atlas;
- RID reflection_atlas;
- RID reflection_probe;
- int reflection_probe_pass = 0;
- float screen_lod_threshold = 0.0;
-
- const RenderShadowData *render_shadows = nullptr;
+ const RendererSceneRender::RenderShadowData *render_shadows = nullptr;
int render_shadow_count = 0;
- const RenderSDFGIData *render_sdfgi_regions = nullptr;
+ const RendererSceneRender::RenderSDFGIData *render_sdfgi_regions = nullptr;
int render_sdfgi_region_count = 0;
- const RenderSDFGIUpdateData *sdfgi_update_data = nullptr;
+ const RendererSceneRender::RenderSDFGIUpdateData *sdfgi_update_data = nullptr;
- uint32_t directional_light_count = 0;
uint32_t gi_probe_count = 0;
LocalVector<int> cube_shadows;
LocalVector<int> shadows;
LocalVector<int> directional_shadows;
- bool depth_prepass_used;
+ bool depth_prepass_used; // this does not seem used anywhere...
} render_state;
struct VolumetricFog {
diff --git a/servers/rendering/renderer_rd/shaders/blit.glsl b/servers/rendering/renderer_rd/shaders/blit.glsl
new file mode 100644
index 0000000000..967da1e6e4
--- /dev/null
+++ b/servers/rendering/renderer_rd/shaders/blit.glsl
@@ -0,0 +1,95 @@
+#[vertex]
+
+#version 450
+
+#VERSION_DEFINES
+
+layout(push_constant, binding = 0, std140) uniform Pos {
+ vec4 dst_rect;
+
+ vec2 eye_center;
+ float k1;
+ float k2;
+
+ float upscale;
+ float aspect_ratio;
+ uint layer;
+ uint pad1;
+}
+data;
+
+layout(location = 0) out vec2 uv;
+
+void main() {
+ vec2 base_arr[4] = vec2[](vec2(0.0, 0.0), vec2(0.0, 1.0), vec2(1.0, 1.0), vec2(1.0, 0.0));
+ uv = base_arr[gl_VertexIndex];
+ vec2 vtx = data.dst_rect.xy + uv * data.dst_rect.zw;
+ gl_Position = vec4(vtx * 2.0 - 1.0, 0.0, 1.0);
+}
+
+#[fragment]
+
+#version 450
+
+#VERSION_DEFINES
+
+layout(push_constant, binding = 0, std140) uniform Pos {
+ vec4 dst_rect;
+
+ vec2 eye_center;
+ float k1;
+ float k2;
+
+ float upscale;
+ float aspect_ratio;
+ uint layer;
+ uint pad1;
+}
+data;
+
+layout(location = 0) in vec2 uv;
+
+layout(location = 0) out vec4 color;
+
+#ifdef USE_LAYER
+layout(binding = 0) uniform sampler2DArray src_rt;
+#else
+layout(binding = 0) uniform sampler2D src_rt;
+#endif
+
+void main() {
+#ifdef APPLY_LENS_DISTORTION
+ vec2 coords = uv * 2.0 - 1.0;
+ vec2 offset = coords - data.eye_center;
+
+ // take aspect ratio into account
+ offset.y /= data.aspect_ratio;
+
+ // distort
+ vec2 offset_sq = offset * offset;
+ float radius_sq = offset_sq.x + offset_sq.y;
+ float radius_s4 = radius_sq * radius_sq;
+ float distortion_scale = 1.0 + (data.k1 * radius_sq) + (data.k2 * radius_s4);
+ offset *= distortion_scale;
+
+ // reapply aspect ratio
+ offset.y *= data.aspect_ratio;
+
+ // add our eye center back in
+ coords = offset + data.eye_center;
+ coords /= data.upscale;
+
+ // and check our color
+ if (coords.x < -1.0 || coords.y < -1.0 || coords.x > 1.0 || coords.y > 1.0) {
+ color = vec4(0.0, 0.0, 0.0, 1.0);
+ } else {
+ // layer is always used here
+ coords = (coords + vec2(1.0)) / vec2(2.0);
+ color = texture(src_rt, vec3(coords, data.layer));
+ }
+#elif defined(USE_LAYER)
+ color = texture(src_rt, vec3(uv, data.layer));
+#else
+ color = texture(src_rt, uv);
+#endif
+}