1
0
mirror of https://github.com/godotengine/godot.git synced 2025-11-05 12:10:55 +00:00

Extract shared scene data into a separate class

This commit is contained in:
Bastiaan Olij
2022-09-07 21:23:01 +10:00
parent 20d6672846
commit 02ea1de7d0
18 changed files with 1019 additions and 1042 deletions

View File

@@ -37,7 +37,7 @@
#include "servers/rendering/renderer_rd/forward_clustered/scene_shader_forward_clustered.h" #include "servers/rendering/renderer_rd/forward_clustered/scene_shader_forward_clustered.h"
#include "servers/rendering/renderer_rd/pipeline_cache_rd.h" #include "servers/rendering/renderer_rd/pipeline_cache_rd.h"
#include "servers/rendering/renderer_rd/renderer_scene_render_rd.h" #include "servers/rendering/renderer_rd/renderer_scene_render_rd.h"
#include "servers/rendering/renderer_rd/shaders/scene_forward_clustered.glsl.gen.h" #include "servers/rendering/renderer_rd/shaders/forward_clustered/scene_forward_clustered.glsl.gen.h"
#include "servers/rendering/renderer_rd/storage_rd/utilities.h" #include "servers/rendering/renderer_rd/storage_rd/utilities.h"
#define RB_SCOPE_FORWARD_CLUSTERED SNAME("forward_clustered") #define RB_SCOPE_FORWARD_CLUSTERED SNAME("forward_clustered")
@@ -249,61 +249,22 @@ class RenderForwardClustered : public RendererSceneRenderRD {
}; };
struct SceneState { struct SceneState {
// This struct is loaded into Set 1 - Binding 0, populated at start of rendering a frame, must match with shader code // This struct is loaded into Set 1 - Binding 1, populated at start of rendering a frame, must match with shader code
struct UBO { struct UBO {
float projection_matrix[16];
float inv_projection_matrix[16];
float inv_view_matrix[16];
float view_matrix[16];
float projection_matrix_view[RendererSceneRender::MAX_RENDER_VIEWS][16];
float inv_projection_matrix_view[RendererSceneRender::MAX_RENDER_VIEWS][16];
float eye_offset[RendererSceneRender::MAX_RENDER_VIEWS][4];
float viewport_size[2];
float screen_pixel_size[2];
uint32_t cluster_shift; uint32_t cluster_shift;
uint32_t cluster_width; uint32_t cluster_width;
uint32_t cluster_type_size; uint32_t cluster_type_size;
uint32_t max_cluster_element_count_div_32; uint32_t max_cluster_element_count_div_32;
float directional_penumbra_shadow_kernel[128]; //32 vec4s
float directional_soft_shadow_kernel[128];
float penumbra_shadow_kernel[128];
float soft_shadow_kernel[128];
float ambient_light_color_energy[4];
float ambient_color_sky_mix;
uint32_t use_ambient_light;
uint32_t use_ambient_cubemap;
uint32_t use_reflection_cubemap;
float radiance_inverse_xform[12];
float shadow_atlas_pixel_size[2];
float directional_shadow_pixel_size[2];
uint32_t directional_light_count;
float dual_paraboloid_side;
float z_far;
float z_near;
uint32_t ss_effects_flags; uint32_t ss_effects_flags;
float ssao_light_affect; float ssao_light_affect;
float ssao_ao_affect; float ssao_ao_affect;
uint32_t roughness_limiter_enabled; uint32_t pad1;
float roughness_limiter_amount;
float roughness_limiter_limit;
float opaque_prepass_threshold;
uint32_t roughness_limiter_pad;
float sdf_to_bounds[16]; float sdf_to_bounds[16];
int32_t sdf_offset[3]; int32_t sdf_offset[3];
uint32_t material_uv2_mode; uint32_t pad2;
int32_t sdf_size[3]; int32_t sdf_size[3];
uint32_t gi_upscale_for_msaa; uint32_t gi_upscale_for_msaa;
@@ -312,26 +273,6 @@ class RenderForwardClustered : public RendererSceneRenderRD {
float volumetric_fog_inv_length; float volumetric_fog_inv_length;
float volumetric_fog_detail_spread; float volumetric_fog_detail_spread;
uint32_t volumetric_fog_pad; uint32_t volumetric_fog_pad;
// Fog
uint32_t fog_enabled;
float fog_density;
float fog_height;
float fog_height_density;
float fog_light_color[3];
float fog_sun_scatter;
float fog_aerial_perspective;
float time;
float reflection_multiplier;
uint32_t pancake_shadows;
float taa_jitter[2];
float emissive_exposure_normalization; // Needed to normalize emissive when using physical units.
float IBL_exposure_normalization;
}; };
struct PushConstant { struct PushConstant {
@@ -351,11 +292,10 @@ class RenderForwardClustered : public RendererSceneRenderRD {
float lightmap_uv_scale[4]; float lightmap_uv_scale[4];
}; };
UBO ubo_data[2]; UBO ubo;
UBO &ubo = ubo_data[0];
UBO &prev_ubo = ubo_data[1];
LocalVector<RID> uniform_buffers; LocalVector<RID> uniform_buffers;
LocalVector<RID> implementation_uniform_buffers;
LightmapData lightmaps[MAX_LIGHTMAPS]; LightmapData lightmaps[MAX_LIGHTMAPS];
RID lightmap_ids[MAX_LIGHTMAPS]; RID lightmap_ids[MAX_LIGHTMAPS];

View File

@@ -32,7 +32,7 @@
#define SCENE_SHADER_FORWARD_CLUSTERED_H #define SCENE_SHADER_FORWARD_CLUSTERED_H
#include "servers/rendering/renderer_rd/renderer_scene_render_rd.h" #include "servers/rendering/renderer_rd/renderer_scene_render_rd.h"
#include "servers/rendering/renderer_rd/shaders/scene_forward_clustered.glsl.gen.h" #include "servers/rendering/renderer_rd/shaders/forward_clustered/scene_forward_clustered.glsl.gen.h"
namespace RendererSceneRenderImplementation { namespace RendererSceneRenderImplementation {

View File

@@ -504,8 +504,20 @@ void RenderForwardMobile::_render_scene(RenderDataRD *p_render_data, const Color
RENDER_TIMESTAMP("Setup 3D Scene"); RENDER_TIMESTAMP("Setup 3D Scene");
scene_state.ubo.directional_light_count = 0; /* TODO
scene_state.ubo.opaque_prepass_threshold = 0.0; // check if we need motion vectors
if (get_debug_draw_mode() == RS::VIEWPORT_DEBUG_DRAW_MOTION_VECTORS) {
p_render_data->scene_data->calculate_motion_vectors = true;
} else if (render target has velocity override) { // TODO
p_render_data->scene_data->calculate_motion_vectors = true;
} else {
p_render_data->scene_data->calculate_motion_vectors = false;
}
*/
p_render_data->scene_data->calculate_motion_vectors = false; // for now, not yet supported...
p_render_data->scene_data->directional_light_count = 0;
p_render_data->scene_data->opaque_prepass_threshold = 0.0;
// We can only use our full subpass approach if we're: // We can only use our full subpass approach if we're:
// - not reading from SCREEN_TEXTURE/DEPTH_TEXTURE // - not reading from SCREEN_TEXTURE/DEPTH_TEXTURE
@@ -581,13 +593,11 @@ void RenderForwardMobile::_render_scene(RenderDataRD *p_render_data, const Color
ERR_FAIL(); //bug? ERR_FAIL(); //bug?
} }
scene_state.ubo.viewport_size[0] = screen_size.x; p_render_data->scene_data->emissive_exposure_normalization = -1.0;
scene_state.ubo.viewport_size[1] = screen_size.y;
scene_state.ubo.emissive_exposure_normalization = -1.0;
RD::get_singleton()->draw_command_begin_label("Render Setup"); RD::get_singleton()->draw_command_begin_label("Render Setup");
_setup_lightmaps(p_render_data, *p_render_data->lightmaps, p_render_data->cam_transform); _setup_lightmaps(p_render_data, *p_render_data->lightmaps, p_render_data->scene_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); _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) _update_render_base_uniform_set(); //may have changed due to the above (light buffer enlarged, as an example)
@@ -658,20 +668,20 @@ void RenderForwardMobile::_render_scene(RenderDataRD *p_render_data, const Color
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) { 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"); RENDER_TIMESTAMP("Setup Sky");
RD::get_singleton()->draw_command_begin_label("Setup Sky"); RD::get_singleton()->draw_command_begin_label("Setup Sky");
Projection projection = p_render_data->cam_projection; Projection projection = p_render_data->scene_data->cam_projection;
if (p_render_data->reflection_probe.is_valid()) { if (p_render_data->reflection_probe.is_valid()) {
Projection correction; Projection correction;
correction.set_depth_correction(true); correction.set_depth_correction(true);
projection = correction * p_render_data->cam_projection; projection = correction * p_render_data->scene_data->cam_projection;
} }
sky.setup(p_render_data->environment, p_render_data->render_buffers, *p_render_data->lights, p_render_data->camera_attributes, projection, p_render_data->cam_transform, screen_size, this); sky.setup(p_render_data->environment, p_render_data->render_buffers, *p_render_data->lights, p_render_data->camera_attributes, projection, p_render_data->scene_data->cam_transform, screen_size, this);
sky_energy_multiplier *= bg_energy_multiplier; sky_energy_multiplier *= bg_energy_multiplier;
RID sky_rid = environment_get_sky(p_render_data->environment); RID sky_rid = environment_get_sky(p_render_data->environment);
if (sky_rid.is_valid()) { if (sky_rid.is_valid()) {
sky.update(p_render_data->environment, projection, p_render_data->cam_transform, time, sky_energy_multiplier); sky.update(p_render_data->environment, projection, p_render_data->scene_data->cam_transform, time, sky_energy_multiplier);
radiance_texture = sky.sky_get_radiance_texture_rd(sky_rid); radiance_texture = sky.sky_get_radiance_texture_rd(sky_rid);
} else { } else {
// do not try to draw sky if invalid // do not try to draw sky if invalid
@@ -694,10 +704,10 @@ void RenderForwardMobile::_render_scene(RenderDataRD *p_render_data, const Color
if (p_render_data->reflection_probe.is_valid()) { if (p_render_data->reflection_probe.is_valid()) {
Projection correction; Projection correction;
correction.set_depth_correction(true); correction.set_depth_correction(true);
Projection projection = correction * p_render_data->cam_projection; Projection projection = correction * p_render_data->scene_data->cam_projection;
sky.update_res_buffers(p_render_data->environment, 1, &projection, p_render_data->cam_transform, time, sky_energy_multiplier); sky.update_res_buffers(p_render_data->environment, 1, &projection, p_render_data->scene_data->cam_transform, time, sky_energy_multiplier);
} else { } else {
sky.update_res_buffers(p_render_data->environment, p_render_data->view_count, p_render_data->view_projection, p_render_data->cam_transform, time, sky_energy_multiplier); sky.update_res_buffers(p_render_data->environment, p_render_data->scene_data->view_count, p_render_data->scene_data->view_projection, p_render_data->scene_data->cam_transform, time, sky_energy_multiplier);
} }
RD::get_singleton()->draw_command_end_label(); // Setup Sky resolution buffers RD::get_singleton()->draw_command_end_label(); // Setup Sky resolution buffers
@@ -734,7 +744,7 @@ void RenderForwardMobile::_render_scene(RenderDataRD *p_render_data, const Color
RD::get_singleton()->draw_command_begin_label("Render Opaque Subpass"); RD::get_singleton()->draw_command_begin_label("Render Opaque Subpass");
scene_state.ubo.directional_light_count = p_render_data->directional_light_count; p_render_data->scene_data->directional_light_count = p_render_data->directional_light_count;
_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()); _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());
@@ -765,7 +775,7 @@ void RenderForwardMobile::_render_scene(RenderDataRD *p_render_data, const Color
} }
RD::FramebufferFormatID fb_format = RD::get_singleton()->framebuffer_get_format(framebuffer); RD::FramebufferFormatID fb_format = RD::get_singleton()->framebuffer_get_format(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, PASS_MODE_COLOR, rp_uniform_set, spec_constant_base_flags, 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_mesh_lod_threshold, p_render_data->view_count); 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, spec_constant_base_flags, get_debug_draw_mode() == RS::VIEWPORT_DEBUG_DRAW_WIREFRAME, Vector2(), p_render_data->scene_data->lod_camera_plane, p_render_data->scene_data->lod_distance_multiplier, p_render_data->scene_data->screen_mesh_lod_threshold, p_render_data->scene_data->view_count);
render_list_params.framebuffer_format = fb_format; render_list_params.framebuffer_format = fb_format;
if ((uint32_t)render_list_params.element_count > render_list_thread_threshold && false) { if ((uint32_t)render_list_params.element_count > render_list_thread_threshold && false) {
// secondary command buffers need more testing at this time // secondary command buffers need more testing at this time
@@ -793,10 +803,10 @@ void RenderForwardMobile::_render_scene(RenderDataRD *p_render_data, const Color
if (p_render_data->reflection_probe.is_valid()) { if (p_render_data->reflection_probe.is_valid()) {
Projection correction; Projection correction;
correction.set_depth_correction(true); correction.set_depth_correction(true);
Projection projection = correction * p_render_data->cam_projection; Projection projection = correction * p_render_data->scene_data->cam_projection;
sky.draw(draw_list, p_render_data->environment, framebuffer, 1, &projection, p_render_data->cam_transform, time, sky_energy_multiplier); sky.draw(draw_list, p_render_data->environment, framebuffer, 1, &projection, p_render_data->scene_data->cam_transform, time, sky_energy_multiplier);
} else { } else {
sky.draw(draw_list, p_render_data->environment, framebuffer, p_render_data->view_count, p_render_data->view_projection, p_render_data->cam_transform, time, sky_energy_multiplier); sky.draw(draw_list, p_render_data->environment, framebuffer, p_render_data->scene_data->view_count, p_render_data->scene_data->view_projection, p_render_data->scene_data->cam_transform, time, sky_energy_multiplier);
} }
RD::get_singleton()->draw_command_end_label(); // Draw Sky Subpass RD::get_singleton()->draw_command_end_label(); // Draw Sky Subpass
@@ -832,7 +842,7 @@ void RenderForwardMobile::_render_scene(RenderDataRD *p_render_data, const Color
if (using_subpass_transparent) { if (using_subpass_transparent) {
RD::FramebufferFormatID fb_format = RD::get_singleton()->framebuffer_get_format(framebuffer); RD::FramebufferFormatID fb_format = RD::get_singleton()->framebuffer_get_format(framebuffer);
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_TRANSPARENT, rp_uniform_set, spec_constant_base_flags, 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_mesh_lod_threshold, p_render_data->view_count); 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_TRANSPARENT, rp_uniform_set, spec_constant_base_flags, get_debug_draw_mode() == RS::VIEWPORT_DEBUG_DRAW_WIREFRAME, Vector2(), p_render_data->scene_data->lod_camera_plane, p_render_data->scene_data->lod_distance_multiplier, p_render_data->scene_data->screen_mesh_lod_threshold, p_render_data->scene_data->view_count);
render_list_params.framebuffer_format = fb_format; render_list_params.framebuffer_format = fb_format;
if ((uint32_t)render_list_params.element_count > render_list_thread_threshold && false) { if ((uint32_t)render_list_params.element_count > render_list_thread_threshold && false) {
// secondary command buffers need more testing at this time // secondary command buffers need more testing at this time
@@ -871,7 +881,7 @@ void RenderForwardMobile::_render_scene(RenderDataRD *p_render_data, const Color
// _setup_environment(p_render_data, p_render_data->reflection_probe.is_valid(), screen_size, !p_render_data->reflection_probe.is_valid(), p_default_bg_color, false); // _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);
RD::FramebufferFormatID fb_format = RD::get_singleton()->framebuffer_get_format(framebuffer); RD::FramebufferFormatID fb_format = RD::get_singleton()->framebuffer_get_format(framebuffer);
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, spec_constant_base_flags, 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_mesh_lod_threshold, p_render_data->view_count); 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, spec_constant_base_flags, get_debug_draw_mode() == RS::VIEWPORT_DEBUG_DRAW_WIREFRAME, Vector2(), p_render_data->scene_data->lod_camera_plane, p_render_data->scene_data->lod_distance_multiplier, p_render_data->scene_data->screen_mesh_lod_threshold, p_render_data->scene_data->view_count);
render_list_params.framebuffer_format = fb_format; render_list_params.framebuffer_format = fb_format;
if ((uint32_t)render_list_params.element_count > render_list_thread_threshold && false) { if ((uint32_t)render_list_params.element_count > render_list_thread_threshold && false) {
// secondary command buffers need more testing at this time // secondary command buffers need more testing at this time
@@ -928,26 +938,29 @@ void RenderForwardMobile::_render_shadow_append(RID p_framebuffer, const PagedAr
p_render_info->info[RS::VIEWPORT_RENDER_INFO_TYPE_SHADOW][RS::VIEWPORT_RENDER_INFO_DRAW_CALLS_IN_FRAME] = p_instances.size(); p_render_info->info[RS::VIEWPORT_RENDER_INFO_TYPE_SHADOW][RS::VIEWPORT_RENDER_INFO_DRAW_CALLS_IN_FRAME] = p_instances.size();
p_render_info->info[RS::VIEWPORT_RENDER_INFO_TYPE_SHADOW][RS::VIEWPORT_RENDER_INFO_OBJECTS_IN_FRAME] = p_instances.size(); p_render_info->info[RS::VIEWPORT_RENDER_INFO_TYPE_SHADOW][RS::VIEWPORT_RENDER_INFO_OBJECTS_IN_FRAME] = p_instances.size();
} }
RenderSceneDataRD scene_data;
scene_data.cam_projection = p_projection;
scene_data.cam_transform = p_transform;
scene_data.view_projection[0] = p_projection;
scene_data.z_near = 0.0;
scene_data.z_far = p_zfar;
scene_data.lod_camera_plane = p_camera_plane;
scene_data.lod_distance_multiplier = p_lod_distance_multiplier;
scene_data.dual_paraboloid_side = p_use_dp_flip ? -1 : 1;
scene_data.opaque_prepass_threshold = 0.1;
RenderDataRD render_data; RenderDataRD render_data;
render_data.cam_projection = p_projection; render_data.scene_data = &scene_data;
render_data.cam_transform = p_transform;
render_data.view_projection[0] = p_projection;
render_data.z_near = 0.0;
render_data.z_far = p_zfar;
render_data.instances = &p_instances; render_data.instances = &p_instances;
render_data.render_info = p_render_info; render_data.render_info = p_render_info;
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;
scene_state.ubo.opaque_prepass_threshold = 0.1;
_setup_environment(&render_data, true, Vector2(1, 1), !p_flip_y, Color(), 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) { if (get_debug_draw_mode() == RS::VIEWPORT_DEBUG_DRAW_DISABLE_LOD) {
render_data.screen_mesh_lod_threshold = 0.0; scene_data.screen_mesh_lod_threshold = 0.0;
} else { } else {
render_data.screen_mesh_lod_threshold = p_screen_mesh_lod_threshold; scene_data.screen_mesh_lod_threshold = p_screen_mesh_lod_threshold;
} }
PassMode pass_mode = p_use_dp ? PASS_MODE_SHADOW_DP : PASS_MODE_SHADOW; PassMode pass_mode = p_use_dp ? PASS_MODE_SHADOW_DP : PASS_MODE_SHADOW;
@@ -972,8 +985,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.rp_uniform_set = RID(); //will be filled later when instance buffer is complete
shadow_pass.camera_plane = p_camera_plane; shadow_pass.camera_plane = p_camera_plane;
shadow_pass.screen_mesh_lod_threshold = render_data.screen_mesh_lod_threshold; shadow_pass.screen_mesh_lod_threshold = scene_data.screen_mesh_lod_threshold;
shadow_pass.lod_distance_multiplier = render_data.lod_distance_multiplier; shadow_pass.lod_distance_multiplier = scene_data.lod_distance_multiplier;
shadow_pass.framebuffer = p_framebuffer; 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); 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);
@@ -1020,15 +1033,17 @@ void RenderForwardMobile::_render_material(const Transform3D &p_cam_transform, c
_update_render_base_uniform_set(); _update_render_base_uniform_set();
scene_state.ubo.dual_paraboloid_side = 0; RenderSceneDataRD scene_data;
scene_state.ubo.material_uv2_mode = false; scene_data.cam_projection = p_cam_projection;
scene_state.ubo.opaque_prepass_threshold = 0.0f; scene_data.cam_transform = p_cam_transform;
scene_state.ubo.emissive_exposure_normalization = p_exposure_normalization; scene_data.view_projection[0] = p_cam_projection;
scene_data.dual_paraboloid_side = 0;
scene_data.material_uv2_mode = false;
scene_data.opaque_prepass_threshold = 0.0f;
scene_data.emissive_exposure_normalization = p_exposure_normalization;
RenderDataRD render_data; RenderDataRD render_data;
render_data.cam_projection = p_cam_projection; render_data.scene_data = &scene_data;
render_data.cam_transform = p_cam_transform;
render_data.view_projection[0] = p_cam_projection;
render_data.instances = &p_instances; render_data.instances = &p_instances;
_setup_environment(&render_data, true, Vector2(1, 1), false, Color()); _setup_environment(&render_data, true, Vector2(1, 1), false, Color());
@@ -1067,11 +1082,13 @@ void RenderForwardMobile::_render_uv2(const PagedArray<RenderGeometryInstance *>
_update_render_base_uniform_set(); _update_render_base_uniform_set();
scene_state.ubo.dual_paraboloid_side = 0; RenderSceneDataRD scene_data;
scene_state.ubo.material_uv2_mode = true; scene_data.dual_paraboloid_side = 0;
scene_state.ubo.emissive_exposure_normalization = -1.0; scene_data.material_uv2_mode = true;
scene_data.emissive_exposure_normalization = -1.0;
RenderDataRD render_data; RenderDataRD render_data;
render_data.scene_data = &scene_data;
render_data.instances = &p_instances; render_data.instances = &p_instances;
_setup_environment(&render_data, true, Vector2(1, 1), false, Color()); _setup_environment(&render_data, true, Vector2(1, 1), false, Color());
@@ -1138,15 +1155,18 @@ void RenderForwardMobile::_render_particle_collider_heightfield(RID p_fb, const
RD::get_singleton()->draw_command_begin_label("Render Collider Heightfield"); RD::get_singleton()->draw_command_begin_label("Render Collider Heightfield");
_update_render_base_uniform_set(); _update_render_base_uniform_set();
scene_state.ubo.dual_paraboloid_side = 0;
scene_state.ubo.opaque_prepass_threshold = 0.0; RenderSceneDataRD scene_data;
scene_data.cam_projection = p_cam_projection;
scene_data.cam_transform = p_cam_transform;
scene_data.view_projection[0] = p_cam_projection;
scene_data.z_near = 0.0;
scene_data.z_far = p_cam_projection.get_z_far();
scene_data.dual_paraboloid_side = 0;
scene_data.opaque_prepass_threshold = 0.0;
RenderDataRD render_data; RenderDataRD render_data;
render_data.cam_projection = p_cam_projection; render_data.scene_data = &scene_data;
render_data.cam_transform = p_cam_transform;
render_data.view_projection[0] = p_cam_projection;
render_data.z_near = 0.0;
render_data.z_far = p_cam_projection.get_z_far();
render_data.instances = &p_instances; render_data.instances = &p_instances;
_setup_environment(&render_data, true, Vector2(1, 1), true, Color(), false, false); _setup_environment(&render_data, true, Vector2(1, 1), true, Color(), false, false);
@@ -1385,9 +1405,9 @@ void RenderForwardMobile::_fill_render_list(RenderListType p_render_list, const
} }
uint32_t lightmap_captures_used = 0; uint32_t lightmap_captures_used = 0;
Plane near_plane(-p_render_data->cam_transform.basis.get_column(Vector3::AXIS_Z), p_render_data->cam_transform.origin); Plane near_plane(-p_render_data->scene_data->cam_transform.basis.get_column(Vector3::AXIS_Z), p_render_data->scene_data->cam_transform.origin);
near_plane.d += p_render_data->cam_projection.get_z_near(); near_plane.d += p_render_data->scene_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(); float z_max = p_render_data->scene_data->cam_projection.get_z_far() - p_render_data->scene_data->cam_projection.get_z_near();
RenderList *rl = &render_list[p_render_list]; RenderList *rl = &render_list[p_render_list];
@@ -1466,13 +1486,13 @@ void RenderForwardMobile::_fill_render_list(RenderListType p_render_list, const
// LOD // LOD
if (p_render_data->screen_mesh_lod_threshold > 0.0 && mesh_storage->mesh_surface_has_lod(surf->surface)) { if (p_render_data->scene_data->screen_mesh_lod_threshold > 0.0 && mesh_storage->mesh_surface_has_lod(surf->surface)) {
//lod //lod
Vector3 lod_support_min = inst->transformed_aabb.get_support(-p_render_data->lod_camera_plane.normal); Vector3 lod_support_min = inst->transformed_aabb.get_support(-p_render_data->scene_data->lod_camera_plane.normal);
Vector3 lod_support_max = inst->transformed_aabb.get_support(p_render_data->lod_camera_plane.normal); Vector3 lod_support_max = inst->transformed_aabb.get_support(p_render_data->scene_data->lod_camera_plane.normal);
float distance_min = p_render_data->lod_camera_plane.distance_to(lod_support_min); float distance_min = p_render_data->scene_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_max = p_render_data->scene_data->lod_camera_plane.distance_to(lod_support_max);
float distance = 0.0; float distance = 0.0;
@@ -1485,12 +1505,12 @@ void RenderForwardMobile::_fill_render_list(RenderListType p_render_list, const
distance = -distance_max; distance = -distance_max;
} }
if (p_render_data->cam_orthogonal) { if (p_render_data->scene_data->cam_orthogonal) {
distance = 1.0; distance = 1.0;
} }
uint32_t indices; uint32_t indices;
surf->lod_index = mesh_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_mesh_lod_threshold, &indices); surf->lod_index = mesh_storage->mesh_surface_get_lod(surf->surface, inst->lod_model_scale * inst->lod_bias, distance * p_render_data->scene_data->lod_distance_multiplier, p_render_data->scene_data->screen_mesh_lod_threshold, &indices);
if (p_render_data->render_info) { if (p_render_data->render_info) {
indices = _indices_to_primitives(surf->primitive, indices); indices = _indices_to_primitives(surf->primitive, indices);
if (p_render_list == RENDER_LIST_OPAQUE) { //opaque if (p_render_list == RENDER_LIST_OPAQUE) { //opaque
@@ -1562,184 +1582,20 @@ void RenderForwardMobile::_fill_render_list(RenderListType p_render_list, const
} }
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) { 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 Ref<RenderSceneBuffersRD> rd = p_render_data->render_buffers;
RID env = is_environment(p_render_data->environment) ? p_render_data->environment : RID();
// This populates our UBO with main scene data that is pushed into set 1 RID reflection_probe_instance = p_render_data->reflection_probe.is_valid() ? reflection_probe_instance_get_probe(p_render_data->reflection_probe) : RID();
//Projection projection = p_render_data->cam_projection;
//projection.flip_y(); // Vulkan and modern APIs use Y-Down
Projection correction;
correction.set_depth_correction(p_flip_y);
Projection projection = correction * p_render_data->cam_projection;
//store camera into ubo
RendererRD::MaterialStorage::store_camera(projection, scene_state.ubo.projection_matrix);
RendererRD::MaterialStorage::store_camera(projection.inverse(), scene_state.ubo.inv_projection_matrix);
RendererRD::MaterialStorage::store_transform(p_render_data->cam_transform, scene_state.ubo.inv_view_matrix);
RendererRD::MaterialStorage::store_transform(p_render_data->cam_transform.affine_inverse(), scene_state.ubo.view_matrix);
for (uint32_t v = 0; v < p_render_data->view_count; v++) {
projection = correction * p_render_data->view_projection[v];
RendererRD::MaterialStorage::store_camera(projection, scene_state.ubo.projection_matrix_view[v]);
RendererRD::MaterialStorage::store_camera(projection.inverse(), scene_state.ubo.inv_projection_matrix_view[v]);
scene_state.ubo.eye_offset[v][0] = p_render_data->view_eye_offset[v].x;
scene_state.ubo.eye_offset[v][1] = p_render_data->view_eye_offset[v].y;
scene_state.ubo.eye_offset[v][2] = p_render_data->view_eye_offset[v].z;
scene_state.ubo.eye_offset[v][3] = 0.0;
}
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;
RendererRD::MaterialStorage::store_soft_shadow_kernel(directional_penumbra_shadow_kernel_get(), scene_state.ubo.directional_penumbra_shadow_kernel);
RendererRD::MaterialStorage::store_soft_shadow_kernel(directional_soft_shadow_kernel_get(), scene_state.ubo.directional_soft_shadow_kernel);
RendererRD::MaterialStorage::store_soft_shadow_kernel(penumbra_shadow_kernel_get(), scene_state.ubo.penumbra_shadow_kernel);
RendererRD::MaterialStorage::store_soft_shadow_kernel(soft_shadow_kernel_get(), scene_state.ubo.soft_shadow_kernel);
Size2 screen_pixel_size = Vector2(1.0, 1.0) / Size2(p_screen_size);
scene_state.ubo.screen_pixel_size[0] = screen_pixel_size.x;
scene_state.ubo.screen_pixel_size[1] = screen_pixel_size.y;
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;
}
{
Vector2 dss = directional_shadow_get_size();
scene_state.ubo.directional_shadow_pixel_size[0] = 1.0 / dss.x;
scene_state.ubo.directional_shadow_pixel_size[1] = 1.0 / dss.y;
}
//time global variables
scene_state.ubo.time = time;
if (get_debug_draw_mode() == RS::VIEWPORT_DEBUG_DRAW_UNSHADED) {
scene_state.ubo.use_ambient_light = true;
scene_state.ubo.ambient_light_color_energy[0] = 1;
scene_state.ubo.ambient_light_color_energy[1] = 1;
scene_state.ubo.ambient_light_color_energy[2] = 1;
scene_state.ubo.ambient_light_color_energy[3] = 1.0;
scene_state.ubo.use_ambient_cubemap = false;
scene_state.ubo.use_reflection_cubemap = false;
scene_state.ubo.ssao_enabled = false;
} 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_multiplier = environment_get_bg_energy_multiplier(p_render_data->environment);
scene_state.ubo.ambient_light_color_energy[3] = bg_energy_multiplier;
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_render_data->environment);
color = color.srgb_to_linear();
scene_state.ubo.ambient_light_color_energy[0] = color.r * bg_energy_multiplier;
scene_state.ubo.ambient_light_color_energy[1] = color.g * bg_energy_multiplier;
scene_state.ubo.ambient_light_color_energy[2] = color.b * bg_energy_multiplier;
scene_state.ubo.use_ambient_light = true;
scene_state.ubo.use_ambient_cubemap = false;
} else {
float energy = environment_get_ambient_light_energy(p_render_data->environment);
Color color = environment_get_ambient_light(p_render_data->environment);
color = color.srgb_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_render_data->environment);
sky_transform = sky_transform.inverse() * p_render_data->cam_transform.basis;
RendererRD::MaterialStorage::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;
scene_state.ubo.use_ambient_light = scene_state.ubo.use_ambient_cubemap || ambient_src == RS::ENV_AMBIENT_SOURCE_COLOR;
}
//specular
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_get_ssao_enabled(p_render_data->environment);
scene_state.ubo.ssao_ao_affect = environment_get_ssao_ao_channel_affect(p_render_data->environment);
scene_state.ubo.ssao_light_affect = environment_get_ssao_direct_light_affect(p_render_data->environment);
scene_state.ubo.fog_enabled = environment_get_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);
scene_state.ubo.fog_aerial_perspective = environment_get_fog_aerial_perspective(p_render_data->environment);
Color fog_color = environment_get_fog_light_color(p_render_data->environment).srgb_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_render_data->environment);
} else {
if (p_render_data->reflection_probe.is_valid() && RendererRD::LightStorage::get_singleton()->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;
Color clear_color = p_default_bg_color;
clear_color = clear_color.srgb_to_linear();
scene_state.ubo.ambient_light_color_energy[0] = clear_color.r;
scene_state.ubo.ambient_light_color_energy[1] = clear_color.g;
scene_state.ubo.ambient_light_color_energy[2] = clear_color.b;
scene_state.ubo.ambient_light_color_energy[3] = 1.0;
}
scene_state.ubo.use_ambient_cubemap = false;
scene_state.ubo.use_reflection_cubemap = false;
scene_state.ubo.ssao_enabled = false;
}
if (p_render_data->camera_attributes.is_valid()) {
scene_state.ubo.emissive_exposure_normalization = RSG::camera_attributes->camera_attributes_get_exposure_normalization_factor(p_render_data->camera_attributes);
scene_state.ubo.IBL_exposure_normalization = 1.0;
if (is_environment(p_render_data->environment)) {
RID sky_rid = environment_get_sky(p_render_data->environment);
if (sky_rid.is_valid()) {
float current_exposure = RSG::camera_attributes->camera_attributes_get_exposure_normalization_factor(p_render_data->camera_attributes) * environment_get_bg_intensity(p_render_data->environment) / _render_buffers_get_luminance_multiplier();
scene_state.ubo.IBL_exposure_normalization = current_exposure / MAX(0.001, sky.sky_get_baked_exposure(sky_rid));
}
}
} else if (scene_state.ubo.emissive_exposure_normalization > 0.0) {
// This branch is triggered when using render_material().
// Emissive is set outside the function, so don't set it.
// IBL isn't used don't set it.
} else {
scene_state.ubo.emissive_exposure_normalization = 1.0;
scene_state.ubo.IBL_exposure_normalization = 1.0;
}
scene_state.ubo.roughness_limiter_enabled = p_opaque_render_buffers && screen_space_roughness_limiter_is_active();
scene_state.ubo.roughness_limiter_amount = screen_space_roughness_limiter_get_amount();
scene_state.ubo.roughness_limiter_limit = screen_space_roughness_limiter_get_limit();
// May do this earlier in RenderSceneRenderRD::render_scene
if (p_index >= (int)scene_state.uniform_buffers.size()) { if (p_index >= (int)scene_state.uniform_buffers.size()) {
uint32_t from = scene_state.uniform_buffers.size(); uint32_t from = scene_state.uniform_buffers.size();
scene_state.uniform_buffers.resize(p_index + 1); scene_state.uniform_buffers.resize(p_index + 1);
render_pass_uniform_sets.resize(p_index + 1);
for (uint32_t i = from; i < scene_state.uniform_buffers.size(); i++) { for (uint32_t i = from; i < scene_state.uniform_buffers.size(); i++) {
scene_state.uniform_buffers[i] = RD::get_singleton()->uniform_buffer_create(sizeof(SceneState::UBO)); scene_state.uniform_buffers[i] = p_render_data->scene_data->create_uniform_buffer();
} }
} }
RD::get_singleton()->buffer_update(scene_state.uniform_buffers[p_index], 0, sizeof(SceneState::UBO), &scene_state.ubo, RD::BARRIER_MASK_RASTER);
p_render_data->scene_data->update_ubo(scene_state.uniform_buffers[p_index], get_debug_draw_mode(), env, reflection_probe_instance, p_render_data->camera_attributes, p_flip_y, p_pancake_shadows, p_screen_size, p_default_bg_color, _render_buffers_get_luminance_multiplier(), p_opaque_render_buffers);
} }
void RenderForwardMobile::_fill_element_info(RenderListType p_render_list, uint32_t p_offset, int32_t p_max_elements) { void RenderForwardMobile::_fill_element_info(RenderListType p_render_list, uint32_t p_offset, int32_t p_max_elements) {

View File

@@ -252,75 +252,6 @@ protected:
/* Scene state */ /* Scene state */
struct SceneState { struct SceneState {
// This struct is loaded into Set 1 - Binding 0, populated at start of rendering a frame, must match with shader code
struct UBO {
float projection_matrix[16];
float inv_projection_matrix[16];
float inv_view_matrix[16];
float view_matrix[16];
float projection_matrix_view[RendererSceneRender::MAX_RENDER_VIEWS][16];
float inv_projection_matrix_view[RendererSceneRender::MAX_RENDER_VIEWS][16];
float eye_offset[RendererSceneRender::MAX_RENDER_VIEWS][4];
float viewport_size[2];
float screen_pixel_size[2];
float directional_penumbra_shadow_kernel[128]; //32 vec4s
float directional_soft_shadow_kernel[128];
float penumbra_shadow_kernel[128];
float soft_shadow_kernel[128];
float ambient_light_color_energy[4];
float ambient_color_sky_mix;
uint32_t use_ambient_light;
uint32_t use_ambient_cubemap;
uint32_t use_reflection_cubemap;
float radiance_inverse_xform[12];
float shadow_atlas_pixel_size[2];
float directional_shadow_pixel_size[2];
uint32_t directional_light_count;
float dual_paraboloid_side;
float z_far;
float z_near;
uint32_t ssao_enabled;
float ssao_light_affect;
float ssao_ao_affect;
uint32_t roughness_limiter_enabled;
float roughness_limiter_amount;
float roughness_limiter_limit;
float opaque_prepass_threshold;
uint32_t roughness_limiter_pad;
// Fog
uint32_t fog_enabled;
float fog_density;
float fog_height;
float fog_height_density;
float fog_light_color[3];
float fog_sun_scatter;
float fog_aerial_perspective;
uint32_t material_uv2_mode;
float time;
float reflection_multiplier;
uint32_t pancake_shadows;
float emissive_exposure_normalization; // Needed to normalize emissive when using physical units.
float IBL_exposure_normalization; // Adjusts for baked exposure.
uint32_t pad3;
};
UBO ubo;
LocalVector<RID> uniform_buffers; LocalVector<RID> uniform_buffers;
// !BAS! We need to change lightmaps, we're not going to do this with a buffer but pushing the used lightmap in // !BAS! We need to change lightmaps, we're not going to do this with a buffer but pushing the used lightmap in

View File

@@ -32,7 +32,7 @@
#define SCENE_SHADER_FORWARD_MOBILE_H #define SCENE_SHADER_FORWARD_MOBILE_H
#include "servers/rendering/renderer_rd/renderer_scene_render_rd.h" #include "servers/rendering/renderer_rd/renderer_scene_render_rd.h"
#include "servers/rendering/renderer_rd/shaders/scene_forward_mobile.glsl.gen.h" #include "servers/rendering/renderer_rd/shaders/forward_mobile/scene_forward_mobile.glsl.gen.h"
namespace RendererSceneRenderImplementation { namespace RendererSceneRenderImplementation {

View File

@@ -1492,7 +1492,7 @@ void RendererSceneRenderRD::_render_buffers_copy_depth_texture(const RenderDataR
bool can_use_storage = _render_buffers_can_be_storage(); bool can_use_storage = _render_buffers_can_be_storage();
Size2i size = rb->get_internal_size(); Size2i size = rb->get_internal_size();
for (uint32_t v = 0; v < p_render_data->view_count; v++) { for (uint32_t v = 0; v < p_render_data->scene_data->view_count; v++) {
RID depth_texture = rb->get_depth_texture(v); RID depth_texture = rb->get_depth_texture(v);
RID depth_back_texture = rb->get_texture_slice(RB_SCOPE_BUFFERS, RB_TEX_BACK_DEPTH, v, 0); RID depth_back_texture = rb->get_texture_slice(RB_SCOPE_BUFFERS, RB_TEX_BACK_DEPTH, v, 0);
@@ -1544,9 +1544,9 @@ void RendererSceneRenderRD::_render_buffers_post_process_and_tonemap(const Rende
buffers.depth_texture = rb->get_depth_texture(i); buffers.depth_texture = rb->get_depth_texture(i);
// In stereo p_render_data->z_near and p_render_data->z_far can be offset for our combined frustrum // In stereo p_render_data->z_near and p_render_data->z_far can be offset for our combined frustrum
float z_near = p_render_data->view_projection[i].get_z_near(); float z_near = p_render_data->scene_data->view_projection[i].get_z_near();
float z_far = p_render_data->view_projection[i].get_z_far(); float z_far = p_render_data->scene_data->view_projection[i].get_z_far();
bokeh_dof->bokeh_dof_compute(buffers, p_render_data->camera_attributes, z_near, z_far, p_render_data->cam_orthogonal); bokeh_dof->bokeh_dof_compute(buffers, p_render_data->camera_attributes, z_near, z_far, p_render_data->scene_data->cam_orthogonal);
}; };
} else { } else {
// Set framebuffers. // Set framebuffers.
@@ -1567,9 +1567,9 @@ void RendererSceneRenderRD::_render_buffers_post_process_and_tonemap(const Rende
buffers.base_fb = FramebufferCacheRD::get_singleton()->get_cache(buffers.base_texture); // TODO move this into bokeh_dof_raster, we can do this internally buffers.base_fb = FramebufferCacheRD::get_singleton()->get_cache(buffers.base_texture); // TODO move this into bokeh_dof_raster, we can do this internally
// In stereo p_render_data->z_near and p_render_data->z_far can be offset for our combined frustrum // In stereo p_render_data->z_near and p_render_data->z_far can be offset for our combined frustrum
float z_near = p_render_data->view_projection[i].get_z_near(); float z_near = p_render_data->scene_data->view_projection[i].get_z_near();
float z_far = p_render_data->view_projection[i].get_z_far(); float z_far = p_render_data->scene_data->view_projection[i].get_z_far();
bokeh_dof->bokeh_dof_raster(buffers, p_render_data->camera_attributes, z_near, z_far, p_render_data->cam_orthogonal); bokeh_dof->bokeh_dof_raster(buffers, p_render_data->camera_attributes, z_near, z_far, p_render_data->scene_data->cam_orthogonal);
} }
} }
RD::get_singleton()->draw_command_end_label(); RD::get_singleton()->draw_command_end_label();
@@ -2901,8 +2901,8 @@ void RendererSceneRenderRD::_pre_opaque_render(RenderDataRD *p_render_data, bool
render_state.shadows.clear(); render_state.shadows.clear();
render_state.directional_shadows.clear(); render_state.directional_shadows.clear();
Plane camera_plane(-p_render_data->cam_transform.basis.get_column(Vector3::AXIS_Z), p_render_data->cam_transform.origin); Plane camera_plane(-p_render_data->scene_data->cam_transform.basis.get_column(Vector3::AXIS_Z), p_render_data->scene_data->cam_transform.origin);
float lod_distance_multiplier = p_render_data->cam_projection.get_lod_multiplier(); float lod_distance_multiplier = p_render_data->scene_data->cam_projection.get_lod_multiplier();
{ {
for (int i = 0; i < render_state.render_shadow_count; i++) { for (int i = 0; i < render_state.render_shadow_count; i++) {
LightInstance *li = light_instance_owner.get_or_null(render_state.render_shadows[i].light); LightInstance *li = light_instance_owner.get_or_null(render_state.render_shadows[i].light);
@@ -2918,7 +2918,7 @@ void RendererSceneRenderRD::_pre_opaque_render(RenderDataRD *p_render_data, bool
//cube shadows are rendered in their own way //cube shadows are rendered in their own way
for (uint32_t i = 0; i < render_state.cube_shadows.size(); i++) { for (uint32_t i = 0; i < render_state.cube_shadows.size(); i++) {
_render_shadow_pass(render_state.render_shadows[render_state.cube_shadows[i]].light, p_render_data->shadow_atlas, render_state.render_shadows[render_state.cube_shadows[i]].pass, render_state.render_shadows[render_state.cube_shadows[i]].instances, camera_plane, lod_distance_multiplier, p_render_data->screen_mesh_lod_threshold, true, true, true, p_render_data->render_info); _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->scene_data->screen_mesh_lod_threshold, true, true, true, p_render_data->render_info);
} }
if (render_state.directional_shadows.size()) { if (render_state.directional_shadows.size()) {
@@ -2948,11 +2948,11 @@ void RendererSceneRenderRD::_pre_opaque_render(RenderDataRD *p_render_data, bool
//render directional shadows //render directional shadows
for (uint32_t i = 0; i < render_state.directional_shadows.size(); i++) { for (uint32_t i = 0; i < render_state.directional_shadows.size(); i++) {
_render_shadow_pass(render_state.render_shadows[render_state.directional_shadows[i]].light, p_render_data->shadow_atlas, render_state.render_shadows[render_state.directional_shadows[i]].pass, render_state.render_shadows[render_state.directional_shadows[i]].instances, camera_plane, lod_distance_multiplier, p_render_data->screen_mesh_lod_threshold, false, i == render_state.directional_shadows.size() - 1, false, p_render_data->render_info); _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->scene_data->screen_mesh_lod_threshold, false, i == render_state.directional_shadows.size() - 1, false, p_render_data->render_info);
} }
//render positional shadows //render positional shadows
for (uint32_t i = 0; i < render_state.shadows.size(); i++) { for (uint32_t i = 0; i < render_state.shadows.size(); i++) {
_render_shadow_pass(render_state.render_shadows[render_state.shadows[i]].light, p_render_data->shadow_atlas, render_state.render_shadows[render_state.shadows[i]].pass, render_state.render_shadows[render_state.shadows[i]].instances, camera_plane, lod_distance_multiplier, p_render_data->screen_mesh_lod_threshold, i == 0, i == render_state.shadows.size() - 1, true, p_render_data->render_info); _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->scene_data->screen_mesh_lod_threshold, i == 0, i == render_state.shadows.size() - 1, true, p_render_data->render_info);
} }
_render_shadow_process(); _render_shadow_process();
@@ -2960,7 +2960,7 @@ void RendererSceneRenderRD::_pre_opaque_render(RenderDataRD *p_render_data, bool
//start GI //start GI
if (render_gi) { if (render_gi) {
gi.process_gi(p_render_data->render_buffers, p_normal_roughness_slices, p_voxel_gi_buffer, p_render_data->environment, p_render_data->view_count, p_render_data->view_projection, p_render_data->view_eye_offset, p_render_data->cam_transform, *p_render_data->voxel_gi_instances); gi.process_gi(p_render_data->render_buffers, p_normal_roughness_slices, p_voxel_gi_buffer, p_render_data->environment, p_render_data->scene_data->view_count, p_render_data->scene_data->view_projection, p_render_data->scene_data->view_eye_offset, p_render_data->scene_data->cam_transform, *p_render_data->voxel_gi_instances);
} }
//Do shadow rendering (in parallel with GI) //Do shadow rendering (in parallel with GI)
@@ -2999,17 +2999,17 @@ void RendererSceneRenderRD::_pre_opaque_render(RenderDataRD *p_render_data, bool
} }
RID depth_texture = rb->get_depth_texture(); RID depth_texture = rb->get_depth_texture();
ss_effects->downsample_depth(depth_texture, rb->ss_effects.linear_depth_slices, ssao_quality, ssil_quality, invalidate_uniform_set, ssao_half_size, ssil_half_size, size, p_render_data->cam_projection); ss_effects->downsample_depth(depth_texture, rb->ss_effects.linear_depth_slices, ssao_quality, ssil_quality, invalidate_uniform_set, ssao_half_size, ssil_half_size, size, p_render_data->scene_data->cam_projection);
} }
if (p_use_ssao) { if (p_use_ssao) {
// TODO make these proper stereo // TODO make these proper stereo
_process_ssao(p_render_data->render_buffers, p_render_data->environment, p_normal_roughness_slices[0], p_render_data->cam_projection); _process_ssao(p_render_data->render_buffers, p_render_data->environment, p_normal_roughness_slices[0], p_render_data->scene_data->cam_projection);
} }
if (p_use_ssil) { if (p_use_ssil) {
// TODO make these proper stereo // TODO make these proper stereo
_process_ssil(p_render_data->render_buffers, p_render_data->environment, p_normal_roughness_slices[0], p_render_data->cam_projection, p_render_data->cam_transform); _process_ssil(p_render_data->render_buffers, p_render_data->environment, p_normal_roughness_slices[0], p_render_data->scene_data->cam_projection, p_render_data->scene_data->cam_transform);
} }
} }
@@ -3017,7 +3017,7 @@ void RendererSceneRenderRD::_pre_opaque_render(RenderDataRD *p_render_data, bool
RD::get_singleton()->barrier(RD::BARRIER_MASK_ALL, RD::BARRIER_MASK_ALL); RD::get_singleton()->barrier(RD::BARRIER_MASK_ALL, RD::BARRIER_MASK_ALL);
if (current_cluster_builder) { if (current_cluster_builder) {
current_cluster_builder->begin(p_render_data->cam_transform, p_render_data->cam_projection, !p_render_data->reflection_probe.is_valid()); current_cluster_builder->begin(p_render_data->scene_data->cam_transform, p_render_data->scene_data->cam_projection, !p_render_data->reflection_probe.is_valid());
} }
bool using_shadows = true; bool using_shadows = true;
@@ -3028,13 +3028,13 @@ void RendererSceneRenderRD::_pre_opaque_render(RenderDataRD *p_render_data, bool
} }
} else { } else {
//do not render reflections when rendering a reflection probe //do not render reflections when rendering a reflection probe
_setup_reflections(p_render_data, *p_render_data->reflection_probes, p_render_data->cam_transform.affine_inverse(), p_render_data->environment); _setup_reflections(p_render_data, *p_render_data->reflection_probes, p_render_data->scene_data->cam_transform.affine_inverse(), p_render_data->environment);
} }
uint32_t directional_light_count = 0; uint32_t directional_light_count = 0;
uint32_t positional_light_count = 0; uint32_t positional_light_count = 0;
_setup_lights(p_render_data, *p_render_data->lights, p_render_data->cam_transform, p_render_data->shadow_atlas, using_shadows, directional_light_count, positional_light_count, p_render_data->directional_light_soft_shadows); _setup_lights(p_render_data, *p_render_data->lights, p_render_data->scene_data->cam_transform, p_render_data->shadow_atlas, using_shadows, directional_light_count, positional_light_count, p_render_data->directional_light_soft_shadows);
_setup_decals(*p_render_data->decals, p_render_data->cam_transform.affine_inverse()); _setup_decals(*p_render_data->decals, p_render_data->scene_data->cam_transform.affine_inverse());
p_render_data->directional_light_count = directional_light_count; p_render_data->directional_light_count = directional_light_count;
@@ -3051,7 +3051,7 @@ void RendererSceneRenderRD::_pre_opaque_render(RenderDataRD *p_render_data, bool
} }
} }
if (is_volumetric_supported()) { if (is_volumetric_supported()) {
_update_volumetric_fog(p_render_data->render_buffers, p_render_data->environment, p_render_data->cam_projection, p_render_data->cam_transform, p_render_data->prev_cam_transform.affine_inverse(), p_render_data->shadow_atlas, directional_light_count, directional_shadows, positional_light_count, render_state.voxel_gi_count, *p_render_data->fog_volumes); _update_volumetric_fog(p_render_data->render_buffers, p_render_data->environment, p_render_data->scene_data->cam_projection, p_render_data->scene_data->cam_transform, p_render_data->scene_data->prev_cam_transform.affine_inverse(), p_render_data->shadow_atlas, directional_light_count, directional_shadows, positional_light_count, render_state.voxel_gi_count, *p_render_data->fog_volumes);
} }
} }
} }
@@ -3066,33 +3066,62 @@ void RendererSceneRenderRD::render_scene(const Ref<RenderSceneBuffers> &p_render
ERR_FAIL_COND(rb.is_null()); ERR_FAIL_COND(rb.is_null());
} }
// setup scene data
RenderSceneDataRD scene_data;
{
// Our first camera is used by default
scene_data.cam_transform = p_camera_data->main_transform;
scene_data.cam_projection = p_camera_data->main_projection;
scene_data.cam_orthogonal = p_camera_data->is_orthogonal;
scene_data.taa_jitter = p_camera_data->taa_jitter;
scene_data.view_count = p_camera_data->view_count;
for (uint32_t v = 0; v < p_camera_data->view_count; v++) {
scene_data.view_eye_offset[v] = p_camera_data->view_offset[v].origin;
scene_data.view_projection[v] = p_camera_data->view_projection[v];
}
scene_data.prev_cam_transform = p_prev_camera_data->main_transform;
scene_data.prev_cam_projection = p_prev_camera_data->main_projection;
scene_data.prev_taa_jitter = p_prev_camera_data->taa_jitter;
for (uint32_t v = 0; v < p_camera_data->view_count; v++) {
scene_data.prev_view_projection[v] = p_prev_camera_data->view_projection[v];
}
scene_data.z_near = p_camera_data->main_projection.get_z_near();
scene_data.z_far = p_camera_data->main_projection.get_z_far();
// this should be the same for all cameras..
scene_data.lod_distance_multiplier = p_camera_data->main_projection.get_lod_multiplier();
scene_data.lod_camera_plane = Plane(-p_camera_data->main_transform.basis.get_column(Vector3::AXIS_Z), p_camera_data->main_transform.get_origin());
if (get_debug_draw_mode() == RS::VIEWPORT_DEBUG_DRAW_DISABLE_LOD) {
scene_data.screen_mesh_lod_threshold = 0.0;
} else {
scene_data.screen_mesh_lod_threshold = p_screen_mesh_lod_threshold;
}
if (p_shadow_atlas.is_valid()) {
Vector2 sas = shadow_atlas_get_size(p_shadow_atlas);
scene_data.shadow_atlas_pixel_size.x = 1.0 / sas.x;
scene_data.shadow_atlas_pixel_size.y = 1.0 / sas.y;
}
{
Vector2 dss = directional_shadow_get_size();
scene_data.directional_shadow_pixel_size.x = 1.0 / dss.x;
scene_data.directional_shadow_pixel_size.y = 1.0 / dss.y;
}
scene_data.time = time;
scene_data.time_step = time_step;
}
//assign render data //assign render data
RenderDataRD render_data; RenderDataRD render_data;
{ {
render_data.render_buffers = rb; render_data.render_buffers = rb;
render_data.scene_data = &scene_data;
// Our first camera is used by default
render_data.cam_transform = p_camera_data->main_transform;
render_data.cam_projection = p_camera_data->main_projection;
render_data.cam_orthogonal = p_camera_data->is_orthogonal;
render_data.taa_jitter = p_camera_data->taa_jitter;
render_data.view_count = p_camera_data->view_count;
for (uint32_t v = 0; v < p_camera_data->view_count; v++) {
render_data.view_eye_offset[v] = p_camera_data->view_offset[v].origin;
render_data.view_projection[v] = p_camera_data->view_projection[v];
}
render_data.prev_cam_transform = p_prev_camera_data->main_transform;
render_data.prev_cam_projection = p_prev_camera_data->main_projection;
render_data.prev_taa_jitter = p_prev_camera_data->taa_jitter;
for (uint32_t v = 0; v < p_camera_data->view_count; v++) {
render_data.prev_view_projection[v] = p_prev_camera_data->view_projection[v];
}
render_data.z_near = p_camera_data->main_projection.get_z_near();
render_data.z_far = p_camera_data->main_projection.get_z_far();
render_data.instances = &p_instances; render_data.instances = &p_instances;
render_data.lights = &p_lights; render_data.lights = &p_lights;
@@ -3108,16 +3137,6 @@ void RendererSceneRenderRD::render_scene(const Ref<RenderSceneBuffers> &p_render
render_data.reflection_probe = p_reflection_probe; render_data.reflection_probe = p_reflection_probe;
render_data.reflection_probe_pass = p_reflection_probe_pass; render_data.reflection_probe_pass = p_reflection_probe_pass;
// this should be the same for all cameras..
render_data.lod_distance_multiplier = p_camera_data->main_projection.get_lod_multiplier();
render_data.lod_camera_plane = Plane(-p_camera_data->main_transform.basis.get_column(Vector3::AXIS_Z), p_camera_data->main_transform.get_origin());
if (get_debug_draw_mode() == RS::VIEWPORT_DEBUG_DRAW_DISABLE_LOD) {
render_data.screen_mesh_lod_threshold = 0.0;
} else {
render_data.screen_mesh_lod_threshold = p_screen_mesh_lod_threshold;
}
render_state.render_shadows = p_render_shadows; render_state.render_shadows = p_render_shadows;
render_state.render_shadow_count = p_render_shadow_count; render_state.render_shadow_count = p_render_shadow_count;
render_state.render_sdfgi_regions = p_render_sdfgi_regions; render_state.render_sdfgi_regions = p_render_sdfgi_regions;
@@ -3134,7 +3153,7 @@ void RendererSceneRenderRD::render_scene(const Ref<RenderSceneBuffers> &p_render
render_data.voxel_gi_instances = &empty; render_data.voxel_gi_instances = &empty;
} }
//sdfgi first // sdfgi first
if (rb.is_valid() && rb->has_custom_data(RB_SCOPE_SDFGI)) { if (rb.is_valid() && rb->has_custom_data(RB_SCOPE_SDFGI)) {
Ref<RendererRD::GI::SDFGI> sdfgi = rb->get_custom_data(RB_SCOPE_SDFGI); Ref<RendererRD::GI::SDFGI> sdfgi = rb->get_custom_data(RB_SCOPE_SDFGI);
float exposure_normalization = 1.0; float exposure_normalization = 1.0;
@@ -3191,12 +3210,12 @@ void RendererSceneRenderRD::render_scene(const Ref<RenderSceneBuffers> &p_render
Ref<RendererRD::GI::SDFGI> sdfgi = rb->get_custom_data(RB_SCOPE_SDFGI); Ref<RendererRD::GI::SDFGI> sdfgi = rb->get_custom_data(RB_SCOPE_SDFGI);
if (sdfgi.is_valid()) { if (sdfgi.is_valid()) {
sdfgi->update_cascades(); sdfgi->update_cascades();
sdfgi->pre_process_gi(render_data.cam_transform, &render_data, this); sdfgi->pre_process_gi(scene_data.cam_transform, &render_data, this);
sdfgi->update_light(); sdfgi->update_light();
} }
} }
gi.setup_voxel_gi_instances(&render_data, render_data.render_buffers, render_data.cam_transform, *render_data.voxel_gi_instances, render_state.voxel_gi_count, this); gi.setup_voxel_gi_instances(&render_data, render_data.render_buffers, scene_data.cam_transform, *render_data.voxel_gi_instances, render_state.voxel_gi_count, this);
} }
render_state.depth_prepass_used = false; render_state.depth_prepass_used = false;
@@ -3246,7 +3265,7 @@ void RendererSceneRenderRD::render_scene(const Ref<RenderSceneBuffers> &p_render
view_rids.push_back(rb->get_internal_texture(v)); view_rids.push_back(rb->get_internal_texture(v));
} }
sdfgi->debug_draw(render_data.view_count, render_data.view_projection, render_data.cam_transform, size.x, size.y, rb->get_render_target(), source_texture, view_rids); sdfgi->debug_draw(scene_data.view_count, scene_data.view_projection, scene_data.cam_transform, size.x, size.y, rb->get_render_target(), source_texture, view_rids);
} }
} }
} }

