Split RenderDataRD struct from RenderState struct to simplify passing our render data around the renderer.

This commit is contained in:
Bastiaan Olij 2021-05-05 15:41:12 +10:00
parent 6e3f47983c
commit 308b26762b
8 changed files with 483 additions and 423 deletions

View file

@ -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);
}

View file

@ -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);

View file

@ -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;

View file

@ -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;

View file

@ -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;

View file

@ -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);
};

View file

@ -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);

View file

@ -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 {