2019-06-22 18:34:26 +02:00
/*************************************************************************/
2020-12-04 19:26:24 +01:00
/* renderer_storage_rd.cpp */
2019-06-22 18:34:26 +02:00
/*************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
2022-01-03 21:27:34 +01:00
/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */
2019-06-22 18:34:26 +02: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 19:26:24 +01:00
# include "renderer_storage_rd.h"
2020-03-31 13:50:25 +02:00
2020-11-07 23:33:38 +01:00
# include "core/config/engine.h"
# include "core/config/project_settings.h"
2020-04-17 04:52:00 +02:00
# include "core/io/resource_loader.h"
2021-05-19 14:12:55 +02:00
# include "core/math/math_defs.h"
2020-12-04 19:26:24 +01:00
# include "renderer_compositor_rd.h"
2022-04-02 07:29:04 +02:00
# include "servers/rendering/renderer_rd/storage_rd/canvas_texture_storage.h"
# include "servers/rendering/renderer_rd/storage_rd/decal_atlas_storage.h"
# include "servers/rendering/renderer_rd/storage_rd/mesh_storage.h"
# include "servers/rendering/renderer_rd/storage_rd/texture_storage.h"
2021-07-01 04:17:47 +02:00
# include "servers/rendering/rendering_server_globals.h"
2020-03-27 19:21:27 +01:00
# include "servers/rendering/shader_language.h"
2019-06-11 20:43:37 +02:00
2022-03-12 12:19:59 +01:00
/* CANVAS TEXTURE */
2020-10-24 17:15:43 +02:00
2021-11-23 22:16:03 +01:00
void RendererStorageRD : : sampler_rd_configure_custom ( float p_mipmap_bias ) {
for ( int i = 1 ; i < RS : : CANVAS_ITEM_TEXTURE_FILTER_MAX ; i + + ) {
for ( int j = 1 ; j < RS : : CANVAS_ITEM_TEXTURE_REPEAT_MAX ; j + + ) {
RD : : SamplerState sampler_state ;
switch ( i ) {
case RS : : CANVAS_ITEM_TEXTURE_FILTER_NEAREST : {
sampler_state . mag_filter = RD : : SAMPLER_FILTER_NEAREST ;
sampler_state . min_filter = RD : : SAMPLER_FILTER_NEAREST ;
sampler_state . max_lod = 0 ;
} break ;
case RS : : CANVAS_ITEM_TEXTURE_FILTER_LINEAR : {
sampler_state . mag_filter = RD : : SAMPLER_FILTER_LINEAR ;
sampler_state . min_filter = RD : : SAMPLER_FILTER_LINEAR ;
sampler_state . max_lod = 0 ;
} break ;
case RS : : CANVAS_ITEM_TEXTURE_FILTER_NEAREST_WITH_MIPMAPS : {
sampler_state . mag_filter = RD : : SAMPLER_FILTER_NEAREST ;
sampler_state . min_filter = RD : : SAMPLER_FILTER_NEAREST ;
if ( GLOBAL_GET ( " rendering/textures/default_filters/use_nearest_mipmap_filter " ) ) {
sampler_state . mip_filter = RD : : SAMPLER_FILTER_NEAREST ;
} else {
sampler_state . mip_filter = RD : : SAMPLER_FILTER_LINEAR ;
}
sampler_state . lod_bias = p_mipmap_bias ;
} break ;
case RS : : CANVAS_ITEM_TEXTURE_FILTER_LINEAR_WITH_MIPMAPS : {
sampler_state . mag_filter = RD : : SAMPLER_FILTER_LINEAR ;
sampler_state . min_filter = RD : : SAMPLER_FILTER_LINEAR ;
if ( GLOBAL_GET ( " rendering/textures/default_filters/use_nearest_mipmap_filter " ) ) {
sampler_state . mip_filter = RD : : SAMPLER_FILTER_NEAREST ;
} else {
sampler_state . mip_filter = RD : : SAMPLER_FILTER_LINEAR ;
}
sampler_state . lod_bias = p_mipmap_bias ;
} break ;
case RS : : CANVAS_ITEM_TEXTURE_FILTER_NEAREST_WITH_MIPMAPS_ANISOTROPIC : {
sampler_state . mag_filter = RD : : SAMPLER_FILTER_NEAREST ;
sampler_state . min_filter = RD : : SAMPLER_FILTER_NEAREST ;
if ( GLOBAL_GET ( " rendering/textures/default_filters/use_nearest_mipmap_filter " ) ) {
sampler_state . mip_filter = RD : : SAMPLER_FILTER_NEAREST ;
} else {
sampler_state . mip_filter = RD : : SAMPLER_FILTER_LINEAR ;
}
sampler_state . lod_bias = p_mipmap_bias ;
sampler_state . use_anisotropy = true ;
sampler_state . anisotropy_max = 1 < < int ( GLOBAL_GET ( " rendering/textures/default_filters/anisotropic_filtering_level " ) ) ;
} break ;
case RS : : CANVAS_ITEM_TEXTURE_FILTER_LINEAR_WITH_MIPMAPS_ANISOTROPIC : {
sampler_state . mag_filter = RD : : SAMPLER_FILTER_LINEAR ;
sampler_state . min_filter = RD : : SAMPLER_FILTER_LINEAR ;
if ( GLOBAL_GET ( " rendering/textures/default_filters/use_nearest_mipmap_filter " ) ) {
sampler_state . mip_filter = RD : : SAMPLER_FILTER_NEAREST ;
} else {
sampler_state . mip_filter = RD : : SAMPLER_FILTER_LINEAR ;
}
sampler_state . lod_bias = p_mipmap_bias ;
sampler_state . use_anisotropy = true ;
sampler_state . anisotropy_max = 1 < < int ( GLOBAL_GET ( " rendering/textures/default_filters/anisotropic_filtering_level " ) ) ;
} break ;
default : {
}
}
switch ( j ) {
case RS : : CANVAS_ITEM_TEXTURE_REPEAT_DISABLED : {
sampler_state . repeat_u = RD : : SAMPLER_REPEAT_MODE_CLAMP_TO_EDGE ;
sampler_state . repeat_v = RD : : SAMPLER_REPEAT_MODE_CLAMP_TO_EDGE ;
sampler_state . repeat_w = RD : : SAMPLER_REPEAT_MODE_CLAMP_TO_EDGE ;
} break ;
case RS : : CANVAS_ITEM_TEXTURE_REPEAT_ENABLED : {
sampler_state . repeat_u = RD : : SAMPLER_REPEAT_MODE_REPEAT ;
sampler_state . repeat_v = RD : : SAMPLER_REPEAT_MODE_REPEAT ;
sampler_state . repeat_w = RD : : SAMPLER_REPEAT_MODE_REPEAT ;
} break ;
case RS : : CANVAS_ITEM_TEXTURE_REPEAT_MIRROR : {
sampler_state . repeat_u = RD : : SAMPLER_REPEAT_MODE_MIRRORED_REPEAT ;
sampler_state . repeat_v = RD : : SAMPLER_REPEAT_MODE_MIRRORED_REPEAT ;
sampler_state . repeat_w = RD : : SAMPLER_REPEAT_MODE_MIRRORED_REPEAT ;
} break ;
default : {
}
}
if ( custom_rd_samplers [ i ] [ j ] . is_valid ( ) ) {
RD : : get_singleton ( ) - > free ( custom_rd_samplers [ i ] [ j ] ) ;
}
custom_rd_samplers [ i ] [ j ] = RD : : get_singleton ( ) - > sampler_create ( sampler_state ) ;
}
}
}
2020-08-19 15:38:24 +02:00
/* PARTICLES */
2019-09-23 23:53:05 +02:00
2021-02-09 17:19:03 +01:00
RID RendererStorageRD : : particles_allocate ( ) {
return particles_owner . allocate_rid ( ) ;
}
void RendererStorageRD : : particles_initialize ( RID p_rid ) {
particles_owner . initialize_rid ( p_rid , Particles ( ) ) ;
2020-08-19 15:38:24 +02:00
}
2021-05-10 18:12:44 +02:00
void RendererStorageRD : : particles_set_mode ( RID p_particles , RS : : ParticlesMode p_mode ) {
2021-09-29 19:08:41 +02:00
Particles * particles = particles_owner . get_or_null ( p_particles ) ;
2021-05-10 18:12:44 +02:00
ERR_FAIL_COND ( ! particles ) ;
if ( particles - > mode = = p_mode ) {
return ;
}
_particles_free_data ( particles ) ;
particles - > mode = p_mode ;
}
2020-12-04 19:26:24 +01:00
void RendererStorageRD : : particles_set_emitting ( RID p_particles , bool p_emitting ) {
2021-09-29 19:08:41 +02:00
Particles * particles = particles_owner . get_or_null ( p_particles ) ;
2020-08-19 15:38:24 +02:00
ERR_FAIL_COND ( ! particles ) ;
particles - > emitting = p_emitting ;
}
2020-12-04 19:26:24 +01:00
bool RendererStorageRD : : particles_get_emitting ( RID p_particles ) {
2021-07-01 04:17:47 +02:00
ERR_FAIL_COND_V_MSG ( RSG : : threaded , false , " This function should never be used with threaded rendering, as it stalls the renderer. " ) ;
2021-09-29 19:08:41 +02:00
Particles * particles = particles_owner . get_or_null ( p_particles ) ;
2020-08-19 15:38:24 +02:00
ERR_FAIL_COND_V ( ! particles , false ) ;
return particles - > emitting ;
}
2020-12-04 19:26:24 +01:00
void RendererStorageRD : : _particles_free_data ( Particles * particles ) {
2021-04-27 17:43:49 +02:00
if ( particles - > particle_buffer . is_valid ( ) ) {
RD : : get_singleton ( ) - > free ( particles - > particle_buffer ) ;
particles - > particle_buffer = RID ( ) ;
RD : : get_singleton ( ) - > free ( particles - > particle_instance_buffer ) ;
particles - > particle_instance_buffer = RID ( ) ;
}
2022-02-14 13:27:10 +01:00
particles - > userdata_count = 0 ;
2021-04-27 17:43:49 +02:00
if ( particles - > frame_params_buffer . is_valid ( ) ) {
RD : : get_singleton ( ) - > free ( particles - > frame_params_buffer ) ;
particles - > frame_params_buffer = RID ( ) ;
2020-09-06 14:18:10 +02:00
}
particles - > particles_transforms_buffer_uniform_set = RID ( ) ;
2021-04-27 17:43:49 +02:00
if ( RD : : get_singleton ( ) - > uniform_set_is_valid ( particles - > trail_bind_pose_uniform_set ) ) {
RD : : get_singleton ( ) - > free ( particles - > trail_bind_pose_uniform_set ) ;
}
particles - > trail_bind_pose_uniform_set = RID ( ) ;
if ( particles - > trail_bind_pose_buffer . is_valid ( ) ) {
RD : : get_singleton ( ) - > free ( particles - > trail_bind_pose_buffer ) ;
particles - > trail_bind_pose_buffer = RID ( ) ;
}
2020-10-08 02:29:49 +02:00
if ( RD : : get_singleton ( ) - > uniform_set_is_valid ( particles - > collision_textures_uniform_set ) ) {
RD : : get_singleton ( ) - > free ( particles - > collision_textures_uniform_set ) ;
}
2021-04-27 17:43:49 +02:00
particles - > collision_textures_uniform_set = RID ( ) ;
2020-10-08 02:29:49 +02:00
2020-09-06 14:18:10 +02:00
if ( particles - > particles_sort_buffer . is_valid ( ) ) {
RD : : get_singleton ( ) - > free ( particles - > particles_sort_buffer ) ;
particles - > particles_sort_buffer = RID ( ) ;
2021-04-27 17:43:49 +02:00
particles - > particles_sort_uniform_set = RID ( ) ;
2020-09-06 14:18:10 +02:00
}
if ( particles - > emission_buffer ! = nullptr ) {
particles - > emission_buffer = nullptr ;
particles - > emission_buffer_data . clear ( ) ;
RD : : get_singleton ( ) - > free ( particles - > emission_storage_buffer ) ;
particles - > emission_storage_buffer = RID ( ) ;
}
2021-04-27 17:43:49 +02:00
if ( RD : : get_singleton ( ) - > uniform_set_is_valid ( particles - > particles_material_uniform_set ) ) {
//will need to be re-created
RD : : get_singleton ( ) - > free ( particles - > particles_material_uniform_set ) ;
}
particles - > particles_material_uniform_set = RID ( ) ;
2020-09-06 14:18:10 +02:00
}
2020-12-04 19:26:24 +01:00
void RendererStorageRD : : particles_set_amount ( RID p_particles , int p_amount ) {
2021-09-29 19:08:41 +02:00
Particles * particles = particles_owner . get_or_null ( p_particles ) ;
2020-08-19 15:38:24 +02:00
ERR_FAIL_COND ( ! particles ) ;
2020-09-06 14:18:10 +02:00
if ( particles - > amount = = p_amount ) {
return ;
}
2020-08-19 15:38:24 +02:00
2020-09-06 14:18:10 +02:00
_particles_free_data ( particles ) ;
2020-08-19 15:38:24 +02:00
2020-09-06 14:18:10 +02:00
particles - > amount = p_amount ;
2020-08-19 15:38:24 +02:00
particles - > prev_ticks = 0 ;
particles - > phase = 0 ;
particles - > prev_phase = 0 ;
particles - > clear = true ;
2021-04-27 17:43:49 +02:00
particles - > dependency . changed_notify ( DEPENDENCY_CHANGED_PARTICLES ) ;
2020-08-19 15:38:24 +02:00
}
2021-02-02 03:16:37 +01:00
void RendererStorageRD : : particles_set_lifetime ( RID p_particles , double p_lifetime ) {
2021-09-29 19:08:41 +02:00
Particles * particles = particles_owner . get_or_null ( p_particles ) ;
2020-08-19 15:38:24 +02:00
ERR_FAIL_COND ( ! particles ) ;
particles - > lifetime = p_lifetime ;
}
2020-12-04 19:26:24 +01:00
void RendererStorageRD : : particles_set_one_shot ( RID p_particles , bool p_one_shot ) {
2021-09-29 19:08:41 +02:00
Particles * particles = particles_owner . get_or_null ( p_particles ) ;
2020-08-19 15:38:24 +02:00
ERR_FAIL_COND ( ! particles ) ;
particles - > one_shot = p_one_shot ;
}
2021-02-02 03:16:37 +01:00
void RendererStorageRD : : particles_set_pre_process_time ( RID p_particles , double p_time ) {
2021-09-29 19:08:41 +02:00
Particles * particles = particles_owner . get_or_null ( p_particles ) ;
2020-08-19 15:38:24 +02:00
ERR_FAIL_COND ( ! particles ) ;
particles - > pre_process_time = p_time ;
}
2021-08-12 16:07:47 +02:00
void RendererStorageRD : : particles_set_explosiveness_ratio ( RID p_particles , real_t p_ratio ) {
2021-09-29 19:08:41 +02:00
Particles * particles = particles_owner . get_or_null ( p_particles ) ;
2020-08-19 15:38:24 +02:00
ERR_FAIL_COND ( ! particles ) ;
particles - > explosiveness = p_ratio ;
}
2021-08-12 16:07:47 +02:00
void RendererStorageRD : : particles_set_randomness_ratio ( RID p_particles , real_t p_ratio ) {
2021-09-29 19:08:41 +02:00
Particles * particles = particles_owner . get_or_null ( p_particles ) ;
2020-08-19 15:38:24 +02:00
ERR_FAIL_COND ( ! particles ) ;
particles - > randomness = p_ratio ;
}
2020-12-04 19:26:24 +01:00
void RendererStorageRD : : particles_set_custom_aabb ( RID p_particles , const AABB & p_aabb ) {
2021-09-29 19:08:41 +02:00
Particles * particles = particles_owner . get_or_null ( p_particles ) ;
2020-08-19 15:38:24 +02:00
ERR_FAIL_COND ( ! particles ) ;
particles - > custom_aabb = p_aabb ;
2021-01-04 13:33:25 +01:00
particles - > dependency . changed_notify ( DEPENDENCY_CHANGED_AABB ) ;
2020-08-19 15:38:24 +02:00
}
2021-02-02 03:16:37 +01:00
void RendererStorageRD : : particles_set_speed_scale ( RID p_particles , double p_scale ) {
2021-09-29 19:08:41 +02:00
Particles * particles = particles_owner . get_or_null ( p_particles ) ;
2020-08-19 15:38:24 +02:00
ERR_FAIL_COND ( ! particles ) ;
particles - > speed_scale = p_scale ;
}
2020-12-04 19:26:24 +01:00
void RendererStorageRD : : particles_set_use_local_coordinates ( RID p_particles , bool p_enable ) {
2021-09-29 19:08:41 +02:00
Particles * particles = particles_owner . get_or_null ( p_particles ) ;
2020-08-19 15:38:24 +02:00
ERR_FAIL_COND ( ! particles ) ;
particles - > use_local_coords = p_enable ;
2021-09-25 23:37:16 +02:00
particles - > dependency . changed_notify ( DEPENDENCY_CHANGED_PARTICLES ) ;
2020-08-19 15:38:24 +02:00
}
2020-12-04 19:26:24 +01:00
void RendererStorageRD : : particles_set_fixed_fps ( RID p_particles , int p_fps ) {
2021-09-29 19:08:41 +02:00
Particles * particles = particles_owner . get_or_null ( p_particles ) ;
2020-08-19 15:38:24 +02:00
ERR_FAIL_COND ( ! particles ) ;
particles - > fixed_fps = p_fps ;
2021-04-27 17:43:49 +02:00
_particles_free_data ( particles ) ;
particles - > prev_ticks = 0 ;
particles - > phase = 0 ;
particles - > prev_phase = 0 ;
particles - > clear = true ;
particles - > dependency . changed_notify ( DEPENDENCY_CHANGED_PARTICLES ) ;
}
void RendererStorageRD : : particles_set_interpolate ( RID p_particles , bool p_enable ) {
2021-09-29 19:08:41 +02:00
Particles * particles = particles_owner . get_or_null ( p_particles ) ;
2021-04-27 17:43:49 +02:00
ERR_FAIL_COND ( ! particles ) ;
particles - > interpolate = p_enable ;
2020-08-19 15:38:24 +02:00
}
2020-12-04 19:26:24 +01:00
void RendererStorageRD : : particles_set_fractional_delta ( RID p_particles , bool p_enable ) {
2021-09-29 19:08:41 +02:00
Particles * particles = particles_owner . get_or_null ( p_particles ) ;
2020-08-19 15:38:24 +02:00
ERR_FAIL_COND ( ! particles ) ;
particles - > fractional_delta = p_enable ;
}
2021-08-12 16:07:47 +02:00
void RendererStorageRD : : particles_set_trails ( RID p_particles , bool p_enable , double p_length ) {
2021-09-29 19:08:41 +02:00
Particles * particles = particles_owner . get_or_null ( p_particles ) ;
2021-04-27 17:43:49 +02:00
ERR_FAIL_COND ( ! particles ) ;
ERR_FAIL_COND ( p_length < 0.1 ) ;
p_length = MIN ( 10.0 , p_length ) ;
particles - > trails_enabled = p_enable ;
particles - > trail_length = p_length ;
_particles_free_data ( particles ) ;
particles - > prev_ticks = 0 ;
particles - > phase = 0 ;
particles - > prev_phase = 0 ;
particles - > clear = true ;
particles - > dependency . changed_notify ( DEPENDENCY_CHANGED_PARTICLES ) ;
}
2020-10-17 07:08:21 +02:00
void RendererStorageRD : : particles_set_trail_bind_poses ( RID p_particles , const Vector < Transform3D > & p_bind_poses ) {
2021-09-29 19:08:41 +02:00
Particles * particles = particles_owner . get_or_null ( p_particles ) ;
2021-04-27 17:43:49 +02:00
ERR_FAIL_COND ( ! particles ) ;
if ( particles - > trail_bind_pose_buffer . is_valid ( ) & & particles - > trail_bind_poses . size ( ) ! = p_bind_poses . size ( ) ) {
_particles_free_data ( particles ) ;
particles - > prev_ticks = 0 ;
particles - > phase = 0 ;
particles - > prev_phase = 0 ;
particles - > clear = true ;
}
particles - > trail_bind_poses = p_bind_poses ;
particles - > trail_bind_poses_dirty = true ;
particles - > dependency . changed_notify ( DEPENDENCY_CHANGED_PARTICLES ) ;
}
2021-08-12 16:07:47 +02:00
void RendererStorageRD : : particles_set_collision_base_size ( RID p_particles , real_t p_size ) {
2021-09-29 19:08:41 +02:00
Particles * particles = particles_owner . get_or_null ( p_particles ) ;
2020-10-08 02:29:49 +02:00
ERR_FAIL_COND ( ! particles ) ;
particles - > collision_base_size = p_size ;
}
2021-04-27 17:43:49 +02:00
void RendererStorageRD : : particles_set_transform_align ( RID p_particles , RS : : ParticlesTransformAlign p_transform_align ) {
2021-09-29 19:08:41 +02:00
Particles * particles = particles_owner . get_or_null ( p_particles ) ;
2021-04-27 17:43:49 +02:00
ERR_FAIL_COND ( ! particles ) ;
particles - > transform_align = p_transform_align ;
}
2020-12-04 19:26:24 +01:00
void RendererStorageRD : : particles_set_process_material ( RID p_particles , RID p_material ) {
2021-09-29 19:08:41 +02:00
Particles * particles = particles_owner . get_or_null ( p_particles ) ;
2020-08-19 15:38:24 +02:00
ERR_FAIL_COND ( ! particles ) ;
particles - > process_material = p_material ;
2022-02-14 13:27:10 +01:00
particles - > dependency . changed_notify ( DEPENDENCY_CHANGED_PARTICLES ) ; //the instance buffer may have changed
}
RID RendererStorageRD : : particles_get_process_material ( RID p_particles ) const {
Particles * particles = particles_owner . get_or_null ( p_particles ) ;
ERR_FAIL_COND_V ( ! particles , RID ( ) ) ;
return particles - > process_material ;
2020-08-19 15:38:24 +02:00
}
2020-12-04 19:26:24 +01:00
void RendererStorageRD : : particles_set_draw_order ( RID p_particles , RS : : ParticlesDrawOrder p_order ) {
2021-09-29 19:08:41 +02:00
Particles * particles = particles_owner . get_or_null ( p_particles ) ;
2020-08-19 15:38:24 +02:00
ERR_FAIL_COND ( ! particles ) ;
particles - > draw_order = p_order ;
}
2020-12-04 19:26:24 +01:00
void RendererStorageRD : : particles_set_draw_passes ( RID p_particles , int p_passes ) {
2021-09-29 19:08:41 +02:00
Particles * particles = particles_owner . get_or_null ( p_particles ) ;
2020-08-19 15:38:24 +02:00
ERR_FAIL_COND ( ! particles ) ;
particles - > draw_passes . resize ( p_passes ) ;
}
2020-12-04 19:26:24 +01:00
void RendererStorageRD : : particles_set_draw_pass_mesh ( RID p_particles , int p_pass , RID p_mesh ) {
2021-09-29 19:08:41 +02:00
Particles * particles = particles_owner . get_or_null ( p_particles ) ;
2020-08-19 15:38:24 +02:00
ERR_FAIL_COND ( ! particles ) ;
ERR_FAIL_INDEX ( p_pass , particles - > draw_passes . size ( ) ) ;
particles - > draw_passes . write [ p_pass ] = p_mesh ;
}
2020-12-04 19:26:24 +01:00
void RendererStorageRD : : particles_restart ( RID p_particles ) {
2021-09-29 19:08:41 +02:00
Particles * particles = particles_owner . get_or_null ( p_particles ) ;
2020-08-19 15:38:24 +02:00
ERR_FAIL_COND ( ! particles ) ;
particles - > restart_request = true ;
}
2020-12-04 19:26:24 +01:00
void RendererStorageRD : : _particles_allocate_emission_buffer ( Particles * particles ) {
2020-09-06 14:18:10 +02:00
ERR_FAIL_COND ( particles - > emission_buffer ! = nullptr ) ;
particles - > emission_buffer_data . resize ( sizeof ( ParticleEmissionBuffer : : Data ) * particles - > amount + sizeof ( uint32_t ) * 4 ) ;
2021-04-27 16:19:21 +02:00
memset ( particles - > emission_buffer_data . ptrw ( ) , 0 , particles - > emission_buffer_data . size ( ) ) ;
2022-04-05 12:40:26 +02:00
particles - > emission_buffer = reinterpret_cast < ParticleEmissionBuffer * > ( particles - > emission_buffer_data . ptrw ( ) ) ;
2020-09-06 14:18:10 +02:00
particles - > emission_buffer - > particle_max = particles - > amount ;
particles - > emission_storage_buffer = RD : : get_singleton ( ) - > storage_buffer_create ( particles - > emission_buffer_data . size ( ) , particles - > emission_buffer_data ) ;
if ( RD : : get_singleton ( ) - > uniform_set_is_valid ( particles - > particles_material_uniform_set ) ) {
//will need to be re-created
RD : : get_singleton ( ) - > free ( particles - > particles_material_uniform_set ) ;
particles - > particles_material_uniform_set = RID ( ) ;
}
}
2020-12-04 19:26:24 +01:00
void RendererStorageRD : : particles_set_subemitter ( RID p_particles , RID p_subemitter_particles ) {
2021-09-29 19:08:41 +02:00
Particles * particles = particles_owner . get_or_null ( p_particles ) ;
2020-09-06 14:18:10 +02:00
ERR_FAIL_COND ( ! particles ) ;
ERR_FAIL_COND ( p_particles = = p_subemitter_particles ) ;
particles - > sub_emitter = p_subemitter_particles ;
if ( RD : : get_singleton ( ) - > uniform_set_is_valid ( particles - > particles_material_uniform_set ) ) {
RD : : get_singleton ( ) - > free ( particles - > particles_material_uniform_set ) ;
particles - > particles_material_uniform_set = RID ( ) ; //clear and force to re create sub emitting
}
}
2020-10-17 07:08:21 +02:00
void RendererStorageRD : : particles_emit ( RID p_particles , const Transform3D & p_transform , const Vector3 & p_velocity , const Color & p_color , const Color & p_custom , uint32_t p_emit_flags ) {
2021-09-29 19:08:41 +02:00
Particles * particles = particles_owner . get_or_null ( p_particles ) ;
2020-09-06 14:18:10 +02:00
ERR_FAIL_COND ( ! particles ) ;
ERR_FAIL_COND ( particles - > amount = = 0 ) ;
if ( particles - > emitting ) {
particles - > clear = true ;
particles - > emitting = false ;
}
if ( particles - > emission_buffer = = nullptr ) {
_particles_allocate_emission_buffer ( particles ) ;
}
if ( particles - > inactive ) {
//in case it was inactive, make active again
particles - > inactive = false ;
particles - > inactive_time = 0 ;
}
int32_t idx = particles - > emission_buffer - > particle_count ;
if ( idx < particles - > emission_buffer - > particle_max ) {
store_transform ( p_transform , particles - > emission_buffer - > data [ idx ] . xform ) ;
particles - > emission_buffer - > data [ idx ] . velocity [ 0 ] = p_velocity . x ;
particles - > emission_buffer - > data [ idx ] . velocity [ 1 ] = p_velocity . y ;
particles - > emission_buffer - > data [ idx ] . velocity [ 2 ] = p_velocity . z ;
particles - > emission_buffer - > data [ idx ] . custom [ 0 ] = p_custom . r ;
particles - > emission_buffer - > data [ idx ] . custom [ 1 ] = p_custom . g ;
particles - > emission_buffer - > data [ idx ] . custom [ 2 ] = p_custom . b ;
particles - > emission_buffer - > data [ idx ] . custom [ 3 ] = p_custom . a ;
particles - > emission_buffer - > data [ idx ] . color [ 0 ] = p_color . r ;
particles - > emission_buffer - > data [ idx ] . color [ 1 ] = p_color . g ;
particles - > emission_buffer - > data [ idx ] . color [ 2 ] = p_color . b ;
particles - > emission_buffer - > data [ idx ] . color [ 3 ] = p_color . a ;
particles - > emission_buffer - > data [ idx ] . flags = p_emit_flags ;
particles - > emission_buffer - > particle_count + + ;
}
}
2020-12-04 19:26:24 +01:00
void RendererStorageRD : : particles_request_process ( RID p_particles ) {
2021-09-29 19:08:41 +02:00
Particles * particles = particles_owner . get_or_null ( p_particles ) ;
2020-08-19 15:38:24 +02:00
ERR_FAIL_COND ( ! particles ) ;
if ( ! particles - > dirty ) {
particles - > dirty = true ;
particles - > update_list = particle_update_list ;
particle_update_list = particles ;
}
}
2020-12-04 19:26:24 +01:00
AABB RendererStorageRD : : particles_get_current_aabb ( RID p_particles ) {
2021-07-01 04:17:47 +02:00
if ( RSG : : threaded ) {
WARN_PRINT_ONCE ( " Calling this function with threaded rendering enabled stalls the renderer, use with care. " ) ;
}
2021-09-29 19:08:41 +02:00
const Particles * particles = particles_owner . get_or_null ( p_particles ) ;
2020-08-19 15:38:24 +02:00
ERR_FAIL_COND_V ( ! particles , AABB ( ) ) ;
2021-04-27 17:43:49 +02:00
int total_amount = particles - > amount ;
if ( particles - > trails_enabled & & particles - > trail_bind_poses . size ( ) > 1 ) {
total_amount * = particles - > trail_bind_poses . size ( ) ;
}
2020-08-19 15:38:24 +02:00
Vector < uint8_t > buffer = RD : : get_singleton ( ) - > buffer_get_data ( particles - > particle_buffer ) ;
2021-09-25 17:35:56 +02:00
ERR_FAIL_COND_V ( buffer . size ( ) ! = ( int ) ( total_amount * sizeof ( ParticleData ) ) , AABB ( ) ) ;
2020-08-19 15:38:24 +02:00
2020-10-17 07:08:21 +02:00
Transform3D inv = particles - > emission_transform . affine_inverse ( ) ;
2020-08-19 15:38:24 +02:00
AABB aabb ;
if ( buffer . size ( ) ) {
bool first = true ;
2021-04-27 17:43:49 +02:00
2022-02-14 13:27:10 +01:00
const uint8_t * data_ptr = ( const uint8_t * ) buffer . ptr ( ) ;
uint32_t particle_data_size = sizeof ( ParticleData ) + sizeof ( float ) * particles - > userdata_count ;
2021-04-27 17:43:49 +02:00
for ( int i = 0 ; i < total_amount ; i + + ) {
2022-02-14 13:27:10 +01:00
const ParticleData & particle_data = * ( const ParticleData * ) & data_ptr [ particle_data_size * i ] ;
if ( particle_data . active ) {
Vector3 pos = Vector3 ( particle_data . xform [ 12 ] , particle_data . xform [ 13 ] , particle_data . xform [ 14 ] ) ;
2020-08-19 15:38:24 +02:00
if ( ! particles - > use_local_coords ) {
pos = inv . xform ( pos ) ;
}
if ( first ) {
aabb . position = pos ;
first = false ;
} else {
aabb . expand_to ( pos ) ;
}
}
}
}
float longest_axis_size = 0 ;
for ( int i = 0 ; i < particles - > draw_passes . size ( ) ; i + + ) {
if ( particles - > draw_passes [ i ] . is_valid ( ) ) {
2022-04-02 07:29:04 +02:00
AABB maabb = RendererRD : : MeshStorage : : get_singleton ( ) - > mesh_get_aabb ( particles - > draw_passes [ i ] , RID ( ) ) ;
2020-08-19 15:38:24 +02:00
longest_axis_size = MAX ( maabb . get_longest_axis_size ( ) , longest_axis_size ) ;
}
}
aabb . grow_by ( longest_axis_size ) ;
return aabb ;
}
2020-12-04 19:26:24 +01:00
AABB RendererStorageRD : : particles_get_aabb ( RID p_particles ) const {
2021-09-29 19:08:41 +02:00
const Particles * particles = particles_owner . get_or_null ( p_particles ) ;
2020-08-19 15:38:24 +02:00
ERR_FAIL_COND_V ( ! particles , AABB ( ) ) ;
return particles - > custom_aabb ;
}
2020-10-17 07:08:21 +02:00
void RendererStorageRD : : particles_set_emission_transform ( RID p_particles , const Transform3D & p_transform ) {
2021-09-29 19:08:41 +02:00
Particles * particles = particles_owner . get_or_null ( p_particles ) ;
2020-08-19 15:38:24 +02:00
ERR_FAIL_COND ( ! particles ) ;
particles - > emission_transform = p_transform ;
}
2020-12-04 19:26:24 +01:00
int RendererStorageRD : : particles_get_draw_passes ( RID p_particles ) const {
2021-09-29 19:08:41 +02:00
const Particles * particles = particles_owner . get_or_null ( p_particles ) ;
2020-08-19 15:38:24 +02:00
ERR_FAIL_COND_V ( ! particles , 0 ) ;
return particles - > draw_passes . size ( ) ;
}
2020-12-04 19:26:24 +01:00
RID RendererStorageRD : : particles_get_draw_pass_mesh ( RID p_particles , int p_pass ) const {
2021-09-29 19:08:41 +02:00
const Particles * particles = particles_owner . get_or_null ( p_particles ) ;
2020-08-19 15:38:24 +02:00
ERR_FAIL_COND_V ( ! particles , RID ( ) ) ;
ERR_FAIL_INDEX_V ( p_pass , particles - > draw_passes . size ( ) , RID ( ) ) ;
return particles - > draw_passes [ p_pass ] ;
}
2020-12-31 13:42:56 +01:00
void RendererStorageRD : : particles_add_collision ( RID p_particles , RID p_particles_collision_instance ) {
2021-09-29 19:08:41 +02:00
Particles * particles = particles_owner . get_or_null ( p_particles ) ;
2020-10-08 02:29:49 +02:00
ERR_FAIL_COND ( ! particles ) ;
2020-12-31 13:42:56 +01:00
particles - > collisions . insert ( p_particles_collision_instance ) ;
2020-10-08 02:29:49 +02:00
}
2020-12-31 13:42:56 +01:00
void RendererStorageRD : : particles_remove_collision ( RID p_particles , RID p_particles_collision_instance ) {
2021-09-29 19:08:41 +02:00
Particles * particles = particles_owner . get_or_null ( p_particles ) ;
2020-10-08 02:29:49 +02:00
ERR_FAIL_COND ( ! particles ) ;
2020-12-31 13:42:56 +01:00
particles - > collisions . erase ( p_particles_collision_instance ) ;
2020-10-08 02:29:49 +02:00
}
2021-05-20 16:25:06 +02:00
void RendererStorageRD : : particles_set_canvas_sdf_collision ( RID p_particles , bool p_enable , const Transform2D & p_xform , const Rect2 & p_to_screen , RID p_texture ) {
2021-09-29 19:08:41 +02:00
Particles * particles = particles_owner . get_or_null ( p_particles ) ;
2021-05-20 16:25:06 +02:00
ERR_FAIL_COND ( ! particles ) ;
particles - > has_sdf_collision = p_enable ;
particles - > sdf_collision_transform = p_xform ;
particles - > sdf_collision_to_screen = p_to_screen ;
particles - > sdf_collision_texture = p_texture ;
}
2021-02-02 03:16:37 +01:00
void RendererStorageRD : : _particles_process ( Particles * p_particles , double p_delta ) {
2022-03-12 12:19:59 +01:00
RendererRD : : TextureStorage * texture_storage = RendererRD : : TextureStorage : : get_singleton ( ) ;
2022-03-21 12:25:25 +01:00
RendererRD : : MaterialStorage * material_storage = RendererRD : : MaterialStorage : : get_singleton ( ) ;
2022-03-12 12:19:59 +01:00
2020-09-06 14:18:10 +02:00
if ( p_particles - > particles_material_uniform_set . is_null ( ) | | ! RD : : get_singleton ( ) - > uniform_set_is_valid ( p_particles - > particles_material_uniform_set ) ) {
Vector < RD : : Uniform > uniforms ;
{
RD : : Uniform u ;
2020-10-17 03:19:21 +02:00
u . uniform_type = RD : : UNIFORM_TYPE_STORAGE_BUFFER ;
2020-09-06 14:18:10 +02:00
u . binding = 0 ;
2022-03-06 12:57:09 +01:00
u . append_id ( p_particles - > frame_params_buffer ) ;
2020-09-06 14:18:10 +02:00
uniforms . push_back ( u ) ;
}
{
RD : : Uniform u ;
2020-10-17 03:19:21 +02:00
u . uniform_type = RD : : UNIFORM_TYPE_STORAGE_BUFFER ;
2020-09-06 14:18:10 +02:00
u . binding = 1 ;
2022-03-06 12:57:09 +01:00
u . append_id ( p_particles - > particle_buffer ) ;
2020-09-06 14:18:10 +02:00
uniforms . push_back ( u ) ;
}
{
RD : : Uniform u ;
2020-10-17 03:19:21 +02:00
u . uniform_type = RD : : UNIFORM_TYPE_STORAGE_BUFFER ;
2020-09-06 14:18:10 +02:00
u . binding = 2 ;
if ( p_particles - > emission_storage_buffer . is_valid ( ) ) {
2022-03-06 12:57:09 +01:00
u . append_id ( p_particles - > emission_storage_buffer ) ;
2020-09-06 14:18:10 +02:00
} else {
2022-04-02 07:29:04 +02:00
u . append_id ( RendererRD : : MeshStorage : : get_singleton ( ) - > get_default_rd_storage_buffer ( ) ) ;
2020-09-06 14:18:10 +02:00
}
uniforms . push_back ( u ) ;
}
{
RD : : Uniform u ;
2020-10-17 03:19:21 +02:00
u . uniform_type = RD : : UNIFORM_TYPE_STORAGE_BUFFER ;
2020-09-06 14:18:10 +02:00
u . binding = 3 ;
2021-09-29 19:08:41 +02:00
Particles * sub_emitter = particles_owner . get_or_null ( p_particles - > sub_emitter ) ;
2020-09-06 14:18:10 +02:00
if ( sub_emitter ) {
if ( sub_emitter - > emission_buffer = = nullptr ) { //no emission buffer, allocate emission buffer
_particles_allocate_emission_buffer ( sub_emitter ) ;
}
2022-03-06 12:57:09 +01:00
u . append_id ( sub_emitter - > emission_storage_buffer ) ;
2020-09-06 14:18:10 +02:00
} else {
2022-04-02 07:29:04 +02:00
u . append_id ( RendererRD : : MeshStorage : : get_singleton ( ) - > get_default_rd_storage_buffer ( ) ) ;
2020-09-06 14:18:10 +02:00
}
uniforms . push_back ( u ) ;
}
p_particles - > particles_material_uniform_set = RD : : get_singleton ( ) - > uniform_set_create ( uniforms , particles_shader . default_shader_rd , 1 ) ;
}
2021-02-02 03:16:37 +01:00
double new_phase = Math : : fmod ( ( double ) p_particles - > phase + ( p_delta / p_particles - > lifetime ) * p_particles - > speed_scale , 1.0 ) ;
2020-08-19 15:38:24 +02:00
2021-04-27 17:43:49 +02:00
//move back history (if there is any)
for ( uint32_t i = p_particles - > frame_history . size ( ) - 1 ; i > 0 ; i - - ) {
p_particles - > frame_history [ i ] = p_particles - > frame_history [ i - 1 ] ;
}
//update current frame
ParticlesFrameParams & frame_params = p_particles - > frame_history [ 0 ] ;
2020-08-19 15:38:24 +02:00
if ( p_particles - > clear ) {
p_particles - > cycle_number = 0 ;
p_particles - > random_seed = Math : : rand ( ) ;
} else if ( new_phase < p_particles - > phase ) {
if ( p_particles - > one_shot ) {
p_particles - > emitting = false ;
}
p_particles - > cycle_number + + ;
}
frame_params . emitting = p_particles - > emitting ;
frame_params . system_phase = new_phase ;
frame_params . prev_system_phase = p_particles - > phase ;
p_particles - > phase = new_phase ;
2020-12-04 19:26:24 +01:00
frame_params . time = RendererCompositorRD : : singleton - > get_total_time ( ) ;
2020-08-19 15:38:24 +02:00
frame_params . delta = p_delta * p_particles - > speed_scale ;
frame_params . random_seed = p_particles - > random_seed ;
frame_params . explosiveness = p_particles - > explosiveness ;
frame_params . randomness = p_particles - > randomness ;
if ( p_particles - > use_local_coords ) {
2020-10-17 07:08:21 +02:00
store_transform ( Transform3D ( ) , frame_params . emission_transform ) ;
2020-08-19 15:38:24 +02:00
} else {
store_transform ( p_particles - > emission_transform , frame_params . emission_transform ) ;
}
frame_params . cycle = p_particles - > cycle_number ;
2021-04-27 17:43:49 +02:00
frame_params . frame = p_particles - > frame_counter + + ;
frame_params . pad0 = 0 ;
frame_params . pad1 = 0 ;
frame_params . pad2 = 0 ;
2020-08-19 15:38:24 +02:00
2020-10-08 02:29:49 +02:00
{ //collision and attractors
frame_params . collider_count = 0 ;
frame_params . attractor_count = 0 ;
frame_params . particle_size = p_particles - > collision_base_size ;
RID collision_3d_textures [ ParticlesFrameParams : : MAX_3D_TEXTURES ] ;
RID collision_heightmap_texture ;
2020-10-17 07:08:21 +02:00
Transform3D to_particles ;
2020-10-08 02:29:49 +02:00
if ( p_particles - > use_local_coords ) {
to_particles = p_particles - > emission_transform . affine_inverse ( ) ;
}
2021-05-20 16:25:06 +02:00
if ( p_particles - > has_sdf_collision & & RD : : get_singleton ( ) - > texture_is_valid ( p_particles - > sdf_collision_texture ) ) {
//2D collision
Transform2D xform = p_particles - > sdf_collision_transform ; //will use dotproduct manually so invert beforehand
Transform2D revert = xform . affine_inverse ( ) ;
frame_params . collider_count = 1 ;
frame_params . colliders [ 0 ] . transform [ 0 ] = xform . elements [ 0 ] [ 0 ] ;
frame_params . colliders [ 0 ] . transform [ 1 ] = xform . elements [ 0 ] [ 1 ] ;
frame_params . colliders [ 0 ] . transform [ 2 ] = 0 ;
frame_params . colliders [ 0 ] . transform [ 3 ] = xform . elements [ 2 ] [ 0 ] ;
frame_params . colliders [ 0 ] . transform [ 4 ] = xform . elements [ 1 ] [ 0 ] ;
frame_params . colliders [ 0 ] . transform [ 5 ] = xform . elements [ 1 ] [ 1 ] ;
frame_params . colliders [ 0 ] . transform [ 6 ] = 0 ;
frame_params . colliders [ 0 ] . transform [ 7 ] = xform . elements [ 2 ] [ 1 ] ;
frame_params . colliders [ 0 ] . transform [ 8 ] = revert . elements [ 0 ] [ 0 ] ;
frame_params . colliders [ 0 ] . transform [ 9 ] = revert . elements [ 0 ] [ 1 ] ;
frame_params . colliders [ 0 ] . transform [ 10 ] = 0 ;
frame_params . colliders [ 0 ] . transform [ 11 ] = revert . elements [ 2 ] [ 0 ] ;
frame_params . colliders [ 0 ] . transform [ 12 ] = revert . elements [ 1 ] [ 0 ] ;
frame_params . colliders [ 0 ] . transform [ 13 ] = revert . elements [ 1 ] [ 1 ] ;
frame_params . colliders [ 0 ] . transform [ 14 ] = 0 ;
frame_params . colliders [ 0 ] . transform [ 15 ] = revert . elements [ 2 ] [ 1 ] ;
frame_params . colliders [ 0 ] . extents [ 0 ] = p_particles - > sdf_collision_to_screen . size . x ;
frame_params . colliders [ 0 ] . extents [ 1 ] = p_particles - > sdf_collision_to_screen . size . y ;
frame_params . colliders [ 0 ] . extents [ 2 ] = p_particles - > sdf_collision_to_screen . position . x ;
frame_params . colliders [ 0 ] . scale = p_particles - > sdf_collision_to_screen . position . y ;
frame_params . colliders [ 0 ] . texture_index = 0 ;
frame_params . colliders [ 0 ] . type = ParticlesFrameParams : : COLLISION_TYPE_2D_SDF ;
collision_heightmap_texture = p_particles - > sdf_collision_texture ;
//replace in all other history frames where used because parameters are no longer valid if screen moves
for ( uint32_t i = 1 ; i < p_particles - > frame_history . size ( ) ; i + + ) {
if ( p_particles - > frame_history [ i ] . collider_count > 0 & & p_particles - > frame_history [ i ] . colliders [ 0 ] . type = = ParticlesFrameParams : : COLLISION_TYPE_2D_SDF ) {
p_particles - > frame_history [ i ] . colliders [ 0 ] = frame_params . colliders [ 0 ] ;
}
}
}
2020-10-08 02:29:49 +02:00
uint32_t collision_3d_textures_used = 0 ;
2020-12-31 13:42:56 +01:00
for ( const Set < RID > : : Element * E = p_particles - > collisions . front ( ) ; E ; E = E - > next ( ) ) {
2021-09-29 19:08:41 +02:00
ParticlesCollisionInstance * pci = particles_collision_instance_owner . get_or_null ( E - > get ( ) ) ;
2020-12-31 13:42:56 +01:00
if ( ! pci | | ! pci - > active ) {
continue ;
}
2021-09-29 19:08:41 +02:00
ParticlesCollision * pc = particles_collision_owner . get_or_null ( pci - > collision ) ;
2020-12-31 13:42:56 +01:00
ERR_CONTINUE ( ! pc ) ;
2020-10-17 07:08:21 +02:00
Transform3D to_collider = pci - > transform ;
2020-10-08 02:29:49 +02:00
if ( p_particles - > use_local_coords ) {
to_collider = to_particles * to_collider ;
}
Vector3 scale = to_collider . basis . get_scale ( ) ;
to_collider . basis . orthonormalize ( ) ;
if ( pc - > type < = RS : : PARTICLES_COLLISION_TYPE_VECTOR_FIELD_ATTRACT ) {
//attractor
if ( frame_params . attractor_count > = ParticlesFrameParams : : MAX_ATTRACTORS ) {
continue ;
}
ParticlesFrameParams : : Attractor & attr = frame_params . attractors [ frame_params . attractor_count ] ;
store_transform ( to_collider , attr . transform ) ;
attr . strength = pc - > attractor_strength ;
attr . attenuation = pc - > attractor_attenuation ;
attr . directionality = pc - > attractor_directionality ;
switch ( pc - > type ) {
case RS : : PARTICLES_COLLISION_TYPE_SPHERE_ATTRACT : {
attr . type = ParticlesFrameParams : : ATTRACTOR_TYPE_SPHERE ;
float radius = pc - > radius ;
radius * = ( scale . x + scale . y + scale . z ) / 3.0 ;
attr . extents [ 0 ] = radius ;
attr . extents [ 1 ] = radius ;
attr . extents [ 2 ] = radius ;
} break ;
case RS : : PARTICLES_COLLISION_TYPE_BOX_ATTRACT : {
attr . type = ParticlesFrameParams : : ATTRACTOR_TYPE_BOX ;
Vector3 extents = pc - > extents * scale ;
attr . extents [ 0 ] = extents . x ;
attr . extents [ 1 ] = extents . y ;
attr . extents [ 2 ] = extents . z ;
} break ;
case RS : : PARTICLES_COLLISION_TYPE_VECTOR_FIELD_ATTRACT : {
if ( collision_3d_textures_used > = ParticlesFrameParams : : MAX_3D_TEXTURES ) {
continue ;
}
attr . type = ParticlesFrameParams : : ATTRACTOR_TYPE_VECTOR_FIELD ;
Vector3 extents = pc - > extents * scale ;
attr . extents [ 0 ] = extents . x ;
attr . extents [ 1 ] = extents . y ;
attr . extents [ 2 ] = extents . z ;
attr . texture_index = collision_3d_textures_used ;
collision_3d_textures [ collision_3d_textures_used ] = pc - > field_texture ;
collision_3d_textures_used + + ;
} break ;
default : {
}
}
frame_params . attractor_count + + ;
} else {
//collider
if ( frame_params . collider_count > = ParticlesFrameParams : : MAX_COLLIDERS ) {
continue ;
}
ParticlesFrameParams : : Collider & col = frame_params . colliders [ frame_params . collider_count ] ;
store_transform ( to_collider , col . transform ) ;
switch ( pc - > type ) {
case RS : : PARTICLES_COLLISION_TYPE_SPHERE_COLLIDE : {
col . type = ParticlesFrameParams : : COLLISION_TYPE_SPHERE ;
float radius = pc - > radius ;
radius * = ( scale . x + scale . y + scale . z ) / 3.0 ;
col . extents [ 0 ] = radius ;
col . extents [ 1 ] = radius ;
col . extents [ 2 ] = radius ;
} break ;
case RS : : PARTICLES_COLLISION_TYPE_BOX_COLLIDE : {
col . type = ParticlesFrameParams : : COLLISION_TYPE_BOX ;
Vector3 extents = pc - > extents * scale ;
col . extents [ 0 ] = extents . x ;
col . extents [ 1 ] = extents . y ;
col . extents [ 2 ] = extents . z ;
} break ;
case RS : : PARTICLES_COLLISION_TYPE_SDF_COLLIDE : {
if ( collision_3d_textures_used > = ParticlesFrameParams : : MAX_3D_TEXTURES ) {
continue ;
}
col . type = ParticlesFrameParams : : COLLISION_TYPE_SDF ;
Vector3 extents = pc - > extents * scale ;
col . extents [ 0 ] = extents . x ;
col . extents [ 1 ] = extents . y ;
col . extents [ 2 ] = extents . z ;
col . texture_index = collision_3d_textures_used ;
col . scale = ( scale . x + scale . y + scale . z ) * 0.333333333333 ; //non uniform scale non supported
collision_3d_textures [ collision_3d_textures_used ] = pc - > field_texture ;
collision_3d_textures_used + + ;
} break ;
case RS : : PARTICLES_COLLISION_TYPE_HEIGHTFIELD_COLLIDE : {
if ( collision_heightmap_texture ! = RID ( ) ) { //already taken
continue ;
}
col . type = ParticlesFrameParams : : COLLISION_TYPE_HEIGHT_FIELD ;
Vector3 extents = pc - > extents * scale ;
col . extents [ 0 ] = extents . x ;
col . extents [ 1 ] = extents . y ;
col . extents [ 2 ] = extents . z ;
collision_heightmap_texture = pc - > heightfield_texture ;
} break ;
default : {
}
}
frame_params . collider_count + + ;
}
}
bool different = false ;
if ( collision_3d_textures_used = = p_particles - > collision_3d_textures_used ) {
for ( int i = 0 ; i < ParticlesFrameParams : : MAX_3D_TEXTURES ; i + + ) {
if ( p_particles - > collision_3d_textures [ i ] ! = collision_3d_textures [ i ] ) {
different = true ;
break ;
}
}
}
if ( collision_heightmap_texture ! = p_particles - > collision_heightmap_texture ) {
different = true ;
}
bool uniform_set_valid = RD : : get_singleton ( ) - > uniform_set_is_valid ( p_particles - > collision_textures_uniform_set ) ;
if ( different | | ! uniform_set_valid ) {
if ( uniform_set_valid ) {
RD : : get_singleton ( ) - > free ( p_particles - > collision_textures_uniform_set ) ;
}
Vector < RD : : Uniform > uniforms ;
{
RD : : Uniform u ;
2020-10-17 03:19:21 +02:00
u . uniform_type = RD : : UNIFORM_TYPE_TEXTURE ;
2020-10-08 02:29:49 +02:00
u . binding = 0 ;
for ( uint32_t i = 0 ; i < ParticlesFrameParams : : MAX_3D_TEXTURES ; i + + ) {
RID rd_tex ;
if ( i < collision_3d_textures_used ) {
2022-03-12 12:19:59 +01:00
RendererRD : : Texture * t = RendererRD : : TextureStorage : : get_singleton ( ) - > get_texture ( collision_3d_textures [ i ] ) ;
if ( t & & t - > type = = RendererRD : : Texture : : TYPE_3D ) {
2020-10-08 02:29:49 +02:00
rd_tex = t - > rd_texture ;
}
}
if ( rd_tex = = RID ( ) ) {
2022-03-12 12:19:59 +01:00
rd_tex = texture_storage - > texture_rd_get_default ( RendererRD : : DEFAULT_RD_TEXTURE_3D_WHITE ) ;
2020-10-08 02:29:49 +02:00
}
2022-03-06 12:57:09 +01:00
u . append_id ( rd_tex ) ;
2020-10-08 02:29:49 +02:00
}
uniforms . push_back ( u ) ;
}
{
RD : : Uniform u ;
2020-10-17 03:19:21 +02:00
u . uniform_type = RD : : UNIFORM_TYPE_TEXTURE ;
2020-10-08 02:29:49 +02:00
u . binding = 1 ;
if ( collision_heightmap_texture . is_valid ( ) ) {
2022-03-06 12:57:09 +01:00
u . append_id ( collision_heightmap_texture ) ;
2020-10-08 02:29:49 +02:00
} else {
2022-03-12 12:19:59 +01:00
u . append_id ( texture_storage - > texture_rd_get_default ( RendererRD : : DEFAULT_RD_TEXTURE_BLACK ) ) ;
2020-10-08 02:29:49 +02:00
}
uniforms . push_back ( u ) ;
}
p_particles - > collision_textures_uniform_set = RD : : get_singleton ( ) - > uniform_set_create ( uniforms , particles_shader . default_shader_rd , 2 ) ;
}
}
2020-08-19 15:38:24 +02:00
ParticlesShader : : PushConstant push_constant ;
2021-04-27 17:43:49 +02:00
int process_amount = p_particles - > amount ;
if ( p_particles - > trails_enabled & & p_particles - > trail_bind_poses . size ( ) > 1 ) {
process_amount * = p_particles - > trail_bind_poses . size ( ) ;
}
2020-08-19 15:38:24 +02:00
push_constant . clear = p_particles - > clear ;
push_constant . total_particles = p_particles - > amount ;
push_constant . lifetime = p_particles - > lifetime ;
2021-04-27 17:43:49 +02:00
push_constant . trail_size = p_particles - > trail_params . size ( ) ;
2020-08-19 15:38:24 +02:00
push_constant . use_fractional_delta = p_particles - > fractional_delta ;
2020-09-06 14:18:10 +02:00
push_constant . sub_emitter_mode = ! p_particles - > emitting & & p_particles - > emission_buffer & & ( p_particles - > emission_buffer - > particle_count > 0 | | p_particles - > force_sub_emit ) ;
2021-04-27 17:43:49 +02:00
push_constant . trail_pass = false ;
2020-09-06 14:18:10 +02:00
p_particles - > force_sub_emit = false ; //reset
2021-09-29 19:08:41 +02:00
Particles * sub_emitter = particles_owner . get_or_null ( p_particles - > sub_emitter ) ;
2020-09-06 14:18:10 +02:00
if ( sub_emitter & & sub_emitter - > emission_storage_buffer . is_valid ( ) ) {
// print_line("updating subemitter buffer");
int32_t zero [ 4 ] = { 0 , sub_emitter - > amount , 0 , 0 } ;
2021-01-26 01:52:58 +01:00
RD : : get_singleton ( ) - > buffer_update ( sub_emitter - > emission_storage_buffer , 0 , sizeof ( uint32_t ) * 4 , zero ) ;
2020-09-06 14:18:10 +02:00
push_constant . can_emit = true ;
if ( sub_emitter - > emitting ) {
sub_emitter - > emitting = false ;
sub_emitter - > clear = true ; //will need to clear if it was emitting, sorry
}
//make sure the sub emitter processes particles too
sub_emitter - > inactive = false ;
sub_emitter - > inactive_time = 0 ;
sub_emitter - > force_sub_emit = true ;
} else {
push_constant . can_emit = false ;
}
if ( p_particles - > emission_buffer & & p_particles - > emission_buffer - > particle_count ) {
2021-01-26 01:52:58 +01:00
RD : : get_singleton ( ) - > buffer_update ( p_particles - > emission_storage_buffer , 0 , sizeof ( uint32_t ) * 4 + sizeof ( ParticleEmissionBuffer : : Data ) * p_particles - > emission_buffer - > particle_count , p_particles - > emission_buffer ) ;
2020-09-06 14:18:10 +02:00
p_particles - > emission_buffer - > particle_count = 0 ;
}
2020-08-19 15:38:24 +02:00
p_particles - > clear = false ;
2021-04-27 17:43:49 +02:00
if ( p_particles - > trail_params . size ( ) > 1 ) {
//fill the trail params
for ( uint32_t i = 0 ; i < p_particles - > trail_params . size ( ) ; i + + ) {
uint32_t src_idx = i * p_particles - > frame_history . size ( ) / p_particles - > trail_params . size ( ) ;
p_particles - > trail_params [ i ] = p_particles - > frame_history [ src_idx ] ;
}
} else {
p_particles - > trail_params [ 0 ] = p_particles - > frame_history [ 0 ] ;
}
RD : : get_singleton ( ) - > buffer_update ( p_particles - > frame_params_buffer , 0 , sizeof ( ParticlesFrameParams ) * p_particles - > trail_params . size ( ) , p_particles - > trail_params . ptr ( ) ) ;
2020-08-19 15:38:24 +02:00
2022-04-05 12:40:26 +02:00
ParticlesMaterialData * m = static_cast < ParticlesMaterialData * > ( material_storage - > material_get_data ( p_particles - > process_material , RendererRD : : SHADER_TYPE_PARTICLES ) ) ;
2020-08-19 15:38:24 +02:00
if ( ! m ) {
2022-04-05 12:40:26 +02:00
m = static_cast < ParticlesMaterialData * > ( material_storage - > material_get_data ( particles_shader . default_material , RendererRD : : SHADER_TYPE_PARTICLES ) ) ;
2020-08-19 15:38:24 +02:00
}
ERR_FAIL_COND ( ! m ) ;
2021-05-20 16:25:06 +02:00
p_particles - > has_collision_cache = m - > shader_data - > uses_collision ;
2020-08-19 15:38:24 +02:00
//todo should maybe compute all particle systems together?
RD : : ComputeListID compute_list = RD : : get_singleton ( ) - > compute_list_begin ( ) ;
RD : : get_singleton ( ) - > compute_list_bind_compute_pipeline ( compute_list , m - > shader_data - > pipeline ) ;
RD : : get_singleton ( ) - > compute_list_bind_uniform_set ( compute_list , particles_shader . base_uniform_set , 0 ) ;
RD : : get_singleton ( ) - > compute_list_bind_uniform_set ( compute_list , p_particles - > particles_material_uniform_set , 1 ) ;
2020-10-08 02:29:49 +02:00
RD : : get_singleton ( ) - > compute_list_bind_uniform_set ( compute_list , p_particles - > collision_textures_uniform_set , 2 ) ;
2021-08-19 08:10:44 +02:00
if ( m - > uniform_set . is_valid ( ) & & RD : : get_singleton ( ) - > uniform_set_is_valid ( m - > uniform_set ) ) {
2020-10-08 02:29:49 +02:00
RD : : get_singleton ( ) - > compute_list_bind_uniform_set ( compute_list , m - > uniform_set , 3 ) ;
2020-08-19 15:38:24 +02:00
}
RD : : get_singleton ( ) - > compute_list_set_push_constant ( compute_list , & push_constant , sizeof ( ParticlesShader : : PushConstant ) ) ;
2021-04-27 17:43:49 +02:00
if ( p_particles - > trails_enabled & & p_particles - > trail_bind_poses . size ( ) > 1 ) {
//trails requires two passes in order to catch particle starts
RD : : get_singleton ( ) - > compute_list_dispatch_threads ( compute_list , process_amount / p_particles - > trail_bind_poses . size ( ) , 1 , 1 ) ;
RD : : get_singleton ( ) - > compute_list_add_barrier ( compute_list ) ;
push_constant . trail_pass = true ;
RD : : get_singleton ( ) - > compute_list_set_push_constant ( compute_list , & push_constant , sizeof ( ParticlesShader : : PushConstant ) ) ;
RD : : get_singleton ( ) - > compute_list_dispatch_threads ( compute_list , process_amount - p_particles - > amount , 1 , 1 ) ;
} else {
RD : : get_singleton ( ) - > compute_list_dispatch_threads ( compute_list , process_amount , 1 , 1 ) ;
}
2020-08-19 15:38:24 +02:00
RD : : get_singleton ( ) - > compute_list_end ( ) ;
}
2021-04-27 17:43:49 +02:00
void RendererStorageRD : : particles_set_view_axis ( RID p_particles , const Vector3 & p_axis , const Vector3 & p_up_axis ) {
2021-09-29 19:08:41 +02:00
Particles * particles = particles_owner . get_or_null ( p_particles ) ;
2020-08-19 15:38:24 +02:00
ERR_FAIL_COND ( ! particles ) ;
2021-04-27 17:43:49 +02:00
if ( particles - > draw_order ! = RS : : PARTICLES_DRAW_ORDER_VIEW_DEPTH & & particles - > transform_align ! = RS : : PARTICLES_TRANSFORM_ALIGN_Z_BILLBOARD & & particles - > transform_align ! = RS : : PARTICLES_TRANSFORM_ALIGN_Z_BILLBOARD_Y_TO_VELOCITY ) {
return ;
}
if ( particles - > particle_buffer . is_null ( ) ) {
return ; //particles have not processed yet
2020-08-19 15:38:24 +02:00
}
2021-04-27 17:43:49 +02:00
bool do_sort = particles - > draw_order = = RS : : PARTICLES_DRAW_ORDER_VIEW_DEPTH ;
2020-08-19 15:38:24 +02:00
//copy to sort buffer
2021-04-27 17:43:49 +02:00
if ( do_sort & & particles - > particles_sort_buffer = = RID ( ) ) {
2020-08-19 15:38:24 +02:00
uint32_t size = particles - > amount ;
if ( size & 1 ) {
size + + ; //make multiple of 16
}
size * = sizeof ( float ) * 2 ;
particles - > particles_sort_buffer = RD : : get_singleton ( ) - > storage_buffer_create ( size ) ;
2021-04-27 17:43:49 +02:00
2020-08-19 15:38:24 +02:00
{
Vector < RD : : Uniform > uniforms ;
{
RD : : Uniform u ;
2020-10-17 03:19:21 +02:00
u . uniform_type = RD : : UNIFORM_TYPE_STORAGE_BUFFER ;
2020-08-19 15:38:24 +02:00
u . binding = 0 ;
2022-03-06 12:57:09 +01:00
u . append_id ( particles - > particles_sort_buffer ) ;
2020-08-19 15:38:24 +02:00
uniforms . push_back ( u ) ;
}
particles - > particles_sort_uniform_set = RD : : get_singleton ( ) - > uniform_set_create ( uniforms , particles_shader . copy_shader . version_get_shader ( particles_shader . copy_shader_version , ParticlesShader : : COPY_MODE_FILL_SORT_BUFFER ) , 1 ) ;
}
}
2021-04-27 17:43:49 +02:00
ParticlesShader : : CopyPushConstant copy_push_constant ;
if ( particles - > trails_enabled & & particles - > trail_bind_poses . size ( ) > 1 ) {
int fixed_fps = 60.0 ;
if ( particles - > fixed_fps > 0 ) {
fixed_fps = particles - > fixed_fps ;
}
copy_push_constant . trail_size = particles - > trail_bind_poses . size ( ) ;
copy_push_constant . trail_total = particles - > frame_history . size ( ) ;
copy_push_constant . frame_delta = 1.0 / fixed_fps ;
} else {
copy_push_constant . trail_size = 1 ;
copy_push_constant . trail_total = 1 ;
copy_push_constant . frame_delta = 0.0 ;
}
2021-05-20 16:25:06 +02:00
copy_push_constant . order_by_lifetime = ( particles - > draw_order = = RS : : PARTICLES_DRAW_ORDER_LIFETIME | | particles - > draw_order = = RS : : PARTICLES_DRAW_ORDER_REVERSE_LIFETIME ) ;
copy_push_constant . lifetime_split = MIN ( particles - > amount * particles - > phase , particles - > amount - 1 ) ;
copy_push_constant . lifetime_reverse = particles - > draw_order = = RS : : PARTICLES_DRAW_ORDER_REVERSE_LIFETIME ;
2021-04-27 17:43:49 +02:00
copy_push_constant . frame_remainder = particles - > interpolate ? particles - > frame_remainder : 0.0 ;
copy_push_constant . total_particles = particles - > amount ;
2022-02-14 13:27:10 +01:00
copy_push_constant . copy_mode_2d = false ;
2021-04-27 17:43:49 +02:00
2020-08-19 15:38:24 +02:00
Vector3 axis = - p_axis ; // cameras look to z negative
if ( particles - > use_local_coords ) {
axis = particles - > emission_transform . basis . xform_inv ( axis ) . normalized ( ) ;
}
copy_push_constant . sort_direction [ 0 ] = axis . x ;
copy_push_constant . sort_direction [ 1 ] = axis . y ;
copy_push_constant . sort_direction [ 2 ] = axis . z ;
2021-04-27 17:43:49 +02:00
copy_push_constant . align_up [ 0 ] = p_up_axis . x ;
copy_push_constant . align_up [ 1 ] = p_up_axis . y ;
copy_push_constant . align_up [ 2 ] = p_up_axis . z ;
2020-08-19 15:38:24 +02:00
2021-04-27 17:43:49 +02:00
copy_push_constant . align_mode = particles - > transform_align ;
2020-08-19 15:38:24 +02:00
2021-04-27 17:43:49 +02:00
if ( do_sort ) {
RD : : ComputeListID compute_list = RD : : get_singleton ( ) - > compute_list_begin ( ) ;
2022-02-14 13:27:10 +01:00
RD : : get_singleton ( ) - > compute_list_bind_compute_pipeline ( compute_list , particles_shader . copy_pipelines [ ParticlesShader : : COPY_MODE_FILL_SORT_BUFFER + particles - > userdata_count * ParticlesShader : : COPY_MODE_MAX ] ) ;
2021-04-27 17:43:49 +02:00
RD : : get_singleton ( ) - > compute_list_bind_uniform_set ( compute_list , particles - > particles_copy_uniform_set , 0 ) ;
RD : : get_singleton ( ) - > compute_list_bind_uniform_set ( compute_list , particles - > particles_sort_uniform_set , 1 ) ;
RD : : get_singleton ( ) - > compute_list_bind_uniform_set ( compute_list , particles - > trail_bind_pose_uniform_set , 2 ) ;
RD : : get_singleton ( ) - > compute_list_set_push_constant ( compute_list , & copy_push_constant , sizeof ( ParticlesShader : : CopyPushConstant ) ) ;
RD : : get_singleton ( ) - > compute_list_dispatch_threads ( compute_list , particles - > amount , 1 , 1 ) ;
2020-08-19 15:38:24 +02:00
2021-04-27 17:43:49 +02:00
RD : : get_singleton ( ) - > compute_list_end ( ) ;
2021-07-20 13:40:16 +02:00
effects - > sort_buffer ( particles - > particles_sort_uniform_set , particles - > amount ) ;
2021-04-27 17:43:49 +02:00
}
copy_push_constant . total_particles * = copy_push_constant . total_particles ;
2020-08-19 15:38:24 +02:00
2021-04-27 17:43:49 +02:00
RD : : ComputeListID compute_list = RD : : get_singleton ( ) - > compute_list_begin ( ) ;
2022-02-14 13:27:10 +01:00
uint32_t copy_pipeline = do_sort ? ParticlesShader : : COPY_MODE_FILL_INSTANCES_WITH_SORT_BUFFER : ParticlesShader : : COPY_MODE_FILL_INSTANCES ;
copy_pipeline + = particles - > userdata_count * ParticlesShader : : COPY_MODE_MAX ;
copy_push_constant . copy_mode_2d = particles - > mode = = RS : : PARTICLES_MODE_2D ? 1 : 0 ;
RD : : get_singleton ( ) - > compute_list_bind_compute_pipeline ( compute_list , particles_shader . copy_pipelines [ copy_pipeline ] ) ;
2020-08-19 15:38:24 +02:00
RD : : get_singleton ( ) - > compute_list_bind_uniform_set ( compute_list , particles - > particles_copy_uniform_set , 0 ) ;
2021-04-27 17:43:49 +02:00
if ( do_sort ) {
RD : : get_singleton ( ) - > compute_list_bind_uniform_set ( compute_list , particles - > particles_sort_uniform_set , 1 ) ;
}
RD : : get_singleton ( ) - > compute_list_bind_uniform_set ( compute_list , particles - > trail_bind_pose_uniform_set , 2 ) ;
2020-08-19 15:38:24 +02:00
RD : : get_singleton ( ) - > compute_list_set_push_constant ( compute_list , & copy_push_constant , sizeof ( ParticlesShader : : CopyPushConstant ) ) ;
2021-04-27 17:43:49 +02:00
RD : : get_singleton ( ) - > compute_list_dispatch_threads ( compute_list , copy_push_constant . total_particles , 1 , 1 ) ;
2020-08-19 15:38:24 +02:00
RD : : get_singleton ( ) - > compute_list_end ( ) ;
}
2021-04-27 17:43:49 +02:00
void RendererStorageRD : : _particles_update_buffers ( Particles * particles ) {
2022-02-14 13:27:10 +01:00
uint32_t userdata_count = 0 ;
2022-03-21 12:25:25 +01:00
const RendererRD : : Material * material = RendererRD : : MaterialStorage : : get_singleton ( ) - > get_material ( particles - > process_material ) ;
2022-02-14 13:27:10 +01:00
if ( material & & material - > shader & & material - > shader - > data ) {
const ParticlesShaderData * shader_data = static_cast < const ParticlesShaderData * > ( material - > shader - > data ) ;
userdata_count = shader_data - > userdata_count ;
}
if ( userdata_count ! = particles - > userdata_count ) {
// Mismatch userdata, re-create buffers.
_particles_free_data ( particles ) ;
}
2021-04-27 17:43:49 +02:00
if ( particles - > amount > 0 & & particles - > particle_buffer . is_null ( ) ) {
int total_amount = particles - > amount ;
if ( particles - > trails_enabled & & particles - > trail_bind_poses . size ( ) > 1 ) {
total_amount * = particles - > trail_bind_poses . size ( ) ;
}
2021-05-10 18:12:44 +02:00
uint32_t xform_size = particles - > mode = = RS : : PARTICLES_MODE_2D ? 2 : 3 ;
2022-02-14 13:27:10 +01:00
particles - > particle_buffer = RD : : get_singleton ( ) - > storage_buffer_create ( ( sizeof ( ParticleData ) + userdata_count * sizeof ( float ) * 4 ) * total_amount ) ;
particles - > userdata_count = userdata_count ;
2021-05-10 18:12:44 +02:00
particles - > particle_instance_buffer = RD : : get_singleton ( ) - > storage_buffer_create ( sizeof ( float ) * 4 * ( xform_size + 1 + 1 ) * total_amount ) ;
2021-04-27 17:43:49 +02:00
//needs to clear it
{
Vector < RD : : Uniform > uniforms ;
{
RD : : Uniform u ;
u . uniform_type = RD : : UNIFORM_TYPE_STORAGE_BUFFER ;
u . binding = 1 ;
2022-03-06 12:57:09 +01:00
u . append_id ( particles - > particle_buffer ) ;
2021-04-27 17:43:49 +02:00
uniforms . push_back ( u ) ;
}
{
RD : : Uniform u ;
u . uniform_type = RD : : UNIFORM_TYPE_STORAGE_BUFFER ;
u . binding = 2 ;
2022-03-06 12:57:09 +01:00
u . append_id ( particles - > particle_instance_buffer ) ;
2021-04-27 17:43:49 +02:00
uniforms . push_back ( u ) ;
}
particles - > particles_copy_uniform_set = RD : : get_singleton ( ) - > uniform_set_create ( uniforms , particles_shader . copy_shader . version_get_shader ( particles_shader . copy_shader_version , 0 ) , 0 ) ;
}
}
}
2020-12-04 19:26:24 +01:00
void RendererStorageRD : : update_particles ( ) {
2020-08-19 15:38:24 +02:00
while ( particle_update_list ) {
//use transform feedback to process particles
Particles * particles = particle_update_list ;
//take and remove
particle_update_list = particles - > update_list ;
particles - > update_list = nullptr ;
particles - > dirty = false ;
2021-04-27 17:43:49 +02:00
_particles_update_buffers ( particles ) ;
2020-08-19 15:38:24 +02:00
if ( particles - > restart_request ) {
particles - > prev_ticks = 0 ;
particles - > phase = 0 ;
particles - > prev_phase = 0 ;
particles - > clear = true ;
particles - > restart_request = false ;
}
if ( particles - > inactive & & ! particles - > emitting ) {
//go next
continue ;
}
if ( particles - > emitting ) {
if ( particles - > inactive ) {
//restart system from scratch
particles - > prev_ticks = 0 ;
particles - > phase = 0 ;
particles - > prev_phase = 0 ;
particles - > clear = true ;
}
particles - > inactive = false ;
particles - > inactive_time = 0 ;
} else {
2020-12-04 19:26:24 +01:00
particles - > inactive_time + = particles - > speed_scale * RendererCompositorRD : : singleton - > get_frame_delta_time ( ) ;
2020-08-19 15:38:24 +02:00
if ( particles - > inactive_time > particles - > lifetime * 1.2 ) {
particles - > inactive = true ;
continue ;
}
}
2021-04-27 17:43:49 +02:00
# ifndef _MSC_VER
# warning Should use display refresh rate for all this
# endif
float screen_hz = 60 ;
int fixed_fps = 0 ;
if ( particles - > fixed_fps > 0 ) {
fixed_fps = particles - > fixed_fps ;
} else if ( particles - > trails_enabled & & particles - > trail_bind_poses . size ( ) > 1 ) {
fixed_fps = screen_hz ;
}
{
//update trails
int history_size = 1 ;
int trail_steps = 1 ;
if ( particles - > trails_enabled & & particles - > trail_bind_poses . size ( ) > 1 ) {
history_size = MAX ( 1 , int ( particles - > trail_length * fixed_fps ) ) ;
trail_steps = particles - > trail_bind_poses . size ( ) ;
}
if ( uint32_t ( history_size ) ! = particles - > frame_history . size ( ) ) {
particles - > frame_history . resize ( history_size ) ;
memset ( particles - > frame_history . ptr ( ) , 0 , sizeof ( ParticlesFrameParams ) * history_size ) ;
}
if ( uint32_t ( trail_steps ) ! = particles - > trail_params . size ( ) | | particles - > frame_params_buffer . is_null ( ) ) {
particles - > trail_params . resize ( trail_steps ) ;
if ( particles - > frame_params_buffer . is_valid ( ) ) {
RD : : get_singleton ( ) - > free ( particles - > frame_params_buffer ) ;
}
particles - > frame_params_buffer = RD : : get_singleton ( ) - > storage_buffer_create ( sizeof ( ParticlesFrameParams ) * trail_steps ) ;
}
if ( particles - > trail_bind_poses . size ( ) > 1 & & particles - > trail_bind_pose_buffer . is_null ( ) ) {
particles - > trail_bind_pose_buffer = RD : : get_singleton ( ) - > storage_buffer_create ( sizeof ( float ) * 16 * particles - > trail_bind_poses . size ( ) ) ;
particles - > trail_bind_poses_dirty = true ;
}
if ( particles - > trail_bind_pose_uniform_set . is_null ( ) ) {
Vector < RD : : Uniform > uniforms ;
{
RD : : Uniform u ;
u . uniform_type = RD : : UNIFORM_TYPE_STORAGE_BUFFER ;
u . binding = 0 ;
if ( particles - > trail_bind_pose_buffer . is_valid ( ) ) {
2022-03-06 12:57:09 +01:00
u . append_id ( particles - > trail_bind_pose_buffer ) ;
2021-04-27 17:43:49 +02:00
} else {
2022-04-02 07:29:04 +02:00
u . append_id ( RendererRD : : MeshStorage : : get_singleton ( ) - > get_default_rd_storage_buffer ( ) ) ;
2021-04-27 17:43:49 +02:00
}
uniforms . push_back ( u ) ;
}
particles - > trail_bind_pose_uniform_set = RD : : get_singleton ( ) - > uniform_set_create ( uniforms , particles_shader . copy_shader . version_get_shader ( particles_shader . copy_shader_version , 0 ) , 2 ) ;
}
if ( particles - > trail_bind_pose_buffer . is_valid ( ) & & particles - > trail_bind_poses_dirty ) {
if ( particles_shader . pose_update_buffer . size ( ) < uint32_t ( particles - > trail_bind_poses . size ( ) ) * 16 ) {
particles_shader . pose_update_buffer . resize ( particles - > trail_bind_poses . size ( ) * 16 ) ;
}
for ( int i = 0 ; i < particles - > trail_bind_poses . size ( ) ; i + + ) {
store_transform ( particles - > trail_bind_poses [ i ] , & particles_shader . pose_update_buffer [ i * 16 ] ) ;
}
RD : : get_singleton ( ) - > buffer_update ( particles - > trail_bind_pose_buffer , 0 , particles - > trail_bind_poses . size ( ) * 16 * sizeof ( float ) , particles_shader . pose_update_buffer . ptr ( ) ) ;
}
}
2020-08-19 15:38:24 +02:00
bool zero_time_scale = Engine : : get_singleton ( ) - > get_time_scale ( ) < = 0.0 ;
if ( particles - > clear & & particles - > pre_process_time > 0.0 ) {
2021-02-02 03:16:37 +01:00
double frame_time ;
2021-04-27 17:43:49 +02:00
if ( fixed_fps > 0 ) {
frame_time = 1.0 / fixed_fps ;
2021-04-05 14:09:59 +02:00
} else {
2020-08-19 15:38:24 +02:00
frame_time = 1.0 / 30.0 ;
2021-04-05 14:09:59 +02:00
}
2020-08-19 15:38:24 +02:00
2021-02-02 03:16:37 +01:00
double todo = particles - > pre_process_time ;
2020-08-19 15:38:24 +02:00
while ( todo > = 0 ) {
_particles_process ( particles , frame_time ) ;
todo - = frame_time ;
}
}
2021-04-27 17:43:49 +02:00
if ( fixed_fps > 0 ) {
2021-02-02 03:16:37 +01:00
double frame_time ;
double decr ;
2020-08-19 15:38:24 +02:00
if ( zero_time_scale ) {
frame_time = 0.0 ;
2021-04-27 17:43:49 +02:00
decr = 1.0 / fixed_fps ;
2020-08-19 15:38:24 +02:00
} else {
2021-04-27 17:43:49 +02:00
frame_time = 1.0 / fixed_fps ;
2020-08-19 15:38:24 +02:00
decr = frame_time ;
}
2021-02-02 03:16:37 +01:00
double delta = RendererCompositorRD : : singleton - > get_frame_delta_time ( ) ;
2020-08-19 15:38:24 +02:00
if ( delta > 0.1 ) { //avoid recursive stalls if fps goes below 10
delta = 0.1 ;
} else if ( delta < = 0.0 ) { //unlikely but..
delta = 0.001 ;
}
2021-02-02 03:16:37 +01:00
double todo = particles - > frame_remainder + delta ;
2020-08-19 15:38:24 +02:00
while ( todo > = frame_time ) {
_particles_process ( particles , frame_time ) ;
todo - = decr ;
}
particles - > frame_remainder = todo ;
} else {
2021-04-05 14:09:59 +02:00
if ( zero_time_scale ) {
2020-08-19 15:38:24 +02:00
_particles_process ( particles , 0.0 ) ;
2021-04-05 14:09:59 +02:00
} else {
2020-12-04 19:26:24 +01:00
_particles_process ( particles , RendererCompositorRD : : singleton - > get_frame_delta_time ( ) ) ;
2021-04-05 14:09:59 +02:00
}
2020-08-19 15:38:24 +02:00
}
//copy particles to instance buffer
2021-04-27 17:43:49 +02:00
if ( particles - > draw_order ! = RS : : PARTICLES_DRAW_ORDER_VIEW_DEPTH & & particles - > transform_align ! = RS : : PARTICLES_TRANSFORM_ALIGN_Z_BILLBOARD & & particles - > transform_align ! = RS : : PARTICLES_TRANSFORM_ALIGN_Z_BILLBOARD_Y_TO_VELOCITY ) {
//does not need view dependent operation, do copy here
2020-08-19 15:38:24 +02:00
ParticlesShader : : CopyPushConstant copy_push_constant ;
2021-04-27 17:43:49 +02:00
int total_amount = particles - > amount ;
if ( particles - > trails_enabled & & particles - > trail_bind_poses . size ( ) > 1 ) {
total_amount * = particles - > trail_bind_poses . size ( ) ;
}
2022-02-02 04:49:54 +01:00
// Affect 2D only.
if ( particles - > use_local_coords ) {
// In local mode, particle positions are calculated locally (relative to the node position)
// and they're also drawn locally.
// It works as expected, so we just pass an identity transform.
store_transform ( Transform3D ( ) , copy_push_constant . inv_emission_transform ) ;
} else {
// In global mode, particle positions are calculated globally (relative to the canvas origin)
// but they're drawn locally.
// So, we need to pass the inverse of the emission transform to bring the
// particles to local coordinates before drawing.
Transform3D inv = particles - > emission_transform . affine_inverse ( ) ;
store_transform ( inv , copy_push_constant . inv_emission_transform ) ;
}
2021-04-27 17:43:49 +02:00
copy_push_constant . total_particles = total_amount ;
copy_push_constant . frame_remainder = particles - > interpolate ? particles - > frame_remainder : 0.0 ;
copy_push_constant . align_mode = particles - > transform_align ;
copy_push_constant . align_up [ 0 ] = 0 ;
copy_push_constant . align_up [ 1 ] = 0 ;
copy_push_constant . align_up [ 2 ] = 0 ;
if ( particles - > trails_enabled & & particles - > trail_bind_poses . size ( ) > 1 ) {
copy_push_constant . trail_size = particles - > trail_bind_poses . size ( ) ;
copy_push_constant . trail_total = particles - > frame_history . size ( ) ;
copy_push_constant . frame_delta = 1.0 / fixed_fps ;
} else {
copy_push_constant . trail_size = 1 ;
copy_push_constant . trail_total = 1 ;
copy_push_constant . frame_delta = 0.0 ;
}
2020-08-19 15:38:24 +02:00
2021-05-20 16:25:06 +02:00
copy_push_constant . order_by_lifetime = ( particles - > draw_order = = RS : : PARTICLES_DRAW_ORDER_LIFETIME | | particles - > draw_order = = RS : : PARTICLES_DRAW_ORDER_REVERSE_LIFETIME ) ;
copy_push_constant . lifetime_split = MIN ( particles - > amount * particles - > phase , particles - > amount - 1 ) ;
copy_push_constant . lifetime_reverse = particles - > draw_order = = RS : : PARTICLES_DRAW_ORDER_REVERSE_LIFETIME ;
2020-08-19 15:38:24 +02:00
RD : : ComputeListID compute_list = RD : : get_singleton ( ) - > compute_list_begin ( ) ;
2022-02-14 13:27:10 +01:00
copy_push_constant . copy_mode_2d = particles - > mode = = RS : : PARTICLES_MODE_2D ? 1 : 0 ;
RD : : get_singleton ( ) - > compute_list_bind_compute_pipeline ( compute_list , particles_shader . copy_pipelines [ ParticlesShader : : COPY_MODE_FILL_INSTANCES + particles - > userdata_count * ParticlesShader : : COPY_MODE_MAX ] ) ;
2020-08-19 15:38:24 +02:00
RD : : get_singleton ( ) - > compute_list_bind_uniform_set ( compute_list , particles - > particles_copy_uniform_set , 0 ) ;
2021-04-27 17:43:49 +02:00
RD : : get_singleton ( ) - > compute_list_bind_uniform_set ( compute_list , particles - > trail_bind_pose_uniform_set , 2 ) ;
2020-08-19 15:38:24 +02:00
RD : : get_singleton ( ) - > compute_list_set_push_constant ( compute_list , & copy_push_constant , sizeof ( ParticlesShader : : CopyPushConstant ) ) ;
2021-04-27 17:43:49 +02:00
RD : : get_singleton ( ) - > compute_list_dispatch_threads ( compute_list , total_amount , 1 , 1 ) ;
2020-08-19 15:38:24 +02:00
RD : : get_singleton ( ) - > compute_list_end ( ) ;
}
2021-01-04 13:33:25 +01:00
particles - > dependency . changed_notify ( DEPENDENCY_CHANGED_AABB ) ;
2020-08-19 15:38:24 +02:00
}
}
2020-12-04 19:26:24 +01:00
bool RendererStorageRD : : particles_is_inactive ( RID p_particles ) const {
2021-07-01 04:17:47 +02:00
ERR_FAIL_COND_V_MSG ( RSG : : threaded , false , " This function should never be used with threaded rendering, as it stalls the renderer. " ) ;
2021-09-29 19:08:41 +02:00
const Particles * particles = particles_owner . get_or_null ( p_particles ) ;
2020-08-19 15:38:24 +02:00
ERR_FAIL_COND_V ( ! particles , false ) ;
return ! particles - > emitting & & particles - > inactive ;
}
/* SKY SHADER */
2020-12-04 19:26:24 +01:00
void RendererStorageRD : : ParticlesShaderData : : set_code ( const String & p_code ) {
2020-08-19 15:38:24 +02:00
//compile
code = p_code ;
valid = false ;
ubo_size = 0 ;
uniforms . clear ( ) ;
2021-05-20 16:25:06 +02:00
uses_collision = false ;
2020-08-19 15:38:24 +02:00
2021-12-09 10:42:46 +01:00
if ( code . is_empty ( ) ) {
2020-08-19 15:38:24 +02:00
return ; //just invalid, but no error
}
2021-11-16 16:25:42 +01:00
ShaderCompiler : : GeneratedCode gen_code ;
ShaderCompiler : : IdentifierActions actions ;
actions . entry_point_stages [ " start " ] = ShaderCompiler : : STAGE_COMPUTE ;
actions . entry_point_stages [ " process " ] = ShaderCompiler : : STAGE_COMPUTE ;
2020-08-19 15:38:24 +02:00
/*
uses_time = false ;
actions . render_mode_flags [ " use_half_res_pass " ] = & uses_half_res ;
actions . render_mode_flags [ " use_quarter_res_pass " ] = & uses_quarter_res ;
actions . usage_flag_pointers [ " TIME " ] = & uses_time ;
*/
2021-05-20 16:25:06 +02:00
actions . usage_flag_pointers [ " COLLIDED " ] = & uses_collision ;
2022-02-14 13:27:10 +01:00
userdata_count = 0 ;
for ( uint32_t i = 0 ; i < ParticlesShader : : MAX_USERDATAS ; i + + ) {
userdatas_used [ i ] = false ;
actions . usage_flag_pointers [ " USERDATA " + itos ( i + 1 ) ] = & userdatas_used [ i ] ;
}
2020-08-19 15:38:24 +02:00
actions . uniforms = & uniforms ;
Error err = base_singleton - > particles_shader . compiler . compile ( RS : : SHADER_PARTICLES , code , & actions , path , gen_code ) ;
2021-08-16 10:25:20 +02:00
ERR_FAIL_COND_MSG ( err ! = OK , " Shader compilation failed. " ) ;
2020-08-19 15:38:24 +02:00
if ( version . is_null ( ) ) {
version = base_singleton - > particles_shader . shader . version_create ( ) ;
}
2022-02-14 13:27:10 +01:00
for ( uint32_t i = 0 ; i < ParticlesShader : : MAX_USERDATAS ; i + + ) {
if ( userdatas_used [ i ] ) {
userdata_count + + ;
}
}
2021-11-16 16:25:42 +01:00
base_singleton - > particles_shader . shader . version_set_compute_code ( version , gen_code . code , gen_code . uniforms , gen_code . stage_globals [ ShaderCompiler : : STAGE_COMPUTE ] , gen_code . defines ) ;
2020-08-19 15:38:24 +02:00
ERR_FAIL_COND ( ! base_singleton - > particles_shader . shader . version_is_valid ( version ) ) ;
ubo_size = gen_code . uniform_total_size ;
ubo_offsets = gen_code . uniform_offsets ;
texture_uniforms = gen_code . texture_uniforms ;
//update pipelines
pipeline = RD : : get_singleton ( ) - > compute_pipeline_create ( base_singleton - > particles_shader . shader . version_get_shader ( version , 0 ) ) ;
valid = true ;
}
2021-10-17 13:38:26 +02:00
void RendererStorageRD : : ParticlesShaderData : : set_default_texture_param ( const StringName & p_name , RID p_texture , int p_index ) {
2020-08-19 15:38:24 +02:00
if ( ! p_texture . is_valid ( ) ) {
2021-10-17 13:38:26 +02:00
if ( default_texture_params . has ( p_name ) & & default_texture_params [ p_name ] . has ( p_index ) ) {
default_texture_params [ p_name ] . erase ( p_index ) ;
if ( default_texture_params [ p_name ] . is_empty ( ) ) {
default_texture_params . erase ( p_name ) ;
}
}
2020-08-19 15:38:24 +02:00
} else {
2021-10-17 13:38:26 +02:00
if ( ! default_texture_params . has ( p_name ) ) {
default_texture_params [ p_name ] = Map < int , RID > ( ) ;
}
default_texture_params [ p_name ] [ p_index ] = p_texture ;
2020-08-19 15:38:24 +02:00
}
}
2020-12-04 19:26:24 +01:00
void RendererStorageRD : : ParticlesShaderData : : get_param_list ( List < PropertyInfo > * p_param_list ) const {
2020-08-19 15:38:24 +02:00
Map < int , StringName > order ;
2021-08-09 22:13:42 +02:00
for ( const KeyValue < StringName , ShaderLanguage : : ShaderNode : : Uniform > & E : uniforms ) {
if ( E . value . scope = = ShaderLanguage : : ShaderNode : : Uniform : : SCOPE_GLOBAL | | E . value . scope = = ShaderLanguage : : ShaderNode : : Uniform : : SCOPE_INSTANCE ) {
2020-08-19 15:38:24 +02:00
continue ;
}
2021-08-09 22:13:42 +02:00
if ( E . value . texture_order > = 0 ) {
order [ E . value . texture_order + 100000 ] = E . key ;
2020-08-19 15:38:24 +02:00
} else {
2021-08-09 22:13:42 +02:00
order [ E . value . order ] = E . key ;
2020-08-19 15:38:24 +02:00
}
}
2021-08-09 22:13:42 +02:00
for ( const KeyValue < int , StringName > & E : order ) {
PropertyInfo pi = ShaderLanguage : : uniform_to_property_info ( uniforms [ E . value ] ) ;
pi . name = E . value ;
2020-08-19 15:38:24 +02:00
p_param_list - > push_back ( pi ) ;
}
}
2022-03-21 12:25:25 +01:00
void RendererStorageRD : : ParticlesShaderData : : get_instance_param_list ( List < RendererMaterialStorage : : InstanceShaderParam > * p_param_list ) const {
2021-08-09 22:13:42 +02:00
for ( const KeyValue < StringName , ShaderLanguage : : ShaderNode : : Uniform > & E : uniforms ) {
if ( E . value . scope ! = ShaderLanguage : : ShaderNode : : Uniform : : SCOPE_INSTANCE ) {
2020-08-19 15:38:24 +02:00
continue ;
}
2022-03-21 12:25:25 +01:00
RendererMaterialStorage : : InstanceShaderParam p ;
2021-08-09 22:13:42 +02:00
p . info = ShaderLanguage : : uniform_to_property_info ( E . value ) ;
p . info . name = E . key ; //supply name
p . index = E . value . instance_index ;
2021-06-09 11:33:41 +02:00
p . default_value = ShaderLanguage : : constant_value_to_variant ( E . value . default_value , E . value . type , E . value . array_size , E . value . hint ) ;
2020-08-19 15:38:24 +02:00
p_param_list - > push_back ( p ) ;
}
}
2020-12-04 19:26:24 +01:00
bool RendererStorageRD : : ParticlesShaderData : : is_param_texture ( const StringName & p_param ) const {
2020-08-19 15:38:24 +02:00
if ( ! uniforms . has ( p_param ) ) {
return false ;
}
return uniforms [ p_param ] . texture_order > = 0 ;
}
2020-12-04 19:26:24 +01:00
bool RendererStorageRD : : ParticlesShaderData : : is_animated ( ) const {
2020-08-19 15:38:24 +02:00
return false ;
}
2020-12-04 19:26:24 +01:00
bool RendererStorageRD : : ParticlesShaderData : : casts_shadows ( ) const {
2020-08-19 15:38:24 +02:00
return false ;
}
2020-12-04 19:26:24 +01:00
Variant RendererStorageRD : : ParticlesShaderData : : get_default_parameter ( const StringName & p_parameter ) const {
2020-08-19 15:38:24 +02:00
if ( uniforms . has ( p_parameter ) ) {
ShaderLanguage : : ShaderNode : : Uniform uniform = uniforms [ p_parameter ] ;
Vector < ShaderLanguage : : ConstantNode : : Value > default_value = uniform . default_value ;
2021-06-09 11:33:41 +02:00
return ShaderLanguage : : constant_value_to_variant ( default_value , uniform . type , uniform . array_size , uniform . hint ) ;
2020-08-19 15:38:24 +02:00
}
return Variant ( ) ;
}
2021-01-06 00:01:50 +01:00
RS : : ShaderNativeSourceCode RendererStorageRD : : ParticlesShaderData : : get_native_source_code ( ) const {
return base_singleton - > particles_shader . shader . version_get_native_source_code ( version ) ;
}
2020-12-04 19:26:24 +01:00
RendererStorageRD : : ParticlesShaderData : : ParticlesShaderData ( ) {
2020-08-19 15:38:24 +02:00
valid = false ;
}
2020-12-04 19:26:24 +01:00
RendererStorageRD : : ParticlesShaderData : : ~ ParticlesShaderData ( ) {
2020-08-19 15:38:24 +02:00
//pipeline variants will clear themselves if shader is gone
if ( version . is_valid ( ) ) {
base_singleton - > particles_shader . shader . version_free ( version ) ;
}
}
2022-03-21 12:25:25 +01:00
RendererRD : : ShaderData * RendererStorageRD : : _create_particles_shader_func ( ) {
2020-08-19 15:38:24 +02:00
ParticlesShaderData * shader_data = memnew ( ParticlesShaderData ) ;
return shader_data ;
}
2021-07-06 23:56:28 +02:00
bool RendererStorageRD : : ParticlesMaterialData : : update_parameters ( const Map < StringName , Variant > & p_parameters , bool p_uniform_dirty , bool p_textures_dirty ) {
return update_parameters_uniform_set ( p_parameters , p_uniform_dirty , p_textures_dirty , shader_data - > uniforms , shader_data - > ubo_offsets . ptr ( ) , shader_data - > texture_uniforms , shader_data - > default_texture_params , shader_data - > ubo_size , uniform_set , base_singleton - > particles_shader . shader . version_get_shader ( shader_data - > version , 0 ) , 3 ) ;
2020-08-19 15:38:24 +02:00
}
2020-12-04 19:26:24 +01:00
RendererStorageRD : : ParticlesMaterialData : : ~ ParticlesMaterialData ( ) {
2021-07-08 00:55:20 +02:00
free_parameters_uniform_set ( uniform_set ) ;
2020-08-19 15:38:24 +02:00
}
2022-03-21 12:25:25 +01:00
RendererRD : : MaterialData * RendererStorageRD : : _create_particles_material_func ( ParticlesShaderData * p_shader ) {
2020-08-19 15:38:24 +02:00
ParticlesMaterialData * material_data = memnew ( ParticlesMaterialData ) ;
material_data - > shader_data = p_shader ;
//update will happen later anyway so do nothing.
return material_data ;
}
////////
2020-10-08 02:29:49 +02:00
/* PARTICLES COLLISION API */
2021-02-09 17:19:03 +01:00
RID RendererStorageRD : : particles_collision_allocate ( ) {
return particles_collision_owner . allocate_rid ( ) ;
}
void RendererStorageRD : : particles_collision_initialize ( RID p_rid ) {
particles_collision_owner . initialize_rid ( p_rid , ParticlesCollision ( ) ) ;
2020-10-08 02:29:49 +02:00
}
2020-12-04 19:26:24 +01:00
RID RendererStorageRD : : particles_collision_get_heightfield_framebuffer ( RID p_particles_collision ) const {
2021-09-29 19:08:41 +02:00
ParticlesCollision * particles_collision = particles_collision_owner . get_or_null ( p_particles_collision ) ;
2020-10-08 02:29:49 +02:00
ERR_FAIL_COND_V ( ! particles_collision , RID ( ) ) ;
ERR_FAIL_COND_V ( particles_collision - > type ! = RS : : PARTICLES_COLLISION_TYPE_HEIGHTFIELD_COLLIDE , RID ( ) ) ;
if ( particles_collision - > heightfield_texture = = RID ( ) ) {
//create
int resolutions [ RS : : PARTICLES_COLLISION_HEIGHTFIELD_RESOLUTION_MAX ] = { 256 , 512 , 1024 , 2048 , 4096 , 8192 } ;
Size2i size ;
if ( particles_collision - > extents . x > particles_collision - > extents . z ) {
size . x = resolutions [ particles_collision - > heightfield_resolution ] ;
size . y = int32_t ( particles_collision - > extents . z / particles_collision - > extents . x * size . x ) ;
} else {
size . y = resolutions [ particles_collision - > heightfield_resolution ] ;
size . x = int32_t ( particles_collision - > extents . x / particles_collision - > extents . z * size . y ) ;
}
RD : : TextureFormat tf ;
tf . format = RD : : DATA_FORMAT_D32_SFLOAT ;
tf . width = size . x ;
tf . height = size . y ;
2020-11-27 04:50:05 +01:00
tf . texture_type = RD : : TEXTURE_TYPE_2D ;
2020-10-08 02:29:49 +02:00
tf . usage_bits = RD : : TEXTURE_USAGE_SAMPLING_BIT | RD : : TEXTURE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT ;
particles_collision - > heightfield_texture = RD : : get_singleton ( ) - > texture_create ( tf , RD : : TextureView ( ) ) ;
Vector < RID > fb_tex ;
fb_tex . push_back ( particles_collision - > heightfield_texture ) ;
particles_collision - > heightfield_fb = RD : : get_singleton ( ) - > framebuffer_create ( fb_tex ) ;
particles_collision - > heightfield_fb_size = size ;
}
return particles_collision - > heightfield_fb ;
}
2020-12-04 19:26:24 +01:00
void RendererStorageRD : : particles_collision_set_collision_type ( RID p_particles_collision , RS : : ParticlesCollisionType p_type ) {
2021-09-29 19:08:41 +02:00
ParticlesCollision * particles_collision = particles_collision_owner . get_or_null ( p_particles_collision ) ;
2020-10-08 02:29:49 +02:00
ERR_FAIL_COND ( ! particles_collision ) ;
if ( p_type = = particles_collision - > type ) {
return ;
}
if ( particles_collision - > heightfield_texture . is_valid ( ) ) {
RD : : get_singleton ( ) - > free ( particles_collision - > heightfield_texture ) ;
particles_collision - > heightfield_texture = RID ( ) ;
}
particles_collision - > type = p_type ;
2021-01-04 13:33:25 +01:00
particles_collision - > dependency . changed_notify ( DEPENDENCY_CHANGED_AABB ) ;
2020-10-08 02:29:49 +02:00
}
2020-12-04 19:26:24 +01:00
void RendererStorageRD : : particles_collision_set_cull_mask ( RID p_particles_collision , uint32_t p_cull_mask ) {
2021-09-29 19:08:41 +02:00
ParticlesCollision * particles_collision = particles_collision_owner . get_or_null ( p_particles_collision ) ;
2020-10-08 02:29:49 +02:00
ERR_FAIL_COND ( ! particles_collision ) ;
particles_collision - > cull_mask = p_cull_mask ;
}
2021-08-12 16:07:47 +02:00
void RendererStorageRD : : particles_collision_set_sphere_radius ( RID p_particles_collision , real_t p_radius ) {
2021-09-29 19:08:41 +02:00
ParticlesCollision * particles_collision = particles_collision_owner . get_or_null ( p_particles_collision ) ;
2020-10-08 02:29:49 +02:00
ERR_FAIL_COND ( ! particles_collision ) ;
particles_collision - > radius = p_radius ;
2021-01-04 13:33:25 +01:00
particles_collision - > dependency . changed_notify ( DEPENDENCY_CHANGED_AABB ) ;
2020-10-08 02:29:49 +02:00
}
2020-12-04 19:26:24 +01:00
void RendererStorageRD : : particles_collision_set_box_extents ( RID p_particles_collision , const Vector3 & p_extents ) {
2021-09-29 19:08:41 +02:00
ParticlesCollision * particles_collision = particles_collision_owner . get_or_null ( p_particles_collision ) ;
2020-10-08 02:29:49 +02:00
ERR_FAIL_COND ( ! particles_collision ) ;
particles_collision - > extents = p_extents ;
2021-01-04 13:33:25 +01:00
particles_collision - > dependency . changed_notify ( DEPENDENCY_CHANGED_AABB ) ;
2020-10-08 02:29:49 +02:00
}
2021-08-12 16:07:47 +02:00
void RendererStorageRD : : particles_collision_set_attractor_strength ( RID p_particles_collision , real_t p_strength ) {
2021-09-29 19:08:41 +02:00
ParticlesCollision * particles_collision = particles_collision_owner . get_or_null ( p_particles_collision ) ;
2020-10-08 02:29:49 +02:00
ERR_FAIL_COND ( ! particles_collision ) ;
particles_collision - > attractor_strength = p_strength ;
}
2021-08-12 16:07:47 +02:00
void RendererStorageRD : : particles_collision_set_attractor_directionality ( RID p_particles_collision , real_t p_directionality ) {
2021-09-29 19:08:41 +02:00
ParticlesCollision * particles_collision = particles_collision_owner . get_or_null ( p_particles_collision ) ;
2020-10-08 02:29:49 +02:00
ERR_FAIL_COND ( ! particles_collision ) ;
particles_collision - > attractor_directionality = p_directionality ;
}
2021-08-12 16:07:47 +02:00
void RendererStorageRD : : particles_collision_set_attractor_attenuation ( RID p_particles_collision , real_t p_curve ) {
2021-09-29 19:08:41 +02:00
ParticlesCollision * particles_collision = particles_collision_owner . get_or_null ( p_particles_collision ) ;
2020-10-08 02:29:49 +02:00
ERR_FAIL_COND ( ! particles_collision ) ;
particles_collision - > attractor_attenuation = p_curve ;
}
2020-12-04 19:26:24 +01:00
void RendererStorageRD : : particles_collision_set_field_texture ( RID p_particles_collision , RID p_texture ) {
2021-09-29 19:08:41 +02:00
ParticlesCollision * particles_collision = particles_collision_owner . get_or_null ( p_particles_collision ) ;
2020-10-08 02:29:49 +02:00
ERR_FAIL_COND ( ! particles_collision ) ;
particles_collision - > field_texture = p_texture ;
}
2020-12-04 19:26:24 +01:00
void RendererStorageRD : : particles_collision_height_field_update ( RID p_particles_collision ) {
2021-09-29 19:08:41 +02:00
ParticlesCollision * particles_collision = particles_collision_owner . get_or_null ( p_particles_collision ) ;
2020-10-08 02:29:49 +02:00
ERR_FAIL_COND ( ! particles_collision ) ;
2021-01-04 13:33:25 +01:00
particles_collision - > dependency . changed_notify ( DEPENDENCY_CHANGED_AABB ) ;
2020-10-08 02:29:49 +02:00
}
2020-12-04 19:26:24 +01:00
void RendererStorageRD : : particles_collision_set_height_field_resolution ( RID p_particles_collision , RS : : ParticlesCollisionHeightfieldResolution p_resolution ) {
2021-09-29 19:08:41 +02:00
ParticlesCollision * particles_collision = particles_collision_owner . get_or_null ( p_particles_collision ) ;
2020-10-08 02:29:49 +02:00
ERR_FAIL_COND ( ! particles_collision ) ;
2021-03-17 14:46:25 +01:00
ERR_FAIL_INDEX ( p_resolution , RS : : PARTICLES_COLLISION_HEIGHTFIELD_RESOLUTION_MAX ) ;
2020-10-08 02:29:49 +02:00
if ( particles_collision - > heightfield_resolution = = p_resolution ) {
return ;
}
particles_collision - > heightfield_resolution = p_resolution ;
if ( particles_collision - > heightfield_texture . is_valid ( ) ) {
RD : : get_singleton ( ) - > free ( particles_collision - > heightfield_texture ) ;
particles_collision - > heightfield_texture = RID ( ) ;
}
}
2020-12-04 19:26:24 +01:00
AABB RendererStorageRD : : particles_collision_get_aabb ( RID p_particles_collision ) const {
2021-09-29 19:08:41 +02:00
ParticlesCollision * particles_collision = particles_collision_owner . get_or_null ( p_particles_collision ) ;
2020-10-08 02:29:49 +02:00
ERR_FAIL_COND_V ( ! particles_collision , AABB ( ) ) ;
switch ( particles_collision - > type ) {
case RS : : PARTICLES_COLLISION_TYPE_SPHERE_ATTRACT :
case RS : : PARTICLES_COLLISION_TYPE_SPHERE_COLLIDE : {
AABB aabb ;
aabb . position = - Vector3 ( 1 , 1 , 1 ) * particles_collision - > radius ;
aabb . size = Vector3 ( 2 , 2 , 2 ) * particles_collision - > radius ;
return aabb ;
}
default : {
AABB aabb ;
aabb . position = - particles_collision - > extents ;
aabb . size = particles_collision - > extents * 2 ;
return aabb ;
}
}
return AABB ( ) ;
}
2020-12-04 19:26:24 +01:00
Vector3 RendererStorageRD : : particles_collision_get_extents ( RID p_particles_collision ) const {
2021-09-29 19:08:41 +02:00
const ParticlesCollision * particles_collision = particles_collision_owner . get_or_null ( p_particles_collision ) ;
2020-10-08 02:29:49 +02:00
ERR_FAIL_COND_V ( ! particles_collision , Vector3 ( ) ) ;
return particles_collision - > extents ;
}
2020-12-04 19:26:24 +01:00
bool RendererStorageRD : : particles_collision_is_heightfield ( RID p_particles_collision ) const {
2021-09-29 19:08:41 +02:00
const ParticlesCollision * particles_collision = particles_collision_owner . get_or_null ( p_particles_collision ) ;
2020-10-08 02:29:49 +02:00
ERR_FAIL_COND_V ( ! particles_collision , false ) ;
return particles_collision - > type = = RS : : PARTICLES_COLLISION_TYPE_HEIGHTFIELD_COLLIDE ;
}
2020-12-31 13:42:56 +01:00
RID RendererStorageRD : : particles_collision_instance_create ( RID p_collision ) {
ParticlesCollisionInstance pci ;
pci . collision = p_collision ;
return particles_collision_instance_owner . make_rid ( pci ) ;
}
2020-10-17 07:08:21 +02:00
void RendererStorageRD : : particles_collision_instance_set_transform ( RID p_collision_instance , const Transform3D & p_transform ) {
2021-09-29 19:08:41 +02:00
ParticlesCollisionInstance * pci = particles_collision_instance_owner . get_or_null ( p_collision_instance ) ;
2020-12-31 13:42:56 +01:00
ERR_FAIL_COND ( ! pci ) ;
pci - > transform = p_transform ;
}
void RendererStorageRD : : particles_collision_instance_set_active ( RID p_collision_instance , bool p_active ) {
2021-09-29 19:08:41 +02:00
ParticlesCollisionInstance * pci = particles_collision_instance_owner . get_or_null ( p_collision_instance ) ;
2020-12-31 13:42:56 +01:00
ERR_FAIL_COND ( ! pci ) ;
pci - > active = p_active ;
}
2021-10-03 13:28:55 +02:00
/* FOG VOLUMES */
RID RendererStorageRD : : fog_volume_allocate ( ) {
return fog_volume_owner . allocate_rid ( ) ;
}
void RendererStorageRD : : fog_volume_initialize ( RID p_rid ) {
fog_volume_owner . initialize_rid ( p_rid , FogVolume ( ) ) ;
}
void RendererStorageRD : : fog_volume_set_shape ( RID p_fog_volume , RS : : FogVolumeShape p_shape ) {
FogVolume * fog_volume = fog_volume_owner . get_or_null ( p_fog_volume ) ;
ERR_FAIL_COND ( ! fog_volume ) ;
if ( p_shape = = fog_volume - > shape ) {
return ;
}
fog_volume - > shape = p_shape ;
fog_volume - > dependency . changed_notify ( DEPENDENCY_CHANGED_AABB ) ;
}
void RendererStorageRD : : fog_volume_set_extents ( RID p_fog_volume , const Vector3 & p_extents ) {
FogVolume * fog_volume = fog_volume_owner . get_or_null ( p_fog_volume ) ;
ERR_FAIL_COND ( ! fog_volume ) ;
fog_volume - > extents = p_extents ;
fog_volume - > dependency . changed_notify ( DEPENDENCY_CHANGED_AABB ) ;
}
void RendererStorageRD : : fog_volume_set_material ( RID p_fog_volume , RID p_material ) {
FogVolume * fog_volume = fog_volume_owner . get_or_null ( p_fog_volume ) ;
ERR_FAIL_COND ( ! fog_volume ) ;
fog_volume - > material = p_material ;
}
RID RendererStorageRD : : fog_volume_get_material ( RID p_fog_volume ) const {
FogVolume * fog_volume = fog_volume_owner . get_or_null ( p_fog_volume ) ;
ERR_FAIL_COND_V ( ! fog_volume , RID ( ) ) ;
return fog_volume - > material ;
}
RS : : FogVolumeShape RendererStorageRD : : fog_volume_get_shape ( RID p_fog_volume ) const {
FogVolume * fog_volume = fog_volume_owner . get_or_null ( p_fog_volume ) ;
ERR_FAIL_COND_V ( ! fog_volume , RS : : FOG_VOLUME_SHAPE_BOX ) ;
return fog_volume - > shape ;
}
AABB RendererStorageRD : : fog_volume_get_aabb ( RID p_fog_volume ) const {
FogVolume * fog_volume = fog_volume_owner . get_or_null ( p_fog_volume ) ;
ERR_FAIL_COND_V ( ! fog_volume , AABB ( ) ) ;
switch ( fog_volume - > shape ) {
case RS : : FOG_VOLUME_SHAPE_ELLIPSOID :
case RS : : FOG_VOLUME_SHAPE_BOX : {
AABB aabb ;
aabb . position = - fog_volume - > extents ;
aabb . size = fog_volume - > extents * 2 ;
return aabb ;
}
default : {
// Need some size otherwise will get culled
return AABB ( Vector3 ( - 1 , - 1 , - 1 ) , Vector3 ( 2 , 2 , 2 ) ) ;
}
}
return AABB ( ) ;
}
Vector3 RendererStorageRD : : fog_volume_get_extents ( RID p_fog_volume ) const {
const FogVolume * fog_volume = fog_volume_owner . get_or_null ( p_fog_volume ) ;
ERR_FAIL_COND_V ( ! fog_volume , Vector3 ( ) ) ;
return fog_volume - > extents ;
}
2021-06-16 20:43:02 +02:00
/* VISIBILITY NOTIFIER */
RID RendererStorageRD : : visibility_notifier_allocate ( ) {
return visibility_notifier_owner . allocate_rid ( ) ;
}
void RendererStorageRD : : visibility_notifier_initialize ( RID p_notifier ) {
visibility_notifier_owner . initialize_rid ( p_notifier , VisibilityNotifier ( ) ) ;
}
void RendererStorageRD : : visibility_notifier_set_aabb ( RID p_notifier , const AABB & p_aabb ) {
2021-09-29 19:08:41 +02:00
VisibilityNotifier * vn = visibility_notifier_owner . get_or_null ( p_notifier ) ;
2021-06-16 20:43:02 +02:00
ERR_FAIL_COND ( ! vn ) ;
vn - > aabb = p_aabb ;
vn - > dependency . changed_notify ( DEPENDENCY_CHANGED_AABB ) ;
}
void RendererStorageRD : : visibility_notifier_set_callbacks ( RID p_notifier , const Callable & p_enter_callbable , const Callable & p_exit_callable ) {
2021-09-29 19:08:41 +02:00
VisibilityNotifier * vn = visibility_notifier_owner . get_or_null ( p_notifier ) ;
2021-06-16 20:43:02 +02:00
ERR_FAIL_COND ( ! vn ) ;
vn - > enter_callback = p_enter_callbable ;
vn - > exit_callback = p_exit_callable ;
}
AABB RendererStorageRD : : visibility_notifier_get_aabb ( RID p_notifier ) const {
2021-09-29 19:08:41 +02:00
const VisibilityNotifier * vn = visibility_notifier_owner . get_or_null ( p_notifier ) ;
2021-06-16 20:43:02 +02:00
ERR_FAIL_COND_V ( ! vn , AABB ( ) ) ;
return vn - > aabb ;
}
void RendererStorageRD : : visibility_notifier_call ( RID p_notifier , bool p_enter , bool p_deferred ) {
2021-09-29 19:08:41 +02:00
VisibilityNotifier * vn = visibility_notifier_owner . get_or_null ( p_notifier ) ;
2021-06-16 20:43:02 +02:00
ERR_FAIL_COND ( ! vn ) ;
if ( p_enter ) {
if ( ! vn - > enter_callback . is_null ( ) ) {
if ( p_deferred ) {
vn - > enter_callback . call_deferred ( nullptr , 0 ) ;
} else {
Variant r ;
Callable : : CallError ce ;
vn - > enter_callback . call ( nullptr , 0 , r , ce ) ;
}
}
} else {
if ( ! vn - > exit_callback . is_null ( ) ) {
if ( p_deferred ) {
vn - > exit_callback . call_deferred ( nullptr , 0 ) ;
} else {
Variant r ;
Callable : : CallError ce ;
vn - > exit_callback . call ( nullptr , 0 , r , ce ) ;
}
}
}
}
2019-09-07 03:51:27 +02:00
/* LIGHT */
2021-02-09 17:19:03 +01:00
void RendererStorageRD : : _light_initialize ( RID p_light , RS : : LightType p_type ) {
2019-09-07 03:51:27 +02:00
Light light ;
light . type = p_type ;
2020-03-27 19:21:27 +01:00
light . param [ RS : : LIGHT_PARAM_ENERGY ] = 1.0 ;
light . param [ RS : : LIGHT_PARAM_INDIRECT_ENERGY ] = 1.0 ;
light . param [ RS : : LIGHT_PARAM_SPECULAR ] = 0.5 ;
light . param [ RS : : LIGHT_PARAM_RANGE ] = 1.0 ;
2020-04-09 20:11:15 +02:00
light . param [ RS : : LIGHT_PARAM_SIZE ] = 0.0 ;
2020-12-31 13:42:56 +01:00
light . param [ RS : : LIGHT_PARAM_ATTENUATION ] = 1.0 ;
2020-03-27 19:21:27 +01:00
light . param [ RS : : LIGHT_PARAM_SPOT_ANGLE ] = 45 ;
2020-12-31 13:42:56 +01:00
light . param [ RS : : LIGHT_PARAM_SPOT_ATTENUATION ] = 1.0 ;
2020-03-27 19:21:27 +01:00
light . param [ RS : : LIGHT_PARAM_SHADOW_MAX_DISTANCE ] = 0 ;
light . param [ RS : : LIGHT_PARAM_SHADOW_SPLIT_1_OFFSET ] = 0.1 ;
light . param [ RS : : LIGHT_PARAM_SHADOW_SPLIT_2_OFFSET ] = 0.3 ;
light . param [ RS : : LIGHT_PARAM_SHADOW_SPLIT_3_OFFSET ] = 0.6 ;
light . param [ RS : : LIGHT_PARAM_SHADOW_FADE_START ] = 0.8 ;
2020-04-08 03:51:52 +02:00
light . param [ RS : : LIGHT_PARAM_SHADOW_NORMAL_BIAS ] = 1.0 ;
2020-12-31 13:42:56 +01:00
light . param [ RS : : LIGHT_PARAM_SHADOW_BIAS ] = 0.02 ;
light . param [ RS : : LIGHT_PARAM_SHADOW_BLUR ] = 0 ;
2020-04-08 03:51:52 +02:00
light . param [ RS : : LIGHT_PARAM_SHADOW_PANCAKE_SIZE ] = 20.0 ;
2021-02-06 15:51:56 +01:00
light . param [ RS : : LIGHT_PARAM_SHADOW_VOLUMETRIC_FOG_FADE ] = 0.1 ;
2020-12-31 13:42:56 +01:00
light . param [ RS : : LIGHT_PARAM_TRANSMITTANCE_BIAS ] = 0.05 ;
2019-09-07 03:51:27 +02:00
2021-02-09 17:19:03 +01:00
light_owner . initialize_rid ( p_light , light ) ;
}
RID RendererStorageRD : : directional_light_allocate ( ) {
return light_owner . allocate_rid ( ) ;
}
void RendererStorageRD : : directional_light_initialize ( RID p_light ) {
_light_initialize ( p_light , RS : : LIGHT_DIRECTIONAL ) ;
}
RID RendererStorageRD : : omni_light_allocate ( ) {
return light_owner . allocate_rid ( ) ;
}
void RendererStorageRD : : omni_light_initialize ( RID p_light ) {
_light_initialize ( p_light , RS : : LIGHT_OMNI ) ;
}
RID RendererStorageRD : : spot_light_allocate ( ) {
return light_owner . allocate_rid ( ) ;
}
void RendererStorageRD : : spot_light_initialize ( RID p_light ) {
_light_initialize ( p_light , RS : : LIGHT_SPOT ) ;
2019-09-07 03:51:27 +02:00
}
2020-12-04 19:26:24 +01:00
void RendererStorageRD : : light_set_color ( RID p_light , const Color & p_color ) {
2021-09-29 19:08:41 +02:00
Light * light = light_owner . get_or_null ( p_light ) ;
2019-09-07 03:51:27 +02:00
ERR_FAIL_COND ( ! light ) ;
light - > color = p_color ;
}
2020-05-14 14:29:06 +02:00
2020-12-04 19:26:24 +01:00
void RendererStorageRD : : light_set_param ( RID p_light , RS : : LightParam p_param , float p_value ) {
2021-09-29 19:08:41 +02:00
Light * light = light_owner . get_or_null ( p_light ) ;
2019-09-07 03:51:27 +02:00
ERR_FAIL_COND ( ! light ) ;
2020-03-27 19:21:27 +01:00
ERR_FAIL_INDEX ( p_param , RS : : LIGHT_PARAM_MAX ) ;
2019-09-07 03:51:27 +02:00
2021-07-13 01:32:05 +02:00
if ( light - > param [ p_param ] = = p_value ) {
return ;
}
2019-09-07 03:51:27 +02:00
switch ( p_param ) {
2020-03-27 19:21:27 +01:00
case RS : : LIGHT_PARAM_RANGE :
case RS : : LIGHT_PARAM_SPOT_ANGLE :
case RS : : LIGHT_PARAM_SHADOW_MAX_DISTANCE :
case RS : : LIGHT_PARAM_SHADOW_SPLIT_1_OFFSET :
case RS : : LIGHT_PARAM_SHADOW_SPLIT_2_OFFSET :
case RS : : LIGHT_PARAM_SHADOW_SPLIT_3_OFFSET :
case RS : : LIGHT_PARAM_SHADOW_NORMAL_BIAS :
2020-04-08 03:51:52 +02:00
case RS : : LIGHT_PARAM_SHADOW_PANCAKE_SIZE :
2020-03-27 19:21:27 +01:00
case RS : : LIGHT_PARAM_SHADOW_BIAS : {
2019-09-07 03:51:27 +02:00
light - > version + + ;
2021-01-04 13:33:25 +01:00
light - > dependency . changed_notify ( DEPENDENCY_CHANGED_LIGHT ) ;
2019-09-07 03:51:27 +02:00
} break ;
2021-07-13 01:32:05 +02:00
case RS : : LIGHT_PARAM_SIZE : {
if ( ( light - > param [ p_param ] > CMP_EPSILON ) ! = ( p_value > CMP_EPSILON ) ) {
//changing from no size to size and the opposite
light - > dependency . changed_notify ( DEPENDENCY_CHANGED_LIGHT_SOFT_SHADOW_AND_PROJECTOR ) ;
}
} break ;
2019-09-07 03:51:27 +02:00
default : {
}
}
light - > param [ p_param ] = p_value ;
}
2020-05-14 14:29:06 +02:00
2020-12-04 19:26:24 +01:00
void RendererStorageRD : : light_set_shadow ( RID p_light , bool p_enabled ) {
2021-09-29 19:08:41 +02:00
Light * light = light_owner . get_or_null ( p_light ) ;
2019-09-07 03:51:27 +02:00
ERR_FAIL_COND ( ! light ) ;
light - > shadow = p_enabled ;
light - > version + + ;
2021-01-04 13:33:25 +01:00
light - > dependency . changed_notify ( DEPENDENCY_CHANGED_LIGHT ) ;
2019-09-07 03:51:27 +02:00
}
2020-12-04 19:26:24 +01:00
void RendererStorageRD : : light_set_projector ( RID p_light , RID p_texture ) {
2022-03-20 12:28:24 +01:00
RendererRD : : DecalAtlasStorage * decal_atlas_storage = RendererRD : : DecalAtlasStorage : : get_singleton ( ) ;
2021-09-29 19:08:41 +02:00
Light * light = light_owner . get_or_null ( p_light ) ;
2019-09-07 03:51:27 +02:00
ERR_FAIL_COND ( ! light ) ;
2020-04-14 22:05:45 +02:00
if ( light - > projector = = p_texture ) {
return ;
}
if ( light - > type ! = RS : : LIGHT_DIRECTIONAL & & light - > projector . is_valid ( ) ) {
2022-03-20 12:28:24 +01:00
decal_atlas_storage - > texture_remove_from_decal_atlas ( light - > projector , light - > type = = RS : : LIGHT_OMNI ) ;
2020-04-14 22:05:45 +02:00
}
2019-09-07 03:51:27 +02:00
light - > projector = p_texture ;
2020-04-14 22:05:45 +02:00
2021-07-13 01:32:05 +02:00
if ( light - > type ! = RS : : LIGHT_DIRECTIONAL ) {
if ( light - > projector . is_valid ( ) ) {
2022-03-20 12:28:24 +01:00
decal_atlas_storage - > texture_add_to_decal_atlas ( light - > projector , light - > type = = RS : : LIGHT_OMNI ) ;
2021-07-13 01:32:05 +02:00
}
light - > dependency . changed_notify ( DEPENDENCY_CHANGED_LIGHT_SOFT_SHADOW_AND_PROJECTOR ) ;
2020-04-14 22:05:45 +02:00
}
2019-09-07 03:51:27 +02:00
}
2020-12-04 19:26:24 +01:00
void RendererStorageRD : : light_set_negative ( RID p_light , bool p_enable ) {
2021-09-29 19:08:41 +02:00
Light * light = light_owner . get_or_null ( p_light ) ;
2019-09-07 03:51:27 +02:00
ERR_FAIL_COND ( ! light ) ;
light - > negative = p_enable ;
}
2020-05-14 14:29:06 +02:00
2020-12-04 19:26:24 +01:00
void RendererStorageRD : : light_set_cull_mask ( RID p_light , uint32_t p_mask ) {
2021-09-29 19:08:41 +02:00
Light * light = light_owner . get_or_null ( p_light ) ;
2019-09-07 03:51:27 +02:00
ERR_FAIL_COND ( ! light ) ;
light - > cull_mask = p_mask ;
light - > version + + ;
2021-01-04 13:33:25 +01:00
light - > dependency . changed_notify ( DEPENDENCY_CHANGED_LIGHT ) ;
2019-09-07 03:51:27 +02:00
}
2022-02-24 22:55:14 +01:00
void RendererStorageRD : : light_set_distance_fade ( RID p_light , bool p_enabled , float p_begin , float p_shadow , float p_length ) {
Light * light = light_owner . get_or_null ( p_light ) ;
ERR_FAIL_COND ( ! light ) ;
light - > distance_fade = p_enabled ;
light - > distance_fade_begin = p_begin ;
light - > distance_fade_shadow = p_shadow ;
light - > distance_fade_length = p_length ;
}
2020-12-04 19:26:24 +01:00
void RendererStorageRD : : light_set_reverse_cull_face_mode ( RID p_light , bool p_enabled ) {
2021-09-29 19:08:41 +02:00
Light * light = light_owner . get_or_null ( p_light ) ;
2019-09-07 03:51:27 +02:00
ERR_FAIL_COND ( ! light ) ;
light - > reverse_cull = p_enabled ;
light - > version + + ;
2021-01-04 13:33:25 +01:00
light - > dependency . changed_notify ( DEPENDENCY_CHANGED_LIGHT ) ;
2019-09-07 03:51:27 +02:00
}
2020-12-04 19:26:24 +01:00
void RendererStorageRD : : light_set_bake_mode ( RID p_light , RS : : LightBakeMode p_bake_mode ) {
2021-09-29 19:08:41 +02:00
Light * light = light_owner . get_or_null ( p_light ) ;
2019-09-07 03:51:27 +02:00
ERR_FAIL_COND ( ! light ) ;
2020-06-25 15:33:28 +02:00
light - > bake_mode = p_bake_mode ;
light - > version + + ;
2021-01-04 13:33:25 +01:00
light - > dependency . changed_notify ( DEPENDENCY_CHANGED_LIGHT ) ;
2020-06-25 15:33:28 +02:00
}
2020-12-04 19:26:24 +01:00
void RendererStorageRD : : light_set_max_sdfgi_cascade ( RID p_light , uint32_t p_cascade ) {
2021-09-29 19:08:41 +02:00
Light * light = light_owner . get_or_null ( p_light ) ;
2020-06-25 15:33:28 +02:00
ERR_FAIL_COND ( ! light ) ;
light - > max_sdfgi_cascade = p_cascade ;
2019-09-07 03:51:27 +02:00
light - > version + + ;
2021-01-04 13:33:25 +01:00
light - > dependency . changed_notify ( DEPENDENCY_CHANGED_LIGHT ) ;
2019-09-07 03:51:27 +02:00
}
2020-05-14 14:29:06 +02:00
2020-12-04 19:26:24 +01:00
void RendererStorageRD : : light_omni_set_shadow_mode ( RID p_light , RS : : LightOmniShadowMode p_mode ) {
2021-09-29 19:08:41 +02:00
Light * light = light_owner . get_or_null ( p_light ) ;
2019-09-07 03:51:27 +02:00
ERR_FAIL_COND ( ! light ) ;
light - > omni_shadow_mode = p_mode ;
light - > version + + ;
2021-01-04 13:33:25 +01:00
light - > dependency . changed_notify ( DEPENDENCY_CHANGED_LIGHT ) ;
2019-09-07 03:51:27 +02:00
}
2020-12-04 19:26:24 +01:00
RS : : LightOmniShadowMode RendererStorageRD : : light_omni_get_shadow_mode ( RID p_light ) {
2021-09-29 19:08:41 +02:00
const Light * light = light_owner . get_or_null ( p_light ) ;
2020-03-27 19:21:27 +01:00
ERR_FAIL_COND_V ( ! light , RS : : LIGHT_OMNI_SHADOW_CUBE ) ;
2019-09-07 03:51:27 +02:00
return light - > omni_shadow_mode ;
}
2020-12-04 19:26:24 +01:00
void RendererStorageRD : : light_directional_set_shadow_mode ( RID p_light , RS : : LightDirectionalShadowMode p_mode ) {
2021-09-29 19:08:41 +02:00
Light * light = light_owner . get_or_null ( p_light ) ;
2019-09-07 03:51:27 +02:00
ERR_FAIL_COND ( ! light ) ;
light - > directional_shadow_mode = p_mode ;
light - > version + + ;
2021-01-04 13:33:25 +01:00
light - > dependency . changed_notify ( DEPENDENCY_CHANGED_LIGHT ) ;
2019-09-07 03:51:27 +02:00
}
2020-12-04 19:26:24 +01:00
void RendererStorageRD : : light_directional_set_blend_splits ( RID p_light , bool p_enable ) {
2021-09-29 19:08:41 +02:00
Light * light = light_owner . get_or_null ( p_light ) ;
2019-09-07 03:51:27 +02:00
ERR_FAIL_COND ( ! light ) ;
light - > directional_blend_splits = p_enable ;
light - > version + + ;
2021-01-04 13:33:25 +01:00
light - > dependency . changed_notify ( DEPENDENCY_CHANGED_LIGHT ) ;
2019-09-07 03:51:27 +02:00
}
2020-12-04 19:26:24 +01:00
bool RendererStorageRD : : light_directional_get_blend_splits ( RID p_light ) const {
2021-09-29 19:08:41 +02:00
const Light * light = light_owner . get_or_null ( p_light ) ;
2019-09-07 03:51:27 +02:00
ERR_FAIL_COND_V ( ! light , false ) ;
return light - > directional_blend_splits ;
}
2021-10-20 00:40:46 +02:00
void RendererStorageRD : : light_directional_set_sky_mode ( RID p_light , RS : : LightDirectionalSkyMode p_mode ) {
2021-09-29 19:08:41 +02:00
Light * light = light_owner . get_or_null ( p_light ) ;
2020-10-22 08:22:53 +02:00
ERR_FAIL_COND ( ! light ) ;
2021-10-20 00:40:46 +02:00
light - > directional_sky_mode = p_mode ;
2020-10-22 08:22:53 +02:00
}
2021-10-20 00:40:46 +02:00
RS : : LightDirectionalSkyMode RendererStorageRD : : light_directional_get_sky_mode ( RID p_light ) const {
2021-09-29 19:08:41 +02:00
const Light * light = light_owner . get_or_null ( p_light ) ;
2021-10-20 00:40:46 +02:00
ERR_FAIL_COND_V ( ! light , RS : : LIGHT_DIRECTIONAL_SKY_MODE_LIGHT_AND_SKY ) ;
2020-10-22 08:22:53 +02:00
2021-10-20 00:40:46 +02:00
return light - > directional_sky_mode ;
2020-10-22 08:22:53 +02:00
}
2020-12-04 19:26:24 +01:00
RS : : LightDirectionalShadowMode RendererStorageRD : : light_directional_get_shadow_mode ( RID p_light ) {
2021-09-29 19:08:41 +02:00
const Light * light = light_owner . get_or_null ( p_light ) ;
2020-03-27 19:21:27 +01:00
ERR_FAIL_COND_V ( ! light , RS : : LIGHT_DIRECTIONAL_SHADOW_ORTHOGONAL ) ;
2019-09-07 03:51:27 +02:00
return light - > directional_shadow_mode ;
}
2020-12-04 19:26:24 +01:00
uint32_t RendererStorageRD : : light_get_max_sdfgi_cascade ( RID p_light ) {
2021-09-29 19:08:41 +02:00
const Light * light = light_owner . get_or_null ( p_light ) ;
2020-06-25 15:33:28 +02:00
ERR_FAIL_COND_V ( ! light , 0 ) ;
return light - > max_sdfgi_cascade ;
}
2020-12-04 19:26:24 +01:00
RS : : LightBakeMode RendererStorageRD : : light_get_bake_mode ( RID p_light ) {
2021-09-29 19:08:41 +02:00
const Light * light = light_owner . get_or_null ( p_light ) ;
2020-06-25 15:33:28 +02:00
ERR_FAIL_COND_V ( ! light , RS : : LIGHT_BAKE_DISABLED ) ;
2019-09-07 03:51:27 +02:00
2020-06-25 15:33:28 +02:00
return light - > bake_mode ;
2019-09-07 03:51:27 +02:00
}
2020-12-04 19:26:24 +01:00
uint64_t RendererStorageRD : : light_get_version ( RID p_light ) const {
2021-09-29 19:08:41 +02:00
const Light * light = light_owner . get_or_null ( p_light ) ;
2019-09-07 03:51:27 +02:00
ERR_FAIL_COND_V ( ! light , 0 ) ;
return light - > version ;
}
2020-12-04 19:26:24 +01:00
AABB RendererStorageRD : : light_get_aabb ( RID p_light ) const {
2021-09-29 19:08:41 +02:00
const Light * light = light_owner . get_or_null ( p_light ) ;
2019-09-07 03:51:27 +02:00
ERR_FAIL_COND_V ( ! light , AABB ( ) ) ;
switch ( light - > type ) {
2020-03-27 19:21:27 +01:00
case RS : : LIGHT_SPOT : {
float len = light - > param [ RS : : LIGHT_PARAM_RANGE ] ;
float size = Math : : tan ( Math : : deg2rad ( light - > param [ RS : : LIGHT_PARAM_SPOT_ANGLE ] ) ) * len ;
2019-09-07 03:51:27 +02:00
return AABB ( Vector3 ( - size , - size , - len ) , Vector3 ( size * 2 , size * 2 , len ) ) ;
} ;
2020-03-27 19:21:27 +01:00
case RS : : LIGHT_OMNI : {
float r = light - > param [ RS : : LIGHT_PARAM_RANGE ] ;
2019-09-07 03:51:27 +02:00
return AABB ( - Vector3 ( r , r , r ) , Vector3 ( r , r , r ) * 2 ) ;
} ;
2020-03-27 19:21:27 +01:00
case RS : : LIGHT_DIRECTIONAL : {
2019-09-07 03:51:27 +02:00
return AABB ( ) ;
} ;
}
ERR_FAIL_V ( AABB ( ) ) ;
}
/* REFLECTION PROBE */
2021-02-09 17:19:03 +01:00
RID RendererStorageRD : : reflection_probe_allocate ( ) {
return reflection_probe_owner . allocate_rid ( ) ;
}
void RendererStorageRD : : reflection_probe_initialize ( RID p_reflection_probe ) {
reflection_probe_owner . initialize_rid ( p_reflection_probe , ReflectionProbe ( ) ) ;
2019-09-07 03:51:27 +02:00
}
2020-12-04 19:26:24 +01:00
void RendererStorageRD : : reflection_probe_set_update_mode ( RID p_probe , RS : : ReflectionProbeUpdateMode p_mode ) {
2021-09-29 19:08:41 +02:00
ReflectionProbe * reflection_probe = reflection_probe_owner . get_or_null ( p_probe ) ;
2019-09-07 03:51:27 +02:00
ERR_FAIL_COND ( ! reflection_probe ) ;
reflection_probe - > update_mode = p_mode ;
2021-01-04 13:33:25 +01:00
reflection_probe - > dependency . changed_notify ( DEPENDENCY_CHANGED_REFLECTION_PROBE ) ;
2019-09-07 03:51:27 +02:00
}
2020-12-04 19:26:24 +01:00
void RendererStorageRD : : reflection_probe_set_intensity ( RID p_probe , float p_intensity ) {
2021-09-29 19:08:41 +02:00
ReflectionProbe * reflection_probe = reflection_probe_owner . get_or_null ( p_probe ) ;
2019-09-07 03:51:27 +02:00
ERR_FAIL_COND ( ! reflection_probe ) ;
reflection_probe - > intensity = p_intensity ;
}
2020-12-04 19:26:24 +01:00
void RendererStorageRD : : reflection_probe_set_ambient_mode ( RID p_probe , RS : : ReflectionProbeAmbientMode p_mode ) {
2021-09-29 19:08:41 +02:00
ReflectionProbe * reflection_probe = reflection_probe_owner . get_or_null ( p_probe ) ;
2019-09-07 03:51:27 +02:00
ERR_FAIL_COND ( ! reflection_probe ) ;
2020-06-25 15:33:28 +02:00
reflection_probe - > ambient_mode = p_mode ;
2019-09-07 03:51:27 +02:00
}
2020-12-04 19:26:24 +01:00
void RendererStorageRD : : reflection_probe_set_ambient_color ( RID p_probe , const Color & p_color ) {
2021-09-29 19:08:41 +02:00
ReflectionProbe * reflection_probe = reflection_probe_owner . get_or_null ( p_probe ) ;
2019-09-07 03:51:27 +02:00
ERR_FAIL_COND ( ! reflection_probe ) ;
2020-06-25 15:33:28 +02:00
reflection_probe - > ambient_color = p_color ;
2019-09-07 03:51:27 +02:00
}
2020-12-04 19:26:24 +01:00
void RendererStorageRD : : reflection_probe_set_ambient_energy ( RID p_probe , float p_energy ) {
2021-09-29 19:08:41 +02:00
ReflectionProbe * reflection_probe = reflection_probe_owner . get_or_null ( p_probe ) ;
2019-09-07 03:51:27 +02:00
ERR_FAIL_COND ( ! reflection_probe ) ;
2020-06-25 15:33:28 +02:00
reflection_probe - > ambient_color_energy = p_energy ;
2019-09-07 03:51:27 +02:00
}
2020-12-04 19:26:24 +01:00
void RendererStorageRD : : reflection_probe_set_max_distance ( RID p_probe , float p_distance ) {
2021-09-29 19:08:41 +02:00
ReflectionProbe * reflection_probe = reflection_probe_owner . get_or_null ( p_probe ) ;
2019-09-07 03:51:27 +02:00
ERR_FAIL_COND ( ! reflection_probe ) ;
reflection_probe - > max_distance = p_distance ;
2021-01-04 13:33:25 +01:00
reflection_probe - > dependency . changed_notify ( DEPENDENCY_CHANGED_REFLECTION_PROBE ) ;
2019-09-07 03:51:27 +02:00
}
2020-05-14 14:29:06 +02:00
2020-12-04 19:26:24 +01:00
void RendererStorageRD : : reflection_probe_set_extents ( RID p_probe , const Vector3 & p_extents ) {
2021-09-29 19:08:41 +02:00
ReflectionProbe * reflection_probe = reflection_probe_owner . get_or_null ( p_probe ) ;
2019-09-07 03:51:27 +02:00
ERR_FAIL_COND ( ! reflection_probe ) ;
2020-10-08 02:29:49 +02:00
if ( reflection_probe - > extents = = p_extents ) {
return ;
}
2019-09-07 03:51:27 +02:00
reflection_probe - > extents = p_extents ;
2021-01-04 13:33:25 +01:00
reflection_probe - > dependency . changed_notify ( DEPENDENCY_CHANGED_REFLECTION_PROBE ) ;
2019-09-07 03:51:27 +02:00
}
2020-05-14 14:29:06 +02:00
2020-12-04 19:26:24 +01:00
void RendererStorageRD : : reflection_probe_set_origin_offset ( RID p_probe , const Vector3 & p_offset ) {
2021-09-29 19:08:41 +02:00
ReflectionProbe * reflection_probe = reflection_probe_owner . get_or_null ( p_probe ) ;
2019-09-07 03:51:27 +02:00
ERR_FAIL_COND ( ! reflection_probe ) ;
reflection_probe - > origin_offset = p_offset ;
2021-01-04 13:33:25 +01:00
reflection_probe - > dependency . changed_notify ( DEPENDENCY_CHANGED_REFLECTION_PROBE ) ;
2019-09-07 03:51:27 +02:00
}
2020-12-04 19:26:24 +01:00
void RendererStorageRD : : reflection_probe_set_as_interior ( RID p_probe , bool p_enable ) {
2021-09-29 19:08:41 +02:00
ReflectionProbe * reflection_probe = reflection_probe_owner . get_or_null ( p_probe ) ;
2019-09-07 03:51:27 +02:00
ERR_FAIL_COND ( ! reflection_probe ) ;
reflection_probe - > interior = p_enable ;
2021-01-04 13:33:25 +01:00
reflection_probe - > dependency . changed_notify ( DEPENDENCY_CHANGED_REFLECTION_PROBE ) ;
2019-09-07 03:51:27 +02:00
}
2020-05-14 14:29:06 +02:00
2020-12-04 19:26:24 +01:00
void RendererStorageRD : : reflection_probe_set_enable_box_projection ( RID p_probe , bool p_enable ) {
2021-09-29 19:08:41 +02:00
ReflectionProbe * reflection_probe = reflection_probe_owner . get_or_null ( p_probe ) ;
2019-09-07 03:51:27 +02:00
ERR_FAIL_COND ( ! reflection_probe ) ;
reflection_probe - > box_projection = p_enable ;
}
2020-12-04 19:26:24 +01:00
void RendererStorageRD : : reflection_probe_set_enable_shadows ( RID p_probe , bool p_enable ) {
2021-09-29 19:08:41 +02:00
ReflectionProbe * reflection_probe = reflection_probe_owner . get_or_null ( p_probe ) ;
2019-09-07 03:51:27 +02:00
ERR_FAIL_COND ( ! reflection_probe ) ;
reflection_probe - > enable_shadows = p_enable ;
2021-01-04 13:33:25 +01:00
reflection_probe - > dependency . changed_notify ( DEPENDENCY_CHANGED_REFLECTION_PROBE ) ;
2019-09-07 03:51:27 +02:00
}
2020-05-14 14:29:06 +02:00
2020-12-04 19:26:24 +01:00
void RendererStorageRD : : reflection_probe_set_cull_mask ( RID p_probe , uint32_t p_layers ) {
2021-09-29 19:08:41 +02:00
ReflectionProbe * reflection_probe = reflection_probe_owner . get_or_null ( p_probe ) ;
2019-09-07 03:51:27 +02:00
ERR_FAIL_COND ( ! reflection_probe ) ;
reflection_probe - > cull_mask = p_layers ;
2021-01-04 13:33:25 +01:00
reflection_probe - > dependency . changed_notify ( DEPENDENCY_CHANGED_REFLECTION_PROBE ) ;
2019-09-07 03:51:27 +02:00
}
2020-12-04 19:26:24 +01:00
void RendererStorageRD : : reflection_probe_set_resolution ( RID p_probe , int p_resolution ) {
2021-09-29 19:08:41 +02:00
ReflectionProbe * reflection_probe = reflection_probe_owner . get_or_null ( p_probe ) ;
2019-09-07 03:51:27 +02:00
ERR_FAIL_COND ( ! reflection_probe ) ;
ERR_FAIL_COND ( p_resolution < 32 ) ;
reflection_probe - > resolution = p_resolution ;
}
2021-12-29 00:10:41 +01:00
void RendererStorageRD : : reflection_probe_set_mesh_lod_threshold ( RID p_probe , float p_ratio ) {
2021-09-29 19:08:41 +02:00
ReflectionProbe * reflection_probe = reflection_probe_owner . get_or_null ( p_probe ) ;
2020-12-17 19:56:59 +01:00
ERR_FAIL_COND ( ! reflection_probe ) ;
2021-12-29 00:10:41 +01:00
reflection_probe - > mesh_lod_threshold = p_ratio ;
2020-12-17 19:56:59 +01:00
2021-01-04 13:33:25 +01:00
reflection_probe - > dependency . changed_notify ( DEPENDENCY_CHANGED_REFLECTION_PROBE ) ;
2020-12-17 19:56:59 +01:00
}
2020-12-04 19:26:24 +01:00
AABB RendererStorageRD : : reflection_probe_get_aabb ( RID p_probe ) const {
2021-09-29 19:08:41 +02:00
const ReflectionProbe * reflection_probe = reflection_probe_owner . get_or_null ( p_probe ) ;
2019-09-07 03:51:27 +02:00
ERR_FAIL_COND_V ( ! reflection_probe , AABB ( ) ) ;
AABB aabb ;
aabb . position = - reflection_probe - > extents ;
aabb . size = reflection_probe - > extents * 2.0 ;
return aabb ;
}
2020-05-14 14:29:06 +02:00
2020-12-04 19:26:24 +01:00
RS : : ReflectionProbeUpdateMode RendererStorageRD : : reflection_probe_get_update_mode ( RID p_probe ) const {
2021-09-29 19:08:41 +02:00
const ReflectionProbe * reflection_probe = reflection_probe_owner . get_or_null ( p_probe ) ;
2020-03-27 19:21:27 +01:00
ERR_FAIL_COND_V ( ! reflection_probe , RS : : REFLECTION_PROBE_UPDATE_ALWAYS ) ;
2019-09-07 03:51:27 +02:00
return reflection_probe - > update_mode ;
}
2020-12-04 19:26:24 +01:00
uint32_t RendererStorageRD : : reflection_probe_get_cull_mask ( RID p_probe ) const {
2021-09-29 19:08:41 +02:00
const ReflectionProbe * reflection_probe = reflection_probe_owner . get_or_null ( p_probe ) ;
2019-09-07 03:51:27 +02:00
ERR_FAIL_COND_V ( ! reflection_probe , 0 ) ;
return reflection_probe - > cull_mask ;
}
2020-12-04 19:26:24 +01:00
Vector3 RendererStorageRD : : reflection_probe_get_extents ( RID p_probe ) const {
2021-09-29 19:08:41 +02:00
const ReflectionProbe * reflection_probe = reflection_probe_owner . get_or_null ( p_probe ) ;
2019-09-07 03:51:27 +02:00
ERR_FAIL_COND_V ( ! reflection_probe , Vector3 ( ) ) ;
return reflection_probe - > extents ;
}
2020-05-14 14:29:06 +02:00
2020-12-04 19:26:24 +01:00
Vector3 RendererStorageRD : : reflection_probe_get_origin_offset ( RID p_probe ) const {
2021-09-29 19:08:41 +02:00
const ReflectionProbe * reflection_probe = reflection_probe_owner . get_or_null ( p_probe ) ;
2019-09-07 03:51:27 +02:00
ERR_FAIL_COND_V ( ! reflection_probe , Vector3 ( ) ) ;
return reflection_probe - > origin_offset ;
}
2020-12-04 19:26:24 +01:00
bool RendererStorageRD : : reflection_probe_renders_shadows ( RID p_probe ) const {
2021-09-29 19:08:41 +02:00
const ReflectionProbe * reflection_probe = reflection_probe_owner . get_or_null ( p_probe ) ;
2019-09-07 03:51:27 +02:00
ERR_FAIL_COND_V ( ! reflection_probe , false ) ;
return reflection_probe - > enable_shadows ;
}
2020-12-04 19:26:24 +01:00
float RendererStorageRD : : reflection_probe_get_origin_max_distance ( RID p_probe ) const {
2021-09-29 19:08:41 +02:00
const ReflectionProbe * reflection_probe = reflection_probe_owner . get_or_null ( p_probe ) ;
2019-09-07 03:51:27 +02:00
ERR_FAIL_COND_V ( ! reflection_probe , 0 ) ;
return reflection_probe - > max_distance ;
}
2021-12-29 00:10:41 +01:00
float RendererStorageRD : : reflection_probe_get_mesh_lod_threshold ( RID p_probe ) const {
2021-09-29 19:08:41 +02:00
const ReflectionProbe * reflection_probe = reflection_probe_owner . get_or_null ( p_probe ) ;
2020-12-17 19:56:59 +01:00
ERR_FAIL_COND_V ( ! reflection_probe , 0 ) ;
2021-12-29 00:10:41 +01:00
return reflection_probe - > mesh_lod_threshold ;
2020-12-17 19:56:59 +01:00
}
2020-12-04 19:26:24 +01:00
int RendererStorageRD : : reflection_probe_get_resolution ( RID p_probe ) const {
2021-09-29 19:08:41 +02:00
const ReflectionProbe * reflection_probe = reflection_probe_owner . get_or_null ( p_probe ) ;
2019-09-07 03:51:27 +02:00
ERR_FAIL_COND_V ( ! reflection_probe , 0 ) ;
return reflection_probe - > resolution ;
}
2020-12-04 19:26:24 +01:00
float RendererStorageRD : : reflection_probe_get_intensity ( RID p_probe ) const {
2021-09-29 19:08:41 +02:00
const ReflectionProbe * reflection_probe = reflection_probe_owner . get_or_null ( p_probe ) ;
2019-09-07 03:51:27 +02:00
ERR_FAIL_COND_V ( ! reflection_probe , 0 ) ;
return reflection_probe - > intensity ;
}
2020-05-14 14:29:06 +02:00
2020-12-04 19:26:24 +01:00
bool RendererStorageRD : : reflection_probe_is_interior ( RID p_probe ) const {
2021-09-29 19:08:41 +02:00
const ReflectionProbe * reflection_probe = reflection_probe_owner . get_or_null ( p_probe ) ;
2019-09-07 03:51:27 +02:00
ERR_FAIL_COND_V ( ! reflection_probe , false ) ;
return reflection_probe - > interior ;
}
2020-05-14 14:29:06 +02:00
2020-12-04 19:26:24 +01:00
bool RendererStorageRD : : reflection_probe_is_box_projection ( RID p_probe ) const {
2021-09-29 19:08:41 +02:00
const ReflectionProbe * reflection_probe = reflection_probe_owner . get_or_null ( p_probe ) ;
2019-09-07 03:51:27 +02:00
ERR_FAIL_COND_V ( ! reflection_probe , false ) ;
return reflection_probe - > box_projection ;
}
2020-12-04 19:26:24 +01:00
RS : : ReflectionProbeAmbientMode RendererStorageRD : : reflection_probe_get_ambient_mode ( RID p_probe ) const {
2021-09-29 19:08:41 +02:00
const ReflectionProbe * reflection_probe = reflection_probe_owner . get_or_null ( p_probe ) ;
2020-06-25 15:33:28 +02:00
ERR_FAIL_COND_V ( ! reflection_probe , RS : : REFLECTION_PROBE_AMBIENT_DISABLED ) ;
return reflection_probe - > ambient_mode ;
2019-09-07 03:51:27 +02:00
}
2020-05-14 14:29:06 +02:00
2020-12-04 19:26:24 +01:00
Color RendererStorageRD : : reflection_probe_get_ambient_color ( RID p_probe ) const {
2021-09-29 19:08:41 +02:00
const ReflectionProbe * reflection_probe = reflection_probe_owner . get_or_null ( p_probe ) ;
2020-06-25 15:33:28 +02:00
ERR_FAIL_COND_V ( ! reflection_probe , Color ( ) ) ;
2019-09-07 03:51:27 +02:00
2020-06-25 15:33:28 +02:00
return reflection_probe - > ambient_color ;
2019-09-07 03:51:27 +02:00
}
2020-12-04 19:26:24 +01:00
float RendererStorageRD : : reflection_probe_get_ambient_color_energy ( RID p_probe ) const {
2021-09-29 19:08:41 +02:00
const ReflectionProbe * reflection_probe = reflection_probe_owner . get_or_null ( p_probe ) ;
2019-09-07 03:51:27 +02:00
ERR_FAIL_COND_V ( ! reflection_probe , 0 ) ;
2020-06-25 15:33:28 +02:00
return reflection_probe - > ambient_color_energy ;
2019-09-07 03:51:27 +02:00
}
2021-06-05 00:47:26 +02:00
RID RendererStorageRD : : voxel_gi_allocate ( ) {
return voxel_gi_owner . allocate_rid ( ) ;
2021-02-09 17:19:03 +01:00
}
2021-06-05 00:47:26 +02:00
void RendererStorageRD : : voxel_gi_initialize ( RID p_voxel_gi ) {
voxel_gi_owner . initialize_rid ( p_voxel_gi , VoxelGI ( ) ) ;
2019-10-03 22:39:08 +02:00
}
2021-06-05 00:47:26 +02:00
void RendererStorageRD : : voxel_gi_allocate_data ( RID p_voxel_gi , const Transform3D & p_to_cell_xform , const AABB & p_aabb , const Vector3i & p_octree_size , const Vector < uint8_t > & p_octree_cells , const Vector < uint8_t > & p_data_cells , const Vector < uint8_t > & p_distance_field , const Vector < int > & p_level_counts ) {
2021-09-29 19:08:41 +02:00
VoxelGI * voxel_gi = voxel_gi_owner . get_or_null ( p_voxel_gi ) ;
2021-06-05 00:47:26 +02:00
ERR_FAIL_COND ( ! voxel_gi ) ;
2019-10-03 22:39:08 +02:00
2021-06-05 00:47:26 +02:00
if ( voxel_gi - > octree_buffer . is_valid ( ) ) {
RD : : get_singleton ( ) - > free ( voxel_gi - > octree_buffer ) ;
RD : : get_singleton ( ) - > free ( voxel_gi - > data_buffer ) ;
if ( voxel_gi - > sdf_texture . is_valid ( ) ) {
RD : : get_singleton ( ) - > free ( voxel_gi - > sdf_texture ) ;
2019-10-03 22:39:08 +02:00
}
2021-06-05 00:47:26 +02:00
voxel_gi - > sdf_texture = RID ( ) ;
voxel_gi - > octree_buffer = RID ( ) ;
voxel_gi - > data_buffer = RID ( ) ;
voxel_gi - > octree_buffer_size = 0 ;
voxel_gi - > data_buffer_size = 0 ;
voxel_gi - > cell_count = 0 ;
2019-10-03 22:39:08 +02:00
}
2021-06-05 00:47:26 +02:00
voxel_gi - > to_cell_xform = p_to_cell_xform ;
voxel_gi - > bounds = p_aabb ;
voxel_gi - > octree_size = p_octree_size ;
voxel_gi - > level_counts = p_level_counts ;
2019-10-03 22:39:08 +02:00
2019-10-11 04:14:56 +02:00
if ( p_octree_cells . size ( ) ) {
2019-10-03 22:39:08 +02:00
ERR_FAIL_COND ( p_octree_cells . size ( ) % 32 ! = 0 ) ; //cells size must be a multiple of 32
uint32_t cell_count = p_octree_cells . size ( ) / 32 ;
2020-02-13 15:53:32 +01:00
ERR_FAIL_COND ( p_data_cells . size ( ) ! = ( int ) cell_count * 16 ) ; //see that data size matches
2019-10-03 22:39:08 +02:00
2021-06-05 00:47:26 +02:00
voxel_gi - > cell_count = cell_count ;
voxel_gi - > octree_buffer = RD : : get_singleton ( ) - > storage_buffer_create ( p_octree_cells . size ( ) , p_octree_cells ) ;
voxel_gi - > octree_buffer_size = p_octree_cells . size ( ) ;
voxel_gi - > data_buffer = RD : : get_singleton ( ) - > storage_buffer_create ( p_data_cells . size ( ) , p_data_cells ) ;
voxel_gi - > data_buffer_size = p_data_cells . size ( ) ;
2019-10-11 04:14:56 +02:00
2019-10-13 02:24:03 +02:00
if ( p_distance_field . size ( ) ) {
RD : : TextureFormat tf ;
tf . format = RD : : DATA_FORMAT_R8_UNORM ;
2021-06-05 00:47:26 +02:00
tf . width = voxel_gi - > octree_size . x ;
tf . height = voxel_gi - > octree_size . y ;
tf . depth = voxel_gi - > octree_size . z ;
2020-11-27 04:50:05 +01:00
tf . texture_type = RD : : TEXTURE_TYPE_3D ;
2019-10-13 02:24:03 +02:00
tf . usage_bits = RD : : TEXTURE_USAGE_SAMPLING_BIT | RD : : TEXTURE_USAGE_CAN_UPDATE_BIT | RD : : TEXTURE_USAGE_CAN_COPY_FROM_BIT ;
2020-03-17 07:33:00 +01:00
Vector < Vector < uint8_t > > s ;
2019-10-13 02:24:03 +02:00
s . push_back ( p_distance_field ) ;
2021-06-05 00:47:26 +02:00
voxel_gi - > sdf_texture = RD : : get_singleton ( ) - > texture_create ( tf , RD : : TextureView ( ) , s ) ;
2019-10-13 02:24:03 +02:00
}
#if 0
2019-10-11 04:14:56 +02:00
{
RD : : TextureFormat tf ;
tf . format = RD : : DATA_FORMAT_R8_UNORM ;
2021-06-05 00:47:26 +02:00
tf . width = voxel_gi - > octree_size . x ;
tf . height = voxel_gi - > octree_size . y ;
tf . depth = voxel_gi - > octree_size . z ;
2019-10-11 04:14:56 +02:00
tf . type = RD : : TEXTURE_TYPE_3D ;
tf . usage_bits = RD : : TEXTURE_USAGE_SAMPLING_BIT | RD : : TEXTURE_USAGE_STORAGE_BIT | RD : : TEXTURE_USAGE_CAN_COPY_TO_BIT ;
tf . shareable_formats . push_back ( RD : : DATA_FORMAT_R8_UNORM ) ;
tf . shareable_formats . push_back ( RD : : DATA_FORMAT_R8_UINT ) ;
2021-06-05 00:47:26 +02:00
voxel_gi - > sdf_texture = RD : : get_singleton ( ) - > texture_create ( tf , RD : : TextureView ( ) ) ;
2019-10-11 04:14:56 +02:00
}
RID shared_tex ;
{
RD : : TextureView tv ;
tv . format_override = RD : : DATA_FORMAT_R8_UINT ;
2021-06-05 00:47:26 +02:00
shared_tex = RD : : get_singleton ( ) - > texture_create_shared ( tv , voxel_gi - > sdf_texture ) ;
2019-10-11 04:14:56 +02:00
}
//update SDF texture
Vector < RD : : Uniform > uniforms ;
{
RD : : Uniform u ;
2020-10-17 03:19:21 +02:00
u . uniform_type = RD : : UNIFORM_TYPE_STORAGE_BUFFER ;
2019-10-11 04:14:56 +02:00
u . binding = 1 ;
2022-03-06 12:57:09 +01:00
u . append_id ( voxel_gi - > octree_buffer ) ;
2019-10-11 04:14:56 +02:00
uniforms . push_back ( u ) ;
}
{
RD : : Uniform u ;
2020-10-17 03:19:21 +02:00
u . uniform_type = RD : : UNIFORM_TYPE_STORAGE_BUFFER ;
2019-10-11 04:14:56 +02:00
u . binding = 2 ;
2022-03-06 12:57:09 +01:00
u . append_id ( voxel_gi - > data_buffer ) ;
2019-10-11 04:14:56 +02:00
uniforms . push_back ( u ) ;
}
{
RD : : Uniform u ;
2020-10-17 03:19:21 +02:00
u . uniform_type = RD : : UNIFORM_TYPE_IMAGE ;
2019-10-11 04:14:56 +02:00
u . binding = 3 ;
2022-03-06 12:57:09 +01:00
u . append_id ( shared_tex ) ;
2019-10-11 04:14:56 +02:00
uniforms . push_back ( u ) ;
}
2021-06-05 00:47:26 +02:00
RID uniform_set = RD : : get_singleton ( ) - > uniform_set_create ( uniforms , voxel_gi_sdf_shader_version_shader , 0 ) ;
2019-10-11 04:14:56 +02:00
{
uint32_t push_constant [ 4 ] = { 0 , 0 , 0 , 0 } ;
2021-06-05 00:47:26 +02:00
for ( int i = 0 ; i < voxel_gi - > level_counts . size ( ) - 1 ; i + + ) {
push_constant [ 0 ] + = voxel_gi - > level_counts [ i ] ;
2019-10-11 04:14:56 +02:00
}
2021-06-05 00:47:26 +02:00
push_constant [ 1 ] = push_constant [ 0 ] + voxel_gi - > level_counts [ voxel_gi - > level_counts . size ( ) - 1 ] ;
2019-10-11 04:14:56 +02:00
print_line ( " offset: " + itos ( push_constant [ 0 ] ) ) ;
print_line ( " size: " + itos ( push_constant [ 1 ] ) ) ;
//create SDF
RD : : ComputeListID compute_list = RD : : get_singleton ( ) - > compute_list_begin ( ) ;
2021-06-05 00:47:26 +02:00
RD : : get_singleton ( ) - > compute_list_bind_compute_pipeline ( compute_list , voxel_gi_sdf_shader_pipeline ) ;
2019-10-11 04:14:56 +02:00
RD : : get_singleton ( ) - > compute_list_bind_uniform_set ( compute_list , uniform_set , 0 ) ;
RD : : get_singleton ( ) - > compute_list_set_push_constant ( compute_list , push_constant , sizeof ( uint32_t ) * 4 ) ;
2021-06-05 00:47:26 +02:00
RD : : get_singleton ( ) - > compute_list_dispatch ( compute_list , voxel_gi - > octree_size . x / 4 , voxel_gi - > octree_size . y / 4 , voxel_gi - > octree_size . z / 4 ) ;
2019-10-11 04:14:56 +02:00
RD : : get_singleton ( ) - > compute_list_end ( ) ;
}
RD : : get_singleton ( ) - > free ( uniform_set ) ;
RD : : get_singleton ( ) - > free ( shared_tex ) ;
}
2019-10-13 02:24:03 +02:00
# endif
2019-10-03 22:39:08 +02:00
}
2021-06-05 00:47:26 +02:00
voxel_gi - > version + + ;
voxel_gi - > data_version + + ;
2019-10-11 04:14:56 +02:00
2021-06-05 00:47:26 +02:00
voxel_gi - > dependency . changed_notify ( DEPENDENCY_CHANGED_AABB ) ;
2019-10-03 22:39:08 +02:00
}
2021-06-05 00:47:26 +02:00
AABB RendererStorageRD : : voxel_gi_get_bounds ( RID p_voxel_gi ) const {
2021-09-29 19:08:41 +02:00
VoxelGI * voxel_gi = voxel_gi_owner . get_or_null ( p_voxel_gi ) ;
2021-06-05 00:47:26 +02:00
ERR_FAIL_COND_V ( ! voxel_gi , AABB ( ) ) ;
2019-10-03 22:39:08 +02:00
2021-06-05 00:47:26 +02:00
return voxel_gi - > bounds ;
2019-10-03 22:39:08 +02:00
}
2021-06-05 00:47:26 +02:00
Vector3i RendererStorageRD : : voxel_gi_get_octree_size ( RID p_voxel_gi ) const {
2021-09-29 19:08:41 +02:00
VoxelGI * voxel_gi = voxel_gi_owner . get_or_null ( p_voxel_gi ) ;
2021-06-05 00:47:26 +02:00
ERR_FAIL_COND_V ( ! voxel_gi , Vector3i ( ) ) ;
return voxel_gi - > octree_size ;
2019-10-03 22:39:08 +02:00
}
2020-05-14 14:29:06 +02:00
2021-06-05 00:47:26 +02:00
Vector < uint8_t > RendererStorageRD : : voxel_gi_get_octree_cells ( RID p_voxel_gi ) const {
2021-09-29 19:08:41 +02:00
VoxelGI * voxel_gi = voxel_gi_owner . get_or_null ( p_voxel_gi ) ;
2021-06-05 00:47:26 +02:00
ERR_FAIL_COND_V ( ! voxel_gi , Vector < uint8_t > ( ) ) ;
2019-10-03 22:39:08 +02:00
2021-06-05 00:47:26 +02:00
if ( voxel_gi - > octree_buffer . is_valid ( ) ) {
return RD : : get_singleton ( ) - > buffer_get_data ( voxel_gi - > octree_buffer ) ;
2019-10-03 22:39:08 +02:00
}
2020-02-17 22:06:54 +01:00
return Vector < uint8_t > ( ) ;
2019-10-03 22:39:08 +02:00
}
2020-05-14 14:29:06 +02:00
2021-06-05 00:47:26 +02:00
Vector < uint8_t > RendererStorageRD : : voxel_gi_get_data_cells ( RID p_voxel_gi ) const {
2021-09-29 19:08:41 +02:00
VoxelGI * voxel_gi = voxel_gi_owner . get_or_null ( p_voxel_gi ) ;
2021-06-05 00:47:26 +02:00
ERR_FAIL_COND_V ( ! voxel_gi , Vector < uint8_t > ( ) ) ;
2019-10-03 22:39:08 +02:00
2021-06-05 00:47:26 +02:00
if ( voxel_gi - > data_buffer . is_valid ( ) ) {
return RD : : get_singleton ( ) - > buffer_get_data ( voxel_gi - > data_buffer ) ;
2019-10-03 22:39:08 +02:00
}
2020-02-17 22:06:54 +01:00
return Vector < uint8_t > ( ) ;
2019-10-03 22:39:08 +02:00
}
2020-05-14 14:29:06 +02:00
2021-06-05 00:47:26 +02:00
Vector < uint8_t > RendererStorageRD : : voxel_gi_get_distance_field ( RID p_voxel_gi ) const {
2021-09-29 19:08:41 +02:00
VoxelGI * voxel_gi = voxel_gi_owner . get_or_null ( p_voxel_gi ) ;
2021-06-05 00:47:26 +02:00
ERR_FAIL_COND_V ( ! voxel_gi , Vector < uint8_t > ( ) ) ;
2019-10-13 02:24:03 +02:00
2021-06-05 00:47:26 +02:00
if ( voxel_gi - > data_buffer . is_valid ( ) ) {
return RD : : get_singleton ( ) - > texture_get_data ( voxel_gi - > sdf_texture , 0 ) ;
2019-10-13 02:24:03 +02:00
}
2020-02-17 22:06:54 +01:00
return Vector < uint8_t > ( ) ;
2019-10-13 02:24:03 +02:00
}
2020-05-14 14:29:06 +02:00
2021-06-05 00:47:26 +02:00
Vector < int > RendererStorageRD : : voxel_gi_get_level_counts ( RID p_voxel_gi ) const {
2021-09-29 19:08:41 +02:00
VoxelGI * voxel_gi = voxel_gi_owner . get_or_null ( p_voxel_gi ) ;
2021-06-05 00:47:26 +02:00
ERR_FAIL_COND_V ( ! voxel_gi , Vector < int > ( ) ) ;
2019-10-03 22:39:08 +02:00
2021-06-05 00:47:26 +02:00
return voxel_gi - > level_counts ;
2019-10-03 22:39:08 +02:00
}
2020-05-14 14:29:06 +02:00
2021-06-05 00:47:26 +02:00
Transform3D RendererStorageRD : : voxel_gi_get_to_cell_xform ( RID p_voxel_gi ) const {
2021-09-29 19:08:41 +02:00
VoxelGI * voxel_gi = voxel_gi_owner . get_or_null ( p_voxel_gi ) ;
2021-06-05 00:47:26 +02:00
ERR_FAIL_COND_V ( ! voxel_gi , Transform3D ( ) ) ;
2019-10-03 22:39:08 +02:00
2021-06-05 00:47:26 +02:00
return voxel_gi - > to_cell_xform ;
2019-10-03 22:39:08 +02:00
}
2021-06-05 00:47:26 +02:00
void RendererStorageRD : : voxel_gi_set_dynamic_range ( RID p_voxel_gi , float p_range ) {
2021-09-29 19:08:41 +02:00
VoxelGI * voxel_gi = voxel_gi_owner . get_or_null ( p_voxel_gi ) ;
2021-06-05 00:47:26 +02:00
ERR_FAIL_COND ( ! voxel_gi ) ;
2019-10-03 22:39:08 +02:00
2021-06-05 00:47:26 +02:00
voxel_gi - > dynamic_range = p_range ;
voxel_gi - > version + + ;
2019-10-03 22:39:08 +02:00
}
2020-05-14 14:29:06 +02:00
2021-06-05 00:47:26 +02:00
float RendererStorageRD : : voxel_gi_get_dynamic_range ( RID p_voxel_gi ) const {
2021-09-29 19:08:41 +02:00
VoxelGI * voxel_gi = voxel_gi_owner . get_or_null ( p_voxel_gi ) ;
2021-06-05 00:47:26 +02:00
ERR_FAIL_COND_V ( ! voxel_gi , 0 ) ;
2019-10-03 22:39:08 +02:00
2021-06-05 00:47:26 +02:00
return voxel_gi - > dynamic_range ;
2019-10-03 22:39:08 +02:00
}
2021-06-05 00:47:26 +02:00
void RendererStorageRD : : voxel_gi_set_propagation ( RID p_voxel_gi , float p_range ) {
2021-09-29 19:08:41 +02:00
VoxelGI * voxel_gi = voxel_gi_owner . get_or_null ( p_voxel_gi ) ;
2021-06-05 00:47:26 +02:00
ERR_FAIL_COND ( ! voxel_gi ) ;
2019-10-03 22:39:08 +02:00
2021-06-05 00:47:26 +02:00
voxel_gi - > propagation = p_range ;
voxel_gi - > version + + ;
2019-10-03 22:39:08 +02:00
}
2020-05-14 14:29:06 +02:00
2021-06-05 00:47:26 +02:00
float RendererStorageRD : : voxel_gi_get_propagation ( RID p_voxel_gi ) const {
2021-09-29 19:08:41 +02:00
VoxelGI * voxel_gi = voxel_gi_owner . get_or_null ( p_voxel_gi ) ;
2021-06-05 00:47:26 +02:00
ERR_FAIL_COND_V ( ! voxel_gi , 0 ) ;
return voxel_gi - > propagation ;
2019-10-03 22:39:08 +02:00
}
2021-06-05 00:47:26 +02:00
void RendererStorageRD : : voxel_gi_set_energy ( RID p_voxel_gi , float p_energy ) {
2021-09-29 19:08:41 +02:00
VoxelGI * voxel_gi = voxel_gi_owner . get_or_null ( p_voxel_gi ) ;
2021-06-05 00:47:26 +02:00
ERR_FAIL_COND ( ! voxel_gi ) ;
2019-10-03 22:39:08 +02:00
2021-06-05 00:47:26 +02:00
voxel_gi - > energy = p_energy ;
2019-10-03 22:39:08 +02:00
}
2020-05-14 14:29:06 +02:00
2021-06-05 00:47:26 +02:00
float RendererStorageRD : : voxel_gi_get_energy ( RID p_voxel_gi ) const {
2021-09-29 19:08:41 +02:00
VoxelGI * voxel_gi = voxel_gi_owner . get_or_null ( p_voxel_gi ) ;
2021-06-05 00:47:26 +02:00
ERR_FAIL_COND_V ( ! voxel_gi , 0 ) ;
return voxel_gi - > energy ;
2019-10-03 22:39:08 +02:00
}
2021-06-05 00:47:26 +02:00
void RendererStorageRD : : voxel_gi_set_bias ( RID p_voxel_gi , float p_bias ) {
2021-09-29 19:08:41 +02:00
VoxelGI * voxel_gi = voxel_gi_owner . get_or_null ( p_voxel_gi ) ;
2021-06-05 00:47:26 +02:00
ERR_FAIL_COND ( ! voxel_gi ) ;
2019-10-03 22:39:08 +02:00
2021-06-05 00:47:26 +02:00
voxel_gi - > bias = p_bias ;
2019-10-03 22:39:08 +02:00
}
2020-05-14 14:29:06 +02:00
2021-06-05 00:47:26 +02:00
float RendererStorageRD : : voxel_gi_get_bias ( RID p_voxel_gi ) const {
2021-09-29 19:08:41 +02:00
VoxelGI * voxel_gi = voxel_gi_owner . get_or_null ( p_voxel_gi ) ;
2021-06-05 00:47:26 +02:00
ERR_FAIL_COND_V ( ! voxel_gi , 0 ) ;
return voxel_gi - > bias ;
2019-10-03 22:39:08 +02:00
}
2021-06-05 00:47:26 +02:00
void RendererStorageRD : : voxel_gi_set_normal_bias ( RID p_voxel_gi , float p_normal_bias ) {
2021-09-29 19:08:41 +02:00
VoxelGI * voxel_gi = voxel_gi_owner . get_or_null ( p_voxel_gi ) ;
2021-06-05 00:47:26 +02:00
ERR_FAIL_COND ( ! voxel_gi ) ;
2019-10-03 22:39:08 +02:00
2021-06-05 00:47:26 +02:00
voxel_gi - > normal_bias = p_normal_bias ;
2019-10-03 22:39:08 +02:00
}
2020-05-14 14:29:06 +02:00
2021-06-05 00:47:26 +02:00
float RendererStorageRD : : voxel_gi_get_normal_bias ( RID p_voxel_gi ) const {
2021-09-29 19:08:41 +02:00
VoxelGI * voxel_gi = voxel_gi_owner . get_or_null ( p_voxel_gi ) ;
2021-06-05 00:47:26 +02:00
ERR_FAIL_COND_V ( ! voxel_gi , 0 ) ;
return voxel_gi - > normal_bias ;
2019-10-03 22:39:08 +02:00
}
2021-06-05 00:47:26 +02:00
void RendererStorageRD : : voxel_gi_set_anisotropy_strength ( RID p_voxel_gi , float p_strength ) {
2021-09-29 19:08:41 +02:00
VoxelGI * voxel_gi = voxel_gi_owner . get_or_null ( p_voxel_gi ) ;
2021-06-05 00:47:26 +02:00
ERR_FAIL_COND ( ! voxel_gi ) ;
2019-10-03 22:39:08 +02:00
2021-06-05 00:47:26 +02:00
voxel_gi - > anisotropy_strength = p_strength ;
2019-10-03 22:39:08 +02:00
}
2021-06-05 00:47:26 +02:00
float RendererStorageRD : : voxel_gi_get_anisotropy_strength ( RID p_voxel_gi ) const {
2021-09-29 19:08:41 +02:00
VoxelGI * voxel_gi = voxel_gi_owner . get_or_null ( p_voxel_gi ) ;
2021-06-05 00:47:26 +02:00
ERR_FAIL_COND_V ( ! voxel_gi , 0 ) ;
return voxel_gi - > anisotropy_strength ;
2019-10-03 22:39:08 +02:00
}
2021-06-05 00:47:26 +02:00
void RendererStorageRD : : voxel_gi_set_interior ( RID p_voxel_gi , bool p_enable ) {
2021-09-29 19:08:41 +02:00
VoxelGI * voxel_gi = voxel_gi_owner . get_or_null ( p_voxel_gi ) ;
2021-06-05 00:47:26 +02:00
ERR_FAIL_COND ( ! voxel_gi ) ;
2019-10-03 22:39:08 +02:00
2021-06-05 00:47:26 +02:00
voxel_gi - > interior = p_enable ;
2019-10-03 22:39:08 +02:00
}
2021-06-05 00:47:26 +02:00
void RendererStorageRD : : voxel_gi_set_use_two_bounces ( RID p_voxel_gi , bool p_enable ) {
2021-09-29 19:08:41 +02:00
VoxelGI * voxel_gi = voxel_gi_owner . get_or_null ( p_voxel_gi ) ;
2021-06-05 00:47:26 +02:00
ERR_FAIL_COND ( ! voxel_gi ) ;
2019-10-03 22:39:08 +02:00
2021-06-05 00:47:26 +02:00
voxel_gi - > use_two_bounces = p_enable ;
voxel_gi - > version + + ;
2019-10-03 22:39:08 +02:00
}
2021-06-05 00:47:26 +02:00
bool RendererStorageRD : : voxel_gi_is_using_two_bounces ( RID p_voxel_gi ) const {
2021-09-29 19:08:41 +02:00
VoxelGI * voxel_gi = voxel_gi_owner . get_or_null ( p_voxel_gi ) ;
2021-06-05 00:47:26 +02:00
ERR_FAIL_COND_V ( ! voxel_gi , false ) ;
return voxel_gi - > use_two_bounces ;
2019-10-03 22:39:08 +02:00
}
2021-06-05 00:47:26 +02:00
bool RendererStorageRD : : voxel_gi_is_interior ( RID p_voxel_gi ) const {
2021-09-29 19:08:41 +02:00
VoxelGI * voxel_gi = voxel_gi_owner . get_or_null ( p_voxel_gi ) ;
2021-06-05 00:47:26 +02:00
ERR_FAIL_COND_V ( ! voxel_gi , 0 ) ;
return voxel_gi - > interior ;
2019-10-03 22:39:08 +02:00
}
2021-06-05 00:47:26 +02:00
uint32_t RendererStorageRD : : voxel_gi_get_version ( RID p_voxel_gi ) {
2021-09-29 19:08:41 +02:00
VoxelGI * voxel_gi = voxel_gi_owner . get_or_null ( p_voxel_gi ) ;
2021-06-05 00:47:26 +02:00
ERR_FAIL_COND_V ( ! voxel_gi , 0 ) ;
return voxel_gi - > version ;
2019-10-03 22:39:08 +02:00
}
2021-06-05 00:47:26 +02:00
uint32_t RendererStorageRD : : voxel_gi_get_data_version ( RID p_voxel_gi ) {
2021-09-29 19:08:41 +02:00
VoxelGI * voxel_gi = voxel_gi_owner . get_or_null ( p_voxel_gi ) ;
2021-06-05 00:47:26 +02:00
ERR_FAIL_COND_V ( ! voxel_gi , 0 ) ;
return voxel_gi - > data_version ;
2019-10-03 22:39:08 +02:00
}
2021-06-05 00:47:26 +02:00
RID RendererStorageRD : : voxel_gi_get_octree_buffer ( RID p_voxel_gi ) const {
2021-09-29 19:08:41 +02:00
VoxelGI * voxel_gi = voxel_gi_owner . get_or_null ( p_voxel_gi ) ;
2021-06-05 00:47:26 +02:00
ERR_FAIL_COND_V ( ! voxel_gi , RID ( ) ) ;
return voxel_gi - > octree_buffer ;
2019-10-03 22:39:08 +02:00
}
2020-05-14 14:29:06 +02:00
2021-06-05 00:47:26 +02:00
RID RendererStorageRD : : voxel_gi_get_data_buffer ( RID p_voxel_gi ) const {
2021-09-29 19:08:41 +02:00
VoxelGI * voxel_gi = voxel_gi_owner . get_or_null ( p_voxel_gi ) ;
2021-06-05 00:47:26 +02:00
ERR_FAIL_COND_V ( ! voxel_gi , RID ( ) ) ;
return voxel_gi - > data_buffer ;
2019-10-03 22:39:08 +02:00
}
2021-06-05 00:47:26 +02:00
RID RendererStorageRD : : voxel_gi_get_sdf_texture ( RID p_voxel_gi ) {
2021-09-29 19:08:41 +02:00
VoxelGI * voxel_gi = voxel_gi_owner . get_or_null ( p_voxel_gi ) ;
2021-06-05 00:47:26 +02:00
ERR_FAIL_COND_V ( ! voxel_gi , RID ( ) ) ;
2019-10-11 04:14:56 +02:00
2021-06-05 00:47:26 +02:00
return voxel_gi - > sdf_texture ;
2019-10-11 04:14:56 +02:00
}
2020-05-14 14:29:06 +02:00
2020-05-01 14:34:23 +02:00
/* LIGHTMAP API */
2021-02-09 17:19:03 +01:00
RID RendererStorageRD : : lightmap_allocate ( ) {
return lightmap_owner . allocate_rid ( ) ;
}
void RendererStorageRD : : lightmap_initialize ( RID p_lightmap ) {
lightmap_owner . initialize_rid ( p_lightmap , Lightmap ( ) ) ;
2020-05-01 14:34:23 +02:00
}
2020-12-04 19:26:24 +01:00
void RendererStorageRD : : lightmap_set_textures ( RID p_lightmap , RID p_light , bool p_uses_spherical_haromics ) {
2022-03-12 12:19:59 +01:00
RendererRD : : TextureStorage * texture_storage = RendererRD : : TextureStorage : : get_singleton ( ) ;
2021-09-29 19:08:41 +02:00
Lightmap * lm = lightmap_owner . get_or_null ( p_lightmap ) ;
2020-05-01 14:34:23 +02:00
ERR_FAIL_COND ( ! lm ) ;
lightmap_array_version + + ;
//erase lightmap users
if ( lm - > light_texture . is_valid ( ) ) {
2022-03-12 12:19:59 +01:00
RendererRD : : Texture * t = RendererRD : : TextureStorage : : get_singleton ( ) - > get_texture ( lm - > light_texture ) ;
2020-05-01 14:34:23 +02:00
if ( t ) {
t - > lightmap_users . erase ( p_lightmap ) ;
}
}
2022-03-12 12:19:59 +01:00
RendererRD : : Texture * t = RendererRD : : TextureStorage : : get_singleton ( ) - > get_texture ( p_light ) ;
2020-05-01 14:34:23 +02:00
lm - > light_texture = p_light ;
lm - > uses_spherical_harmonics = p_uses_spherical_haromics ;
2022-03-12 12:19:59 +01:00
RID default_2d_array = texture_storage - > texture_rd_get_default ( RendererRD : : DEFAULT_RD_TEXTURE_2D_ARRAY_WHITE ) ;
2020-05-01 14:34:23 +02:00
if ( ! t ) {
if ( using_lightmap_array ) {
if ( lm - > array_index > = 0 ) {
lightmap_textures . write [ lm - > array_index ] = default_2d_array ;
lm - > array_index = - 1 ;
}
}
return ;
}
t - > lightmap_users . insert ( p_lightmap ) ;
if ( using_lightmap_array ) {
if ( lm - > array_index < 0 ) {
//not in array, try to put in array
for ( int i = 0 ; i < lightmap_textures . size ( ) ; i + + ) {
if ( lightmap_textures [ i ] = = default_2d_array ) {
lm - > array_index = i ;
break ;
}
}
}
ERR_FAIL_COND_MSG ( lm - > array_index < 0 , " Maximum amount of lightmaps in use ( " + itos ( lightmap_textures . size ( ) ) + " ) has been exceeded, lightmap will nod display properly. " ) ;
lightmap_textures . write [ lm - > array_index ] = t - > rd_texture ;
}
}
2020-12-04 19:26:24 +01:00
void RendererStorageRD : : lightmap_set_probe_bounds ( RID p_lightmap , const AABB & p_bounds ) {
2021-09-29 19:08:41 +02:00
Lightmap * lm = lightmap_owner . get_or_null ( p_lightmap ) ;
2020-05-01 14:34:23 +02:00
ERR_FAIL_COND ( ! lm ) ;
lm - > bounds = p_bounds ;
}
2020-12-04 19:26:24 +01:00
void RendererStorageRD : : lightmap_set_probe_interior ( RID p_lightmap , bool p_interior ) {
2021-09-29 19:08:41 +02:00
Lightmap * lm = lightmap_owner . get_or_null ( p_lightmap ) ;
2020-05-01 14:34:23 +02:00
ERR_FAIL_COND ( ! lm ) ;
lm - > interior = p_interior ;
}
2020-12-04 19:26:24 +01:00
void RendererStorageRD : : lightmap_set_probe_capture_data ( RID p_lightmap , const PackedVector3Array & p_points , const PackedColorArray & p_point_sh , const PackedInt32Array & p_tetrahedra , const PackedInt32Array & p_bsp_tree ) {
2021-09-29 19:08:41 +02:00
Lightmap * lm = lightmap_owner . get_or_null ( p_lightmap ) ;
2020-05-01 14:34:23 +02:00
ERR_FAIL_COND ( ! lm ) ;
if ( p_points . size ( ) ) {
ERR_FAIL_COND ( p_points . size ( ) * 9 ! = p_point_sh . size ( ) ) ;
ERR_FAIL_COND ( ( p_tetrahedra . size ( ) % 4 ) ! = 0 ) ;
ERR_FAIL_COND ( ( p_bsp_tree . size ( ) % 6 ) ! = 0 ) ;
}
lm - > points = p_points ;
lm - > bsp_tree = p_bsp_tree ;
lm - > point_sh = p_point_sh ;
lm - > tetrahedra = p_tetrahedra ;
}
2020-12-04 19:26:24 +01:00
PackedVector3Array RendererStorageRD : : lightmap_get_probe_capture_points ( RID p_lightmap ) const {
2021-09-29 19:08:41 +02:00
Lightmap * lm = lightmap_owner . get_or_null ( p_lightmap ) ;
2020-05-01 14:34:23 +02:00
ERR_FAIL_COND_V ( ! lm , PackedVector3Array ( ) ) ;
return lm - > points ;
}
2020-05-14 14:29:06 +02:00
2020-12-04 19:26:24 +01:00
PackedColorArray RendererStorageRD : : lightmap_get_probe_capture_sh ( RID p_lightmap ) const {
2021-09-29 19:08:41 +02:00
Lightmap * lm = lightmap_owner . get_or_null ( p_lightmap ) ;
2020-05-01 14:34:23 +02:00
ERR_FAIL_COND_V ( ! lm , PackedColorArray ( ) ) ;
return lm - > point_sh ;
}
2020-05-14 14:29:06 +02:00
2020-12-04 19:26:24 +01:00
PackedInt32Array RendererStorageRD : : lightmap_get_probe_capture_tetrahedra ( RID p_lightmap ) const {
2021-09-29 19:08:41 +02:00
Lightmap * lm = lightmap_owner . get_or_null ( p_lightmap ) ;
2020-05-01 14:34:23 +02:00
ERR_FAIL_COND_V ( ! lm , PackedInt32Array ( ) ) ;
return lm - > tetrahedra ;
}
2020-05-14 14:29:06 +02:00
2020-12-04 19:26:24 +01:00
PackedInt32Array RendererStorageRD : : lightmap_get_probe_capture_bsp_tree ( RID p_lightmap ) const {
2021-09-29 19:08:41 +02:00
Lightmap * lm = lightmap_owner . get_or_null ( p_lightmap ) ;
2020-05-01 14:34:23 +02:00
ERR_FAIL_COND_V ( ! lm , PackedInt32Array ( ) ) ;
return lm - > bsp_tree ;
}
2020-12-04 19:26:24 +01:00
void RendererStorageRD : : lightmap_set_probe_capture_update_speed ( float p_speed ) {
2020-05-01 14:34:23 +02:00
lightmap_probe_capture_update_speed = p_speed ;
}
2020-12-04 19:26:24 +01:00
void RendererStorageRD : : lightmap_tap_sh_light ( RID p_lightmap , const Vector3 & p_point , Color * r_sh ) {
2021-09-29 19:08:41 +02:00
Lightmap * lm = lightmap_owner . get_or_null ( p_lightmap ) ;
2020-05-01 14:34:23 +02:00
ERR_FAIL_COND ( ! lm ) ;
for ( int i = 0 ; i < 9 ; i + + ) {
r_sh [ i ] = Color ( 0 , 0 , 0 , 0 ) ;
}
if ( ! lm - > points . size ( ) | | ! lm - > bsp_tree . size ( ) | | ! lm - > tetrahedra . size ( ) ) {
return ;
}
static_assert ( sizeof ( Lightmap : : BSP ) = = 24 ) ;
const Lightmap : : BSP * bsp = ( const Lightmap : : BSP * ) lm - > bsp_tree . ptr ( ) ;
int32_t node = 0 ;
while ( node > = 0 ) {
if ( Plane ( bsp [ node ] . plane [ 0 ] , bsp [ node ] . plane [ 1 ] , bsp [ node ] . plane [ 2 ] , bsp [ node ] . plane [ 3 ] ) . is_point_over ( p_point ) ) {
# ifdef DEBUG_ENABLED
ERR_FAIL_COND ( bsp [ node ] . over > = 0 & & bsp [ node ] . over < node ) ;
# endif
node = bsp [ node ] . over ;
} else {
# ifdef DEBUG_ENABLED
ERR_FAIL_COND ( bsp [ node ] . under > = 0 & & bsp [ node ] . under < node ) ;
# endif
node = bsp [ node ] . under ;
}
}
if ( node = = Lightmap : : BSP : : EMPTY_LEAF ) {
return ; //nothing could be done
}
node = ABS ( node ) - 1 ;
uint32_t * tetrahedron = ( uint32_t * ) & lm - > tetrahedra [ node * 4 ] ;
Vector3 points [ 4 ] = { lm - > points [ tetrahedron [ 0 ] ] , lm - > points [ tetrahedron [ 1 ] ] , lm - > points [ tetrahedron [ 2 ] ] , lm - > points [ tetrahedron [ 3 ] ] } ;
const Color * sh_colors [ 4 ] { & lm - > point_sh [ tetrahedron [ 0 ] * 9 ] , & lm - > point_sh [ tetrahedron [ 1 ] * 9 ] , & lm - > point_sh [ tetrahedron [ 2 ] * 9 ] , & lm - > point_sh [ tetrahedron [ 3 ] * 9 ] } ;
2020-05-25 19:20:45 +02:00
Color barycentric = Geometry3D : : tetrahedron_get_barycentric_coords ( points [ 0 ] , points [ 1 ] , points [ 2 ] , points [ 3 ] , p_point ) ;
2020-05-01 14:34:23 +02:00
for ( int i = 0 ; i < 4 ; i + + ) {
float c = CLAMP ( barycentric [ i ] , 0.0 , 1.0 ) ;
for ( int j = 0 ; j < 9 ; j + + ) {
r_sh [ j ] + = sh_colors [ i ] [ j ] * c ;
}
}
}
2020-12-04 19:26:24 +01:00
bool RendererStorageRD : : lightmap_is_interior ( RID p_lightmap ) const {
2021-09-29 19:08:41 +02:00
const Lightmap * lm = lightmap_owner . get_or_null ( p_lightmap ) ;
2020-05-01 14:34:23 +02:00
ERR_FAIL_COND_V ( ! lm , false ) ;
return lm - > interior ;
}
2020-05-14 14:29:06 +02:00
2020-12-04 19:26:24 +01:00
AABB RendererStorageRD : : lightmap_get_aabb ( RID p_lightmap ) const {
2021-09-29 19:08:41 +02:00
const Lightmap * lm = lightmap_owner . get_or_null ( p_lightmap ) ;
2020-05-01 14:34:23 +02:00
ERR_FAIL_COND_V ( ! lm , AABB ( ) ) ;
return lm - > bounds ;
}
2019-10-11 04:14:56 +02:00
2019-06-16 04:45:24 +02:00
/* RENDER TARGET API */
2020-12-04 19:26:24 +01:00
void RendererStorageRD : : _clear_render_target ( RenderTarget * rt ) {
2019-06-16 04:45:24 +02:00
//free in reverse dependency order
if ( rt - > framebuffer . is_valid ( ) ) {
RD : : get_singleton ( ) - > free ( rt - > framebuffer ) ;
2020-10-24 17:15:43 +02:00
rt - > framebuffer_uniform_set = RID ( ) ; //chain deleted
2019-06-16 04:45:24 +02:00
}
if ( rt - > color . is_valid ( ) ) {
RD : : get_singleton ( ) - > free ( rt - > color ) ;
}
2019-07-27 15:23:24 +02:00
if ( rt - > backbuffer . is_valid ( ) ) {
RD : : get_singleton ( ) - > free ( rt - > backbuffer ) ;
rt - > backbuffer = RID ( ) ;
rt - > backbuffer_mipmaps . clear ( ) ;
2020-10-24 17:15:43 +02:00
rt - > backbuffer_uniform_set = RID ( ) ; //chain deleted
2019-07-27 15:23:24 +02:00
}
2020-11-26 13:50:21 +01:00
_render_target_clear_sdf ( rt ) ;
2019-06-16 04:45:24 +02:00
rt - > framebuffer = RID ( ) ;
rt - > color = RID ( ) ;
}
2020-12-04 19:26:24 +01:00
void RendererStorageRD : : _update_render_target ( RenderTarget * rt ) {
2019-06-24 21:13:06 +02:00
if ( rt - > texture . is_null ( ) ) {
//create a placeholder until updated
2022-03-12 12:19:59 +01:00
rt - > texture = RendererRD : : TextureStorage : : get_singleton ( ) - > texture_allocate ( ) ;
RendererRD : : TextureStorage : : get_singleton ( ) - > texture_2d_placeholder_initialize ( rt - > texture ) ;
RendererRD : : Texture * tex = RendererRD : : TextureStorage : : get_singleton ( ) - > get_texture ( rt - > texture ) ;
2019-06-24 21:13:06 +02:00
tex - > is_render_target = true ;
}
2019-06-16 04:45:24 +02:00
_clear_render_target ( rt ) ;
2019-06-19 22:03:19 +02:00
if ( rt - > size . width = = 0 | | rt - > size . height = = 0 ) {
return ;
}
2020-03-11 18:59:18 +01:00
//until we implement support for HDR monitors (and render target is attached to screen), this is enough.
2019-06-16 04:45:24 +02:00
rt - > color_format = RD : : DATA_FORMAT_R8G8B8A8_UNORM ;
rt - > color_format_srgb = RD : : DATA_FORMAT_R8G8B8A8_SRGB ;
rt - > image_format = rt - > flags [ RENDER_TARGET_TRANSPARENT ] ? Image : : FORMAT_RGBA8 : Image : : FORMAT_RGB8 ;
RD : : TextureFormat rd_format ;
RD : : TextureView rd_view ;
{ //attempt register
rd_format . format = rt - > color_format ;
rd_format . width = rt - > size . width ;
rd_format . height = rt - > size . height ;
rd_format . depth = 1 ;
2021-05-07 15:19:04 +02:00
rd_format . array_layers = rt - > view_count ; // for stereo we create two (or more) layers, need to see if we can make fallback work like this too if we don't have multiview
2019-06-16 04:45:24 +02:00
rd_format . mipmaps = 1 ;
2021-05-07 15:19:04 +02:00
if ( rd_format . array_layers > 1 ) { // why are we not using rt->texture_type ??
rd_format . texture_type = RD : : TEXTURE_TYPE_2D_ARRAY ;
} else {
rd_format . texture_type = RD : : TEXTURE_TYPE_2D ;
}
2019-06-16 04:45:24 +02:00
rd_format . samples = RD : : TEXTURE_SAMPLES_1 ;
2019-07-27 15:23:24 +02:00
rd_format . usage_bits = RD : : TEXTURE_USAGE_SAMPLING_BIT | RD : : TEXTURE_USAGE_COLOR_ATTACHMENT_BIT | RD : : TEXTURE_USAGE_CAN_COPY_FROM_BIT ;
2019-06-19 22:03:19 +02:00
rd_format . shareable_formats . push_back ( rt - > color_format ) ;
rd_format . shareable_formats . push_back ( rt - > color_format_srgb ) ;
2019-06-16 04:45:24 +02:00
}
rt - > color = RD : : get_singleton ( ) - > texture_create ( rd_format , rd_view ) ;
ERR_FAIL_COND ( rt - > color . is_null ( ) ) ;
Vector < RID > fb_textures ;
fb_textures . push_back ( rt - > color ) ;
2021-05-07 15:19:04 +02:00
rt - > framebuffer = RD : : get_singleton ( ) - > framebuffer_create ( fb_textures , RenderingDevice : : INVALID_ID , rt - > view_count ) ;
2019-06-16 04:45:24 +02:00
if ( rt - > framebuffer . is_null ( ) ) {
_clear_render_target ( rt ) ;
ERR_FAIL_COND ( rt - > framebuffer . is_null ( ) ) ;
}
2019-06-19 22:03:19 +02:00
2019-06-24 21:13:06 +02:00
{ //update texture
2022-03-12 12:19:59 +01:00
RendererRD : : Texture * tex = RendererRD : : TextureStorage : : get_singleton ( ) - > get_texture ( rt - > texture ) ;
2019-06-24 21:13:06 +02:00
//free existing textures
if ( RD : : get_singleton ( ) - > texture_is_valid ( tex - > rd_texture ) ) {
RD : : get_singleton ( ) - > free ( tex - > rd_texture ) ;
}
if ( RD : : get_singleton ( ) - > texture_is_valid ( tex - > rd_texture_srgb ) ) {
RD : : get_singleton ( ) - > free ( tex - > rd_texture_srgb ) ;
}
tex - > rd_texture = RID ( ) ;
tex - > rd_texture_srgb = RID ( ) ;
//create shared textures to the color buffer,
//so transparent can be supported
RD : : TextureView view ;
view . format_override = rt - > color_format ;
if ( ! rt - > flags [ RENDER_TARGET_TRANSPARENT ] ) {
view . swizzle_a = RD : : TEXTURE_SWIZZLE_ONE ;
}
tex - > rd_texture = RD : : get_singleton ( ) - > texture_create_shared ( view , rt - > color ) ;
if ( rt - > color_format_srgb ! = RD : : DATA_FORMAT_MAX ) {
view . format_override = rt - > color_format_srgb ;
tex - > rd_texture_srgb = RD : : get_singleton ( ) - > texture_create_shared ( view , rt - > color ) ;
}
tex - > rd_view = view ;
tex - > width = rt - > size . width ;
tex - > height = rt - > size . height ;
tex - > width_2d = rt - > size . width ;
tex - > height_2d = rt - > size . height ;
tex - > rd_format = rt - > color_format ;
tex - > rd_format_srgb = rt - > color_format_srgb ;
tex - > format = rt - > image_format ;
Vector < RID > proxies = tex - > proxies ; //make a copy, since update may change it
for ( int i = 0 ; i < proxies . size ( ) ; i + + ) {
2022-03-12 12:19:59 +01:00
RendererRD : : TextureStorage : : get_singleton ( ) - > texture_proxy_update ( proxies [ i ] , rt - > texture ) ;
2019-06-24 21:13:06 +02:00
}
}
2019-06-16 04:45:24 +02:00
}
2020-12-04 19:26:24 +01:00
void RendererStorageRD : : _create_render_target_backbuffer ( RenderTarget * rt ) {
2019-07-27 15:23:24 +02:00
ERR_FAIL_COND ( rt - > backbuffer . is_valid ( ) ) ;
uint32_t mipmaps_required = Image : : get_image_required_mipmaps ( rt - > size . width , rt - > size . height , Image : : FORMAT_RGBA8 ) ;
RD : : TextureFormat tf ;
tf . format = rt - > color_format ;
tf . width = rt - > size . width ;
tf . height = rt - > size . height ;
2020-11-27 04:50:05 +01:00
tf . texture_type = RD : : TEXTURE_TYPE_2D ;
2020-10-28 19:34:27 +01:00
tf . usage_bits = RD : : TEXTURE_USAGE_COLOR_ATTACHMENT_BIT | RD : : TEXTURE_USAGE_STORAGE_BIT | RD : : TEXTURE_USAGE_SAMPLING_BIT | RD : : TEXTURE_USAGE_CAN_COPY_TO_BIT ;
2019-07-27 15:23:24 +02:00
tf . mipmaps = mipmaps_required ;
rt - > backbuffer = RD : : get_singleton ( ) - > texture_create ( tf , RD : : TextureView ( ) ) ;
2022-02-06 00:03:39 +01:00
RD : : get_singleton ( ) - > set_resource_name ( rt - > backbuffer , " Render Target Back Buffer " ) ;
2020-04-11 19:43:12 +02:00
rt - > backbuffer_mipmap0 = RD : : get_singleton ( ) - > texture_create_shared_from_slice ( RD : : TextureView ( ) , rt - > backbuffer , 0 , 0 ) ;
2022-02-06 00:03:39 +01:00
RD : : get_singleton ( ) - > set_resource_name ( rt - > backbuffer_mipmap0 , " Back Buffer slice mipmap 0 " ) ;
2019-07-27 15:23:24 +02:00
2020-10-28 19:34:27 +01:00
{
Vector < RID > fb_tex ;
fb_tex . push_back ( rt - > backbuffer_mipmap0 ) ;
rt - > backbuffer_fb = RD : : get_singleton ( ) - > framebuffer_create ( fb_tex ) ;
}
2020-10-24 17:15:43 +02:00
if ( rt - > framebuffer_uniform_set . is_valid ( ) & & RD : : get_singleton ( ) - > uniform_set_is_valid ( rt - > framebuffer_uniform_set ) ) {
//the new one will require the backbuffer.
RD : : get_singleton ( ) - > free ( rt - > framebuffer_uniform_set ) ;
rt - > framebuffer_uniform_set = RID ( ) ;
}
2019-07-27 15:23:24 +02:00
//create mipmaps
for ( uint32_t i = 1 ; i < mipmaps_required ; i + + ) {
2022-02-06 00:03:39 +01:00
RID mipmap = RD : : get_singleton ( ) - > texture_create_shared_from_slice ( RD : : TextureView ( ) , rt - > backbuffer , 0 , i ) ;
RD : : get_singleton ( ) - > set_resource_name ( mipmap , " Back Buffer slice mip: " + itos ( i ) ) ;
2019-07-27 15:23:24 +02:00
2022-02-06 00:03:39 +01:00
rt - > backbuffer_mipmaps . push_back ( mipmap ) ;
2019-07-27 15:23:24 +02:00
}
}
2020-12-04 19:26:24 +01:00
RID RendererStorageRD : : render_target_create ( ) {
2019-06-16 04:45:24 +02:00
RenderTarget render_target ;
2019-06-25 03:24:07 +02:00
2019-06-16 04:45:24 +02:00
render_target . was_used = false ;
2019-06-24 21:13:06 +02:00
render_target . clear_requested = false ;
2019-06-16 04:45:24 +02:00
for ( int i = 0 ; i < RENDER_TARGET_FLAG_MAX ; i + + ) {
render_target . flags [ i ] = false ;
}
2019-06-25 03:24:07 +02:00
_update_render_target ( & render_target ) ;
2019-06-16 04:45:24 +02:00
return render_target_owner . make_rid ( render_target ) ;
}
2020-12-04 19:26:24 +01:00
void RendererStorageRD : : render_target_set_position ( RID p_render_target , int p_x , int p_y ) {
2019-06-16 04:45:24 +02:00
//unused for this render target
}
2021-05-07 15:19:04 +02:00
void RendererStorageRD : : render_target_set_size ( RID p_render_target , int p_width , int p_height , uint32_t p_view_count ) {
2021-09-29 19:08:41 +02:00
RenderTarget * rt = render_target_owner . get_or_null ( p_render_target ) ;
2019-06-16 04:45:24 +02:00
ERR_FAIL_COND ( ! rt ) ;
2021-05-07 15:19:04 +02:00
if ( rt - > size . x ! = p_width | | rt - > size . y ! = p_height | | rt - > view_count ! = p_view_count ) {
rt - > size . x = p_width ;
rt - > size . y = p_height ;
rt - > view_count = p_view_count ;
_update_render_target ( rt ) ;
}
2019-06-16 04:45:24 +02:00
}
2020-12-04 19:26:24 +01:00
RID RendererStorageRD : : render_target_get_texture ( RID p_render_target ) {
2021-09-29 19:08:41 +02:00
RenderTarget * rt = render_target_owner . get_or_null ( p_render_target ) ;
2019-06-16 04:45:24 +02:00
ERR_FAIL_COND_V ( ! rt , RID ( ) ) ;
return rt - > texture ;
}
2020-12-04 19:26:24 +01:00
void RendererStorageRD : : render_target_set_external_texture ( RID p_render_target , unsigned int p_texture_id ) {
2019-06-16 04:45:24 +02:00
}
2020-12-04 19:26:24 +01:00
void RendererStorageRD : : render_target_set_flag ( RID p_render_target , RenderTargetFlags p_flag , bool p_value ) {
2021-09-29 19:08:41 +02:00
RenderTarget * rt = render_target_owner . get_or_null ( p_render_target ) ;
2019-06-16 04:45:24 +02:00
ERR_FAIL_COND ( ! rt ) ;
rt - > flags [ p_flag ] = p_value ;
2019-06-25 03:24:07 +02:00
_update_render_target ( rt ) ;
2019-06-16 04:45:24 +02:00
}
2020-12-04 19:26:24 +01:00
bool RendererStorageRD : : render_target_was_used ( RID p_render_target ) {
2021-09-29 19:08:41 +02:00
RenderTarget * rt = render_target_owner . get_or_null ( p_render_target ) ;
2019-06-16 04:45:24 +02:00
ERR_FAIL_COND_V ( ! rt , false ) ;
return rt - > was_used ;
}
2020-12-04 19:26:24 +01:00
void RendererStorageRD : : render_target_set_as_unused ( RID p_render_target ) {
2021-09-29 19:08:41 +02:00
RenderTarget * rt = render_target_owner . get_or_null ( p_render_target ) ;
2019-06-16 04:45:24 +02:00
ERR_FAIL_COND ( ! rt ) ;
rt - > was_used = false ;
}
2020-12-04 19:26:24 +01:00
Size2 RendererStorageRD : : render_target_get_size ( RID p_render_target ) {
2021-09-29 19:08:41 +02:00
RenderTarget * rt = render_target_owner . get_or_null ( p_render_target ) ;
2019-06-16 04:45:24 +02:00
ERR_FAIL_COND_V ( ! rt , Size2 ( ) ) ;
return rt - > size ;
}
2020-12-04 19:26:24 +01:00
RID RendererStorageRD : : render_target_get_rd_framebuffer ( RID p_render_target ) {
2021-09-29 19:08:41 +02:00
RenderTarget * rt = render_target_owner . get_or_null ( p_render_target ) ;
2019-06-16 04:45:24 +02:00
ERR_FAIL_COND_V ( ! rt , RID ( ) ) ;
return rt - > framebuffer ;
}
2020-05-14 14:29:06 +02:00
2020-12-04 19:26:24 +01:00
RID RendererStorageRD : : render_target_get_rd_texture ( RID p_render_target ) {
2021-09-29 19:08:41 +02:00
RenderTarget * rt = render_target_owner . get_or_null ( p_render_target ) ;
2020-04-11 19:43:12 +02:00
ERR_FAIL_COND_V ( ! rt , RID ( ) ) ;
2019-06-16 04:45:24 +02:00
2020-04-11 19:43:12 +02:00
return rt - > color ;
}
2020-05-14 14:29:06 +02:00
2020-12-04 19:26:24 +01:00
RID RendererStorageRD : : render_target_get_rd_backbuffer ( RID p_render_target ) {
2021-09-29 19:08:41 +02:00
RenderTarget * rt = render_target_owner . get_or_null ( p_render_target ) ;
2020-10-24 17:15:43 +02:00
ERR_FAIL_COND_V ( ! rt , RID ( ) ) ;
return rt - > backbuffer ;
}
2020-12-04 19:26:24 +01:00
RID RendererStorageRD : : render_target_get_rd_backbuffer_framebuffer ( RID p_render_target ) {
2021-09-29 19:08:41 +02:00
RenderTarget * rt = render_target_owner . get_or_null ( p_render_target ) ;
2020-10-28 19:34:27 +01:00
ERR_FAIL_COND_V ( ! rt , RID ( ) ) ;
if ( ! rt - > backbuffer . is_valid ( ) ) {
_create_render_target_backbuffer ( rt ) ;
}
return rt - > backbuffer_fb ;
}
2020-12-04 19:26:24 +01:00
void RendererStorageRD : : render_target_request_clear ( RID p_render_target , const Color & p_clear_color ) {
2021-09-29 19:08:41 +02:00
RenderTarget * rt = render_target_owner . get_or_null ( p_render_target ) ;
2019-06-24 21:13:06 +02:00
ERR_FAIL_COND ( ! rt ) ;
rt - > clear_requested = true ;
rt - > clear_color = p_clear_color ;
}
2020-12-04 19:26:24 +01:00
bool RendererStorageRD : : render_target_is_clear_requested ( RID p_render_target ) {
2021-09-29 19:08:41 +02:00
RenderTarget * rt = render_target_owner . get_or_null ( p_render_target ) ;
2019-06-24 21:13:06 +02:00
ERR_FAIL_COND_V ( ! rt , false ) ;
return rt - > clear_requested ;
}
2020-12-04 19:26:24 +01:00
Color RendererStorageRD : : render_target_get_clear_request_color ( RID p_render_target ) {
2021-09-29 19:08:41 +02:00
RenderTarget * rt = render_target_owner . get_or_null ( p_render_target ) ;
2019-06-24 21:13:06 +02:00
ERR_FAIL_COND_V ( ! rt , Color ( ) ) ;
return rt - > clear_color ;
}
2020-12-04 19:26:24 +01:00
void RendererStorageRD : : render_target_disable_clear_request ( RID p_render_target ) {
2021-09-29 19:08:41 +02:00
RenderTarget * rt = render_target_owner . get_or_null ( p_render_target ) ;
2019-06-24 21:13:06 +02:00
ERR_FAIL_COND ( ! rt ) ;
rt - > clear_requested = false ;
}
2020-12-04 19:26:24 +01:00
void RendererStorageRD : : render_target_do_clear_request ( RID p_render_target ) {
2021-09-29 19:08:41 +02:00
RenderTarget * rt = render_target_owner . get_or_null ( p_render_target ) ;
2019-06-25 03:24:07 +02:00
ERR_FAIL_COND ( ! rt ) ;
if ( ! rt - > clear_requested ) {
return ;
}
Vector < Color > clear_colors ;
clear_colors . push_back ( rt - > clear_color ) ;
2019-10-03 22:39:08 +02:00
RD : : get_singleton ( ) - > draw_list_begin ( rt - > framebuffer , RD : : INITIAL_ACTION_CLEAR , RD : : FINAL_ACTION_READ , RD : : INITIAL_ACTION_KEEP , RD : : FINAL_ACTION_DISCARD , clear_colors ) ;
2019-06-25 03:24:07 +02:00
RD : : get_singleton ( ) - > draw_list_end ( ) ;
rt - > clear_requested = false ;
}
2020-12-04 19:26:24 +01:00
void RendererStorageRD : : render_target_set_sdf_size_and_scale ( RID p_render_target , RS : : ViewportSDFOversize p_size , RS : : ViewportSDFScale p_scale ) {
2021-09-29 19:08:41 +02:00
RenderTarget * rt = render_target_owner . get_or_null ( p_render_target ) ;
2020-11-26 13:50:21 +01:00
ERR_FAIL_COND ( ! rt ) ;
if ( rt - > sdf_oversize = = p_size & & rt - > sdf_scale = = p_scale ) {
return ;
}
rt - > sdf_oversize = p_size ;
rt - > sdf_scale = p_scale ;
_render_target_clear_sdf ( rt ) ;
}
2020-12-04 19:26:24 +01:00
Rect2i RendererStorageRD : : _render_target_get_sdf_rect ( const RenderTarget * rt ) const {
2020-11-26 13:50:21 +01:00
Size2i margin ;
int scale ;
switch ( rt - > sdf_oversize ) {
case RS : : VIEWPORT_SDF_OVERSIZE_100_PERCENT : {
scale = 100 ;
} break ;
case RS : : VIEWPORT_SDF_OVERSIZE_120_PERCENT : {
scale = 120 ;
} break ;
case RS : : VIEWPORT_SDF_OVERSIZE_150_PERCENT : {
scale = 150 ;
} break ;
case RS : : VIEWPORT_SDF_OVERSIZE_200_PERCENT : {
scale = 200 ;
} break ;
default : {
}
}
margin = ( rt - > size * scale / 100 ) - rt - > size ;
Rect2i r ( Vector2i ( ) , rt - > size ) ;
r . position - = margin ;
r . size + = margin * 2 ;
return r ;
}
2020-12-04 19:26:24 +01:00
Rect2i RendererStorageRD : : render_target_get_sdf_rect ( RID p_render_target ) const {
2021-09-29 19:08:41 +02:00
const RenderTarget * rt = render_target_owner . get_or_null ( p_render_target ) ;
2020-11-26 13:50:21 +01:00
ERR_FAIL_COND_V ( ! rt , Rect2i ( ) ) ;
return _render_target_get_sdf_rect ( rt ) ;
}
2021-05-20 16:25:06 +02:00
void RendererStorageRD : : render_target_mark_sdf_enabled ( RID p_render_target , bool p_enabled ) {
2021-09-29 19:08:41 +02:00
RenderTarget * rt = render_target_owner . get_or_null ( p_render_target ) ;
2021-05-20 16:25:06 +02:00
ERR_FAIL_COND ( ! rt ) ;
rt - > sdf_enabled = p_enabled ;
}
bool RendererStorageRD : : render_target_is_sdf_enabled ( RID p_render_target ) const {
2021-09-29 19:08:41 +02:00
const RenderTarget * rt = render_target_owner . get_or_null ( p_render_target ) ;
2021-05-20 16:25:06 +02:00
ERR_FAIL_COND_V ( ! rt , false ) ;
return rt - > sdf_enabled ;
}
2020-12-04 19:26:24 +01:00
RID RendererStorageRD : : render_target_get_sdf_texture ( RID p_render_target ) {
2021-09-29 19:08:41 +02:00
RenderTarget * rt = render_target_owner . get_or_null ( p_render_target ) ;
2020-11-26 13:50:21 +01:00
ERR_FAIL_COND_V ( ! rt , RID ( ) ) ;
if ( rt - > sdf_buffer_read . is_null ( ) ) {
// no texture, create a dummy one for the 2D uniform set
RD : : TextureFormat tformat ;
tformat . format = RD : : DATA_FORMAT_R8G8B8A8_UNORM ;
tformat . width = 4 ;
tformat . height = 4 ;
tformat . usage_bits = RD : : TEXTURE_USAGE_SAMPLING_BIT ;
2020-11-27 04:50:05 +01:00
tformat . texture_type = RD : : TEXTURE_TYPE_2D ;
2020-11-26 13:50:21 +01:00
Vector < uint8_t > pv ;
pv . resize ( 16 * 4 ) ;
2021-04-27 16:19:21 +02:00
memset ( pv . ptrw ( ) , 0 , 16 * 4 ) ;
2020-11-26 13:50:21 +01:00
Vector < Vector < uint8_t > > vpv ;
rt - > sdf_buffer_read = RD : : get_singleton ( ) - > texture_create ( tformat , RD : : TextureView ( ) , vpv ) ;
}
return rt - > sdf_buffer_read ;
}
2020-12-04 19:26:24 +01:00
void RendererStorageRD : : _render_target_allocate_sdf ( RenderTarget * rt ) {
2020-11-26 13:50:21 +01:00
ERR_FAIL_COND ( rt - > sdf_buffer_write_fb . is_valid ( ) ) ;
if ( rt - > sdf_buffer_read . is_valid ( ) ) {
RD : : get_singleton ( ) - > free ( rt - > sdf_buffer_read ) ;
rt - > sdf_buffer_read = RID ( ) ;
}
Size2i size = _render_target_get_sdf_rect ( rt ) . size ;
RD : : TextureFormat tformat ;
tformat . format = RD : : DATA_FORMAT_R8_UNORM ;
tformat . width = size . width ;
tformat . height = size . height ;
tformat . usage_bits = RD : : TEXTURE_USAGE_SAMPLING_BIT | RD : : TEXTURE_USAGE_STORAGE_BIT | RD : : TEXTURE_USAGE_COLOR_ATTACHMENT_BIT ;
2020-11-27 04:50:05 +01:00
tformat . texture_type = RD : : TEXTURE_TYPE_2D ;
2020-11-26 13:50:21 +01:00
rt - > sdf_buffer_write = RD : : get_singleton ( ) - > texture_create ( tformat , RD : : TextureView ( ) ) ;
{
Vector < RID > write_fb ;
write_fb . push_back ( rt - > sdf_buffer_write ) ;
rt - > sdf_buffer_write_fb = RD : : get_singleton ( ) - > framebuffer_create ( write_fb ) ;
}
int scale ;
switch ( rt - > sdf_scale ) {
case RS : : VIEWPORT_SDF_SCALE_100_PERCENT : {
scale = 100 ;
} break ;
case RS : : VIEWPORT_SDF_SCALE_50_PERCENT : {
scale = 50 ;
} break ;
case RS : : VIEWPORT_SDF_SCALE_25_PERCENT : {
scale = 25 ;
} break ;
default : {
scale = 100 ;
} break ;
}
rt - > process_size = size * scale / 100 ;
rt - > process_size . x = MAX ( rt - > process_size . x , 1 ) ;
rt - > process_size . y = MAX ( rt - > process_size . y , 1 ) ;
2021-05-20 16:25:06 +02:00
tformat . format = RD : : DATA_FORMAT_R16G16_SINT ;
2020-11-26 13:50:21 +01:00
tformat . width = rt - > process_size . width ;
tformat . height = rt - > process_size . height ;
tformat . usage_bits = RD : : TEXTURE_USAGE_STORAGE_BIT ;
rt - > sdf_buffer_process [ 0 ] = RD : : get_singleton ( ) - > texture_create ( tformat , RD : : TextureView ( ) ) ;
rt - > sdf_buffer_process [ 1 ] = RD : : get_singleton ( ) - > texture_create ( tformat , RD : : TextureView ( ) ) ;
2021-05-20 16:25:06 +02:00
tformat . format = RD : : DATA_FORMAT_R16_SNORM ;
2020-11-26 13:50:21 +01:00
tformat . usage_bits = RD : : TEXTURE_USAGE_SAMPLING_BIT | RD : : TEXTURE_USAGE_STORAGE_BIT ;
rt - > sdf_buffer_read = RD : : get_singleton ( ) - > texture_create ( tformat , RD : : TextureView ( ) ) ;
{
Vector < RD : : Uniform > uniforms ;
{
RD : : Uniform u ;
2020-10-17 03:19:21 +02:00
u . uniform_type = RD : : UNIFORM_TYPE_IMAGE ;
2020-11-26 13:50:21 +01:00
u . binding = 1 ;
2022-03-06 12:57:09 +01:00
u . append_id ( rt - > sdf_buffer_write ) ;
2020-11-26 13:50:21 +01:00
uniforms . push_back ( u ) ;
}
{
RD : : Uniform u ;
2020-10-17 03:19:21 +02:00
u . uniform_type = RD : : UNIFORM_TYPE_IMAGE ;
2020-11-26 13:50:21 +01:00
u . binding = 2 ;
2022-03-06 12:57:09 +01:00
u . append_id ( rt - > sdf_buffer_read ) ;
2020-11-26 13:50:21 +01:00
uniforms . push_back ( u ) ;
}
{
RD : : Uniform u ;
2020-10-17 03:19:21 +02:00
u . uniform_type = RD : : UNIFORM_TYPE_IMAGE ;
2020-11-26 13:50:21 +01:00
u . binding = 3 ;
2022-03-06 12:57:09 +01:00
u . append_id ( rt - > sdf_buffer_process [ 0 ] ) ;
2020-11-26 13:50:21 +01:00
uniforms . push_back ( u ) ;
}
{
RD : : Uniform u ;
2020-10-17 03:19:21 +02:00
u . uniform_type = RD : : UNIFORM_TYPE_IMAGE ;
2020-11-26 13:50:21 +01:00
u . binding = 4 ;
2022-03-06 12:57:09 +01:00
u . append_id ( rt - > sdf_buffer_process [ 1 ] ) ;
2020-11-26 13:50:21 +01:00
uniforms . push_back ( u ) ;
}
rt - > sdf_buffer_process_uniform_sets [ 0 ] = RD : : get_singleton ( ) - > uniform_set_create ( uniforms , rt_sdf . shader . version_get_shader ( rt_sdf . shader_version , 0 ) , 0 ) ;
2022-03-06 12:57:09 +01:00
RID aux2 = uniforms . write [ 2 ] . get_id ( 0 ) ;
RID aux3 = uniforms . write [ 3 ] . get_id ( 0 ) ;
uniforms . write [ 2 ] . set_id ( 0 , aux3 ) ;
uniforms . write [ 3 ] . set_id ( 0 , aux2 ) ;
2020-11-26 13:50:21 +01:00
rt - > sdf_buffer_process_uniform_sets [ 1 ] = RD : : get_singleton ( ) - > uniform_set_create ( uniforms , rt_sdf . shader . version_get_shader ( rt_sdf . shader_version , 0 ) , 0 ) ;
}
}
2020-12-04 19:26:24 +01:00
void RendererStorageRD : : _render_target_clear_sdf ( RenderTarget * rt ) {
2020-11-26 13:50:21 +01:00
if ( rt - > sdf_buffer_read . is_valid ( ) ) {
RD : : get_singleton ( ) - > free ( rt - > sdf_buffer_read ) ;
rt - > sdf_buffer_read = RID ( ) ;
}
if ( rt - > sdf_buffer_write_fb . is_valid ( ) ) {
RD : : get_singleton ( ) - > free ( rt - > sdf_buffer_write ) ;
RD : : get_singleton ( ) - > free ( rt - > sdf_buffer_process [ 0 ] ) ;
RD : : get_singleton ( ) - > free ( rt - > sdf_buffer_process [ 1 ] ) ;
rt - > sdf_buffer_write = RID ( ) ;
rt - > sdf_buffer_write_fb = RID ( ) ;
rt - > sdf_buffer_process [ 0 ] = RID ( ) ;
rt - > sdf_buffer_process [ 1 ] = RID ( ) ;
rt - > sdf_buffer_process_uniform_sets [ 0 ] = RID ( ) ;
rt - > sdf_buffer_process_uniform_sets [ 1 ] = RID ( ) ;
}
}
2020-12-04 19:26:24 +01:00
RID RendererStorageRD : : render_target_get_sdf_framebuffer ( RID p_render_target ) {
2021-09-29 19:08:41 +02:00
RenderTarget * rt = render_target_owner . get_or_null ( p_render_target ) ;
2020-11-26 13:50:21 +01:00
ERR_FAIL_COND_V ( ! rt , RID ( ) ) ;
if ( rt - > sdf_buffer_write_fb . is_null ( ) ) {
_render_target_allocate_sdf ( rt ) ;
}
return rt - > sdf_buffer_write_fb ;
}
2020-12-04 19:26:24 +01:00
void RendererStorageRD : : render_target_sdf_process ( RID p_render_target ) {
2021-09-29 19:08:41 +02:00
RenderTarget * rt = render_target_owner . get_or_null ( p_render_target ) ;
2020-11-26 13:50:21 +01:00
ERR_FAIL_COND ( ! rt ) ;
ERR_FAIL_COND ( rt - > sdf_buffer_write_fb . is_null ( ) ) ;
RenderTargetSDF : : PushConstant push_constant ;
Rect2i r = _render_target_get_sdf_rect ( rt ) ;
push_constant . size [ 0 ] = r . size . width ;
push_constant . size [ 1 ] = r . size . height ;
push_constant . stride = 0 ;
push_constant . shift = 0 ;
push_constant . base_size [ 0 ] = r . size . width ;
push_constant . base_size [ 1 ] = r . size . height ;
bool shrink = false ;
switch ( rt - > sdf_scale ) {
case RS : : VIEWPORT_SDF_SCALE_50_PERCENT : {
push_constant . size [ 0 ] > > = 1 ;
push_constant . size [ 1 ] > > = 1 ;
push_constant . shift = 1 ;
shrink = true ;
} break ;
case RS : : VIEWPORT_SDF_SCALE_25_PERCENT : {
push_constant . size [ 0 ] > > = 2 ;
push_constant . size [ 1 ] > > = 2 ;
push_constant . shift = 2 ;
shrink = true ;
} break ;
default : {
} ;
}
RD : : ComputeListID compute_list = RD : : get_singleton ( ) - > compute_list_begin ( ) ;
/* Load */
RD : : get_singleton ( ) - > compute_list_bind_compute_pipeline ( compute_list , rt_sdf . pipelines [ shrink ? RenderTargetSDF : : SHADER_LOAD_SHRINK : RenderTargetSDF : : SHADER_LOAD ] ) ;
RD : : get_singleton ( ) - > compute_list_bind_uniform_set ( compute_list , rt - > sdf_buffer_process_uniform_sets [ 1 ] , 0 ) ; //fill [0]
RD : : get_singleton ( ) - > compute_list_set_push_constant ( compute_list , & push_constant , sizeof ( RenderTargetSDF : : PushConstant ) ) ;
2021-02-02 20:51:36 +01:00
RD : : get_singleton ( ) - > compute_list_dispatch_threads ( compute_list , push_constant . size [ 0 ] , push_constant . size [ 1 ] , 1 ) ;
2020-11-26 13:50:21 +01:00
/* Process */
int stride = nearest_power_of_2_templated ( MAX ( push_constant . size [ 0 ] , push_constant . size [ 1 ] ) / 2 ) ;
RD : : get_singleton ( ) - > compute_list_bind_compute_pipeline ( compute_list , rt_sdf . pipelines [ RenderTargetSDF : : SHADER_PROCESS ] ) ;
RD : : get_singleton ( ) - > compute_list_add_barrier ( compute_list ) ;
bool swap = false ;
//jumpflood
while ( stride > 0 ) {
RD : : get_singleton ( ) - > compute_list_bind_uniform_set ( compute_list , rt - > sdf_buffer_process_uniform_sets [ swap ? 1 : 0 ] , 0 ) ;
push_constant . stride = stride ;
RD : : get_singleton ( ) - > compute_list_set_push_constant ( compute_list , & push_constant , sizeof ( RenderTargetSDF : : PushConstant ) ) ;
2021-02-02 20:51:36 +01:00
RD : : get_singleton ( ) - > compute_list_dispatch_threads ( compute_list , push_constant . size [ 0 ] , push_constant . size [ 1 ] , 1 ) ;
2020-11-26 13:50:21 +01:00
stride / = 2 ;
swap = ! swap ;
RD : : get_singleton ( ) - > compute_list_add_barrier ( compute_list ) ;
}
/* Store */
RD : : get_singleton ( ) - > compute_list_bind_compute_pipeline ( compute_list , rt_sdf . pipelines [ shrink ? RenderTargetSDF : : SHADER_STORE_SHRINK : RenderTargetSDF : : SHADER_STORE ] ) ;
RD : : get_singleton ( ) - > compute_list_bind_uniform_set ( compute_list , rt - > sdf_buffer_process_uniform_sets [ swap ? 1 : 0 ] , 0 ) ;
RD : : get_singleton ( ) - > compute_list_set_push_constant ( compute_list , & push_constant , sizeof ( RenderTargetSDF : : PushConstant ) ) ;
2021-02-02 20:51:36 +01:00
RD : : get_singleton ( ) - > compute_list_dispatch_threads ( compute_list , push_constant . size [ 0 ] , push_constant . size [ 1 ] , 1 ) ;
2020-11-26 13:50:21 +01:00
RD : : get_singleton ( ) - > compute_list_end ( ) ;
}
2020-12-04 19:26:24 +01:00
void RendererStorageRD : : render_target_copy_to_back_buffer ( RID p_render_target , const Rect2i & p_region , bool p_gen_mipmaps ) {
2021-09-29 19:08:41 +02:00
RenderTarget * rt = render_target_owner . get_or_null ( p_render_target ) ;
2019-07-27 15:23:24 +02:00
ERR_FAIL_COND ( ! rt ) ;
if ( ! rt - > backbuffer . is_valid ( ) ) {
_create_render_target_backbuffer ( rt ) ;
}
2020-10-28 19:34:27 +01:00
Rect2i region ;
if ( p_region = = Rect2i ( ) ) {
2019-07-27 15:23:24 +02:00
region . size = rt - > size ;
2020-10-28 19:34:27 +01:00
} else {
2020-12-19 13:43:35 +01:00
region = Rect2i ( Size2i ( ) , rt - > size ) . intersection ( p_region ) ;
2020-10-28 19:34:27 +01:00
if ( region . size = = Size2i ( ) ) {
return ; //nothing to do
}
2019-07-27 15:23:24 +02:00
}
//single texture copy for backbuffer
2020-10-28 19:34:27 +01:00
//RD::get_singleton()->texture_copy(rt->color, rt->backbuffer_mipmap0, Vector3(region.position.x, region.position.y, 0), Vector3(region.position.x, region.position.y, 0), Vector3(region.size.x, region.size.y, 1), 0, 0, 0, 0, true);
2021-07-20 13:40:16 +02:00
effects - > copy_to_rect ( rt - > color , rt - > backbuffer_mipmap0 , region , false , false , false , true , true ) ;
2020-10-28 19:34:27 +01:00
if ( ! p_gen_mipmaps ) {
return ;
}
2022-02-06 00:03:39 +01:00
RD : : get_singleton ( ) - > draw_command_begin_label ( " Gaussian Blur Mipmaps " ) ;
2019-07-27 15:23:24 +02:00
//then mipmap blur
RID prev_texture = rt - > color ; //use color, not backbuffer, as bb has mipmaps.
for ( int i = 0 ; i < rt - > backbuffer_mipmaps . size ( ) ; i + + ) {
2020-04-11 19:43:12 +02:00
region . position . x > > = 1 ;
region . position . y > > = 1 ;
region . size . x = MAX ( 1 , region . size . x > > 1 ) ;
region . size . y = MAX ( 1 , region . size . y > > 1 ) ;
2022-02-06 00:03:39 +01:00
RID mipmap = rt - > backbuffer_mipmaps [ i ] ;
effects - > gaussian_blur ( prev_texture , mipmap , region , true ) ;
prev_texture = mipmap ;
2019-07-27 15:23:24 +02:00
}
2022-02-06 00:03:39 +01:00
RD : : get_singleton ( ) - > draw_command_end_label ( ) ;
2019-07-27 15:23:24 +02:00
}
2020-12-04 19:26:24 +01:00
void RendererStorageRD : : render_target_clear_back_buffer ( RID p_render_target , const Rect2i & p_region , const Color & p_color ) {
2021-09-29 19:08:41 +02:00
RenderTarget * rt = render_target_owner . get_or_null ( p_render_target ) ;
2020-10-28 19:34:27 +01:00
ERR_FAIL_COND ( ! rt ) ;
if ( ! rt - > backbuffer . is_valid ( ) ) {
_create_render_target_backbuffer ( rt ) ;
}
Rect2i region ;
if ( p_region = = Rect2i ( ) ) {
region . size = rt - > size ;
} else {
2020-12-19 13:43:35 +01:00
region = Rect2i ( Size2i ( ) , rt - > size ) . intersection ( p_region ) ;
2020-10-28 19:34:27 +01:00
if ( region . size = = Size2i ( ) ) {
return ; //nothing to do
}
}
//single texture copy for backbuffer
2021-07-20 13:40:16 +02:00
effects - > set_color ( rt - > backbuffer_mipmap0 , p_color , region , true ) ;
2020-10-28 19:34:27 +01:00
}
2020-12-04 19:26:24 +01:00
void RendererStorageRD : : render_target_gen_back_buffer_mipmaps ( RID p_render_target , const Rect2i & p_region ) {
2021-09-29 19:08:41 +02:00
RenderTarget * rt = render_target_owner . get_or_null ( p_render_target ) ;
2020-10-28 19:34:27 +01:00
ERR_FAIL_COND ( ! rt ) ;
if ( ! rt - > backbuffer . is_valid ( ) ) {
_create_render_target_backbuffer ( rt ) ;
}
Rect2i region ;
if ( p_region = = Rect2i ( ) ) {
region . size = rt - > size ;
} else {
2020-12-19 13:43:35 +01:00
region = Rect2i ( Size2i ( ) , rt - > size ) . intersection ( p_region ) ;
2020-10-28 19:34:27 +01:00
if ( region . size = = Size2i ( ) ) {
return ; //nothing to do
}
}
2022-02-06 00:03:39 +01:00
RD : : get_singleton ( ) - > draw_command_begin_label ( " Gaussian Blur Mipmaps2 " ) ;
2020-10-28 19:34:27 +01:00
//then mipmap blur
RID prev_texture = rt - > backbuffer_mipmap0 ;
for ( int i = 0 ; i < rt - > backbuffer_mipmaps . size ( ) ; i + + ) {
region . position . x > > = 1 ;
region . position . y > > = 1 ;
region . size . x = MAX ( 1 , region . size . x > > 1 ) ;
region . size . y = MAX ( 1 , region . size . y > > 1 ) ;
2022-02-06 00:03:39 +01:00
RID mipmap = rt - > backbuffer_mipmaps [ i ] ;
effects - > gaussian_blur ( prev_texture , mipmap , region , true ) ;
prev_texture = mipmap ;
2020-10-28 19:34:27 +01:00
}
2022-02-06 00:03:39 +01:00
RD : : get_singleton ( ) - > draw_command_end_label ( ) ;
2020-10-28 19:34:27 +01:00
}
2020-12-04 19:26:24 +01:00
RID RendererStorageRD : : render_target_get_framebuffer_uniform_set ( RID p_render_target ) {
2021-09-29 19:08:41 +02:00
RenderTarget * rt = render_target_owner . get_or_null ( p_render_target ) ;
2020-10-24 17:15:43 +02:00
ERR_FAIL_COND_V ( ! rt , RID ( ) ) ;
return rt - > framebuffer_uniform_set ;
}
2020-12-04 19:26:24 +01:00
RID RendererStorageRD : : render_target_get_backbuffer_uniform_set ( RID p_render_target ) {
2021-09-29 19:08:41 +02:00
RenderTarget * rt = render_target_owner . get_or_null ( p_render_target ) ;
2019-07-27 15:23:24 +02:00
ERR_FAIL_COND_V ( ! rt , RID ( ) ) ;
return rt - > backbuffer_uniform_set ;
}
2020-12-04 19:26:24 +01:00
void RendererStorageRD : : render_target_set_framebuffer_uniform_set ( RID p_render_target , RID p_uniform_set ) {
2021-09-29 19:08:41 +02:00
RenderTarget * rt = render_target_owner . get_or_null ( p_render_target ) ;
2020-10-24 17:15:43 +02:00
ERR_FAIL_COND ( ! rt ) ;
rt - > framebuffer_uniform_set = p_uniform_set ;
}
2020-12-04 19:26:24 +01:00
void RendererStorageRD : : render_target_set_backbuffer_uniform_set ( RID p_render_target , RID p_uniform_set ) {
2021-09-29 19:08:41 +02:00
RenderTarget * rt = render_target_owner . get_or_null ( p_render_target ) ;
2020-10-24 17:15:43 +02:00
ERR_FAIL_COND ( ! rt ) ;
rt - > backbuffer_uniform_set = p_uniform_set ;
}
2021-01-04 13:33:25 +01:00
void RendererStorageRD : : base_update_dependency ( RID p_base , DependencyTracker * p_instance ) {
2022-04-02 07:29:04 +02:00
if ( RendererRD : : MeshStorage : : get_singleton ( ) - > owns_mesh ( p_base ) ) {
RendererRD : : Mesh * mesh = RendererRD : : MeshStorage : : get_singleton ( ) - > get_mesh ( p_base ) ;
2021-01-04 13:33:25 +01:00
p_instance - > update_dependency ( & mesh - > dependency ) ;
2022-04-02 07:29:04 +02:00
} else if ( RendererRD : : MeshStorage : : get_singleton ( ) - > owns_multimesh ( p_base ) ) {
RendererRD : : MultiMesh * multimesh = RendererRD : : MeshStorage : : get_singleton ( ) - > get_multimesh ( p_base ) ;
2021-01-04 13:33:25 +01:00
p_instance - > update_dependency ( & multimesh - > dependency ) ;
2019-09-14 05:37:42 +02:00
if ( multimesh - > mesh . is_valid ( ) ) {
base_update_dependency ( multimesh - > mesh , p_instance ) ;
}
2019-09-07 03:51:27 +02:00
} else if ( reflection_probe_owner . owns ( p_base ) ) {
2021-09-29 19:08:41 +02:00
ReflectionProbe * rp = reflection_probe_owner . get_or_null ( p_base ) ;
2021-01-04 13:33:25 +01:00
p_instance - > update_dependency ( & rp - > dependency ) ;
2022-03-20 12:28:24 +01:00
} else if ( RendererRD : : DecalAtlasStorage : : get_singleton ( ) - > owns_decal ( p_base ) ) {
RendererRD : : Decal * decal = RendererRD : : DecalAtlasStorage : : get_singleton ( ) - > get_decal ( p_base ) ;
2021-01-04 13:33:25 +01:00
p_instance - > update_dependency ( & decal - > dependency ) ;
2021-06-05 00:47:26 +02:00
} else if ( voxel_gi_owner . owns ( p_base ) ) {
2021-09-29 19:08:41 +02:00
VoxelGI * gip = voxel_gi_owner . get_or_null ( p_base ) ;
2021-01-04 13:33:25 +01:00
p_instance - > update_dependency ( & gip - > dependency ) ;
2020-05-01 14:34:23 +02:00
} else if ( lightmap_owner . owns ( p_base ) ) {
2021-09-29 19:08:41 +02:00
Lightmap * lm = lightmap_owner . get_or_null ( p_base ) ;
2021-01-04 13:33:25 +01:00
p_instance - > update_dependency ( & lm - > dependency ) ;
2019-09-07 03:51:27 +02:00
} else if ( light_owner . owns ( p_base ) ) {
2021-09-29 19:08:41 +02:00
Light * l = light_owner . get_or_null ( p_base ) ;
2021-01-04 13:33:25 +01:00
p_instance - > update_dependency ( & l - > dependency ) ;
2020-08-19 15:38:24 +02:00
} else if ( particles_owner . owns ( p_base ) ) {
2021-09-29 19:08:41 +02:00
Particles * p = particles_owner . get_or_null ( p_base ) ;
2021-01-04 13:33:25 +01:00
p_instance - > update_dependency ( & p - > dependency ) ;
2020-10-08 02:29:49 +02:00
} else if ( particles_collision_owner . owns ( p_base ) ) {
2021-09-29 19:08:41 +02:00
ParticlesCollision * pc = particles_collision_owner . get_or_null ( p_base ) ;
2021-01-04 13:33:25 +01:00
p_instance - > update_dependency ( & pc - > dependency ) ;
2021-10-03 13:28:55 +02:00
} else if ( fog_volume_owner . owns ( p_base ) ) {
FogVolume * fv = fog_volume_owner . get_or_null ( p_base ) ;
p_instance - > update_dependency ( & fv - > dependency ) ;
2021-06-16 20:43:02 +02:00
} else if ( visibility_notifier_owner . owns ( p_base ) ) {
2021-09-29 19:08:41 +02:00
VisibilityNotifier * vn = visibility_notifier_owner . get_or_null ( p_base ) ;
2021-06-16 20:43:02 +02:00
p_instance - > update_dependency ( & vn - > dependency ) ;
2019-08-19 00:40:52 +02:00
}
}
2020-12-04 19:26:24 +01:00
RS : : InstanceType RendererStorageRD : : get_base_type ( RID p_rid ) const {
2022-04-02 07:29:04 +02:00
if ( RendererRD : : MeshStorage : : get_singleton ( ) - > owns_mesh ( p_rid ) ) {
2020-03-27 19:21:27 +01:00
return RS : : INSTANCE_MESH ;
2019-08-20 22:54:03 +02:00
}
2022-04-02 07:29:04 +02:00
if ( RendererRD : : MeshStorage : : get_singleton ( ) - > owns_multimesh ( p_rid ) ) {
2020-03-27 19:21:27 +01:00
return RS : : INSTANCE_MULTIMESH ;
2019-09-14 05:37:42 +02:00
}
2019-09-07 03:51:27 +02:00
if ( reflection_probe_owner . owns ( p_rid ) ) {
2020-03-27 19:21:27 +01:00
return RS : : INSTANCE_REFLECTION_PROBE ;
2019-09-07 03:51:27 +02:00
}
2022-03-20 12:28:24 +01:00
if ( RendererRD : : DecalAtlasStorage : : get_singleton ( ) - > owns_decal ( p_rid ) ) {
2020-04-14 05:05:21 +02:00
return RS : : INSTANCE_DECAL ;
}
2021-06-05 00:47:26 +02:00
if ( voxel_gi_owner . owns ( p_rid ) ) {
return RS : : INSTANCE_VOXEL_GI ;
2019-10-03 22:39:08 +02:00
}
2019-09-07 03:51:27 +02:00
if ( light_owner . owns ( p_rid ) ) {
2020-03-27 19:21:27 +01:00
return RS : : INSTANCE_LIGHT ;
2019-09-07 03:51:27 +02:00
}
2020-05-01 14:34:23 +02:00
if ( lightmap_owner . owns ( p_rid ) ) {
return RS : : INSTANCE_LIGHTMAP ;
}
2020-08-19 15:38:24 +02:00
if ( particles_owner . owns ( p_rid ) ) {
return RS : : INSTANCE_PARTICLES ;
}
2020-10-08 02:29:49 +02:00
if ( particles_collision_owner . owns ( p_rid ) ) {
return RS : : INSTANCE_PARTICLES_COLLISION ;
}
2021-10-03 13:28:55 +02:00
if ( fog_volume_owner . owns ( p_rid ) ) {
return RS : : INSTANCE_FOG_VOLUME ;
}
2021-06-16 20:43:02 +02:00
if ( visibility_notifier_owner . owns ( p_rid ) ) {
return RS : : INSTANCE_VISIBLITY_NOTIFIER ;
}
2019-09-07 03:51:27 +02:00
2020-03-27 19:21:27 +01:00
return RS : : INSTANCE_NONE ;
2019-08-20 22:54:03 +02:00
}
2020-04-14 05:05:21 +02:00
2020-12-04 19:26:24 +01:00
void RendererStorageRD : : update_dirty_resources ( ) {
2022-03-21 12:25:25 +01:00
RendererRD : : MaterialStorage : : get_singleton ( ) - > _update_global_variables ( ) ; //must do before materials, so it can queue them for update
RendererRD : : MaterialStorage : : get_singleton ( ) - > _update_queued_materials ( ) ;
2022-04-02 07:29:04 +02:00
RendererRD : : MeshStorage : : get_singleton ( ) - > _update_dirty_multimeshes ( ) ;
RendererRD : : MeshStorage : : get_singleton ( ) - > _update_dirty_skeletons ( ) ;
2022-03-20 12:28:24 +01:00
RendererRD : : DecalAtlasStorage : : get_singleton ( ) - > update_decal_atlas ( ) ;
2019-07-21 16:31:30 +02:00
}
2020-12-04 19:26:24 +01:00
bool RendererStorageRD : : has_os_feature ( const String & p_feature ) const {
2019-09-27 04:16:44 +02:00
if ( p_feature = = " rgtc " & & RD : : get_singleton ( ) - > texture_is_format_supported_for_usage ( RD : : DATA_FORMAT_BC5_UNORM_BLOCK , RD : : TEXTURE_USAGE_SAMPLING_BIT ) ) {
return true ;
}
2019-09-14 05:37:42 +02:00
if ( p_feature = = " s3tc " & & RD : : get_singleton ( ) - > texture_is_format_supported_for_usage ( RD : : DATA_FORMAT_BC1_RGB_UNORM_BLOCK , RD : : TEXTURE_USAGE_SAMPLING_BIT ) ) {
return true ;
}
if ( p_feature = = " bptc " & & RD : : get_singleton ( ) - > texture_is_format_supported_for_usage ( RD : : DATA_FORMAT_BC7_UNORM_BLOCK , RD : : TEXTURE_USAGE_SAMPLING_BIT ) ) {
return true ;
}
if ( ( p_feature = = " etc " | | p_feature = = " etc2 " ) & & RD : : get_singleton ( ) - > texture_is_format_supported_for_usage ( RD : : DATA_FORMAT_ETC2_R8G8B8_UNORM_BLOCK , RD : : TEXTURE_USAGE_SAMPLING_BIT ) ) {
return true ;
}
return false ;
}
2020-05-14 14:29:06 +02:00
2020-12-04 19:26:24 +01:00
bool RendererStorageRD : : free ( RID p_rid ) {
2022-03-12 12:19:59 +01:00
if ( RendererRD : : TextureStorage : : get_singleton ( ) - > owns_texture ( p_rid ) ) {
RendererRD : : TextureStorage : : get_singleton ( ) - > texture_free ( p_rid ) ;
} else if ( RendererRD : : CanvasTextureStorage : : get_singleton ( ) - > owns_canvas_texture ( p_rid ) ) {
RendererRD : : CanvasTextureStorage : : get_singleton ( ) - > canvas_texture_free ( p_rid ) ;
2022-03-21 12:25:25 +01:00
} else if ( RendererRD : : MaterialStorage : : get_singleton ( ) - > owns_shader ( p_rid ) ) {
RendererRD : : MaterialStorage : : get_singleton ( ) - > shader_free ( p_rid ) ;
} else if ( RendererRD : : MaterialStorage : : get_singleton ( ) - > owns_material ( p_rid ) ) {
RendererRD : : MaterialStorage : : get_singleton ( ) - > material_free ( p_rid ) ;
2022-04-02 07:29:04 +02:00
} else if ( RendererRD : : MeshStorage : : get_singleton ( ) - > owns_mesh ( p_rid ) ) {
RendererRD : : MeshStorage : : get_singleton ( ) - > mesh_free ( p_rid ) ;
} else if ( RendererRD : : MeshStorage : : get_singleton ( ) - > owns_mesh_instance ( p_rid ) ) {
RendererRD : : MeshStorage : : get_singleton ( ) - > mesh_instance_free ( p_rid ) ;
} else if ( RendererRD : : MeshStorage : : get_singleton ( ) - > owns_multimesh ( p_rid ) ) {
RendererRD : : MeshStorage : : get_singleton ( ) - > multimesh_free ( p_rid ) ;
} else if ( RendererRD : : MeshStorage : : get_singleton ( ) - > owns_skeleton ( p_rid ) ) {
RendererRD : : MeshStorage : : get_singleton ( ) - > skeleton_free ( p_rid ) ;
2019-09-07 03:51:27 +02:00
} else if ( reflection_probe_owner . owns ( p_rid ) ) {
2021-09-29 19:08:41 +02:00
ReflectionProbe * reflection_probe = reflection_probe_owner . get_or_null ( p_rid ) ;
2021-01-04 13:33:25 +01:00
reflection_probe - > dependency . deleted_notify ( p_rid ) ;
2019-09-07 03:51:27 +02:00
reflection_probe_owner . free ( p_rid ) ;
2022-03-20 12:28:24 +01:00
} else if ( RendererRD : : DecalAtlasStorage : : get_singleton ( ) - > owns_decal ( p_rid ) ) {
RendererRD : : DecalAtlasStorage : : get_singleton ( ) - > decal_free ( p_rid ) ;
2021-06-05 00:47:26 +02:00
} else if ( voxel_gi_owner . owns ( p_rid ) ) {
voxel_gi_allocate_data ( p_rid , Transform3D ( ) , AABB ( ) , Vector3i ( ) , Vector < uint8_t > ( ) , Vector < uint8_t > ( ) , Vector < uint8_t > ( ) , Vector < int > ( ) ) ; //deallocate
2021-09-29 19:08:41 +02:00
VoxelGI * voxel_gi = voxel_gi_owner . get_or_null ( p_rid ) ;
2021-06-05 00:47:26 +02:00
voxel_gi - > dependency . deleted_notify ( p_rid ) ;
voxel_gi_owner . free ( p_rid ) ;
2020-05-01 14:34:23 +02:00
} else if ( lightmap_owner . owns ( p_rid ) ) {
lightmap_set_textures ( p_rid , RID ( ) , false ) ;
2021-09-29 19:08:41 +02:00
Lightmap * lightmap = lightmap_owner . get_or_null ( p_rid ) ;
2021-01-04 13:33:25 +01:00
lightmap - > dependency . deleted_notify ( p_rid ) ;
2020-05-01 14:34:23 +02:00
lightmap_owner . free ( p_rid ) ;
2019-09-07 03:51:27 +02:00
} else if ( light_owner . owns ( p_rid ) ) {
2020-04-14 22:05:45 +02:00
light_set_projector ( p_rid , RID ( ) ) ; //clear projector
2019-09-07 03:51:27 +02:00
// delete the texture
2021-09-29 19:08:41 +02:00
Light * light = light_owner . get_or_null ( p_rid ) ;
2021-01-04 13:33:25 +01:00
light - > dependency . deleted_notify ( p_rid ) ;
2019-09-07 03:51:27 +02:00
light_owner . free ( p_rid ) ;
2020-09-06 14:18:10 +02:00
} else if ( particles_owner . owns ( p_rid ) ) {
2021-04-27 17:43:49 +02:00
update_particles ( ) ;
2021-09-29 19:08:41 +02:00
Particles * particles = particles_owner . get_or_null ( p_rid ) ;
2021-01-04 13:33:25 +01:00
particles - > dependency . deleted_notify ( p_rid ) ;
2021-04-27 17:43:49 +02:00
_particles_free_data ( particles ) ;
2020-09-06 14:18:10 +02:00
particles_owner . free ( p_rid ) ;
2020-10-08 02:29:49 +02:00
} else if ( particles_collision_owner . owns ( p_rid ) ) {
2021-09-29 19:08:41 +02:00
ParticlesCollision * particles_collision = particles_collision_owner . get_or_null ( p_rid ) ;
2020-10-08 02:29:49 +02:00
if ( particles_collision - > heightfield_texture . is_valid ( ) ) {
RD : : get_singleton ( ) - > free ( particles_collision - > heightfield_texture ) ;
}
2021-01-04 13:33:25 +01:00
particles_collision - > dependency . deleted_notify ( p_rid ) ;
2020-10-08 02:29:49 +02:00
particles_collision_owner . free ( p_rid ) ;
2021-06-16 20:43:02 +02:00
} else if ( visibility_notifier_owner . owns ( p_rid ) ) {
2021-09-29 19:08:41 +02:00
VisibilityNotifier * vn = visibility_notifier_owner . get_or_null ( p_rid ) ;
2021-06-16 20:43:02 +02:00
vn - > dependency . deleted_notify ( p_rid ) ;
visibility_notifier_owner . free ( p_rid ) ;
2020-12-31 13:42:56 +01:00
} else if ( particles_collision_instance_owner . owns ( p_rid ) ) {
particles_collision_instance_owner . free ( p_rid ) ;
2021-10-03 13:28:55 +02:00
} else if ( fog_volume_owner . owns ( p_rid ) ) {
FogVolume * fog_volume = fog_volume_owner . get_or_null ( p_rid ) ;
fog_volume - > dependency . deleted_notify ( p_rid ) ;
fog_volume_owner . free ( p_rid ) ;
2019-06-16 04:45:24 +02:00
} else if ( render_target_owner . owns ( p_rid ) ) {
2021-09-29 19:08:41 +02:00
RenderTarget * rt = render_target_owner . get_or_null ( p_rid ) ;
2019-06-16 04:45:24 +02:00
_clear_render_target ( rt ) ;
if ( rt - > texture . is_valid ( ) ) {
2022-03-12 12:19:59 +01:00
RendererRD : : Texture * tex = RendererRD : : TextureStorage : : get_singleton ( ) - > get_texture ( rt - > texture ) ;
2019-06-25 03:24:07 +02:00
tex - > is_render_target = false ;
free ( rt - > texture ) ;
2019-06-16 04:45:24 +02:00
}
render_target_owner . free ( p_rid ) ;
} else {
return false ;
}
return true ;
}
2019-07-21 16:31:30 +02:00
2021-07-20 13:40:16 +02:00
void RendererStorageRD : : init_effects ( bool p_prefer_raster_effects ) {
effects = memnew ( EffectsRD ( p_prefer_raster_effects ) ) ;
}
2020-12-04 19:26:24 +01:00
EffectsRD * RendererStorageRD : : get_effects ( ) {
2021-07-20 13:40:16 +02:00
ERR_FAIL_NULL_V_MSG ( effects , nullptr , " Effects haven't been initialised yet. " ) ;
return effects ;
2019-07-27 15:23:24 +02:00
}
2020-12-04 19:26:24 +01:00
void RendererStorageRD : : capture_timestamps_begin ( ) {
2021-01-26 01:52:58 +01:00
RD : : get_singleton ( ) - > capture_timestamp ( " Frame Begin " ) ;
2019-09-20 22:58:06 +02:00
}
2020-12-04 19:26:24 +01:00
void RendererStorageRD : : capture_timestamp ( const String & p_name ) {
2021-01-26 01:52:58 +01:00
RD : : get_singleton ( ) - > capture_timestamp ( p_name ) ;
2019-09-20 22:58:06 +02:00
}
2020-12-04 19:26:24 +01:00
uint32_t RendererStorageRD : : get_captured_timestamps_count ( ) const {
2019-09-20 22:58:06 +02:00
return RD : : get_singleton ( ) - > get_captured_timestamps_count ( ) ;
}
2020-05-14 14:29:06 +02:00
2020-12-04 19:26:24 +01:00
uint64_t RendererStorageRD : : get_captured_timestamps_frame ( ) const {
2019-09-20 22:58:06 +02:00
return RD : : get_singleton ( ) - > get_captured_timestamps_frame ( ) ;
}
2020-12-04 19:26:24 +01:00
uint64_t RendererStorageRD : : get_captured_timestamp_gpu_time ( uint32_t p_index ) const {
2019-09-20 22:58:06 +02:00
return RD : : get_singleton ( ) - > get_captured_timestamp_gpu_time ( p_index ) ;
}
2020-05-14 14:29:06 +02:00
2020-12-04 19:26:24 +01:00
uint64_t RendererStorageRD : : get_captured_timestamp_cpu_time ( uint32_t p_index ) const {
2019-09-20 22:58:06 +02:00
return RD : : get_singleton ( ) - > get_captured_timestamp_cpu_time ( p_index ) ;
}
2020-05-14 14:29:06 +02:00
2020-12-04 19:26:24 +01:00
String RendererStorageRD : : get_captured_timestamp_name ( uint32_t p_index ) const {
2019-09-20 22:58:06 +02:00
return RD : : get_singleton ( ) - > get_captured_timestamp_name ( p_index ) ;
}
2021-07-03 01:14:19 +02:00
void RendererStorageRD : : update_memory_info ( ) {
texture_mem_cache = RenderingDevice : : get_singleton ( ) - > get_memory_usage ( RenderingDevice : : MEMORY_TEXTURES ) ;
buffer_mem_cache = RenderingDevice : : get_singleton ( ) - > get_memory_usage ( RenderingDevice : : MEMORY_BUFFERS ) ;
total_mem_cache = RenderingDevice : : get_singleton ( ) - > get_memory_usage ( RenderingDevice : : MEMORY_TOTAL ) ;
}
uint64_t RendererStorageRD : : get_rendering_info ( RS : : RenderingInfo p_info ) {
if ( p_info = = RS : : RENDERING_INFO_TEXTURE_MEM_USED ) {
return texture_mem_cache ;
} else if ( p_info = = RS : : RENDERING_INFO_BUFFER_MEM_USED ) {
return buffer_mem_cache ;
} else if ( p_info = = RS : : RENDERING_INFO_VIDEO_MEM_USED ) {
return total_mem_cache ;
}
return 0 ;
}
String RendererStorageRD : : get_video_adapter_name ( ) const {
return RenderingDevice : : get_singleton ( ) - > get_device_name ( ) ;
}
2021-12-10 17:01:51 +01:00
2021-07-03 01:14:19 +02:00
String RendererStorageRD : : get_video_adapter_vendor ( ) const {
return RenderingDevice : : get_singleton ( ) - > get_device_vendor_name ( ) ;
}
2021-12-10 17:01:51 +01:00
RenderingDevice : : DeviceType RendererStorageRD : : get_video_adapter_type ( ) const {
return RenderingDevice : : get_singleton ( ) - > get_device_type ( ) ;
}
2020-12-04 19:26:24 +01:00
RendererStorageRD * RendererStorageRD : : base_singleton = nullptr ;
2020-04-17 04:52:00 +02:00
2020-12-04 19:26:24 +01:00
RendererStorageRD : : RendererStorageRD ( ) {
2020-04-17 04:52:00 +02:00
base_singleton = this ;
2022-03-12 12:19:59 +01:00
RendererRD : : TextureStorage * texture_storage = RendererRD : : TextureStorage : : get_singleton ( ) ;
2022-03-21 12:25:25 +01:00
RendererRD : : MaterialStorage * material_storage = RendererRD : : MaterialStorage : : get_singleton ( ) ;
2020-04-17 04:52:00 +02:00
2019-07-21 16:31:30 +02:00
//default samplers
2020-03-27 19:21:27 +01:00
for ( int i = 1 ; i < RS : : CANVAS_ITEM_TEXTURE_FILTER_MAX ; i + + ) {
for ( int j = 1 ; j < RS : : CANVAS_ITEM_TEXTURE_REPEAT_MAX ; j + + ) {
2019-07-21 16:31:30 +02:00
RD : : SamplerState sampler_state ;
switch ( i ) {
2020-03-27 19:21:27 +01:00
case RS : : CANVAS_ITEM_TEXTURE_FILTER_NEAREST : {
2019-07-21 16:31:30 +02:00
sampler_state . mag_filter = RD : : SAMPLER_FILTER_NEAREST ;
sampler_state . min_filter = RD : : SAMPLER_FILTER_NEAREST ;
sampler_state . max_lod = 0 ;
} break ;
2020-03-27 19:21:27 +01:00
case RS : : CANVAS_ITEM_TEXTURE_FILTER_LINEAR : {
2019-07-21 16:31:30 +02:00
sampler_state . mag_filter = RD : : SAMPLER_FILTER_LINEAR ;
sampler_state . min_filter = RD : : SAMPLER_FILTER_LINEAR ;
sampler_state . max_lod = 0 ;
} break ;
2020-03-27 19:21:27 +01:00
case RS : : CANVAS_ITEM_TEXTURE_FILTER_NEAREST_WITH_MIPMAPS : {
2019-07-21 16:31:30 +02:00
sampler_state . mag_filter = RD : : SAMPLER_FILTER_NEAREST ;
2021-08-12 03:05:03 +02:00
sampler_state . min_filter = RD : : SAMPLER_FILTER_NEAREST ;
2021-08-12 01:57:33 +02:00
if ( GLOBAL_GET ( " rendering/textures/default_filters/use_nearest_mipmap_filter " ) ) {
sampler_state . mip_filter = RD : : SAMPLER_FILTER_NEAREST ;
} else {
sampler_state . mip_filter = RD : : SAMPLER_FILTER_LINEAR ;
}
2019-07-21 16:31:30 +02:00
} break ;
2020-03-27 19:21:27 +01:00
case RS : : CANVAS_ITEM_TEXTURE_FILTER_LINEAR_WITH_MIPMAPS : {
2019-07-21 16:31:30 +02:00
sampler_state . mag_filter = RD : : SAMPLER_FILTER_LINEAR ;
sampler_state . min_filter = RD : : SAMPLER_FILTER_LINEAR ;
2021-08-12 01:57:33 +02:00
if ( GLOBAL_GET ( " rendering/textures/default_filters/use_nearest_mipmap_filter " ) ) {
sampler_state . mip_filter = RD : : SAMPLER_FILTER_NEAREST ;
} else {
sampler_state . mip_filter = RD : : SAMPLER_FILTER_LINEAR ;
}
2019-07-21 16:31:30 +02:00
} break ;
2020-03-27 19:21:27 +01:00
case RS : : CANVAS_ITEM_TEXTURE_FILTER_NEAREST_WITH_MIPMAPS_ANISOTROPIC : {
2019-07-21 16:31:30 +02:00
sampler_state . mag_filter = RD : : SAMPLER_FILTER_NEAREST ;
2021-08-12 03:05:03 +02:00
sampler_state . min_filter = RD : : SAMPLER_FILTER_NEAREST ;
2021-08-12 01:57:33 +02:00
if ( GLOBAL_GET ( " rendering/textures/default_filters/use_nearest_mipmap_filter " ) ) {
sampler_state . mip_filter = RD : : SAMPLER_FILTER_NEAREST ;
} else {
sampler_state . mip_filter = RD : : SAMPLER_FILTER_LINEAR ;
}
2019-07-21 16:31:30 +02:00
sampler_state . use_anisotropy = true ;
2021-02-17 17:44:49 +01:00
sampler_state . anisotropy_max = 1 < < int ( GLOBAL_GET ( " rendering/textures/default_filters/anisotropic_filtering_level " ) ) ;
2019-07-21 16:31:30 +02:00
} break ;
2020-03-27 19:21:27 +01:00
case RS : : CANVAS_ITEM_TEXTURE_FILTER_LINEAR_WITH_MIPMAPS_ANISOTROPIC : {
2019-07-21 16:31:30 +02:00
sampler_state . mag_filter = RD : : SAMPLER_FILTER_LINEAR ;
sampler_state . min_filter = RD : : SAMPLER_FILTER_LINEAR ;
2021-08-12 01:57:33 +02:00
if ( GLOBAL_GET ( " rendering/textures/default_filters/use_nearest_mipmap_filter " ) ) {
sampler_state . mip_filter = RD : : SAMPLER_FILTER_NEAREST ;
} else {
sampler_state . mip_filter = RD : : SAMPLER_FILTER_LINEAR ;
}
2019-07-21 16:31:30 +02:00
sampler_state . use_anisotropy = true ;
2021-02-17 17:44:49 +01:00
sampler_state . anisotropy_max = 1 < < int ( GLOBAL_GET ( " rendering/textures/default_filters/anisotropic_filtering_level " ) ) ;
2019-07-21 16:31:30 +02:00
} break ;
default : {
}
}
switch ( j ) {
2020-03-27 19:21:27 +01:00
case RS : : CANVAS_ITEM_TEXTURE_REPEAT_DISABLED : {
2019-07-21 16:31:30 +02:00
sampler_state . repeat_u = RD : : SAMPLER_REPEAT_MODE_CLAMP_TO_EDGE ;
sampler_state . repeat_v = RD : : SAMPLER_REPEAT_MODE_CLAMP_TO_EDGE ;
2020-09-10 02:59:51 +02:00
sampler_state . repeat_w = RD : : SAMPLER_REPEAT_MODE_CLAMP_TO_EDGE ;
2019-07-21 16:31:30 +02:00
} break ;
2020-03-27 19:21:27 +01:00
case RS : : CANVAS_ITEM_TEXTURE_REPEAT_ENABLED : {
2019-07-21 16:31:30 +02:00
sampler_state . repeat_u = RD : : SAMPLER_REPEAT_MODE_REPEAT ;
sampler_state . repeat_v = RD : : SAMPLER_REPEAT_MODE_REPEAT ;
2020-09-10 02:59:51 +02:00
sampler_state . repeat_w = RD : : SAMPLER_REPEAT_MODE_REPEAT ;
2019-07-21 16:31:30 +02:00
} break ;
2020-03-27 19:21:27 +01:00
case RS : : CANVAS_ITEM_TEXTURE_REPEAT_MIRROR : {
2019-07-21 16:31:30 +02:00
sampler_state . repeat_u = RD : : SAMPLER_REPEAT_MODE_MIRRORED_REPEAT ;
sampler_state . repeat_v = RD : : SAMPLER_REPEAT_MODE_MIRRORED_REPEAT ;
2020-09-10 02:59:51 +02:00
sampler_state . repeat_w = RD : : SAMPLER_REPEAT_MODE_MIRRORED_REPEAT ;
2019-07-21 16:31:30 +02:00
} break ;
default : {
}
}
default_rd_samplers [ i ] [ j ] = RD : : get_singleton ( ) - > sampler_create ( sampler_state ) ;
}
}
2019-08-19 00:40:52 +02:00
2021-11-23 22:16:03 +01:00
//custom sampler
sampler_rd_configure_custom ( 0.0f ) ;
2020-05-01 14:34:23 +02:00
using_lightmap_array = true ; // high end
if ( using_lightmap_array ) {
2022-03-10 18:43:27 +01:00
uint64_t textures_per_stage = RD : : get_singleton ( ) - > limit_get ( RD : : LIMIT_MAX_TEXTURES_PER_SHADER_STAGE ) ;
2020-05-01 14:34:23 +02:00
if ( textures_per_stage < = 256 ) {
lightmap_textures . resize ( 32 ) ;
} else {
lightmap_textures . resize ( 1024 ) ;
}
for ( int i = 0 ; i < lightmap_textures . size ( ) ; i + + ) {
2022-03-12 12:19:59 +01:00
lightmap_textures . write [ i ] = texture_storage - > texture_rd_get_default ( RendererRD : : DEFAULT_RD_TEXTURE_2D_ARRAY_WHITE ) ;
2020-05-01 14:34:23 +02:00
}
2019-10-11 04:14:56 +02:00
}
2021-02-17 17:44:49 +01:00
lightmap_probe_capture_update_speed = GLOBAL_GET ( " rendering/lightmapping/probe_capture/update_speed " ) ;
2020-08-19 15:38:24 +02:00
/* Particles */
{
// Initialize particles
Vector < String > particles_modes ;
particles_modes . push_back ( " " ) ;
particles_shader . shader . initialize ( particles_modes , String ( ) ) ;
}
2022-03-21 12:25:25 +01:00
RendererRD : : MaterialStorage : : get_singleton ( ) - > shader_set_data_request_function ( RendererRD : : SHADER_TYPE_PARTICLES , _create_particles_shader_funcs ) ;
RendererRD : : MaterialStorage : : get_singleton ( ) - > material_set_data_request_function ( RendererRD : : SHADER_TYPE_PARTICLES , _create_particles_material_funcs ) ;
2020-08-19 15:38:24 +02:00
{
2021-11-16 16:25:42 +01:00
ShaderCompiler : : DefaultIdentifierActions actions ;
2020-08-19 15:38:24 +02:00
actions . renames [ " COLOR " ] = " PARTICLE.color " ;
actions . renames [ " VELOCITY " ] = " PARTICLE.velocity " ;
//actions.renames["MASS"] = "mass"; ?
2021-04-27 17:43:49 +02:00
actions . renames [ " ACTIVE " ] = " particle_active " ;
2020-08-19 15:38:24 +02:00
actions . renames [ " RESTART " ] = " restart " ;
actions . renames [ " CUSTOM " ] = " PARTICLE.custom " ;
2022-02-14 13:27:10 +01:00
for ( int i = 0 ; i < ParticlesShader : : MAX_USERDATAS ; i + + ) {
String udname = " USERDATA " + itos ( i + 1 ) ;
actions . renames [ udname ] = " PARTICLE.userdata " + itos ( i + 1 ) ;
actions . usage_defines [ udname ] = " #define USERDATA " + itos ( i + 1 ) + " _USED \n " ;
}
2020-08-19 15:38:24 +02:00
actions . renames [ " TRANSFORM " ] = " PARTICLE.xform " ;
2021-11-26 16:34:28 +01:00
actions . renames [ " TIME " ] = " frame_history.data[0].time " ;
2021-05-19 14:12:55 +02:00
actions . renames [ " PI " ] = _MKSTR ( Math_PI ) ;
actions . renames [ " TAU " ] = _MKSTR ( Math_TAU ) ;
actions . renames [ " E " ] = _MKSTR ( Math_E ) ;
2020-08-19 15:38:24 +02:00
actions . renames [ " LIFETIME " ] = " params.lifetime " ;
actions . renames [ " DELTA " ] = " local_delta " ;
2021-04-27 17:43:49 +02:00
actions . renames [ " NUMBER " ] = " particle_number " ;
2020-08-19 15:38:24 +02:00
actions . renames [ " INDEX " ] = " index " ;
//actions.renames["GRAVITY"] = "current_gravity";
actions . renames [ " EMISSION_TRANSFORM " ] = " FRAME.emission_transform " ;
actions . renames [ " RANDOM_SEED " ] = " FRAME.random_seed " ;
2020-09-06 14:18:10 +02:00
actions . renames [ " FLAG_EMIT_POSITION " ] = " EMISSION_FLAG_HAS_POSITION " ;
actions . renames [ " FLAG_EMIT_ROT_SCALE " ] = " EMISSION_FLAG_HAS_ROTATION_SCALE " ;
actions . renames [ " FLAG_EMIT_VELOCITY " ] = " EMISSION_FLAG_HAS_VELOCITY " ;
actions . renames [ " FLAG_EMIT_COLOR " ] = " EMISSION_FLAG_HAS_COLOR " ;
actions . renames [ " FLAG_EMIT_CUSTOM " ] = " EMISSION_FLAG_HAS_CUSTOM " ;
actions . renames [ " RESTART_POSITION " ] = " restart_position " ;
actions . renames [ " RESTART_ROT_SCALE " ] = " restart_rotation_scale " ;
actions . renames [ " RESTART_VELOCITY " ] = " restart_velocity " ;
actions . renames [ " RESTART_COLOR " ] = " restart_color " ;
actions . renames [ " RESTART_CUSTOM " ] = " restart_custom " ;
2021-01-12 07:23:04 +01:00
actions . renames [ " emit_subparticle " ] = " emit_subparticle " ;
2020-10-08 02:29:49 +02:00
actions . renames [ " COLLIDED " ] = " collided " ;
actions . renames [ " COLLISION_NORMAL " ] = " collision_normal " ;
actions . renames [ " COLLISION_DEPTH " ] = " collision_depth " ;
actions . renames [ " ATTRACTOR_FORCE " ] = " attractor_force " ;
2020-08-19 15:38:24 +02:00
actions . render_mode_defines [ " disable_force " ] = " #define DISABLE_FORCE \n " ;
actions . render_mode_defines [ " disable_velocity " ] = " #define DISABLE_VELOCITY \n " ;
actions . render_mode_defines [ " keep_data " ] = " #define ENABLE_KEEP_DATA \n " ;
2020-10-08 02:29:49 +02:00
actions . render_mode_defines [ " collision_use_scale " ] = " #define USE_COLLISON_SCALE \n " ;
2020-08-19 15:38:24 +02:00
actions . sampler_array_name = " material_samplers " ;
actions . base_texture_binding_index = 1 ;
2020-10-08 02:29:49 +02:00
actions . texture_layout_set = 3 ;
2020-08-19 15:38:24 +02:00
actions . base_uniform_string = " material. " ;
actions . base_varying_index = 10 ;
actions . default_filter = ShaderLanguage : : FILTER_LINEAR_MIPMAP ;
actions . default_repeat = ShaderLanguage : : REPEAT_ENABLE ;
actions . global_buffer_array_variable = " global_variables.data " ;
particles_shader . compiler . initialize ( actions ) ;
}
{
// default material and shader for particles shader
2022-03-21 12:25:25 +01:00
particles_shader . default_shader = material_storage - > shader_allocate ( ) ;
material_storage - > shader_initialize ( particles_shader . default_shader ) ;
material_storage - > shader_set_code ( particles_shader . default_shader , R " (
2021-08-18 03:09:22 +02:00
// Default particles shader.
2021-07-19 08:06:51 +02:00
shader_type particles ;
void process ( ) {
COLOR = vec4 ( 1.0 ) ;
}
) " );
2022-03-21 12:25:25 +01:00
particles_shader . default_material = material_storage - > material_allocate ( ) ;
material_storage - > material_initialize ( particles_shader . default_material ) ;
material_storage - > material_set_shader ( particles_shader . default_material , particles_shader . default_shader ) ;
2020-08-19 15:38:24 +02:00
2022-04-05 12:40:26 +02:00
ParticlesMaterialData * md = static_cast < ParticlesMaterialData * > ( material_storage - > material_get_data ( particles_shader . default_material , RendererRD : : SHADER_TYPE_PARTICLES ) ) ;
2020-08-19 15:38:24 +02:00
particles_shader . default_shader_rd = particles_shader . shader . version_get_shader ( md - > shader_data - > version , 0 ) ;
Vector < RD : : Uniform > uniforms ;
{
2022-03-06 12:57:09 +01:00
Vector < RID > ids ;
ids . resize ( 12 ) ;
RID * ids_ptr = ids . ptrw ( ) ;
2020-08-19 15:38:24 +02:00
ids_ptr [ 0 ] = sampler_rd_get_default ( RS : : CANVAS_ITEM_TEXTURE_FILTER_NEAREST , RS : : CANVAS_ITEM_TEXTURE_REPEAT_DISABLED ) ;
ids_ptr [ 1 ] = sampler_rd_get_default ( RS : : CANVAS_ITEM_TEXTURE_FILTER_LINEAR , RS : : CANVAS_ITEM_TEXTURE_REPEAT_DISABLED ) ;
ids_ptr [ 2 ] = sampler_rd_get_default ( RS : : CANVAS_ITEM_TEXTURE_FILTER_NEAREST_WITH_MIPMAPS , RS : : CANVAS_ITEM_TEXTURE_REPEAT_DISABLED ) ;
ids_ptr [ 3 ] = sampler_rd_get_default ( RS : : CANVAS_ITEM_TEXTURE_FILTER_LINEAR_WITH_MIPMAPS , RS : : CANVAS_ITEM_TEXTURE_REPEAT_DISABLED ) ;
ids_ptr [ 4 ] = sampler_rd_get_default ( RS : : CANVAS_ITEM_TEXTURE_FILTER_NEAREST_WITH_MIPMAPS_ANISOTROPIC , RS : : CANVAS_ITEM_TEXTURE_REPEAT_DISABLED ) ;
ids_ptr [ 5 ] = sampler_rd_get_default ( RS : : CANVAS_ITEM_TEXTURE_FILTER_LINEAR_WITH_MIPMAPS_ANISOTROPIC , RS : : CANVAS_ITEM_TEXTURE_REPEAT_DISABLED ) ;
ids_ptr [ 6 ] = sampler_rd_get_default ( RS : : CANVAS_ITEM_TEXTURE_FILTER_NEAREST , RS : : CANVAS_ITEM_TEXTURE_REPEAT_ENABLED ) ;
ids_ptr [ 7 ] = sampler_rd_get_default ( RS : : CANVAS_ITEM_TEXTURE_FILTER_LINEAR , RS : : CANVAS_ITEM_TEXTURE_REPEAT_ENABLED ) ;
ids_ptr [ 8 ] = sampler_rd_get_default ( RS : : CANVAS_ITEM_TEXTURE_FILTER_NEAREST_WITH_MIPMAPS , RS : : CANVAS_ITEM_TEXTURE_REPEAT_ENABLED ) ;
ids_ptr [ 9 ] = sampler_rd_get_default ( RS : : CANVAS_ITEM_TEXTURE_FILTER_LINEAR_WITH_MIPMAPS , RS : : CANVAS_ITEM_TEXTURE_REPEAT_ENABLED ) ;
ids_ptr [ 10 ] = sampler_rd_get_default ( RS : : CANVAS_ITEM_TEXTURE_FILTER_NEAREST_WITH_MIPMAPS_ANISOTROPIC , RS : : CANVAS_ITEM_TEXTURE_REPEAT_ENABLED ) ;
ids_ptr [ 11 ] = sampler_rd_get_default ( RS : : CANVAS_ITEM_TEXTURE_FILTER_LINEAR_WITH_MIPMAPS_ANISOTROPIC , RS : : CANVAS_ITEM_TEXTURE_REPEAT_ENABLED ) ;
2022-03-06 12:57:09 +01:00
RD : : Uniform u ( RD : : UNIFORM_TYPE_SAMPLER , 1 , ids ) ;
2020-08-19 15:38:24 +02:00
uniforms . push_back ( u ) ;
}
{
RD : : Uniform u ;
2020-10-17 03:19:21 +02:00
u . uniform_type = RD : : UNIFORM_TYPE_STORAGE_BUFFER ;
2020-08-19 15:38:24 +02:00
u . binding = 2 ;
2022-03-21 12:25:25 +01:00
u . append_id ( material_storage - > global_variables_get_storage_buffer ( ) ) ;
2020-08-19 15:38:24 +02:00
uniforms . push_back ( u ) ;
}
particles_shader . base_uniform_set = RD : : get_singleton ( ) - > uniform_set_create ( uniforms , particles_shader . default_shader_rd , 0 ) ;
}
{
Vector < String > copy_modes ;
2022-02-14 13:27:10 +01:00
for ( int i = 0 ; i < = ParticlesShader : : MAX_USERDATAS ; i + + ) {
if ( i = = 0 ) {
copy_modes . push_back ( " \n #define MODE_FILL_INSTANCES \n " ) ;
copy_modes . push_back ( " \n #define MODE_FILL_SORT_BUFFER \n #define USE_SORT_BUFFER \n " ) ;
copy_modes . push_back ( " \n #define MODE_FILL_INSTANCES \n #define USE_SORT_BUFFER \n " ) ;
} else {
copy_modes . push_back ( " \n #define MODE_FILL_INSTANCES \n #define USERDATA_COUNT " + itos ( i ) + " \n " ) ;
copy_modes . push_back ( " \n #define MODE_FILL_SORT_BUFFER \n #define USE_SORT_BUFFER \n #define USERDATA_COUNT " + itos ( i ) + " \n " ) ;
copy_modes . push_back ( " \n #define MODE_FILL_INSTANCES \n #define USE_SORT_BUFFER \n #define USERDATA_COUNT " + itos ( i ) + " \n " ) ;
}
}
2020-08-19 15:38:24 +02:00
particles_shader . copy_shader . initialize ( copy_modes ) ;
particles_shader . copy_shader_version = particles_shader . copy_shader . version_create ( ) ;
2022-02-14 13:27:10 +01:00
for ( int i = 0 ; i < = ParticlesShader : : MAX_USERDATAS ; i + + ) {
for ( int j = 0 ; j < ParticlesShader : : COPY_MODE_MAX ; j + + ) {
particles_shader . copy_pipelines [ i * ParticlesShader : : COPY_MODE_MAX + j ] = RD : : get_singleton ( ) - > compute_pipeline_create ( particles_shader . copy_shader . version_get_shader ( particles_shader . copy_shader_version , i * ParticlesShader : : COPY_MODE_MAX + j ) ) ;
}
2020-08-19 15:38:24 +02:00
}
}
2020-11-26 13:50:21 +01:00
{
Vector < String > sdf_modes ;
sdf_modes . push_back ( " \n #define MODE_LOAD \n " ) ;
sdf_modes . push_back ( " \n #define MODE_LOAD_SHRINK \n " ) ;
sdf_modes . push_back ( " \n #define MODE_PROCESS \n " ) ;
sdf_modes . push_back ( " \n #define MODE_PROCESS_OPTIMIZED \n " ) ;
sdf_modes . push_back ( " \n #define MODE_STORE \n " ) ;
sdf_modes . push_back ( " \n #define MODE_STORE_SHRINK \n " ) ;
rt_sdf . shader . initialize ( sdf_modes ) ;
rt_sdf . shader_version = rt_sdf . shader . version_create ( ) ;
for ( int i = 0 ; i < RenderTargetSDF : : SHADER_MAX ; i + + ) {
rt_sdf . pipelines [ i ] = RD : : get_singleton ( ) - > compute_pipeline_create ( rt_sdf . shader . version_get_shader ( rt_sdf . shader_version , i ) ) ;
}
}
2019-07-21 16:31:30 +02:00
}
2020-12-04 19:26:24 +01:00
RendererStorageRD : : ~ RendererStorageRD ( ) {
2022-03-21 12:25:25 +01:00
RendererRD : : MaterialStorage * material_storage = RendererRD : : MaterialStorage : : get_singleton ( ) ;
2020-04-17 04:52:00 +02:00
2019-07-21 16:31:30 +02:00
//def samplers
2020-03-27 19:21:27 +01:00
for ( int i = 1 ; i < RS : : CANVAS_ITEM_TEXTURE_FILTER_MAX ; i + + ) {
for ( int j = 1 ; j < RS : : CANVAS_ITEM_TEXTURE_REPEAT_MAX ; j + + ) {
2019-07-21 16:31:30 +02:00
RD : : get_singleton ( ) - > free ( default_rd_samplers [ i ] [ j ] ) ;
}
}
2019-08-19 00:40:52 +02:00
2021-11-23 22:16:03 +01:00
//custom samplers
for ( int i = 1 ; i < RS : : CANVAS_ITEM_TEXTURE_FILTER_MAX ; i + + ) {
for ( int j = 0 ; j < RS : : CANVAS_ITEM_TEXTURE_REPEAT_MAX ; j + + ) {
if ( custom_rd_samplers [ i ] [ j ] . is_valid ( ) ) {
RD : : get_singleton ( ) - > free ( custom_rd_samplers [ i ] [ j ] ) ;
}
}
}
2020-10-12 09:47:12 +02:00
particles_shader . copy_shader . version_free ( particles_shader . copy_shader_version ) ;
2020-12-05 09:27:44 +01:00
rt_sdf . shader . version_free ( rt_sdf . shader_version ) ;
2020-04-14 05:05:21 +02:00
2022-03-21 12:25:25 +01:00
material_storage - > material_free ( particles_shader . default_material ) ;
material_storage - > shader_free ( particles_shader . default_shader ) ;
2020-10-12 18:06:47 +02:00
2021-07-20 13:40:16 +02:00
if ( effects ) {
memdelete ( effects ) ;
2021-10-12 09:30:55 +02:00
effects = nullptr ;
2021-07-20 13:40:16 +02:00
}
2019-07-21 16:31:30 +02:00
}