Merge pull request #45376 from reduz/gi-optimizations
Several GI related optimizations and fixes
This commit is contained in:
commit
71f0b4f4b9
@ -3104,6 +3104,7 @@ VkRenderPass RenderingDeviceVulkan::_render_pass_create(const Vector<AttachmentF
|
||||
// the read. If this is a performance issue, one could track the actual last accessor of each resource, adding only that
|
||||
// stage
|
||||
switch (is_depth_stencil ? p_initial_depth_action : p_initial_color_action) {
|
||||
case INITIAL_ACTION_CLEAR_REGION:
|
||||
case INITIAL_ACTION_CLEAR: {
|
||||
description.loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR;
|
||||
description.stencilLoadOp = VK_ATTACHMENT_LOAD_OP_CLEAR;
|
||||
@ -3116,9 +3117,9 @@ VkRenderPass RenderingDeviceVulkan::_render_pass_create(const Vector<AttachmentF
|
||||
description.initialLayout = is_sampled ? VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL : (is_storage ? VK_IMAGE_LAYOUT_GENERAL : VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL);
|
||||
description.stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE;
|
||||
} else if (p_format[i].usage_flags & TEXTURE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT) {
|
||||
description.loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR;
|
||||
description.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED; //don't care what is there
|
||||
description.stencilLoadOp = VK_ATTACHMENT_LOAD_OP_CLEAR;
|
||||
description.loadOp = VK_ATTACHMENT_LOAD_OP_LOAD;
|
||||
description.initialLayout = is_sampled ? VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL : (is_storage ? VK_IMAGE_LAYOUT_GENERAL : VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL);
|
||||
description.stencilLoadOp = VK_ATTACHMENT_LOAD_OP_LOAD;
|
||||
dependency_from_external.srcStageMask |= reading_stages;
|
||||
} else {
|
||||
description.loadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE;
|
||||
@ -5726,11 +5727,18 @@ Error RenderingDeviceVulkan::_draw_list_render_pass_begin(Framebuffer *framebuff
|
||||
render_pass_begin.pNext = nullptr;
|
||||
render_pass_begin.renderPass = render_pass;
|
||||
render_pass_begin.framebuffer = vkframebuffer;
|
||||
|
||||
/*
|
||||
* Given how API works, it makes sense to always fully operate on the whole framebuffer.
|
||||
* This allows better continue operations for operations like shadowmapping.
|
||||
render_pass_begin.renderArea.extent.width = viewport_size.width;
|
||||
render_pass_begin.renderArea.extent.height = viewport_size.height;
|
||||
render_pass_begin.renderArea.offset.x = viewport_offset.x;
|
||||
render_pass_begin.renderArea.offset.y = viewport_offset.y;
|
||||
*/
|
||||
render_pass_begin.renderArea.extent.width = framebuffer->size.width;
|
||||
render_pass_begin.renderArea.extent.height = framebuffer->size.height;
|
||||
render_pass_begin.renderArea.offset.x = 0;
|
||||
render_pass_begin.renderArea.offset.y = 0;
|
||||
|
||||
Vector<VkClearValue> clear_values;
|
||||
clear_values.resize(framebuffer->texture_ids.size());
|
||||
@ -5879,11 +5887,11 @@ RenderingDevice::DrawListID RenderingDeviceVulkan::draw_list_begin(RID p_framebu
|
||||
viewport_offset = regioni.position;
|
||||
viewport_size = regioni.size;
|
||||
|
||||
if (p_initial_color_action == INITIAL_ACTION_CLEAR) {
|
||||
if (p_initial_color_action == INITIAL_ACTION_CLEAR_REGION) {
|
||||
needs_clear_color = true;
|
||||
p_initial_color_action = INITIAL_ACTION_KEEP;
|
||||
}
|
||||
if (p_initial_depth_action == INITIAL_ACTION_CLEAR) {
|
||||
if (p_initial_depth_action == INITIAL_ACTION_CLEAR_REGION) {
|
||||
needs_clear_depth = true;
|
||||
p_initial_depth_action = INITIAL_ACTION_KEEP;
|
||||
}
|
||||
@ -5969,11 +5977,11 @@ Error RenderingDeviceVulkan::draw_list_begin_split(RID p_framebuffer, uint32_t p
|
||||
viewport_offset = regioni.position;
|
||||
viewport_size = regioni.size;
|
||||
|
||||
if (p_initial_color_action == INITIAL_ACTION_CLEAR) {
|
||||
if (p_initial_color_action == INITIAL_ACTION_CLEAR_REGION) {
|
||||
needs_clear_color = true;
|
||||
p_initial_color_action = INITIAL_ACTION_KEEP;
|
||||
}
|
||||
if (p_initial_depth_action == INITIAL_ACTION_CLEAR) {
|
||||
if (p_initial_depth_action == INITIAL_ACTION_CLEAR_REGION) {
|
||||
needs_clear_depth = true;
|
||||
p_initial_depth_action = INITIAL_ACTION_KEEP;
|
||||
}
|
||||
|
@ -498,6 +498,11 @@ void EditorNode::_notification(int p_what) {
|
||||
float sss_scale = GLOBAL_GET("rendering/quality/subsurface_scattering/subsurface_scattering_scale");
|
||||
float sss_depth_scale = GLOBAL_GET("rendering/quality/subsurface_scattering/subsurface_scattering_depth_scale");
|
||||
RS::get_singleton()->sub_surface_scattering_set_scale(sss_scale, sss_depth_scale);
|
||||
|
||||
uint32_t directional_shadow_size = GLOBAL_GET("rendering/quality/directional_shadow/size");
|
||||
uint32_t directional_shadow_16_bits = GLOBAL_GET("rendering/quality/directional_shadow/16_bits");
|
||||
RS::get_singleton()->directional_shadow_atlas_set_size(directional_shadow_size, directional_shadow_16_bits);
|
||||
|
||||
RS::ShadowQuality shadows_quality = RS::ShadowQuality(int(GLOBAL_GET("rendering/quality/shadows/soft_shadow_quality")));
|
||||
RS::get_singleton()->shadows_quality_set(shadows_quality);
|
||||
RS::ShadowQuality directional_shadow_quality = RS::ShadowQuality(int(GLOBAL_GET("rendering/quality/directional_shadow/soft_shadow_quality")));
|
||||
@ -516,6 +521,9 @@ void EditorNode::_notification(int p_what) {
|
||||
RS::get_singleton()->environment_set_volumetric_fog_positional_shadow_shrink_size(GLOBAL_GET("rendering/volumetric_fog/positional_shadow_shrink"));
|
||||
RS::get_singleton()->canvas_set_shadow_texture_size(GLOBAL_GET("rendering/quality/2d_shadow_atlas/size"));
|
||||
|
||||
bool use_half_res_gi = GLOBAL_DEF("rendering/quality/gi/use_half_resolution", false);
|
||||
RS::get_singleton()->gi_set_use_half_resolution(use_half_res_gi);
|
||||
|
||||
bool snap_2d_transforms = GLOBAL_GET("rendering/quality/2d/snap_2d_transforms_to_pixel");
|
||||
scene_root->set_snap_2d_transforms_to_pixel(snap_2d_transforms);
|
||||
bool snap_2d_vertices = GLOBAL_GET("rendering/quality/2d/snap_2d_vertices_to_pixel");
|
||||
|
@ -2445,12 +2445,14 @@ void Node3DEditorViewport::_notification(int p_what) {
|
||||
//update shadow atlas if changed
|
||||
|
||||
int shadowmap_size = ProjectSettings::get_singleton()->get("rendering/quality/shadow_atlas/size");
|
||||
bool shadowmap_16_bits = ProjectSettings::get_singleton()->get("rendering/quality/shadow_atlas/16_bits");
|
||||
int atlas_q0 = ProjectSettings::get_singleton()->get("rendering/quality/shadow_atlas/quadrant_0_subdiv");
|
||||
int atlas_q1 = ProjectSettings::get_singleton()->get("rendering/quality/shadow_atlas/quadrant_1_subdiv");
|
||||
int atlas_q2 = ProjectSettings::get_singleton()->get("rendering/quality/shadow_atlas/quadrant_2_subdiv");
|
||||
int atlas_q3 = ProjectSettings::get_singleton()->get("rendering/quality/shadow_atlas/quadrant_3_subdiv");
|
||||
|
||||
viewport->set_shadow_atlas_size(shadowmap_size);
|
||||
viewport->set_shadow_atlas_16_bits(shadowmap_16_bits);
|
||||
viewport->set_shadow_atlas_quadrant_subdiv(0, Viewport::ShadowAtlasQuadrantSubdiv(atlas_q0));
|
||||
viewport->set_shadow_atlas_quadrant_subdiv(1, Viewport::ShadowAtlasQuadrantSubdiv(atlas_q1));
|
||||
viewport->set_shadow_atlas_quadrant_subdiv(2, Viewport::ShadowAtlasQuadrantSubdiv(atlas_q2));
|
||||
|
@ -171,6 +171,8 @@ static bool disable_render_loop = false;
|
||||
static int fixed_fps = -1;
|
||||
static bool print_fps = false;
|
||||
|
||||
bool profile_gpu = false;
|
||||
|
||||
/* Helper methods */
|
||||
|
||||
// Used by Mono module, should likely be registered in Engine singleton instead
|
||||
@ -357,6 +359,7 @@ void Main::print_help(const char *p_binary) {
|
||||
OS::get_singleton()->print(" --disable-crash-handler Disable crash handler when supported by the platform code.\n");
|
||||
OS::get_singleton()->print(" --fixed-fps <fps> Force a fixed number of frames per second. This setting disables real-time synchronization.\n");
|
||||
OS::get_singleton()->print(" --print-fps Print the frames per second to the stdout.\n");
|
||||
OS::get_singleton()->print(" --profile-gpu Show a simple profile of the tasks that took more time during frame rendering.\n");
|
||||
OS::get_singleton()->print("\n");
|
||||
|
||||
OS::get_singleton()->print("Standalone tools:\n");
|
||||
@ -1006,6 +1009,8 @@ Error Main::setup(const char *execpath, int argc, char *argv[], bool p_second_ph
|
||||
}
|
||||
} else if (I->get() == "--print-fps") {
|
||||
print_fps = true;
|
||||
} else if (I->get() == "--profile-gpu") {
|
||||
profile_gpu = true;
|
||||
} else if (I->get() == "--disable-crash-handler") {
|
||||
OS::get_singleton()->disable_crash_handler();
|
||||
} else if (I->get() == "--skip-breakpoints") {
|
||||
@ -1574,6 +1579,10 @@ Error Main::setup2(Thread::ID p_main_tid_override) {
|
||||
rendering_server->init();
|
||||
rendering_server->set_render_loop_enabled(!disable_render_loop);
|
||||
|
||||
if (profile_gpu) {
|
||||
rendering_server->set_print_gpu_profile(true);
|
||||
}
|
||||
|
||||
OS::get_singleton()->initialize_joypads();
|
||||
|
||||
/* Initialize Audio Driver */
|
||||
@ -2142,11 +2151,6 @@ bool Main::start() {
|
||||
}
|
||||
#endif
|
||||
|
||||
{
|
||||
int directional_atlas_size = GLOBAL_GET("rendering/quality/directional_shadow/size");
|
||||
RenderingServer::get_singleton()->directional_shadow_atlas_set_size(directional_atlas_size);
|
||||
}
|
||||
|
||||
if (!editor && !project_manager) {
|
||||
//standard helpers that can be changed from main config
|
||||
|
||||
@ -2190,22 +2194,6 @@ bool Main::start() {
|
||||
DisplayServer::get_singleton()->window_set_title(appname);
|
||||
#endif
|
||||
|
||||
int shadow_atlas_size = GLOBAL_GET("rendering/quality/shadow_atlas/size");
|
||||
int shadow_atlas_q0_subdiv = GLOBAL_GET("rendering/quality/shadow_atlas/quadrant_0_subdiv");
|
||||
int shadow_atlas_q1_subdiv = GLOBAL_GET("rendering/quality/shadow_atlas/quadrant_1_subdiv");
|
||||
int shadow_atlas_q2_subdiv = GLOBAL_GET("rendering/quality/shadow_atlas/quadrant_2_subdiv");
|
||||
int shadow_atlas_q3_subdiv = GLOBAL_GET("rendering/quality/shadow_atlas/quadrant_3_subdiv");
|
||||
|
||||
sml->get_root()->set_shadow_atlas_size(shadow_atlas_size);
|
||||
sml->get_root()->set_shadow_atlas_quadrant_subdiv(0, Viewport::ShadowAtlasQuadrantSubdiv(
|
||||
shadow_atlas_q0_subdiv));
|
||||
sml->get_root()->set_shadow_atlas_quadrant_subdiv(1, Viewport::ShadowAtlasQuadrantSubdiv(
|
||||
shadow_atlas_q1_subdiv));
|
||||
sml->get_root()->set_shadow_atlas_quadrant_subdiv(2, Viewport::ShadowAtlasQuadrantSubdiv(
|
||||
shadow_atlas_q2_subdiv));
|
||||
sml->get_root()->set_shadow_atlas_quadrant_subdiv(3, Viewport::ShadowAtlasQuadrantSubdiv(
|
||||
shadow_atlas_q3_subdiv));
|
||||
|
||||
bool snap_controls = GLOBAL_DEF("gui/common/snap_controls_to_pixels", true);
|
||||
sml->get_root()->set_snap_controls_to_pixels(snap_controls);
|
||||
|
||||
|
@ -520,7 +520,10 @@ String GIProbe::get_configuration_warning() const {
|
||||
warning += "\n\n";
|
||||
}
|
||||
warning += TTR("GIProbes are not supported by the GLES2 video driver.\nUse a BakedLightmap instead.");
|
||||
} else if (probe_data.is_null()) {
|
||||
warning += TTR("No GIProbe data set, so this node is disabled. Bake static objects to enable GI.");
|
||||
}
|
||||
|
||||
return warning;
|
||||
}
|
||||
|
||||
|
@ -1372,6 +1372,26 @@ SceneTree::SceneTree() {
|
||||
bool snap_2d_vertices = GLOBAL_DEF("rendering/quality/2d/snap_2d_vertices_to_pixel", false);
|
||||
root->set_snap_2d_vertices_to_pixel(snap_2d_vertices);
|
||||
|
||||
int shadowmap_size = GLOBAL_DEF("rendering/quality/shadow_atlas/size", 4096);
|
||||
ProjectSettings::get_singleton()->set_custom_property_info("rendering/quality/shadow_atlas/size", PropertyInfo(Variant::INT, "rendering/quality/shadow_atlas/size", PROPERTY_HINT_RANGE, "256,16384"));
|
||||
GLOBAL_DEF("rendering/quality/shadow_atlas/size.mobile", 2048);
|
||||
bool shadowmap_16_bits = GLOBAL_DEF("rendering/quality/shadow_atlas/16_bits", true);
|
||||
int atlas_q0 = GLOBAL_DEF("rendering/quality/shadow_atlas/quadrant_0_subdiv", 2);
|
||||
int atlas_q1 = GLOBAL_DEF("rendering/quality/shadow_atlas/quadrant_1_subdiv", 2);
|
||||
int atlas_q2 = GLOBAL_DEF("rendering/quality/shadow_atlas/quadrant_2_subdiv", 3);
|
||||
int atlas_q3 = GLOBAL_DEF("rendering/quality/shadow_atlas/quadrant_3_subdiv", 4);
|
||||
ProjectSettings::get_singleton()->set_custom_property_info("rendering/quality/shadow_atlas/quadrant_0_subdiv", PropertyInfo(Variant::INT, "rendering/quality/shadow_atlas/quadrant_0_subdiv", PROPERTY_HINT_ENUM, "Disabled,1 Shadow,4 Shadows,16 Shadows,64 Shadows,256 Shadows,1024 Shadows"));
|
||||
ProjectSettings::get_singleton()->set_custom_property_info("rendering/quality/shadow_atlas/quadrant_1_subdiv", PropertyInfo(Variant::INT, "rendering/quality/shadow_atlas/quadrant_1_subdiv", PROPERTY_HINT_ENUM, "Disabled,1 Shadow,4 Shadows,16 Shadows,64 Shadows,256 Shadows,1024 Shadows"));
|
||||
ProjectSettings::get_singleton()->set_custom_property_info("rendering/quality/shadow_atlas/quadrant_2_subdiv", PropertyInfo(Variant::INT, "rendering/quality/shadow_atlas/quadrant_2_subdiv", PROPERTY_HINT_ENUM, "Disabled,1 Shadow,4 Shadows,16 Shadows,64 Shadows,256 Shadows,1024 Shadows"));
|
||||
ProjectSettings::get_singleton()->set_custom_property_info("rendering/quality/shadow_atlas/quadrant_3_subdiv", PropertyInfo(Variant::INT, "rendering/quality/shadow_atlas/quadrant_3_subdiv", PROPERTY_HINT_ENUM, "Disabled,1 Shadow,4 Shadows,16 Shadows,64 Shadows,256 Shadows,1024 Shadows"));
|
||||
|
||||
root->set_shadow_atlas_size(shadowmap_size);
|
||||
root->set_shadow_atlas_16_bits(shadowmap_16_bits);
|
||||
root->set_shadow_atlas_quadrant_subdiv(0, Viewport::ShadowAtlasQuadrantSubdiv(atlas_q0));
|
||||
root->set_shadow_atlas_quadrant_subdiv(1, Viewport::ShadowAtlasQuadrantSubdiv(atlas_q1));
|
||||
root->set_shadow_atlas_quadrant_subdiv(2, Viewport::ShadowAtlasQuadrantSubdiv(atlas_q2));
|
||||
root->set_shadow_atlas_quadrant_subdiv(3, Viewport::ShadowAtlasQuadrantSubdiv(atlas_q3));
|
||||
|
||||
Viewport::SDFOversize sdf_oversize = Viewport::SDFOversize(int(GLOBAL_DEF("rendering/quality/2d_sdf/oversize", 1)));
|
||||
root->set_sdf_oversize(sdf_oversize);
|
||||
Viewport::SDFScale sdf_scale = Viewport::SDFScale(int(GLOBAL_DEF("rendering/quality/2d_sdf/scale", 1)));
|
||||
|
@ -1416,18 +1416,26 @@ Ref<ViewportTexture> Viewport::get_texture() const {
|
||||
}
|
||||
|
||||
void Viewport::set_shadow_atlas_size(int p_size) {
|
||||
if (shadow_atlas_size == p_size) {
|
||||
return;
|
||||
}
|
||||
|
||||
shadow_atlas_size = p_size;
|
||||
RS::get_singleton()->viewport_set_shadow_atlas_size(viewport, p_size);
|
||||
RS::get_singleton()->viewport_set_shadow_atlas_size(viewport, p_size, shadow_atlas_16_bits);
|
||||
}
|
||||
|
||||
int Viewport::get_shadow_atlas_size() const {
|
||||
return shadow_atlas_size;
|
||||
}
|
||||
|
||||
void Viewport::set_shadow_atlas_16_bits(bool p_16_bits) {
|
||||
if (shadow_atlas_16_bits == p_16_bits) {
|
||||
return;
|
||||
}
|
||||
|
||||
shadow_atlas_16_bits = p_16_bits;
|
||||
RS::get_singleton()->viewport_set_shadow_atlas_size(viewport, shadow_atlas_size, shadow_atlas_16_bits);
|
||||
}
|
||||
|
||||
bool Viewport::get_shadow_atlas_16_bits() const {
|
||||
return shadow_atlas_16_bits;
|
||||
}
|
||||
void Viewport::set_shadow_atlas_quadrant_subdiv(int p_quadrant, ShadowAtlasQuadrantSubdiv p_subdiv) {
|
||||
ERR_FAIL_INDEX(p_quadrant, 4);
|
||||
ERR_FAIL_INDEX(p_subdiv, SHADOW_ATLAS_QUADRANT_SUBDIV_MAX);
|
||||
@ -3481,6 +3489,9 @@ void Viewport::_bind_methods() {
|
||||
ClassDB::bind_method(D_METHOD("set_shadow_atlas_size", "size"), &Viewport::set_shadow_atlas_size);
|
||||
ClassDB::bind_method(D_METHOD("get_shadow_atlas_size"), &Viewport::get_shadow_atlas_size);
|
||||
|
||||
ClassDB::bind_method(D_METHOD("set_shadow_atlas_16_bits", "enable"), &Viewport::set_shadow_atlas_16_bits);
|
||||
ClassDB::bind_method(D_METHOD("get_shadow_atlas_16_bits"), &Viewport::get_shadow_atlas_16_bits);
|
||||
|
||||
ClassDB::bind_method(D_METHOD("set_snap_controls_to_pixels", "enabled"), &Viewport::set_snap_controls_to_pixels);
|
||||
ClassDB::bind_method(D_METHOD("is_snap_controls_to_pixels_enabled"), &Viewport::is_snap_controls_to_pixels_enabled);
|
||||
|
||||
@ -3548,6 +3559,7 @@ void Viewport::_bind_methods() {
|
||||
ADD_PROPERTY(PropertyInfo(Variant::INT, "sdf_scale", PROPERTY_HINT_ENUM, "100%,50%,25%"), "set_sdf_scale", "get_sdf_scale");
|
||||
ADD_GROUP("Shadow Atlas", "shadow_atlas_");
|
||||
ADD_PROPERTY(PropertyInfo(Variant::INT, "shadow_atlas_size"), "set_shadow_atlas_size", "get_shadow_atlas_size");
|
||||
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "shadow_atlas_16_bits"), "set_shadow_atlas_16_bits", "get_shadow_atlas_16_bits");
|
||||
ADD_PROPERTYI(PropertyInfo(Variant::INT, "shadow_atlas_quad_0", PROPERTY_HINT_ENUM, "Disabled,1 Shadow,4 Shadows,16 Shadows,64 Shadows,256 Shadows,1024 Shadows"), "set_shadow_atlas_quadrant_subdiv", "get_shadow_atlas_quadrant_subdiv", 0);
|
||||
ADD_PROPERTYI(PropertyInfo(Variant::INT, "shadow_atlas_quad_1", PROPERTY_HINT_ENUM, "Disabled,1 Shadow,4 Shadows,16 Shadows,64 Shadows,256 Shadows,1024 Shadows"), "set_shadow_atlas_quadrant_subdiv", "get_shadow_atlas_quadrant_subdiv", 1);
|
||||
ADD_PROPERTYI(PropertyInfo(Variant::INT, "shadow_atlas_quad_2", PROPERTY_HINT_ENUM, "Disabled,1 Shadow,4 Shadows,16 Shadows,64 Shadows,256 Shadows,1024 Shadows"), "set_shadow_atlas_quadrant_subdiv", "get_shadow_atlas_quadrant_subdiv", 2);
|
||||
@ -3662,7 +3674,10 @@ Viewport::Viewport() {
|
||||
physics_has_last_mousepos = false;
|
||||
physics_last_mousepos = Vector2(Math_INF, Math_INF);
|
||||
|
||||
shadow_atlas_size = 0;
|
||||
shadow_atlas_16_bits = true;
|
||||
shadow_atlas_size = 2048;
|
||||
set_shadow_atlas_size(shadow_atlas_size);
|
||||
|
||||
for (int i = 0; i < 4; i++) {
|
||||
shadow_atlas_quadrant_subdiv[i] = SHADOW_ATLAS_QUADRANT_SUBDIV_MAX;
|
||||
}
|
||||
|
@ -297,6 +297,7 @@ private:
|
||||
DebugDraw debug_draw;
|
||||
|
||||
int shadow_atlas_size;
|
||||
bool shadow_atlas_16_bits = true;
|
||||
ShadowAtlasQuadrantSubdiv shadow_atlas_quadrant_subdiv[4];
|
||||
|
||||
MSAA msaa;
|
||||
@ -537,6 +538,9 @@ public:
|
||||
void set_shadow_atlas_size(int p_size);
|
||||
int get_shadow_atlas_size() const;
|
||||
|
||||
void set_shadow_atlas_16_bits(bool p_16_bits);
|
||||
bool get_shadow_atlas_16_bits() const;
|
||||
|
||||
void set_shadow_atlas_quadrant_subdiv(int p_quadrant, ShadowAtlasQuadrantSubdiv p_subdiv);
|
||||
ShadowAtlasQuadrantSubdiv get_shadow_atlas_quadrant_subdiv(int p_quadrant) const;
|
||||
|
||||
|
@ -702,27 +702,24 @@ void EffectsRD::make_mipmap(RID p_source_rd_texture, RID p_dest_texture, const S
|
||||
RD::get_singleton()->compute_list_end();
|
||||
}
|
||||
|
||||
void EffectsRD::copy_cubemap_to_dp(RID p_source_rd_texture, RID p_dest_texture, const Rect2i &p_rect, float p_z_near, float p_z_far, float p_bias, bool p_dp_flip) {
|
||||
void EffectsRD::copy_cubemap_to_dp(RID p_source_rd_texture, RID p_dst_framebuffer, const Rect2 &p_rect, float p_z_near, float p_z_far, bool p_dp_flip) {
|
||||
CopyToDPPushConstant push_constant;
|
||||
push_constant.screen_size[0] = p_rect.size.x;
|
||||
push_constant.screen_size[1] = p_rect.size.y;
|
||||
push_constant.dest_offset[0] = p_rect.position.x;
|
||||
push_constant.dest_offset[1] = p_rect.position.y;
|
||||
push_constant.bias = p_bias;
|
||||
push_constant.screen_rect[0] = p_rect.position.x;
|
||||
push_constant.screen_rect[1] = p_rect.position.y;
|
||||
push_constant.screen_rect[2] = p_rect.size.width;
|
||||
push_constant.screen_rect[3] = p_rect.size.height;
|
||||
push_constant.z_far = p_z_far;
|
||||
push_constant.z_near = p_z_near;
|
||||
push_constant.z_flip = p_dp_flip;
|
||||
|
||||
int32_t x_groups = (p_rect.size.width - 1) / 8 + 1;
|
||||
int32_t y_groups = (p_rect.size.height - 1) / 8 + 1;
|
||||
RD::DrawListID draw_list = RD::get_singleton()->draw_list_begin(p_dst_framebuffer, RD::INITIAL_ACTION_DROP, RD::FINAL_ACTION_DISCARD, RD::INITIAL_ACTION_KEEP, RD::FINAL_ACTION_READ);
|
||||
RD::get_singleton()->draw_list_bind_render_pipeline(draw_list, cube_to_dp.pipeline.get_render_pipeline(RD::INVALID_ID, RD::get_singleton()->framebuffer_get_format(p_dst_framebuffer)));
|
||||
RD::get_singleton()->draw_list_bind_uniform_set(draw_list, _get_uniform_set_from_texture(p_source_rd_texture), 0);
|
||||
RD::get_singleton()->draw_list_bind_index_array(draw_list, index_array);
|
||||
|
||||
RD::ComputeListID compute_list = RD::get_singleton()->compute_list_begin();
|
||||
RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, cube_to_dp.pipeline);
|
||||
RD::get_singleton()->compute_list_bind_uniform_set(compute_list, _get_compute_uniform_set_from_texture(p_source_rd_texture), 0);
|
||||
RD::get_singleton()->compute_list_bind_uniform_set(compute_list, _get_uniform_set_from_image(p_dest_texture), 1);
|
||||
RD::get_singleton()->compute_list_set_push_constant(compute_list, &push_constant, sizeof(CopyToDPPushConstant));
|
||||
RD::get_singleton()->compute_list_dispatch(compute_list, x_groups, y_groups, 1);
|
||||
RD::get_singleton()->compute_list_end();
|
||||
RD::get_singleton()->draw_list_set_push_constant(draw_list, &push_constant, sizeof(CopyToDPPushConstant));
|
||||
RD::get_singleton()->draw_list_draw(draw_list, true);
|
||||
RD::get_singleton()->draw_list_end();
|
||||
}
|
||||
|
||||
void EffectsRD::tonemapper(RID p_source_color, RID p_dst_framebuffer, const TonemapSettings &p_settings) {
|
||||
@ -1678,8 +1675,12 @@ EffectsRD::EffectsRD() {
|
||||
cube_to_dp.shader.initialize(copy_modes);
|
||||
|
||||
cube_to_dp.shader_version = cube_to_dp.shader.version_create();
|
||||
|
||||
cube_to_dp.pipeline = RD::get_singleton()->compute_pipeline_create(cube_to_dp.shader.version_get_shader(cube_to_dp.shader_version, 0));
|
||||
RID shader = cube_to_dp.shader.version_get_shader(cube_to_dp.shader_version, 0);
|
||||
RD::PipelineDepthStencilState dss;
|
||||
dss.enable_depth_test = true;
|
||||
dss.depth_compare_operator = RD::COMPARE_OP_ALWAYS;
|
||||
dss.enable_depth_write = true;
|
||||
cube_to_dp.pipeline.setup(shader, RD::RENDER_PRIMITIVE_TRIANGLES, RD::PipelineRasterizationState(), RD::PipelineMultisampleState(), dss, RD::PipelineColorBlendState(), 0);
|
||||
}
|
||||
|
||||
{
|
||||
|
@ -234,18 +234,17 @@ class EffectsRD {
|
||||
} luminance_reduce;
|
||||
|
||||
struct CopyToDPPushConstant {
|
||||
int32_t screen_size[2];
|
||||
int32_t dest_offset[2];
|
||||
float bias;
|
||||
float z_far;
|
||||
float z_near;
|
||||
uint32_t z_flip;
|
||||
uint32_t pad;
|
||||
float screen_rect[4];
|
||||
};
|
||||
|
||||
struct CoptToDP {
|
||||
CubeToDpShaderRD shader;
|
||||
RID shader_version;
|
||||
RID pipeline;
|
||||
PipelineCacheRD pipeline;
|
||||
} cube_to_dp;
|
||||
|
||||
struct BokehPushConstant {
|
||||
@ -687,7 +686,7 @@ public:
|
||||
|
||||
void cubemap_roughness(RID p_source_rd_texture, RID p_dest_framebuffer, uint32_t p_face_id, uint32_t p_sample_count, float p_roughness, float p_size);
|
||||
void make_mipmap(RID p_source_rd_texture, RID p_dest_texture, const Size2i &p_size);
|
||||
void copy_cubemap_to_dp(RID p_source_rd_texture, RID p_dest_texture, const Rect2i &p_rect, float p_z_near, float p_z_far, float p_bias, bool p_dp_flip);
|
||||
void copy_cubemap_to_dp(RID p_source_rd_texture, RID p_dest_texture, const Rect2 &p_rect, float p_z_near, float p_z_far, bool p_dp_flip);
|
||||
void luminance_reduction(RID p_source_texture, const Size2i p_source_size, const Vector<RID> p_reduce, RID p_prev_luminance, float p_min_luminance, float p_max_luminance, float p_adjust, bool p_set = false);
|
||||
void bokeh_dof(RID p_base_texture, RID p_depth_texture, const Size2i &p_base_texture_size, RID p_secondary_texture, RID p_bokeh_texture1, RID p_bokeh_texture2, bool p_dof_far, float p_dof_far_begin, float p_dof_far_size, bool p_dof_near, float p_dof_near_begin, float p_dof_near_size, float p_bokeh_size, RS::DOFBokehShape p_bokeh_shape, RS::DOFBlurQuality p_quality, bool p_use_jitter, float p_cam_znear, float p_cam_zfar, bool p_cam_orthogonal);
|
||||
|
||||
|
@ -583,19 +583,6 @@ void RendererSceneRenderForward::RenderBufferDataForward::ensure_specular() {
|
||||
}
|
||||
}
|
||||
|
||||
void RendererSceneRenderForward::RenderBufferDataForward::ensure_gi() {
|
||||
if (!reflection_buffer.is_valid()) {
|
||||
RD::TextureFormat tf;
|
||||
tf.format = RD::DATA_FORMAT_R16G16B16A16_SFLOAT;
|
||||
tf.width = width;
|
||||
tf.height = height;
|
||||
tf.usage_bits = RD::TEXTURE_USAGE_SAMPLING_BIT | RD::TEXTURE_USAGE_STORAGE_BIT;
|
||||
|
||||
reflection_buffer = RD::get_singleton()->texture_create(tf, RD::TextureView());
|
||||
ambient_buffer = RD::get_singleton()->texture_create(tf, RD::TextureView());
|
||||
}
|
||||
}
|
||||
|
||||
void RendererSceneRenderForward::RenderBufferDataForward::ensure_giprobe() {
|
||||
if (!giprobe_buffer.is_valid()) {
|
||||
RD::TextureFormat tf;
|
||||
@ -633,16 +620,6 @@ void RendererSceneRenderForward::RenderBufferDataForward::ensure_giprobe() {
|
||||
}
|
||||
|
||||
void RendererSceneRenderForward::RenderBufferDataForward::clear() {
|
||||
if (ambient_buffer != RID() && ambient_buffer != color) {
|
||||
RD::get_singleton()->free(ambient_buffer);
|
||||
ambient_buffer = RID();
|
||||
}
|
||||
|
||||
if (reflection_buffer != RID() && reflection_buffer != specular) {
|
||||
RD::get_singleton()->free(reflection_buffer);
|
||||
reflection_buffer = RID();
|
||||
}
|
||||
|
||||
if (giprobe_buffer != RID()) {
|
||||
RD::get_singleton()->free(giprobe_buffer);
|
||||
giprobe_buffer = RID();
|
||||
@ -1403,6 +1380,7 @@ void RendererSceneRenderForward::_fill_render_list(const PagedArray<GeometryInst
|
||||
}
|
||||
|
||||
inst->push_constant.gi_offset = probe0_index | (probe1_index << 16);
|
||||
flags |= INSTANCE_DATA_FLAG_USE_GIPROBE;
|
||||
uses_gi = true;
|
||||
} else {
|
||||
if (p_using_sdfgi && inst->can_sdfgi) {
|
||||
@ -1553,7 +1531,6 @@ void RendererSceneRenderForward::_render_scene(RID p_render_buffer, const Transf
|
||||
|
||||
if (!low_end && p_gi_probes.size() > 0) {
|
||||
using_giprobe = true;
|
||||
render_buffer->ensure_gi();
|
||||
}
|
||||
|
||||
if (!p_environment.is_valid() && using_giprobe) {
|
||||
@ -1563,7 +1540,6 @@ void RendererSceneRenderForward::_render_scene(RID p_render_buffer, const Transf
|
||||
if (environment_is_sdfgi_enabled(p_environment)) {
|
||||
depth_pass_mode = using_giprobe ? PASS_MODE_DEPTH_NORMAL_ROUGHNESS_GIPROBE : PASS_MODE_DEPTH_NORMAL_ROUGHNESS; // also giprobe
|
||||
using_sdfgi = true;
|
||||
render_buffer->ensure_gi();
|
||||
} else {
|
||||
depth_pass_mode = using_giprobe ? PASS_MODE_DEPTH_NORMAL_ROUGHNESS_GIPROBE : PASS_MODE_DEPTH_NORMAL_ROUGHNESS;
|
||||
}
|
||||
@ -1739,14 +1715,14 @@ void RendererSceneRenderForward::_render_scene(RID p_render_buffer, const Transf
|
||||
}
|
||||
|
||||
if (using_sdfgi || using_giprobe) {
|
||||
_process_gi(p_render_buffer, render_buffer->normal_roughness_buffer, render_buffer->ambient_buffer, render_buffer->reflection_buffer, render_buffer->giprobe_buffer, p_environment, p_cam_projection, p_cam_transform, p_gi_probes);
|
||||
_process_gi(p_render_buffer, render_buffer->normal_roughness_buffer, render_buffer->giprobe_buffer, p_environment, p_cam_projection, p_cam_transform, p_gi_probes);
|
||||
}
|
||||
|
||||
_setup_environment(p_environment, p_render_buffer, p_cam_projection, p_cam_transform, p_reflection_probe, p_reflection_probe.is_valid(), screen_size, p_cluster_size, p_max_cluster_elements, p_shadow_atlas, !p_reflection_probe.is_valid(), p_default_bg_color, p_cam_projection.get_z_near(), p_cam_projection.get_z_far(), p_render_buffer.is_valid());
|
||||
|
||||
RENDER_TIMESTAMP("Render Opaque Pass");
|
||||
|
||||
RID rp_uniform_set = _setup_render_pass_uniform_set(p_render_buffer, radiance_texture, p_shadow_atlas, p_reflection_atlas, p_cluster_buffer, p_gi_probes, p_lightmaps);
|
||||
RID rp_uniform_set = _setup_render_pass_uniform_set(p_render_buffer, radiance_texture, p_shadow_atlas, p_reflection_atlas, p_cluster_buffer, p_gi_probes, p_lightmaps, true);
|
||||
|
||||
bool can_continue_color = !scene_state.used_screen_texture && !using_ssr && !using_sss;
|
||||
bool can_continue_depth = !scene_state.used_depth_texture && !using_ssr && !using_sss;
|
||||
@ -1862,7 +1838,7 @@ void RendererSceneRenderForward::_render_scene(RID p_render_buffer, const Transf
|
||||
}
|
||||
}
|
||||
|
||||
void RendererSceneRenderForward::_render_shadow(RID p_framebuffer, const PagedArray<GeometryInstance *> &p_instances, const CameraMatrix &p_projection, const Transform &p_transform, float p_zfar, float p_bias, float p_normal_bias, bool p_use_dp, bool p_use_dp_flip, bool p_use_pancake, const Plane &p_camera_plane, float p_lod_distance_multiplier, float p_screen_lod_threshold) {
|
||||
void RendererSceneRenderForward::_render_shadow(RID p_framebuffer, const PagedArray<GeometryInstance *> &p_instances, const CameraMatrix &p_projection, const Transform &p_transform, float p_zfar, float p_bias, float p_normal_bias, bool p_use_dp, bool p_use_dp_flip, bool p_use_pancake, const Plane &p_camera_plane, float p_lod_distance_multiplier, float p_screen_lod_threshold, const Rect2i &p_rect, bool p_flip_y, bool p_clear_region, bool p_begin, bool p_end) {
|
||||
RENDER_TIMESTAMP("Setup Rendering Shadow");
|
||||
|
||||
_update_render_base_uniform_set();
|
||||
@ -1871,7 +1847,7 @@ void RendererSceneRenderForward::_render_shadow(RID p_framebuffer, const PagedAr
|
||||
|
||||
scene_state.ubo.dual_paraboloid_side = p_use_dp_flip ? -1 : 1;
|
||||
|
||||
_setup_environment(RID(), RID(), p_projection, p_transform, RID(), true, Vector2(1, 1), 1, 32, RID(), true, Color(), 0, p_zfar, false, p_use_pancake);
|
||||
_setup_environment(RID(), RID(), p_projection, p_transform, RID(), true, Vector2(1, 1), 1, 32, RID(), !p_flip_y, Color(), 0, p_zfar, false, p_use_pancake);
|
||||
|
||||
if (get_debug_draw_mode() == RS::VIEWPORT_DEBUG_DRAW_DISABLE_LOD) {
|
||||
p_screen_lod_threshold = 0.0;
|
||||
@ -1889,8 +1865,12 @@ void RendererSceneRenderForward::_render_shadow(RID p_framebuffer, const PagedAr
|
||||
|
||||
{
|
||||
//regular forward for now
|
||||
RenderListParameters render_list_params(render_list.elements, render_list.element_count, p_use_dp_flip, pass_mode, true, rp_uniform_set, false, Vector2(), p_camera_plane, p_lod_distance_multiplier, p_screen_lod_threshold);
|
||||
_render_list_with_threads(&render_list_params, p_framebuffer, RD::INITIAL_ACTION_CLEAR, RD::FINAL_ACTION_READ, RD::INITIAL_ACTION_CLEAR, RD::FINAL_ACTION_READ);
|
||||
bool flip_cull = p_use_dp_flip;
|
||||
if (p_flip_y) {
|
||||
flip_cull = !flip_cull;
|
||||
}
|
||||
RenderListParameters render_list_params(render_list.elements, render_list.element_count, flip_cull, pass_mode, true, rp_uniform_set, false, Vector2(), p_camera_plane, p_lod_distance_multiplier, p_screen_lod_threshold);
|
||||
_render_list_with_threads(&render_list_params, p_framebuffer, RD::INITIAL_ACTION_DROP, RD::FINAL_ACTION_DISCARD, p_begin ? (p_clear_region ? RD::INITIAL_ACTION_CLEAR_REGION : RD::INITIAL_ACTION_CLEAR) : RD::INITIAL_ACTION_CONTINUE, p_end ? RD::FINAL_ACTION_READ : RD::FINAL_ACTION_CONTINUE, Vector<Color>(), 1.0, 0, p_rect);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1930,7 +1910,7 @@ void RendererSceneRenderForward::_render_material(const Transform &p_cam_transfo
|
||||
render_pass++;
|
||||
|
||||
scene_state.ubo.dual_paraboloid_side = 0;
|
||||
scene_state.ubo.material_uv2_mode = true;
|
||||
scene_state.ubo.material_uv2_mode = false;
|
||||
|
||||
_setup_environment(RID(), RID(), p_cam_projection, p_cam_transform, RID(), true, Vector2(1, 1), 1, 32, RID(), false, Color(), 0, 0);
|
||||
|
||||
@ -2152,14 +2132,14 @@ void RendererSceneRenderForward::_update_render_base_uniform_set() {
|
||||
|
||||
{
|
||||
RD::Uniform u;
|
||||
u.binding = 5;
|
||||
u.binding = 4;
|
||||
u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER;
|
||||
u.ids.push_back(get_omni_light_buffer());
|
||||
uniforms.push_back(u);
|
||||
}
|
||||
{
|
||||
RD::Uniform u;
|
||||
u.binding = 6;
|
||||
u.binding = 5;
|
||||
u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER;
|
||||
u.ids.push_back(get_spot_light_buffer());
|
||||
uniforms.push_back(u);
|
||||
@ -2167,35 +2147,35 @@ void RendererSceneRenderForward::_update_render_base_uniform_set() {
|
||||
|
||||
{
|
||||
RD::Uniform u;
|
||||
u.binding = 7;
|
||||
u.binding = 6;
|
||||
u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER;
|
||||
u.ids.push_back(get_reflection_probe_buffer());
|
||||
uniforms.push_back(u);
|
||||
}
|
||||
{
|
||||
RD::Uniform u;
|
||||
u.binding = 8;
|
||||
u.binding = 7;
|
||||
u.uniform_type = RD::UNIFORM_TYPE_UNIFORM_BUFFER;
|
||||
u.ids.push_back(get_directional_light_buffer());
|
||||
uniforms.push_back(u);
|
||||
}
|
||||
{
|
||||
RD::Uniform u;
|
||||
u.binding = 10;
|
||||
u.binding = 8;
|
||||
u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER;
|
||||
u.ids.push_back(scene_state.lightmap_buffer);
|
||||
uniforms.push_back(u);
|
||||
}
|
||||
{
|
||||
RD::Uniform u;
|
||||
u.binding = 11;
|
||||
u.binding = 9;
|
||||
u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER;
|
||||
u.ids.push_back(scene_state.lightmap_capture_buffer);
|
||||
uniforms.push_back(u);
|
||||
}
|
||||
{
|
||||
RD::Uniform u;
|
||||
u.binding = 12;
|
||||
u.binding = 10;
|
||||
u.uniform_type = RD::UNIFORM_TYPE_TEXTURE;
|
||||
RID decal_atlas = storage->decal_atlas_get_texture();
|
||||
u.ids.push_back(decal_atlas);
|
||||
@ -2203,7 +2183,7 @@ void RendererSceneRenderForward::_update_render_base_uniform_set() {
|
||||
}
|
||||
{
|
||||
RD::Uniform u;
|
||||
u.binding = 13;
|
||||
u.binding = 11;
|
||||
u.uniform_type = RD::UNIFORM_TYPE_TEXTURE;
|
||||
RID decal_atlas = storage->decal_atlas_get_texture_srgb();
|
||||
u.ids.push_back(decal_atlas);
|
||||
@ -2211,28 +2191,16 @@ void RendererSceneRenderForward::_update_render_base_uniform_set() {
|
||||
}
|
||||
{
|
||||
RD::Uniform u;
|
||||
u.binding = 14;
|
||||
u.binding = 12;
|
||||
u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER;
|
||||
u.ids.push_back(get_decal_buffer());
|
||||
uniforms.push_back(u);
|
||||
}
|
||||
|
||||
{
|
||||
RD::Uniform u;
|
||||
u.binding = 15;
|
||||
u.uniform_type = RD::UNIFORM_TYPE_TEXTURE;
|
||||
if (directional_shadow_get_texture().is_valid()) {
|
||||
u.ids.push_back(directional_shadow_get_texture());
|
||||
} else {
|
||||
u.ids.push_back(storage->texture_rd_get_default(RendererStorageRD::DEFAULT_RD_TEXTURE_WHITE));
|
||||
}
|
||||
uniforms.push_back(u);
|
||||
}
|
||||
|
||||
{
|
||||
RD::Uniform u;
|
||||
u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER;
|
||||
u.binding = 16;
|
||||
u.binding = 13;
|
||||
u.ids.push_back(storage->global_variables_get_storage_buffer());
|
||||
uniforms.push_back(u);
|
||||
}
|
||||
@ -2240,7 +2208,7 @@ void RendererSceneRenderForward::_update_render_base_uniform_set() {
|
||||
if (!low_end) {
|
||||
RD::Uniform u;
|
||||
u.uniform_type = RD::UNIFORM_TYPE_UNIFORM_BUFFER;
|
||||
u.binding = 17;
|
||||
u.binding = 14;
|
||||
u.ids.push_back(sdfgi_get_ubo());
|
||||
uniforms.push_back(u);
|
||||
}
|
||||
@ -2249,7 +2217,7 @@ void RendererSceneRenderForward::_update_render_base_uniform_set() {
|
||||
}
|
||||
}
|
||||
|
||||
RID RendererSceneRenderForward::_setup_render_pass_uniform_set(RID p_render_buffers, RID p_radiance_texture, RID p_shadow_atlas, RID p_reflection_atlas, RID p_cluster_buffer, const PagedArray<RID> &p_gi_probes, const PagedArray<RID> &p_lightmaps) {
|
||||
RID RendererSceneRenderForward::_setup_render_pass_uniform_set(RID p_render_buffers, RID p_radiance_texture, RID p_shadow_atlas, RID p_reflection_atlas, RID p_cluster_buffer, const PagedArray<RID> &p_gi_probes, const PagedArray<RID> &p_lightmaps, bool p_use_directional_shadow_atlas) {
|
||||
if (render_pass_uniform_set.is_valid() && RD::get_singleton()->uniform_set_is_valid(render_pass_uniform_set)) {
|
||||
RD::get_singleton()->free(render_pass_uniform_set);
|
||||
}
|
||||
@ -2308,6 +2276,17 @@ RID RendererSceneRenderForward::_setup_render_pass_uniform_set(RID p_render_buff
|
||||
RD::Uniform u;
|
||||
u.binding = 3;
|
||||
u.uniform_type = RD::UNIFORM_TYPE_TEXTURE;
|
||||
if (p_use_directional_shadow_atlas && directional_shadow_get_texture().is_valid()) {
|
||||
u.ids.push_back(directional_shadow_get_texture());
|
||||
} else {
|
||||
u.ids.push_back(storage->texture_rd_get_default(RendererStorageRD::DEFAULT_RD_TEXTURE_WHITE));
|
||||
}
|
||||
uniforms.push_back(u);
|
||||
}
|
||||
{
|
||||
RD::Uniform u;
|
||||
u.binding = 4;
|
||||
u.uniform_type = RD::UNIFORM_TYPE_TEXTURE;
|
||||
u.ids.resize(scene_state.max_lightmaps);
|
||||
RID default_tex = storage->texture_rd_get_default(RendererStorageRD::DEFAULT_RD_TEXTURE_2D_ARRAY_WHITE);
|
||||
for (uint32_t i = 0; i < scene_state.max_lightmaps; i++) {
|
||||
@ -2325,7 +2304,7 @@ RID RendererSceneRenderForward::_setup_render_pass_uniform_set(RID p_render_buff
|
||||
}
|
||||
{
|
||||
RD::Uniform u;
|
||||
u.binding = 4;
|
||||
u.binding = 5;
|
||||
u.uniform_type = RD::UNIFORM_TYPE_TEXTURE;
|
||||
u.ids.resize(MAX_GI_PROBES);
|
||||
RID default_tex = storage->texture_rd_get_default(RendererStorageRD::DEFAULT_RD_TEXTURE_3D_WHITE);
|
||||
@ -2346,7 +2325,7 @@ RID RendererSceneRenderForward::_setup_render_pass_uniform_set(RID p_render_buff
|
||||
|
||||
{
|
||||
RD::Uniform u;
|
||||
u.binding = 5;
|
||||
u.binding = 6;
|
||||
u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER;
|
||||
RID cb = p_cluster_buffer.is_valid() ? p_cluster_buffer : default_vec4_xform_buffer;
|
||||
u.ids.push_back(cb);
|
||||
@ -2355,7 +2334,7 @@ RID RendererSceneRenderForward::_setup_render_pass_uniform_set(RID p_render_buff
|
||||
|
||||
{
|
||||
RD::Uniform u;
|
||||
u.binding = 6;
|
||||
u.binding = 7;
|
||||
u.uniform_type = RD::UNIFORM_TYPE_TEXTURE;
|
||||
RID texture = (false && rb && rb->depth.is_valid()) ? rb->depth : storage->texture_rd_get_default(RendererStorageRD::DEFAULT_RD_TEXTURE_WHITE);
|
||||
u.ids.push_back(texture);
|
||||
@ -2363,7 +2342,7 @@ RID RendererSceneRenderForward::_setup_render_pass_uniform_set(RID p_render_buff
|
||||
}
|
||||
{
|
||||
RD::Uniform u;
|
||||
u.binding = 7;
|
||||
u.binding = 8;
|
||||
u.uniform_type = RD::UNIFORM_TYPE_TEXTURE;
|
||||
RID bbt = rb ? render_buffers_get_back_buffer_texture(p_render_buffers) : RID();
|
||||
RID texture = bbt.is_valid() ? bbt : storage->texture_rd_get_default(RendererStorageRD::DEFAULT_RD_TEXTURE_BLACK);
|
||||
@ -2374,7 +2353,7 @@ RID RendererSceneRenderForward::_setup_render_pass_uniform_set(RID p_render_buff
|
||||
if (!low_end) {
|
||||
{
|
||||
RD::Uniform u;
|
||||
u.binding = 8;
|
||||
u.binding = 9;
|
||||
u.uniform_type = RD::UNIFORM_TYPE_TEXTURE;
|
||||
RID texture = rb && rb->normal_roughness_buffer.is_valid() ? rb->normal_roughness_buffer : storage->texture_rd_get_default(RendererStorageRD::DEFAULT_RD_TEXTURE_NORMAL);
|
||||
u.ids.push_back(texture);
|
||||
@ -2383,7 +2362,7 @@ RID RendererSceneRenderForward::_setup_render_pass_uniform_set(RID p_render_buff
|
||||
|
||||
{
|
||||
RD::Uniform u;
|
||||
u.binding = 9;
|
||||
u.binding = 10;
|
||||
u.uniform_type = RD::UNIFORM_TYPE_TEXTURE;
|
||||
RID aot = rb ? render_buffers_get_ao_texture(p_render_buffers) : RID();
|
||||
RID texture = aot.is_valid() ? aot : storage->texture_rd_get_default(RendererStorageRD::DEFAULT_RD_TEXTURE_BLACK);
|
||||
@ -2393,24 +2372,26 @@ RID RendererSceneRenderForward::_setup_render_pass_uniform_set(RID p_render_buff
|
||||
|
||||
{
|
||||
RD::Uniform u;
|
||||
u.binding = 10;
|
||||
u.binding = 11;
|
||||
u.uniform_type = RD::UNIFORM_TYPE_TEXTURE;
|
||||
RID texture = rb && rb->ambient_buffer.is_valid() ? rb->ambient_buffer : storage->texture_rd_get_default(RendererStorageRD::DEFAULT_RD_TEXTURE_BLACK);
|
||||
RID ambient_buffer = p_render_buffers.is_valid() ? render_buffers_get_gi_ambient_texture(p_render_buffers) : RID();
|
||||
RID texture = ambient_buffer.is_valid() ? ambient_buffer : storage->texture_rd_get_default(RendererStorageRD::DEFAULT_RD_TEXTURE_BLACK);
|
||||
u.ids.push_back(texture);
|
||||
uniforms.push_back(u);
|
||||
}
|
||||
|
||||
{
|
||||
RD::Uniform u;
|
||||
u.binding = 11;
|
||||
u.binding = 12;
|
||||
u.uniform_type = RD::UNIFORM_TYPE_TEXTURE;
|
||||
RID texture = rb && rb->reflection_buffer.is_valid() ? rb->reflection_buffer : storage->texture_rd_get_default(RendererStorageRD::DEFAULT_RD_TEXTURE_BLACK);
|
||||
RID reflection_buffer = p_render_buffers.is_valid() ? render_buffers_get_gi_reflection_texture(p_render_buffers) : RID();
|
||||
RID texture = reflection_buffer.is_valid() ? reflection_buffer : storage->texture_rd_get_default(RendererStorageRD::DEFAULT_RD_TEXTURE_BLACK);
|
||||
u.ids.push_back(texture);
|
||||
uniforms.push_back(u);
|
||||
}
|
||||
{
|
||||
RD::Uniform u;
|
||||
u.binding = 12;
|
||||
u.binding = 13;
|
||||
u.uniform_type = RD::UNIFORM_TYPE_TEXTURE;
|
||||
RID t;
|
||||
if (rb && render_buffers_is_sdfgi_enabled(p_render_buffers)) {
|
||||
@ -2423,7 +2404,7 @@ RID RendererSceneRenderForward::_setup_render_pass_uniform_set(RID p_render_buff
|
||||
}
|
||||
{
|
||||
RD::Uniform u;
|
||||
u.binding = 13;
|
||||
u.binding = 14;
|
||||
u.uniform_type = RD::UNIFORM_TYPE_TEXTURE;
|
||||
if (rb && render_buffers_is_sdfgi_enabled(p_render_buffers)) {
|
||||
u.ids.push_back(render_buffers_get_sdfgi_occlusion_texture(p_render_buffers));
|
||||
@ -2434,14 +2415,14 @@ RID RendererSceneRenderForward::_setup_render_pass_uniform_set(RID p_render_buff
|
||||
}
|
||||
{
|
||||
RD::Uniform u;
|
||||
u.binding = 14;
|
||||
u.binding = 15;
|
||||
u.uniform_type = RD::UNIFORM_TYPE_UNIFORM_BUFFER;
|
||||
u.ids.push_back(rb ? render_buffers_get_gi_probe_buffer(p_render_buffers) : render_buffers_get_default_gi_probe_buffer());
|
||||
uniforms.push_back(u);
|
||||
}
|
||||
{
|
||||
RD::Uniform u;
|
||||
u.binding = 15;
|
||||
u.binding = 16;
|
||||
u.uniform_type = RD::UNIFORM_TYPE_TEXTURE;
|
||||
RID vfog = RID();
|
||||
if (rb && render_buffers_has_volumetric_fog(p_render_buffers)) {
|
||||
@ -2499,10 +2480,20 @@ RID RendererSceneRenderForward::_setup_sdfgi_render_pass_uniform_set(RID p_albed
|
||||
}
|
||||
|
||||
{
|
||||
// No Lightmaps
|
||||
// No directional shadow atlas.
|
||||
RD::Uniform u;
|
||||
u.binding = 3;
|
||||
u.uniform_type = RD::UNIFORM_TYPE_TEXTURE;
|
||||
RID texture = storage->texture_rd_get_default(RendererStorageRD::DEFAULT_RD_TEXTURE_WHITE);
|
||||
u.ids.push_back(texture);
|
||||
uniforms.push_back(u);
|
||||
}
|
||||
|
||||
{
|
||||
// No Lightmaps
|
||||
RD::Uniform u;
|
||||
u.binding = 4;
|
||||
u.uniform_type = RD::UNIFORM_TYPE_TEXTURE;
|
||||
u.ids.resize(scene_state.max_lightmaps);
|
||||
RID default_tex = storage->texture_rd_get_default(RendererStorageRD::DEFAULT_RD_TEXTURE_2D_ARRAY_WHITE);
|
||||
for (uint32_t i = 0; i < scene_state.max_lightmaps; i++) {
|
||||
@ -2515,7 +2506,7 @@ RID RendererSceneRenderForward::_setup_sdfgi_render_pass_uniform_set(RID p_albed
|
||||
{
|
||||
// No GIProbes
|
||||
RD::Uniform u;
|
||||
u.binding = 4;
|
||||
u.binding = 5;
|
||||
u.uniform_type = RD::UNIFORM_TYPE_TEXTURE;
|
||||
u.ids.resize(MAX_GI_PROBES);
|
||||
RID default_tex = storage->texture_rd_get_default(RendererStorageRD::DEFAULT_RD_TEXTURE_3D_WHITE);
|
||||
@ -2528,7 +2519,7 @@ RID RendererSceneRenderForward::_setup_sdfgi_render_pass_uniform_set(RID p_albed
|
||||
|
||||
{
|
||||
RD::Uniform u;
|
||||
u.binding = 5;
|
||||
u.binding = 6;
|
||||
u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER;
|
||||
RID cb = default_vec4_xform_buffer;
|
||||
u.ids.push_back(cb);
|
||||
@ -2540,28 +2531,28 @@ RID RendererSceneRenderForward::_setup_sdfgi_render_pass_uniform_set(RID p_albed
|
||||
{
|
||||
RD::Uniform u;
|
||||
u.uniform_type = RD::UNIFORM_TYPE_IMAGE;
|
||||
u.binding = 6;
|
||||
u.binding = 7;
|
||||
u.ids.push_back(p_albedo_texture);
|
||||
uniforms.push_back(u);
|
||||
}
|
||||
{
|
||||
RD::Uniform u;
|
||||
u.uniform_type = RD::UNIFORM_TYPE_IMAGE;
|
||||
u.binding = 7;
|
||||
u.binding = 8;
|
||||
u.ids.push_back(p_emission_texture);
|
||||
uniforms.push_back(u);
|
||||
}
|
||||
{
|
||||
RD::Uniform u;
|
||||
u.uniform_type = RD::UNIFORM_TYPE_IMAGE;
|
||||
u.binding = 8;
|
||||
u.binding = 9;
|
||||
u.ids.push_back(p_emission_aniso_texture);
|
||||
uniforms.push_back(u);
|
||||
}
|
||||
{
|
||||
RD::Uniform u;
|
||||
u.uniform_type = RD::UNIFORM_TYPE_IMAGE;
|
||||
u.binding = 9;
|
||||
u.binding = 10;
|
||||
u.ids.push_back(p_geom_facing_texture);
|
||||
uniforms.push_back(u);
|
||||
}
|
||||
@ -2585,18 +2576,6 @@ RID RendererSceneRenderForward::_render_buffers_get_normal_texture(RID p_render_
|
||||
return rb->normal_roughness_buffer;
|
||||
}
|
||||
|
||||
RID RendererSceneRenderForward::_render_buffers_get_ambient_texture(RID p_render_buffers) {
|
||||
RenderBufferDataForward *rb = (RenderBufferDataForward *)render_buffers_get_data(p_render_buffers);
|
||||
|
||||
return rb->ambient_buffer;
|
||||
}
|
||||
|
||||
RID RendererSceneRenderForward::_render_buffers_get_reflection_texture(RID p_render_buffers) {
|
||||
RenderBufferDataForward *rb = (RenderBufferDataForward *)render_buffers_get_data(p_render_buffers);
|
||||
|
||||
return rb->reflection_buffer;
|
||||
}
|
||||
|
||||
RendererSceneRenderForward *RendererSceneRenderForward::singleton = nullptr;
|
||||
|
||||
void RendererSceneRenderForward::set_time(double p_time, double p_step) {
|
||||
|
@ -213,9 +213,6 @@ class RendererSceneRenderForward : public RendererSceneRenderRD {
|
||||
RID normal_roughness_buffer;
|
||||
RID giprobe_buffer;
|
||||
|
||||
RID ambient_buffer;
|
||||
RID reflection_buffer;
|
||||
|
||||
RS::ViewportMSAA msaa;
|
||||
RD::TextureSamples texture_samples;
|
||||
|
||||
@ -236,7 +233,6 @@ class RendererSceneRenderForward : public RendererSceneRenderRD {
|
||||
|
||||
RID render_sdfgi_uniform_set;
|
||||
void ensure_specular();
|
||||
void ensure_gi();
|
||||
void ensure_giprobe();
|
||||
void clear();
|
||||
virtual void configure(RID p_color_buffer, RID p_depth_buffer, int p_width, int p_height, RS::ViewportMSAA p_msaa);
|
||||
@ -258,12 +254,10 @@ class RendererSceneRenderForward : public RendererSceneRenderRD {
|
||||
void _render_buffers_clear_uniform_set(RenderBufferDataForward *rb);
|
||||
virtual void _render_buffers_uniform_set_changed(RID p_render_buffers);
|
||||
virtual RID _render_buffers_get_normal_texture(RID p_render_buffers);
|
||||
virtual RID _render_buffers_get_ambient_texture(RID p_render_buffers);
|
||||
virtual RID _render_buffers_get_reflection_texture(RID p_render_buffers);
|
||||
|
||||
void _update_render_base_uniform_set();
|
||||
RID _setup_sdfgi_render_pass_uniform_set(RID p_albedo_texture, RID p_emission_texture, RID p_emission_aniso_texture, RID p_geom_facing_texture);
|
||||
RID _setup_render_pass_uniform_set(RID p_render_buffers, RID p_radiance_texture, RID p_shadow_atlas, RID p_reflection_atlas, RID p_cluster_buffer, const PagedArray<RID> &p_gi_probes, const PagedArray<RID> &p_lightmaps);
|
||||
RID _setup_render_pass_uniform_set(RID p_render_buffers, RID p_radiance_texture, RID p_shadow_atlas, RID p_reflection_atlas, RID p_cluster_buffer, const PagedArray<RID> &p_gi_probes, const PagedArray<RID> &p_lightmaps, bool p_use_directional_shadow_atlas = false);
|
||||
|
||||
struct LightmapData {
|
||||
float normal_xform[12];
|
||||
@ -707,7 +701,7 @@ class RendererSceneRenderForward : public RendererSceneRenderRD {
|
||||
|
||||
protected:
|
||||
virtual void _render_scene(RID p_render_buffer, const Transform &p_cam_transform, const CameraMatrix &p_cam_projection, bool p_cam_ortogonal, const PagedArray<GeometryInstance *> &p_instances, int p_directional_light_count, const PagedArray<RID> &p_gi_probes, const PagedArray<RID> &p_lightmaps, RID p_environment, RID p_cluster_buffer, uint32_t p_cluster_size, uint32_t p_max_cluster_elements, RID p_camera_effects, RID p_shadow_atlas, RID p_reflection_atlas, RID p_reflection_probe, int p_reflection_probe_pass, const Color &p_default_bg_color, float p_lod_threshold);
|
||||
virtual void _render_shadow(RID p_framebuffer, const PagedArray<GeometryInstance *> &p_instances, const CameraMatrix &p_projection, const Transform &p_transform, float p_zfar, float p_bias, float p_normal_bias, bool p_use_dp, bool p_use_dp_flip, bool p_use_pancake, const Plane &p_camera_plane = Plane(), float p_lod_distance_multiplier = 0.0, float p_screen_lod_threshold = 0.0);
|
||||
virtual void _render_shadow(RID p_framebuffer, const PagedArray<GeometryInstance *> &p_instances, const CameraMatrix &p_projection, const Transform &p_transform, float p_zfar, float p_bias, float p_normal_bias, bool p_use_dp, bool use_dp_flip, bool p_use_pancake, const Plane &p_camera_plane = Plane(), float p_lod_distance_multiplier = 0.0, float p_screen_lod_threshold = 0.0, const Rect2i &p_rect = Rect2i(), bool p_flip_y = false, bool p_clear_region = true, bool p_begin = true, bool p_end = true);
|
||||
virtual void _render_material(const Transform &p_cam_transform, const CameraMatrix &p_cam_projection, bool p_cam_ortogonal, const PagedArray<GeometryInstance *> &p_instances, RID p_framebuffer, const Rect2i &p_region);
|
||||
virtual void _render_uv2(const PagedArray<GeometryInstance *> &p_instances, RID p_framebuffer, const Rect2i &p_region);
|
||||
virtual void _render_sdfgi(RID p_render_buffers, const Vector3i &p_from, const Vector3i &p_size, const AABB &p_bounds, const PagedArray<GeometryInstance *> &p_instances, const RID &p_albedo_texture, const RID &p_emission_texture, const RID &p_emission_aniso_texture, const RID &p_geom_facing_texture);
|
||||
|
@ -1276,14 +1276,26 @@ void RendererSceneRenderRD::sdfgi_update_probes(RID p_render_buffers, RID p_envi
|
||||
push_constant.multibounce = rb->sdfgi->uses_multibounce;
|
||||
push_constant.y_mult = rb->sdfgi->y_mult;
|
||||
|
||||
push_constant.process_offset = 0;
|
||||
push_constant.process_increment = 1;
|
||||
|
||||
for (uint32_t i = 0; i < rb->sdfgi->cascades.size(); i++) {
|
||||
SDFGI::Cascade &cascade = rb->sdfgi->cascades[i];
|
||||
push_constant.light_count = cascade_light_count[i];
|
||||
push_constant.cascade = i;
|
||||
|
||||
if (rb->sdfgi->cascades[i].all_dynamic_lights_dirty || sdfgi_frames_to_update_light == RS::ENV_SDFGI_UPDATE_LIGHT_IN_1_FRAME) {
|
||||
push_constant.process_offset = 0;
|
||||
push_constant.process_increment = 1;
|
||||
} else {
|
||||
static uint32_t frames_to_update_table[RS::ENV_SDFGI_UPDATE_LIGHT_MAX] = {
|
||||
1, 2, 4, 8, 16
|
||||
};
|
||||
|
||||
uint32_t frames_to_update = frames_to_update_table[sdfgi_frames_to_update_light];
|
||||
|
||||
push_constant.process_offset = RSG::rasterizer->get_frame_number() % frames_to_update;
|
||||
push_constant.process_increment = frames_to_update;
|
||||
}
|
||||
rb->sdfgi->cascades[i].all_dynamic_lights_dirty = false;
|
||||
|
||||
RD::get_singleton()->compute_list_bind_uniform_set(compute_list, cascade.sdf_direct_light_uniform_set, 0);
|
||||
RD::get_singleton()->compute_list_set_push_constant(compute_list, &push_constant, sizeof(SDGIShader::DirectLightPushConstant));
|
||||
RD::get_singleton()->compute_list_dispatch_indirect(compute_list, cascade.solid_cell_dispatch_buffer, 0);
|
||||
@ -1301,7 +1313,7 @@ void RendererSceneRenderRD::sdfgi_update_probes(RID p_render_buffers, RID p_envi
|
||||
push_constant.probe_axis_size = rb->sdfgi->probe_axis_count;
|
||||
push_constant.history_index = rb->sdfgi->render_pass % rb->sdfgi->history_size;
|
||||
push_constant.history_size = rb->sdfgi->history_size;
|
||||
static const uint32_t ray_count[RS::ENV_SDFGI_RAY_COUNT_MAX] = { 8, 16, 32, 64, 96, 128 };
|
||||
static const uint32_t ray_count[RS::ENV_SDFGI_RAY_COUNT_MAX] = { 4, 8, 16, 32, 64, 96, 128 };
|
||||
push_constant.ray_count = ray_count[sdfgi_ray_count];
|
||||
push_constant.ray_bias = rb->sdfgi->probe_bias;
|
||||
push_constant.image_size[0] = rb->sdfgi->probe_axis_count * rb->sdfgi->probe_axis_count;
|
||||
@ -1492,13 +1504,35 @@ void RendererSceneRenderRD::_setup_giprobes(RID p_render_buffers, const Transfor
|
||||
}
|
||||
}
|
||||
|
||||
void RendererSceneRenderRD::_process_gi(RID p_render_buffers, RID p_normal_roughness_buffer, RID p_ambient_buffer, RID p_reflection_buffer, RID p_gi_probe_buffer, RID p_environment, const CameraMatrix &p_projection, const Transform &p_transform, const PagedArray<RID> &p_gi_probes) {
|
||||
void RendererSceneRenderRD::_process_gi(RID p_render_buffers, RID p_normal_roughness_buffer, RID p_gi_probe_buffer, RID p_environment, const CameraMatrix &p_projection, const Transform &p_transform, const PagedArray<RID> &p_gi_probes) {
|
||||
RENDER_TIMESTAMP("Render GI");
|
||||
|
||||
RenderBuffers *rb = render_buffers_owner.getornull(p_render_buffers);
|
||||
ERR_FAIL_COND(rb == nullptr);
|
||||
Environment *env = environment_owner.getornull(p_environment);
|
||||
|
||||
if (rb->ambient_buffer.is_null() || rb->using_half_size_gi != gi.half_resolution) {
|
||||
if (rb->ambient_buffer.is_valid()) {
|
||||
RD::get_singleton()->free(rb->ambient_buffer);
|
||||
RD::get_singleton()->free(rb->reflection_buffer);
|
||||
}
|
||||
|
||||
RD::TextureFormat tf;
|
||||
tf.format = RD::DATA_FORMAT_R16G16B16A16_SFLOAT;
|
||||
tf.width = rb->width;
|
||||
tf.height = rb->height;
|
||||
if (gi.half_resolution) {
|
||||
tf.width >>= 1;
|
||||
tf.height >>= 1;
|
||||
}
|
||||
tf.usage_bits = RD::TEXTURE_USAGE_SAMPLING_BIT | RD::TEXTURE_USAGE_STORAGE_BIT;
|
||||
rb->reflection_buffer = RD::get_singleton()->texture_create(tf, RD::TextureView());
|
||||
rb->ambient_buffer = RD::get_singleton()->texture_create(tf, RD::TextureView());
|
||||
rb->using_half_size_gi = gi.half_resolution;
|
||||
|
||||
_render_buffers_uniform_set_changed(p_render_buffers);
|
||||
}
|
||||
|
||||
GI::PushConstant push_constant;
|
||||
|
||||
push_constant.screen_size[0] = rb->width;
|
||||
@ -1693,7 +1727,7 @@ void RendererSceneRenderRD::_process_gi(RID p_render_buffers, RID p_normal_rough
|
||||
RD::Uniform u;
|
||||
u.uniform_type = RD::UNIFORM_TYPE_IMAGE;
|
||||
u.binding = 9;
|
||||
u.ids.push_back(p_ambient_buffer);
|
||||
u.ids.push_back(rb->ambient_buffer);
|
||||
uniforms.push_back(u);
|
||||
}
|
||||
|
||||
@ -1701,7 +1735,7 @@ void RendererSceneRenderRD::_process_gi(RID p_render_buffers, RID p_normal_rough
|
||||
RD::Uniform u;
|
||||
u.uniform_type = RD::UNIFORM_TYPE_IMAGE;
|
||||
u.binding = 10;
|
||||
u.ids.push_back(p_reflection_buffer);
|
||||
u.ids.push_back(rb->reflection_buffer);
|
||||
uniforms.push_back(u);
|
||||
}
|
||||
|
||||
@ -1765,12 +1799,23 @@ void RendererSceneRenderRD::_process_gi(RID p_render_buffers, RID p_normal_rough
|
||||
rb->gi_uniform_set = RD::get_singleton()->uniform_set_create(uniforms, gi.shader.version_get_shader(gi.shader_version, 0), 0);
|
||||
}
|
||||
|
||||
GI::Mode mode = (use_sdfgi && use_giprobes) ? GI::MODE_COMBINED : (use_sdfgi ? GI::MODE_SDFGI : GI::MODE_GIPROBE);
|
||||
GI::Mode mode;
|
||||
|
||||
if (rb->using_half_size_gi) {
|
||||
mode = (use_sdfgi && use_giprobes) ? GI::MODE_HALF_RES_COMBINED : (use_sdfgi ? GI::MODE_HALF_RES_SDFGI : GI::MODE_HALF_RES_GIPROBE);
|
||||
} else {
|
||||
mode = (use_sdfgi && use_giprobes) ? GI::MODE_COMBINED : (use_sdfgi ? GI::MODE_SDFGI : GI::MODE_GIPROBE);
|
||||
}
|
||||
RD::ComputeListID compute_list = RD::get_singleton()->compute_list_begin();
|
||||
RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, gi.pipelines[mode]);
|
||||
RD::get_singleton()->compute_list_bind_uniform_set(compute_list, rb->gi_uniform_set, 0);
|
||||
RD::get_singleton()->compute_list_set_push_constant(compute_list, &push_constant, sizeof(GI::PushConstant));
|
||||
RD::get_singleton()->compute_list_dispatch_threads(compute_list, rb->width, rb->height, 1, 8, 8, 1);
|
||||
|
||||
if (rb->using_half_size_gi) {
|
||||
RD::get_singleton()->compute_list_dispatch_threads(compute_list, rb->width >> 1, rb->height >> 1, 1, 8, 8, 1);
|
||||
} else {
|
||||
RD::get_singleton()->compute_list_dispatch_threads(compute_list, rb->width, rb->height, 1, 8, 8, 1);
|
||||
}
|
||||
RD::get_singleton()->compute_list_end();
|
||||
}
|
||||
|
||||
@ -3105,6 +3150,9 @@ void RendererSceneRenderRD::environment_set_sdfgi_ray_count(RS::EnvironmentSDFGI
|
||||
void RendererSceneRenderRD::environment_set_sdfgi_frames_to_converge(RS::EnvironmentSDFGIFramesToConverge p_frames) {
|
||||
sdfgi_frames_to_converge = p_frames;
|
||||
}
|
||||
void RendererSceneRenderRD::environment_set_sdfgi_frames_to_update_light(RS::EnvironmentSDFGIFramesToUpdateLight p_update) {
|
||||
sdfgi_frames_to_update_light = p_update;
|
||||
}
|
||||
|
||||
void RendererSceneRenderRD::environment_set_ssr(RID p_env, bool p_enable, int p_max_steps, float p_fade_int, float p_fade_out, float p_depth_tolerance) {
|
||||
Environment *env = environment_owner.getornull(p_env);
|
||||
@ -3516,13 +3564,28 @@ RID RendererSceneRenderRD::shadow_atlas_create() {
|
||||
return shadow_atlas_owner.make_rid(ShadowAtlas());
|
||||
}
|
||||
|
||||
void RendererSceneRenderRD::shadow_atlas_set_size(RID p_atlas, int p_size) {
|
||||
void RendererSceneRenderRD::_update_shadow_atlas(ShadowAtlas *shadow_atlas) {
|
||||
if (shadow_atlas->size > 0 && shadow_atlas->depth.is_null()) {
|
||||
RD::TextureFormat tf;
|
||||
tf.format = shadow_atlas->use_16_bits ? RD::DATA_FORMAT_D16_UNORM : RD::DATA_FORMAT_D32_SFLOAT;
|
||||
tf.width = shadow_atlas->size;
|
||||
tf.height = shadow_atlas->size;
|
||||
tf.usage_bits = RD::TEXTURE_USAGE_SAMPLING_BIT | RD::TEXTURE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT;
|
||||
|
||||
shadow_atlas->depth = RD::get_singleton()->texture_create(tf, RD::TextureView());
|
||||
Vector<RID> fb_tex;
|
||||
fb_tex.push_back(shadow_atlas->depth);
|
||||
shadow_atlas->fb = RD::get_singleton()->framebuffer_create(fb_tex);
|
||||
}
|
||||
}
|
||||
|
||||
void RendererSceneRenderRD::shadow_atlas_set_size(RID p_atlas, int p_size, bool p_16_bits) {
|
||||
ShadowAtlas *shadow_atlas = shadow_atlas_owner.getornull(p_atlas);
|
||||
ERR_FAIL_COND(!shadow_atlas);
|
||||
ERR_FAIL_COND(p_size < 0);
|
||||
p_size = next_power_of_2(p_size);
|
||||
|
||||
if (p_size == shadow_atlas->size) {
|
||||
if (p_size == shadow_atlas->size && p_16_bits == shadow_atlas->use_16_bits) {
|
||||
return;
|
||||
}
|
||||
|
||||
@ -3549,16 +3612,7 @@ void RendererSceneRenderRD::shadow_atlas_set_size(RID p_atlas, int p_size) {
|
||||
shadow_atlas->shadow_owners.clear();
|
||||
|
||||
shadow_atlas->size = p_size;
|
||||
|
||||
if (shadow_atlas->size) {
|
||||
RD::TextureFormat tf;
|
||||
tf.format = RD::DATA_FORMAT_R32_SFLOAT;
|
||||
tf.width = shadow_atlas->size;
|
||||
tf.height = shadow_atlas->size;
|
||||
tf.usage_bits = RD::TEXTURE_USAGE_SAMPLING_BIT | RD::TEXTURE_USAGE_STORAGE_BIT;
|
||||
|
||||
shadow_atlas->depth = RD::get_singleton()->texture_create(tf, RD::TextureView());
|
||||
}
|
||||
shadow_atlas->use_16_bits = p_size;
|
||||
}
|
||||
|
||||
void RendererSceneRenderRD::shadow_atlas_set_quadrant_subdivision(RID p_atlas, int p_quadrant, int p_subdivision) {
|
||||
@ -3813,10 +3867,24 @@ bool RendererSceneRenderRD::shadow_atlas_update_light(RID p_atlas, RID p_light_i
|
||||
return false;
|
||||
}
|
||||
|
||||
void RendererSceneRenderRD::directional_shadow_atlas_set_size(int p_size) {
|
||||
void RendererSceneRenderRD::_update_directional_shadow_atlas() {
|
||||
if (directional_shadow.depth.is_null() && directional_shadow.size > 0) {
|
||||
RD::TextureFormat tf;
|
||||
tf.format = directional_shadow.use_16_bits ? RD::DATA_FORMAT_D16_UNORM : RD::DATA_FORMAT_D32_SFLOAT;
|
||||
tf.width = directional_shadow.size;
|
||||
tf.height = directional_shadow.size;
|
||||
tf.usage_bits = RD::TEXTURE_USAGE_SAMPLING_BIT | RD::TEXTURE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT;
|
||||
|
||||
directional_shadow.depth = RD::get_singleton()->texture_create(tf, RD::TextureView());
|
||||
Vector<RID> fb_tex;
|
||||
fb_tex.push_back(directional_shadow.depth);
|
||||
directional_shadow.fb = RD::get_singleton()->framebuffer_create(fb_tex);
|
||||
}
|
||||
}
|
||||
void RendererSceneRenderRD::directional_shadow_atlas_set_size(int p_size, bool p_16_bits) {
|
||||
p_size = nearest_power_of_2_templated(p_size);
|
||||
|
||||
if (directional_shadow.size == p_size) {
|
||||
if (directional_shadow.size == p_size && directional_shadow.use_16_bits == p_16_bits) {
|
||||
return;
|
||||
}
|
||||
|
||||
@ -3826,19 +3894,8 @@ void RendererSceneRenderRD::directional_shadow_atlas_set_size(int p_size) {
|
||||
RD::get_singleton()->free(directional_shadow.depth);
|
||||
_clear_shadow_shrink_stages(directional_shadow.shrink_stages);
|
||||
directional_shadow.depth = RID();
|
||||
_base_uniforms_changed();
|
||||
}
|
||||
|
||||
if (p_size > 0) {
|
||||
RD::TextureFormat tf;
|
||||
tf.format = RD::DATA_FORMAT_R32_SFLOAT;
|
||||
tf.width = p_size;
|
||||
tf.height = p_size;
|
||||
tf.usage_bits = RD::TEXTURE_USAGE_SAMPLING_BIT | RD::TEXTURE_USAGE_STORAGE_BIT;
|
||||
|
||||
directional_shadow.depth = RD::get_singleton()->texture_create(tf, RD::TextureView());
|
||||
}
|
||||
|
||||
_base_uniforms_changed();
|
||||
}
|
||||
|
||||
void RendererSceneRenderRD::set_directional_shadow_count(int p_count) {
|
||||
@ -4008,29 +4065,6 @@ RendererSceneRenderRD::ShadowCubemap *RendererSceneRenderRD::_get_shadow_cubemap
|
||||
return &shadow_cubemaps[p_size];
|
||||
}
|
||||
|
||||
RendererSceneRenderRD::ShadowMap *RendererSceneRenderRD::_get_shadow_map(const Size2i &p_size) {
|
||||
if (!shadow_maps.has(p_size)) {
|
||||
ShadowMap sm;
|
||||
{
|
||||
RD::TextureFormat tf;
|
||||
tf.format = RD::get_singleton()->texture_is_format_supported_for_usage(RD::DATA_FORMAT_D32_SFLOAT, RD::TEXTURE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT) ? RD::DATA_FORMAT_D32_SFLOAT : RD::DATA_FORMAT_X8_D24_UNORM_PACK32;
|
||||
tf.width = p_size.width;
|
||||
tf.height = p_size.height;
|
||||
tf.usage_bits = RD::TEXTURE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT | RD::TEXTURE_USAGE_SAMPLING_BIT;
|
||||
|
||||
sm.depth = RD::get_singleton()->texture_create(tf, RD::TextureView());
|
||||
}
|
||||
|
||||
Vector<RID> fbtex;
|
||||
fbtex.push_back(sm.depth);
|
||||
sm.fb = RD::get_singleton()->framebuffer_create(fbtex);
|
||||
|
||||
shadow_maps[p_size] = sm;
|
||||
}
|
||||
|
||||
return &shadow_maps[p_size];
|
||||
}
|
||||
|
||||
//////////////////////////
|
||||
|
||||
RID RendererSceneRenderRD::decal_instance_create(RID p_decal) {
|
||||
@ -5159,6 +5193,13 @@ void RendererSceneRenderRD::_free_render_buffer_data(RenderBuffers *rb) {
|
||||
RD::get_singleton()->free(rb->ssr.normal_scaled);
|
||||
rb->ssr.normal_scaled = RID();
|
||||
}
|
||||
|
||||
if (rb->ambient_buffer.is_valid()) {
|
||||
RD::get_singleton()->free(rb->ambient_buffer);
|
||||
RD::get_singleton()->free(rb->reflection_buffer);
|
||||
rb->ambient_buffer = RID();
|
||||
rb->reflection_buffer = RID();
|
||||
}
|
||||
}
|
||||
|
||||
void RendererSceneRenderRD::_process_sss(RID p_render_buffers, const CameraMatrix &p_camera) {
|
||||
@ -5558,10 +5599,10 @@ void RendererSceneRenderRD::_render_buffers_debug_draw(RID p_render_buffers, RID
|
||||
effects->copy_to_fb_rect(_render_buffers_get_normal_texture(p_render_buffers), storage->render_target_get_rd_framebuffer(rb->render_target), Rect2(Vector2(), rtsize), false, false);
|
||||
}
|
||||
|
||||
if (debug_draw == RS::VIEWPORT_DEBUG_DRAW_GI_BUFFER && _render_buffers_get_ambient_texture(p_render_buffers).is_valid()) {
|
||||
if (debug_draw == RS::VIEWPORT_DEBUG_DRAW_GI_BUFFER && rb->ambient_buffer.is_valid()) {
|
||||
Size2 rtsize = storage->render_target_get_size(rb->render_target);
|
||||
RID ambient_texture = _render_buffers_get_ambient_texture(p_render_buffers);
|
||||
RID reflection_texture = _render_buffers_get_reflection_texture(p_render_buffers);
|
||||
RID ambient_texture = rb->ambient_buffer;
|
||||
RID reflection_texture = rb->reflection_buffer;
|
||||
effects->copy_to_fb_rect(ambient_texture, storage->render_target_get_rd_framebuffer(rb->render_target), Rect2(Vector2(), rtsize), false, false, false, true, reflection_texture);
|
||||
}
|
||||
}
|
||||
@ -5753,6 +5794,17 @@ RID RendererSceneRenderRD::render_buffers_get_default_gi_probe_buffer() {
|
||||
return default_giprobe_buffer;
|
||||
}
|
||||
|
||||
RID RendererSceneRenderRD::render_buffers_get_gi_ambient_texture(RID p_render_buffers) {
|
||||
RenderBuffers *rb = render_buffers_owner.getornull(p_render_buffers);
|
||||
ERR_FAIL_COND_V(!rb, RID());
|
||||
return rb->ambient_buffer;
|
||||
}
|
||||
RID RendererSceneRenderRD::render_buffers_get_gi_reflection_texture(RID p_render_buffers) {
|
||||
RenderBuffers *rb = render_buffers_owner.getornull(p_render_buffers);
|
||||
ERR_FAIL_COND_V(!rb, RID());
|
||||
return rb->reflection_buffer;
|
||||
}
|
||||
|
||||
uint32_t RendererSceneRenderRD::render_buffers_get_sdfgi_cascade_count(RID p_render_buffers) const {
|
||||
const RenderBuffers *rb = render_buffers_owner.getornull(p_render_buffers);
|
||||
ERR_FAIL_COND_V(!rb, 0);
|
||||
@ -5939,6 +5991,10 @@ void RendererSceneRenderRD::render_buffers_configure(RID p_render_buffers, RID p
|
||||
rb->cluster_builder->setup(Size2i(p_width, p_height), max_cluster_elements, rb->depth_texture, storage->sampler_rd_get_default(RS::CANVAS_ITEM_TEXTURE_FILTER_NEAREST, RS::CANVAS_ITEM_TEXTURE_REPEAT_DISABLED), rb->texture);
|
||||
}
|
||||
|
||||
void RendererSceneRenderRD::gi_set_use_half_resolution(bool p_enable) {
|
||||
gi.half_resolution = p_enable;
|
||||
}
|
||||
|
||||
void RendererSceneRenderRD::sub_surface_scattering_set_quality(RS::SubSurfaceScatteringQuality p_quality) {
|
||||
sss_quality = p_quality;
|
||||
}
|
||||
@ -7386,26 +7442,31 @@ void RendererSceneRenderRD::render_shadow(RID p_light, RID p_shadow_atlas, int p
|
||||
ERR_FAIL_COND(!light_instance);
|
||||
|
||||
Rect2i atlas_rect;
|
||||
RID atlas_texture;
|
||||
uint32_t atlas_size;
|
||||
RID atlas_fb;
|
||||
|
||||
bool using_dual_paraboloid = false;
|
||||
bool using_dual_paraboloid_flip = false;
|
||||
float znear = 0;
|
||||
float zfar = 0;
|
||||
RID render_fb;
|
||||
RID render_texture;
|
||||
float bias = 0;
|
||||
float normal_bias = 0;
|
||||
float zfar;
|
||||
|
||||
bool use_pancake = false;
|
||||
bool use_linear_depth = false;
|
||||
bool render_cubemap = false;
|
||||
bool finalize_cubemap = false;
|
||||
|
||||
bool flip_y = false;
|
||||
|
||||
CameraMatrix light_projection;
|
||||
Transform light_transform;
|
||||
|
||||
bool clear_region = true;
|
||||
bool begin_texture = true;
|
||||
bool end_texture = true;
|
||||
|
||||
if (storage->light_get_type(light_instance->light) == RS::LIGHT_DIRECTIONAL) {
|
||||
_update_directional_shadow_atlas();
|
||||
|
||||
//set pssm stuff
|
||||
if (light_instance->last_scene_shadow_pass != scene_pass) {
|
||||
light_instance->directional_rect = _get_directional_shadow_rect(directional_shadow.size, directional_shadow.light_count, directional_shadow.current_light);
|
||||
@ -7422,6 +7483,7 @@ void RendererSceneRenderRD::render_shadow(RID p_light, RID p_shadow_atlas, int p
|
||||
atlas_rect.size.width = light_instance->directional_rect.size.x;
|
||||
atlas_rect.size.height = light_instance->directional_rect.size.y;
|
||||
|
||||
int pass_count = 1;
|
||||
if (storage->light_directional_get_shadow_mode(light_instance->light) == RS::LIGHT_DIRECTIONAL_SHADOW_PARALLEL_4_SPLITS) {
|
||||
atlas_rect.size.width /= 2;
|
||||
atlas_rect.size.height /= 2;
|
||||
@ -7434,7 +7496,7 @@ void RendererSceneRenderRD::render_shadow(RID p_light, RID p_shadow_atlas, int p
|
||||
atlas_rect.position.x += atlas_rect.size.width;
|
||||
atlas_rect.position.y += atlas_rect.size.height;
|
||||
}
|
||||
|
||||
pass_count = 4;
|
||||
} else if (storage->light_directional_get_shadow_mode(light_instance->light) == RS::LIGHT_DIRECTIONAL_SHADOW_PARALLEL_2_SPLITS) {
|
||||
atlas_rect.size.height /= 2;
|
||||
|
||||
@ -7442,6 +7504,7 @@ void RendererSceneRenderRD::render_shadow(RID p_light, RID p_shadow_atlas, int p
|
||||
} else {
|
||||
atlas_rect.position.y += atlas_rect.size.height;
|
||||
}
|
||||
pass_count = 2;
|
||||
}
|
||||
|
||||
light_instance->shadow_transform[p_pass].atlas_rect = atlas_rect;
|
||||
@ -7449,15 +7512,15 @@ void RendererSceneRenderRD::render_shadow(RID p_light, RID p_shadow_atlas, int p
|
||||
light_instance->shadow_transform[p_pass].atlas_rect.position /= directional_shadow.size;
|
||||
light_instance->shadow_transform[p_pass].atlas_rect.size /= directional_shadow.size;
|
||||
|
||||
float bias_mult = light_instance->shadow_transform[p_pass].bias_scale;
|
||||
zfar = storage->light_get_param(light_instance->light, RS::LIGHT_PARAM_RANGE);
|
||||
bias = storage->light_get_param(light_instance->light, RS::LIGHT_PARAM_SHADOW_BIAS) * bias_mult;
|
||||
normal_bias = storage->light_get_param(light_instance->light, RS::LIGHT_PARAM_SHADOW_NORMAL_BIAS) * bias_mult;
|
||||
|
||||
ShadowMap *shadow_map = _get_shadow_map(atlas_rect.size);
|
||||
render_fb = shadow_map->fb;
|
||||
render_texture = shadow_map->depth;
|
||||
atlas_texture = directional_shadow.depth;
|
||||
render_fb = directional_shadow.fb;
|
||||
render_texture = RID();
|
||||
flip_y = true;
|
||||
|
||||
clear_region = false;
|
||||
begin_texture = (directional_shadow.current_light == 1) && (p_pass == 0); //light is 1-index because it was incremented above
|
||||
end_texture = (directional_shadow.current_light == directional_shadow.light_count) && (p_pass == pass_count - 1);
|
||||
|
||||
} else {
|
||||
//set from shadow atlas
|
||||
@ -7466,6 +7529,8 @@ void RendererSceneRenderRD::render_shadow(RID p_light, RID p_shadow_atlas, int p
|
||||
ERR_FAIL_COND(!shadow_atlas);
|
||||
ERR_FAIL_COND(!shadow_atlas->shadow_owners.has(p_light));
|
||||
|
||||
_update_shadow_atlas(shadow_atlas);
|
||||
|
||||
uint32_t key = shadow_atlas->shadow_owners[p_light];
|
||||
|
||||
uint32_t quadrant = (key >> ShadowAtlas::QUADRANT_SHIFT) & 0x3;
|
||||
@ -7484,11 +7549,8 @@ void RendererSceneRenderRD::render_shadow(RID p_light, RID p_shadow_atlas, int p
|
||||
|
||||
atlas_rect.size.width = shadow_size;
|
||||
atlas_rect.size.height = shadow_size;
|
||||
atlas_texture = shadow_atlas->depth;
|
||||
|
||||
zfar = storage->light_get_param(light_instance->light, RS::LIGHT_PARAM_RANGE);
|
||||
bias = storage->light_get_param(light_instance->light, RS::LIGHT_PARAM_SHADOW_BIAS);
|
||||
normal_bias = storage->light_get_param(light_instance->light, RS::LIGHT_PARAM_SHADOW_NORMAL_BIAS);
|
||||
|
||||
if (storage->light_get_type(light_instance->light) == RS::LIGHT_OMNI) {
|
||||
if (storage->light_omni_get_shadow_mode(light_instance->light) == RS::LIGHT_OMNI_SHADOW_CUBE) {
|
||||
@ -7501,6 +7563,10 @@ void RendererSceneRenderRD::render_shadow(RID p_light, RID p_shadow_atlas, int p
|
||||
light_transform = light_instance->shadow_transform[0].transform;
|
||||
render_cubemap = true;
|
||||
finalize_cubemap = p_pass == 5;
|
||||
atlas_fb = shadow_atlas->fb;
|
||||
|
||||
atlas_size = shadow_atlas->size;
|
||||
clear_region = false;
|
||||
|
||||
} else {
|
||||
light_projection = light_instance->shadow_transform[0].camera;
|
||||
@ -7511,22 +7577,17 @@ void RendererSceneRenderRD::render_shadow(RID p_light, RID p_shadow_atlas, int p
|
||||
|
||||
using_dual_paraboloid = true;
|
||||
using_dual_paraboloid_flip = p_pass == 1;
|
||||
|
||||
ShadowMap *shadow_map = _get_shadow_map(atlas_rect.size);
|
||||
render_fb = shadow_map->fb;
|
||||
render_texture = shadow_map->depth;
|
||||
render_fb = shadow_atlas->fb;
|
||||
flip_y = true;
|
||||
}
|
||||
|
||||
} else if (storage->light_get_type(light_instance->light) == RS::LIGHT_SPOT) {
|
||||
light_projection = light_instance->shadow_transform[0].camera;
|
||||
light_transform = light_instance->shadow_transform[0].transform;
|
||||
|
||||
ShadowMap *shadow_map = _get_shadow_map(atlas_rect.size);
|
||||
render_fb = shadow_map->fb;
|
||||
render_texture = shadow_map->depth;
|
||||
render_fb = shadow_atlas->fb;
|
||||
|
||||
znear = light_instance->shadow_transform[0].camera.get_z_near();
|
||||
use_linear_depth = true;
|
||||
flip_y = true;
|
||||
}
|
||||
}
|
||||
|
||||
@ -7535,25 +7596,19 @@ void RendererSceneRenderRD::render_shadow(RID p_light, RID p_shadow_atlas, int p
|
||||
_render_shadow(render_fb, p_instances, light_projection, light_transform, zfar, 0, 0, false, false, use_pancake, p_camera_plane, p_lod_distance_multiplier, p_screen_lod_threshold);
|
||||
if (finalize_cubemap) {
|
||||
//reblit
|
||||
atlas_rect.size.height /= 2;
|
||||
storage->get_effects()->copy_cubemap_to_dp(render_texture, atlas_texture, atlas_rect, light_projection.get_z_near(), light_projection.get_z_far(), 0.0, false);
|
||||
atlas_rect.position.y += atlas_rect.size.height;
|
||||
storage->get_effects()->copy_cubemap_to_dp(render_texture, atlas_texture, atlas_rect, light_projection.get_z_near(), light_projection.get_z_far(), 0.0, true);
|
||||
Rect2 atlas_rect_norm = atlas_rect;
|
||||
atlas_rect_norm.position.x /= float(atlas_size);
|
||||
atlas_rect_norm.position.y /= float(atlas_size);
|
||||
atlas_rect_norm.size.x /= float(atlas_size);
|
||||
atlas_rect_norm.size.y /= float(atlas_size);
|
||||
atlas_rect_norm.size.height /= 2;
|
||||
storage->get_effects()->copy_cubemap_to_dp(render_texture, atlas_fb, atlas_rect_norm, light_projection.get_z_near(), light_projection.get_z_far(), false);
|
||||
atlas_rect_norm.position.y += atlas_rect_norm.size.height;
|
||||
storage->get_effects()->copy_cubemap_to_dp(render_texture, atlas_fb, atlas_rect_norm, light_projection.get_z_near(), light_projection.get_z_far(), true);
|
||||
}
|
||||
} else {
|
||||
//render shadow
|
||||
|
||||
_render_shadow(render_fb, p_instances, light_projection, light_transform, zfar, bias, normal_bias, using_dual_paraboloid, using_dual_paraboloid_flip, use_pancake, p_camera_plane, p_lod_distance_multiplier, p_screen_lod_threshold);
|
||||
|
||||
//copy to atlas
|
||||
if (use_linear_depth) {
|
||||
storage->get_effects()->copy_depth_to_rect_and_linearize(render_texture, atlas_texture, atlas_rect, true, znear, zfar);
|
||||
} else {
|
||||
storage->get_effects()->copy_depth_to_rect(render_texture, atlas_texture, atlas_rect, true);
|
||||
}
|
||||
|
||||
//does not work from depth to color
|
||||
//RD::get_singleton()->texture_copy(render_texture, atlas_texture, Vector3(0, 0, 0), Vector3(atlas_rect.position.x, atlas_rect.position.y, 0), Vector3(atlas_rect.size.x, atlas_rect.size.y, 1), 0, 0, 0, 0, true);
|
||||
_render_shadow(render_fb, p_instances, light_projection, light_transform, zfar, 0, 0, using_dual_paraboloid, using_dual_paraboloid_flip, use_pancake, p_camera_plane, p_lod_distance_multiplier, p_screen_lod_threshold, atlas_rect, flip_y, clear_region, begin_texture, end_texture);
|
||||
}
|
||||
}
|
||||
|
||||
@ -7609,6 +7664,9 @@ void RendererSceneRenderRD::render_sdfgi(RID p_render_buffers, int p_region, con
|
||||
push_constant.scroll[1] = 0;
|
||||
push_constant.scroll[2] = 0;
|
||||
}
|
||||
|
||||
rb->sdfgi->cascades[cascade].all_dynamic_lights_dirty = true;
|
||||
|
||||
push_constant.grid_size = rb->sdfgi->cascade_size;
|
||||
push_constant.cascade = cascade;
|
||||
|
||||
@ -7684,6 +7742,23 @@ void RendererSceneRenderRD::render_sdfgi(RID p_render_buffers, int p_region, con
|
||||
RD::get_singleton()->compute_list_bind_uniform_set(compute_list, sdfgi_shader.integrate_default_sky_uniform_set, 1);
|
||||
RD::get_singleton()->compute_list_set_push_constant(compute_list, &ipush_constant, sizeof(SDGIShader::IntegratePushConstant));
|
||||
RD::get_singleton()->compute_list_dispatch_threads(compute_list, rb->sdfgi->probe_axis_count * rb->sdfgi->probe_axis_count, rb->sdfgi->probe_axis_count, 1, 8, 8, 1);
|
||||
|
||||
RD::get_singleton()->compute_list_add_barrier(compute_list);
|
||||
|
||||
if (rb->sdfgi->uses_multibounce) {
|
||||
//multibounce requires this to be stored so direct light can read from it
|
||||
|
||||
RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, sdfgi_shader.integrate_pipeline[SDGIShader::INTEGRATE_MODE_STORE]);
|
||||
|
||||
//convert to octahedral to store
|
||||
ipush_constant.image_size[0] *= SDFGI::LIGHTPROBE_OCT_SIZE;
|
||||
ipush_constant.image_size[1] *= SDFGI::LIGHTPROBE_OCT_SIZE;
|
||||
|
||||
RD::get_singleton()->compute_list_bind_uniform_set(compute_list, rb->sdfgi->cascades[cascade].integrate_uniform_set, 0);
|
||||
RD::get_singleton()->compute_list_bind_uniform_set(compute_list, sdfgi_shader.integrate_default_sky_uniform_set, 1);
|
||||
RD::get_singleton()->compute_list_set_push_constant(compute_list, &ipush_constant, sizeof(SDGIShader::IntegratePushConstant));
|
||||
RD::get_singleton()->compute_list_dispatch_threads(compute_list, rb->sdfgi->probe_axis_count * rb->sdfgi->probe_axis_count * SDFGI::LIGHTPROBE_OCT_SIZE, rb->sdfgi->probe_axis_count * SDFGI::LIGHTPROBE_OCT_SIZE, 1, 8, 8, 1);
|
||||
}
|
||||
}
|
||||
|
||||
//ok finally barrier
|
||||
@ -7922,25 +7997,8 @@ void RendererSceneRenderRD::render_sdfgi_static_lights(RID p_render_buffers, uin
|
||||
|
||||
_sdfgi_update_cascades(p_render_buffers); //need cascades updated for this
|
||||
|
||||
RD::ComputeListID compute_list = RD::get_singleton()->compute_list_begin();
|
||||
|
||||
RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, sdfgi_shader.direct_light_pipeline[SDGIShader::DIRECT_LIGHT_MODE_STATIC]);
|
||||
|
||||
SDGIShader::DirectLightPushConstant dl_push_constant;
|
||||
|
||||
dl_push_constant.grid_size[0] = rb->sdfgi->cascade_size;
|
||||
dl_push_constant.grid_size[1] = rb->sdfgi->cascade_size;
|
||||
dl_push_constant.grid_size[2] = rb->sdfgi->cascade_size;
|
||||
dl_push_constant.max_cascades = rb->sdfgi->cascades.size();
|
||||
dl_push_constant.probe_axis_size = rb->sdfgi->probe_axis_count;
|
||||
dl_push_constant.multibounce = false; // this is static light, do not multibounce yet
|
||||
dl_push_constant.y_mult = rb->sdfgi->y_mult;
|
||||
|
||||
//all must be processed
|
||||
dl_push_constant.process_offset = 0;
|
||||
dl_push_constant.process_increment = 1;
|
||||
|
||||
SDGIShader::Light lights[SDFGI::MAX_STATIC_LIGHTS];
|
||||
uint32_t light_count[SDFGI::MAX_STATIC_LIGHTS];
|
||||
|
||||
for (uint32_t i = 0; i < p_cascade_count; i++) {
|
||||
ERR_CONTINUE(p_cascade_indices[i] >= rb->sdfgi->cascades.size());
|
||||
@ -8005,9 +8063,36 @@ void RendererSceneRenderRD::render_sdfgi_static_lights(RID p_render_buffers, uin
|
||||
if (idx > 0) {
|
||||
RD::get_singleton()->buffer_update(cc.lights_buffer, 0, idx * sizeof(SDGIShader::Light), lights, true);
|
||||
}
|
||||
dl_push_constant.light_count = idx;
|
||||
}
|
||||
|
||||
light_count[i] = idx;
|
||||
}
|
||||
}
|
||||
|
||||
/* Static Lights */
|
||||
RD::ComputeListID compute_list = RD::get_singleton()->compute_list_begin();
|
||||
|
||||
RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, sdfgi_shader.direct_light_pipeline[SDGIShader::DIRECT_LIGHT_MODE_STATIC]);
|
||||
|
||||
SDGIShader::DirectLightPushConstant dl_push_constant;
|
||||
|
||||
dl_push_constant.grid_size[0] = rb->sdfgi->cascade_size;
|
||||
dl_push_constant.grid_size[1] = rb->sdfgi->cascade_size;
|
||||
dl_push_constant.grid_size[2] = rb->sdfgi->cascade_size;
|
||||
dl_push_constant.max_cascades = rb->sdfgi->cascades.size();
|
||||
dl_push_constant.probe_axis_size = rb->sdfgi->probe_axis_count;
|
||||
dl_push_constant.multibounce = false; // this is static light, do not multibounce yet
|
||||
dl_push_constant.y_mult = rb->sdfgi->y_mult;
|
||||
|
||||
//all must be processed
|
||||
dl_push_constant.process_offset = 0;
|
||||
dl_push_constant.process_increment = 1;
|
||||
|
||||
for (uint32_t i = 0; i < p_cascade_count; i++) {
|
||||
ERR_CONTINUE(p_cascade_indices[i] >= rb->sdfgi->cascades.size());
|
||||
|
||||
SDFGI::Cascade &cc = rb->sdfgi->cascades[p_cascade_indices[i]];
|
||||
|
||||
dl_push_constant.light_count = light_count[i];
|
||||
dl_push_constant.cascade = p_cascade_indices[i];
|
||||
|
||||
if (dl_push_constant.light_count > 0) {
|
||||
@ -8299,7 +8384,13 @@ RendererSceneRenderRD::RendererSceneRenderRD(RendererStorageRD *p_storage) {
|
||||
roughness_layers = GLOBAL_GET("rendering/quality/reflections/roughness_layers");
|
||||
sky_ggx_samples_quality = GLOBAL_GET("rendering/quality/reflections/ggx_samples");
|
||||
sky_use_cubemap_array = GLOBAL_GET("rendering/quality/reflections/texture_array_reflections");
|
||||
// sky_use_cubemap_array = false;
|
||||
|
||||
sdfgi_ray_count = RS::EnvironmentSDFGIRayCount(CLAMP(int32_t(GLOBAL_GET("rendering/sdfgi/probe_ray_count")), 0, int32_t(RS::ENV_SDFGI_RAY_COUNT_MAX - 1)));
|
||||
sdfgi_frames_to_converge = RS::EnvironmentSDFGIFramesToConverge(CLAMP(int32_t(GLOBAL_GET("rendering/sdfgi/frames_to_converge")), 0, int32_t(RS::ENV_SDFGI_CONVERGE_MAX - 1)));
|
||||
sdfgi_frames_to_update_light = RS::EnvironmentSDFGIFramesToUpdateLight(CLAMP(int32_t(GLOBAL_GET("rendering/sdfgi/frames_to_update_lights")), 0, int32_t(RS::ENV_SDFGI_UPDATE_LIGHT_MAX - 1)));
|
||||
|
||||
directional_shadow.size = GLOBAL_GET("rendering/quality/directional_shadow/size");
|
||||
directional_shadow.use_16_bits = GLOBAL_GET("rendering/quality/directional_shadow/16_bits");
|
||||
|
||||
uint32_t textures_per_stage = RD::get_singleton()->limit_get(RD::LIMIT_MAX_TEXTURES_PER_SHADER_STAGE);
|
||||
|
||||
@ -8632,9 +8723,12 @@ RendererSceneRenderRD::RendererSceneRenderRD(RendererStorageRD *p_storage) {
|
||||
//calculate tables
|
||||
String defines = "\n#define SDFGI_OCT_SIZE " + itos(SDFGI::LIGHTPROBE_OCT_SIZE) + "\n";
|
||||
Vector<String> gi_modes;
|
||||
gi_modes.push_back("\n#define USE_GIPROBE\n");
|
||||
gi_modes.push_back("\n#define USE_GIPROBES\n");
|
||||
gi_modes.push_back("\n#define USE_SDFGI\n");
|
||||
gi_modes.push_back("\n#define USE_SDFGI\n\n#define USE_GIPROBE\n");
|
||||
gi_modes.push_back("\n#define USE_SDFGI\n\n#define USE_GIPROBES\n");
|
||||
gi_modes.push_back("\n#define MODE_HALF_RES\n#define USE_GIPROBES\n");
|
||||
gi_modes.push_back("\n#define MODE_HALF_RES\n#define USE_SDFGI\n");
|
||||
gi_modes.push_back("\n#define MODE_HALF_RES\n#define USE_SDFGI\n\n#define USE_GIPROBES\n");
|
||||
|
||||
gi.shader.initialize(gi_modes, defines);
|
||||
gi.shader_version = gi.shader.version_create();
|
||||
@ -8766,12 +8860,11 @@ RendererSceneRenderRD::RendererSceneRenderRD(RendererStorageRD *p_storage) {
|
||||
environment_set_volumetric_fog_positional_shadow_shrink_size(GLOBAL_GET("rendering/volumetric_fog/positional_shadow_shrink"));
|
||||
|
||||
cull_argument.set_page_pool(&cull_argument_pool);
|
||||
|
||||
gi.half_resolution = GLOBAL_GET("rendering/quality/gi/use_half_resolution");
|
||||
}
|
||||
|
||||
RendererSceneRenderRD::~RendererSceneRenderRD() {
|
||||
for (Map<Vector2i, ShadowMap>::Element *E = shadow_maps.front(); E; E = E->next()) {
|
||||
RD::get_singleton()->free(E->get().depth);
|
||||
}
|
||||
for (Map<int, ShadowCubemap>::Element *E = shadow_cubemaps.front(); E; E = E->next()) {
|
||||
RD::get_singleton()->free(E->get().cubemap);
|
||||
}
|
||||
|
@ -110,7 +110,7 @@ protected:
|
||||
void _setup_giprobes(RID p_render_buffers, const Transform &p_transform, const PagedArray<RID> &p_gi_probes, uint32_t &r_gi_probes_used);
|
||||
|
||||
virtual void _render_scene(RID p_render_buffer, const Transform &p_cam_transform, const CameraMatrix &p_cam_projection, bool p_cam_ortogonal, const PagedArray<GeometryInstance *> &p_instances, int p_directional_light_count, const PagedArray<RID> &p_gi_probes, const PagedArray<RID> &p_lightmaps, RID p_environment, RID p_cluster_buffer, uint32_t p_cluster_size, uint32_t p_cluster_max_elements, RID p_camera_effects, RID p_shadow_atlas, RID p_reflection_atlas, RID p_reflection_probe, int p_reflection_probe_pass, const Color &p_default_color, float p_screen_lod_threshold) = 0;
|
||||
virtual void _render_shadow(RID p_framebuffer, const PagedArray<GeometryInstance *> &p_instances, const CameraMatrix &p_projection, const Transform &p_transform, float p_zfar, float p_bias, float p_normal_bias, bool p_use_dp, bool use_dp_flip, bool p_use_pancake, const Plane &p_camera_plane = Plane(), float p_lod_distance_multiplier = 0.0, float p_screen_lod_threshold = 0.0) = 0;
|
||||
virtual void _render_shadow(RID p_framebuffer, const PagedArray<GeometryInstance *> &p_instances, const CameraMatrix &p_projection, const Transform &p_transform, float p_zfar, float p_bias, float p_normal_bias, bool p_use_dp, bool use_dp_flip, bool p_use_pancake, const Plane &p_camera_plane = Plane(), float p_lod_distance_multiplier = 0.0, float p_screen_lod_threshold = 0.0, const Rect2i &p_rect = Rect2i(), bool p_flip_y = false, bool p_clear_region = true, bool p_begin = true, bool p_end = true) = 0;
|
||||
virtual void _render_material(const Transform &p_cam_transform, const CameraMatrix &p_cam_projection, bool p_cam_ortogonal, const PagedArray<GeometryInstance *> &p_instances, RID p_framebuffer, const Rect2i &p_region) = 0;
|
||||
virtual void _render_uv2(const PagedArray<GeometryInstance *> &p_instances, RID p_framebuffer, const Rect2i &p_region) = 0;
|
||||
virtual void _render_sdfgi(RID p_render_buffers, const Vector3i &p_from, const Vector3i &p_size, const AABB &p_bounds, const PagedArray<GeometryInstance *> &p_instances, const RID &p_albedo_texture, const RID &p_emission_texture, const RID &p_emission_aniso_texture, const RID &p_geom_facing_texture) = 0;
|
||||
@ -124,8 +124,6 @@ protected:
|
||||
virtual void _base_uniforms_changed() = 0;
|
||||
virtual void _render_buffers_uniform_set_changed(RID p_render_buffers) = 0;
|
||||
virtual RID _render_buffers_get_normal_texture(RID p_render_buffers) = 0;
|
||||
virtual RID _render_buffers_get_ambient_texture(RID p_render_buffers) = 0;
|
||||
virtual RID _render_buffers_get_reflection_texture(RID p_render_buffers) = 0;
|
||||
|
||||
void _process_ssao(RID p_render_buffers, RID p_environment, RID p_normal_buffer, const CameraMatrix &p_projection);
|
||||
void _process_ssr(RID p_render_buffers, RID p_dest_framebuffer, RID p_normal_buffer, RID p_specular_buffer, RID p_metallic, const Color &p_metallic_mask, RID p_environment, const CameraMatrix &p_projection, bool p_use_additive);
|
||||
@ -134,7 +132,7 @@ protected:
|
||||
void _setup_sky(RID p_environment, RID p_render_buffers, const CameraMatrix &p_projection, const Transform &p_transform, const Size2i p_screen_size);
|
||||
void _update_sky(RID p_environment, const CameraMatrix &p_projection, const Transform &p_transform);
|
||||
void _draw_sky(bool p_can_continue_color, bool p_can_continue_depth, RID p_fb, RID p_environment, const CameraMatrix &p_projection, const Transform &p_transform);
|
||||
void _process_gi(RID p_render_buffers, RID p_normal_roughness_buffer, RID p_ambient_buffer, RID p_reflection_buffer, RID p_gi_probe_buffer, RID p_environment, const CameraMatrix &p_projection, const Transform &p_transform, const PagedArray<RID> &p_gi_probes);
|
||||
void _process_gi(RID p_render_buffers, RID p_normal_roughness_buffer, RID p_gi_probe_buffer, RID p_environment, const CameraMatrix &p_projection, const Transform &p_transform, const PagedArray<RID> &p_gi_probes);
|
||||
|
||||
// needed for a single argument calls (material and uv2)
|
||||
PagedArrayPool<GeometryInstance *> cull_argument_pool;
|
||||
@ -574,6 +572,7 @@ private:
|
||||
uint32_t smallest_subdiv = 0;
|
||||
|
||||
int size = 0;
|
||||
bool use_16_bits = false;
|
||||
|
||||
RID depth;
|
||||
RID fb; //for copying
|
||||
@ -585,6 +584,8 @@ private:
|
||||
|
||||
RID_Owner<ShadowAtlas> shadow_atlas_owner;
|
||||
|
||||
void _update_shadow_atlas(ShadowAtlas *shadow_atlas);
|
||||
|
||||
bool _shadow_atlas_find_shadow(ShadowAtlas *shadow_atlas, int *p_in_quadrants, int p_quadrant_count, int p_current_subdiv, uint64_t p_tick, int &r_quadrant, int &r_shadow);
|
||||
|
||||
RS::ShadowQuality shadows_quality = RS::SHADOW_QUALITY_MAX; //So it always updates when first set
|
||||
@ -605,9 +606,11 @@ private:
|
||||
|
||||
struct DirectionalShadow {
|
||||
RID depth;
|
||||
RID fb; //when renderign direct
|
||||
|
||||
int light_count = 0;
|
||||
int size = 0;
|
||||
bool use_16_bits = false;
|
||||
int current_light = 0;
|
||||
|
||||
Vector<ShadowShrinkStage> shrink_stages;
|
||||
@ -617,6 +620,8 @@ private:
|
||||
void _allocate_shadow_shrink_stages(RID p_base, int p_base_size, Vector<ShadowShrinkStage> &shrink_stages, uint32_t p_target_size);
|
||||
void _clear_shadow_shrink_stages(Vector<ShadowShrinkStage> &shrink_stages);
|
||||
|
||||
void _update_directional_shadow_atlas();
|
||||
|
||||
/* SHADOW CUBEMAPS */
|
||||
|
||||
struct ShadowCubemap {
|
||||
@ -627,14 +632,6 @@ private:
|
||||
Map<int, ShadowCubemap> shadow_cubemaps;
|
||||
ShadowCubemap *_get_shadow_cubemap(int p_size);
|
||||
|
||||
struct ShadowMap {
|
||||
RID depth;
|
||||
RID fb;
|
||||
};
|
||||
|
||||
Map<Vector2i, ShadowMap> shadow_maps;
|
||||
ShadowMap *_get_shadow_map(const Size2i &p_size);
|
||||
|
||||
void _create_shadow_cubemaps();
|
||||
|
||||
/* LIGHT INSTANCE */
|
||||
@ -904,6 +901,16 @@ private:
|
||||
|
||||
RID giprobe_textures[MAX_GIPROBES];
|
||||
RID giprobe_buffer;
|
||||
|
||||
RID ambient_buffer;
|
||||
RID reflection_buffer;
|
||||
bool using_half_size_gi = false;
|
||||
|
||||
struct GI {
|
||||
RID full_buffer;
|
||||
RID full_dispatch;
|
||||
RID full_mask;
|
||||
} gi;
|
||||
};
|
||||
|
||||
RID default_giprobe_buffer;
|
||||
@ -965,6 +972,8 @@ private:
|
||||
RID scroll_occlusion_uniform_set;
|
||||
RID integrate_uniform_set;
|
||||
RID lights_buffer;
|
||||
|
||||
bool all_dynamic_lights_dirty = true;
|
||||
};
|
||||
|
||||
//used for rendering (voxelization)
|
||||
@ -1026,6 +1035,8 @@ private:
|
||||
|
||||
RS::EnvironmentSDFGIRayCount sdfgi_ray_count = RS::ENV_SDFGI_RAY_COUNT_16;
|
||||
RS::EnvironmentSDFGIFramesToConverge sdfgi_frames_to_converge = RS::ENV_SDFGI_CONVERGE_IN_10_FRAMES;
|
||||
RS::EnvironmentSDFGIFramesToUpdateLight sdfgi_frames_to_update_light = RS::ENV_SDFGI_UPDATE_LIGHT_IN_4_FRAMES;
|
||||
|
||||
float sdfgi_solid_cell_ratio = 0.25;
|
||||
Vector3 sdfgi_debug_probe_pos;
|
||||
Vector3 sdfgi_debug_probe_dir;
|
||||
@ -1263,14 +1274,12 @@ private:
|
||||
float z_far;
|
||||
|
||||
float proj_info[4];
|
||||
|
||||
uint32_t max_giprobes;
|
||||
uint32_t high_quality_vct;
|
||||
uint32_t pad2;
|
||||
uint32_t orthogonal;
|
||||
|
||||
float ao_color[3];
|
||||
uint32_t pad;
|
||||
uint32_t max_giprobes;
|
||||
|
||||
uint32_t high_quality_vct;
|
||||
uint32_t orthogonal;
|
||||
uint32_t pad[2];
|
||||
|
||||
float cam_rotation[12];
|
||||
};
|
||||
@ -1280,9 +1289,13 @@ private:
|
||||
MODE_GIPROBE,
|
||||
MODE_SDFGI,
|
||||
MODE_COMBINED,
|
||||
MODE_HALF_RES_GIPROBE,
|
||||
MODE_HALF_RES_SDFGI,
|
||||
MODE_HALF_RES_COMBINED,
|
||||
MODE_MAX
|
||||
};
|
||||
|
||||
bool half_resolution = false;
|
||||
GiShaderRD shader;
|
||||
RID shader_version;
|
||||
RID pipelines[MODE_MAX];
|
||||
@ -1541,7 +1554,7 @@ public:
|
||||
/* SHADOW ATLAS API */
|
||||
|
||||
RID shadow_atlas_create();
|
||||
void shadow_atlas_set_size(RID p_atlas, int p_size);
|
||||
void shadow_atlas_set_size(RID p_atlas, int p_size, bool p_16_bits = false);
|
||||
void shadow_atlas_set_quadrant_subdivision(RID p_atlas, int p_quadrant, int p_subdivision);
|
||||
bool shadow_atlas_update_light(RID p_atlas, RID p_light_intance, float p_coverage, uint64_t p_light_version);
|
||||
_FORCE_INLINE_ bool shadow_atlas_owns_light_instance(RID p_atlas, RID p_light_intance) {
|
||||
@ -1562,7 +1575,7 @@ public:
|
||||
return Size2(atlas->size, atlas->size);
|
||||
}
|
||||
|
||||
void directional_shadow_atlas_set_size(int p_size);
|
||||
void directional_shadow_atlas_set_size(int p_size, bool p_16_bits = false);
|
||||
int get_directional_light_shadow_size(RID p_light_intance);
|
||||
void set_directional_shadow_count(int p_count);
|
||||
|
||||
@ -1657,6 +1670,7 @@ public:
|
||||
virtual void environment_set_sdfgi(RID p_env, bool p_enable, RS::EnvironmentSDFGICascades p_cascades, float p_min_cell_size, RS::EnvironmentSDFGIYScale p_y_scale, bool p_use_occlusion, bool p_use_multibounce, bool p_read_sky, float p_energy, float p_normal_bias, float p_probe_bias);
|
||||
virtual void environment_set_sdfgi_ray_count(RS::EnvironmentSDFGIRayCount p_ray_count);
|
||||
virtual void environment_set_sdfgi_frames_to_converge(RS::EnvironmentSDFGIFramesToConverge p_frames);
|
||||
virtual void environment_set_sdfgi_frames_to_update_light(RS::EnvironmentSDFGIFramesToUpdateLight p_update);
|
||||
|
||||
void environment_set_ssr_roughness_quality(RS::EnvironmentSSRRoughnessQuality p_quality);
|
||||
RS::EnvironmentSSRRoughnessQuality environment_get_ssr_roughness_quality() const;
|
||||
@ -1955,11 +1969,14 @@ public:
|
||||
*/
|
||||
RID render_buffers_create();
|
||||
void render_buffers_configure(RID p_render_buffers, RID p_render_target, int p_width, int p_height, RS::ViewportMSAA p_msaa, RS::ViewportScreenSpaceAA p_screen_space_aa, bool p_use_debanding);
|
||||
void gi_set_use_half_resolution(bool p_enable);
|
||||
|
||||
RID render_buffers_get_ao_texture(RID p_render_buffers);
|
||||
RID render_buffers_get_back_buffer_texture(RID p_render_buffers);
|
||||
RID render_buffers_get_gi_probe_buffer(RID p_render_buffers);
|
||||
RID render_buffers_get_default_gi_probe_buffer();
|
||||
RID render_buffers_get_gi_ambient_texture(RID p_render_buffers);
|
||||
RID render_buffers_get_gi_reflection_texture(RID p_render_buffers);
|
||||
|
||||
uint32_t render_buffers_get_sdfgi_cascade_count(RID p_render_buffers) const;
|
||||
bool render_buffers_is_sdfgi_enabled(RID p_render_buffers) const;
|
||||
|
@ -1,33 +1,48 @@
|
||||
#[compute]
|
||||
#[vertex]
|
||||
|
||||
#version 450
|
||||
|
||||
VERSION_DEFINES
|
||||
|
||||
layout(local_size_x = 8, local_size_y = 8, local_size_z = 1) in;
|
||||
layout(push_constant, binding = 1, std430) uniform Params {
|
||||
float z_far;
|
||||
float z_near;
|
||||
bool z_flip;
|
||||
uint pad;
|
||||
vec4 screen_rect;
|
||||
}
|
||||
params;
|
||||
|
||||
layout(location = 0) out vec2 uv_interp;
|
||||
|
||||
void main() {
|
||||
vec2 base_arr[4] = vec2[](vec2(0.0, 0.0), vec2(0.0, 1.0), vec2(1.0, 1.0), vec2(1.0, 0.0));
|
||||
uv_interp = base_arr[gl_VertexIndex];
|
||||
vec2 screen_pos = uv_interp * params.screen_rect.zw + params.screen_rect.xy;
|
||||
gl_Position = vec4(screen_pos * 2.0 - 1.0, 0.0, 1.0);
|
||||
}
|
||||
|
||||
#[fragment]
|
||||
|
||||
#version 450
|
||||
|
||||
VERSION_DEFINES
|
||||
|
||||
layout(location = 0) in vec2 uv_interp;
|
||||
|
||||
layout(set = 0, binding = 0) uniform samplerCube source_cube;
|
||||
|
||||
layout(push_constant, binding = 1, std430) uniform Params {
|
||||
ivec2 screen_size;
|
||||
ivec2 offset;
|
||||
float bias;
|
||||
float z_far;
|
||||
float z_near;
|
||||
bool z_flip;
|
||||
uint pad;
|
||||
vec4 screen_rect;
|
||||
}
|
||||
params;
|
||||
|
||||
layout(r32f, set = 1, binding = 0) uniform restrict writeonly image2D depth_buffer;
|
||||
|
||||
void main() {
|
||||
ivec2 pos = ivec2(gl_GlobalInvocationID.xy);
|
||||
if (any(greaterThan(pos, params.screen_size))) { //too large, do nothing
|
||||
return;
|
||||
}
|
||||
|
||||
vec2 pixel_size = 1.0 / vec2(params.screen_size);
|
||||
vec2 uv = (vec2(pos) + 0.5) * pixel_size;
|
||||
vec2 uv = uv_interp;
|
||||
|
||||
vec3 normal = vec3(uv * 2.0 - 1.0, 0.0);
|
||||
|
||||
@ -65,5 +80,5 @@ void main() {
|
||||
float linear_depth = 2.0 * params.z_near * params.z_far / (params.z_far + params.z_near - depth * (params.z_far - params.z_near));
|
||||
depth = (linear_depth * depth_fix) / params.z_far;
|
||||
|
||||
imageStore(depth_buffer, pos + params.offset, vec4(depth));
|
||||
gl_FragDepth = depth;
|
||||
}
|
||||
|
@ -97,13 +97,12 @@ layout(push_constant, binding = 0, std430) uniform Params {
|
||||
|
||||
vec4 proj_info;
|
||||
|
||||
uint max_giprobes;
|
||||
bool high_quality_vct;
|
||||
uint pad2;
|
||||
bool orthogonal;
|
||||
|
||||
vec3 ao_color;
|
||||
uint pad;
|
||||
uint max_giprobes;
|
||||
|
||||
bool high_quality_vct;
|
||||
bool orthogonal;
|
||||
uint pad[2];
|
||||
|
||||
mat3x4 cam_rotation;
|
||||
}
|
||||
@ -594,28 +593,16 @@ vec4 fetch_normal_and_roughness(ivec2 pos) {
|
||||
return normal_roughness;
|
||||
}
|
||||
|
||||
void main() {
|
||||
// Pixel being shaded
|
||||
ivec2 pos = ivec2(gl_GlobalInvocationID.xy);
|
||||
if (any(greaterThanEqual(pos, params.screen_size))) { //too large, do nothing
|
||||
return;
|
||||
}
|
||||
|
||||
vec3 vertex = reconstruct_position(pos);
|
||||
vertex.y = -vertex.y;
|
||||
|
||||
void process_gi(ivec2 pos, vec3 vertex, inout vec4 ambient_light, inout vec4 reflection_light) {
|
||||
vec4 normal_roughness = fetch_normal_and_roughness(pos);
|
||||
vec3 normal = normal_roughness.xyz;
|
||||
|
||||
vec4 ambient_light = vec4(0.0), reflection_light = vec4(0.0);
|
||||
vec3 normal = normal_roughness.xyz;
|
||||
|
||||
if (normal.length() > 0.5) {
|
||||
//valid normal, can do GI
|
||||
float roughness = normal_roughness.w;
|
||||
|
||||
vertex = mat3(params.cam_rotation) * vertex;
|
||||
normal = normalize(mat3(params.cam_rotation) * normal);
|
||||
|
||||
vec3 reflection = normalize(reflect(normalize(vertex), normal));
|
||||
|
||||
#ifdef USE_SDFGI
|
||||
@ -646,16 +633,39 @@ void main() {
|
||||
spec_accum /= blend_accum;
|
||||
}
|
||||
|
||||
if (params.use_sdfgi) {
|
||||
reflection_light = blend_color(spec_accum, reflection_light);
|
||||
ambient_light = blend_color(amb_accum, ambient_light);
|
||||
} else {
|
||||
reflection_light = spec_accum;
|
||||
ambient_light = amb_accum;
|
||||
}
|
||||
#ifdef USE_SDFGI
|
||||
reflection_light = blend_color(spec_accum, reflection_light);
|
||||
ambient_light = blend_color(amb_accum, ambient_light);
|
||||
#else
|
||||
reflection_light = spec_accum;
|
||||
ambient_light = amb_accum;
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
void main() {
|
||||
ivec2 pos = ivec2(gl_GlobalInvocationID.xy);
|
||||
|
||||
#ifdef MODE_HALF_RES
|
||||
pos <<= 1;
|
||||
#endif
|
||||
if (any(greaterThanEqual(pos, params.screen_size))) { //too large, do nothing
|
||||
return;
|
||||
}
|
||||
|
||||
vec4 ambient_light = vec4(0.0);
|
||||
vec4 reflection_light = vec4(0.0);
|
||||
|
||||
vec3 vertex = reconstruct_position(pos);
|
||||
vertex.y = -vertex.y;
|
||||
|
||||
process_gi(pos, vertex, ambient_light, reflection_light);
|
||||
|
||||
#ifdef MODE_HALF_RES
|
||||
pos >>= 1;
|
||||
#endif
|
||||
|
||||
imageStore(ambient_buffer, pos, ambient_light);
|
||||
imageStore(reflection_buffer, pos, reflection_light);
|
||||
|
@ -58,6 +58,116 @@ void main() {
|
||||
|
||||
#else
|
||||
|
||||
#if 1
|
||||
|
||||
vec4 group1;
|
||||
vec4 group2;
|
||||
vec4 group3;
|
||||
vec4 group4;
|
||||
int best_index = 0;
|
||||
|
||||
//2X
|
||||
group1.x = texelFetch(source_depth, pos, 0).r;
|
||||
group1.y = texelFetch(source_depth, pos, 1).r;
|
||||
|
||||
//4X
|
||||
if (params.sample_count >= 4) {
|
||||
group1.z = texelFetch(source_depth, pos, 2).r;
|
||||
group1.w = texelFetch(source_depth, pos, 3).r;
|
||||
}
|
||||
//8X
|
||||
if (params.sample_count >= 8) {
|
||||
group2.x = texelFetch(source_depth, pos, 4).r;
|
||||
group2.y = texelFetch(source_depth, pos, 5).r;
|
||||
group2.z = texelFetch(source_depth, pos, 6).r;
|
||||
group2.w = texelFetch(source_depth, pos, 7).r;
|
||||
}
|
||||
//16X
|
||||
if (params.sample_count >= 16) {
|
||||
group3.x = texelFetch(source_depth, pos, 8).r;
|
||||
group3.y = texelFetch(source_depth, pos, 9).r;
|
||||
group3.z = texelFetch(source_depth, pos, 10).r;
|
||||
group3.w = texelFetch(source_depth, pos, 11).r;
|
||||
|
||||
group4.x = texelFetch(source_depth, pos, 12).r;
|
||||
group4.y = texelFetch(source_depth, pos, 13).r;
|
||||
group4.z = texelFetch(source_depth, pos, 14).r;
|
||||
group4.w = texelFetch(source_depth, pos, 15).r;
|
||||
}
|
||||
|
||||
if (params.sample_count == 2) {
|
||||
best_index = (pos.x & 1) ^ ((pos.y >> 1) & 1); //not much can be done here
|
||||
} else if (params.sample_count == 4) {
|
||||
vec4 freq = vec4(equal(group1, vec4(group1.x)));
|
||||
freq += vec4(equal(group1, vec4(group1.y)));
|
||||
freq += vec4(equal(group1, vec4(group1.z)));
|
||||
freq += vec4(equal(group1, vec4(group1.w)));
|
||||
|
||||
float min_f = freq.x;
|
||||
best_index = 0;
|
||||
if (freq.y < min_f) {
|
||||
best_index = 1;
|
||||
min_f = freq.y;
|
||||
}
|
||||
if (freq.z < min_f) {
|
||||
best_index = 2;
|
||||
min_f = freq.z;
|
||||
}
|
||||
if (freq.w < min_f) {
|
||||
best_index = 3;
|
||||
}
|
||||
} else if (params.sample_count == 8) {
|
||||
vec4 freq0 = vec4(equal(group1, vec4(group1.x)));
|
||||
vec4 freq1 = vec4(equal(group2, vec4(group1.x)));
|
||||
freq0 += vec4(equal(group1, vec4(group1.y)));
|
||||
freq1 += vec4(equal(group2, vec4(group1.y)));
|
||||
freq0 += vec4(equal(group1, vec4(group1.z)));
|
||||
freq1 += vec4(equal(group2, vec4(group1.z)));
|
||||
freq0 += vec4(equal(group1, vec4(group1.w)));
|
||||
freq1 += vec4(equal(group2, vec4(group1.w)));
|
||||
freq0 += vec4(equal(group1, vec4(group2.x)));
|
||||
freq1 += vec4(equal(group2, vec4(group2.x)));
|
||||
freq0 += vec4(equal(group1, vec4(group2.y)));
|
||||
freq1 += vec4(equal(group2, vec4(group2.y)));
|
||||
freq0 += vec4(equal(group1, vec4(group2.z)));
|
||||
freq1 += vec4(equal(group2, vec4(group2.z)));
|
||||
freq0 += vec4(equal(group1, vec4(group2.w)));
|
||||
freq1 += vec4(equal(group2, vec4(group2.w)));
|
||||
|
||||
float min_f0 = freq0.x;
|
||||
int best_index0 = 0;
|
||||
if (freq0.y < min_f0) {
|
||||
best_index0 = 1;
|
||||
min_f0 = freq0.y;
|
||||
}
|
||||
if (freq0.z < min_f0) {
|
||||
best_index0 = 2;
|
||||
min_f0 = freq0.z;
|
||||
}
|
||||
if (freq0.w < min_f0) {
|
||||
best_index0 = 3;
|
||||
min_f0 = freq0.w;
|
||||
}
|
||||
|
||||
float min_f1 = freq1.x;
|
||||
int best_index1 = 4;
|
||||
if (freq1.y < min_f1) {
|
||||
best_index1 = 5;
|
||||
min_f1 = freq1.y;
|
||||
}
|
||||
if (freq1.z < min_f1) {
|
||||
best_index1 = 6;
|
||||
min_f1 = freq1.z;
|
||||
}
|
||||
if (freq1.w < min_f1) {
|
||||
best_index1 = 7;
|
||||
min_f1 = freq1.w;
|
||||
}
|
||||
|
||||
best_index = mix(best_index0, best_index1, min_f0 < min_f1);
|
||||
}
|
||||
|
||||
#else
|
||||
float depths[16];
|
||||
int depth_indices[16];
|
||||
int depth_amount[16];
|
||||
@ -91,7 +201,7 @@ void main() {
|
||||
depth_least = depth_amount[j];
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
best_depth = texelFetch(source_depth, pos, best_index).r;
|
||||
best_normal_roughness = texelFetch(source_normal_roughness, pos, best_index);
|
||||
#ifdef GIPROBE_RESOLVE
|
||||
|
@ -1282,7 +1282,7 @@ float light_process_spot_shadow(uint idx, vec3 vertex, vec3 normal) {
|
||||
} else {
|
||||
#endif
|
||||
//hard shadow
|
||||
vec4 shadow_uv = vec4(splane.xy * spot_lights.data[idx].atlas_rect.zw + spot_lights.data[idx].atlas_rect.xy, z_norm, 1.0);
|
||||
vec4 shadow_uv = vec4(splane.xy * spot_lights.data[idx].atlas_rect.zw + spot_lights.data[idx].atlas_rect.xy, splane.z, 1.0);
|
||||
|
||||
shadow = sample_pcf_shadow(shadow_atlas, spot_lights.data[idx].soft_shadow_scale * scene_data.shadow_atlas_pixel_size, shadow_uv);
|
||||
#ifdef USE_SOFT_SHADOWS
|
||||
@ -2371,17 +2371,17 @@ FRAGMENT_SHADER_CODE
|
||||
|
||||
if (bool(draw_call.flags & INSTANCE_FLAGS_USE_GI_BUFFERS)) { //use GI buffers
|
||||
|
||||
ivec2 coord;
|
||||
vec2 coord;
|
||||
|
||||
if (scene_data.gi_upscale_for_msaa) {
|
||||
ivec2 base_coord = ivec2(gl_FragCoord.xy);
|
||||
ivec2 closest_coord = base_coord;
|
||||
float closest_ang = dot(normal, texelFetch(sampler2D(normal_roughness_buffer, material_samplers[SAMPLER_LINEAR_CLAMP]), base_coord, 0).xyz * 2.0 - 1.0);
|
||||
vec2 base_coord = screen_uv;
|
||||
vec2 closest_coord = base_coord;
|
||||
float closest_ang = dot(normal, textureLod(sampler2D(normal_roughness_buffer, material_samplers[SAMPLER_LINEAR_CLAMP]), base_coord, 0.0).xyz * 2.0 - 1.0);
|
||||
|
||||
for (int i = 0; i < 4; i++) {
|
||||
const ivec2 neighbours[4] = ivec2[](ivec2(-1, 0), ivec2(1, 0), ivec2(0, -1), ivec2(0, 1));
|
||||
ivec2 neighbour_coord = base_coord + neighbours[i];
|
||||
float neighbour_ang = dot(normal, texelFetch(sampler2D(normal_roughness_buffer, material_samplers[SAMPLER_LINEAR_CLAMP]), neighbour_coord, 0).xyz * 2.0 - 1.0);
|
||||
const vec2 neighbours[4] = vec2[](vec2(-1, 0), vec2(1, 0), vec2(0, -1), vec2(0, 1));
|
||||
vec2 neighbour_coord = base_coord + neighbours[i] * scene_data.screen_pixel_size;
|
||||
float neighbour_ang = dot(normal, textureLod(sampler2D(normal_roughness_buffer, material_samplers[SAMPLER_LINEAR_CLAMP]), neighbour_coord, 0.0).xyz * 2.0 - 1.0);
|
||||
if (neighbour_ang > closest_ang) {
|
||||
closest_ang = neighbour_ang;
|
||||
closest_coord = neighbour_coord;
|
||||
@ -2391,11 +2391,11 @@ FRAGMENT_SHADER_CODE
|
||||
coord = closest_coord;
|
||||
|
||||
} else {
|
||||
coord = ivec2(gl_FragCoord.xy);
|
||||
coord = screen_uv;
|
||||
}
|
||||
|
||||
vec4 buffer_ambient = texelFetch(sampler2D(ambient_buffer, material_samplers[SAMPLER_LINEAR_CLAMP]), coord, 0);
|
||||
vec4 buffer_reflection = texelFetch(sampler2D(reflection_buffer, material_samplers[SAMPLER_LINEAR_CLAMP]), coord, 0);
|
||||
vec4 buffer_ambient = textureLod(sampler2D(ambient_buffer, material_samplers[SAMPLER_LINEAR_CLAMP]), coord, 0.0);
|
||||
vec4 buffer_reflection = textureLod(sampler2D(reflection_buffer, material_samplers[SAMPLER_LINEAR_CLAMP]), coord, 0.0);
|
||||
|
||||
ambient_light = mix(ambient_light, buffer_ambient.rgb, buffer_ambient.a);
|
||||
specular_light = mix(specular_light, buffer_reflection.rgb, buffer_reflection.a);
|
||||
|
@ -153,22 +153,22 @@ scene_data;
|
||||
#define INSTANCE_FLAGS_SKELETON (1 << 19)
|
||||
#define INSTANCE_FLAGS_NON_UNIFORM_SCALE (1 << 20)
|
||||
|
||||
layout(set = 0, binding = 5, std430) restrict readonly buffer OmniLights {
|
||||
layout(set = 0, binding = 4, std430) restrict readonly buffer OmniLights {
|
||||
LightData data[];
|
||||
}
|
||||
omni_lights;
|
||||
|
||||
layout(set = 0, binding = 6, std430) restrict readonly buffer SpotLights {
|
||||
layout(set = 0, binding = 5, std430) restrict readonly buffer SpotLights {
|
||||
LightData data[];
|
||||
}
|
||||
spot_lights;
|
||||
|
||||
layout(set = 0, binding = 7) buffer restrict readonly ReflectionProbeData {
|
||||
layout(set = 0, binding = 6) buffer restrict readonly ReflectionProbeData {
|
||||
ReflectionData data[];
|
||||
}
|
||||
reflections;
|
||||
|
||||
layout(set = 0, binding = 8, std140) uniform DirectionalLights {
|
||||
layout(set = 0, binding = 7, std140) uniform DirectionalLights {
|
||||
DirectionalLightData data[MAX_DIRECTIONAL_LIGHT_DATA_STRUCTS];
|
||||
}
|
||||
directional_lights;
|
||||
@ -180,7 +180,7 @@ struct Lightmap {
|
||||
mat3 normal_xform;
|
||||
};
|
||||
|
||||
layout(set = 0, binding = 10, std140) restrict readonly buffer Lightmaps {
|
||||
layout(set = 0, binding = 8, std140) restrict readonly buffer Lightmaps {
|
||||
Lightmap data[];
|
||||
}
|
||||
lightmaps;
|
||||
@ -189,22 +189,20 @@ struct LightmapCapture {
|
||||
vec4 sh[9];
|
||||
};
|
||||
|
||||
layout(set = 0, binding = 11, std140) restrict readonly buffer LightmapCaptures {
|
||||
layout(set = 0, binding = 9, std140) restrict readonly buffer LightmapCaptures {
|
||||
LightmapCapture data[];
|
||||
}
|
||||
lightmap_captures;
|
||||
|
||||
layout(set = 0, binding = 12) uniform texture2D decal_atlas;
|
||||
layout(set = 0, binding = 13) uniform texture2D decal_atlas_srgb;
|
||||
layout(set = 0, binding = 10) uniform texture2D decal_atlas;
|
||||
layout(set = 0, binding = 11) uniform texture2D decal_atlas_srgb;
|
||||
|
||||
layout(set = 0, binding = 14, std430) restrict readonly buffer Decals {
|
||||
layout(set = 0, binding = 12, std430) restrict readonly buffer Decals {
|
||||
DecalData data[];
|
||||
}
|
||||
decals;
|
||||
|
||||
layout(set = 0, binding = 15) uniform texture2D directional_shadow_atlas;
|
||||
|
||||
layout(set = 0, binding = 16, std430) restrict readonly buffer GlobalVariableData {
|
||||
layout(set = 0, binding = 13, std430) restrict readonly buffer GlobalVariableData {
|
||||
vec4 data[];
|
||||
}
|
||||
global_variables;
|
||||
@ -218,7 +216,7 @@ struct SDFGIProbeCascadeData {
|
||||
float to_cell; // 1/bounds * grid_size
|
||||
};
|
||||
|
||||
layout(set = 0, binding = 17, std140) uniform SDFGI {
|
||||
layout(set = 0, binding = 14, std140) uniform SDFGI {
|
||||
vec3 grid_size;
|
||||
uint max_cascades;
|
||||
|
||||
@ -268,13 +266,15 @@ layout(set = 1, binding = 1) uniform textureCubeArray reflection_atlas;
|
||||
|
||||
layout(set = 1, binding = 2) uniform texture2D shadow_atlas;
|
||||
|
||||
layout(set = 1, binding = 3) uniform texture2DArray lightmap_textures[MAX_LIGHTMAP_TEXTURES];
|
||||
layout(set = 1, binding = 3) uniform texture2D directional_shadow_atlas;
|
||||
|
||||
layout(set = 1, binding = 4) uniform texture2DArray lightmap_textures[MAX_LIGHTMAP_TEXTURES];
|
||||
|
||||
#ifndef LOW_END_MODE
|
||||
layout(set = 1, binding = 4) uniform texture3D gi_probe_textures[MAX_GI_PROBES];
|
||||
layout(set = 1, binding = 5) uniform texture3D gi_probe_textures[MAX_GI_PROBES];
|
||||
#endif
|
||||
|
||||
layout(set = 1, binding = 5, std430) buffer restrict readonly ClusterBuffer {
|
||||
layout(set = 1, binding = 6, std430) buffer restrict readonly ClusterBuffer {
|
||||
uint data[];
|
||||
}
|
||||
cluster_buffer;
|
||||
@ -283,10 +283,10 @@ cluster_buffer;
|
||||
|
||||
#ifdef MODE_RENDER_SDF
|
||||
|
||||
layout(r16ui, set = 1, binding = 6) uniform restrict writeonly uimage3D albedo_volume_grid;
|
||||
layout(r32ui, set = 1, binding = 7) uniform restrict writeonly uimage3D emission_grid;
|
||||
layout(r32ui, set = 1, binding = 8) uniform restrict writeonly uimage3D emission_aniso_grid;
|
||||
layout(r32ui, set = 1, binding = 9) uniform restrict uimage3D geom_facing_grid;
|
||||
layout(r16ui, set = 1, binding = 7) uniform restrict writeonly uimage3D albedo_volume_grid;
|
||||
layout(r32ui, set = 1, binding = 8) uniform restrict writeonly uimage3D emission_grid;
|
||||
layout(r32ui, set = 1, binding = 9) uniform restrict writeonly uimage3D emission_aniso_grid;
|
||||
layout(r32ui, set = 1, binding = 10) uniform restrict uimage3D geom_facing_grid;
|
||||
|
||||
//still need to be present for shaders that use it, so remap them to something
|
||||
#define depth_buffer shadow_atlas
|
||||
@ -295,17 +295,17 @@ layout(r32ui, set = 1, binding = 9) uniform restrict uimage3D geom_facing_grid;
|
||||
|
||||
#else
|
||||
|
||||
layout(set = 1, binding = 6) uniform texture2D depth_buffer;
|
||||
layout(set = 1, binding = 7) uniform texture2D color_buffer;
|
||||
layout(set = 1, binding = 7) uniform texture2D depth_buffer;
|
||||
layout(set = 1, binding = 8) uniform texture2D color_buffer;
|
||||
|
||||
#ifndef LOW_END_MODE
|
||||
|
||||
layout(set = 1, binding = 8) uniform texture2D normal_roughness_buffer;
|
||||
layout(set = 1, binding = 9) uniform texture2D ao_buffer;
|
||||
layout(set = 1, binding = 10) uniform texture2D ambient_buffer;
|
||||
layout(set = 1, binding = 11) uniform texture2D reflection_buffer;
|
||||
layout(set = 1, binding = 12) uniform texture2DArray sdfgi_lightprobe_texture;
|
||||
layout(set = 1, binding = 13) uniform texture3D sdfgi_occlusion_cascades;
|
||||
layout(set = 1, binding = 9) uniform texture2D normal_roughness_buffer;
|
||||
layout(set = 1, binding = 10) uniform texture2D ao_buffer;
|
||||
layout(set = 1, binding = 11) uniform texture2D ambient_buffer;
|
||||
layout(set = 1, binding = 12) uniform texture2D reflection_buffer;
|
||||
layout(set = 1, binding = 13) uniform texture2DArray sdfgi_lightprobe_texture;
|
||||
layout(set = 1, binding = 14) uniform texture3D sdfgi_occlusion_cascades;
|
||||
|
||||
struct GIProbeData {
|
||||
mat4 xform;
|
||||
@ -323,12 +323,12 @@ struct GIProbeData {
|
||||
uint mipmaps;
|
||||
};
|
||||
|
||||
layout(set = 1, binding = 14, std140) uniform GIProbes {
|
||||
layout(set = 1, binding = 15, std140) uniform GIProbes {
|
||||
GIProbeData data[MAX_GI_PROBES];
|
||||
}
|
||||
gi_probes;
|
||||
|
||||
layout(set = 1, binding = 15) uniform texture3D volumetric_fog_texture;
|
||||
layout(set = 1, binding = 16) uniform texture3D volumetric_fog_texture;
|
||||
|
||||
#endif // LOW_END_MODE
|
||||
|
||||
|
@ -97,6 +97,8 @@ void main() {
|
||||
float blend = 0.0;
|
||||
|
||||
#if 1
|
||||
// No interpolation
|
||||
|
||||
vec3 inv_dir = 1.0 / ray_dir;
|
||||
|
||||
float rough = 0.5;
|
||||
@ -161,114 +163,11 @@ void main() {
|
||||
|
||||
hit_light *= (dot(max(vec3(0.0), (hit_normal * hit_aniso0)), vec3(1.0)) + dot(max(vec3(0.0), (-hit_normal * hit_aniso1)), vec3(1.0)));
|
||||
|
||||
if (blend > 0.0) {
|
||||
light = mix(light, hit_light, blend);
|
||||
blend = 0.0;
|
||||
} else {
|
||||
light = hit_light;
|
||||
|
||||
//process blend
|
||||
float blend_from = (float(params.probe_axis_size - 1) / 2.0) - 2.5;
|
||||
float blend_to = blend_from + 2.0;
|
||||
|
||||
vec3 cam_pos = params.cam_transform[3].xyz - cascades.data[i].offset;
|
||||
cam_pos *= cascades.data[i].to_cell;
|
||||
|
||||
pos += ray_dir * min(advance, max_advance);
|
||||
vec3 inner_pos = pos - cam_pos;
|
||||
|
||||
inner_pos = inner_pos * float(params.probe_axis_size - 1) / params.grid_size.x;
|
||||
|
||||
float len = length(inner_pos);
|
||||
|
||||
inner_pos = abs(normalize(inner_pos));
|
||||
len *= max(inner_pos.x, max(inner_pos.y, inner_pos.z));
|
||||
|
||||
if (len >= blend_from) {
|
||||
blend = smoothstep(blend_from, blend_to, len);
|
||||
|
||||
pos /= cascades.data[i].to_cell;
|
||||
pos += cascades.data[i].offset;
|
||||
ray_pos = pos;
|
||||
hit = false; //continue trace for blend
|
||||
|
||||
continue;
|
||||
}
|
||||
}
|
||||
light = hit_light;
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
light = mix(light, vec3(0.0), blend);
|
||||
|
||||
#else
|
||||
|
||||
vec3 inv_dir = 1.0 / ray_dir;
|
||||
|
||||
bool hit = false;
|
||||
vec4 light_accum = vec4(0.0);
|
||||
|
||||
float blend_size = (params.grid_size.x / float(params.probe_axis_size - 1)) * 0.5;
|
||||
|
||||
float radius_sizes[MAX_CASCADES];
|
||||
for (uint i = 0; i < params.max_cascades; i++) {
|
||||
radius_sizes[i] = (1.0 / cascades.data[i].to_cell) * (params.grid_size.x * 0.5 - blend_size);
|
||||
}
|
||||
|
||||
float max_distance = radius_sizes[params.max_cascades - 1];
|
||||
float advance = 0;
|
||||
while (advance < max_distance) {
|
||||
for (uint i = 0; i < params.max_cascades; i++) {
|
||||
if (advance < radius_sizes[i]) {
|
||||
vec3 pos = (ray_pos + ray_dir * advance) - cascades.data[i].offset;
|
||||
pos *= cascades.data[i].to_cell * pos_to_uvw;
|
||||
|
||||
float distance = texture(sampler3D(sdf_cascades[i], linear_sampler), pos).r * 255.0 - 1.0;
|
||||
|
||||
vec4 hit_light = vec4(0.0);
|
||||
if (distance < 1.0) {
|
||||
hit_light.a = max(0.0, 1.0 - distance);
|
||||
hit_light.rgb = texture(sampler3D(light_cascades[i], linear_sampler), pos).rgb;
|
||||
hit_light.rgb *= hit_light.a;
|
||||
}
|
||||
|
||||
distance /= cascades.data[i].to_cell;
|
||||
|
||||
if (i < (params.max_cascades - 1)) {
|
||||
pos = (ray_pos + ray_dir * advance) - cascades.data[i + 1].offset;
|
||||
pos *= cascades.data[i + 1].to_cell * pos_to_uvw;
|
||||
|
||||
float distance2 = texture(sampler3D(sdf_cascades[i + 1], linear_sampler), pos).r * 255.0 - 1.0;
|
||||
|
||||
vec4 hit_light2 = vec4(0.0);
|
||||
if (distance2 < 1.0) {
|
||||
hit_light2.a = max(0.0, 1.0 - distance2);
|
||||
hit_light2.rgb = texture(sampler3D(light_cascades[i + 1], linear_sampler), pos).rgb;
|
||||
hit_light2.rgb *= hit_light2.a;
|
||||
}
|
||||
|
||||
float prev_radius = i == 0 ? 0.0 : radius_sizes[i - 1];
|
||||
float blend = (advance - prev_radius) / (radius_sizes[i] - prev_radius);
|
||||
|
||||
distance2 /= cascades.data[i + 1].to_cell;
|
||||
|
||||
hit_light = mix(hit_light, hit_light2, blend);
|
||||
distance = mix(distance, distance2, blend);
|
||||
}
|
||||
|
||||
light_accum += hit_light;
|
||||
advance += distance;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (light_accum.a > 0.98) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
light = light_accum.rgb / light_accum.a;
|
||||
|
||||
#endif
|
||||
|
||||
imageStore(screen_buffer, screen_pos, vec4(linear_to_srgb(light), 1.0));
|
||||
|
@ -125,7 +125,10 @@ void main() {
|
||||
uint voxel_index = uint(gl_GlobalInvocationID.x);
|
||||
|
||||
//used for skipping voxels every N frames
|
||||
voxel_index = params.process_offset + voxel_index * params.process_increment;
|
||||
if (params.process_increment > 1) {
|
||||
voxel_index *= params.process_increment;
|
||||
voxel_index += params.process_offset;
|
||||
}
|
||||
|
||||
if (voxel_index >= dispatch_data.total_count) {
|
||||
return;
|
||||
|
@ -189,14 +189,12 @@ void main() {
|
||||
vec3 inv_dir = 1.0 / ray_dir;
|
||||
|
||||
bool hit = false;
|
||||
vec3 hit_normal;
|
||||
vec3 hit_light;
|
||||
vec3 hit_aniso0;
|
||||
vec3 hit_aniso1;
|
||||
uint hit_cascade;
|
||||
|
||||
float bias = params.ray_bias;
|
||||
vec3 abs_ray_dir = abs(ray_dir);
|
||||
ray_pos += ray_dir * 1.0 / max(abs_ray_dir.x, max(abs_ray_dir.y, abs_ray_dir.z)) * bias / cascades.data[params.cascade].to_cell;
|
||||
vec3 uvw;
|
||||
|
||||
for (uint j = params.cascade; j < params.max_cascades; j++) {
|
||||
//convert to local bounds
|
||||
@ -215,14 +213,12 @@ void main() {
|
||||
|
||||
float advance = 0.0;
|
||||
|
||||
vec3 uvw;
|
||||
|
||||
while (advance < max_advance) {
|
||||
//read how much to advance from SDF
|
||||
uvw = (pos + ray_dir * advance) * pos_to_uvw;
|
||||
|
||||
float distance = texture(sampler3D(sdf_cascades[j], linear_sampler), uvw).r * 255.0 - 1.0;
|
||||
if (distance < 0.001) {
|
||||
if (distance < 0.05) {
|
||||
//consider hit
|
||||
hit = true;
|
||||
break;
|
||||
@ -232,17 +228,7 @@ void main() {
|
||||
}
|
||||
|
||||
if (hit) {
|
||||
const float EPSILON = 0.001;
|
||||
hit_normal = normalize(vec3(
|
||||
texture(sampler3D(sdf_cascades[j], linear_sampler), uvw + vec3(EPSILON, 0.0, 0.0)).r - texture(sampler3D(sdf_cascades[j], linear_sampler), uvw - vec3(EPSILON, 0.0, 0.0)).r,
|
||||
texture(sampler3D(sdf_cascades[j], linear_sampler), uvw + vec3(0.0, EPSILON, 0.0)).r - texture(sampler3D(sdf_cascades[j], linear_sampler), uvw - vec3(0.0, EPSILON, 0.0)).r,
|
||||
texture(sampler3D(sdf_cascades[j], linear_sampler), uvw + vec3(0.0, 0.0, EPSILON)).r - texture(sampler3D(sdf_cascades[j], linear_sampler), uvw - vec3(0.0, 0.0, EPSILON)).r));
|
||||
|
||||
hit_light = texture(sampler3D(light_cascades[j], linear_sampler), uvw).rgb;
|
||||
vec4 aniso0 = texture(sampler3D(aniso0_cascades[j], linear_sampler), uvw);
|
||||
hit_aniso0 = aniso0.rgb;
|
||||
hit_aniso1 = vec3(aniso0.a, texture(sampler3D(aniso1_cascades[j], linear_sampler), uvw).rg);
|
||||
|
||||
hit_cascade = j;
|
||||
break;
|
||||
}
|
||||
|
||||
@ -255,6 +241,17 @@ void main() {
|
||||
|
||||
vec4 light;
|
||||
if (hit) {
|
||||
const float EPSILON = 0.001;
|
||||
vec3 hit_normal = normalize(vec3(
|
||||
texture(sampler3D(sdf_cascades[hit_cascade], linear_sampler), uvw + vec3(EPSILON, 0.0, 0.0)).r - texture(sampler3D(sdf_cascades[hit_cascade], linear_sampler), uvw - vec3(EPSILON, 0.0, 0.0)).r,
|
||||
texture(sampler3D(sdf_cascades[hit_cascade], linear_sampler), uvw + vec3(0.0, EPSILON, 0.0)).r - texture(sampler3D(sdf_cascades[hit_cascade], linear_sampler), uvw - vec3(0.0, EPSILON, 0.0)).r,
|
||||
texture(sampler3D(sdf_cascades[hit_cascade], linear_sampler), uvw + vec3(0.0, 0.0, EPSILON)).r - texture(sampler3D(sdf_cascades[hit_cascade], linear_sampler), uvw - vec3(0.0, 0.0, EPSILON)).r));
|
||||
|
||||
vec3 hit_light = texture(sampler3D(light_cascades[hit_cascade], linear_sampler), uvw).rgb;
|
||||
vec4 aniso0 = texture(sampler3D(aniso0_cascades[hit_cascade], linear_sampler), uvw);
|
||||
vec3 hit_aniso0 = aniso0.rgb;
|
||||
vec3 hit_aniso1 = vec3(aniso0.a, texture(sampler3D(aniso1_cascades[hit_cascade], linear_sampler), uvw).rg);
|
||||
|
||||
//one liner magic
|
||||
light.rgb = hit_light * (dot(max(vec3(0.0), (hit_normal * hit_aniso0)), vec3(1.0)) + dot(max(vec3(0.0), (-hit_normal * hit_aniso1)), vec3(1.0)));
|
||||
light.a = 1.0;
|
||||
@ -490,13 +487,15 @@ void main() {
|
||||
//can't scroll, must look for position in parent cascade
|
||||
|
||||
//to global coords
|
||||
float probe_cell_size = float(params.grid_size.x / float(params.probe_axis_size - 1)) / cascades.data[params.cascade].to_cell;
|
||||
float cell_to_probe = float(params.grid_size.x / float(params.probe_axis_size - 1));
|
||||
|
||||
float probe_cell_size = cell_to_probe / cascades.data[params.cascade].to_cell;
|
||||
vec3 probe_pos = cascades.data[params.cascade].offset + vec3(probe_cell) * probe_cell_size;
|
||||
|
||||
//to parent local coords
|
||||
float probe_cell_size_next = cell_to_probe / cascades.data[params.cascade + 1].to_cell;
|
||||
probe_pos -= cascades.data[params.cascade + 1].offset;
|
||||
probe_pos *= cascades.data[params.cascade + 1].to_cell;
|
||||
probe_pos = probe_pos * float(params.probe_axis_size - 1) / float(params.grid_size.x);
|
||||
probe_pos /= probe_cell_size_next;
|
||||
|
||||
ivec3 probe_posi = ivec3(probe_pos);
|
||||
//add up all light, no need to use occlusion here, since occlusion will do its work afterwards
|
||||
@ -549,20 +548,28 @@ void main() {
|
||||
}
|
||||
|
||||
} else {
|
||||
// clear and let it re-raytrace, only for the last cascade, which happens very un-often
|
||||
//scroll
|
||||
//scroll at the edge of the highest cascade, just copy what is there,
|
||||
//since its the closest we have anyway
|
||||
|
||||
for (uint j = 0; j < params.history_size; j++) {
|
||||
ivec2 tex_pos;
|
||||
tex_pos = probe_cell.xy;
|
||||
tex_pos.x += probe_cell.z * int(params.probe_axis_size);
|
||||
|
||||
for (int i = 0; i < SH_SIZE; i++) {
|
||||
// copy from history texture
|
||||
ivec3 src_pos = ivec3(tex_pos.x, tex_pos.y * SH_SIZE + i, int(j));
|
||||
ivec3 dst_pos = ivec3(pos.x, pos.y * SH_SIZE + i, int(j));
|
||||
imageStore(lightprobe_history_scroll_texture, dst_pos, ivec4(0));
|
||||
ivec4 value = imageLoad(lightprobe_history_texture, dst_pos);
|
||||
imageStore(lightprobe_history_scroll_texture, dst_pos, value);
|
||||
}
|
||||
}
|
||||
|
||||
for (int i = 0; i < SH_SIZE; i++) {
|
||||
// copy from average texture
|
||||
ivec2 dst_pos = ivec2(pos.x, pos.y * SH_SIZE + i);
|
||||
imageStore(lightprobe_average_scroll_texture, dst_pos, ivec4(0));
|
||||
ivec2 spos = ivec2(pos.x, pos.y * SH_SIZE + i);
|
||||
ivec4 average = imageLoad(lightprobe_average_texture, spos);
|
||||
imageStore(lightprobe_average_scroll_texture, spos, average);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -95,7 +95,7 @@ public:
|
||||
virtual Variant instance_geometry_get_shader_parameter(RID p_instance, const StringName &p_parameter) const = 0;
|
||||
virtual Variant instance_geometry_get_shader_parameter_default_value(RID p_instance, const StringName &p_parameter) const = 0;
|
||||
|
||||
virtual void directional_shadow_atlas_set_size(int p_size) = 0;
|
||||
virtual void directional_shadow_atlas_set_size(int p_size, bool p_16_bits = false) = 0;
|
||||
|
||||
/* SKY API */
|
||||
|
||||
@ -140,6 +140,7 @@ public:
|
||||
|
||||
virtual void environment_set_sdfgi_ray_count(RS::EnvironmentSDFGIRayCount p_ray_count) = 0;
|
||||
virtual void environment_set_sdfgi_frames_to_converge(RS::EnvironmentSDFGIFramesToConverge p_frames) = 0;
|
||||
virtual void environment_set_sdfgi_frames_to_update_light(RS::EnvironmentSDFGIFramesToUpdateLight p_update) = 0;
|
||||
|
||||
virtual void environment_set_tonemap(RID p_env, RS::EnvironmentToneMapper p_tone_mapper, float p_exposure, float p_white, bool p_auto_exposure, float p_min_luminance, float p_max_luminance, float p_auto_exp_speed, float p_auto_exp_scale) = 0;
|
||||
|
||||
@ -172,7 +173,7 @@ public:
|
||||
virtual void directional_shadow_quality_set(RS::ShadowQuality p_quality) = 0;
|
||||
|
||||
virtual RID shadow_atlas_create() = 0;
|
||||
virtual void shadow_atlas_set_size(RID p_atlas, int p_size) = 0;
|
||||
virtual void shadow_atlas_set_size(RID p_atlas, int p_size, bool p_use_16_bits = false) = 0;
|
||||
virtual void shadow_atlas_set_quadrant_subdivision(RID p_atlas, int p_quadrant, int p_subdivision) = 0;
|
||||
|
||||
/* Render Buffers */
|
||||
@ -180,6 +181,8 @@ public:
|
||||
virtual RID render_buffers_create() = 0;
|
||||
virtual void render_buffers_configure(RID p_render_buffers, RID p_render_target, int p_width, int p_height, RS::ViewportMSAA p_msaa, RS::ViewportScreenSpaceAA p_screen_space_aa, bool p_use_debanding) = 0;
|
||||
|
||||
virtual void gi_set_use_half_resolution(bool p_enable) = 0;
|
||||
|
||||
virtual void set_debug_draw_mode(RS::ViewportDebugDraw p_debug_draw) = 0;
|
||||
|
||||
virtual TypedArray<Image> bake_render_uv2(RID p_base, const Vector<RID> &p_material_overrides, const Size2i &p_image_size) = 0;
|
||||
|
@ -795,6 +795,7 @@ public:
|
||||
lightmaps.set_page_pool(p_rid_pool);
|
||||
reflections.set_page_pool(p_rid_pool);
|
||||
decals.set_page_pool(p_rid_pool);
|
||||
gi_probes.set_page_pool(p_rid_pool);
|
||||
mesh_instances.set_page_pool(p_rid_pool);
|
||||
for (int i = 0; i < RendererSceneRender::MAX_DIRECTIONAL_LIGHTS; i++) {
|
||||
for (int j = 0; j < RendererSceneRender::MAX_DIRECTIONAL_LIGHT_CASCADES; j++) {
|
||||
@ -946,7 +947,7 @@ public:
|
||||
|
||||
#define PASSBASE scene_render
|
||||
|
||||
PASS1(directional_shadow_atlas_set_size, int)
|
||||
PASS2(directional_shadow_atlas_set_size, int, bool)
|
||||
PASS1(gi_probe_set_quality, RS::GIProbeQuality)
|
||||
|
||||
/* SKY API */
|
||||
@ -995,6 +996,7 @@ public:
|
||||
PASS11(environment_set_sdfgi, RID, bool, RS::EnvironmentSDFGICascades, float, RS::EnvironmentSDFGIYScale, bool, bool, bool, float, float, float)
|
||||
PASS1(environment_set_sdfgi_ray_count, RS::EnvironmentSDFGIRayCount)
|
||||
PASS1(environment_set_sdfgi_frames_to_converge, RS::EnvironmentSDFGIFramesToConverge)
|
||||
PASS1(environment_set_sdfgi_frames_to_update_light, RS::EnvironmentSDFGIFramesToUpdateLight)
|
||||
|
||||
PASS1RC(RS::EnvironmentBG, environment_get_background, RID)
|
||||
PASS1RC(int, environment_get_canvas_max_layer, RID)
|
||||
@ -1024,10 +1026,11 @@ public:
|
||||
|
||||
PASS0R(RID, render_buffers_create)
|
||||
PASS7(render_buffers_configure, RID, RID, int, int, RS::ViewportMSAA, RS::ViewportScreenSpaceAA, bool)
|
||||
PASS1(gi_set_use_half_resolution, bool)
|
||||
|
||||
/* Shadow Atlas */
|
||||
PASS0R(RID, shadow_atlas_create)
|
||||
PASS2(shadow_atlas_set_size, RID, int)
|
||||
PASS3(shadow_atlas_set_size, RID, int, bool)
|
||||
PASS3(shadow_atlas_set_quadrant_subdivision, RID, int, int)
|
||||
|
||||
PASS1(set_debug_draw_mode, RS::ViewportDebugDraw)
|
||||
|
@ -73,11 +73,11 @@ public:
|
||||
|
||||
virtual RID
|
||||
shadow_atlas_create() = 0;
|
||||
virtual void shadow_atlas_set_size(RID p_atlas, int p_size) = 0;
|
||||
virtual void shadow_atlas_set_size(RID p_atlas, int p_size, bool p_16_bits = false) = 0;
|
||||
virtual void shadow_atlas_set_quadrant_subdivision(RID p_atlas, int p_quadrant, int p_subdivision) = 0;
|
||||
virtual bool shadow_atlas_update_light(RID p_atlas, RID p_light_intance, float p_coverage, uint64_t p_light_version) = 0;
|
||||
|
||||
virtual void directional_shadow_atlas_set_size(int p_size) = 0;
|
||||
virtual void directional_shadow_atlas_set_size(int p_size, bool p_16_bits = false) = 0;
|
||||
virtual int get_directional_light_shadow_size(RID p_light_intance) = 0;
|
||||
virtual void set_directional_shadow_count(int p_count) = 0;
|
||||
|
||||
@ -136,6 +136,7 @@ public:
|
||||
|
||||
virtual void environment_set_sdfgi_ray_count(RS::EnvironmentSDFGIRayCount p_ray_count) = 0;
|
||||
virtual void environment_set_sdfgi_frames_to_converge(RS::EnvironmentSDFGIFramesToConverge p_frames) = 0;
|
||||
virtual void environment_set_sdfgi_frames_to_update_light(RS::EnvironmentSDFGIFramesToUpdateLight p_update) = 0;
|
||||
|
||||
virtual void environment_set_tonemap(RID p_env, RS::EnvironmentToneMapper p_tone_mapper, float p_exposure, float p_white, bool p_auto_exposure, float p_min_luminance, float p_max_luminance, float p_auto_exp_speed, float p_auto_exp_scale) = 0;
|
||||
|
||||
@ -208,6 +209,7 @@ public:
|
||||
|
||||
virtual RID render_buffers_create() = 0;
|
||||
virtual void render_buffers_configure(RID p_render_buffers, RID p_render_target, int p_width, int p_height, RS::ViewportMSAA p_msaa, RS::ViewportScreenSpaceAA p_screen_space_aa, bool p_use_debanding) = 0;
|
||||
virtual void gi_set_use_half_resolution(bool p_enable) = 0;
|
||||
|
||||
virtual void screen_space_roughness_limiter_set_active(bool p_enable, float p_amount, float p_limit) = 0;
|
||||
virtual bool screen_space_roughness_limiter_is_active() const = 0;
|
||||
|
@ -831,13 +831,14 @@ void RendererViewport::viewport_set_canvas_stacking(RID p_viewport, RID p_canvas
|
||||
viewport->canvas_map[p_canvas].sublayer = p_sublayer;
|
||||
}
|
||||
|
||||
void RendererViewport::viewport_set_shadow_atlas_size(RID p_viewport, int p_size) {
|
||||
void RendererViewport::viewport_set_shadow_atlas_size(RID p_viewport, int p_size, bool p_16_bits) {
|
||||
Viewport *viewport = viewport_owner.getornull(p_viewport);
|
||||
ERR_FAIL_COND(!viewport);
|
||||
|
||||
viewport->shadow_atlas_size = p_size;
|
||||
viewport->shadow_atlas_16_bits = p_16_bits;
|
||||
|
||||
RSG::scene->shadow_atlas_set_size(viewport->shadow_atlas, viewport->shadow_atlas_size);
|
||||
RSG::scene->shadow_atlas_set_size(viewport->shadow_atlas, viewport->shadow_atlas_size, viewport->shadow_atlas_16_bits);
|
||||
}
|
||||
|
||||
void RendererViewport::viewport_set_shadow_atlas_quadrant_subdivision(RID p_viewport, int p_quadrant, int p_subdiv) {
|
||||
|
@ -81,6 +81,7 @@ public:
|
||||
|
||||
RID shadow_atlas;
|
||||
int shadow_atlas_size;
|
||||
bool shadow_atlas_16_bits = false;
|
||||
|
||||
bool sdf_active;
|
||||
|
||||
@ -217,7 +218,7 @@ public:
|
||||
void viewport_set_global_canvas_transform(RID p_viewport, const Transform2D &p_transform);
|
||||
void viewport_set_canvas_stacking(RID p_viewport, RID p_canvas, int p_layer, int p_sublayer);
|
||||
|
||||
void viewport_set_shadow_atlas_size(RID p_viewport, int p_size);
|
||||
void viewport_set_shadow_atlas_size(RID p_viewport, int p_size, bool p_16_bits = false);
|
||||
void viewport_set_shadow_atlas_quadrant_subdivision(RID p_viewport, int p_quadrant, int p_subdiv);
|
||||
|
||||
void viewport_set_msaa(RID p_viewport, RS::ViewportMSAA p_msaa);
|
||||
|
@ -745,6 +745,7 @@ void RenderingDevice::_bind_methods() {
|
||||
BIND_ENUM_CONSTANT(DYNAMIC_STATE_STENCIL_REFERENCE);
|
||||
|
||||
BIND_ENUM_CONSTANT(INITIAL_ACTION_CLEAR); //start rendering and clear the framebuffer (supply params)
|
||||
BIND_ENUM_CONSTANT(INITIAL_ACTION_CLEAR_REGION); //start rendering and clear the framebuffer (supply params)
|
||||
BIND_ENUM_CONSTANT(INITIAL_ACTION_KEEP); //start rendering); but keep attached color texture contents (depth will be cleared)
|
||||
BIND_ENUM_CONSTANT(INITIAL_ACTION_DROP); //start rendering); ignore what is there); just write above it
|
||||
BIND_ENUM_CONSTANT(INITIAL_ACTION_CONTINUE); //continue rendering (framebuffer must have been left in "continue" state as final action previously)
|
||||
|
@ -931,7 +931,8 @@ public:
|
||||
/********************/
|
||||
|
||||
enum InitialAction {
|
||||
INITIAL_ACTION_CLEAR, //start rendering and clear the framebuffer (supply params)
|
||||
INITIAL_ACTION_CLEAR, //start rendering and clear the whole framebuffer (region or not) (supply params)
|
||||
INITIAL_ACTION_CLEAR_REGION, //start rendering and clear the framebuffer in the specified region (supply params)
|
||||
INITIAL_ACTION_KEEP, //start rendering, but keep attached color texture contents (depth will be cleared)
|
||||
INITIAL_ACTION_DROP, //start rendering, ignore what is there, just write above it
|
||||
INITIAL_ACTION_CONTINUE, //continue rendering (framebuffer must have been left in "continue" state as final action previously)
|
||||
|
@ -162,6 +162,51 @@ void RenderingServerDefault::draw(bool p_swap_buffers, double frame_step) {
|
||||
}
|
||||
|
||||
frame_profile_frame = RSG::storage->get_captured_timestamps_frame();
|
||||
|
||||
if (print_gpu_profile) {
|
||||
if (print_frame_profile_ticks_from == 0) {
|
||||
print_frame_profile_ticks_from = OS::get_singleton()->get_ticks_usec();
|
||||
}
|
||||
float total_time = 0.0;
|
||||
|
||||
for (int i = 0; i < frame_profile.size() - 1; i++) {
|
||||
String name = frame_profile[i].name;
|
||||
if (name[0] == '<' || name[0] == '>') {
|
||||
continue;
|
||||
}
|
||||
|
||||
float time = frame_profile[i + 1].gpu_msec - frame_profile[i].gpu_msec;
|
||||
|
||||
if (name[0] != '<' && name[0] != '>') {
|
||||
if (print_gpu_profile_task_time.has(name)) {
|
||||
print_gpu_profile_task_time[name] += time;
|
||||
} else {
|
||||
print_gpu_profile_task_time[name] = time;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (frame_profile.size()) {
|
||||
total_time = frame_profile[frame_profile.size() - 1].gpu_msec;
|
||||
}
|
||||
|
||||
uint64_t ticks_elapsed = OS::get_singleton()->get_ticks_usec() - print_frame_profile_ticks_from;
|
||||
print_frame_profile_frame_count++;
|
||||
if (ticks_elapsed > 1000000) {
|
||||
print_line("GPU PROFILE (total " + rtos(total_time) + "ms): ");
|
||||
|
||||
float print_threshold = 0.01;
|
||||
for (OrderedHashMap<String, float>::Element E = print_gpu_profile_task_time.front(); E; E = E.next()) {
|
||||
float time = E.value() / float(print_frame_profile_frame_count);
|
||||
if (time > print_threshold) {
|
||||
print_line("\t-" + E.key() + ": " + rtos(time) + "ms");
|
||||
}
|
||||
}
|
||||
print_gpu_profile_task_time.clear();
|
||||
print_frame_profile_ticks_from = OS::get_singleton()->get_ticks_usec();
|
||||
print_frame_profile_frame_count = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
float RenderingServerDefault::get_frame_setup_time_cpu() const {
|
||||
@ -232,6 +277,11 @@ void RenderingServerDefault::sdfgi_set_debug_probe_select(const Vector3 &p_posit
|
||||
RSG::scene->sdfgi_set_debug_probe_select(p_position, p_dir);
|
||||
}
|
||||
|
||||
void RenderingServerDefault::set_print_gpu_profile(bool p_enable) {
|
||||
RSG::storage->capturing_timestamps = p_enable;
|
||||
print_gpu_profile = p_enable;
|
||||
}
|
||||
|
||||
RID RenderingServerDefault::get_test_cube() {
|
||||
if (!test_cube.is_valid()) {
|
||||
test_cube = _make_test_cube();
|
||||
|
@ -32,6 +32,7 @@
|
||||
#define RENDERING_SERVER_DEFAULT_H
|
||||
|
||||
#include "core/math/octree.h"
|
||||
#include "core/templates/ordered_hash_map.h"
|
||||
#include "renderer_canvas_cull.h"
|
||||
#include "renderer_scene_cull.h"
|
||||
#include "renderer_viewport.h"
|
||||
@ -74,6 +75,12 @@ class RenderingServerDefault : public RenderingServer {
|
||||
|
||||
float frame_setup_time = 0;
|
||||
|
||||
//for printing
|
||||
bool print_gpu_profile = false;
|
||||
OrderedHashMap<String, float> print_gpu_profile_task_time;
|
||||
uint64_t print_frame_profile_ticks_from = 0;
|
||||
uint32_t print_frame_profile_frame_count = 0;
|
||||
|
||||
public:
|
||||
//if editor is redrawing when it shouldn't, enable this and put a breakpoint in _changes_changed()
|
||||
//#define DEBUG_CHANGES
|
||||
@ -544,7 +551,7 @@ public:
|
||||
|
||||
BIND2(viewport_set_global_canvas_transform, RID, const Transform2D &)
|
||||
BIND4(viewport_set_canvas_stacking, RID, RID, int, int)
|
||||
BIND2(viewport_set_shadow_atlas_size, RID, int)
|
||||
BIND3(viewport_set_shadow_atlas_size, RID, int, bool)
|
||||
BIND3(viewport_set_sdf_oversize_and_scale, RID, ViewportSDFOversize, ViewportSDFScale)
|
||||
BIND3(viewport_set_shadow_atlas_quadrant_subdivision, RID, int, int)
|
||||
BIND2(viewport_set_msaa, RID, ViewportMSAA)
|
||||
@ -565,7 +572,7 @@ public:
|
||||
//from now on, calls forwarded to this singleton
|
||||
#define BINDBASE RSG::scene
|
||||
|
||||
BIND1(directional_shadow_atlas_set_size, int)
|
||||
BIND2(directional_shadow_atlas_set_size, int, bool)
|
||||
BIND1(gi_probe_set_quality, GIProbeQuality)
|
||||
|
||||
/* SKY API */
|
||||
@ -616,6 +623,7 @@ public:
|
||||
BIND11(environment_set_sdfgi, RID, bool, EnvironmentSDFGICascades, float, EnvironmentSDFGIYScale, bool, bool, bool, float, float, float)
|
||||
BIND1(environment_set_sdfgi_ray_count, EnvironmentSDFGIRayCount)
|
||||
BIND1(environment_set_sdfgi_frames_to_converge, EnvironmentSDFGIFramesToConverge)
|
||||
BIND1(environment_set_sdfgi_frames_to_update_light, EnvironmentSDFGIFramesToUpdateLight)
|
||||
|
||||
BIND3R(Ref<Image>, environment_bake_panorama, RID, bool, const Size2i &)
|
||||
|
||||
@ -688,6 +696,8 @@ public:
|
||||
|
||||
BIND3R(TypedArray<Image>, bake_render_uv2, RID, const Vector<RID> &, const Size2i &)
|
||||
|
||||
BIND1(gi_set_use_half_resolution, bool)
|
||||
|
||||
#undef BINDBASE
|
||||
//from now on, calls forwarded to this singleton
|
||||
#define BINDBASE RSG::canvas
|
||||
@ -865,6 +875,8 @@ public:
|
||||
|
||||
virtual void sdfgi_set_debug_probe_select(const Vector3 &p_position, const Vector3 &p_dir);
|
||||
|
||||
virtual void set_print_gpu_profile(bool p_enable);
|
||||
|
||||
RenderingServerDefault();
|
||||
~RenderingServerDefault();
|
||||
|
||||
|
@ -445,7 +445,7 @@ public:
|
||||
|
||||
FUNC2(viewport_set_global_canvas_transform, RID, const Transform2D &)
|
||||
FUNC4(viewport_set_canvas_stacking, RID, RID, int, int)
|
||||
FUNC2(viewport_set_shadow_atlas_size, RID, int)
|
||||
FUNC3(viewport_set_shadow_atlas_size, RID, int, bool)
|
||||
FUNC3(viewport_set_sdf_oversize_and_scale, RID, ViewportSDFOversize, ViewportSDFScale)
|
||||
|
||||
FUNC3(viewport_set_shadow_atlas_quadrant_subdivision, RID, int, int)
|
||||
@ -470,7 +470,7 @@ public:
|
||||
return rendering_server->viewport_get_measured_render_time_gpu(p_viewport);
|
||||
}
|
||||
|
||||
FUNC1(directional_shadow_atlas_set_size, int)
|
||||
FUNC2(directional_shadow_atlas_set_size, int, bool)
|
||||
|
||||
/* SKY API */
|
||||
|
||||
@ -507,6 +507,7 @@ public:
|
||||
FUNC11(environment_set_sdfgi, RID, bool, EnvironmentSDFGICascades, float, EnvironmentSDFGIYScale, bool, bool, bool, float, float, float)
|
||||
FUNC1(environment_set_sdfgi_ray_count, EnvironmentSDFGIRayCount)
|
||||
FUNC1(environment_set_sdfgi_frames_to_converge, EnvironmentSDFGIFramesToConverge)
|
||||
FUNC1(environment_set_sdfgi_frames_to_update_light, EnvironmentSDFGIFramesToUpdateLight)
|
||||
|
||||
FUNC11(environment_set_glow, RID, bool, Vector<float>, float, float, float, float, EnvironmentGlowBlendMode, float, float, float)
|
||||
FUNC1(environment_glow_set_use_bicubic_upscale, bool)
|
||||
@ -744,6 +745,8 @@ public:
|
||||
return rendering_server->get_video_adapter_vendor();
|
||||
}
|
||||
|
||||
FUNC1(gi_set_use_half_resolution, bool)
|
||||
|
||||
FUNC4(set_boot_image, const Ref<Image> &, const Color &, bool, bool)
|
||||
FUNC1(set_default_clear_color, const Color &)
|
||||
|
||||
@ -786,6 +789,10 @@ public:
|
||||
rendering_server->sdfgi_set_debug_probe_select(p_position, p_dir);
|
||||
}
|
||||
|
||||
virtual void set_print_gpu_profile(bool p_enable) {
|
||||
rendering_server->set_print_gpu_profile(p_enable);
|
||||
}
|
||||
|
||||
RenderingServerWrapMT(RenderingServer *p_contained, bool p_create_thread);
|
||||
~RenderingServerWrapMT();
|
||||
|
||||
|
@ -1661,7 +1661,7 @@ void RenderingServer::_bind_methods() {
|
||||
ClassDB::bind_method(D_METHOD("viewport_set_transparent_background", "viewport", "enabled"), &RenderingServer::viewport_set_transparent_background);
|
||||
ClassDB::bind_method(D_METHOD("viewport_set_global_canvas_transform", "viewport", "transform"), &RenderingServer::viewport_set_global_canvas_transform);
|
||||
ClassDB::bind_method(D_METHOD("viewport_set_canvas_stacking", "viewport", "canvas", "layer", "sublayer"), &RenderingServer::viewport_set_canvas_stacking);
|
||||
ClassDB::bind_method(D_METHOD("viewport_set_shadow_atlas_size", "viewport", "size"), &RenderingServer::viewport_set_shadow_atlas_size);
|
||||
ClassDB::bind_method(D_METHOD("viewport_set_shadow_atlas_size", "viewport", "size", "use_16_bits"), &RenderingServer::viewport_set_shadow_atlas_size, DEFVAL(false));
|
||||
ClassDB::bind_method(D_METHOD("viewport_set_shadow_atlas_quadrant_subdivision", "viewport", "quadrant", "subdivision"), &RenderingServer::viewport_set_shadow_atlas_quadrant_subdivision);
|
||||
ClassDB::bind_method(D_METHOD("viewport_set_msaa", "viewport", "msaa"), &RenderingServer::viewport_set_msaa);
|
||||
ClassDB::bind_method(D_METHOD("viewport_set_use_debanding", "viewport", "enable"), &RenderingServer::viewport_set_use_debanding);
|
||||
@ -2272,6 +2272,7 @@ RenderingServer::RenderingServer() {
|
||||
GLOBAL_DEF("rendering/quality/directional_shadow/soft_shadow_quality", 2);
|
||||
GLOBAL_DEF("rendering/quality/directional_shadow/soft_shadow_quality.mobile", 0);
|
||||
ProjectSettings::get_singleton()->set_custom_property_info("rendering/quality/directional_shadow/soft_shadow_quality", PropertyInfo(Variant::INT, "rendering/quality/directional_shadow/soft_shadow_quality", PROPERTY_HINT_ENUM, "Hard (Fastest),Soft Low (Fast),Soft Medium (Average),Soft High (Slow),Soft Ultra (Slowest)"));
|
||||
GLOBAL_DEF("rendering/quality/directional_shadow/16_bits", true);
|
||||
|
||||
GLOBAL_DEF("rendering/quality/shadows/soft_shadow_quality", 2);
|
||||
GLOBAL_DEF("rendering/quality/shadows/soft_shadow_quality.mobile", 0);
|
||||
@ -2282,18 +2283,6 @@ RenderingServer::RenderingServer() {
|
||||
GLOBAL_DEF("rendering/quality/rd_renderer/use_low_end_renderer", false);
|
||||
GLOBAL_DEF("rendering/quality/rd_renderer/use_low_end_renderer.mobile", true);
|
||||
|
||||
GLOBAL_DEF("rendering/quality/shadow_atlas/size", 4096);
|
||||
GLOBAL_DEF("rendering/quality/shadow_atlas/size.mobile", 2048);
|
||||
ProjectSettings::get_singleton()->set_custom_property_info("rendering/quality/shadow_atlas/size", PropertyInfo(Variant::INT, "rendering/quality/shadow_atlas/size", PROPERTY_HINT_RANGE, "256,16384"));
|
||||
GLOBAL_DEF("rendering/quality/shadow_atlas/quadrant_0_subdiv", 1);
|
||||
GLOBAL_DEF("rendering/quality/shadow_atlas/quadrant_1_subdiv", 2);
|
||||
GLOBAL_DEF("rendering/quality/shadow_atlas/quadrant_2_subdiv", 3);
|
||||
GLOBAL_DEF("rendering/quality/shadow_atlas/quadrant_3_subdiv", 4);
|
||||
ProjectSettings::get_singleton()->set_custom_property_info("rendering/quality/shadow_atlas/quadrant_0_subdiv", PropertyInfo(Variant::INT, "rendering/quality/shadow_atlas/quadrant_0_subdiv", PROPERTY_HINT_ENUM, "Disabled,1 Shadow,4 Shadows,16 Shadows,64 Shadows,256 Shadows,1024 Shadows"));
|
||||
ProjectSettings::get_singleton()->set_custom_property_info("rendering/quality/shadow_atlas/quadrant_1_subdiv", PropertyInfo(Variant::INT, "rendering/quality/shadow_atlas/quadrant_1_subdiv", PROPERTY_HINT_ENUM, "Disabled,1 Shadow,4 Shadows,16 Shadows,64 Shadows,256 Shadows,1024 Shadows"));
|
||||
ProjectSettings::get_singleton()->set_custom_property_info("rendering/quality/shadow_atlas/quadrant_2_subdiv", PropertyInfo(Variant::INT, "rendering/quality/shadow_atlas/quadrant_2_subdiv", PROPERTY_HINT_ENUM, "Disabled,1 Shadow,4 Shadows,16 Shadows,64 Shadows,256 Shadows,1024 Shadows"));
|
||||
ProjectSettings::get_singleton()->set_custom_property_info("rendering/quality/shadow_atlas/quadrant_3_subdiv", PropertyInfo(Variant::INT, "rendering/quality/shadow_atlas/quadrant_3_subdiv", PROPERTY_HINT_ENUM, "Disabled,1 Shadow,4 Shadows,16 Shadows,64 Shadows,256 Shadows,1024 Shadows"));
|
||||
|
||||
GLOBAL_DEF("rendering/quality/reflections/roughness_layers", 8);
|
||||
GLOBAL_DEF("rendering/quality/reflections/texture_array_reflections", true);
|
||||
GLOBAL_DEF("rendering/quality/reflections/texture_array_reflections.mobile", false);
|
||||
@ -2304,6 +2293,8 @@ RenderingServer::RenderingServer() {
|
||||
GLOBAL_DEF("rendering/quality/reflection_atlas/reflection_size.mobile", 128);
|
||||
GLOBAL_DEF("rendering/quality/reflection_atlas/reflection_count", 64);
|
||||
|
||||
GLOBAL_DEF("rendering/quality/gi/use_half_resolution", false);
|
||||
|
||||
GLOBAL_DEF("rendering/quality/gi_probes/anisotropic", false);
|
||||
GLOBAL_DEF("rendering/quality/gi_probes/quality", 1);
|
||||
ProjectSettings::get_singleton()->set_custom_property_info("rendering/quality/gi_probes/quality", PropertyInfo(Variant::INT, "rendering/quality/gi_probes/quality", PROPERTY_HINT_ENUM, "Low (4 Cones - Fast),High (6 Cones - Slow)"));
|
||||
@ -2367,10 +2358,12 @@ RenderingServer::RenderingServer() {
|
||||
GLOBAL_DEF("rendering/lightmapper/probe_capture_update_speed", 15);
|
||||
ProjectSettings::get_singleton()->set_custom_property_info("rendering/lightmapper/probe_capture_update_speed", PropertyInfo(Variant::FLOAT, "rendering/lightmapper/probe_capture_update_speed", PROPERTY_HINT_RANGE, "0.001,256,0.001"));
|
||||
|
||||
GLOBAL_DEF("rendering/sdfgi/probe_ray_count", 2);
|
||||
GLOBAL_DEF("rendering/sdfgi/probe_ray_count", 1);
|
||||
ProjectSettings::get_singleton()->set_custom_property_info("rendering/sdfgi/probe_ray_count", PropertyInfo(Variant::INT, "rendering/sdfgi/probe_ray_count", PROPERTY_HINT_ENUM, "8 (Fastest),16,32,64,96,128 (Slowest)"));
|
||||
GLOBAL_DEF("rendering/sdfgi/frames_to_converge", 1);
|
||||
GLOBAL_DEF("rendering/sdfgi/frames_to_converge", 4);
|
||||
ProjectSettings::get_singleton()->set_custom_property_info("rendering/sdfgi/frames_to_converge", PropertyInfo(Variant::INT, "rendering/sdfgi/frames_to_converge", PROPERTY_HINT_ENUM, "5 (Less Latency but Lower Quality),10,15,20,25,30 (More Latency but Higher Quality)"));
|
||||
GLOBAL_DEF("rendering/sdfgi/frames_to_update_lights", 2);
|
||||
ProjectSettings::get_singleton()->set_custom_property_info("rendering/sdfgi/frames_to_update_lights", PropertyInfo(Variant::INT, "rendering/sdfgi/frames_to_update_lights", PROPERTY_HINT_ENUM, "1 (Slower),2,4,8,16 (Faster)"));
|
||||
|
||||
GLOBAL_DEF("rendering/volumetric_fog/volume_size", 64);
|
||||
ProjectSettings::get_singleton()->set_custom_property_info("rendering/volumetric_fog/volume_size", PropertyInfo(Variant::INT, "rendering/volumetric_fog/volume_size", PROPERTY_HINT_RANGE, "16,512,1"));
|
||||
|
@ -798,7 +798,7 @@ public:
|
||||
|
||||
virtual void viewport_set_sdf_oversize_and_scale(RID p_viewport, ViewportSDFOversize p_oversize, ViewportSDFScale p_scale) = 0;
|
||||
|
||||
virtual void viewport_set_shadow_atlas_size(RID p_viewport, int p_size) = 0;
|
||||
virtual void viewport_set_shadow_atlas_size(RID p_viewport, int p_size, bool p_16_bits = false) = 0;
|
||||
virtual void viewport_set_shadow_atlas_quadrant_subdivision(RID p_viewport, int p_quadrant, int p_subdiv) = 0;
|
||||
|
||||
enum ViewportMSAA {
|
||||
@ -868,7 +868,7 @@ public:
|
||||
virtual float viewport_get_measured_render_time_cpu(RID p_viewport) const = 0;
|
||||
virtual float viewport_get_measured_render_time_gpu(RID p_viewport) const = 0;
|
||||
|
||||
virtual void directional_shadow_atlas_set_size(int p_size) = 0;
|
||||
virtual void directional_shadow_atlas_set_size(int p_size, bool p_16_bits = false) = 0;
|
||||
|
||||
/* SKY API */
|
||||
|
||||
@ -986,6 +986,7 @@ public:
|
||||
virtual void environment_set_sdfgi(RID p_env, bool p_enable, EnvironmentSDFGICascades p_cascades, float p_min_cell_size, EnvironmentSDFGIYScale p_y_scale, bool p_use_occlusion, bool p_use_multibounce, bool p_read_sky, float p_energy, float p_normal_bias, float p_probe_bias) = 0;
|
||||
|
||||
enum EnvironmentSDFGIRayCount {
|
||||
ENV_SDFGI_RAY_COUNT_4,
|
||||
ENV_SDFGI_RAY_COUNT_8,
|
||||
ENV_SDFGI_RAY_COUNT_16,
|
||||
ENV_SDFGI_RAY_COUNT_32,
|
||||
@ -1009,6 +1010,17 @@ public:
|
||||
|
||||
virtual void environment_set_sdfgi_frames_to_converge(EnvironmentSDFGIFramesToConverge p_frames) = 0;
|
||||
|
||||
enum EnvironmentSDFGIFramesToUpdateLight {
|
||||
ENV_SDFGI_UPDATE_LIGHT_IN_1_FRAME,
|
||||
ENV_SDFGI_UPDATE_LIGHT_IN_2_FRAMES,
|
||||
ENV_SDFGI_UPDATE_LIGHT_IN_4_FRAMES,
|
||||
ENV_SDFGI_UPDATE_LIGHT_IN_8_FRAMES,
|
||||
ENV_SDFGI_UPDATE_LIGHT_IN_16_FRAMES,
|
||||
ENV_SDFGI_UPDATE_LIGHT_MAX,
|
||||
};
|
||||
|
||||
virtual void environment_set_sdfgi_frames_to_update_light(EnvironmentSDFGIFramesToUpdateLight p_update) = 0;
|
||||
|
||||
virtual void environment_set_fog(RID p_env, bool p_enable, const Color &p_light_color, float p_light_energy, float p_sun_scatter, float p_density, float p_height, float p_height_density, float p_aerial_perspective) = 0;
|
||||
|
||||
enum EnvVolumetricFogShadowFilter {
|
||||
@ -1430,6 +1442,8 @@ public:
|
||||
|
||||
virtual float get_frame_setup_time_cpu() const = 0;
|
||||
|
||||
virtual void gi_set_use_half_resolution(bool p_enable) = 0;
|
||||
|
||||
/* TESTING */
|
||||
|
||||
virtual RID get_test_cube() = 0;
|
||||
@ -1462,6 +1476,8 @@ public:
|
||||
|
||||
virtual bool is_low_end() const = 0;
|
||||
|
||||
virtual void set_print_gpu_profile(bool p_enable) = 0;
|
||||
|
||||
RenderingDevice *create_local_rendering_device() const;
|
||||
|
||||
bool is_render_loop_enabled() const;
|
||||
|
Loading…
Reference in New Issue
Block a user