View File

@@ -46,30 +46,14 @@
#include "servers/rendering/renderer_rd/environment/sky.h" #include "servers/rendering/renderer_rd/environment/sky.h"
#include "servers/rendering/renderer_rd/framebuffer_cache_rd.h" #include "servers/rendering/renderer_rd/framebuffer_cache_rd.h"
#include "servers/rendering/renderer_rd/storage_rd/render_scene_buffers_rd.h" #include "servers/rendering/renderer_rd/storage_rd/render_scene_buffers_rd.h"
#include "servers/rendering/renderer_rd/storage_rd/render_scene_data_rd.h"
#include "servers/rendering/renderer_scene.h" #include "servers/rendering/renderer_scene.h"
#include "servers/rendering/renderer_scene_render.h" #include "servers/rendering/renderer_scene_render.h"
#include "servers/rendering/rendering_device.h" #include "servers/rendering/rendering_device.h"
struct RenderDataRD { struct RenderDataRD {
Ref<RenderSceneBuffersRD> render_buffers; Ref<RenderSceneBuffersRD> render_buffers;
RenderSceneDataRD *scene_data;
Transform3D cam_transform;
Projection cam_projection;
Vector2 taa_jitter;
bool cam_orthogonal = false;
// For stereo rendering
uint32_t view_count = 1;
Vector3 view_eye_offset[RendererSceneRender::MAX_RENDER_VIEWS];
Projection view_projection[RendererSceneRender::MAX_RENDER_VIEWS];
Transform3D prev_cam_transform;
Projection prev_cam_projection;
Vector2 prev_taa_jitter;
Projection prev_view_projection[RendererSceneRender::MAX_RENDER_VIEWS];
float z_near = 0.0;
float z_far = 0.0;
const PagedArray<RenderGeometryInstance *> *instances = nullptr; const PagedArray<RenderGeometryInstance *> *instances = nullptr;
const PagedArray<RID> *lights = nullptr; const PagedArray<RID> *lights = nullptr;
@@ -85,10 +69,6 @@ struct RenderDataRD {
RID reflection_probe; RID reflection_probe;
int reflection_probe_pass = 0; int reflection_probe_pass = 0;
float lod_distance_multiplier = 0.0;
Plane lod_camera_plane;
float screen_mesh_lod_threshold = 0.0;
RID cluster_buffer; RID cluster_buffer;
uint32_t cluster_size = 0; uint32_t cluster_size = 0;
uint32_t cluster_max_elements = 0; uint32_t cluster_max_elements = 0;
@@ -598,13 +578,6 @@ private:
uint64_t scene_pass = 0; uint64_t scene_pass = 0;
uint64_t shadow_atlas_realloc_tolerance_msec = 500; uint64_t shadow_atlas_realloc_tolerance_msec = 500;
/* !BAS! is this used anywhere?
struct SDFGICosineNeighbour {
uint32_t neighbour;
float weight;
};
*/
uint32_t max_cluster_elements = 512; uint32_t max_cluster_elements = 512;
void _render_shadow_pass(RID p_light, RID p_shadow_atlas, int p_pass, const PagedArray<RenderGeometryInstance *> &p_instances, const Plane &p_camera_plane = Plane(), float p_lod_distance_multiplier = 0, float p_screen_mesh_lod_threshold = 0.0, bool p_open_pass = true, bool p_close_pass = true, bool p_clear_region = true, RendererScene::RenderInfo *p_render_info = nullptr); void _render_shadow_pass(RID p_light, RID p_shadow_atlas, int p_pass, const PagedArray<RenderGeometryInstance *> &p_instances, const Plane &p_camera_plane = Plane(), float p_lod_distance_multiplier = 0, float p_screen_mesh_lod_threshold = 0.0, bool p_open_pass = true, bool p_close_pass = true, bool p_clear_region = true, RendererScene::RenderInfo *p_render_info = nullptr);
@@ -627,6 +600,10 @@ public:
RendererRD::GI *get_gi() { return &gi; } RendererRD::GI *get_gi() { return &gi; }
/* SKY */
RendererRD::SkyRD *get_sky() { return &sky; }
/* SHADOW ATLAS API */ /* SHADOW ATLAS API */
virtual RID shadow_atlas_create() override; virtual RID shadow_atlas_create() override;

View File

@@ -18,3 +18,5 @@ if "RD_GLSL" in env["BUILDERS"]:
SConscript("effects/SCsub") SConscript("effects/SCsub")
SConscript("environment/SCsub") SConscript("environment/SCsub")
SConscript("forward_clustered/SCsub")
SConscript("forward_mobile/SCsub")

View File

@@ -0,0 +1,17 @@
#!/usr/bin/env python
Import("env")
if "RD_GLSL" in env["BUILDERS"]:
# find all include files
gl_include_files = [str(f) for f in Glob("*_inc.glsl")]
# find all shader code(all glsl files excluding our include files)
glsl_files = [str(f) for f in Glob("*.glsl") if str(f) not in gl_include_files]
# make sure we recompile shaders if include files change
env.Depends([f + ".gen.h" for f in glsl_files], gl_include_files + ["#glsl_builders.py"])
# compile shaders
for glsl_file in glsl_files:
env.RD_GLSL(glsl_file)

View File

@@ -326,10 +326,6 @@ void vertex_shader(in uint instance_index, in bool is_multimesh, in uint multime
vertex_interp = vertex; vertex_interp = vertex;
#ifdef MOTION_VECTORS
screen_pos = projection_matrix * vec4(vertex_interp, 1.0);
#endif
#ifdef NORMAL_USED #ifdef NORMAL_USED
normal_interp = normal; normal_interp = normal;
#endif #endif
@@ -367,6 +363,10 @@ void vertex_shader(in uint instance_index, in bool is_multimesh, in uint multime
gl_Position = projection_matrix * vec4(vertex_interp, 1.0); gl_Position = projection_matrix * vec4(vertex_interp, 1.0);
#endif #endif
#ifdef MOTION_VECTORS
screen_pos = gl_Position;
#endif
#ifdef MODE_RENDER_DEPTH #ifdef MODE_RENDER_DEPTH
if (scene_data.pancake_shadows) { if (scene_data.pancake_shadows) {
if (gl_Position.z <= 0.00001) { if (gl_Position.z <= 0.00001) {
@@ -553,7 +553,7 @@ layout(location = 0) out vec4 frag_color;
layout(location = 2) out vec2 motion_vector; layout(location = 2) out vec2 motion_vector;
#endif #endif
#include "scene_forward_aa_inc.glsl" #include "../scene_forward_aa_inc.glsl"
#if !defined(MODE_RENDER_DEPTH) && !defined(MODE_UNSHADED) #if !defined(MODE_RENDER_DEPTH) && !defined(MODE_UNSHADED)
@@ -562,20 +562,20 @@ layout(location = 2) out vec2 motion_vector;
#define SPECULAR_SCHLICK_GGX #define SPECULAR_SCHLICK_GGX
#endif #endif
#include "scene_forward_lights_inc.glsl" #include "../scene_forward_lights_inc.glsl"
#include "scene_forward_gi_inc.glsl" #include "../scene_forward_gi_inc.glsl"
#endif //!defined(MODE_RENDER_DEPTH) && !defined(MODE_UNSHADED) #endif //!defined(MODE_RENDER_DEPTH) && !defined(MODE_UNSHADED)
#ifndef MODE_RENDER_DEPTH #ifndef MODE_RENDER_DEPTH
vec4 volumetric_fog_process(vec2 screen_uv, float z) { vec4 volumetric_fog_process(vec2 screen_uv, float z) {
vec3 fog_pos = vec3(screen_uv, z * scene_data_block.data.volumetric_fog_inv_length); vec3 fog_pos = vec3(screen_uv, z * implementation_data.volumetric_fog_inv_length);
if (fog_pos.z < 0.0) { if (fog_pos.z < 0.0) {
return vec4(0.0); return vec4(0.0);
} else if (fog_pos.z < 1.0) { } else if (fog_pos.z < 1.0) {
fog_pos.z = pow(fog_pos.z, scene_data_block.data.volumetric_fog_detail_spread); fog_pos.z = pow(fog_pos.z, implementation_data.volumetric_fog_detail_spread);
} }
return texture(sampler3D(volumetric_fog_texture, material_samplers[SAMPLER_LINEAR_CLAMP]), fog_pos); return texture(sampler3D(volumetric_fog_texture, material_samplers[SAMPLER_LINEAR_CLAMP]), fog_pos);
@@ -821,7 +821,7 @@ void fragment_shader(in SceneData scene_data) {
fog = fog_process(vertex); fog = fog_process(vertex);
} }
if (scene_data.volumetric_fog_enabled) { if (implementation_data.volumetric_fog_enabled) {
vec4 volumetric_fog = volumetric_fog_process(screen_uv, -vertex.z); vec4 volumetric_fog = volumetric_fog_process(screen_uv, -vertex.z);
if (scene_data.fog_enabled) { if (scene_data.fog_enabled) {
//must use the full blending equation here to blend fogs //must use the full blending equation here to blend fogs
@@ -849,8 +849,8 @@ void fragment_shader(in SceneData scene_data) {
#ifndef MODE_RENDER_DEPTH #ifndef MODE_RENDER_DEPTH
uvec2 cluster_pos = uvec2(gl_FragCoord.xy) >> scene_data.cluster_shift; uvec2 cluster_pos = uvec2(gl_FragCoord.xy) >> implementation_data.cluster_shift;
uint cluster_offset = (scene_data.cluster_width * cluster_pos.y + cluster_pos.x) * (scene_data.max_cluster_element_count_div_32 + 32); uint cluster_offset = (implementation_data.cluster_width * cluster_pos.y + cluster_pos.x) * (implementation_data.max_cluster_element_count_div_32 + 32);
uint cluster_z = uint(clamp((-vertex.z / scene_data.z_far) * 32.0, 0.0, 31.0)); uint cluster_z = uint(clamp((-vertex.z / scene_data.z_far) * 32.0, 0.0, 31.0));
@@ -860,14 +860,14 @@ void fragment_shader(in SceneData scene_data) {
{ // process decals { // process decals
uint cluster_decal_offset = cluster_offset + scene_data.cluster_type_size * 2; uint cluster_decal_offset = cluster_offset + implementation_data.cluster_type_size * 2;
uint item_min; uint item_min;
uint item_max; uint item_max;
uint item_from; uint item_from;
uint item_to; uint item_to;
cluster_get_item_range(cluster_decal_offset + scene_data.max_cluster_element_count_div_32 + cluster_z, item_min, item_max, item_from, item_to); cluster_get_item_range(cluster_decal_offset + implementation_data.max_cluster_element_count_div_32 + cluster_z, item_min, item_max, item_from, item_to);
#ifdef USE_SUBGROUPS #ifdef USE_SUBGROUPS
item_from = subgroupBroadcastFirst(subgroupMin(item_from)); item_from = subgroupBroadcastFirst(subgroupMin(item_from));
@@ -1256,7 +1256,7 @@ void fragment_shader(in SceneData scene_data) {
vec2 coord; vec2 coord;
if (scene_data.gi_upscale_for_msaa) { if (implementation_data.gi_upscale_for_msaa) {
vec2 base_coord = screen_uv; vec2 base_coord = screen_uv;
vec2 closest_coord = base_coord; vec2 closest_coord = base_coord;
#ifdef USE_MULTIVIEW #ifdef USE_MULTIVIEW
@@ -1298,10 +1298,10 @@ void fragment_shader(in SceneData scene_data) {
} }
#endif // !USE_LIGHTMAP #endif // !USE_LIGHTMAP
if (bool(scene_data.ss_effects_flags & SCREEN_SPACE_EFFECTS_FLAGS_USE_SSAO)) { if (bool(implementation_data.ss_effects_flags & SCREEN_SPACE_EFFECTS_FLAGS_USE_SSAO)) {
float ssao = texture(sampler2D(ao_buffer, material_samplers[SAMPLER_LINEAR_CLAMP]), screen_uv).r; float ssao = texture(sampler2D(ao_buffer, material_samplers[SAMPLER_LINEAR_CLAMP]), screen_uv).r;
ao = min(ao, ssao); ao = min(ao, ssao);
ao_light_affect = mix(ao_light_affect, max(ao_light_affect, scene_data.ssao_light_affect), scene_data.ssao_ao_affect); ao_light_affect = mix(ao_light_affect, max(ao_light_affect, implementation_data.ssao_light_affect), implementation_data.ssao_ao_affect);
} }
{ // process reflections { // process reflections
@@ -1309,14 +1309,14 @@ void fragment_shader(in SceneData scene_data) {
vec4 reflection_accum = vec4(0.0, 0.0, 0.0, 0.0); vec4 reflection_accum = vec4(0.0, 0.0, 0.0, 0.0);
vec4 ambient_accum = vec4(0.0, 0.0, 0.0, 0.0); vec4 ambient_accum = vec4(0.0, 0.0, 0.0, 0.0);
uint cluster_reflection_offset = cluster_offset + scene_data.cluster_type_size * 3; uint cluster_reflection_offset = cluster_offset + implementation_data.cluster_type_size * 3;
uint item_min; uint item_min;
uint item_max; uint item_max;
uint item_from; uint item_from;
uint item_to; uint item_to;
cluster_get_item_range(cluster_reflection_offset + scene_data.max_cluster_element_count_div_32 + cluster_z, item_min, item_max, item_from, item_to); cluster_get_item_range(cluster_reflection_offset + implementation_data.max_cluster_element_count_div_32 + cluster_z, item_min, item_max, item_from, item_to);
#ifdef USE_SUBGROUPS #ifdef USE_SUBGROUPS
item_from = subgroupBroadcastFirst(subgroupMin(item_from)); item_from = subgroupBroadcastFirst(subgroupMin(item_from));
@@ -1380,7 +1380,7 @@ void fragment_shader(in SceneData scene_data) {
// convert ao to direct light ao // convert ao to direct light ao
ao = mix(1.0, ao, ao_light_affect); ao = mix(1.0, ao, ao_light_affect);
if (bool(scene_data.ss_effects_flags & SCREEN_SPACE_EFFECTS_FLAGS_USE_SSIL)) { if (bool(implementation_data.ss_effects_flags & SCREEN_SPACE_EFFECTS_FLAGS_USE_SSIL)) {
vec4 ssil = textureLod(sampler2D(ssil_buffer, material_samplers[SAMPLER_LINEAR_CLAMP]), screen_uv, 0.0); vec4 ssil = textureLod(sampler2D(ssil_buffer, material_samplers[SAMPLER_LINEAR_CLAMP]), screen_uv, 0.0);
ambient_light *= 1.0 - ssil.a; ambient_light *= 1.0 - ssil.a;
ambient_light += ssil.rgb * albedo.rgb; ambient_light += ssil.rgb * albedo.rgb;
@@ -1748,7 +1748,7 @@ void fragment_shader(in SceneData scene_data) {
uint item_from; uint item_from;
uint item_to; uint item_to;
cluster_get_item_range(cluster_omni_offset + scene_data.max_cluster_element_count_div_32 + cluster_z, item_min, item_max, item_from, item_to); cluster_get_item_range(cluster_omni_offset + implementation_data.max_cluster_element_count_div_32 + cluster_z, item_min, item_max, item_from, item_to);
#ifdef USE_SUBGROUPS #ifdef USE_SUBGROUPS
item_from = subgroupBroadcastFirst(subgroupMin(item_from)); item_from = subgroupBroadcastFirst(subgroupMin(item_from));
@@ -1812,14 +1812,14 @@ void fragment_shader(in SceneData scene_data) {
{ //spot lights { //spot lights
uint cluster_spot_offset = cluster_offset + scene_data.cluster_type_size; uint cluster_spot_offset = cluster_offset + implementation_data.cluster_type_size;
uint item_min; uint item_min;
uint item_max; uint item_max;
uint item_from; uint item_from;
uint item_to; uint item_to;
cluster_get_item_range(cluster_spot_offset + scene_data.max_cluster_element_count_div_32 + cluster_z, item_min, item_max, item_from, item_to); cluster_get_item_range(cluster_spot_offset + implementation_data.max_cluster_element_count_div_32 + cluster_z, item_min, item_max, item_from, item_to);
#ifdef USE_SUBGROUPS #ifdef USE_SUBGROUPS
item_from = subgroupBroadcastFirst(subgroupMin(item_from)); item_from = subgroupBroadcastFirst(subgroupMin(item_from));
@@ -1909,8 +1909,8 @@ void fragment_shader(in SceneData scene_data) {
#ifdef MODE_RENDER_SDF #ifdef MODE_RENDER_SDF
{ {
vec3 local_pos = (scene_data.sdf_to_bounds * vec4(vertex, 1.0)).xyz; vec3 local_pos = (implementation_data.sdf_to_bounds * vec4(vertex, 1.0)).xyz;
ivec3 grid_pos = scene_data.sdf_offset + ivec3(local_pos * vec3(scene_data.sdf_size)); ivec3 grid_pos = implementation_data.sdf_offset + ivec3(local_pos * vec3(implementation_data.sdf_size));
uint albedo16 = 0x1; //solid flag uint albedo16 = 0x1; //solid flag
albedo16 |= clamp(uint(albedo.r * 31.0), 0, 31) << 11; albedo16 |= clamp(uint(albedo.r * 31.0), 0, 31) << 11;

View File

@@ -17,8 +17,9 @@
#extension GL_EXT_multiview : enable #extension GL_EXT_multiview : enable
#endif #endif
#include "cluster_data_inc.glsl" #include "../cluster_data_inc.glsl"
#include "decal_data_inc.glsl" #include "../decal_data_inc.glsl"
#include "../scene_data_inc.glsl"
#if !defined(MODE_RENDER_DEPTH) || defined(MODE_RENDER_MATERIAL) || defined(MODE_RENDER_SDF) || defined(MODE_RENDER_NORMAL_ROUGHNESS) || defined(MODE_RENDER_VOXEL_GI) || defined(TANGENT_USED) || defined(NORMAL_MAP_USED) || defined(LIGHT_ANISOTROPY_USED) #if !defined(MODE_RENDER_DEPTH) || defined(MODE_RENDER_MATERIAL) || defined(MODE_RENDER_SDF) || defined(MODE_RENDER_NORMAL_ROUGHNESS) || defined(MODE_RENDER_VOXEL_GI) || defined(TANGENT_USED) || defined(NORMAL_MAP_USED) || defined(LIGHT_ANISOTROPY_USED)
#ifndef NORMAL_USED #ifndef NORMAL_USED
@@ -38,7 +39,7 @@ draw_call;
/* Set 0: Base Pass (never changes) */ /* Set 0: Base Pass (never changes) */
#include "light_data_inc.glsl" #include "../light_data_inc.glsl"
#define SAMPLER_NEAREST_CLAMP 0 #define SAMPLER_NEAREST_CLAMP 0
#define SAMPLER_LINEAR_CLAMP 1 #define SAMPLER_LINEAR_CLAMP 1
@@ -175,62 +176,27 @@ sdfgi;
/* Set 1: Render Pass (changes per render pass) */ /* Set 1: Render Pass (changes per render pass) */
struct SceneData { layout(set = 1, binding = 0, std140) uniform SceneDataBlock {
mat4 projection_matrix; SceneData data;
mat4 inv_projection_matrix; SceneData prev_data;
mat4 inv_view_matrix; }
mat4 view_matrix; scene_data_block;
// only used for multiview
mat4 projection_matrix_view[MAX_VIEWS];
mat4 inv_projection_matrix_view[MAX_VIEWS];
vec4 eye_offset[MAX_VIEWS];
vec2 viewport_size;
vec2 screen_pixel_size;
struct ImplementationData {
uint cluster_shift; uint cluster_shift;
uint cluster_width; uint cluster_width;
uint cluster_type_size; uint cluster_type_size;
uint max_cluster_element_count_div_32; uint max_cluster_element_count_div_32;
// Use vec4s because std140 doesn't play nice with vec2s, z and w are wasted.
vec4 directional_penumbra_shadow_kernel[32];
vec4 directional_soft_shadow_kernel[32];
vec4 penumbra_shadow_kernel[32];
vec4 soft_shadow_kernel[32];
vec4 ambient_light_color_energy;
float ambient_color_sky_mix;
bool use_ambient_light;
bool use_ambient_cubemap;
bool use_reflection_cubemap;
mat3 radiance_inverse_xform;
vec2 shadow_atlas_pixel_size;
vec2 directional_shadow_pixel_size;
uint directional_light_count;
float dual_paraboloid_side;
float z_far;
float z_near;
uint ss_effects_flags; uint ss_effects_flags;
float ssao_light_affect; float ssao_light_affect;
float ssao_ao_affect; float ssao_ao_affect;
bool roughness_limiter_enabled; uint pad1;
float roughness_limiter_amount;
float roughness_limiter_limit;
float opaque_prepass_threshold;
uint roughness_limiter_pad;
mat4 sdf_to_bounds; mat4 sdf_to_bounds;
ivec3 sdf_offset; ivec3 sdf_offset;
bool material_uv2_mode; uint pad2;
ivec3 sdf_size; ivec3 sdf_size;
bool gi_upscale_for_msaa; bool gi_upscale_for_msaa;
@@ -239,31 +205,14 @@ struct SceneData {
float volumetric_fog_inv_length; float volumetric_fog_inv_length;
float volumetric_fog_detail_spread; float volumetric_fog_detail_spread;
uint volumetric_fog_pad; uint volumetric_fog_pad;
bool fog_enabled;
float fog_density;
float fog_height;
float fog_height_density;
vec3 fog_light_color;
float fog_sun_scatter;
float fog_aerial_perspective;
float time;
float reflection_multiplier; // one normally, zero when rendering reflections
bool pancake_shadows;
vec2 taa_jitter;
float emissive_exposure_normalization;
float IBL_exposure_normalization;
}; };
layout(set = 1, binding = 0, std140) uniform SceneDataBlock { layout(set = 1, binding = 1, std140) uniform ImplementationDataBlock {
SceneData data; ImplementationData data;
SceneData prev_data;
} }
scene_data_block; implementation_data_block;
#define implementation_data implementation_data_block.data
struct InstanceData { struct InstanceData {
mat4 transform; mat4 transform;
@@ -275,42 +224,42 @@ struct InstanceData {
vec4 lightmap_uv_scale; vec4 lightmap_uv_scale;
}; };
layout(set = 1, binding = 1, std430) buffer restrict readonly InstanceDataBuffer { layout(set = 1, binding = 2, std430) buffer restrict readonly InstanceDataBuffer {
InstanceData data[]; InstanceData data[];
} }
instances; instances;
#ifdef USE_RADIANCE_CUBEMAP_ARRAY #ifdef USE_RADIANCE_CUBEMAP_ARRAY
layout(set = 1, binding = 2) uniform textureCubeArray radiance_cubemap; layout(set = 1, binding = 3) uniform textureCubeArray radiance_cubemap;
#else #else
layout(set = 1, binding = 2) uniform textureCube radiance_cubemap; layout(set = 1, binding = 3) uniform textureCube radiance_cubemap;
#endif #endif
layout(set = 1, binding = 3) uniform textureCubeArray reflection_atlas; layout(set = 1, binding = 4) uniform textureCubeArray reflection_atlas;
layout(set = 1, binding = 4) uniform texture2D shadow_atlas; layout(set = 1, binding = 5) uniform texture2D shadow_atlas;
layout(set = 1, binding = 5) uniform texture2D directional_shadow_atlas; layout(set = 1, binding = 6) uniform texture2D directional_shadow_atlas;
layout(set = 1, binding = 6) uniform texture2DArray lightmap_textures[MAX_LIGHTMAP_TEXTURES]; layout(set = 1, binding = 7) uniform texture2DArray lightmap_textures[MAX_LIGHTMAP_TEXTURES];
layout(set = 1, binding = 7) uniform texture3D voxel_gi_textures[MAX_VOXEL_GI_INSTANCES]; layout(set = 1, binding = 8) uniform texture3D voxel_gi_textures[MAX_VOXEL_GI_INSTANCES];
layout(set = 1, binding = 8, std430) buffer restrict readonly ClusterBuffer { layout(set = 1, binding = 9, std430) buffer restrict readonly ClusterBuffer {
uint data[]; uint data[];
} }
cluster_buffer; cluster_buffer;
#ifdef MODE_RENDER_SDF #ifdef MODE_RENDER_SDF
layout(r16ui, set = 1, binding = 9) uniform restrict writeonly uimage3D albedo_volume_grid; layout(r16ui, set = 1, binding = 10) uniform restrict writeonly uimage3D albedo_volume_grid;
layout(r32ui, set = 1, binding = 10) uniform restrict writeonly uimage3D emission_grid; layout(r32ui, set = 1, binding = 11) uniform restrict writeonly uimage3D emission_grid;
layout(r32ui, set = 1, binding = 11) uniform restrict writeonly uimage3D emission_aniso_grid; layout(r32ui, set = 1, binding = 12) uniform restrict writeonly uimage3D emission_aniso_grid;
layout(r32ui, set = 1, binding = 12) uniform restrict uimage3D geom_facing_grid; layout(r32ui, set = 1, binding = 13) uniform restrict uimage3D geom_facing_grid;
//still need to be present for shaders that use it, so remap them to something //still need to be present for shaders that use it, so remap them to something
#define depth_buffer shadow_atlas #define depth_buffer shadow_atlas
@@ -319,21 +268,21 @@ layout(r32ui, set = 1, binding = 12) uniform restrict uimage3D geom_facing_grid;
#else #else
layout(set = 1, binding = 9) uniform texture2D depth_buffer; layout(set = 1, binding = 10) uniform texture2D depth_buffer;
layout(set = 1, binding = 10) uniform texture2D color_buffer; layout(set = 1, binding = 11) uniform texture2D color_buffer;
#ifdef USE_MULTIVIEW #ifdef USE_MULTIVIEW
layout(set = 1, binding = 11) uniform texture2DArray normal_roughness_buffer; layout(set = 1, binding = 12) uniform texture2DArray normal_roughness_buffer;
layout(set = 1, binding = 13) uniform texture2DArray ambient_buffer; layout(set = 1, binding = 14) uniform texture2DArray ambient_buffer;
layout(set = 1, binding = 14) uniform texture2DArray reflection_buffer; layout(set = 1, binding = 15) uniform texture2DArray reflection_buffer;
#else // USE_MULTIVIEW #else // USE_MULTIVIEW
layout(set = 1, binding = 11) uniform texture2D normal_roughness_buffer; layout(set = 1, binding = 12) uniform texture2D normal_roughness_buffer;
layout(set = 1, binding = 13) uniform texture2D ambient_buffer; layout(set = 1, binding = 14) uniform texture2D ambient_buffer;
layout(set = 1, binding = 14) uniform texture2D reflection_buffer; layout(set = 1, binding = 15) uniform texture2D reflection_buffer;
#endif #endif
layout(set = 1, binding = 12) uniform texture2D ao_buffer; layout(set = 1, binding = 13) uniform texture2D ao_buffer;
layout(set = 1, binding = 15) uniform texture2DArray sdfgi_lightprobe_texture; layout(set = 1, binding = 16) uniform texture2DArray sdfgi_lightprobe_texture;
layout(set = 1, binding = 16) uniform texture3D sdfgi_occlusion_cascades; layout(set = 1, binding = 17) uniform texture3D sdfgi_occlusion_cascades;
struct VoxelGIData { struct VoxelGIData {
mat4 xform; // 64 - 64 mat4 xform; // 64 - 64
@@ -350,14 +299,14 @@ struct VoxelGIData {
float exposure_normalization; // 4 - 112 float exposure_normalization; // 4 - 112
}; };
layout(set = 1, binding = 17, std140) uniform VoxelGIs { layout(set = 1, binding = 18, std140) uniform VoxelGIs {
VoxelGIData data[MAX_VOXEL_GI_INSTANCES]; VoxelGIData data[MAX_VOXEL_GI_INSTANCES];
} }
voxel_gi_instances; voxel_gi_instances;
layout(set = 1, binding = 18) uniform texture3D volumetric_fog_texture; layout(set = 1, binding = 19) uniform texture3D volumetric_fog_texture;
layout(set = 1, binding = 19) uniform texture2D ssil_buffer; layout(set = 1, binding = 20) uniform texture2D ssil_buffer;
#endif #endif

View File

@@ -0,0 +1,17 @@
#!/usr/bin/env python
Import("env")
if "RD_GLSL" in env["BUILDERS"]:
# find all include files
gl_include_files = [str(f) for f in Glob("*_inc.glsl")]
# find all shader code(all glsl files excluding our include files)
glsl_files = [str(f) for f in Glob("*.glsl") if str(f) not in gl_include_files]
# make sure we recompile shaders if include files change
env.Depends([f + ".gen.h" for f in glsl_files], gl_include_files + ["#glsl_builders.py"])
# compile shaders
for glsl_file in glsl_files:
env.RD_GLSL(glsl_file)

View File

@@ -101,7 +101,7 @@ layout(set = MATERIAL_UNIFORM_SET, binding = 0, std140) uniform MaterialUniforms
#ifdef MODE_DUAL_PARABOLOID #ifdef MODE_DUAL_PARABOLOID
layout(location = 8) out highp float dp_clip; layout(location = 9) out highp float dp_clip;
#endif #endif
@@ -450,7 +450,7 @@ layout(location = 6) mediump in vec3 binormal_interp;
#ifdef MODE_DUAL_PARABOLOID #ifdef MODE_DUAL_PARABOLOID
layout(location = 8) highp in float dp_clip; layout(location = 9) highp in float dp_clip;
#endif #endif
@@ -519,7 +519,7 @@ layout(location = 0) out mediump vec4 frag_color;
#endif // RENDER DEPTH #endif // RENDER DEPTH
#include "scene_forward_aa_inc.glsl" #include "../scene_forward_aa_inc.glsl"
#if !defined(MODE_RENDER_DEPTH) && !defined(MODE_UNSHADED) #if !defined(MODE_RENDER_DEPTH) && !defined(MODE_UNSHADED)
@@ -528,7 +528,7 @@ layout(location = 0) out mediump vec4 frag_color;
#define SPECULAR_SCHLICK_GGX #define SPECULAR_SCHLICK_GGX
#endif #endif
#include "scene_forward_lights_inc.glsl" #include "../scene_forward_lights_inc.glsl"
#endif //!defined(MODE_RENDER_DEPTH) && !defined(MODE_UNSHADED) #endif //!defined(MODE_RENDER_DEPTH) && !defined(MODE_UNSHADED)

View File

@@ -5,7 +5,8 @@
#extension GL_EXT_multiview : enable #extension GL_EXT_multiview : enable
#endif #endif
#include "decal_data_inc.glsl" #include "../decal_data_inc.glsl"
#include "../scene_data_inc.glsl"
#if !defined(MODE_RENDER_DEPTH) || defined(MODE_RENDER_MATERIAL) || defined(TANGENT_USED) || defined(NORMAL_MAP_USED) || defined(LIGHT_ANISOTROPY_USED) #if !defined(MODE_RENDER_DEPTH) || defined(MODE_RENDER_MATERIAL) || defined(TANGENT_USED) || defined(NORMAL_MAP_USED) || defined(LIGHT_ANISOTROPY_USED)
#ifndef NORMAL_USED #ifndef NORMAL_USED
@@ -32,7 +33,7 @@ draw_call;
/* Set 0: Base Pass (never changes) */ /* Set 0: Base Pass (never changes) */
#include "light_data_inc.glsl" #include "../light_data_inc.glsl"
#define SAMPLER_NEAREST_CLAMP 0 #define SAMPLER_NEAREST_CLAMP 0
#define SAMPLER_LINEAR_CLAMP 1 #define SAMPLER_LINEAR_CLAMP 1
@@ -127,75 +128,9 @@ global_shader_uniforms;
/* Set 1: Render Pass (changes per render pass) */ /* Set 1: Render Pass (changes per render pass) */
struct SceneData {
highp mat4 projection_matrix;
highp mat4 inv_projection_matrix;
highp mat4 inv_view_matrix;
highp mat4 view_matrix;
// only used for multiview
highp mat4 projection_matrix_view[MAX_VIEWS];
highp mat4 inv_projection_matrix_view[MAX_VIEWS];
highp vec4 eye_offset[MAX_VIEWS];
highp vec2 viewport_size;
highp vec2 screen_pixel_size;
// Use vec4s because std140 doesn't play nice with vec2s, z and w are wasted.
highp vec4 directional_penumbra_shadow_kernel[32];
highp vec4 directional_soft_shadow_kernel[32];
highp vec4 penumbra_shadow_kernel[32];
highp vec4 soft_shadow_kernel[32];
mediump vec4 ambient_light_color_energy;
mediump float ambient_color_sky_mix;
bool use_ambient_light;
bool use_ambient_cubemap;
bool use_reflection_cubemap;
mediump mat3 radiance_inverse_xform;
highp vec2 shadow_atlas_pixel_size;
highp vec2 directional_shadow_pixel_size;
uint directional_light_count;
mediump float dual_paraboloid_side;
highp float z_far;
highp float z_near;
bool ssao_enabled;
mediump float ssao_light_affect;
mediump float ssao_ao_affect;
bool roughness_limiter_enabled;
mediump float roughness_limiter_amount;
mediump float roughness_limiter_limit;
mediump float opaque_prepass_threshold;
uint roughness_limiter_pad;
bool fog_enabled;
highp float fog_density;
highp float fog_height;
highp float fog_height_density;
mediump vec3 fog_light_color;
mediump float fog_sun_scatter;
mediump float fog_aerial_perspective;
bool material_uv2_mode;
highp float time;
mediump float reflection_multiplier; // one normally, zero when rendering reflections
bool pancake_shadows;
float emissive_exposure_normalization;
float IBL_exposure_normalization;
uint pad3;
};
layout(set = 1, binding = 0, std140) uniform SceneDataBlock { layout(set = 1, binding = 0, std140) uniform SceneDataBlock {
SceneData data; SceneData data;
SceneData prev_data;
} }
scene_data_block; scene_data_block;

View File

@@ -0,0 +1,69 @@
// Scene data stores all our 3D rendering globals for a frame such as our matrices
// where this information is independent of the different RD implementations.
// This enables us to use this UBO in our main scene render shaders but also in
// effects that need access to this data.
struct SceneData {
highp mat4 projection_matrix;
highp mat4 inv_projection_matrix;
highp mat4 inv_view_matrix;
highp mat4 view_matrix;
// only used for multiview
highp mat4 projection_matrix_view[MAX_VIEWS];
highp mat4 inv_projection_matrix_view[MAX_VIEWS];
highp vec4 eye_offset[MAX_VIEWS];
highp vec2 viewport_size;
highp vec2 screen_pixel_size;
// Use vec4s because std140 doesn't play nice with vec2s, z and w are wasted.
highp vec4 directional_penumbra_shadow_kernel[32];
highp vec4 directional_soft_shadow_kernel[32];
highp vec4 penumbra_shadow_kernel[32];
highp vec4 soft_shadow_kernel[32];
mediump mat3 radiance_inverse_xform;
mediump vec4 ambient_light_color_energy;
mediump float ambient_color_sky_mix;
bool use_ambient_light;
bool use_ambient_cubemap;
bool use_reflection_cubemap;
highp vec2 shadow_atlas_pixel_size;
highp vec2 directional_shadow_pixel_size;
uint directional_light_count;
mediump float dual_paraboloid_side;
highp float z_far;
highp float z_near;
bool roughness_limiter_enabled;
mediump float roughness_limiter_amount;
mediump float roughness_limiter_limit;
mediump float opaque_prepass_threshold;
bool fog_enabled;
highp float fog_density;
highp float fog_height;
highp float fog_height_density;
mediump vec3 fog_light_color;
mediump float fog_sun_scatter;
mediump float fog_aerial_perspective;
highp float time;
mediump float reflection_multiplier; // one normally, zero when rendering reflections
bool material_uv2_mode;
vec2 taa_jitter;
float emissive_exposure_normalization;
float IBL_exposure_normalization;
bool pancake_shadows;
uint pad1;
uint pad2;
uint pad3;
};

View File

@@ -0,0 +1,246 @@
/*************************************************************************/
/* render_scene_data_rd.cpp */
/*************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
/* "Software"), to deal in the Software without restriction, including */
/* without limitation the rights to use, copy, modify, merge, publish, */
/* distribute, sublicense, and/or sell copies of the Software, and to */
/* permit persons to whom the Software is furnished to do so, subject to */
/* the following conditions: */
/* */
/* The above copyright notice and this permission notice shall be */
/* included in all copies or substantial portions of the Software. */
/* */
/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
#include "render_scene_data_rd.h"
#include "servers/rendering/renderer_rd/renderer_scene_render_rd.h"
#include "servers/rendering/renderer_rd/storage_rd/light_storage.h"
#include "servers/rendering/renderer_rd/storage_rd/texture_storage.h"
#include "servers/rendering/rendering_server_default.h"
RID RenderSceneDataRD::create_uniform_buffer() {
return RD::get_singleton()->uniform_buffer_create(sizeof(UBODATA));
}
void RenderSceneDataRD::update_ubo(RID p_uniform_buffer, RS::ViewportDebugDraw p_debug_mode, RID p_env, RID p_reflection_probe_instance, RID p_camera_attributes, bool p_flip_y, bool p_pancake_shadows, const Size2i &p_screen_size, const Color &p_default_bg_color, float p_luminance_multiplier, bool p_opaque_render_buffers) {
RendererSceneRenderRD *render_scene_render = RendererSceneRenderRD::get_singleton();
UBODATA ubo_data;
memset(&ubo_data, 0, sizeof(UBODATA));
// just for easy access..
UBO &ubo = ubo_data.ubo;
UBO &prev_ubo = ubo_data.prev_ubo;
Projection correction;
correction.set_depth_correction(p_flip_y);
correction.add_jitter_offset(taa_jitter);
Projection projection = correction * cam_projection;
//store camera into ubo
RendererRD::MaterialStorage::store_camera(projection, ubo.projection_matrix);
RendererRD::MaterialStorage::store_camera(projection.inverse(), ubo.inv_projection_matrix);
RendererRD::MaterialStorage::store_transform(cam_transform, ubo.inv_view_matrix);
RendererRD::MaterialStorage::store_transform(cam_transform.affine_inverse(), ubo.view_matrix);
for (uint32_t v = 0; v < view_count; v++) {
projection = correction * view_projection[v];
RendererRD::MaterialStorage::store_camera(projection, ubo.projection_matrix_view[v]);
RendererRD::MaterialStorage::store_camera(projection.inverse(), ubo.inv_projection_matrix_view[v]);
ubo.eye_offset[v][0] = view_eye_offset[v].x;
ubo.eye_offset[v][1] = view_eye_offset[v].y;
ubo.eye_offset[v][2] = view_eye_offset[v].z;
ubo.eye_offset[v][3] = 0.0;
}
ubo.taa_jitter[0] = taa_jitter.x;
ubo.taa_jitter[1] = taa_jitter.y;
ubo.z_far = z_far;
ubo.z_near = z_near;
ubo.pancake_shadows = p_pancake_shadows;
RendererRD::MaterialStorage::store_soft_shadow_kernel(render_scene_render->directional_penumbra_shadow_kernel_get(), ubo.directional_penumbra_shadow_kernel);
RendererRD::MaterialStorage::store_soft_shadow_kernel(render_scene_render->directional_soft_shadow_kernel_get(), ubo.directional_soft_shadow_kernel);
RendererRD::MaterialStorage::store_soft_shadow_kernel(render_scene_render->penumbra_shadow_kernel_get(), ubo.penumbra_shadow_kernel);
RendererRD::MaterialStorage::store_soft_shadow_kernel(render_scene_render->soft_shadow_kernel_get(), ubo.soft_shadow_kernel);
ubo.viewport_size[0] = p_screen_size.x;
ubo.viewport_size[1] = p_screen_size.y;
Size2 screen_pixel_size = Vector2(1.0, 1.0) / Size2(p_screen_size);
ubo.screen_pixel_size[0] = screen_pixel_size.x;
ubo.screen_pixel_size[1] = screen_pixel_size.y;
ubo.shadow_atlas_pixel_size[0] = shadow_atlas_pixel_size.x;
ubo.shadow_atlas_pixel_size[1] = shadow_atlas_pixel_size.y;
ubo.directional_shadow_pixel_size[0] = directional_shadow_pixel_size.x;
ubo.directional_shadow_pixel_size[1] = directional_shadow_pixel_size.y;
ubo.time = time;
ubo.directional_light_count = directional_light_count;
ubo.dual_paraboloid_side = dual_paraboloid_side;
ubo.opaque_prepass_threshold = opaque_prepass_threshold;
ubo.material_uv2_mode = material_uv2_mode;
ubo.fog_enabled = false;
if (p_debug_mode == RS::VIEWPORT_DEBUG_DRAW_UNSHADED) {
ubo.use_ambient_light = true;
ubo.ambient_light_color_energy[0] = 1;
ubo.ambient_light_color_energy[1] = 1;
ubo.ambient_light_color_energy[2] = 1;
ubo.ambient_light_color_energy[3] = 1.0;
ubo.use_ambient_cubemap = false;
ubo.use_reflection_cubemap = false;
} else if (p_env.is_valid()) {
RS::EnvironmentBG env_bg = render_scene_render->environment_get_background(p_env);
RS::EnvironmentAmbientSource ambient_src = render_scene_render->environment_get_ambient_source(p_env);
float bg_energy_multiplier = render_scene_render->environment_get_bg_energy_multiplier(p_env);
ubo.ambient_light_color_energy[3] = bg_energy_multiplier;
ubo.ambient_color_sky_mix = render_scene_render->environment_get_ambient_sky_contribution(p_env);
//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 : render_scene_render->environment_get_bg_color(p_env);
color = color.srgb_to_linear();
ubo.ambient_light_color_energy[0] = color.r * bg_energy_multiplier;
ubo.ambient_light_color_energy[1] = color.g * bg_energy_multiplier;
ubo.ambient_light_color_energy[2] = color.b * bg_energy_multiplier;
ubo.use_ambient_light = true;
ubo.use_ambient_cubemap = false;
} else {
float energy = render_scene_render->environment_get_ambient_light_energy(p_env);
Color color = render_scene_render->environment_get_ambient_light(p_env);
color = color.srgb_to_linear();
ubo.ambient_light_color_energy[0] = color.r * energy;
ubo.ambient_light_color_energy[1] = color.g * energy;
ubo.ambient_light_color_energy[2] = color.b * energy;
Basis sky_transform = render_scene_render->environment_get_sky_orientation(p_env);
sky_transform = sky_transform.inverse() * cam_transform.basis;
RendererRD::MaterialStorage::store_transform_3x3(sky_transform, ubo.radiance_inverse_xform);
ubo.use_ambient_cubemap = (ambient_src == RS::ENV_AMBIENT_SOURCE_BG && env_bg == RS::ENV_BG_SKY) || ambient_src == RS::ENV_AMBIENT_SOURCE_SKY;
ubo.use_ambient_light = ubo.use_ambient_cubemap || ambient_src == RS::ENV_AMBIENT_SOURCE_COLOR;
}
//specular
RS::EnvironmentReflectionSource ref_src = render_scene_render->environment_get_reflection_source(p_env);
if ((ref_src == RS::ENV_REFLECTION_SOURCE_BG && env_bg == RS::ENV_BG_SKY) || ref_src == RS::ENV_REFLECTION_SOURCE_SKY) {
ubo.use_reflection_cubemap = true;
} else {
ubo.use_reflection_cubemap = false;
}
ubo.fog_enabled = render_scene_render->environment_get_fog_enabled(p_env);
ubo.fog_density = render_scene_render->environment_get_fog_density(p_env);
ubo.fog_height = render_scene_render->environment_get_fog_height(p_env);
ubo.fog_height_density = render_scene_render->environment_get_fog_height_density(p_env);
ubo.fog_aerial_perspective = render_scene_render->environment_get_fog_aerial_perspective(p_env);
Color fog_color = render_scene_render->environment_get_fog_light_color(p_env).srgb_to_linear();
float fog_energy = render_scene_render->environment_get_fog_light_energy(p_env);
ubo.fog_light_color[0] = fog_color.r * fog_energy;
ubo.fog_light_color[1] = fog_color.g * fog_energy;
ubo.fog_light_color[2] = fog_color.b * fog_energy;
ubo.fog_sun_scatter = render_scene_render->environment_get_fog_sun_scatter(p_env);
} else {
if (p_reflection_probe_instance.is_valid() && RendererRD::LightStorage::get_singleton()->reflection_probe_is_interior(p_reflection_probe_instance)) {
ubo.use_ambient_light = false;
} else {
ubo.use_ambient_light = true;
Color clear_color = p_default_bg_color;
clear_color = clear_color.srgb_to_linear();
ubo.ambient_light_color_energy[0] = clear_color.r;
ubo.ambient_light_color_energy[1] = clear_color.g;
ubo.ambient_light_color_energy[2] = clear_color.b;
ubo.ambient_light_color_energy[3] = 1.0;
}
ubo.use_ambient_cubemap = false;
ubo.use_reflection_cubemap = false;
}
if (p_camera_attributes.is_valid()) {
ubo.emissive_exposure_normalization = RSG::camera_attributes->camera_attributes_get_exposure_normalization_factor(p_camera_attributes);
ubo.IBL_exposure_normalization = 1.0;
if (p_env.is_valid()) {
RID sky_rid = render_scene_render->environment_get_sky(p_env);
if (sky_rid.is_valid()) {
float current_exposure = RSG::camera_attributes->camera_attributes_get_exposure_normalization_factor(p_camera_attributes) * render_scene_render->environment_get_bg_intensity(p_env) / p_luminance_multiplier;
ubo.IBL_exposure_normalization = current_exposure / MAX(0.001, render_scene_render->get_sky()->sky_get_baked_exposure(sky_rid));
}
}
} else if (emissive_exposure_normalization > 0.0) {
// This branch is triggered when using render_material().
// Emissive is set outside the function.
ubo.emissive_exposure_normalization = emissive_exposure_normalization;
// IBL isn't used don't set it.
} else {
ubo.emissive_exposure_normalization = 1.0;
ubo.IBL_exposure_normalization = 1.0;
}
ubo.roughness_limiter_enabled = p_opaque_render_buffers && render_scene_render->screen_space_roughness_limiter_is_active();
ubo.roughness_limiter_amount = render_scene_render->screen_space_roughness_limiter_get_amount();
ubo.roughness_limiter_limit = render_scene_render->screen_space_roughness_limiter_get_limit();
if (calculate_motion_vectors) {
// Q : Should we make a complete copy or should we define a separate UBO with just the components we need?
memcpy(&prev_ubo, &ubo, sizeof(UBO));
Projection prev_correction;
prev_correction.set_depth_correction(true);
prev_correction.add_jitter_offset(prev_taa_jitter);
Projection prev_projection = prev_correction * prev_cam_projection;
//store camera into ubo
RendererRD::MaterialStorage::store_camera(prev_projection, prev_ubo.projection_matrix);
RendererRD::MaterialStorage::store_camera(prev_projection.inverse(), prev_ubo.inv_projection_matrix);
RendererRD::MaterialStorage::store_transform(prev_cam_transform, prev_ubo.inv_view_matrix);
RendererRD::MaterialStorage::store_transform(prev_cam_transform.affine_inverse(), prev_ubo.view_matrix);
for (uint32_t v = 0; v < view_count; v++) {
prev_projection = prev_correction * view_projection[v];
RendererRD::MaterialStorage::store_camera(prev_projection, prev_ubo.projection_matrix_view[v]);
RendererRD::MaterialStorage::store_camera(prev_projection.inverse(), prev_ubo.inv_projection_matrix_view[v]);
}
prev_ubo.taa_jitter[0] = prev_taa_jitter.x;
prev_ubo.taa_jitter[1] = prev_taa_jitter.y;
prev_ubo.time -= time_step;
}
uniform_buffer = p_uniform_buffer;
RD::get_singleton()->buffer_update(uniform_buffer, 0, sizeof(UBODATA), &ubo, RD::BARRIER_MASK_RASTER);
}
RID RenderSceneDataRD::get_uniform_buffer() {
return uniform_buffer;
}

View File

@@ -0,0 +1,157 @@
/*************************************************************************/
/* render_scene_data_rd.h */
/*************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
/* "Software"), to deal in the Software without restriction, including */
/* without limitation the rights to use, copy, modify, merge, publish, */
/* distribute, sublicense, and/or sell copies of the Software, and to */
/* permit persons to whom the Software is furnished to do so, subject to */
/* the following conditions: */
/* */
/* The above copyright notice and this permission notice shall be */
/* included in all copies or substantial portions of the Software. */
/* */
/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
#ifndef RENDER_SCENE_DATA_RD_H
#define RENDER_SCENE_DATA_RD_H
#include "render_scene_buffers_rd.h"
#include "servers/rendering/renderer_scene_render.h"
#include "servers/rendering/rendering_device.h"
// This is a container for data related to rendering a single frame of a viewport where we load this data into a UBO
// that can be used by the main scene shader but also by various effects.
class RenderSceneDataRD {
public:
bool calculate_motion_vectors = false;
Transform3D cam_transform;
Projection cam_projection;
Vector2 taa_jitter;
bool cam_orthogonal = false;
// For stereo rendering
uint32_t view_count = 1;
Vector3 view_eye_offset[RendererSceneRender::MAX_RENDER_VIEWS];
Projection view_projection[RendererSceneRender::MAX_RENDER_VIEWS];
Transform3D prev_cam_transform;
Projection prev_cam_projection;
Vector2 prev_taa_jitter;
Projection prev_view_projection[RendererSceneRender::MAX_RENDER_VIEWS];
float z_near = 0.0;
float z_far = 0.0;
float lod_distance_multiplier = 0.0;
Plane lod_camera_plane;
float screen_mesh_lod_threshold = 0.0;
uint32_t directional_light_count = 0;
float dual_paraboloid_side = 0.0;
float opaque_prepass_threshold = 0.0;
bool material_uv2_mode = false;
float emissive_exposure_normalization = 0.0;
Size2 shadow_atlas_pixel_size;
Size2 directional_shadow_pixel_size;
float time;
float time_step;
RID create_uniform_buffer();
void update_ubo(RID p_uniform_buffer, RS::ViewportDebugDraw p_debug_mode, RID p_env, RID p_reflection_probe_instance, RID p_camera_attributes, bool p_flip_y, bool p_pancake_shadows, const Size2i &p_screen_size, const Color &p_default_bg_color, float p_luminance_multiplier, bool p_opaque_render_buffers);
RID get_uniform_buffer();
private:
RID uniform_buffer; // loaded into this uniform buffer (supplied externally)
// This struct is loaded into Set 1 - Binding 0, populated at start of rendering a frame, must match with shader code
struct UBO {
float projection_matrix[16];
float inv_projection_matrix[16];
float inv_view_matrix[16];
float view_matrix[16];
float projection_matrix_view[RendererSceneRender::MAX_RENDER_VIEWS][16];
float inv_projection_matrix_view[RendererSceneRender::MAX_RENDER_VIEWS][16];
float eye_offset[RendererSceneRender::MAX_RENDER_VIEWS][4];
float viewport_size[2];
float screen_pixel_size[2];
float directional_penumbra_shadow_kernel[128]; //32 vec4s
float directional_soft_shadow_kernel[128];
float penumbra_shadow_kernel[128];
float soft_shadow_kernel[128];
float radiance_inverse_xform[12];
float ambient_light_color_energy[4];
float ambient_color_sky_mix;
uint32_t use_ambient_light;
uint32_t use_ambient_cubemap;
uint32_t use_reflection_cubemap;
float shadow_atlas_pixel_size[2];
float directional_shadow_pixel_size[2];
uint32_t directional_light_count;
float dual_paraboloid_side;
float z_far;
float z_near;
uint32_t roughness_limiter_enabled;
float roughness_limiter_amount;
float roughness_limiter_limit;
float opaque_prepass_threshold;
// Fog
uint32_t fog_enabled;
float fog_density;
float fog_height;
float fog_height_density;
float fog_light_color[3];
float fog_sun_scatter;
float fog_aerial_perspective;
float time;
float reflection_multiplier;
uint32_t material_uv2_mode;
float taa_jitter[2];
float emissive_exposure_normalization; // Needed to normalize emissive when using physical units.
float IBL_exposure_normalization; // Adjusts for baked exposure.
uint32_t pancake_shadows;
uint32_t pad1;
uint32_t pad2;
uint32_t pad3;
};
struct UBODATA {
UBO ubo;
UBO prev_ubo;
};
};
#endif // RENDER_SCENE_DATA_RD_H