Path: blob/master/servers/rendering/renderer_rd/environment/gi.cpp
20784 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 "core/math/geometry_3d.h"34#include "servers/rendering/renderer_rd/renderer_compositor_rd.h"35#include "servers/rendering/renderer_rd/renderer_scene_render_rd.h"36#include "servers/rendering/renderer_rd/storage_rd/material_storage.h"37#include "servers/rendering/renderer_rd/storage_rd/render_scene_buffers_rd.h"38#include "servers/rendering/renderer_rd/storage_rd/texture_storage.h"39#include "servers/rendering/rendering_server_default.h"4041using namespace RendererRD;4243const Vector3i GI::SDFGI::Cascade::DIRTY_ALL = Vector3i(0x7FFFFFFF, 0x7FFFFFFF, 0x7FFFFFFF);4445GI *GI::singleton = nullptr;4647////////////////////////////////////////////////////////////////////////////////48// VOXEL GI STORAGE4950RID GI::voxel_gi_allocate() {51return voxel_gi_owner.allocate_rid();52}5354void GI::voxel_gi_free(RID p_voxel_gi) {55voxel_gi_allocate_data(p_voxel_gi, Transform3D(), AABB(), Vector3i(), Vector<uint8_t>(), Vector<uint8_t>(), Vector<uint8_t>(), Vector<int>()); //deallocate56VoxelGI *voxel_gi = voxel_gi_owner.get_or_null(p_voxel_gi);57voxel_gi->dependency.deleted_notify(p_voxel_gi);58voxel_gi_owner.free(p_voxel_gi);59}6061void GI::voxel_gi_initialize(RID p_voxel_gi) {62voxel_gi_owner.initialize_rid(p_voxel_gi, VoxelGI());63}6465void 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) {66VoxelGI *voxel_gi = voxel_gi_owner.get_or_null(p_voxel_gi);67ERR_FAIL_NULL(voxel_gi);6869if (voxel_gi->octree_buffer.is_valid()) {70RD::get_singleton()->free_rid(voxel_gi->octree_buffer);71RD::get_singleton()->free_rid(voxel_gi->data_buffer);72if (voxel_gi->sdf_texture.is_valid()) {73RD::get_singleton()->free_rid(voxel_gi->sdf_texture);74}7576voxel_gi->sdf_texture = RID();77voxel_gi->octree_buffer = RID();78voxel_gi->data_buffer = RID();79voxel_gi->octree_buffer_size = 0;80voxel_gi->data_buffer_size = 0;81voxel_gi->cell_count = 0;82}8384voxel_gi->to_cell_xform = p_to_cell_xform;85voxel_gi->bounds = p_aabb;86voxel_gi->octree_size = p_octree_size;87voxel_gi->level_counts = p_level_counts;8889if (p_octree_cells.size()) {90ERR_FAIL_COND(p_octree_cells.size() % 32 != 0); //cells size must be a multiple of 329192uint32_t cell_count = p_octree_cells.size() / 32;9394ERR_FAIL_COND(p_data_cells.size() != (int)cell_count * 16); //see that data size matches9596voxel_gi->cell_count = cell_count;97voxel_gi->octree_buffer = RD::get_singleton()->storage_buffer_create(p_octree_cells.size(), p_octree_cells);98voxel_gi->octree_buffer_size = p_octree_cells.size();99voxel_gi->data_buffer = RD::get_singleton()->storage_buffer_create(p_data_cells.size(), p_data_cells);100voxel_gi->data_buffer_size = p_data_cells.size();101102if (p_distance_field.size()) {103RD::TextureFormat tf;104tf.format = RD::DATA_FORMAT_R8_UNORM;105tf.width = voxel_gi->octree_size.x;106tf.height = voxel_gi->octree_size.y;107tf.depth = voxel_gi->octree_size.z;108tf.texture_type = RD::TEXTURE_TYPE_3D;109tf.usage_bits = RD::TEXTURE_USAGE_SAMPLING_BIT | RD::TEXTURE_USAGE_CAN_UPDATE_BIT | RD::TEXTURE_USAGE_CAN_COPY_FROM_BIT;110Vector<Vector<uint8_t>> s;111s.push_back(p_distance_field);112voxel_gi->sdf_texture = RD::get_singleton()->texture_create(tf, RD::TextureView(), s);113RD::get_singleton()->set_resource_name(voxel_gi->sdf_texture, "VoxelGI SDF Texture");114}115#if 0116{117RD::TextureFormat tf;118tf.format = RD::DATA_FORMAT_R8_UNORM;119tf.width = voxel_gi->octree_size.x;120tf.height = voxel_gi->octree_size.y;121tf.depth = voxel_gi->octree_size.z;122tf.type = RD::TEXTURE_TYPE_3D;123tf.usage_bits = RD::TEXTURE_USAGE_SAMPLING_BIT | RD::TEXTURE_USAGE_STORAGE_BIT | RD::TEXTURE_USAGE_CAN_COPY_TO_BIT;124tf.shareable_formats.push_back(RD::DATA_FORMAT_R8_UNORM);125tf.shareable_formats.push_back(RD::DATA_FORMAT_R8_UINT);126voxel_gi->sdf_texture = RD::get_singleton()->texture_create(tf, RD::TextureView());127RD::get_singleton()->set_resource_name(voxel_gi->sdf_texture, "VoxelGI SDF Texture");128}129RID shared_tex;130{131RD::TextureView tv;132tv.format_override = RD::DATA_FORMAT_R8_UINT;133shared_tex = RD::get_singleton()->texture_create_shared(tv, voxel_gi->sdf_texture);134}135//update SDF texture136Vector<RD::Uniform> uniforms;137{138RD::Uniform u;139u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER;140u.binding = 1;141u.append_id(voxel_gi->octree_buffer);142uniforms.push_back(u);143}144{145RD::Uniform u;146u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER;147u.binding = 2;148u.append_id(voxel_gi->data_buffer);149uniforms.push_back(u);150}151{152RD::Uniform u;153u.uniform_type = RD::UNIFORM_TYPE_IMAGE;154u.binding = 3;155u.append_id(shared_tex);156uniforms.push_back(u);157}158159RID uniform_set = RD::get_singleton()->uniform_set_create(uniforms, voxel_gi_sdf_shader_version_shader, 0);160161{162uint32_t push_constant[4] = { 0, 0, 0, 0 };163164for (int i = 0; i < voxel_gi->level_counts.size() - 1; i++) {165push_constant[0] += voxel_gi->level_counts[i];166}167push_constant[1] = push_constant[0] + voxel_gi->level_counts[voxel_gi->level_counts.size() - 1];168169print_line("offset: " + itos(push_constant[0]));170print_line("size: " + itos(push_constant[1]));171//create SDF172RD::ComputeListID compute_list = RD::get_singleton()->compute_list_begin();173RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, voxel_gi_sdf_shader_pipeline);174RD::get_singleton()->compute_list_bind_uniform_set(compute_list, uniform_set, 0);175RD::get_singleton()->compute_list_set_push_constant(compute_list, push_constant, sizeof(uint32_t) * 4);176RD::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);177RD::get_singleton()->compute_list_end();178}179180RD::get_singleton()->free(uniform_set);181RD::get_singleton()->free(shared_tex);182}183#endif184}185186voxel_gi->version++;187voxel_gi->data_version++;188189voxel_gi->dependency.changed_notify(Dependency::DEPENDENCY_CHANGED_AABB);190}191192AABB GI::voxel_gi_get_bounds(RID p_voxel_gi) const {193VoxelGI *voxel_gi = voxel_gi_owner.get_or_null(p_voxel_gi);194ERR_FAIL_NULL_V(voxel_gi, AABB());195196return voxel_gi->bounds;197}198199Vector3i GI::voxel_gi_get_octree_size(RID p_voxel_gi) const {200VoxelGI *voxel_gi = voxel_gi_owner.get_or_null(p_voxel_gi);201ERR_FAIL_NULL_V(voxel_gi, Vector3i());202return voxel_gi->octree_size;203}204205Vector<uint8_t> GI::voxel_gi_get_octree_cells(RID p_voxel_gi) const {206VoxelGI *voxel_gi = voxel_gi_owner.get_or_null(p_voxel_gi);207ERR_FAIL_NULL_V(voxel_gi, Vector<uint8_t>());208209if (voxel_gi->octree_buffer.is_valid()) {210return RD::get_singleton()->buffer_get_data(voxel_gi->octree_buffer);211}212return Vector<uint8_t>();213}214215Vector<uint8_t> GI::voxel_gi_get_data_cells(RID p_voxel_gi) const {216VoxelGI *voxel_gi = voxel_gi_owner.get_or_null(p_voxel_gi);217ERR_FAIL_NULL_V(voxel_gi, Vector<uint8_t>());218219if (voxel_gi->data_buffer.is_valid()) {220return RD::get_singleton()->buffer_get_data(voxel_gi->data_buffer);221}222return Vector<uint8_t>();223}224225Vector<uint8_t> GI::voxel_gi_get_distance_field(RID p_voxel_gi) const {226VoxelGI *voxel_gi = voxel_gi_owner.get_or_null(p_voxel_gi);227ERR_FAIL_NULL_V(voxel_gi, Vector<uint8_t>());228229if (voxel_gi->data_buffer.is_valid()) {230return RD::get_singleton()->texture_get_data(voxel_gi->sdf_texture, 0);231}232return Vector<uint8_t>();233}234235Vector<int> GI::voxel_gi_get_level_counts(RID p_voxel_gi) const {236VoxelGI *voxel_gi = voxel_gi_owner.get_or_null(p_voxel_gi);237ERR_FAIL_NULL_V(voxel_gi, Vector<int>());238239return voxel_gi->level_counts;240}241242Transform3D GI::voxel_gi_get_to_cell_xform(RID p_voxel_gi) const {243VoxelGI *voxel_gi = voxel_gi_owner.get_or_null(p_voxel_gi);244ERR_FAIL_NULL_V(voxel_gi, Transform3D());245246return voxel_gi->to_cell_xform;247}248249void GI::voxel_gi_set_dynamic_range(RID p_voxel_gi, float p_range) {250VoxelGI *voxel_gi = voxel_gi_owner.get_or_null(p_voxel_gi);251ERR_FAIL_NULL(voxel_gi);252253voxel_gi->dynamic_range = p_range;254voxel_gi->version++;255}256257float GI::voxel_gi_get_dynamic_range(RID p_voxel_gi) const {258VoxelGI *voxel_gi = voxel_gi_owner.get_or_null(p_voxel_gi);259ERR_FAIL_NULL_V(voxel_gi, 0);260261return voxel_gi->dynamic_range;262}263264void GI::voxel_gi_set_propagation(RID p_voxel_gi, float p_range) {265VoxelGI *voxel_gi = voxel_gi_owner.get_or_null(p_voxel_gi);266ERR_FAIL_NULL(voxel_gi);267268voxel_gi->propagation = p_range;269voxel_gi->version++;270}271272float GI::voxel_gi_get_propagation(RID p_voxel_gi) const {273VoxelGI *voxel_gi = voxel_gi_owner.get_or_null(p_voxel_gi);274ERR_FAIL_NULL_V(voxel_gi, 0);275return voxel_gi->propagation;276}277278void GI::voxel_gi_set_energy(RID p_voxel_gi, float p_energy) {279VoxelGI *voxel_gi = voxel_gi_owner.get_or_null(p_voxel_gi);280ERR_FAIL_NULL(voxel_gi);281282voxel_gi->energy = p_energy;283}284285float GI::voxel_gi_get_energy(RID p_voxel_gi) const {286VoxelGI *voxel_gi = voxel_gi_owner.get_or_null(p_voxel_gi);287ERR_FAIL_NULL_V(voxel_gi, 0);288return voxel_gi->energy;289}290291void GI::voxel_gi_set_baked_exposure_normalization(RID p_voxel_gi, float p_baked_exposure) {292VoxelGI *voxel_gi = voxel_gi_owner.get_or_null(p_voxel_gi);293ERR_FAIL_NULL(voxel_gi);294295voxel_gi->baked_exposure = p_baked_exposure;296}297298float GI::voxel_gi_get_baked_exposure_normalization(RID p_voxel_gi) const {299VoxelGI *voxel_gi = voxel_gi_owner.get_or_null(p_voxel_gi);300ERR_FAIL_NULL_V(voxel_gi, 0);301return voxel_gi->baked_exposure;302}303304void GI::voxel_gi_set_bias(RID p_voxel_gi, float p_bias) {305VoxelGI *voxel_gi = voxel_gi_owner.get_or_null(p_voxel_gi);306ERR_FAIL_NULL(voxel_gi);307308voxel_gi->bias = p_bias;309}310311float GI::voxel_gi_get_bias(RID p_voxel_gi) const {312VoxelGI *voxel_gi = voxel_gi_owner.get_or_null(p_voxel_gi);313ERR_FAIL_NULL_V(voxel_gi, 0);314return voxel_gi->bias;315}316317void GI::voxel_gi_set_normal_bias(RID p_voxel_gi, float p_normal_bias) {318VoxelGI *voxel_gi = voxel_gi_owner.get_or_null(p_voxel_gi);319ERR_FAIL_NULL(voxel_gi);320321voxel_gi->normal_bias = p_normal_bias;322}323324float GI::voxel_gi_get_normal_bias(RID p_voxel_gi) const {325VoxelGI *voxel_gi = voxel_gi_owner.get_or_null(p_voxel_gi);326ERR_FAIL_NULL_V(voxel_gi, 0);327return voxel_gi->normal_bias;328}329330void GI::voxel_gi_set_interior(RID p_voxel_gi, bool p_enable) {331VoxelGI *voxel_gi = voxel_gi_owner.get_or_null(p_voxel_gi);332ERR_FAIL_NULL(voxel_gi);333334voxel_gi->interior = p_enable;335}336337void GI::voxel_gi_set_use_two_bounces(RID p_voxel_gi, bool p_enable) {338VoxelGI *voxel_gi = voxel_gi_owner.get_or_null(p_voxel_gi);339ERR_FAIL_NULL(voxel_gi);340341voxel_gi->use_two_bounces = p_enable;342voxel_gi->version++;343}344345bool GI::voxel_gi_is_using_two_bounces(RID p_voxel_gi) const {346VoxelGI *voxel_gi = voxel_gi_owner.get_or_null(p_voxel_gi);347ERR_FAIL_NULL_V(voxel_gi, false);348return voxel_gi->use_two_bounces;349}350351bool GI::voxel_gi_is_interior(RID p_voxel_gi) const {352VoxelGI *voxel_gi = voxel_gi_owner.get_or_null(p_voxel_gi);353ERR_FAIL_NULL_V(voxel_gi, false);354return voxel_gi->interior;355}356357uint32_t GI::voxel_gi_get_version(RID p_voxel_gi) const {358VoxelGI *voxel_gi = voxel_gi_owner.get_or_null(p_voxel_gi);359ERR_FAIL_NULL_V(voxel_gi, 0);360return voxel_gi->version;361}362363uint32_t GI::voxel_gi_get_data_version(RID p_voxel_gi) {364VoxelGI *voxel_gi = voxel_gi_owner.get_or_null(p_voxel_gi);365ERR_FAIL_NULL_V(voxel_gi, 0);366return voxel_gi->data_version;367}368369RID GI::voxel_gi_get_octree_buffer(RID p_voxel_gi) const {370VoxelGI *voxel_gi = voxel_gi_owner.get_or_null(p_voxel_gi);371ERR_FAIL_NULL_V(voxel_gi, RID());372return voxel_gi->octree_buffer;373}374375RID GI::voxel_gi_get_data_buffer(RID p_voxel_gi) const {376VoxelGI *voxel_gi = voxel_gi_owner.get_or_null(p_voxel_gi);377ERR_FAIL_NULL_V(voxel_gi, RID());378return voxel_gi->data_buffer;379}380381RID GI::voxel_gi_get_sdf_texture(RID p_voxel_gi) {382VoxelGI *voxel_gi = voxel_gi_owner.get_or_null(p_voxel_gi);383ERR_FAIL_NULL_V(voxel_gi, RID());384385return voxel_gi->sdf_texture;386}387388Dependency *GI::voxel_gi_get_dependency(RID p_voxel_gi) const {389VoxelGI *voxel_gi = voxel_gi_owner.get_or_null(p_voxel_gi);390ERR_FAIL_NULL_V(voxel_gi, nullptr);391392return &voxel_gi->dependency;393}394395void GI::sdfgi_reset() {396sdfgi_current_version++;397}398399////////////////////////////////////////////////////////////////////////////////400// SDFGI401402static RID create_clear_texture(const RD::TextureFormat &p_format, const String &p_name) {403RID texture = RD::get_singleton()->texture_create(p_format, RD::TextureView());404ERR_FAIL_COND_V_MSG(texture.is_null(), RID(), String("Cannot create texture: ") + p_name);405406RD::get_singleton()->set_resource_name(texture, p_name);407RD::get_singleton()->texture_clear(texture, Color(0, 0, 0, 0), 0, p_format.mipmaps, 0, p_format.array_layers);408409return texture;410}411412void GI::SDFGI::create(RID p_env, const Vector3 &p_world_position, uint32_t p_requested_history_size, GI *p_gi) {413RendererRD::TextureStorage *texture_storage = RendererRD::TextureStorage::get_singleton();414RendererRD::MaterialStorage *material_storage = RendererRD::MaterialStorage::get_singleton();415416gi = p_gi;417num_cascades = RendererSceneRenderRD::get_singleton()->environment_get_sdfgi_cascades(p_env);418min_cell_size = RendererSceneRenderRD::get_singleton()->environment_get_sdfgi_min_cell_size(p_env);419uses_occlusion = RendererSceneRenderRD::get_singleton()->environment_get_sdfgi_use_occlusion(p_env);420y_scale_mode = RendererSceneRenderRD::get_singleton()->environment_get_sdfgi_y_scale(p_env);421static const float y_scale[3] = { 2.0, 1.5, 1.0 };422y_mult = y_scale[y_scale_mode];423version = gi->sdfgi_current_version;424cascades.resize(num_cascades);425probe_axis_count = SDFGI::PROBE_DIVISOR + 1;426solid_cell_ratio = gi->sdfgi_solid_cell_ratio;427solid_cell_count = uint32_t(float(cascade_size * cascade_size * cascade_size) * solid_cell_ratio);428429float base_cell_size = min_cell_size;430431RD::TextureFormat tf_sdf;432tf_sdf.format = RD::DATA_FORMAT_R8_UNORM;433tf_sdf.width = cascade_size; // Always 64x64434tf_sdf.height = cascade_size;435tf_sdf.depth = cascade_size;436tf_sdf.texture_type = RD::TEXTURE_TYPE_3D;437tf_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;438439{440RD::TextureFormat tf_render = tf_sdf;441tf_render.format = RD::DATA_FORMAT_R16_UINT;442render_albedo = create_clear_texture(tf_render, "SDFGI Render Albedo");443444tf_render.format = RD::DATA_FORMAT_R32_UINT;445render_emission = create_clear_texture(tf_render, "SDFGI Render Emission");446render_emission_aniso = create_clear_texture(tf_render, "SDFGI Render Emission Aniso");447448tf_render.format = RD::DATA_FORMAT_R8_UNORM; //at least its easy to visualize449450for (int i = 0; i < 8; i++) {451render_occlusion[i] = create_clear_texture(tf_render, String("SDFGI Render Occlusion ") + itos(i));452}453454tf_render.format = RD::DATA_FORMAT_R32_UINT;455render_geom_facing = create_clear_texture(tf_render, "SDFGI Render Geometry Facing");456457tf_render.format = RD::DATA_FORMAT_R8G8B8A8_UINT;458render_sdf[0] = create_clear_texture(tf_render, "SDFGI Render SDF 0");459render_sdf[1] = create_clear_texture(tf_render, "SDFGI Render SDF 1");460461tf_render.width /= 2;462tf_render.height /= 2;463tf_render.depth /= 2;464465render_sdf_half[0] = create_clear_texture(tf_render, "SDFGI Render SDF Half 0");466render_sdf_half[1] = create_clear_texture(tf_render, "SDFGI Render SDF Half 1");467}468469RD::TextureFormat tf_occlusion = tf_sdf;470tf_occlusion.format = RD::DATA_FORMAT_R16_UINT;471tf_occlusion.shareable_formats.push_back(RD::DATA_FORMAT_R16_UINT);472tf_occlusion.shareable_formats.push_back(RD::DATA_FORMAT_R4G4B4A4_UNORM_PACK16);473tf_occlusion.depth *= cascades.size(); //use depth for occlusion slices474tf_occlusion.width *= 2; //use width for the other half475476RD::TextureFormat tf_light = tf_sdf;477tf_light.format = RD::DATA_FORMAT_R32_UINT;478tf_light.shareable_formats.push_back(RD::DATA_FORMAT_R32_UINT);479tf_light.shareable_formats.push_back(RD::DATA_FORMAT_E5B9G9R9_UFLOAT_PACK32);480481RD::TextureFormat tf_aniso0 = tf_sdf;482tf_aniso0.format = RD::DATA_FORMAT_R8G8B8A8_UNORM;483RD::TextureFormat tf_aniso1 = tf_sdf;484tf_aniso1.format = RD::DATA_FORMAT_R8G8_UNORM;485486int passes = nearest_shift(cascade_size) - 1;487488//store lightprobe SH489RD::TextureFormat tf_probes;490tf_probes.format = RD::DATA_FORMAT_R16G16B16A16_SFLOAT;491tf_probes.width = probe_axis_count * probe_axis_count;492tf_probes.height = probe_axis_count * SDFGI::SH_SIZE;493tf_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;494tf_probes.texture_type = RD::TEXTURE_TYPE_2D_ARRAY;495496history_size = p_requested_history_size;497498RD::TextureFormat tf_probe_history = tf_probes;499tf_probe_history.format = RD::DATA_FORMAT_R16G16B16A16_SINT; //signed integer because SH are signed500tf_probe_history.array_layers = history_size;501502RD::TextureFormat tf_probe_average = tf_probes;503tf_probe_average.format = RD::DATA_FORMAT_R32G32B32A32_SINT; //signed integer because SH are signed504tf_probe_average.texture_type = RD::TEXTURE_TYPE_2D;505506lightprobe_history_scroll = create_clear_texture(tf_probe_history, "SDFGI LightProbe History Scroll");507lightprobe_average_scroll = create_clear_texture(tf_probe_average, "SDFGI LightProbe Average Scroll");508509{510//octahedral lightprobes511RD::TextureFormat tf_octprobes = tf_probes;512tf_octprobes.array_layers = cascades.size() * 2;513tf_octprobes.format = RD::DATA_FORMAT_R32_UINT; //pack well with RGBE514tf_octprobes.width = probe_axis_count * probe_axis_count * (SDFGI::LIGHTPROBE_OCT_SIZE + 2);515tf_octprobes.height = probe_axis_count * (SDFGI::LIGHTPROBE_OCT_SIZE + 2);516tf_octprobes.shareable_formats.push_back(RD::DATA_FORMAT_R32_UINT);517tf_octprobes.shareable_formats.push_back(RD::DATA_FORMAT_E5B9G9R9_UFLOAT_PACK32);518//lightprobe texture is an octahedral texture519520lightprobe_data = create_clear_texture(tf_octprobes, "SDFGI LightProbe Data");521RD::TextureView tv;522tv.format_override = RD::DATA_FORMAT_E5B9G9R9_UFLOAT_PACK32;523lightprobe_texture = RD::get_singleton()->texture_create_shared(tv, lightprobe_data);524525//texture handling ambient data, to integrate with volumetric foc526RD::TextureFormat tf_ambient = tf_probes;527tf_ambient.array_layers = cascades.size();528tf_ambient.format = RD::DATA_FORMAT_R16G16B16A16_SFLOAT; //pack well with RGBE529tf_ambient.width = probe_axis_count * probe_axis_count;530tf_ambient.height = probe_axis_count;531tf_ambient.texture_type = RD::TEXTURE_TYPE_2D_ARRAY;532//lightprobe texture is an octahedral texture533ambient_texture = create_clear_texture(tf_ambient, "SDFGI Ambient Texture");534}535536cascades_ubo = RD::get_singleton()->uniform_buffer_create(sizeof(SDFGI::Cascade::UBO) * SDFGI::MAX_CASCADES);537538occlusion_data = create_clear_texture(tf_occlusion, "SDFGI Occlusion Data");539{540RD::TextureView tv;541tv.format_override = RD::DATA_FORMAT_R4G4B4A4_UNORM_PACK16;542occlusion_texture = RD::get_singleton()->texture_create_shared(tv, occlusion_data);543}544545for (SDFGI::Cascade &cascade : cascades) {546/* 3D Textures */547548cascade.sdf_tex = create_clear_texture(tf_sdf, "SDFGI Cascade SDF Texture");549550cascade.light_data = create_clear_texture(tf_light, "SDFGI Cascade Light Data");551552cascade.light_aniso_0_tex = create_clear_texture(tf_aniso0, "SDFGI Cascade Light Aniso 0 Texture");553cascade.light_aniso_1_tex = create_clear_texture(tf_aniso1, "SDFGI Cascade Light Aniso 1 Texture");554555{556RD::TextureView tv;557tv.format_override = RD::DATA_FORMAT_E5B9G9R9_UFLOAT_PACK32;558cascade.light_tex = RD::get_singleton()->texture_create_shared(tv, cascade.light_data);559}560561cascade.cell_size = base_cell_size;562Vector3 world_position = p_world_position;563world_position.y *= y_mult;564int32_t probe_cells = cascade_size / SDFGI::PROBE_DIVISOR;565Vector3 probe_size = Vector3(1, 1, 1) * cascade.cell_size * probe_cells;566Vector3i probe_pos = Vector3i((world_position / probe_size + Vector3(0.5, 0.5, 0.5)).floor());567cascade.position = probe_pos * probe_cells;568569cascade.dirty_regions = SDFGI::Cascade::DIRTY_ALL;570571base_cell_size *= 2.0;572573/* Probe History */574575cascade.lightprobe_history_tex = RD::get_singleton()->texture_create(tf_probe_history, RD::TextureView());576RD::get_singleton()->set_resource_name(cascade.lightprobe_history_tex, "SDFGI Cascade LightProbe History Texture");577RD::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 work578579cascade.lightprobe_average_tex = RD::get_singleton()->texture_create(tf_probe_average, RD::TextureView());580RD::get_singleton()->set_resource_name(cascade.lightprobe_average_tex, "SDFGI Cascade LightProbe Average Texture");581RD::get_singleton()->texture_clear(cascade.lightprobe_average_tex, Color(0, 0, 0, 0), 0, 1, 0, 1); //needs to be cleared for average to work582583/* Buffers */584585cascade.solid_cell_buffer = RD::get_singleton()->storage_buffer_create(sizeof(SDFGI::Cascade::SolidCell) * solid_cell_count);586cascade.solid_cell_dispatch_buffer_storage = RD::get_singleton()->storage_buffer_create(sizeof(uint32_t) * 4, Vector<uint8_t>());587cascade.solid_cell_dispatch_buffer_call = RD::get_singleton()->storage_buffer_create(sizeof(uint32_t) * 4, Vector<uint8_t>(), RD::STORAGE_BUFFER_USAGE_DISPATCH_INDIRECT);588cascade.lights_buffer = RD::get_singleton()->storage_buffer_create(sizeof(SDFGIShader::Light) * MAX(SDFGI::MAX_STATIC_LIGHTS, SDFGI::MAX_DYNAMIC_LIGHTS));589{590Vector<RD::Uniform> uniforms;591{592RD::Uniform u;593u.uniform_type = RD::UNIFORM_TYPE_IMAGE;594u.binding = 1;595u.append_id(render_sdf[(passes & 1) ? 1 : 0]); //if passes are even, we read from buffer 0, else we read from buffer 1596uniforms.push_back(u);597}598{599RD::Uniform u;600u.uniform_type = RD::UNIFORM_TYPE_IMAGE;601u.binding = 2;602u.append_id(render_albedo);603uniforms.push_back(u);604}605{606RD::Uniform u;607u.uniform_type = RD::UNIFORM_TYPE_IMAGE;608u.binding = 3;609for (int j = 0; j < 8; j++) {610u.append_id(render_occlusion[j]);611}612uniforms.push_back(u);613}614{615RD::Uniform u;616u.uniform_type = RD::UNIFORM_TYPE_IMAGE;617u.binding = 4;618u.append_id(render_emission);619uniforms.push_back(u);620}621{622RD::Uniform u;623u.uniform_type = RD::UNIFORM_TYPE_IMAGE;624u.binding = 5;625u.append_id(render_emission_aniso);626uniforms.push_back(u);627}628{629RD::Uniform u;630u.uniform_type = RD::UNIFORM_TYPE_IMAGE;631u.binding = 6;632u.append_id(render_geom_facing);633uniforms.push_back(u);634}635636{637RD::Uniform u;638u.uniform_type = RD::UNIFORM_TYPE_IMAGE;639u.binding = 7;640u.append_id(cascade.sdf_tex);641uniforms.push_back(u);642}643{644RD::Uniform u;645u.uniform_type = RD::UNIFORM_TYPE_IMAGE;646u.binding = 8;647u.append_id(occlusion_data);648uniforms.push_back(u);649}650{651RD::Uniform u;652u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER;653u.binding = 10;654u.append_id(cascade.solid_cell_dispatch_buffer_storage);655uniforms.push_back(u);656}657{658RD::Uniform u;659u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER;660u.binding = 11;661u.append_id(cascade.solid_cell_buffer);662uniforms.push_back(u);663}664665cascade.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);666}667668{669Vector<RD::Uniform> uniforms;670{671RD::Uniform u;672u.uniform_type = RD::UNIFORM_TYPE_IMAGE;673u.binding = 1;674u.append_id(render_albedo);675uniforms.push_back(u);676}677{678RD::Uniform u;679u.uniform_type = RD::UNIFORM_TYPE_IMAGE;680u.binding = 2;681u.append_id(render_geom_facing);682uniforms.push_back(u);683}684{685RD::Uniform u;686u.uniform_type = RD::UNIFORM_TYPE_IMAGE;687u.binding = 3;688u.append_id(render_emission);689uniforms.push_back(u);690}691{692RD::Uniform u;693u.uniform_type = RD::UNIFORM_TYPE_IMAGE;694u.binding = 4;695u.append_id(render_emission_aniso);696uniforms.push_back(u);697}698{699RD::Uniform u;700u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER;701u.binding = 5;702u.append_id(cascade.solid_cell_dispatch_buffer_storage);703uniforms.push_back(u);704}705{706RD::Uniform u;707u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER;708u.binding = 6;709u.append_id(cascade.solid_cell_buffer);710uniforms.push_back(u);711}712713cascade.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);714}715{716Vector<RD::Uniform> uniforms;717{718RD::Uniform u;719u.uniform_type = RD::UNIFORM_TYPE_IMAGE;720u.binding = 1;721for (int j = 0; j < 8; j++) {722u.append_id(render_occlusion[j]);723}724uniforms.push_back(u);725}726{727RD::Uniform u;728u.uniform_type = RD::UNIFORM_TYPE_IMAGE;729u.binding = 2;730u.append_id(occlusion_data);731uniforms.push_back(u);732}733734cascade.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);735}736}737738//direct light739for (SDFGI::Cascade &cascade : cascades) {740Vector<RD::Uniform> uniforms;741{742RD::Uniform u;743u.binding = 1;744u.uniform_type = RD::UNIFORM_TYPE_TEXTURE;745for (uint32_t j = 0; j < SDFGI::MAX_CASCADES; j++) {746if (j < cascades.size()) {747u.append_id(cascades[j].sdf_tex);748} else {749u.append_id(texture_storage->texture_rd_get_default(RendererRD::TextureStorage::DEFAULT_RD_TEXTURE_3D_WHITE));750}751}752uniforms.push_back(u);753}754{755RD::Uniform u;756u.binding = 2;757u.uniform_type = RD::UNIFORM_TYPE_SAMPLER;758u.append_id(material_storage->sampler_rd_get_default(RS::CANVAS_ITEM_TEXTURE_FILTER_LINEAR, RS::CANVAS_ITEM_TEXTURE_REPEAT_DISABLED));759uniforms.push_back(u);760}761{762RD::Uniform u;763u.binding = 3;764u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER;765u.append_id(cascade.solid_cell_dispatch_buffer_storage);766uniforms.push_back(u);767}768{769RD::Uniform u;770u.binding = 4;771u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER;772u.append_id(cascade.solid_cell_buffer);773uniforms.push_back(u);774}775{776RD::Uniform u;777u.binding = 5;778u.uniform_type = RD::UNIFORM_TYPE_IMAGE;779u.append_id(cascade.light_data);780uniforms.push_back(u);781}782{783RD::Uniform u;784u.binding = 6;785u.uniform_type = RD::UNIFORM_TYPE_IMAGE;786u.append_id(cascade.light_aniso_0_tex);787uniforms.push_back(u);788}789{790RD::Uniform u;791u.binding = 7;792u.uniform_type = RD::UNIFORM_TYPE_IMAGE;793u.append_id(cascade.light_aniso_1_tex);794uniforms.push_back(u);795}796{797RD::Uniform u;798u.binding = 8;799u.uniform_type = RD::UNIFORM_TYPE_UNIFORM_BUFFER;800u.append_id(cascades_ubo);801uniforms.push_back(u);802}803{804RD::Uniform u;805u.binding = 9;806u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER;807u.append_id(cascade.lights_buffer);808uniforms.push_back(u);809}810{811RD::Uniform u;812u.binding = 10;813u.uniform_type = RD::UNIFORM_TYPE_TEXTURE;814u.append_id(lightprobe_texture);815uniforms.push_back(u);816}817{818RD::Uniform u;819u.binding = 11;820u.uniform_type = RD::UNIFORM_TYPE_TEXTURE;821u.append_id(occlusion_texture);822uniforms.push_back(u);823}824825cascade.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);826cascade.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);827}828829//preprocess initialize uniform set830{831Vector<RD::Uniform> uniforms;832{833RD::Uniform u;834u.uniform_type = RD::UNIFORM_TYPE_IMAGE;835u.binding = 1;836u.append_id(render_albedo);837uniforms.push_back(u);838}839{840RD::Uniform u;841u.uniform_type = RD::UNIFORM_TYPE_IMAGE;842u.binding = 2;843u.append_id(render_sdf[0]);844uniforms.push_back(u);845}846847sdf_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);848}849850{851Vector<RD::Uniform> uniforms;852{853RD::Uniform u;854u.uniform_type = RD::UNIFORM_TYPE_IMAGE;855u.binding = 1;856u.append_id(render_albedo);857uniforms.push_back(u);858}859{860RD::Uniform u;861u.uniform_type = RD::UNIFORM_TYPE_IMAGE;862u.binding = 2;863u.append_id(render_sdf_half[0]);864uniforms.push_back(u);865}866867sdf_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);868}869870//jump flood uniform set871{872Vector<RD::Uniform> uniforms;873{874RD::Uniform u;875u.uniform_type = RD::UNIFORM_TYPE_IMAGE;876u.binding = 1;877u.append_id(render_sdf[0]);878uniforms.push_back(u);879}880{881RD::Uniform u;882u.uniform_type = RD::UNIFORM_TYPE_IMAGE;883u.binding = 2;884u.append_id(render_sdf[1]);885uniforms.push_back(u);886}887888jump_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);889RID aux0 = uniforms.write[0].get_id(0);890RID aux1 = uniforms.write[1].get_id(0);891uniforms.write[0].set_id(0, aux1);892uniforms.write[1].set_id(0, aux0);893jump_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);894}895//jump flood half uniform set896{897Vector<RD::Uniform> uniforms;898{899RD::Uniform u;900u.uniform_type = RD::UNIFORM_TYPE_IMAGE;901u.binding = 1;902u.append_id(render_sdf_half[0]);903uniforms.push_back(u);904}905{906RD::Uniform u;907u.uniform_type = RD::UNIFORM_TYPE_IMAGE;908u.binding = 2;909u.append_id(render_sdf_half[1]);910uniforms.push_back(u);911}912913jump_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);914RID aux0 = uniforms.write[0].get_id(0);915RID aux1 = uniforms.write[1].get_id(0);916uniforms.write[0].set_id(0, aux1);917uniforms.write[1].set_id(0, aux0);918jump_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);919}920921//upscale half size sdf922{923Vector<RD::Uniform> uniforms;924{925RD::Uniform u;926u.uniform_type = RD::UNIFORM_TYPE_IMAGE;927u.binding = 1;928u.append_id(render_albedo);929uniforms.push_back(u);930}931{932RD::Uniform u;933u.uniform_type = RD::UNIFORM_TYPE_IMAGE;934u.binding = 2;935u.append_id(render_sdf_half[(passes & 1) ? 0 : 1]); //reverse pass order because half size936uniforms.push_back(u);937}938{939RD::Uniform u;940u.uniform_type = RD::UNIFORM_TYPE_IMAGE;941u.binding = 3;942u.append_id(render_sdf[(passes & 1) ? 0 : 1]); //reverse pass order because it needs an extra JFA pass943uniforms.push_back(u);944}945946upscale_jfa_uniform_set_index = (passes & 1) ? 0 : 1;947sdf_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);948}949950//occlusion uniform set951{952Vector<RD::Uniform> uniforms;953{954RD::Uniform u;955u.uniform_type = RD::UNIFORM_TYPE_IMAGE;956u.binding = 1;957u.append_id(render_albedo);958uniforms.push_back(u);959}960{961RD::Uniform u;962u.uniform_type = RD::UNIFORM_TYPE_IMAGE;963u.binding = 2;964for (int i = 0; i < 8; i++) {965u.append_id(render_occlusion[i]);966}967uniforms.push_back(u);968}969{970RD::Uniform u;971u.uniform_type = RD::UNIFORM_TYPE_IMAGE;972u.binding = 3;973u.append_id(render_geom_facing);974uniforms.push_back(u);975}976977occlusion_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);978}979980for (uint32_t i = 0; i < cascades.size(); i++) {981//integrate uniform982983Vector<RD::Uniform> uniforms;984985{986RD::Uniform u;987u.binding = 1;988u.uniform_type = RD::UNIFORM_TYPE_TEXTURE;989for (uint32_t j = 0; j < SDFGI::MAX_CASCADES; j++) {990if (j < cascades.size()) {991u.append_id(cascades[j].sdf_tex);992} else {993u.append_id(texture_storage->texture_rd_get_default(RendererRD::TextureStorage::DEFAULT_RD_TEXTURE_3D_WHITE));994}995}996uniforms.push_back(u);997}998{999RD::Uniform u;1000u.binding = 2;1001u.uniform_type = RD::UNIFORM_TYPE_TEXTURE;1002for (uint32_t j = 0; j < SDFGI::MAX_CASCADES; j++) {1003if (j < cascades.size()) {1004u.append_id(cascades[j].light_tex);1005} else {1006u.append_id(texture_storage->texture_rd_get_default(RendererRD::TextureStorage::DEFAULT_RD_TEXTURE_3D_WHITE));1007}1008}1009uniforms.push_back(u);1010}1011{1012RD::Uniform u;1013u.binding = 3;1014u.uniform_type = RD::UNIFORM_TYPE_TEXTURE;1015for (uint32_t j = 0; j < SDFGI::MAX_CASCADES; j++) {1016if (j < cascades.size()) {1017u.append_id(cascades[j].light_aniso_0_tex);1018} else {1019u.append_id(texture_storage->texture_rd_get_default(RendererRD::TextureStorage::DEFAULT_RD_TEXTURE_3D_WHITE));1020}1021}1022uniforms.push_back(u);1023}1024{1025RD::Uniform u;1026u.binding = 4;1027u.uniform_type = RD::UNIFORM_TYPE_TEXTURE;1028for (uint32_t j = 0; j < SDFGI::MAX_CASCADES; j++) {1029if (j < cascades.size()) {1030u.append_id(cascades[j].light_aniso_1_tex);1031} else {1032u.append_id(texture_storage->texture_rd_get_default(RendererRD::TextureStorage::DEFAULT_RD_TEXTURE_3D_WHITE));1033}1034}1035uniforms.push_back(u);1036}1037{1038RD::Uniform u;1039u.uniform_type = RD::UNIFORM_TYPE_SAMPLER;1040u.binding = 6;1041u.append_id(material_storage->sampler_rd_get_default(RS::CANVAS_ITEM_TEXTURE_FILTER_LINEAR, RS::CANVAS_ITEM_TEXTURE_REPEAT_DISABLED));1042uniforms.push_back(u);1043}10441045{1046RD::Uniform u;1047u.uniform_type = RD::UNIFORM_TYPE_UNIFORM_BUFFER;1048u.binding = 7;1049u.append_id(cascades_ubo);1050uniforms.push_back(u);1051}1052{1053RD::Uniform u;1054u.uniform_type = RD::UNIFORM_TYPE_IMAGE;1055u.binding = 8;1056u.append_id(lightprobe_data);1057uniforms.push_back(u);1058}10591060{1061RD::Uniform u;1062u.uniform_type = RD::UNIFORM_TYPE_IMAGE;1063u.binding = 9;1064u.append_id(cascades[i].lightprobe_history_tex);1065uniforms.push_back(u);1066}1067{1068RD::Uniform u;1069u.uniform_type = RD::UNIFORM_TYPE_IMAGE;1070u.binding = 10;1071u.append_id(cascades[i].lightprobe_average_tex);1072uniforms.push_back(u);1073}10741075{1076RD::Uniform u;1077u.uniform_type = RD::UNIFORM_TYPE_IMAGE;1078u.binding = 11;1079u.append_id(lightprobe_history_scroll);1080uniforms.push_back(u);1081}1082{1083RD::Uniform u;1084u.uniform_type = RD::UNIFORM_TYPE_IMAGE;1085u.binding = 12;1086u.append_id(lightprobe_average_scroll);1087uniforms.push_back(u);1088}1089{1090RD::Uniform u;1091u.uniform_type = RD::UNIFORM_TYPE_IMAGE;1092u.binding = 13;1093RID parent_average;1094if (cascades.size() == 1) {1095// If there is only one SDFGI cascade, we can't use the previous cascade for blending.1096parent_average = cascades[i].lightprobe_average_tex;1097} else if (i < cascades.size() - 1) {1098parent_average = cascades[i + 1].lightprobe_average_tex;1099} else {1100parent_average = cascades[i - 1].lightprobe_average_tex; //to use something, but it won't be used1101}1102u.append_id(parent_average);1103uniforms.push_back(u);1104}1105{1106RD::Uniform u;1107u.uniform_type = RD::UNIFORM_TYPE_IMAGE;1108u.binding = 14;1109u.append_id(ambient_texture);1110uniforms.push_back(u);1111}11121113cascades[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);1114}11151116bounce_feedback = RendererSceneRenderRD::get_singleton()->environment_get_sdfgi_bounce_feedback(p_env);1117energy = RendererSceneRenderRD::get_singleton()->environment_get_sdfgi_energy(p_env);1118normal_bias = RendererSceneRenderRD::get_singleton()->environment_get_sdfgi_normal_bias(p_env);1119probe_bias = RendererSceneRenderRD::get_singleton()->environment_get_sdfgi_probe_bias(p_env);1120reads_sky = RendererSceneRenderRD::get_singleton()->environment_get_sdfgi_read_sky_light(p_env);1121}11221123void GI::SDFGI::free_data() {1124// we don't free things here, we handle SDFGI differently at the moment destructing the object when it needs to change.1125}11261127GI::SDFGI::~SDFGI() {1128for (const SDFGI::Cascade &c : cascades) {1129RD::get_singleton()->free_rid(c.light_data);1130RD::get_singleton()->free_rid(c.light_aniso_0_tex);1131RD::get_singleton()->free_rid(c.light_aniso_1_tex);1132RD::get_singleton()->free_rid(c.sdf_tex);1133RD::get_singleton()->free_rid(c.solid_cell_dispatch_buffer_storage);1134RD::get_singleton()->free_rid(c.solid_cell_dispatch_buffer_call);1135RD::get_singleton()->free_rid(c.solid_cell_buffer);1136RD::get_singleton()->free_rid(c.lightprobe_history_tex);1137RD::get_singleton()->free_rid(c.lightprobe_average_tex);1138RD::get_singleton()->free_rid(c.lights_buffer);1139}11401141RD::get_singleton()->free_rid(render_albedo);1142RD::get_singleton()->free_rid(render_emission);1143RD::get_singleton()->free_rid(render_emission_aniso);11441145RD::get_singleton()->free_rid(render_sdf[0]);1146RD::get_singleton()->free_rid(render_sdf[1]);11471148RD::get_singleton()->free_rid(render_sdf_half[0]);1149RD::get_singleton()->free_rid(render_sdf_half[1]);11501151for (int i = 0; i < 8; i++) {1152RD::get_singleton()->free_rid(render_occlusion[i]);1153}11541155RD::get_singleton()->free_rid(render_geom_facing);11561157RD::get_singleton()->free_rid(lightprobe_data);1158RD::get_singleton()->free_rid(lightprobe_history_scroll);1159RD::get_singleton()->free_rid(lightprobe_average_scroll);1160RD::get_singleton()->free_rid(occlusion_data);1161RD::get_singleton()->free_rid(ambient_texture);11621163RD::get_singleton()->free_rid(cascades_ubo);11641165for (uint32_t v = 0; v < RendererSceneRender::MAX_RENDER_VIEWS; v++) {1166if (RD::get_singleton()->uniform_set_is_valid(debug_uniform_set[v])) {1167RD::get_singleton()->free_rid(debug_uniform_set[v]);1168}1169debug_uniform_set[v] = RID();1170}11711172if (RD::get_singleton()->uniform_set_is_valid(debug_probes_uniform_set)) {1173RD::get_singleton()->free_rid(debug_probes_uniform_set);1174}1175debug_probes_uniform_set = RID();11761177if (debug_probes_scene_data_ubo.is_valid()) {1178RD::get_singleton()->free_rid(debug_probes_scene_data_ubo);1179debug_probes_scene_data_ubo = RID();1180}1181}11821183void GI::SDFGI::update(RID p_env, const Vector3 &p_world_position) {1184bounce_feedback = RendererSceneRenderRD::get_singleton()->environment_get_sdfgi_bounce_feedback(p_env);1185energy = RendererSceneRenderRD::get_singleton()->environment_get_sdfgi_energy(p_env);1186normal_bias = RendererSceneRenderRD::get_singleton()->environment_get_sdfgi_normal_bias(p_env);1187probe_bias = RendererSceneRenderRD::get_singleton()->environment_get_sdfgi_probe_bias(p_env);1188reads_sky = RendererSceneRenderRD::get_singleton()->environment_get_sdfgi_read_sky_light(p_env);11891190int32_t drag_margin = (cascade_size / SDFGI::PROBE_DIVISOR) / 2;11911192for (SDFGI::Cascade &cascade : cascades) {1193cascade.dirty_regions = Vector3i();11941195Vector3 probe_half_size = Vector3(1, 1, 1) * cascade.cell_size * float(cascade_size / SDFGI::PROBE_DIVISOR) * 0.5;1196probe_half_size = Vector3(0, 0, 0);11971198Vector3 world_position = p_world_position;1199world_position.y *= y_mult;1200Vector3i pos_in_cascade = Vector3i((world_position + probe_half_size) / cascade.cell_size);12011202for (int j = 0; j < 3; j++) {1203if (pos_in_cascade[j] < cascade.position[j]) {1204while (pos_in_cascade[j] < (cascade.position[j] - drag_margin)) {1205cascade.position[j] -= drag_margin * 2;1206cascade.dirty_regions[j] += drag_margin * 2;1207}1208} else if (pos_in_cascade[j] > cascade.position[j]) {1209while (pos_in_cascade[j] > (cascade.position[j] + drag_margin)) {1210cascade.position[j] += drag_margin * 2;1211cascade.dirty_regions[j] -= drag_margin * 2;1212}1213}12141215if (cascade.dirty_regions[j] == 0) {1216continue; // not dirty1217} else if (uint32_t(Math::abs(cascade.dirty_regions[j])) >= cascade_size) {1218//moved too much, just redraw everything (make all dirty)1219cascade.dirty_regions = SDFGI::Cascade::DIRTY_ALL;1220break;1221}1222}12231224if (cascade.dirty_regions != Vector3i() && cascade.dirty_regions != SDFGI::Cascade::DIRTY_ALL) {1225//see how much the total dirty volume represents from the total volume1226uint32_t total_volume = cascade_size * cascade_size * cascade_size;1227uint32_t safe_volume = 1;1228for (int j = 0; j < 3; j++) {1229safe_volume *= cascade_size - Math::abs(cascade.dirty_regions[j]);1230}1231uint32_t dirty_volume = total_volume - safe_volume;1232if (dirty_volume > (safe_volume / 2)) {1233//more than half the volume is dirty, make all dirty so its only rendered once1234cascade.dirty_regions = SDFGI::Cascade::DIRTY_ALL;1235}1236}1237}1238}12391240void GI::SDFGI::update_light() {1241RD::get_singleton()->draw_command_begin_label("SDFGI Update Dynamic Light");12421243for (uint32_t i = 0; i < cascades.size(); i++) {1244RD::get_singleton()->buffer_copy(cascades[i].solid_cell_dispatch_buffer_storage, cascades[i].solid_cell_dispatch_buffer_call, 0, 0, sizeof(uint32_t) * 4);1245}12461247/* Update dynamic light */12481249RD::ComputeListID compute_list = RD::get_singleton()->compute_list_begin();1250RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, gi->sdfgi_shader.direct_light_pipeline[SDFGIShader::DIRECT_LIGHT_MODE_DYNAMIC].get_rid());12511252SDFGIShader::DirectLightPushConstant push_constant;12531254push_constant.grid_size[0] = cascade_size;1255push_constant.grid_size[1] = cascade_size;1256push_constant.grid_size[2] = cascade_size;1257push_constant.max_cascades = cascades.size();1258push_constant.probe_axis_size = probe_axis_count;1259push_constant.bounce_feedback = bounce_feedback;1260push_constant.y_mult = y_mult;1261push_constant.use_occlusion = uses_occlusion;12621263for (uint32_t i = 0; i < cascades.size(); i++) {1264SDFGI::Cascade &cascade = cascades[i];1265push_constant.light_count = cascade_dynamic_light_count[i];1266push_constant.cascade = i;12671268if (cascades[i].all_dynamic_lights_dirty || gi->sdfgi_frames_to_update_light == RS::ENV_SDFGI_UPDATE_LIGHT_IN_1_FRAME) {1269push_constant.process_offset = 0;1270push_constant.process_increment = 1;1271} else {1272static const uint32_t frames_to_update_table[RS::ENV_SDFGI_UPDATE_LIGHT_MAX] = {12731, 2, 4, 8, 161274};12751276uint32_t frames_to_update = frames_to_update_table[gi->sdfgi_frames_to_update_light];12771278push_constant.process_offset = RSG::rasterizer->get_frame_number() % frames_to_update;1279push_constant.process_increment = frames_to_update;1280}1281cascades[i].all_dynamic_lights_dirty = false;12821283RD::get_singleton()->compute_list_bind_uniform_set(compute_list, cascade.sdf_direct_light_dynamic_uniform_set, 0);1284RD::get_singleton()->compute_list_set_push_constant(compute_list, &push_constant, sizeof(SDFGIShader::DirectLightPushConstant));1285RD::get_singleton()->compute_list_dispatch_indirect(compute_list, cascade.solid_cell_dispatch_buffer_call, 0);1286}1287RD::get_singleton()->compute_list_end();1288RD::get_singleton()->draw_command_end_label();1289}12901291void GI::SDFGI::update_probes(RID p_env, SkyRD::Sky *p_sky) {1292RD::get_singleton()->draw_command_begin_label("SDFGI Update Probes");12931294SDFGIShader::IntegratePushConstant push_constant;1295push_constant.grid_size[1] = cascade_size;1296push_constant.grid_size[2] = cascade_size;1297push_constant.grid_size[0] = cascade_size;1298push_constant.max_cascades = cascades.size();1299push_constant.probe_axis_size = probe_axis_count;1300push_constant.history_index = render_pass % history_size;1301push_constant.history_size = history_size;1302static const uint32_t ray_count[RS::ENV_SDFGI_RAY_COUNT_MAX] = { 4, 8, 16, 32, 64, 96, 128 };1303push_constant.ray_count = ray_count[gi->sdfgi_ray_count];1304push_constant.ray_bias = probe_bias;1305push_constant.image_size[0] = probe_axis_count * probe_axis_count;1306push_constant.image_size[1] = probe_axis_count;1307push_constant.store_ambient_texture = RendererSceneRenderRD::get_singleton()->environment_get_volumetric_fog_enabled(p_env);13081309const float sky_irradiance_border_size = p_sky != nullptr ? p_sky->uv_border_size : 0.0f;1310push_constant.sky_irradiance_border_size[0] = sky_irradiance_border_size;1311push_constant.sky_irradiance_border_size[1] = 1.0 - sky_irradiance_border_size * 2.0f;13121313RID sky_uniform_set = gi->sdfgi_shader.integrate_default_sky_uniform_set;1314push_constant.sky_flags = 0;1315push_constant.y_mult = y_mult;13161317if (reads_sky && p_env.is_valid()) {1318push_constant.sky_energy = RendererSceneRenderRD::get_singleton()->environment_get_bg_energy_multiplier(p_env);13191320if (RendererSceneRenderRD::get_singleton()->environment_get_background(p_env) == RS::ENV_BG_CLEAR_COLOR) {1321push_constant.sky_flags |= SDFGIShader::IntegratePushConstant::SKY_FLAGS_MODE_COLOR;1322Color c = RSG::texture_storage->get_default_clear_color().srgb_to_linear();1323push_constant.sky_color_or_orientation[0] = c.r;1324push_constant.sky_color_or_orientation[1] = c.g;1325push_constant.sky_color_or_orientation[2] = c.b;1326} else if (RendererSceneRenderRD::get_singleton()->environment_get_background(p_env) == RS::ENV_BG_COLOR) {1327push_constant.sky_flags |= SDFGIShader::IntegratePushConstant::SKY_FLAGS_MODE_COLOR;1328Color c = RendererSceneRenderRD::get_singleton()->environment_get_bg_color(p_env);1329push_constant.sky_color_or_orientation[0] = c.r;1330push_constant.sky_color_or_orientation[1] = c.g;1331push_constant.sky_color_or_orientation[2] = c.b;13321333} else if (RendererSceneRenderRD::get_singleton()->environment_get_background(p_env) == RS::ENV_BG_SKY) {1334if (p_sky && p_sky->radiance.is_valid()) {1335if (integrate_sky_uniform_set.is_null() || !RD::get_singleton()->uniform_set_is_valid(integrate_sky_uniform_set)) {1336Vector<RD::Uniform> uniforms;13371338{1339RD::Uniform u;1340u.uniform_type = RD::UNIFORM_TYPE_TEXTURE;1341u.binding = 0;1342u.append_id(p_sky->radiance);1343uniforms.push_back(u);1344}13451346{1347RD::Uniform u;1348u.uniform_type = RD::UNIFORM_TYPE_SAMPLER;1349u.binding = 1;1350u.append_id(RendererRD::MaterialStorage::get_singleton()->sampler_rd_get_default(RS::CANVAS_ITEM_TEXTURE_FILTER_LINEAR_WITH_MIPMAPS, RS::CANVAS_ITEM_TEXTURE_REPEAT_DISABLED));1351uniforms.push_back(u);1352}13531354integrate_sky_uniform_set = RD::get_singleton()->uniform_set_create(uniforms, gi->sdfgi_shader.integrate.version_get_shader(gi->sdfgi_shader.integrate_shader, 0), 1);1355}1356sky_uniform_set = integrate_sky_uniform_set;1357push_constant.sky_flags |= SDFGIShader::IntegratePushConstant::SKY_FLAGS_MODE_SKY;13581359// Encode sky orientation as quaternion in existing push constants.1360const Basis sky_basis = RendererSceneRenderRD::get_singleton()->environment_get_sky_orientation(p_env);1361const Quaternion sky_quaternion = sky_basis.get_quaternion().inverse();1362push_constant.sky_color_or_orientation[0] = sky_quaternion.x;1363push_constant.sky_color_or_orientation[1] = sky_quaternion.y;1364push_constant.sky_color_or_orientation[2] = sky_quaternion.z;1365// 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.1366push_constant.sky_flags |= SDFGIShader::IntegratePushConstant::SKY_FLAGS_ORIENTATION_SIGN * (sky_quaternion.w < 0.0 ? 0 : 1);1367}1368}1369}13701371render_pass++;13721373RD::ComputeListID compute_list = RD::get_singleton()->compute_list_begin();1374RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, gi->sdfgi_shader.integrate_pipeline[SDFGIShader::INTEGRATE_MODE_PROCESS].get_rid());13751376int32_t probe_divisor = cascade_size / SDFGI::PROBE_DIVISOR;1377for (uint32_t i = 0; i < cascades.size(); i++) {1378push_constant.cascade = i;1379push_constant.world_offset[0] = cascades[i].position.x / probe_divisor;1380push_constant.world_offset[1] = cascades[i].position.y / probe_divisor;1381push_constant.world_offset[2] = cascades[i].position.z / probe_divisor;13821383RD::get_singleton()->compute_list_bind_uniform_set(compute_list, cascades[i].integrate_uniform_set, 0);1384RD::get_singleton()->compute_list_bind_uniform_set(compute_list, sky_uniform_set, 1);13851386RD::get_singleton()->compute_list_set_push_constant(compute_list, &push_constant, sizeof(SDFGIShader::IntegratePushConstant));1387RD::get_singleton()->compute_list_dispatch_threads(compute_list, probe_axis_count * probe_axis_count, probe_axis_count, 1);1388}13891390RD::get_singleton()->compute_list_end();1391RD::get_singleton()->draw_command_end_label();1392}13931394void GI::SDFGI::store_probes() {1395RD::get_singleton()->draw_command_begin_label("SDFGI Store Probes");13961397SDFGIShader::IntegratePushConstant push_constant;1398push_constant.grid_size[1] = cascade_size;1399push_constant.grid_size[2] = cascade_size;1400push_constant.grid_size[0] = cascade_size;1401push_constant.max_cascades = cascades.size();1402push_constant.probe_axis_size = probe_axis_count;1403push_constant.history_index = render_pass % history_size;1404push_constant.history_size = history_size;1405static const uint32_t ray_count[RS::ENV_SDFGI_RAY_COUNT_MAX] = { 4, 8, 16, 32, 64, 96, 128 };1406push_constant.ray_count = ray_count[gi->sdfgi_ray_count];1407push_constant.ray_bias = probe_bias;1408push_constant.image_size[0] = probe_axis_count * probe_axis_count;1409push_constant.image_size[1] = probe_axis_count;1410push_constant.store_ambient_texture = false;14111412push_constant.sky_flags = 0;1413push_constant.y_mult = y_mult;14141415// Then store values into the lightprobe texture. Separating these steps has a small performance hit, but it allows for multiple bounces1416RENDER_TIMESTAMP("Average SDFGI Probes");14171418RD::ComputeListID compute_list = RD::get_singleton()->compute_list_begin();1419RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, gi->sdfgi_shader.integrate_pipeline[SDFGIShader::INTEGRATE_MODE_STORE].get_rid());14201421//convert to octahedral to store1422push_constant.image_size[0] *= SDFGI::LIGHTPROBE_OCT_SIZE;1423push_constant.image_size[1] *= SDFGI::LIGHTPROBE_OCT_SIZE;14241425for (uint32_t i = 0; i < cascades.size(); i++) {1426push_constant.cascade = i;1427RD::get_singleton()->compute_list_bind_uniform_set(compute_list, cascades[i].integrate_uniform_set, 0);1428RD::get_singleton()->compute_list_bind_uniform_set(compute_list, gi->sdfgi_shader.integrate_default_sky_uniform_set, 1);1429RD::get_singleton()->compute_list_set_push_constant(compute_list, &push_constant, sizeof(SDFGIShader::IntegratePushConstant));1430RD::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);1431}14321433RD::get_singleton()->compute_list_end();14341435RD::get_singleton()->draw_command_end_label();1436}14371438int GI::SDFGI::get_pending_region_data(int p_region, Vector3i &r_local_offset, Vector3i &r_local_size, AABB &r_bounds) const {1439int dirty_count = 0;1440for (uint32_t i = 0; i < cascades.size(); i++) {1441const SDFGI::Cascade &c = cascades[i];14421443if (c.dirty_regions == SDFGI::Cascade::DIRTY_ALL) {1444if (dirty_count == p_region) {1445r_local_offset = Vector3i();1446r_local_size = Vector3i(1, 1, 1) * cascade_size;14471448r_bounds.position = Vector3((Vector3i(1, 1, 1) * -int32_t(cascade_size >> 1) + c.position)) * c.cell_size * Vector3(1, 1.0 / y_mult, 1);1449r_bounds.size = Vector3(r_local_size) * c.cell_size * Vector3(1, 1.0 / y_mult, 1);1450return i;1451}1452dirty_count++;1453} else {1454for (int j = 0; j < 3; j++) {1455if (c.dirty_regions[j] != 0) {1456if (dirty_count == p_region) {1457Vector3i from = Vector3i(0, 0, 0);1458Vector3i to = Vector3i(1, 1, 1) * cascade_size;14591460if (c.dirty_regions[j] > 0) {1461//fill from the beginning1462to[j] = c.dirty_regions[j];1463} else {1464//fill from the end1465from[j] = to[j] + c.dirty_regions[j];1466}14671468for (int k = 0; k < j; k++) {1469// "chip" away previous regions to avoid re-voxelizing the same thing1470if (c.dirty_regions[k] > 0) {1471from[k] += c.dirty_regions[k];1472} else if (c.dirty_regions[k] < 0) {1473to[k] += c.dirty_regions[k];1474}1475}14761477r_local_offset = from;1478r_local_size = to - from;14791480r_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);1481r_bounds.size = Vector3(r_local_size) * c.cell_size * Vector3(1, 1.0 / y_mult, 1);14821483return i;1484}14851486dirty_count++;1487}1488}1489}1490}1491return -1;1492}14931494void GI::SDFGI::update_cascades() {1495//update cascades1496SDFGI::Cascade::UBO cascade_data[SDFGI::MAX_CASCADES];1497int32_t probe_divisor = cascade_size / SDFGI::PROBE_DIVISOR;14981499for (uint32_t i = 0; i < cascades.size(); i++) {1500Vector3 pos = Vector3((Vector3i(1, 1, 1) * -int32_t(cascade_size >> 1) + cascades[i].position)) * cascades[i].cell_size;15011502cascade_data[i].offset[0] = pos.x;1503cascade_data[i].offset[1] = pos.y;1504cascade_data[i].offset[2] = pos.z;1505cascade_data[i].to_cell = 1.0 / cascades[i].cell_size;1506cascade_data[i].probe_offset[0] = cascades[i].position.x / probe_divisor;1507cascade_data[i].probe_offset[1] = cascades[i].position.y / probe_divisor;1508cascade_data[i].probe_offset[2] = cascades[i].position.z / probe_divisor;1509cascade_data[i].pad = 0;1510}15111512RD::get_singleton()->buffer_update(cascades_ubo, 0, sizeof(SDFGI::Cascade::UBO) * SDFGI::MAX_CASCADES, cascade_data);1513}15141515void 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) {1516RendererRD::TextureStorage *texture_storage = RendererRD::TextureStorage::get_singleton();1517RendererRD::MaterialStorage *material_storage = RendererRD::MaterialStorage::get_singleton();1518RendererRD::CopyEffects *copy_effects = RendererRD::CopyEffects::get_singleton();15191520for (uint32_t v = 0; v < p_view_count; v++) {1521if (!debug_uniform_set[v].is_valid() || !RD::get_singleton()->uniform_set_is_valid(debug_uniform_set[v])) {1522Vector<RD::Uniform> uniforms;1523{1524RD::Uniform u;1525u.binding = 1;1526u.uniform_type = RD::UNIFORM_TYPE_TEXTURE;1527for (uint32_t i = 0; i < SDFGI::MAX_CASCADES; i++) {1528if (i < cascades.size()) {1529u.append_id(cascades[i].sdf_tex);1530} else {1531u.append_id(texture_storage->texture_rd_get_default(RendererRD::TextureStorage::DEFAULT_RD_TEXTURE_3D_WHITE));1532}1533}1534uniforms.push_back(u);1535}1536{1537RD::Uniform u;1538u.binding = 2;1539u.uniform_type = RD::UNIFORM_TYPE_TEXTURE;1540for (uint32_t i = 0; i < SDFGI::MAX_CASCADES; i++) {1541if (i < cascades.size()) {1542u.append_id(cascades[i].light_tex);1543} else {1544u.append_id(texture_storage->texture_rd_get_default(RendererRD::TextureStorage::DEFAULT_RD_TEXTURE_3D_WHITE));1545}1546}1547uniforms.push_back(u);1548}1549{1550RD::Uniform u;1551u.binding = 3;1552u.uniform_type = RD::UNIFORM_TYPE_TEXTURE;1553for (uint32_t i = 0; i < SDFGI::MAX_CASCADES; i++) {1554if (i < cascades.size()) {1555u.append_id(cascades[i].light_aniso_0_tex);1556} else {1557u.append_id(texture_storage->texture_rd_get_default(RendererRD::TextureStorage::DEFAULT_RD_TEXTURE_3D_WHITE));1558}1559}1560uniforms.push_back(u);1561}1562{1563RD::Uniform u;1564u.binding = 4;1565u.uniform_type = RD::UNIFORM_TYPE_TEXTURE;1566for (uint32_t i = 0; i < SDFGI::MAX_CASCADES; i++) {1567if (i < cascades.size()) {1568u.append_id(cascades[i].light_aniso_1_tex);1569} else {1570u.append_id(texture_storage->texture_rd_get_default(RendererRD::TextureStorage::DEFAULT_RD_TEXTURE_3D_WHITE));1571}1572}1573uniforms.push_back(u);1574}1575{1576RD::Uniform u;1577u.binding = 5;1578u.uniform_type = RD::UNIFORM_TYPE_TEXTURE;1579u.append_id(occlusion_texture);1580uniforms.push_back(u);1581}1582{1583RD::Uniform u;1584u.binding = 8;1585u.uniform_type = RD::UNIFORM_TYPE_SAMPLER;1586u.append_id(material_storage->sampler_rd_get_default(RS::CANVAS_ITEM_TEXTURE_FILTER_LINEAR, RS::CANVAS_ITEM_TEXTURE_REPEAT_DISABLED));1587uniforms.push_back(u);1588}1589{1590RD::Uniform u;1591u.binding = 9;1592u.uniform_type = RD::UNIFORM_TYPE_UNIFORM_BUFFER;1593u.append_id(cascades_ubo);1594uniforms.push_back(u);1595}1596{1597RD::Uniform u;1598u.binding = 10;1599u.uniform_type = RD::UNIFORM_TYPE_IMAGE;1600u.append_id(p_texture_views[v]);1601uniforms.push_back(u);1602}1603{1604RD::Uniform u;1605u.binding = 11;1606u.uniform_type = RD::UNIFORM_TYPE_TEXTURE;1607u.append_id(lightprobe_texture);1608uniforms.push_back(u);1609}1610debug_uniform_set[v] = RD::get_singleton()->uniform_set_create(uniforms, gi->sdfgi_shader.debug_shader_version, 0);1611}16121613RD::ComputeListID compute_list = RD::get_singleton()->compute_list_begin();1614RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, gi->sdfgi_shader.debug_pipeline.get_rid());1615RD::get_singleton()->compute_list_bind_uniform_set(compute_list, debug_uniform_set[v], 0);16161617SDFGIShader::DebugPushConstant push_constant;1618push_constant.grid_size[0] = cascade_size;1619push_constant.grid_size[1] = cascade_size;1620push_constant.grid_size[2] = cascade_size;1621push_constant.max_cascades = cascades.size();1622push_constant.screen_size[0] = p_width;1623push_constant.screen_size[1] = p_height;1624push_constant.y_mult = y_mult;16251626push_constant.z_near = -p_projections[v].get_z_near();16271628for (int i = 0; i < 3; i++) {1629for (int j = 0; j < 3; j++) {1630push_constant.cam_basis[i][j] = p_transform.basis.rows[j][i];1631}1632}1633push_constant.cam_origin[0] = p_transform.origin[0];1634push_constant.cam_origin[1] = p_transform.origin[1];1635push_constant.cam_origin[2] = p_transform.origin[2];16361637// need to properly unproject for asymmetric projection matrices in stereo..1638Projection inv_projection = p_projections[v].inverse();1639for (int i = 0; i < 4; i++) {1640for (int j = 0; j < 3; j++) {1641push_constant.inv_projection[j][i] = inv_projection.columns[i][j];1642}1643}16441645RD::get_singleton()->compute_list_set_push_constant(compute_list, &push_constant, sizeof(SDFGIShader::DebugPushConstant));16461647RD::get_singleton()->compute_list_dispatch_threads(compute_list, p_width, p_height, 1);1648RD::get_singleton()->compute_list_end();1649}16501651Size2i rtsize = texture_storage->render_target_get_size(p_render_target);1652copy_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);1653}16541655void GI::SDFGI::debug_probes(RID p_framebuffer, const uint32_t p_view_count, const Projection *p_camera_with_transforms) {1656RendererRD::MaterialStorage *material_storage = RendererRD::MaterialStorage::get_singleton();16571658// setup scene data1659{1660SDFGIShader::DebugProbesSceneData scene_data;16611662if (debug_probes_scene_data_ubo.is_null()) {1663debug_probes_scene_data_ubo = RD::get_singleton()->uniform_buffer_create(sizeof(SDFGIShader::DebugProbesSceneData));1664}16651666for (uint32_t v = 0; v < p_view_count; v++) {1667RendererRD::MaterialStorage::store_camera(p_camera_with_transforms[v], scene_data.projection[v]);1668}16691670RD::get_singleton()->buffer_update(debug_probes_scene_data_ubo, 0, sizeof(SDFGIShader::DebugProbesSceneData), &scene_data);1671}16721673// setup push constant1674SDFGIShader::DebugProbesPushConstant push_constant;16751676//gen spheres from strips1677uint32_t band_points = 16;1678push_constant.band_power = 4;1679push_constant.sections_in_band = ((band_points / 2) - 1);1680push_constant.band_mask = band_points - 2;1681push_constant.section_arc = Math::TAU / float(push_constant.sections_in_band);1682push_constant.y_mult = y_mult;16831684uint32_t total_points = push_constant.sections_in_band * band_points;1685uint32_t total_probes = probe_axis_count * probe_axis_count * probe_axis_count;16861687push_constant.grid_size[0] = cascade_size;1688push_constant.grid_size[1] = cascade_size;1689push_constant.grid_size[2] = cascade_size;1690push_constant.cascade = 0;16911692push_constant.probe_axis_size = probe_axis_count;16931694if (!debug_probes_uniform_set.is_valid() || !RD::get_singleton()->uniform_set_is_valid(debug_probes_uniform_set)) {1695Vector<RD::Uniform> uniforms;1696{1697RD::Uniform u;1698u.binding = 1;1699u.uniform_type = RD::UNIFORM_TYPE_UNIFORM_BUFFER;1700u.append_id(cascades_ubo);1701uniforms.push_back(u);1702}1703{1704RD::Uniform u;1705u.binding = 2;1706u.uniform_type = RD::UNIFORM_TYPE_TEXTURE;1707u.append_id(lightprobe_texture);1708uniforms.push_back(u);1709}1710{1711RD::Uniform u;1712u.binding = 3;1713u.uniform_type = RD::UNIFORM_TYPE_SAMPLER;1714u.append_id(material_storage->sampler_rd_get_default(RS::CANVAS_ITEM_TEXTURE_FILTER_LINEAR, RS::CANVAS_ITEM_TEXTURE_REPEAT_DISABLED));1715uniforms.push_back(u);1716}1717{1718RD::Uniform u;1719u.binding = 4;1720u.uniform_type = RD::UNIFORM_TYPE_TEXTURE;1721u.append_id(occlusion_texture);1722uniforms.push_back(u);1723}1724{1725RD::Uniform u;1726u.binding = 5;1727u.uniform_type = RD::UNIFORM_TYPE_UNIFORM_BUFFER;1728u.append_id(debug_probes_scene_data_ubo);1729uniforms.push_back(u);1730}17311732debug_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);1733}17341735SDFGIShader::ProbeDebugMode mode = p_view_count > 1 ? SDFGIShader::PROBE_DEBUG_PROBES_MULTIVIEW : SDFGIShader::PROBE_DEBUG_PROBES;17361737RD::DrawListID draw_list = RD::get_singleton()->draw_list_begin(p_framebuffer);1738RD::get_singleton()->draw_command_begin_label("Debug SDFGI");17391740RD::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)));1741RD::get_singleton()->draw_list_bind_uniform_set(draw_list, debug_probes_uniform_set, 0);1742RD::get_singleton()->draw_list_set_push_constant(draw_list, &push_constant, sizeof(SDFGIShader::DebugProbesPushConstant));1743RD::get_singleton()->draw_list_draw(draw_list, false, total_probes, total_points);17441745if (gi->sdfgi_debug_probe_dir != Vector3()) {1746uint32_t cascade = 0;1747Vector3 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);1748Vector3 probe_size = cascades[cascade].cell_size * (cascade_size / SDFGI::PROBE_DIVISOR) * Vector3(1.0, 1.0 / y_mult, 1.0);1749Vector3 ray_from = gi->sdfgi_debug_probe_pos;1750Vector3 ray_to = gi->sdfgi_debug_probe_pos + gi->sdfgi_debug_probe_dir * cascades[cascade].cell_size * Math::sqrt(3.0) * cascade_size;1751float sphere_radius = 0.2;1752float closest_dist = 1e20;1753gi->sdfgi_debug_probe_enabled = false;17541755Vector3i probe_from = cascades[cascade].position / (cascade_size / SDFGI::PROBE_DIVISOR);1756for (int i = 0; i < (SDFGI::PROBE_DIVISOR + 1); i++) {1757for (int j = 0; j < (SDFGI::PROBE_DIVISOR + 1); j++) {1758for (int k = 0; k < (SDFGI::PROBE_DIVISOR + 1); k++) {1759Vector3 pos = offset + probe_size * Vector3(i, j, k);1760Vector3 res;1761if (Geometry3D::segment_intersects_sphere(ray_from, ray_to, pos, sphere_radius, &res)) {1762float d = ray_from.distance_to(res);1763if (d < closest_dist) {1764closest_dist = d;1765gi->sdfgi_debug_probe_enabled = true;1766gi->sdfgi_debug_probe_index = probe_from + Vector3i(i, j, k);1767}1768}1769}1770}1771}17721773gi->sdfgi_debug_probe_dir = Vector3();1774}17751776if (gi->sdfgi_debug_probe_enabled) {1777uint32_t cascade = 0;1778uint32_t probe_cells = (cascade_size / SDFGI::PROBE_DIVISOR);1779Vector3i probe_from = cascades[cascade].position / probe_cells;1780Vector3i ofs = gi->sdfgi_debug_probe_index - probe_from;1781if (ofs.x < 0 || ofs.y < 0 || ofs.z < 0) {1782return;1783}1784if (ofs.x > SDFGI::PROBE_DIVISOR || ofs.y > SDFGI::PROBE_DIVISOR || ofs.z > SDFGI::PROBE_DIVISOR) {1785return;1786}17871788uint32_t mult = (SDFGI::PROBE_DIVISOR + 1);1789uint32_t index = ofs.z * mult * mult + ofs.y * mult + ofs.x;17901791push_constant.probe_debug_index = index;17921793uint32_t cell_count = probe_cells * 2 * probe_cells * 2 * probe_cells * 2;17941795RD::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)));1796RD::get_singleton()->draw_list_bind_uniform_set(draw_list, debug_probes_uniform_set, 0);1797RD::get_singleton()->draw_list_set_push_constant(draw_list, &push_constant, sizeof(SDFGIShader::DebugProbesPushConstant));1798RD::get_singleton()->draw_list_draw(draw_list, false, cell_count, total_points);1799}18001801RD::get_singleton()->draw_command_end_label();1802RD::get_singleton()->draw_list_end();1803}18041805void GI::SDFGI::pre_process_gi(const Transform3D &p_transform, RenderDataRD *p_render_data) {1806if (p_render_data->sdfgi_update_data == nullptr) {1807return;1808}18091810RendererRD::LightStorage *light_storage = RendererRD::LightStorage::get_singleton();1811/* Update general SDFGI Buffer */18121813SDFGIData sdfgi_data;18141815sdfgi_data.grid_size[0] = cascade_size;1816sdfgi_data.grid_size[1] = cascade_size;1817sdfgi_data.grid_size[2] = cascade_size;18181819sdfgi_data.max_cascades = cascades.size();1820sdfgi_data.probe_axis_size = probe_axis_count;1821sdfgi_data.cascade_probe_size[0] = sdfgi_data.probe_axis_size - 1; //float version for performance1822sdfgi_data.cascade_probe_size[1] = sdfgi_data.probe_axis_size - 1;1823sdfgi_data.cascade_probe_size[2] = sdfgi_data.probe_axis_size - 1;18241825float csize = cascade_size;1826sdfgi_data.probe_to_uvw = 1.0 / float(sdfgi_data.cascade_probe_size[0]);1827sdfgi_data.use_occlusion = uses_occlusion;1828//sdfgi_data.energy = energy;18291830sdfgi_data.y_mult = y_mult;18311832float cascade_voxel_size = (csize / sdfgi_data.cascade_probe_size[0]);1833float occlusion_clamp = (cascade_voxel_size - 0.5) / cascade_voxel_size;1834sdfgi_data.occlusion_clamp[0] = occlusion_clamp;1835sdfgi_data.occlusion_clamp[1] = occlusion_clamp;1836sdfgi_data.occlusion_clamp[2] = occlusion_clamp;1837sdfgi_data.normal_bias = (normal_bias / csize) * sdfgi_data.cascade_probe_size[0];18381839//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 ) );1840//vec3 probe_uv_offset = (ivec3(OCT_SIZE+2,OCT_SIZE+2,(OCT_SIZE+2) * params.probe_axis_size)) * tex_pixel_size.xyx;18411842uint32_t oct_size = SDFGI::LIGHTPROBE_OCT_SIZE;18431844sdfgi_data.lightprobe_tex_pixel_size[0] = 1.0 / ((oct_size + 2) * sdfgi_data.probe_axis_size * sdfgi_data.probe_axis_size);1845sdfgi_data.lightprobe_tex_pixel_size[1] = 1.0 / ((oct_size + 2) * sdfgi_data.probe_axis_size);1846sdfgi_data.lightprobe_tex_pixel_size[2] = 1.0;18471848sdfgi_data.energy = energy;18491850sdfgi_data.lightprobe_uv_offset[0] = float(oct_size + 2) * sdfgi_data.lightprobe_tex_pixel_size[0];1851sdfgi_data.lightprobe_uv_offset[1] = float(oct_size + 2) * sdfgi_data.lightprobe_tex_pixel_size[1];1852sdfgi_data.lightprobe_uv_offset[2] = float((oct_size + 2) * sdfgi_data.probe_axis_size) * sdfgi_data.lightprobe_tex_pixel_size[0];18531854sdfgi_data.occlusion_renormalize[0] = 0.5;1855sdfgi_data.occlusion_renormalize[1] = 1.0;1856sdfgi_data.occlusion_renormalize[2] = 1.0 / float(sdfgi_data.max_cascades);18571858int32_t probe_divisor = cascade_size / SDFGI::PROBE_DIVISOR;18591860for (uint32_t i = 0; i < sdfgi_data.max_cascades; i++) {1861SDFGIData::ProbeCascadeData &c = sdfgi_data.cascades[i];1862Vector3 pos = Vector3((Vector3i(1, 1, 1) * -int32_t(cascade_size >> 1) + cascades[i].position)) * cascades[i].cell_size;1863Vector3 cam_origin = p_transform.origin;1864cam_origin.y *= y_mult;1865pos -= cam_origin; //make pos local to camera, to reduce numerical error1866c.position[0] = pos.x;1867c.position[1] = pos.y;1868c.position[2] = pos.z;1869c.to_probe = 1.0 / (float(cascade_size) * cascades[i].cell_size / float(probe_axis_count - 1));18701871Vector3i probe_ofs = cascades[i].position / probe_divisor;1872c.probe_world_offset[0] = probe_ofs.x;1873c.probe_world_offset[1] = probe_ofs.y;1874c.probe_world_offset[2] = probe_ofs.z;18751876c.to_cell = 1.0 / cascades[i].cell_size;1877c.exposure_normalization = 1.0;1878if (p_render_data->camera_attributes.is_valid()) {1879float exposure_normalization = RSG::camera_attributes->camera_attributes_get_exposure_normalization_factor(p_render_data->camera_attributes);1880c.exposure_normalization = exposure_normalization / cascades[i].baked_exposure_normalization;1881}1882}18831884RD::get_singleton()->buffer_update(gi->sdfgi_ubo, 0, sizeof(SDFGIData), &sdfgi_data);18851886/* Update dynamic lights in SDFGI cascades */18871888for (uint32_t i = 0; i < cascades.size(); i++) {1889SDFGI::Cascade &cascade = cascades[i];18901891SDFGIShader::Light lights[SDFGI::MAX_DYNAMIC_LIGHTS];1892uint32_t idx = 0;1893for (uint32_t j = 0; j < (uint32_t)p_render_data->sdfgi_update_data->directional_lights->size(); j++) {1894if (idx == SDFGI::MAX_DYNAMIC_LIGHTS) {1895break;1896}18971898RID light_instance = p_render_data->sdfgi_update_data->directional_lights->get(j);1899ERR_CONTINUE(!light_storage->owns_light_instance(light_instance));19001901RID light = light_storage->light_instance_get_base_light(light_instance);1902Transform3D light_transform = light_storage->light_instance_get_base_transform(light_instance);19031904if (RSG::light_storage->light_directional_get_sky_mode(light) == RS::LIGHT_DIRECTIONAL_SKY_MODE_SKY_ONLY) {1905continue;1906}19071908Vector3 dir = -light_transform.basis.get_column(Vector3::AXIS_Z);1909dir.y *= y_mult;1910dir.normalize();1911lights[idx].direction[0] = dir.x;1912lights[idx].direction[1] = dir.y;1913lights[idx].direction[2] = dir.z;1914Color color = RSG::light_storage->light_get_color(light);1915color = color.srgb_to_linear();1916lights[idx].color[0] = color.r;1917lights[idx].color[1] = color.g;1918lights[idx].color[2] = color.b;1919lights[idx].type = RS::LIGHT_DIRECTIONAL;1920lights[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);1921if (RendererSceneRenderRD::get_singleton()->is_using_physical_light_units()) {1922lights[idx].energy *= RSG::light_storage->light_get_param(light, RS::LIGHT_PARAM_INTENSITY);1923}19241925if (p_render_data->camera_attributes.is_valid()) {1926lights[idx].energy *= RSG::camera_attributes->camera_attributes_get_exposure_normalization_factor(p_render_data->camera_attributes);1927}19281929lights[idx].has_shadow = RSG::light_storage->light_has_shadow(light);19301931idx++;1932}19331934AABB cascade_aabb;1935cascade_aabb.position = Vector3((Vector3i(1, 1, 1) * -int32_t(cascade_size >> 1) + cascade.position)) * cascade.cell_size;1936cascade_aabb.size = Vector3(1, 1, 1) * cascade_size * cascade.cell_size;19371938for (uint32_t j = 0; j < p_render_data->sdfgi_update_data->positional_light_count; j++) {1939if (idx == SDFGI::MAX_DYNAMIC_LIGHTS) {1940break;1941}19421943RID light_instance = p_render_data->sdfgi_update_data->positional_light_instances[j];1944ERR_CONTINUE(!light_storage->owns_light_instance(light_instance));19451946RID light = light_storage->light_instance_get_base_light(light_instance);1947AABB light_aabb = light_storage->light_instance_get_base_aabb(light_instance);1948Transform3D light_transform = light_storage->light_instance_get_base_transform(light_instance);19491950uint32_t max_sdfgi_cascade = RSG::light_storage->light_get_max_sdfgi_cascade(light);1951if (i > max_sdfgi_cascade) {1952continue;1953}19541955if (!cascade_aabb.intersects(light_aabb)) {1956continue;1957}19581959Vector3 dir = -light_transform.basis.get_column(Vector3::AXIS_Z);1960//faster to not do this here1961//dir.y *= y_mult;1962//dir.normalize();1963lights[idx].direction[0] = dir.x;1964lights[idx].direction[1] = dir.y;1965lights[idx].direction[2] = dir.z;1966Vector3 pos = light_transform.origin;1967pos.y *= y_mult;1968lights[idx].position[0] = pos.x;1969lights[idx].position[1] = pos.y;1970lights[idx].position[2] = pos.z;1971Color color = RSG::light_storage->light_get_color(light);1972color = color.srgb_to_linear();1973lights[idx].color[0] = color.r;1974lights[idx].color[1] = color.g;1975lights[idx].color[2] = color.b;1976lights[idx].type = RSG::light_storage->light_get_type(light);19771978lights[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);1979if (RendererSceneRenderRD::get_singleton()->is_using_physical_light_units()) {1980lights[idx].energy *= RSG::light_storage->light_get_param(light, RS::LIGHT_PARAM_INTENSITY);19811982// Convert from Luminous Power to Luminous Intensity1983if (lights[idx].type == RS::LIGHT_OMNI) {1984lights[idx].energy *= 1.0 / (Math::PI * 4.0);1985} else if (lights[idx].type == RS::LIGHT_SPOT) {1986// Spot Lights are not physically accurate, Luminous Intensity should change in relation to the cone angle.1987// We make this assumption to keep them easy to control.1988lights[idx].energy *= 1.0 / Math::PI;1989}1990}19911992if (p_render_data->camera_attributes.is_valid()) {1993lights[idx].energy *= RSG::camera_attributes->camera_attributes_get_exposure_normalization_factor(p_render_data->camera_attributes);1994}19951996lights[idx].has_shadow = RSG::light_storage->light_has_shadow(light);1997lights[idx].attenuation = RSG::light_storage->light_get_param(light, RS::LIGHT_PARAM_ATTENUATION);1998lights[idx].radius = RSG::light_storage->light_get_param(light, RS::LIGHT_PARAM_RANGE);1999lights[idx].cos_spot_angle = Math::cos(Math::deg_to_rad(RSG::light_storage->light_get_param(light, RS::LIGHT_PARAM_SPOT_ANGLE)));2000lights[idx].inv_spot_attenuation = 1.0f / RSG::light_storage->light_get_param(light, RS::LIGHT_PARAM_SPOT_ATTENUATION);20012002idx++;2003}20042005if (idx > 0) {2006RD::get_singleton()->buffer_update(cascade.lights_buffer, 0, idx * sizeof(SDFGIShader::Light), lights);2007}20082009cascade_dynamic_light_count[i] = idx;2010}2011}20122013void GI::SDFGI::render_region(Ref<RenderSceneBuffersRD> p_render_buffers, int p_region, const PagedArray<RenderGeometryInstance *> &p_instances, float p_exposure_normalization) {2014//print_line("rendering region " + itos(p_region));2015ERR_FAIL_COND(p_render_buffers.is_null()); // we wouldn't be here if this failed but...2016AABB bounds;2017Vector3i from;2018Vector3i size;20192020int cascade_prev = get_pending_region_data(p_region - 1, from, size, bounds);2021int cascade_next = get_pending_region_data(p_region + 1, from, size, bounds);2022int cascade = get_pending_region_data(p_region, from, size, bounds);2023ERR_FAIL_COND(cascade < 0);20242025if (cascade_prev != cascade) {2026//initialize render2027RD::get_singleton()->texture_clear(render_albedo, Color(0, 0, 0, 0), 0, 1, 0, 1);2028RD::get_singleton()->texture_clear(render_emission, Color(0, 0, 0, 0), 0, 1, 0, 1);2029RD::get_singleton()->texture_clear(render_emission_aniso, Color(0, 0, 0, 0), 0, 1, 0, 1);2030RD::get_singleton()->texture_clear(render_geom_facing, Color(0, 0, 0, 0), 0, 1, 0, 1);2031}20322033//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));2034RendererSceneRenderRD::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);20352036if (cascade_next != cascade) {2037RD::get_singleton()->draw_command_begin_label("SDFGI Pre-Process Cascade");20382039RENDER_TIMESTAMP("> SDFGI Update SDF");2040//done rendering! must update SDF2041//clear dispatch indirect data20422043SDFGIShader::PreprocessPushConstant push_constant;2044memset(&push_constant, 0, sizeof(SDFGIShader::PreprocessPushConstant));20452046RENDER_TIMESTAMP("SDFGI Scroll SDF");20472048//scroll2049if (cascades[cascade].dirty_regions != SDFGI::Cascade::DIRTY_ALL) {2050//for scroll2051Vector3i dirty = cascades[cascade].dirty_regions;2052push_constant.scroll[0] = dirty.x;2053push_constant.scroll[1] = dirty.y;2054push_constant.scroll[2] = dirty.z;2055} else {2056//for no scroll2057push_constant.scroll[0] = 0;2058push_constant.scroll[1] = 0;2059push_constant.scroll[2] = 0;2060}20612062cascades[cascade].all_dynamic_lights_dirty = true;2063cascades[cascade].baked_exposure_normalization = p_exposure_normalization;20642065push_constant.grid_size = cascade_size;2066push_constant.cascade = cascade;20672068if (cascades[cascade].dirty_regions != SDFGI::Cascade::DIRTY_ALL) {2069RD::get_singleton()->buffer_copy(cascades[cascade].solid_cell_dispatch_buffer_storage, cascades[cascade].solid_cell_dispatch_buffer_call, 0, 0, sizeof(uint32_t) * 4);20702071RD::ComputeListID compute_list = RD::get_singleton()->compute_list_begin();20722073//must pre scroll existing data because not all is dirty2074RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, gi->sdfgi_shader.preprocess_pipeline[SDFGIShader::PRE_PROCESS_SCROLL].get_rid());2075RD::get_singleton()->compute_list_bind_uniform_set(compute_list, cascades[cascade].scroll_uniform_set, 0);20762077RD::get_singleton()->compute_list_set_push_constant(compute_list, &push_constant, sizeof(SDFGIShader::PreprocessPushConstant));2078RD::get_singleton()->compute_list_dispatch_indirect(compute_list, cascades[cascade].solid_cell_dispatch_buffer_call, 0);2079// no barrier do all together20802081RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, gi->sdfgi_shader.preprocess_pipeline[SDFGIShader::PRE_PROCESS_SCROLL_OCCLUSION].get_rid());2082RD::get_singleton()->compute_list_bind_uniform_set(compute_list, cascades[cascade].scroll_occlusion_uniform_set, 0);20832084Vector3i dirty = cascades[cascade].dirty_regions;2085Vector3i groups;2086groups.x = cascade_size - Math::abs(dirty.x);2087groups.y = cascade_size - Math::abs(dirty.y);2088groups.z = cascade_size - Math::abs(dirty.z);20892090RD::get_singleton()->compute_list_set_push_constant(compute_list, &push_constant, sizeof(SDFGIShader::PreprocessPushConstant));2091RD::get_singleton()->compute_list_dispatch_threads(compute_list, groups.x, groups.y, groups.z);20922093//no barrier, continue together20942095{2096//scroll probes and their history also20972098SDFGIShader::IntegratePushConstant ipush_constant;2099ipush_constant.grid_size[1] = cascade_size;2100ipush_constant.grid_size[2] = cascade_size;2101ipush_constant.grid_size[0] = cascade_size;2102ipush_constant.max_cascades = cascades.size();2103ipush_constant.probe_axis_size = probe_axis_count;2104ipush_constant.history_index = 0;2105ipush_constant.history_size = history_size;2106ipush_constant.ray_count = 0;2107ipush_constant.ray_bias = 0;2108ipush_constant.sky_flags = 0;2109ipush_constant.sky_energy = 0;2110ipush_constant.sky_color_or_orientation[0] = 0;2111ipush_constant.sky_color_or_orientation[1] = 0;2112ipush_constant.sky_color_or_orientation[2] = 0;2113ipush_constant.y_mult = y_mult;2114ipush_constant.store_ambient_texture = false;21152116ipush_constant.image_size[0] = probe_axis_count * probe_axis_count;2117ipush_constant.image_size[1] = probe_axis_count;21182119int32_t probe_divisor = cascade_size / SDFGI::PROBE_DIVISOR;2120ipush_constant.cascade = cascade;2121ipush_constant.world_offset[0] = cascades[cascade].position.x / probe_divisor;2122ipush_constant.world_offset[1] = cascades[cascade].position.y / probe_divisor;2123ipush_constant.world_offset[2] = cascades[cascade].position.z / probe_divisor;21242125ipush_constant.scroll[0] = dirty.x / probe_divisor;2126ipush_constant.scroll[1] = dirty.y / probe_divisor;2127ipush_constant.scroll[2] = dirty.z / probe_divisor;21282129RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, gi->sdfgi_shader.integrate_pipeline[SDFGIShader::INTEGRATE_MODE_SCROLL].get_rid());2130RD::get_singleton()->compute_list_bind_uniform_set(compute_list, cascades[cascade].integrate_uniform_set, 0);2131RD::get_singleton()->compute_list_bind_uniform_set(compute_list, gi->sdfgi_shader.integrate_default_sky_uniform_set, 1);2132RD::get_singleton()->compute_list_set_push_constant(compute_list, &ipush_constant, sizeof(SDFGIShader::IntegratePushConstant));2133RD::get_singleton()->compute_list_dispatch_threads(compute_list, probe_axis_count * probe_axis_count, probe_axis_count, 1);21342135RD::get_singleton()->compute_list_add_barrier(compute_list);21362137RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, gi->sdfgi_shader.integrate_pipeline[SDFGIShader::INTEGRATE_MODE_SCROLL_STORE].get_rid());2138RD::get_singleton()->compute_list_bind_uniform_set(compute_list, cascades[cascade].integrate_uniform_set, 0);2139RD::get_singleton()->compute_list_bind_uniform_set(compute_list, gi->sdfgi_shader.integrate_default_sky_uniform_set, 1);2140RD::get_singleton()->compute_list_set_push_constant(compute_list, &ipush_constant, sizeof(SDFGIShader::IntegratePushConstant));2141RD::get_singleton()->compute_list_dispatch_threads(compute_list, probe_axis_count * probe_axis_count, probe_axis_count, 1);21422143RD::get_singleton()->compute_list_add_barrier(compute_list);21442145if (bounce_feedback > 0.0) {2146//multibounce requires this to be stored so direct light can read from it21472148RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, gi->sdfgi_shader.integrate_pipeline[SDFGIShader::INTEGRATE_MODE_STORE].get_rid());21492150//convert to octahedral to store2151ipush_constant.image_size[0] *= SDFGI::LIGHTPROBE_OCT_SIZE;2152ipush_constant.image_size[1] *= SDFGI::LIGHTPROBE_OCT_SIZE;21532154RD::get_singleton()->compute_list_bind_uniform_set(compute_list, cascades[cascade].integrate_uniform_set, 0);2155RD::get_singleton()->compute_list_bind_uniform_set(compute_list, gi->sdfgi_shader.integrate_default_sky_uniform_set, 1);2156RD::get_singleton()->compute_list_set_push_constant(compute_list, &ipush_constant, sizeof(SDFGIShader::IntegratePushConstant));2157RD::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);2158}2159}21602161//ok finally barrier2162RD::get_singleton()->compute_list_end();2163}21642165//clear dispatch indirect data2166uint32_t dispatch_indirect_data[4] = { 0, 0, 0, 0 };2167RD::get_singleton()->buffer_update(cascades[cascade].solid_cell_dispatch_buffer_storage, 0, sizeof(uint32_t) * 4, dispatch_indirect_data);21682169RD::ComputeListID compute_list = RD::get_singleton()->compute_list_begin();21702171bool half_size = true; //much faster, very little difference2172static const int optimized_jf_group_size = 8;21732174if (half_size) {2175push_constant.grid_size >>= 1;21762177uint32_t cascade_half_size = cascade_size >> 1;2178RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, gi->sdfgi_shader.preprocess_pipeline[SDFGIShader::PRE_PROCESS_JUMP_FLOOD_INITIALIZE_HALF].get_rid());2179RD::get_singleton()->compute_list_bind_uniform_set(compute_list, sdf_initialize_half_uniform_set, 0);2180RD::get_singleton()->compute_list_set_push_constant(compute_list, &push_constant, sizeof(SDFGIShader::PreprocessPushConstant));2181RD::get_singleton()->compute_list_dispatch_threads(compute_list, cascade_half_size, cascade_half_size, cascade_half_size);2182RD::get_singleton()->compute_list_add_barrier(compute_list);21832184//must start with regular jumpflood21852186push_constant.half_size = true;2187{2188RENDER_TIMESTAMP("SDFGI Jump Flood (Half-Size)");21892190uint32_t s = cascade_half_size;21912192RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, gi->sdfgi_shader.preprocess_pipeline[SDFGIShader::PRE_PROCESS_JUMP_FLOOD].get_rid());21932194int jf_us = 0;2195//start with regular jump flood for very coarse reads, as this is impossible to optimize2196while (s > 1) {2197s /= 2;2198push_constant.step_size = s;2199RD::get_singleton()->compute_list_bind_uniform_set(compute_list, jump_flood_half_uniform_set[jf_us], 0);2200RD::get_singleton()->compute_list_set_push_constant(compute_list, &push_constant, sizeof(SDFGIShader::PreprocessPushConstant));2201RD::get_singleton()->compute_list_dispatch_threads(compute_list, cascade_half_size, cascade_half_size, cascade_half_size);2202RD::get_singleton()->compute_list_add_barrier(compute_list);2203jf_us = jf_us == 0 ? 1 : 0;22042205if (cascade_half_size / (s / 2) >= optimized_jf_group_size) {2206break;2207}2208}22092210RENDER_TIMESTAMP("SDFGI Jump Flood Optimized (Half-Size)");22112212//continue with optimized jump flood for smaller reads2213RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, gi->sdfgi_shader.preprocess_pipeline[SDFGIShader::PRE_PROCESS_JUMP_FLOOD_OPTIMIZED].get_rid());2214while (s > 1) {2215s /= 2;2216push_constant.step_size = s;2217RD::get_singleton()->compute_list_bind_uniform_set(compute_list, jump_flood_half_uniform_set[jf_us], 0);2218RD::get_singleton()->compute_list_set_push_constant(compute_list, &push_constant, sizeof(SDFGIShader::PreprocessPushConstant));2219RD::get_singleton()->compute_list_dispatch_threads(compute_list, cascade_half_size, cascade_half_size, cascade_half_size);2220RD::get_singleton()->compute_list_add_barrier(compute_list);2221jf_us = jf_us == 0 ? 1 : 0;2222}2223}22242225// restore grid size for last passes2226push_constant.grid_size = cascade_size;22272228RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, gi->sdfgi_shader.preprocess_pipeline[SDFGIShader::PRE_PROCESS_JUMP_FLOOD_UPSCALE].get_rid());2229RD::get_singleton()->compute_list_bind_uniform_set(compute_list, sdf_upscale_uniform_set, 0);2230RD::get_singleton()->compute_list_set_push_constant(compute_list, &push_constant, sizeof(SDFGIShader::PreprocessPushConstant));2231RD::get_singleton()->compute_list_dispatch_threads(compute_list, cascade_size, cascade_size, cascade_size);2232RD::get_singleton()->compute_list_add_barrier(compute_list);22332234//run one pass of fullsize jumpflood to fix up half size artifacts22352236push_constant.half_size = false;2237push_constant.step_size = 1;2238RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, gi->sdfgi_shader.preprocess_pipeline[SDFGIShader::PRE_PROCESS_JUMP_FLOOD_OPTIMIZED].get_rid());2239RD::get_singleton()->compute_list_bind_uniform_set(compute_list, jump_flood_uniform_set[upscale_jfa_uniform_set_index], 0);2240RD::get_singleton()->compute_list_set_push_constant(compute_list, &push_constant, sizeof(SDFGIShader::PreprocessPushConstant));2241RD::get_singleton()->compute_list_dispatch_threads(compute_list, cascade_size, cascade_size, cascade_size);2242RD::get_singleton()->compute_list_add_barrier(compute_list);22432244} else {2245//full size jumpflood2246RENDER_TIMESTAMP("SDFGI Jump Flood (Full-Size)");22472248RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, gi->sdfgi_shader.preprocess_pipeline[SDFGIShader::PRE_PROCESS_JUMP_FLOOD_INITIALIZE].get_rid());2249RD::get_singleton()->compute_list_bind_uniform_set(compute_list, sdf_initialize_uniform_set, 0);2250RD::get_singleton()->compute_list_set_push_constant(compute_list, &push_constant, sizeof(SDFGIShader::PreprocessPushConstant));2251RD::get_singleton()->compute_list_dispatch_threads(compute_list, cascade_size, cascade_size, cascade_size);22522253RD::get_singleton()->compute_list_add_barrier(compute_list);22542255push_constant.half_size = false;2256{2257uint32_t s = cascade_size;22582259RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, gi->sdfgi_shader.preprocess_pipeline[SDFGIShader::PRE_PROCESS_JUMP_FLOOD].get_rid());22602261int jf_us = 0;2262//start with regular jump flood for very coarse reads, as this is impossible to optimize2263while (s > 1) {2264s /= 2;2265push_constant.step_size = s;2266RD::get_singleton()->compute_list_bind_uniform_set(compute_list, jump_flood_uniform_set[jf_us], 0);2267RD::get_singleton()->compute_list_set_push_constant(compute_list, &push_constant, sizeof(SDFGIShader::PreprocessPushConstant));2268RD::get_singleton()->compute_list_dispatch_threads(compute_list, cascade_size, cascade_size, cascade_size);2269RD::get_singleton()->compute_list_add_barrier(compute_list);2270jf_us = jf_us == 0 ? 1 : 0;22712272if (cascade_size / (s / 2) >= optimized_jf_group_size) {2273break;2274}2275}22762277RENDER_TIMESTAMP("SDFGI Jump Flood Optimized (Full-Size)");22782279//continue with optimized jump flood for smaller reads2280RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, gi->sdfgi_shader.preprocess_pipeline[SDFGIShader::PRE_PROCESS_JUMP_FLOOD_OPTIMIZED].get_rid());2281while (s > 1) {2282s /= 2;2283push_constant.step_size = s;2284RD::get_singleton()->compute_list_bind_uniform_set(compute_list, jump_flood_uniform_set[jf_us], 0);2285RD::get_singleton()->compute_list_set_push_constant(compute_list, &push_constant, sizeof(SDFGIShader::PreprocessPushConstant));2286RD::get_singleton()->compute_list_dispatch_threads(compute_list, cascade_size, cascade_size, cascade_size);2287RD::get_singleton()->compute_list_add_barrier(compute_list);2288jf_us = jf_us == 0 ? 1 : 0;2289}2290}2291}22922293RENDER_TIMESTAMP("SDFGI Occlusion");22942295// occlusion2296{2297uint32_t probe_size = cascade_size / SDFGI::PROBE_DIVISOR;2298Vector3i probe_global_pos = cascades[cascade].position / probe_size;22992300RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, gi->sdfgi_shader.preprocess_pipeline[SDFGIShader::PRE_PROCESS_OCCLUSION].get_rid());2301RD::get_singleton()->compute_list_bind_uniform_set(compute_list, occlusion_uniform_set, 0);2302for (int i = 0; i < 8; i++) {2303//dispatch all at once for performance2304Vector3i offset(i & 1, (i >> 1) & 1, (i >> 2) & 1);23052306if ((probe_global_pos.x & 1) != 0) {2307offset.x = (offset.x + 1) & 1;2308}2309if ((probe_global_pos.y & 1) != 0) {2310offset.y = (offset.y + 1) & 1;2311}2312if ((probe_global_pos.z & 1) != 0) {2313offset.z = (offset.z + 1) & 1;2314}2315push_constant.probe_offset[0] = offset.x;2316push_constant.probe_offset[1] = offset.y;2317push_constant.probe_offset[2] = offset.z;2318push_constant.occlusion_index = i;2319RD::get_singleton()->compute_list_set_push_constant(compute_list, &push_constant, sizeof(SDFGIShader::PreprocessPushConstant));23202321Vector3i groups = Vector3i(probe_size + 1, probe_size + 1, probe_size + 1) - offset; //if offset, it's one less probe per axis to compute2322RD::get_singleton()->compute_list_dispatch(compute_list, groups.x, groups.y, groups.z);2323}2324RD::get_singleton()->compute_list_add_barrier(compute_list);2325}23262327RENDER_TIMESTAMP("SDFGI Store");23282329// store2330RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, gi->sdfgi_shader.preprocess_pipeline[SDFGIShader::PRE_PROCESS_STORE].get_rid());2331RD::get_singleton()->compute_list_bind_uniform_set(compute_list, cascades[cascade].sdf_store_uniform_set, 0);2332RD::get_singleton()->compute_list_set_push_constant(compute_list, &push_constant, sizeof(SDFGIShader::PreprocessPushConstant));2333RD::get_singleton()->compute_list_dispatch_threads(compute_list, cascade_size, cascade_size, cascade_size);23342335RD::get_singleton()->compute_list_end();23362337//clear these textures, as they will have previous garbage on next draw2338RD::get_singleton()->texture_clear(cascades[cascade].light_tex, Color(0, 0, 0, 0), 0, 1, 0, 1);2339RD::get_singleton()->texture_clear(cascades[cascade].light_aniso_0_tex, Color(0, 0, 0, 0), 0, 1, 0, 1);2340RD::get_singleton()->texture_clear(cascades[cascade].light_aniso_1_tex, Color(0, 0, 0, 0), 0, 1, 0, 1);23412342#if 02343Vector<uint8_t> data = RD::get_singleton()->texture_get_data(cascades[cascade].sdf, 0);2344Ref<Image> img;2345img.instantiate();2346for (uint32_t i = 0; i < cascade_size; i++) {2347Vector<uint8_t> subarr = data.slice(128 * 128 * i, 128 * 128 * (i + 1));2348img->set_data(cascade_size, cascade_size, false, Image::FORMAT_L8, subarr);2349img->save_png("res://cascade_sdf_" + itos(cascade) + "_" + itos(i) + ".png");2350}23512352//finalize render and update sdf2353#endif23542355#if 02356Vector<uint8_t> data = RD::get_singleton()->texture_get_data(render_albedo, 0);2357Ref<Image> img;2358img.instantiate();2359for (uint32_t i = 0; i < cascade_size; i++) {2360Vector<uint8_t> subarr = data.slice(128 * 128 * i * 2, 128 * 128 * (i + 1) * 2);2361img->createcascade_size, cascade_size, false, Image::FORMAT_RGB565, subarr);2362img->convert(Image::FORMAT_RGBA8);2363img->save_png("res://cascade_" + itos(cascade) + "_" + itos(i) + ".png");2364}23652366//finalize render and update sdf2367#endif23682369RENDER_TIMESTAMP("< SDFGI Update SDF");2370RD::get_singleton()->draw_command_end_label();2371}2372}23732374void 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) {2375ERR_FAIL_COND(p_render_buffers.is_null()); // we wouldn't be here if this failed but...23762377RendererRD::LightStorage *light_storage = RendererRD::LightStorage::get_singleton();23782379RD::get_singleton()->draw_command_begin_label("SDFGI Render Static Lights");23802381update_cascades();23822383SDFGIShader::Light lights[SDFGI::MAX_STATIC_LIGHTS];2384uint32_t light_count[SDFGI::MAX_STATIC_LIGHTS];23852386for (uint32_t i = 0; i < p_cascade_count; i++) {2387ERR_CONTINUE(p_cascade_indices[i] >= cascades.size());23882389SDFGI::Cascade &cc = cascades[p_cascade_indices[i]];23902391{ //fill light buffer23922393AABB cascade_aabb;2394cascade_aabb.position = Vector3((Vector3i(1, 1, 1) * -int32_t(cascade_size >> 1) + cc.position)) * cc.cell_size;2395cascade_aabb.size = Vector3(1, 1, 1) * cascade_size * cc.cell_size;23962397int idx = 0;23982399for (uint32_t j = 0; j < (uint32_t)p_positional_light_cull_result[i].size(); j++) {2400if (idx == SDFGI::MAX_STATIC_LIGHTS) {2401break;2402}24032404RID light_instance = p_positional_light_cull_result[i][j];2405ERR_CONTINUE(!light_storage->owns_light_instance(light_instance));24062407RID light = light_storage->light_instance_get_base_light(light_instance);2408AABB light_aabb = light_storage->light_instance_get_base_aabb(light_instance);2409Transform3D light_transform = light_storage->light_instance_get_base_transform(light_instance);24102411uint32_t max_sdfgi_cascade = RSG::light_storage->light_get_max_sdfgi_cascade(light);2412if (p_cascade_indices[i] > max_sdfgi_cascade) {2413continue;2414}24152416if (!cascade_aabb.intersects(light_aabb)) {2417continue;2418}24192420lights[idx].type = RSG::light_storage->light_get_type(light);24212422Vector3 dir = -light_transform.basis.get_column(Vector3::AXIS_Z);2423if (lights[idx].type == RS::LIGHT_DIRECTIONAL) {2424dir.y *= y_mult; //only makes sense for directional2425dir.normalize();2426}2427lights[idx].direction[0] = dir.x;2428lights[idx].direction[1] = dir.y;2429lights[idx].direction[2] = dir.z;2430Vector3 pos = light_transform.origin;2431pos.y *= y_mult;2432lights[idx].position[0] = pos.x;2433lights[idx].position[1] = pos.y;2434lights[idx].position[2] = pos.z;2435Color color = RSG::light_storage->light_get_color(light);2436color = color.srgb_to_linear();2437lights[idx].color[0] = color.r;2438lights[idx].color[1] = color.g;2439lights[idx].color[2] = color.b;24402441lights[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);2442if (RendererSceneRenderRD::get_singleton()->is_using_physical_light_units()) {2443lights[idx].energy *= RSG::light_storage->light_get_param(light, RS::LIGHT_PARAM_INTENSITY);24442445// Convert from Luminous Power to Luminous Intensity2446if (lights[idx].type == RS::LIGHT_OMNI) {2447lights[idx].energy *= 1.0 / (Math::PI * 4.0);2448} else if (lights[idx].type == RS::LIGHT_SPOT) {2449// Spot Lights are not physically accurate, Luminous Intensity should change in relation to the cone angle.2450// We make this assumption to keep them easy to control.2451lights[idx].energy *= 1.0 / Math::PI;2452}2453}24542455if (p_render_data->camera_attributes.is_valid()) {2456lights[idx].energy *= RSG::camera_attributes->camera_attributes_get_exposure_normalization_factor(p_render_data->camera_attributes);2457}24582459lights[idx].has_shadow = RSG::light_storage->light_has_shadow(light);2460lights[idx].attenuation = RSG::light_storage->light_get_param(light, RS::LIGHT_PARAM_ATTENUATION);2461lights[idx].radius = RSG::light_storage->light_get_param(light, RS::LIGHT_PARAM_RANGE);2462lights[idx].cos_spot_angle = Math::cos(Math::deg_to_rad(RSG::light_storage->light_get_param(light, RS::LIGHT_PARAM_SPOT_ANGLE)));2463lights[idx].inv_spot_attenuation = 1.0f / RSG::light_storage->light_get_param(light, RS::LIGHT_PARAM_SPOT_ATTENUATION);24642465idx++;2466}24672468if (idx > 0) {2469RD::get_singleton()->buffer_update(cc.lights_buffer, 0, idx * sizeof(SDFGIShader::Light), lights);2470}24712472light_count[i] = idx;2473}2474}24752476for (uint32_t i = 0; i < p_cascade_count; i++) {2477ERR_CONTINUE(p_cascade_indices[i] >= cascades.size());24782479SDFGI::Cascade &cc = cascades[p_cascade_indices[i]];2480if (light_count[i] > 0) {2481RD::get_singleton()->buffer_copy(cc.solid_cell_dispatch_buffer_storage, cc.solid_cell_dispatch_buffer_call, 0, 0, sizeof(uint32_t) * 4);2482}2483}24842485/* Static Lights */2486RD::ComputeListID compute_list = RD::get_singleton()->compute_list_begin();24872488RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, gi->sdfgi_shader.direct_light_pipeline[SDFGIShader::DIRECT_LIGHT_MODE_STATIC].get_rid());24892490SDFGIShader::DirectLightPushConstant dl_push_constant;24912492dl_push_constant.grid_size[0] = cascade_size;2493dl_push_constant.grid_size[1] = cascade_size;2494dl_push_constant.grid_size[2] = cascade_size;2495dl_push_constant.max_cascades = cascades.size();2496dl_push_constant.probe_axis_size = probe_axis_count;2497dl_push_constant.bounce_feedback = 0.0; // this is static light, do not multibounce yet2498dl_push_constant.y_mult = y_mult;2499dl_push_constant.use_occlusion = uses_occlusion;25002501//all must be processed2502dl_push_constant.process_offset = 0;2503dl_push_constant.process_increment = 1;25042505for (uint32_t i = 0; i < p_cascade_count; i++) {2506ERR_CONTINUE(p_cascade_indices[i] >= cascades.size());25072508SDFGI::Cascade &cc = cascades[p_cascade_indices[i]];25092510dl_push_constant.light_count = light_count[i];2511dl_push_constant.cascade = p_cascade_indices[i];25122513if (dl_push_constant.light_count > 0) {2514RD::get_singleton()->compute_list_bind_uniform_set(compute_list, cc.sdf_direct_light_static_uniform_set, 0);2515RD::get_singleton()->compute_list_set_push_constant(compute_list, &dl_push_constant, sizeof(SDFGIShader::DirectLightPushConstant));2516RD::get_singleton()->compute_list_dispatch_indirect(compute_list, cc.solid_cell_dispatch_buffer_call, 0);2517}2518}25192520RD::get_singleton()->compute_list_end();25212522RD::get_singleton()->draw_command_end_label();2523}25242525////////////////////////////////////////////////////////////////////////////////2526// VoxelGIInstance25272528void GI::VoxelGIInstance::update(bool p_update_light_instances, const Vector<RID> &p_light_instances, const PagedArray<RenderGeometryInstance *> &p_dynamic_objects) {2529RendererRD::LightStorage *light_storage = RendererRD::LightStorage::get_singleton();2530RendererRD::MaterialStorage *material_storage = RendererRD::MaterialStorage::get_singleton();25312532uint32_t data_version = gi->voxel_gi_get_data_version(probe);25332534// (RE)CREATE IF NEEDED25352536if (last_probe_data_version != data_version) {2537//need to re-create everything2538free_resources();25392540Vector3i octree_size = gi->voxel_gi_get_octree_size(probe);25412542if (octree_size != Vector3i()) {2543//can create a 3D texture2544Vector<int> levels = gi->voxel_gi_get_level_counts(probe);25452546RD::TextureFormat tf;2547tf.format = RD::DATA_FORMAT_R8G8B8A8_UNORM;2548tf.width = octree_size.x;2549tf.height = octree_size.y;2550tf.depth = octree_size.z;2551tf.texture_type = RD::TEXTURE_TYPE_3D;2552tf.mipmaps = levels.size();25532554tf.usage_bits = RD::TEXTURE_USAGE_SAMPLING_BIT | RD::TEXTURE_USAGE_STORAGE_BIT | RD::TEXTURE_USAGE_CAN_COPY_TO_BIT;25552556texture = RD::get_singleton()->texture_create(tf, RD::TextureView());2557RD::get_singleton()->set_resource_name(texture, "VoxelGI Instance Texture");25582559RD::get_singleton()->texture_clear(texture, Color(0, 0, 0, 0), 0, levels.size(), 0, 1);25602561{2562int total_elements = 0;2563for (int i = 0; i < levels.size(); i++) {2564total_elements += levels[i];2565}25662567write_buffer = RD::get_singleton()->storage_buffer_create(total_elements * 16);2568}25692570for (int i = 0; i < levels.size(); i++) {2571VoxelGIInstance::Mipmap mipmap;2572mipmap.texture = RD::get_singleton()->texture_create_shared_from_slice(RD::TextureView(), texture, 0, i, 1, RD::TEXTURE_SLICE_3D);2573mipmap.level = levels.size() - i - 1;2574mipmap.cell_offset = 0;2575for (uint32_t j = 0; j < mipmap.level; j++) {2576mipmap.cell_offset += levels[j];2577}2578mipmap.cell_count = levels[mipmap.level];25792580Vector<RD::Uniform> uniforms;2581{2582RD::Uniform u;2583u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER;2584u.binding = 1;2585u.append_id(gi->voxel_gi_get_octree_buffer(probe));2586uniforms.push_back(u);2587}2588{2589RD::Uniform u;2590u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER;2591u.binding = 2;2592u.append_id(gi->voxel_gi_get_data_buffer(probe));2593uniforms.push_back(u);2594}25952596{2597RD::Uniform u;2598u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER;2599u.binding = 4;2600u.append_id(write_buffer);2601uniforms.push_back(u);2602}2603{2604RD::Uniform u;2605u.uniform_type = RD::UNIFORM_TYPE_TEXTURE;2606u.binding = 9;2607u.append_id(gi->voxel_gi_get_sdf_texture(probe));2608uniforms.push_back(u);2609}2610{2611RD::Uniform u;2612u.uniform_type = RD::UNIFORM_TYPE_SAMPLER;2613u.binding = 10;2614u.append_id(material_storage->sampler_rd_get_default(RS::CANVAS_ITEM_TEXTURE_FILTER_LINEAR_WITH_MIPMAPS, RS::CANVAS_ITEM_TEXTURE_REPEAT_DISABLED));2615uniforms.push_back(u);2616}26172618{2619Vector<RD::Uniform> copy_uniforms = uniforms;2620if (i == 0) {2621{2622RD::Uniform u;2623u.uniform_type = RD::UNIFORM_TYPE_UNIFORM_BUFFER;2624u.binding = 3;2625u.append_id(gi->voxel_gi_lights_uniform);2626copy_uniforms.push_back(u);2627}26282629mipmap.uniform_set = RD::get_singleton()->uniform_set_create(copy_uniforms, gi->voxel_gi_lighting_shader_version_shaders[VOXEL_GI_SHADER_VERSION_COMPUTE_LIGHT], 0);26302631copy_uniforms = uniforms; //restore26322633{2634RD::Uniform u;2635u.uniform_type = RD::UNIFORM_TYPE_TEXTURE;2636u.binding = 5;2637u.append_id(texture);2638copy_uniforms.push_back(u);2639}2640mipmap.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);2641} else {2642mipmap.uniform_set = RD::get_singleton()->uniform_set_create(copy_uniforms, gi->voxel_gi_lighting_shader_version_shaders[VOXEL_GI_SHADER_VERSION_COMPUTE_MIPMAP], 0);2643}2644}26452646{2647RD::Uniform u;2648u.uniform_type = RD::UNIFORM_TYPE_IMAGE;2649u.binding = 5;2650u.append_id(mipmap.texture);2651uniforms.push_back(u);2652}26532654mipmap.write_uniform_set = RD::get_singleton()->uniform_set_create(uniforms, gi->voxel_gi_lighting_shader_version_shaders[VOXEL_GI_SHADER_VERSION_WRITE_TEXTURE], 0);26552656mipmaps.push_back(mipmap);2657}26582659{2660uint32_t dynamic_map_size = MAX(MAX(octree_size.x, octree_size.y), octree_size.z);2661uint32_t oversample = nearest_power_of_2_templated(4);2662int mipmap_index = 0;26632664while (mipmap_index < mipmaps.size()) {2665VoxelGIInstance::DynamicMap dmap;26662667if (oversample > 0) {2668dmap.size = dynamic_map_size * (1 << oversample);2669dmap.mipmap = -1;2670oversample--;2671} else {2672dmap.size = dynamic_map_size >> mipmap_index;2673dmap.mipmap = mipmap_index;2674mipmap_index++;2675}26762677RD::TextureFormat dtf;2678dtf.width = dmap.size;2679dtf.height = dmap.size;2680dtf.format = RD::DATA_FORMAT_R16G16B16A16_SFLOAT;2681dtf.usage_bits = RD::TEXTURE_USAGE_STORAGE_BIT;26822683if (dynamic_maps.is_empty()) {2684dtf.usage_bits |= RD::TEXTURE_USAGE_COLOR_ATTACHMENT_BIT;2685}2686dmap.texture = RD::get_singleton()->texture_create(dtf, RD::TextureView());2687RD::get_singleton()->set_resource_name(dmap.texture, "VoxelGI Instance DMap Texture");26882689if (dynamic_maps.is_empty()) {2690// Render depth for first one.2691// Use 16-bit depth when supported to improve performance.2692dtf.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;2693dtf.usage_bits = RD::TEXTURE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT;2694dmap.fb_depth = RD::get_singleton()->texture_create(dtf, RD::TextureView());2695RD::get_singleton()->set_resource_name(dmap.fb_depth, "VoxelGI Instance DMap FB Depth");2696}26972698//just use depth as-is2699dtf.format = RD::DATA_FORMAT_R32_SFLOAT;2700dtf.usage_bits = RD::TEXTURE_USAGE_STORAGE_BIT | RD::TEXTURE_USAGE_COLOR_ATTACHMENT_BIT;27012702dmap.depth = RD::get_singleton()->texture_create(dtf, RD::TextureView());2703RD::get_singleton()->set_resource_name(dmap.depth, "VoxelGI Instance DMap Depth");27042705if (dynamic_maps.is_empty()) {2706dtf.format = RD::DATA_FORMAT_R8G8B8A8_UNORM;2707dtf.usage_bits = RD::TEXTURE_USAGE_STORAGE_BIT | RD::TEXTURE_USAGE_COLOR_ATTACHMENT_BIT;2708dmap.albedo = RD::get_singleton()->texture_create(dtf, RD::TextureView());2709RD::get_singleton()->set_resource_name(dmap.albedo, "VoxelGI Instance DMap Albedo");2710dmap.normal = RD::get_singleton()->texture_create(dtf, RD::TextureView());2711RD::get_singleton()->set_resource_name(dmap.normal, "VoxelGI Instance DMap Normal");2712dmap.orm = RD::get_singleton()->texture_create(dtf, RD::TextureView());2713RD::get_singleton()->set_resource_name(dmap.orm, "VoxelGI Instance DMap ORM");27142715Vector<RID> fb;2716fb.push_back(dmap.albedo);2717fb.push_back(dmap.normal);2718fb.push_back(dmap.orm);2719fb.push_back(dmap.texture); //emission2720fb.push_back(dmap.depth);2721fb.push_back(dmap.fb_depth);27222723dmap.fb = RD::get_singleton()->framebuffer_create(fb);27242725{2726Vector<RD::Uniform> uniforms;2727{2728RD::Uniform u;2729u.uniform_type = RD::UNIFORM_TYPE_UNIFORM_BUFFER;2730u.binding = 3;2731u.append_id(gi->voxel_gi_lights_uniform);2732uniforms.push_back(u);2733}27342735{2736RD::Uniform u;2737u.uniform_type = RD::UNIFORM_TYPE_IMAGE;2738u.binding = 5;2739u.append_id(dmap.albedo);2740uniforms.push_back(u);2741}2742{2743RD::Uniform u;2744u.uniform_type = RD::UNIFORM_TYPE_IMAGE;2745u.binding = 6;2746u.append_id(dmap.normal);2747uniforms.push_back(u);2748}2749{2750RD::Uniform u;2751u.uniform_type = RD::UNIFORM_TYPE_IMAGE;2752u.binding = 7;2753u.append_id(dmap.orm);2754uniforms.push_back(u);2755}2756{2757RD::Uniform u;2758u.uniform_type = RD::UNIFORM_TYPE_TEXTURE;2759u.binding = 8;2760u.append_id(dmap.fb_depth);2761uniforms.push_back(u);2762}2763{2764RD::Uniform u;2765u.uniform_type = RD::UNIFORM_TYPE_TEXTURE;2766u.binding = 9;2767u.append_id(gi->voxel_gi_get_sdf_texture(probe));2768uniforms.push_back(u);2769}2770{2771RD::Uniform u;2772u.uniform_type = RD::UNIFORM_TYPE_SAMPLER;2773u.binding = 10;2774u.append_id(material_storage->sampler_rd_get_default(RS::CANVAS_ITEM_TEXTURE_FILTER_LINEAR_WITH_MIPMAPS, RS::CANVAS_ITEM_TEXTURE_REPEAT_DISABLED));2775uniforms.push_back(u);2776}2777{2778RD::Uniform u;2779u.uniform_type = RD::UNIFORM_TYPE_IMAGE;2780u.binding = 11;2781u.append_id(dmap.texture);2782uniforms.push_back(u);2783}2784{2785RD::Uniform u;2786u.uniform_type = RD::UNIFORM_TYPE_IMAGE;2787u.binding = 12;2788u.append_id(dmap.depth);2789uniforms.push_back(u);2790}27912792dmap.uniform_set = RD::get_singleton()->uniform_set_create(uniforms, gi->voxel_gi_lighting_shader_version_shaders[VOXEL_GI_SHADER_VERSION_DYNAMIC_OBJECT_LIGHTING], 0);2793}2794} else {2795bool plot = dmap.mipmap >= 0;2796bool write = dmap.mipmap < (mipmaps.size() - 1);27972798Vector<RD::Uniform> uniforms;27992800{2801RD::Uniform u;2802u.uniform_type = RD::UNIFORM_TYPE_IMAGE;2803u.binding = 5;2804u.append_id(dynamic_maps[dynamic_maps.size() - 1].texture);2805uniforms.push_back(u);2806}2807{2808RD::Uniform u;2809u.uniform_type = RD::UNIFORM_TYPE_IMAGE;2810u.binding = 6;2811u.append_id(dynamic_maps[dynamic_maps.size() - 1].depth);2812uniforms.push_back(u);2813}28142815if (write) {2816{2817RD::Uniform u;2818u.uniform_type = RD::UNIFORM_TYPE_IMAGE;2819u.binding = 7;2820u.append_id(dmap.texture);2821uniforms.push_back(u);2822}2823{2824RD::Uniform u;2825u.uniform_type = RD::UNIFORM_TYPE_IMAGE;2826u.binding = 8;2827u.append_id(dmap.depth);2828uniforms.push_back(u);2829}2830}28312832{2833RD::Uniform u;2834u.uniform_type = RD::UNIFORM_TYPE_TEXTURE;2835u.binding = 9;2836u.append_id(gi->voxel_gi_get_sdf_texture(probe));2837uniforms.push_back(u);2838}2839{2840RD::Uniform u;2841u.uniform_type = RD::UNIFORM_TYPE_SAMPLER;2842u.binding = 10;2843u.append_id(material_storage->sampler_rd_get_default(RS::CANVAS_ITEM_TEXTURE_FILTER_LINEAR_WITH_MIPMAPS, RS::CANVAS_ITEM_TEXTURE_REPEAT_DISABLED));2844uniforms.push_back(u);2845}28462847if (plot) {2848{2849RD::Uniform u;2850u.uniform_type = RD::UNIFORM_TYPE_IMAGE;2851u.binding = 11;2852u.append_id(mipmaps[dmap.mipmap].texture);2853uniforms.push_back(u);2854}2855}28562857dmap.uniform_set = RD::get_singleton()->uniform_set_create(2858uniforms,2859gi->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)],28600);2861}28622863dynamic_maps.push_back(dmap);2864}2865}2866}28672868last_probe_data_version = data_version;2869p_update_light_instances = true; //just in case28702871RendererSceneRenderRD::get_singleton()->base_uniforms_changed();2872}28732874// UDPDATE TIME28752876if (has_dynamic_object_data) {2877//if it has dynamic object data, it needs to be cleared2878RD::get_singleton()->texture_clear(texture, Color(0, 0, 0, 0), 0, mipmaps.size(), 0, 1);2879}28802881uint32_t light_count = 0;28822883if (p_update_light_instances || p_dynamic_objects.size() > 0) {2884light_count = MIN(gi->voxel_gi_max_lights, (uint32_t)p_light_instances.size());28852886{2887Transform3D to_cell = gi->voxel_gi_get_to_cell_xform(probe);2888Transform3D to_probe_xform = to_cell * transform.affine_inverse();28892890//update lights28912892for (uint32_t i = 0; i < light_count; i++) {2893VoxelGILight &l = gi->voxel_gi_lights[i];2894RID light_instance = p_light_instances[i];2895RID light = light_storage->light_instance_get_base_light(light_instance);28962897l.type = RSG::light_storage->light_get_type(light);2898if (l.type == RS::LIGHT_DIRECTIONAL && RSG::light_storage->light_directional_get_sky_mode(light) == RS::LIGHT_DIRECTIONAL_SKY_MODE_SKY_ONLY) {2899light_count--;2900continue;2901}29022903l.attenuation = RSG::light_storage->light_get_param(light, RS::LIGHT_PARAM_ATTENUATION);2904l.energy = RSG::light_storage->light_get_param(light, RS::LIGHT_PARAM_ENERGY) * RSG::light_storage->light_get_param(light, RS::LIGHT_PARAM_INDIRECT_ENERGY);29052906if (RendererSceneRenderRD::get_singleton()->is_using_physical_light_units()) {2907l.energy *= RSG::light_storage->light_get_param(light, RS::LIGHT_PARAM_INTENSITY);29082909l.energy *= gi->voxel_gi_get_baked_exposure_normalization(probe);29102911// Convert from Luminous Power to Luminous Intensity2912if (l.type == RS::LIGHT_OMNI) {2913l.energy *= 1.0 / (Math::PI * 4.0);2914} else if (l.type == RS::LIGHT_SPOT) {2915// Spot Lights are not physically accurate, Luminous Intensity should change in relation to the cone angle.2916// We make this assumption to keep them easy to control.2917l.energy *= 1.0 / Math::PI;2918}2919}29202921l.radius = to_cell.basis.xform(Vector3(RSG::light_storage->light_get_param(light, RS::LIGHT_PARAM_RANGE), 0, 0)).length();2922Color color = RSG::light_storage->light_get_color(light).srgb_to_linear();2923l.color[0] = color.r;2924l.color[1] = color.g;2925l.color[2] = color.b;29262927l.cos_spot_angle = Math::cos(Math::deg_to_rad(RSG::light_storage->light_get_param(light, RS::LIGHT_PARAM_SPOT_ANGLE)));2928l.inv_spot_attenuation = 1.0f / RSG::light_storage->light_get_param(light, RS::LIGHT_PARAM_SPOT_ATTENUATION);29292930Transform3D xform = light_storage->light_instance_get_base_transform(light_instance);29312932Vector3 pos = to_probe_xform.xform(xform.origin);2933Vector3 dir = to_probe_xform.basis.xform(-xform.basis.get_column(2)).normalized();29342935l.position[0] = pos.x;2936l.position[1] = pos.y;2937l.position[2] = pos.z;29382939l.direction[0] = dir.x;2940l.direction[1] = dir.y;2941l.direction[2] = dir.z;29422943l.has_shadow = RSG::light_storage->light_has_shadow(light);2944}29452946RD::get_singleton()->buffer_update(gi->voxel_gi_lights_uniform, 0, sizeof(VoxelGILight) * light_count, gi->voxel_gi_lights);2947}2948}29492950if (has_dynamic_object_data || p_update_light_instances || p_dynamic_objects.size()) {2951// PROCESS MIPMAPS2952if (mipmaps.size()) {2953//can update mipmaps29542955Vector3i probe_size = gi->voxel_gi_get_octree_size(probe);29562957Vector3 ps = probe_size / gi->voxel_gi_get_bounds(probe).size;2958float cell_size = (1.0 / MAX(MAX(ps.x, ps.y), ps.z)); // probe size relative to 1 unit in world space29592960VoxelGIPushConstant push_constant;29612962push_constant.limits[0] = probe_size.x;2963push_constant.limits[1] = probe_size.y;2964push_constant.limits[2] = probe_size.z;2965push_constant.stack_size = mipmaps.size();2966push_constant.emission_scale = 1.0;2967push_constant.propagation = gi->voxel_gi_get_propagation(probe);2968push_constant.dynamic_range = gi->voxel_gi_get_dynamic_range(probe);2969push_constant.light_count = light_count;2970push_constant.aniso_strength = 0;2971push_constant.cell_size = cell_size;29722973/* print_line("probe update to version " + itos(last_probe_version));2974print_line("propagation " + rtos(push_constant.propagation));2975print_line("dynrange " + rtos(push_constant.dynamic_range));2976*/2977RD::ComputeListID compute_list = RD::get_singleton()->compute_list_begin();29782979int passes;2980if (p_update_light_instances) {2981passes = gi->voxel_gi_is_using_two_bounces(probe) ? 2 : 1;2982} else {2983passes = 1; //only re-blitting is necessary2984}2985int wg_size = 64;2986int64_t wg_limit_x = (int64_t)RD::get_singleton()->limit_get(RD::LIMIT_MAX_COMPUTE_WORKGROUP_COUNT_X);29872988for (int pass = 0; pass < passes; pass++) {2989if (p_update_light_instances) {2990for (int i = 0; i < mipmaps.size(); i++) {2991if (i == 0) {2992RD::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].get_rid());2993} else if (i == 1) {2994RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, gi->voxel_gi_lighting_shader_version_pipelines[VOXEL_GI_SHADER_VERSION_COMPUTE_MIPMAP].get_rid());2995}29962997if (pass == 1 || i > 0) {2998RD::get_singleton()->compute_list_add_barrier(compute_list); //wait til previous step is done2999}3000if (pass == 0 || i > 0) {3001RD::get_singleton()->compute_list_bind_uniform_set(compute_list, mipmaps[i].uniform_set, 0);3002} else {3003RD::get_singleton()->compute_list_bind_uniform_set(compute_list, mipmaps[i].second_bounce_uniform_set, 0);3004}30053006push_constant.cell_offset = mipmaps[i].cell_offset;3007push_constant.cell_count = mipmaps[i].cell_count;30083009int64_t wg_todo = (mipmaps[i].cell_count + wg_size - 1) / wg_size;3010while (wg_todo) {3011int64_t wg_count = MIN(wg_todo, wg_limit_x);3012RD::get_singleton()->compute_list_set_push_constant(compute_list, &push_constant, sizeof(VoxelGIPushConstant));3013RD::get_singleton()->compute_list_dispatch(compute_list, wg_count, 1, 1);3014wg_todo -= wg_count;3015push_constant.cell_offset += wg_count * wg_size;3016}3017}30183019RD::get_singleton()->compute_list_add_barrier(compute_list); //wait til previous step is done3020}30213022RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, gi->voxel_gi_lighting_shader_version_pipelines[VOXEL_GI_SHADER_VERSION_WRITE_TEXTURE].get_rid());30233024for (int i = 0; i < mipmaps.size(); i++) {3025RD::get_singleton()->compute_list_bind_uniform_set(compute_list, mipmaps[i].write_uniform_set, 0);30263027push_constant.cell_offset = mipmaps[i].cell_offset;3028push_constant.cell_count = mipmaps[i].cell_count;30293030int64_t wg_todo = (mipmaps[i].cell_count + wg_size - 1) / wg_size;3031while (wg_todo) {3032int64_t wg_count = MIN(wg_todo, wg_limit_x);3033RD::get_singleton()->compute_list_set_push_constant(compute_list, &push_constant, sizeof(VoxelGIPushConstant));3034RD::get_singleton()->compute_list_dispatch(compute_list, wg_count, 1, 1);3035wg_todo -= wg_count;3036push_constant.cell_offset += wg_count * wg_size;3037}3038}3039}30403041RD::get_singleton()->compute_list_end();3042}3043}30443045has_dynamic_object_data = false; //clear until dynamic object data is used again30463047if (p_dynamic_objects.size() && dynamic_maps.size()) {3048Vector3i octree_size = gi->voxel_gi_get_octree_size(probe);3049int multiplier = dynamic_maps[0].size / MAX(MAX(octree_size.x, octree_size.y), octree_size.z);30503051Transform3D oversample_scale;3052oversample_scale.basis.scale(Vector3(multiplier, multiplier, multiplier));30533054Transform3D to_cell = oversample_scale * gi->voxel_gi_get_to_cell_xform(probe);3055Transform3D to_world_xform = transform * to_cell.affine_inverse();3056Transform3D to_probe_xform = to_world_xform.affine_inverse();30573058AABB probe_aabb(Vector3(), octree_size);30593060//this could probably be better parallelized in compute..3061for (int i = 0; i < (int)p_dynamic_objects.size(); i++) {3062RenderGeometryInstance *instance = p_dynamic_objects[i];30633064//transform aabb to voxel_gi3065AABB aabb = (to_probe_xform * instance->get_transform()).xform(instance->get_aabb());30663067//this needs to wrap to grid resolution to avoid jitter3068//also extend margin a bit just in case3069Vector3i begin = aabb.position - Vector3i(1, 1, 1);3070Vector3i end = aabb.position + aabb.size + Vector3i(1, 1, 1);30713072for (int j = 0; j < 3; j++) {3073if ((end[j] - begin[j]) & 1) {3074end[j]++; //for half extents split, it needs to be even3075}3076begin[j] = MAX(begin[j], 0);3077end[j] = MIN(end[j], octree_size[j] * multiplier);3078}30793080//aabb = aabb.intersection(probe_aabb); //intersect3081aabb.position = begin;3082aabb.size = end - begin;30833084//print_line("aabb: " + aabb);30853086for (int j = 0; j < 6; j++) {3087//if (j != 0 && j != 3) {3088// continue;3089//}3090static const Vector3 render_z[6] = {3091Vector3(1, 0, 0),3092Vector3(0, 1, 0),3093Vector3(0, 0, 1),3094Vector3(-1, 0, 0),3095Vector3(0, -1, 0),3096Vector3(0, 0, -1),3097};3098static const Vector3 render_up[6] = {3099Vector3(0, 1, 0),3100Vector3(0, 0, 1),3101Vector3(0, 1, 0),3102Vector3(0, 1, 0),3103Vector3(0, 0, 1),3104Vector3(0, 1, 0),3105};31063107Vector3 render_dir = render_z[j];3108Vector3 up_dir = render_up[j];31093110Vector3 center = aabb.get_center();3111Transform3D xform;3112xform.set_look_at(center - aabb.size * 0.5 * render_dir, center, up_dir);31133114Vector3 x_dir = xform.basis.get_column(0).abs();3115int x_axis = int(Vector3(0, 1, 2).dot(x_dir));3116Vector3 y_dir = xform.basis.get_column(1).abs();3117int y_axis = int(Vector3(0, 1, 2).dot(y_dir));3118Vector3 z_dir = -xform.basis.get_column(2);3119int z_axis = int(Vector3(0, 1, 2).dot(z_dir.abs()));31203121Rect2i rect(aabb.position[x_axis], aabb.position[y_axis], aabb.size[x_axis], aabb.size[y_axis]);3122bool x_flip = bool(Vector3(1, 1, 1).dot(xform.basis.get_column(0)) < 0);3123bool y_flip = bool(Vector3(1, 1, 1).dot(xform.basis.get_column(1)) < 0);3124bool z_flip = bool(Vector3(1, 1, 1).dot(xform.basis.get_column(2)) > 0);31253126Projection cm;3127cm.set_orthogonal(-rect.size.width / 2, rect.size.width / 2, -rect.size.height / 2, rect.size.height / 2, 0.0001, aabb.size[z_axis]);31283129if (RendererSceneRenderRD::get_singleton()->cull_argument.size() == 0) {3130RendererSceneRenderRD::get_singleton()->cull_argument.push_back(nullptr);3131}3132RendererSceneRenderRD::get_singleton()->cull_argument[0] = instance;31333134float exposure_normalization = 1.0;3135if (RendererSceneRenderRD::get_singleton()->is_using_physical_light_units()) {3136exposure_normalization = gi->voxel_gi_get_baked_exposure_normalization(probe);3137}31383139RendererSceneRenderRD::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);31403141Vector3 ps = octree_size / gi->voxel_gi_get_bounds(probe).size;3142float cell_size = (1.0 / MAX(MAX(ps.x, ps.y), ps.z)); // probe size relative to 1 unit in world space31433144VoxelGIDynamicPushConstant push_constant;3145memset(&push_constant, 0, sizeof(VoxelGIDynamicPushConstant));3146push_constant.limits[0] = octree_size.x;3147push_constant.limits[1] = octree_size.y;3148push_constant.limits[2] = octree_size.z;3149push_constant.light_count = p_light_instances.size();3150push_constant.x_dir[0] = x_dir[0];3151push_constant.x_dir[1] = x_dir[1];3152push_constant.x_dir[2] = x_dir[2];3153push_constant.y_dir[0] = y_dir[0];3154push_constant.y_dir[1] = y_dir[1];3155push_constant.y_dir[2] = y_dir[2];3156push_constant.z_dir[0] = z_dir[0];3157push_constant.z_dir[1] = z_dir[1];3158push_constant.z_dir[2] = z_dir[2];3159push_constant.z_base = xform.origin[z_axis];3160push_constant.z_sign = (z_flip ? -1.0 : 1.0);3161push_constant.pos_multiplier = float(1.0) / multiplier;3162push_constant.dynamic_range = gi->voxel_gi_get_dynamic_range(probe);3163push_constant.flip_x = x_flip;3164push_constant.flip_y = y_flip;3165push_constant.rect_pos[0] = rect.position[0];3166push_constant.rect_pos[1] = rect.position[1];3167push_constant.rect_size[0] = rect.size[0];3168push_constant.rect_size[1] = rect.size[1];3169push_constant.prev_rect_ofs[0] = 0;3170push_constant.prev_rect_ofs[1] = 0;3171push_constant.prev_rect_size[0] = 0;3172push_constant.prev_rect_size[1] = 0;3173push_constant.on_mipmap = false;3174push_constant.propagation = gi->voxel_gi_get_propagation(probe);3175push_constant.cell_size = cell_size;3176push_constant.pad[0] = 0;3177push_constant.pad[1] = 0;31783179//process lighting3180RD::ComputeListID compute_list = RD::get_singleton()->compute_list_begin();3181RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, gi->voxel_gi_lighting_shader_version_pipelines[VOXEL_GI_SHADER_VERSION_DYNAMIC_OBJECT_LIGHTING].get_rid());3182RD::get_singleton()->compute_list_bind_uniform_set(compute_list, dynamic_maps[0].uniform_set, 0);3183RD::get_singleton()->compute_list_set_push_constant(compute_list, &push_constant, sizeof(VoxelGIDynamicPushConstant));3184RD::get_singleton()->compute_list_dispatch(compute_list, Math::division_round_up(rect.size.x, 8), Math::division_round_up(rect.size.y, 8), 1);3185//print_line("rect: " + itos(i) + ": " + rect);31863187for (int k = 1; k < dynamic_maps.size(); k++) {3188// enlarge the rect if needed so all pixels fit when downscaled,3189// this ensures downsampling is smooth and optimal because no pixels are left behind31903191//x3192if (rect.position.x & 1) {3193rect.size.x++;3194push_constant.prev_rect_ofs[0] = 1; //this is used to ensure reading is also optimal3195} else {3196push_constant.prev_rect_ofs[0] = 0;3197}3198if (rect.size.x & 1) {3199rect.size.x++;3200}32013202rect.position.x >>= 1;3203rect.size.x = MAX(1, rect.size.x >> 1);32043205//y3206if (rect.position.y & 1) {3207rect.size.y++;3208push_constant.prev_rect_ofs[1] = 1;3209} else {3210push_constant.prev_rect_ofs[1] = 0;3211}3212if (rect.size.y & 1) {3213rect.size.y++;3214}32153216rect.position.y >>= 1;3217rect.size.y = MAX(1, rect.size.y >> 1);32183219//shrink limits to ensure plot does not go outside map3220if (dynamic_maps[k].mipmap > 0) {3221for (int l = 0; l < 3; l++) {3222push_constant.limits[l] = MAX(1, push_constant.limits[l] >> 1);3223}3224}32253226//print_line("rect: " + itos(i) + ": " + rect);3227push_constant.rect_pos[0] = rect.position[0];3228push_constant.rect_pos[1] = rect.position[1];3229push_constant.prev_rect_size[0] = push_constant.rect_size[0];3230push_constant.prev_rect_size[1] = push_constant.rect_size[1];3231push_constant.rect_size[0] = rect.size[0];3232push_constant.rect_size[1] = rect.size[1];3233push_constant.on_mipmap = dynamic_maps[k].mipmap > 0;32343235RD::get_singleton()->compute_list_add_barrier(compute_list);32363237if (dynamic_maps[k].mipmap < 0) {3238RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, gi->voxel_gi_lighting_shader_version_pipelines[VOXEL_GI_SHADER_VERSION_DYNAMIC_SHRINK_WRITE].get_rid());3239} else if (k < dynamic_maps.size() - 1) {3240RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, gi->voxel_gi_lighting_shader_version_pipelines[VOXEL_GI_SHADER_VERSION_DYNAMIC_SHRINK_WRITE_PLOT].get_rid());3241} else {3242RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, gi->voxel_gi_lighting_shader_version_pipelines[VOXEL_GI_SHADER_VERSION_DYNAMIC_SHRINK_PLOT].get_rid());3243}3244RD::get_singleton()->compute_list_bind_uniform_set(compute_list, dynamic_maps[k].uniform_set, 0);3245RD::get_singleton()->compute_list_set_push_constant(compute_list, &push_constant, sizeof(VoxelGIDynamicPushConstant));3246RD::get_singleton()->compute_list_dispatch(compute_list, Math::division_round_up(rect.size.x, 8), Math::division_round_up(rect.size.y, 8), 1);3247}32483249RD::get_singleton()->compute_list_end();3250}3251}32523253has_dynamic_object_data = true; //clear until dynamic object data is used again3254}32553256last_probe_version = gi->voxel_gi_get_version(probe);3257}32583259void GI::VoxelGIInstance::free_resources() {3260if (texture.is_valid()) {3261RD::get_singleton()->free_rid(texture);3262RD::get_singleton()->free_rid(write_buffer);32633264texture = RID();3265write_buffer = RID();3266mipmaps.clear();3267}32683269for (int i = 0; i < dynamic_maps.size(); i++) {3270RD::get_singleton()->free_rid(dynamic_maps[i].texture);3271RD::get_singleton()->free_rid(dynamic_maps[i].depth);32723273// these only exist on the first level...3274if (dynamic_maps[i].fb_depth.is_valid()) {3275RD::get_singleton()->free_rid(dynamic_maps[i].fb_depth);3276}3277if (dynamic_maps[i].albedo.is_valid()) {3278RD::get_singleton()->free_rid(dynamic_maps[i].albedo);3279}3280if (dynamic_maps[i].normal.is_valid()) {3281RD::get_singleton()->free_rid(dynamic_maps[i].normal);3282}3283if (dynamic_maps[i].orm.is_valid()) {3284RD::get_singleton()->free_rid(dynamic_maps[i].orm);3285}3286}3287dynamic_maps.clear();3288}32893290void 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) {3291RendererRD::MaterialStorage *material_storage = RendererRD::MaterialStorage::get_singleton();32923293if (mipmaps.is_empty()) {3294return;3295}32963297Projection cam_transform = (p_camera_with_transform * Projection(transform)) * Projection(gi->voxel_gi_get_to_cell_xform(probe).affine_inverse());32983299int level = 0;3300Vector3i octree_size = gi->voxel_gi_get_octree_size(probe);33013302VoxelGIDebugPushConstant push_constant;3303push_constant.alpha = p_alpha;3304push_constant.dynamic_range = gi->voxel_gi_get_dynamic_range(probe);3305push_constant.cell_offset = mipmaps[level].cell_offset;3306push_constant.level = level;33073308push_constant.bounds[0] = octree_size.x >> level;3309push_constant.bounds[1] = octree_size.y >> level;3310push_constant.bounds[2] = octree_size.z >> level;3311push_constant.pad = 0;33123313for (int i = 0; i < 4; i++) {3314for (int j = 0; j < 4; j++) {3315push_constant.projection[i * 4 + j] = cam_transform.columns[i][j];3316}3317}33183319if (gi->voxel_gi_debug_uniform_set.is_valid()) {3320RD::get_singleton()->free_rid(gi->voxel_gi_debug_uniform_set);3321}3322Vector<RD::Uniform> uniforms;3323{3324RD::Uniform u;3325u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER;3326u.binding = 1;3327u.append_id(gi->voxel_gi_get_data_buffer(probe));3328uniforms.push_back(u);3329}3330{3331RD::Uniform u;3332u.uniform_type = RD::UNIFORM_TYPE_TEXTURE;3333u.binding = 2;3334u.append_id(texture);3335uniforms.push_back(u);3336}3337{3338RD::Uniform u;3339u.uniform_type = RD::UNIFORM_TYPE_SAMPLER;3340u.binding = 3;3341u.append_id(material_storage->sampler_rd_get_default(RS::CANVAS_ITEM_TEXTURE_FILTER_NEAREST, RS::CANVAS_ITEM_TEXTURE_REPEAT_DISABLED));3342uniforms.push_back(u);3343}33443345int cell_count;3346if (!p_emission && p_lighting && has_dynamic_object_data) {3347cell_count = push_constant.bounds[0] * push_constant.bounds[1] * push_constant.bounds[2];3348} else {3349cell_count = mipmaps[level].cell_count;3350}33513352gi->voxel_gi_debug_uniform_set = RD::get_singleton()->uniform_set_create(uniforms, gi->voxel_gi_debug_shader_version_shaders[0], 0);33533354int voxel_gi_debug_pipeline = VOXEL_GI_DEBUG_COLOR;3355if (p_emission) {3356voxel_gi_debug_pipeline = VOXEL_GI_DEBUG_EMISSION;3357} else if (p_lighting) {3358voxel_gi_debug_pipeline = has_dynamic_object_data ? VOXEL_GI_DEBUG_LIGHT_FULL : VOXEL_GI_DEBUG_LIGHT;3359}3360RD::get_singleton()->draw_list_bind_render_pipeline(3361p_draw_list,3362gi->voxel_gi_debug_shader_version_pipelines[voxel_gi_debug_pipeline].get_render_pipeline(RD::INVALID_ID, RD::get_singleton()->framebuffer_get_format(p_framebuffer)));3363RD::get_singleton()->draw_list_bind_uniform_set(p_draw_list, gi->voxel_gi_debug_uniform_set, 0);3364RD::get_singleton()->draw_list_set_push_constant(p_draw_list, &push_constant, sizeof(VoxelGIDebugPushConstant));3365RD::get_singleton()->draw_list_draw(p_draw_list, false, cell_count, 36);3366}33673368////////////////////////////////////////////////////////////////////////////////3369// GI33703371GI::GI() {3372singleton = this;33733374sdfgi_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)));3375sdfgi_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)));3376sdfgi_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)));3377}33783379GI::~GI() {3380for (int v = 0; v < SHADER_SPECIALIZATION_VARIATIONS; v++) {3381for (int i = 0; i < MODE_MAX; i++) {3382pipelines[v][i].free();3383}3384}33853386sdfgi_shader.debug_pipeline.free();33873388for (int i = 0; i < SDFGIShader::DIRECT_LIGHT_MODE_MAX; i++) {3389sdfgi_shader.direct_light_pipeline[i].free();3390}33913392for (int i = 0; i < SDFGIShader::INTEGRATE_MODE_MAX; i++) {3393sdfgi_shader.integrate_pipeline[i].free();3394}33953396for (int i = 0; i < SDFGIShader::PRE_PROCESS_MAX; i++) {3397sdfgi_shader.preprocess_pipeline[i].free();3398}33993400for (int i = 0; i < VOXEL_GI_SHADER_VERSION_MAX; i++) {3401voxel_gi_lighting_shader_version_pipelines[i].free();3402}34033404if (voxel_gi_debug_shader_version.is_valid()) {3405voxel_gi_debug_shader.version_free(voxel_gi_debug_shader_version);3406}3407if (voxel_gi_lighting_shader_version.is_valid()) {3408voxel_gi_shader.version_free(voxel_gi_lighting_shader_version);3409}3410if (shader_version.is_valid()) {3411shader.version_free(shader_version);3412}3413if (sdfgi_shader.debug_probes_shader.is_valid()) {3414sdfgi_shader.debug_probes.version_free(sdfgi_shader.debug_probes_shader);3415}3416if (sdfgi_shader.debug_shader.is_valid()) {3417sdfgi_shader.debug.version_free(sdfgi_shader.debug_shader);3418}3419if (sdfgi_shader.direct_light_shader.is_valid()) {3420sdfgi_shader.direct_light.version_free(sdfgi_shader.direct_light_shader);3421}3422if (sdfgi_shader.integrate_shader.is_valid()) {3423sdfgi_shader.integrate.version_free(sdfgi_shader.integrate_shader);3424}3425if (sdfgi_shader.preprocess_shader.is_valid()) {3426sdfgi_shader.preprocess.version_free(sdfgi_shader.preprocess_shader);3427}34283429singleton = nullptr;3430}34313432void GI::init(SkyRD *p_sky) {3433RendererRD::TextureStorage *texture_storage = RendererRD::TextureStorage::get_singleton();3434RendererRD::MaterialStorage *material_storage = RendererRD::MaterialStorage::get_singleton();34353436/* GI */34373438{3439//kinda complicated to compute the amount of slots, we try to use as many as we can34403441voxel_gi_lights = memnew_arr(VoxelGILight, voxel_gi_max_lights);3442voxel_gi_lights_uniform = RD::get_singleton()->uniform_buffer_create(voxel_gi_max_lights * sizeof(VoxelGILight));3443voxel_gi_quality = RS::VoxelGIQuality(CLAMP(int(GLOBAL_GET("rendering/global_illumination/voxel_gi/quality")), 0, 1));34443445String defines = "\n#define MAX_LIGHTS " + itos(voxel_gi_max_lights) + "\n";34463447Vector<String> versions;3448versions.push_back("\n#define MODE_COMPUTE_LIGHT\n");3449versions.push_back("\n#define MODE_SECOND_BOUNCE\n");3450versions.push_back("\n#define MODE_UPDATE_MIPMAPS\n");3451versions.push_back("\n#define MODE_WRITE_TEXTURE\n");3452versions.push_back("\n#define MODE_DYNAMIC\n#define MODE_DYNAMIC_LIGHTING\n");3453versions.push_back("\n#define MODE_DYNAMIC\n#define MODE_DYNAMIC_SHRINK\n#define MODE_DYNAMIC_SHRINK_WRITE\n");3454versions.push_back("\n#define MODE_DYNAMIC\n#define MODE_DYNAMIC_SHRINK\n#define MODE_DYNAMIC_SHRINK_PLOT\n");3455versions.push_back("\n#define MODE_DYNAMIC\n#define MODE_DYNAMIC_SHRINK\n#define MODE_DYNAMIC_SHRINK_PLOT\n#define MODE_DYNAMIC_SHRINK_WRITE\n");34563457voxel_gi_shader.initialize(versions, defines);3458voxel_gi_lighting_shader_version = voxel_gi_shader.version_create();3459for (int i = 0; i < VOXEL_GI_SHADER_VERSION_MAX; i++) {3460voxel_gi_lighting_shader_version_shaders[i] = voxel_gi_shader.version_get_shader(voxel_gi_lighting_shader_version, i);3461voxel_gi_lighting_shader_version_pipelines[i].create_compute_pipeline(voxel_gi_lighting_shader_version_shaders[i]);3462}3463}34643465{3466String defines;3467Vector<String> versions;3468versions.push_back("\n#define MODE_DEBUG_COLOR\n");3469versions.push_back("\n#define MODE_DEBUG_LIGHT\n");3470versions.push_back("\n#define MODE_DEBUG_EMISSION\n");3471versions.push_back("\n#define MODE_DEBUG_LIGHT\n#define MODE_DEBUG_LIGHT_FULL\n");34723473voxel_gi_debug_shader.initialize(versions, defines);3474voxel_gi_debug_shader_version = voxel_gi_debug_shader.version_create();3475for (int i = 0; i < VOXEL_GI_DEBUG_MAX; i++) {3476voxel_gi_debug_shader_version_shaders[i] = voxel_gi_debug_shader.version_get_shader(voxel_gi_debug_shader_version, i);34773478RD::PipelineRasterizationState rs;3479rs.cull_mode = RD::POLYGON_CULL_FRONT;3480RD::PipelineDepthStencilState ds;3481ds.enable_depth_test = true;3482ds.enable_depth_write = true;3483ds.depth_compare_operator = RD::COMPARE_OP_GREATER_OR_EQUAL;34843485voxel_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);3486}3487}34883489/* SDGFI */34903491{3492Vector<String> preprocess_modes;3493preprocess_modes.push_back("\n#define MODE_SCROLL\n");3494preprocess_modes.push_back("\n#define MODE_SCROLL_OCCLUSION\n");3495preprocess_modes.push_back("\n#define MODE_INITIALIZE_JUMP_FLOOD\n");3496preprocess_modes.push_back("\n#define MODE_INITIALIZE_JUMP_FLOOD_HALF\n");3497preprocess_modes.push_back("\n#define MODE_JUMPFLOOD\n");3498preprocess_modes.push_back("\n#define MODE_JUMPFLOOD_OPTIMIZED\n");3499preprocess_modes.push_back("\n#define MODE_UPSCALE_JUMP_FLOOD\n");3500preprocess_modes.push_back("\n#define MODE_OCCLUSION\n");3501preprocess_modes.push_back("\n#define MODE_STORE\n");3502String defines = "\n#define OCCLUSION_SIZE " + itos(SDFGI::CASCADE_SIZE / SDFGI::PROBE_DIVISOR) + "\n";3503sdfgi_shader.preprocess.initialize(preprocess_modes, defines);3504sdfgi_shader.preprocess_shader = sdfgi_shader.preprocess.version_create();3505for (int i = 0; i < SDFGIShader::PRE_PROCESS_MAX; i++) {3506sdfgi_shader.preprocess_pipeline[i].create_compute_pipeline(sdfgi_shader.preprocess.version_get_shader(sdfgi_shader.preprocess_shader, i));3507}3508}35093510{3511//calculate tables3512String defines = "\n#define OCT_SIZE " + itos(SDFGI::LIGHTPROBE_OCT_SIZE) + "\n";35133514Vector<String> direct_light_modes;3515direct_light_modes.push_back("\n#define MODE_PROCESS_STATIC\n");3516direct_light_modes.push_back("\n#define MODE_PROCESS_DYNAMIC\n");3517sdfgi_shader.direct_light.initialize(direct_light_modes, defines);3518sdfgi_shader.direct_light_shader = sdfgi_shader.direct_light.version_create();3519for (int i = 0; i < SDFGIShader::DIRECT_LIGHT_MODE_MAX; i++) {3520sdfgi_shader.direct_light_pipeline[i].create_compute_pipeline(sdfgi_shader.direct_light.version_get_shader(sdfgi_shader.direct_light_shader, i));3521}3522}35233524{3525//calculate tables3526String defines = "\n#define OCT_SIZE " + itos(SDFGI::LIGHTPROBE_OCT_SIZE) + "\n";3527defines += "\n#define SH_SIZE " + itos(SDFGI::SH_SIZE) + "\n";3528if (p_sky->sky_use_octmap_array) {3529defines += "\n#define USE_OCTMAP_ARRAY\n";3530}35313532Vector<String> integrate_modes;3533integrate_modes.push_back("\n#define MODE_PROCESS\n");3534integrate_modes.push_back("\n#define MODE_STORE\n");3535integrate_modes.push_back("\n#define MODE_SCROLL\n");3536integrate_modes.push_back("\n#define MODE_SCROLL_STORE\n");3537sdfgi_shader.integrate.initialize(integrate_modes, defines);3538sdfgi_shader.integrate_shader = sdfgi_shader.integrate.version_create();35393540for (int i = 0; i < SDFGIShader::INTEGRATE_MODE_MAX; i++) {3541sdfgi_shader.integrate_pipeline[i].create_compute_pipeline(sdfgi_shader.integrate.version_get_shader(sdfgi_shader.integrate_shader, i));3542}35433544{3545Vector<RD::Uniform> uniforms;35463547{3548RD::Uniform u;3549u.uniform_type = RD::UNIFORM_TYPE_TEXTURE;3550u.binding = 0;3551if (p_sky->sky_use_octmap_array) {3552u.append_id(texture_storage->texture_rd_get_default(RendererRD::TextureStorage::DEFAULT_RD_TEXTURE_2D_ARRAY_WHITE));3553} else {3554u.append_id(texture_storage->texture_rd_get_default(RendererRD::TextureStorage::DEFAULT_RD_TEXTURE_WHITE));3555}3556uniforms.push_back(u);3557}3558{3559RD::Uniform u;3560u.uniform_type = RD::UNIFORM_TYPE_SAMPLER;3561u.binding = 1;3562u.append_id(material_storage->sampler_rd_get_default(RS::CANVAS_ITEM_TEXTURE_FILTER_LINEAR_WITH_MIPMAPS, RS::CANVAS_ITEM_TEXTURE_REPEAT_DISABLED));3563uniforms.push_back(u);3564}35653566sdfgi_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);3567}3568}35693570//GK3571{3572//calculate tables3573String defines = "\n#define SDFGI_OCT_SIZE " + itos(SDFGI::LIGHTPROBE_OCT_SIZE) + "\n";35743575Vector<ShaderRD::VariantDefine> variants;3576for (uint32_t vrs = 0; vrs < 2; vrs++) {3577String vrs_base = vrs ? "\n#define USE_VRS\n" : "";3578Group group = vrs ? GROUP_VRS : GROUP_NORMAL;3579bool default_enabled = vrs == 0;3580variants.push_back(ShaderRD::VariantDefine(group, vrs_base + "\n#define USE_VOXEL_GI_INSTANCES\n", default_enabled)); // MODE_VOXEL_GI3581variants.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_SAMPLER3582variants.push_back(ShaderRD::VariantDefine(group, vrs_base + "\n#define USE_SDFGI\n", default_enabled)); // MODE_SDFGI3583variants.push_back(ShaderRD::VariantDefine(group, vrs_base + "\n#define USE_SDFGI\n\n#define USE_VOXEL_GI_INSTANCES\n", default_enabled)); // MODE_COMBINED3584variants.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_SAMPLER3585}35863587shader.initialize(variants, defines);35883589bool vrs_supported = RendererSceneRenderRD::get_singleton()->is_vrs_supported();3590if (vrs_supported) {3591shader.enable_group(GROUP_VRS);3592}35933594shader_version = shader.version_create();35953596Vector<RD::PipelineSpecializationConstant> specialization_constants;35973598{3599RD::PipelineSpecializationConstant sc;3600sc.type = RD::PIPELINE_SPECIALIZATION_CONSTANT_TYPE_BOOL;3601sc.constant_id = 0; // SHADER_SPECIALIZATION_HALF_RES3602sc.bool_value = false;3603specialization_constants.push_back(sc);36043605sc.type = RD::PIPELINE_SPECIALIZATION_CONSTANT_TYPE_BOOL;3606sc.constant_id = 1; // SHADER_SPECIALIZATION_USE_FULL_PROJECTION_MATRIX3607sc.bool_value = false;3608specialization_constants.push_back(sc);36093610sc.type = RD::PIPELINE_SPECIALIZATION_CONSTANT_TYPE_BOOL;3611sc.constant_id = 2; // SHADER_SPECIALIZATION_USE_VRS3612sc.bool_value = false;3613specialization_constants.push_back(sc);3614}36153616for (int v = 0; v < SHADER_SPECIALIZATION_VARIATIONS; v++) {3617specialization_constants.ptrw()[0].bool_value = (v & SHADER_SPECIALIZATION_HALF_RES) ? true : false;3618specialization_constants.ptrw()[1].bool_value = (v & SHADER_SPECIALIZATION_USE_FULL_PROJECTION_MATRIX) ? true : false;3619specialization_constants.ptrw()[2].bool_value = (v & SHADER_SPECIALIZATION_USE_VRS) ? true : false;36203621int variant_base = vrs_supported ? MODE_MAX : 0;3622for (int i = 0; i < MODE_MAX; i++) {3623pipelines[v][i].create_compute_pipeline(shader.version_get_shader(shader_version, variant_base + i), specialization_constants);3624}3625}36263627sdfgi_ubo = RD::get_singleton()->uniform_buffer_create(sizeof(SDFGIData));3628}3629{3630String defines = "\n#define OCT_SIZE " + itos(SDFGI::LIGHTPROBE_OCT_SIZE) + "\n";3631Vector<String> debug_modes;3632debug_modes.push_back("");3633sdfgi_shader.debug.initialize(debug_modes, defines);3634sdfgi_shader.debug_shader = sdfgi_shader.debug.version_create();3635sdfgi_shader.debug_shader_version = sdfgi_shader.debug.version_get_shader(sdfgi_shader.debug_shader, 0);3636sdfgi_shader.debug_pipeline.create_compute_pipeline(sdfgi_shader.debug_shader_version);3637}3638{3639String defines = "\n#define OCT_SIZE " + itos(SDFGI::LIGHTPROBE_OCT_SIZE) + "\n";36403641Vector<String> versions;3642versions.push_back("\n#define MODE_PROBES\n");3643versions.push_back("\n#define MODE_PROBES\n#define USE_MULTIVIEW\n");3644versions.push_back("\n#define MODE_VISIBILITY\n");3645versions.push_back("\n#define MODE_VISIBILITY\n#define USE_MULTIVIEW\n");36463647sdfgi_shader.debug_probes.initialize(versions, defines);36483649// TODO disable multiview versions if turned off36503651sdfgi_shader.debug_probes_shader = sdfgi_shader.debug_probes.version_create();36523653{3654RD::PipelineRasterizationState rs;3655rs.cull_mode = RD::POLYGON_CULL_DISABLED;3656RD::PipelineDepthStencilState ds;3657ds.enable_depth_test = true;3658ds.enable_depth_write = true;3659ds.depth_compare_operator = RD::COMPARE_OP_GREATER_OR_EQUAL;3660for (int i = 0; i < SDFGIShader::PROBE_DEBUG_MAX; i++) {3661// TODO check if version is enabled36623663RID debug_probes_shader_version = sdfgi_shader.debug_probes.version_get_shader(sdfgi_shader.debug_probes_shader, i);3664sdfgi_shader.debug_probes_pipeline[i].setup(debug_probes_shader_version, RD::RENDER_PRIMITIVE_TRIANGLE_STRIPS, rs, RD::PipelineMultisampleState(), ds, RD::PipelineColorBlendState::create_disabled(), 0);3665}3666}3667}3668default_voxel_gi_buffer = RD::get_singleton()->uniform_buffer_create(sizeof(VoxelGIData) * MAX_VOXEL_GI_INSTANCES);3669half_resolution = GLOBAL_GET("rendering/global_illumination/gi/use_half_resolution");3670}36713672void GI::free() {3673if (default_voxel_gi_buffer.is_valid()) {3674RD::get_singleton()->free_rid(default_voxel_gi_buffer);3675}3676if (voxel_gi_lights_uniform.is_valid()) {3677RD::get_singleton()->free_rid(voxel_gi_lights_uniform);3678}3679if (sdfgi_ubo.is_valid()) {3680RD::get_singleton()->free_rid(sdfgi_ubo);3681}36823683if (voxel_gi_lights) {3684memdelete_arr(voxel_gi_lights);3685}3686}36873688Ref<GI::SDFGI> GI::create_sdfgi(RID p_env, const Vector3 &p_world_position, uint32_t p_requested_history_size) {3689Ref<SDFGI> sdfgi;3690sdfgi.instantiate();36913692sdfgi->create(p_env, p_world_position, p_requested_history_size, this);36933694return sdfgi;3695}36963697void 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) {3698ERR_FAIL_COND(p_render_buffers.is_null());36993700RendererRD::TextureStorage *texture_storage = RendererRD::TextureStorage::get_singleton();3701ERR_FAIL_NULL(texture_storage);37023703r_voxel_gi_instances_used = 0;37043705Ref<RenderBuffersGI> rbgi = p_render_buffers->get_custom_data(RB_SCOPE_GI);3706ERR_FAIL_COND(rbgi.is_null());37073708RID voxel_gi_buffer = rbgi->get_voxel_gi_buffer();3709VoxelGIData voxel_gi_data[MAX_VOXEL_GI_INSTANCES];37103711bool voxel_gi_instances_changed = false;37123713Transform3D to_camera;3714to_camera.origin = p_transform.origin; //only translation, make local37153716for (int i = 0; i < MAX_VOXEL_GI_INSTANCES; i++) {3717RID texture;3718if (i < (int)p_voxel_gi_instances.size()) {3719VoxelGIInstance *gipi = voxel_gi_instance_owner.get_or_null(p_voxel_gi_instances[i]);37203721if (gipi) {3722texture = gipi->texture;3723VoxelGIData &gipd = voxel_gi_data[i];37243725RID base_probe = gipi->probe;37263727Transform3D to_cell = voxel_gi_get_to_cell_xform(gipi->probe) * gipi->transform.affine_inverse() * to_camera;37283729gipd.xform[0] = to_cell.basis.rows[0][0];3730gipd.xform[1] = to_cell.basis.rows[1][0];3731gipd.xform[2] = to_cell.basis.rows[2][0];3732gipd.xform[3] = 0;3733gipd.xform[4] = to_cell.basis.rows[0][1];3734gipd.xform[5] = to_cell.basis.rows[1][1];3735gipd.xform[6] = to_cell.basis.rows[2][1];3736gipd.xform[7] = 0;3737gipd.xform[8] = to_cell.basis.rows[0][2];3738gipd.xform[9] = to_cell.basis.rows[1][2];3739gipd.xform[10] = to_cell.basis.rows[2][2];3740gipd.xform[11] = 0;3741gipd.xform[12] = to_cell.origin.x;3742gipd.xform[13] = to_cell.origin.y;3743gipd.xform[14] = to_cell.origin.z;3744gipd.xform[15] = 1;37453746Vector3 bounds = voxel_gi_get_octree_size(base_probe);37473748gipd.bounds[0] = bounds.x;3749gipd.bounds[1] = bounds.y;3750gipd.bounds[2] = bounds.z;37513752gipd.dynamic_range = voxel_gi_get_dynamic_range(base_probe) * voxel_gi_get_energy(base_probe);3753gipd.bias = voxel_gi_get_bias(base_probe);3754gipd.normal_bias = voxel_gi_get_normal_bias(base_probe);3755gipd.blend_ambient = !voxel_gi_is_interior(base_probe);3756gipd.mipmaps = gipi->mipmaps.size();3757gipd.exposure_normalization = 1.0;3758if (p_render_data->camera_attributes.is_valid()) {3759float exposure_normalization = RSG::camera_attributes->camera_attributes_get_exposure_normalization_factor(p_render_data->camera_attributes);3760gipd.exposure_normalization = exposure_normalization / voxel_gi_get_baked_exposure_normalization(base_probe);3761}3762}37633764r_voxel_gi_instances_used++;3765}37663767if (texture == RID()) {3768texture = texture_storage->texture_rd_get_default(RendererRD::TextureStorage::DEFAULT_RD_TEXTURE_3D_WHITE);3769}37703771if (texture != rbgi->voxel_gi_textures[i]) {3772voxel_gi_instances_changed = true;3773rbgi->voxel_gi_textures[i] = texture;3774}3775}37763777if (voxel_gi_instances_changed) {3778for (uint32_t v = 0; v < RendererSceneRender::MAX_RENDER_VIEWS; v++) {3779if (RD::get_singleton()->uniform_set_is_valid(rbgi->uniform_set[v])) {3780RD::get_singleton()->free_rid(rbgi->uniform_set[v]);3781}3782rbgi->uniform_set[v] = RID();3783}37843785if (p_render_buffers->has_custom_data(RB_SCOPE_FOG)) {3786// VoxelGI instances have changed, so we need to update volumetric fog.3787Ref<RendererRD::Fog::VolumetricFog> fog = p_render_buffers->get_custom_data(RB_SCOPE_FOG);3788fog->sync_gi_dependent_sets_validity(true);3789}3790}37913792if (p_voxel_gi_instances.size() > 0) {3793RD::get_singleton()->draw_command_begin_label("VoxelGIs Setup");37943795RD::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);37963797RD::get_singleton()->draw_command_end_label();3798}3799}38003801RID GI::RenderBuffersGI::get_voxel_gi_buffer() {3802if (voxel_gi_buffer.is_null()) {3803voxel_gi_buffer = RD::get_singleton()->uniform_buffer_create(sizeof(GI::VoxelGIData) * GI::MAX_VOXEL_GI_INSTANCES);3804}3805return voxel_gi_buffer;3806}38073808void GI::RenderBuffersGI::free_data() {3809for (uint32_t v = 0; v < RendererSceneRender::MAX_RENDER_VIEWS; v++) {3810if (RD::get_singleton()->uniform_set_is_valid(uniform_set[v])) {3811RD::get_singleton()->free_rid(uniform_set[v]);3812}3813uniform_set[v] = RID();3814}38153816if (scene_data_ubo.is_valid()) {3817RD::get_singleton()->free_rid(scene_data_ubo);3818scene_data_ubo = RID();3819}38203821if (voxel_gi_buffer.is_valid()) {3822RD::get_singleton()->free_rid(voxel_gi_buffer);3823voxel_gi_buffer = RID();3824}3825}38263827void 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) {3828RendererRD::TextureStorage *texture_storage = RendererRD::TextureStorage::get_singleton();3829RendererRD::MaterialStorage *material_storage = RendererRD::MaterialStorage::get_singleton();38303831ERR_FAIL_COND_MSG(p_view_count > 2, "Maximum of 2 views supported for Processing GI.");38323833RD::get_singleton()->draw_command_begin_label("GI Render");38343835ERR_FAIL_COND(p_render_buffers.is_null());38363837Ref<RenderBuffersGI> rbgi = p_render_buffers->get_custom_data(RB_SCOPE_GI);3838ERR_FAIL_COND(rbgi.is_null());38393840Size2i internal_size = p_render_buffers->get_internal_size();38413842if (rbgi->using_half_size_gi != half_resolution) {3843p_render_buffers->clear_context(RB_SCOPE_GI);3844}38453846if (!p_render_buffers->has_texture(RB_SCOPE_GI, RB_TEX_AMBIENT)) {3847Size2i size = internal_size;3848uint32_t usage_bits = RD::TEXTURE_USAGE_SAMPLING_BIT | RD::TEXTURE_USAGE_STORAGE_BIT;38493850if (half_resolution) {3851size.x >>= 1;3852size.y >>= 1;3853}38543855p_render_buffers->create_texture(RB_SCOPE_GI, RB_TEX_AMBIENT, RD::DATA_FORMAT_R16G16B16A16_SFLOAT, usage_bits, RD::TEXTURE_SAMPLES_1, size);3856p_render_buffers->create_texture(RB_SCOPE_GI, RB_TEX_REFLECTION, RD::DATA_FORMAT_R16G16B16A16_SFLOAT, usage_bits, RD::TEXTURE_SAMPLES_1, size);38573858rbgi->using_half_size_gi = half_resolution;3859}38603861// Setup our scene data3862{3863SceneData scene_data;38643865if (rbgi->scene_data_ubo.is_null()) {3866rbgi->scene_data_ubo = RD::get_singleton()->uniform_buffer_create(sizeof(SceneData));3867}38683869Projection correction;3870correction.set_depth_correction(false);38713872for (uint32_t v = 0; v < p_view_count; v++) {3873Projection temp = correction * p_projections[v];38743875RendererRD::MaterialStorage::store_camera(temp.inverse(), scene_data.inv_projection[v]);3876scene_data.eye_offset[v][0] = p_eye_offsets[v].x;3877scene_data.eye_offset[v][1] = p_eye_offsets[v].y;3878scene_data.eye_offset[v][2] = p_eye_offsets[v].z;3879scene_data.eye_offset[v][3] = 0.0;3880}38813882// Note that we will be ignoring the origin of this transform.3883RendererRD::MaterialStorage::store_transform(p_cam_transform, scene_data.cam_transform);38843885scene_data.screen_size[0] = internal_size.x;3886scene_data.screen_size[1] = internal_size.y;38873888RD::get_singleton()->buffer_update(rbgi->scene_data_ubo, 0, sizeof(SceneData), &scene_data);3889}38903891// Now compute the contents of our buffers.3892RD::ComputeListID compute_list = RD::get_singleton()->compute_list_begin();38933894// Render each eye separately.3895// We need to look into whether we can make our compute shader use Multiview but not sure that works or makes a difference..38963897// setup our push constant38983899PushConstant push_constant;39003901push_constant.max_voxel_gi_instances = MIN((uint64_t)MAX_VOXEL_GI_INSTANCES, p_voxel_gi_instances.size());3902push_constant.high_quality_vct = voxel_gi_quality == RS::VOXEL_GI_QUALITY_HIGH;39033904// these should be the same for all views3905push_constant.orthogonal = p_projections[0].is_orthogonal();3906push_constant.z_near = p_projections[0].get_z_near();3907push_constant.z_far = p_projections[0].get_z_far();39083909// these are only used if we have 1 view, else we use the projections in our scene data3910push_constant.proj_info[0] = -2.0f / (internal_size.x * p_projections[0].columns[0][0]);3911push_constant.proj_info[1] = -2.0f / (internal_size.y * p_projections[0].columns[1][1]);3912push_constant.proj_info[2] = (1.0f - p_projections[0].columns[0][2]) / p_projections[0].columns[0][0];3913push_constant.proj_info[3] = (1.0f + p_projections[0].columns[1][2]) / p_projections[0].columns[1][1];39143915bool use_sdfgi = p_render_buffers->has_custom_data(RB_SCOPE_SDFGI);3916bool use_voxel_gi_instances = push_constant.max_voxel_gi_instances > 0;39173918Ref<SDFGI> sdfgi;3919if (use_sdfgi) {3920sdfgi = p_render_buffers->get_custom_data(RB_SCOPE_SDFGI);3921}39223923uint32_t pipeline_specialization = 0;3924if (rbgi->using_half_size_gi) {3925pipeline_specialization |= SHADER_SPECIALIZATION_HALF_RES;3926}3927if (p_view_count > 1) {3928pipeline_specialization |= SHADER_SPECIALIZATION_USE_FULL_PROJECTION_MATRIX;3929}3930bool has_vrs_texture = p_render_buffers->has_texture(RB_SCOPE_VRS, RB_TEXTURE);3931if (has_vrs_texture) {3932pipeline_specialization |= SHADER_SPECIALIZATION_USE_VRS;3933}39343935bool without_sampler = RD::get_singleton()->sampler_is_format_supported_for_filter(RD::DATA_FORMAT_R8G8_UINT, RD::SAMPLER_FILTER_LINEAR);3936Mode mode;3937if (use_sdfgi && use_voxel_gi_instances) {3938mode = without_sampler ? MODE_COMBINED_WITHOUT_SAMPLER : MODE_COMBINED;3939} else if (use_sdfgi) {3940mode = MODE_SDFGI;3941} else {3942mode = without_sampler ? MODE_VOXEL_GI_WITHOUT_SAMPLER : MODE_VOXEL_GI;3943}39443945for (uint32_t v = 0; v < p_view_count; v++) {3946push_constant.view_index = v;39473948// setup our uniform set3949if (rbgi->uniform_set[v].is_null() || !RD::get_singleton()->uniform_set_is_valid(rbgi->uniform_set[v])) {3950Vector<RD::Uniform> uniforms;3951{3952RD::Uniform u;3953u.binding = 1;3954u.uniform_type = RD::UNIFORM_TYPE_TEXTURE;3955for (uint32_t j = 0; j < SDFGI::MAX_CASCADES; j++) {3956if (use_sdfgi && j < sdfgi->cascades.size()) {3957u.append_id(sdfgi->cascades[j].sdf_tex);3958} else {3959u.append_id(texture_storage->texture_rd_get_default(RendererRD::TextureStorage::DEFAULT_RD_TEXTURE_3D_WHITE));3960}3961}3962uniforms.push_back(u);3963}3964{3965RD::Uniform u;3966u.binding = 2;3967u.uniform_type = RD::UNIFORM_TYPE_TEXTURE;3968for (uint32_t j = 0; j < SDFGI::MAX_CASCADES; j++) {3969if (use_sdfgi && j < sdfgi->cascades.size()) {3970u.append_id(sdfgi->cascades[j].light_tex);3971} else {3972u.append_id(texture_storage->texture_rd_get_default(RendererRD::TextureStorage::DEFAULT_RD_TEXTURE_3D_WHITE));3973}3974}3975uniforms.push_back(u);3976}3977{3978RD::Uniform u;3979u.binding = 3;3980u.uniform_type = RD::UNIFORM_TYPE_TEXTURE;3981for (uint32_t j = 0; j < SDFGI::MAX_CASCADES; j++) {3982if (use_sdfgi && j < sdfgi->cascades.size()) {3983u.append_id(sdfgi->cascades[j].light_aniso_0_tex);3984} else {3985u.append_id(texture_storage->texture_rd_get_default(RendererRD::TextureStorage::DEFAULT_RD_TEXTURE_3D_WHITE));3986}3987}3988uniforms.push_back(u);3989}3990{3991RD::Uniform u;3992u.binding = 4;3993u.uniform_type = RD::UNIFORM_TYPE_TEXTURE;3994for (uint32_t j = 0; j < SDFGI::MAX_CASCADES; j++) {3995if (use_sdfgi && j < sdfgi->cascades.size()) {3996u.append_id(sdfgi->cascades[j].light_aniso_1_tex);3997} else {3998u.append_id(texture_storage->texture_rd_get_default(RendererRD::TextureStorage::DEFAULT_RD_TEXTURE_3D_WHITE));3999}4000}4001uniforms.push_back(u);4002}4003{4004RD::Uniform u;4005u.uniform_type = RD::UNIFORM_TYPE_TEXTURE;4006u.binding = 5;4007if (use_sdfgi) {4008u.append_id(sdfgi->occlusion_texture);4009} else {4010u.append_id(texture_storage->texture_rd_get_default(RendererRD::TextureStorage::DEFAULT_RD_TEXTURE_3D_WHITE));4011}4012uniforms.push_back(u);4013}4014{4015RD::Uniform u;4016u.uniform_type = RD::UNIFORM_TYPE_SAMPLER;4017u.binding = 6;4018u.append_id(material_storage->sampler_rd_get_default(RS::CANVAS_ITEM_TEXTURE_FILTER_LINEAR, RS::CANVAS_ITEM_TEXTURE_REPEAT_DISABLED));4019uniforms.push_back(u);4020}4021{4022RD::Uniform u;4023u.uniform_type = RD::UNIFORM_TYPE_SAMPLER;4024u.binding = 7;4025u.append_id(material_storage->sampler_rd_get_default(RS::CANVAS_ITEM_TEXTURE_FILTER_LINEAR_WITH_MIPMAPS, RS::CANVAS_ITEM_TEXTURE_REPEAT_DISABLED));4026uniforms.push_back(u);4027}4028{4029RD::Uniform u;4030u.uniform_type = RD::UNIFORM_TYPE_IMAGE;4031u.binding = 9;4032u.append_id(p_render_buffers->get_texture_slice(RB_SCOPE_GI, RB_TEX_AMBIENT, v, 0));4033uniforms.push_back(u);4034}40354036{4037RD::Uniform u;4038u.uniform_type = RD::UNIFORM_TYPE_IMAGE;4039u.binding = 10;4040u.append_id(p_render_buffers->get_texture_slice(RB_SCOPE_GI, RB_TEX_REFLECTION, v, 0));4041uniforms.push_back(u);4042}40434044{4045RD::Uniform u;4046u.uniform_type = RD::UNIFORM_TYPE_TEXTURE;4047u.binding = 11;4048if (use_sdfgi) {4049u.append_id(sdfgi->lightprobe_texture);4050} else {4051u.append_id(texture_storage->texture_rd_get_default(RendererRD::TextureStorage::DEFAULT_RD_TEXTURE_2D_ARRAY_WHITE));4052}4053uniforms.push_back(u);4054}4055{4056RD::Uniform u;4057u.uniform_type = RD::UNIFORM_TYPE_TEXTURE;4058u.binding = 12;4059u.append_id(p_render_buffers->get_depth_texture(v));4060uniforms.push_back(u);4061}4062{4063RD::Uniform u;4064u.uniform_type = RD::UNIFORM_TYPE_TEXTURE;4065u.binding = 13;4066u.append_id(p_normal_roughness_slices[v]);4067uniforms.push_back(u);4068}4069{4070RD::Uniform u;4071u.uniform_type = RD::UNIFORM_TYPE_TEXTURE;4072u.binding = 14;4073RID buffer = p_voxel_gi_buffer.is_valid() ? p_voxel_gi_buffer : texture_storage->texture_rd_get_default(RendererRD::TextureStorage::DEFAULT_RD_TEXTURE_BLACK);4074u.append_id(buffer);4075uniforms.push_back(u);4076}4077{4078RD::Uniform u;4079u.uniform_type = RD::UNIFORM_TYPE_UNIFORM_BUFFER;4080u.binding = 15;4081u.append_id(sdfgi_ubo);4082uniforms.push_back(u);4083}4084{4085RD::Uniform u;4086u.uniform_type = RD::UNIFORM_TYPE_UNIFORM_BUFFER;4087u.binding = 16;4088u.append_id(rbgi->get_voxel_gi_buffer());4089uniforms.push_back(u);4090}4091{4092RD::Uniform u;4093u.uniform_type = RD::UNIFORM_TYPE_TEXTURE;4094u.binding = 17;4095for (int i = 0; i < MAX_VOXEL_GI_INSTANCES; i++) {4096u.append_id(rbgi->voxel_gi_textures[i]);4097}4098uniforms.push_back(u);4099}4100{4101RD::Uniform u;4102u.uniform_type = RD::UNIFORM_TYPE_UNIFORM_BUFFER;4103u.binding = 18;4104u.append_id(rbgi->scene_data_ubo);4105uniforms.push_back(u);4106}4107if (RendererSceneRenderRD::get_singleton()->is_vrs_supported()) {4108RD::Uniform u;4109u.uniform_type = RD::UNIFORM_TYPE_IMAGE;4110u.binding = 19;4111RID 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);4112u.append_id(buffer);4113uniforms.push_back(u);4114}41154116bool vrs_supported = RendererSceneRenderRD::get_singleton()->is_vrs_supported();4117int variant_base = vrs_supported ? MODE_MAX : 0;4118rbgi->uniform_set[v] = RD::get_singleton()->uniform_set_create(uniforms, shader.version_get_shader(shader_version, variant_base), 0);4119}41204121RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, pipelines[pipeline_specialization][mode].get_rid());4122RD::get_singleton()->compute_list_bind_uniform_set(compute_list, rbgi->uniform_set[v], 0);4123RD::get_singleton()->compute_list_set_push_constant(compute_list, &push_constant, sizeof(PushConstant));41244125if (rbgi->using_half_size_gi) {4126RD::get_singleton()->compute_list_dispatch_threads(compute_list, internal_size.x >> 1, internal_size.y >> 1, 1);4127} else {4128RD::get_singleton()->compute_list_dispatch_threads(compute_list, internal_size.x, internal_size.y, 1);4129}4130}41314132RD::get_singleton()->compute_list_end();4133RD::get_singleton()->draw_command_end_label();4134}41354136RID GI::voxel_gi_instance_create(RID p_base) {4137VoxelGIInstance voxel_gi;4138voxel_gi.gi = this;4139voxel_gi.probe = p_base;4140RID rid = voxel_gi_instance_owner.make_rid(voxel_gi);4141return rid;4142}41434144void GI::voxel_gi_instance_free(RID p_rid) {4145GI::VoxelGIInstance *voxel_gi = voxel_gi_instance_owner.get_or_null(p_rid);4146voxel_gi->free_resources();4147voxel_gi_instance_owner.free(p_rid);4148}41494150void GI::voxel_gi_instance_set_transform_to_data(RID p_probe, const Transform3D &p_xform) {4151VoxelGIInstance *voxel_gi = voxel_gi_instance_owner.get_or_null(p_probe);4152ERR_FAIL_NULL(voxel_gi);41534154voxel_gi->transform = p_xform;4155}41564157bool GI::voxel_gi_needs_update(RID p_probe) const {4158VoxelGIInstance *voxel_gi = voxel_gi_instance_owner.get_or_null(p_probe);4159ERR_FAIL_NULL_V(voxel_gi, false);41604161return voxel_gi->last_probe_version != voxel_gi_get_version(voxel_gi->probe);4162}41634164void GI::voxel_gi_update(RID p_probe, bool p_update_light_instances, const Vector<RID> &p_light_instances, const PagedArray<RenderGeometryInstance *> &p_dynamic_objects) {4165VoxelGIInstance *voxel_gi = voxel_gi_instance_owner.get_or_null(p_probe);4166ERR_FAIL_NULL(voxel_gi);41674168voxel_gi->update(p_update_light_instances, p_light_instances, p_dynamic_objects);4169}41704171void 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) {4172VoxelGIInstance *voxel_gi = voxel_gi_instance_owner.get_or_null(p_voxel_gi);4173ERR_FAIL_NULL(voxel_gi);41744175voxel_gi->debug(p_draw_list, p_framebuffer, p_camera_with_transform, p_lighting, p_emission, p_alpha);4176}41774178void GI::enable_vrs_shader_group() {4179shader.enable_group(GROUP_VRS);4180}418141824183