2019-11-05 11:01:00 +00:00
/*************************************************************************/
2020-12-04 18:26:24 +00:00
/* renderer_scene_render_rd.cpp */
2019-11-05 11:01:00 +00:00
/*************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
2022-01-03 20:27:34 +00:00
/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */
2019-11-05 11:01:00 +00:00
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
/* "Software"), to deal in the Software without restriction, including */
/* without limitation the rights to use, copy, modify, merge, publish, */
/* distribute, sublicense, and/or sell copies of the Software, and to */
/* permit persons to whom the Software is furnished to do so, subject to */
/* the following conditions: */
/* */
/* The above copyright notice and this permission notice shall be */
/* included in all copies or substantial portions of the Software. */
/* */
/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
2020-12-04 18:26:24 +00:00
# include "renderer_scene_render_rd.h"
2020-02-12 08:59:06 +00:00
2020-11-07 22:33:38 +00:00
# include "core/config/project_settings.h"
2019-09-07 01:51:27 +00:00
# include "core/os/os.h"
2020-12-04 18:26:24 +00:00
# include "renderer_compositor_rd.h"
2022-06-21 00:08:33 +00:00
# include "servers/rendering/renderer_rd/environment/fog.h"
2022-03-21 11:25:25 +00:00
# include "servers/rendering/renderer_rd/storage_rd/material_storage.h"
# include "servers/rendering/renderer_rd/storage_rd/texture_storage.h"
2020-12-03 21:09:47 +00:00
# include "servers/rendering/rendering_server_default.h"
2022-07-31 23:20:24 +00:00
# include "servers/rendering/storage/camera_attributes_storage.h"
2020-07-01 12:18:13 +00:00
2020-04-10 09:30:36 +00:00
void get_vogel_disk ( float * r_kernel , int p_sample_count ) {
const float golden_angle = 2.4 ;
for ( int i = 0 ; i < p_sample_count ; i + + ) {
float r = Math : : sqrt ( float ( i ) + 0.5 ) / Math : : sqrt ( float ( p_sample_count ) ) ;
float theta = float ( i ) * golden_angle ;
r_kernel [ i * 4 ] = Math : : cos ( theta ) * r ;
r_kernel [ i * 4 + 1 ] = Math : : sin ( theta ) * r ;
}
}
2022-08-04 08:40:39 +00:00
void RendererSceneRenderRD : : sdfgi_update ( const Ref < RenderSceneBuffers > & p_render_buffers , RID p_environment , const Vector3 & p_world_position ) {
Ref < RenderSceneBuffersRD > rb = p_render_buffers ;
ERR_FAIL_COND ( rb . is_null ( ) ) ;
Ref < RendererRD : : GI : : SDFGI > sdfgi ;
if ( rb - > has_custom_data ( RB_SCOPE_SDFGI ) ) {
sdfgi = rb - > get_custom_data ( RB_SCOPE_SDFGI ) ;
}
2022-07-27 06:14:23 +00:00
bool needs_sdfgi = p_environment . is_valid ( ) & & environment_get_sdfgi_enabled ( p_environment ) ;
2020-06-25 13:33:28 +00:00
if ( ! needs_sdfgi ) {
2022-08-04 08:40:39 +00:00
if ( sdfgi . is_valid ( ) ) {
// delete it
sdfgi . unref ( ) ;
rb - > set_custom_data ( RB_SCOPE_SDFGI , sdfgi ) ;
2020-06-25 13:33:28 +00:00
}
return ;
}
static const uint32_t history_frames_to_converge [ RS : : ENV_SDFGI_CONVERGE_MAX ] = { 5 , 10 , 15 , 20 , 25 , 30 } ;
2021-02-13 12:08:08 +00:00
uint32_t requested_history_size = history_frames_to_converge [ gi . sdfgi_frames_to_converge ] ;
2020-06-25 13:33:28 +00:00
2022-08-04 08:40:39 +00:00
if ( sdfgi . is_valid ( ) & & ( sdfgi - > num_cascades ! = environment_get_sdfgi_cascades ( p_environment ) | | sdfgi - > min_cell_size ! = environment_get_sdfgi_min_cell_size ( p_environment ) | | requested_history_size ! = sdfgi - > history_size | | sdfgi - > uses_occlusion ! = environment_get_sdfgi_use_occlusion ( p_environment ) | | sdfgi - > y_scale_mode ! = environment_get_sdfgi_y_scale ( p_environment ) ) ) {
2020-06-25 13:33:28 +00:00
//configuration changed, erase
2022-08-04 08:40:39 +00:00
sdfgi . unref ( ) ;
rb - > set_custom_data ( RB_SCOPE_SDFGI , sdfgi ) ;
2020-06-25 13:33:28 +00:00
}
2022-08-04 08:40:39 +00:00
if ( sdfgi . is_null ( ) ) {
2021-02-13 12:08:08 +00:00
// re-create
2022-08-04 08:40:39 +00:00
sdfgi = gi . create_sdfgi ( p_environment , p_world_position , requested_history_size ) ;
rb - > set_custom_data ( RB_SCOPE_SDFGI , sdfgi ) ;
2021-02-13 12:08:08 +00:00
} else {
//check for updates
2022-08-04 08:40:39 +00:00
sdfgi - > update ( p_environment , p_world_position ) ;
2021-02-13 12:08:08 +00:00
}
}
2020-06-25 13:33:28 +00:00
2022-08-04 08:40:39 +00:00
int RendererSceneRenderRD : : sdfgi_get_pending_region_count ( const Ref < RenderSceneBuffers > & p_render_buffers ) const {
Ref < RenderSceneBuffersRD > rb = p_render_buffers ;
ERR_FAIL_COND_V ( rb . is_null ( ) , 0 ) ;
2020-06-25 13:33:28 +00:00
2022-08-04 08:40:39 +00:00
if ( ! rb - > has_custom_data ( RB_SCOPE_SDFGI ) ) {
2021-02-13 12:08:08 +00:00
return 0 ;
}
2022-08-04 08:40:39 +00:00
Ref < RendererRD : : GI : : SDFGI > sdfgi = rb - > get_custom_data ( RB_SCOPE_SDFGI ) ;
2020-06-25 13:33:28 +00:00
2021-02-13 12:08:08 +00:00
int dirty_count = 0 ;
2022-08-04 08:40:39 +00:00
for ( uint32_t i = 0 ; i < sdfgi - > cascades . size ( ) ; i + + ) {
const RendererRD : : GI : : SDFGI : : Cascade & c = sdfgi - > cascades [ i ] ;
2020-06-25 13:33:28 +00:00
2022-05-20 02:52:19 +00:00
if ( c . dirty_regions = = RendererRD : : GI : : SDFGI : : Cascade : : DIRTY_ALL ) {
2020-06-25 13:33:28 +00:00
dirty_count + + ;
} else {
2021-02-13 12:08:08 +00:00
for ( int j = 0 ; j < 3 ; j + + ) {
if ( c . dirty_regions [ j ] ! = 0 ) {
dirty_count + + ;
}
}
2020-03-20 00:32:19 +00:00
}
}
2021-02-13 12:08:08 +00:00
return dirty_count ;
}
2020-03-20 00:32:19 +00:00
2022-08-04 08:40:39 +00:00
AABB RendererSceneRenderRD : : sdfgi_get_pending_region_bounds ( const Ref < RenderSceneBuffers > & p_render_buffers , int p_region ) const {
2021-02-13 12:08:08 +00:00
AABB bounds ;
Vector3i from ;
Vector3i size ;
2020-03-20 00:32:19 +00:00
2022-08-04 08:40:39 +00:00
Ref < RenderSceneBuffersRD > rb = p_render_buffers ;
ERR_FAIL_COND_V ( rb . is_null ( ) , AABB ( ) ) ;
Ref < RendererRD : : GI : : SDFGI > sdfgi = rb - > get_custom_data ( RB_SCOPE_SDFGI ) ;
ERR_FAIL_COND_V ( sdfgi . is_null ( ) , AABB ( ) ) ;
int c = sdfgi - > get_pending_region_data ( p_region , from , size , bounds ) ;
2021-02-13 12:08:08 +00:00
ERR_FAIL_COND_V ( c = = - 1 , AABB ( ) ) ;
return bounds ;
}
2020-03-20 00:32:19 +00:00
2022-08-04 08:40:39 +00:00
uint32_t RendererSceneRenderRD : : sdfgi_get_pending_region_cascade ( const Ref < RenderSceneBuffers > & p_render_buffers , int p_region ) const {
2021-02-13 12:08:08 +00:00
AABB bounds ;
Vector3i from ;
Vector3i size ;
2020-03-20 00:32:19 +00:00
2022-08-04 08:40:39 +00:00
Ref < RenderSceneBuffersRD > rb = p_render_buffers ;
ERR_FAIL_COND_V ( rb . is_null ( ) , - 1 ) ;
Ref < RendererRD : : GI : : SDFGI > sdfgi = rb - > get_custom_data ( RB_SCOPE_SDFGI ) ;
ERR_FAIL_COND_V ( sdfgi . is_null ( ) , - 1 ) ;
return sdfgi - > get_pending_region_data ( p_region , from , size , bounds ) ;
2021-02-13 12:08:08 +00:00
}
2020-03-20 00:32:19 +00:00
2021-02-13 12:08:08 +00:00
RID RendererSceneRenderRD : : sky_allocate ( ) {
return sky . allocate_sky_rid ( ) ;
}
void RendererSceneRenderRD : : sky_initialize ( RID p_rid ) {
sky . initialize_sky_rid ( p_rid ) ;
}
2020-03-20 00:32:19 +00:00
2021-02-13 12:08:08 +00:00
void RendererSceneRenderRD : : sky_set_radiance_size ( RID p_sky , int p_radiance_size ) {
sky . sky_set_radiance_size ( p_sky , p_radiance_size ) ;
2020-03-20 00:32:19 +00:00
}
2021-02-13 12:08:08 +00:00
void RendererSceneRenderRD : : sky_set_mode ( RID p_sky , RS : : SkyMode p_mode ) {
sky . sky_set_mode ( p_sky , p_mode ) ;
}
2020-03-20 00:32:19 +00:00
2021-02-13 12:08:08 +00:00
void RendererSceneRenderRD : : sky_set_material ( RID p_sky , RID p_material ) {
sky . sky_set_material ( p_sky , p_material ) ;
2020-03-20 00:32:19 +00:00
}
2021-02-13 12:08:08 +00:00
Ref < Image > RendererSceneRenderRD : : sky_bake_panorama ( RID p_sky , float p_energy , bool p_bake_irradiance , const Size2i & p_size ) {
return sky . sky_bake_panorama ( p_sky , p_energy , p_bake_irradiance , p_size ) ;
2020-03-20 00:32:19 +00:00
}
2020-12-04 18:26:24 +00:00
void RendererSceneRenderRD : : environment_glow_set_use_bicubic_upscale ( bool p_enable ) {
2020-03-30 13:46:03 +00:00
glow_bicubic_upscale = p_enable ;
2019-08-27 18:27:35 +00:00
}
2020-12-04 18:26:24 +00:00
void RendererSceneRenderRD : : environment_glow_set_use_high_quality ( bool p_enable ) {
2020-09-01 06:04:45 +00:00
glow_high_quality = p_enable ;
}
2020-12-04 18:26:24 +00:00
void RendererSceneRenderRD : : environment_set_volumetric_fog_volume_size ( int p_size , int p_depth ) {
2020-08-13 01:21:01 +00:00
volumetric_fog_size = p_size ;
volumetric_fog_depth = p_depth ;
}
2020-12-04 18:26:24 +00:00
void RendererSceneRenderRD : : environment_set_volumetric_fog_filter_active ( bool p_enable ) {
2020-08-13 01:21:01 +00:00
volumetric_fog_filter_active = p_enable ;
}
2020-12-04 18:26:24 +00:00
void RendererSceneRenderRD : : environment_set_sdfgi_ray_count ( RS : : EnvironmentSDFGIRayCount p_ray_count ) {
2021-02-13 12:08:08 +00:00
gi . sdfgi_ray_count = p_ray_count ;
2020-06-25 13:33:28 +00:00
}
2020-12-04 18:26:24 +00:00
void RendererSceneRenderRD : : environment_set_sdfgi_frames_to_converge ( RS : : EnvironmentSDFGIFramesToConverge p_frames ) {
2021-02-13 12:08:08 +00:00
gi . sdfgi_frames_to_converge = p_frames ;
2020-06-25 13:33:28 +00:00
}
2021-01-22 23:50:24 +00:00
void RendererSceneRenderRD : : environment_set_sdfgi_frames_to_update_light ( RS : : EnvironmentSDFGIFramesToUpdateLight p_update ) {
2021-02-13 12:08:08 +00:00
gi . sdfgi_frames_to_update_light = p_update ;
2021-01-22 23:50:24 +00:00
}
2020-06-25 13:33:28 +00:00
2020-12-04 18:26:24 +00:00
void RendererSceneRenderRD : : environment_set_ssr_roughness_quality ( RS : : EnvironmentSSRRoughnessQuality p_quality ) {
2020-04-02 02:24:52 +00:00
ssr_roughness_quality = p_quality ;
}
2020-12-04 18:26:24 +00:00
RS : : EnvironmentSSRRoughnessQuality RendererSceneRenderRD : : environment_get_ssr_roughness_quality ( ) const {
2020-04-02 02:24:52 +00:00
return ssr_roughness_quality ;
}
2020-12-08 05:37:09 +00:00
void RendererSceneRenderRD : : environment_set_ssao_quality ( RS : : EnvironmentSSAOQuality p_quality , bool p_half_size , float p_adaptive_target , int p_blur_passes , float p_fadeout_from , float p_fadeout_to ) {
2020-01-25 10:18:55 +00:00
ssao_quality = p_quality ;
2020-10-18 22:27:51 +00:00
ssao_half_size = p_half_size ;
2020-12-08 05:37:09 +00:00
ssao_adaptive_target = p_adaptive_target ;
ssao_blur_passes = p_blur_passes ;
ssao_fadeout_from = p_fadeout_from ;
ssao_fadeout_to = p_fadeout_to ;
2020-01-25 10:18:55 +00:00
}
2021-08-03 07:07:32 +00:00
void RendererSceneRenderRD : : environment_set_ssil_quality ( RS : : EnvironmentSSILQuality p_quality , bool p_half_size , float p_adaptive_target , int p_blur_passes , float p_fadeout_from , float p_fadeout_to ) {
ssil_quality = p_quality ;
ssil_half_size = p_half_size ;
ssil_adaptive_target = p_adaptive_target ;
ssil_blur_passes = p_blur_passes ;
ssil_fadeout_from = p_fadeout_from ;
ssil_fadeout_to = p_fadeout_to ;
}
2020-12-04 18:26:24 +00:00
Ref < Image > RendererSceneRenderRD : : environment_bake_panorama ( RID p_env , bool p_bake_irradiance , const Size2i & p_size ) {
2022-07-27 06:14:23 +00:00
ERR_FAIL_COND_V ( p_env . is_null ( ) , Ref < Image > ( ) ) ;
2020-05-01 12:34:23 +00:00
2022-07-27 06:14:23 +00:00
RS : : EnvironmentBG environment_background = environment_get_background ( p_env ) ;
2021-12-24 14:47:42 +00:00
if ( environment_background = = RS : : ENV_BG_CAMERA_FEED | | environment_background = = RS : : ENV_BG_CANVAS | | environment_background = = RS : : ENV_BG_KEEP ) {
2020-05-01 12:34:23 +00:00
return Ref < Image > ( ) ; //nothing to bake
}
2022-07-27 06:14:23 +00:00
RS : : EnvironmentAmbientSource ambient_source = environment_get_ambient_source ( p_env ) ;
2021-12-24 14:47:42 +00:00
bool use_ambient_light = false ;
bool use_cube_map = false ;
if ( ambient_source = = RS : : ENV_AMBIENT_SOURCE_BG & & ( environment_background = = RS : : ENV_BG_CLEAR_COLOR | | environment_background = = RS : : ENV_BG_COLOR ) ) {
use_ambient_light = true ;
} else {
use_cube_map = ( ambient_source = = RS : : ENV_AMBIENT_SOURCE_BG & & environment_background = = RS : : ENV_BG_SKY ) | | ambient_source = = RS : : ENV_AMBIENT_SOURCE_SKY ;
use_ambient_light = use_cube_map | | ambient_source = = RS : : ENV_AMBIENT_SOURCE_COLOR ;
}
2022-07-27 06:14:23 +00:00
use_cube_map = use_cube_map | | ( environment_background = = RS : : ENV_BG_SKY & & environment_get_sky ( p_env ) . is_valid ( ) ) ;
2021-12-24 14:47:42 +00:00
Color ambient_color ;
2022-07-27 06:14:23 +00:00
float ambient_color_sky_mix = 0.0 ;
2021-12-24 14:47:42 +00:00
if ( use_ambient_light ) {
2022-07-27 06:14:23 +00:00
ambient_color_sky_mix = environment_get_ambient_sky_contribution ( p_env ) ;
const float ambient_energy = environment_get_ambient_light_energy ( p_env ) ;
ambient_color = environment_get_ambient_light ( p_env ) ;
2022-04-13 08:37:22 +00:00
ambient_color = ambient_color . srgb_to_linear ( ) ;
2021-12-24 14:47:42 +00:00
ambient_color . r * = ambient_energy ;
ambient_color . g * = ambient_energy ;
ambient_color . b * = ambient_energy ;
}
if ( use_cube_map ) {
2022-07-31 23:20:24 +00:00
Ref < Image > panorama = sky_bake_panorama ( environment_get_sky ( p_env ) , environment_get_bg_energy_multiplier ( p_env ) , p_bake_irradiance , p_size ) ;
2021-12-24 14:47:42 +00:00
if ( use_ambient_light ) {
for ( int x = 0 ; x < p_size . width ; x + + ) {
for ( int y = 0 ; y < p_size . height ; y + + ) {
panorama - > set_pixel ( x , y , ambient_color . lerp ( panorama - > get_pixel ( x , y ) , ambient_color_sky_mix ) ) ;
}
2020-05-01 12:34:23 +00:00
}
}
2021-12-24 14:47:42 +00:00
return panorama ;
} else {
2022-07-31 23:20:24 +00:00
const float bg_energy_multiplier = environment_get_bg_energy_multiplier ( p_env ) ;
2022-07-27 06:14:23 +00:00
Color panorama_color = ( ( environment_background = = RS : : ENV_BG_CLEAR_COLOR ) ? RSG : : texture_storage - > get_default_clear_color ( ) : environment_get_bg_color ( p_env ) ) ;
2022-04-13 08:37:22 +00:00
panorama_color = panorama_color . srgb_to_linear ( ) ;
2022-07-31 23:20:24 +00:00
panorama_color . r * = bg_energy_multiplier ;
panorama_color . g * = bg_energy_multiplier ;
panorama_color . b * = bg_energy_multiplier ;
2021-12-24 14:47:42 +00:00
if ( use_ambient_light ) {
panorama_color = ambient_color . lerp ( panorama_color , ambient_color_sky_mix ) ;
}
2020-05-01 12:34:23 +00:00
2021-12-24 14:47:42 +00:00
Ref < Image > panorama ;
panorama . instantiate ( ) ;
panorama - > create ( p_size . width , p_size . height , false , Image : : FORMAT_RGBAF ) ;
2022-01-08 11:58:15 +00:00
panorama - > fill ( panorama_color ) ;
2021-12-24 14:47:42 +00:00
return panorama ;
2020-05-01 12:34:23 +00:00
}
}
2019-09-07 01:51:27 +00:00
////////////////////////////////////////////////////////////
2021-10-03 11:28:55 +00:00
RID RendererSceneRenderRD : : fog_volume_instance_create ( RID p_fog_volume ) {
2022-07-19 04:17:58 +00:00
return RendererRD : : Fog : : get_singleton ( ) - > fog_volume_instance_create ( p_fog_volume ) ;
2021-10-03 11:28:55 +00:00
}
2022-07-19 04:17:58 +00:00
2021-10-03 11:28:55 +00:00
void RendererSceneRenderRD : : fog_volume_instance_set_transform ( RID p_fog_volume_instance , const Transform3D & p_transform ) {
2022-07-19 04:17:58 +00:00
RendererRD : : Fog : : FogVolumeInstance * fvi = RendererRD : : Fog : : get_singleton ( ) - > get_fog_volume_instance ( p_fog_volume_instance ) ;
2021-10-03 11:28:55 +00:00
ERR_FAIL_COND ( ! fvi ) ;
fvi - > transform = p_transform ;
}
void RendererSceneRenderRD : : fog_volume_instance_set_active ( RID p_fog_volume_instance , bool p_active ) {
2022-07-19 04:17:58 +00:00
RendererRD : : Fog : : FogVolumeInstance * fvi = RendererRD : : Fog : : get_singleton ( ) - > get_fog_volume_instance ( p_fog_volume_instance ) ;
2021-10-03 11:28:55 +00:00
ERR_FAIL_COND ( ! fvi ) ;
fvi - > active = p_active ;
}
RID RendererSceneRenderRD : : fog_volume_instance_get_volume ( RID p_fog_volume_instance ) const {
2022-07-19 04:17:58 +00:00
RendererRD : : Fog : : FogVolumeInstance * fvi = RendererRD : : Fog : : get_singleton ( ) - > get_fog_volume_instance ( p_fog_volume_instance ) ;
2021-10-03 11:28:55 +00:00
ERR_FAIL_COND_V ( ! fvi , RID ( ) ) ;
return fvi - > volume ;
}
Vector3 RendererSceneRenderRD : : fog_volume_instance_get_position ( RID p_fog_volume_instance ) const {
2022-07-19 04:17:58 +00:00
RendererRD : : Fog : : FogVolumeInstance * fvi = RendererRD : : Fog : : get_singleton ( ) - > get_fog_volume_instance ( p_fog_volume_instance ) ;
2021-10-03 11:28:55 +00:00
ERR_FAIL_COND_V ( ! fvi , Vector3 ( ) ) ;
return fvi - > transform . get_origin ( ) ;
}
////////////////////////////////////////////////////////////
2020-12-04 18:26:24 +00:00
RID RendererSceneRenderRD : : reflection_atlas_create ( ) {
2019-09-09 20:50:51 +00:00
ReflectionAtlas ra ;
2021-02-17 16:44:49 +00:00
ra . count = GLOBAL_GET ( " rendering/reflections/reflection_atlas/reflection_count " ) ;
ra . size = GLOBAL_GET ( " rendering/reflections/reflection_atlas/reflection_size " ) ;
2019-09-09 20:50:51 +00:00
2021-03-23 10:46:31 +00:00
if ( is_clustered_enabled ( ) ) {
ra . cluster_builder = memnew ( ClusterBuilderRD ) ;
ra . cluster_builder - > set_shared ( & cluster_builder_shared ) ;
ra . cluster_builder - > setup ( Size2i ( ra . size , ra . size ) , max_cluster_elements , RID ( ) , RID ( ) , RID ( ) ) ;
} else {
ra . cluster_builder = nullptr ;
}
2021-01-17 16:25:38 +00:00
2019-09-09 20:50:51 +00:00
return reflection_atlas_owner . make_rid ( ra ) ;
}
2020-12-04 18:26:24 +00:00
void RendererSceneRenderRD : : reflection_atlas_set_size ( RID p_ref_atlas , int p_reflection_size , int p_reflection_count ) {
2021-09-29 17:08:41 +00:00
ReflectionAtlas * ra = reflection_atlas_owner . get_or_null ( p_ref_atlas ) ;
2019-09-09 20:50:51 +00:00
ERR_FAIL_COND ( ! ra ) ;
if ( ra - > size = = p_reflection_size & & ra - > count = = p_reflection_count ) {
return ; //no changes
}
2021-03-23 10:46:31 +00:00
if ( ra - > cluster_builder ) {
// only if we're using our cluster
ra - > cluster_builder - > setup ( Size2i ( ra - > size , ra - > size ) , max_cluster_elements , RID ( ) , RID ( ) , RID ( ) ) ;
}
2021-01-17 16:25:38 +00:00
2020-02-20 23:27:34 +00:00
ra - > size = p_reflection_size ;
ra - > count = p_reflection_count ;
2019-09-09 20:50:51 +00:00
if ( ra - > reflection . is_valid ( ) ) {
//clear and invalidate everything
RD : : get_singleton ( ) - > free ( ra - > reflection ) ;
ra - > reflection = RID ( ) ;
2020-03-01 07:26:57 +00:00
RD : : get_singleton ( ) - > free ( ra - > depth_buffer ) ;
ra - > depth_buffer = RID ( ) ;
2019-09-09 20:50:51 +00:00
for ( int i = 0 ; i < ra - > reflections . size ( ) ; i + + ) {
2021-02-13 12:08:08 +00:00
ra - > reflections . write [ i ] . data . clear_reflection_data ( ) ;
2019-09-09 20:50:51 +00:00
if ( ra - > reflections [ i ] . owner . is_null ( ) ) {
continue ;
}
reflection_probe_release_atlas_index ( ra - > reflections [ i ] . owner ) ;
//rp->atlasindex clear
}
ra - > reflections . clear ( ) ;
}
}
2020-12-17 18:56:59 +00:00
int RendererSceneRenderRD : : reflection_atlas_get_size ( RID p_ref_atlas ) const {
2021-09-29 17:08:41 +00:00
ReflectionAtlas * ra = reflection_atlas_owner . get_or_null ( p_ref_atlas ) ;
2020-12-17 18:56:59 +00:00
ERR_FAIL_COND_V ( ! ra , 0 ) ;
return ra - > size ;
}
2019-09-09 20:50:51 +00:00
////////////////////////
2020-12-04 18:26:24 +00:00
RID RendererSceneRenderRD : : reflection_probe_instance_create ( RID p_probe ) {
2019-09-07 01:51:27 +00:00
ReflectionProbeInstance rpi ;
rpi . probe = p_probe ;
2021-07-15 20:06:33 +00:00
rpi . forward_id = _allocate_forward_id ( FORWARD_ID_TYPE_REFLECTION_PROBE ) ;
2019-09-07 01:51:27 +00:00
return reflection_probe_instance_owner . make_rid ( rpi ) ;
}
2020-10-17 05:08:21 +00:00
void RendererSceneRenderRD : : reflection_probe_instance_set_transform ( RID p_instance , const Transform3D & p_transform ) {
2021-09-29 17:08:41 +00:00
ReflectionProbeInstance * rpi = reflection_probe_instance_owner . get_or_null ( p_instance ) ;
2019-09-07 01:51:27 +00:00
ERR_FAIL_COND ( ! rpi ) ;
rpi - > transform = p_transform ;
rpi - > dirty = true ;
}
2020-12-04 18:26:24 +00:00
void RendererSceneRenderRD : : reflection_probe_release_atlas_index ( RID p_instance ) {
2021-09-29 17:08:41 +00:00
ReflectionProbeInstance * rpi = reflection_probe_instance_owner . get_or_null ( p_instance ) ;
2019-09-09 20:50:51 +00:00
ERR_FAIL_COND ( ! rpi ) ;
if ( rpi - > atlas . is_null ( ) ) {
return ; //nothing to release
}
2021-09-29 17:08:41 +00:00
ReflectionAtlas * atlas = reflection_atlas_owner . get_or_null ( rpi - > atlas ) ;
2019-09-09 20:50:51 +00:00
ERR_FAIL_COND ( ! atlas ) ;
ERR_FAIL_INDEX ( rpi - > atlas_index , atlas - > reflections . size ( ) ) ;
atlas - > reflections . write [ rpi - > atlas_index ] . owner = RID ( ) ;
rpi - > atlas_index = - 1 ;
rpi - > atlas = RID ( ) ;
}
2020-12-04 18:26:24 +00:00
bool RendererSceneRenderRD : : reflection_probe_instance_needs_redraw ( RID p_instance ) {
2021-09-29 17:08:41 +00:00
ReflectionProbeInstance * rpi = reflection_probe_instance_owner . get_or_null ( p_instance ) ;
2019-09-07 01:51:27 +00:00
ERR_FAIL_COND_V ( ! rpi , false ) ;
if ( rpi - > rendering ) {
return false ;
}
if ( rpi - > dirty ) {
return true ;
}
2022-04-09 09:34:31 +00:00
if ( RSG : : light_storage - > reflection_probe_get_update_mode ( rpi - > probe ) = = RS : : REFLECTION_PROBE_UPDATE_ALWAYS ) {
2019-09-07 01:51:27 +00:00
return true ;
}
2019-09-09 20:50:51 +00:00
return rpi - > atlas_index = = - 1 ;
2019-09-07 01:51:27 +00:00
}
2020-12-04 18:26:24 +00:00
bool RendererSceneRenderRD : : reflection_probe_instance_has_reflection ( RID p_instance ) {
2021-09-29 17:08:41 +00:00
ReflectionProbeInstance * rpi = reflection_probe_instance_owner . get_or_null ( p_instance ) ;
2019-09-09 20:50:51 +00:00
ERR_FAIL_COND_V ( ! rpi , false ) ;
2019-09-07 01:51:27 +00:00
2019-09-09 20:50:51 +00:00
return rpi - > atlas . is_valid ( ) ;
}
2019-09-07 01:51:27 +00:00
2020-12-04 18:26:24 +00:00
bool RendererSceneRenderRD : : reflection_probe_instance_begin_render ( RID p_instance , RID p_reflection_atlas ) {
2021-09-29 17:08:41 +00:00
ReflectionAtlas * atlas = reflection_atlas_owner . get_or_null ( p_reflection_atlas ) ;
2019-09-09 20:50:51 +00:00
ERR_FAIL_COND_V ( ! atlas , false ) ;
2021-09-29 17:08:41 +00:00
ReflectionProbeInstance * rpi = reflection_probe_instance_owner . get_or_null ( p_instance ) ;
2020-02-20 23:27:34 +00:00
ERR_FAIL_COND_V ( ! rpi , false ) ;
2021-07-27 13:33:47 +00:00
RD : : get_singleton ( ) - > draw_command_begin_label ( " Reflection probe render " ) ;
2022-04-09 09:34:31 +00:00
if ( RSG : : light_storage - > reflection_probe_get_update_mode ( rpi - > probe ) = = RS : : REFLECTION_PROBE_UPDATE_ALWAYS & & atlas - > reflection . is_valid ( ) & & atlas - > size ! = 256 ) {
2020-03-20 00:32:19 +00:00
WARN_PRINT ( " ReflectionProbes set to UPDATE_ALWAYS must have an atlas size of 256. Please update the atlas size in the ProjectSettings. " ) ;
reflection_atlas_set_size ( p_reflection_atlas , 256 , atlas - > count ) ;
2020-02-20 23:27:34 +00:00
}
2022-04-09 09:34:31 +00:00
if ( RSG : : light_storage - > reflection_probe_get_update_mode ( rpi - > probe ) = = RS : : REFLECTION_PROBE_UPDATE_ALWAYS & & atlas - > reflection . is_valid ( ) & & atlas - > reflections [ 0 ] . data . layers [ 0 ] . mipmaps . size ( ) ! = 8 ) {
2020-03-01 01:16:50 +00:00
// Invalidate reflection atlas, need to regenerate
RD : : get_singleton ( ) - > free ( atlas - > reflection ) ;
atlas - > reflection = RID ( ) ;
for ( int i = 0 ; i < atlas - > reflections . size ( ) ; i + + ) {
if ( atlas - > reflections [ i ] . owner . is_null ( ) ) {
continue ;
}
reflection_probe_release_atlas_index ( atlas - > reflections [ i ] . owner ) ;
}
atlas - > reflections . clear ( ) ;
}
2019-09-09 20:50:51 +00:00
if ( atlas - > reflection . is_null ( ) ) {
2021-02-13 12:08:08 +00:00
int mipmaps = MIN ( sky . roughness_layers , Image : : get_image_required_mipmaps ( atlas - > size , atlas - > size , Image : : FORMAT_RGBAH ) + 1 ) ;
2022-04-09 09:34:31 +00:00
mipmaps = RSG : : light_storage - > reflection_probe_get_update_mode ( rpi - > probe ) = = RS : : REFLECTION_PROBE_UPDATE_ALWAYS ? 8 : mipmaps ; // always use 8 mipmaps with real time filtering
2019-09-07 01:51:27 +00:00
{
2019-09-09 20:50:51 +00:00
//reflection atlas was unused, create:
2019-09-07 01:51:27 +00:00
RD : : TextureFormat tf ;
2019-09-09 20:50:51 +00:00
tf . array_layers = 6 * atlas - > count ;
2021-06-17 10:37:08 +00:00
tf . format = _render_buffers_get_color_format ( ) ;
2020-11-27 03:50:05 +00:00
tf . texture_type = RD : : TEXTURE_TYPE_CUBE_ARRAY ;
2020-02-20 23:27:34 +00:00
tf . mipmaps = mipmaps ;
2019-09-09 20:50:51 +00:00
tf . width = atlas - > size ;
tf . height = atlas - > size ;
2021-07-15 20:06:33 +00:00
tf . usage_bits = RD : : TEXTURE_USAGE_COLOR_ATTACHMENT_BIT | RD : : TEXTURE_USAGE_SAMPLING_BIT | ( _render_buffers_can_be_storage ( ) ? RD : : TEXTURE_USAGE_STORAGE_BIT : 0 ) ;
2019-09-09 20:50:51 +00:00
atlas - > reflection = RD : : get_singleton ( ) - > texture_create ( tf , RD : : TextureView ( ) ) ;
}
{
RD : : TextureFormat tf ;
tf . format = RD : : get_singleton ( ) - > texture_is_format_supported_for_usage ( RD : : DATA_FORMAT_D32_SFLOAT , RD : : TEXTURE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT ) ? RD : : DATA_FORMAT_D32_SFLOAT : RD : : DATA_FORMAT_X8_D24_UNORM_PACK32 ;
tf . width = atlas - > size ;
tf . height = atlas - > size ;
tf . usage_bits = RD : : TEXTURE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT | RD : : TEXTURE_USAGE_SAMPLING_BIT ;
atlas - > depth_buffer = RD : : get_singleton ( ) - > texture_create ( tf , RD : : TextureView ( ) ) ;
2019-09-07 01:51:27 +00:00
}
2019-09-09 20:50:51 +00:00
atlas - > reflections . resize ( atlas - > count ) ;
for ( int i = 0 ; i < atlas - > count ; i + + ) {
2022-06-21 00:08:33 +00:00
atlas - > reflections . write [ i ] . data . update_reflection_data ( atlas - > size , mipmaps , false , atlas - > reflection , i * 6 , RSG : : light_storage - > reflection_probe_get_update_mode ( rpi - > probe ) = = RS : : REFLECTION_PROBE_UPDATE_ALWAYS , sky . roughness_layers , _render_buffers_get_color_format ( ) ) ;
2019-09-09 20:50:51 +00:00
for ( int j = 0 ; j < 6 ; j + + ) {
2021-06-26 10:49:25 +00:00
atlas - > reflections . write [ i ] . fbs [ j ] = reflection_probe_create_framebuffer ( atlas - > reflections . write [ i ] . data . layers [ 0 ] . mipmaps [ 0 ] . views [ j ] , atlas - > depth_buffer ) ;
2019-09-09 20:50:51 +00:00
}
}
2019-10-03 20:39:08 +00:00
Vector < RID > fb ;
fb . push_back ( atlas - > depth_buffer ) ;
atlas - > depth_fb = RD : : get_singleton ( ) - > framebuffer_create ( fb ) ;
2019-09-09 20:50:51 +00:00
}
2019-09-07 01:51:27 +00:00
2019-09-09 20:50:51 +00:00
if ( rpi - > atlas_index = = - 1 ) {
for ( int i = 0 ; i < atlas - > reflections . size ( ) ; i + + ) {
if ( atlas - > reflections [ i ] . owner . is_null ( ) ) {
rpi - > atlas_index = i ;
break ;
}
}
//find the one used last
if ( rpi - > atlas_index = = - 1 ) {
//everything is in use, find the one least used via LRU
uint64_t pass_min = 0 ;
for ( int i = 0 ; i < atlas - > reflections . size ( ) ; i + + ) {
2021-09-29 17:08:41 +00:00
ReflectionProbeInstance * rpi2 = reflection_probe_instance_owner . get_or_null ( atlas - > reflections [ i ] . owner ) ;
2019-09-09 20:50:51 +00:00
if ( rpi2 - > last_pass < pass_min ) {
pass_min = rpi2 - > last_pass ;
rpi - > atlas_index = i ;
}
}
2019-09-07 01:51:27 +00:00
}
}
2019-09-09 20:50:51 +00:00
2021-07-06 03:00:33 +00:00
if ( rpi - > atlas_index ! = - 1 ) { // should we fail if this is still -1 ?
atlas - > reflections . write [ rpi - > atlas_index ] . owner = p_instance ;
}
2019-09-09 20:50:51 +00:00
rpi - > atlas = p_reflection_atlas ;
rpi - > rendering = true ;
rpi - > dirty = false ;
2020-03-01 01:16:50 +00:00
rpi - > processing_layer = 1 ;
2019-09-09 20:50:51 +00:00
rpi - > processing_side = 0 ;
2021-07-27 13:33:47 +00:00
RD : : get_singleton ( ) - > draw_command_end_label ( ) ;
2019-09-09 20:50:51 +00:00
return true ;
2019-09-07 01:51:27 +00:00
}
2021-06-26 10:49:25 +00:00
RID RendererSceneRenderRD : : reflection_probe_create_framebuffer ( RID p_color , RID p_depth ) {
Vector < RID > fb ;
fb . push_back ( p_color ) ;
fb . push_back ( p_depth ) ;
return RD : : get_singleton ( ) - > framebuffer_create ( fb ) ;
}
2020-12-04 18:26:24 +00:00
bool RendererSceneRenderRD : : reflection_probe_instance_postprocess_step ( RID p_instance ) {
2021-09-29 17:08:41 +00:00
ReflectionProbeInstance * rpi = reflection_probe_instance_owner . get_or_null ( p_instance ) ;
2019-09-07 01:51:27 +00:00
ERR_FAIL_COND_V ( ! rpi , false ) ;
ERR_FAIL_COND_V ( ! rpi - > rendering , false ) ;
2019-09-09 20:50:51 +00:00
ERR_FAIL_COND_V ( rpi - > atlas . is_null ( ) , false ) ;
2021-09-29 17:08:41 +00:00
ReflectionAtlas * atlas = reflection_atlas_owner . get_or_null ( rpi - > atlas ) ;
2019-09-09 20:50:51 +00:00
if ( ! atlas | | rpi - > atlas_index = = - 1 ) {
//does not belong to an atlas anymore, cancel (was removed from atlas or atlas changed while rendering)
rpi - > rendering = false ;
return false ;
}
2019-09-07 01:51:27 +00:00
2022-04-09 09:34:31 +00:00
if ( RSG : : light_storage - > reflection_probe_get_update_mode ( rpi - > probe ) = = RS : : REFLECTION_PROBE_UPDATE_ALWAYS ) {
2020-03-20 00:32:19 +00:00
// Using real time reflections, all roughness is done in one step
2022-06-21 00:08:33 +00:00
atlas - > reflections . write [ rpi - > atlas_index ] . data . create_reflection_fast_filter ( false ) ;
2020-03-20 00:32:19 +00:00
rpi - > rendering = false ;
rpi - > processing_side = 0 ;
rpi - > processing_layer = 1 ;
return true ;
}
2020-03-01 01:16:50 +00:00
if ( rpi - > processing_layer > 1 ) {
2022-06-21 00:08:33 +00:00
atlas - > reflections . write [ rpi - > atlas_index ] . data . create_reflection_importance_sample ( false , 10 , rpi - > processing_layer , sky . sky_ggx_samples_quality ) ;
2020-03-01 01:16:50 +00:00
rpi - > processing_layer + + ;
if ( rpi - > processing_layer = = atlas - > reflections [ rpi - > atlas_index ] . data . layers [ 0 ] . mipmaps . size ( ) ) {
rpi - > rendering = false ;
rpi - > processing_side = 0 ;
rpi - > processing_layer = 1 ;
return true ;
}
return false ;
} else {
2022-06-21 00:08:33 +00:00
atlas - > reflections . write [ rpi - > atlas_index ] . data . create_reflection_importance_sample ( false , rpi - > processing_side , rpi - > processing_layer , sky . sky_ggx_samples_quality ) ;
2020-02-20 23:27:34 +00:00
}
2019-09-07 01:51:27 +00:00
rpi - > processing_side + + ;
if ( rpi - > processing_side = = 6 ) {
rpi - > processing_side = 0 ;
2020-03-01 01:16:50 +00:00
rpi - > processing_layer + + ;
2019-09-07 01:51:27 +00:00
}
2020-03-01 01:16:50 +00:00
return false ;
2019-09-07 01:51:27 +00:00
}
2020-12-04 18:26:24 +00:00
uint32_t RendererSceneRenderRD : : reflection_probe_instance_get_resolution ( RID p_instance ) {
2021-09-29 17:08:41 +00:00
ReflectionProbeInstance * rpi = reflection_probe_instance_owner . get_or_null ( p_instance ) ;
2019-09-07 01:51:27 +00:00
ERR_FAIL_COND_V ( ! rpi , 0 ) ;
2021-09-29 17:08:41 +00:00
ReflectionAtlas * atlas = reflection_atlas_owner . get_or_null ( rpi - > atlas ) ;
2019-09-09 20:50:51 +00:00
ERR_FAIL_COND_V ( ! atlas , 0 ) ;
return atlas - > size ;
2019-09-07 01:51:27 +00:00
}
2020-12-04 18:26:24 +00:00
RID RendererSceneRenderRD : : reflection_probe_instance_get_framebuffer ( RID p_instance , int p_index ) {
2021-09-29 17:08:41 +00:00
ReflectionProbeInstance * rpi = reflection_probe_instance_owner . get_or_null ( p_instance ) ;
2019-09-07 01:51:27 +00:00
ERR_FAIL_COND_V ( ! rpi , RID ( ) ) ;
ERR_FAIL_INDEX_V ( p_index , 6 , RID ( ) ) ;
2021-09-29 17:08:41 +00:00
ReflectionAtlas * atlas = reflection_atlas_owner . get_or_null ( rpi - > atlas ) ;
2019-09-09 20:50:51 +00:00
ERR_FAIL_COND_V ( ! atlas , RID ( ) ) ;
return atlas - > reflections [ rpi - > atlas_index ] . fbs [ p_index ] ;
2019-09-07 01:51:27 +00:00
}
2020-12-04 18:26:24 +00:00
RID RendererSceneRenderRD : : reflection_probe_instance_get_depth_framebuffer ( RID p_instance , int p_index ) {
2021-09-29 17:08:41 +00:00
ReflectionProbeInstance * rpi = reflection_probe_instance_owner . get_or_null ( p_instance ) ;
2019-10-03 20:39:08 +00:00
ERR_FAIL_COND_V ( ! rpi , RID ( ) ) ;
ERR_FAIL_INDEX_V ( p_index , 6 , RID ( ) ) ;
2021-09-29 17:08:41 +00:00
ReflectionAtlas * atlas = reflection_atlas_owner . get_or_null ( rpi - > atlas ) ;
2019-10-03 20:39:08 +00:00
ERR_FAIL_COND_V ( ! atlas , RID ( ) ) ;
return atlas - > depth_fb ;
}
2019-09-07 01:51:27 +00:00
///////////////////////////////////////////////////////////
2020-12-04 18:26:24 +00:00
RID RendererSceneRenderRD : : shadow_atlas_create ( ) {
2019-09-07 01:51:27 +00:00
return shadow_atlas_owner . make_rid ( ShadowAtlas ( ) ) ;
}
2021-01-24 19:00:20 +00:00
void RendererSceneRenderRD : : _update_shadow_atlas ( ShadowAtlas * shadow_atlas ) {
if ( shadow_atlas - > size > 0 & & shadow_atlas - > depth . is_null ( ) ) {
RD : : TextureFormat tf ;
tf . format = shadow_atlas - > use_16_bits ? RD : : DATA_FORMAT_D16_UNORM : RD : : DATA_FORMAT_D32_SFLOAT ;
tf . width = shadow_atlas - > size ;
tf . height = shadow_atlas - > size ;
tf . usage_bits = RD : : TEXTURE_USAGE_SAMPLING_BIT | RD : : TEXTURE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT ;
shadow_atlas - > depth = RD : : get_singleton ( ) - > texture_create ( tf , RD : : TextureView ( ) ) ;
Vector < RID > fb_tex ;
fb_tex . push_back ( shadow_atlas - > depth ) ;
shadow_atlas - > fb = RD : : get_singleton ( ) - > framebuffer_create ( fb_tex ) ;
}
}
void RendererSceneRenderRD : : shadow_atlas_set_size ( RID p_atlas , int p_size , bool p_16_bits ) {
2021-09-29 17:08:41 +00:00
ShadowAtlas * shadow_atlas = shadow_atlas_owner . get_or_null ( p_atlas ) ;
2019-09-07 01:51:27 +00:00
ERR_FAIL_COND ( ! shadow_atlas ) ;
ERR_FAIL_COND ( p_size < 0 ) ;
p_size = next_power_of_2 ( p_size ) ;
2021-01-24 19:00:20 +00:00
if ( p_size = = shadow_atlas - > size & & p_16_bits = = shadow_atlas - > use_16_bits ) {
2019-09-07 01:51:27 +00:00
return ;
2020-05-14 14:41:43 +00:00
}
2019-09-07 01:51:27 +00:00
// erasing atlas
if ( shadow_atlas - > depth . is_valid ( ) ) {
RD : : get_singleton ( ) - > free ( shadow_atlas - > depth ) ;
shadow_atlas - > depth = RID ( ) ;
}
for ( int i = 0 ; i < 4 ; i + + ) {
//clear subdivisions
2022-02-01 18:19:13 +00:00
shadow_atlas - > quadrants [ i ] . shadows . clear ( ) ;
2019-09-07 01:51:27 +00:00
shadow_atlas - > quadrants [ i ] . shadows . resize ( 1 < < shadow_atlas - > quadrants [ i ] . subdivision ) ;
}
//erase shadow atlas reference from lights
2021-08-09 20:13:42 +00:00
for ( const KeyValue < RID , uint32_t > & E : shadow_atlas - > shadow_owners ) {
LightInstance * li = light_instance_owner . get_or_null ( E . key ) ;
2019-09-07 01:51:27 +00:00
ERR_CONTINUE ( ! li ) ;
li - > shadow_atlases . erase ( p_atlas ) ;
}
//clear owners
shadow_atlas - > shadow_owners . clear ( ) ;
shadow_atlas - > size = p_size ;
2021-08-04 15:18:06 +00:00
shadow_atlas - > use_16_bits = p_16_bits ;
2019-09-07 01:51:27 +00:00
}
2020-12-04 18:26:24 +00:00
void RendererSceneRenderRD : : shadow_atlas_set_quadrant_subdivision ( RID p_atlas , int p_quadrant , int p_subdivision ) {
2021-09-29 17:08:41 +00:00
ShadowAtlas * shadow_atlas = shadow_atlas_owner . get_or_null ( p_atlas ) ;
2019-09-07 01:51:27 +00:00
ERR_FAIL_COND ( ! shadow_atlas ) ;
ERR_FAIL_INDEX ( p_quadrant , 4 ) ;
ERR_FAIL_INDEX ( p_subdivision , 16384 ) ;
uint32_t subdiv = next_power_of_2 ( p_subdivision ) ;
if ( subdiv & 0xaaaaaaaa ) { //sqrt(subdiv) must be integer
subdiv < < = 1 ;
}
subdiv = int ( Math : : sqrt ( ( float ) subdiv ) ) ;
//obtain the number that will be x*x
2020-05-14 14:41:43 +00:00
if ( shadow_atlas - > quadrants [ p_quadrant ] . subdivision = = subdiv ) {
2019-09-07 01:51:27 +00:00
return ;
2020-05-14 14:41:43 +00:00
}
2019-09-07 01:51:27 +00:00
//erase all data from quadrant
for ( int i = 0 ; i < shadow_atlas - > quadrants [ p_quadrant ] . shadows . size ( ) ; i + + ) {
if ( shadow_atlas - > quadrants [ p_quadrant ] . shadows [ i ] . owner . is_valid ( ) ) {
shadow_atlas - > shadow_owners . erase ( shadow_atlas - > quadrants [ p_quadrant ] . shadows [ i ] . owner ) ;
2021-09-29 17:08:41 +00:00
LightInstance * li = light_instance_owner . get_or_null ( shadow_atlas - > quadrants [ p_quadrant ] . shadows [ i ] . owner ) ;
2019-09-07 01:51:27 +00:00
ERR_CONTINUE ( ! li ) ;
li - > shadow_atlases . erase ( p_atlas ) ;
}
}
2022-02-01 18:19:13 +00:00
shadow_atlas - > quadrants [ p_quadrant ] . shadows . clear ( ) ;
2019-09-07 01:51:27 +00:00
shadow_atlas - > quadrants [ p_quadrant ] . shadows . resize ( subdiv * subdiv ) ;
shadow_atlas - > quadrants [ p_quadrant ] . subdivision = subdiv ;
//cache the smallest subdiv (for faster allocation in light update)
shadow_atlas - > smallest_subdiv = 1 < < 30 ;
for ( int i = 0 ; i < 4 ; i + + ) {
if ( shadow_atlas - > quadrants [ i ] . subdivision ) {
shadow_atlas - > smallest_subdiv = MIN ( shadow_atlas - > smallest_subdiv , shadow_atlas - > quadrants [ i ] . subdivision ) ;
}
}
if ( shadow_atlas - > smallest_subdiv = = 1 < < 30 ) {
shadow_atlas - > smallest_subdiv = 0 ;
}
//resort the size orders, simple bublesort for 4 elements..
int swaps = 0 ;
do {
swaps = 0 ;
for ( int i = 0 ; i < 3 ; i + + ) {
if ( shadow_atlas - > quadrants [ shadow_atlas - > size_order [ i ] ] . subdivision < shadow_atlas - > quadrants [ shadow_atlas - > size_order [ i + 1 ] ] . subdivision ) {
SWAP ( shadow_atlas - > size_order [ i ] , shadow_atlas - > size_order [ i + 1 ] ) ;
swaps + + ;
}
}
} while ( swaps > 0 ) ;
}
2020-12-04 18:26:24 +00:00
bool RendererSceneRenderRD : : _shadow_atlas_find_shadow ( ShadowAtlas * shadow_atlas , int * p_in_quadrants , int p_quadrant_count , int p_current_subdiv , uint64_t p_tick , int & r_quadrant , int & r_shadow ) {
2019-09-07 01:51:27 +00:00
for ( int i = p_quadrant_count - 1 ; i > = 0 ; i - - ) {
int qidx = p_in_quadrants [ i ] ;
if ( shadow_atlas - > quadrants [ qidx ] . subdivision = = ( uint32_t ) p_current_subdiv ) {
return false ;
}
//look for an empty space
int sc = shadow_atlas - > quadrants [ qidx ] . shadows . size ( ) ;
2021-08-04 15:18:06 +00:00
const ShadowAtlas : : Quadrant : : Shadow * sarr = shadow_atlas - > quadrants [ qidx ] . shadows . ptr ( ) ;
2019-09-07 01:51:27 +00:00
int found_free_idx = - 1 ; //found a free one
int found_used_idx = - 1 ; //found existing one, must steal it
uint64_t min_pass = 0 ; // pass of the existing one, try to use the least recently used one (LRU fashion)
for ( int j = 0 ; j < sc ; j + + ) {
if ( ! sarr [ j ] . owner . is_valid ( ) ) {
found_free_idx = j ;
break ;
}
2021-09-29 17:08:41 +00:00
LightInstance * sli = light_instance_owner . get_or_null ( sarr [ j ] . owner ) ;
2019-09-07 01:51:27 +00:00
ERR_CONTINUE ( ! sli ) ;
if ( sli - > last_scene_pass ! = scene_pass ) {
//was just allocated, don't kill it so soon, wait a bit..
2020-05-14 14:41:43 +00:00
if ( p_tick - sarr [ j ] . alloc_tick < shadow_atlas_realloc_tolerance_msec ) {
2019-09-07 01:51:27 +00:00
continue ;
2020-05-14 14:41:43 +00:00
}
2019-09-07 01:51:27 +00:00
if ( found_used_idx = = - 1 | | sli - > last_scene_pass < min_pass ) {
found_used_idx = j ;
min_pass = sli - > last_scene_pass ;
}
}
}
2020-05-14 14:41:43 +00:00
if ( found_free_idx = = - 1 & & found_used_idx = = - 1 ) {
2019-09-07 01:51:27 +00:00
continue ; //nothing found
2020-05-14 14:41:43 +00:00
}
2019-09-07 01:51:27 +00:00
if ( found_free_idx = = - 1 & & found_used_idx ! = - 1 ) {
found_free_idx = found_used_idx ;
}
r_quadrant = qidx ;
r_shadow = found_free_idx ;
return true ;
}
return false ;
}
2021-08-04 15:18:06 +00:00
bool RendererSceneRenderRD : : _shadow_atlas_find_omni_shadows ( ShadowAtlas * shadow_atlas , int * p_in_quadrants , int p_quadrant_count , int p_current_subdiv , uint64_t p_tick , int & r_quadrant , int & r_shadow ) {
for ( int i = p_quadrant_count - 1 ; i > = 0 ; i - - ) {
int qidx = p_in_quadrants [ i ] ;
if ( shadow_atlas - > quadrants [ qidx ] . subdivision = = ( uint32_t ) p_current_subdiv ) {
return false ;
}
//look for an empty space
int sc = shadow_atlas - > quadrants [ qidx ] . shadows . size ( ) ;
const ShadowAtlas : : Quadrant : : Shadow * sarr = shadow_atlas - > quadrants [ qidx ] . shadows . ptr ( ) ;
int found_idx = - 1 ;
uint64_t min_pass = 0 ; // sum of currently selected spots, try to get the least recently used pair
for ( int j = 0 ; j < sc - 1 ; j + + ) {
uint64_t pass = 0 ;
if ( sarr [ j ] . owner . is_valid ( ) ) {
2021-09-29 17:08:41 +00:00
LightInstance * sli = light_instance_owner . get_or_null ( sarr [ j ] . owner ) ;
2021-08-04 15:18:06 +00:00
ERR_CONTINUE ( ! sli ) ;
if ( sli - > last_scene_pass = = scene_pass ) {
continue ;
}
//was just allocated, don't kill it so soon, wait a bit..
if ( p_tick - sarr [ j ] . alloc_tick < shadow_atlas_realloc_tolerance_msec ) {
continue ;
}
pass + = sli - > last_scene_pass ;
}
if ( sarr [ j + 1 ] . owner . is_valid ( ) ) {
2021-09-29 17:08:41 +00:00
LightInstance * sli = light_instance_owner . get_or_null ( sarr [ j + 1 ] . owner ) ;
2021-08-04 15:18:06 +00:00
ERR_CONTINUE ( ! sli ) ;
if ( sli - > last_scene_pass = = scene_pass ) {
continue ;
}
//was just allocated, don't kill it so soon, wait a bit..
if ( p_tick - sarr [ j + 1 ] . alloc_tick < shadow_atlas_realloc_tolerance_msec ) {
continue ;
}
pass + = sli - > last_scene_pass ;
}
if ( found_idx = = - 1 | | pass < min_pass ) {
found_idx = j ;
min_pass = pass ;
// we found two empty spots, no need to check the rest
if ( pass = = 0 ) {
break ;
}
}
}
if ( found_idx = = - 1 ) {
continue ; //nothing found
}
r_quadrant = qidx ;
r_shadow = found_idx ;
return true ;
}
return false ;
}
2022-01-24 14:55:32 +00:00
bool RendererSceneRenderRD : : shadow_atlas_update_light ( RID p_atlas , RID p_light_instance , float p_coverage , uint64_t p_light_version ) {
2021-09-29 17:08:41 +00:00
ShadowAtlas * shadow_atlas = shadow_atlas_owner . get_or_null ( p_atlas ) ;
2019-09-07 01:51:27 +00:00
ERR_FAIL_COND_V ( ! shadow_atlas , false ) ;
2022-01-24 14:55:32 +00:00
LightInstance * li = light_instance_owner . get_or_null ( p_light_instance ) ;
2019-09-07 01:51:27 +00:00
ERR_FAIL_COND_V ( ! li , false ) ;
if ( shadow_atlas - > size = = 0 | | shadow_atlas - > smallest_subdiv = = 0 ) {
return false ;
}
uint32_t quad_size = shadow_atlas - > size > > 1 ;
int desired_fit = MIN ( quad_size / shadow_atlas - > smallest_subdiv , next_power_of_2 ( quad_size * p_coverage ) ) ;
int valid_quadrants [ 4 ] ;
int valid_quadrant_count = 0 ;
int best_size = - 1 ; //best size found
int best_subdiv = - 1 ; //subdiv for the best size
//find the quadrants this fits into, and the best possible size it can fit into
for ( int i = 0 ; i < 4 ; i + + ) {
int q = shadow_atlas - > size_order [ i ] ;
int sd = shadow_atlas - > quadrants [ q ] . subdivision ;
2020-05-14 14:41:43 +00:00
if ( sd = = 0 ) {
2019-09-07 01:51:27 +00:00
continue ; //unused
2020-05-14 14:41:43 +00:00
}
2019-09-07 01:51:27 +00:00
int max_fit = quad_size / sd ;
2020-05-14 14:41:43 +00:00
if ( best_size ! = - 1 & & max_fit > best_size ) {
2019-09-07 01:51:27 +00:00
break ; //too large
2020-05-14 14:41:43 +00:00
}
2019-09-07 01:51:27 +00:00
valid_quadrants [ valid_quadrant_count + + ] = q ;
best_subdiv = sd ;
if ( max_fit > = desired_fit ) {
best_size = max_fit ;
}
}
ERR_FAIL_COND_V ( valid_quadrant_count = = 0 , false ) ;
uint64_t tick = OS : : get_singleton ( ) - > get_ticks_msec ( ) ;
2021-08-04 15:18:06 +00:00
uint32_t old_key = ShadowAtlas : : SHADOW_INVALID ;
uint32_t old_quadrant = ShadowAtlas : : SHADOW_INVALID ;
uint32_t old_shadow = ShadowAtlas : : SHADOW_INVALID ;
int old_subdivision = - 1 ;
bool should_realloc = false ;
bool should_redraw = false ;
2019-09-07 01:51:27 +00:00
2022-01-24 14:55:32 +00:00
if ( shadow_atlas - > shadow_owners . has ( p_light_instance ) ) {
old_key = shadow_atlas - > shadow_owners [ p_light_instance ] ;
2021-08-04 15:18:06 +00:00
old_quadrant = ( old_key > > ShadowAtlas : : QUADRANT_SHIFT ) & 0x3 ;
old_shadow = old_key & ShadowAtlas : : SHADOW_INDEX_MASK ;
2019-09-07 01:51:27 +00:00
2021-08-04 15:18:06 +00:00
should_realloc = shadow_atlas - > quadrants [ old_quadrant ] . subdivision ! = ( uint32_t ) best_subdiv & & ( shadow_atlas - > quadrants [ old_quadrant ] . shadows [ old_shadow ] . alloc_tick - tick > shadow_atlas_realloc_tolerance_msec ) ;
should_redraw = shadow_atlas - > quadrants [ old_quadrant ] . shadows [ old_shadow ] . version ! = p_light_version ;
2019-09-07 01:51:27 +00:00
if ( ! should_realloc ) {
2021-08-04 15:18:06 +00:00
shadow_atlas - > quadrants [ old_quadrant ] . shadows . write [ old_shadow ] . version = p_light_version ;
2019-09-07 01:51:27 +00:00
//already existing, see if it should redraw or it's just OK
return should_redraw ;
}
2021-08-04 15:18:06 +00:00
old_subdivision = shadow_atlas - > quadrants [ old_quadrant ] . subdivision ;
}
2019-09-07 01:51:27 +00:00
2021-08-04 15:18:06 +00:00
bool is_omni = li - > light_type = = RS : : LIGHT_OMNI ;
bool found_shadow = false ;
int new_quadrant = - 1 ;
int new_shadow = - 1 ;
2019-09-07 01:51:27 +00:00
2021-08-04 15:18:06 +00:00
if ( is_omni ) {
found_shadow = _shadow_atlas_find_omni_shadows ( shadow_atlas , valid_quadrants , valid_quadrant_count , old_subdivision , tick , new_quadrant , new_shadow ) ;
} else {
found_shadow = _shadow_atlas_find_shadow ( shadow_atlas , valid_quadrants , valid_quadrant_count , old_subdivision , tick , new_quadrant , new_shadow ) ;
}
2019-09-07 01:51:27 +00:00
2021-08-04 15:18:06 +00:00
if ( found_shadow ) {
if ( old_quadrant ! = ShadowAtlas : : SHADOW_INVALID ) {
shadow_atlas - > quadrants [ old_quadrant ] . shadows . write [ old_shadow ] . version = 0 ;
shadow_atlas - > quadrants [ old_quadrant ] . shadows . write [ old_shadow ] . owner = RID ( ) ;
if ( old_key & ShadowAtlas : : OMNI_LIGHT_FLAG ) {
shadow_atlas - > quadrants [ old_quadrant ] . shadows . write [ old_shadow + 1 ] . version = 0 ;
shadow_atlas - > quadrants [ old_quadrant ] . shadows . write [ old_shadow + 1 ] . owner = RID ( ) ;
}
2019-09-07 01:51:27 +00:00
}
2021-08-04 15:18:06 +00:00
uint32_t new_key = new_quadrant < < ShadowAtlas : : QUADRANT_SHIFT ;
new_key | = new_shadow ;
2019-09-07 01:51:27 +00:00
2021-08-04 15:18:06 +00:00
ShadowAtlas : : Quadrant : : Shadow * sh = & shadow_atlas - > quadrants [ new_quadrant ] . shadows . write [ new_shadow ] ;
_shadow_atlas_invalidate_shadow ( sh , p_atlas , shadow_atlas , new_quadrant , new_shadow ) ;
2019-09-07 01:51:27 +00:00
2022-01-24 14:55:32 +00:00
sh - > owner = p_light_instance ;
2021-08-04 15:18:06 +00:00
sh - > alloc_tick = tick ;
sh - > version = p_light_version ;
2019-09-07 01:51:27 +00:00
2021-08-04 15:18:06 +00:00
if ( is_omni ) {
new_key | = ShadowAtlas : : OMNI_LIGHT_FLAG ;
2019-09-07 01:51:27 +00:00
2021-08-04 15:18:06 +00:00
int new_omni_shadow = new_shadow + 1 ;
ShadowAtlas : : Quadrant : : Shadow * extra_sh = & shadow_atlas - > quadrants [ new_quadrant ] . shadows . write [ new_omni_shadow ] ;
_shadow_atlas_invalidate_shadow ( extra_sh , p_atlas , shadow_atlas , new_quadrant , new_omni_shadow ) ;
2019-09-07 01:51:27 +00:00
2022-01-24 14:55:32 +00:00
extra_sh - > owner = p_light_instance ;
2021-08-04 15:18:06 +00:00
extra_sh - > alloc_tick = tick ;
extra_sh - > version = p_light_version ;
2019-09-07 01:51:27 +00:00
}
li - > shadow_atlases . insert ( p_atlas ) ;
//update it in map
2022-01-24 14:55:32 +00:00
shadow_atlas - > shadow_owners [ p_light_instance ] = new_key ;
2019-09-07 01:51:27 +00:00
//make it dirty, as it should redraw anyway
return true ;
}
2021-08-04 15:18:06 +00:00
return should_redraw ;
}
2019-09-07 01:51:27 +00:00
2021-08-04 15:18:06 +00:00
void RendererSceneRenderRD : : _shadow_atlas_invalidate_shadow ( RendererSceneRenderRD : : ShadowAtlas : : Quadrant : : Shadow * p_shadow , RID p_atlas , RendererSceneRenderRD : : ShadowAtlas * p_shadow_atlas , uint32_t p_quadrant , uint32_t p_shadow_idx ) {
if ( p_shadow - > owner . is_valid ( ) ) {
2021-09-29 17:08:41 +00:00
LightInstance * sli = light_instance_owner . get_or_null ( p_shadow - > owner ) ;
2021-08-04 15:18:06 +00:00
uint32_t old_key = p_shadow_atlas - > shadow_owners [ p_shadow - > owner ] ;
if ( old_key & ShadowAtlas : : OMNI_LIGHT_FLAG ) {
uint32_t s = old_key & ShadowAtlas : : SHADOW_INDEX_MASK ;
uint32_t omni_shadow_idx = p_shadow_idx + ( s = = ( uint32_t ) p_shadow_idx ? 1 : - 1 ) ;
RendererSceneRenderRD : : ShadowAtlas : : Quadrant : : Shadow * omni_shadow = & p_shadow_atlas - > quadrants [ p_quadrant ] . shadows . write [ omni_shadow_idx ] ;
omni_shadow - > version = 0 ;
omni_shadow - > owner = RID ( ) ;
}
2022-01-24 14:55:32 +00:00
p_shadow_atlas - > shadow_owners . erase ( p_shadow - > owner ) ;
2021-08-04 15:18:06 +00:00
p_shadow - > version = 0 ;
p_shadow - > owner = RID ( ) ;
sli - > shadow_atlases . erase ( p_atlas ) ;
}
2019-09-07 01:51:27 +00:00
}
2021-01-24 19:00:20 +00:00
void RendererSceneRenderRD : : _update_directional_shadow_atlas ( ) {
if ( directional_shadow . depth . is_null ( ) & & directional_shadow . size > 0 ) {
RD : : TextureFormat tf ;
tf . format = directional_shadow . use_16_bits ? RD : : DATA_FORMAT_D16_UNORM : RD : : DATA_FORMAT_D32_SFLOAT ;
tf . width = directional_shadow . size ;
tf . height = directional_shadow . size ;
tf . usage_bits = RD : : TEXTURE_USAGE_SAMPLING_BIT | RD : : TEXTURE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT ;
directional_shadow . depth = RD : : get_singleton ( ) - > texture_create ( tf , RD : : TextureView ( ) ) ;
Vector < RID > fb_tex ;
fb_tex . push_back ( directional_shadow . depth ) ;
directional_shadow . fb = RD : : get_singleton ( ) - > framebuffer_create ( fb_tex ) ;
}
}
void RendererSceneRenderRD : : directional_shadow_atlas_set_size ( int p_size , bool p_16_bits ) {
2019-09-07 01:51:27 +00:00
p_size = nearest_power_of_2_templated ( p_size ) ;
2021-01-24 19:00:20 +00:00
if ( directional_shadow . size = = p_size & & directional_shadow . use_16_bits = = p_16_bits ) {
2019-09-07 01:51:27 +00:00
return ;
}
2019-09-07 17:38:17 +00:00
directional_shadow . size = p_size ;
2021-08-04 15:18:06 +00:00
directional_shadow . use_16_bits = p_16_bits ;
2019-09-07 17:38:17 +00:00
2019-09-07 01:51:27 +00:00
if ( directional_shadow . depth . is_valid ( ) ) {
RD : : get_singleton ( ) - > free ( directional_shadow . depth ) ;
directional_shadow . depth = RID ( ) ;
2021-01-24 19:00:20 +00:00
_base_uniforms_changed ( ) ;
2019-09-07 01:51:27 +00:00
}
}
2020-12-04 18:26:24 +00:00
void RendererSceneRenderRD : : set_directional_shadow_count ( int p_count ) {
2019-09-07 01:51:27 +00:00
directional_shadow . light_count = p_count ;
directional_shadow . current_light = 0 ;
}
2019-09-07 17:38:17 +00:00
static Rect2i _get_directional_shadow_rect ( int p_size , int p_shadow_count , int p_shadow_index ) {
int split_h = 1 ;
int split_v = 1 ;
while ( split_h * split_v < p_shadow_count ) {
if ( split_h = = split_v ) {
split_h < < = 1 ;
} else {
split_v < < = 1 ;
}
}
Rect2i rect ( 0 , 0 , p_size , p_size ) ;
rect . size . width / = split_h ;
rect . size . height / = split_v ;
rect . position . x = rect . size . width * ( p_shadow_index % split_h ) ;
rect . position . y = rect . size . height * ( p_shadow_index / split_h ) ;
return rect ;
}
2020-12-04 18:26:24 +00:00
int RendererSceneRenderRD : : get_directional_light_shadow_size ( RID p_light_intance ) {
2019-09-07 01:51:27 +00:00
ERR_FAIL_COND_V ( directional_shadow . light_count = = 0 , 0 ) ;
2019-09-07 17:38:17 +00:00
Rect2i r = _get_directional_shadow_rect ( directional_shadow . size , directional_shadow . light_count , 0 ) ;
2019-09-07 01:51:27 +00:00
2021-09-29 17:08:41 +00:00
LightInstance * light_instance = light_instance_owner . get_or_null ( p_light_intance ) ;
2019-09-07 01:51:27 +00:00
ERR_FAIL_COND_V ( ! light_instance , 0 ) ;
2022-04-09 09:34:31 +00:00
switch ( RSG : : light_storage - > light_directional_get_shadow_mode ( light_instance - > light ) ) {
2020-03-27 18:21:27 +00:00
case RS : : LIGHT_DIRECTIONAL_SHADOW_ORTHOGONAL :
2019-09-07 01:51:27 +00:00
break ; //none
2020-05-10 11:00:47 +00:00
case RS : : LIGHT_DIRECTIONAL_SHADOW_PARALLEL_2_SPLITS :
r . size . height / = 2 ;
break ;
case RS : : LIGHT_DIRECTIONAL_SHADOW_PARALLEL_4_SPLITS :
r . size / = 2 ;
break ;
2019-09-07 01:51:27 +00:00
}
2019-09-07 17:38:17 +00:00
return MAX ( r . size . width , r . size . height ) ;
2019-09-07 01:51:27 +00:00
}
//////////////////////////////////////////////////
2020-12-04 18:26:24 +00:00
RID RendererSceneRenderRD : : light_instance_create ( RID p_light ) {
2019-09-07 01:51:27 +00:00
RID li = light_instance_owner . make_rid ( LightInstance ( ) ) ;
2021-09-29 17:08:41 +00:00
LightInstance * light_instance = light_instance_owner . get_or_null ( li ) ;
2019-09-07 01:51:27 +00:00
light_instance - > self = li ;
light_instance - > light = p_light ;
2022-04-09 09:34:31 +00:00
light_instance - > light_type = RSG : : light_storage - > light_get_type ( p_light ) ;
2021-07-15 20:06:33 +00:00
if ( light_instance - > light_type ! = RS : : LIGHT_DIRECTIONAL ) {
light_instance - > forward_id = _allocate_forward_id ( light_instance - > light_type = = RS : : LIGHT_OMNI ? FORWARD_ID_TYPE_OMNI_LIGHT : FORWARD_ID_TYPE_SPOT_LIGHT ) ;
}
2019-09-07 01:51:27 +00:00
return li ;
}
2020-10-17 05:08:21 +00:00
void RendererSceneRenderRD : : light_instance_set_transform ( RID p_light_instance , const Transform3D & p_transform ) {
2021-09-29 17:08:41 +00:00
LightInstance * light_instance = light_instance_owner . get_or_null ( p_light_instance ) ;
2019-09-07 01:51:27 +00:00
ERR_FAIL_COND ( ! light_instance ) ;
light_instance - > transform = p_transform ;
}
2020-12-04 18:26:24 +00:00
void RendererSceneRenderRD : : light_instance_set_aabb ( RID p_light_instance , const AABB & p_aabb ) {
2021-09-29 17:08:41 +00:00
LightInstance * light_instance = light_instance_owner . get_or_null ( p_light_instance ) ;
2020-06-25 13:33:28 +00:00
ERR_FAIL_COND ( ! light_instance ) ;
light_instance - > aabb = p_aabb ;
}
Implement Vector4, Vector4i, Projection
Implement built-in classes Vector4, Vector4i and Projection.
* Two versions of Vector4 (float and integer).
* A Projection class, which is a 4x4 matrix specialized in projection types.
These types have been requested for a long time, but given they were very corner case they were not added before.
Because in Godot 4, reimplementing parts of the rendering engine is now possible, access to these types (heavily used by the rendering code) becomes a necessity.
**Q**: Why Projection and not Matrix4?
**A**: Godot does not use Matrix2, Matrix3, Matrix4x3, etc. naming convention because, within the engine, these types always have a *purpose*. As such, Godot names them: Transform2D, Transform3D or Basis. In this case, this 4x4 matrix is _always_ used as a _Projection_, hence the naming.
2022-07-19 23:11:13 +00:00
void RendererSceneRenderRD : : light_instance_set_shadow_transform ( RID p_light_instance , const Projection & p_projection , const Transform3D & p_transform , float p_far , float p_split , int p_pass , float p_shadow_texel_size , float p_bias_scale , float p_range_begin , const Vector2 & p_uv_scale ) {
2021-09-29 17:08:41 +00:00
LightInstance * light_instance = light_instance_owner . get_or_null ( p_light_instance ) ;
2019-09-07 01:51:27 +00:00
ERR_FAIL_COND ( ! light_instance ) ;
2021-02-02 19:51:36 +00:00
ERR_FAIL_INDEX ( p_pass , 6 ) ;
2019-09-07 01:51:27 +00:00
light_instance - > shadow_transform [ p_pass ] . camera = p_projection ;
light_instance - > shadow_transform [ p_pass ] . transform = p_transform ;
light_instance - > shadow_transform [ p_pass ] . farplane = p_far ;
light_instance - > shadow_transform [ p_pass ] . split = p_split ;
light_instance - > shadow_transform [ p_pass ] . bias_scale = p_bias_scale ;
2020-04-09 18:11:15 +00:00
light_instance - > shadow_transform [ p_pass ] . range_begin = p_range_begin ;
2020-04-08 01:51:52 +00:00
light_instance - > shadow_transform [ p_pass ] . shadow_texel_size = p_shadow_texel_size ;
2020-04-09 18:11:15 +00:00
light_instance - > shadow_transform [ p_pass ] . uv_scale = p_uv_scale ;
2019-09-07 01:51:27 +00:00
}
2020-12-04 18:26:24 +00:00
void RendererSceneRenderRD : : light_instance_mark_visible ( RID p_light_instance ) {
2021-09-29 17:08:41 +00:00
LightInstance * light_instance = light_instance_owner . get_or_null ( p_light_instance ) ;
2019-09-07 01:51:27 +00:00
ERR_FAIL_COND ( ! light_instance ) ;
light_instance - > last_scene_pass = scene_pass ;
}
2020-12-04 18:26:24 +00:00
RendererSceneRenderRD : : ShadowCubemap * RendererSceneRenderRD : : _get_shadow_cubemap ( int p_size ) {
2019-09-07 01:51:27 +00:00
if ( ! shadow_cubemaps . has ( p_size ) ) {
ShadowCubemap sc ;
{
RD : : TextureFormat tf ;
tf . format = RD : : get_singleton ( ) - > texture_is_format_supported_for_usage ( RD : : DATA_FORMAT_D32_SFLOAT , RD : : TEXTURE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT ) ? RD : : DATA_FORMAT_D32_SFLOAT : RD : : DATA_FORMAT_X8_D24_UNORM_PACK32 ;
tf . width = p_size ;
tf . height = p_size ;
2020-11-27 03:50:05 +00:00
tf . texture_type = RD : : TEXTURE_TYPE_CUBE ;
2019-09-07 01:51:27 +00:00
tf . array_layers = 6 ;
tf . usage_bits = RD : : TEXTURE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT | RD : : TEXTURE_USAGE_SAMPLING_BIT ;
sc . cubemap = RD : : get_singleton ( ) - > texture_create ( tf , RD : : TextureView ( ) ) ;
}
2021-02-13 12:08:08 +00:00
for ( int i = 0 ; i < 6 ; i + + ) {
RID side_texture = RD : : get_singleton ( ) - > texture_create_shared_from_slice ( RD : : TextureView ( ) , sc . cubemap , i , 0 ) ;
Vector < RID > fbtex ;
fbtex . push_back ( side_texture ) ;
sc . side_fb [ i ] = RD : : get_singleton ( ) - > framebuffer_create ( fbtex ) ;
}
2019-10-11 02:14:56 +00:00
2021-02-13 12:08:08 +00:00
shadow_cubemaps [ p_size ] = sc ;
}
2019-10-11 02:14:56 +00:00
2021-02-13 12:08:08 +00:00
return & shadow_cubemaps [ p_size ] ;
}
2019-10-11 02:14:56 +00:00
2021-02-13 12:08:08 +00:00
//////////////////////////
2019-10-03 20:39:08 +00:00
2021-02-13 12:08:08 +00:00
RID RendererSceneRenderRD : : decal_instance_create ( RID p_decal ) {
DecalInstance di ;
di . decal = p_decal ;
2021-07-15 20:06:33 +00:00
di . forward_id = _allocate_forward_id ( FORWARD_ID_TYPE_DECAL ) ;
2021-02-13 12:08:08 +00:00
return decal_instance_owner . make_rid ( di ) ;
}
2019-10-03 20:39:08 +00:00
2020-10-17 05:08:21 +00:00
void RendererSceneRenderRD : : decal_instance_set_transform ( RID p_decal , const Transform3D & p_transform ) {
2021-09-29 17:08:41 +00:00
DecalInstance * di = decal_instance_owner . get_or_null ( p_decal ) ;
2021-02-13 12:08:08 +00:00
ERR_FAIL_COND ( ! di ) ;
di - > transform = p_transform ;
}
2019-10-03 20:39:08 +00:00
2021-02-13 12:08:08 +00:00
/////////////////////////////////
2019-10-03 20:39:08 +00:00
2021-02-13 12:08:08 +00:00
RID RendererSceneRenderRD : : lightmap_instance_create ( RID p_lightmap ) {
LightmapInstance li ;
li . lightmap = p_lightmap ;
return lightmap_instance_owner . make_rid ( li ) ;
}
2020-10-17 05:08:21 +00:00
void RendererSceneRenderRD : : lightmap_instance_set_transform ( RID p_lightmap , const Transform3D & p_transform ) {
2021-09-29 17:08:41 +00:00
LightmapInstance * li = lightmap_instance_owner . get_or_null ( p_lightmap ) ;
2021-02-13 12:08:08 +00:00
ERR_FAIL_COND ( ! li ) ;
li - > transform = p_transform ;
}
2019-10-11 02:14:56 +00:00
2021-02-13 12:08:08 +00:00
/////////////////////////////////
2019-10-11 02:14:56 +00:00
2021-06-04 22:47:26 +00:00
RID RendererSceneRenderRD : : voxel_gi_instance_create ( RID p_base ) {
return gi . voxel_gi_instance_create ( p_base ) ;
2021-02-13 12:08:08 +00:00
}
2019-10-11 02:14:56 +00:00
2021-06-04 22:47:26 +00:00
void RendererSceneRenderRD : : voxel_gi_instance_set_transform_to_data ( RID p_probe , const Transform3D & p_xform ) {
gi . voxel_gi_instance_set_transform_to_data ( p_probe , p_xform ) ;
2021-02-13 12:08:08 +00:00
}
2019-10-11 02:14:56 +00:00
2021-06-04 22:47:26 +00:00
bool RendererSceneRenderRD : : voxel_gi_needs_update ( RID p_probe ) const {
2021-04-07 11:06:48 +00:00
if ( ! is_dynamic_gi_supported ( ) ) {
2021-02-13 12:08:08 +00:00
return false ;
2019-10-03 20:39:08 +00:00
}
2021-06-04 22:47:26 +00:00
return gi . voxel_gi_needs_update ( p_probe ) ;
2019-10-03 20:39:08 +00:00
}
2022-07-23 14:01:53 +00:00
void RendererSceneRenderRD : : voxel_gi_update ( RID p_probe , bool p_update_light_instances , const Vector < RID > & p_light_instances , const PagedArray < RenderGeometryInstance * > & p_dynamic_objects ) {
2021-04-07 11:06:48 +00:00
if ( ! is_dynamic_gi_supported ( ) ) {
2019-10-03 20:39:08 +00:00
return ;
}
2021-06-04 22:47:26 +00:00
gi . voxel_gi_update ( p_probe , p_update_light_instances , p_light_instances , p_dynamic_objects , this ) ;
2019-10-03 20:39:08 +00:00
}
2022-08-04 08:40:39 +00:00
void RendererSceneRenderRD : : _debug_sdfgi_probes ( Ref < RenderSceneBuffersRD > p_render_buffers , RID p_framebuffer , const uint32_t p_view_count , const Projection * p_camera_with_transforms , bool p_will_continue_color , bool p_will_continue_depth ) {
ERR_FAIL_COND ( p_render_buffers . is_null ( ) ) ;
2020-06-25 13:33:28 +00:00
2022-08-04 08:40:39 +00:00
if ( ! p_render_buffers - > has_custom_data ( RB_SCOPE_SDFGI ) ) {
2020-06-25 13:33:28 +00:00
return ; //nothing to debug
}
2022-08-04 08:40:39 +00:00
Ref < RendererRD : : GI : : SDFGI > sdfgi = p_render_buffers - > get_custom_data ( RB_SCOPE_SDFGI ) ;
2019-09-07 01:51:27 +00:00
2022-08-04 08:40:39 +00:00
sdfgi - > debug_probes ( p_framebuffer , p_view_count , p_camera_with_transforms , p_will_continue_color , p_will_continue_depth ) ;
2019-08-18 22:40:52 +00:00
}
2022-08-04 08:40:39 +00:00
////////////////////////////////
Ref < RenderSceneBuffers > RendererSceneRenderRD : : render_buffers_create ( ) {
Ref < RenderSceneBuffersRD > rb ;
rb . instantiate ( ) ;
2021-07-29 07:43:17 +00:00
2022-08-04 08:40:39 +00:00
rb - > set_can_be_storage ( _render_buffers_can_be_storage ( ) ) ;
rb - > set_max_cluster_elements ( max_cluster_elements ) ;
rb - > set_base_data_format ( _render_buffers_get_color_format ( ) ) ;
if ( ss_effects ) {
rb - > set_sseffects ( ss_effects ) ;
2021-07-29 07:43:17 +00:00
}
2022-08-04 08:40:39 +00:00
if ( vrs ) {
rb - > set_vrs ( vrs ) ;
2021-08-11 11:00:12 +00:00
}
2022-08-04 08:40:39 +00:00
setup_render_buffer_data ( rb ) ;
2021-08-11 11:00:12 +00:00
2022-08-04 08:40:39 +00:00
return rb ;
2021-08-11 11:00:12 +00:00
}
2022-08-04 08:40:39 +00:00
void RendererSceneRenderRD : : _allocate_luminance_textures ( Ref < RenderSceneBuffersRD > rb ) {
2020-01-12 01:26:52 +00:00
ERR_FAIL_COND ( ! rb - > luminance . current . is_null ( ) ) ;
2022-08-04 08:40:39 +00:00
Size2i internal_size = rb - > get_internal_size ( ) ;
int w = internal_size . x ;
int h = internal_size . y ;
2020-01-12 01:26:52 +00:00
while ( true ) {
w = MAX ( w / 8 , 1 ) ;
h = MAX ( h / 8 , 1 ) ;
RD : : TextureFormat tf ;
tf . format = RD : : DATA_FORMAT_R32_SFLOAT ;
tf . width = w ;
tf . height = h ;
bool final = w = = 1 & & h = = 1 ;
2021-07-20 11:40:16 +00:00
if ( _render_buffers_can_be_storage ( ) ) {
tf . usage_bits = RD : : TEXTURE_USAGE_STORAGE_BIT ;
if ( final ) {
tf . usage_bits | = RD : : TEXTURE_USAGE_SAMPLING_BIT ;
}
} else {
tf . usage_bits = RD : : TEXTURE_USAGE_COLOR_ATTACHMENT_BIT | RD : : TEXTURE_USAGE_SAMPLING_BIT ;
2020-01-12 01:26:52 +00:00
}
RID texture = RD : : get_singleton ( ) - > texture_create ( tf , RD : : TextureView ( ) ) ;
rb - > luminance . reduce . push_back ( texture ) ;
2021-07-20 11:40:16 +00:00
if ( ! _render_buffers_can_be_storage ( ) ) {
Vector < RID > fb ;
fb . push_back ( texture ) ;
rb - > luminance . fb . push_back ( RD : : get_singleton ( ) - > framebuffer_create ( fb ) ) ;
}
2020-01-12 01:26:52 +00:00
if ( final ) {
rb - > luminance . current = RD : : get_singleton ( ) - > texture_create ( tf , RD : : TextureView ( ) ) ;
2021-07-20 11:40:16 +00:00
if ( ! _render_buffers_can_be_storage ( ) ) {
Vector < RID > fb ;
fb . push_back ( rb - > luminance . current ) ;
rb - > luminance . current_fb = RD : : get_singleton ( ) - > framebuffer_create ( fb ) ;
}
2020-01-12 01:26:52 +00:00
break ;
}
}
}
2022-08-04 08:40:39 +00:00
void RendererSceneRenderRD : : _process_sss ( Ref < RenderSceneBuffersRD > p_render_buffers , const Projection & p_camera ) {
ERR_FAIL_COND ( p_render_buffers . is_null ( ) ) ;
2021-08-11 11:00:12 +00:00
2022-08-04 08:40:39 +00:00
Size2i internal_size = p_render_buffers - > get_internal_size ( ) ;
bool can_use_effects = internal_size . x > = 8 & & internal_size . y > = 8 ;
2020-04-04 02:42:26 +00:00
if ( ! can_use_effects ) {
//just copy
return ;
}
2022-08-04 08:40:39 +00:00
p_render_buffers - > allocate_blur_textures ( ) ;
2020-04-04 02:42:26 +00:00
2022-08-04 08:40:39 +00:00
for ( uint32_t v = 0 ; v < p_render_buffers - > get_view_count ( ) ; v + + ) {
RID internal_texture = p_render_buffers - > get_internal_texture ( v ) ;
RID depth_texture = p_render_buffers - > get_depth_texture ( v ) ;
ss_effects - > sub_surface_scattering ( p_render_buffers , internal_texture , depth_texture , p_camera , internal_size , sss_scale , sss_depth_scale , sss_quality ) ;
}
2020-04-04 02:42:26 +00:00
}
2022-09-09 22:52:07 +00:00
void RendererSceneRenderRD : : _process_ssr ( Ref < RenderSceneBuffersRD > p_render_buffers , RID p_dest_framebuffer , const RID * p_normal_slices , RID p_specular_buffer , const RID * p_metallic_slices , RID p_environment , const Projection * p_projections , const Vector3 * p_eye_offsets , bool p_use_additive ) {
2022-06-28 09:10:36 +00:00
ERR_FAIL_NULL ( ss_effects ) ;
2022-08-04 08:40:39 +00:00
ERR_FAIL_COND ( p_render_buffers . is_null ( ) ) ;
2022-06-28 09:10:36 +00:00
2022-08-04 08:40:39 +00:00
Size2i internal_size = p_render_buffers - > get_internal_size ( ) ;
bool can_use_effects = internal_size . x > = 8 & & internal_size . y > = 8 ;
uint32_t view_count = p_render_buffers - > get_view_count ( ) ;
2020-04-02 02:24:52 +00:00
if ( ! can_use_effects ) {
//just copy
2022-08-04 08:40:39 +00:00
copy_effects - > merge_specular ( p_dest_framebuffer , p_specular_buffer , p_use_additive ? RID ( ) : p_render_buffers - > get_internal_texture ( ) , RID ( ) , view_count ) ;
2020-04-02 02:24:52 +00:00
return ;
}
2022-07-27 06:14:23 +00:00
ERR_FAIL_COND ( p_environment . is_null ( ) ) ;
ERR_FAIL_COND ( ! environment_get_ssr_enabled ( p_environment ) ) ;
2020-04-02 02:24:52 +00:00
2022-08-04 08:40:39 +00:00
Size2i half_size = Size2i ( internal_size . x / 2 , internal_size . y / 2 ) ;
if ( p_render_buffers - > ssr . output . is_null ( ) ) {
ss_effects - > ssr_allocate_buffers ( p_render_buffers - > ssr , _render_buffers_get_color_format ( ) , ssr_roughness_quality , half_size , view_count ) ;
2020-04-02 02:24:52 +00:00
}
2022-06-28 09:10:36 +00:00
RID texture_slices [ RendererSceneRender : : MAX_RENDER_VIEWS ] ;
RID depth_slices [ RendererSceneRender : : MAX_RENDER_VIEWS ] ;
2022-08-04 08:40:39 +00:00
for ( uint32_t v = 0 ; v < view_count ; v + + ) {
texture_slices [ v ] = p_render_buffers - > get_internal_texture ( v ) ;
depth_slices [ v ] = p_render_buffers - > get_depth_texture ( v ) ;
2020-04-02 02:24:52 +00:00
}
2022-09-09 22:52:07 +00:00
ss_effects - > screen_space_reflection ( p_render_buffers - > ssr , texture_slices , p_normal_slices , ssr_roughness_quality , p_metallic_slices , depth_slices , half_size , environment_get_ssr_max_steps ( p_environment ) , environment_get_ssr_fade_in ( p_environment ) , environment_get_ssr_fade_out ( p_environment ) , environment_get_ssr_depth_tolerance ( p_environment ) , view_count , p_projections , p_eye_offsets ) ;
2022-08-04 08:40:39 +00:00
copy_effects - > merge_specular ( p_dest_framebuffer , p_specular_buffer , p_use_additive ? RID ( ) : p_render_buffers - > get_internal_texture ( ) , p_render_buffers - > ssr . output , view_count ) ;
2020-01-25 10:18:55 +00:00
}
2022-08-04 08:40:39 +00:00
void RendererSceneRenderRD : : _process_ssao ( Ref < RenderSceneBuffersRD > p_render_buffers , RID p_environment , RID p_normal_buffer , const Projection & p_projection ) {
2022-06-28 09:10:36 +00:00
ERR_FAIL_NULL ( ss_effects ) ;
2022-08-04 08:40:39 +00:00
ERR_FAIL_COND ( p_render_buffers . is_null ( ) ) ;
2022-07-27 06:14:23 +00:00
ERR_FAIL_COND ( p_environment . is_null ( ) ) ;
2020-01-25 10:18:55 +00:00
2020-08-13 01:21:01 +00:00
RENDER_TIMESTAMP ( " Process SSAO " ) ;
2022-06-28 09:10:36 +00:00
RendererRD : : SSEffects : : SSAOSettings settings ;
2022-07-27 06:14:23 +00:00
settings . radius = environment_get_ssao_radius ( p_environment ) ;
settings . intensity = environment_get_ssao_intensity ( p_environment ) ;
settings . power = environment_get_ssao_power ( p_environment ) ;
settings . detail = environment_get_ssao_detail ( p_environment ) ;
settings . horizon = environment_get_ssao_horizon ( p_environment ) ;
settings . sharpness = environment_get_ssao_sharpness ( p_environment ) ;
2020-12-08 05:37:09 +00:00
settings . quality = ssao_quality ;
settings . half_size = ssao_half_size ;
settings . adaptive_target = ssao_adaptive_target ;
settings . blur_passes = ssao_blur_passes ;
settings . fadeout_from = ssao_fadeout_from ;
settings . fadeout_to = ssao_fadeout_to ;
2022-08-04 08:40:39 +00:00
settings . full_screen_size = p_render_buffers - > get_internal_size ( ) ;
2020-12-08 05:37:09 +00:00
2022-08-04 08:40:39 +00:00
ss_effects - > ssao_allocate_buffers ( p_render_buffers - > ss_effects . ssao , settings , p_render_buffers - > ss_effects . linear_depth ) ;
ss_effects - > generate_ssao ( p_render_buffers - > ss_effects . ssao , p_normal_buffer , p_projection , settings ) ;
2021-08-03 07:07:32 +00:00
}
2022-08-04 08:40:39 +00:00
void RendererSceneRenderRD : : _process_ssil ( Ref < RenderSceneBuffersRD > p_render_buffers , RID p_environment , RID p_normal_buffer , const Projection & p_projection , const Transform3D & p_transform ) {
2022-06-28 09:10:36 +00:00
ERR_FAIL_NULL ( ss_effects ) ;
2022-08-04 08:40:39 +00:00
ERR_FAIL_COND ( p_render_buffers . is_null ( ) ) ;
2022-07-27 06:14:23 +00:00
ERR_FAIL_COND ( p_environment . is_null ( ) ) ;
2021-08-03 07:07:32 +00:00
RENDER_TIMESTAMP ( " Process SSIL " ) ;
2022-06-28 09:10:36 +00:00
RendererRD : : SSEffects : : SSILSettings settings ;
2022-07-27 06:14:23 +00:00
settings . radius = environment_get_ssil_radius ( p_environment ) ;
settings . intensity = environment_get_ssil_intensity ( p_environment ) ;
settings . sharpness = environment_get_ssil_sharpness ( p_environment ) ;
settings . normal_rejection = environment_get_ssil_normal_rejection ( p_environment ) ;
2021-08-03 07:07:32 +00:00
settings . quality = ssil_quality ;
settings . half_size = ssil_half_size ;
settings . adaptive_target = ssil_adaptive_target ;
settings . blur_passes = ssil_blur_passes ;
settings . fadeout_from = ssil_fadeout_from ;
settings . fadeout_to = ssil_fadeout_to ;
2022-08-04 08:40:39 +00:00
settings . full_screen_size = p_render_buffers - > get_internal_size ( ) ;
2021-08-03 07:07:32 +00:00
Implement Vector4, Vector4i, Projection
Implement built-in classes Vector4, Vector4i and Projection.
* Two versions of Vector4 (float and integer).
* A Projection class, which is a 4x4 matrix specialized in projection types.
These types have been requested for a long time, but given they were very corner case they were not added before.
Because in Godot 4, reimplementing parts of the rendering engine is now possible, access to these types (heavily used by the rendering code) becomes a necessity.
**Q**: Why Projection and not Matrix4?
**A**: Godot does not use Matrix2, Matrix3, Matrix4x3, etc. naming convention because, within the engine, these types always have a *purpose*. As such, Godot names them: Transform2D, Transform3D or Basis. In this case, this 4x4 matrix is _always_ used as a _Projection_, hence the naming.
2022-07-19 23:11:13 +00:00
Projection correction ;
2021-08-03 07:07:32 +00:00
correction . set_depth_correction ( true ) ;
Implement Vector4, Vector4i, Projection
Implement built-in classes Vector4, Vector4i and Projection.
* Two versions of Vector4 (float and integer).
* A Projection class, which is a 4x4 matrix specialized in projection types.
These types have been requested for a long time, but given they were very corner case they were not added before.
Because in Godot 4, reimplementing parts of the rendering engine is now possible, access to these types (heavily used by the rendering code) becomes a necessity.
**Q**: Why Projection and not Matrix4?
**A**: Godot does not use Matrix2, Matrix3, Matrix4x3, etc. naming convention because, within the engine, these types always have a *purpose*. As such, Godot names them: Transform2D, Transform3D or Basis. In this case, this 4x4 matrix is _always_ used as a _Projection_, hence the naming.
2022-07-19 23:11:13 +00:00
Projection projection = correction * p_projection ;
2021-08-03 07:07:32 +00:00
Transform3D transform = p_transform ;
transform . set_origin ( Vector3 ( 0.0 , 0.0 , 0.0 ) ) ;
2022-08-04 08:40:39 +00:00
Projection last_frame_projection = p_render_buffers - > ss_effects . last_frame_projection * Projection ( p_render_buffers - > ss_effects . last_frame_transform . affine_inverse ( ) ) * Projection ( transform ) * projection . inverse ( ) ;
2021-08-03 07:07:32 +00:00
2022-08-04 08:40:39 +00:00
ss_effects - > ssil_allocate_buffers ( p_render_buffers - > ss_effects . ssil , settings , p_render_buffers - > ss_effects . linear_depth ) ;
ss_effects - > screen_space_indirect_lighting ( p_render_buffers - > ss_effects . ssil , p_normal_buffer , p_projection , last_frame_projection , settings ) ;
p_render_buffers - > ss_effects . last_frame_projection = projection ;
p_render_buffers - > ss_effects . last_frame_transform = transform ;
2021-08-03 07:07:32 +00:00
}
2022-08-04 08:40:39 +00:00
void RendererSceneRenderRD : : _copy_framebuffer_to_ssil ( Ref < RenderSceneBuffersRD > p_render_buffers ) {
ERR_FAIL_COND ( p_render_buffers . is_null ( ) ) ;
2021-08-03 07:07:32 +00:00
2022-08-04 08:40:39 +00:00
if ( p_render_buffers - > ss_effects . ssil . last_frame . is_valid ( ) ) {
Size2i size = p_render_buffers - > get_internal_size ( ) ;
RID texture = p_render_buffers - > get_internal_texture ( ) ;
copy_effects - > copy_to_rect ( texture , p_render_buffers - > ss_effects . ssil . last_frame , Rect2i ( 0 , 0 , size . x , size . y ) ) ;
2021-08-03 07:07:32 +00:00
2022-08-04 08:40:39 +00:00
int width = size . x ;
int height = size . y ;
for ( int i = 0 ; i < p_render_buffers - > ss_effects . ssil . last_frame_slices . size ( ) - 1 ; i + + ) {
2021-08-03 07:07:32 +00:00
width = MAX ( 1 , width > > 1 ) ;
height = MAX ( 1 , height > > 1 ) ;
2022-08-04 08:40:39 +00:00
copy_effects - > make_mipmap ( p_render_buffers - > ss_effects . ssil . last_frame_slices [ i ] , p_render_buffers - > ss_effects . ssil . last_frame_slices [ i + 1 ] , Size2i ( width , height ) ) ;
2022-04-04 14:10:22 +00:00
}
}
}
2021-08-11 11:00:12 +00:00
void RendererSceneRenderRD : : _render_buffers_copy_screen_texture ( const RenderDataRD * p_render_data ) {
2022-08-04 08:40:39 +00:00
Ref < RenderSceneBuffersRD > rb = p_render_data - > render_buffers ;
ERR_FAIL_COND ( rb . is_null ( ) ) ;
2021-08-11 11:00:12 +00:00
RD : : get_singleton ( ) - > draw_command_begin_label ( " Copy screen texture " ) ;
2022-08-04 08:40:39 +00:00
rb - > allocate_blur_textures ( ) ;
2021-08-11 11:00:12 +00:00
bool can_use_storage = _render_buffers_can_be_storage ( ) ;
2022-08-04 08:40:39 +00:00
Size2i size = rb - > get_internal_size ( ) ;
for ( uint32_t v = 0 ; v < rb - > get_view_count ( ) ; v + + ) {
RID texture = rb - > get_internal_texture ( v ) ;
int mipmaps = int ( rb - > get_texture_format ( RB_SCOPE_BUFFERS , RB_TEX_BLUR_0 ) . mipmaps ) ;
RID dest = rb - > get_texture_slice ( RB_SCOPE_BUFFERS , RB_TEX_BLUR_0 , v , 0 ) ;
2021-08-11 11:00:12 +00:00
2022-04-29 07:10:54 +00:00
if ( can_use_storage ) {
2022-08-04 08:40:39 +00:00
copy_effects - > copy_to_rect ( texture , dest , Rect2i ( 0 , 0 , size . x , size . y ) ) ;
2022-04-29 07:10:54 +00:00
} else {
2022-08-04 08:40:39 +00:00
RID fb = FramebufferCacheRD : : get_singleton ( ) - > get_cache ( dest ) ;
copy_effects - > copy_to_fb_rect ( texture , fb , Rect2i ( 0 , 0 , size . x , size . y ) ) ;
}
for ( int i = 1 ; i < mipmaps ; i + + ) {
RID source = dest ;
dest = rb - > get_texture_slice ( RB_SCOPE_BUFFERS , RB_TEX_BLUR_0 , v , i ) ;
Size2i msize = rb - > get_texture_slice_size ( RB_SCOPE_BUFFERS , RB_TEX_BLUR_0 , v , i ) ;
if ( can_use_storage ) {
copy_effects - > make_mipmap ( source , dest , msize ) ;
} else {
copy_effects - > make_mipmap_raster ( source , dest , msize ) ;
2022-04-29 07:10:54 +00:00
}
2021-08-11 11:00:12 +00:00
}
}
RD : : get_singleton ( ) - > draw_command_end_label ( ) ;
}
void RendererSceneRenderRD : : _render_buffers_copy_depth_texture ( const RenderDataRD * p_render_data ) {
2022-08-04 08:40:39 +00:00
Ref < RenderSceneBuffersRD > rb = p_render_data - > render_buffers ;
ERR_FAIL_COND ( rb . is_null ( ) ) ;
2021-08-11 11:00:12 +00:00
RD : : get_singleton ( ) - > draw_command_begin_label ( " Copy depth texture " ) ;
2022-08-04 08:40:39 +00:00
// note, this only creates our back depth texture if we haven't already created it.
uint32_t usage_bits = RD : : TEXTURE_USAGE_SAMPLING_BIT ;
usage_bits | = RD : : TEXTURE_USAGE_CAN_COPY_TO_BIT | RD : : TEXTURE_USAGE_STORAGE_BIT ;
usage_bits | = RD : : TEXTURE_USAGE_COLOR_ATTACHMENT_BIT ; // set this as color attachment because we're copying data into it, it's not actually used as a depth buffer
2021-08-11 11:00:12 +00:00
2022-08-04 08:40:39 +00:00
rb - > create_texture ( RB_SCOPE_BUFFERS , RB_TEX_BACK_DEPTH , RD : : DATA_FORMAT_R32_SFLOAT , usage_bits , RD : : TEXTURE_SAMPLES_1 ) ;
2021-08-11 11:00:12 +00:00
bool can_use_storage = _render_buffers_can_be_storage ( ) ;
2022-08-04 08:40:39 +00:00
Size2i size = rb - > get_internal_size ( ) ;
2022-09-07 11:23:01 +00:00
for ( uint32_t v = 0 ; v < p_render_data - > scene_data - > view_count ; v + + ) {
2022-08-04 08:40:39 +00:00
RID depth_texture = rb - > get_depth_texture ( v ) ;
RID depth_back_texture = rb - > get_texture_slice ( RB_SCOPE_BUFFERS , RB_TEX_BACK_DEPTH , v , 0 ) ;
2021-08-11 11:00:12 +00:00
2022-08-04 08:40:39 +00:00
if ( can_use_storage ) {
copy_effects - > copy_to_rect ( depth_texture , depth_back_texture , Rect2i ( 0 , 0 , size . x , size . y ) ) ;
} else {
RID depth_back_fb = FramebufferCacheRD : : get_singleton ( ) - > get_cache ( depth_back_texture ) ;
copy_effects - > copy_to_fb_rect ( depth_texture , depth_back_fb , Rect2i ( 0 , 0 , size . x , size . y ) ) ;
}
2021-08-11 11:00:12 +00:00
}
RD : : get_singleton ( ) - > draw_command_end_label ( ) ;
}
2021-05-05 05:41:12 +00:00
void RendererSceneRenderRD : : _render_buffers_post_process_and_tonemap ( const RenderDataRD * p_render_data ) {
2022-03-21 11:25:25 +00:00
RendererRD : : TextureStorage * texture_storage = RendererRD : : TextureStorage : : get_singleton ( ) ;
2022-08-04 08:40:39 +00:00
Ref < RenderSceneBuffersRD > rb = p_render_data - > render_buffers ;
ERR_FAIL_COND ( rb . is_null ( ) ) ;
2020-01-10 00:40:26 +00:00
2022-07-31 23:20:24 +00:00
// Glow, auto exposure and DoF (if enabled).
2022-08-04 08:40:39 +00:00
Size2i internal_size = rb - > get_internal_size ( ) ;
Size2i target_size = rb - > get_target_size ( ) ;
bool can_use_effects = target_size . x > = 8 & & target_size . y > = 8 ; // FIXME I think this should check internal size, we do all our post processing at this size...
2021-07-20 11:40:16 +00:00
bool can_use_storage = _render_buffers_can_be_storage ( ) ;
2022-08-04 08:40:39 +00:00
RID render_target = rb - > get_render_target ( ) ;
RID internal_texture = rb - > get_internal_texture ( ) ;
2022-07-31 23:20:24 +00:00
if ( can_use_effects & & RSG : : camera_attributes - > camera_attributes_uses_dof ( p_render_data - > camera_attributes ) ) {
2022-05-21 15:39:49 +00:00
RENDER_TIMESTAMP ( " Depth of Field " ) ;
2021-07-20 11:40:16 +00:00
RD : : get_singleton ( ) - > draw_command_begin_label ( " DOF " ) ;
2022-08-04 08:40:39 +00:00
rb - > allocate_blur_textures ( ) ;
2020-01-13 18:37:24 +00:00
2022-04-29 07:10:54 +00:00
RendererRD : : BokehDOF : : BokehBuffers buffers ;
2021-07-29 07:43:17 +00:00
2021-11-23 21:16:03 +00:00
// Textures we use
2022-08-04 08:40:39 +00:00
buffers . base_texture_size = rb - > get_internal_size ( ) ;
buffers . secondary_texture = rb - > get_texture_slice ( RB_SCOPE_BUFFERS , RB_TEX_BLUR_0 , 0 , 0 ) ;
buffers . half_texture [ 0 ] = rb - > get_texture_slice ( RB_SCOPE_BUFFERS , RB_TEX_BLUR_1 , 0 , 0 ) ;
buffers . half_texture [ 1 ] = rb - > get_texture_slice ( RB_SCOPE_BUFFERS , RB_TEX_BLUR_0 , 0 , 1 ) ;
2021-07-29 07:43:17 +00:00
2021-07-20 11:40:16 +00:00
if ( can_use_storage ) {
2022-08-04 08:40:39 +00:00
for ( uint32_t i = 0 ; i < rb - > get_view_count ( ) ; i + + ) {
buffers . base_texture = rb - > get_internal_texture ( i ) ;
buffers . depth_texture = rb - > get_depth_texture ( i ) ;
2022-04-29 07:10:54 +00:00
// In stereo p_render_data->z_near and p_render_data->z_far can be offset for our combined frustrum
2022-09-07 11:23:01 +00:00
float z_near = p_render_data - > scene_data - > view_projection [ i ] . get_z_near ( ) ;
float z_far = p_render_data - > scene_data - > view_projection [ i ] . get_z_far ( ) ;
bokeh_dof - > bokeh_dof_compute ( buffers , p_render_data - > camera_attributes , z_near , z_far , p_render_data - > scene_data - > cam_orthogonal ) ;
2022-04-29 07:10:54 +00:00
} ;
2021-07-20 11:40:16 +00:00
} else {
2021-11-08 09:08:02 +00:00
// Set framebuffers.
2021-07-29 07:43:17 +00:00
buffers . secondary_fb = rb - > weight_buffers [ 1 ] . fb ;
buffers . half_fb [ 0 ] = rb - > weight_buffers [ 2 ] . fb ;
buffers . half_fb [ 1 ] = rb - > weight_buffers [ 3 ] . fb ;
buffers . weight_texture [ 0 ] = rb - > weight_buffers [ 0 ] . weight ;
buffers . weight_texture [ 1 ] = rb - > weight_buffers [ 1 ] . weight ;
buffers . weight_texture [ 2 ] = rb - > weight_buffers [ 2 ] . weight ;
buffers . weight_texture [ 3 ] = rb - > weight_buffers [ 3 ] . weight ;
2021-11-08 09:08:02 +00:00
// Set weight buffers.
2022-04-29 07:10:54 +00:00
buffers . base_weight_fb = rb - > weight_buffers [ 0 ] . fb ;
2022-08-04 08:40:39 +00:00
for ( uint32_t i = 0 ; i < rb - > get_view_count ( ) ; i + + ) {
buffers . base_texture = rb - > get_internal_texture ( i ) ;
buffers . depth_texture = rb - > get_depth_texture ( i ) ;
buffers . base_fb = FramebufferCacheRD : : get_singleton ( ) - > get_cache ( buffers . base_texture ) ; // TODO move this into bokeh_dof_raster, we can do this internally
2021-07-29 07:43:17 +00:00
2022-04-29 07:10:54 +00:00
// In stereo p_render_data->z_near and p_render_data->z_far can be offset for our combined frustrum
2022-09-07 11:23:01 +00:00
float z_near = p_render_data - > scene_data - > view_projection [ i ] . get_z_near ( ) ;
float z_far = p_render_data - > scene_data - > view_projection [ i ] . get_z_far ( ) ;
bokeh_dof - > bokeh_dof_raster ( buffers , p_render_data - > camera_attributes , z_near , z_far , p_render_data - > scene_data - > cam_orthogonal ) ;
2022-04-29 07:10:54 +00:00
}
2021-07-20 11:40:16 +00:00
}
RD : : get_singleton ( ) - > draw_command_end_label ( ) ;
2020-01-13 18:37:24 +00:00
}
2022-07-31 23:20:24 +00:00
float auto_exposure_scale = 1.0 ;
if ( can_use_effects & & RSG : : camera_attributes - > camera_attributes_uses_auto_exposure ( p_render_data - > camera_attributes ) ) {
2022-05-21 15:39:49 +00:00
RENDER_TIMESTAMP ( " Auto exposure " ) ;
2022-07-31 23:20:24 +00:00
2021-07-20 11:40:16 +00:00
RD : : get_singleton ( ) - > draw_command_begin_label ( " Auto exposure " ) ;
2020-01-12 01:26:52 +00:00
if ( rb - > luminance . current . is_null ( ) ) {
_allocate_luminance_textures ( rb ) ;
}
2022-07-31 23:20:24 +00:00
uint64_t auto_exposure_version = RSG : : camera_attributes - > camera_attributes_get_auto_exposure_version ( p_render_data - > camera_attributes ) ;
2022-08-04 08:40:39 +00:00
bool set_immediate = auto_exposure_version ! = rb - > get_auto_exposure_version ( ) ;
rb - > set_auto_exposure_version ( auto_exposure_version ) ;
2020-01-12 01:26:52 +00:00
2022-07-31 23:20:24 +00:00
double step = RSG : : camera_attributes - > camera_attributes_get_auto_exposure_adjust_speed ( p_render_data - > camera_attributes ) * time_step ;
float auto_exposure_min_sensitivity = RSG : : camera_attributes - > camera_attributes_get_auto_exposure_min_sensitivity ( p_render_data - > camera_attributes ) ;
float auto_exposure_max_sensitivity = RSG : : camera_attributes - > camera_attributes_get_auto_exposure_max_sensitivity ( p_render_data - > camera_attributes ) ;
2021-07-20 11:40:16 +00:00
if ( can_use_storage ) {
2022-08-04 08:40:39 +00:00
RendererCompositorRD : : singleton - > get_effects ( ) - > luminance_reduction ( internal_texture , internal_size , rb - > luminance . reduce , rb - > luminance . current , auto_exposure_min_sensitivity , auto_exposure_max_sensitivity , step , set_immediate ) ;
2021-07-20 11:40:16 +00:00
} else {
2022-08-04 08:40:39 +00:00
RendererCompositorRD : : singleton - > get_effects ( ) - > luminance_reduction_raster ( internal_texture , internal_size , rb - > luminance . reduce , rb - > luminance . fb , rb - > luminance . current , auto_exposure_min_sensitivity , auto_exposure_max_sensitivity , step , set_immediate ) ;
2021-07-20 11:40:16 +00:00
}
2021-11-08 09:08:02 +00:00
// Swap final reduce with prev luminance.
2020-01-12 01:26:52 +00:00
SWAP ( rb - > luminance . current , rb - > luminance . reduce . write [ rb - > luminance . reduce . size ( ) - 1 ] ) ;
2021-07-20 11:40:16 +00:00
if ( ! can_use_storage ) {
SWAP ( rb - > luminance . current_fb , rb - > luminance . fb . write [ rb - > luminance . fb . size ( ) - 1 ] ) ;
}
2022-07-31 23:20:24 +00:00
auto_exposure_scale = RSG : : camera_attributes - > camera_attributes_get_auto_exposure_scale ( p_render_data - > camera_attributes ) ;
2021-11-08 09:08:02 +00:00
RenderingServerDefault : : redraw_request ( ) ; // Redraw all the time if auto exposure rendering is on.
2021-07-20 11:40:16 +00:00
RD : : get_singleton ( ) - > draw_command_end_label ( ) ;
2020-01-12 01:26:52 +00:00
}
2020-01-10 00:40:26 +00:00
int max_glow_level = - 1 ;
2022-07-27 06:14:23 +00:00
if ( can_use_effects & & p_render_data - > environment . is_valid ( ) & & environment_get_glow_enabled ( p_render_data - > environment ) ) {
2022-05-21 15:39:49 +00:00
RENDER_TIMESTAMP ( " Glow " ) ;
2021-07-20 11:40:16 +00:00
RD : : get_singleton ( ) - > draw_command_begin_label ( " Gaussian Glow " ) ;
2022-08-04 08:40:39 +00:00
rb - > allocate_blur_textures ( ) ;
2020-01-10 00:40:26 +00:00
2020-03-27 18:21:27 +00:00
for ( int i = 0 ; i < RS : : MAX_GLOW_LEVELS ; i + + ) {
2022-07-27 06:14:23 +00:00
if ( environment_get_glow_levels ( p_render_data - > environment ) [ i ] > 0.0 ) {
2022-08-04 08:40:39 +00:00
int mipmaps = int ( rb - > get_texture_format ( RB_SCOPE_BUFFERS , RB_TEX_BLUR_1 ) . mipmaps ) ;
if ( i > = mipmaps ) {
max_glow_level = mipmaps - 1 ;
2020-01-10 00:40:26 +00:00
} else {
max_glow_level = i ;
}
}
}
2022-04-29 07:10:54 +00:00
float luminance_multiplier = _render_buffers_get_luminance_multiplier ( ) ;
2022-08-04 08:40:39 +00:00
for ( uint32_t l = 0 ; l < rb - > get_view_count ( ) ; l + + ) {
2022-04-29 07:10:54 +00:00
for ( int i = 0 ; i < ( max_glow_level + 1 ) ; i + + ) {
2022-08-04 08:40:39 +00:00
Size2i vp_size = rb - > get_texture_slice_size ( RB_SCOPE_BUFFERS , RB_TEX_BLUR_1 , l , i ) ;
2020-01-10 00:40:26 +00:00
2022-04-29 07:10:54 +00:00
if ( i = = 0 ) {
RID luminance_texture ;
2022-07-31 23:20:24 +00:00
if ( RSG : : camera_attributes - > camera_attributes_uses_auto_exposure ( p_render_data - > camera_attributes ) & & rb - > luminance . current . is_valid ( ) ) {
2022-04-29 07:10:54 +00:00
luminance_texture = rb - > luminance . current ;
}
2022-08-04 08:40:39 +00:00
RID source = rb - > get_internal_texture ( l ) ;
RID dest = rb - > get_texture_slice ( RB_SCOPE_BUFFERS , RB_TEX_BLUR_1 , l , i ) ;
2022-04-29 07:10:54 +00:00
if ( can_use_storage ) {
2022-08-04 08:40:39 +00:00
copy_effects - > gaussian_glow ( source , dest , vp_size , environment_get_glow_strength ( p_render_data - > environment ) , glow_high_quality , true , environment_get_glow_hdr_luminance_cap ( p_render_data - > environment ) , environment_get_exposure ( p_render_data - > environment ) , environment_get_glow_bloom ( p_render_data - > environment ) , environment_get_glow_hdr_bleed_threshold ( p_render_data - > environment ) , environment_get_glow_hdr_bleed_scale ( p_render_data - > environment ) , luminance_texture , auto_exposure_scale ) ;
2022-04-29 07:10:54 +00:00
} else {
2022-08-04 08:40:39 +00:00
RID half = rb - > get_texture_slice ( RB_SCOPE_BUFFERS , RB_TEX_HALF_BLUR , 0 , i ) ; // we can reuse this for each view
copy_effects - > gaussian_glow_raster ( source , half , dest , luminance_multiplier , vp_size , environment_get_glow_strength ( p_render_data - > environment ) , glow_high_quality , true , environment_get_glow_hdr_luminance_cap ( p_render_data - > environment ) , environment_get_exposure ( p_render_data - > environment ) , environment_get_glow_bloom ( p_render_data - > environment ) , environment_get_glow_hdr_bleed_threshold ( p_render_data - > environment ) , environment_get_glow_hdr_bleed_scale ( p_render_data - > environment ) , luminance_texture , auto_exposure_scale ) ;
2022-04-29 07:10:54 +00:00
}
2021-07-20 11:40:16 +00:00
} else {
2022-08-04 08:40:39 +00:00
RID source = rb - > get_texture_slice ( RB_SCOPE_BUFFERS , RB_TEX_BLUR_1 , l , i - 1 ) ;
RID dest = rb - > get_texture_slice ( RB_SCOPE_BUFFERS , RB_TEX_BLUR_1 , l , i ) ;
2022-04-29 07:10:54 +00:00
if ( can_use_storage ) {
2022-08-04 08:40:39 +00:00
copy_effects - > gaussian_glow ( source , dest , vp_size , environment_get_glow_strength ( p_render_data - > environment ) , glow_high_quality ) ;
2022-04-29 07:10:54 +00:00
} else {
2022-08-04 08:40:39 +00:00
RID half = rb - > get_texture_slice ( RB_SCOPE_BUFFERS , RB_TEX_HALF_BLUR , 0 , i ) ; // we can reuse this for each view
copy_effects - > gaussian_glow_raster ( source , half , dest , luminance_multiplier , vp_size , environment_get_glow_strength ( p_render_data - > environment ) , glow_high_quality ) ;
2022-04-29 07:10:54 +00:00
}
2021-07-20 11:40:16 +00:00
}
2020-01-10 00:40:26 +00:00
}
}
2021-07-20 11:40:16 +00:00
RD : : get_singleton ( ) - > draw_command_end_label ( ) ;
2020-01-10 00:40:26 +00:00
}
{
2022-05-21 15:39:49 +00:00
RENDER_TIMESTAMP ( " Tonemap " ) ;
2021-07-20 11:40:16 +00:00
RD : : get_singleton ( ) - > draw_command_begin_label ( " Tonemap " ) ;
2022-04-27 03:42:50 +00:00
RendererRD : : ToneMapper : : TonemapSettings tonemap ;
2020-01-10 00:40:26 +00:00
2022-07-31 23:20:24 +00:00
if ( can_use_effects & & RSG : : camera_attributes - > camera_attributes_uses_auto_exposure ( p_render_data - > camera_attributes ) & & rb - > luminance . current . is_valid ( ) ) {
2020-01-12 01:26:52 +00:00
tonemap . use_auto_exposure = true ;
tonemap . exposure_texture = rb - > luminance . current ;
2022-07-31 23:20:24 +00:00
tonemap . auto_exposure_scale = auto_exposure_scale ;
2020-01-12 01:26:52 +00:00
} else {
2022-08-01 01:59:14 +00:00
tonemap . exposure_texture = texture_storage - > texture_rd_get_default ( RendererRD : : TextureStorage : : DEFAULT_RD_TEXTURE_WHITE ) ;
2020-01-12 01:26:52 +00:00
}
2022-07-27 06:14:23 +00:00
if ( can_use_effects & & p_render_data - > environment . is_valid ( ) & & environment_get_glow_enabled ( p_render_data - > environment ) ) {
2020-01-10 00:40:26 +00:00
tonemap . use_glow = true ;
2022-07-27 06:14:23 +00:00
tonemap . glow_mode = RendererRD : : ToneMapper : : TonemapSettings : : GlowMode ( environment_get_glow_blend_mode ( p_render_data - > environment ) ) ;
tonemap . glow_intensity = environment_get_glow_blend_mode ( p_render_data - > environment ) = = RS : : ENV_GLOW_BLEND_MODE_MIX ? environment_get_glow_mix ( p_render_data - > environment ) : environment_get_glow_intensity ( p_render_data - > environment ) ;
2020-09-19 22:02:32 +00:00
for ( int i = 0 ; i < RS : : MAX_GLOW_LEVELS ; i + + ) {
2022-07-27 06:14:23 +00:00
tonemap . glow_levels [ i ] = environment_get_glow_levels ( p_render_data - > environment ) [ i ] ;
2020-09-19 22:02:32 +00:00
}
2022-08-04 08:40:39 +00:00
Size2i msize = rb - > get_texture_slice_size ( RB_SCOPE_BUFFERS , RB_TEX_BLUR_1 , 0 , 0 ) ;
tonemap . glow_texture_size . x = msize . width ;
tonemap . glow_texture_size . y = msize . height ;
2020-03-30 13:46:03 +00:00
tonemap . glow_use_bicubic_upscale = glow_bicubic_upscale ;
2022-08-04 08:40:39 +00:00
tonemap . glow_texture = rb - > get_texture ( RB_SCOPE_BUFFERS , RB_TEX_BLUR_1 ) ;
2022-07-27 06:14:23 +00:00
if ( environment_get_glow_map ( p_render_data - > environment ) . is_valid ( ) ) {
tonemap . glow_map_strength = environment_get_glow_map_strength ( p_render_data - > environment ) ;
tonemap . glow_map = texture_storage - > texture_get_rd_texture ( environment_get_glow_map ( p_render_data - > environment ) ) ;
2022-01-20 15:47:25 +00:00
} else {
tonemap . glow_map_strength = 0.0f ;
2022-08-01 01:59:14 +00:00
tonemap . glow_map = texture_storage - > texture_rd_get_default ( RendererRD : : TextureStorage : : DEFAULT_RD_TEXTURE_WHITE ) ;
2022-01-20 15:47:25 +00:00
}
2020-01-10 00:40:26 +00:00
} else {
2022-08-01 01:59:14 +00:00
tonemap . glow_texture = texture_storage - > texture_rd_get_default ( RendererRD : : TextureStorage : : DEFAULT_RD_TEXTURE_BLACK ) ;
tonemap . glow_map = texture_storage - > texture_rd_get_default ( RendererRD : : TextureStorage : : DEFAULT_RD_TEXTURE_WHITE ) ;
2020-01-10 00:40:26 +00:00
}
2022-08-04 08:40:39 +00:00
if ( rb - > get_screen_space_aa ( ) = = RS : : VIEWPORT_SCREEN_SPACE_AA_FXAA ) {
2020-04-12 04:49:10 +00:00
tonemap . use_fxaa = true ;
}
2022-08-04 08:40:39 +00:00
tonemap . use_debanding = rb - > get_use_debanding ( ) ;
tonemap . texture_size = Vector2i ( rb - > get_internal_size ( ) . x , rb - > get_internal_size ( ) . y ) ;
2020-04-12 04:49:10 +00:00
2022-07-27 06:14:23 +00:00
if ( p_render_data - > environment . is_valid ( ) ) {
tonemap . tonemap_mode = environment_get_tone_mapper ( p_render_data - > environment ) ;
tonemap . white = environment_get_white ( p_render_data - > environment ) ;
tonemap . exposure = environment_get_exposure ( p_render_data - > environment ) ;
2020-01-10 00:40:26 +00:00
}
2020-12-02 01:40:47 +00:00
tonemap . use_color_correction = false ;
tonemap . use_1d_color_correction = false ;
2022-08-01 01:59:14 +00:00
tonemap . color_correction_texture = texture_storage - > texture_rd_get_default ( RendererRD : : TextureStorage : : DEFAULT_RD_TEXTURE_3D_WHITE ) ;
2020-12-02 01:40:47 +00:00
2022-07-27 06:14:23 +00:00
if ( can_use_effects & & p_render_data - > environment . is_valid ( ) ) {
tonemap . use_bcs = environment_get_adjustments_enabled ( p_render_data - > environment ) ;
tonemap . brightness = environment_get_adjustments_brightness ( p_render_data - > environment ) ;
tonemap . contrast = environment_get_adjustments_contrast ( p_render_data - > environment ) ;
tonemap . saturation = environment_get_adjustments_saturation ( p_render_data - > environment ) ;
if ( environment_get_adjustments_enabled ( p_render_data - > environment ) & & environment_get_color_correction ( p_render_data - > environment ) . is_valid ( ) ) {
2020-11-23 01:51:31 +00:00
tonemap . use_color_correction = true ;
2022-07-27 06:14:23 +00:00
tonemap . use_1d_color_correction = environment_get_use_1d_color_correction ( p_render_data - > environment ) ;
tonemap . color_correction_texture = texture_storage - > texture_get_rd_texture ( environment_get_color_correction ( p_render_data - > environment ) ) ;
2020-11-23 01:51:31 +00:00
}
}
2021-07-26 11:31:15 +00:00
tonemap . luminance_multiplier = _render_buffers_get_luminance_multiplier ( ) ;
2022-08-04 08:40:39 +00:00
tonemap . view_count = rb - > get_view_count ( ) ;
RID dest_fb ;
if ( fsr & & can_use_effects & & ( internal_size . x ! = target_size . x | | internal_size . y ! = target_size . y ) ) {
// If we use FSR to upscale we need to write our result into an intermediate buffer.
// Note that this is cached so we only create the texture the first time.
RID dest_texture = rb - > create_texture ( SNAME ( " Tonemapper " ) , SNAME ( " destination " ) , _render_buffers_get_color_format ( ) , RD : : TEXTURE_USAGE_SAMPLING_BIT | RD : : TEXTURE_USAGE_STORAGE_BIT | RD : : TEXTURE_USAGE_COLOR_ATTACHMENT_BIT ) ;
dest_fb = FramebufferCacheRD : : get_singleton ( ) - > get_cache ( dest_texture ) ;
} else {
// If we do a bilinear upscale we just render into our render target and our shader will upscale automatically.
// Target size in this case is lying as we never get our real target size communicated.
// Bit nasty but...
dest_fb = texture_storage - > render_target_get_rd_framebuffer ( render_target ) ;
}
2021-05-07 13:19:04 +00:00
2022-08-04 08:40:39 +00:00
tone_mapper - > tonemapper ( internal_texture , dest_fb , tonemap ) ;
2021-11-23 21:16:03 +00:00
RD : : get_singleton ( ) - > draw_command_end_label ( ) ;
}
2022-08-04 08:40:39 +00:00
if ( fsr & & can_use_effects & & ( internal_size . x ! = target_size . x | | internal_size . y ! = target_size . y ) ) {
// TODO Investigate? Does this work? We never write into our render target and we've already done so up above in our tonemapper.
// I think FSR should either work before our tonemapper or as an alternative of our tonemapper.
2022-05-12 16:22:17 +00:00
RD : : get_singleton ( ) - > draw_command_begin_label ( " FSR 1.0 Upscale " ) ;
2021-11-23 21:16:03 +00:00
2022-08-04 08:40:39 +00:00
for ( uint32_t v = 0 ; v < rb - > get_view_count ( ) ; v + + ) {
RID source_texture = rb - > get_texture_slice ( SNAME ( " Tonemapper " ) , SNAME ( " destination " ) , v , 0 ) ;
RID dest_texture = texture_storage - > render_target_get_rd_texture_slice ( render_target , v ) ;
fsr - > fsr_upscale ( rb , source_texture , dest_texture ) ;
}
2021-07-20 11:40:16 +00:00
RD : : get_singleton ( ) - > draw_command_end_label ( ) ;
2020-01-10 00:40:26 +00:00
}
2022-08-04 08:40:39 +00:00
texture_storage - > render_target_disable_clear_request ( render_target ) ;
2020-01-10 00:40:26 +00:00
}
2021-06-26 10:49:25 +00:00
void RendererSceneRenderRD : : _post_process_subpass ( RID p_source_texture , RID p_framebuffer , const RenderDataRD * p_render_data ) {
2022-03-21 11:25:25 +00:00
RendererRD : : TextureStorage * texture_storage = RendererRD : : TextureStorage : : get_singleton ( ) ;
2021-06-26 10:49:25 +00:00
RD : : get_singleton ( ) - > draw_command_begin_label ( " Post Process Subpass " ) ;
2022-08-04 08:40:39 +00:00
Ref < RenderSceneBuffersRD > rb = p_render_data - > render_buffers ;
ERR_FAIL_COND ( rb . is_null ( ) ) ;
2021-06-26 10:49:25 +00:00
2022-08-04 08:40:39 +00:00
// FIXME: Our input it our internal_texture, shouldn't this be using internal_size ??
// Seeing we don't support FSR in our mobile renderer right now target_size = internal_size...
Size2i target_size = rb - > get_target_size ( ) ;
bool can_use_effects = target_size . x > = 8 & & target_size . y > = 8 ;
2021-06-26 10:49:25 +00:00
RD : : DrawListID draw_list = RD : : get_singleton ( ) - > draw_list_switch_to_next_pass ( ) ;
2022-04-27 03:42:50 +00:00
RendererRD : : ToneMapper : : TonemapSettings tonemap ;
2021-06-26 10:49:25 +00:00
2022-07-27 06:14:23 +00:00
if ( p_render_data - > environment . is_valid ( ) ) {
tonemap . tonemap_mode = environment_get_tone_mapper ( p_render_data - > environment ) ;
tonemap . exposure = environment_get_exposure ( p_render_data - > environment ) ;
tonemap . white = environment_get_white ( p_render_data - > environment ) ;
2021-06-26 10:49:25 +00:00
}
// We don't support glow or auto exposure here, if they are needed, don't use subpasses!
// The problem is that we need to use the result so far and process them before we can
// apply this to our results.
2022-07-27 06:14:23 +00:00
if ( can_use_effects & & p_render_data - > environment . is_valid ( ) & & environment_get_glow_enabled ( p_render_data - > environment ) ) {
2021-06-26 10:49:25 +00:00
ERR_FAIL_MSG ( " Glow is not supported when using subpasses. " ) ;
}
2022-07-31 23:20:24 +00:00
if ( can_use_effects & & RSG : : camera_attributes - > camera_attributes_uses_auto_exposure ( p_render_data - > camera_attributes ) ) {
ERR_FAIL_MSG ( " Auto Exposure is not supported when using subpasses. " ) ;
2021-06-26 10:49:25 +00:00
}
tonemap . use_glow = false ;
2022-08-01 01:59:14 +00:00
tonemap . glow_texture = texture_storage - > texture_rd_get_default ( RendererRD : : TextureStorage : : DEFAULT_RD_TEXTURE_BLACK ) ;
tonemap . glow_map = texture_storage - > texture_rd_get_default ( RendererRD : : TextureStorage : : DEFAULT_RD_TEXTURE_WHITE ) ;
2021-06-26 10:49:25 +00:00
tonemap . use_auto_exposure = false ;
2022-08-01 01:59:14 +00:00
tonemap . exposure_texture = texture_storage - > texture_rd_get_default ( RendererRD : : TextureStorage : : DEFAULT_RD_TEXTURE_WHITE ) ;
2021-06-26 10:49:25 +00:00
tonemap . use_color_correction = false ;
tonemap . use_1d_color_correction = false ;
2022-08-01 01:59:14 +00:00
tonemap . color_correction_texture = texture_storage - > texture_rd_get_default ( RendererRD : : TextureStorage : : DEFAULT_RD_TEXTURE_3D_WHITE ) ;
2021-06-26 10:49:25 +00:00
2022-07-27 06:14:23 +00:00
if ( can_use_effects & & p_render_data - > environment . is_valid ( ) ) {
tonemap . use_bcs = environment_get_adjustments_enabled ( p_render_data - > environment ) ;
tonemap . brightness = environment_get_adjustments_brightness ( p_render_data - > environment ) ;
tonemap . contrast = environment_get_adjustments_contrast ( p_render_data - > environment ) ;
tonemap . saturation = environment_get_adjustments_saturation ( p_render_data - > environment ) ;
if ( environment_get_adjustments_enabled ( p_render_data - > environment ) & & environment_get_color_correction ( p_render_data - > environment ) . is_valid ( ) ) {
2021-06-26 10:49:25 +00:00
tonemap . use_color_correction = true ;
2022-07-27 06:14:23 +00:00
tonemap . use_1d_color_correction = environment_get_use_1d_color_correction ( p_render_data - > environment ) ;
tonemap . color_correction_texture = texture_storage - > texture_get_rd_texture ( environment_get_color_correction ( p_render_data - > environment ) ) ;
2021-06-26 10:49:25 +00:00
}
}
2022-08-04 08:40:39 +00:00
tonemap . use_debanding = rb - > get_use_debanding ( ) ;
tonemap . texture_size = Vector2i ( target_size . x , target_size . y ) ;
2021-06-26 10:49:25 +00:00
2021-07-26 11:31:15 +00:00
tonemap . luminance_multiplier = _render_buffers_get_luminance_multiplier ( ) ;
2022-08-04 08:40:39 +00:00
tonemap . view_count = rb - > get_view_count ( ) ;
2021-06-26 10:49:25 +00:00
2022-04-27 03:42:50 +00:00
tone_mapper - > tonemapper ( draw_list , p_source_texture , RD : : get_singleton ( ) - > framebuffer_get_format ( p_framebuffer ) , tonemap ) ;
2021-06-26 10:49:25 +00:00
RD : : get_singleton ( ) - > draw_command_end_label ( ) ;
}
void RendererSceneRenderRD : : _disable_clear_request ( const RenderDataRD * p_render_data ) {
2022-08-04 08:40:39 +00:00
ERR_FAIL_COND ( p_render_data - > render_buffers . is_null ( ) ) ;
2021-06-26 10:49:25 +00:00
2022-04-07 14:00:51 +00:00
RendererRD : : TextureStorage * texture_storage = RendererRD : : TextureStorage : : get_singleton ( ) ;
2022-08-04 08:40:39 +00:00
texture_storage - > render_target_disable_clear_request ( p_render_data - > render_buffers - > get_render_target ( ) ) ;
2021-06-26 10:49:25 +00:00
}
2022-08-04 08:40:39 +00:00
void RendererSceneRenderRD : : _render_buffers_debug_draw ( Ref < RenderSceneBuffersRD > p_render_buffers , RID p_shadow_atlas , RID p_occlusion_buffer ) {
2022-03-21 11:25:25 +00:00
RendererRD : : TextureStorage * texture_storage = RendererRD : : TextureStorage : : get_singleton ( ) ;
2020-01-10 00:40:26 +00:00
2022-08-04 08:40:39 +00:00
ERR_FAIL_COND ( p_render_buffers . is_null ( ) ) ;
RID render_target = p_render_buffers - > get_render_target ( ) ;
2020-01-10 00:40:26 +00:00
2020-03-27 18:21:27 +00:00
if ( debug_draw = = RS : : VIEWPORT_DEBUG_DRAW_SHADOW_ATLAS ) {
2020-01-10 00:40:26 +00:00
if ( p_shadow_atlas . is_valid ( ) ) {
RID shadow_atlas_texture = shadow_atlas_get_texture ( p_shadow_atlas ) ;
2022-01-24 14:55:32 +00:00
if ( shadow_atlas_texture . is_null ( ) ) {
2022-08-01 01:59:14 +00:00
shadow_atlas_texture = texture_storage - > texture_rd_get_default ( RendererRD : : TextureStorage : : DEFAULT_RD_TEXTURE_BLACK ) ;
2022-01-24 14:55:32 +00:00
}
2022-08-04 08:40:39 +00:00
Size2 rtsize = texture_storage - > render_target_get_size ( render_target ) ;
copy_effects - > copy_to_fb_rect ( shadow_atlas_texture , texture_storage - > render_target_get_rd_framebuffer ( render_target ) , Rect2i ( Vector2 ( ) , rtsize / 2 ) , false , true ) ;
2020-01-10 00:40:26 +00:00
}
}
2020-03-27 18:21:27 +00:00
if ( debug_draw = = RS : : VIEWPORT_DEBUG_DRAW_DIRECTIONAL_SHADOW_ATLAS ) {
2020-01-10 00:40:26 +00:00
if ( directional_shadow_get_texture ( ) . is_valid ( ) ) {
RID shadow_atlas_texture = directional_shadow_get_texture ( ) ;
2022-08-04 08:40:39 +00:00
Size2 rtsize = texture_storage - > render_target_get_size ( render_target ) ;
2020-01-10 00:40:26 +00:00
2022-08-04 08:40:39 +00:00
copy_effects - > copy_to_fb_rect ( shadow_atlas_texture , texture_storage - > render_target_get_rd_framebuffer ( render_target ) , Rect2i ( Vector2 ( ) , rtsize / 2 ) , false , true ) ;
2020-01-10 00:40:26 +00:00
}
}
2020-01-12 01:26:52 +00:00
2020-04-14 03:05:21 +00:00
if ( debug_draw = = RS : : VIEWPORT_DEBUG_DRAW_DECAL_ATLAS ) {
2022-04-07 14:00:51 +00:00
RID decal_atlas = RendererRD : : TextureStorage : : get_singleton ( ) - > decal_atlas_get_texture ( ) ;
2020-04-14 03:05:21 +00:00
if ( decal_atlas . is_valid ( ) ) {
2022-08-04 08:40:39 +00:00
Size2 rtsize = texture_storage - > render_target_get_size ( render_target ) ;
2020-04-14 03:05:21 +00:00
2022-08-04 08:40:39 +00:00
copy_effects - > copy_to_fb_rect ( decal_atlas , texture_storage - > render_target_get_rd_framebuffer ( render_target ) , Rect2i ( Vector2 ( ) , rtsize / 2 ) , false , false , true ) ;
2020-06-25 13:33:28 +00:00
}
}
2021-02-13 12:08:08 +00:00
if ( debug_draw = = RS : : VIEWPORT_DEBUG_DRAW_SCENE_LUMINANCE ) {
2022-08-04 08:40:39 +00:00
if ( p_render_buffers - > luminance . current . is_valid ( ) ) {
Size2 rtsize = texture_storage - > render_target_get_size ( render_target ) ;
2021-02-13 12:08:08 +00:00
2022-08-04 08:40:39 +00:00
copy_effects - > copy_to_fb_rect ( p_render_buffers - > luminance . current , texture_storage - > render_target_get_rd_framebuffer ( render_target ) , Rect2 ( Vector2 ( ) , rtsize / 8 ) , false , true ) ;
2021-02-13 12:08:08 +00:00
}
}
2022-08-04 08:40:39 +00:00
if ( debug_draw = = RS : : VIEWPORT_DEBUG_DRAW_SSAO & & p_render_buffers - > ss_effects . ssao . ao_final . is_valid ( ) ) {
Size2 rtsize = texture_storage - > render_target_get_size ( render_target ) ;
copy_effects - > copy_to_fb_rect ( p_render_buffers - > ss_effects . ssao . ao_final , texture_storage - > render_target_get_rd_framebuffer ( render_target ) , Rect2 ( Vector2 ( ) , rtsize ) , false , true ) ;
2021-08-03 07:07:32 +00:00
}
2022-08-04 08:40:39 +00:00
if ( debug_draw = = RS : : VIEWPORT_DEBUG_DRAW_SSIL & & p_render_buffers - > ss_effects . ssil . ssil_final . is_valid ( ) ) {
Size2 rtsize = texture_storage - > render_target_get_size ( render_target ) ;
copy_effects - > copy_to_fb_rect ( p_render_buffers - > ss_effects . ssil . ssil_final , texture_storage - > render_target_get_rd_framebuffer ( render_target ) , Rect2 ( Vector2 ( ) , rtsize ) , false , false ) ;
2021-02-13 12:08:08 +00:00
}
if ( debug_draw = = RS : : VIEWPORT_DEBUG_DRAW_NORMAL_BUFFER & & _render_buffers_get_normal_texture ( p_render_buffers ) . is_valid ( ) ) {
2022-08-04 08:40:39 +00:00
Size2 rtsize = texture_storage - > render_target_get_size ( render_target ) ;
copy_effects - > copy_to_fb_rect ( _render_buffers_get_normal_texture ( p_render_buffers ) , texture_storage - > render_target_get_rd_framebuffer ( render_target ) , Rect2 ( Vector2 ( ) , rtsize ) , false , false ) ;
2021-02-13 12:08:08 +00:00
}
2022-08-04 08:40:39 +00:00
if ( debug_draw = = RS : : VIEWPORT_DEBUG_DRAW_GI_BUFFER & & p_render_buffers - > has_texture ( RB_SCOPE_GI , RB_TEX_AMBIENT ) ) {
Size2 rtsize = texture_storage - > render_target_get_size ( render_target ) ;
RID ambient_texture = p_render_buffers - > get_texture ( RB_SCOPE_GI , RB_TEX_AMBIENT ) ;
RID reflection_texture = p_render_buffers - > get_texture ( RB_SCOPE_GI , RB_TEX_REFLECTION ) ;
copy_effects - > copy_to_fb_rect ( ambient_texture , texture_storage - > render_target_get_rd_framebuffer ( render_target ) , Rect2 ( Vector2 ( ) , rtsize ) , false , false , false , true , reflection_texture , p_render_buffers - > get_view_count ( ) > 1 ) ;
2021-02-13 12:08:08 +00:00
}
2021-04-20 16:40:24 +00:00
if ( debug_draw = = RS : : VIEWPORT_DEBUG_DRAW_OCCLUDERS ) {
if ( p_occlusion_buffer . is_valid ( ) ) {
2022-08-04 08:40:39 +00:00
Size2 rtsize = texture_storage - > render_target_get_size ( render_target ) ;
copy_effects - > copy_to_fb_rect ( texture_storage - > texture_get_rd_texture ( p_occlusion_buffer ) , texture_storage - > render_target_get_rd_framebuffer ( render_target ) , Rect2i ( Vector2 ( ) , rtsize ) , true , false ) ;
2021-04-20 16:40:24 +00:00
}
}
2022-04-04 14:10:22 +00:00
if ( debug_draw = = RS : : VIEWPORT_DEBUG_DRAW_MOTION_VECTORS & & _render_buffers_get_velocity_texture ( p_render_buffers ) . is_valid ( ) ) {
2022-08-04 08:40:39 +00:00
Size2 rtsize = texture_storage - > render_target_get_size ( render_target ) ;
copy_effects - > copy_to_fb_rect ( _render_buffers_get_velocity_texture ( p_render_buffers ) , texture_storage - > render_target_get_rd_framebuffer ( render_target ) , Rect2 ( Vector2 ( ) , rtsize ) , false , false ) ;
2020-06-25 13:33:28 +00:00
}
}
2021-06-04 22:47:26 +00:00
RID RendererSceneRenderRD : : render_buffers_get_default_voxel_gi_buffer ( ) {
return gi . default_voxel_gi_buffer ;
2020-06-25 13:33:28 +00:00
}
2021-07-26 11:31:15 +00:00
float RendererSceneRenderRD : : _render_buffers_get_luminance_multiplier ( ) {
return 1.0 ;
}
2021-06-17 10:37:08 +00:00
RD : : DataFormat RendererSceneRenderRD : : _render_buffers_get_color_format ( ) {
return RD : : DATA_FORMAT_R16G16B16A16_SFLOAT ;
}
2021-07-15 20:06:33 +00:00
bool RendererSceneRenderRD : : _render_buffers_can_be_storage ( ) {
return true ;
}
2021-01-22 23:50:24 +00:00
void RendererSceneRenderRD : : gi_set_use_half_resolution ( bool p_enable ) {
gi . half_resolution = p_enable ;
}
2020-12-04 18:26:24 +00:00
void RendererSceneRenderRD : : sub_surface_scattering_set_quality ( RS : : SubSurfaceScatteringQuality p_quality ) {
2020-04-04 02:42:26 +00:00
sss_quality = p_quality ;
}
2020-12-04 18:26:24 +00:00
RS : : SubSurfaceScatteringQuality RendererSceneRenderRD : : sub_surface_scattering_get_quality ( ) const {
2020-04-04 02:42:26 +00:00
return sss_quality ;
}
2020-12-04 18:26:24 +00:00
void RendererSceneRenderRD : : sub_surface_scattering_set_scale ( float p_scale , float p_depth_scale ) {
2020-04-04 02:42:26 +00:00
sss_scale = p_scale ;
sss_depth_scale = p_depth_scale ;
}
2022-04-30 23:40:30 +00:00
void RendererSceneRenderRD : : positional_soft_shadow_filter_set_quality ( RS : : ShadowQuality p_quality ) {
2020-04-10 09:30:36 +00:00
ERR_FAIL_INDEX_MSG ( p_quality , RS : : SHADOW_QUALITY_MAX , " Shadow quality too high, please see RenderingServer's ShadowQuality enum " ) ;
if ( shadows_quality ! = p_quality ) {
shadows_quality = p_quality ;
switch ( shadows_quality ) {
case RS : : SHADOW_QUALITY_HARD : {
penumbra_shadow_samples = 4 ;
2021-10-19 14:52:57 +00:00
soft_shadow_samples = 0 ;
2020-04-10 09:30:36 +00:00
shadows_quality_radius = 1.0 ;
} break ;
2021-10-19 14:52:57 +00:00
case RS : : SHADOW_QUALITY_SOFT_VERY_LOW : {
penumbra_shadow_samples = 4 ;
soft_shadow_samples = 1 ;
shadows_quality_radius = 1.5 ;
} break ;
2020-04-10 09:30:36 +00:00
case RS : : SHADOW_QUALITY_SOFT_LOW : {
penumbra_shadow_samples = 8 ;
soft_shadow_samples = 4 ;
shadows_quality_radius = 2.0 ;
} break ;
case RS : : SHADOW_QUALITY_SOFT_MEDIUM : {
penumbra_shadow_samples = 12 ;
soft_shadow_samples = 8 ;
shadows_quality_radius = 2.0 ;
} break ;
case RS : : SHADOW_QUALITY_SOFT_HIGH : {
penumbra_shadow_samples = 24 ;
soft_shadow_samples = 16 ;
shadows_quality_radius = 3.0 ;
} break ;
case RS : : SHADOW_QUALITY_SOFT_ULTRA : {
penumbra_shadow_samples = 32 ;
soft_shadow_samples = 32 ;
shadows_quality_radius = 4.0 ;
} break ;
case RS : : SHADOW_QUALITY_MAX :
break ;
}
get_vogel_disk ( penumbra_shadow_kernel , penumbra_shadow_samples ) ;
get_vogel_disk ( soft_shadow_kernel , soft_shadow_samples ) ;
}
2021-07-19 19:41:55 +00:00
_update_shader_quality_settings ( ) ;
2020-04-10 09:30:36 +00:00
}
2022-04-30 23:40:30 +00:00
void RendererSceneRenderRD : : directional_soft_shadow_filter_set_quality ( RS : : ShadowQuality p_quality ) {
2020-04-10 09:30:36 +00:00
ERR_FAIL_INDEX_MSG ( p_quality , RS : : SHADOW_QUALITY_MAX , " Shadow quality too high, please see RenderingServer's ShadowQuality enum " ) ;
if ( directional_shadow_quality ! = p_quality ) {
directional_shadow_quality = p_quality ;
switch ( directional_shadow_quality ) {
case RS : : SHADOW_QUALITY_HARD : {
directional_penumbra_shadow_samples = 4 ;
2021-10-19 14:52:57 +00:00
directional_soft_shadow_samples = 0 ;
2020-04-10 09:30:36 +00:00
directional_shadow_quality_radius = 1.0 ;
} break ;
2021-10-19 14:52:57 +00:00
case RS : : SHADOW_QUALITY_SOFT_VERY_LOW : {
directional_penumbra_shadow_samples = 4 ;
directional_soft_shadow_samples = 1 ;
directional_shadow_quality_radius = 1.5 ;
} break ;
2020-04-10 09:30:36 +00:00
case RS : : SHADOW_QUALITY_SOFT_LOW : {
directional_penumbra_shadow_samples = 8 ;
directional_soft_shadow_samples = 4 ;
directional_shadow_quality_radius = 2.0 ;
} break ;
case RS : : SHADOW_QUALITY_SOFT_MEDIUM : {
directional_penumbra_shadow_samples = 12 ;
directional_soft_shadow_samples = 8 ;
directional_shadow_quality_radius = 2.0 ;
} break ;
case RS : : SHADOW_QUALITY_SOFT_HIGH : {
directional_penumbra_shadow_samples = 24 ;
directional_soft_shadow_samples = 16 ;
directional_shadow_quality_radius = 3.0 ;
} break ;
case RS : : SHADOW_QUALITY_SOFT_ULTRA : {
directional_penumbra_shadow_samples = 32 ;
directional_soft_shadow_samples = 32 ;
directional_shadow_quality_radius = 4.0 ;
} break ;
case RS : : SHADOW_QUALITY_MAX :
break ;
}
get_vogel_disk ( directional_penumbra_shadow_kernel , directional_penumbra_shadow_samples ) ;
get_vogel_disk ( directional_soft_shadow_kernel , directional_soft_shadow_samples ) ;
}
2021-07-19 19:41:55 +00:00
_update_shader_quality_settings ( ) ;
}
void RendererSceneRenderRD : : decals_set_filter ( RenderingServer : : DecalFilter p_filter ) {
if ( decals_filter = = p_filter ) {
return ;
}
decals_filter = p_filter ;
_update_shader_quality_settings ( ) ;
}
void RendererSceneRenderRD : : light_projectors_set_filter ( RenderingServer : : LightProjectorFilter p_filter ) {
if ( light_projectors_filter = = p_filter ) {
return ;
}
light_projectors_filter = p_filter ;
_update_shader_quality_settings ( ) ;
2020-04-08 01:51:52 +00:00
}
2020-12-04 18:26:24 +00:00
int RendererSceneRenderRD : : get_roughness_layers ( ) const {
2021-02-13 12:08:08 +00:00
return sky . roughness_layers ;
2019-08-26 20:43:58 +00:00
}
2020-12-04 18:26:24 +00:00
bool RendererSceneRenderRD : : is_using_radiance_cubemap_array ( ) const {
2021-02-13 12:08:08 +00:00
return sky . sky_use_cubemap_array ;
2019-08-26 20:43:58 +00:00
}
2022-07-31 23:20:24 +00:00
void RendererSceneRenderRD : : _setup_reflections ( RenderDataRD * p_render_data , const PagedArray < RID > & p_reflections , const Transform3D & p_camera_inverse_transform , RID p_environment ) {
2022-04-09 09:34:31 +00:00
RendererRD : : LightStorage * light_storage = RendererRD : : LightStorage : : get_singleton ( ) ;
2021-01-17 16:25:38 +00:00
cluster . reflection_count = 0 ;
2020-12-23 16:52:58 +00:00
for ( uint32_t i = 0 ; i < ( uint32_t ) p_reflections . size ( ) ; i + + ) {
2021-01-17 16:25:38 +00:00
if ( cluster . reflection_count = = cluster . max_reflections ) {
break ;
}
2020-07-22 23:39:09 +00:00
2021-09-29 17:08:41 +00:00
ReflectionProbeInstance * rpi = reflection_probe_instance_owner . get_or_null ( p_reflections [ i ] ) ;
2021-01-17 16:25:38 +00:00
if ( ! rpi ) {
2020-07-22 23:39:09 +00:00
continue ;
}
2021-01-17 16:25:38 +00:00
cluster . reflection_sort [ cluster . reflection_count ] . instance = rpi ;
cluster . reflection_sort [ cluster . reflection_count ] . depth = - p_camera_inverse_transform . xform ( rpi - > transform . origin ) . z ;
cluster . reflection_count + + ;
}
if ( cluster . reflection_count > 0 ) {
SortArray < Cluster : : InstanceSort < ReflectionProbeInstance > > sort_array ;
sort_array . sort ( cluster . reflection_sort , cluster . reflection_count ) ;
}
2021-07-15 20:06:33 +00:00
bool using_forward_ids = _uses_forward_ids ( ) ;
2021-01-17 16:25:38 +00:00
for ( uint32_t i = 0 ; i < cluster . reflection_count ; i + + ) {
ReflectionProbeInstance * rpi = cluster . reflection_sort [ i ] . instance ;
2021-07-15 20:06:33 +00:00
if ( using_forward_ids ) {
_map_forward_id ( FORWARD_ID_TYPE_REFLECTION_PROBE , rpi - > forward_id , i ) ;
}
2020-07-22 23:39:09 +00:00
2021-01-17 16:25:38 +00:00
RID base_probe = rpi - > probe ;
2020-07-22 23:39:09 +00:00
Cluster : : ReflectionData & reflection_ubo = cluster . reflections [ i ] ;
2022-04-09 09:34:31 +00:00
Vector3 extents = light_storage - > reflection_probe_get_extents ( base_probe ) ;
2020-07-22 23:39:09 +00:00
2022-04-09 09:34:31 +00:00
rpi - > cull_mask = light_storage - > reflection_probe_get_cull_mask ( base_probe ) ;
2021-03-10 11:23:55 +00:00
2020-07-22 23:39:09 +00:00
reflection_ubo . box_extents [ 0 ] = extents . x ;
reflection_ubo . box_extents [ 1 ] = extents . y ;
reflection_ubo . box_extents [ 2 ] = extents . z ;
2021-01-17 16:25:38 +00:00
reflection_ubo . index = rpi - > atlas_index ;
2020-07-22 23:39:09 +00:00
2022-04-09 09:34:31 +00:00
Vector3 origin_offset = light_storage - > reflection_probe_get_origin_offset ( base_probe ) ;
2020-07-22 23:39:09 +00:00
reflection_ubo . box_offset [ 0 ] = origin_offset . x ;
reflection_ubo . box_offset [ 1 ] = origin_offset . y ;
reflection_ubo . box_offset [ 2 ] = origin_offset . z ;
2022-04-09 09:34:31 +00:00
reflection_ubo . mask = light_storage - > reflection_probe_get_cull_mask ( base_probe ) ;
2020-07-22 23:39:09 +00:00
2022-04-09 09:34:31 +00:00
reflection_ubo . intensity = light_storage - > reflection_probe_get_intensity ( base_probe ) ;
reflection_ubo . ambient_mode = light_storage - > reflection_probe_get_ambient_mode ( base_probe ) ;
2020-07-22 23:39:09 +00:00
2022-04-09 09:34:31 +00:00
reflection_ubo . exterior = ! light_storage - > reflection_probe_is_interior ( base_probe ) ;
reflection_ubo . box_project = light_storage - > reflection_probe_is_box_projection ( base_probe ) ;
2022-07-31 23:20:24 +00:00
reflection_ubo . exposure_normalization = 1.0 ;
if ( p_render_data - > camera_attributes . is_valid ( ) ) {
float exposure = RSG : : camera_attributes - > camera_attributes_get_exposure_normalization_factor ( p_render_data - > camera_attributes ) ;
reflection_ubo . exposure_normalization = exposure / light_storage - > reflection_probe_get_baked_exposure ( base_probe ) ;
}
2020-07-22 23:39:09 +00:00
2022-04-09 09:34:31 +00:00
Color ambient_linear = light_storage - > reflection_probe_get_ambient_color ( base_probe ) . srgb_to_linear ( ) ;
float interior_ambient_energy = light_storage - > reflection_probe_get_ambient_color_energy ( base_probe ) ;
2020-07-22 23:39:09 +00:00
reflection_ubo . ambient [ 0 ] = ambient_linear . r * interior_ambient_energy ;
reflection_ubo . ambient [ 1 ] = ambient_linear . g * interior_ambient_energy ;
reflection_ubo . ambient [ 2 ] = ambient_linear . b * interior_ambient_energy ;
2020-10-17 05:08:21 +00:00
Transform3D transform = rpi - > transform ;
Transform3D proj = ( p_camera_inverse_transform * transform ) . inverse ( ) ;
2022-06-21 00:08:33 +00:00
RendererRD : : MaterialStorage : : store_transform ( proj , reflection_ubo . local_matrix ) ;
2020-07-22 23:39:09 +00:00
2021-03-10 11:23:55 +00:00
if ( current_cluster_builder ! = nullptr ) {
current_cluster_builder - > add_box ( ClusterBuilderRD : : BOX_TYPE_REFLECTION_PROBE , transform , extents ) ;
}
2020-07-22 23:39:09 +00:00
2021-01-17 16:25:38 +00:00
rpi - > last_pass = RSG : : rasterizer - > get_frame_number ( ) ;
2020-07-22 23:39:09 +00:00
}
2021-01-17 16:25:38 +00:00
if ( cluster . reflection_count ) {
2021-04-20 13:59:46 +00:00
RD : : get_singleton ( ) - > buffer_update ( cluster . reflection_buffer , 0 , cluster . reflection_count * sizeof ( Cluster : : ReflectionData ) , cluster . reflections , RD : : BARRIER_MASK_RASTER | RD : : BARRIER_MASK_COMPUTE ) ;
2020-07-22 23:39:09 +00:00
}
}
2022-07-31 23:20:24 +00:00
void RendererSceneRenderRD : : _setup_lights ( RenderDataRD * p_render_data , const PagedArray < RID > & p_lights , const Transform3D & p_camera_transform , RID p_shadow_atlas , bool p_using_shadows , uint32_t & r_directional_light_count , uint32_t & r_positional_light_count , bool & r_directional_light_soft_shadows ) {
2022-04-07 14:00:51 +00:00
RendererRD : : TextureStorage * texture_storage = RendererRD : : TextureStorage : : get_singleton ( ) ;
2022-04-09 09:34:31 +00:00
RendererRD : : LightStorage * light_storage = RendererRD : : LightStorage : : get_singleton ( ) ;
2022-03-20 11:28:24 +00:00
2020-10-17 05:08:21 +00:00
Transform3D inverse_transform = p_camera_transform . affine_inverse ( ) ;
2021-01-17 16:25:38 +00:00
2020-07-22 23:39:09 +00:00
r_directional_light_count = 0 ;
2020-08-13 01:21:01 +00:00
r_positional_light_count = 0 ;
2020-07-22 23:39:09 +00:00
2022-05-03 12:50:35 +00:00
Plane camera_plane ( - p_camera_transform . basis . get_column ( Vector3 : : AXIS_Z ) . normalized ( ) , p_camera_transform . origin ) ;
2021-01-17 16:25:38 +00:00
cluster . omni_light_count = 0 ;
cluster . spot_light_count = 0 ;
2021-07-12 23:32:05 +00:00
r_directional_light_soft_shadows = false ;
2020-12-23 16:52:58 +00:00
for ( int i = 0 ; i < ( int ) p_lights . size ( ) ; i + + ) {
2021-09-29 17:08:41 +00:00
LightInstance * li = light_instance_owner . get_or_null ( p_lights [ i ] ) ;
2021-01-17 16:25:38 +00:00
if ( ! li ) {
continue ;
}
RID base = li - > light ;
2020-07-22 23:39:09 +00:00
ERR_CONTINUE ( base . is_null ( ) ) ;
2022-04-09 09:34:31 +00:00
RS : : LightType type = light_storage - > light_get_type ( base ) ;
2020-07-22 23:39:09 +00:00
switch ( type ) {
case RS : : LIGHT_DIRECTIONAL : {
2022-04-09 09:34:31 +00:00
if ( r_directional_light_count > = cluster . max_directional_lights | | light_storage - > light_directional_get_sky_mode ( base ) = = RS : : LIGHT_DIRECTIONAL_SKY_MODE_SKY_ONLY ) {
2020-07-22 23:39:09 +00:00
continue ;
}
Cluster : : DirectionalLightData & light_data = cluster . directional_lights [ r_directional_light_count ] ;
2020-10-17 05:08:21 +00:00
Transform3D light_transform = li - > transform ;
2020-07-22 23:39:09 +00:00
2021-01-17 16:25:38 +00:00
Vector3 direction = inverse_transform . basis . xform ( light_transform . basis . xform ( Vector3 ( 0 , 0 , 1 ) ) ) . normalized ( ) ;
2020-07-22 23:39:09 +00:00
light_data . direction [ 0 ] = direction . x ;
light_data . direction [ 1 ] = direction . y ;
light_data . direction [ 2 ] = direction . z ;
2022-04-09 09:34:31 +00:00
float sign = light_storage - > light_is_negative ( base ) ? - 1 : 1 ;
2020-07-22 23:39:09 +00:00
2022-07-31 23:20:24 +00:00
light_data . energy = sign * light_storage - > light_get_param ( base , RS : : LIGHT_PARAM_ENERGY ) ;
if ( is_using_physical_light_units ( ) ) {
light_data . energy * = light_storage - > light_get_param ( base , RS : : LIGHT_PARAM_INTENSITY ) ;
} else {
light_data . energy * = Math_PI ;
}
if ( p_render_data - > camera_attributes . is_valid ( ) ) {
light_data . energy * = RSG : : camera_attributes - > camera_attributes_get_exposure_normalization_factor ( p_render_data - > camera_attributes ) ;
}
2020-07-22 23:39:09 +00:00
2022-04-09 09:34:31 +00:00
Color linear_col = light_storage - > light_get_color ( base ) . srgb_to_linear ( ) ;
2020-07-22 23:39:09 +00:00
light_data . color [ 0 ] = linear_col . r ;
light_data . color [ 1 ] = linear_col . g ;
light_data . color [ 2 ] = linear_col . b ;
2022-04-09 09:34:31 +00:00
light_data . specular = light_storage - > light_get_param ( base , RS : : LIGHT_PARAM_SPECULAR ) ;
2021-07-09 08:28:33 +00:00
light_data . volumetric_fog_energy = light_storage - > light_get_param ( base , RS : : LIGHT_PARAM_VOLUMETRIC_FOG_ENERGY ) ;
2022-04-09 09:34:31 +00:00
light_data . mask = light_storage - > light_get_cull_mask ( base ) ;
2020-07-22 23:39:09 +00:00
2022-04-09 09:34:31 +00:00
float size = light_storage - > light_get_param ( base , RS : : LIGHT_PARAM_SIZE ) ;
2020-07-22 23:39:09 +00:00
2022-08-13 15:45:42 +00:00
light_data . size = 1.0 - Math : : cos ( Math : : deg_to_rad ( size ) ) ; //angle to cosine offset
2020-07-22 23:39:09 +00:00
if ( get_debug_draw_mode ( ) = = RS : : VIEWPORT_DEBUG_DRAW_PSSM_SPLITS ) {
2021-06-08 21:20:09 +00:00
WARN_PRINT_ONCE ( " The DirectionalLight3D PSSM splits debug draw mode is not reimplemented yet. " ) ;
2020-07-22 23:39:09 +00:00
}
2022-08-19 23:05:44 +00:00
light_data . shadow_opacity = ( p_using_shadows & & light_storage - > light_has_shadow ( base ) )
? light_storage - > light_get_param ( base , RS : : LIGHT_PARAM_SHADOW_OPACITY )
: 0.0 ;
2020-07-22 23:39:09 +00:00
2022-04-09 09:34:31 +00:00
float angular_diameter = light_storage - > light_get_param ( base , RS : : LIGHT_PARAM_SIZE ) ;
2020-07-22 23:39:09 +00:00
if ( angular_diameter > 0.0 ) {
// I know tan(0) is 0, but let's not risk it with numerical precision.
// technically this will keep expanding until reaching the sun, but all we care
// is expand until we reach the radius of the near plane (there can't be more occluders than that)
2022-08-13 15:45:42 +00:00
angular_diameter = Math : : tan ( Math : : deg_to_rad ( angular_diameter ) ) ;
2021-07-16 01:33:10 +00:00
if ( light_storage - > light_has_shadow ( base ) & & light_storage - > light_get_param ( base , RS : : LIGHT_PARAM_SHADOW_BLUR ) > 0.0 ) {
// Only enable PCSS-like soft shadows if blurring is enabled.
// Otherwise, performance would decrease with no visual difference.
2022-01-23 23:06:49 +00:00
r_directional_light_soft_shadows = true ;
}
2020-07-22 23:39:09 +00:00
} else {
angular_diameter = 0.0 ;
}
2022-06-10 10:47:06 +00:00
if ( light_data . shadow_opacity > 0.001 ) {
2022-04-09 09:34:31 +00:00
RS : : LightDirectionalShadowMode smode = light_storage - > light_directional_get_shadow_mode ( base ) ;
2020-07-22 23:39:09 +00:00
int limit = smode = = RS : : LIGHT_DIRECTIONAL_SHADOW_ORTHOGONAL ? 0 : ( smode = = RS : : LIGHT_DIRECTIONAL_SHADOW_PARALLEL_2_SPLITS ? 1 : 3 ) ;
2022-04-09 09:34:31 +00:00
light_data . blend_splits = ( smode ! = RS : : LIGHT_DIRECTIONAL_SHADOW_ORTHOGONAL ) & & light_storage - > light_directional_get_blend_splits ( base ) ;
2020-07-22 23:39:09 +00:00
for ( int j = 0 ; j < 4 ; j + + ) {
2021-01-17 16:25:38 +00:00
Rect2 atlas_rect = li - > shadow_transform [ j ] . atlas_rect ;
Implement Vector4, Vector4i, Projection
Implement built-in classes Vector4, Vector4i and Projection.
* Two versions of Vector4 (float and integer).
* A Projection class, which is a 4x4 matrix specialized in projection types.
These types have been requested for a long time, but given they were very corner case they were not added before.
Because in Godot 4, reimplementing parts of the rendering engine is now possible, access to these types (heavily used by the rendering code) becomes a necessity.
**Q**: Why Projection and not Matrix4?
**A**: Godot does not use Matrix2, Matrix3, Matrix4x3, etc. naming convention because, within the engine, these types always have a *purpose*. As such, Godot names them: Transform2D, Transform3D or Basis. In this case, this 4x4 matrix is _always_ used as a _Projection_, hence the naming.
2022-07-19 23:11:13 +00:00
Projection matrix = li - > shadow_transform [ j ] . camera ;
2021-01-17 16:25:38 +00:00
float split = li - > shadow_transform [ MIN ( limit , j ) ] . split ;
2020-07-22 23:39:09 +00:00
Implement Vector4, Vector4i, Projection
Implement built-in classes Vector4, Vector4i and Projection.
* Two versions of Vector4 (float and integer).
* A Projection class, which is a 4x4 matrix specialized in projection types.
These types have been requested for a long time, but given they were very corner case they were not added before.
Because in Godot 4, reimplementing parts of the rendering engine is now possible, access to these types (heavily used by the rendering code) becomes a necessity.
**Q**: Why Projection and not Matrix4?
**A**: Godot does not use Matrix2, Matrix3, Matrix4x3, etc. naming convention because, within the engine, these types always have a *purpose*. As such, Godot names them: Transform2D, Transform3D or Basis. In this case, this 4x4 matrix is _always_ used as a _Projection_, hence the naming.
2022-07-19 23:11:13 +00:00
Projection bias ;
2020-07-22 23:39:09 +00:00
bias . set_light_bias ( ) ;
Implement Vector4, Vector4i, Projection
Implement built-in classes Vector4, Vector4i and Projection.
* Two versions of Vector4 (float and integer).
* A Projection class, which is a 4x4 matrix specialized in projection types.
These types have been requested for a long time, but given they were very corner case they were not added before.
Because in Godot 4, reimplementing parts of the rendering engine is now possible, access to these types (heavily used by the rendering code) becomes a necessity.
**Q**: Why Projection and not Matrix4?
**A**: Godot does not use Matrix2, Matrix3, Matrix4x3, etc. naming convention because, within the engine, these types always have a *purpose*. As such, Godot names them: Transform2D, Transform3D or Basis. In this case, this 4x4 matrix is _always_ used as a _Projection_, hence the naming.
2022-07-19 23:11:13 +00:00
Projection rectm ;
2020-07-22 23:39:09 +00:00
rectm . set_light_atlas_rect ( atlas_rect ) ;
2020-10-17 05:08:21 +00:00
Transform3D modelview = ( inverse_transform * li - > shadow_transform [ j ] . transform ) . inverse ( ) ;
2020-07-22 23:39:09 +00:00
Implement Vector4, Vector4i, Projection
Implement built-in classes Vector4, Vector4i and Projection.
* Two versions of Vector4 (float and integer).
* A Projection class, which is a 4x4 matrix specialized in projection types.
These types have been requested for a long time, but given they were very corner case they were not added before.
Because in Godot 4, reimplementing parts of the rendering engine is now possible, access to these types (heavily used by the rendering code) becomes a necessity.
**Q**: Why Projection and not Matrix4?
**A**: Godot does not use Matrix2, Matrix3, Matrix4x3, etc. naming convention because, within the engine, these types always have a *purpose*. As such, Godot names them: Transform2D, Transform3D or Basis. In this case, this 4x4 matrix is _always_ used as a _Projection_, hence the naming.
2022-07-19 23:11:13 +00:00
Projection shadow_mtx = rectm * bias * matrix * modelview ;
2020-07-22 23:39:09 +00:00
light_data . shadow_split_offsets [ j ] = split ;
2021-01-17 16:25:38 +00:00
float bias_scale = li - > shadow_transform [ j ] . bias_scale ;
2022-04-09 09:34:31 +00:00
light_data . shadow_bias [ j ] = light_storage - > light_get_param ( base , RS : : LIGHT_PARAM_SHADOW_BIAS ) / 100.0 * bias_scale ;
light_data . shadow_normal_bias [ j ] = light_storage - > light_get_param ( base , RS : : LIGHT_PARAM_SHADOW_NORMAL_BIAS ) * li - > shadow_transform [ j ] . shadow_texel_size ;
light_data . shadow_transmittance_bias [ j ] = light_storage - > light_get_transmittance_bias ( base ) * bias_scale ;
2021-01-17 16:25:38 +00:00
light_data . shadow_z_range [ j ] = li - > shadow_transform [ j ] . farplane ;
light_data . shadow_range_begin [ j ] = li - > shadow_transform [ j ] . range_begin ;
2022-06-21 00:08:33 +00:00
RendererRD : : MaterialStorage : : store_camera ( shadow_mtx , light_data . shadow_matrices [ j ] ) ;
2020-07-22 23:39:09 +00:00
2021-01-17 16:25:38 +00:00
Vector2 uv_scale = li - > shadow_transform [ j ] . uv_scale ;
2020-07-22 23:39:09 +00:00
uv_scale * = atlas_rect . size ; //adapt to atlas size
switch ( j ) {
case 0 : {
light_data . uv_scale1 [ 0 ] = uv_scale . x ;
light_data . uv_scale1 [ 1 ] = uv_scale . y ;
} break ;
case 1 : {
light_data . uv_scale2 [ 0 ] = uv_scale . x ;
light_data . uv_scale2 [ 1 ] = uv_scale . y ;
} break ;
case 2 : {
light_data . uv_scale3 [ 0 ] = uv_scale . x ;
light_data . uv_scale3 [ 1 ] = uv_scale . y ;
} break ;
case 3 : {
light_data . uv_scale4 [ 0 ] = uv_scale . x ;
light_data . uv_scale4 [ 1 ] = uv_scale . y ;
} break ;
}
}
2022-04-09 09:34:31 +00:00
float fade_start = light_storage - > light_get_param ( base , RS : : LIGHT_PARAM_SHADOW_FADE_START ) ;
2020-07-22 23:39:09 +00:00
light_data . fade_from = - light_data . shadow_split_offsets [ 3 ] * MIN ( fade_start , 0.999 ) ; //using 1.0 would break smoothstep
light_data . fade_to = - light_data . shadow_split_offsets [ 3 ] ;
2022-04-09 09:34:31 +00:00
light_data . soft_shadow_scale = light_storage - > light_get_param ( base , RS : : LIGHT_PARAM_SHADOW_BLUR ) ;
2020-07-22 23:39:09 +00:00
light_data . softshadow_angle = angular_diameter ;
2022-04-09 09:34:31 +00:00
light_data . bake_mode = light_storage - > light_get_bake_mode ( base ) ;
2020-07-22 23:39:09 +00:00
if ( angular_diameter < = 0.0 ) {
light_data . soft_shadow_scale * = directional_shadow_quality_radius_get ( ) ; // Only use quality radius for PCF
}
}
r_directional_light_count + + ;
} break ;
case RS : : LIGHT_OMNI : {
2021-01-17 16:25:38 +00:00
if ( cluster . omni_light_count > = cluster . max_lights ) {
2020-07-22 23:39:09 +00:00
continue ;
}
2022-02-24 21:55:14 +00:00
const real_t distance = camera_plane . distance_to ( li - > transform . origin ) ;
2022-04-09 09:34:31 +00:00
if ( light_storage - > light_is_distance_fade_enabled ( li - > light ) ) {
const float fade_begin = light_storage - > light_get_distance_fade_begin ( li - > light ) ;
const float fade_length = light_storage - > light_get_distance_fade_length ( li - > light ) ;
2022-02-24 21:55:14 +00:00
if ( distance > fade_begin ) {
if ( distance > fade_begin + fade_length ) {
// Out of range, don't draw this light to improve performance.
continue ;
}
}
}
2021-01-17 16:25:38 +00:00
cluster . omni_light_sort [ cluster . omni_light_count ] . instance = li ;
2022-02-24 21:55:14 +00:00
cluster . omni_light_sort [ cluster . omni_light_count ] . depth = distance ;
2021-01-17 16:25:38 +00:00
cluster . omni_light_count + + ;
} break ;
case RS : : LIGHT_SPOT : {
if ( cluster . spot_light_count > = cluster . max_lights ) {
continue ;
}
2020-07-22 23:39:09 +00:00
2022-02-24 21:55:14 +00:00
const real_t distance = camera_plane . distance_to ( li - > transform . origin ) ;
2022-04-09 09:34:31 +00:00
if ( light_storage - > light_is_distance_fade_enabled ( li - > light ) ) {
const float fade_begin = light_storage - > light_get_distance_fade_begin ( li - > light ) ;
const float fade_length = light_storage - > light_get_distance_fade_length ( li - > light ) ;
2022-02-24 21:55:14 +00:00
if ( distance > fade_begin ) {
if ( distance > fade_begin + fade_length ) {
// Out of range, don't draw this light to improve performance.
continue ;
}
}
}
2021-01-17 16:25:38 +00:00
cluster . spot_light_sort [ cluster . spot_light_count ] . instance = li ;
2022-02-24 21:55:14 +00:00
cluster . spot_light_sort [ cluster . spot_light_count ] . depth = distance ;
2021-01-17 16:25:38 +00:00
cluster . spot_light_count + + ;
} break ;
}
2020-07-22 23:39:09 +00:00
2021-01-17 16:25:38 +00:00
li - > last_pass = RSG : : rasterizer - > get_frame_number ( ) ;
}
2020-07-22 23:39:09 +00:00
2021-01-17 16:25:38 +00:00
if ( cluster . omni_light_count ) {
SortArray < Cluster : : InstanceSort < LightInstance > > sorter ;
sorter . sort ( cluster . omni_light_sort , cluster . omni_light_count ) ;
}
2020-07-22 23:39:09 +00:00
2021-01-17 16:25:38 +00:00
if ( cluster . spot_light_count ) {
SortArray < Cluster : : InstanceSort < LightInstance > > sorter ;
sorter . sort ( cluster . spot_light_sort , cluster . spot_light_count ) ;
}
2021-01-08 16:03:09 +00:00
2021-01-17 16:25:38 +00:00
ShadowAtlas * shadow_atlas = nullptr ;
2020-07-22 23:39:09 +00:00
2021-01-17 16:25:38 +00:00
if ( p_shadow_atlas . is_valid ( ) & & p_using_shadows ) {
2021-09-29 17:08:41 +00:00
shadow_atlas = shadow_atlas_owner . get_or_null ( p_shadow_atlas ) ;
2021-01-17 16:25:38 +00:00
}
2020-07-22 23:39:09 +00:00
2021-07-15 20:06:33 +00:00
bool using_forward_ids = _uses_forward_ids ( ) ;
2021-01-17 16:25:38 +00:00
for ( uint32_t i = 0 ; i < ( cluster . omni_light_count + cluster . spot_light_count ) ; i + + ) {
uint32_t index = ( i < cluster . omni_light_count ) ? i : i - ( cluster . omni_light_count ) ;
Cluster : : LightData & light_data = ( i < cluster . omni_light_count ) ? cluster . omni_lights [ index ] : cluster . spot_lights [ index ] ;
RS : : LightType type = ( i < cluster . omni_light_count ) ? RS : : LIGHT_OMNI : RS : : LIGHT_SPOT ;
LightInstance * li = ( i < cluster . omni_light_count ) ? cluster . omni_light_sort [ index ] . instance : cluster . spot_light_sort [ index ] . instance ;
RID base = li - > light ;
2020-07-22 23:39:09 +00:00
2021-07-15 20:06:33 +00:00
if ( using_forward_ids ) {
_map_forward_id ( type = = RS : : LIGHT_OMNI ? FORWARD_ID_TYPE_OMNI_LIGHT : FORWARD_ID_TYPE_SPOT_LIGHT , li - > forward_id , index ) ;
}
2020-10-17 05:08:21 +00:00
Transform3D light_transform = li - > transform ;
2020-07-22 23:39:09 +00:00
2022-04-09 09:34:31 +00:00
float sign = light_storage - > light_is_negative ( base ) ? - 1 : 1 ;
Color linear_col = light_storage - > light_get_color ( base ) . srgb_to_linear ( ) ;
2020-07-22 23:39:09 +00:00
2022-04-09 09:34:31 +00:00
light_data . attenuation = light_storage - > light_get_param ( base , RS : : LIGHT_PARAM_ATTENUATION ) ;
2020-07-22 23:39:09 +00:00
2022-02-24 21:55:14 +00:00
// Reuse fade begin, fade length and distance for shadow LOD determination later.
float fade_begin = 0.0 ;
2022-06-10 10:47:06 +00:00
float fade_shadow = 0.0 ;
2022-02-24 21:55:14 +00:00
float fade_length = 0.0 ;
real_t distance = 0.0 ;
float fade = 1.0 ;
2022-06-10 10:47:06 +00:00
float shadow_opacity_fade = 1.0 ;
2022-04-09 09:34:31 +00:00
if ( light_storage - > light_is_distance_fade_enabled ( li - > light ) ) {
fade_begin = light_storage - > light_get_distance_fade_begin ( li - > light ) ;
2022-06-10 10:47:06 +00:00
fade_shadow = light_storage - > light_get_distance_fade_shadow ( li - > light ) ;
2022-04-09 09:34:31 +00:00
fade_length = light_storage - > light_get_distance_fade_length ( li - > light ) ;
2022-02-24 21:55:14 +00:00
distance = camera_plane . distance_to ( li - > transform . origin ) ;
2022-06-10 10:47:06 +00:00
// Use `smoothstep()` to make opacity changes more gradual and less noticeable to the player.
2022-02-24 21:55:14 +00:00
if ( distance > fade_begin ) {
fade = Math : : smoothstep ( 0.0f , 1.0f , 1.0f - float ( distance - fade_begin ) / fade_length ) ;
}
2022-06-10 10:47:06 +00:00
if ( distance > fade_shadow ) {
shadow_opacity_fade = Math : : smoothstep ( 0.0f , 1.0f , 1.0f - float ( distance - fade_shadow ) / fade_length ) ;
}
2022-02-24 21:55:14 +00:00
}
2022-07-31 23:20:24 +00:00
float energy = sign * light_storage - > light_get_param ( base , RS : : LIGHT_PARAM_ENERGY ) * fade ;
if ( is_using_physical_light_units ( ) ) {
energy * = light_storage - > light_get_param ( base , RS : : LIGHT_PARAM_INTENSITY ) ;
// Convert from Luminous Power to Luminous Intensity
if ( type = = RS : : LIGHT_OMNI ) {
energy * = 1.0 / ( Math_PI * 4.0 ) ;
} else {
// Spot Lights are not physically accurate, Luminous Intensity should change in relation to the cone angle.
// We make this assumption to keep them easy to control.
energy * = 1.0 / Math_PI ;
}
} else {
energy * = Math_PI ;
}
if ( p_render_data - > camera_attributes . is_valid ( ) ) {
energy * = RSG : : camera_attributes - > camera_attributes_get_exposure_normalization_factor ( p_render_data - > camera_attributes ) ;
}
2020-07-22 23:39:09 +00:00
2021-01-17 16:25:38 +00:00
light_data . color [ 0 ] = linear_col . r * energy ;
light_data . color [ 1 ] = linear_col . g * energy ;
light_data . color [ 2 ] = linear_col . b * energy ;
2022-04-09 09:34:31 +00:00
light_data . specular_amount = light_storage - > light_get_param ( base , RS : : LIGHT_PARAM_SPECULAR ) * 2.0 ;
2021-07-09 08:28:33 +00:00
light_data . volumetric_fog_energy = light_storage - > light_get_param ( base , RS : : LIGHT_PARAM_VOLUMETRIC_FOG_ENERGY ) ;
2022-04-09 09:34:31 +00:00
light_data . bake_mode = light_storage - > light_get_bake_mode ( base ) ;
2020-07-22 23:39:09 +00:00
2022-04-09 09:34:31 +00:00
float radius = MAX ( 0.001 , light_storage - > light_get_param ( base , RS : : LIGHT_PARAM_RANGE ) ) ;
2021-01-17 16:25:38 +00:00
light_data . inv_radius = 1.0 / radius ;
2020-07-22 23:39:09 +00:00
2021-01-17 16:25:38 +00:00
Vector3 pos = inverse_transform . xform ( light_transform . origin ) ;
2020-07-22 23:39:09 +00:00
2021-01-17 16:25:38 +00:00
light_data . position [ 0 ] = pos . x ;
light_data . position [ 1 ] = pos . y ;
light_data . position [ 2 ] = pos . z ;
2020-07-22 23:39:09 +00:00
2021-01-17 16:25:38 +00:00
Vector3 direction = inverse_transform . basis . xform ( light_transform . basis . xform ( Vector3 ( 0 , 0 , - 1 ) ) ) . normalized ( ) ;
2020-07-22 23:39:09 +00:00
2021-01-17 16:25:38 +00:00
light_data . direction [ 0 ] = direction . x ;
light_data . direction [ 1 ] = direction . y ;
light_data . direction [ 2 ] = direction . z ;
2020-07-22 23:39:09 +00:00
2022-04-09 09:34:31 +00:00
float size = light_storage - > light_get_param ( base , RS : : LIGHT_PARAM_SIZE ) ;
2020-07-22 23:39:09 +00:00
2021-01-17 16:25:38 +00:00
light_data . size = size ;
2020-07-22 23:39:09 +00:00
2022-04-09 09:34:31 +00:00
light_data . inv_spot_attenuation = 1.0f / light_storage - > light_get_param ( base , RS : : LIGHT_PARAM_SPOT_ATTENUATION ) ;
float spot_angle = light_storage - > light_get_param ( base , RS : : LIGHT_PARAM_SPOT_ANGLE ) ;
2022-08-13 15:45:42 +00:00
light_data . cos_spot_angle = Math : : cos ( Math : : deg_to_rad ( spot_angle ) ) ;
2020-07-22 23:39:09 +00:00
2022-04-09 09:34:31 +00:00
light_data . mask = light_storage - > light_get_cull_mask ( base ) ;
2020-07-22 23:39:09 +00:00
2021-01-17 16:25:38 +00:00
light_data . atlas_rect [ 0 ] = 0 ;
light_data . atlas_rect [ 1 ] = 0 ;
light_data . atlas_rect [ 2 ] = 0 ;
light_data . atlas_rect [ 3 ] = 0 ;
2020-07-22 23:39:09 +00:00
2022-04-09 09:34:31 +00:00
RID projector = light_storage - > light_get_projector ( base ) ;
2020-07-22 23:39:09 +00:00
2021-01-17 16:25:38 +00:00
if ( projector . is_valid ( ) ) {
2022-04-07 14:00:51 +00:00
Rect2 rect = texture_storage - > decal_atlas_get_texture_rect ( projector ) ;
2020-07-22 23:39:09 +00:00
2021-01-17 16:25:38 +00:00
if ( type = = RS : : LIGHT_SPOT ) {
light_data . projector_rect [ 0 ] = rect . position . x ;
light_data . projector_rect [ 1 ] = rect . position . y + rect . size . height ; //flip because shadow is flipped
light_data . projector_rect [ 2 ] = rect . size . width ;
light_data . projector_rect [ 3 ] = - rect . size . height ;
} else {
light_data . projector_rect [ 0 ] = rect . position . x ;
light_data . projector_rect [ 1 ] = rect . position . y ;
light_data . projector_rect [ 2 ] = rect . size . width ;
light_data . projector_rect [ 3 ] = rect . size . height * 0.5 ; //used by dp, so needs to be half
}
} else {
light_data . projector_rect [ 0 ] = 0 ;
light_data . projector_rect [ 1 ] = 0 ;
light_data . projector_rect [ 2 ] = 0 ;
light_data . projector_rect [ 3 ] = 0 ;
}
2020-07-22 23:39:09 +00:00
2022-08-19 23:05:44 +00:00
const bool needs_shadow =
shadow_atlas & &
shadow_atlas - > shadow_owners . has ( li - > self ) & &
p_using_shadows & &
light_storage - > light_has_shadow ( base ) ;
2022-02-24 21:55:14 +00:00
bool in_shadow_range = true ;
2022-04-09 09:34:31 +00:00
if ( needs_shadow & & light_storage - > light_is_distance_fade_enabled ( li - > light ) ) {
2022-06-10 10:47:06 +00:00
if ( distance > light_storage - > light_get_distance_fade_shadow ( li - > light ) + light_storage - > light_get_distance_fade_length ( li - > light ) ) {
2022-02-24 21:55:14 +00:00
// Out of range, don't draw shadows to improve performance.
in_shadow_range = false ;
}
}
if ( needs_shadow & & in_shadow_range ) {
2021-01-17 16:25:38 +00:00
// fill in the shadow information
2020-07-22 23:39:09 +00:00
2022-06-10 10:47:06 +00:00
light_data . shadow_opacity = light_storage - > light_get_param ( base , RS : : LIGHT_PARAM_SHADOW_OPACITY ) * shadow_opacity_fade ;
2020-07-22 23:39:09 +00:00
2021-08-04 15:18:06 +00:00
float shadow_texel_size = light_instance_get_shadow_texel_size ( li - > self , p_shadow_atlas ) ;
2022-04-09 09:34:31 +00:00
light_data . shadow_normal_bias = light_storage - > light_get_param ( base , RS : : LIGHT_PARAM_SHADOW_NORMAL_BIAS ) * shadow_texel_size * 10.0 ;
2020-07-22 23:39:09 +00:00
2021-08-04 15:18:06 +00:00
if ( type = = RS : : LIGHT_SPOT ) {
2022-04-09 09:34:31 +00:00
light_data . shadow_bias = light_storage - > light_get_param ( base , RS : : LIGHT_PARAM_SHADOW_BIAS ) / 100.0 ;
2021-08-04 15:18:06 +00:00
} else { //omni
2022-04-09 09:34:31 +00:00
light_data . shadow_bias = light_storage - > light_get_param ( base , RS : : LIGHT_PARAM_SHADOW_BIAS ) ;
2021-01-17 16:25:38 +00:00
}
2020-07-22 23:39:09 +00:00
2022-04-09 09:34:31 +00:00
light_data . transmittance_bias = light_storage - > light_get_transmittance_bias ( base ) ;
2020-07-22 23:39:09 +00:00
2021-08-04 15:18:06 +00:00
Vector2i omni_offset ;
Rect2 rect = light_instance_get_shadow_atlas_rect ( li - > self , p_shadow_atlas , omni_offset ) ;
2021-01-17 16:25:38 +00:00
light_data . atlas_rect [ 0 ] = rect . position . x ;
light_data . atlas_rect [ 1 ] = rect . position . y ;
light_data . atlas_rect [ 2 ] = rect . size . width ;
light_data . atlas_rect [ 3 ] = rect . size . height ;
2022-04-09 09:34:31 +00:00
light_data . soft_shadow_scale = light_storage - > light_get_param ( base , RS : : LIGHT_PARAM_SHADOW_BLUR ) ;
2021-01-17 16:25:38 +00:00
if ( type = = RS : : LIGHT_OMNI ) {
2020-10-17 05:08:21 +00:00
Transform3D proj = ( inverse_transform * light_transform ) . inverse ( ) ;
2021-01-17 16:25:38 +00:00
2022-06-21 00:08:33 +00:00
RendererRD : : MaterialStorage : : store_transform ( proj , light_data . shadow_matrix ) ;
2021-01-17 16:25:38 +00:00
2021-07-16 01:33:10 +00:00
if ( size > 0.0 & & light_data . soft_shadow_scale > 0.0 ) {
// Only enable PCSS-like soft shadows if blurring is enabled.
// Otherwise, performance would decrease with no visual difference.
2021-01-17 16:25:38 +00:00
light_data . soft_shadow_size = size ;
2020-07-22 23:39:09 +00:00
} else {
2021-01-17 16:25:38 +00:00
light_data . soft_shadow_size = 0.0 ;
light_data . soft_shadow_scale * = shadows_quality_radius_get ( ) ; // Only use quality radius for PCF
2020-07-22 23:39:09 +00:00
}
2021-08-04 15:18:06 +00:00
light_data . direction [ 0 ] = omni_offset . x * float ( rect . size . width ) ;
light_data . direction [ 1 ] = omni_offset . y * float ( rect . size . height ) ;
2021-01-17 16:25:38 +00:00
} else if ( type = = RS : : LIGHT_SPOT ) {
2020-10-17 05:08:21 +00:00
Transform3D modelview = ( inverse_transform * light_transform ) . inverse ( ) ;
Implement Vector4, Vector4i, Projection
Implement built-in classes Vector4, Vector4i and Projection.
* Two versions of Vector4 (float and integer).
* A Projection class, which is a 4x4 matrix specialized in projection types.
These types have been requested for a long time, but given they were very corner case they were not added before.
Because in Godot 4, reimplementing parts of the rendering engine is now possible, access to these types (heavily used by the rendering code) becomes a necessity.
**Q**: Why Projection and not Matrix4?
**A**: Godot does not use Matrix2, Matrix3, Matrix4x3, etc. naming convention because, within the engine, these types always have a *purpose*. As such, Godot names them: Transform2D, Transform3D or Basis. In this case, this 4x4 matrix is _always_ used as a _Projection_, hence the naming.
2022-07-19 23:11:13 +00:00
Projection bias ;
2021-01-17 16:25:38 +00:00
bias . set_light_bias ( ) ;
2020-07-22 23:39:09 +00:00
Implement Vector4, Vector4i, Projection
Implement built-in classes Vector4, Vector4i and Projection.
* Two versions of Vector4 (float and integer).
* A Projection class, which is a 4x4 matrix specialized in projection types.
These types have been requested for a long time, but given they were very corner case they were not added before.
Because in Godot 4, reimplementing parts of the rendering engine is now possible, access to these types (heavily used by the rendering code) becomes a necessity.
**Q**: Why Projection and not Matrix4?
**A**: Godot does not use Matrix2, Matrix3, Matrix4x3, etc. naming convention because, within the engine, these types always have a *purpose*. As such, Godot names them: Transform2D, Transform3D or Basis. In this case, this 4x4 matrix is _always_ used as a _Projection_, hence the naming.
2022-07-19 23:11:13 +00:00
Projection shadow_mtx = bias * li - > shadow_transform [ 0 ] . camera * modelview ;
2022-06-21 00:08:33 +00:00
RendererRD : : MaterialStorage : : store_camera ( shadow_mtx , light_data . shadow_matrix ) ;
2020-07-22 23:39:09 +00:00
2021-07-16 01:33:10 +00:00
if ( size > 0.0 & & light_data . soft_shadow_scale > 0.0 ) {
// Only enable PCSS-like soft shadows if blurring is enabled.
// Otherwise, performance would decrease with no visual difference.
Implement Vector4, Vector4i, Projection
Implement built-in classes Vector4, Vector4i and Projection.
* Two versions of Vector4 (float and integer).
* A Projection class, which is a 4x4 matrix specialized in projection types.
These types have been requested for a long time, but given they were very corner case they were not added before.
Because in Godot 4, reimplementing parts of the rendering engine is now possible, access to these types (heavily used by the rendering code) becomes a necessity.
**Q**: Why Projection and not Matrix4?
**A**: Godot does not use Matrix2, Matrix3, Matrix4x3, etc. naming convention because, within the engine, these types always have a *purpose*. As such, Godot names them: Transform2D, Transform3D or Basis. In this case, this 4x4 matrix is _always_ used as a _Projection_, hence the naming.
2022-07-19 23:11:13 +00:00
Projection cm = li - > shadow_transform [ 0 ] . camera ;
2022-08-13 15:45:42 +00:00
float half_np = cm . get_z_near ( ) * Math : : tan ( Math : : deg_to_rad ( spot_angle ) ) ;
2021-01-17 16:25:38 +00:00
light_data . soft_shadow_size = ( size * 0.5 / radius ) / ( half_np / cm . get_z_near ( ) ) * rect . size . width ;
} else {
light_data . soft_shadow_size = 0.0 ;
light_data . soft_shadow_scale * = shadows_quality_radius_get ( ) ; // Only use quality radius for PCF
}
}
} else {
2022-06-10 10:47:06 +00:00
light_data . shadow_opacity = 0.0 ;
2020-07-22 23:39:09 +00:00
}
2022-04-09 09:34:31 +00:00
li - > cull_mask = light_storage - > light_get_cull_mask ( base ) ;
2021-01-17 16:25:38 +00:00
2021-03-10 11:23:55 +00:00
if ( current_cluster_builder ! = nullptr ) {
current_cluster_builder - > add_light ( type = = RS : : LIGHT_SPOT ? ClusterBuilderRD : : LIGHT_TYPE_SPOT : ClusterBuilderRD : : LIGHT_TYPE_OMNI , light_transform , radius , spot_angle ) ;
}
2020-07-22 23:39:09 +00:00
2021-01-17 16:25:38 +00:00
r_positional_light_count + + ;
2020-07-22 23:39:09 +00:00
}
2021-02-02 19:51:36 +00:00
//update without barriers
2021-01-17 16:25:38 +00:00
if ( cluster . omni_light_count ) {
2021-02-05 03:02:06 +00:00
RD : : get_singleton ( ) - > buffer_update ( cluster . omni_light_buffer , 0 , sizeof ( Cluster : : LightData ) * cluster . omni_light_count , cluster . omni_lights , RD : : BARRIER_MASK_RASTER | RD : : BARRIER_MASK_COMPUTE ) ;
2021-01-17 16:25:38 +00:00
}
if ( cluster . spot_light_count ) {
2021-02-05 03:02:06 +00:00
RD : : get_singleton ( ) - > buffer_update ( cluster . spot_light_buffer , 0 , sizeof ( Cluster : : LightData ) * cluster . spot_light_count , cluster . spot_lights , RD : : BARRIER_MASK_RASTER | RD : : BARRIER_MASK_COMPUTE ) ;
2020-07-22 23:39:09 +00:00
}
if ( r_directional_light_count ) {
2021-02-05 03:02:06 +00:00
RD : : get_singleton ( ) - > buffer_update ( cluster . directional_light_buffer , 0 , sizeof ( Cluster : : DirectionalLightData ) * r_directional_light_count , cluster . directional_lights , RD : : BARRIER_MASK_RASTER | RD : : BARRIER_MASK_COMPUTE ) ;
2020-07-22 23:39:09 +00:00
}
}
2020-10-17 05:08:21 +00:00
void RendererSceneRenderRD : : _setup_decals ( const PagedArray < RID > & p_decals , const Transform3D & p_camera_inverse_xform ) {
2022-04-07 14:00:51 +00:00
RendererRD : : TextureStorage * texture_storage = RendererRD : : TextureStorage : : get_singleton ( ) ;
2022-03-20 11:28:24 +00:00
2020-10-17 05:08:21 +00:00
Transform3D uv_xform ;
2020-07-22 23:39:09 +00:00
uv_xform . basis . scale ( Vector3 ( 2.0 , 1.0 , 2.0 ) ) ;
uv_xform . origin = Vector3 ( - 1.0 , 0.0 , - 1.0 ) ;
2021-01-17 16:25:38 +00:00
uint32_t decal_count = p_decals . size ( ) ;
cluster . decal_count = 0 ;
2020-12-23 16:52:58 +00:00
for ( uint32_t i = 0 ; i < decal_count ; i + + ) {
2021-01-17 16:25:38 +00:00
if ( cluster . decal_count = = cluster . max_decals ) {
break ;
}
2021-09-29 17:08:41 +00:00
DecalInstance * di = decal_instance_owner . get_or_null ( p_decals [ i ] ) ;
2021-01-17 16:25:38 +00:00
if ( ! di ) {
continue ;
}
RID decal = di - > decal ;
2020-07-22 23:39:09 +00:00
2020-10-17 05:08:21 +00:00
Transform3D xform = di - > transform ;
2020-07-22 23:39:09 +00:00
2021-01-17 16:25:38 +00:00
real_t distance = - p_camera_inverse_xform . xform ( xform . origin ) . z ;
2020-07-22 23:39:09 +00:00
2022-04-07 14:00:51 +00:00
if ( texture_storage - > decal_is_distance_fade_enabled ( decal ) ) {
float fade_begin = texture_storage - > decal_get_distance_fade_begin ( decal ) ;
float fade_length = texture_storage - > decal_get_distance_fade_length ( decal ) ;
2020-07-22 23:39:09 +00:00
if ( distance > fade_begin ) {
if ( distance > fade_begin + fade_length ) {
continue ; // do not use this decal, its invisible
}
2021-01-17 16:25:38 +00:00
}
}
2020-07-22 23:39:09 +00:00
2021-01-17 16:25:38 +00:00
cluster . decal_sort [ cluster . decal_count ] . instance = di ;
cluster . decal_sort [ cluster . decal_count ] . depth = distance ;
cluster . decal_count + + ;
}
if ( cluster . decal_count > 0 ) {
SortArray < Cluster : : InstanceSort < DecalInstance > > sort_array ;
sort_array . sort ( cluster . decal_sort , cluster . decal_count ) ;
}
2021-07-15 20:06:33 +00:00
bool using_forward_ids = _uses_forward_ids ( ) ;
2021-01-17 16:25:38 +00:00
for ( uint32_t i = 0 ; i < cluster . decal_count ; i + + ) {
DecalInstance * di = cluster . decal_sort [ i ] . instance ;
RID decal = di - > decal ;
2021-07-15 20:06:33 +00:00
if ( using_forward_ids ) {
_map_forward_id ( FORWARD_ID_TYPE_DECAL , di - > forward_id , i ) ;
}
2022-04-07 14:00:51 +00:00
di - > cull_mask = texture_storage - > decal_get_cull_mask ( decal ) ;
2021-03-10 11:23:55 +00:00
2020-10-17 05:08:21 +00:00
Transform3D xform = di - > transform ;
2021-01-17 16:25:38 +00:00
float fade = 1.0 ;
2022-04-07 14:00:51 +00:00
if ( texture_storage - > decal_is_distance_fade_enabled ( decal ) ) {
2022-02-18 21:36:03 +00:00
const real_t distance = - p_camera_inverse_xform . xform ( xform . origin ) . z ;
const float fade_begin = texture_storage - > decal_get_distance_fade_begin ( decal ) ;
const float fade_length = texture_storage - > decal_get_distance_fade_length ( decal ) ;
2021-01-17 16:25:38 +00:00
if ( distance > fade_begin ) {
2022-02-18 21:36:03 +00:00
// Use `smoothstep()` to make opacity changes more gradual and less noticeable to the player.
fade = Math : : smoothstep ( 0.0f , 1.0f , 1.0f - float ( distance - fade_begin ) / fade_length ) ;
2020-07-22 23:39:09 +00:00
}
}
2021-01-17 16:25:38 +00:00
Cluster : : DecalData & dd = cluster . decals [ i ] ;
2020-07-22 23:39:09 +00:00
2022-04-07 14:00:51 +00:00
Vector3 decal_extents = texture_storage - > decal_get_extents ( decal ) ;
2020-07-22 23:39:09 +00:00
2020-10-17 05:08:21 +00:00
Transform3D scale_xform ;
2021-09-23 14:58:43 +00:00
scale_xform . basis . scale ( decal_extents ) ;
2020-10-17 05:08:21 +00:00
Transform3D to_decal_xform = ( p_camera_inverse_xform * di - > transform * scale_xform * uv_xform ) . affine_inverse ( ) ;
2022-06-21 00:08:33 +00:00
RendererRD : : MaterialStorage : : store_transform ( to_decal_xform , dd . xform ) ;
2020-07-22 23:39:09 +00:00
2022-05-03 12:50:35 +00:00
Vector3 normal = xform . basis . get_column ( Vector3 : : AXIS_Y ) . normalized ( ) ;
2020-07-22 23:39:09 +00:00
normal = p_camera_inverse_xform . basis . xform ( normal ) ; //camera is normalized, so fine
dd . normal [ 0 ] = normal . x ;
dd . normal [ 1 ] = normal . y ;
dd . normal [ 2 ] = normal . z ;
2022-04-07 14:00:51 +00:00
dd . normal_fade = texture_storage - > decal_get_normal_fade ( decal ) ;
2020-07-22 23:39:09 +00:00
2022-04-07 14:00:51 +00:00
RID albedo_tex = texture_storage - > decal_get_texture ( decal , RS : : DECAL_TEXTURE_ALBEDO ) ;
RID emission_tex = texture_storage - > decal_get_texture ( decal , RS : : DECAL_TEXTURE_EMISSION ) ;
2020-07-22 23:39:09 +00:00
if ( albedo_tex . is_valid ( ) ) {
2022-04-07 14:00:51 +00:00
Rect2 rect = texture_storage - > decal_atlas_get_texture_rect ( albedo_tex ) ;
2020-07-22 23:39:09 +00:00
dd . albedo_rect [ 0 ] = rect . position . x ;
dd . albedo_rect [ 1 ] = rect . position . y ;
dd . albedo_rect [ 2 ] = rect . size . x ;
dd . albedo_rect [ 3 ] = rect . size . y ;
} else {
if ( ! emission_tex . is_valid ( ) ) {
continue ; //no albedo, no emission, no decal.
}
dd . albedo_rect [ 0 ] = 0 ;
dd . albedo_rect [ 1 ] = 0 ;
dd . albedo_rect [ 2 ] = 0 ;
dd . albedo_rect [ 3 ] = 0 ;
}
2022-04-07 14:00:51 +00:00
RID normal_tex = texture_storage - > decal_get_texture ( decal , RS : : DECAL_TEXTURE_NORMAL ) ;
2020-07-22 23:39:09 +00:00
if ( normal_tex . is_valid ( ) ) {
2022-04-07 14:00:51 +00:00
Rect2 rect = texture_storage - > decal_atlas_get_texture_rect ( normal_tex ) ;
2020-07-22 23:39:09 +00:00
dd . normal_rect [ 0 ] = rect . position . x ;
dd . normal_rect [ 1 ] = rect . position . y ;
dd . normal_rect [ 2 ] = rect . size . x ;
dd . normal_rect [ 3 ] = rect . size . y ;
Basis normal_xform = p_camera_inverse_xform . basis * xform . basis . orthonormalized ( ) ;
2022-06-21 00:08:33 +00:00
RendererRD : : MaterialStorage : : store_basis_3x4 ( normal_xform , dd . normal_xform ) ;
2020-07-22 23:39:09 +00:00
} else {
dd . normal_rect [ 0 ] = 0 ;
dd . normal_rect [ 1 ] = 0 ;
dd . normal_rect [ 2 ] = 0 ;
dd . normal_rect [ 3 ] = 0 ;
}
2022-04-07 14:00:51 +00:00
RID orm_tex = texture_storage - > decal_get_texture ( decal , RS : : DECAL_TEXTURE_ORM ) ;
2020-07-22 23:39:09 +00:00
if ( orm_tex . is_valid ( ) ) {
2022-04-07 14:00:51 +00:00
Rect2 rect = texture_storage - > decal_atlas_get_texture_rect ( orm_tex ) ;
2020-07-22 23:39:09 +00:00
dd . orm_rect [ 0 ] = rect . position . x ;
dd . orm_rect [ 1 ] = rect . position . y ;
dd . orm_rect [ 2 ] = rect . size . x ;
dd . orm_rect [ 3 ] = rect . size . y ;
} else {
dd . orm_rect [ 0 ] = 0 ;
dd . orm_rect [ 1 ] = 0 ;
dd . orm_rect [ 2 ] = 0 ;
dd . orm_rect [ 3 ] = 0 ;
}
if ( emission_tex . is_valid ( ) ) {
2022-04-07 14:00:51 +00:00
Rect2 rect = texture_storage - > decal_atlas_get_texture_rect ( emission_tex ) ;
2020-07-22 23:39:09 +00:00
dd . emission_rect [ 0 ] = rect . position . x ;
dd . emission_rect [ 1 ] = rect . position . y ;
dd . emission_rect [ 2 ] = rect . size . x ;
dd . emission_rect [ 3 ] = rect . size . y ;
} else {
dd . emission_rect [ 0 ] = 0 ;
dd . emission_rect [ 1 ] = 0 ;
dd . emission_rect [ 2 ] = 0 ;
dd . emission_rect [ 3 ] = 0 ;
}
2022-04-07 14:00:51 +00:00
Color modulate = texture_storage - > decal_get_modulate ( decal ) ;
2020-07-22 23:39:09 +00:00
dd . modulate [ 0 ] = modulate . r ;
dd . modulate [ 1 ] = modulate . g ;
dd . modulate [ 2 ] = modulate . b ;
dd . modulate [ 3 ] = modulate . a * fade ;
2022-04-07 14:00:51 +00:00
dd . emission_energy = texture_storage - > decal_get_emission_energy ( decal ) * fade ;
dd . albedo_mix = texture_storage - > decal_get_albedo_mix ( decal ) ;
dd . mask = texture_storage - > decal_get_cull_mask ( decal ) ;
dd . upper_fade = texture_storage - > decal_get_upper_fade ( decal ) ;
dd . lower_fade = texture_storage - > decal_get_lower_fade ( decal ) ;
2020-07-22 23:39:09 +00:00
2021-03-10 11:23:55 +00:00
if ( current_cluster_builder ! = nullptr ) {
current_cluster_builder - > add_box ( ClusterBuilderRD : : BOX_TYPE_DECAL , xform , decal_extents ) ;
}
2020-07-22 23:39:09 +00:00
}
2021-01-17 16:25:38 +00:00
if ( cluster . decal_count > 0 ) {
2021-02-05 03:02:06 +00:00
RD : : get_singleton ( ) - > buffer_update ( cluster . decal_buffer , 0 , sizeof ( Cluster : : DecalData ) * cluster . decal_count , cluster . decals , RD : : BARRIER_MASK_RASTER | RD : : BARRIER_MASK_COMPUTE ) ;
2020-07-22 23:39:09 +00:00
}
}
2021-10-03 11:28:55 +00:00
////////////////////////////////////////////////////////////////////////////////
// FOG SHADER
2022-08-04 08:40:39 +00:00
void RendererSceneRenderRD : : _update_volumetric_fog ( Ref < RenderSceneBuffersRD > p_render_buffers , RID p_environment , const Projection & p_cam_projection , const Transform3D & p_cam_transform , const Transform3D & p_prev_cam_inv_transform , RID p_shadow_atlas , int p_directional_light_count , bool p_use_directional_shadows , int p_positional_light_count , int p_voxel_gi_count , const PagedArray < RID > & p_fog_volumes ) {
2021-03-23 10:46:31 +00:00
ERR_FAIL_COND ( ! is_clustered_enabled ( ) ) ; // can't use volumetric fog without clustered
2022-08-04 08:40:39 +00:00
ERR_FAIL_COND ( p_render_buffers . is_null ( ) ) ;
// These should be available for our clustered renderer, at some point _update_volumetric_fog should be called by the renderer implemetentation itself
ERR_FAIL_COND ( ! p_render_buffers - > has_custom_data ( RB_SCOPE_GI ) ) ;
Ref < RendererRD : : GI : : RenderBuffersGI > rbgi = p_render_buffers - > get_custom_data ( RB_SCOPE_GI ) ;
Ref < RendererRD : : GI : : SDFGI > sdfgi ;
if ( p_render_buffers - > has_custom_data ( RB_SCOPE_SDFGI ) ) {
sdfgi = p_render_buffers - > get_custom_data ( RB_SCOPE_SDFGI ) ;
}
2020-08-13 01:21:01 +00:00
2022-08-04 08:40:39 +00:00
Size2i size = p_render_buffers - > get_internal_size ( ) ;
float ratio = float ( size . x ) / float ( ( size . x + size . y ) / 2 ) ;
2020-08-13 01:21:01 +00:00
uint32_t target_width = uint32_t ( float ( volumetric_fog_size ) * ratio ) ;
uint32_t target_height = uint32_t ( float ( volumetric_fog_size ) / ratio ) ;
2022-08-04 08:40:39 +00:00
if ( p_render_buffers - > has_custom_data ( RB_SCOPE_FOG ) ) {
Ref < RendererRD : : Fog : : VolumetricFog > fog = p_render_buffers - > get_custom_data ( RB_SCOPE_FOG ) ;
2020-08-13 01:21:01 +00:00
//validate
2022-08-04 08:40:39 +00:00
if ( p_environment . is_null ( ) | | ! environment_get_volumetric_fog_enabled ( p_environment ) | | fog - > width ! = target_width | | fog - > height ! = target_height | | fog - > depth ! = volumetric_fog_depth ) {
p_render_buffers - > set_custom_data ( RB_SCOPE_FOG , Ref < RenderBufferCustomDataRD > ( ) ) ;
2020-08-13 01:21:01 +00:00
}
}
2022-07-27 06:14:23 +00:00
if ( p_environment . is_null ( ) | | ! environment_get_volumetric_fog_enabled ( p_environment ) ) {
2020-08-13 01:21:01 +00:00
//no reason to enable or update, bye
return ;
}
2022-08-04 08:40:39 +00:00
if ( p_environment . is_valid ( ) & & environment_get_volumetric_fog_enabled ( p_environment ) & & ! p_render_buffers - > has_custom_data ( RB_SCOPE_FOG ) ) {
2020-08-13 01:21:01 +00:00
//required volumetric fog but not existing, create
2022-08-04 08:40:39 +00:00
Ref < RendererRD : : Fog : : VolumetricFog > fog ;
fog . instantiate ( ) ;
fog - > init ( Vector3i ( target_width , target_height , volumetric_fog_depth ) , sky . sky_shader . default_shader_rd ) ;
p_render_buffers - > set_custom_data ( RB_SCOPE_FOG , fog ) ;
2021-10-03 11:28:55 +00:00
}
2022-08-04 08:40:39 +00:00
if ( p_render_buffers - > has_custom_data ( RB_SCOPE_FOG ) ) {
Ref < RendererRD : : Fog : : VolumetricFog > fog = p_render_buffers - > get_custom_data ( RB_SCOPE_FOG ) ;
2022-07-19 04:17:58 +00:00
RendererRD : : Fog : : VolumetricFogSettings settings ;
2022-08-04 08:40:39 +00:00
settings . rb_size = size ;
2022-07-19 04:17:58 +00:00
settings . time = time ;
settings . is_using_radiance_cubemap_array = is_using_radiance_cubemap_array ( ) ;
settings . max_cluster_elements = max_cluster_elements ;
settings . volumetric_fog_filter_active = volumetric_fog_filter_active ;
settings . shadow_sampler = shadow_sampler ;
ShadowAtlas * shadow_atlas = shadow_atlas_owner . get_or_null ( p_shadow_atlas ) ;
settings . shadow_atlas_depth = shadow_atlas ? shadow_atlas - > depth : RID ( ) ;
2022-08-04 08:40:39 +00:00
settings . voxel_gi_buffer = rbgi - > get_voxel_gi_buffer ( ) ;
2022-07-19 04:17:58 +00:00
settings . omni_light_buffer = get_omni_light_buffer ( ) ;
settings . spot_light_buffer = get_spot_light_buffer ( ) ;
settings . directional_shadow_depth = directional_shadow . depth ;
settings . directional_light_buffer = get_directional_light_buffer ( ) ;
2020-08-13 01:21:01 +00:00
2022-08-04 08:40:39 +00:00
settings . vfog = fog ;
settings . cluster_builder = p_render_buffers - > cluster_builder ;
settings . rbgi = rbgi ;
settings . sdfgi = sdfgi ;
2022-07-27 06:14:23 +00:00
settings . env = p_environment ;
2022-07-19 04:17:58 +00:00
settings . sky = & sky ;
settings . gi = & gi ;
2020-08-13 01:21:01 +00:00
2022-07-19 04:17:58 +00:00
RendererRD : : Fog : : get_singleton ( ) - > volumetric_fog_update ( settings , p_cam_projection , p_cam_transform , p_prev_cam_inv_transform , p_shadow_atlas , p_directional_light_count , p_use_directional_shadows , p_positional_light_count , p_voxel_gi_count , p_fog_volumes ) ;
2020-08-13 01:21:01 +00:00
}
}
2021-05-05 05:41:12 +00:00
bool RendererSceneRenderRD : : _needs_post_prepass_render ( RenderDataRD * p_render_data , bool p_use_gi ) {
if ( p_render_data - > render_buffers . is_valid ( ) ) {
2022-08-04 08:40:39 +00:00
if ( p_render_data - > render_buffers - > has_custom_data ( RB_SCOPE_SDFGI ) ) {
2021-02-02 19:51:36 +00:00
return true ;
}
2020-01-10 00:40:26 +00:00
}
2021-02-02 19:51:36 +00:00
return false ;
}
2019-08-18 22:40:52 +00:00
2021-05-05 05:41:12 +00:00
void RendererSceneRenderRD : : _post_prepass_render ( RenderDataRD * p_render_data , bool p_use_gi ) {
2022-08-04 08:40:39 +00:00
if ( p_render_data - > render_buffers . is_valid ( ) & & p_use_gi ) {
if ( ! p_render_data - > render_buffers - > has_custom_data ( RB_SCOPE_SDFGI ) ) {
return ;
2020-06-25 13:33:28 +00:00
}
2022-08-04 08:40:39 +00:00
Ref < RendererRD : : GI : : SDFGI > sdfgi = p_render_data - > render_buffers - > get_custom_data ( RB_SCOPE_SDFGI ) ;
sdfgi - > update_probes ( p_render_data - > environment , sky . sky_owner . get_or_null ( environment_get_sky ( p_render_data - > environment ) ) ) ;
2020-06-25 13:33:28 +00:00
}
2021-02-02 19:51:36 +00:00
}
2020-06-25 13:33:28 +00:00
2021-05-05 05:41:12 +00:00
void RendererSceneRenderRD : : _pre_resolve_render ( RenderDataRD * p_render_data , bool p_use_gi ) {
if ( p_render_data - > render_buffers . is_valid ( ) ) {
2021-02-02 19:51:36 +00:00
if ( p_use_gi ) {
RD : : get_singleton ( ) - > compute_list_end ( ) ;
}
}
}
2020-12-23 16:52:58 +00:00
2022-08-04 08:40:39 +00:00
void RendererSceneRenderRD : : _pre_opaque_render ( RenderDataRD * p_render_data , bool p_use_ssao , bool p_use_ssil , bool p_use_gi , const RID * p_normal_roughness_slices , RID p_voxel_gi_buffer ) {
2021-02-02 19:51:36 +00:00
// Render shadows while GI is rendering, due to how barriers are handled, this should happen at the same time
2022-04-09 09:34:31 +00:00
RendererRD : : LightStorage * light_storage = RendererRD : : LightStorage : : get_singleton ( ) ;
2020-12-23 16:52:58 +00:00
2022-08-04 08:40:39 +00:00
if ( p_render_data - > render_buffers . is_valid ( ) & & p_use_gi & & p_render_data - > render_buffers - > has_custom_data ( RB_SCOPE_SDFGI ) ) {
Ref < RendererRD : : GI : : SDFGI > sdfgi = p_render_data - > render_buffers - > get_custom_data ( RB_SCOPE_SDFGI ) ;
sdfgi - > store_probes ( ) ;
2020-07-22 23:39:09 +00:00
}
2021-02-02 19:51:36 +00:00
render_state . cube_shadows . clear ( ) ;
render_state . shadows . clear ( ) ;
render_state . directional_shadows . clear ( ) ;
2022-09-07 11:23:01 +00:00
Plane camera_plane ( - p_render_data - > scene_data - > cam_transform . basis . get_column ( Vector3 : : AXIS_Z ) , p_render_data - > scene_data - > cam_transform . origin ) ;
float lod_distance_multiplier = p_render_data - > scene_data - > cam_projection . get_lod_multiplier ( ) ;
2021-02-02 19:51:36 +00:00
{
for ( int i = 0 ; i < render_state . render_shadow_count ; i + + ) {
2021-09-29 17:08:41 +00:00
LightInstance * li = light_instance_owner . get_or_null ( render_state . render_shadows [ i ] . light ) ;
2021-02-02 19:51:36 +00:00
2022-04-09 09:34:31 +00:00
if ( light_storage - > light_get_type ( li - > light ) = = RS : : LIGHT_DIRECTIONAL ) {
2021-02-02 19:51:36 +00:00
render_state . directional_shadows . push_back ( i ) ;
2022-04-09 09:34:31 +00:00
} else if ( light_storage - > light_get_type ( li - > light ) = = RS : : LIGHT_OMNI & & light_storage - > light_omni_get_shadow_mode ( li - > light ) = = RS : : LIGHT_OMNI_SHADOW_CUBE ) {
2021-02-02 19:51:36 +00:00
render_state . cube_shadows . push_back ( i ) ;
} else {
render_state . shadows . push_back ( i ) ;
}
2021-01-17 16:25:38 +00:00
}
2021-02-02 19:51:36 +00:00
//cube shadows are rendered in their own way
for ( uint32_t i = 0 ; i < render_state . cube_shadows . size ( ) ; i + + ) {
2022-09-07 11:23:01 +00:00
_render_shadow_pass ( render_state . render_shadows [ render_state . cube_shadows [ i ] ] . light , p_render_data - > shadow_atlas , render_state . render_shadows [ render_state . cube_shadows [ i ] ] . pass , render_state . render_shadows [ render_state . cube_shadows [ i ] ] . instances , camera_plane , lod_distance_multiplier , p_render_data - > scene_data - > screen_mesh_lod_threshold , true , true , true , p_render_data - > render_info ) ;
2021-02-02 19:51:36 +00:00
}
if ( render_state . directional_shadows . size ( ) ) {
//open the pass for directional shadows
_update_directional_shadow_atlas ( ) ;
RD : : get_singleton ( ) - > draw_list_begin ( directional_shadow . fb , RD : : INITIAL_ACTION_DROP , RD : : FINAL_ACTION_DISCARD , RD : : INITIAL_ACTION_CLEAR , RD : : FINAL_ACTION_CONTINUE ) ;
RD : : get_singleton ( ) - > draw_list_end ( ) ;
}
}
// Render GI
bool render_shadows = render_state . directional_shadows . size ( ) | | render_state . shadows . size ( ) ;
2021-05-05 05:41:12 +00:00
bool render_gi = p_render_data - > render_buffers . is_valid ( ) & & p_use_gi ;
2021-02-02 19:51:36 +00:00
if ( render_shadows & & render_gi ) {
2022-03-04 07:44:29 +00:00
RENDER_TIMESTAMP ( " Render GI + Render Shadows (Parallel) " ) ;
2021-02-02 19:51:36 +00:00
} else if ( render_shadows ) {
RENDER_TIMESTAMP ( " Render Shadows " ) ;
} else if ( render_gi ) {
RENDER_TIMESTAMP ( " Render GI " ) ;
2021-01-17 16:25:38 +00:00
}
2021-02-02 19:51:36 +00:00
//prepare shadow rendering
if ( render_shadows ) {
_render_shadow_begin ( ) ;
//render directional shadows
for ( uint32_t i = 0 ; i < render_state . directional_shadows . size ( ) ; i + + ) {
2022-09-07 11:23:01 +00:00
_render_shadow_pass ( render_state . render_shadows [ render_state . directional_shadows [ i ] ] . light , p_render_data - > shadow_atlas , render_state . render_shadows [ render_state . directional_shadows [ i ] ] . pass , render_state . render_shadows [ render_state . directional_shadows [ i ] ] . instances , camera_plane , lod_distance_multiplier , p_render_data - > scene_data - > screen_mesh_lod_threshold , false , i = = render_state . directional_shadows . size ( ) - 1 , false , p_render_data - > render_info ) ;
2021-02-02 19:51:36 +00:00
}
//render positional shadows
for ( uint32_t i = 0 ; i < render_state . shadows . size ( ) ; i + + ) {
2022-09-07 11:23:01 +00:00
_render_shadow_pass ( render_state . render_shadows [ render_state . shadows [ i ] ] . light , p_render_data - > shadow_atlas , render_state . render_shadows [ render_state . shadows [ i ] ] . pass , render_state . render_shadows [ render_state . shadows [ i ] ] . instances , camera_plane , lod_distance_multiplier , p_render_data - > scene_data - > screen_mesh_lod_threshold , i = = 0 , i = = render_state . shadows . size ( ) - 1 , true , p_render_data - > render_info ) ;
2021-02-02 19:51:36 +00:00
}
_render_shadow_process ( ) ;
}
//start GI
if ( render_gi ) {
2022-09-07 11:23:01 +00:00
gi . process_gi ( p_render_data - > render_buffers , p_normal_roughness_slices , p_voxel_gi_buffer , p_render_data - > environment , p_render_data - > scene_data - > view_count , p_render_data - > scene_data - > view_projection , p_render_data - > scene_data - > view_eye_offset , p_render_data - > scene_data - > cam_transform , * p_render_data - > voxel_gi_instances ) ;
2021-02-02 19:51:36 +00:00
}
//Do shadow rendering (in parallel with GI)
if ( render_shadows ) {
_render_shadow_end ( RD : : BARRIER_MASK_NO_BARRIER ) ;
}
if ( render_gi ) {
RD : : get_singleton ( ) - > compute_list_end ( RD : : BARRIER_MASK_NO_BARRIER ) ; //use a later barrier
}
2022-06-28 09:10:36 +00:00
if ( p_render_data - > render_buffers . is_valid ( ) & & ss_effects ) {
2021-08-03 07:07:32 +00:00
if ( p_use_ssao | | p_use_ssil ) {
2022-08-04 08:40:39 +00:00
Ref < RenderSceneBuffersRD > rb = p_render_data - > render_buffers ;
ERR_FAIL_COND ( rb . is_null ( ) ) ;
Size2i size = rb - > get_internal_size ( ) ;
2021-08-03 07:07:32 +00:00
bool invalidate_uniform_set = false ;
if ( rb - > ss_effects . linear_depth . is_null ( ) ) {
RD : : TextureFormat tf ;
tf . format = RD : : DATA_FORMAT_R16_SFLOAT ;
tf . texture_type = RD : : TEXTURE_TYPE_2D_ARRAY ;
2022-08-04 08:40:39 +00:00
tf . width = ( size . x + 1 ) / 2 ;
tf . height = ( size . y + 1 ) / 2 ;
2021-08-03 07:07:32 +00:00
tf . mipmaps = 5 ;
tf . array_layers = 4 ;
tf . usage_bits = RD : : TEXTURE_USAGE_SAMPLING_BIT | RD : : TEXTURE_USAGE_STORAGE_BIT ;
rb - > ss_effects . linear_depth = RD : : get_singleton ( ) - > texture_create ( tf , RD : : TextureView ( ) ) ;
RD : : get_singleton ( ) - > set_resource_name ( rb - > ss_effects . linear_depth , " SS Effects Depth " ) ;
for ( uint32_t i = 0 ; i < tf . mipmaps ; i + + ) {
RID slice = RD : : get_singleton ( ) - > texture_create_shared_from_slice ( RD : : TextureView ( ) , rb - > ss_effects . linear_depth , 0 , i , 1 , RD : : TEXTURE_SLICE_2D_ARRAY ) ;
rb - > ss_effects . linear_depth_slices . push_back ( slice ) ;
RD : : get_singleton ( ) - > set_resource_name ( slice , " SS Effects Depth Mip " + itos ( i ) + " " ) ;
}
invalidate_uniform_set = true ;
}
2022-08-04 08:40:39 +00:00
RID depth_texture = rb - > get_depth_texture ( ) ;
2022-09-07 11:23:01 +00:00
ss_effects - > downsample_depth ( depth_texture , rb - > ss_effects . linear_depth_slices , ssao_quality , ssil_quality , invalidate_uniform_set , ssao_half_size , ssil_half_size , size , p_render_data - > scene_data - > cam_projection ) ;
2021-08-03 07:07:32 +00:00
}
2021-02-02 19:51:36 +00:00
if ( p_use_ssao ) {
2022-02-11 11:33:54 +00:00
// TODO make these proper stereo
2022-09-07 11:23:01 +00:00
_process_ssao ( p_render_data - > render_buffers , p_render_data - > environment , p_normal_roughness_slices [ 0 ] , p_render_data - > scene_data - > cam_projection ) ;
2021-02-02 19:51:36 +00:00
}
2021-08-03 07:07:32 +00:00
if ( p_use_ssil ) {
2022-02-11 11:33:54 +00:00
// TODO make these proper stereo
2022-09-07 11:23:01 +00:00
_process_ssil ( p_render_data - > render_buffers , p_render_data - > environment , p_normal_roughness_slices [ 0 ] , p_render_data - > scene_data - > cam_projection , p_render_data - > scene_data - > cam_transform ) ;
2021-08-03 07:07:32 +00:00
}
2021-02-02 19:51:36 +00:00
}
2021-02-05 03:02:06 +00:00
//full barrier here, we need raster, transfer and compute and it depends from the previous work
RD : : get_singleton ( ) - > barrier ( RD : : BARRIER_MASK_ALL , RD : : BARRIER_MASK_ALL ) ;
2021-02-02 19:51:36 +00:00
if ( current_cluster_builder ) {
2022-09-07 11:23:01 +00:00
current_cluster_builder - > begin ( p_render_data - > scene_data - > cam_transform , p_render_data - > scene_data - > cam_projection , ! p_render_data - > reflection_probe . is_valid ( ) ) ;
2021-02-02 19:51:36 +00:00
}
2020-07-22 23:39:09 +00:00
bool using_shadows = true ;
2021-05-05 05:41:12 +00:00
if ( p_render_data - > reflection_probe . is_valid ( ) ) {
2022-04-09 09:34:31 +00:00
if ( ! RSG : : light_storage - > reflection_probe_renders_shadows ( reflection_probe_instance_get_probe ( p_render_data - > reflection_probe ) ) ) {
2020-07-22 23:39:09 +00:00
using_shadows = false ;
}
} else {
//do not render reflections when rendering a reflection probe
2022-09-07 11:23:01 +00:00
_setup_reflections ( p_render_data , * p_render_data - > reflection_probes , p_render_data - > scene_data - > cam_transform . affine_inverse ( ) , p_render_data - > environment ) ;
2020-07-22 23:39:09 +00:00
}
uint32_t directional_light_count = 0 ;
2020-08-13 01:21:01 +00:00
uint32_t positional_light_count = 0 ;
2022-09-07 11:23:01 +00:00
_setup_lights ( p_render_data , * p_render_data - > lights , p_render_data - > scene_data - > cam_transform , p_render_data - > shadow_atlas , using_shadows , directional_light_count , positional_light_count , p_render_data - > directional_light_soft_shadows ) ;
_setup_decals ( * p_render_data - > decals , p_render_data - > scene_data - > cam_transform . affine_inverse ( ) ) ;
2021-01-17 16:25:38 +00:00
2021-05-05 05:41:12 +00:00
p_render_data - > directional_light_count = directional_light_count ;
2020-07-22 23:39:09 +00:00
2021-02-02 19:51:36 +00:00
if ( current_cluster_builder ) {
current_cluster_builder - > bake_cluster ( ) ;
2021-01-17 16:25:38 +00:00
}
2020-08-13 01:21:01 +00:00
2021-05-05 05:41:12 +00:00
if ( p_render_data - > render_buffers . is_valid ( ) ) {
2020-08-13 01:21:01 +00:00
bool directional_shadows = false ;
for ( uint32_t i = 0 ; i < directional_light_count ; i + + ) {
2022-06-10 10:47:06 +00:00
if ( cluster . directional_lights [ i ] . shadow_opacity > 0.001 ) {
2020-08-13 01:21:01 +00:00
directional_shadows = true ;
break ;
}
}
2021-03-23 10:46:31 +00:00
if ( is_volumetric_supported ( ) ) {
2022-09-07 11:23:01 +00:00
_update_volumetric_fog ( p_render_data - > render_buffers , p_render_data - > environment , p_render_data - > scene_data - > cam_projection , p_render_data - > scene_data - > cam_transform , p_render_data - > scene_data - > prev_cam_transform . affine_inverse ( ) , p_render_data - > shadow_atlas , directional_light_count , directional_shadows , positional_light_count , render_state . voxel_gi_count , * p_render_data - > fog_volumes ) ;
2021-03-23 10:46:31 +00:00
}
2021-02-02 19:51:36 +00:00
}
}
2022-09-08 00:44:36 +00:00
void RendererSceneRenderRD : : render_scene ( const Ref < RenderSceneBuffers > & p_render_buffers , const CameraData * p_camera_data , const CameraData * p_prev_camera_data , const PagedArray < RenderGeometryInstance * > & p_instances , const PagedArray < RID > & p_lights , const PagedArray < RID > & p_reflection_probes , const PagedArray < RID > & p_voxel_gi_instances , const PagedArray < RID > & p_decals , const PagedArray < RID > & p_lightmaps , const PagedArray < RID > & p_fog_volumes , RID p_environment , RID p_camera_attributes , RID p_shadow_atlas , RID p_occluder_debug_tex , RID p_reflection_atlas , RID p_reflection_probe , int p_reflection_probe_pass , float p_screen_mesh_lod_threshold , const RenderShadowData * p_render_shadows , int p_render_shadow_count , const RenderSDFGIData * p_render_sdfgi_regions , int p_render_sdfgi_region_count , const RenderSDFGIUpdateData * p_sdfgi_update_data , RenderingMethod : : RenderInfo * r_render_info ) {
2022-04-07 14:00:51 +00:00
RendererRD : : TextureStorage * texture_storage = RendererRD : : TextureStorage : : get_singleton ( ) ;
2021-02-13 12:08:08 +00:00
// getting this here now so we can direct call a bunch of things more easily
2022-08-04 08:40:39 +00:00
Ref < RenderSceneBuffersRD > rb ;
2021-02-13 12:08:08 +00:00
if ( p_render_buffers . is_valid ( ) ) {
2022-08-04 08:40:39 +00:00
rb = p_render_buffers ; // cast it...
ERR_FAIL_COND ( rb . is_null ( ) ) ;
2021-02-13 12:08:08 +00:00
}
2022-09-07 11:23:01 +00:00
// setup scene data
RenderSceneDataRD scene_data ;
2021-02-02 19:51:36 +00:00
{
2021-05-07 13:19:04 +00:00
// Our first camera is used by default
2022-09-07 11:23:01 +00:00
scene_data . cam_transform = p_camera_data - > main_transform ;
scene_data . cam_projection = p_camera_data - > main_projection ;
scene_data . cam_orthogonal = p_camera_data - > is_orthogonal ;
scene_data . taa_jitter = p_camera_data - > taa_jitter ;
2021-05-07 13:19:04 +00:00
2022-09-07 11:23:01 +00:00
scene_data . view_count = p_camera_data - > view_count ;
2021-05-07 13:19:04 +00:00
for ( uint32_t v = 0 ; v < p_camera_data - > view_count ; v + + ) {
2022-09-07 11:23:01 +00:00
scene_data . view_eye_offset [ v ] = p_camera_data - > view_offset [ v ] . origin ;
scene_data . view_projection [ v ] = p_camera_data - > view_projection [ v ] ;
2021-05-07 13:19:04 +00:00
}
2022-09-07 11:23:01 +00:00
scene_data . prev_cam_transform = p_prev_camera_data - > main_transform ;
scene_data . prev_cam_projection = p_prev_camera_data - > main_projection ;
scene_data . prev_taa_jitter = p_prev_camera_data - > taa_jitter ;
2022-04-04 14:10:22 +00:00
for ( uint32_t v = 0 ; v < p_camera_data - > view_count ; v + + ) {
2022-09-07 11:23:01 +00:00
scene_data . prev_view_projection [ v ] = p_prev_camera_data - > view_projection [ v ] ;
}
scene_data . z_near = p_camera_data - > main_projection . get_z_near ( ) ;
scene_data . z_far = p_camera_data - > main_projection . get_z_far ( ) ;
// this should be the same for all cameras..
scene_data . lod_distance_multiplier = p_camera_data - > main_projection . get_lod_multiplier ( ) ;
scene_data . lod_camera_plane = Plane ( - p_camera_data - > main_transform . basis . get_column ( Vector3 : : AXIS_Z ) , p_camera_data - > main_transform . get_origin ( ) ) ;
if ( get_debug_draw_mode ( ) = = RS : : VIEWPORT_DEBUG_DRAW_DISABLE_LOD ) {
scene_data . screen_mesh_lod_threshold = 0.0 ;
} else {
scene_data . screen_mesh_lod_threshold = p_screen_mesh_lod_threshold ;
}
if ( p_shadow_atlas . is_valid ( ) ) {
Vector2 sas = shadow_atlas_get_size ( p_shadow_atlas ) ;
scene_data . shadow_atlas_pixel_size . x = 1.0 / sas . x ;
scene_data . shadow_atlas_pixel_size . y = 1.0 / sas . y ;
2022-04-04 14:10:22 +00:00
}
2022-09-07 11:23:01 +00:00
{
Vector2 dss = directional_shadow_get_size ( ) ;
scene_data . directional_shadow_pixel_size . x = 1.0 / dss . x ;
scene_data . directional_shadow_pixel_size . y = 1.0 / dss . y ;
}
scene_data . time = time ;
scene_data . time_step = time_step ;
}
2022-04-04 14:10:22 +00:00
2022-09-07 11:23:01 +00:00
//assign render data
RenderDataRD render_data ;
{
render_data . render_buffers = rb ;
render_data . scene_data = & scene_data ;
2021-05-05 05:41:12 +00:00
render_data . instances = & p_instances ;
render_data . lights = & p_lights ;
render_data . reflection_probes = & p_reflection_probes ;
2021-06-04 22:47:26 +00:00
render_data . voxel_gi_instances = & p_voxel_gi_instances ;
2021-05-05 05:41:12 +00:00
render_data . decals = & p_decals ;
render_data . lightmaps = & p_lightmaps ;
2021-10-03 11:28:55 +00:00
render_data . fog_volumes = & p_fog_volumes ;
2021-05-05 05:41:12 +00:00
render_data . environment = p_environment ;
2022-07-31 23:20:24 +00:00
render_data . camera_attributes = p_camera_attributes ;
2021-05-05 05:41:12 +00:00
render_data . shadow_atlas = p_shadow_atlas ;
render_data . reflection_atlas = p_reflection_atlas ;
render_data . reflection_probe = p_reflection_probe ;
render_data . reflection_probe_pass = p_reflection_probe_pass ;
2021-02-02 19:51:36 +00:00
render_state . render_shadows = p_render_shadows ;
render_state . render_shadow_count = p_render_shadow_count ;
render_state . render_sdfgi_regions = p_render_sdfgi_regions ;
render_state . render_sdfgi_region_count = p_render_sdfgi_region_count ;
render_state . sdfgi_update_data = p_sdfgi_update_data ;
2021-07-02 23:14:19 +00:00
render_data . render_info = r_render_info ;
2021-02-02 19:51:36 +00:00
}
PagedArray < RID > empty ;
if ( get_debug_draw_mode ( ) = = RS : : VIEWPORT_DEBUG_DRAW_UNSHADED ) {
2021-05-05 05:41:12 +00:00
render_data . lights = & empty ;
render_data . reflection_probes = & empty ;
2021-06-04 22:47:26 +00:00
render_data . voxel_gi_instances = & empty ;
2021-02-02 19:51:36 +00:00
}
2022-09-07 11:23:01 +00:00
// sdfgi first
2022-08-04 08:40:39 +00:00
if ( rb . is_valid ( ) & & rb - > has_custom_data ( RB_SCOPE_SDFGI ) ) {
Ref < RendererRD : : GI : : SDFGI > sdfgi = rb - > get_custom_data ( RB_SCOPE_SDFGI ) ;
2022-07-31 23:20:24 +00:00
float exposure_normalization = 1.0 ;
2022-08-04 08:40:39 +00:00
2022-07-31 23:20:24 +00:00
if ( p_camera_attributes . is_valid ( ) ) {
exposure_normalization = RSG : : camera_attributes - > camera_attributes_get_exposure_normalization_factor ( p_camera_attributes ) ;
}
2021-02-02 19:51:36 +00:00
for ( int i = 0 ; i < render_state . render_sdfgi_region_count ; i + + ) {
2022-08-04 08:40:39 +00:00
sdfgi - > render_region ( rb , render_state . render_sdfgi_regions [ i ] . region , render_state . render_sdfgi_regions [ i ] . instances , this , exposure_normalization ) ;
2021-02-02 19:51:36 +00:00
}
if ( render_state . sdfgi_update_data - > update_static ) {
2022-08-04 08:40:39 +00:00
sdfgi - > render_static_lights ( & render_data , rb , render_state . sdfgi_update_data - > static_cascade_count , p_sdfgi_update_data - > static_cascade_indices , render_state . sdfgi_update_data - > static_positional_lights , this ) ;
2021-02-02 19:51:36 +00:00
}
}
Color clear_color ;
if ( p_render_buffers . is_valid ( ) ) {
2022-08-04 08:40:39 +00:00
clear_color = texture_storage - > render_target_get_clear_request_color ( rb - > get_render_target ( ) ) ;
2021-02-02 19:51:36 +00:00
} else {
2022-06-21 00:08:33 +00:00
clear_color = RSG : : texture_storage - > get_default_clear_color ( ) ;
2021-02-02 19:51:36 +00:00
}
2021-06-04 22:47:26 +00:00
//assign render indices to voxel_gi_instances
2021-03-10 11:23:55 +00:00
if ( is_dynamic_gi_supported ( ) ) {
2021-06-04 22:47:26 +00:00
for ( uint32_t i = 0 ; i < ( uint32_t ) p_voxel_gi_instances . size ( ) ; i + + ) {
2022-08-04 08:40:39 +00:00
gi . voxel_gi_instance_set_render_index ( p_voxel_gi_instances [ i ] , i ) ;
2021-02-02 19:51:36 +00:00
}
}
2022-08-04 08:40:39 +00:00
if ( rb . is_valid ( ) ) {
2021-05-05 05:41:12 +00:00
// render_data.render_buffers == p_render_buffers so we can use our already retrieved rb
2021-03-23 10:46:31 +00:00
current_cluster_builder = rb - > cluster_builder ;
2021-05-05 05:41:12 +00:00
} else if ( reflection_probe_instance_owner . owns ( render_data . reflection_probe ) ) {
2021-09-29 17:08:41 +00:00
ReflectionProbeInstance * rpi = reflection_probe_instance_owner . get_or_null ( render_data . reflection_probe ) ;
ReflectionAtlas * ra = reflection_atlas_owner . get_or_null ( rpi - > atlas ) ;
2021-02-02 19:51:36 +00:00
if ( ! ra ) {
ERR_PRINT ( " reflection probe has no reflection atlas! Bug? " ) ;
current_cluster_builder = nullptr ;
} else {
current_cluster_builder = ra - > cluster_builder ;
}
2022-07-31 23:20:24 +00:00
if ( p_camera_attributes . is_valid ( ) ) {
RendererRD : : LightStorage : : get_singleton ( ) - > reflection_probe_set_baked_exposure ( rpi - > probe , RSG : : camera_attributes - > camera_attributes_get_exposure_normalization_factor ( p_camera_attributes ) ) ;
}
2021-02-02 19:51:36 +00:00
} else {
2021-03-23 10:46:31 +00:00
ERR_PRINT ( " No render buffer nor reflection atlas, bug " ) ; //should never happen, will crash
2021-02-02 19:51:36 +00:00
current_cluster_builder = nullptr ;
}
2021-06-04 22:47:26 +00:00
render_state . voxel_gi_count = 0 ;
2021-02-13 12:08:08 +00:00
2022-08-04 08:40:39 +00:00
if ( rb . is_valid ( ) & & is_dynamic_gi_supported ( ) ) {
if ( rb - > has_custom_data ( RB_SCOPE_SDFGI ) ) {
Ref < RendererRD : : GI : : SDFGI > sdfgi = rb - > get_custom_data ( RB_SCOPE_SDFGI ) ;
if ( sdfgi . is_valid ( ) ) {
sdfgi - > update_cascades ( ) ;
2022-09-07 11:23:01 +00:00
sdfgi - > pre_process_gi ( scene_data . cam_transform , & render_data , this ) ;
2022-08-04 08:40:39 +00:00
sdfgi - > update_light ( ) ;
}
2021-06-12 23:37:56 +00:00
}
2022-09-07 11:23:01 +00:00
gi . setup_voxel_gi_instances ( & render_data , render_data . render_buffers , scene_data . cam_transform , * render_data . voxel_gi_instances , render_state . voxel_gi_count , this ) ;
2020-08-13 01:21:01 +00:00
}
2021-02-02 19:51:36 +00:00
render_state . depth_prepass_used = false ;
//calls _pre_opaque_render between depth pre-pass and opaque pass
2021-03-10 11:23:55 +00:00
if ( current_cluster_builder ! = nullptr ) {
2021-05-05 05:41:12 +00:00
render_data . cluster_buffer = current_cluster_builder - > get_cluster_buffer ( ) ;
render_data . cluster_size = current_cluster_builder - > get_cluster_size ( ) ;
render_data . cluster_max_elements = current_cluster_builder - > get_max_cluster_elements ( ) ;
2021-03-10 11:23:55 +00:00
}
2020-01-13 18:37:24 +00:00
2022-08-04 08:40:39 +00:00
if ( rb . is_valid ( ) & & vrs ) {
RS : : ViewportVRSMode vrs_mode = texture_storage - > render_target_get_vrs_mode ( rb - > get_render_target ( ) ) ;
if ( vrs_mode ! = RS : : VIEWPORT_VRS_DISABLED ) {
RID vrs_texture = rb - > get_texture ( RB_SCOPE_VRS , RB_TEXTURE ) ;
// We use get_cache_multipass instead of get_cache_multiview because the default behavior is for
// our vrs_texture to be used as the VRS attachment. In this particular case we're writing to it
// so it needs to be set as our color attachment
Vector < RID > textures ;
textures . push_back ( vrs_texture ) ;
Vector < RD : : FramebufferPass > passes ;
RD : : FramebufferPass pass ;
pass . color_attachments . push_back ( 0 ) ;
passes . push_back ( pass ) ;
RID vrs_fb = FramebufferCacheRD : : get_singleton ( ) - > get_cache_multipass ( textures , passes , rb - > get_view_count ( ) ) ;
vrs - > update_vrs_texture ( vrs_fb , rb - > get_render_target ( ) ) ;
}
2022-02-11 11:33:54 +00:00
}
2021-05-05 05:41:12 +00:00
_render_scene ( & render_data , clear_color ) ;
2022-08-04 08:40:39 +00:00
if ( rb . is_valid ( ) ) {
_render_buffers_debug_draw ( rb , p_shadow_atlas , p_occluder_debug_tex ) ;
2021-06-26 10:49:25 +00:00
2022-08-04 08:40:39 +00:00
if ( debug_draw = = RS : : VIEWPORT_DEBUG_DRAW_SDFGI & & rb - > has_custom_data ( RB_SCOPE_SDFGI ) ) {
Ref < RendererRD : : GI : : SDFGI > sdfgi = rb - > get_custom_data ( RB_SCOPE_SDFGI ) ;
2022-05-20 02:52:19 +00:00
Vector < RID > view_rids ;
2022-08-04 08:40:39 +00:00
// SDFGI renders at internal resolution, need to check if our debug correctly supports outputting upscaled.
Size2i size = rb - > get_internal_size ( ) ;
RID source_texture = rb - > get_internal_texture ( ) ;
for ( uint32_t v = 0 ; v < rb - > get_view_count ( ) ; v + + ) {
view_rids . push_back ( rb - > get_internal_texture ( v ) ) ;
2022-05-20 02:52:19 +00:00
}
2022-09-07 11:23:01 +00:00
sdfgi - > debug_draw ( scene_data . view_count , scene_data . view_projection , scene_data . cam_transform , size . x , size . y , rb - > get_render_target ( ) , source_texture , view_rids ) ;
2021-06-26 10:49:25 +00:00
}
}
}
2022-08-04 08:40:39 +00:00
void RendererSceneRenderRD : : _debug_draw_cluster ( Ref < RenderSceneBuffersRD > p_render_buffers ) {
2021-06-26 10:49:25 +00:00
if ( p_render_buffers . is_valid ( ) & & current_cluster_builder ! = nullptr ) {
RS : : ViewportDebugDraw dd = get_debug_draw_mode ( ) ;
if ( dd = = RS : : VIEWPORT_DEBUG_DRAW_CLUSTER_OMNI_LIGHTS | | dd = = RS : : VIEWPORT_DEBUG_DRAW_CLUSTER_SPOT_LIGHTS | | dd = = RS : : VIEWPORT_DEBUG_DRAW_CLUSTER_DECALS | | dd = = RS : : VIEWPORT_DEBUG_DRAW_CLUSTER_REFLECTION_PROBES ) {
2021-01-17 16:25:38 +00:00
ClusterBuilderRD : : ElementType elem_type = ClusterBuilderRD : : ELEMENT_TYPE_MAX ;
2021-06-26 10:49:25 +00:00
switch ( dd ) {
2021-01-17 16:25:38 +00:00
case RS : : VIEWPORT_DEBUG_DRAW_CLUSTER_OMNI_LIGHTS :
elem_type = ClusterBuilderRD : : ELEMENT_TYPE_OMNI_LIGHT ;
break ;
case RS : : VIEWPORT_DEBUG_DRAW_CLUSTER_SPOT_LIGHTS :
elem_type = ClusterBuilderRD : : ELEMENT_TYPE_SPOT_LIGHT ;
break ;
case RS : : VIEWPORT_DEBUG_DRAW_CLUSTER_DECALS :
elem_type = ClusterBuilderRD : : ELEMENT_TYPE_DECAL ;
break ;
case RS : : VIEWPORT_DEBUG_DRAW_CLUSTER_REFLECTION_PROBES :
elem_type = ClusterBuilderRD : : ELEMENT_TYPE_REFLECTION_PROBE ;
break ;
default : {
}
}
2021-06-26 10:49:25 +00:00
current_cluster_builder - > debug ( elem_type ) ;
2020-06-25 13:33:28 +00:00
}
2020-01-13 18:37:24 +00:00
}
2019-09-07 01:51:27 +00:00
}
2022-09-08 00:44:36 +00:00
void RendererSceneRenderRD : : _render_shadow_pass ( RID p_light , RID p_shadow_atlas , int p_pass , const PagedArray < RenderGeometryInstance * > & p_instances , const Plane & p_camera_plane , float p_lod_distance_multiplier , float p_screen_mesh_lod_threshold , bool p_open_pass , bool p_close_pass , bool p_clear_region , RenderingMethod : : RenderInfo * p_render_info ) {
2021-09-29 17:08:41 +00:00
LightInstance * light_instance = light_instance_owner . get_or_null ( p_light ) ;
2019-09-07 01:51:27 +00:00
ERR_FAIL_COND ( ! light_instance ) ;
Rect2i atlas_rect ;
2022-09-22 07:25:47 +00:00
uint32_t atlas_size = 1 ;
2021-01-24 19:00:20 +00:00
RID atlas_fb ;
2019-09-07 01:51:27 +00:00
bool using_dual_paraboloid = false ;
bool using_dual_paraboloid_flip = false ;
2021-08-04 15:18:06 +00:00
Vector2i dual_paraboloid_offset ;
2019-09-07 01:51:27 +00:00
RID render_fb ;
RID render_texture ;
2021-01-24 19:00:20 +00:00
float zfar ;
2019-09-07 01:51:27 +00:00
2020-04-08 01:51:52 +00:00
bool use_pancake = false ;
2019-09-07 01:51:27 +00:00
bool render_cubemap = false ;
bool finalize_cubemap = false ;
2021-01-24 19:00:20 +00:00
bool flip_y = false ;
Implement Vector4, Vector4i, Projection
Implement built-in classes Vector4, Vector4i and Projection.
* Two versions of Vector4 (float and integer).
* A Projection class, which is a 4x4 matrix specialized in projection types.
These types have been requested for a long time, but given they were very corner case they were not added before.
Because in Godot 4, reimplementing parts of the rendering engine is now possible, access to these types (heavily used by the rendering code) becomes a necessity.
**Q**: Why Projection and not Matrix4?
**A**: Godot does not use Matrix2, Matrix3, Matrix4x3, etc. naming convention because, within the engine, these types always have a *purpose*. As such, Godot names them: Transform2D, Transform3D or Basis. In this case, this 4x4 matrix is _always_ used as a _Projection_, hence the naming.
2022-07-19 23:11:13 +00:00
Projection light_projection ;
2020-10-17 05:08:21 +00:00
Transform3D light_transform ;
2019-09-07 01:51:27 +00:00
2022-04-09 09:34:31 +00:00
if ( RSG : : light_storage - > light_get_type ( light_instance - > light ) = = RS : : LIGHT_DIRECTIONAL ) {
2019-09-07 01:51:27 +00:00
//set pssm stuff
if ( light_instance - > last_scene_shadow_pass ! = scene_pass ) {
2019-09-07 17:38:17 +00:00
light_instance - > directional_rect = _get_directional_shadow_rect ( directional_shadow . size , directional_shadow . light_count , directional_shadow . current_light ) ;
2019-09-07 01:51:27 +00:00
directional_shadow . current_light + + ;
2019-09-07 17:38:17 +00:00
light_instance - > last_scene_shadow_pass = scene_pass ;
2019-09-07 01:51:27 +00:00
}
2022-04-09 09:34:31 +00:00
use_pancake = RSG : : light_storage - > light_get_param ( light_instance - > light , RS : : LIGHT_PARAM_SHADOW_PANCAKE_SIZE ) > 0 ;
2019-09-07 01:51:27 +00:00
light_projection = light_instance - > shadow_transform [ p_pass ] . camera ;
light_transform = light_instance - > shadow_transform [ p_pass ] . transform ;
2021-09-25 09:01:45 +00:00
atlas_rect = light_instance - > directional_rect ;
2019-09-07 01:51:27 +00:00
2022-04-09 09:34:31 +00:00
if ( RSG : : light_storage - > light_directional_get_shadow_mode ( light_instance - > light ) = = RS : : LIGHT_DIRECTIONAL_SHADOW_PARALLEL_4_SPLITS ) {
2019-09-07 01:51:27 +00:00
atlas_rect . size . width / = 2 ;
atlas_rect . size . height / = 2 ;
if ( p_pass = = 1 ) {
atlas_rect . position . x + = atlas_rect . size . width ;
} else if ( p_pass = = 2 ) {
atlas_rect . position . y + = atlas_rect . size . height ;
} else if ( p_pass = = 3 ) {
2021-09-25 09:01:45 +00:00
atlas_rect . position + = atlas_rect . size ;
2019-09-07 01:51:27 +00:00
}
2022-04-09 09:34:31 +00:00
} else if ( RSG : : light_storage - > light_directional_get_shadow_mode ( light_instance - > light ) = = RS : : LIGHT_DIRECTIONAL_SHADOW_PARALLEL_2_SPLITS ) {
2019-09-07 01:51:27 +00:00
atlas_rect . size . height / = 2 ;
if ( p_pass = = 0 ) {
} else {
atlas_rect . position . y + = atlas_rect . size . height ;
}
}
2021-02-13 12:08:08 +00:00
light_instance - > shadow_transform [ p_pass ] . atlas_rect = atlas_rect ;
2020-06-25 13:33:28 +00:00
2021-02-13 12:08:08 +00:00
light_instance - > shadow_transform [ p_pass ] . atlas_rect . position / = directional_shadow . size ;
light_instance - > shadow_transform [ p_pass ] . atlas_rect . size / = directional_shadow . size ;
2020-06-25 13:33:28 +00:00
2022-04-09 09:34:31 +00:00
zfar = RSG : : light_storage - > light_get_param ( light_instance - > light , RS : : LIGHT_PARAM_RANGE ) ;
2020-06-25 13:33:28 +00:00
2021-02-13 12:08:08 +00:00
render_fb = directional_shadow . fb ;
render_texture = RID ( ) ;
flip_y = true ;
2020-10-08 00:29:49 +00:00
2021-02-13 12:08:08 +00:00
} else {
//set from shadow atlas
2020-10-08 00:29:49 +00:00
2021-09-29 17:08:41 +00:00
ShadowAtlas * shadow_atlas = shadow_atlas_owner . get_or_null ( p_shadow_atlas ) ;
2021-02-13 12:08:08 +00:00
ERR_FAIL_COND ( ! shadow_atlas ) ;
ERR_FAIL_COND ( ! shadow_atlas - > shadow_owners . has ( p_light ) ) ;
2020-10-08 00:29:49 +00:00
2021-02-13 12:08:08 +00:00
_update_shadow_atlas ( shadow_atlas ) ;
2020-10-08 00:29:49 +00:00
2021-02-13 12:08:08 +00:00
uint32_t key = shadow_atlas - > shadow_owners [ p_light ] ;
2020-10-08 00:29:49 +00:00
2021-02-13 12:08:08 +00:00
uint32_t quadrant = ( key > > ShadowAtlas : : QUADRANT_SHIFT ) & 0x3 ;
uint32_t shadow = key & ShadowAtlas : : SHADOW_INDEX_MASK ;
2020-06-25 13:33:28 +00:00
2021-02-13 12:08:08 +00:00
ERR_FAIL_INDEX ( ( int ) shadow , shadow_atlas - > quadrants [ quadrant ] . shadows . size ( ) ) ;
2021-02-02 19:51:36 +00:00
2021-02-13 12:08:08 +00:00
uint32_t quadrant_size = shadow_atlas - > size > > 1 ;
2020-06-25 13:33:28 +00:00
2021-02-13 12:08:08 +00:00
atlas_rect . position . x = ( quadrant & 1 ) * quadrant_size ;
atlas_rect . position . y = ( quadrant > > 1 ) * quadrant_size ;
2020-06-25 13:33:28 +00:00
2021-02-13 12:08:08 +00:00
uint32_t shadow_size = ( quadrant_size / shadow_atlas - > quadrants [ quadrant ] . subdivision ) ;
atlas_rect . position . x + = ( shadow % shadow_atlas - > quadrants [ quadrant ] . subdivision ) * shadow_size ;
atlas_rect . position . y + = ( shadow / shadow_atlas - > quadrants [ quadrant ] . subdivision ) * shadow_size ;
2020-06-25 13:33:28 +00:00
2021-02-13 12:08:08 +00:00
atlas_rect . size . width = shadow_size ;
atlas_rect . size . height = shadow_size ;
2020-06-25 13:33:28 +00:00
2022-04-09 09:34:31 +00:00
zfar = RSG : : light_storage - > light_get_param ( light_instance - > light , RS : : LIGHT_PARAM_RANGE ) ;
2020-06-25 13:33:28 +00:00
2022-04-09 09:34:31 +00:00
if ( RSG : : light_storage - > light_get_type ( light_instance - > light ) = = RS : : LIGHT_OMNI ) {
2021-08-04 15:18:06 +00:00
bool wrap = ( shadow + 1 ) % shadow_atlas - > quadrants [ quadrant ] . subdivision = = 0 ;
dual_paraboloid_offset = wrap ? Vector2i ( 1 - shadow_atlas - > quadrants [ quadrant ] . subdivision , 1 ) : Vector2i ( 1 , 0 ) ;
2022-04-09 09:34:31 +00:00
if ( RSG : : light_storage - > light_omni_get_shadow_mode ( light_instance - > light ) = = RS : : LIGHT_OMNI_SHADOW_CUBE ) {
2021-02-13 12:08:08 +00:00
ShadowCubemap * cubemap = _get_shadow_cubemap ( shadow_size / 2 ) ;
2020-06-25 13:33:28 +00:00
2021-02-13 12:08:08 +00:00
render_fb = cubemap - > side_fb [ p_pass ] ;
render_texture = cubemap - > cubemap ;
2020-06-25 13:33:28 +00:00
2021-02-13 12:08:08 +00:00
light_projection = light_instance - > shadow_transform [ p_pass ] . camera ;
light_transform = light_instance - > shadow_transform [ p_pass ] . transform ;
render_cubemap = true ;
finalize_cubemap = p_pass = = 5 ;
atlas_fb = shadow_atlas - > fb ;
2020-06-25 13:33:28 +00:00
2021-02-13 12:08:08 +00:00
atlas_size = shadow_atlas - > size ;
2020-06-25 13:33:28 +00:00
2021-02-13 12:08:08 +00:00
if ( p_pass = = 0 ) {
_render_shadow_begin ( ) ;
2020-06-25 13:33:28 +00:00
}
2021-02-13 12:08:08 +00:00
} else {
2021-08-04 15:18:06 +00:00
atlas_rect . position . x + = 1 ;
atlas_rect . position . y + = 1 ;
atlas_rect . size . x - = 2 ;
atlas_rect . size . y - = 2 ;
atlas_rect . position + = p_pass * atlas_rect . size * dual_paraboloid_offset ;
2021-02-13 12:08:08 +00:00
light_projection = light_instance - > shadow_transform [ 0 ] . camera ;
light_transform = light_instance - > shadow_transform [ 0 ] . transform ;
2020-06-25 13:33:28 +00:00
2021-02-13 12:08:08 +00:00
using_dual_paraboloid = true ;
using_dual_paraboloid_flip = p_pass = = 1 ;
render_fb = shadow_atlas - > fb ;
flip_y = true ;
2020-06-25 13:33:28 +00:00
}
2022-04-09 09:34:31 +00:00
} else if ( RSG : : light_storage - > light_get_type ( light_instance - > light ) = = RS : : LIGHT_SPOT ) {
2021-02-13 12:08:08 +00:00
light_projection = light_instance - > shadow_transform [ 0 ] . camera ;
light_transform = light_instance - > shadow_transform [ 0 ] . transform ;
render_fb = shadow_atlas - > fb ;
2021-01-22 23:50:24 +00:00
2021-02-13 12:08:08 +00:00
flip_y = true ;
2020-06-25 13:33:28 +00:00
}
2021-01-22 23:50:24 +00:00
}
2021-02-13 12:08:08 +00:00
if ( render_cubemap ) {
//rendering to cubemap
2021-12-28 23:10:41 +00:00
_render_shadow_append ( render_fb , p_instances , light_projection , light_transform , zfar , 0 , 0 , false , false , use_pancake , p_camera_plane , p_lod_distance_multiplier , p_screen_mesh_lod_threshold , Rect2 ( ) , false , true , true , true , p_render_info ) ;
2021-02-13 12:08:08 +00:00
if ( finalize_cubemap ) {
_render_shadow_process ( ) ;
_render_shadow_end ( ) ;
//reblit
Rect2 atlas_rect_norm = atlas_rect ;
2021-09-25 09:01:45 +00:00
atlas_rect_norm . position / = float ( atlas_size ) ;
atlas_rect_norm . size / = float ( atlas_size ) ;
2022-06-17 03:55:23 +00:00
copy_effects - > copy_cubemap_to_dp ( render_texture , atlas_fb , atlas_rect_norm , atlas_rect . size , light_projection . get_z_near ( ) , light_projection . get_z_far ( ) , false ) ;
2021-08-04 15:18:06 +00:00
atlas_rect_norm . position + = Vector2 ( dual_paraboloid_offset ) * atlas_rect_norm . size ;
2022-06-17 03:55:23 +00:00
copy_effects - > copy_cubemap_to_dp ( render_texture , atlas_fb , atlas_rect_norm , atlas_rect . size , light_projection . get_z_near ( ) , light_projection . get_z_far ( ) , true ) ;
2021-01-22 23:50:24 +00:00
2021-02-13 12:08:08 +00:00
//restore transform so it can be properly used
Implement Vector4, Vector4i, Projection
Implement built-in classes Vector4, Vector4i and Projection.
* Two versions of Vector4 (float and integer).
* A Projection class, which is a 4x4 matrix specialized in projection types.
These types have been requested for a long time, but given they were very corner case they were not added before.
Because in Godot 4, reimplementing parts of the rendering engine is now possible, access to these types (heavily used by the rendering code) becomes a necessity.
**Q**: Why Projection and not Matrix4?
**A**: Godot does not use Matrix2, Matrix3, Matrix4x3, etc. naming convention because, within the engine, these types always have a *purpose*. As such, Godot names them: Transform2D, Transform3D or Basis. In this case, this 4x4 matrix is _always_ used as a _Projection_, hence the naming.
2022-07-19 23:11:13 +00:00
light_instance_set_shadow_transform ( p_light , Projection ( ) , light_instance - > transform , zfar , 0 , 0 , 0 ) ;
2021-02-13 12:08:08 +00:00
}
2021-01-22 23:50:24 +00:00
2021-02-13 12:08:08 +00:00
} else {
//render shadow
2021-12-28 23:10:41 +00:00
_render_shadow_append ( render_fb , p_instances , light_projection , light_transform , zfar , 0 , 0 , using_dual_paraboloid , using_dual_paraboloid_flip , use_pancake , p_camera_plane , p_lod_distance_multiplier , p_screen_mesh_lod_threshold , atlas_rect , flip_y , p_clear_region , p_open_pass , p_close_pass , p_render_info ) ;
2021-02-13 12:08:08 +00:00
}
}
2021-01-22 23:50:24 +00:00
2022-07-23 14:01:53 +00:00
void RendererSceneRenderRD : : render_material ( const Transform3D & p_cam_transform , const Projection & p_cam_projection , bool p_cam_orthogonal , const PagedArray < RenderGeometryInstance * > & p_instances , RID p_framebuffer , const Rect2i & p_region ) {
2022-07-31 23:20:24 +00:00
_render_material ( p_cam_transform , p_cam_projection , p_cam_orthogonal , p_instances , p_framebuffer , p_region , 1.0 ) ;
2021-02-13 12:08:08 +00:00
}
2021-01-22 23:50:24 +00:00
2022-07-23 14:01:53 +00:00
void RendererSceneRenderRD : : render_particle_collider_heightfield ( RID p_collider , const Transform3D & p_transform , const PagedArray < RenderGeometryInstance * > & p_instances ) {
2022-04-12 11:41:50 +00:00
RendererRD : : ParticlesStorage * particles_storage = RendererRD : : ParticlesStorage : : get_singleton ( ) ;
ERR_FAIL_COND ( ! particles_storage - > particles_collision_is_heightfield ( p_collider ) ) ;
Vector3 extents = particles_storage - > particles_collision_get_extents ( p_collider ) * p_transform . basis . get_scale ( ) ;
Implement Vector4, Vector4i, Projection
Implement built-in classes Vector4, Vector4i and Projection.
* Two versions of Vector4 (float and integer).
* A Projection class, which is a 4x4 matrix specialized in projection types.
These types have been requested for a long time, but given they were very corner case they were not added before.
Because in Godot 4, reimplementing parts of the rendering engine is now possible, access to these types (heavily used by the rendering code) becomes a necessity.
**Q**: Why Projection and not Matrix4?
**A**: Godot does not use Matrix2, Matrix3, Matrix4x3, etc. naming convention because, within the engine, these types always have a *purpose*. As such, Godot names them: Transform2D, Transform3D or Basis. In this case, this 4x4 matrix is _always_ used as a _Projection_, hence the naming.
2022-07-19 23:11:13 +00:00
Projection cm ;
2021-02-13 12:08:08 +00:00
cm . set_orthogonal ( - extents . x , extents . x , - extents . z , extents . z , 0 , extents . y * 2.0 ) ;
2021-01-22 23:50:24 +00:00
2021-02-13 12:08:08 +00:00
Vector3 cam_pos = p_transform . origin ;
cam_pos . y + = extents . y ;
2020-06-25 13:33:28 +00:00
2020-10-17 05:08:21 +00:00
Transform3D cam_xform ;
2022-05-03 12:50:35 +00:00
cam_xform . set_look_at ( cam_pos , cam_pos - p_transform . basis . get_column ( Vector3 : : AXIS_Y ) , - p_transform . basis . get_column ( Vector3 : : AXIS_Z ) . normalized ( ) ) ;
2020-06-25 13:33:28 +00:00
2022-04-12 11:41:50 +00:00
RID fb = particles_storage - > particles_collision_get_heightfield_framebuffer ( p_collider ) ;
2021-02-02 19:51:36 +00:00
2021-02-13 12:08:08 +00:00
_render_particle_collider_heightfield ( fb , cam_xform , cm , p_instances ) ;
2020-06-25 13:33:28 +00:00
}
2020-12-04 18:26:24 +00:00
bool RendererSceneRenderRD : : free ( RID p_rid ) {
2022-08-04 08:40:39 +00:00
if ( is_environment ( p_rid ) ) {
2022-07-27 06:14:23 +00:00
environment_free ( p_rid ) ;
2022-07-31 23:20:24 +00:00
} else if ( RSG : : camera_attributes - > owns_camera_attributes ( p_rid ) ) {
RSG : : camera_attributes - > camera_attributes_free ( p_rid ) ;
2019-09-09 20:50:51 +00:00
} else if ( reflection_atlas_owner . owns ( p_rid ) ) {
reflection_atlas_set_size ( p_rid , 0 , 0 ) ;
2021-09-29 17:08:41 +00:00
ReflectionAtlas * ra = reflection_atlas_owner . get_or_null ( p_rid ) ;
2021-01-17 16:25:38 +00:00
if ( ra - > cluster_builder ) {
memdelete ( ra - > cluster_builder ) ;
}
2019-09-09 20:50:51 +00:00
reflection_atlas_owner . free ( p_rid ) ;
2019-09-07 01:51:27 +00:00
} else if ( reflection_probe_instance_owner . owns ( p_rid ) ) {
2021-09-29 17:08:41 +00:00
ReflectionProbeInstance * rpi = reflection_probe_instance_owner . get_or_null ( p_rid ) ;
2021-07-15 20:06:33 +00:00
_free_forward_id ( FORWARD_ID_TYPE_REFLECTION_PROBE , rpi - > forward_id ) ;
2019-09-09 20:50:51 +00:00
reflection_probe_release_atlas_index ( p_rid ) ;
2019-09-07 01:51:27 +00:00
reflection_probe_instance_owner . free ( p_rid ) ;
2020-04-14 03:05:21 +00:00
} else if ( decal_instance_owner . owns ( p_rid ) ) {
2021-09-29 17:08:41 +00:00
DecalInstance * di = decal_instance_owner . get_or_null ( p_rid ) ;
2021-07-15 20:06:33 +00:00
_free_forward_id ( FORWARD_ID_TYPE_DECAL , di - > forward_id ) ;
2020-04-14 03:05:21 +00:00
decal_instance_owner . free ( p_rid ) ;
2020-12-31 12:42:56 +00:00
} else if ( lightmap_instance_owner . owns ( p_rid ) ) {
lightmap_instance_owner . free ( p_rid ) ;
2022-08-09 05:18:03 +00:00
} else if ( gi . voxel_gi_instance_owns ( p_rid ) ) {
gi . voxel_gi_instance_free ( p_rid ) ;
2021-02-13 12:08:08 +00:00
} else if ( sky . sky_owner . owns ( p_rid ) ) {
sky . update_dirty_skys ( ) ;
sky . free_sky ( p_rid ) ;
2019-09-07 01:51:27 +00:00
} else if ( light_instance_owner . owns ( p_rid ) ) {
2021-09-29 17:08:41 +00:00
LightInstance * light_instance = light_instance_owner . get_or_null ( p_rid ) ;
2019-09-07 01:51:27 +00:00
//remove from shadow atlases..
2022-05-18 23:43:40 +00:00
for ( const RID & E : light_instance - > shadow_atlases ) {
ShadowAtlas * shadow_atlas = shadow_atlas_owner . get_or_null ( E ) ;
2019-09-07 01:51:27 +00:00
ERR_CONTINUE ( ! shadow_atlas - > shadow_owners . has ( p_rid ) ) ;
uint32_t key = shadow_atlas - > shadow_owners [ p_rid ] ;
uint32_t q = ( key > > ShadowAtlas : : QUADRANT_SHIFT ) & 0x3 ;
uint32_t s = key & ShadowAtlas : : SHADOW_INDEX_MASK ;
shadow_atlas - > quadrants [ q ] . shadows . write [ s ] . owner = RID ( ) ;
2021-08-04 15:18:06 +00:00
if ( key & ShadowAtlas : : OMNI_LIGHT_FLAG ) {
// Omni lights use two atlas spots, make sure to clear the other as well
shadow_atlas - > quadrants [ q ] . shadows . write [ s + 1 ] . owner = RID ( ) ;
}
2019-09-07 01:51:27 +00:00
shadow_atlas - > shadow_owners . erase ( p_rid ) ;
}
2021-07-15 20:06:33 +00:00
if ( light_instance - > light_type ! = RS : : LIGHT_DIRECTIONAL ) {
_free_forward_id ( light_instance - > light_type = = RS : : LIGHT_OMNI ? FORWARD_ID_TYPE_OMNI_LIGHT : FORWARD_ID_TYPE_SPOT_LIGHT , light_instance - > forward_id ) ;
}
2019-09-07 01:51:27 +00:00
light_instance_owner . free ( p_rid ) ;
} else if ( shadow_atlas_owner . owns ( p_rid ) ) {
shadow_atlas_set_size ( p_rid , 0 ) ;
shadow_atlas_owner . free ( p_rid ) ;
2022-07-19 04:17:58 +00:00
} else if ( RendererRD : : Fog : : get_singleton ( ) - > owns_fog_volume_instance ( p_rid ) ) {
RendererRD : : Fog : : get_singleton ( ) - > fog_instance_free ( p_rid ) ;
2019-08-18 22:40:52 +00:00
} else {
return false ;
}
return true ;
}
2020-12-04 18:26:24 +00:00
void RendererSceneRenderRD : : set_debug_draw_mode ( RS : : ViewportDebugDraw p_debug_draw ) {
2020-01-10 00:40:26 +00:00
debug_draw = p_debug_draw ;
}
2020-12-04 18:26:24 +00:00
void RendererSceneRenderRD : : update ( ) {
2021-02-13 12:08:08 +00:00
sky . update_dirty_skys ( ) ;
2019-08-26 20:43:58 +00:00
}
2020-12-04 18:26:24 +00:00
void RendererSceneRenderRD : : set_time ( double p_time , double p_step ) {
2020-03-20 00:32:19 +00:00
time = p_time ;
2020-01-12 01:26:52 +00:00
time_step = p_step ;
}
2020-12-04 18:26:24 +00:00
void RendererSceneRenderRD : : screen_space_roughness_limiter_set_active ( bool p_enable , float p_amount , float p_limit ) {
2020-01-26 23:09:40 +00:00
screen_space_roughness_limiter = p_enable ;
2020-06-25 13:33:28 +00:00
screen_space_roughness_limiter_amount = p_amount ;
screen_space_roughness_limiter_limit = p_limit ;
2020-01-26 23:09:40 +00:00
}
2020-12-04 18:26:24 +00:00
bool RendererSceneRenderRD : : screen_space_roughness_limiter_is_active ( ) const {
2020-01-26 23:09:40 +00:00
return screen_space_roughness_limiter ;
}
2020-12-04 18:26:24 +00:00
float RendererSceneRenderRD : : screen_space_roughness_limiter_get_amount ( ) const {
2020-06-25 13:33:28 +00:00
return screen_space_roughness_limiter_amount ;
}
2020-12-04 18:26:24 +00:00
float RendererSceneRenderRD : : screen_space_roughness_limiter_get_limit ( ) const {
2020-06-25 13:33:28 +00:00
return screen_space_roughness_limiter_limit ;
2020-01-26 23:09:40 +00:00
}
2022-08-31 17:24:04 +00:00
TypedArray < Image > RendererSceneRenderRD : : bake_render_uv2 ( RID p_base , const TypedArray < RID > & p_material_overrides , const Size2i & p_image_size ) {
2020-05-01 12:34:23 +00:00
RD : : TextureFormat tf ;
tf . format = RD : : DATA_FORMAT_R8G8B8A8_UNORM ;
tf . width = p_image_size . width ; // Always 64x64
tf . height = p_image_size . height ;
tf . usage_bits = RD : : TEXTURE_USAGE_COLOR_ATTACHMENT_BIT | RD : : TEXTURE_USAGE_CAN_COPY_FROM_BIT ;
RID albedo_alpha_tex = RD : : get_singleton ( ) - > texture_create ( tf , RD : : TextureView ( ) ) ;
RID normal_tex = RD : : get_singleton ( ) - > texture_create ( tf , RD : : TextureView ( ) ) ;
RID orm_tex = RD : : get_singleton ( ) - > texture_create ( tf , RD : : TextureView ( ) ) ;
tf . format = RD : : DATA_FORMAT_R16G16B16A16_SFLOAT ;
RID emission_tex = RD : : get_singleton ( ) - > texture_create ( tf , RD : : TextureView ( ) ) ;
tf . format = RD : : DATA_FORMAT_R32_SFLOAT ;
RID depth_write_tex = RD : : get_singleton ( ) - > texture_create ( tf , RD : : TextureView ( ) ) ;
tf . usage_bits = RD : : TEXTURE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT | RD : : TEXTURE_USAGE_CAN_COPY_FROM_BIT ;
tf . format = RD : : get_singleton ( ) - > texture_is_format_supported_for_usage ( RD : : DATA_FORMAT_D32_SFLOAT , RD : : TEXTURE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT ) ? RD : : DATA_FORMAT_D32_SFLOAT : RD : : DATA_FORMAT_X8_D24_UNORM_PACK32 ;
RID depth_tex = RD : : get_singleton ( ) - > texture_create ( tf , RD : : TextureView ( ) ) ;
Vector < RID > fb_tex ;
fb_tex . push_back ( albedo_alpha_tex ) ;
fb_tex . push_back ( normal_tex ) ;
fb_tex . push_back ( orm_tex ) ;
fb_tex . push_back ( emission_tex ) ;
fb_tex . push_back ( depth_write_tex ) ;
fb_tex . push_back ( depth_tex ) ;
RID fb = RD : : get_singleton ( ) - > framebuffer_create ( fb_tex ) ;
//RID sampled_light;
2022-07-23 14:01:53 +00:00
RenderGeometryInstance * gi = geometry_instance_create ( p_base ) ;
2020-12-31 12:42:56 +00:00
2022-04-02 05:29:04 +00:00
uint32_t sc = RSG : : mesh_storage - > mesh_get_surface_count ( p_base ) ;
2020-12-31 12:42:56 +00:00
Vector < RID > materials ;
materials . resize ( sc ) ;
2020-05-01 12:34:23 +00:00
2020-12-31 12:42:56 +00:00
for ( uint32_t i = 0 ; i < sc ; i + + ) {
if ( i < ( uint32_t ) p_material_overrides . size ( ) ) {
materials . write [ i ] = p_material_overrides [ i ] ;
2020-05-01 12:34:23 +00:00
}
}
2022-07-23 14:01:53 +00:00
gi - > set_surface_materials ( materials ) ;
2020-12-31 12:42:56 +00:00
2020-12-23 16:52:58 +00:00
if ( cull_argument . size ( ) = = 0 ) {
cull_argument . push_back ( nullptr ) ;
}
2020-12-31 12:42:56 +00:00
cull_argument [ 0 ] = gi ;
2020-12-23 16:52:58 +00:00
_render_uv2 ( cull_argument , fb , Rect2i ( 0 , 0 , p_image_size . width , p_image_size . height ) ) ;
2020-05-01 12:34:23 +00:00
2020-12-31 12:42:56 +00:00
geometry_instance_free ( gi ) ;
2020-05-01 12:34:23 +00:00
TypedArray < Image > ret ;
{
PackedByteArray data = RD : : get_singleton ( ) - > texture_get_data ( albedo_alpha_tex , 0 ) ;
Ref < Image > img ;
2021-06-17 22:03:09 +00:00
img . instantiate ( ) ;
2020-05-01 12:34:23 +00:00
img - > create ( p_image_size . width , p_image_size . height , false , Image : : FORMAT_RGBA8 , data ) ;
RD : : get_singleton ( ) - > free ( albedo_alpha_tex ) ;
ret . push_back ( img ) ;
}
{
PackedByteArray data = RD : : get_singleton ( ) - > texture_get_data ( normal_tex , 0 ) ;
Ref < Image > img ;
2021-06-17 22:03:09 +00:00
img . instantiate ( ) ;
2020-05-01 12:34:23 +00:00
img - > create ( p_image_size . width , p_image_size . height , false , Image : : FORMAT_RGBA8 , data ) ;
RD : : get_singleton ( ) - > free ( normal_tex ) ;
ret . push_back ( img ) ;
}
{
PackedByteArray data = RD : : get_singleton ( ) - > texture_get_data ( orm_tex , 0 ) ;
Ref < Image > img ;
2021-06-17 22:03:09 +00:00
img . instantiate ( ) ;
2020-05-01 12:34:23 +00:00
img - > create ( p_image_size . width , p_image_size . height , false , Image : : FORMAT_RGBA8 , data ) ;
RD : : get_singleton ( ) - > free ( orm_tex ) ;
ret . push_back ( img ) ;
}
{
PackedByteArray data = RD : : get_singleton ( ) - > texture_get_data ( emission_tex , 0 ) ;
Ref < Image > img ;
2021-06-17 22:03:09 +00:00
img . instantiate ( ) ;
2020-05-01 12:34:23 +00:00
img - > create ( p_image_size . width , p_image_size . height , false , Image : : FORMAT_RGBAH , data ) ;
RD : : get_singleton ( ) - > free ( emission_tex ) ;
ret . push_back ( img ) ;
}
RD : : get_singleton ( ) - > free ( depth_write_tex ) ;
RD : : get_singleton ( ) - > free ( depth_tex ) ;
return ret ;
}
2020-12-04 18:26:24 +00:00
void RendererSceneRenderRD : : sdfgi_set_debug_probe_select ( const Vector3 & p_position , const Vector3 & p_dir ) {
2021-02-13 12:08:08 +00:00
gi . sdfgi_debug_probe_pos = p_position ;
gi . sdfgi_debug_probe_dir = p_dir ;
2020-06-25 13:33:28 +00:00
}
2020-12-04 18:26:24 +00:00
RendererSceneRenderRD * RendererSceneRenderRD : : singleton = nullptr ;
2020-03-20 00:32:19 +00:00
2020-12-04 18:26:24 +00:00
RID RendererSceneRenderRD : : get_reflection_probe_buffer ( ) {
2020-07-22 23:39:09 +00:00
return cluster . reflection_buffer ;
}
2021-01-17 16:25:38 +00:00
RID RendererSceneRenderRD : : get_omni_light_buffer ( ) {
return cluster . omni_light_buffer ;
}
RID RendererSceneRenderRD : : get_spot_light_buffer ( ) {
return cluster . spot_light_buffer ;
2020-07-22 23:39:09 +00:00
}
2021-01-17 16:25:38 +00:00
2020-12-04 18:26:24 +00:00
RID RendererSceneRenderRD : : get_directional_light_buffer ( ) {
2020-07-22 23:39:09 +00:00
return cluster . directional_light_buffer ;
}
2020-12-04 18:26:24 +00:00
RID RendererSceneRenderRD : : get_decal_buffer ( ) {
2020-07-22 23:39:09 +00:00
return cluster . decal_buffer ;
}
2020-12-04 18:26:24 +00:00
int RendererSceneRenderRD : : get_max_directional_lights ( ) const {
2020-07-22 23:39:09 +00:00
return cluster . max_directional_lights ;
}
2022-02-11 11:33:54 +00:00
bool RendererSceneRenderRD : : is_vrs_supported ( ) const {
return RD : : get_singleton ( ) - > has_feature ( RD : : SUPPORTS_ATTACHMENT_VRS ) ;
}
2021-03-23 10:46:31 +00:00
bool RendererSceneRenderRD : : is_dynamic_gi_supported ( ) const {
// usable by default (unless low end = true)
return true ;
}
bool RendererSceneRenderRD : : is_clustered_enabled ( ) const {
// used by default.
return true ;
}
bool RendererSceneRenderRD : : is_volumetric_supported ( ) const {
// usable by default (unless low end = true)
return true ;
2020-12-07 21:27:38 +00:00
}
2021-03-10 11:23:55 +00:00
uint32_t RendererSceneRenderRD : : get_max_elements ( ) const {
return GLOBAL_GET ( " rendering/limits/cluster_builder/max_clustered_elements " ) ;
}
2022-06-21 00:08:33 +00:00
RendererSceneRenderRD : : RendererSceneRenderRD ( ) {
2020-03-20 00:32:19 +00:00
singleton = this ;
2021-08-16 17:51:29 +00:00
}
void RendererSceneRenderRD : : init ( ) {
max_cluster_elements = get_max_elements ( ) ;
2019-08-26 20:43:58 +00:00
2022-07-31 23:20:24 +00:00
directional_shadow . size = GLOBAL_GET ( " rendering/lights_and_shadows/directional_shadow/size " ) ;
directional_shadow . use_16_bits = GLOBAL_GET ( " rendering/lights_and_shadows/directional_shadow/16_bits " ) ;
2021-01-24 19:00:20 +00:00
2020-03-20 00:32:19 +00:00
/* SKY SHADER */
2022-06-21 00:08:33 +00:00
sky . init ( ) ;
2020-03-20 00:32:19 +00:00
2021-03-11 03:35:05 +00:00
/* GI */
2021-04-07 11:06:48 +00:00
if ( is_dynamic_gi_supported ( ) ) {
2022-06-21 00:08:33 +00:00
gi . init ( & sky ) ;
2020-06-25 13:33:28 +00:00
}
2021-02-01 20:43:08 +00:00
{ //decals
cluster . max_decals = max_cluster_elements ;
uint32_t decal_buffer_size = cluster . max_decals * sizeof ( Cluster : : DecalData ) ;
cluster . decals = memnew_arr ( Cluster : : DecalData , cluster . max_decals ) ;
cluster . decal_sort = memnew_arr ( Cluster : : InstanceSort < DecalInstance > , cluster . max_decals ) ;
cluster . decal_buffer = RD : : get_singleton ( ) - > storage_buffer_create ( decal_buffer_size ) ;
}
2020-07-22 23:39:09 +00:00
{ //reflections
2021-01-17 16:25:38 +00:00
cluster . max_reflections = max_cluster_elements ;
2020-07-22 23:39:09 +00:00
cluster . reflections = memnew_arr ( Cluster : : ReflectionData , cluster . max_reflections ) ;
2021-02-02 19:51:36 +00:00
cluster . reflection_sort = memnew_arr ( Cluster : : InstanceSort < ReflectionProbeInstance > , cluster . max_reflections ) ;
2021-01-17 16:25:38 +00:00
cluster . reflection_buffer = RD : : get_singleton ( ) - > storage_buffer_create ( sizeof ( Cluster : : ReflectionData ) * cluster . max_reflections ) ;
2020-07-22 23:39:09 +00:00
}
{ //lights
2021-01-17 16:25:38 +00:00
cluster . max_lights = max_cluster_elements ;
2020-07-22 23:39:09 +00:00
uint32_t light_buffer_size = cluster . max_lights * sizeof ( Cluster : : LightData ) ;
2021-01-17 16:25:38 +00:00
cluster . omni_lights = memnew_arr ( Cluster : : LightData , cluster . max_lights ) ;
cluster . omni_light_buffer = RD : : get_singleton ( ) - > storage_buffer_create ( light_buffer_size ) ;
cluster . omni_light_sort = memnew_arr ( Cluster : : InstanceSort < LightInstance > , cluster . max_lights ) ;
cluster . spot_lights = memnew_arr ( Cluster : : LightData , cluster . max_lights ) ;
cluster . spot_light_buffer = RD : : get_singleton ( ) - > storage_buffer_create ( light_buffer_size ) ;
cluster . spot_light_sort = memnew_arr ( Cluster : : InstanceSort < LightInstance > , cluster . max_lights ) ;
2020-07-22 23:39:09 +00:00
//defines += "\n#define MAX_LIGHT_DATA_STRUCTS " + itos(cluster.max_lights) + "\n";
2021-01-17 16:25:38 +00:00
2020-12-26 12:05:36 +00:00
cluster . max_directional_lights = MAX_DIRECTIONAL_LIGHTS ;
2020-07-22 23:39:09 +00:00
uint32_t directional_light_buffer_size = cluster . max_directional_lights * sizeof ( Cluster : : DirectionalLightData ) ;
cluster . directional_lights = memnew_arr ( Cluster : : DirectionalLightData , cluster . max_directional_lights ) ;
cluster . directional_light_buffer = RD : : get_singleton ( ) - > uniform_buffer_create ( directional_light_buffer_size ) ;
}
2021-04-07 11:06:48 +00:00
if ( is_volumetric_supported ( ) ) {
2022-07-19 04:17:58 +00:00
RendererRD : : Fog : : get_singleton ( ) - > init_fog_shader ( cluster . max_directional_lights , get_roughness_layers ( ) , is_using_radiance_cubemap_array ( ) ) ;
2020-08-13 01:21:01 +00:00
}
2020-06-25 13:33:28 +00:00
2020-08-13 01:21:01 +00:00
{
RD : : SamplerState sampler ;
2020-10-24 15:15:43 +00:00
sampler . mag_filter = RD : : SAMPLER_FILTER_NEAREST ;
sampler . min_filter = RD : : SAMPLER_FILTER_NEAREST ;
2020-08-13 01:21:01 +00:00
sampler . enable_compare = true ;
sampler . compare_op = RD : : COMPARE_OP_LESS ;
shadow_sampler = RD : : get_singleton ( ) - > sampler_create ( sampler ) ;
}
2022-07-31 23:20:24 +00:00
RSG : : camera_attributes - > camera_attributes_set_dof_blur_bokeh_shape ( RS : : DOFBokehShape ( int ( GLOBAL_GET ( " rendering/camera/depth_of_field/depth_of_field_bokeh_shape " ) ) ) ) ;
RSG : : camera_attributes - > camera_attributes_set_dof_blur_quality ( RS : : DOFBlurQuality ( int ( GLOBAL_GET ( " rendering/camera/depth_of_field/depth_of_field_bokeh_quality " ) ) ) , GLOBAL_GET ( " rendering/camera/depth_of_field/depth_of_field_use_jitter " ) ) ;
use_physical_light_units = GLOBAL_GET ( " rendering/lights_and_shadows/use_physical_light_units " ) ;
2021-02-17 16:44:49 +00:00
environment_set_ssao_quality ( RS : : EnvironmentSSAOQuality ( int ( GLOBAL_GET ( " rendering/environment/ssao/quality " ) ) ) , GLOBAL_GET ( " rendering/environment/ssao/half_size " ) , GLOBAL_GET ( " rendering/environment/ssao/adaptive_target " ) , GLOBAL_GET ( " rendering/environment/ssao/blur_passes " ) , GLOBAL_GET ( " rendering/environment/ssao/fadeout_from " ) , GLOBAL_GET ( " rendering/environment/ssao/fadeout_to " ) ) ;
screen_space_roughness_limiter = GLOBAL_GET ( " rendering/anti_aliasing/screen_space_roughness_limiter/enabled " ) ;
screen_space_roughness_limiter_amount = GLOBAL_GET ( " rendering/anti_aliasing/screen_space_roughness_limiter/amount " ) ;
screen_space_roughness_limiter_limit = GLOBAL_GET ( " rendering/anti_aliasing/screen_space_roughness_limiter/limit " ) ;
glow_bicubic_upscale = int ( GLOBAL_GET ( " rendering/environment/glow/upscale_mode " ) ) > 0 ;
glow_high_quality = GLOBAL_GET ( " rendering/environment/glow/use_high_quality " ) ;
ssr_roughness_quality = RS : : EnvironmentSSRRoughnessQuality ( int ( GLOBAL_GET ( " rendering/environment/screen_space_reflection/roughness_quality " ) ) ) ;
sss_quality = RS : : SubSurfaceScatteringQuality ( int ( GLOBAL_GET ( " rendering/environment/subsurface_scattering/subsurface_scattering_quality " ) ) ) ;
sss_scale = GLOBAL_GET ( " rendering/environment/subsurface_scattering/subsurface_scattering_scale " ) ;
sss_depth_scale = GLOBAL_GET ( " rendering/environment/subsurface_scattering/subsurface_scattering_depth_scale " ) ;
2021-08-03 07:07:32 +00:00
environment_set_ssil_quality ( RS : : EnvironmentSSILQuality ( int ( GLOBAL_GET ( " rendering/environment/ssil/quality " ) ) ) , GLOBAL_GET ( " rendering/environment/ssil/half_size " ) , GLOBAL_GET ( " rendering/environment/ssil/adaptive_target " ) , GLOBAL_GET ( " rendering/environment/ssil/blur_passes " ) , GLOBAL_GET ( " rendering/environment/ssil/fadeout_from " ) , GLOBAL_GET ( " rendering/environment/ssil/fadeout_to " ) ) ;
2020-04-10 09:30:36 +00:00
directional_penumbra_shadow_kernel = memnew_arr ( float , 128 ) ;
directional_soft_shadow_kernel = memnew_arr ( float , 128 ) ;
penumbra_shadow_kernel = memnew_arr ( float , 128 ) ;
soft_shadow_kernel = memnew_arr ( float , 128 ) ;
2022-07-31 23:20:24 +00:00
positional_soft_shadow_filter_set_quality ( RS : : ShadowQuality ( int ( GLOBAL_GET ( " rendering/lights_and_shadows/positional_shadow/soft_shadow_filter_quality " ) ) ) ) ;
directional_soft_shadow_filter_set_quality ( RS : : ShadowQuality ( int ( GLOBAL_GET ( " rendering/lights_and_shadows/directional_shadow/soft_shadow_filter_quality " ) ) ) ) ;
2020-08-13 01:21:01 +00:00
2021-02-17 16:44:49 +00:00
environment_set_volumetric_fog_volume_size ( GLOBAL_GET ( " rendering/environment/volumetric_fog/volume_size " ) , GLOBAL_GET ( " rendering/environment/volumetric_fog/volume_depth " ) ) ;
environment_set_volumetric_fog_filter_active ( GLOBAL_GET ( " rendering/environment/volumetric_fog/use_filter " ) ) ;
2020-12-23 16:52:58 +00:00
2021-07-19 19:41:55 +00:00
decals_set_filter ( RS : : DecalFilter ( int ( GLOBAL_GET ( " rendering/textures/decals/filter " ) ) ) ) ;
light_projectors_set_filter ( RS : : LightProjectorFilter ( int ( GLOBAL_GET ( " rendering/textures/light_projectors/filter " ) ) ) ) ;
2020-12-23 16:52:58 +00:00
cull_argument . set_page_pool ( & cull_argument_pool ) ;
2022-04-27 03:42:50 +00:00
2022-04-29 07:10:54 +00:00
bool can_use_storage = _render_buffers_can_be_storage ( ) ;
bokeh_dof = memnew ( RendererRD : : BokehDOF ( ! can_use_storage ) ) ;
copy_effects = memnew ( RendererRD : : CopyEffects ( ! can_use_storage ) ) ;
2022-04-27 03:42:50 +00:00
tone_mapper = memnew ( RendererRD : : ToneMapper ) ;
2022-02-11 11:33:54 +00:00
vrs = memnew ( RendererRD : : VRS ) ;
2022-06-28 09:10:36 +00:00
if ( can_use_storage ) {
2022-08-04 08:40:39 +00:00
fsr = memnew ( RendererRD : : FSR ) ;
2022-06-28 09:10:36 +00:00
ss_effects = memnew ( RendererRD : : SSEffects ) ;
}
2019-08-18 22:40:52 +00:00
}
2019-09-07 01:51:27 +00:00
2020-12-04 18:26:24 +00:00
RendererSceneRenderRD : : ~ RendererSceneRenderRD ( ) {
2022-04-29 07:10:54 +00:00
if ( bokeh_dof ) {
memdelete ( bokeh_dof ) ;
}
if ( copy_effects ) {
memdelete ( copy_effects ) ;
}
2022-04-27 03:42:50 +00:00
if ( tone_mapper ) {
memdelete ( tone_mapper ) ;
}
2022-02-11 11:33:54 +00:00
if ( vrs ) {
memdelete ( vrs ) ;
}
2022-08-04 08:40:39 +00:00
if ( fsr ) {
memdelete ( fsr ) ;
}
2022-06-28 09:10:36 +00:00
if ( ss_effects ) {
memdelete ( ss_effects ) ;
}
2022-04-27 03:42:50 +00:00
2021-08-09 20:13:42 +00:00
for ( const KeyValue < int , ShadowCubemap > & E : shadow_cubemaps ) {
RD : : get_singleton ( ) - > free ( E . value . cubemap ) ;
2019-09-07 01:51:27 +00:00
}
2019-10-03 20:39:08 +00:00
2021-02-13 12:08:08 +00:00
if ( sky . sky_scene_state . uniform_set . is_valid ( ) & & RD : : get_singleton ( ) - > uniform_set_is_valid ( sky . sky_scene_state . uniform_set ) ) {
RD : : get_singleton ( ) - > free ( sky . sky_scene_state . uniform_set ) ;
2020-03-20 00:32:19 +00:00
}
2021-04-07 11:06:48 +00:00
if ( is_dynamic_gi_supported ( ) ) {
2021-02-13 12:08:08 +00:00
gi . free ( ) ;
2021-10-03 11:28:55 +00:00
}
2020-06-27 13:08:20 +00:00
2021-10-03 11:28:55 +00:00
if ( is_volumetric_supported ( ) ) {
2022-07-19 04:17:58 +00:00
RendererRD : : Fog : : get_singleton ( ) - > free_fog_shader ( ) ;
2022-03-21 11:25:25 +00:00
}
2020-04-10 09:30:36 +00:00
memdelete_arr ( directional_penumbra_shadow_kernel ) ;
memdelete_arr ( directional_soft_shadow_kernel ) ;
memdelete_arr ( penumbra_shadow_kernel ) ;
memdelete_arr ( soft_shadow_kernel ) ;
2020-07-22 23:39:09 +00:00
{
RD : : get_singleton ( ) - > free ( cluster . directional_light_buffer ) ;
2021-01-17 16:25:38 +00:00
RD : : get_singleton ( ) - > free ( cluster . omni_light_buffer ) ;
RD : : get_singleton ( ) - > free ( cluster . spot_light_buffer ) ;
2020-07-22 23:39:09 +00:00
RD : : get_singleton ( ) - > free ( cluster . reflection_buffer ) ;
RD : : get_singleton ( ) - > free ( cluster . decal_buffer ) ;
memdelete_arr ( cluster . directional_lights ) ;
2021-01-17 16:25:38 +00:00
memdelete_arr ( cluster . omni_lights ) ;
memdelete_arr ( cluster . spot_lights ) ;
memdelete_arr ( cluster . omni_light_sort ) ;
memdelete_arr ( cluster . spot_light_sort ) ;
2020-07-22 23:39:09 +00:00
memdelete_arr ( cluster . reflections ) ;
2021-01-17 16:25:38 +00:00
memdelete_arr ( cluster . reflection_sort ) ;
2020-07-22 23:39:09 +00:00
memdelete_arr ( cluster . decals ) ;
2021-01-17 16:25:38 +00:00
memdelete_arr ( cluster . decal_sort ) ;
2020-07-22 23:39:09 +00:00
}
2020-08-13 01:21:01 +00:00
RD : : get_singleton ( ) - > free ( shadow_sampler ) ;
directional_shadow_atlas_set_size ( 0 ) ;
2020-12-23 16:52:58 +00:00
cull_argument . reset ( ) ; //avoid exit error
2019-09-07 01:51:27 +00:00
}