Path: blob/master/servers/rendering/renderer_rd/environment/gi.cpp
10279 views
/**************************************************************************/1/* gi.cpp */2/**************************************************************************/3/* This file is part of: */4/* GODOT ENGINE */5/* https://godotengine.org */6/**************************************************************************/7/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */8/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */9/* */10/* Permission is hereby granted, free of charge, to any person obtaining */11/* a copy of this software and associated documentation files (the */12/* "Software"), to deal in the Software without restriction, including */13/* without limitation the rights to use, copy, modify, merge, publish, */14/* distribute, sublicense, and/or sell copies of the Software, and to */15/* permit persons to whom the Software is furnished to do so, subject to */16/* the following conditions: */17/* */18/* The above copyright notice and this permission notice shall be */19/* included in all copies or substantial portions of the Software. */20/* */21/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */22/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */23/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. */24/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */25/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */26/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */27/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */28/**************************************************************************/2930#include "gi.h"3132#include "core/config/project_settings.h"33#include "servers/rendering/renderer_rd/renderer_compositor_rd.h"34#include "servers/rendering/renderer_rd/renderer_scene_render_rd.h"35#include "servers/rendering/renderer_rd/storage_rd/material_storage.h"36#include "servers/rendering/renderer_rd/storage_rd/render_scene_buffers_rd.h"37#include "servers/rendering/renderer_rd/storage_rd/texture_storage.h"38#include "servers/rendering/rendering_server_default.h"3940using namespace RendererRD;4142const Vector3i GI::SDFGI::Cascade::DIRTY_ALL = Vector3i(0x7FFFFFFF, 0x7FFFFFFF, 0x7FFFFFFF);4344GI *GI::singleton = nullptr;4546////////////////////////////////////////////////////////////////////////////////47// VOXEL GI STORAGE4849RID GI::voxel_gi_allocate() {50return voxel_gi_owner.allocate_rid();51}5253void GI::voxel_gi_free(RID p_voxel_gi) {54voxel_gi_allocate_data(p_voxel_gi, Transform3D(), AABB(), Vector3i(), Vector<uint8_t>(), Vector<uint8_t>(), Vector<uint8_t>(), Vector<int>()); //deallocate55VoxelGI *voxel_gi = voxel_gi_owner.get_or_null(p_voxel_gi);56voxel_gi->dependency.deleted_notify(p_voxel_gi);57voxel_gi_owner.free(p_voxel_gi);58}5960void GI::voxel_gi_initialize(RID p_voxel_gi) {61voxel_gi_owner.initialize_rid(p_voxel_gi, VoxelGI());62}6364void GI::voxel_gi_allocate_data(RID p_voxel_gi, const Transform3D &p_to_cell_xform, const AABB &p_aabb, const Vector3i &p_octree_size, const Vector<uint8_t> &p_octree_cells, const Vector<uint8_t> &p_data_cells, const Vector<uint8_t> &p_distance_field, const Vector<int> &p_level_counts) {65VoxelGI *voxel_gi = voxel_gi_owner.get_or_null(p_voxel_gi);66ERR_FAIL_NULL(voxel_gi);6768if (voxel_gi->octree_buffer.is_valid()) {69RD::get_singleton()->free(voxel_gi->octree_buffer);70RD::get_singleton()->free(voxel_gi->data_buffer);71if (voxel_gi->sdf_texture.is_valid()) {72RD::get_singleton()->free(voxel_gi->sdf_texture);73}7475voxel_gi->sdf_texture = RID();76voxel_gi->octree_buffer = RID();77voxel_gi->data_buffer = RID();78voxel_gi->octree_buffer_size = 0;79voxel_gi->data_buffer_size = 0;80voxel_gi->cell_count = 0;81}8283voxel_gi->to_cell_xform = p_to_cell_xform;84voxel_gi->bounds = p_aabb;85voxel_gi->octree_size = p_octree_size;86voxel_gi->level_counts = p_level_counts;8788if (p_octree_cells.size()) {89ERR_FAIL_COND(p_octree_cells.size() % 32 != 0); //cells size must be a multiple of 329091uint32_t cell_count = p_octree_cells.size() / 32;9293ERR_FAIL_COND(p_data_cells.size() != (int)cell_count * 16); //see that data size matches9495voxel_gi->cell_count = cell_count;96voxel_gi->octree_buffer = RD::get_singleton()->storage_buffer_create(p_octree_cells.size(), p_octree_cells);97voxel_gi->octree_buffer_size = p_octree_cells.size();98voxel_gi->data_buffer = RD::get_singleton()->storage_buffer_create(p_data_cells.size(), p_data_cells);99voxel_gi->data_buffer_size = p_data_cells.size();100101if (p_distance_field.size()) {102RD::TextureFormat tf;103tf.format = RD::DATA_FORMAT_R8_UNORM;104tf.width = voxel_gi->octree_size.x;105tf.height = voxel_gi->octree_size.y;106tf.depth = voxel_gi->octree_size.z;107tf.texture_type = RD::TEXTURE_TYPE_3D;108tf.usage_bits = RD::TEXTURE_USAGE_SAMPLING_BIT | RD::TEXTURE_USAGE_CAN_UPDATE_BIT | RD::TEXTURE_USAGE_CAN_COPY_FROM_BIT;109Vector<Vector<uint8_t>> s;110s.push_back(p_distance_field);111voxel_gi->sdf_texture = RD::get_singleton()->texture_create(tf, RD::TextureView(), s);112RD::get_singleton()->set_resource_name(voxel_gi->sdf_texture, "VoxelGI SDF Texture");113}114#if 0115{116RD::TextureFormat tf;117tf.format = RD::DATA_FORMAT_R8_UNORM;118tf.width = voxel_gi->octree_size.x;119tf.height = voxel_gi->octree_size.y;120tf.depth = voxel_gi->octree_size.z;121tf.type = RD::TEXTURE_TYPE_3D;122tf.usage_bits = RD::TEXTURE_USAGE_SAMPLING_BIT | RD::TEXTURE_USAGE_STORAGE_BIT | RD::TEXTURE_USAGE_CAN_COPY_TO_BIT;123tf.shareable_formats.push_back(RD::DATA_FORMAT_R8_UNORM);124tf.shareable_formats.push_back(RD::DATA_FORMAT_R8_UINT);125voxel_gi->sdf_texture = RD::get_singleton()->texture_create(tf, RD::TextureView());126RD::get_singleton()->set_resource_name(voxel_gi->sdf_texture, "VoxelGI SDF Texture");127}128RID shared_tex;129{130RD::TextureView tv;131tv.format_override = RD::DATA_FORMAT_R8_UINT;132shared_tex = RD::get_singleton()->texture_create_shared(tv, voxel_gi->sdf_texture);133}134//update SDF texture135Vector<RD::Uniform> uniforms;136{137RD::Uniform u;138u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER;139u.binding = 1;140u.append_id(voxel_gi->octree_buffer);141uniforms.push_back(u);142}143{144RD::Uniform u;145u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER;146u.binding = 2;147u.append_id(voxel_gi->data_buffer);148uniforms.push_back(u);149}150{151RD::Uniform u;152u.uniform_type = RD::UNIFORM_TYPE_IMAGE;153u.binding = 3;154u.append_id(shared_tex);155uniforms.push_back(u);156}157158RID uniform_set = RD::get_singleton()->uniform_set_create(uniforms, voxel_gi_sdf_shader_version_shader, 0);159160{161uint32_t push_constant[4] = { 0, 0, 0, 0 };162163for (int i = 0; i < voxel_gi->level_counts.size() - 1; i++) {164push_constant[0] += voxel_gi->level_counts[i];165}166push_constant[1] = push_constant[0] + voxel_gi->level_counts[voxel_gi->level_counts.size() - 1];167168print_line("offset: " + itos(push_constant[0]));169print_line("size: " + itos(push_constant[1]));170//create SDF171RD::ComputeListID compute_list = RD::get_singleton()->compute_list_begin();172RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, voxel_gi_sdf_shader_pipeline);173RD::get_singleton()->compute_list_bind_uniform_set(compute_list, uniform_set, 0);174RD::get_singleton()->compute_list_set_push_constant(compute_list, push_constant, sizeof(uint32_t) * 4);175RD::get_singleton()->compute_list_dispatch(compute_list, voxel_gi->octree_size.x / 4, voxel_gi->octree_size.y / 4, voxel_gi->octree_size.z / 4);176RD::get_singleton()->compute_list_end();177}178179RD::get_singleton()->free(uniform_set);180RD::get_singleton()->free(shared_tex);181}182#endif183}184185voxel_gi->version++;186voxel_gi->data_version++;187188voxel_gi->dependency.changed_notify(Dependency::DEPENDENCY_CHANGED_AABB);189}190191AABB GI::voxel_gi_get_bounds(RID p_voxel_gi) const {192VoxelGI *voxel_gi = voxel_gi_owner.get_or_null(p_voxel_gi);193ERR_FAIL_NULL_V(voxel_gi, AABB());194195return voxel_gi->bounds;196}197198Vector3i GI::voxel_gi_get_octree_size(RID p_voxel_gi) const {199VoxelGI *voxel_gi = voxel_gi_owner.get_or_null(p_voxel_gi);200ERR_FAIL_NULL_V(voxel_gi, Vector3i());201return voxel_gi->octree_size;202}203204Vector<uint8_t> GI::voxel_gi_get_octree_cells(RID p_voxel_gi) const {205VoxelGI *voxel_gi = voxel_gi_owner.get_or_null(p_voxel_gi);206ERR_FAIL_NULL_V(voxel_gi, Vector<uint8_t>());207208if (voxel_gi->octree_buffer.is_valid()) {209return RD::get_singleton()->buffer_get_data(voxel_gi->octree_buffer);210}211return Vector<uint8_t>();212}213214Vector<uint8_t> GI::voxel_gi_get_data_cells(RID p_voxel_gi) const {215VoxelGI *voxel_gi = voxel_gi_owner.get_or_null(p_voxel_gi);216ERR_FAIL_NULL_V(voxel_gi, Vector<uint8_t>());217218if (voxel_gi->data_buffer.is_valid()) {219return RD::get_singleton()->buffer_get_data(voxel_gi->data_buffer);220}221return Vector<uint8_t>();222}223224Vector<uint8_t> GI::voxel_gi_get_distance_field(RID p_voxel_gi) const {225VoxelGI *voxel_gi = voxel_gi_owner.get_or_null(p_voxel_gi);226ERR_FAIL_NULL_V(voxel_gi, Vector<uint8_t>());227228if (voxel_gi->data_buffer.is_valid()) {229return RD::get_singleton()->texture_get_data(voxel_gi->sdf_texture, 0);230}231return Vector<uint8_t>();232}233234Vector<int> GI::voxel_gi_get_level_counts(RID p_voxel_gi) const {235VoxelGI *voxel_gi = voxel_gi_owner.get_or_null(p_voxel_gi);236ERR_FAIL_NULL_V(voxel_gi, Vector<int>());237238return voxel_gi->level_counts;239}240241Transform3D GI::voxel_gi_get_to_cell_xform(RID p_voxel_gi) const {242VoxelGI *voxel_gi = voxel_gi_owner.get_or_null(p_voxel_gi);243ERR_FAIL_NULL_V(voxel_gi, Transform3D());244245return voxel_gi->to_cell_xform;246}247248void GI::voxel_gi_set_dynamic_range(RID p_voxel_gi, float p_range) {249VoxelGI *voxel_gi = voxel_gi_owner.get_or_null(p_voxel_gi);250ERR_FAIL_NULL(voxel_gi);251252voxel_gi->dynamic_range = p_range;253voxel_gi->version++;254}255256float GI::voxel_gi_get_dynamic_range(RID p_voxel_gi) const {257VoxelGI *voxel_gi = voxel_gi_owner.get_or_null(p_voxel_gi);258ERR_FAIL_NULL_V(voxel_gi, 0);259260return voxel_gi->dynamic_range;261}262263void GI::voxel_gi_set_propagation(RID p_voxel_gi, float p_range) {264VoxelGI *voxel_gi = voxel_gi_owner.get_or_null(p_voxel_gi);265ERR_FAIL_NULL(voxel_gi);266267voxel_gi->propagation = p_range;268voxel_gi->version++;269}270271float GI::voxel_gi_get_propagation(RID p_voxel_gi) const {272VoxelGI *voxel_gi = voxel_gi_owner.get_or_null(p_voxel_gi);273ERR_FAIL_NULL_V(voxel_gi, 0);274return voxel_gi->propagation;275}276277void GI::voxel_gi_set_energy(RID p_voxel_gi, float p_energy) {278VoxelGI *voxel_gi = voxel_gi_owner.get_or_null(p_voxel_gi);279ERR_FAIL_NULL(voxel_gi);280281voxel_gi->energy = p_energy;282}283284float GI::voxel_gi_get_energy(RID p_voxel_gi) const {285VoxelGI *voxel_gi = voxel_gi_owner.get_or_null(p_voxel_gi);286ERR_FAIL_NULL_V(voxel_gi, 0);287return voxel_gi->energy;288}289290void GI::voxel_gi_set_baked_exposure_normalization(RID p_voxel_gi, float p_baked_exposure) {291VoxelGI *voxel_gi = voxel_gi_owner.get_or_null(p_voxel_gi);292ERR_FAIL_NULL(voxel_gi);293294voxel_gi->baked_exposure = p_baked_exposure;295}296297float GI::voxel_gi_get_baked_exposure_normalization(RID p_voxel_gi) const {298VoxelGI *voxel_gi = voxel_gi_owner.get_or_null(p_voxel_gi);299ERR_FAIL_NULL_V(voxel_gi, 0);300return voxel_gi->baked_exposure;301}302303void GI::voxel_gi_set_bias(RID p_voxel_gi, float p_bias) {304VoxelGI *voxel_gi = voxel_gi_owner.get_or_null(p_voxel_gi);305ERR_FAIL_NULL(voxel_gi);306307voxel_gi->bias = p_bias;308}309310float GI::voxel_gi_get_bias(RID p_voxel_gi) const {311VoxelGI *voxel_gi = voxel_gi_owner.get_or_null(p_voxel_gi);312ERR_FAIL_NULL_V(voxel_gi, 0);313return voxel_gi->bias;314}315316void GI::voxel_gi_set_normal_bias(RID p_voxel_gi, float p_normal_bias) {317VoxelGI *voxel_gi = voxel_gi_owner.get_or_null(p_voxel_gi);318ERR_FAIL_NULL(voxel_gi);319320voxel_gi->normal_bias = p_normal_bias;321}322323float GI::voxel_gi_get_normal_bias(RID p_voxel_gi) const {324VoxelGI *voxel_gi = voxel_gi_owner.get_or_null(p_voxel_gi);325ERR_FAIL_NULL_V(voxel_gi, 0);326return voxel_gi->normal_bias;327}328329void GI::voxel_gi_set_interior(RID p_voxel_gi, bool p_enable) {330VoxelGI *voxel_gi = voxel_gi_owner.get_or_null(p_voxel_gi);331ERR_FAIL_NULL(voxel_gi);332333voxel_gi->interior = p_enable;334}335336void GI::voxel_gi_set_use_two_bounces(RID p_voxel_gi, bool p_enable) {337VoxelGI *voxel_gi = voxel_gi_owner.get_or_null(p_voxel_gi);338ERR_FAIL_NULL(voxel_gi);339340voxel_gi->use_two_bounces = p_enable;341voxel_gi->version++;342}343344bool GI::voxel_gi_is_using_two_bounces(RID p_voxel_gi) const {345VoxelGI *voxel_gi = voxel_gi_owner.get_or_null(p_voxel_gi);346ERR_FAIL_NULL_V(voxel_gi, false);347return voxel_gi->use_two_bounces;348}349350bool GI::voxel_gi_is_interior(RID p_voxel_gi) const {351VoxelGI *voxel_gi = voxel_gi_owner.get_or_null(p_voxel_gi);352ERR_FAIL_NULL_V(voxel_gi, false);353return voxel_gi->interior;354}355356uint32_t GI::voxel_gi_get_version(RID p_voxel_gi) const {357VoxelGI *voxel_gi = voxel_gi_owner.get_or_null(p_voxel_gi);358ERR_FAIL_NULL_V(voxel_gi, 0);359return voxel_gi->version;360}361362uint32_t GI::voxel_gi_get_data_version(RID p_voxel_gi) {363VoxelGI *voxel_gi = voxel_gi_owner.get_or_null(p_voxel_gi);364ERR_FAIL_NULL_V(voxel_gi, 0);365return voxel_gi->data_version;366}367368RID GI::voxel_gi_get_octree_buffer(RID p_voxel_gi) const {369VoxelGI *voxel_gi = voxel_gi_owner.get_or_null(p_voxel_gi);370ERR_FAIL_NULL_V(voxel_gi, RID());371return voxel_gi->octree_buffer;372}373374RID GI::voxel_gi_get_data_buffer(RID p_voxel_gi) const {375VoxelGI *voxel_gi = voxel_gi_owner.get_or_null(p_voxel_gi);376ERR_FAIL_NULL_V(voxel_gi, RID());377return voxel_gi->data_buffer;378}379380RID GI::voxel_gi_get_sdf_texture(RID p_voxel_gi) {381VoxelGI *voxel_gi = voxel_gi_owner.get_or_null(p_voxel_gi);382ERR_FAIL_NULL_V(voxel_gi, RID());383384return voxel_gi->sdf_texture;385}386387Dependency *GI::voxel_gi_get_dependency(RID p_voxel_gi) const {388VoxelGI *voxel_gi = voxel_gi_owner.get_or_null(p_voxel_gi);389ERR_FAIL_NULL_V(voxel_gi, nullptr);390391return &voxel_gi->dependency;392}393394void GI::sdfgi_reset() {395sdfgi_current_version++;396}397398////////////////////////////////////////////////////////////////////////////////399// SDFGI400401static RID create_clear_texture(const RD::TextureFormat &p_format, const String &p_name) {402RID texture = RD::get_singleton()->texture_create(p_format, RD::TextureView());403ERR_FAIL_COND_V_MSG(texture.is_null(), RID(), String("Cannot create texture: ") + p_name);404405RD::get_singleton()->set_resource_name(texture, p_name);406RD::get_singleton()->texture_clear(texture, Color(0, 0, 0, 0), 0, p_format.mipmaps, 0, p_format.array_layers);407408return texture;409}410411void GI::SDFGI::create(RID p_env, const Vector3 &p_world_position, uint32_t p_requested_history_size, GI *p_gi) {412RendererRD::TextureStorage *texture_storage = RendererRD::TextureStorage::get_singleton();413RendererRD::MaterialStorage *material_storage = RendererRD::MaterialStorage::get_singleton();414415gi = p_gi;416num_cascades = RendererSceneRenderRD::get_singleton()->environment_get_sdfgi_cascades(p_env);417min_cell_size = RendererSceneRenderRD::get_singleton()->environment_get_sdfgi_min_cell_size(p_env);418uses_occlusion = RendererSceneRenderRD::get_singleton()->environment_get_sdfgi_use_occlusion(p_env);419y_scale_mode = RendererSceneRenderRD::get_singleton()->environment_get_sdfgi_y_scale(p_env);420static const float y_scale[3] = { 2.0, 1.5, 1.0 };421y_mult = y_scale[y_scale_mode];422version = gi->sdfgi_current_version;423cascades.resize(num_cascades);424probe_axis_count = SDFGI::PROBE_DIVISOR + 1;425solid_cell_ratio = gi->sdfgi_solid_cell_ratio;426solid_cell_count = uint32_t(float(cascade_size * cascade_size * cascade_size) * solid_cell_ratio);427428float base_cell_size = min_cell_size;429430RD::TextureFormat tf_sdf;431tf_sdf.format = RD::DATA_FORMAT_R8_UNORM;432tf_sdf.width = cascade_size; // Always 64x64433tf_sdf.height = cascade_size;434tf_sdf.depth = cascade_size;435tf_sdf.texture_type = RD::TEXTURE_TYPE_3D;436tf_sdf.usage_bits = RD::TEXTURE_USAGE_SAMPLING_BIT | RD::TEXTURE_USAGE_STORAGE_BIT | RD::TEXTURE_USAGE_CAN_COPY_TO_BIT | RD::TEXTURE_USAGE_CAN_COPY_FROM_BIT;437438{439RD::TextureFormat tf_render = tf_sdf;440tf_render.format = RD::DATA_FORMAT_R16_UINT;441render_albedo = create_clear_texture(tf_render, "SDFGI Render Albedo");442443tf_render.format = RD::DATA_FORMAT_R32_UINT;444render_emission = create_clear_texture(tf_render, "SDFGI Render Emission");445render_emission_aniso = create_clear_texture(tf_render, "SDFGI Render Emission Aniso");446447tf_render.format = RD::DATA_FORMAT_R8_UNORM; //at least its easy to visualize448449for (int i = 0; i < 8; i++) {450render_occlusion[i] = create_clear_texture(tf_render, String("SDFGI Render Occlusion ") + itos(i));451}452453tf_render.format = RD::DATA_FORMAT_R32_UINT;454render_geom_facing = create_clear_texture(tf_render, "SDFGI Render Geometry Facing");455456tf_render.format = RD::DATA_FORMAT_R8G8B8A8_UINT;457render_sdf[0] = create_clear_texture(tf_render, "SDFGI Render SDF 0");458render_sdf[1] = create_clear_texture(tf_render, "SDFGI Render SDF 1");459460tf_render.width /= 2;461tf_render.height /= 2;462tf_render.depth /= 2;463464render_sdf_half[0] = create_clear_texture(tf_render, "SDFGI Render SDF Half 0");465render_sdf_half[1] = create_clear_texture(tf_render, "SDFGI Render SDF Half 1");466}467468RD::TextureFormat tf_occlusion = tf_sdf;469tf_occlusion.format = RD::DATA_FORMAT_R16_UINT;470tf_occlusion.shareable_formats.push_back(RD::DATA_FORMAT_R16_UINT);471tf_occlusion.shareable_formats.push_back(RD::DATA_FORMAT_R4G4B4A4_UNORM_PACK16);472tf_occlusion.depth *= cascades.size(); //use depth for occlusion slices473tf_occlusion.width *= 2; //use width for the other half474475RD::TextureFormat tf_light = tf_sdf;476tf_light.format = RD::DATA_FORMAT_R32_UINT;477tf_light.shareable_formats.push_back(RD::DATA_FORMAT_R32_UINT);478tf_light.shareable_formats.push_back(RD::DATA_FORMAT_E5B9G9R9_UFLOAT_PACK32);479480RD::TextureFormat tf_aniso0 = tf_sdf;481tf_aniso0.format = RD::DATA_FORMAT_R8G8B8A8_UNORM;482RD::TextureFormat tf_aniso1 = tf_sdf;483tf_aniso1.format = RD::DATA_FORMAT_R8G8_UNORM;484485int passes = nearest_shift(cascade_size) - 1;486487//store lightprobe SH488RD::TextureFormat tf_probes;489tf_probes.format = RD::DATA_FORMAT_R16G16B16A16_SFLOAT;490tf_probes.width = probe_axis_count * probe_axis_count;491tf_probes.height = probe_axis_count * SDFGI::SH_SIZE;492tf_probes.usage_bits = RD::TEXTURE_USAGE_SAMPLING_BIT | RD::TEXTURE_USAGE_STORAGE_BIT | RD::TEXTURE_USAGE_CAN_COPY_TO_BIT | RD::TEXTURE_USAGE_CAN_COPY_FROM_BIT;493tf_probes.texture_type = RD::TEXTURE_TYPE_2D_ARRAY;494495history_size = p_requested_history_size;496497RD::TextureFormat tf_probe_history = tf_probes;498tf_probe_history.format = RD::DATA_FORMAT_R16G16B16A16_SINT; //signed integer because SH are signed499tf_probe_history.array_layers = history_size;500501RD::TextureFormat tf_probe_average = tf_probes;502tf_probe_average.format = RD::DATA_FORMAT_R32G32B32A32_SINT; //signed integer because SH are signed503tf_probe_average.texture_type = RD::TEXTURE_TYPE_2D;504505lightprobe_history_scroll = create_clear_texture(tf_probe_history, "SDFGI LightProbe History Scroll");506lightprobe_average_scroll = create_clear_texture(tf_probe_average, "SDFGI LightProbe Average Scroll");507508{509//octahedral lightprobes510RD::TextureFormat tf_octprobes = tf_probes;511tf_octprobes.array_layers = cascades.size() * 2;512tf_octprobes.format = RD::DATA_FORMAT_R32_UINT; //pack well with RGBE513tf_octprobes.width = probe_axis_count * probe_axis_count * (SDFGI::LIGHTPROBE_OCT_SIZE + 2);514tf_octprobes.height = probe_axis_count * (SDFGI::LIGHTPROBE_OCT_SIZE + 2);515tf_octprobes.shareable_formats.push_back(RD::DATA_FORMAT_R32_UINT);516tf_octprobes.shareable_formats.push_back(RD::DATA_FORMAT_E5B9G9R9_UFLOAT_PACK32);517//lightprobe texture is an octahedral texture518519lightprobe_data = create_clear_texture(tf_octprobes, "SDFGI LightProbe Data");520RD::TextureView tv;521tv.format_override = RD::DATA_FORMAT_E5B9G9R9_UFLOAT_PACK32;522lightprobe_texture = RD::get_singleton()->texture_create_shared(tv, lightprobe_data);523524//texture handling ambient data, to integrate with volumetric foc525RD::TextureFormat tf_ambient = tf_probes;526tf_ambient.array_layers = cascades.size();527tf_ambient.format = RD::DATA_FORMAT_R16G16B16A16_SFLOAT; //pack well with RGBE528tf_ambient.width = probe_axis_count * probe_axis_count;529tf_ambient.height = probe_axis_count;530tf_ambient.texture_type = RD::TEXTURE_TYPE_2D_ARRAY;531//lightprobe texture is an octahedral texture532ambient_texture = create_clear_texture(tf_ambient, "SDFGI Ambient Texture");533}534535cascades_ubo = RD::get_singleton()->uniform_buffer_create(sizeof(SDFGI::Cascade::UBO) * SDFGI::MAX_CASCADES);536537occlusion_data = create_clear_texture(tf_occlusion, "SDFGI Occlusion Data");538{539RD::TextureView tv;540tv.format_override = RD::DATA_FORMAT_R4G4B4A4_UNORM_PACK16;541occlusion_texture = RD::get_singleton()->texture_create_shared(tv, occlusion_data);542}543544for (SDFGI::Cascade &cascade : cascades) {545/* 3D Textures */546547cascade.sdf_tex = create_clear_texture(tf_sdf, "SDFGI Cascade SDF Texture");548549cascade.light_data = create_clear_texture(tf_light, "SDFGI Cascade Light Data");550551cascade.light_aniso_0_tex = create_clear_texture(tf_aniso0, "SDFGI Cascade Light Aniso 0 Texture");552cascade.light_aniso_1_tex = create_clear_texture(tf_aniso1, "SDFGI Cascade Light Aniso 1 Texture");553554{555RD::TextureView tv;556tv.format_override = RD::DATA_FORMAT_E5B9G9R9_UFLOAT_PACK32;557cascade.light_tex = RD::get_singleton()->texture_create_shared(tv, cascade.light_data);558}559560cascade.cell_size = base_cell_size;561Vector3 world_position = p_world_position;562world_position.y *= y_mult;563int32_t probe_cells = cascade_size / SDFGI::PROBE_DIVISOR;564Vector3 probe_size = Vector3(1, 1, 1) * cascade.cell_size * probe_cells;565Vector3i probe_pos = Vector3i((world_position / probe_size + Vector3(0.5, 0.5, 0.5)).floor());566cascade.position = probe_pos * probe_cells;567568cascade.dirty_regions = SDFGI::Cascade::DIRTY_ALL;569570base_cell_size *= 2.0;571572/* Probe History */573574cascade.lightprobe_history_tex = RD::get_singleton()->texture_create(tf_probe_history, RD::TextureView());575RD::get_singleton()->set_resource_name(cascade.lightprobe_history_tex, "SDFGI Cascade LightProbe History Texture");576RD::get_singleton()->texture_clear(cascade.lightprobe_history_tex, Color(0, 0, 0, 0), 0, 1, 0, tf_probe_history.array_layers); //needs to be cleared for average to work577578cascade.lightprobe_average_tex = RD::get_singleton()->texture_create(tf_probe_average, RD::TextureView());579RD::get_singleton()->set_resource_name(cascade.lightprobe_average_tex, "SDFGI Cascade LightProbe Average Texture");580RD::get_singleton()->texture_clear(cascade.lightprobe_average_tex, Color(0, 0, 0, 0), 0, 1, 0, 1); //needs to be cleared for average to work581582/* Buffers */583584cascade.solid_cell_buffer = RD::get_singleton()->storage_buffer_create(sizeof(SDFGI::Cascade::SolidCell) * solid_cell_count);585cascade.solid_cell_dispatch_buffer_storage = RD::get_singleton()->storage_buffer_create(sizeof(uint32_t) * 4, Vector<uint8_t>());586cascade.solid_cell_dispatch_buffer_call = RD::get_singleton()->storage_buffer_create(sizeof(uint32_t) * 4, Vector<uint8_t>(), RD::STORAGE_BUFFER_USAGE_DISPATCH_INDIRECT);587cascade.lights_buffer = RD::get_singleton()->storage_buffer_create(sizeof(SDFGIShader::Light) * MAX(SDFGI::MAX_STATIC_LIGHTS, SDFGI::MAX_DYNAMIC_LIGHTS));588{589Vector<RD::Uniform> uniforms;590{591RD::Uniform u;592u.uniform_type = RD::UNIFORM_TYPE_IMAGE;593u.binding = 1;594u.append_id(render_sdf[(passes & 1) ? 1 : 0]); //if passes are even, we read from buffer 0, else we read from buffer 1595uniforms.push_back(u);596}597{598RD::Uniform u;599u.uniform_type = RD::UNIFORM_TYPE_IMAGE;600u.binding = 2;601u.append_id(render_albedo);602uniforms.push_back(u);603}604{605RD::Uniform u;606u.uniform_type = RD::UNIFORM_TYPE_IMAGE;607u.binding = 3;608for (int j = 0; j < 8; j++) {609u.append_id(render_occlusion[j]);610}611uniforms.push_back(u);612}613{614RD::Uniform u;615u.uniform_type = RD::UNIFORM_TYPE_IMAGE;616u.binding = 4;617u.append_id(render_emission);618uniforms.push_back(u);619}620{621RD::Uniform u;622u.uniform_type = RD::UNIFORM_TYPE_IMAGE;623u.binding = 5;624u.append_id(render_emission_aniso);625uniforms.push_back(u);626}627{628RD::Uniform u;629u.uniform_type = RD::UNIFORM_TYPE_IMAGE;630u.binding = 6;631u.append_id(render_geom_facing);632uniforms.push_back(u);633}634635{636RD::Uniform u;637u.uniform_type = RD::UNIFORM_TYPE_IMAGE;638u.binding = 7;639u.append_id(cascade.sdf_tex);640uniforms.push_back(u);641}642{643RD::Uniform u;644u.uniform_type = RD::UNIFORM_TYPE_IMAGE;645u.binding = 8;646u.append_id(occlusion_data);647uniforms.push_back(u);648}649{650RD::Uniform u;651u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER;652u.binding = 10;653u.append_id(cascade.solid_cell_dispatch_buffer_storage);654uniforms.push_back(u);655}656{657RD::Uniform u;658u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER;659u.binding = 11;660u.append_id(cascade.solid_cell_buffer);661uniforms.push_back(u);662}663664cascade.sdf_store_uniform_set = RD::get_singleton()->uniform_set_create(uniforms, gi->sdfgi_shader.preprocess.version_get_shader(gi->sdfgi_shader.preprocess_shader, SDFGIShader::PRE_PROCESS_STORE), 0);665}666667{668Vector<RD::Uniform> uniforms;669{670RD::Uniform u;671u.uniform_type = RD::UNIFORM_TYPE_IMAGE;672u.binding = 1;673u.append_id(render_albedo);674uniforms.push_back(u);675}676{677RD::Uniform u;678u.uniform_type = RD::UNIFORM_TYPE_IMAGE;679u.binding = 2;680u.append_id(render_geom_facing);681uniforms.push_back(u);682}683{684RD::Uniform u;685u.uniform_type = RD::UNIFORM_TYPE_IMAGE;686u.binding = 3;687u.append_id(render_emission);688uniforms.push_back(u);689}690{691RD::Uniform u;692u.uniform_type = RD::UNIFORM_TYPE_IMAGE;693u.binding = 4;694u.append_id(render_emission_aniso);695uniforms.push_back(u);696}697{698RD::Uniform u;699u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER;700u.binding = 5;701u.append_id(cascade.solid_cell_dispatch_buffer_storage);702uniforms.push_back(u);703}704{705RD::Uniform u;706u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER;707u.binding = 6;708u.append_id(cascade.solid_cell_buffer);709uniforms.push_back(u);710}711712cascade.scroll_uniform_set = RD::get_singleton()->uniform_set_create(uniforms, gi->sdfgi_shader.preprocess.version_get_shader(gi->sdfgi_shader.preprocess_shader, SDFGIShader::PRE_PROCESS_SCROLL), 0);713}714{715Vector<RD::Uniform> uniforms;716{717RD::Uniform u;718u.uniform_type = RD::UNIFORM_TYPE_IMAGE;719u.binding = 1;720for (int j = 0; j < 8; j++) {721u.append_id(render_occlusion[j]);722}723uniforms.push_back(u);724}725{726RD::Uniform u;727u.uniform_type = RD::UNIFORM_TYPE_IMAGE;728u.binding = 2;729u.append_id(occlusion_data);730uniforms.push_back(u);731}732733cascade.scroll_occlusion_uniform_set = RD::get_singleton()->uniform_set_create(uniforms, gi->sdfgi_shader.preprocess.version_get_shader(gi->sdfgi_shader.preprocess_shader, SDFGIShader::PRE_PROCESS_SCROLL_OCCLUSION), 0);734}735}736737//direct light738for (SDFGI::Cascade &cascade : cascades) {739Vector<RD::Uniform> uniforms;740{741RD::Uniform u;742u.binding = 1;743u.uniform_type = RD::UNIFORM_TYPE_TEXTURE;744for (uint32_t j = 0; j < SDFGI::MAX_CASCADES; j++) {745if (j < cascades.size()) {746u.append_id(cascades[j].sdf_tex);747} else {748u.append_id(texture_storage->texture_rd_get_default(RendererRD::TextureStorage::DEFAULT_RD_TEXTURE_3D_WHITE));749}750}751uniforms.push_back(u);752}753{754RD::Uniform u;755u.binding = 2;756u.uniform_type = RD::UNIFORM_TYPE_SAMPLER;757u.append_id(material_storage->sampler_rd_get_default(RS::CANVAS_ITEM_TEXTURE_FILTER_LINEAR, RS::CANVAS_ITEM_TEXTURE_REPEAT_DISABLED));758uniforms.push_back(u);759}760{761RD::Uniform u;762u.binding = 3;763u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER;764u.append_id(cascade.solid_cell_dispatch_buffer_storage);765uniforms.push_back(u);766}767{768RD::Uniform u;769u.binding = 4;770u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER;771u.append_id(cascade.solid_cell_buffer);772uniforms.push_back(u);773}774{775RD::Uniform u;776u.binding = 5;777u.uniform_type = RD::UNIFORM_TYPE_IMAGE;778u.append_id(cascade.light_data);779uniforms.push_back(u);780}781{782RD::Uniform u;783u.binding = 6;784u.uniform_type = RD::UNIFORM_TYPE_IMAGE;785u.append_id(cascade.light_aniso_0_tex);786uniforms.push_back(u);787}788{789RD::Uniform u;790u.binding = 7;791u.uniform_type = RD::UNIFORM_TYPE_IMAGE;792u.append_id(cascade.light_aniso_1_tex);793uniforms.push_back(u);794}795{796RD::Uniform u;797u.binding = 8;798u.uniform_type = RD::UNIFORM_TYPE_UNIFORM_BUFFER;799u.append_id(cascades_ubo);800uniforms.push_back(u);801}802{803RD::Uniform u;804u.binding = 9;805u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER;806u.append_id(cascade.lights_buffer);807uniforms.push_back(u);808}809{810RD::Uniform u;811u.binding = 10;812u.uniform_type = RD::UNIFORM_TYPE_TEXTURE;813u.append_id(lightprobe_texture);814uniforms.push_back(u);815}816{817RD::Uniform u;818u.binding = 11;819u.uniform_type = RD::UNIFORM_TYPE_TEXTURE;820u.append_id(occlusion_texture);821uniforms.push_back(u);822}823824cascade.sdf_direct_light_static_uniform_set = RD::get_singleton()->uniform_set_create(uniforms, gi->sdfgi_shader.direct_light.version_get_shader(gi->sdfgi_shader.direct_light_shader, SDFGIShader::DIRECT_LIGHT_MODE_STATIC), 0);825cascade.sdf_direct_light_dynamic_uniform_set = RD::get_singleton()->uniform_set_create(uniforms, gi->sdfgi_shader.direct_light.version_get_shader(gi->sdfgi_shader.direct_light_shader, SDFGIShader::DIRECT_LIGHT_MODE_DYNAMIC), 0);826}827828//preprocess initialize uniform set829{830Vector<RD::Uniform> uniforms;831{832RD::Uniform u;833u.uniform_type = RD::UNIFORM_TYPE_IMAGE;834u.binding = 1;835u.append_id(render_albedo);836uniforms.push_back(u);837}838{839RD::Uniform u;840u.uniform_type = RD::UNIFORM_TYPE_IMAGE;841u.binding = 2;842u.append_id(render_sdf[0]);843uniforms.push_back(u);844}845846sdf_initialize_uniform_set = RD::get_singleton()->uniform_set_create(uniforms, gi->sdfgi_shader.preprocess.version_get_shader(gi->sdfgi_shader.preprocess_shader, SDFGIShader::PRE_PROCESS_JUMP_FLOOD_INITIALIZE), 0);847}848849{850Vector<RD::Uniform> uniforms;851{852RD::Uniform u;853u.uniform_type = RD::UNIFORM_TYPE_IMAGE;854u.binding = 1;855u.append_id(render_albedo);856uniforms.push_back(u);857}858{859RD::Uniform u;860u.uniform_type = RD::UNIFORM_TYPE_IMAGE;861u.binding = 2;862u.append_id(render_sdf_half[0]);863uniforms.push_back(u);864}865866sdf_initialize_half_uniform_set = RD::get_singleton()->uniform_set_create(uniforms, gi->sdfgi_shader.preprocess.version_get_shader(gi->sdfgi_shader.preprocess_shader, SDFGIShader::PRE_PROCESS_JUMP_FLOOD_INITIALIZE_HALF), 0);867}868869//jump flood uniform set870{871Vector<RD::Uniform> uniforms;872{873RD::Uniform u;874u.uniform_type = RD::UNIFORM_TYPE_IMAGE;875u.binding = 1;876u.append_id(render_sdf[0]);877uniforms.push_back(u);878}879{880RD::Uniform u;881u.uniform_type = RD::UNIFORM_TYPE_IMAGE;882u.binding = 2;883u.append_id(render_sdf[1]);884uniforms.push_back(u);885}886887jump_flood_uniform_set[0] = RD::get_singleton()->uniform_set_create(uniforms, gi->sdfgi_shader.preprocess.version_get_shader(gi->sdfgi_shader.preprocess_shader, SDFGIShader::PRE_PROCESS_JUMP_FLOOD), 0);888RID aux0 = uniforms.write[0].get_id(0);889RID aux1 = uniforms.write[1].get_id(0);890uniforms.write[0].set_id(0, aux1);891uniforms.write[1].set_id(0, aux0);892jump_flood_uniform_set[1] = RD::get_singleton()->uniform_set_create(uniforms, gi->sdfgi_shader.preprocess.version_get_shader(gi->sdfgi_shader.preprocess_shader, SDFGIShader::PRE_PROCESS_JUMP_FLOOD), 0);893}894//jump flood half uniform set895{896Vector<RD::Uniform> uniforms;897{898RD::Uniform u;899u.uniform_type = RD::UNIFORM_TYPE_IMAGE;900u.binding = 1;901u.append_id(render_sdf_half[0]);902uniforms.push_back(u);903}904{905RD::Uniform u;906u.uniform_type = RD::UNIFORM_TYPE_IMAGE;907u.binding = 2;908u.append_id(render_sdf_half[1]);909uniforms.push_back(u);910}911912jump_flood_half_uniform_set[0] = RD::get_singleton()->uniform_set_create(uniforms, gi->sdfgi_shader.preprocess.version_get_shader(gi->sdfgi_shader.preprocess_shader, SDFGIShader::PRE_PROCESS_JUMP_FLOOD), 0);913RID aux0 = uniforms.write[0].get_id(0);914RID aux1 = uniforms.write[1].get_id(0);915uniforms.write[0].set_id(0, aux1);916uniforms.write[1].set_id(0, aux0);917jump_flood_half_uniform_set[1] = RD::get_singleton()->uniform_set_create(uniforms, gi->sdfgi_shader.preprocess.version_get_shader(gi->sdfgi_shader.preprocess_shader, SDFGIShader::PRE_PROCESS_JUMP_FLOOD), 0);918}919920//upscale half size sdf921{922Vector<RD::Uniform> uniforms;923{924RD::Uniform u;925u.uniform_type = RD::UNIFORM_TYPE_IMAGE;926u.binding = 1;927u.append_id(render_albedo);928uniforms.push_back(u);929}930{931RD::Uniform u;932u.uniform_type = RD::UNIFORM_TYPE_IMAGE;933u.binding = 2;934u.append_id(render_sdf_half[(passes & 1) ? 0 : 1]); //reverse pass order because half size935uniforms.push_back(u);936}937{938RD::Uniform u;939u.uniform_type = RD::UNIFORM_TYPE_IMAGE;940u.binding = 3;941u.append_id(render_sdf[(passes & 1) ? 0 : 1]); //reverse pass order because it needs an extra JFA pass942uniforms.push_back(u);943}944945upscale_jfa_uniform_set_index = (passes & 1) ? 0 : 1;946sdf_upscale_uniform_set = RD::get_singleton()->uniform_set_create(uniforms, gi->sdfgi_shader.preprocess.version_get_shader(gi->sdfgi_shader.preprocess_shader, SDFGIShader::PRE_PROCESS_JUMP_FLOOD_UPSCALE), 0);947}948949//occlusion uniform set950{951Vector<RD::Uniform> uniforms;952{953RD::Uniform u;954u.uniform_type = RD::UNIFORM_TYPE_IMAGE;955u.binding = 1;956u.append_id(render_albedo);957uniforms.push_back(u);958}959{960RD::Uniform u;961u.uniform_type = RD::UNIFORM_TYPE_IMAGE;962u.binding = 2;963for (int i = 0; i < 8; i++) {964u.append_id(render_occlusion[i]);965}966uniforms.push_back(u);967}968{969RD::Uniform u;970u.uniform_type = RD::UNIFORM_TYPE_IMAGE;971u.binding = 3;972u.append_id(render_geom_facing);973uniforms.push_back(u);974}975976occlusion_uniform_set = RD::get_singleton()->uniform_set_create(uniforms, gi->sdfgi_shader.preprocess.version_get_shader(gi->sdfgi_shader.preprocess_shader, SDFGIShader::PRE_PROCESS_OCCLUSION), 0);977}978979for (uint32_t i = 0; i < cascades.size(); i++) {980//integrate uniform981982Vector<RD::Uniform> uniforms;983984{985RD::Uniform u;986u.binding = 1;987u.uniform_type = RD::UNIFORM_TYPE_TEXTURE;988for (uint32_t j = 0; j < SDFGI::MAX_CASCADES; j++) {989if (j < cascades.size()) {990u.append_id(cascades[j].sdf_tex);991} else {992u.append_id(texture_storage->texture_rd_get_default(RendererRD::TextureStorage::DEFAULT_RD_TEXTURE_3D_WHITE));993}994}995uniforms.push_back(u);996}997{998RD::Uniform u;999u.binding = 2;1000u.uniform_type = RD::UNIFORM_TYPE_TEXTURE;1001for (uint32_t j = 0; j < SDFGI::MAX_CASCADES; j++) {1002if (j < cascades.size()) {1003u.append_id(cascades[j].light_tex);1004} else {1005u.append_id(texture_storage->texture_rd_get_default(RendererRD::TextureStorage::DEFAULT_RD_TEXTURE_3D_WHITE));1006}1007}1008uniforms.push_back(u);1009}1010{1011RD::Uniform u;1012u.binding = 3;1013u.uniform_type = RD::UNIFORM_TYPE_TEXTURE;1014for (uint32_t j = 0; j < SDFGI::MAX_CASCADES; j++) {1015if (j < cascades.size()) {1016u.append_id(cascades[j].light_aniso_0_tex);1017} else {1018u.append_id(texture_storage->texture_rd_get_default(RendererRD::TextureStorage::DEFAULT_RD_TEXTURE_3D_WHITE));1019}1020}1021uniforms.push_back(u);1022}1023{1024RD::Uniform u;1025u.binding = 4;1026u.uniform_type = RD::UNIFORM_TYPE_TEXTURE;1027for (uint32_t j = 0; j < SDFGI::MAX_CASCADES; j++) {1028if (j < cascades.size()) {1029u.append_id(cascades[j].light_aniso_1_tex);1030} else {1031u.append_id(texture_storage->texture_rd_get_default(RendererRD::TextureStorage::DEFAULT_RD_TEXTURE_3D_WHITE));1032}1033}1034uniforms.push_back(u);1035}1036{1037RD::Uniform u;1038u.uniform_type = RD::UNIFORM_TYPE_SAMPLER;1039u.binding = 6;1040u.append_id(material_storage->sampler_rd_get_default(RS::CANVAS_ITEM_TEXTURE_FILTER_LINEAR, RS::CANVAS_ITEM_TEXTURE_REPEAT_DISABLED));1041uniforms.push_back(u);1042}10431044{1045RD::Uniform u;1046u.uniform_type = RD::UNIFORM_TYPE_UNIFORM_BUFFER;1047u.binding = 7;1048u.append_id(cascades_ubo);1049uniforms.push_back(u);1050}1051{1052RD::Uniform u;1053u.uniform_type = RD::UNIFORM_TYPE_IMAGE;1054u.binding = 8;1055u.append_id(lightprobe_data);1056uniforms.push_back(u);1057}10581059{1060RD::Uniform u;1061u.uniform_type = RD::UNIFORM_TYPE_IMAGE;1062u.binding = 9;1063u.append_id(cascades[i].lightprobe_history_tex);1064uniforms.push_back(u);1065}1066{1067RD::Uniform u;1068u.uniform_type = RD::UNIFORM_TYPE_IMAGE;1069u.binding = 10;1070u.append_id(cascades[i].lightprobe_average_tex);1071uniforms.push_back(u);1072}10731074{1075RD::Uniform u;1076u.uniform_type = RD::UNIFORM_TYPE_IMAGE;1077u.binding = 11;1078u.append_id(lightprobe_history_scroll);1079uniforms.push_back(u);1080}1081{1082RD::Uniform u;1083u.uniform_type = RD::UNIFORM_TYPE_IMAGE;1084u.binding = 12;1085u.append_id(lightprobe_average_scroll);1086uniforms.push_back(u);1087}1088{1089RD::Uniform u;1090u.uniform_type = RD::UNIFORM_TYPE_IMAGE;1091u.binding = 13;1092RID parent_average;1093if (cascades.size() == 1) {1094// If there is only one SDFGI cascade, we can't use the previous cascade for blending.1095parent_average = cascades[i].lightprobe_average_tex;1096} else if (i < cascades.size() - 1) {1097parent_average = cascades[i + 1].lightprobe_average_tex;1098} else {1099parent_average = cascades[i - 1].lightprobe_average_tex; //to use something, but it won't be used1100}1101u.append_id(parent_average);1102uniforms.push_back(u);1103}1104{1105RD::Uniform u;1106u.uniform_type = RD::UNIFORM_TYPE_IMAGE;1107u.binding = 14;1108u.append_id(ambient_texture);1109uniforms.push_back(u);1110}11111112cascades[i].integrate_uniform_set = RD::get_singleton()->uniform_set_create(uniforms, gi->sdfgi_shader.integrate.version_get_shader(gi->sdfgi_shader.integrate_shader, 0), 0);1113}11141115bounce_feedback = RendererSceneRenderRD::get_singleton()->environment_get_sdfgi_bounce_feedback(p_env);1116energy = RendererSceneRenderRD::get_singleton()->environment_get_sdfgi_energy(p_env);1117normal_bias = RendererSceneRenderRD::get_singleton()->environment_get_sdfgi_normal_bias(p_env);1118probe_bias = RendererSceneRenderRD::get_singleton()->environment_get_sdfgi_probe_bias(p_env);1119reads_sky = RendererSceneRenderRD::get_singleton()->environment_get_sdfgi_read_sky_light(p_env);1120}11211122void GI::SDFGI::free_data() {1123// we don't free things here, we handle SDFGI differently at the moment destructing the object when it needs to change.1124}11251126GI::SDFGI::~SDFGI() {1127for (const SDFGI::Cascade &c : cascades) {1128RD::get_singleton()->free(c.light_data);1129RD::get_singleton()->free(c.light_aniso_0_tex);1130RD::get_singleton()->free(c.light_aniso_1_tex);1131RD::get_singleton()->free(c.sdf_tex);1132RD::get_singleton()->free(c.solid_cell_dispatch_buffer_storage);1133RD::get_singleton()->free(c.solid_cell_dispatch_buffer_call);1134RD::get_singleton()->free(c.solid_cell_buffer);1135RD::get_singleton()->free(c.lightprobe_history_tex);1136RD::get_singleton()->free(c.lightprobe_average_tex);1137RD::get_singleton()->free(c.lights_buffer);1138}11391140RD::get_singleton()->free(render_albedo);1141RD::get_singleton()->free(render_emission);1142RD::get_singleton()->free(render_emission_aniso);11431144RD::get_singleton()->free(render_sdf[0]);1145RD::get_singleton()->free(render_sdf[1]);11461147RD::get_singleton()->free(render_sdf_half[0]);1148RD::get_singleton()->free(render_sdf_half[1]);11491150for (int i = 0; i < 8; i++) {1151RD::get_singleton()->free(render_occlusion[i]);1152}11531154RD::get_singleton()->free(render_geom_facing);11551156RD::get_singleton()->free(lightprobe_data);1157RD::get_singleton()->free(lightprobe_history_scroll);1158RD::get_singleton()->free(lightprobe_average_scroll);1159RD::get_singleton()->free(occlusion_data);1160RD::get_singleton()->free(ambient_texture);11611162RD::get_singleton()->free(cascades_ubo);11631164for (uint32_t v = 0; v < RendererSceneRender::MAX_RENDER_VIEWS; v++) {1165if (RD::get_singleton()->uniform_set_is_valid(debug_uniform_set[v])) {1166RD::get_singleton()->free(debug_uniform_set[v]);1167}1168debug_uniform_set[v] = RID();1169}11701171if (RD::get_singleton()->uniform_set_is_valid(debug_probes_uniform_set)) {1172RD::get_singleton()->free(debug_probes_uniform_set);1173}1174debug_probes_uniform_set = RID();11751176if (debug_probes_scene_data_ubo.is_valid()) {1177RD::get_singleton()->free(debug_probes_scene_data_ubo);1178debug_probes_scene_data_ubo = RID();1179}1180}11811182void GI::SDFGI::update(RID p_env, const Vector3 &p_world_position) {1183bounce_feedback = RendererSceneRenderRD::get_singleton()->environment_get_sdfgi_bounce_feedback(p_env);1184energy = RendererSceneRenderRD::get_singleton()->environment_get_sdfgi_energy(p_env);1185normal_bias = RendererSceneRenderRD::get_singleton()->environment_get_sdfgi_normal_bias(p_env);1186probe_bias = RendererSceneRenderRD::get_singleton()->environment_get_sdfgi_probe_bias(p_env);1187reads_sky = RendererSceneRenderRD::get_singleton()->environment_get_sdfgi_read_sky_light(p_env);11881189int32_t drag_margin = (cascade_size / SDFGI::PROBE_DIVISOR) / 2;11901191for (SDFGI::Cascade &cascade : cascades) {1192cascade.dirty_regions = Vector3i();11931194Vector3 probe_half_size = Vector3(1, 1, 1) * cascade.cell_size * float(cascade_size / SDFGI::PROBE_DIVISOR) * 0.5;1195probe_half_size = Vector3(0, 0, 0);11961197Vector3 world_position = p_world_position;1198world_position.y *= y_mult;1199Vector3i pos_in_cascade = Vector3i((world_position + probe_half_size) / cascade.cell_size);12001201for (int j = 0; j < 3; j++) {1202if (pos_in_cascade[j] < cascade.position[j]) {1203while (pos_in_cascade[j] < (cascade.position[j] - drag_margin)) {1204cascade.position[j] -= drag_margin * 2;1205cascade.dirty_regions[j] += drag_margin * 2;1206}1207} else if (pos_in_cascade[j] > cascade.position[j]) {1208while (pos_in_cascade[j] > (cascade.position[j] + drag_margin)) {1209cascade.position[j] += drag_margin * 2;1210cascade.dirty_regions[j] -= drag_margin * 2;1211}1212}12131214if (cascade.dirty_regions[j] == 0) {1215continue; // not dirty1216} else if (uint32_t(Math::abs(cascade.dirty_regions[j])) >= cascade_size) {1217//moved too much, just redraw everything (make all dirty)1218cascade.dirty_regions = SDFGI::Cascade::DIRTY_ALL;1219break;1220}1221}12221223if (cascade.dirty_regions != Vector3i() && cascade.dirty_regions != SDFGI::Cascade::DIRTY_ALL) {1224//see how much the total dirty volume represents from the total volume1225uint32_t total_volume = cascade_size * cascade_size * cascade_size;1226uint32_t safe_volume = 1;1227for (int j = 0; j < 3; j++) {1228safe_volume *= cascade_size - Math::abs(cascade.dirty_regions[j]);1229}1230uint32_t dirty_volume = total_volume - safe_volume;1231if (dirty_volume > (safe_volume / 2)) {1232//more than half the volume is dirty, make all dirty so its only rendered once1233cascade.dirty_regions = SDFGI::Cascade::DIRTY_ALL;1234}1235}1236}1237}12381239void GI::SDFGI::update_light() {1240RD::get_singleton()->draw_command_begin_label("SDFGI Update dynamic Light");12411242for (uint32_t i = 0; i < cascades.size(); i++) {1243RD::get_singleton()->buffer_copy(cascades[i].solid_cell_dispatch_buffer_storage, cascades[i].solid_cell_dispatch_buffer_call, 0, 0, sizeof(uint32_t) * 4);1244}12451246/* Update dynamic light */12471248RD::ComputeListID compute_list = RD::get_singleton()->compute_list_begin();1249RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, gi->sdfgi_shader.direct_light_pipeline[SDFGIShader::DIRECT_LIGHT_MODE_DYNAMIC]);12501251SDFGIShader::DirectLightPushConstant push_constant;12521253push_constant.grid_size[0] = cascade_size;1254push_constant.grid_size[1] = cascade_size;1255push_constant.grid_size[2] = cascade_size;1256push_constant.max_cascades = cascades.size();1257push_constant.probe_axis_size = probe_axis_count;1258push_constant.bounce_feedback = bounce_feedback;1259push_constant.y_mult = y_mult;1260push_constant.use_occlusion = uses_occlusion;12611262for (uint32_t i = 0; i < cascades.size(); i++) {1263SDFGI::Cascade &cascade = cascades[i];1264push_constant.light_count = cascade_dynamic_light_count[i];1265push_constant.cascade = i;12661267if (cascades[i].all_dynamic_lights_dirty || gi->sdfgi_frames_to_update_light == RS::ENV_SDFGI_UPDATE_LIGHT_IN_1_FRAME) {1268push_constant.process_offset = 0;1269push_constant.process_increment = 1;1270} else {1271static const uint32_t frames_to_update_table[RS::ENV_SDFGI_UPDATE_LIGHT_MAX] = {12721, 2, 4, 8, 161273};12741275uint32_t frames_to_update = frames_to_update_table[gi->sdfgi_frames_to_update_light];12761277push_constant.process_offset = RSG::rasterizer->get_frame_number() % frames_to_update;1278push_constant.process_increment = frames_to_update;1279}1280cascades[i].all_dynamic_lights_dirty = false;12811282RD::get_singleton()->compute_list_bind_uniform_set(compute_list, cascade.sdf_direct_light_dynamic_uniform_set, 0);1283RD::get_singleton()->compute_list_set_push_constant(compute_list, &push_constant, sizeof(SDFGIShader::DirectLightPushConstant));1284RD::get_singleton()->compute_list_dispatch_indirect(compute_list, cascade.solid_cell_dispatch_buffer_call, 0);1285}1286RD::get_singleton()->compute_list_end();1287RD::get_singleton()->draw_command_end_label();1288}12891290void GI::SDFGI::update_probes(RID p_env, SkyRD::Sky *p_sky) {1291RD::get_singleton()->draw_command_begin_label("SDFGI Update Probes");12921293SDFGIShader::IntegratePushConstant push_constant;1294push_constant.grid_size[1] = cascade_size;1295push_constant.grid_size[2] = cascade_size;1296push_constant.grid_size[0] = cascade_size;1297push_constant.max_cascades = cascades.size();1298push_constant.probe_axis_size = probe_axis_count;1299push_constant.history_index = render_pass % history_size;1300push_constant.history_size = history_size;1301static const uint32_t ray_count[RS::ENV_SDFGI_RAY_COUNT_MAX] = { 4, 8, 16, 32, 64, 96, 128 };1302push_constant.ray_count = ray_count[gi->sdfgi_ray_count];1303push_constant.ray_bias = probe_bias;1304push_constant.image_size[0] = probe_axis_count * probe_axis_count;1305push_constant.image_size[1] = probe_axis_count;1306push_constant.store_ambient_texture = RendererSceneRenderRD::get_singleton()->environment_get_volumetric_fog_enabled(p_env);13071308RID sky_uniform_set = gi->sdfgi_shader.integrate_default_sky_uniform_set;1309push_constant.sky_flags = 0;1310push_constant.y_mult = y_mult;13111312if (reads_sky && p_env.is_valid()) {1313push_constant.sky_energy = RendererSceneRenderRD::get_singleton()->environment_get_bg_energy_multiplier(p_env);13141315if (RendererSceneRenderRD::get_singleton()->environment_get_background(p_env) == RS::ENV_BG_CLEAR_COLOR) {1316push_constant.sky_flags |= SDFGIShader::IntegratePushConstant::SKY_FLAGS_MODE_COLOR;1317Color c = RSG::texture_storage->get_default_clear_color().srgb_to_linear();1318push_constant.sky_color_or_orientation[0] = c.r;1319push_constant.sky_color_or_orientation[1] = c.g;1320push_constant.sky_color_or_orientation[2] = c.b;1321} else if (RendererSceneRenderRD::get_singleton()->environment_get_background(p_env) == RS::ENV_BG_COLOR) {1322push_constant.sky_flags |= SDFGIShader::IntegratePushConstant::SKY_FLAGS_MODE_COLOR;1323Color c = RendererSceneRenderRD::get_singleton()->environment_get_bg_color(p_env);1324push_constant.sky_color_or_orientation[0] = c.r;1325push_constant.sky_color_or_orientation[1] = c.g;1326push_constant.sky_color_or_orientation[2] = c.b;13271328} else if (RendererSceneRenderRD::get_singleton()->environment_get_background(p_env) == RS::ENV_BG_SKY) {1329if (p_sky && p_sky->radiance.is_valid()) {1330if (integrate_sky_uniform_set.is_null() || !RD::get_singleton()->uniform_set_is_valid(integrate_sky_uniform_set)) {1331Vector<RD::Uniform> uniforms;13321333{1334RD::Uniform u;1335u.uniform_type = RD::UNIFORM_TYPE_TEXTURE;1336u.binding = 0;1337u.append_id(p_sky->radiance);1338uniforms.push_back(u);1339}13401341{1342RD::Uniform u;1343u.uniform_type = RD::UNIFORM_TYPE_SAMPLER;1344u.binding = 1;1345u.append_id(RendererRD::MaterialStorage::get_singleton()->sampler_rd_get_default(RS::CANVAS_ITEM_TEXTURE_FILTER_LINEAR_WITH_MIPMAPS, RS::CANVAS_ITEM_TEXTURE_REPEAT_DISABLED));1346uniforms.push_back(u);1347}13481349integrate_sky_uniform_set = RD::get_singleton()->uniform_set_create(uniforms, gi->sdfgi_shader.integrate.version_get_shader(gi->sdfgi_shader.integrate_shader, 0), 1);1350}1351sky_uniform_set = integrate_sky_uniform_set;1352push_constant.sky_flags |= SDFGIShader::IntegratePushConstant::SKY_FLAGS_MODE_SKY;13531354// Encode sky orientation as quaternion in existing push constants.1355const Basis sky_basis = RendererSceneRenderRD::get_singleton()->environment_get_sky_orientation(p_env);1356const Quaternion sky_quaternion = sky_basis.get_quaternion().inverse();1357push_constant.sky_color_or_orientation[0] = sky_quaternion.x;1358push_constant.sky_color_or_orientation[1] = sky_quaternion.y;1359push_constant.sky_color_or_orientation[2] = sky_quaternion.z;1360// Ideally we would reconstruct the largest component for least error, but sky contribution to GI is low frequency so just needs to get the idea across.1361push_constant.sky_flags |= SDFGIShader::IntegratePushConstant::SKY_FLAGS_ORIENTATION_SIGN * (sky_quaternion.w < 0.0 ? 0 : 1);1362}1363}1364}13651366render_pass++;13671368RD::ComputeListID compute_list = RD::get_singleton()->compute_list_begin();1369RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, gi->sdfgi_shader.integrate_pipeline[SDFGIShader::INTEGRATE_MODE_PROCESS]);13701371int32_t probe_divisor = cascade_size / SDFGI::PROBE_DIVISOR;1372for (uint32_t i = 0; i < cascades.size(); i++) {1373push_constant.cascade = i;1374push_constant.world_offset[0] = cascades[i].position.x / probe_divisor;1375push_constant.world_offset[1] = cascades[i].position.y / probe_divisor;1376push_constant.world_offset[2] = cascades[i].position.z / probe_divisor;13771378RD::get_singleton()->compute_list_bind_uniform_set(compute_list, cascades[i].integrate_uniform_set, 0);1379RD::get_singleton()->compute_list_bind_uniform_set(compute_list, sky_uniform_set, 1);13801381RD::get_singleton()->compute_list_set_push_constant(compute_list, &push_constant, sizeof(SDFGIShader::IntegratePushConstant));1382RD::get_singleton()->compute_list_dispatch_threads(compute_list, probe_axis_count * probe_axis_count, probe_axis_count, 1);1383}13841385RD::get_singleton()->compute_list_end();1386RD::get_singleton()->draw_command_end_label();1387}13881389void GI::SDFGI::store_probes() {1390RD::get_singleton()->draw_command_begin_label("SDFGI Store Probes");13911392SDFGIShader::IntegratePushConstant push_constant;1393push_constant.grid_size[1] = cascade_size;1394push_constant.grid_size[2] = cascade_size;1395push_constant.grid_size[0] = cascade_size;1396push_constant.max_cascades = cascades.size();1397push_constant.probe_axis_size = probe_axis_count;1398push_constant.history_index = render_pass % history_size;1399push_constant.history_size = history_size;1400static const uint32_t ray_count[RS::ENV_SDFGI_RAY_COUNT_MAX] = { 4, 8, 16, 32, 64, 96, 128 };1401push_constant.ray_count = ray_count[gi->sdfgi_ray_count];1402push_constant.ray_bias = probe_bias;1403push_constant.image_size[0] = probe_axis_count * probe_axis_count;1404push_constant.image_size[1] = probe_axis_count;1405push_constant.store_ambient_texture = false;14061407push_constant.sky_flags = 0;1408push_constant.y_mult = y_mult;14091410// Then store values into the lightprobe texture. Separating these steps has a small performance hit, but it allows for multiple bounces1411RENDER_TIMESTAMP("Average SDFGI Probes");14121413RD::ComputeListID compute_list = RD::get_singleton()->compute_list_begin();1414RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, gi->sdfgi_shader.integrate_pipeline[SDFGIShader::INTEGRATE_MODE_STORE]);14151416//convert to octahedral to store1417push_constant.image_size[0] *= SDFGI::LIGHTPROBE_OCT_SIZE;1418push_constant.image_size[1] *= SDFGI::LIGHTPROBE_OCT_SIZE;14191420for (uint32_t i = 0; i < cascades.size(); i++) {1421push_constant.cascade = i;1422RD::get_singleton()->compute_list_bind_uniform_set(compute_list, cascades[i].integrate_uniform_set, 0);1423RD::get_singleton()->compute_list_bind_uniform_set(compute_list, gi->sdfgi_shader.integrate_default_sky_uniform_set, 1);1424RD::get_singleton()->compute_list_set_push_constant(compute_list, &push_constant, sizeof(SDFGIShader::IntegratePushConstant));1425RD::get_singleton()->compute_list_dispatch_threads(compute_list, probe_axis_count * probe_axis_count * SDFGI::LIGHTPROBE_OCT_SIZE, probe_axis_count * SDFGI::LIGHTPROBE_OCT_SIZE, 1);1426}14271428RD::get_singleton()->compute_list_end();14291430RD::get_singleton()->draw_command_end_label();1431}14321433int GI::SDFGI::get_pending_region_data(int p_region, Vector3i &r_local_offset, Vector3i &r_local_size, AABB &r_bounds) const {1434int dirty_count = 0;1435for (uint32_t i = 0; i < cascades.size(); i++) {1436const SDFGI::Cascade &c = cascades[i];14371438if (c.dirty_regions == SDFGI::Cascade::DIRTY_ALL) {1439if (dirty_count == p_region) {1440r_local_offset = Vector3i();1441r_local_size = Vector3i(1, 1, 1) * cascade_size;14421443r_bounds.position = Vector3((Vector3i(1, 1, 1) * -int32_t(cascade_size >> 1) + c.position)) * c.cell_size * Vector3(1, 1.0 / y_mult, 1);1444r_bounds.size = Vector3(r_local_size) * c.cell_size * Vector3(1, 1.0 / y_mult, 1);1445return i;1446}1447dirty_count++;1448} else {1449for (int j = 0; j < 3; j++) {1450if (c.dirty_regions[j] != 0) {1451if (dirty_count == p_region) {1452Vector3i from = Vector3i(0, 0, 0);1453Vector3i to = Vector3i(1, 1, 1) * cascade_size;14541455if (c.dirty_regions[j] > 0) {1456//fill from the beginning1457to[j] = c.dirty_regions[j];1458} else {1459//fill from the end1460from[j] = to[j] + c.dirty_regions[j];1461}14621463for (int k = 0; k < j; k++) {1464// "chip" away previous regions to avoid re-voxelizing the same thing1465if (c.dirty_regions[k] > 0) {1466from[k] += c.dirty_regions[k];1467} else if (c.dirty_regions[k] < 0) {1468to[k] += c.dirty_regions[k];1469}1470}14711472r_local_offset = from;1473r_local_size = to - from;14741475r_bounds.position = Vector3(from + Vector3i(1, 1, 1) * -int32_t(cascade_size >> 1) + c.position) * c.cell_size * Vector3(1, 1.0 / y_mult, 1);1476r_bounds.size = Vector3(r_local_size) * c.cell_size * Vector3(1, 1.0 / y_mult, 1);14771478return i;1479}14801481dirty_count++;1482}1483}1484}1485}1486return -1;1487}14881489void GI::SDFGI::update_cascades() {1490//update cascades1491SDFGI::Cascade::UBO cascade_data[SDFGI::MAX_CASCADES];1492int32_t probe_divisor = cascade_size / SDFGI::PROBE_DIVISOR;14931494for (uint32_t i = 0; i < cascades.size(); i++) {1495Vector3 pos = Vector3((Vector3i(1, 1, 1) * -int32_t(cascade_size >> 1) + cascades[i].position)) * cascades[i].cell_size;14961497cascade_data[i].offset[0] = pos.x;1498cascade_data[i].offset[1] = pos.y;1499cascade_data[i].offset[2] = pos.z;1500cascade_data[i].to_cell = 1.0 / cascades[i].cell_size;1501cascade_data[i].probe_offset[0] = cascades[i].position.x / probe_divisor;1502cascade_data[i].probe_offset[1] = cascades[i].position.y / probe_divisor;1503cascade_data[i].probe_offset[2] = cascades[i].position.z / probe_divisor;1504cascade_data[i].pad = 0;1505}15061507RD::get_singleton()->buffer_update(cascades_ubo, 0, sizeof(SDFGI::Cascade::UBO) * SDFGI::MAX_CASCADES, cascade_data);1508}15091510void GI::SDFGI::debug_draw(uint32_t p_view_count, const Projection *p_projections, const Transform3D &p_transform, int p_width, int p_height, RID p_render_target, RID p_texture, const Vector<RID> &p_texture_views) {1511RendererRD::TextureStorage *texture_storage = RendererRD::TextureStorage::get_singleton();1512RendererRD::MaterialStorage *material_storage = RendererRD::MaterialStorage::get_singleton();1513RendererRD::CopyEffects *copy_effects = RendererRD::CopyEffects::get_singleton();15141515for (uint32_t v = 0; v < p_view_count; v++) {1516if (!debug_uniform_set[v].is_valid() || !RD::get_singleton()->uniform_set_is_valid(debug_uniform_set[v])) {1517Vector<RD::Uniform> uniforms;1518{1519RD::Uniform u;1520u.binding = 1;1521u.uniform_type = RD::UNIFORM_TYPE_TEXTURE;1522for (uint32_t i = 0; i < SDFGI::MAX_CASCADES; i++) {1523if (i < cascades.size()) {1524u.append_id(cascades[i].sdf_tex);1525} else {1526u.append_id(texture_storage->texture_rd_get_default(RendererRD::TextureStorage::DEFAULT_RD_TEXTURE_3D_WHITE));1527}1528}1529uniforms.push_back(u);1530}1531{1532RD::Uniform u;1533u.binding = 2;1534u.uniform_type = RD::UNIFORM_TYPE_TEXTURE;1535for (uint32_t i = 0; i < SDFGI::MAX_CASCADES; i++) {1536if (i < cascades.size()) {1537u.append_id(cascades[i].light_tex);1538} else {1539u.append_id(texture_storage->texture_rd_get_default(RendererRD::TextureStorage::DEFAULT_RD_TEXTURE_3D_WHITE));1540}1541}1542uniforms.push_back(u);1543}1544{1545RD::Uniform u;1546u.binding = 3;1547u.uniform_type = RD::UNIFORM_TYPE_TEXTURE;1548for (uint32_t i = 0; i < SDFGI::MAX_CASCADES; i++) {1549if (i < cascades.size()) {1550u.append_id(cascades[i].light_aniso_0_tex);1551} else {1552u.append_id(texture_storage->texture_rd_get_default(RendererRD::TextureStorage::DEFAULT_RD_TEXTURE_3D_WHITE));1553}1554}1555uniforms.push_back(u);1556}1557{1558RD::Uniform u;1559u.binding = 4;1560u.uniform_type = RD::UNIFORM_TYPE_TEXTURE;1561for (uint32_t i = 0; i < SDFGI::MAX_CASCADES; i++) {1562if (i < cascades.size()) {1563u.append_id(cascades[i].light_aniso_1_tex);1564} else {1565u.append_id(texture_storage->texture_rd_get_default(RendererRD::TextureStorage::DEFAULT_RD_TEXTURE_3D_WHITE));1566}1567}1568uniforms.push_back(u);1569}1570{1571RD::Uniform u;1572u.binding = 5;1573u.uniform_type = RD::UNIFORM_TYPE_TEXTURE;1574u.append_id(occlusion_texture);1575uniforms.push_back(u);1576}1577{1578RD::Uniform u;1579u.binding = 8;1580u.uniform_type = RD::UNIFORM_TYPE_SAMPLER;1581u.append_id(material_storage->sampler_rd_get_default(RS::CANVAS_ITEM_TEXTURE_FILTER_LINEAR, RS::CANVAS_ITEM_TEXTURE_REPEAT_DISABLED));1582uniforms.push_back(u);1583}1584{1585RD::Uniform u;1586u.binding = 9;1587u.uniform_type = RD::UNIFORM_TYPE_UNIFORM_BUFFER;1588u.append_id(cascades_ubo);1589uniforms.push_back(u);1590}1591{1592RD::Uniform u;1593u.binding = 10;1594u.uniform_type = RD::UNIFORM_TYPE_IMAGE;1595u.append_id(p_texture_views[v]);1596uniforms.push_back(u);1597}1598{1599RD::Uniform u;1600u.binding = 11;1601u.uniform_type = RD::UNIFORM_TYPE_TEXTURE;1602u.append_id(lightprobe_texture);1603uniforms.push_back(u);1604}1605debug_uniform_set[v] = RD::get_singleton()->uniform_set_create(uniforms, gi->sdfgi_shader.debug_shader_version, 0);1606}16071608RD::ComputeListID compute_list = RD::get_singleton()->compute_list_begin();1609RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, gi->sdfgi_shader.debug_pipeline);1610RD::get_singleton()->compute_list_bind_uniform_set(compute_list, debug_uniform_set[v], 0);16111612SDFGIShader::DebugPushConstant push_constant;1613push_constant.grid_size[0] = cascade_size;1614push_constant.grid_size[1] = cascade_size;1615push_constant.grid_size[2] = cascade_size;1616push_constant.max_cascades = cascades.size();1617push_constant.screen_size[0] = p_width;1618push_constant.screen_size[1] = p_height;1619push_constant.y_mult = y_mult;16201621push_constant.z_near = -p_projections[v].get_z_near();16221623for (int i = 0; i < 3; i++) {1624for (int j = 0; j < 3; j++) {1625push_constant.cam_basis[i][j] = p_transform.basis.rows[j][i];1626}1627}1628push_constant.cam_origin[0] = p_transform.origin[0];1629push_constant.cam_origin[1] = p_transform.origin[1];1630push_constant.cam_origin[2] = p_transform.origin[2];16311632// need to properly unproject for asymmetric projection matrices in stereo..1633Projection inv_projection = p_projections[v].inverse();1634for (int i = 0; i < 4; i++) {1635for (int j = 0; j < 3; j++) {1636push_constant.inv_projection[j][i] = inv_projection.columns[i][j];1637}1638}16391640RD::get_singleton()->compute_list_set_push_constant(compute_list, &push_constant, sizeof(SDFGIShader::DebugPushConstant));16411642RD::get_singleton()->compute_list_dispatch_threads(compute_list, p_width, p_height, 1);1643RD::get_singleton()->compute_list_end();1644}16451646Size2i rtsize = texture_storage->render_target_get_size(p_render_target);1647copy_effects->copy_to_fb_rect(p_texture, texture_storage->render_target_get_rd_framebuffer(p_render_target), Rect2i(Point2i(), rtsize), true, false, false, false, RID(), p_view_count > 1);1648}16491650void GI::SDFGI::debug_probes(RID p_framebuffer, const uint32_t p_view_count, const Projection *p_camera_with_transforms) {1651RendererRD::MaterialStorage *material_storage = RendererRD::MaterialStorage::get_singleton();16521653// setup scene data1654{1655SDFGIShader::DebugProbesSceneData scene_data;16561657if (debug_probes_scene_data_ubo.is_null()) {1658debug_probes_scene_data_ubo = RD::get_singleton()->uniform_buffer_create(sizeof(SDFGIShader::DebugProbesSceneData));1659}16601661for (uint32_t v = 0; v < p_view_count; v++) {1662RendererRD::MaterialStorage::store_camera(p_camera_with_transforms[v], scene_data.projection[v]);1663}16641665RD::get_singleton()->buffer_update(debug_probes_scene_data_ubo, 0, sizeof(SDFGIShader::DebugProbesSceneData), &scene_data);1666}16671668// setup push constant1669SDFGIShader::DebugProbesPushConstant push_constant;16701671//gen spheres from strips1672uint32_t band_points = 16;1673push_constant.band_power = 4;1674push_constant.sections_in_band = ((band_points / 2) - 1);1675push_constant.band_mask = band_points - 2;1676push_constant.section_arc = Math::TAU / float(push_constant.sections_in_band);1677push_constant.y_mult = y_mult;16781679uint32_t total_points = push_constant.sections_in_band * band_points;1680uint32_t total_probes = probe_axis_count * probe_axis_count * probe_axis_count;16811682push_constant.grid_size[0] = cascade_size;1683push_constant.grid_size[1] = cascade_size;1684push_constant.grid_size[2] = cascade_size;1685push_constant.cascade = 0;16861687push_constant.probe_axis_size = probe_axis_count;16881689if (!debug_probes_uniform_set.is_valid() || !RD::get_singleton()->uniform_set_is_valid(debug_probes_uniform_set)) {1690Vector<RD::Uniform> uniforms;1691{1692RD::Uniform u;1693u.binding = 1;1694u.uniform_type = RD::UNIFORM_TYPE_UNIFORM_BUFFER;1695u.append_id(cascades_ubo);1696uniforms.push_back(u);1697}1698{1699RD::Uniform u;1700u.binding = 2;1701u.uniform_type = RD::UNIFORM_TYPE_TEXTURE;1702u.append_id(lightprobe_texture);1703uniforms.push_back(u);1704}1705{1706RD::Uniform u;1707u.binding = 3;1708u.uniform_type = RD::UNIFORM_TYPE_SAMPLER;1709u.append_id(material_storage->sampler_rd_get_default(RS::CANVAS_ITEM_TEXTURE_FILTER_LINEAR, RS::CANVAS_ITEM_TEXTURE_REPEAT_DISABLED));1710uniforms.push_back(u);1711}1712{1713RD::Uniform u;1714u.binding = 4;1715u.uniform_type = RD::UNIFORM_TYPE_TEXTURE;1716u.append_id(occlusion_texture);1717uniforms.push_back(u);1718}1719{1720RD::Uniform u;1721u.binding = 5;1722u.uniform_type = RD::UNIFORM_TYPE_UNIFORM_BUFFER;1723u.append_id(debug_probes_scene_data_ubo);1724uniforms.push_back(u);1725}17261727debug_probes_uniform_set = RD::get_singleton()->uniform_set_create(uniforms, gi->sdfgi_shader.debug_probes.version_get_shader(gi->sdfgi_shader.debug_probes_shader, 0), 0);1728}17291730SDFGIShader::ProbeDebugMode mode = p_view_count > 1 ? SDFGIShader::PROBE_DEBUG_PROBES_MULTIVIEW : SDFGIShader::PROBE_DEBUG_PROBES;17311732RD::DrawListID draw_list = RD::get_singleton()->draw_list_begin(p_framebuffer);1733RD::get_singleton()->draw_command_begin_label("Debug SDFGI");17341735RD::get_singleton()->draw_list_bind_render_pipeline(draw_list, gi->sdfgi_shader.debug_probes_pipeline[mode].get_render_pipeline(RD::INVALID_FORMAT_ID, RD::get_singleton()->framebuffer_get_format(p_framebuffer)));1736RD::get_singleton()->draw_list_bind_uniform_set(draw_list, debug_probes_uniform_set, 0);1737RD::get_singleton()->draw_list_set_push_constant(draw_list, &push_constant, sizeof(SDFGIShader::DebugProbesPushConstant));1738RD::get_singleton()->draw_list_draw(draw_list, false, total_probes, total_points);17391740if (gi->sdfgi_debug_probe_dir != Vector3()) {1741uint32_t cascade = 0;1742Vector3 offset = Vector3((Vector3i(1, 1, 1) * -int32_t(cascade_size >> 1) + cascades[cascade].position)) * cascades[cascade].cell_size * Vector3(1.0, 1.0 / y_mult, 1.0);1743Vector3 probe_size = cascades[cascade].cell_size * (cascade_size / SDFGI::PROBE_DIVISOR) * Vector3(1.0, 1.0 / y_mult, 1.0);1744Vector3 ray_from = gi->sdfgi_debug_probe_pos;1745Vector3 ray_to = gi->sdfgi_debug_probe_pos + gi->sdfgi_debug_probe_dir * cascades[cascade].cell_size * Math::sqrt(3.0) * cascade_size;1746float sphere_radius = 0.2;1747float closest_dist = 1e20;1748gi->sdfgi_debug_probe_enabled = false;17491750Vector3i probe_from = cascades[cascade].position / (cascade_size / SDFGI::PROBE_DIVISOR);1751for (int i = 0; i < (SDFGI::PROBE_DIVISOR + 1); i++) {1752for (int j = 0; j < (SDFGI::PROBE_DIVISOR + 1); j++) {1753for (int k = 0; k < (SDFGI::PROBE_DIVISOR + 1); k++) {1754Vector3 pos = offset + probe_size * Vector3(i, j, k);1755Vector3 res;1756if (Geometry3D::segment_intersects_sphere(ray_from, ray_to, pos, sphere_radius, &res)) {1757float d = ray_from.distance_to(res);1758if (d < closest_dist) {1759closest_dist = d;1760gi->sdfgi_debug_probe_enabled = true;1761gi->sdfgi_debug_probe_index = probe_from + Vector3i(i, j, k);1762}1763}1764}1765}1766}17671768gi->sdfgi_debug_probe_dir = Vector3();1769}17701771if (gi->sdfgi_debug_probe_enabled) {1772uint32_t cascade = 0;1773uint32_t probe_cells = (cascade_size / SDFGI::PROBE_DIVISOR);1774Vector3i probe_from = cascades[cascade].position / probe_cells;1775Vector3i ofs = gi->sdfgi_debug_probe_index - probe_from;1776if (ofs.x < 0 || ofs.y < 0 || ofs.z < 0) {1777return;1778}1779if (ofs.x > SDFGI::PROBE_DIVISOR || ofs.y > SDFGI::PROBE_DIVISOR || ofs.z > SDFGI::PROBE_DIVISOR) {1780return;1781}17821783uint32_t mult = (SDFGI::PROBE_DIVISOR + 1);1784uint32_t index = ofs.z * mult * mult + ofs.y * mult + ofs.x;17851786push_constant.probe_debug_index = index;17871788uint32_t cell_count = probe_cells * 2 * probe_cells * 2 * probe_cells * 2;17891790RD::get_singleton()->draw_list_bind_render_pipeline(draw_list, gi->sdfgi_shader.debug_probes_pipeline[p_view_count > 1 ? SDFGIShader::PROBE_DEBUG_VISIBILITY_MULTIVIEW : SDFGIShader::PROBE_DEBUG_VISIBILITY].get_render_pipeline(RD::INVALID_FORMAT_ID, RD::get_singleton()->framebuffer_get_format(p_framebuffer)));1791RD::get_singleton()->draw_list_bind_uniform_set(draw_list, debug_probes_uniform_set, 0);1792RD::get_singleton()->draw_list_set_push_constant(draw_list, &push_constant, sizeof(SDFGIShader::DebugProbesPushConstant));1793RD::get_singleton()->draw_list_draw(draw_list, false, cell_count, total_points);1794}17951796RD::get_singleton()->draw_command_end_label();1797RD::get_singleton()->draw_list_end();1798}17991800void GI::SDFGI::pre_process_gi(const Transform3D &p_transform, RenderDataRD *p_render_data) {1801if (p_render_data->sdfgi_update_data == nullptr) {1802return;1803}18041805RendererRD::LightStorage *light_storage = RendererRD::LightStorage::get_singleton();1806/* Update general SDFGI Buffer */18071808SDFGIData sdfgi_data;18091810sdfgi_data.grid_size[0] = cascade_size;1811sdfgi_data.grid_size[1] = cascade_size;1812sdfgi_data.grid_size[2] = cascade_size;18131814sdfgi_data.max_cascades = cascades.size();1815sdfgi_data.probe_axis_size = probe_axis_count;1816sdfgi_data.cascade_probe_size[0] = sdfgi_data.probe_axis_size - 1; //float version for performance1817sdfgi_data.cascade_probe_size[1] = sdfgi_data.probe_axis_size - 1;1818sdfgi_data.cascade_probe_size[2] = sdfgi_data.probe_axis_size - 1;18191820float csize = cascade_size;1821sdfgi_data.probe_to_uvw = 1.0 / float(sdfgi_data.cascade_probe_size[0]);1822sdfgi_data.use_occlusion = uses_occlusion;1823//sdfgi_data.energy = energy;18241825sdfgi_data.y_mult = y_mult;18261827float cascade_voxel_size = (csize / sdfgi_data.cascade_probe_size[0]);1828float occlusion_clamp = (cascade_voxel_size - 0.5) / cascade_voxel_size;1829sdfgi_data.occlusion_clamp[0] = occlusion_clamp;1830sdfgi_data.occlusion_clamp[1] = occlusion_clamp;1831sdfgi_data.occlusion_clamp[2] = occlusion_clamp;1832sdfgi_data.normal_bias = (normal_bias / csize) * sdfgi_data.cascade_probe_size[0];18331834//vec2 tex_pixel_size = 1.0 / vec2(ivec2( (OCT_SIZE+2) * params.probe_axis_size * params.probe_axis_size, (OCT_SIZE+2) * params.probe_axis_size ) );1835//vec3 probe_uv_offset = (ivec3(OCT_SIZE+2,OCT_SIZE+2,(OCT_SIZE+2) * params.probe_axis_size)) * tex_pixel_size.xyx;18361837uint32_t oct_size = SDFGI::LIGHTPROBE_OCT_SIZE;18381839sdfgi_data.lightprobe_tex_pixel_size[0] = 1.0 / ((oct_size + 2) * sdfgi_data.probe_axis_size * sdfgi_data.probe_axis_size);1840sdfgi_data.lightprobe_tex_pixel_size[1] = 1.0 / ((oct_size + 2) * sdfgi_data.probe_axis_size);1841sdfgi_data.lightprobe_tex_pixel_size[2] = 1.0;18421843sdfgi_data.energy = energy;18441845sdfgi_data.lightprobe_uv_offset[0] = float(oct_size + 2) * sdfgi_data.lightprobe_tex_pixel_size[0];1846sdfgi_data.lightprobe_uv_offset[1] = float(oct_size + 2) * sdfgi_data.lightprobe_tex_pixel_size[1];1847sdfgi_data.lightprobe_uv_offset[2] = float((oct_size + 2) * sdfgi_data.probe_axis_size) * sdfgi_data.lightprobe_tex_pixel_size[0];18481849sdfgi_data.occlusion_renormalize[0] = 0.5;1850sdfgi_data.occlusion_renormalize[1] = 1.0;1851sdfgi_data.occlusion_renormalize[2] = 1.0 / float(sdfgi_data.max_cascades);18521853int32_t probe_divisor = cascade_size / SDFGI::PROBE_DIVISOR;18541855for (uint32_t i = 0; i < sdfgi_data.max_cascades; i++) {1856SDFGIData::ProbeCascadeData &c = sdfgi_data.cascades[i];1857Vector3 pos = Vector3((Vector3i(1, 1, 1) * -int32_t(cascade_size >> 1) + cascades[i].position)) * cascades[i].cell_size;1858Vector3 cam_origin = p_transform.origin;1859cam_origin.y *= y_mult;1860pos -= cam_origin; //make pos local to camera, to reduce numerical error1861c.position[0] = pos.x;1862c.position[1] = pos.y;1863c.position[2] = pos.z;1864c.to_probe = 1.0 / (float(cascade_size) * cascades[i].cell_size / float(probe_axis_count - 1));18651866Vector3i probe_ofs = cascades[i].position / probe_divisor;1867c.probe_world_offset[0] = probe_ofs.x;1868c.probe_world_offset[1] = probe_ofs.y;1869c.probe_world_offset[2] = probe_ofs.z;18701871c.to_cell = 1.0 / cascades[i].cell_size;1872c.exposure_normalization = 1.0;1873if (p_render_data->camera_attributes.is_valid()) {1874float exposure_normalization = RSG::camera_attributes->camera_attributes_get_exposure_normalization_factor(p_render_data->camera_attributes);1875c.exposure_normalization = exposure_normalization / cascades[i].baked_exposure_normalization;1876}1877}18781879RD::get_singleton()->buffer_update(gi->sdfgi_ubo, 0, sizeof(SDFGIData), &sdfgi_data);18801881/* Update dynamic lights in SDFGI cascades */18821883for (uint32_t i = 0; i < cascades.size(); i++) {1884SDFGI::Cascade &cascade = cascades[i];18851886SDFGIShader::Light lights[SDFGI::MAX_DYNAMIC_LIGHTS];1887uint32_t idx = 0;1888for (uint32_t j = 0; j < (uint32_t)p_render_data->sdfgi_update_data->directional_lights->size(); j++) {1889if (idx == SDFGI::MAX_DYNAMIC_LIGHTS) {1890break;1891}18921893RID light_instance = p_render_data->sdfgi_update_data->directional_lights->get(j);1894ERR_CONTINUE(!light_storage->owns_light_instance(light_instance));18951896RID light = light_storage->light_instance_get_base_light(light_instance);1897Transform3D light_transform = light_storage->light_instance_get_base_transform(light_instance);18981899if (RSG::light_storage->light_directional_get_sky_mode(light) == RS::LIGHT_DIRECTIONAL_SKY_MODE_SKY_ONLY) {1900continue;1901}19021903Vector3 dir = -light_transform.basis.get_column(Vector3::AXIS_Z);1904dir.y *= y_mult;1905dir.normalize();1906lights[idx].direction[0] = dir.x;1907lights[idx].direction[1] = dir.y;1908lights[idx].direction[2] = dir.z;1909Color color = RSG::light_storage->light_get_color(light);1910color = color.srgb_to_linear();1911lights[idx].color[0] = color.r;1912lights[idx].color[1] = color.g;1913lights[idx].color[2] = color.b;1914lights[idx].type = RS::LIGHT_DIRECTIONAL;1915lights[idx].energy = RSG::light_storage->light_get_param(light, RS::LIGHT_PARAM_ENERGY) * RSG::light_storage->light_get_param(light, RS::LIGHT_PARAM_INDIRECT_ENERGY);1916if (RendererSceneRenderRD::get_singleton()->is_using_physical_light_units()) {1917lights[idx].energy *= RSG::light_storage->light_get_param(light, RS::LIGHT_PARAM_INTENSITY);1918}19191920if (p_render_data->camera_attributes.is_valid()) {1921lights[idx].energy *= RSG::camera_attributes->camera_attributes_get_exposure_normalization_factor(p_render_data->camera_attributes);1922}19231924lights[idx].has_shadow = RSG::light_storage->light_has_shadow(light);19251926idx++;1927}19281929AABB cascade_aabb;1930cascade_aabb.position = Vector3((Vector3i(1, 1, 1) * -int32_t(cascade_size >> 1) + cascade.position)) * cascade.cell_size;1931cascade_aabb.size = Vector3(1, 1, 1) * cascade_size * cascade.cell_size;19321933for (uint32_t j = 0; j < p_render_data->sdfgi_update_data->positional_light_count; j++) {1934if (idx == SDFGI::MAX_DYNAMIC_LIGHTS) {1935break;1936}19371938RID light_instance = p_render_data->sdfgi_update_data->positional_light_instances[j];1939ERR_CONTINUE(!light_storage->owns_light_instance(light_instance));19401941RID light = light_storage->light_instance_get_base_light(light_instance);1942AABB light_aabb = light_storage->light_instance_get_base_aabb(light_instance);1943Transform3D light_transform = light_storage->light_instance_get_base_transform(light_instance);19441945uint32_t max_sdfgi_cascade = RSG::light_storage->light_get_max_sdfgi_cascade(light);1946if (i > max_sdfgi_cascade) {1947continue;1948}19491950if (!cascade_aabb.intersects(light_aabb)) {1951continue;1952}19531954Vector3 dir = -light_transform.basis.get_column(Vector3::AXIS_Z);1955//faster to not do this here1956//dir.y *= y_mult;1957//dir.normalize();1958lights[idx].direction[0] = dir.x;1959lights[idx].direction[1] = dir.y;1960lights[idx].direction[2] = dir.z;1961Vector3 pos = light_transform.origin;1962pos.y *= y_mult;1963lights[idx].position[0] = pos.x;1964lights[idx].position[1] = pos.y;1965lights[idx].position[2] = pos.z;1966Color color = RSG::light_storage->light_get_color(light);1967color = color.srgb_to_linear();1968lights[idx].color[0] = color.r;1969lights[idx].color[1] = color.g;1970lights[idx].color[2] = color.b;1971lights[idx].type = RSG::light_storage->light_get_type(light);19721973lights[idx].energy = RSG::light_storage->light_get_param(light, RS::LIGHT_PARAM_ENERGY) * RSG::light_storage->light_get_param(light, RS::LIGHT_PARAM_INDIRECT_ENERGY);1974if (RendererSceneRenderRD::get_singleton()->is_using_physical_light_units()) {1975lights[idx].energy *= RSG::light_storage->light_get_param(light, RS::LIGHT_PARAM_INTENSITY);19761977// Convert from Luminous Power to Luminous Intensity1978if (lights[idx].type == RS::LIGHT_OMNI) {1979lights[idx].energy *= 1.0 / (Math::PI * 4.0);1980} else if (lights[idx].type == RS::LIGHT_SPOT) {1981// Spot Lights are not physically accurate, Luminous Intensity should change in relation to the cone angle.1982// We make this assumption to keep them easy to control.1983lights[idx].energy *= 1.0 / Math::PI;1984}1985}19861987if (p_render_data->camera_attributes.is_valid()) {1988lights[idx].energy *= RSG::camera_attributes->camera_attributes_get_exposure_normalization_factor(p_render_data->camera_attributes);1989}19901991lights[idx].has_shadow = RSG::light_storage->light_has_shadow(light);1992lights[idx].attenuation = RSG::light_storage->light_get_param(light, RS::LIGHT_PARAM_ATTENUATION);1993lights[idx].radius = RSG::light_storage->light_get_param(light, RS::LIGHT_PARAM_RANGE);1994lights[idx].cos_spot_angle = Math::cos(Math::deg_to_rad(RSG::light_storage->light_get_param(light, RS::LIGHT_PARAM_SPOT_ANGLE)));1995lights[idx].inv_spot_attenuation = 1.0f / RSG::light_storage->light_get_param(light, RS::LIGHT_PARAM_SPOT_ATTENUATION);19961997idx++;1998}19992000if (idx > 0) {2001RD::get_singleton()->buffer_update(cascade.lights_buffer, 0, idx * sizeof(SDFGIShader::Light), lights);2002}20032004cascade_dynamic_light_count[i] = idx;2005}2006}20072008void GI::SDFGI::render_region(Ref<RenderSceneBuffersRD> p_render_buffers, int p_region, const PagedArray<RenderGeometryInstance *> &p_instances, float p_exposure_normalization) {2009//print_line("rendering region " + itos(p_region));2010ERR_FAIL_COND(p_render_buffers.is_null()); // we wouldn't be here if this failed but...2011AABB bounds;2012Vector3i from;2013Vector3i size;20142015int cascade_prev = get_pending_region_data(p_region - 1, from, size, bounds);2016int cascade_next = get_pending_region_data(p_region + 1, from, size, bounds);2017int cascade = get_pending_region_data(p_region, from, size, bounds);2018ERR_FAIL_COND(cascade < 0);20192020if (cascade_prev != cascade) {2021//initialize render2022RD::get_singleton()->texture_clear(render_albedo, Color(0, 0, 0, 0), 0, 1, 0, 1);2023RD::get_singleton()->texture_clear(render_emission, Color(0, 0, 0, 0), 0, 1, 0, 1);2024RD::get_singleton()->texture_clear(render_emission_aniso, Color(0, 0, 0, 0), 0, 1, 0, 1);2025RD::get_singleton()->texture_clear(render_geom_facing, Color(0, 0, 0, 0), 0, 1, 0, 1);2026}20272028//print_line("rendering cascade " + itos(p_region) + " objects: " + itos(p_cull_count) + " bounds: " + bounds + " from: " + from + " size: " + size + " cell size: " + rtos(cascades[cascade].cell_size));2029RendererSceneRenderRD::get_singleton()->_render_sdfgi(p_render_buffers, from, size, bounds, p_instances, render_albedo, render_emission, render_emission_aniso, render_geom_facing, p_exposure_normalization);20302031if (cascade_next != cascade) {2032RD::get_singleton()->draw_command_begin_label("SDFGI Pre-Process Cascade");20332034RENDER_TIMESTAMP("> SDFGI Update SDF");2035//done rendering! must update SDF2036//clear dispatch indirect data20372038SDFGIShader::PreprocessPushConstant push_constant;2039memset(&push_constant, 0, sizeof(SDFGIShader::PreprocessPushConstant));20402041RENDER_TIMESTAMP("SDFGI Scroll SDF");20422043//scroll2044if (cascades[cascade].dirty_regions != SDFGI::Cascade::DIRTY_ALL) {2045//for scroll2046Vector3i dirty = cascades[cascade].dirty_regions;2047push_constant.scroll[0] = dirty.x;2048push_constant.scroll[1] = dirty.y;2049push_constant.scroll[2] = dirty.z;2050} else {2051//for no scroll2052push_constant.scroll[0] = 0;2053push_constant.scroll[1] = 0;2054push_constant.scroll[2] = 0;2055}20562057cascades[cascade].all_dynamic_lights_dirty = true;2058cascades[cascade].baked_exposure_normalization = p_exposure_normalization;20592060push_constant.grid_size = cascade_size;2061push_constant.cascade = cascade;20622063if (cascades[cascade].dirty_regions != SDFGI::Cascade::DIRTY_ALL) {2064RD::get_singleton()->buffer_copy(cascades[cascade].solid_cell_dispatch_buffer_storage, cascades[cascade].solid_cell_dispatch_buffer_call, 0, 0, sizeof(uint32_t) * 4);20652066RD::ComputeListID compute_list = RD::get_singleton()->compute_list_begin();20672068//must pre scroll existing data because not all is dirty2069RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, gi->sdfgi_shader.preprocess_pipeline[SDFGIShader::PRE_PROCESS_SCROLL]);2070RD::get_singleton()->compute_list_bind_uniform_set(compute_list, cascades[cascade].scroll_uniform_set, 0);20712072RD::get_singleton()->compute_list_set_push_constant(compute_list, &push_constant, sizeof(SDFGIShader::PreprocessPushConstant));2073RD::get_singleton()->compute_list_dispatch_indirect(compute_list, cascades[cascade].solid_cell_dispatch_buffer_call, 0);2074// no barrier do all together20752076RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, gi->sdfgi_shader.preprocess_pipeline[SDFGIShader::PRE_PROCESS_SCROLL_OCCLUSION]);2077RD::get_singleton()->compute_list_bind_uniform_set(compute_list, cascades[cascade].scroll_occlusion_uniform_set, 0);20782079Vector3i dirty = cascades[cascade].dirty_regions;2080Vector3i groups;2081groups.x = cascade_size - Math::abs(dirty.x);2082groups.y = cascade_size - Math::abs(dirty.y);2083groups.z = cascade_size - Math::abs(dirty.z);20842085RD::get_singleton()->compute_list_set_push_constant(compute_list, &push_constant, sizeof(SDFGIShader::PreprocessPushConstant));2086RD::get_singleton()->compute_list_dispatch_threads(compute_list, groups.x, groups.y, groups.z);20872088//no barrier, continue together20892090{2091//scroll probes and their history also20922093SDFGIShader::IntegratePushConstant ipush_constant;2094ipush_constant.grid_size[1] = cascade_size;2095ipush_constant.grid_size[2] = cascade_size;2096ipush_constant.grid_size[0] = cascade_size;2097ipush_constant.max_cascades = cascades.size();2098ipush_constant.probe_axis_size = probe_axis_count;2099ipush_constant.history_index = 0;2100ipush_constant.history_size = history_size;2101ipush_constant.ray_count = 0;2102ipush_constant.ray_bias = 0;2103ipush_constant.sky_flags = 0;2104ipush_constant.sky_energy = 0;2105ipush_constant.sky_color_or_orientation[0] = 0;2106ipush_constant.sky_color_or_orientation[1] = 0;2107ipush_constant.sky_color_or_orientation[2] = 0;2108ipush_constant.y_mult = y_mult;2109ipush_constant.store_ambient_texture = false;21102111ipush_constant.image_size[0] = probe_axis_count * probe_axis_count;2112ipush_constant.image_size[1] = probe_axis_count;21132114int32_t probe_divisor = cascade_size / SDFGI::PROBE_DIVISOR;2115ipush_constant.cascade = cascade;2116ipush_constant.world_offset[0] = cascades[cascade].position.x / probe_divisor;2117ipush_constant.world_offset[1] = cascades[cascade].position.y / probe_divisor;2118ipush_constant.world_offset[2] = cascades[cascade].position.z / probe_divisor;21192120ipush_constant.scroll[0] = dirty.x / probe_divisor;2121ipush_constant.scroll[1] = dirty.y / probe_divisor;2122ipush_constant.scroll[2] = dirty.z / probe_divisor;21232124RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, gi->sdfgi_shader.integrate_pipeline[SDFGIShader::INTEGRATE_MODE_SCROLL]);2125RD::get_singleton()->compute_list_bind_uniform_set(compute_list, cascades[cascade].integrate_uniform_set, 0);2126RD::get_singleton()->compute_list_bind_uniform_set(compute_list, gi->sdfgi_shader.integrate_default_sky_uniform_set, 1);2127RD::get_singleton()->compute_list_set_push_constant(compute_list, &ipush_constant, sizeof(SDFGIShader::IntegratePushConstant));2128RD::get_singleton()->compute_list_dispatch_threads(compute_list, probe_axis_count * probe_axis_count, probe_axis_count, 1);21292130RD::get_singleton()->compute_list_add_barrier(compute_list);21312132RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, gi->sdfgi_shader.integrate_pipeline[SDFGIShader::INTEGRATE_MODE_SCROLL_STORE]);2133RD::get_singleton()->compute_list_bind_uniform_set(compute_list, cascades[cascade].integrate_uniform_set, 0);2134RD::get_singleton()->compute_list_bind_uniform_set(compute_list, gi->sdfgi_shader.integrate_default_sky_uniform_set, 1);2135RD::get_singleton()->compute_list_set_push_constant(compute_list, &ipush_constant, sizeof(SDFGIShader::IntegratePushConstant));2136RD::get_singleton()->compute_list_dispatch_threads(compute_list, probe_axis_count * probe_axis_count, probe_axis_count, 1);21372138RD::get_singleton()->compute_list_add_barrier(compute_list);21392140if (bounce_feedback > 0.0) {2141//multibounce requires this to be stored so direct light can read from it21422143RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, gi->sdfgi_shader.integrate_pipeline[SDFGIShader::INTEGRATE_MODE_STORE]);21442145//convert to octahedral to store2146ipush_constant.image_size[0] *= SDFGI::LIGHTPROBE_OCT_SIZE;2147ipush_constant.image_size[1] *= SDFGI::LIGHTPROBE_OCT_SIZE;21482149RD::get_singleton()->compute_list_bind_uniform_set(compute_list, cascades[cascade].integrate_uniform_set, 0);2150RD::get_singleton()->compute_list_bind_uniform_set(compute_list, gi->sdfgi_shader.integrate_default_sky_uniform_set, 1);2151RD::get_singleton()->compute_list_set_push_constant(compute_list, &ipush_constant, sizeof(SDFGIShader::IntegratePushConstant));2152RD::get_singleton()->compute_list_dispatch_threads(compute_list, probe_axis_count * probe_axis_count * SDFGI::LIGHTPROBE_OCT_SIZE, probe_axis_count * SDFGI::LIGHTPROBE_OCT_SIZE, 1);2153}2154}21552156//ok finally barrier2157RD::get_singleton()->compute_list_end();2158}21592160//clear dispatch indirect data2161uint32_t dispatch_indirect_data[4] = { 0, 0, 0, 0 };2162RD::get_singleton()->buffer_update(cascades[cascade].solid_cell_dispatch_buffer_storage, 0, sizeof(uint32_t) * 4, dispatch_indirect_data);21632164RD::ComputeListID compute_list = RD::get_singleton()->compute_list_begin();21652166bool half_size = true; //much faster, very little difference2167static const int optimized_jf_group_size = 8;21682169if (half_size) {2170push_constant.grid_size >>= 1;21712172uint32_t cascade_half_size = cascade_size >> 1;2173RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, gi->sdfgi_shader.preprocess_pipeline[SDFGIShader::PRE_PROCESS_JUMP_FLOOD_INITIALIZE_HALF]);2174RD::get_singleton()->compute_list_bind_uniform_set(compute_list, sdf_initialize_half_uniform_set, 0);2175RD::get_singleton()->compute_list_set_push_constant(compute_list, &push_constant, sizeof(SDFGIShader::PreprocessPushConstant));2176RD::get_singleton()->compute_list_dispatch_threads(compute_list, cascade_half_size, cascade_half_size, cascade_half_size);2177RD::get_singleton()->compute_list_add_barrier(compute_list);21782179//must start with regular jumpflood21802181push_constant.half_size = true;2182{2183RENDER_TIMESTAMP("SDFGI Jump Flood (Half-Size)");21842185uint32_t s = cascade_half_size;21862187RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, gi->sdfgi_shader.preprocess_pipeline[SDFGIShader::PRE_PROCESS_JUMP_FLOOD]);21882189int jf_us = 0;2190//start with regular jump flood for very coarse reads, as this is impossible to optimize2191while (s > 1) {2192s /= 2;2193push_constant.step_size = s;2194RD::get_singleton()->compute_list_bind_uniform_set(compute_list, jump_flood_half_uniform_set[jf_us], 0);2195RD::get_singleton()->compute_list_set_push_constant(compute_list, &push_constant, sizeof(SDFGIShader::PreprocessPushConstant));2196RD::get_singleton()->compute_list_dispatch_threads(compute_list, cascade_half_size, cascade_half_size, cascade_half_size);2197RD::get_singleton()->compute_list_add_barrier(compute_list);2198jf_us = jf_us == 0 ? 1 : 0;21992200if (cascade_half_size / (s / 2) >= optimized_jf_group_size) {2201break;2202}2203}22042205RENDER_TIMESTAMP("SDFGI Jump Flood Optimized (Half-Size)");22062207//continue with optimized jump flood for smaller reads2208RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, gi->sdfgi_shader.preprocess_pipeline[SDFGIShader::PRE_PROCESS_JUMP_FLOOD_OPTIMIZED]);2209while (s > 1) {2210s /= 2;2211push_constant.step_size = s;2212RD::get_singleton()->compute_list_bind_uniform_set(compute_list, jump_flood_half_uniform_set[jf_us], 0);2213RD::get_singleton()->compute_list_set_push_constant(compute_list, &push_constant, sizeof(SDFGIShader::PreprocessPushConstant));2214RD::get_singleton()->compute_list_dispatch_threads(compute_list, cascade_half_size, cascade_half_size, cascade_half_size);2215RD::get_singleton()->compute_list_add_barrier(compute_list);2216jf_us = jf_us == 0 ? 1 : 0;2217}2218}22192220// restore grid size for last passes2221push_constant.grid_size = cascade_size;22222223RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, gi->sdfgi_shader.preprocess_pipeline[SDFGIShader::PRE_PROCESS_JUMP_FLOOD_UPSCALE]);2224RD::get_singleton()->compute_list_bind_uniform_set(compute_list, sdf_upscale_uniform_set, 0);2225RD::get_singleton()->compute_list_set_push_constant(compute_list, &push_constant, sizeof(SDFGIShader::PreprocessPushConstant));2226RD::get_singleton()->compute_list_dispatch_threads(compute_list, cascade_size, cascade_size, cascade_size);2227RD::get_singleton()->compute_list_add_barrier(compute_list);22282229//run one pass of fullsize jumpflood to fix up half size artifacts22302231push_constant.half_size = false;2232push_constant.step_size = 1;2233RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, gi->sdfgi_shader.preprocess_pipeline[SDFGIShader::PRE_PROCESS_JUMP_FLOOD_OPTIMIZED]);2234RD::get_singleton()->compute_list_bind_uniform_set(compute_list, jump_flood_uniform_set[upscale_jfa_uniform_set_index], 0);2235RD::get_singleton()->compute_list_set_push_constant(compute_list, &push_constant, sizeof(SDFGIShader::PreprocessPushConstant));2236RD::get_singleton()->compute_list_dispatch_threads(compute_list, cascade_size, cascade_size, cascade_size);2237RD::get_singleton()->compute_list_add_barrier(compute_list);22382239} else {2240//full size jumpflood2241RENDER_TIMESTAMP("SDFGI Jump Flood (Full-Size)");22422243RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, gi->sdfgi_shader.preprocess_pipeline[SDFGIShader::PRE_PROCESS_JUMP_FLOOD_INITIALIZE]);2244RD::get_singleton()->compute_list_bind_uniform_set(compute_list, sdf_initialize_uniform_set, 0);2245RD::get_singleton()->compute_list_set_push_constant(compute_list, &push_constant, sizeof(SDFGIShader::PreprocessPushConstant));2246RD::get_singleton()->compute_list_dispatch_threads(compute_list, cascade_size, cascade_size, cascade_size);22472248RD::get_singleton()->compute_list_add_barrier(compute_list);22492250push_constant.half_size = false;2251{2252uint32_t s = cascade_size;22532254RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, gi->sdfgi_shader.preprocess_pipeline[SDFGIShader::PRE_PROCESS_JUMP_FLOOD]);22552256int jf_us = 0;2257//start with regular jump flood for very coarse reads, as this is impossible to optimize2258while (s > 1) {2259s /= 2;2260push_constant.step_size = s;2261RD::get_singleton()->compute_list_bind_uniform_set(compute_list, jump_flood_uniform_set[jf_us], 0);2262RD::get_singleton()->compute_list_set_push_constant(compute_list, &push_constant, sizeof(SDFGIShader::PreprocessPushConstant));2263RD::get_singleton()->compute_list_dispatch_threads(compute_list, cascade_size, cascade_size, cascade_size);2264RD::get_singleton()->compute_list_add_barrier(compute_list);2265jf_us = jf_us == 0 ? 1 : 0;22662267if (cascade_size / (s / 2) >= optimized_jf_group_size) {2268break;2269}2270}22712272RENDER_TIMESTAMP("SDFGI Jump Flood Optimized (Full-Size)");22732274//continue with optimized jump flood for smaller reads2275RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, gi->sdfgi_shader.preprocess_pipeline[SDFGIShader::PRE_PROCESS_JUMP_FLOOD_OPTIMIZED]);2276while (s > 1) {2277s /= 2;2278push_constant.step_size = s;2279RD::get_singleton()->compute_list_bind_uniform_set(compute_list, jump_flood_uniform_set[jf_us], 0);2280RD::get_singleton()->compute_list_set_push_constant(compute_list, &push_constant, sizeof(SDFGIShader::PreprocessPushConstant));2281RD::get_singleton()->compute_list_dispatch_threads(compute_list, cascade_size, cascade_size, cascade_size);2282RD::get_singleton()->compute_list_add_barrier(compute_list);2283jf_us = jf_us == 0 ? 1 : 0;2284}2285}2286}22872288RENDER_TIMESTAMP("SDFGI Occlusion");22892290// occlusion2291{2292uint32_t probe_size = cascade_size / SDFGI::PROBE_DIVISOR;2293Vector3i probe_global_pos = cascades[cascade].position / probe_size;22942295RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, gi->sdfgi_shader.preprocess_pipeline[SDFGIShader::PRE_PROCESS_OCCLUSION]);2296RD::get_singleton()->compute_list_bind_uniform_set(compute_list, occlusion_uniform_set, 0);2297for (int i = 0; i < 8; i++) {2298//dispatch all at once for performance2299Vector3i offset(i & 1, (i >> 1) & 1, (i >> 2) & 1);23002301if ((probe_global_pos.x & 1) != 0) {2302offset.x = (offset.x + 1) & 1;2303}2304if ((probe_global_pos.y & 1) != 0) {2305offset.y = (offset.y + 1) & 1;2306}2307if ((probe_global_pos.z & 1) != 0) {2308offset.z = (offset.z + 1) & 1;2309}2310push_constant.probe_offset[0] = offset.x;2311push_constant.probe_offset[1] = offset.y;2312push_constant.probe_offset[2] = offset.z;2313push_constant.occlusion_index = i;2314RD::get_singleton()->compute_list_set_push_constant(compute_list, &push_constant, sizeof(SDFGIShader::PreprocessPushConstant));23152316Vector3i groups = Vector3i(probe_size + 1, probe_size + 1, probe_size + 1) - offset; //if offset, it's one less probe per axis to compute2317RD::get_singleton()->compute_list_dispatch(compute_list, groups.x, groups.y, groups.z);2318}2319RD::get_singleton()->compute_list_add_barrier(compute_list);2320}23212322RENDER_TIMESTAMP("SDFGI Store");23232324// store2325RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, gi->sdfgi_shader.preprocess_pipeline[SDFGIShader::PRE_PROCESS_STORE]);2326RD::get_singleton()->compute_list_bind_uniform_set(compute_list, cascades[cascade].sdf_store_uniform_set, 0);2327RD::get_singleton()->compute_list_set_push_constant(compute_list, &push_constant, sizeof(SDFGIShader::PreprocessPushConstant));2328RD::get_singleton()->compute_list_dispatch_threads(compute_list, cascade_size, cascade_size, cascade_size);23292330RD::get_singleton()->compute_list_end();23312332//clear these textures, as they will have previous garbage on next draw2333RD::get_singleton()->texture_clear(cascades[cascade].light_tex, Color(0, 0, 0, 0), 0, 1, 0, 1);2334RD::get_singleton()->texture_clear(cascades[cascade].light_aniso_0_tex, Color(0, 0, 0, 0), 0, 1, 0, 1);2335RD::get_singleton()->texture_clear(cascades[cascade].light_aniso_1_tex, Color(0, 0, 0, 0), 0, 1, 0, 1);23362337#if 02338Vector<uint8_t> data = RD::get_singleton()->texture_get_data(cascades[cascade].sdf, 0);2339Ref<Image> img;2340img.instantiate();2341for (uint32_t i = 0; i < cascade_size; i++) {2342Vector<uint8_t> subarr = data.slice(128 * 128 * i, 128 * 128 * (i + 1));2343img->set_data(cascade_size, cascade_size, false, Image::FORMAT_L8, subarr);2344img->save_png("res://cascade_sdf_" + itos(cascade) + "_" + itos(i) + ".png");2345}23462347//finalize render and update sdf2348#endif23492350#if 02351Vector<uint8_t> data = RD::get_singleton()->texture_get_data(render_albedo, 0);2352Ref<Image> img;2353img.instantiate();2354for (uint32_t i = 0; i < cascade_size; i++) {2355Vector<uint8_t> subarr = data.slice(128 * 128 * i * 2, 128 * 128 * (i + 1) * 2);2356img->createcascade_size, cascade_size, false, Image::FORMAT_RGB565, subarr);2357img->convert(Image::FORMAT_RGBA8);2358img->save_png("res://cascade_" + itos(cascade) + "_" + itos(i) + ".png");2359}23602361//finalize render and update sdf2362#endif23632364RENDER_TIMESTAMP("< SDFGI Update SDF");2365RD::get_singleton()->draw_command_end_label();2366}2367}23682369void GI::SDFGI::render_static_lights(RenderDataRD *p_render_data, Ref<RenderSceneBuffersRD> p_render_buffers, uint32_t p_cascade_count, const uint32_t *p_cascade_indices, const PagedArray<RID> *p_positional_light_cull_result) {2370ERR_FAIL_COND(p_render_buffers.is_null()); // we wouldn't be here if this failed but...23712372RendererRD::LightStorage *light_storage = RendererRD::LightStorage::get_singleton();23732374RD::get_singleton()->draw_command_begin_label("SDFGI Render Static Lights");23752376update_cascades();23772378SDFGIShader::Light lights[SDFGI::MAX_STATIC_LIGHTS];2379uint32_t light_count[SDFGI::MAX_STATIC_LIGHTS];23802381for (uint32_t i = 0; i < p_cascade_count; i++) {2382ERR_CONTINUE(p_cascade_indices[i] >= cascades.size());23832384SDFGI::Cascade &cc = cascades[p_cascade_indices[i]];23852386{ //fill light buffer23872388AABB cascade_aabb;2389cascade_aabb.position = Vector3((Vector3i(1, 1, 1) * -int32_t(cascade_size >> 1) + cc.position)) * cc.cell_size;2390cascade_aabb.size = Vector3(1, 1, 1) * cascade_size * cc.cell_size;23912392int idx = 0;23932394for (uint32_t j = 0; j < (uint32_t)p_positional_light_cull_result[i].size(); j++) {2395if (idx == SDFGI::MAX_STATIC_LIGHTS) {2396break;2397}23982399RID light_instance = p_positional_light_cull_result[i][j];2400ERR_CONTINUE(!light_storage->owns_light_instance(light_instance));24012402RID light = light_storage->light_instance_get_base_light(light_instance);2403AABB light_aabb = light_storage->light_instance_get_base_aabb(light_instance);2404Transform3D light_transform = light_storage->light_instance_get_base_transform(light_instance);24052406uint32_t max_sdfgi_cascade = RSG::light_storage->light_get_max_sdfgi_cascade(light);2407if (p_cascade_indices[i] > max_sdfgi_cascade) {2408continue;2409}24102411if (!cascade_aabb.intersects(light_aabb)) {2412continue;2413}24142415lights[idx].type = RSG::light_storage->light_get_type(light);24162417Vector3 dir = -light_transform.basis.get_column(Vector3::AXIS_Z);2418if (lights[idx].type == RS::LIGHT_DIRECTIONAL) {2419dir.y *= y_mult; //only makes sense for directional2420dir.normalize();2421}2422lights[idx].direction[0] = dir.x;2423lights[idx].direction[1] = dir.y;2424lights[idx].direction[2] = dir.z;2425Vector3 pos = light_transform.origin;2426pos.y *= y_mult;2427lights[idx].position[0] = pos.x;2428lights[idx].position[1] = pos.y;2429lights[idx].position[2] = pos.z;2430Color color = RSG::light_storage->light_get_color(light);2431color = color.srgb_to_linear();2432lights[idx].color[0] = color.r;2433lights[idx].color[1] = color.g;2434lights[idx].color[2] = color.b;24352436lights[idx].energy = RSG::light_storage->light_get_param(light, RS::LIGHT_PARAM_ENERGY) * RSG::light_storage->light_get_param(light, RS::LIGHT_PARAM_INDIRECT_ENERGY);2437if (RendererSceneRenderRD::get_singleton()->is_using_physical_light_units()) {2438lights[idx].energy *= RSG::light_storage->light_get_param(light, RS::LIGHT_PARAM_INTENSITY);24392440// Convert from Luminous Power to Luminous Intensity2441if (lights[idx].type == RS::LIGHT_OMNI) {2442lights[idx].energy *= 1.0 / (Math::PI * 4.0);2443} else if (lights[idx].type == RS::LIGHT_SPOT) {2444// Spot Lights are not physically accurate, Luminous Intensity should change in relation to the cone angle.2445// We make this assumption to keep them easy to control.2446lights[idx].energy *= 1.0 / Math::PI;2447}2448}24492450if (p_render_data->camera_attributes.is_valid()) {2451lights[idx].energy *= RSG::camera_attributes->camera_attributes_get_exposure_normalization_factor(p_render_data->camera_attributes);2452}24532454lights[idx].has_shadow = RSG::light_storage->light_has_shadow(light);2455lights[idx].attenuation = RSG::light_storage->light_get_param(light, RS::LIGHT_PARAM_ATTENUATION);2456lights[idx].radius = RSG::light_storage->light_get_param(light, RS::LIGHT_PARAM_RANGE);2457lights[idx].cos_spot_angle = Math::cos(Math::deg_to_rad(RSG::light_storage->light_get_param(light, RS::LIGHT_PARAM_SPOT_ANGLE)));2458lights[idx].inv_spot_attenuation = 1.0f / RSG::light_storage->light_get_param(light, RS::LIGHT_PARAM_SPOT_ATTENUATION);24592460idx++;2461}24622463if (idx > 0) {2464RD::get_singleton()->buffer_update(cc.lights_buffer, 0, idx * sizeof(SDFGIShader::Light), lights);2465}24662467light_count[i] = idx;2468}2469}24702471for (uint32_t i = 0; i < p_cascade_count; i++) {2472ERR_CONTINUE(p_cascade_indices[i] >= cascades.size());24732474SDFGI::Cascade &cc = cascades[p_cascade_indices[i]];2475if (light_count[i] > 0) {2476RD::get_singleton()->buffer_copy(cc.solid_cell_dispatch_buffer_storage, cc.solid_cell_dispatch_buffer_call, 0, 0, sizeof(uint32_t) * 4);2477}2478}24792480/* Static Lights */2481RD::ComputeListID compute_list = RD::get_singleton()->compute_list_begin();24822483RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, gi->sdfgi_shader.direct_light_pipeline[SDFGIShader::DIRECT_LIGHT_MODE_STATIC]);24842485SDFGIShader::DirectLightPushConstant dl_push_constant;24862487dl_push_constant.grid_size[0] = cascade_size;2488dl_push_constant.grid_size[1] = cascade_size;2489dl_push_constant.grid_size[2] = cascade_size;2490dl_push_constant.max_cascades = cascades.size();2491dl_push_constant.probe_axis_size = probe_axis_count;2492dl_push_constant.bounce_feedback = 0.0; // this is static light, do not multibounce yet2493dl_push_constant.y_mult = y_mult;2494dl_push_constant.use_occlusion = uses_occlusion;24952496//all must be processed2497dl_push_constant.process_offset = 0;2498dl_push_constant.process_increment = 1;24992500for (uint32_t i = 0; i < p_cascade_count; i++) {2501ERR_CONTINUE(p_cascade_indices[i] >= cascades.size());25022503SDFGI::Cascade &cc = cascades[p_cascade_indices[i]];25042505dl_push_constant.light_count = light_count[i];2506dl_push_constant.cascade = p_cascade_indices[i];25072508if (dl_push_constant.light_count > 0) {2509RD::get_singleton()->compute_list_bind_uniform_set(compute_list, cc.sdf_direct_light_static_uniform_set, 0);2510RD::get_singleton()->compute_list_set_push_constant(compute_list, &dl_push_constant, sizeof(SDFGIShader::DirectLightPushConstant));2511RD::get_singleton()->compute_list_dispatch_indirect(compute_list, cc.solid_cell_dispatch_buffer_call, 0);2512}2513}25142515RD::get_singleton()->compute_list_end();25162517RD::get_singleton()->draw_command_end_label();2518}25192520////////////////////////////////////////////////////////////////////////////////2521// VoxelGIInstance25222523void GI::VoxelGIInstance::update(bool p_update_light_instances, const Vector<RID> &p_light_instances, const PagedArray<RenderGeometryInstance *> &p_dynamic_objects) {2524RendererRD::LightStorage *light_storage = RendererRD::LightStorage::get_singleton();2525RendererRD::MaterialStorage *material_storage = RendererRD::MaterialStorage::get_singleton();25262527uint32_t data_version = gi->voxel_gi_get_data_version(probe);25282529// (RE)CREATE IF NEEDED25302531if (last_probe_data_version != data_version) {2532//need to re-create everything2533free_resources();25342535Vector3i octree_size = gi->voxel_gi_get_octree_size(probe);25362537if (octree_size != Vector3i()) {2538//can create a 3D texture2539Vector<int> levels = gi->voxel_gi_get_level_counts(probe);25402541RD::TextureFormat tf;2542tf.format = RD::DATA_FORMAT_R8G8B8A8_UNORM;2543tf.width = octree_size.x;2544tf.height = octree_size.y;2545tf.depth = octree_size.z;2546tf.texture_type = RD::TEXTURE_TYPE_3D;2547tf.mipmaps = levels.size();25482549tf.usage_bits = RD::TEXTURE_USAGE_SAMPLING_BIT | RD::TEXTURE_USAGE_STORAGE_BIT | RD::TEXTURE_USAGE_CAN_COPY_TO_BIT;25502551texture = RD::get_singleton()->texture_create(tf, RD::TextureView());2552RD::get_singleton()->set_resource_name(texture, "VoxelGI Instance Texture");25532554RD::get_singleton()->texture_clear(texture, Color(0, 0, 0, 0), 0, levels.size(), 0, 1);25552556{2557int total_elements = 0;2558for (int i = 0; i < levels.size(); i++) {2559total_elements += levels[i];2560}25612562write_buffer = RD::get_singleton()->storage_buffer_create(total_elements * 16);2563}25642565for (int i = 0; i < levels.size(); i++) {2566VoxelGIInstance::Mipmap mipmap;2567mipmap.texture = RD::get_singleton()->texture_create_shared_from_slice(RD::TextureView(), texture, 0, i, 1, RD::TEXTURE_SLICE_3D);2568mipmap.level = levels.size() - i - 1;2569mipmap.cell_offset = 0;2570for (uint32_t j = 0; j < mipmap.level; j++) {2571mipmap.cell_offset += levels[j];2572}2573mipmap.cell_count = levels[mipmap.level];25742575Vector<RD::Uniform> uniforms;2576{2577RD::Uniform u;2578u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER;2579u.binding = 1;2580u.append_id(gi->voxel_gi_get_octree_buffer(probe));2581uniforms.push_back(u);2582}2583{2584RD::Uniform u;2585u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER;2586u.binding = 2;2587u.append_id(gi->voxel_gi_get_data_buffer(probe));2588uniforms.push_back(u);2589}25902591{2592RD::Uniform u;2593u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER;2594u.binding = 4;2595u.append_id(write_buffer);2596uniforms.push_back(u);2597}2598{2599RD::Uniform u;2600u.uniform_type = RD::UNIFORM_TYPE_TEXTURE;2601u.binding = 9;2602u.append_id(gi->voxel_gi_get_sdf_texture(probe));2603uniforms.push_back(u);2604}2605{2606RD::Uniform u;2607u.uniform_type = RD::UNIFORM_TYPE_SAMPLER;2608u.binding = 10;2609u.append_id(material_storage->sampler_rd_get_default(RS::CANVAS_ITEM_TEXTURE_FILTER_LINEAR_WITH_MIPMAPS, RS::CANVAS_ITEM_TEXTURE_REPEAT_DISABLED));2610uniforms.push_back(u);2611}26122613{2614Vector<RD::Uniform> copy_uniforms = uniforms;2615if (i == 0) {2616{2617RD::Uniform u;2618u.uniform_type = RD::UNIFORM_TYPE_UNIFORM_BUFFER;2619u.binding = 3;2620u.append_id(gi->voxel_gi_lights_uniform);2621copy_uniforms.push_back(u);2622}26232624mipmap.uniform_set = RD::get_singleton()->uniform_set_create(copy_uniforms, gi->voxel_gi_lighting_shader_version_shaders[VOXEL_GI_SHADER_VERSION_COMPUTE_LIGHT], 0);26252626copy_uniforms = uniforms; //restore26272628{2629RD::Uniform u;2630u.uniform_type = RD::UNIFORM_TYPE_TEXTURE;2631u.binding = 5;2632u.append_id(texture);2633copy_uniforms.push_back(u);2634}2635mipmap.second_bounce_uniform_set = RD::get_singleton()->uniform_set_create(copy_uniforms, gi->voxel_gi_lighting_shader_version_shaders[VOXEL_GI_SHADER_VERSION_COMPUTE_SECOND_BOUNCE], 0);2636} else {2637mipmap.uniform_set = RD::get_singleton()->uniform_set_create(copy_uniforms, gi->voxel_gi_lighting_shader_version_shaders[VOXEL_GI_SHADER_VERSION_COMPUTE_MIPMAP], 0);2638}2639}26402641{2642RD::Uniform u;2643u.uniform_type = RD::UNIFORM_TYPE_IMAGE;2644u.binding = 5;2645u.append_id(mipmap.texture);2646uniforms.push_back(u);2647}26482649mipmap.write_uniform_set = RD::get_singleton()->uniform_set_create(uniforms, gi->voxel_gi_lighting_shader_version_shaders[VOXEL_GI_SHADER_VERSION_WRITE_TEXTURE], 0);26502651mipmaps.push_back(mipmap);2652}26532654{2655uint32_t dynamic_map_size = MAX(MAX(octree_size.x, octree_size.y), octree_size.z);2656uint32_t oversample = nearest_power_of_2_templated(4);2657int mipmap_index = 0;26582659while (mipmap_index < mipmaps.size()) {2660VoxelGIInstance::DynamicMap dmap;26612662if (oversample > 0) {2663dmap.size = dynamic_map_size * (1 << oversample);2664dmap.mipmap = -1;2665oversample--;2666} else {2667dmap.size = dynamic_map_size >> mipmap_index;2668dmap.mipmap = mipmap_index;2669mipmap_index++;2670}26712672RD::TextureFormat dtf;2673dtf.width = dmap.size;2674dtf.height = dmap.size;2675dtf.format = RD::DATA_FORMAT_R16G16B16A16_SFLOAT;2676dtf.usage_bits = RD::TEXTURE_USAGE_STORAGE_BIT;26772678if (dynamic_maps.is_empty()) {2679dtf.usage_bits |= RD::TEXTURE_USAGE_COLOR_ATTACHMENT_BIT;2680}2681dmap.texture = RD::get_singleton()->texture_create(dtf, RD::TextureView());2682RD::get_singleton()->set_resource_name(dmap.texture, "VoxelGI Instance DMap Texture");26832684if (dynamic_maps.is_empty()) {2685// Render depth for first one.2686// Use 16-bit depth when supported to improve performance.2687dtf.format = RD::get_singleton()->texture_is_format_supported_for_usage(RD::DATA_FORMAT_D16_UNORM, RD::TEXTURE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT) ? RD::DATA_FORMAT_D16_UNORM : RD::DATA_FORMAT_X8_D24_UNORM_PACK32;2688dtf.usage_bits = RD::TEXTURE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT;2689dmap.fb_depth = RD::get_singleton()->texture_create(dtf, RD::TextureView());2690RD::get_singleton()->set_resource_name(dmap.fb_depth, "VoxelGI Instance DMap FB Depth");2691}26922693//just use depth as-is2694dtf.format = RD::DATA_FORMAT_R32_SFLOAT;2695dtf.usage_bits = RD::TEXTURE_USAGE_STORAGE_BIT | RD::TEXTURE_USAGE_COLOR_ATTACHMENT_BIT;26962697dmap.depth = RD::get_singleton()->texture_create(dtf, RD::TextureView());2698RD::get_singleton()->set_resource_name(dmap.depth, "VoxelGI Instance DMap Depth");26992700if (dynamic_maps.is_empty()) {2701dtf.format = RD::DATA_FORMAT_R8G8B8A8_UNORM;2702dtf.usage_bits = RD::TEXTURE_USAGE_STORAGE_BIT | RD::TEXTURE_USAGE_COLOR_ATTACHMENT_BIT;2703dmap.albedo = RD::get_singleton()->texture_create(dtf, RD::TextureView());2704RD::get_singleton()->set_resource_name(dmap.albedo, "VoxelGI Instance DMap Albedo");2705dmap.normal = RD::get_singleton()->texture_create(dtf, RD::TextureView());2706RD::get_singleton()->set_resource_name(dmap.normal, "VoxelGI Instance DMap Normal");2707dmap.orm = RD::get_singleton()->texture_create(dtf, RD::TextureView());2708RD::get_singleton()->set_resource_name(dmap.orm, "VoxelGI Instance DMap ORM");27092710Vector<RID> fb;2711fb.push_back(dmap.albedo);2712fb.push_back(dmap.normal);2713fb.push_back(dmap.orm);2714fb.push_back(dmap.texture); //emission2715fb.push_back(dmap.depth);2716fb.push_back(dmap.fb_depth);27172718dmap.fb = RD::get_singleton()->framebuffer_create(fb);27192720{2721Vector<RD::Uniform> uniforms;2722{2723RD::Uniform u;2724u.uniform_type = RD::UNIFORM_TYPE_UNIFORM_BUFFER;2725u.binding = 3;2726u.append_id(gi->voxel_gi_lights_uniform);2727uniforms.push_back(u);2728}27292730{2731RD::Uniform u;2732u.uniform_type = RD::UNIFORM_TYPE_IMAGE;2733u.binding = 5;2734u.append_id(dmap.albedo);2735uniforms.push_back(u);2736}2737{2738RD::Uniform u;2739u.uniform_type = RD::UNIFORM_TYPE_IMAGE;2740u.binding = 6;2741u.append_id(dmap.normal);2742uniforms.push_back(u);2743}2744{2745RD::Uniform u;2746u.uniform_type = RD::UNIFORM_TYPE_IMAGE;2747u.binding = 7;2748u.append_id(dmap.orm);2749uniforms.push_back(u);2750}2751{2752RD::Uniform u;2753u.uniform_type = RD::UNIFORM_TYPE_TEXTURE;2754u.binding = 8;2755u.append_id(dmap.fb_depth);2756uniforms.push_back(u);2757}2758{2759RD::Uniform u;2760u.uniform_type = RD::UNIFORM_TYPE_TEXTURE;2761u.binding = 9;2762u.append_id(gi->voxel_gi_get_sdf_texture(probe));2763uniforms.push_back(u);2764}2765{2766RD::Uniform u;2767u.uniform_type = RD::UNIFORM_TYPE_SAMPLER;2768u.binding = 10;2769u.append_id(material_storage->sampler_rd_get_default(RS::CANVAS_ITEM_TEXTURE_FILTER_LINEAR_WITH_MIPMAPS, RS::CANVAS_ITEM_TEXTURE_REPEAT_DISABLED));2770uniforms.push_back(u);2771}2772{2773RD::Uniform u;2774u.uniform_type = RD::UNIFORM_TYPE_IMAGE;2775u.binding = 11;2776u.append_id(dmap.texture);2777uniforms.push_back(u);2778}2779{2780RD::Uniform u;2781u.uniform_type = RD::UNIFORM_TYPE_IMAGE;2782u.binding = 12;2783u.append_id(dmap.depth);2784uniforms.push_back(u);2785}27862787dmap.uniform_set = RD::get_singleton()->uniform_set_create(uniforms, gi->voxel_gi_lighting_shader_version_shaders[VOXEL_GI_SHADER_VERSION_DYNAMIC_OBJECT_LIGHTING], 0);2788}2789} else {2790bool plot = dmap.mipmap >= 0;2791bool write = dmap.mipmap < (mipmaps.size() - 1);27922793Vector<RD::Uniform> uniforms;27942795{2796RD::Uniform u;2797u.uniform_type = RD::UNIFORM_TYPE_IMAGE;2798u.binding = 5;2799u.append_id(dynamic_maps[dynamic_maps.size() - 1].texture);2800uniforms.push_back(u);2801}2802{2803RD::Uniform u;2804u.uniform_type = RD::UNIFORM_TYPE_IMAGE;2805u.binding = 6;2806u.append_id(dynamic_maps[dynamic_maps.size() - 1].depth);2807uniforms.push_back(u);2808}28092810if (write) {2811{2812RD::Uniform u;2813u.uniform_type = RD::UNIFORM_TYPE_IMAGE;2814u.binding = 7;2815u.append_id(dmap.texture);2816uniforms.push_back(u);2817}2818{2819RD::Uniform u;2820u.uniform_type = RD::UNIFORM_TYPE_IMAGE;2821u.binding = 8;2822u.append_id(dmap.depth);2823uniforms.push_back(u);2824}2825}28262827{2828RD::Uniform u;2829u.uniform_type = RD::UNIFORM_TYPE_TEXTURE;2830u.binding = 9;2831u.append_id(gi->voxel_gi_get_sdf_texture(probe));2832uniforms.push_back(u);2833}2834{2835RD::Uniform u;2836u.uniform_type = RD::UNIFORM_TYPE_SAMPLER;2837u.binding = 10;2838u.append_id(material_storage->sampler_rd_get_default(RS::CANVAS_ITEM_TEXTURE_FILTER_LINEAR_WITH_MIPMAPS, RS::CANVAS_ITEM_TEXTURE_REPEAT_DISABLED));2839uniforms.push_back(u);2840}28412842if (plot) {2843{2844RD::Uniform u;2845u.uniform_type = RD::UNIFORM_TYPE_IMAGE;2846u.binding = 11;2847u.append_id(mipmaps[dmap.mipmap].texture);2848uniforms.push_back(u);2849}2850}28512852dmap.uniform_set = RD::get_singleton()->uniform_set_create(2853uniforms,2854gi->voxel_gi_lighting_shader_version_shaders[(write && plot) ? VOXEL_GI_SHADER_VERSION_DYNAMIC_SHRINK_WRITE_PLOT : (write ? VOXEL_GI_SHADER_VERSION_DYNAMIC_SHRINK_WRITE : VOXEL_GI_SHADER_VERSION_DYNAMIC_SHRINK_PLOT)],28550);2856}28572858dynamic_maps.push_back(dmap);2859}2860}2861}28622863last_probe_data_version = data_version;2864p_update_light_instances = true; //just in case28652866RendererSceneRenderRD::get_singleton()->base_uniforms_changed();2867}28682869// UDPDATE TIME28702871if (has_dynamic_object_data) {2872//if it has dynamic object data, it needs to be cleared2873RD::get_singleton()->texture_clear(texture, Color(0, 0, 0, 0), 0, mipmaps.size(), 0, 1);2874}28752876uint32_t light_count = 0;28772878if (p_update_light_instances || p_dynamic_objects.size() > 0) {2879light_count = MIN(gi->voxel_gi_max_lights, (uint32_t)p_light_instances.size());28802881{2882Transform3D to_cell = gi->voxel_gi_get_to_cell_xform(probe);2883Transform3D to_probe_xform = to_cell * transform.affine_inverse();28842885//update lights28862887for (uint32_t i = 0; i < light_count; i++) {2888VoxelGILight &l = gi->voxel_gi_lights[i];2889RID light_instance = p_light_instances[i];2890RID light = light_storage->light_instance_get_base_light(light_instance);28912892l.type = RSG::light_storage->light_get_type(light);2893if (l.type == RS::LIGHT_DIRECTIONAL && RSG::light_storage->light_directional_get_sky_mode(light) == RS::LIGHT_DIRECTIONAL_SKY_MODE_SKY_ONLY) {2894light_count--;2895continue;2896}28972898l.attenuation = RSG::light_storage->light_get_param(light, RS::LIGHT_PARAM_ATTENUATION);2899l.energy = RSG::light_storage->light_get_param(light, RS::LIGHT_PARAM_ENERGY) * RSG::light_storage->light_get_param(light, RS::LIGHT_PARAM_INDIRECT_ENERGY);29002901if (RendererSceneRenderRD::get_singleton()->is_using_physical_light_units()) {2902l.energy *= RSG::light_storage->light_get_param(light, RS::LIGHT_PARAM_INTENSITY);29032904l.energy *= gi->voxel_gi_get_baked_exposure_normalization(probe);29052906// Convert from Luminous Power to Luminous Intensity2907if (l.type == RS::LIGHT_OMNI) {2908l.energy *= 1.0 / (Math::PI * 4.0);2909} else if (l.type == RS::LIGHT_SPOT) {2910// Spot Lights are not physically accurate, Luminous Intensity should change in relation to the cone angle.2911// We make this assumption to keep them easy to control.2912l.energy *= 1.0 / Math::PI;2913}2914}29152916l.radius = to_cell.basis.xform(Vector3(RSG::light_storage->light_get_param(light, RS::LIGHT_PARAM_RANGE), 0, 0)).length();2917Color color = RSG::light_storage->light_get_color(light).srgb_to_linear();2918l.color[0] = color.r;2919l.color[1] = color.g;2920l.color[2] = color.b;29212922l.cos_spot_angle = Math::cos(Math::deg_to_rad(RSG::light_storage->light_get_param(light, RS::LIGHT_PARAM_SPOT_ANGLE)));2923l.inv_spot_attenuation = 1.0f / RSG::light_storage->light_get_param(light, RS::LIGHT_PARAM_SPOT_ATTENUATION);29242925Transform3D xform = light_storage->light_instance_get_base_transform(light_instance);29262927Vector3 pos = to_probe_xform.xform(xform.origin);2928Vector3 dir = to_probe_xform.basis.xform(-xform.basis.get_column(2)).normalized();29292930l.position[0] = pos.x;2931l.position[1] = pos.y;2932l.position[2] = pos.z;29332934l.direction[0] = dir.x;2935l.direction[1] = dir.y;2936l.direction[2] = dir.z;29372938l.has_shadow = RSG::light_storage->light_has_shadow(light);2939}29402941RD::get_singleton()->buffer_update(gi->voxel_gi_lights_uniform, 0, sizeof(VoxelGILight) * light_count, gi->voxel_gi_lights);2942}2943}29442945if (has_dynamic_object_data || p_update_light_instances || p_dynamic_objects.size()) {2946// PROCESS MIPMAPS2947if (mipmaps.size()) {2948//can update mipmaps29492950Vector3i probe_size = gi->voxel_gi_get_octree_size(probe);29512952Vector3 ps = probe_size / gi->voxel_gi_get_bounds(probe).size;2953float cell_size = (1.0 / MAX(MAX(ps.x, ps.y), ps.z)); // probe size relative to 1 unit in world space29542955VoxelGIPushConstant push_constant;29562957push_constant.limits[0] = probe_size.x;2958push_constant.limits[1] = probe_size.y;2959push_constant.limits[2] = probe_size.z;2960push_constant.stack_size = mipmaps.size();2961push_constant.emission_scale = 1.0;2962push_constant.propagation = gi->voxel_gi_get_propagation(probe);2963push_constant.dynamic_range = gi->voxel_gi_get_dynamic_range(probe);2964push_constant.light_count = light_count;2965push_constant.aniso_strength = 0;2966push_constant.cell_size = cell_size;29672968/* print_line("probe update to version " + itos(last_probe_version));2969print_line("propagation " + rtos(push_constant.propagation));2970print_line("dynrange " + rtos(push_constant.dynamic_range));2971*/2972RD::ComputeListID compute_list = RD::get_singleton()->compute_list_begin();29732974int passes;2975if (p_update_light_instances) {2976passes = gi->voxel_gi_is_using_two_bounces(probe) ? 2 : 1;2977} else {2978passes = 1; //only re-blitting is necessary2979}2980int wg_size = 64;2981int64_t wg_limit_x = (int64_t)RD::get_singleton()->limit_get(RD::LIMIT_MAX_COMPUTE_WORKGROUP_COUNT_X);29822983for (int pass = 0; pass < passes; pass++) {2984if (p_update_light_instances) {2985for (int i = 0; i < mipmaps.size(); i++) {2986if (i == 0) {2987RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, gi->voxel_gi_lighting_shader_version_pipelines[pass == 0 ? VOXEL_GI_SHADER_VERSION_COMPUTE_LIGHT : VOXEL_GI_SHADER_VERSION_COMPUTE_SECOND_BOUNCE]);2988} else if (i == 1) {2989RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, gi->voxel_gi_lighting_shader_version_pipelines[VOXEL_GI_SHADER_VERSION_COMPUTE_MIPMAP]);2990}29912992if (pass == 1 || i > 0) {2993RD::get_singleton()->compute_list_add_barrier(compute_list); //wait til previous step is done2994}2995if (pass == 0 || i > 0) {2996RD::get_singleton()->compute_list_bind_uniform_set(compute_list, mipmaps[i].uniform_set, 0);2997} else {2998RD::get_singleton()->compute_list_bind_uniform_set(compute_list, mipmaps[i].second_bounce_uniform_set, 0);2999}30003001push_constant.cell_offset = mipmaps[i].cell_offset;3002push_constant.cell_count = mipmaps[i].cell_count;30033004int64_t wg_todo = (mipmaps[i].cell_count + wg_size - 1) / wg_size;3005while (wg_todo) {3006int64_t wg_count = MIN(wg_todo, wg_limit_x);3007RD::get_singleton()->compute_list_set_push_constant(compute_list, &push_constant, sizeof(VoxelGIPushConstant));3008RD::get_singleton()->compute_list_dispatch(compute_list, wg_count, 1, 1);3009wg_todo -= wg_count;3010push_constant.cell_offset += wg_count * wg_size;3011}3012}30133014RD::get_singleton()->compute_list_add_barrier(compute_list); //wait til previous step is done3015}30163017RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, gi->voxel_gi_lighting_shader_version_pipelines[VOXEL_GI_SHADER_VERSION_WRITE_TEXTURE]);30183019for (int i = 0; i < mipmaps.size(); i++) {3020RD::get_singleton()->compute_list_bind_uniform_set(compute_list, mipmaps[i].write_uniform_set, 0);30213022push_constant.cell_offset = mipmaps[i].cell_offset;3023push_constant.cell_count = mipmaps[i].cell_count;30243025int64_t wg_todo = (mipmaps[i].cell_count + wg_size - 1) / wg_size;3026while (wg_todo) {3027int64_t wg_count = MIN(wg_todo, wg_limit_x);3028RD::get_singleton()->compute_list_set_push_constant(compute_list, &push_constant, sizeof(VoxelGIPushConstant));3029RD::get_singleton()->compute_list_dispatch(compute_list, wg_count, 1, 1);3030wg_todo -= wg_count;3031push_constant.cell_offset += wg_count * wg_size;3032}3033}3034}30353036RD::get_singleton()->compute_list_end();3037}3038}30393040has_dynamic_object_data = false; //clear until dynamic object data is used again30413042if (p_dynamic_objects.size() && dynamic_maps.size()) {3043Vector3i octree_size = gi->voxel_gi_get_octree_size(probe);3044int multiplier = dynamic_maps[0].size / MAX(MAX(octree_size.x, octree_size.y), octree_size.z);30453046Transform3D oversample_scale;3047oversample_scale.basis.scale(Vector3(multiplier, multiplier, multiplier));30483049Transform3D to_cell = oversample_scale * gi->voxel_gi_get_to_cell_xform(probe);3050Transform3D to_world_xform = transform * to_cell.affine_inverse();3051Transform3D to_probe_xform = to_world_xform.affine_inverse();30523053AABB probe_aabb(Vector3(), octree_size);30543055//this could probably be better parallelized in compute..3056for (int i = 0; i < (int)p_dynamic_objects.size(); i++) {3057RenderGeometryInstance *instance = p_dynamic_objects[i];30583059//transform aabb to voxel_gi3060AABB aabb = (to_probe_xform * instance->get_transform()).xform(instance->get_aabb());30613062//this needs to wrap to grid resolution to avoid jitter3063//also extend margin a bit just in case3064Vector3i begin = aabb.position - Vector3i(1, 1, 1);3065Vector3i end = aabb.position + aabb.size + Vector3i(1, 1, 1);30663067for (int j = 0; j < 3; j++) {3068if ((end[j] - begin[j]) & 1) {3069end[j]++; //for half extents split, it needs to be even3070}3071begin[j] = MAX(begin[j], 0);3072end[j] = MIN(end[j], octree_size[j] * multiplier);3073}30743075//aabb = aabb.intersection(probe_aabb); //intersect3076aabb.position = begin;3077aabb.size = end - begin;30783079//print_line("aabb: " + aabb);30803081for (int j = 0; j < 6; j++) {3082//if (j != 0 && j != 3) {3083// continue;3084//}3085static const Vector3 render_z[6] = {3086Vector3(1, 0, 0),3087Vector3(0, 1, 0),3088Vector3(0, 0, 1),3089Vector3(-1, 0, 0),3090Vector3(0, -1, 0),3091Vector3(0, 0, -1),3092};3093static const Vector3 render_up[6] = {3094Vector3(0, 1, 0),3095Vector3(0, 0, 1),3096Vector3(0, 1, 0),3097Vector3(0, 1, 0),3098Vector3(0, 0, 1),3099Vector3(0, 1, 0),3100};31013102Vector3 render_dir = render_z[j];3103Vector3 up_dir = render_up[j];31043105Vector3 center = aabb.get_center();3106Transform3D xform;3107xform.set_look_at(center - aabb.size * 0.5 * render_dir, center, up_dir);31083109Vector3 x_dir = xform.basis.get_column(0).abs();3110int x_axis = int(Vector3(0, 1, 2).dot(x_dir));3111Vector3 y_dir = xform.basis.get_column(1).abs();3112int y_axis = int(Vector3(0, 1, 2).dot(y_dir));3113Vector3 z_dir = -xform.basis.get_column(2);3114int z_axis = int(Vector3(0, 1, 2).dot(z_dir.abs()));31153116Rect2i rect(aabb.position[x_axis], aabb.position[y_axis], aabb.size[x_axis], aabb.size[y_axis]);3117bool x_flip = bool(Vector3(1, 1, 1).dot(xform.basis.get_column(0)) < 0);3118bool y_flip = bool(Vector3(1, 1, 1).dot(xform.basis.get_column(1)) < 0);3119bool z_flip = bool(Vector3(1, 1, 1).dot(xform.basis.get_column(2)) > 0);31203121Projection cm;3122cm.set_orthogonal(-rect.size.width / 2, rect.size.width / 2, -rect.size.height / 2, rect.size.height / 2, 0.0001, aabb.size[z_axis]);31233124if (RendererSceneRenderRD::get_singleton()->cull_argument.size() == 0) {3125RendererSceneRenderRD::get_singleton()->cull_argument.push_back(nullptr);3126}3127RendererSceneRenderRD::get_singleton()->cull_argument[0] = instance;31283129float exposure_normalization = 1.0;3130if (RendererSceneRenderRD::get_singleton()->is_using_physical_light_units()) {3131exposure_normalization = gi->voxel_gi_get_baked_exposure_normalization(probe);3132}31333134RendererSceneRenderRD::get_singleton()->_render_material(to_world_xform * xform, cm, true, RendererSceneRenderRD::get_singleton()->cull_argument, dynamic_maps[0].fb, Rect2i(Vector2i(), rect.size), exposure_normalization);31353136Vector3 ps = octree_size / gi->voxel_gi_get_bounds(probe).size;3137float cell_size = (1.0 / MAX(MAX(ps.x, ps.y), ps.z)); // probe size relative to 1 unit in world space31383139VoxelGIDynamicPushConstant push_constant;3140memset(&push_constant, 0, sizeof(VoxelGIDynamicPushConstant));3141push_constant.limits[0] = octree_size.x;3142push_constant.limits[1] = octree_size.y;3143push_constant.limits[2] = octree_size.z;3144push_constant.light_count = p_light_instances.size();3145push_constant.x_dir[0] = x_dir[0];3146push_constant.x_dir[1] = x_dir[1];3147push_constant.x_dir[2] = x_dir[2];3148push_constant.y_dir[0] = y_dir[0];3149push_constant.y_dir[1] = y_dir[1];3150push_constant.y_dir[2] = y_dir[2];3151push_constant.z_dir[0] = z_dir[0];3152push_constant.z_dir[1] = z_dir[1];3153push_constant.z_dir[2] = z_dir[2];3154push_constant.z_base = xform.origin[z_axis];3155push_constant.z_sign = (z_flip ? -1.0 : 1.0);3156push_constant.pos_multiplier = float(1.0) / multiplier;3157push_constant.dynamic_range = gi->voxel_gi_get_dynamic_range(probe);3158push_constant.flip_x = x_flip;3159push_constant.flip_y = y_flip;3160push_constant.rect_pos[0] = rect.position[0];3161push_constant.rect_pos[1] = rect.position[1];3162push_constant.rect_size[0] = rect.size[0];3163push_constant.rect_size[1] = rect.size[1];3164push_constant.prev_rect_ofs[0] = 0;3165push_constant.prev_rect_ofs[1] = 0;3166push_constant.prev_rect_size[0] = 0;3167push_constant.prev_rect_size[1] = 0;3168push_constant.on_mipmap = false;3169push_constant.propagation = gi->voxel_gi_get_propagation(probe);3170push_constant.cell_size = cell_size;3171push_constant.pad[0] = 0;3172push_constant.pad[1] = 0;31733174//process lighting3175RD::ComputeListID compute_list = RD::get_singleton()->compute_list_begin();3176RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, gi->voxel_gi_lighting_shader_version_pipelines[VOXEL_GI_SHADER_VERSION_DYNAMIC_OBJECT_LIGHTING]);3177RD::get_singleton()->compute_list_bind_uniform_set(compute_list, dynamic_maps[0].uniform_set, 0);3178RD::get_singleton()->compute_list_set_push_constant(compute_list, &push_constant, sizeof(VoxelGIDynamicPushConstant));3179RD::get_singleton()->compute_list_dispatch(compute_list, Math::division_round_up(rect.size.x, 8), Math::division_round_up(rect.size.y, 8), 1);3180//print_line("rect: " + itos(i) + ": " + rect);31813182for (int k = 1; k < dynamic_maps.size(); k++) {3183// enlarge the rect if needed so all pixels fit when downscaled,3184// this ensures downsampling is smooth and optimal because no pixels are left behind31853186//x3187if (rect.position.x & 1) {3188rect.size.x++;3189push_constant.prev_rect_ofs[0] = 1; //this is used to ensure reading is also optimal3190} else {3191push_constant.prev_rect_ofs[0] = 0;3192}3193if (rect.size.x & 1) {3194rect.size.x++;3195}31963197rect.position.x >>= 1;3198rect.size.x = MAX(1, rect.size.x >> 1);31993200//y3201if (rect.position.y & 1) {3202rect.size.y++;3203push_constant.prev_rect_ofs[1] = 1;3204} else {3205push_constant.prev_rect_ofs[1] = 0;3206}3207if (rect.size.y & 1) {3208rect.size.y++;3209}32103211rect.position.y >>= 1;3212rect.size.y = MAX(1, rect.size.y >> 1);32133214//shrink limits to ensure plot does not go outside map3215if (dynamic_maps[k].mipmap > 0) {3216for (int l = 0; l < 3; l++) {3217push_constant.limits[l] = MAX(1, push_constant.limits[l] >> 1);3218}3219}32203221//print_line("rect: " + itos(i) + ": " + rect);3222push_constant.rect_pos[0] = rect.position[0];3223push_constant.rect_pos[1] = rect.position[1];3224push_constant.prev_rect_size[0] = push_constant.rect_size[0];3225push_constant.prev_rect_size[1] = push_constant.rect_size[1];3226push_constant.rect_size[0] = rect.size[0];3227push_constant.rect_size[1] = rect.size[1];3228push_constant.on_mipmap = dynamic_maps[k].mipmap > 0;32293230RD::get_singleton()->compute_list_add_barrier(compute_list);32313232if (dynamic_maps[k].mipmap < 0) {3233RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, gi->voxel_gi_lighting_shader_version_pipelines[VOXEL_GI_SHADER_VERSION_DYNAMIC_SHRINK_WRITE]);3234} else if (k < dynamic_maps.size() - 1) {3235RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, gi->voxel_gi_lighting_shader_version_pipelines[VOXEL_GI_SHADER_VERSION_DYNAMIC_SHRINK_WRITE_PLOT]);3236} else {3237RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, gi->voxel_gi_lighting_shader_version_pipelines[VOXEL_GI_SHADER_VERSION_DYNAMIC_SHRINK_PLOT]);3238}3239RD::get_singleton()->compute_list_bind_uniform_set(compute_list, dynamic_maps[k].uniform_set, 0);3240RD::get_singleton()->compute_list_set_push_constant(compute_list, &push_constant, sizeof(VoxelGIDynamicPushConstant));3241RD::get_singleton()->compute_list_dispatch(compute_list, Math::division_round_up(rect.size.x, 8), Math::division_round_up(rect.size.y, 8), 1);3242}32433244RD::get_singleton()->compute_list_end();3245}3246}32473248has_dynamic_object_data = true; //clear until dynamic object data is used again3249}32503251last_probe_version = gi->voxel_gi_get_version(probe);3252}32533254void GI::VoxelGIInstance::free_resources() {3255if (texture.is_valid()) {3256RD::get_singleton()->free(texture);3257RD::get_singleton()->free(write_buffer);32583259texture = RID();3260write_buffer = RID();3261mipmaps.clear();3262}32633264for (int i = 0; i < dynamic_maps.size(); i++) {3265RD::get_singleton()->free(dynamic_maps[i].texture);3266RD::get_singleton()->free(dynamic_maps[i].depth);32673268// these only exist on the first level...3269if (dynamic_maps[i].fb_depth.is_valid()) {3270RD::get_singleton()->free(dynamic_maps[i].fb_depth);3271}3272if (dynamic_maps[i].albedo.is_valid()) {3273RD::get_singleton()->free(dynamic_maps[i].albedo);3274}3275if (dynamic_maps[i].normal.is_valid()) {3276RD::get_singleton()->free(dynamic_maps[i].normal);3277}3278if (dynamic_maps[i].orm.is_valid()) {3279RD::get_singleton()->free(dynamic_maps[i].orm);3280}3281}3282dynamic_maps.clear();3283}32843285void GI::VoxelGIInstance::debug(RD::DrawListID p_draw_list, RID p_framebuffer, const Projection &p_camera_with_transform, bool p_lighting, bool p_emission, float p_alpha) {3286RendererRD::MaterialStorage *material_storage = RendererRD::MaterialStorage::get_singleton();32873288if (mipmaps.is_empty()) {3289return;3290}32913292Projection cam_transform = (p_camera_with_transform * Projection(transform)) * Projection(gi->voxel_gi_get_to_cell_xform(probe).affine_inverse());32933294int level = 0;3295Vector3i octree_size = gi->voxel_gi_get_octree_size(probe);32963297VoxelGIDebugPushConstant push_constant;3298push_constant.alpha = p_alpha;3299push_constant.dynamic_range = gi->voxel_gi_get_dynamic_range(probe);3300push_constant.cell_offset = mipmaps[level].cell_offset;3301push_constant.level = level;33023303push_constant.bounds[0] = octree_size.x >> level;3304push_constant.bounds[1] = octree_size.y >> level;3305push_constant.bounds[2] = octree_size.z >> level;3306push_constant.pad = 0;33073308for (int i = 0; i < 4; i++) {3309for (int j = 0; j < 4; j++) {3310push_constant.projection[i * 4 + j] = cam_transform.columns[i][j];3311}3312}33133314if (gi->voxel_gi_debug_uniform_set.is_valid()) {3315RD::get_singleton()->free(gi->voxel_gi_debug_uniform_set);3316}3317Vector<RD::Uniform> uniforms;3318{3319RD::Uniform u;3320u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER;3321u.binding = 1;3322u.append_id(gi->voxel_gi_get_data_buffer(probe));3323uniforms.push_back(u);3324}3325{3326RD::Uniform u;3327u.uniform_type = RD::UNIFORM_TYPE_TEXTURE;3328u.binding = 2;3329u.append_id(texture);3330uniforms.push_back(u);3331}3332{3333RD::Uniform u;3334u.uniform_type = RD::UNIFORM_TYPE_SAMPLER;3335u.binding = 3;3336u.append_id(material_storage->sampler_rd_get_default(RS::CANVAS_ITEM_TEXTURE_FILTER_NEAREST, RS::CANVAS_ITEM_TEXTURE_REPEAT_DISABLED));3337uniforms.push_back(u);3338}33393340int cell_count;3341if (!p_emission && p_lighting && has_dynamic_object_data) {3342cell_count = push_constant.bounds[0] * push_constant.bounds[1] * push_constant.bounds[2];3343} else {3344cell_count = mipmaps[level].cell_count;3345}33463347gi->voxel_gi_debug_uniform_set = RD::get_singleton()->uniform_set_create(uniforms, gi->voxel_gi_debug_shader_version_shaders[0], 0);33483349int voxel_gi_debug_pipeline = VOXEL_GI_DEBUG_COLOR;3350if (p_emission) {3351voxel_gi_debug_pipeline = VOXEL_GI_DEBUG_EMISSION;3352} else if (p_lighting) {3353voxel_gi_debug_pipeline = has_dynamic_object_data ? VOXEL_GI_DEBUG_LIGHT_FULL : VOXEL_GI_DEBUG_LIGHT;3354}3355RD::get_singleton()->draw_list_bind_render_pipeline(3356p_draw_list,3357gi->voxel_gi_debug_shader_version_pipelines[voxel_gi_debug_pipeline].get_render_pipeline(RD::INVALID_ID, RD::get_singleton()->framebuffer_get_format(p_framebuffer)));3358RD::get_singleton()->draw_list_bind_uniform_set(p_draw_list, gi->voxel_gi_debug_uniform_set, 0);3359RD::get_singleton()->draw_list_set_push_constant(p_draw_list, &push_constant, sizeof(VoxelGIDebugPushConstant));3360RD::get_singleton()->draw_list_draw(p_draw_list, false, cell_count, 36);3361}33623363////////////////////////////////////////////////////////////////////////////////3364// GI33653366GI::GI() {3367singleton = this;33683369sdfgi_ray_count = RS::EnvironmentSDFGIRayCount(CLAMP(int32_t(GLOBAL_GET("rendering/global_illumination/sdfgi/probe_ray_count")), 0, int32_t(RS::ENV_SDFGI_RAY_COUNT_MAX - 1)));3370sdfgi_frames_to_converge = RS::EnvironmentSDFGIFramesToConverge(CLAMP(int32_t(GLOBAL_GET("rendering/global_illumination/sdfgi/frames_to_converge")), 0, int32_t(RS::ENV_SDFGI_CONVERGE_MAX - 1)));3371sdfgi_frames_to_update_light = RS::EnvironmentSDFGIFramesToUpdateLight(CLAMP(int32_t(GLOBAL_GET("rendering/global_illumination/sdfgi/frames_to_update_lights")), 0, int32_t(RS::ENV_SDFGI_UPDATE_LIGHT_MAX - 1)));3372}33733374GI::~GI() {3375if (voxel_gi_debug_shader_version.is_valid()) {3376voxel_gi_debug_shader.version_free(voxel_gi_debug_shader_version);3377}3378if (voxel_gi_lighting_shader_version.is_valid()) {3379voxel_gi_shader.version_free(voxel_gi_lighting_shader_version);3380}3381if (shader_version.is_valid()) {3382shader.version_free(shader_version);3383}3384if (sdfgi_shader.debug_probes_shader.is_valid()) {3385sdfgi_shader.debug_probes.version_free(sdfgi_shader.debug_probes_shader);3386}3387if (sdfgi_shader.debug_shader.is_valid()) {3388sdfgi_shader.debug.version_free(sdfgi_shader.debug_shader);3389}3390if (sdfgi_shader.direct_light_shader.is_valid()) {3391sdfgi_shader.direct_light.version_free(sdfgi_shader.direct_light_shader);3392}3393if (sdfgi_shader.integrate_shader.is_valid()) {3394sdfgi_shader.integrate.version_free(sdfgi_shader.integrate_shader);3395}3396if (sdfgi_shader.preprocess_shader.is_valid()) {3397sdfgi_shader.preprocess.version_free(sdfgi_shader.preprocess_shader);3398}33993400singleton = nullptr;3401}34023403void GI::init(SkyRD *p_sky) {3404RendererRD::TextureStorage *texture_storage = RendererRD::TextureStorage::get_singleton();3405RendererRD::MaterialStorage *material_storage = RendererRD::MaterialStorage::get_singleton();34063407/* GI */34083409{3410//kinda complicated to compute the amount of slots, we try to use as many as we can34113412voxel_gi_lights = memnew_arr(VoxelGILight, voxel_gi_max_lights);3413voxel_gi_lights_uniform = RD::get_singleton()->uniform_buffer_create(voxel_gi_max_lights * sizeof(VoxelGILight));3414voxel_gi_quality = RS::VoxelGIQuality(CLAMP(int(GLOBAL_GET("rendering/global_illumination/voxel_gi/quality")), 0, 1));34153416String defines = "\n#define MAX_LIGHTS " + itos(voxel_gi_max_lights) + "\n";34173418Vector<String> versions;3419versions.push_back("\n#define MODE_COMPUTE_LIGHT\n");3420versions.push_back("\n#define MODE_SECOND_BOUNCE\n");3421versions.push_back("\n#define MODE_UPDATE_MIPMAPS\n");3422versions.push_back("\n#define MODE_WRITE_TEXTURE\n");3423versions.push_back("\n#define MODE_DYNAMIC\n#define MODE_DYNAMIC_LIGHTING\n");3424versions.push_back("\n#define MODE_DYNAMIC\n#define MODE_DYNAMIC_SHRINK\n#define MODE_DYNAMIC_SHRINK_WRITE\n");3425versions.push_back("\n#define MODE_DYNAMIC\n#define MODE_DYNAMIC_SHRINK\n#define MODE_DYNAMIC_SHRINK_PLOT\n");3426versions.push_back("\n#define MODE_DYNAMIC\n#define MODE_DYNAMIC_SHRINK\n#define MODE_DYNAMIC_SHRINK_PLOT\n#define MODE_DYNAMIC_SHRINK_WRITE\n");34273428voxel_gi_shader.initialize(versions, defines);3429voxel_gi_lighting_shader_version = voxel_gi_shader.version_create();3430for (int i = 0; i < VOXEL_GI_SHADER_VERSION_MAX; i++) {3431voxel_gi_lighting_shader_version_shaders[i] = voxel_gi_shader.version_get_shader(voxel_gi_lighting_shader_version, i);3432voxel_gi_lighting_shader_version_pipelines[i] = RD::get_singleton()->compute_pipeline_create(voxel_gi_lighting_shader_version_shaders[i]);3433}3434}34353436{3437String defines;3438Vector<String> versions;3439versions.push_back("\n#define MODE_DEBUG_COLOR\n");3440versions.push_back("\n#define MODE_DEBUG_LIGHT\n");3441versions.push_back("\n#define MODE_DEBUG_EMISSION\n");3442versions.push_back("\n#define MODE_DEBUG_LIGHT\n#define MODE_DEBUG_LIGHT_FULL\n");34433444voxel_gi_debug_shader.initialize(versions, defines);3445voxel_gi_debug_shader_version = voxel_gi_debug_shader.version_create();3446for (int i = 0; i < VOXEL_GI_DEBUG_MAX; i++) {3447voxel_gi_debug_shader_version_shaders[i] = voxel_gi_debug_shader.version_get_shader(voxel_gi_debug_shader_version, i);34483449RD::PipelineRasterizationState rs;3450rs.cull_mode = RD::POLYGON_CULL_FRONT;3451RD::PipelineDepthStencilState ds;3452ds.enable_depth_test = true;3453ds.enable_depth_write = true;3454ds.depth_compare_operator = RD::COMPARE_OP_GREATER_OR_EQUAL;34553456voxel_gi_debug_shader_version_pipelines[i].setup(voxel_gi_debug_shader_version_shaders[i], RD::RENDER_PRIMITIVE_TRIANGLES, rs, RD::PipelineMultisampleState(), ds, RD::PipelineColorBlendState::create_disabled(), 0);3457}3458}34593460/* SDGFI */34613462{3463Vector<String> preprocess_modes;3464preprocess_modes.push_back("\n#define MODE_SCROLL\n");3465preprocess_modes.push_back("\n#define MODE_SCROLL_OCCLUSION\n");3466preprocess_modes.push_back("\n#define MODE_INITIALIZE_JUMP_FLOOD\n");3467preprocess_modes.push_back("\n#define MODE_INITIALIZE_JUMP_FLOOD_HALF\n");3468preprocess_modes.push_back("\n#define MODE_JUMPFLOOD\n");3469preprocess_modes.push_back("\n#define MODE_JUMPFLOOD_OPTIMIZED\n");3470preprocess_modes.push_back("\n#define MODE_UPSCALE_JUMP_FLOOD\n");3471preprocess_modes.push_back("\n#define MODE_OCCLUSION\n");3472preprocess_modes.push_back("\n#define MODE_STORE\n");3473String defines = "\n#define OCCLUSION_SIZE " + itos(SDFGI::CASCADE_SIZE / SDFGI::PROBE_DIVISOR) + "\n";3474sdfgi_shader.preprocess.initialize(preprocess_modes, defines);3475sdfgi_shader.preprocess_shader = sdfgi_shader.preprocess.version_create();3476for (int i = 0; i < SDFGIShader::PRE_PROCESS_MAX; i++) {3477sdfgi_shader.preprocess_pipeline[i] = RD::get_singleton()->compute_pipeline_create(sdfgi_shader.preprocess.version_get_shader(sdfgi_shader.preprocess_shader, i));3478}3479}34803481{3482//calculate tables3483String defines = "\n#define OCT_SIZE " + itos(SDFGI::LIGHTPROBE_OCT_SIZE) + "\n";34843485Vector<String> direct_light_modes;3486direct_light_modes.push_back("\n#define MODE_PROCESS_STATIC\n");3487direct_light_modes.push_back("\n#define MODE_PROCESS_DYNAMIC\n");3488sdfgi_shader.direct_light.initialize(direct_light_modes, defines);3489sdfgi_shader.direct_light_shader = sdfgi_shader.direct_light.version_create();3490for (int i = 0; i < SDFGIShader::DIRECT_LIGHT_MODE_MAX; i++) {3491sdfgi_shader.direct_light_pipeline[i] = RD::get_singleton()->compute_pipeline_create(sdfgi_shader.direct_light.version_get_shader(sdfgi_shader.direct_light_shader, i));3492}3493}34943495{3496//calculate tables3497String defines = "\n#define OCT_SIZE " + itos(SDFGI::LIGHTPROBE_OCT_SIZE) + "\n";3498defines += "\n#define SH_SIZE " + itos(SDFGI::SH_SIZE) + "\n";3499if (p_sky->sky_use_cubemap_array) {3500defines += "\n#define USE_CUBEMAP_ARRAY\n";3501}35023503Vector<String> integrate_modes;3504integrate_modes.push_back("\n#define MODE_PROCESS\n");3505integrate_modes.push_back("\n#define MODE_STORE\n");3506integrate_modes.push_back("\n#define MODE_SCROLL\n");3507integrate_modes.push_back("\n#define MODE_SCROLL_STORE\n");3508sdfgi_shader.integrate.initialize(integrate_modes, defines);3509sdfgi_shader.integrate_shader = sdfgi_shader.integrate.version_create();35103511for (int i = 0; i < SDFGIShader::INTEGRATE_MODE_MAX; i++) {3512sdfgi_shader.integrate_pipeline[i] = RD::get_singleton()->compute_pipeline_create(sdfgi_shader.integrate.version_get_shader(sdfgi_shader.integrate_shader, i));3513}35143515{3516Vector<RD::Uniform> uniforms;35173518{3519RD::Uniform u;3520u.uniform_type = RD::UNIFORM_TYPE_TEXTURE;3521u.binding = 0;3522if (p_sky->sky_use_cubemap_array) {3523u.append_id(texture_storage->texture_rd_get_default(RendererRD::TextureStorage::DEFAULT_RD_TEXTURE_CUBEMAP_ARRAY_WHITE));3524} else {3525u.append_id(texture_storage->texture_rd_get_default(RendererRD::TextureStorage::DEFAULT_RD_TEXTURE_CUBEMAP_WHITE));3526}3527uniforms.push_back(u);3528}3529{3530RD::Uniform u;3531u.uniform_type = RD::UNIFORM_TYPE_SAMPLER;3532u.binding = 1;3533u.append_id(material_storage->sampler_rd_get_default(RS::CANVAS_ITEM_TEXTURE_FILTER_LINEAR_WITH_MIPMAPS, RS::CANVAS_ITEM_TEXTURE_REPEAT_DISABLED));3534uniforms.push_back(u);3535}35363537sdfgi_shader.integrate_default_sky_uniform_set = RD::get_singleton()->uniform_set_create(uniforms, sdfgi_shader.integrate.version_get_shader(sdfgi_shader.integrate_shader, 0), 1);3538}3539}35403541//GK3542{3543//calculate tables3544String defines = "\n#define SDFGI_OCT_SIZE " + itos(SDFGI::LIGHTPROBE_OCT_SIZE) + "\n";35453546Vector<ShaderRD::VariantDefine> variants;3547for (uint32_t vrs = 0; vrs < 2; vrs++) {3548String vrs_base = vrs ? "\n#define USE_VRS\n" : "";3549Group group = vrs ? GROUP_VRS : GROUP_NORMAL;3550bool default_enabled = vrs == 0;3551variants.push_back(ShaderRD::VariantDefine(group, vrs_base + "\n#define USE_VOXEL_GI_INSTANCES\n", default_enabled)); // MODE_VOXEL_GI3552variants.push_back(ShaderRD::VariantDefine(group, vrs_base + "\n#define USE_VOXEL_GI_INSTANCES\n#define SAMPLE_VOXEL_GI_NEAREST\n", default_enabled)); // MODE_VOXEL_GI_WITHOUT_SAMPLER3553variants.push_back(ShaderRD::VariantDefine(group, vrs_base + "\n#define USE_SDFGI\n", default_enabled)); // MODE_SDFGI3554variants.push_back(ShaderRD::VariantDefine(group, vrs_base + "\n#define USE_SDFGI\n\n#define USE_VOXEL_GI_INSTANCES\n", default_enabled)); // MODE_COMBINED3555variants.push_back(ShaderRD::VariantDefine(group, vrs_base + "\n#define USE_SDFGI\n\n#define USE_VOXEL_GI_INSTANCES\n#define SAMPLE_VOXEL_GI_NEAREST\n", default_enabled)); // MODE_COMBINED_WITHOUT_SAMPLER3556}35573558shader.initialize(variants, defines);35593560bool vrs_supported = RendererSceneRenderRD::get_singleton()->is_vrs_supported();3561if (vrs_supported) {3562shader.enable_group(GROUP_VRS);3563}35643565shader_version = shader.version_create();35663567Vector<RD::PipelineSpecializationConstant> specialization_constants;35683569{3570RD::PipelineSpecializationConstant sc;3571sc.type = RD::PIPELINE_SPECIALIZATION_CONSTANT_TYPE_BOOL;3572sc.constant_id = 0; // SHADER_SPECIALIZATION_HALF_RES3573sc.bool_value = false;3574specialization_constants.push_back(sc);35753576sc.type = RD::PIPELINE_SPECIALIZATION_CONSTANT_TYPE_BOOL;3577sc.constant_id = 1; // SHADER_SPECIALIZATION_USE_FULL_PROJECTION_MATRIX3578sc.bool_value = false;3579specialization_constants.push_back(sc);35803581sc.type = RD::PIPELINE_SPECIALIZATION_CONSTANT_TYPE_BOOL;3582sc.constant_id = 2; // SHADER_SPECIALIZATION_USE_VRS3583sc.bool_value = false;3584specialization_constants.push_back(sc);3585}35863587for (int v = 0; v < SHADER_SPECIALIZATION_VARIATIONS; v++) {3588specialization_constants.ptrw()[0].bool_value = (v & SHADER_SPECIALIZATION_HALF_RES) ? true : false;3589specialization_constants.ptrw()[1].bool_value = (v & SHADER_SPECIALIZATION_USE_FULL_PROJECTION_MATRIX) ? true : false;3590specialization_constants.ptrw()[2].bool_value = (v & SHADER_SPECIALIZATION_USE_VRS) ? true : false;35913592int variant_base = vrs_supported ? MODE_MAX : 0;3593for (int i = 0; i < MODE_MAX; i++) {3594pipelines[v][i] = RD::get_singleton()->compute_pipeline_create(shader.version_get_shader(shader_version, variant_base + i), specialization_constants);3595}3596}35973598sdfgi_ubo = RD::get_singleton()->uniform_buffer_create(sizeof(SDFGIData));3599}3600{3601String defines = "\n#define OCT_SIZE " + itos(SDFGI::LIGHTPROBE_OCT_SIZE) + "\n";3602Vector<String> debug_modes;3603debug_modes.push_back("");3604sdfgi_shader.debug.initialize(debug_modes, defines);3605sdfgi_shader.debug_shader = sdfgi_shader.debug.version_create();3606sdfgi_shader.debug_shader_version = sdfgi_shader.debug.version_get_shader(sdfgi_shader.debug_shader, 0);3607sdfgi_shader.debug_pipeline = RD::get_singleton()->compute_pipeline_create(sdfgi_shader.debug_shader_version);3608}3609{3610String defines = "\n#define OCT_SIZE " + itos(SDFGI::LIGHTPROBE_OCT_SIZE) + "\n";36113612Vector<String> versions;3613versions.push_back("\n#define MODE_PROBES\n");3614versions.push_back("\n#define MODE_PROBES\n#define USE_MULTIVIEW\n");3615versions.push_back("\n#define MODE_VISIBILITY\n");3616versions.push_back("\n#define MODE_VISIBILITY\n#define USE_MULTIVIEW\n");36173618sdfgi_shader.debug_probes.initialize(versions, defines);36193620// TODO disable multiview versions if turned off36213622sdfgi_shader.debug_probes_shader = sdfgi_shader.debug_probes.version_create();36233624{3625RD::PipelineRasterizationState rs;3626rs.cull_mode = RD::POLYGON_CULL_DISABLED;3627RD::PipelineDepthStencilState ds;3628ds.enable_depth_test = true;3629ds.enable_depth_write = true;3630ds.depth_compare_operator = RD::COMPARE_OP_GREATER_OR_EQUAL;3631for (int i = 0; i < SDFGIShader::PROBE_DEBUG_MAX; i++) {3632// TODO check if version is enabled36333634RID debug_probes_shader_version = sdfgi_shader.debug_probes.version_get_shader(sdfgi_shader.debug_probes_shader, i);3635sdfgi_shader.debug_probes_pipeline[i].setup(debug_probes_shader_version, RD::RENDER_PRIMITIVE_TRIANGLE_STRIPS, rs, RD::PipelineMultisampleState(), ds, RD::PipelineColorBlendState::create_disabled(), 0);3636}3637}3638}3639default_voxel_gi_buffer = RD::get_singleton()->uniform_buffer_create(sizeof(VoxelGIData) * MAX_VOXEL_GI_INSTANCES);3640half_resolution = GLOBAL_GET("rendering/global_illumination/gi/use_half_resolution");3641}36423643void GI::free() {3644if (default_voxel_gi_buffer.is_valid()) {3645RD::get_singleton()->free(default_voxel_gi_buffer);3646}3647if (voxel_gi_lights_uniform.is_valid()) {3648RD::get_singleton()->free(voxel_gi_lights_uniform);3649}3650if (sdfgi_ubo.is_valid()) {3651RD::get_singleton()->free(sdfgi_ubo);3652}36533654if (voxel_gi_lights) {3655memdelete_arr(voxel_gi_lights);3656}3657}36583659Ref<GI::SDFGI> GI::create_sdfgi(RID p_env, const Vector3 &p_world_position, uint32_t p_requested_history_size) {3660Ref<SDFGI> sdfgi;3661sdfgi.instantiate();36623663sdfgi->create(p_env, p_world_position, p_requested_history_size, this);36643665return sdfgi;3666}36673668void GI::setup_voxel_gi_instances(RenderDataRD *p_render_data, Ref<RenderSceneBuffersRD> p_render_buffers, const Transform3D &p_transform, const PagedArray<RID> &p_voxel_gi_instances, uint32_t &r_voxel_gi_instances_used) {3669ERR_FAIL_COND(p_render_buffers.is_null());36703671RendererRD::TextureStorage *texture_storage = RendererRD::TextureStorage::get_singleton();3672ERR_FAIL_NULL(texture_storage);36733674r_voxel_gi_instances_used = 0;36753676Ref<RenderBuffersGI> rbgi = p_render_buffers->get_custom_data(RB_SCOPE_GI);3677ERR_FAIL_COND(rbgi.is_null());36783679RID voxel_gi_buffer = rbgi->get_voxel_gi_buffer();3680VoxelGIData voxel_gi_data[MAX_VOXEL_GI_INSTANCES];36813682bool voxel_gi_instances_changed = false;36833684Transform3D to_camera;3685to_camera.origin = p_transform.origin; //only translation, make local36863687for (int i = 0; i < MAX_VOXEL_GI_INSTANCES; i++) {3688RID texture;3689if (i < (int)p_voxel_gi_instances.size()) {3690VoxelGIInstance *gipi = voxel_gi_instance_owner.get_or_null(p_voxel_gi_instances[i]);36913692if (gipi) {3693texture = gipi->texture;3694VoxelGIData &gipd = voxel_gi_data[i];36953696RID base_probe = gipi->probe;36973698Transform3D to_cell = voxel_gi_get_to_cell_xform(gipi->probe) * gipi->transform.affine_inverse() * to_camera;36993700gipd.xform[0] = to_cell.basis.rows[0][0];3701gipd.xform[1] = to_cell.basis.rows[1][0];3702gipd.xform[2] = to_cell.basis.rows[2][0];3703gipd.xform[3] = 0;3704gipd.xform[4] = to_cell.basis.rows[0][1];3705gipd.xform[5] = to_cell.basis.rows[1][1];3706gipd.xform[6] = to_cell.basis.rows[2][1];3707gipd.xform[7] = 0;3708gipd.xform[8] = to_cell.basis.rows[0][2];3709gipd.xform[9] = to_cell.basis.rows[1][2];3710gipd.xform[10] = to_cell.basis.rows[2][2];3711gipd.xform[11] = 0;3712gipd.xform[12] = to_cell.origin.x;3713gipd.xform[13] = to_cell.origin.y;3714gipd.xform[14] = to_cell.origin.z;3715gipd.xform[15] = 1;37163717Vector3 bounds = voxel_gi_get_octree_size(base_probe);37183719gipd.bounds[0] = bounds.x;3720gipd.bounds[1] = bounds.y;3721gipd.bounds[2] = bounds.z;37223723gipd.dynamic_range = voxel_gi_get_dynamic_range(base_probe) * voxel_gi_get_energy(base_probe);3724gipd.bias = voxel_gi_get_bias(base_probe);3725gipd.normal_bias = voxel_gi_get_normal_bias(base_probe);3726gipd.blend_ambient = !voxel_gi_is_interior(base_probe);3727gipd.mipmaps = gipi->mipmaps.size();3728gipd.exposure_normalization = 1.0;3729if (p_render_data->camera_attributes.is_valid()) {3730float exposure_normalization = RSG::camera_attributes->camera_attributes_get_exposure_normalization_factor(p_render_data->camera_attributes);3731gipd.exposure_normalization = exposure_normalization / voxel_gi_get_baked_exposure_normalization(base_probe);3732}3733}37343735r_voxel_gi_instances_used++;3736}37373738if (texture == RID()) {3739texture = texture_storage->texture_rd_get_default(RendererRD::TextureStorage::DEFAULT_RD_TEXTURE_3D_WHITE);3740}37413742if (texture != rbgi->voxel_gi_textures[i]) {3743voxel_gi_instances_changed = true;3744rbgi->voxel_gi_textures[i] = texture;3745}3746}37473748if (voxel_gi_instances_changed) {3749for (uint32_t v = 0; v < RendererSceneRender::MAX_RENDER_VIEWS; v++) {3750if (RD::get_singleton()->uniform_set_is_valid(rbgi->uniform_set[v])) {3751RD::get_singleton()->free(rbgi->uniform_set[v]);3752}3753rbgi->uniform_set[v] = RID();3754}37553756if (p_render_buffers->has_custom_data(RB_SCOPE_FOG)) {3757// VoxelGI instances have changed, so we need to update volumetric fog.3758Ref<RendererRD::Fog::VolumetricFog> fog = p_render_buffers->get_custom_data(RB_SCOPE_FOG);3759fog->sync_gi_dependent_sets_validity(true);3760}3761}37623763if (p_voxel_gi_instances.size() > 0) {3764RD::get_singleton()->draw_command_begin_label("VoxelGIs Setup");37653766RD::get_singleton()->buffer_update(voxel_gi_buffer, 0, sizeof(VoxelGIData) * MIN((uint64_t)MAX_VOXEL_GI_INSTANCES, p_voxel_gi_instances.size()), voxel_gi_data);37673768RD::get_singleton()->draw_command_end_label();3769}3770}37713772RID GI::RenderBuffersGI::get_voxel_gi_buffer() {3773if (voxel_gi_buffer.is_null()) {3774voxel_gi_buffer = RD::get_singleton()->uniform_buffer_create(sizeof(GI::VoxelGIData) * GI::MAX_VOXEL_GI_INSTANCES);3775}3776return voxel_gi_buffer;3777}37783779void GI::RenderBuffersGI::free_data() {3780for (uint32_t v = 0; v < RendererSceneRender::MAX_RENDER_VIEWS; v++) {3781if (RD::get_singleton()->uniform_set_is_valid(uniform_set[v])) {3782RD::get_singleton()->free(uniform_set[v]);3783}3784uniform_set[v] = RID();3785}37863787if (scene_data_ubo.is_valid()) {3788RD::get_singleton()->free(scene_data_ubo);3789scene_data_ubo = RID();3790}37913792if (voxel_gi_buffer.is_valid()) {3793RD::get_singleton()->free(voxel_gi_buffer);3794voxel_gi_buffer = RID();3795}3796}37973798void GI::process_gi(Ref<RenderSceneBuffersRD> p_render_buffers, const RID *p_normal_roughness_slices, RID p_voxel_gi_buffer, RID p_environment, uint32_t p_view_count, const Projection *p_projections, const Vector3 *p_eye_offsets, const Transform3D &p_cam_transform, const PagedArray<RID> &p_voxel_gi_instances) {3799RendererRD::TextureStorage *texture_storage = RendererRD::TextureStorage::get_singleton();3800RendererRD::MaterialStorage *material_storage = RendererRD::MaterialStorage::get_singleton();38013802ERR_FAIL_COND_MSG(p_view_count > 2, "Maximum of 2 views supported for Processing GI.");38033804RD::get_singleton()->draw_command_begin_label("GI Render");38053806ERR_FAIL_COND(p_render_buffers.is_null());38073808Ref<RenderBuffersGI> rbgi = p_render_buffers->get_custom_data(RB_SCOPE_GI);3809ERR_FAIL_COND(rbgi.is_null());38103811Size2i internal_size = p_render_buffers->get_internal_size();38123813if (rbgi->using_half_size_gi != half_resolution) {3814p_render_buffers->clear_context(RB_SCOPE_GI);3815}38163817if (!p_render_buffers->has_texture(RB_SCOPE_GI, RB_TEX_AMBIENT)) {3818Size2i size = internal_size;3819uint32_t usage_bits = RD::TEXTURE_USAGE_SAMPLING_BIT | RD::TEXTURE_USAGE_STORAGE_BIT;38203821if (half_resolution) {3822size.x >>= 1;3823size.y >>= 1;3824}38253826p_render_buffers->create_texture(RB_SCOPE_GI, RB_TEX_AMBIENT, RD::DATA_FORMAT_R16G16B16A16_SFLOAT, usage_bits, RD::TEXTURE_SAMPLES_1, size);3827p_render_buffers->create_texture(RB_SCOPE_GI, RB_TEX_REFLECTION, RD::DATA_FORMAT_R16G16B16A16_SFLOAT, usage_bits, RD::TEXTURE_SAMPLES_1, size);38283829rbgi->using_half_size_gi = half_resolution;3830}38313832// Setup our scene data3833{3834SceneData scene_data;38353836if (rbgi->scene_data_ubo.is_null()) {3837rbgi->scene_data_ubo = RD::get_singleton()->uniform_buffer_create(sizeof(SceneData));3838}38393840Projection correction;3841correction.set_depth_correction(false);38423843for (uint32_t v = 0; v < p_view_count; v++) {3844Projection temp = correction * p_projections[v];38453846RendererRD::MaterialStorage::store_camera(temp.inverse(), scene_data.inv_projection[v]);3847scene_data.eye_offset[v][0] = p_eye_offsets[v].x;3848scene_data.eye_offset[v][1] = p_eye_offsets[v].y;3849scene_data.eye_offset[v][2] = p_eye_offsets[v].z;3850scene_data.eye_offset[v][3] = 0.0;3851}38523853// Note that we will be ignoring the origin of this transform.3854RendererRD::MaterialStorage::store_transform(p_cam_transform, scene_data.cam_transform);38553856scene_data.screen_size[0] = internal_size.x;3857scene_data.screen_size[1] = internal_size.y;38583859RD::get_singleton()->buffer_update(rbgi->scene_data_ubo, 0, sizeof(SceneData), &scene_data);3860}38613862// Now compute the contents of our buffers.3863RD::ComputeListID compute_list = RD::get_singleton()->compute_list_begin();38643865// Render each eye separately.3866// We need to look into whether we can make our compute shader use Multiview but not sure that works or makes a difference..38673868// setup our push constant38693870PushConstant push_constant;38713872push_constant.max_voxel_gi_instances = MIN((uint64_t)MAX_VOXEL_GI_INSTANCES, p_voxel_gi_instances.size());3873push_constant.high_quality_vct = voxel_gi_quality == RS::VOXEL_GI_QUALITY_HIGH;38743875// these should be the same for all views3876push_constant.orthogonal = p_projections[0].is_orthogonal();3877push_constant.z_near = p_projections[0].get_z_near();3878push_constant.z_far = p_projections[0].get_z_far();38793880// these are only used if we have 1 view, else we use the projections in our scene data3881push_constant.proj_info[0] = -2.0f / (internal_size.x * p_projections[0].columns[0][0]);3882push_constant.proj_info[1] = -2.0f / (internal_size.y * p_projections[0].columns[1][1]);3883push_constant.proj_info[2] = (1.0f - p_projections[0].columns[0][2]) / p_projections[0].columns[0][0];3884push_constant.proj_info[3] = (1.0f + p_projections[0].columns[1][2]) / p_projections[0].columns[1][1];38853886bool use_sdfgi = p_render_buffers->has_custom_data(RB_SCOPE_SDFGI);3887bool use_voxel_gi_instances = push_constant.max_voxel_gi_instances > 0;38883889Ref<SDFGI> sdfgi;3890if (use_sdfgi) {3891sdfgi = p_render_buffers->get_custom_data(RB_SCOPE_SDFGI);3892}38933894uint32_t pipeline_specialization = 0;3895if (rbgi->using_half_size_gi) {3896pipeline_specialization |= SHADER_SPECIALIZATION_HALF_RES;3897}3898if (p_view_count > 1) {3899pipeline_specialization |= SHADER_SPECIALIZATION_USE_FULL_PROJECTION_MATRIX;3900}3901bool has_vrs_texture = p_render_buffers->has_texture(RB_SCOPE_VRS, RB_TEXTURE);3902if (has_vrs_texture) {3903pipeline_specialization |= SHADER_SPECIALIZATION_USE_VRS;3904}39053906bool without_sampler = RD::get_singleton()->sampler_is_format_supported_for_filter(RD::DATA_FORMAT_R8G8_UINT, RD::SAMPLER_FILTER_LINEAR);3907Mode mode;3908if (use_sdfgi && use_voxel_gi_instances) {3909mode = without_sampler ? MODE_COMBINED_WITHOUT_SAMPLER : MODE_COMBINED;3910} else if (use_sdfgi) {3911mode = MODE_SDFGI;3912} else {3913mode = without_sampler ? MODE_VOXEL_GI_WITHOUT_SAMPLER : MODE_VOXEL_GI;3914}39153916for (uint32_t v = 0; v < p_view_count; v++) {3917push_constant.view_index = v;39183919// setup our uniform set3920if (rbgi->uniform_set[v].is_null() || !RD::get_singleton()->uniform_set_is_valid(rbgi->uniform_set[v])) {3921Vector<RD::Uniform> uniforms;3922{3923RD::Uniform u;3924u.binding = 1;3925u.uniform_type = RD::UNIFORM_TYPE_TEXTURE;3926for (uint32_t j = 0; j < SDFGI::MAX_CASCADES; j++) {3927if (use_sdfgi && j < sdfgi->cascades.size()) {3928u.append_id(sdfgi->cascades[j].sdf_tex);3929} else {3930u.append_id(texture_storage->texture_rd_get_default(RendererRD::TextureStorage::DEFAULT_RD_TEXTURE_3D_WHITE));3931}3932}3933uniforms.push_back(u);3934}3935{3936RD::Uniform u;3937u.binding = 2;3938u.uniform_type = RD::UNIFORM_TYPE_TEXTURE;3939for (uint32_t j = 0; j < SDFGI::MAX_CASCADES; j++) {3940if (use_sdfgi && j < sdfgi->cascades.size()) {3941u.append_id(sdfgi->cascades[j].light_tex);3942} else {3943u.append_id(texture_storage->texture_rd_get_default(RendererRD::TextureStorage::DEFAULT_RD_TEXTURE_3D_WHITE));3944}3945}3946uniforms.push_back(u);3947}3948{3949RD::Uniform u;3950u.binding = 3;3951u.uniform_type = RD::UNIFORM_TYPE_TEXTURE;3952for (uint32_t j = 0; j < SDFGI::MAX_CASCADES; j++) {3953if (use_sdfgi && j < sdfgi->cascades.size()) {3954u.append_id(sdfgi->cascades[j].light_aniso_0_tex);3955} else {3956u.append_id(texture_storage->texture_rd_get_default(RendererRD::TextureStorage::DEFAULT_RD_TEXTURE_3D_WHITE));3957}3958}3959uniforms.push_back(u);3960}3961{3962RD::Uniform u;3963u.binding = 4;3964u.uniform_type = RD::UNIFORM_TYPE_TEXTURE;3965for (uint32_t j = 0; j < SDFGI::MAX_CASCADES; j++) {3966if (use_sdfgi && j < sdfgi->cascades.size()) {3967u.append_id(sdfgi->cascades[j].light_aniso_1_tex);3968} else {3969u.append_id(texture_storage->texture_rd_get_default(RendererRD::TextureStorage::DEFAULT_RD_TEXTURE_3D_WHITE));3970}3971}3972uniforms.push_back(u);3973}3974{3975RD::Uniform u;3976u.uniform_type = RD::UNIFORM_TYPE_TEXTURE;3977u.binding = 5;3978if (use_sdfgi) {3979u.append_id(sdfgi->occlusion_texture);3980} else {3981u.append_id(texture_storage->texture_rd_get_default(RendererRD::TextureStorage::DEFAULT_RD_TEXTURE_3D_WHITE));3982}3983uniforms.push_back(u);3984}3985{3986RD::Uniform u;3987u.uniform_type = RD::UNIFORM_TYPE_SAMPLER;3988u.binding = 6;3989u.append_id(material_storage->sampler_rd_get_default(RS::CANVAS_ITEM_TEXTURE_FILTER_LINEAR, RS::CANVAS_ITEM_TEXTURE_REPEAT_DISABLED));3990uniforms.push_back(u);3991}3992{3993RD::Uniform u;3994u.uniform_type = RD::UNIFORM_TYPE_SAMPLER;3995u.binding = 7;3996u.append_id(material_storage->sampler_rd_get_default(RS::CANVAS_ITEM_TEXTURE_FILTER_LINEAR_WITH_MIPMAPS, RS::CANVAS_ITEM_TEXTURE_REPEAT_DISABLED));3997uniforms.push_back(u);3998}3999{4000RD::Uniform u;4001u.uniform_type = RD::UNIFORM_TYPE_IMAGE;4002u.binding = 9;4003u.append_id(p_render_buffers->get_texture_slice(RB_SCOPE_GI, RB_TEX_AMBIENT, v, 0));4004uniforms.push_back(u);4005}40064007{4008RD::Uniform u;4009u.uniform_type = RD::UNIFORM_TYPE_IMAGE;4010u.binding = 10;4011u.append_id(p_render_buffers->get_texture_slice(RB_SCOPE_GI, RB_TEX_REFLECTION, v, 0));4012uniforms.push_back(u);4013}40144015{4016RD::Uniform u;4017u.uniform_type = RD::UNIFORM_TYPE_TEXTURE;4018u.binding = 11;4019if (use_sdfgi) {4020u.append_id(sdfgi->lightprobe_texture);4021} else {4022u.append_id(texture_storage->texture_rd_get_default(RendererRD::TextureStorage::DEFAULT_RD_TEXTURE_2D_ARRAY_WHITE));4023}4024uniforms.push_back(u);4025}4026{4027RD::Uniform u;4028u.uniform_type = RD::UNIFORM_TYPE_TEXTURE;4029u.binding = 12;4030u.append_id(p_render_buffers->get_depth_texture(v));4031uniforms.push_back(u);4032}4033{4034RD::Uniform u;4035u.uniform_type = RD::UNIFORM_TYPE_TEXTURE;4036u.binding = 13;4037u.append_id(p_normal_roughness_slices[v]);4038uniforms.push_back(u);4039}4040{4041RD::Uniform u;4042u.uniform_type = RD::UNIFORM_TYPE_TEXTURE;4043u.binding = 14;4044RID buffer = p_voxel_gi_buffer.is_valid() ? p_voxel_gi_buffer : texture_storage->texture_rd_get_default(RendererRD::TextureStorage::DEFAULT_RD_TEXTURE_BLACK);4045u.append_id(buffer);4046uniforms.push_back(u);4047}4048{4049RD::Uniform u;4050u.uniform_type = RD::UNIFORM_TYPE_UNIFORM_BUFFER;4051u.binding = 15;4052u.append_id(sdfgi_ubo);4053uniforms.push_back(u);4054}4055{4056RD::Uniform u;4057u.uniform_type = RD::UNIFORM_TYPE_UNIFORM_BUFFER;4058u.binding = 16;4059u.append_id(rbgi->get_voxel_gi_buffer());4060uniforms.push_back(u);4061}4062{4063RD::Uniform u;4064u.uniform_type = RD::UNIFORM_TYPE_TEXTURE;4065u.binding = 17;4066for (int i = 0; i < MAX_VOXEL_GI_INSTANCES; i++) {4067u.append_id(rbgi->voxel_gi_textures[i]);4068}4069uniforms.push_back(u);4070}4071{4072RD::Uniform u;4073u.uniform_type = RD::UNIFORM_TYPE_UNIFORM_BUFFER;4074u.binding = 18;4075u.append_id(rbgi->scene_data_ubo);4076uniforms.push_back(u);4077}4078if (RendererSceneRenderRD::get_singleton()->is_vrs_supported()) {4079RD::Uniform u;4080u.uniform_type = RD::UNIFORM_TYPE_IMAGE;4081u.binding = 19;4082RID buffer = has_vrs_texture ? p_render_buffers->get_texture_slice(RB_SCOPE_VRS, RB_TEXTURE, v, 0) : texture_storage->texture_rd_get_default(RendererRD::TextureStorage::DEFAULT_RD_TEXTURE_VRS);4083u.append_id(buffer);4084uniforms.push_back(u);4085}40864087bool vrs_supported = RendererSceneRenderRD::get_singleton()->is_vrs_supported();4088int variant_base = vrs_supported ? MODE_MAX : 0;4089rbgi->uniform_set[v] = RD::get_singleton()->uniform_set_create(uniforms, shader.version_get_shader(shader_version, variant_base), 0);4090}40914092RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, pipelines[pipeline_specialization][mode]);4093RD::get_singleton()->compute_list_bind_uniform_set(compute_list, rbgi->uniform_set[v], 0);4094RD::get_singleton()->compute_list_set_push_constant(compute_list, &push_constant, sizeof(PushConstant));40954096if (rbgi->using_half_size_gi) {4097RD::get_singleton()->compute_list_dispatch_threads(compute_list, internal_size.x >> 1, internal_size.y >> 1, 1);4098} else {4099RD::get_singleton()->compute_list_dispatch_threads(compute_list, internal_size.x, internal_size.y, 1);4100}4101}41024103RD::get_singleton()->compute_list_end();4104RD::get_singleton()->draw_command_end_label();4105}41064107RID GI::voxel_gi_instance_create(RID p_base) {4108VoxelGIInstance voxel_gi;4109voxel_gi.gi = this;4110voxel_gi.probe = p_base;4111RID rid = voxel_gi_instance_owner.make_rid(voxel_gi);4112return rid;4113}41144115void GI::voxel_gi_instance_free(RID p_rid) {4116GI::VoxelGIInstance *voxel_gi = voxel_gi_instance_owner.get_or_null(p_rid);4117voxel_gi->free_resources();4118voxel_gi_instance_owner.free(p_rid);4119}41204121void GI::voxel_gi_instance_set_transform_to_data(RID p_probe, const Transform3D &p_xform) {4122VoxelGIInstance *voxel_gi = voxel_gi_instance_owner.get_or_null(p_probe);4123ERR_FAIL_NULL(voxel_gi);41244125voxel_gi->transform = p_xform;4126}41274128bool GI::voxel_gi_needs_update(RID p_probe) const {4129VoxelGIInstance *voxel_gi = voxel_gi_instance_owner.get_or_null(p_probe);4130ERR_FAIL_NULL_V(voxel_gi, false);41314132return voxel_gi->last_probe_version != voxel_gi_get_version(voxel_gi->probe);4133}41344135void GI::voxel_gi_update(RID p_probe, bool p_update_light_instances, const Vector<RID> &p_light_instances, const PagedArray<RenderGeometryInstance *> &p_dynamic_objects) {4136VoxelGIInstance *voxel_gi = voxel_gi_instance_owner.get_or_null(p_probe);4137ERR_FAIL_NULL(voxel_gi);41384139voxel_gi->update(p_update_light_instances, p_light_instances, p_dynamic_objects);4140}41414142void GI::debug_voxel_gi(RID p_voxel_gi, RD::DrawListID p_draw_list, RID p_framebuffer, const Projection &p_camera_with_transform, bool p_lighting, bool p_emission, float p_alpha) {4143VoxelGIInstance *voxel_gi = voxel_gi_instance_owner.get_or_null(p_voxel_gi);4144ERR_FAIL_NULL(voxel_gi);41454146voxel_gi->debug(p_draw_list, p_framebuffer, p_camera_with_transform, p_lighting, p_emission, p_alpha);4147}41484149void GI::enable_vrs_shader_group() {4150shader.enable_group(GROUP_VRS);4151}415241534154