Path: blob/master/servers/rendering/renderer_rd/effects/copy_effects.cpp
20911 views
/**************************************************************************/1/* copy_effects.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 "copy_effects.h"31#include "core/config/project_settings.h"32#include "servers/rendering/renderer_rd/renderer_compositor_rd.h"33#include "servers/rendering/renderer_rd/storage_rd/material_storage.h"34#include "servers/rendering/renderer_rd/uniform_set_cache_rd.h"35#include "thirdparty/misc/cubemap_coeffs.h"3637using namespace RendererRD;3839CopyEffects *CopyEffects::singleton = nullptr;4041CopyEffects *CopyEffects::get_singleton() {42return singleton;43}4445CopyEffects::CopyEffects(BitField<RasterEffects> p_raster_effects) {46singleton = this;47raster_effects = p_raster_effects;4849if (raster_effects.has_flag(RASTER_EFFECT_GAUSSIAN_BLUR)) {50// init blur shader (on compute use copy shader)5152Vector<String> blur_modes;53blur_modes.push_back("\n#define MODE_MIPMAP\n"); // BLUR_MIPMAP54blur_modes.push_back("\n#define MODE_GAUSSIAN_BLUR\n"); // BLUR_MODE_GAUSSIAN_BLUR55blur_modes.push_back("\n#define MODE_GLOW_GATHER\n"); // BLUR_MODE_GAUSSIAN_GLOW_GATHER56blur_modes.push_back("\n#define MODE_GLOW_DOWNSAMPLE\n"); // BLUR_MODE_GAUSSIAN_GLOW_DOWNSAMPLE57blur_modes.push_back("\n#define MODE_GLOW_UPSAMPLE\n"); // BLUR_MODE_GAUSSIAN_GLOW_UPSAMPLE58blur_modes.push_back("\n#define MODE_COPY\n"); // BLUR_MODE_COPY59blur_modes.push_back("\n#define MODE_SET_COLOR\n"); // BLUR_MODE_SET_COLOR6061blur_raster.shader.initialize(blur_modes);62memset(&blur_raster.push_constant, 0, sizeof(BlurRasterPushConstant));63blur_raster.shader_version = blur_raster.shader.version_create();6465for (int i = 0; i < BLUR_MODE_MAX; i++) {66blur_raster.pipelines[i].setup(blur_raster.shader.version_get_shader(blur_raster.shader_version, i), RD::RENDER_PRIMITIVE_TRIANGLES, RD::PipelineRasterizationState(), RD::PipelineMultisampleState(), RD::PipelineDepthStencilState(), RD::PipelineColorBlendState::create_disabled(), 0);67}6869RD::SamplerState sampler_state;70sampler_state.mag_filter = RD::SAMPLER_FILTER_LINEAR;71sampler_state.min_filter = RD::SAMPLER_FILTER_LINEAR;72sampler_state.repeat_u = RD::SAMPLER_REPEAT_MODE_CLAMP_TO_BORDER;73sampler_state.repeat_v = RD::SAMPLER_REPEAT_MODE_CLAMP_TO_BORDER;74sampler_state.border_color = RD::SAMPLER_BORDER_COLOR_FLOAT_TRANSPARENT_BLACK;7576blur_raster.glow_sampler = RD::get_singleton()->sampler_create(sampler_state);7778} else {79// not used in clustered80for (int i = 0; i < BLUR_MODE_MAX; i++) {81blur_raster.pipelines[i].clear();82}83}8485{86Vector<String> copy_modes;87copy_modes.push_back("\n#define MODE_GAUSSIAN_BLUR\n");88copy_modes.push_back("\n#define MODE_GAUSSIAN_BLUR\n#define DST_IMAGE_8BIT\n");89copy_modes.push_back("\n#define MODE_GAUSSIAN_BLUR\n#define MODE_GLOW\n");90copy_modes.push_back("\n#define MODE_GAUSSIAN_BLUR\n#define MODE_GLOW\n#define GLOW_USE_AUTO_EXPOSURE\n");91copy_modes.push_back("\n#define MODE_SIMPLE_COPY\n");92copy_modes.push_back("\n#define MODE_SIMPLE_COPY\n#define DST_IMAGE_8BIT\n");93copy_modes.push_back("\n#define MODE_SIMPLE_COPY_DEPTH\n");94copy_modes.push_back("\n#define MODE_SET_COLOR\n");95copy_modes.push_back("\n#define MODE_SET_COLOR\n#define DST_IMAGE_8BIT\n");96copy_modes.push_back("\n#define MODE_MIPMAP\n");97copy_modes.push_back("\n#define MODE_LINEARIZE_DEPTH_COPY\n");98copy_modes.push_back("\n#define MODE_OCTMAP_TO_PANORAMA\n");99copy_modes.push_back("\n#define MODE_OCTMAP_ARRAY_TO_PANORAMA\n");100101copy.shader.initialize(copy_modes);102memset(©.push_constant, 0, sizeof(CopyPushConstant));103104copy.shader_version = copy.shader.version_create();105106for (int i = 0; i < COPY_MODE_MAX; i++) {107if (copy.shader.is_variant_enabled(i)) {108copy.pipelines[i].create_compute_pipeline(copy.shader.version_get_shader(copy.shader_version, i));109}110}111}112113{114Vector<String> copy_modes;115copy_modes.push_back("\n"); // COPY_TO_FB_COPY116copy_modes.push_back("\n#define MODE_PANORAMA_TO_DP\n"); // COPY_TO_FB_COPY_PANORAMA_TO_DP117copy_modes.push_back("\n#define MODE_TWO_SOURCES\n"); // COPY_TO_FB_COPY2118copy_modes.push_back("\n#define MODE_SET_COLOR\n"); // COPY_TO_FB_SET_COLOR119copy_modes.push_back("\n#define USE_MULTIVIEW\n"); // COPY_TO_FB_MULTIVIEW120copy_modes.push_back("\n#define USE_MULTIVIEW\n#define MODE_TWO_SOURCES\n"); // COPY_TO_FB_MULTIVIEW_WITH_DEPTH121122copy_to_fb.shader.initialize(copy_modes);123124if (!RendererCompositorRD::get_singleton()->is_xr_enabled()) {125copy_to_fb.shader.set_variant_enabled(COPY_TO_FB_MULTIVIEW, false);126copy_to_fb.shader.set_variant_enabled(COPY_TO_FB_MULTIVIEW_WITH_DEPTH, false);127}128129copy_to_fb.shader_version = copy_to_fb.shader.version_create();130131//use additive132133for (int i = 0; i < COPY_TO_FB_MAX; i++) {134if (copy_to_fb.shader.is_variant_enabled(i)) {135copy_to_fb.pipelines[i].setup(copy_to_fb.shader.version_get_shader(copy_to_fb.shader_version, i), RD::RENDER_PRIMITIVE_TRIANGLES, RD::PipelineRasterizationState(), RD::PipelineMultisampleState(), RD::PipelineDepthStencilState(), RD::PipelineColorBlendState::create_disabled(), 0);136} else {137copy_to_fb.pipelines[i].clear();138}139}140}141142{143// Initialize copier144Vector<String> copy_modes;145copy_modes.push_back("\n");146147cube_to_dp.shader.initialize(copy_modes);148149cube_to_dp.shader_version = cube_to_dp.shader.version_create();150RID shader = cube_to_dp.shader.version_get_shader(cube_to_dp.shader_version, 0);151RD::PipelineDepthStencilState dss;152dss.enable_depth_test = true;153dss.depth_compare_operator = RD::COMPARE_OP_ALWAYS;154dss.enable_depth_write = true;155cube_to_dp.pipeline.setup(shader, RD::RENDER_PRIMITIVE_TRIANGLES, RD::PipelineRasterizationState(), RD::PipelineMultisampleState(), dss, RD::PipelineColorBlendState(), 0);156}157158{159// Initialize cubemap to octmap copier.160cube_to_octmap.shader.initialize({ "" });161cube_to_octmap.shader_version = cube_to_octmap.shader.version_create();162RID shader = cube_to_octmap.shader.version_get_shader(cube_to_octmap.shader_version, 0);163cube_to_octmap.pipeline.setup(shader, RD::RENDER_PRIMITIVE_TRIANGLES, RD::PipelineRasterizationState(), RD::PipelineMultisampleState(), RD::PipelineDepthStencilState(), RD::PipelineColorBlendState::create_disabled());164}165166{167// Initialize octmap downsampler.168169if (raster_effects.has_flag(RASTER_EFFECT_OCTMAP)) {170octmap_downsampler.raster_shader.initialize({ "" });171octmap_downsampler.shader_version = octmap_downsampler.raster_shader.version_create();172octmap_downsampler.raster_pipeline.setup(octmap_downsampler.raster_shader.version_get_shader(octmap_downsampler.shader_version, 0), RD::RENDER_PRIMITIVE_TRIANGLES, RD::PipelineRasterizationState(), RD::PipelineMultisampleState(), RD::PipelineDepthStencilState(), RD::PipelineColorBlendState::create_disabled(), 0);173} else {174Vector<String> downsampler_modes;175for (int i = 0; i < DOWNSAMPLER_MODE_COMPUTE_MAX; i++) {176String mode;177if (i & DOWNSAMPLER_MODE_FLAG_RGB10_A2) {178mode += "\n#define OCTMAP_FORMAT rgb10_a2\n";179} else {180mode += "\n#define OCTMAP_FORMAT rgba16f\n";181}182downsampler_modes.push_back(mode);183}184185octmap_downsampler.compute_shader.initialize(downsampler_modes);186octmap_downsampler.shader_version = octmap_downsampler.compute_shader.version_create();187for (int i = 0; i < DOWNSAMPLER_MODE_COMPUTE_MAX; i++) {188octmap_downsampler.compute_pipelines[i].create_compute_pipeline(octmap_downsampler.compute_shader.version_get_shader(octmap_downsampler.shader_version, i));189}190}191}192193{194// Initialize cubemap filter195filter.use_high_quality = GLOBAL_GET("rendering/reflections/sky_reflections/fast_filter_high_quality");196197if (filter.use_high_quality) {198filter.coefficient_buffer = RD::get_singleton()->storage_buffer_create(sizeof(high_quality_coeffs));199RD::get_singleton()->buffer_update(filter.coefficient_buffer, 0, sizeof(high_quality_coeffs), &high_quality_coeffs[0]);200} else {201filter.coefficient_buffer = RD::get_singleton()->storage_buffer_create(sizeof(low_quality_coeffs));202RD::get_singleton()->buffer_update(filter.coefficient_buffer, 0, sizeof(low_quality_coeffs), &low_quality_coeffs[0]);203}204205Vector<String> cubemap_filter_modes;206if (raster_effects.has_flag(RASTER_EFFECT_OCTMAP)) {207for (int i = 0; i < FILTER_MODE_RASTER_MAX; i++) {208String mode;209if (i & FILTER_MODE_FLAG_HIGH_QUALITY) {210mode += "\n#define USE_HIGH_QUALITY\n";211} else {212mode += "\n#define USE_LOW_QUALITY\n";213}214cubemap_filter_modes.push_back(mode);215}216217filter.raster_shader.initialize(cubemap_filter_modes);218filter.shader_version = filter.raster_shader.version_create();219220for (int i = 0; i < FILTER_MODE_RASTER_MAX; i++) {221filter.raster_pipelines[i].setup(filter.raster_shader.version_get_shader(filter.shader_version, i), RD::RENDER_PRIMITIVE_TRIANGLES, RD::PipelineRasterizationState(), RD::PipelineMultisampleState(), RD::PipelineDepthStencilState(), RD::PipelineColorBlendState::create_disabled(), 0);222}223224Vector<RD::Uniform> uniforms;225{226RD::Uniform u;227u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER;228u.binding = 0;229u.append_id(filter.coefficient_buffer);230uniforms.push_back(u);231}232filter.uniform_set = RD::get_singleton()->uniform_set_create(uniforms, filter.raster_shader.version_get_shader(filter.shader_version, filter.use_high_quality ? 0 : 1), 1);233} else {234for (int i = 0; i < FILTER_MODE_COMPUTE_MAX; i++) {235String mode;236if (i & FILTER_MODE_FLAG_HIGH_QUALITY) {237mode += "\n#define USE_HIGH_QUALITY\n";238} else {239mode += "\n#define USE_LOW_QUALITY\n";240}241if (i & FILTER_MODE_FLAG_ARRAY) {242mode += "\n#define USE_TEXTURE_ARRAY\n";243}244if (i & FILTER_MODE_FLAG_RGB10_A2) {245mode += "\n#define OCTMAP_FORMAT rgb10_a2\n";246} else {247mode += "\n#define OCTMAP_FORMAT rgba16f\n";248}249cubemap_filter_modes.push_back(mode);250}251252filter.compute_shader.initialize(cubemap_filter_modes);253filter.shader_version = filter.compute_shader.version_create();254255for (int i = 0; i < FILTER_MODE_COMPUTE_MAX; i++) {256filter.compute_pipelines[i].create_compute_pipeline(filter.compute_shader.version_get_shader(filter.shader_version, i));257}258259Vector<RD::Uniform> uniforms;260{261RD::Uniform u;262u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER;263u.binding = 0;264u.append_id(filter.coefficient_buffer);265uniforms.push_back(u);266}267filter.uniform_set = RD::get_singleton()->uniform_set_create(uniforms, filter.compute_shader.version_get_shader(filter.shader_version, filter.use_high_quality ? 0 : 1), 1);268}269}270271{272// Initialize roughness273Vector<String> cubemap_roughness_modes;274if (raster_effects.has_flag(RASTER_EFFECT_OCTMAP)) {275cubemap_roughness_modes.push_back("");276277roughness.raster_shader.initialize(cubemap_roughness_modes);278279roughness.shader_version = roughness.raster_shader.version_create();280281roughness.raster_pipeline.setup(roughness.raster_shader.version_get_shader(roughness.shader_version, 0), RD::RENDER_PRIMITIVE_TRIANGLES, RD::PipelineRasterizationState(), RD::PipelineMultisampleState(), RD::PipelineDepthStencilState(), RD::PipelineColorBlendState::create_disabled(), 0);282283} else {284cubemap_roughness_modes.push_back("\n#define OCTMAP_FORMAT rgba16f\n");285cubemap_roughness_modes.push_back("\n#define OCTMAP_FORMAT rgb10_a2\n");286287roughness.compute_shader.initialize(cubemap_roughness_modes);288289roughness.shader_version = roughness.compute_shader.version_create();290291for (int i = 0; i < ROUGHNESS_MODE_MAX; i++) {292roughness.compute_pipelines[i].create_compute_pipeline(roughness.compute_shader.version_get_shader(roughness.shader_version, i));293}294}295}296297{298Vector<String> specular_modes;299specular_modes.push_back("\n#define MODE_MERGE\n"); // SPECULAR_MERGE_ADD300specular_modes.push_back("\n#define MODE_MERGE\n#define MODE_SSR\n"); // SPECULAR_MERGE_SSR301specular_modes.push_back("\n"); // SPECULAR_MERGE_ADDITIVE_ADD302specular_modes.push_back("\n#define MODE_SSR\n"); // SPECULAR_MERGE_ADDITIVE_SSR303304specular_modes.push_back("\n#define USE_MULTIVIEW\n#define MODE_MERGE\n"); // SPECULAR_MERGE_ADD_MULTIVIEW305specular_modes.push_back("\n#define USE_MULTIVIEW\n#define MODE_MERGE\n#define MODE_SSR\n"); // SPECULAR_MERGE_SSR_MULTIVIEW306specular_modes.push_back("\n#define USE_MULTIVIEW\n"); // SPECULAR_MERGE_ADDITIVE_ADD_MULTIVIEW307specular_modes.push_back("\n#define USE_MULTIVIEW\n#define MODE_SSR\n"); // SPECULAR_MERGE_ADDITIVE_SSR_MULTIVIEW308309specular_merge.shader.initialize(specular_modes);310311if (!RendererCompositorRD::get_singleton()->is_xr_enabled()) {312specular_merge.shader.set_variant_enabled(SPECULAR_MERGE_ADD_MULTIVIEW, false);313specular_merge.shader.set_variant_enabled(SPECULAR_MERGE_SSR_MULTIVIEW, false);314specular_merge.shader.set_variant_enabled(SPECULAR_MERGE_ADDITIVE_ADD_MULTIVIEW, false);315specular_merge.shader.set_variant_enabled(SPECULAR_MERGE_ADDITIVE_SSR_MULTIVIEW, false);316}317318specular_merge.shader_version = specular_merge.shader.version_create();319320//use additive321322RD::PipelineColorBlendState::Attachment ba;323ba.enable_blend = true;324ba.src_color_blend_factor = RD::BLEND_FACTOR_ONE;325ba.dst_color_blend_factor = RD::BLEND_FACTOR_ONE;326ba.src_alpha_blend_factor = RD::BLEND_FACTOR_ZERO;327ba.dst_alpha_blend_factor = RD::BLEND_FACTOR_ZERO;328ba.color_blend_op = RD::BLEND_OP_ADD;329ba.alpha_blend_op = RD::BLEND_OP_ADD;330331RD::PipelineColorBlendState blend_additive;332blend_additive.attachments.push_back(ba);333334for (int i = 0; i < SPECULAR_MERGE_MAX; i++) {335if (specular_merge.shader.is_variant_enabled(i)) {336RD::PipelineColorBlendState blend_state;337if (i == SPECULAR_MERGE_ADDITIVE_ADD || i == SPECULAR_MERGE_ADDITIVE_SSR || i == SPECULAR_MERGE_ADDITIVE_ADD_MULTIVIEW || i == SPECULAR_MERGE_ADDITIVE_SSR_MULTIVIEW) {338blend_state = blend_additive;339} else {340blend_state = RD::PipelineColorBlendState::create_disabled();341}342specular_merge.pipelines[i].setup(specular_merge.shader.version_get_shader(specular_merge.shader_version, i), RD::RENDER_PRIMITIVE_TRIANGLES, RD::PipelineRasterizationState(), RD::PipelineMultisampleState(), RD::PipelineDepthStencilState(), blend_state, 0);343}344}345}346}347348CopyEffects::~CopyEffects() {349for (int i = 0; i < COPY_MODE_MAX; i++) {350copy.pipelines[i].free();351}352353if (raster_effects.has_flag(RASTER_EFFECT_GAUSSIAN_BLUR)) {354blur_raster.shader.version_free(blur_raster.shader_version);355RD::get_singleton()->free_rid(blur_raster.glow_sampler);356}357358if (raster_effects.has_flag(RASTER_EFFECT_OCTMAP)) {359octmap_downsampler.raster_shader.version_free(octmap_downsampler.shader_version);360filter.raster_shader.version_free(filter.shader_version);361roughness.raster_shader.version_free(roughness.shader_version);362} else {363// PipelineDeferredRD always needs to be freed before its corresponding shader since the pipeline may not have finished compiling before the shader is freed. This364// ensures that we wait on the pipeline compilation before we free it.365for (int i = 0; i < DOWNSAMPLER_MODE_COMPUTE_MAX; i++) {366octmap_downsampler.compute_pipelines[i].free();367}368octmap_downsampler.compute_shader.version_free(octmap_downsampler.shader_version);369370for (int i = 0; i < FILTER_MODE_COMPUTE_MAX; i++) {371filter.compute_pipelines[i].free();372}373filter.compute_shader.version_free(filter.shader_version);374375for (int i = 0; i < ROUGHNESS_MODE_MAX; i++) {376roughness.compute_pipelines[i].free();377}378roughness.compute_shader.version_free(roughness.shader_version);379}380381copy.shader.version_free(copy.shader_version);382specular_merge.shader.version_free(specular_merge.shader_version);383384RD::get_singleton()->free_rid(filter.coefficient_buffer);385386if (RD::get_singleton()->uniform_set_is_valid(filter.image_uniform_set)) {387RD::get_singleton()->free_rid(filter.image_uniform_set);388}389390if (RD::get_singleton()->uniform_set_is_valid(filter.uniform_set)) {391RD::get_singleton()->free_rid(filter.uniform_set);392}393394copy_to_fb.shader.version_free(copy_to_fb.shader_version);395cube_to_dp.shader.version_free(cube_to_dp.shader_version);396cube_to_octmap.shader.version_free(cube_to_octmap.shader_version);397398singleton = nullptr;399}400401void CopyEffects::copy_to_rect(RID p_source_rd_texture, RID p_dest_texture, const Rect2i &p_rect, bool p_flip_y, bool p_force_luminance, bool p_all_source, bool p_8_bit_dst, bool p_alpha_to_one, bool p_sanitize_inf_nan) {402UniformSetCacheRD *uniform_set_cache = UniformSetCacheRD::get_singleton();403ERR_FAIL_NULL(uniform_set_cache);404MaterialStorage *material_storage = MaterialStorage::get_singleton();405ERR_FAIL_NULL(material_storage);406407memset(©.push_constant, 0, sizeof(CopyPushConstant));408if (p_flip_y) {409copy.push_constant.flags |= COPY_FLAG_FLIP_Y;410}411412if (p_force_luminance) {413copy.push_constant.flags |= COPY_FLAG_FORCE_LUMINANCE;414}415416if (p_all_source) {417copy.push_constant.flags |= COPY_FLAG_ALL_SOURCE;418}419420if (p_alpha_to_one) {421copy.push_constant.flags |= COPY_FLAG_ALPHA_TO_ONE;422}423424if (p_sanitize_inf_nan) {425copy.push_constant.flags |= COPY_FLAG_SANITIZE_INF_NAN;426}427428copy.push_constant.section[0] = p_rect.position.x;429copy.push_constant.section[1] = p_rect.position.y;430copy.push_constant.section[2] = p_rect.size.width;431copy.push_constant.section[3] = p_rect.size.height;432copy.push_constant.target[0] = p_rect.position.x;433copy.push_constant.target[1] = p_rect.position.y;434435// setup our uniforms436RID default_sampler = material_storage->sampler_rd_get_default(RS::CANVAS_ITEM_TEXTURE_FILTER_LINEAR, RS::CANVAS_ITEM_TEXTURE_REPEAT_DISABLED);437438RD::Uniform u_source_rd_texture(RD::UNIFORM_TYPE_SAMPLER_WITH_TEXTURE, 0, Vector<RID>({ default_sampler, p_source_rd_texture }));439RD::Uniform u_dest_texture(RD::UNIFORM_TYPE_IMAGE, 0, p_dest_texture);440441CopyMode mode = p_8_bit_dst ? COPY_MODE_SIMPLY_COPY_8BIT : COPY_MODE_SIMPLY_COPY;442RID shader = copy.shader.version_get_shader(copy.shader_version, mode);443ERR_FAIL_COND(shader.is_null());444445RD::ComputeListID compute_list = RD::get_singleton()->compute_list_begin();446RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, copy.pipelines[mode].get_rid());447RD::get_singleton()->compute_list_bind_uniform_set(compute_list, uniform_set_cache->get_cache(shader, 0, u_source_rd_texture), 0);448RD::get_singleton()->compute_list_bind_uniform_set(compute_list, uniform_set_cache->get_cache(shader, 3, u_dest_texture), 3);449RD::get_singleton()->compute_list_set_push_constant(compute_list, ©.push_constant, sizeof(CopyPushConstant));450RD::get_singleton()->compute_list_dispatch_threads(compute_list, p_rect.size.width, p_rect.size.height, 1);451RD::get_singleton()->compute_list_end();452}453454void CopyEffects::copy_octmap_to_panorama(RID p_source_octmap, RID p_dest_panorama, const Size2i &p_panorama_size, float p_lod, bool p_is_array, const Size2 &p_source_octmap_border_size) {455UniformSetCacheRD *uniform_set_cache = UniformSetCacheRD::get_singleton();456ERR_FAIL_NULL(uniform_set_cache);457MaterialStorage *material_storage = MaterialStorage::get_singleton();458ERR_FAIL_NULL(material_storage);459460memset(©.push_constant, 0, sizeof(CopyPushConstant));461462copy.push_constant.section[0] = 0;463copy.push_constant.section[1] = 0;464copy.push_constant.section[2] = p_panorama_size.width;465copy.push_constant.section[3] = p_panorama_size.height;466copy.push_constant.target[0] = 0;467copy.push_constant.target[1] = 0;468copy.push_constant.camera_z_far = p_lod;469copy.push_constant.octmap_border_size[0] = p_source_octmap_border_size.x;470copy.push_constant.octmap_border_size[1] = p_source_octmap_border_size.y;471472// TODO, if this is needed at the copy stage, then we need to pass in the multiplier.473copy.push_constant.luminance_multiplier = raster_effects.has_flag(RASTER_EFFECT_COPY) ? 2.0 : 1.0;474475// setup our uniforms476RID default_sampler = material_storage->sampler_rd_get_default(RS::CANVAS_ITEM_TEXTURE_FILTER_LINEAR, RS::CANVAS_ITEM_TEXTURE_REPEAT_DISABLED);477478RD::Uniform u_source_octmap(RD::UNIFORM_TYPE_SAMPLER_WITH_TEXTURE, 0, Vector<RID>({ default_sampler, p_source_octmap }));479RD::Uniform u_dest_panorama(RD::UNIFORM_TYPE_IMAGE, 0, p_dest_panorama);480481CopyMode mode = p_is_array ? COPY_MODE_OCTMAP_ARRAY_TO_PANORAMA : COPY_MODE_OCTMAP_TO_PANORAMA;482RID shader = copy.shader.version_get_shader(copy.shader_version, mode);483ERR_FAIL_COND(shader.is_null());484485RD::ComputeListID compute_list = RD::get_singleton()->compute_list_begin();486RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, copy.pipelines[mode].get_rid());487RD::get_singleton()->compute_list_bind_uniform_set(compute_list, uniform_set_cache->get_cache(shader, 0, u_source_octmap), 0);488RD::get_singleton()->compute_list_bind_uniform_set(compute_list, uniform_set_cache->get_cache(shader, 3, u_dest_panorama), 3);489RD::get_singleton()->compute_list_set_push_constant(compute_list, ©.push_constant, sizeof(CopyPushConstant));490RD::get_singleton()->compute_list_dispatch_threads(compute_list, p_panorama_size.width, p_panorama_size.height, 1);491RD::get_singleton()->compute_list_end();492}493494void CopyEffects::copy_depth_to_rect(RID p_source_rd_texture, RID p_dest_texture, const Rect2i &p_rect, bool p_flip_y) {495UniformSetCacheRD *uniform_set_cache = UniformSetCacheRD::get_singleton();496ERR_FAIL_NULL(uniform_set_cache);497MaterialStorage *material_storage = MaterialStorage::get_singleton();498ERR_FAIL_NULL(material_storage);499500memset(©.push_constant, 0, sizeof(CopyPushConstant));501if (p_flip_y) {502copy.push_constant.flags |= COPY_FLAG_FLIP_Y;503}504505copy.push_constant.section[0] = 0;506copy.push_constant.section[1] = 0;507copy.push_constant.section[2] = p_rect.size.width;508copy.push_constant.section[3] = p_rect.size.height;509copy.push_constant.target[0] = p_rect.position.x;510copy.push_constant.target[1] = p_rect.position.y;511512// setup our uniforms513RID default_sampler = material_storage->sampler_rd_get_default(RS::CANVAS_ITEM_TEXTURE_FILTER_LINEAR, RS::CANVAS_ITEM_TEXTURE_REPEAT_DISABLED);514515RD::Uniform u_source_rd_texture(RD::UNIFORM_TYPE_SAMPLER_WITH_TEXTURE, 0, Vector<RID>({ default_sampler, p_source_rd_texture }));516RD::Uniform u_dest_texture(RD::UNIFORM_TYPE_IMAGE, 0, p_dest_texture);517518CopyMode mode = COPY_MODE_SIMPLY_COPY_DEPTH;519RID shader = copy.shader.version_get_shader(copy.shader_version, mode);520ERR_FAIL_COND(shader.is_null());521522RD::ComputeListID compute_list = RD::get_singleton()->compute_list_begin();523RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, copy.pipelines[mode].get_rid());524RD::get_singleton()->compute_list_bind_uniform_set(compute_list, uniform_set_cache->get_cache(shader, 0, u_source_rd_texture), 0);525RD::get_singleton()->compute_list_bind_uniform_set(compute_list, uniform_set_cache->get_cache(shader, 3, u_dest_texture), 3);526RD::get_singleton()->compute_list_set_push_constant(compute_list, ©.push_constant, sizeof(CopyPushConstant));527RD::get_singleton()->compute_list_dispatch_threads(compute_list, p_rect.size.width, p_rect.size.height, 1);528RD::get_singleton()->compute_list_end();529}530531void CopyEffects::copy_depth_to_rect_and_linearize(RID p_source_rd_texture, RID p_dest_texture, const Rect2i &p_rect, bool p_flip_y, float p_z_near, float p_z_far) {532UniformSetCacheRD *uniform_set_cache = UniformSetCacheRD::get_singleton();533ERR_FAIL_NULL(uniform_set_cache);534MaterialStorage *material_storage = MaterialStorage::get_singleton();535ERR_FAIL_NULL(material_storage);536537memset(©.push_constant, 0, sizeof(CopyPushConstant));538if (p_flip_y) {539copy.push_constant.flags |= COPY_FLAG_FLIP_Y;540}541542copy.push_constant.section[0] = 0;543copy.push_constant.section[1] = 0;544copy.push_constant.section[2] = p_rect.size.width;545copy.push_constant.section[3] = p_rect.size.height;546copy.push_constant.target[0] = p_rect.position.x;547copy.push_constant.target[1] = p_rect.position.y;548copy.push_constant.camera_z_far = p_z_far;549copy.push_constant.camera_z_near = p_z_near;550551// setup our uniforms552RID default_sampler = material_storage->sampler_rd_get_default(RS::CANVAS_ITEM_TEXTURE_FILTER_LINEAR, RS::CANVAS_ITEM_TEXTURE_REPEAT_DISABLED);553554RD::Uniform u_source_rd_texture(RD::UNIFORM_TYPE_SAMPLER_WITH_TEXTURE, 0, Vector<RID>({ default_sampler, p_source_rd_texture }));555RD::Uniform u_dest_texture(RD::UNIFORM_TYPE_IMAGE, 0, p_dest_texture);556557CopyMode mode = COPY_MODE_LINEARIZE_DEPTH;558RID shader = copy.shader.version_get_shader(copy.shader_version, mode);559ERR_FAIL_COND(shader.is_null());560561RD::ComputeListID compute_list = RD::get_singleton()->compute_list_begin();562RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, copy.pipelines[mode].get_rid());563RD::get_singleton()->compute_list_bind_uniform_set(compute_list, uniform_set_cache->get_cache(shader, 0, u_source_rd_texture), 0);564RD::get_singleton()->compute_list_bind_uniform_set(compute_list, uniform_set_cache->get_cache(shader, 3, u_dest_texture), 3);565RD::get_singleton()->compute_list_set_push_constant(compute_list, ©.push_constant, sizeof(CopyPushConstant));566RD::get_singleton()->compute_list_dispatch_threads(compute_list, p_rect.size.width, p_rect.size.height, 1);567RD::get_singleton()->compute_list_end();568}569570void CopyEffects::copy_to_atlas_fb(RID p_source_rd_texture, RID p_dest_framebuffer, const Rect2 &p_uv_rect, RD::DrawListID p_draw_list, bool p_flip_y, bool p_panorama) {571UniformSetCacheRD *uniform_set_cache = UniformSetCacheRD::get_singleton();572ERR_FAIL_NULL(uniform_set_cache);573MaterialStorage *material_storage = MaterialStorage::get_singleton();574ERR_FAIL_NULL(material_storage);575576memset(©_to_fb.push_constant, 0, sizeof(CopyToFbPushConstant));577578copy_to_fb.push_constant.flags |= COPY_TO_FB_FLAG_USE_SECTION;579copy_to_fb.push_constant.section[0] = p_uv_rect.position.x;580copy_to_fb.push_constant.section[1] = p_uv_rect.position.y;581copy_to_fb.push_constant.section[2] = p_uv_rect.size.x;582copy_to_fb.push_constant.section[3] = p_uv_rect.size.y;583584if (p_flip_y) {585copy_to_fb.push_constant.flags |= COPY_TO_FB_FLAG_FLIP_Y;586}587588copy_to_fb.push_constant.luminance_multiplier = 1.0;589590// setup our uniforms591RID default_sampler = material_storage->sampler_rd_get_default(RS::CANVAS_ITEM_TEXTURE_FILTER_LINEAR, RS::CANVAS_ITEM_TEXTURE_REPEAT_DISABLED);592593RD::Uniform u_source_rd_texture(RD::UNIFORM_TYPE_SAMPLER_WITH_TEXTURE, 0, Vector<RID>({ default_sampler, p_source_rd_texture }));594595CopyToFBMode mode = p_panorama ? COPY_TO_FB_COPY_PANORAMA_TO_DP : COPY_TO_FB_COPY;596RID shader = copy_to_fb.shader.version_get_shader(copy_to_fb.shader_version, mode);597ERR_FAIL_COND(shader.is_null());598599RD::DrawListID draw_list = p_draw_list;600RD::get_singleton()->draw_list_bind_render_pipeline(draw_list, copy_to_fb.pipelines[mode].get_render_pipeline(RD::INVALID_ID, RD::get_singleton()->framebuffer_get_format(p_dest_framebuffer)));601RD::get_singleton()->draw_list_bind_uniform_set(draw_list, uniform_set_cache->get_cache(shader, 0, u_source_rd_texture), 0);602RD::get_singleton()->draw_list_bind_index_array(draw_list, material_storage->get_quad_index_array());603RD::get_singleton()->draw_list_set_push_constant(draw_list, ©_to_fb.push_constant, sizeof(CopyToFbPushConstant));604RD::get_singleton()->draw_list_draw(draw_list, true);605}606607void CopyEffects::copy_to_fb_rect(RID p_source_rd_texture, RID p_dest_framebuffer, const Rect2i &p_rect, bool p_flip_y, bool p_force_luminance, bool p_alpha_to_zero, bool p_srgb, RID p_secondary, bool p_multiview, bool p_alpha_to_one, bool p_linear, bool p_normal, const Rect2 &p_src_rect, float p_linear_luminance_multiplier) {608UniformSetCacheRD *uniform_set_cache = UniformSetCacheRD::get_singleton();609ERR_FAIL_NULL(uniform_set_cache);610MaterialStorage *material_storage = MaterialStorage::get_singleton();611ERR_FAIL_NULL(material_storage);612613memset(©_to_fb.push_constant, 0, sizeof(CopyToFbPushConstant));614copy_to_fb.push_constant.luminance_multiplier = 1.0;615616if (p_flip_y) {617copy_to_fb.push_constant.flags |= COPY_TO_FB_FLAG_FLIP_Y;618}619if (p_force_luminance) {620copy_to_fb.push_constant.flags |= COPY_TO_FB_FLAG_FORCE_LUMINANCE;621}622if (p_alpha_to_zero) {623copy_to_fb.push_constant.flags |= COPY_TO_FB_FLAG_ALPHA_TO_ZERO;624}625if (p_srgb) {626copy_to_fb.push_constant.flags |= COPY_TO_FB_FLAG_SRGB;627}628if (p_alpha_to_one) {629copy_to_fb.push_constant.flags |= COPY_TO_FB_FLAG_ALPHA_TO_ONE;630}631if (p_linear) {632copy_to_fb.push_constant.flags |= COPY_TO_FB_FLAG_LINEAR;633copy_to_fb.push_constant.luminance_multiplier = p_linear_luminance_multiplier;634}635636if (p_normal) {637copy_to_fb.push_constant.flags |= COPY_TO_FB_FLAG_NORMAL;638}639640if (p_src_rect != Rect2()) {641copy_to_fb.push_constant.section[0] = p_src_rect.position.x;642copy_to_fb.push_constant.section[1] = p_src_rect.position.y;643copy_to_fb.push_constant.section[2] = p_src_rect.size.x;644copy_to_fb.push_constant.section[3] = p_src_rect.size.y;645copy_to_fb.push_constant.flags |= COPY_TO_FB_FLAG_USE_SRC_SECTION;646}647648// setup our uniforms649RID default_sampler = material_storage->sampler_rd_get_default(RS::CANVAS_ITEM_TEXTURE_FILTER_LINEAR, RS::CANVAS_ITEM_TEXTURE_REPEAT_DISABLED);650651RD::Uniform u_source_rd_texture(RD::UNIFORM_TYPE_SAMPLER_WITH_TEXTURE, 0, Vector<RID>({ default_sampler, p_source_rd_texture }));652653CopyToFBMode mode;654if (p_multiview) {655mode = p_secondary.is_valid() ? COPY_TO_FB_MULTIVIEW_WITH_DEPTH : COPY_TO_FB_MULTIVIEW;656} else {657mode = p_secondary.is_valid() ? COPY_TO_FB_COPY2 : COPY_TO_FB_COPY;658}659660RID shader = copy_to_fb.shader.version_get_shader(copy_to_fb.shader_version, mode);661ERR_FAIL_COND(shader.is_null());662663RD::DrawListID draw_list = RD::get_singleton()->draw_list_begin(p_dest_framebuffer, RD::DRAW_DEFAULT_ALL, Vector<Color>(), 1.0f, 0, p_rect);664RD::get_singleton()->draw_list_bind_render_pipeline(draw_list, copy_to_fb.pipelines[mode].get_render_pipeline(RD::INVALID_ID, RD::get_singleton()->framebuffer_get_format(p_dest_framebuffer)));665RD::get_singleton()->draw_list_bind_uniform_set(draw_list, uniform_set_cache->get_cache(shader, 0, u_source_rd_texture), 0);666if (p_secondary.is_valid()) {667// TODO may need to do this differently when reading from depth buffer for multiview668RD::Uniform u_secondary(RD::UNIFORM_TYPE_SAMPLER_WITH_TEXTURE, 0, Vector<RID>({ default_sampler, p_secondary }));669RD::get_singleton()->draw_list_bind_uniform_set(draw_list, uniform_set_cache->get_cache(shader, 1, u_secondary), 1);670}671RD::get_singleton()->draw_list_bind_index_array(draw_list, material_storage->get_quad_index_array());672RD::get_singleton()->draw_list_set_push_constant(draw_list, ©_to_fb.push_constant, sizeof(CopyToFbPushConstant));673RD::get_singleton()->draw_list_draw(draw_list, true);674RD::get_singleton()->draw_list_end();675}676677void CopyEffects::copy_to_drawlist(RD::DrawListID p_draw_list, RD::FramebufferFormatID p_fb_format, RID p_source_rd_texture, bool p_linear, float p_linear_luminance_multiplier) {678UniformSetCacheRD *uniform_set_cache = UniformSetCacheRD::get_singleton();679ERR_FAIL_NULL(uniform_set_cache);680MaterialStorage *material_storage = MaterialStorage::get_singleton();681ERR_FAIL_NULL(material_storage);682683memset(©_to_fb.push_constant, 0, sizeof(CopyToFbPushConstant));684copy_to_fb.push_constant.luminance_multiplier = 1.0;685686if (p_linear) {687copy_to_fb.push_constant.flags |= COPY_TO_FB_FLAG_LINEAR;688copy_to_fb.push_constant.luminance_multiplier = p_linear_luminance_multiplier;689}690691// setup our uniforms692RID default_sampler = material_storage->sampler_rd_get_default(RS::CANVAS_ITEM_TEXTURE_FILTER_LINEAR, RS::CANVAS_ITEM_TEXTURE_REPEAT_DISABLED);693694RD::Uniform u_source_rd_texture(RD::UNIFORM_TYPE_SAMPLER_WITH_TEXTURE, 0, Vector<RID>({ default_sampler, p_source_rd_texture }));695696// Multiview not supported here!697CopyToFBMode mode = COPY_TO_FB_COPY;698699RID shader = copy_to_fb.shader.version_get_shader(copy_to_fb.shader_version, mode);700ERR_FAIL_COND(shader.is_null());701702RD::get_singleton()->draw_list_bind_render_pipeline(p_draw_list, copy_to_fb.pipelines[mode].get_render_pipeline(RD::INVALID_ID, p_fb_format));703RD::get_singleton()->draw_list_bind_uniform_set(p_draw_list, uniform_set_cache->get_cache(shader, 0, u_source_rd_texture), 0);704RD::get_singleton()->draw_list_bind_index_array(p_draw_list, material_storage->get_quad_index_array());705RD::get_singleton()->draw_list_set_push_constant(p_draw_list, ©_to_fb.push_constant, sizeof(CopyToFbPushConstant));706RD::get_singleton()->draw_list_draw(p_draw_list, true);707}708709void CopyEffects::copy_raster(RID p_source_texture, RID p_dest_framebuffer) {710ERR_FAIL_COND_MSG(!raster_effects.has_flag(RASTER_EFFECT_COPY), "Can't use the raster version of the copy.");711712UniformSetCacheRD *uniform_set_cache = UniformSetCacheRD::get_singleton();713ERR_FAIL_NULL(uniform_set_cache);714MaterialStorage *material_storage = MaterialStorage::get_singleton();715ERR_FAIL_NULL(material_storage);716717memset(&blur_raster.push_constant, 0, sizeof(BlurRasterPushConstant));718719// setup our uniforms720RID default_sampler = material_storage->sampler_rd_get_default(RS::CANVAS_ITEM_TEXTURE_FILTER_LINEAR, RS::CANVAS_ITEM_TEXTURE_REPEAT_DISABLED);721722RD::Uniform u_source_texture(RD::UNIFORM_TYPE_SAMPLER_WITH_TEXTURE, 0, Vector<RID>({ default_sampler, p_source_texture }));723724RID shader = blur_raster.shader.version_get_shader(blur_raster.shader_version, BLUR_MODE_COPY);725ERR_FAIL_COND(shader.is_null());726727// Just copy it back (we use our blur raster shader here)..728RD::DrawListID draw_list = RD::get_singleton()->draw_list_begin(p_dest_framebuffer);729RD::get_singleton()->draw_list_bind_render_pipeline(draw_list, blur_raster.pipelines[BLUR_MODE_COPY].get_render_pipeline(RD::INVALID_ID, RD::get_singleton()->framebuffer_get_format(p_dest_framebuffer)));730RD::get_singleton()->draw_list_bind_uniform_set(draw_list, uniform_set_cache->get_cache(shader, 0, u_source_texture), 0);731RD::get_singleton()->draw_list_set_push_constant(draw_list, &blur_raster.push_constant, sizeof(BlurRasterPushConstant));732733RD::get_singleton()->draw_list_draw(draw_list, false, 1u, 3u);734RD::get_singleton()->draw_list_end();735}736737void CopyEffects::gaussian_blur(RID p_source_rd_texture, RID p_texture, const Rect2i &p_region, const Size2i &p_size, bool p_8bit_dst) {738ERR_FAIL_COND_MSG(raster_effects.has_flag(RASTER_EFFECT_GAUSSIAN_BLUR), "Can't use the compute version of the gaussian blur.");739740UniformSetCacheRD *uniform_set_cache = UniformSetCacheRD::get_singleton();741ERR_FAIL_NULL(uniform_set_cache);742MaterialStorage *material_storage = MaterialStorage::get_singleton();743ERR_FAIL_NULL(material_storage);744745memset(©.push_constant, 0, sizeof(CopyPushConstant));746747copy.push_constant.section[0] = p_region.position.x;748copy.push_constant.section[1] = p_region.position.y;749copy.push_constant.target[0] = p_region.position.x;750copy.push_constant.target[1] = p_region.position.y;751copy.push_constant.section[2] = p_size.width;752copy.push_constant.section[3] = p_size.height;753754// setup our uniforms755RID default_sampler = material_storage->sampler_rd_get_default(RS::CANVAS_ITEM_TEXTURE_FILTER_LINEAR, RS::CANVAS_ITEM_TEXTURE_REPEAT_DISABLED);756757RD::Uniform u_source_rd_texture(RD::UNIFORM_TYPE_SAMPLER_WITH_TEXTURE, 0, Vector<RID>({ default_sampler, p_source_rd_texture }));758RD::Uniform u_texture(RD::UNIFORM_TYPE_IMAGE, 0, p_texture);759760CopyMode mode = p_8bit_dst ? COPY_MODE_GAUSSIAN_COPY_8BIT : COPY_MODE_GAUSSIAN_COPY;761RID shader = copy.shader.version_get_shader(copy.shader_version, mode);762ERR_FAIL_COND(shader.is_null());763764RD::DrawListID compute_list = RD::get_singleton()->compute_list_begin();765RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, copy.pipelines[mode].get_rid());766RD::get_singleton()->compute_list_bind_uniform_set(compute_list, uniform_set_cache->get_cache(shader, 0, u_source_rd_texture), 0);767RD::get_singleton()->compute_list_bind_uniform_set(compute_list, uniform_set_cache->get_cache(shader, 3, u_texture), 3);768769RD::get_singleton()->compute_list_set_push_constant(compute_list, ©.push_constant, sizeof(CopyPushConstant));770771RD::get_singleton()->compute_list_dispatch_threads(compute_list, p_region.size.width, p_region.size.height, 1);772773RD::get_singleton()->compute_list_end();774}775776void CopyEffects::gaussian_blur_raster(RID p_source_rd_texture, RID p_dest_texture, const Rect2i &p_region, const Size2i &p_size) {777ERR_FAIL_COND_MSG(!raster_effects.has_flag(RASTER_EFFECT_GAUSSIAN_BLUR), "Can't use the raster version of the gaussian blur.");778779UniformSetCacheRD *uniform_set_cache = UniformSetCacheRD::get_singleton();780ERR_FAIL_NULL(uniform_set_cache);781MaterialStorage *material_storage = MaterialStorage::get_singleton();782ERR_FAIL_NULL(material_storage);783784RID dest_framebuffer = FramebufferCacheRD::get_singleton()->get_cache(p_dest_texture);785786memset(&blur_raster.push_constant, 0, sizeof(BlurRasterPushConstant));787788BlurRasterMode blur_mode = BLUR_MODE_GAUSSIAN_BLUR;789790blur_raster.push_constant.dest_pixel_size[0] = 1.0 / float(p_size.x);791blur_raster.push_constant.dest_pixel_size[1] = 1.0 / float(p_size.y);792793// setup our uniforms794RID default_sampler = material_storage->sampler_rd_get_default(RS::CANVAS_ITEM_TEXTURE_FILTER_LINEAR, RS::CANVAS_ITEM_TEXTURE_REPEAT_DISABLED);795796RD::Uniform u_source_rd_texture(RD::UNIFORM_TYPE_SAMPLER_WITH_TEXTURE, 0, Vector<RID>({ default_sampler, p_source_rd_texture }));797798RID shader = blur_raster.shader.version_get_shader(blur_raster.shader_version, blur_mode);799ERR_FAIL_COND(shader.is_null());800801RD::DrawListID draw_list = RD::get_singleton()->draw_list_begin(dest_framebuffer);802RD::get_singleton()->draw_list_bind_render_pipeline(draw_list, blur_raster.pipelines[blur_mode].get_render_pipeline(RD::INVALID_ID, RD::get_singleton()->framebuffer_get_format(dest_framebuffer)));803RD::get_singleton()->draw_list_bind_uniform_set(draw_list, uniform_set_cache->get_cache(shader, 0, u_source_rd_texture), 0);804805RD::get_singleton()->draw_list_set_push_constant(draw_list, &blur_raster.push_constant, sizeof(BlurRasterPushConstant));806807RD::get_singleton()->draw_list_draw(draw_list, false, 1u, 3u);808RD::get_singleton()->draw_list_end();809}810811void CopyEffects::gaussian_glow(RID p_source_rd_texture, RID p_back_texture, const Size2i &p_size, float p_strength, bool p_first_pass, float p_luminance_cap, float p_exposure, float p_bloom, float p_hdr_bleed_threshold, float p_hdr_bleed_scale, RID p_auto_exposure, float p_auto_exposure_scale) {812ERR_FAIL_COND_MSG(raster_effects.has_flag(RASTER_EFFECT_GAUSSIAN_BLUR), "Can't use the compute version of the gaussian glow.");813814UniformSetCacheRD *uniform_set_cache = UniformSetCacheRD::get_singleton();815ERR_FAIL_NULL(uniform_set_cache);816MaterialStorage *material_storage = MaterialStorage::get_singleton();817ERR_FAIL_NULL(material_storage);818819memset(©.push_constant, 0, sizeof(CopyPushConstant));820821CopyMode copy_mode = p_first_pass && p_auto_exposure.is_valid() ? COPY_MODE_GAUSSIAN_GLOW_AUTO_EXPOSURE : COPY_MODE_GAUSSIAN_GLOW;822uint32_t base_flags = 0;823824copy.push_constant.section[2] = p_size.x;825copy.push_constant.section[3] = p_size.y;826827copy.push_constant.glow_strength = p_strength;828copy.push_constant.glow_bloom = p_bloom;829copy.push_constant.glow_hdr_threshold = p_hdr_bleed_threshold;830copy.push_constant.glow_hdr_scale = p_hdr_bleed_scale;831copy.push_constant.glow_exposure = p_exposure;832copy.push_constant.glow_white = 0; //actually unused833copy.push_constant.glow_luminance_cap = p_luminance_cap;834835copy.push_constant.glow_auto_exposure_scale = p_auto_exposure_scale; //unused also836837// setup our uniforms838RID default_sampler = material_storage->sampler_rd_get_default(RS::CANVAS_ITEM_TEXTURE_FILTER_LINEAR, RS::CANVAS_ITEM_TEXTURE_REPEAT_DISABLED);839840RD::Uniform u_source_rd_texture(RD::UNIFORM_TYPE_SAMPLER_WITH_TEXTURE, 0, Vector<RID>({ default_sampler, p_source_rd_texture }));841RD::Uniform u_back_texture(RD::UNIFORM_TYPE_IMAGE, 0, p_back_texture);842843RID shader = copy.shader.version_get_shader(copy.shader_version, copy_mode);844ERR_FAIL_COND(shader.is_null());845846RD::ComputeListID compute_list = RD::get_singleton()->compute_list_begin();847RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, copy.pipelines[copy_mode].get_rid());848RD::get_singleton()->compute_list_bind_uniform_set(compute_list, uniform_set_cache->get_cache(shader, 0, u_source_rd_texture), 0);849RD::get_singleton()->compute_list_bind_uniform_set(compute_list, uniform_set_cache->get_cache(shader, 3, u_back_texture), 3);850if (p_auto_exposure.is_valid() && p_first_pass) {851RD::Uniform u_auto_exposure(RD::UNIFORM_TYPE_SAMPLER_WITH_TEXTURE, 0, Vector<RID>({ default_sampler, p_auto_exposure }));852RD::get_singleton()->compute_list_bind_uniform_set(compute_list, uniform_set_cache->get_cache(shader, 1, u_auto_exposure), 1);853}854855copy.push_constant.flags = base_flags | (p_first_pass ? COPY_FLAG_GLOW_FIRST_PASS : 0);856RD::get_singleton()->compute_list_set_push_constant(compute_list, ©.push_constant, sizeof(CopyPushConstant));857858RD::get_singleton()->compute_list_dispatch_threads(compute_list, p_size.width, p_size.height, 1);859RD::get_singleton()->compute_list_end();860}861862void CopyEffects::gaussian_glow_downsample_raster(RID p_source_rd_texture, RID p_dest_texture, float p_luminance_multiplier, const Size2i &p_size, float p_strength, bool p_first_pass, float p_luminance_cap, float p_exposure, float p_bloom, float p_hdr_bleed_threshold, float p_hdr_bleed_scale) {863ERR_FAIL_COND_MSG(!raster_effects.has_flag(RASTER_EFFECT_GAUSSIAN_BLUR), "Can't use the raster version of the gaussian glow.");864865UniformSetCacheRD *uniform_set_cache = UniformSetCacheRD::get_singleton();866ERR_FAIL_NULL(uniform_set_cache);867MaterialStorage *material_storage = MaterialStorage::get_singleton();868ERR_FAIL_NULL(material_storage);869870RID dest_framebuffer = FramebufferCacheRD::get_singleton()->get_cache(p_dest_texture);871872memset(&blur_raster.push_constant, 0, sizeof(BlurRasterPushConstant));873874BlurRasterMode blur_mode = p_first_pass ? BLUR_MODE_GAUSSIAN_GLOW_GATHER : BLUR_MODE_GAUSSIAN_GLOW_DOWNSAMPLE;875876blur_raster.push_constant.source_pixel_size[0] = 1.0 / float(p_size.x);877blur_raster.push_constant.source_pixel_size[1] = 1.0 / float(p_size.y);878879blur_raster.push_constant.glow_strength = p_strength;880blur_raster.push_constant.glow_bloom = p_bloom;881blur_raster.push_constant.glow_hdr_threshold = p_hdr_bleed_threshold;882blur_raster.push_constant.glow_hdr_scale = p_hdr_bleed_scale;883blur_raster.push_constant.glow_exposure = p_exposure;884blur_raster.push_constant.glow_white = 0; //actually unused885blur_raster.push_constant.glow_luminance_cap = p_luminance_cap;886887blur_raster.push_constant.luminance_multiplier = p_luminance_multiplier;888889// setup our uniforms890RD::Uniform u_source_rd_texture(RD::UNIFORM_TYPE_SAMPLER_WITH_TEXTURE, 0, Vector<RID>({ blur_raster.glow_sampler, p_source_rd_texture }));891892RID shader = blur_raster.shader.version_get_shader(blur_raster.shader_version, blur_mode);893ERR_FAIL_COND(shader.is_null());894895RD::DrawListID draw_list = RD::get_singleton()->draw_list_begin(dest_framebuffer);896RD::get_singleton()->draw_list_bind_render_pipeline(draw_list, blur_raster.pipelines[blur_mode].get_render_pipeline(RD::INVALID_ID, RD::get_singleton()->framebuffer_get_format(dest_framebuffer)));897RD::get_singleton()->draw_list_bind_uniform_set(draw_list, uniform_set_cache->get_cache(shader, 0, u_source_rd_texture), 0);898899RD::get_singleton()->draw_list_set_push_constant(draw_list, &blur_raster.push_constant, sizeof(BlurRasterPushConstant));900901RD::get_singleton()->draw_list_draw(draw_list, false, 1u, 3u);902RD::get_singleton()->draw_list_end();903}904905void CopyEffects::gaussian_glow_upsample_raster(RID p_source_rd_texture, RID p_dest_texture, RID p_blend_texture, float p_luminance_multiplier, const Size2i &p_source_size, const Size2i &p_dest_size, float p_level, float p_base_strength, bool p_use_debanding) {906ERR_FAIL_COND_MSG(!raster_effects.has_flag(RASTER_EFFECT_GAUSSIAN_BLUR), "Can't use the raster version of the gaussian glow.");907908UniformSetCacheRD *uniform_set_cache = UniformSetCacheRD::get_singleton();909ERR_FAIL_NULL(uniform_set_cache);910MaterialStorage *material_storage = MaterialStorage::get_singleton();911ERR_FAIL_NULL(material_storage);912913RID dest_framebuffer = FramebufferCacheRD::get_singleton()->get_cache(p_dest_texture);914915memset(&blur_raster.push_constant, 0, sizeof(BlurRasterPushConstant));916917BlurRasterMode blur_mode = BLUR_MODE_GAUSSIAN_GLOW_UPSAMPLE;918919blur_raster.push_constant.source_pixel_size[0] = 1.0 / float(p_source_size.x);920blur_raster.push_constant.source_pixel_size[1] = 1.0 / float(p_source_size.y);921blur_raster.push_constant.dest_pixel_size[0] = 1.0 / float(p_dest_size.x);922blur_raster.push_constant.dest_pixel_size[1] = 1.0 / float(p_dest_size.y);923blur_raster.push_constant.luminance_multiplier = p_luminance_multiplier;924blur_raster.push_constant.level = p_level * 0.5;925blur_raster.push_constant.glow_strength = p_base_strength;926927uint32_t spec_constant = p_use_debanding ? 1 : 0;928spec_constant |= p_level > 0.01 ? 2 : 0;929930// setup our uniforms931RID default_sampler = material_storage->sampler_rd_get_default(RS::CANVAS_ITEM_TEXTURE_FILTER_LINEAR, RS::CANVAS_ITEM_TEXTURE_REPEAT_DISABLED);932RD::Uniform u_source_rd_texture(RD::UNIFORM_TYPE_SAMPLER_WITH_TEXTURE, 0, Vector<RID>({ default_sampler, p_source_rd_texture }));933RD::Uniform u_blend_rd_texture(RD::UNIFORM_TYPE_SAMPLER_WITH_TEXTURE, 0, Vector<RID>({ default_sampler, p_blend_texture }));934935RID shader = blur_raster.shader.version_get_shader(blur_raster.shader_version, blur_mode);936ERR_FAIL_COND(shader.is_null());937938RD::DrawListID draw_list = RD::get_singleton()->draw_list_begin(dest_framebuffer);939RD::get_singleton()->draw_list_bind_render_pipeline(draw_list, blur_raster.pipelines[blur_mode].get_render_pipeline(RD::INVALID_ID, RD::get_singleton()->framebuffer_get_format(dest_framebuffer), false, 0, spec_constant));940RD::get_singleton()->draw_list_bind_uniform_set(draw_list, uniform_set_cache->get_cache(shader, 0, u_source_rd_texture), 0);941RD::get_singleton()->draw_list_bind_uniform_set(draw_list, uniform_set_cache->get_cache(shader, 1, u_blend_rd_texture), 1);942943RD::get_singleton()->draw_list_set_push_constant(draw_list, &blur_raster.push_constant, sizeof(BlurRasterPushConstant));944945RD::get_singleton()->draw_list_draw(draw_list, false, 1u, 3u);946RD::get_singleton()->draw_list_end();947}948949void CopyEffects::make_mipmap(RID p_source_rd_texture, RID p_dest_texture, const Size2i &p_size) {950ERR_FAIL_COND_MSG(raster_effects.has_flag(RASTER_EFFECT_COPY), "Can't use the compute version of the make_mipmap shader.");951952UniformSetCacheRD *uniform_set_cache = UniformSetCacheRD::get_singleton();953ERR_FAIL_NULL(uniform_set_cache);954MaterialStorage *material_storage = MaterialStorage::get_singleton();955ERR_FAIL_NULL(material_storage);956957memset(©.push_constant, 0, sizeof(CopyPushConstant));958959copy.push_constant.section[0] = 0;960copy.push_constant.section[1] = 0;961copy.push_constant.section[2] = p_size.width;962copy.push_constant.section[3] = p_size.height;963964// setup our uniforms965RID default_sampler = material_storage->sampler_rd_get_default(RS::CANVAS_ITEM_TEXTURE_FILTER_LINEAR, RS::CANVAS_ITEM_TEXTURE_REPEAT_DISABLED);966967RD::Uniform u_source_rd_texture(RD::UNIFORM_TYPE_SAMPLER_WITH_TEXTURE, 0, Vector<RID>({ default_sampler, p_source_rd_texture }));968RD::Uniform u_dest_texture(RD::UNIFORM_TYPE_IMAGE, 0, p_dest_texture);969970CopyMode mode = COPY_MODE_MIPMAP;971RID shader = copy.shader.version_get_shader(copy.shader_version, mode);972ERR_FAIL_COND(shader.is_null());973974RD::ComputeListID compute_list = RD::get_singleton()->compute_list_begin();975RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, copy.pipelines[mode].get_rid());976RD::get_singleton()->compute_list_bind_uniform_set(compute_list, uniform_set_cache->get_cache(shader, 0, u_source_rd_texture), 0);977RD::get_singleton()->compute_list_bind_uniform_set(compute_list, uniform_set_cache->get_cache(shader, 3, u_dest_texture), 3);978RD::get_singleton()->compute_list_set_push_constant(compute_list, ©.push_constant, sizeof(CopyPushConstant));979RD::get_singleton()->compute_list_dispatch_threads(compute_list, p_size.width, p_size.height, 1);980RD::get_singleton()->compute_list_end();981}982983void CopyEffects::make_mipmap_raster(RID p_source_rd_texture, RID p_dest_texture, const Size2i &p_size) {984ERR_FAIL_COND_MSG(!raster_effects.has_flag(RASTER_EFFECT_COPY), "Can't use the raster version of mipmap.");985986RID dest_framebuffer = FramebufferCacheRD::get_singleton()->get_cache(p_dest_texture);987988UniformSetCacheRD *uniform_set_cache = UniformSetCacheRD::get_singleton();989ERR_FAIL_NULL(uniform_set_cache);990MaterialStorage *material_storage = MaterialStorage::get_singleton();991ERR_FAIL_NULL(material_storage);992993memset(&blur_raster.push_constant, 0, sizeof(BlurRasterPushConstant));994995BlurRasterMode mode = BLUR_MIPMAP;996997blur_raster.push_constant.dest_pixel_size[0] = 1.0 / float(p_size.x);998blur_raster.push_constant.dest_pixel_size[1] = 1.0 / float(p_size.y);9991000// setup our uniforms1001RID default_sampler = material_storage->sampler_rd_get_default(RS::CANVAS_ITEM_TEXTURE_FILTER_LINEAR, RS::CANVAS_ITEM_TEXTURE_REPEAT_DISABLED);10021003RD::Uniform u_source_rd_texture(RD::UNIFORM_TYPE_SAMPLER_WITH_TEXTURE, 0, Vector<RID>({ default_sampler, p_source_rd_texture }));10041005RID shader = blur_raster.shader.version_get_shader(blur_raster.shader_version, mode);1006ERR_FAIL_COND(shader.is_null());10071008RD::DrawListID draw_list = RD::get_singleton()->draw_list_begin(dest_framebuffer);1009RD::get_singleton()->draw_list_bind_render_pipeline(draw_list, blur_raster.pipelines[mode].get_render_pipeline(RD::INVALID_ID, RD::get_singleton()->framebuffer_get_format(dest_framebuffer)));1010RD::get_singleton()->draw_list_bind_uniform_set(draw_list, uniform_set_cache->get_cache(shader, 0, u_source_rd_texture), 0);1011RD::get_singleton()->draw_list_set_push_constant(draw_list, &blur_raster.push_constant, sizeof(BlurRasterPushConstant));10121013RD::get_singleton()->draw_list_draw(draw_list, false, 1u, 3u);1014RD::get_singleton()->draw_list_end();1015}10161017void CopyEffects::set_color(RID p_dest_texture, const Color &p_color, const Rect2i &p_region, bool p_8bit_dst) {1018ERR_FAIL_COND_MSG(raster_effects.has_flag(RASTER_EFFECT_COPY), "Can't use the compute version of the set_color shader.");10191020UniformSetCacheRD *uniform_set_cache = UniformSetCacheRD::get_singleton();1021ERR_FAIL_NULL(uniform_set_cache);10221023memset(©.push_constant, 0, sizeof(CopyPushConstant));10241025copy.push_constant.section[0] = 0;1026copy.push_constant.section[1] = 0;1027copy.push_constant.section[2] = p_region.size.width;1028copy.push_constant.section[3] = p_region.size.height;1029copy.push_constant.target[0] = p_region.position.x;1030copy.push_constant.target[1] = p_region.position.y;1031copy.push_constant.set_color[0] = p_color.r;1032copy.push_constant.set_color[1] = p_color.g;1033copy.push_constant.set_color[2] = p_color.b;1034copy.push_constant.set_color[3] = p_color.a;10351036// setup our uniforms1037RD::Uniform u_dest_texture(RD::UNIFORM_TYPE_IMAGE, 0, p_dest_texture);10381039CopyMode mode = p_8bit_dst ? COPY_MODE_SET_COLOR_8BIT : COPY_MODE_SET_COLOR;1040RID shader = copy.shader.version_get_shader(copy.shader_version, mode);1041ERR_FAIL_COND(shader.is_null());10421043RD::ComputeListID compute_list = RD::get_singleton()->compute_list_begin();1044RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, copy.pipelines[mode].get_rid());1045RD::get_singleton()->compute_list_bind_uniform_set(compute_list, uniform_set_cache->get_cache(shader, 3, u_dest_texture), 3);1046RD::get_singleton()->compute_list_set_push_constant(compute_list, ©.push_constant, sizeof(CopyPushConstant));1047RD::get_singleton()->compute_list_dispatch_threads(compute_list, p_region.size.width, p_region.size.height, 1);1048RD::get_singleton()->compute_list_end();1049}10501051void CopyEffects::set_color_raster(RID p_dest_texture, const Color &p_color, const Rect2i &p_region) {1052ERR_FAIL_COND_MSG(!raster_effects.has_flag(RASTER_EFFECT_COPY), "Can't use the raster version of the set_color shader.");10531054UniformSetCacheRD *uniform_set_cache = UniformSetCacheRD::get_singleton();1055ERR_FAIL_NULL(uniform_set_cache);1056MaterialStorage *material_storage = MaterialStorage::get_singleton();1057ERR_FAIL_NULL(material_storage);10581059memset(©_to_fb.push_constant, 0, sizeof(CopyToFbPushConstant));10601061copy_to_fb.push_constant.set_color[0] = p_color.r;1062copy_to_fb.push_constant.set_color[1] = p_color.g;1063copy_to_fb.push_constant.set_color[2] = p_color.b;1064copy_to_fb.push_constant.set_color[3] = p_color.a;10651066RID dest_framebuffer = FramebufferCacheRD::get_singleton()->get_cache(p_dest_texture);10671068CopyToFBMode mode = COPY_TO_FB_SET_COLOR;10691070RID shader = copy_to_fb.shader.version_get_shader(copy_to_fb.shader_version, mode);1071ERR_FAIL_COND(shader.is_null());10721073RD::DrawListID draw_list = RD::get_singleton()->draw_list_begin(dest_framebuffer, RD::DRAW_DEFAULT_ALL, Vector<Color>(), 1.0f, 0, p_region);1074RD::get_singleton()->draw_list_bind_render_pipeline(draw_list, copy_to_fb.pipelines[mode].get_render_pipeline(RD::INVALID_ID, RD::get_singleton()->framebuffer_get_format(dest_framebuffer)));1075RD::get_singleton()->draw_list_bind_index_array(draw_list, material_storage->get_quad_index_array());1076RD::get_singleton()->draw_list_set_push_constant(draw_list, ©_to_fb.push_constant, sizeof(CopyToFbPushConstant));1077RD::get_singleton()->draw_list_draw(draw_list, true);1078RD::get_singleton()->draw_list_end();1079}10801081void CopyEffects::copy_cubemap_to_dp(RID p_source_rd_texture, RID p_dst_framebuffer, const Rect2 &p_rect, const Vector2 &p_dst_size, float p_z_near, float p_z_far, bool p_dp_flip) {1082UniformSetCacheRD *uniform_set_cache = UniformSetCacheRD::get_singleton();1083ERR_FAIL_NULL(uniform_set_cache);1084MaterialStorage *material_storage = MaterialStorage::get_singleton();1085ERR_FAIL_NULL(material_storage);10861087Rect2i screen_rect;1088float atlas_width = p_dst_size.width / p_rect.size.width;1089float atlas_height = p_dst_size.height / p_rect.size.height;1090screen_rect.position.x = (int32_t)(Math::round(p_rect.position.x * atlas_width));1091screen_rect.position.y = (int32_t)(Math::round(p_rect.position.y * atlas_height));1092screen_rect.size.width = (int32_t)(Math::round(p_dst_size.width));1093screen_rect.size.height = (int32_t)(Math::round(p_dst_size.height));10941095CopyToDPPushConstant push_constant;1096push_constant.z_far = p_z_far;1097push_constant.z_near = p_z_near;1098push_constant.texel_size[0] = 1.0f / p_dst_size.width;1099push_constant.texel_size[1] = 1.0f / p_dst_size.height;1100push_constant.texel_size[0] *= p_dp_flip ? -1.0f : 1.0f; // Encode dp flip as x size sign11011102// setup our uniforms1103RID default_sampler = material_storage->sampler_rd_get_default(RS::CANVAS_ITEM_TEXTURE_FILTER_LINEAR, RS::CANVAS_ITEM_TEXTURE_REPEAT_DISABLED);11041105RD::Uniform u_source_rd_texture(RD::UNIFORM_TYPE_SAMPLER_WITH_TEXTURE, 0, Vector<RID>({ default_sampler, p_source_rd_texture }));11061107RID shader = cube_to_dp.shader.version_get_shader(cube_to_dp.shader_version, 0);1108ERR_FAIL_COND(shader.is_null());11091110RD::DrawListID draw_list = RD::get_singleton()->draw_list_begin(p_dst_framebuffer, RD::DRAW_DEFAULT_ALL, Vector<Color>(), 1.0f, 0, screen_rect);1111RD::get_singleton()->draw_list_bind_render_pipeline(draw_list, cube_to_dp.pipeline.get_render_pipeline(RD::INVALID_ID, RD::get_singleton()->framebuffer_get_format(p_dst_framebuffer)));1112RD::get_singleton()->draw_list_bind_uniform_set(draw_list, uniform_set_cache->get_cache(shader, 0, u_source_rd_texture), 0);1113RD::get_singleton()->draw_list_bind_index_array(draw_list, material_storage->get_quad_index_array());11141115RD::get_singleton()->draw_list_set_push_constant(draw_list, &push_constant, sizeof(CopyToDPPushConstant));1116RD::get_singleton()->draw_list_draw(draw_list, true);1117RD::get_singleton()->draw_list_end();1118}11191120void CopyEffects::copy_cubemap_to_octmap(RID p_source_rd_texture, RID p_dst_framebuffer, float p_border_size) {1121UniformSetCacheRD *uniform_set_cache = UniformSetCacheRD::get_singleton();1122ERR_FAIL_NULL(uniform_set_cache);1123MaterialStorage *material_storage = MaterialStorage::get_singleton();1124ERR_FAIL_NULL(material_storage);1125RID shader = cube_to_octmap.shader.version_get_shader(cube_to_octmap.shader_version, 0);1126ERR_FAIL_COND(shader.is_null());11271128cube_to_octmap.push_constant.border_size = 1.0f - p_border_size * 2.0f;11291130RID default_sampler = material_storage->sampler_rd_get_default(RS::CANVAS_ITEM_TEXTURE_FILTER_LINEAR, RS::CANVAS_ITEM_TEXTURE_REPEAT_DISABLED);1131RD::Uniform u_source_rd_texture(RD::UNIFORM_TYPE_SAMPLER_WITH_TEXTURE, 0, Vector<RID>({ default_sampler, p_source_rd_texture }));11321133RD::DrawListID draw_list = RD::get_singleton()->draw_list_begin(p_dst_framebuffer);1134RD::get_singleton()->draw_list_bind_render_pipeline(draw_list, cube_to_octmap.pipeline.get_render_pipeline(RD::INVALID_ID, RD::get_singleton()->framebuffer_get_format(p_dst_framebuffer)));1135RD::get_singleton()->draw_list_bind_uniform_set(draw_list, uniform_set_cache->get_cache(shader, 0, u_source_rd_texture), 0);1136RD::get_singleton()->draw_list_bind_index_array(draw_list, material_storage->get_quad_index_array());1137RD::get_singleton()->draw_list_set_push_constant(draw_list, &cube_to_octmap.push_constant, sizeof(CopyToOctmapPushConstant));1138RD::get_singleton()->draw_list_draw(draw_list, true);1139RD::get_singleton()->draw_list_end();1140}11411142void CopyEffects::octmap_downsample(RID p_source_octmap, RID p_dest_octmap, const Size2i &p_size, float p_border_size) {1143ERR_FAIL_COND_MSG(raster_effects.has_flag(RASTER_EFFECT_OCTMAP), "Can't use compute based octmap downsample.");11441145UniformSetCacheRD *uniform_set_cache = UniformSetCacheRD::get_singleton();1146ERR_FAIL_NULL(uniform_set_cache);1147MaterialStorage *material_storage = MaterialStorage::get_singleton();1148ERR_FAIL_NULL(material_storage);11491150octmap_downsampler.push_constant.size = p_size.x;1151octmap_downsampler.push_constant.border_size = 1.0f - p_border_size * 2.0f;11521153// setup our uniforms1154RID default_sampler = material_storage->sampler_rd_get_default(RS::CANVAS_ITEM_TEXTURE_FILTER_LINEAR, RS::CANVAS_ITEM_TEXTURE_REPEAT_DISABLED);11551156RD::Uniform u_source_octmap(RD::UNIFORM_TYPE_SAMPLER_WITH_TEXTURE, 0, Vector<RID>({ default_sampler, p_source_octmap }));1157RD::Uniform u_dest_octmap(RD::UNIFORM_TYPE_IMAGE, 0, Vector<RID>({ p_dest_octmap }));11581159int mode = 0;11601161RD::TextureFormat texture_format = RD::get_singleton()->texture_get_format(p_dest_octmap);1162switch (texture_format.format) {1163case RD::DATA_FORMAT_A2B10G10R10_UNORM_PACK32: {1164mode |= DOWNSAMPLER_MODE_FLAG_RGB10_A2;1165} break;1166case RD::DATA_FORMAT_R16G16B16A16_SFLOAT: {1167// Absence of the flag indicates RGBA16F.1168} break;1169default: {1170ERR_FAIL_MSG("Unrecognized octmap format.");1171}1172}11731174RID shader = octmap_downsampler.compute_shader.version_get_shader(octmap_downsampler.shader_version, mode);1175ERR_FAIL_COND(shader.is_null());11761177RD::ComputeListID compute_list = RD::get_singleton()->compute_list_begin();1178RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, octmap_downsampler.compute_pipelines[mode].get_rid());1179RD::get_singleton()->compute_list_bind_uniform_set(compute_list, uniform_set_cache->get_cache(shader, 0, u_source_octmap), 0);1180RD::get_singleton()->compute_list_bind_uniform_set(compute_list, uniform_set_cache->get_cache(shader, 1, u_dest_octmap), 1);11811182int x_groups = Math::division_round_up(p_size.x, 8);1183int y_groups = Math::division_round_up(p_size.y, 8);11841185RD::get_singleton()->compute_list_set_push_constant(compute_list, &octmap_downsampler.push_constant, sizeof(OctmapDownsamplerPushConstant));11861187RD::get_singleton()->compute_list_dispatch(compute_list, x_groups, y_groups, 1);11881189RD::get_singleton()->compute_list_end();1190}11911192void CopyEffects::octmap_downsample_raster(RID p_source_octmap, RID p_dest_framebuffer, const Size2i &p_size, float p_border_size) {1193ERR_FAIL_COND_MSG(!raster_effects.has_flag(RASTER_EFFECT_OCTMAP), "Can't use raster based octmap downsample.");11941195UniformSetCacheRD *uniform_set_cache = UniformSetCacheRD::get_singleton();1196ERR_FAIL_NULL(uniform_set_cache);1197MaterialStorage *material_storage = MaterialStorage::get_singleton();1198ERR_FAIL_NULL(material_storage);11991200octmap_downsampler.push_constant.size = p_size.x;1201octmap_downsampler.push_constant.border_size = 1.0f - p_border_size * 2.0f;12021203// setup our uniforms1204RID default_sampler = material_storage->sampler_rd_get_default(RS::CANVAS_ITEM_TEXTURE_FILTER_LINEAR, RS::CANVAS_ITEM_TEXTURE_REPEAT_DISABLED);12051206RD::Uniform u_source_cubemap(RD::UNIFORM_TYPE_SAMPLER_WITH_TEXTURE, 0, Vector<RID>({ default_sampler, p_source_octmap }));12071208RID shader = octmap_downsampler.raster_shader.version_get_shader(octmap_downsampler.shader_version, 0);1209ERR_FAIL_COND(shader.is_null());12101211RD::DrawListID draw_list = RD::get_singleton()->draw_list_begin(p_dest_framebuffer, RD::DRAW_IGNORE_COLOR_ALL);1212RD::get_singleton()->draw_list_bind_render_pipeline(draw_list, octmap_downsampler.raster_pipeline.get_render_pipeline(RD::INVALID_ID, RD::get_singleton()->framebuffer_get_format(p_dest_framebuffer)));1213RD::get_singleton()->draw_list_bind_uniform_set(draw_list, uniform_set_cache->get_cache(shader, 0, u_source_cubemap), 0);12141215RD::get_singleton()->draw_list_set_push_constant(draw_list, &octmap_downsampler.push_constant, sizeof(OctmapDownsamplerPushConstant));12161217RD::get_singleton()->draw_list_draw(draw_list, false, 1u, 3u);1218RD::get_singleton()->draw_list_end();1219}12201221static constexpr int _compute_dispatch_size(bool p_use_array) {1222constexpr int SIZE = 320;1223constexpr int GROUP = 64;1224constexpr int LEVELS = 6; // One less than Sky::REAL_TIME_ROUGHNESS_LAYERS.1225int size = 0;1226if (p_use_array) {1227size = SIZE * SIZE * LEVELS;1228} else {1229int dim = SIZE;1230for (int i = 0; i < LEVELS && dim >= 2; i++) {1231size += dim * dim;1232dim >>= 1;1233}1234}12351236return (size + GROUP - 1) / GROUP;1237}12381239void CopyEffects::octmap_filter(RID p_source_octmap, const Vector<RID> &p_dest_octmap, bool p_use_array, float p_border_size) {1240ERR_FAIL_COND_MSG(raster_effects.has_flag(RASTER_EFFECT_OCTMAP), "Can't use compute based octmap filter.");1241ERR_FAIL_COND(p_dest_octmap.is_empty());12421243UniformSetCacheRD *uniform_set_cache = UniformSetCacheRD::get_singleton();1244ERR_FAIL_NULL(uniform_set_cache);1245MaterialStorage *material_storage = MaterialStorage::get_singleton();1246ERR_FAIL_NULL(material_storage);12471248OctmapFilterPushConstant push_constant;1249push_constant.border_size[0] = p_border_size;1250push_constant.border_size[1] = 1.0f - p_border_size * 2.0f;12511252Vector<RD::Uniform> uniforms;1253for (int i = 0; i < p_dest_octmap.size(); i++) {1254RD::Uniform u;1255u.uniform_type = RD::UNIFORM_TYPE_IMAGE;1256u.binding = i;1257u.append_id(p_dest_octmap[i]);1258uniforms.push_back(u);1259}1260if (RD::get_singleton()->uniform_set_is_valid(filter.image_uniform_set)) {1261RD::get_singleton()->free_rid(filter.image_uniform_set);1262}1263filter.image_uniform_set = RD::get_singleton()->uniform_set_create(uniforms, filter.compute_shader.version_get_shader(filter.shader_version, 0), 2);12641265// setup our uniforms1266RID default_mipmap_sampler = material_storage->sampler_rd_get_default(RS::CANVAS_ITEM_TEXTURE_FILTER_LINEAR_WITH_MIPMAPS, RS::CANVAS_ITEM_TEXTURE_REPEAT_DISABLED);12671268RD::Uniform u_source_octmap(RD::UNIFORM_TYPE_SAMPLER_WITH_TEXTURE, 0, Vector<RID>({ default_mipmap_sampler, p_source_octmap }));12691270int mode = 0;1271if (p_use_array) {1272mode |= FILTER_MODE_FLAG_ARRAY;1273}1274if (filter.use_high_quality) {1275mode |= FILTER_MODE_FLAG_HIGH_QUALITY;1276}12771278RD::TextureFormat texture_format = RD::get_singleton()->texture_get_format(p_dest_octmap[0]);1279switch (texture_format.format) {1280case RD::DATA_FORMAT_A2B10G10R10_UNORM_PACK32: {1281mode |= FILTER_MODE_FLAG_RGB10_A2;1282} break;1283case RD::DATA_FORMAT_R16G16B16A16_SFLOAT: {1284// Absence of the flag indicates RGBA16F.1285} break;1286default: {1287ERR_FAIL_MSG("Unrecognized octmap format.");1288}1289}12901291RID shader = filter.compute_shader.version_get_shader(filter.shader_version, mode);1292ERR_FAIL_COND(shader.is_null());12931294RD::ComputeListID compute_list = RD::get_singleton()->compute_list_begin();1295RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, filter.compute_pipelines[mode].get_rid());1296RD::get_singleton()->compute_list_bind_uniform_set(compute_list, uniform_set_cache->get_cache(shader, 0, u_source_octmap), 0);1297RD::get_singleton()->compute_list_bind_uniform_set(compute_list, filter.uniform_set, 1);1298RD::get_singleton()->compute_list_bind_uniform_set(compute_list, filter.image_uniform_set, 2);12991300RD::get_singleton()->compute_list_set_push_constant(compute_list, &push_constant, sizeof(OctmapFilterPushConstant));13011302RD::get_singleton()->compute_list_dispatch(compute_list, _compute_dispatch_size(p_use_array), 1, 1);13031304RD::get_singleton()->compute_list_end();1305}13061307void CopyEffects::octmap_filter_raster(RID p_source_octmap, RID p_dest_framebuffer, uint32_t p_mip_level, float p_border_size) {1308ERR_FAIL_COND_MSG(!raster_effects.has_flag(RASTER_EFFECT_OCTMAP), "Can't use raster based octmap filter.");13091310UniformSetCacheRD *uniform_set_cache = UniformSetCacheRD::get_singleton();1311ERR_FAIL_NULL(uniform_set_cache);1312MaterialStorage *material_storage = MaterialStorage::get_singleton();1313ERR_FAIL_NULL(material_storage);13141315OctmapFilterRasterPushConstant push_constant;1316push_constant.border_size[0] = p_border_size;1317push_constant.border_size[1] = 1.0f - p_border_size * 2.0f;1318push_constant.mip_level = p_mip_level;13191320// setup our uniforms1321RID default_mipmap_sampler = material_storage->sampler_rd_get_default(RS::CANVAS_ITEM_TEXTURE_FILTER_LINEAR_WITH_MIPMAPS, RS::CANVAS_ITEM_TEXTURE_REPEAT_DISABLED);13221323RD::Uniform u_source_octmap(RD::UNIFORM_TYPE_SAMPLER_WITH_TEXTURE, 0, Vector<RID>({ default_mipmap_sampler, p_source_octmap }));13241325int mode = 0;1326if (filter.use_high_quality) {1327mode |= FILTER_MODE_FLAG_HIGH_QUALITY;1328}13291330RID shader = filter.raster_shader.version_get_shader(filter.shader_version, mode);1331ERR_FAIL_COND(shader.is_null());13321333RD::DrawListID draw_list = RD::get_singleton()->draw_list_begin(p_dest_framebuffer, RD::DRAW_IGNORE_COLOR_ALL);1334RD::get_singleton()->draw_list_bind_render_pipeline(draw_list, filter.raster_pipelines[mode].get_render_pipeline(RD::INVALID_ID, RD::get_singleton()->framebuffer_get_format(p_dest_framebuffer)));1335RD::get_singleton()->draw_list_bind_uniform_set(draw_list, uniform_set_cache->get_cache(shader, 0, u_source_octmap), 0);1336RD::get_singleton()->draw_list_bind_uniform_set(draw_list, filter.uniform_set, 1);13371338RD::get_singleton()->draw_list_set_push_constant(draw_list, &push_constant, sizeof(OctmapFilterRasterPushConstant));13391340RD::get_singleton()->draw_list_draw(draw_list, false, 1u, 3u);1341RD::get_singleton()->draw_list_end();1342}13431344void CopyEffects::octmap_roughness(RID p_source_rd_texture, RID p_dest_texture, uint32_t p_sample_count, float p_roughness, uint32_t p_source_size, uint32_t p_dest_size, float p_border_size) {1345ERR_FAIL_COND_MSG(raster_effects.has_flag(RASTER_EFFECT_OCTMAP), "Can't use compute based octmap roughness.");13461347UniformSetCacheRD *uniform_set_cache = UniformSetCacheRD::get_singleton();1348ERR_FAIL_NULL(uniform_set_cache);1349MaterialStorage *material_storage = MaterialStorage::get_singleton();1350ERR_FAIL_NULL(material_storage);13511352memset(&roughness.push_constant, 0, sizeof(OctmapRoughnessPushConstant));13531354// Remap to perceptual-roughness^2 to create more detail in lower mips and match the mapping of octmap_filter.1355roughness.push_constant.roughness = p_roughness * p_roughness;1356roughness.push_constant.sample_count = MIN(p_sample_count, 64u);1357roughness.push_constant.source_size = p_source_size;1358roughness.push_constant.dest_size = p_dest_size;1359roughness.push_constant.use_direct_write = p_roughness == 0.0;1360roughness.push_constant.border_size[0] = p_border_size;1361roughness.push_constant.border_size[1] = 1.0f - p_border_size * 2.0;13621363// setup our uniforms1364RID default_mipmap_sampler = material_storage->sampler_rd_get_default(RS::CANVAS_ITEM_TEXTURE_FILTER_LINEAR_WITH_MIPMAPS, RS::CANVAS_ITEM_TEXTURE_REPEAT_DISABLED);13651366RD::Uniform u_source_rd_texture(RD::UNIFORM_TYPE_SAMPLER_WITH_TEXTURE, 0, Vector<RID>({ default_mipmap_sampler, p_source_rd_texture }));1367RD::Uniform u_dest_texture(RD::UNIFORM_TYPE_IMAGE, 0, Vector<RID>({ p_dest_texture }));13681369OctmapRoughnessMode mode;1370RD::TextureFormat texture_format = RD::get_singleton()->texture_get_format(p_dest_texture);1371switch (texture_format.format) {1372case RD::DATA_FORMAT_A2B10G10R10_UNORM_PACK32: {1373mode = ROUGHNESS_MODE_RGB10_A2;1374} break;1375case RD::DATA_FORMAT_R16G16B16A16_SFLOAT: {1376mode = ROUGHNESS_MODE_RGBA16F;1377} break;1378default: {1379ERR_FAIL_MSG("Unrecognized octmap format.");1380}1381}13821383RID shader = roughness.compute_shader.version_get_shader(roughness.shader_version, mode);1384ERR_FAIL_COND(shader.is_null());13851386RD::ComputeListID compute_list = RD::get_singleton()->compute_list_begin();1387RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, roughness.compute_pipelines[mode].get_rid());13881389RD::get_singleton()->compute_list_bind_uniform_set(compute_list, uniform_set_cache->get_cache(shader, 0, u_source_rd_texture), 0);1390RD::get_singleton()->compute_list_bind_uniform_set(compute_list, uniform_set_cache->get_cache(shader, 1, u_dest_texture), 1);13911392RD::get_singleton()->compute_list_set_push_constant(compute_list, &roughness.push_constant, sizeof(OctmapRoughnessPushConstant));13931394int x_groups = (p_dest_size + 7) / 8;1395int y_groups = x_groups;13961397RD::get_singleton()->compute_list_dispatch(compute_list, x_groups, y_groups, 1);13981399RD::get_singleton()->compute_list_end();1400}14011402void CopyEffects::octmap_roughness_raster(RID p_source_rd_texture, RID p_dest_framebuffer, uint32_t p_sample_count, float p_roughness, uint32_t p_source_size, uint32_t p_dest_size, float p_border_size) {1403ERR_FAIL_COND_MSG(!raster_effects.has_flag(RASTER_EFFECT_OCTMAP), "Can't use raster based octmap roughness.");14041405UniformSetCacheRD *uniform_set_cache = UniformSetCacheRD::get_singleton();1406ERR_FAIL_NULL(uniform_set_cache);1407MaterialStorage *material_storage = MaterialStorage::get_singleton();1408ERR_FAIL_NULL(material_storage);14091410memset(&roughness.push_constant, 0, sizeof(OctmapRoughnessPushConstant));14111412roughness.push_constant.roughness = p_roughness * p_roughness; // Shader expects roughness, not perceptual roughness, so multiply before passing in.1413roughness.push_constant.sample_count = MAX(uint32_t(float(p_sample_count * 4u) * roughness.push_constant.roughness), 4u);1414roughness.push_constant.source_size = p_source_size;1415roughness.push_constant.dest_size = p_dest_size;1416roughness.push_constant.use_direct_write = p_roughness == 0.0;1417roughness.push_constant.border_size[0] = p_border_size;1418roughness.push_constant.border_size[1] = 1.0f - p_border_size * 2.0;14191420// Setup our uniforms.1421RID default_sampler = material_storage->sampler_rd_get_default(RS::CANVAS_ITEM_TEXTURE_FILTER_LINEAR_WITH_MIPMAPS, RS::CANVAS_ITEM_TEXTURE_REPEAT_DISABLED);14221423RD::Uniform u_source_rd_texture(RD::UNIFORM_TYPE_SAMPLER_WITH_TEXTURE, 0, Vector<RID>({ default_sampler, p_source_rd_texture }));14241425RID shader = roughness.raster_shader.version_get_shader(roughness.shader_version, 0);1426ERR_FAIL_COND(shader.is_null());14271428RD::DrawListID draw_list = RD::get_singleton()->draw_list_begin(p_dest_framebuffer, RD::DRAW_IGNORE_COLOR_ALL);1429RD::get_singleton()->draw_list_bind_render_pipeline(draw_list, roughness.raster_pipeline.get_render_pipeline(RD::INVALID_ID, RD::get_singleton()->framebuffer_get_format(p_dest_framebuffer)));1430RD::get_singleton()->draw_list_bind_uniform_set(draw_list, uniform_set_cache->get_cache(shader, 0, u_source_rd_texture), 0);14311432RD::get_singleton()->draw_list_set_push_constant(draw_list, &roughness.push_constant, sizeof(OctmapRoughnessPushConstant));14331434RD::get_singleton()->draw_list_draw(draw_list, false, 1u, 3u);1435RD::get_singleton()->draw_list_end();1436}14371438void CopyEffects::merge_specular(RID p_dest_framebuffer, RID p_specular, RID p_base, RID p_reflection, uint32_t p_view_count) {1439UniformSetCacheRD *uniform_set_cache = UniformSetCacheRD::get_singleton();1440ERR_FAIL_NULL(uniform_set_cache);1441MaterialStorage *material_storage = MaterialStorage::get_singleton();1442ERR_FAIL_NULL(material_storage);14431444RID default_sampler = material_storage->sampler_rd_get_default(RS::CANVAS_ITEM_TEXTURE_FILTER_LINEAR, RS::CANVAS_ITEM_TEXTURE_REPEAT_DISABLED);14451446RD::get_singleton()->draw_command_begin_label("Merge Specular");14471448RD::DrawListID draw_list = RD::get_singleton()->draw_list_begin(p_dest_framebuffer);14491450int mode;1451if (p_reflection.is_valid()) {1452if (p_base.is_valid()) {1453mode = SPECULAR_MERGE_SSR;1454} else {1455mode = SPECULAR_MERGE_ADDITIVE_SSR;1456}1457} else {1458if (p_base.is_valid()) {1459mode = SPECULAR_MERGE_ADD;1460} else {1461mode = SPECULAR_MERGE_ADDITIVE_ADD;1462}1463}14641465if (p_view_count > 1) {1466mode += SPECULAR_MERGE_ADD_MULTIVIEW;1467}14681469RID shader = specular_merge.shader.version_get_shader(specular_merge.shader_version, mode);1470RD::get_singleton()->draw_list_bind_render_pipeline(draw_list, specular_merge.pipelines[mode].get_render_pipeline(RD::INVALID_ID, RD::get_singleton()->framebuffer_get_format(p_dest_framebuffer)));14711472if (p_base.is_valid()) {1473RD::Uniform u_base(RD::UNIFORM_TYPE_SAMPLER_WITH_TEXTURE, 0, Vector<RID>({ default_sampler, p_base }));1474RD::get_singleton()->draw_list_bind_uniform_set(draw_list, uniform_set_cache->get_cache(shader, 2, u_base), 2);1475}14761477RD::Uniform u_specular(RD::UNIFORM_TYPE_SAMPLER_WITH_TEXTURE, 0, Vector<RID>({ default_sampler, p_specular }));1478RD::get_singleton()->draw_list_bind_uniform_set(draw_list, uniform_set_cache->get_cache(shader, 0, u_specular), 0);14791480if (p_reflection.is_valid()) {1481RD::Uniform u_reflection(RD::UNIFORM_TYPE_SAMPLER_WITH_TEXTURE, 0, Vector<RID>({ default_sampler, p_reflection }));1482RD::get_singleton()->draw_list_bind_uniform_set(draw_list, uniform_set_cache->get_cache(shader, 1, u_reflection), 1);1483}14841485RD::get_singleton()->draw_list_draw(draw_list, false, 1u, 3u);1486RD::get_singleton()->draw_list_end();14871488RD::get_singleton()->draw_command_end_label();1489}149014911492