2023-01-05 13:25:55 +01:00
/**************************************************************************/
/* sky.cpp */
/**************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
/* https://godotengine.org */
/**************************************************************************/
/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */
/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */
/* */
/* 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. */
/**************************************************************************/
2021-02-13 13:08:08 +01:00
2022-07-19 06:17:58 +02:00
# include "sky.h"
2021-02-13 13:08:08 +01:00
# include "core/config/project_settings.h"
2021-05-19 14:12:55 +02:00
# include "core/math/math_defs.h"
2022-04-29 09:10:54 +02:00
# include "servers/rendering/renderer_rd/effects/copy_effects.h"
2022-12-15 12:20:06 +01:00
# include "servers/rendering/renderer_rd/framebuffer_cache_rd.h"
2021-05-07 15:19:04 +02:00
# include "servers/rendering/renderer_rd/renderer_compositor_rd.h"
2022-07-19 06:17:58 +02:00
# include "servers/rendering/renderer_rd/renderer_scene_render_rd.h"
2022-03-21 12:25:25 +01:00
# include "servers/rendering/renderer_rd/storage_rd/material_storage.h"
2022-08-04 10:40:39 +02:00
# include "servers/rendering/renderer_rd/storage_rd/render_scene_buffers_rd.h"
2022-03-12 12:19:59 +01:00
# include "servers/rendering/renderer_rd/storage_rd/texture_storage.h"
2022-12-15 12:20:06 +01:00
# include "servers/rendering/renderer_rd/uniform_set_cache_rd.h"
2021-02-13 13:08:08 +01:00
# include "servers/rendering/rendering_server_default.h"
2022-06-21 02:08:33 +02:00
# include "servers/rendering/rendering_server_globals.h"
2021-02-13 13:08:08 +01:00
2022-07-19 06:17:58 +02:00
using namespace RendererRD ;
2022-12-15 12:20:06 +01:00
# define RB_SCOPE_SKY SNAME("sky_buffers")
# define RB_HALF_TEXTURE SNAME("half_texture")
# define RB_QUARTER_TEXTURE SNAME("quarter_texture")
2021-02-13 13:08:08 +01:00
////////////////////////////////////////////////////////////////////////////////
// SKY SHADER
2022-07-19 06:17:58 +02:00
void SkyRD : : SkyShaderData : : set_code ( const String & p_code ) {
2021-02-13 13:08:08 +01:00
//compile
code = p_code ;
valid = false ;
ubo_size = 0 ;
uniforms . clear ( ) ;
2021-12-09 10:42:46 +01:00
if ( code . is_empty ( ) ) {
2021-02-13 13:08:08 +01: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 [ " sky " ] = ShaderCompiler : : STAGE_FRAGMENT ;
2021-02-13 13:08:08 +01:00
uses_time = false ;
uses_half_res = false ;
uses_quarter_res = false ;
uses_position = false ;
uses_light = 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 ;
actions . usage_flag_pointers [ " POSITION " ] = & uses_position ;
actions . usage_flag_pointers [ " LIGHT0_ENABLED " ] = & uses_light ;
actions . usage_flag_pointers [ " LIGHT0_ENERGY " ] = & uses_light ;
actions . usage_flag_pointers [ " LIGHT0_DIRECTION " ] = & uses_light ;
actions . usage_flag_pointers [ " LIGHT0_COLOR " ] = & uses_light ;
actions . usage_flag_pointers [ " LIGHT0_SIZE " ] = & uses_light ;
actions . usage_flag_pointers [ " LIGHT1_ENABLED " ] = & uses_light ;
actions . usage_flag_pointers [ " LIGHT1_ENERGY " ] = & uses_light ;
actions . usage_flag_pointers [ " LIGHT1_DIRECTION " ] = & uses_light ;
actions . usage_flag_pointers [ " LIGHT1_COLOR " ] = & uses_light ;
actions . usage_flag_pointers [ " LIGHT1_SIZE " ] = & uses_light ;
actions . usage_flag_pointers [ " LIGHT2_ENABLED " ] = & uses_light ;
actions . usage_flag_pointers [ " LIGHT2_ENERGY " ] = & uses_light ;
actions . usage_flag_pointers [ " LIGHT2_DIRECTION " ] = & uses_light ;
actions . usage_flag_pointers [ " LIGHT2_COLOR " ] = & uses_light ;
actions . usage_flag_pointers [ " LIGHT2_SIZE " ] = & uses_light ;
actions . usage_flag_pointers [ " LIGHT3_ENABLED " ] = & uses_light ;
actions . usage_flag_pointers [ " LIGHT3_ENERGY " ] = & uses_light ;
actions . usage_flag_pointers [ " LIGHT3_DIRECTION " ] = & uses_light ;
actions . usage_flag_pointers [ " LIGHT3_COLOR " ] = & uses_light ;
actions . usage_flag_pointers [ " LIGHT3_SIZE " ] = & uses_light ;
actions . uniforms = & uniforms ;
// !BAS! Contemplate making `SkyShader sky` accessible from this struct or even part of this struct.
2022-04-05 12:40:26 +02:00
RendererSceneRenderRD * scene_singleton = static_cast < RendererSceneRenderRD * > ( RendererSceneRenderRD : : singleton ) ;
2021-02-13 13:08:08 +01:00
Error err = scene_singleton - > sky . sky_shader . compiler . compile ( RS : : SHADER_SKY , code , & actions , path , gen_code ) ;
2021-08-16 10:25:20 +02:00
ERR_FAIL_COND_MSG ( err ! = OK , " Shader compilation failed. " ) ;
2021-02-13 13:08:08 +01:00
if ( version . is_null ( ) ) {
version = scene_singleton - > sky . sky_shader . shader . version_create ( ) ;
}
#if 0
print_line ( " **compiling shader: " ) ;
print_line ( " **defines: \n " ) ;
for ( int i = 0 ; i < gen_code . defines . size ( ) ; i + + ) {
print_line ( gen_code . defines [ i ] ) ;
}
2022-08-09 18:29:49 +02:00
HashMap < String , String > : : Iterator el = gen_code . code . begin ( ) ;
while ( el ) {
print_line ( " \n **code " + el - > key + " : \n " + el - > value ) ;
+ + el ;
}
2021-02-13 13:08:08 +01:00
print_line ( " \n **uniforms: \n " + gen_code . uniforms ) ;
2022-08-09 18:29:49 +02:00
print_line ( " \n **vertex_globals: \n " + gen_code . stage_globals [ ShaderCompiler : : STAGE_VERTEX ] ) ;
print_line ( " \n **fragment_globals: \n " + gen_code . stage_globals [ ShaderCompiler : : STAGE_FRAGMENT ] ) ;
2021-02-13 13:08:08 +01:00
# endif
2021-11-16 16:25:42 +01:00
scene_singleton - > sky . sky_shader . shader . version_set_code ( version , gen_code . code , gen_code . uniforms , gen_code . stage_globals [ ShaderCompiler : : STAGE_VERTEX ] , gen_code . stage_globals [ ShaderCompiler : : STAGE_FRAGMENT ] , gen_code . defines ) ;
2021-02-13 13:08:08 +01:00
ERR_FAIL_COND ( ! scene_singleton - > sky . sky_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
for ( int i = 0 ; i < SKY_VERSION_MAX ; i + + ) {
RD : : PipelineDepthStencilState depth_stencil_state ;
depth_stencil_state . enable_depth_test = true ;
depth_stencil_state . depth_compare_operator = RD : : COMPARE_OP_LESS_OR_EQUAL ;
2021-06-14 03:05:16 +02:00
if ( scene_singleton - > sky . sky_shader . shader . is_variant_enabled ( i ) ) {
RID shader_variant = scene_singleton - > sky . sky_shader . shader . version_get_shader ( version , i ) ;
pipelines [ i ] . setup ( shader_variant , RD : : RENDER_PRIMITIVE_TRIANGLES , RD : : PipelineRasterizationState ( ) , RD : : PipelineMultisampleState ( ) , depth_stencil_state , RD : : PipelineColorBlendState : : create_disabled ( ) , 0 ) ;
} else {
pipelines [ i ] . clear ( ) ;
}
2021-02-13 13:08:08 +01:00
}
valid = true ;
}
2022-07-19 06:17:58 +02:00
bool SkyRD : : SkyShaderData : : is_animated ( ) const {
2021-02-13 13:08:08 +01:00
return false ;
}
2022-07-19 06:17:58 +02:00
bool SkyRD : : SkyShaderData : : casts_shadows ( ) const {
2021-02-13 13:08:08 +01:00
return false ;
}
2022-07-19 06:17:58 +02:00
RS : : ShaderNativeSourceCode SkyRD : : SkyShaderData : : get_native_source_code ( ) const {
2022-04-05 12:40:26 +02:00
RendererSceneRenderRD * scene_singleton = static_cast < RendererSceneRenderRD * > ( RendererSceneRenderRD : : singleton ) ;
2021-02-13 13:08:08 +01:00
return scene_singleton - > sky . sky_shader . shader . version_get_native_source_code ( version ) ;
}
2022-07-19 06:17:58 +02:00
SkyRD : : SkyShaderData : : ~ SkyShaderData ( ) {
2022-04-05 12:40:26 +02:00
RendererSceneRenderRD * scene_singleton = static_cast < RendererSceneRenderRD * > ( RendererSceneRenderRD : : singleton ) ;
2021-02-13 13:08:08 +01:00
ERR_FAIL_COND ( ! scene_singleton ) ;
//pipeline variants will clear themselves if shader is gone
if ( version . is_valid ( ) ) {
scene_singleton - > sky . sky_shader . shader . version_free ( version ) ;
}
}
////////////////////////////////////////////////////////////////////////////////
// Sky material
2022-07-19 06:17:58 +02:00
bool SkyRD : : SkyMaterialData : : update_parameters ( const HashMap < StringName , Variant > & p_parameters , bool p_uniform_dirty , bool p_textures_dirty ) {
2022-04-05 12:40:26 +02:00
RendererSceneRenderRD * scene_singleton = static_cast < RendererSceneRenderRD * > ( RendererSceneRenderRD : : singleton ) ;
2021-02-13 13:08:08 +01:00
uniform_set_updated = true ;
2022-10-01 00:15:11 +02:00
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 , scene_singleton - > sky . sky_shader . shader . version_get_shader ( shader_data - > version , 0 ) , SKY_SET_MATERIAL , true ) ;
2021-02-13 13:08:08 +01:00
}
2022-07-19 06:17:58 +02:00
SkyRD : : SkyMaterialData : : ~ SkyMaterialData ( ) {
2021-07-08 00:55:20 +02:00
free_parameters_uniform_set ( uniform_set ) ;
2021-02-13 13:08:08 +01:00
}
2021-06-22 08:24:09 +02:00
////////////////////////////////////////////////////////////////////////////////
// Render sky
static _FORCE_INLINE_ void store_transform_3x3 ( const Basis & p_basis , float * p_array ) {
2022-04-25 00:07:35 +02:00
p_array [ 0 ] = p_basis . rows [ 0 ] [ 0 ] ;
p_array [ 1 ] = p_basis . rows [ 1 ] [ 0 ] ;
p_array [ 2 ] = p_basis . rows [ 2 ] [ 0 ] ;
2021-06-22 08:24:09 +02:00
p_array [ 3 ] = 0 ;
2022-04-25 00:07:35 +02:00
p_array [ 4 ] = p_basis . rows [ 0 ] [ 1 ] ;
p_array [ 5 ] = p_basis . rows [ 1 ] [ 1 ] ;
p_array [ 6 ] = p_basis . rows [ 2 ] [ 1 ] ;
2021-06-22 08:24:09 +02:00
p_array [ 7 ] = 0 ;
2022-04-25 00:07:35 +02:00
p_array [ 8 ] = p_basis . rows [ 0 ] [ 2 ] ;
p_array [ 9 ] = p_basis . rows [ 1 ] [ 2 ] ;
p_array [ 10 ] = p_basis . rows [ 2 ] [ 2 ] ;
2021-06-22 08:24:09 +02:00
p_array [ 11 ] = 0 ;
}
2022-12-15 12:20:06 +01:00
void SkyRD : : _render_sky ( RD : : DrawListID p_list , float p_time , RID p_fb , PipelineCacheRD * p_pipeline , RID p_uniform_set , RID p_texture_set , const Projection & p_projection , const Basis & p_orientation , const Vector3 & p_position , float p_luminance_multiplier ) {
2021-06-22 08:24:09 +02:00
SkyPushConstant sky_push_constant ;
memset ( & sky_push_constant , 0 , sizeof ( SkyPushConstant ) ) ;
2022-12-15 12:20:06 +01:00
// We only need key components of our projection matrix
sky_push_constant . projection [ 0 ] = p_projection . columns [ 2 ] [ 0 ] ;
sky_push_constant . projection [ 1 ] = p_projection . columns [ 0 ] [ 0 ] ;
sky_push_constant . projection [ 2 ] = p_projection . columns [ 2 ] [ 1 ] ;
sky_push_constant . projection [ 3 ] = p_projection . columns [ 1 ] [ 1 ] ;
2021-06-22 08:24:09 +02:00
sky_push_constant . position [ 0 ] = p_position . x ;
sky_push_constant . position [ 1 ] = p_position . y ;
sky_push_constant . position [ 2 ] = p_position . z ;
sky_push_constant . time = p_time ;
2021-07-26 13:31:15 +02:00
sky_push_constant . luminance_multiplier = p_luminance_multiplier ;
2021-06-22 08:24:09 +02:00
store_transform_3x3 ( p_orientation , sky_push_constant . orientation ) ;
RenderingDevice : : FramebufferFormatID fb_format = RD : : get_singleton ( ) - > framebuffer_get_format ( p_fb ) ;
RD : : DrawListID draw_list = p_list ;
2021-06-26 12:49:25 +02:00
RD : : get_singleton ( ) - > draw_list_bind_render_pipeline ( draw_list , p_pipeline - > get_render_pipeline ( RD : : INVALID_ID , fb_format , false , RD : : get_singleton ( ) - > draw_list_get_current_pass ( ) ) ) ;
2021-06-22 08:24:09 +02:00
2021-08-06 10:17:09 +02:00
// Update uniform sets.
{
RD : : get_singleton ( ) - > draw_list_bind_uniform_set ( draw_list , sky_scene_state . uniform_set , 0 ) ;
2021-08-19 08:10:44 +02:00
if ( p_uniform_set . is_valid ( ) & & RD : : get_singleton ( ) - > uniform_set_is_valid ( p_uniform_set ) ) { // Material may not have a uniform set.
2021-08-06 10:17:09 +02:00
RD : : get_singleton ( ) - > draw_list_bind_uniform_set ( draw_list , p_uniform_set , 1 ) ;
}
RD : : get_singleton ( ) - > draw_list_bind_uniform_set ( draw_list , p_texture_set , 2 ) ;
2021-10-03 13:28:55 +02:00
// Fog uniform set can be invalidated before drawing, so validate at draw time
if ( sky_scene_state . fog_uniform_set . is_valid ( ) & & RD : : get_singleton ( ) - > uniform_set_is_valid ( sky_scene_state . fog_uniform_set ) ) {
RD : : get_singleton ( ) - > draw_list_bind_uniform_set ( draw_list , sky_scene_state . fog_uniform_set , 3 ) ;
} else {
RD : : get_singleton ( ) - > draw_list_bind_uniform_set ( draw_list , sky_scene_state . default_fog_uniform_set , 3 ) ;
}
2021-06-22 08:24:09 +02:00
}
RD : : get_singleton ( ) - > draw_list_bind_index_array ( draw_list , index_array ) ;
RD : : get_singleton ( ) - > draw_list_set_push_constant ( draw_list , & sky_push_constant , sizeof ( SkyPushConstant ) ) ;
RD : : get_singleton ( ) - > draw_list_draw ( draw_list , true ) ;
}
2021-02-13 13:08:08 +01:00
////////////////////////////////////////////////////////////////////////////////
// ReflectionData
2022-07-19 06:17:58 +02:00
void SkyRD : : ReflectionData : : clear_reflection_data ( ) {
2021-02-13 13:08:08 +01:00
layers . clear ( ) ;
radiance_base_cubemap = RID ( ) ;
if ( downsampled_radiance_cubemap . is_valid ( ) ) {
RD : : get_singleton ( ) - > free ( downsampled_radiance_cubemap ) ;
}
downsampled_radiance_cubemap = RID ( ) ;
downsampled_layer . mipmaps . clear ( ) ;
coefficient_buffer = RID ( ) ;
}
2022-07-19 06:17:58 +02:00
void SkyRD : : ReflectionData : : update_reflection_data ( int p_size , int p_mipmaps , bool p_use_array , RID p_base_cube , int p_base_layer , bool p_low_quality , int p_roughness_layers , RD : : DataFormat p_texture_format ) {
2021-02-13 13:08:08 +01:00
//recreate radiance and all data
int mipmaps = p_mipmaps ;
uint32_t w = p_size , h = p_size ;
2023-02-27 04:03:41 +01:00
bool render_buffers_can_be_storage = RendererSceneRenderRD : : get_singleton ( ) - > _render_buffers_can_be_storage ( ) ;
2021-07-27 15:33:47 +02:00
2021-02-13 13:08:08 +01:00
if ( p_use_array ) {
int num_layers = p_low_quality ? 8 : p_roughness_layers ;
for ( int i = 0 ; i < num_layers ; i + + ) {
ReflectionData : : Layer layer ;
uint32_t mmw = w ;
uint32_t mmh = h ;
layer . mipmaps . resize ( mipmaps ) ;
layer . views . resize ( mipmaps ) ;
for ( int j = 0 ; j < mipmaps ; j + + ) {
ReflectionData : : Layer : : Mipmap & mm = layer . mipmaps . write [ j ] ;
mm . size . width = mmw ;
mm . size . height = mmh ;
for ( int k = 0 ; k < 6 ; k + + ) {
mm . views [ k ] = RD : : get_singleton ( ) - > texture_create_shared_from_slice ( RD : : TextureView ( ) , p_base_cube , p_base_layer + i * 6 + k , j ) ;
Vector < RID > fbtex ;
fbtex . push_back ( mm . views [ k ] ) ;
mm . framebuffers [ k ] = RD : : get_singleton ( ) - > framebuffer_create ( fbtex ) ;
}
2021-08-03 09:07:32 +02:00
layer . views . write [ j ] = RD : : get_singleton ( ) - > texture_create_shared_from_slice ( RD : : TextureView ( ) , p_base_cube , p_base_layer + i * 6 , j , 1 , RD : : TEXTURE_SLICE_CUBEMAP ) ;
2021-02-13 13:08:08 +01:00
2022-03-08 15:10:48 +01:00
mmw = MAX ( 1u , mmw > > 1 ) ;
mmh = MAX ( 1u , mmh > > 1 ) ;
2021-02-13 13:08:08 +01:00
}
layers . push_back ( layer ) ;
}
} else {
mipmaps = p_low_quality ? 8 : mipmaps ;
//regular cubemap, lower quality (aliasing, less memory)
ReflectionData : : Layer layer ;
uint32_t mmw = w ;
uint32_t mmh = h ;
layer . mipmaps . resize ( mipmaps ) ;
layer . views . resize ( mipmaps ) ;
for ( int j = 0 ; j < mipmaps ; j + + ) {
ReflectionData : : Layer : : Mipmap & mm = layer . mipmaps . write [ j ] ;
mm . size . width = mmw ;
mm . size . height = mmh ;
for ( int k = 0 ; k < 6 ; k + + ) {
mm . views [ k ] = RD : : get_singleton ( ) - > texture_create_shared_from_slice ( RD : : TextureView ( ) , p_base_cube , p_base_layer + k , j ) ;
Vector < RID > fbtex ;
fbtex . push_back ( mm . views [ k ] ) ;
mm . framebuffers [ k ] = RD : : get_singleton ( ) - > framebuffer_create ( fbtex ) ;
}
2021-08-03 09:07:32 +02:00
layer . views . write [ j ] = RD : : get_singleton ( ) - > texture_create_shared_from_slice ( RD : : TextureView ( ) , p_base_cube , p_base_layer , j , 1 , RD : : TEXTURE_SLICE_CUBEMAP ) ;
2021-02-13 13:08:08 +01:00
2022-03-08 15:10:48 +01:00
mmw = MAX ( 1u , mmw > > 1 ) ;
mmh = MAX ( 1u , mmh > > 1 ) ;
2021-02-13 13:08:08 +01:00
}
layers . push_back ( layer ) ;
}
2021-08-03 09:07:32 +02:00
radiance_base_cubemap = RD : : get_singleton ( ) - > texture_create_shared_from_slice ( RD : : TextureView ( ) , p_base_cube , p_base_layer , 0 , 1 , RD : : TEXTURE_SLICE_CUBEMAP ) ;
2021-07-27 15:33:47 +02:00
RD : : get_singleton ( ) - > set_resource_name ( radiance_base_cubemap , " radiance base cubemap " ) ;
2022-06-23 23:36:29 +02:00
2021-02-13 13:08:08 +01:00
RD : : TextureFormat tf ;
2021-07-27 15:33:47 +02:00
tf . format = p_texture_format ;
2022-06-23 23:36:29 +02:00
tf . width = p_low_quality ? 64 : p_size > > 1 ; // Always 64x64 when using REALTIME.
tf . height = p_low_quality ? 64 : p_size > > 1 ;
2021-02-13 13:08:08 +01:00
tf . texture_type = RD : : TEXTURE_TYPE_CUBE ;
tf . array_layers = 6 ;
2022-06-23 23:36:29 +02:00
tf . mipmaps = p_low_quality ? 7 : mipmaps - 1 ;
2023-01-23 21:38:09 +01:00
tf . usage_bits = RD : : TEXTURE_USAGE_SAMPLING_BIT | RD : : TEXTURE_USAGE_COLOR_ATTACHMENT_BIT ;
2023-02-27 04:03:41 +01:00
if ( render_buffers_can_be_storage ) {
2023-01-23 21:38:09 +01:00
tf . usage_bits | = RD : : TEXTURE_USAGE_STORAGE_BIT ;
}
2021-02-13 13:08:08 +01:00
downsampled_radiance_cubemap = RD : : get_singleton ( ) - > texture_create ( tf , RD : : TextureView ( ) ) ;
2021-07-27 15:33:47 +02:00
RD : : get_singleton ( ) - > set_resource_name ( downsampled_radiance_cubemap , " downsampled radiance cubemap " ) ;
2021-02-13 13:08:08 +01:00
{
2022-06-23 23:36:29 +02:00
uint32_t mmw = tf . width ;
uint32_t mmh = tf . height ;
downsampled_layer . mipmaps . resize ( tf . mipmaps ) ;
2021-02-13 13:08:08 +01:00
for ( int j = 0 ; j < downsampled_layer . mipmaps . size ( ) ; j + + ) {
ReflectionData : : DownsampleLayer : : Mipmap & mm = downsampled_layer . mipmaps . write [ j ] ;
mm . size . width = mmw ;
mm . size . height = mmh ;
2021-08-03 09:07:32 +02:00
mm . view = RD : : get_singleton ( ) - > texture_create_shared_from_slice ( RD : : TextureView ( ) , downsampled_radiance_cubemap , 0 , j , 1 , RD : : TEXTURE_SLICE_CUBEMAP ) ;
2021-07-27 15:33:47 +02:00
RD : : get_singleton ( ) - > set_resource_name ( mm . view , " Downsampled Radiance Cubemap Mip " + itos ( j ) + " " ) ;
2023-04-05 01:43:03 +02:00
if ( ! render_buffers_can_be_storage ) {
2021-07-27 15:33:47 +02:00
// we need a framebuffer for each side of our cubemap
for ( int k = 0 ; k < 6 ; k + + ) {
mm . views [ k ] = RD : : get_singleton ( ) - > texture_create_shared_from_slice ( RD : : TextureView ( ) , downsampled_radiance_cubemap , k , j ) ;
RD : : get_singleton ( ) - > set_resource_name ( mm . view , " Downsampled Radiance Cubemap Mip: " + itos ( j ) + " Face: " + itos ( k ) + " " ) ;
Vector < RID > fbtex ;
fbtex . push_back ( mm . views [ k ] ) ;
mm . framebuffers [ k ] = RD : : get_singleton ( ) - > framebuffer_create ( fbtex ) ;
}
}
2021-02-13 13:08:08 +01:00
2022-03-08 15:10:48 +01:00
mmw = MAX ( 1u , mmw > > 1 ) ;
mmh = MAX ( 1u , mmh > > 1 ) ;
2021-02-13 13:08:08 +01:00
}
}
}
2022-07-19 06:17:58 +02:00
void SkyRD : : ReflectionData : : create_reflection_fast_filter ( bool p_use_arrays ) {
2022-06-17 05:55:23 +02:00
RendererRD : : CopyEffects * copy_effects = RendererRD : : CopyEffects : : get_singleton ( ) ;
2022-11-01 15:29:38 +01:00
ERR_FAIL_NULL_MSG ( copy_effects , " Effects haven't been initialized " ) ;
2022-06-17 05:55:23 +02:00
bool prefer_raster_effects = copy_effects - > get_prefer_raster_effects ( ) ;
2021-07-27 15:33:47 +02:00
if ( prefer_raster_effects ) {
RD : : get_singleton ( ) - > draw_command_begin_label ( " Downsample radiance map " ) ;
for ( int k = 0 ; k < 6 ; k + + ) {
2022-06-17 05:55:23 +02:00
copy_effects - > cubemap_downsample_raster ( radiance_base_cubemap , downsampled_layer . mipmaps [ 0 ] . framebuffers [ k ] , k , downsampled_layer . mipmaps [ 0 ] . size ) ;
2021-07-27 15:33:47 +02:00
}
2021-02-13 13:08:08 +01:00
2021-07-27 15:33:47 +02:00
for ( int i = 1 ; i < downsampled_layer . mipmaps . size ( ) ; i + + ) {
for ( int k = 0 ; k < 6 ; k + + ) {
2022-06-17 05:55:23 +02:00
copy_effects - > cubemap_downsample_raster ( downsampled_layer . mipmaps [ i - 1 ] . view , downsampled_layer . mipmaps [ i ] . framebuffers [ k ] , k , downsampled_layer . mipmaps [ i ] . size ) ;
2021-07-27 15:33:47 +02:00
}
}
RD : : get_singleton ( ) - > draw_command_end_label ( ) ; // Downsample Radiance
2021-02-13 13:08:08 +01:00
2021-07-27 15:33:47 +02:00
if ( p_use_arrays ) {
RD : : get_singleton ( ) - > draw_command_begin_label ( " filter radiance map into array heads " ) ;
for ( int i = 0 ; i < layers . size ( ) ; i + + ) {
for ( int k = 0 ; k < 6 ; k + + ) {
2022-06-17 05:55:23 +02:00
copy_effects - > cubemap_filter_raster ( downsampled_radiance_cubemap , layers [ i ] . mipmaps [ 0 ] . framebuffers [ k ] , k , i ) ;
2021-07-27 15:33:47 +02:00
}
}
} else {
RD : : get_singleton ( ) - > draw_command_begin_label ( " filter radiance map into mipmaps directly " ) ;
for ( int j = 0 ; j < layers [ 0 ] . mipmaps . size ( ) ; j + + ) {
for ( int k = 0 ; k < 6 ; k + + ) {
2022-06-17 05:55:23 +02:00
copy_effects - > cubemap_filter_raster ( downsampled_radiance_cubemap , layers [ 0 ] . mipmaps [ j ] . framebuffers [ k ] , k , j ) ;
2021-07-27 15:33:47 +02:00
}
}
2021-02-13 13:08:08 +01:00
}
2021-07-27 15:33:47 +02:00
RD : : get_singleton ( ) - > draw_command_end_label ( ) ; // Filter radiance
2021-02-13 13:08:08 +01:00
} else {
2022-02-16 09:54:08 +01:00
RD : : get_singleton ( ) - > draw_command_begin_label ( " Downsample radiance map " ) ;
2022-06-17 05:55:23 +02:00
copy_effects - > cubemap_downsample ( radiance_base_cubemap , downsampled_layer . mipmaps [ 0 ] . view , downsampled_layer . mipmaps [ 0 ] . size ) ;
2021-07-27 15:33:47 +02:00
for ( int i = 1 ; i < downsampled_layer . mipmaps . size ( ) ; i + + ) {
2022-06-17 05:55:23 +02:00
copy_effects - > cubemap_downsample ( downsampled_layer . mipmaps [ i - 1 ] . view , downsampled_layer . mipmaps [ i ] . view , downsampled_layer . mipmaps [ i ] . size ) ;
2021-07-27 15:33:47 +02:00
}
2022-02-16 09:54:08 +01:00
RD : : get_singleton ( ) - > draw_command_end_label ( ) ; // Downsample Radiance
2021-07-27 15:33:47 +02:00
Vector < RID > views ;
if ( p_use_arrays ) {
for ( int i = 1 ; i < layers . size ( ) ; i + + ) {
views . push_back ( layers [ i ] . views [ 0 ] ) ;
}
} else {
for ( int i = 1 ; i < layers [ 0 ] . views . size ( ) ; i + + ) {
views . push_back ( layers [ 0 ] . views [ i ] ) ;
}
2021-02-13 13:08:08 +01:00
}
2022-02-16 09:54:08 +01:00
RD : : get_singleton ( ) - > draw_command_begin_label ( " Fast filter radiance " ) ;
2022-06-17 05:55:23 +02:00
copy_effects - > cubemap_filter ( downsampled_radiance_cubemap , views , p_use_arrays ) ;
2022-02-16 09:54:08 +01:00
RD : : get_singleton ( ) - > draw_command_end_label ( ) ; // Filter radiance
2021-07-27 15:33:47 +02:00
}
2021-02-13 13:08:08 +01:00
}
2022-07-19 06:17:58 +02:00
void SkyRD : : ReflectionData : : create_reflection_importance_sample ( bool p_use_arrays , int p_cube_side , int p_base_layer , uint32_t p_sky_ggx_samples_quality ) {
2022-06-17 05:55:23 +02:00
RendererRD : : CopyEffects * copy_effects = RendererRD : : CopyEffects : : get_singleton ( ) ;
2022-11-01 15:29:38 +01:00
ERR_FAIL_NULL_MSG ( copy_effects , " Effects haven't been initialized " ) ;
2022-06-17 05:55:23 +02:00
bool prefer_raster_effects = copy_effects - > get_prefer_raster_effects ( ) ;
2021-07-27 15:33:47 +02:00
if ( prefer_raster_effects ) {
2022-02-16 09:54:08 +01:00
if ( p_base_layer = = 1 ) {
RD : : get_singleton ( ) - > draw_command_begin_label ( " Downsample radiance map " ) ;
for ( int k = 0 ; k < 6 ; k + + ) {
2022-06-17 05:55:23 +02:00
copy_effects - > cubemap_downsample_raster ( radiance_base_cubemap , downsampled_layer . mipmaps [ 0 ] . framebuffers [ k ] , k , downsampled_layer . mipmaps [ 0 ] . size ) ;
2022-02-16 09:54:08 +01:00
}
for ( int i = 1 ; i < downsampled_layer . mipmaps . size ( ) ; i + + ) {
for ( int k = 0 ; k < 6 ; k + + ) {
2022-06-17 05:55:23 +02:00
copy_effects - > cubemap_downsample_raster ( downsampled_layer . mipmaps [ i - 1 ] . view , downsampled_layer . mipmaps [ i ] . framebuffers [ k ] , k , downsampled_layer . mipmaps [ i ] . size ) ;
2022-02-16 09:54:08 +01:00
}
}
RD : : get_singleton ( ) - > draw_command_end_label ( ) ; // Downsample Radiance
}
RD : : get_singleton ( ) - > draw_command_begin_label ( " High Quality filter radiance " ) ;
2021-07-27 15:33:47 +02:00
if ( p_use_arrays ) {
for ( int k = 0 ; k < 6 ; k + + ) {
2022-06-17 05:55:23 +02:00
copy_effects - > cubemap_roughness_raster (
2022-02-16 09:54:08 +01:00
downsampled_radiance_cubemap ,
2021-07-27 15:33:47 +02:00
layers [ p_base_layer ] . mipmaps [ 0 ] . framebuffers [ k ] ,
k ,
p_sky_ggx_samples_quality ,
float ( p_base_layer ) / ( layers . size ( ) - 1.0 ) ,
layers [ p_base_layer ] . mipmaps [ 0 ] . size . x ) ;
}
} else {
for ( int k = 0 ; k < 6 ; k + + ) {
2022-06-17 05:55:23 +02:00
copy_effects - > cubemap_roughness_raster (
2022-02-16 09:54:08 +01:00
downsampled_radiance_cubemap ,
2021-07-27 15:33:47 +02:00
layers [ 0 ] . mipmaps [ p_base_layer ] . framebuffers [ k ] ,
k ,
p_sky_ggx_samples_quality ,
float ( p_base_layer ) / ( layers [ 0 ] . mipmaps . size ( ) - 1.0 ) ,
layers [ 0 ] . mipmaps [ p_base_layer ] . size . x ) ;
}
}
2021-02-13 13:08:08 +01:00
} else {
2022-02-16 09:54:08 +01:00
if ( p_base_layer = = 1 ) {
RD : : get_singleton ( ) - > draw_command_begin_label ( " Downsample radiance map " ) ;
2022-06-17 05:55:23 +02:00
copy_effects - > cubemap_downsample ( radiance_base_cubemap , downsampled_layer . mipmaps [ 0 ] . view , downsampled_layer . mipmaps [ 0 ] . size ) ;
2022-02-16 09:54:08 +01:00
for ( int i = 1 ; i < downsampled_layer . mipmaps . size ( ) ; i + + ) {
2022-06-17 05:55:23 +02:00
copy_effects - > cubemap_downsample ( downsampled_layer . mipmaps [ i - 1 ] . view , downsampled_layer . mipmaps [ i ] . view , downsampled_layer . mipmaps [ i ] . size ) ;
2022-02-16 09:54:08 +01:00
}
RD : : get_singleton ( ) - > draw_command_end_label ( ) ; // Downsample Radiance
}
RD : : get_singleton ( ) - > draw_command_begin_label ( " High Quality filter radiance " ) ;
2021-07-27 15:33:47 +02:00
if ( p_use_arrays ) {
2022-06-17 05:55:23 +02:00
copy_effects - > cubemap_roughness ( downsampled_radiance_cubemap , layers [ p_base_layer ] . views [ 0 ] , p_cube_side , p_sky_ggx_samples_quality , float ( p_base_layer ) / ( layers . size ( ) - 1.0 ) , layers [ p_base_layer ] . mipmaps [ 0 ] . size . x ) ;
2021-07-27 15:33:47 +02:00
} else {
2022-06-17 05:55:23 +02:00
copy_effects - > cubemap_roughness (
2022-02-16 09:54:08 +01:00
downsampled_radiance_cubemap ,
2021-07-27 15:33:47 +02:00
layers [ 0 ] . views [ p_base_layer ] ,
p_cube_side ,
p_sky_ggx_samples_quality ,
float ( p_base_layer ) / ( layers [ 0 ] . mipmaps . size ( ) - 1.0 ) ,
layers [ 0 ] . mipmaps [ p_base_layer ] . size . x ) ;
}
2021-02-13 13:08:08 +01:00
}
2022-02-16 09:54:08 +01:00
RD : : get_singleton ( ) - > draw_command_end_label ( ) ; // Filter radiance
2021-02-13 13:08:08 +01:00
}
2022-07-19 06:17:58 +02:00
void SkyRD : : ReflectionData : : update_reflection_mipmaps ( int p_start , int p_end ) {
2022-06-17 05:55:23 +02:00
RendererRD : : CopyEffects * copy_effects = RendererRD : : CopyEffects : : get_singleton ( ) ;
2022-11-01 15:29:38 +01:00
ERR_FAIL_NULL_MSG ( copy_effects , " Effects haven't been initialized " ) ;
2022-06-17 05:55:23 +02:00
bool prefer_raster_effects = copy_effects - > get_prefer_raster_effects ( ) ;
2021-07-27 15:33:47 +02:00
RD : : get_singleton ( ) - > draw_command_begin_label ( " Update Radiance Cubemap Array Mipmaps " ) ;
2021-02-13 13:08:08 +01:00
for ( int i = p_start ; i < p_end ; i + + ) {
for ( int j = 0 ; j < layers [ i ] . views . size ( ) - 1 ; j + + ) {
RID view = layers [ i ] . views [ j ] ;
Size2i size = layers [ i ] . mipmaps [ j + 1 ] . size ;
2021-07-27 15:33:47 +02:00
if ( prefer_raster_effects ) {
for ( int k = 0 ; k < 6 ; k + + ) {
RID framebuffer = layers [ i ] . mipmaps [ j + 1 ] . framebuffers [ k ] ;
2022-06-17 05:55:23 +02:00
copy_effects - > cubemap_downsample_raster ( view , framebuffer , k , size ) ;
2021-07-27 15:33:47 +02:00
}
} else {
RID texture = layers [ i ] . views [ j + 1 ] ;
2022-06-17 05:55:23 +02:00
copy_effects - > cubemap_downsample ( view , texture , size ) ;
2021-07-27 15:33:47 +02:00
}
2021-02-13 13:08:08 +01:00
}
}
2021-07-27 15:33:47 +02:00
RD : : get_singleton ( ) - > draw_command_end_label ( ) ;
2021-02-13 13:08:08 +01:00
}
////////////////////////////////////////////////////////////////////////////////
2022-07-19 06:17:58 +02:00
// SkyRD::Sky
2021-02-13 13:08:08 +01:00
2022-07-19 06:17:58 +02:00
void SkyRD : : Sky : : free ( ) {
2021-02-13 13:08:08 +01:00
if ( radiance . is_valid ( ) ) {
RD : : get_singleton ( ) - > free ( radiance ) ;
radiance = RID ( ) ;
}
reflection . clear_reflection_data ( ) ;
if ( uniform_buffer . is_valid ( ) ) {
RD : : get_singleton ( ) - > free ( uniform_buffer ) ;
uniform_buffer = RID ( ) ;
}
if ( material . is_valid ( ) ) {
2022-06-21 02:08:33 +02:00
RSG : : material_storage - > material_free ( material ) ;
2021-10-18 13:23:10 +02:00
material = RID ( ) ;
2021-02-13 13:08:08 +01:00
}
}
2022-12-15 12:20:06 +01:00
RID SkyRD : : Sky : : get_textures ( SkyTextureSetVersion p_version , RID p_default_shader_rd , Ref < RenderSceneBuffersRD > p_render_buffers ) {
2022-03-12 12:19:59 +01:00
RendererRD : : TextureStorage * texture_storage = RendererRD : : TextureStorage : : get_singleton ( ) ;
2021-02-13 13:08:08 +01:00
Vector < RD : : Uniform > uniforms ;
{
RD : : Uniform u ;
u . uniform_type = RD : : UNIFORM_TYPE_TEXTURE ;
u . binding = 0 ;
if ( radiance . is_valid ( ) & & p_version < = SKY_TEXTURE_SET_QUARTER_RES ) {
2022-03-06 12:57:09 +01:00
u . append_id ( radiance ) ;
2021-02-13 13:08:08 +01:00
} else {
2022-08-01 03:59:14 +02:00
u . append_id ( texture_storage - > texture_rd_get_default ( RendererRD : : TextureStorage : : DEFAULT_RD_TEXTURE_CUBEMAP_BLACK ) ) ;
2021-02-13 13:08:08 +01:00
}
uniforms . push_back ( u ) ;
}
{
RD : : Uniform u ;
u . uniform_type = RD : : UNIFORM_TYPE_TEXTURE ;
u . binding = 1 ; // half res
2022-12-15 12:20:06 +01:00
if ( p_version > = SKY_TEXTURE_SET_CUBEMAP ) {
2023-01-30 19:36:29 +01:00
if ( reflection . layers . size ( ) & & reflection . layers [ 0 ] . views . size ( ) > = 2 & & reflection . layers [ 0 ] . views [ 1 ] . is_valid ( ) & & p_version ! = SKY_TEXTURE_SET_CUBEMAP_HALF_RES ) {
2022-03-06 12:57:09 +01:00
u . append_id ( reflection . layers [ 0 ] . views [ 1 ] ) ;
2021-02-13 13:08:08 +01:00
} else {
2022-12-15 12:20:06 +01:00
u . append_id ( texture_storage - > texture_rd_get_default ( RendererRD : : TextureStorage : : DEFAULT_RD_TEXTURE_CUBEMAP_BLACK ) ) ;
2021-02-13 13:08:08 +01:00
}
} else {
2022-12-15 12:20:06 +01:00
RID half_texture = p_render_buffers - > has_texture ( RB_SCOPE_SKY , RB_HALF_TEXTURE ) ? p_render_buffers - > get_texture ( RB_SCOPE_SKY , RB_HALF_TEXTURE ) : RID ( ) ;
if ( half_texture . is_valid ( ) & & p_version ! = SKY_TEXTURE_SET_HALF_RES ) {
u . append_id ( half_texture ) ;
2021-02-13 13:08:08 +01:00
} else {
2022-12-15 12:20:06 +01:00
u . append_id ( texture_storage - > texture_rd_get_default ( RendererRD : : TextureStorage : : DEFAULT_RD_TEXTURE_WHITE ) ) ;
2021-02-13 13:08:08 +01:00
}
}
uniforms . push_back ( u ) ;
}
{
RD : : Uniform u ;
u . uniform_type = RD : : UNIFORM_TYPE_TEXTURE ;
u . binding = 2 ; // quarter res
2022-12-15 12:20:06 +01:00
if ( p_version > = SKY_TEXTURE_SET_CUBEMAP ) {
2023-01-30 19:36:29 +01:00
if ( reflection . layers . size ( ) & & reflection . layers [ 0 ] . views . size ( ) > = 3 & & reflection . layers [ 0 ] . views [ 2 ] . is_valid ( ) & & p_version ! = SKY_TEXTURE_SET_CUBEMAP_QUARTER_RES ) {
2022-03-06 12:57:09 +01:00
u . append_id ( reflection . layers [ 0 ] . views [ 2 ] ) ;
2021-02-13 13:08:08 +01:00
} else {
2022-12-15 12:20:06 +01:00
u . append_id ( texture_storage - > texture_rd_get_default ( RendererRD : : TextureStorage : : DEFAULT_RD_TEXTURE_CUBEMAP_BLACK ) ) ;
2021-02-13 13:08:08 +01:00
}
} else {
2022-12-15 12:20:06 +01:00
RID quarter_texture = p_render_buffers - > has_texture ( RB_SCOPE_SKY , RB_QUARTER_TEXTURE ) ? p_render_buffers - > get_texture ( RB_SCOPE_SKY , RB_QUARTER_TEXTURE ) : RID ( ) ;
if ( quarter_texture . is_valid ( ) & & p_version ! = SKY_TEXTURE_SET_QUARTER_RES ) {
u . append_id ( quarter_texture ) ;
2021-02-13 13:08:08 +01:00
} else {
2022-12-15 12:20:06 +01:00
u . append_id ( texture_storage - > texture_rd_get_default ( RendererRD : : TextureStorage : : DEFAULT_RD_TEXTURE_WHITE ) ) ;
2021-02-13 13:08:08 +01:00
}
}
uniforms . push_back ( u ) ;
}
2022-12-15 12:20:06 +01:00
return UniformSetCacheRD : : get_singleton ( ) - > get_cache_vec ( p_default_shader_rd , SKY_SET_TEXTURES , uniforms ) ;
2021-02-13 13:08:08 +01:00
}
2022-07-19 06:17:58 +02:00
bool SkyRD : : Sky : : set_radiance_size ( int p_radiance_size ) {
2021-02-13 13:08:08 +01:00
ERR_FAIL_COND_V ( p_radiance_size < 32 | | p_radiance_size > 2048 , false ) ;
if ( radiance_size = = p_radiance_size ) {
return false ;
}
radiance_size = p_radiance_size ;
if ( mode = = RS : : SKY_MODE_REALTIME & & radiance_size ! = 256 ) {
WARN_PRINT ( " Realtime Skies can only use a radiance size of 256. Radiance size will be set to 256 internally. " ) ;
radiance_size = 256 ;
}
if ( radiance . is_valid ( ) ) {
RD : : get_singleton ( ) - > free ( radiance ) ;
radiance = RID ( ) ;
}
reflection . clear_reflection_data ( ) ;
return true ;
}
2022-07-19 06:17:58 +02:00
bool SkyRD : : Sky : : set_mode ( RS : : SkyMode p_mode ) {
2021-02-13 13:08:08 +01:00
if ( mode = = p_mode ) {
return false ;
}
mode = p_mode ;
if ( mode = = RS : : SKY_MODE_REALTIME & & radiance_size ! = 256 ) {
WARN_PRINT ( " Realtime Skies can only use a radiance size of 256. Radiance size will be set to 256 internally. " ) ;
set_radiance_size ( 256 ) ;
}
if ( radiance . is_valid ( ) ) {
RD : : get_singleton ( ) - > free ( radiance ) ;
radiance = RID ( ) ;
}
reflection . clear_reflection_data ( ) ;
return true ;
}
2022-07-19 06:17:58 +02:00
bool SkyRD : : Sky : : set_material ( RID p_material ) {
2021-02-13 13:08:08 +01:00
if ( material = = p_material ) {
return false ;
}
material = p_material ;
return true ;
}
2022-07-19 06:17:58 +02:00
Ref < Image > SkyRD : : Sky : : bake_panorama ( float p_energy , int p_roughness_layers , const Size2i & p_size ) {
2021-02-13 13:08:08 +01:00
if ( radiance . is_valid ( ) ) {
2022-04-29 09:10:54 +02:00
RendererRD : : CopyEffects * copy_effects = RendererRD : : CopyEffects : : get_singleton ( ) ;
2021-02-13 13:08:08 +01:00
RD : : TextureFormat tf ;
2022-08-01 01:20:24 +02:00
tf . format = RD : : DATA_FORMAT_R32G32B32A32_SFLOAT ; // Could be RGBA16
2021-02-13 13:08:08 +01:00
tf . width = p_size . width ;
tf . height = p_size . height ;
tf . usage_bits = RD : : TEXTURE_USAGE_STORAGE_BIT | RD : : TEXTURE_USAGE_CAN_COPY_FROM_BIT ;
RID rad_tex = RD : : get_singleton ( ) - > texture_create ( tf , RD : : TextureView ( ) ) ;
2022-04-29 09:10:54 +02:00
copy_effects - > copy_cubemap_to_panorama ( radiance , rad_tex , p_size , p_roughness_layers , reflection . layers . size ( ) > 1 ) ;
2021-02-13 13:08:08 +01:00
Vector < uint8_t > data = RD : : get_singleton ( ) - > texture_get_data ( rad_tex , 0 ) ;
RD : : get_singleton ( ) - > free ( rad_tex ) ;
2022-07-22 20:06:19 +02:00
Ref < Image > img = Image : : create_from_data ( p_size . width , p_size . height , false , Image : : FORMAT_RGBAF , data ) ;
2021-02-13 13:08:08 +01:00
for ( int i = 0 ; i < p_size . width ; i + + ) {
for ( int j = 0 ; j < p_size . height ; j + + ) {
Color c = img - > get_pixel ( i , j ) ;
c . r * = p_energy ;
c . g * = p_energy ;
c . b * = p_energy ;
img - > set_pixel ( i , j , c ) ;
}
}
return img ;
}
return Ref < Image > ( ) ;
}
////////////////////////////////////////////////////////////////////////////////
2022-07-19 06:17:58 +02:00
// SkyRD
2021-02-13 13:08:08 +01:00
2022-08-01 03:59:14 +02:00
RendererRD : : MaterialStorage : : ShaderData * SkyRD : : _create_sky_shader_func ( ) {
2021-02-13 13:08:08 +01:00
SkyShaderData * shader_data = memnew ( SkyShaderData ) ;
return shader_data ;
}
2022-08-01 03:59:14 +02:00
RendererRD : : MaterialStorage : : ShaderData * SkyRD : : _create_sky_shader_funcs ( ) {
2021-02-13 13:08:08 +01:00
// !BAS! Why isn't _create_sky_shader_func not just static too?
return static_cast < RendererSceneRenderRD * > ( RendererSceneRenderRD : : singleton ) - > sky . _create_sky_shader_func ( ) ;
} ;
2022-08-01 03:59:14 +02:00
RendererRD : : MaterialStorage : : MaterialData * SkyRD : : _create_sky_material_func ( SkyShaderData * p_shader ) {
2021-02-13 13:08:08 +01:00
SkyMaterialData * material_data = memnew ( SkyMaterialData ) ;
material_data - > shader_data = p_shader ;
//update will happen later anyway so do nothing.
return material_data ;
}
2022-08-01 03:59:14 +02:00
RendererRD : : MaterialStorage : : MaterialData * SkyRD : : _create_sky_material_funcs ( RendererRD : : MaterialStorage : : ShaderData * p_shader ) {
2021-02-13 13:08:08 +01:00
// !BAS! same here, we could just make _create_sky_material_func static?
return static_cast < RendererSceneRenderRD * > ( RendererSceneRenderRD : : singleton ) - > sky . _create_sky_material_func ( static_cast < SkyShaderData * > ( p_shader ) ) ;
} ;
2022-07-19 06:17:58 +02:00
SkyRD : : SkyRD ( ) {
2021-02-13 13:08:08 +01:00
roughness_layers = GLOBAL_GET ( " rendering/reflections/sky_reflections/roughness_layers " ) ;
sky_ggx_samples_quality = GLOBAL_GET ( " rendering/reflections/sky_reflections/ggx_samples " ) ;
sky_use_cubemap_array = GLOBAL_GET ( " rendering/reflections/sky_reflections/texture_array_reflections " ) ;
}
2022-07-19 06:17:58 +02:00
void SkyRD : : init ( ) {
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 ( ) ;
2021-02-13 13:08:08 +01:00
{
// Start with the directional lights for the sky
sky_scene_state . max_directional_lights = 4 ;
uint32_t directional_light_buffer_size = sky_scene_state . max_directional_lights * sizeof ( SkyDirectionalLightData ) ;
sky_scene_state . directional_lights = memnew_arr ( SkyDirectionalLightData , sky_scene_state . max_directional_lights ) ;
sky_scene_state . last_frame_directional_lights = memnew_arr ( SkyDirectionalLightData , sky_scene_state . max_directional_lights ) ;
sky_scene_state . last_frame_directional_light_count = sky_scene_state . max_directional_lights + 1 ;
sky_scene_state . directional_light_buffer = RD : : get_singleton ( ) - > uniform_buffer_create ( directional_light_buffer_size ) ;
String defines = " \n #define MAX_DIRECTIONAL_LIGHT_DATA_STRUCTS " + itos ( sky_scene_state . max_directional_lights ) + " \n " ;
// Initialize sky
Vector < String > sky_modes ;
sky_modes . push_back ( " " ) ; // Full size
sky_modes . push_back ( " \n #define USE_HALF_RES_PASS \n " ) ; // Half Res
sky_modes . push_back ( " \n #define USE_QUARTER_RES_PASS \n " ) ; // Quarter res
sky_modes . push_back ( " \n #define USE_CUBEMAP_PASS \n " ) ; // Cubemap
sky_modes . push_back ( " \n #define USE_CUBEMAP_PASS \n #define USE_HALF_RES_PASS \n " ) ; // Half Res Cubemap
sky_modes . push_back ( " \n #define USE_CUBEMAP_PASS \n #define USE_QUARTER_RES_PASS \n " ) ; // Quarter res Cubemap
2021-05-07 15:19:04 +02:00
sky_modes . push_back ( " \n #define USE_MULTIVIEW \n " ) ; // Full size multiview
sky_modes . push_back ( " \n #define USE_HALF_RES_PASS \n #define USE_MULTIVIEW \n " ) ; // Half Res multiview
sky_modes . push_back ( " \n #define USE_QUARTER_RES_PASS \n #define USE_MULTIVIEW \n " ) ; // Quarter res multiview
2021-02-13 13:08:08 +01:00
sky_shader . shader . initialize ( sky_modes , defines ) ;
2021-05-07 15:19:04 +02:00
2023-01-29 10:14:22 +01:00
if ( ! RendererCompositorRD : : get_singleton ( ) - > is_xr_enabled ( ) ) {
2021-05-07 15:19:04 +02:00
sky_shader . shader . set_variant_enabled ( SKY_VERSION_BACKGROUND_MULTIVIEW , false ) ;
sky_shader . shader . set_variant_enabled ( SKY_VERSION_HALF_RES_MULTIVIEW , false ) ;
sky_shader . shader . set_variant_enabled ( SKY_VERSION_QUARTER_RES_MULTIVIEW , false ) ;
}
2021-02-13 13:08:08 +01:00
}
// register our shader funds
2022-08-01 03:59:14 +02:00
material_storage - > shader_set_data_request_function ( RendererRD : : MaterialStorage : : SHADER_TYPE_SKY , _create_sky_shader_funcs ) ;
material_storage - > material_set_data_request_function ( RendererRD : : MaterialStorage : : SHADER_TYPE_SKY , _create_sky_material_funcs ) ;
2021-02-13 13:08:08 +01:00
{
2021-11-16 16:25:42 +01:00
ShaderCompiler : : DefaultIdentifierActions actions ;
2021-02-13 13:08:08 +01:00
actions . renames [ " COLOR " ] = " color " ;
actions . renames [ " ALPHA " ] = " alpha " ;
actions . renames [ " EYEDIR " ] = " cube_normal " ;
2022-08-01 01:20:24 +02:00
actions . renames [ " POSITION " ] = " params.position " ;
2021-02-13 13:08:08 +01:00
actions . renames [ " SKY_COORDS " ] = " panorama_coords " ;
actions . renames [ " SCREEN_UV " ] = " uv " ;
2022-04-29 21:46:29 +02:00
actions . renames [ " FRAGCOORD " ] = " gl_FragCoord " ;
2021-02-13 13:08:08 +01:00
actions . renames [ " TIME " ] = " params.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 ) ;
2021-02-13 13:08:08 +01:00
actions . renames [ " HALF_RES_COLOR " ] = " half_res_color " ;
actions . renames [ " QUARTER_RES_COLOR " ] = " quarter_res_color " ;
actions . renames [ " RADIANCE " ] = " radiance " ;
actions . renames [ " FOG " ] = " custom_fog " ;
actions . renames [ " LIGHT0_ENABLED " ] = " directional_lights.data[0].enabled " ;
actions . renames [ " LIGHT0_DIRECTION " ] = " directional_lights.data[0].direction_energy.xyz " ;
actions . renames [ " LIGHT0_ENERGY " ] = " directional_lights.data[0].direction_energy.w " ;
actions . renames [ " LIGHT0_COLOR " ] = " directional_lights.data[0].color_size.xyz " ;
actions . renames [ " LIGHT0_SIZE " ] = " directional_lights.data[0].color_size.w " ;
actions . renames [ " LIGHT1_ENABLED " ] = " directional_lights.data[1].enabled " ;
actions . renames [ " LIGHT1_DIRECTION " ] = " directional_lights.data[1].direction_energy.xyz " ;
actions . renames [ " LIGHT1_ENERGY " ] = " directional_lights.data[1].direction_energy.w " ;
actions . renames [ " LIGHT1_COLOR " ] = " directional_lights.data[1].color_size.xyz " ;
actions . renames [ " LIGHT1_SIZE " ] = " directional_lights.data[1].color_size.w " ;
actions . renames [ " LIGHT2_ENABLED " ] = " directional_lights.data[2].enabled " ;
actions . renames [ " LIGHT2_DIRECTION " ] = " directional_lights.data[2].direction_energy.xyz " ;
actions . renames [ " LIGHT2_ENERGY " ] = " directional_lights.data[2].direction_energy.w " ;
actions . renames [ " LIGHT2_COLOR " ] = " directional_lights.data[2].color_size.xyz " ;
actions . renames [ " LIGHT2_SIZE " ] = " directional_lights.data[2].color_size.w " ;
actions . renames [ " LIGHT3_ENABLED " ] = " directional_lights.data[3].enabled " ;
actions . renames [ " LIGHT3_DIRECTION " ] = " directional_lights.data[3].direction_energy.xyz " ;
actions . renames [ " LIGHT3_ENERGY " ] = " directional_lights.data[3].direction_energy.w " ;
actions . renames [ " LIGHT3_COLOR " ] = " directional_lights.data[3].color_size.xyz " ;
actions . renames [ " LIGHT3_SIZE " ] = " directional_lights.data[3].color_size.w " ;
actions . renames [ " AT_CUBEMAP_PASS " ] = " AT_CUBEMAP_PASS " ;
actions . renames [ " AT_HALF_RES_PASS " ] = " AT_HALF_RES_PASS " ;
actions . renames [ " AT_QUARTER_RES_PASS " ] = " AT_QUARTER_RES_PASS " ;
actions . custom_samplers [ " RADIANCE " ] = " material_samplers[3] " ;
actions . usage_defines [ " HALF_RES_COLOR " ] = " \n #define USES_HALF_RES_COLOR \n " ;
actions . usage_defines [ " QUARTER_RES_COLOR " ] = " \n #define USES_QUARTER_RES_COLOR \n " ;
actions . render_mode_defines [ " disable_fog " ] = " #define DISABLE_FOG \n " ;
2022-09-13 19:39:04 +02:00
actions . render_mode_defines [ " use_debanding " ] = " #define USE_DEBANDING \n " ;
2021-02-13 13:08:08 +01:00
actions . sampler_array_name = " material_samplers " ;
actions . base_texture_binding_index = 1 ;
actions . texture_layout_set = 1 ;
actions . base_uniform_string = " material. " ;
actions . base_varying_index = 10 ;
actions . default_filter = ShaderLanguage : : FILTER_LINEAR_MIPMAP ;
actions . default_repeat = ShaderLanguage : : REPEAT_ENABLE ;
2022-04-03 18:56:43 +02:00
actions . global_buffer_array_variable = " global_shader_uniforms.data " ;
2021-02-13 13:08:08 +01:00
sky_shader . compiler . initialize ( actions ) ;
}
{
// default material and shader for sky shader
2022-03-21 12:25:25 +01:00
sky_shader . default_shader = material_storage - > shader_allocate ( ) ;
material_storage - > shader_initialize ( sky_shader . default_shader ) ;
2021-02-13 13:08:08 +01:00
2022-03-21 12:25:25 +01:00
material_storage - > shader_set_code ( sky_shader . default_shader , R " (
2021-08-18 03:09:22 +02:00
// Default sky shader.
2021-07-19 08:06:51 +02:00
shader_type sky ;
void sky ( ) {
COLOR = vec3 ( 0.0 ) ;
}
) " );
2021-02-13 13:08:08 +01:00
2022-03-21 12:25:25 +01:00
sky_shader . default_material = material_storage - > material_allocate ( ) ;
material_storage - > material_initialize ( sky_shader . default_material ) ;
2021-02-13 13:08:08 +01:00
2022-03-21 12:25:25 +01:00
material_storage - > material_set_shader ( sky_shader . default_material , sky_shader . default_shader ) ;
2021-02-13 13:08:08 +01:00
2022-08-01 03:59:14 +02:00
SkyMaterialData * md = static_cast < SkyMaterialData * > ( material_storage - > material_get_data ( sky_shader . default_material , RendererRD : : MaterialStorage : : SHADER_TYPE_SKY ) ) ;
2021-02-13 13:08:08 +01:00
sky_shader . default_shader_rd = sky_shader . shader . version_get_shader ( md - > shader_data - > version , SKY_VERSION_BACKGROUND ) ;
sky_scene_state . uniform_buffer = RD : : get_singleton ( ) - > uniform_buffer_create ( sizeof ( SkySceneState : : UBO ) ) ;
Vector < RD : : Uniform > uniforms ;
{
2022-03-06 12:57:09 +01:00
Vector < RID > ids ;
ids . resize ( 12 ) ;
RID * ids_ptr = ids . ptrw ( ) ;
2022-04-12 13:41:50 +02:00
ids_ptr [ 0 ] = material_storage - > sampler_rd_get_default ( RS : : CANVAS_ITEM_TEXTURE_FILTER_NEAREST , RS : : CANVAS_ITEM_TEXTURE_REPEAT_DISABLED ) ;
ids_ptr [ 1 ] = material_storage - > sampler_rd_get_default ( RS : : CANVAS_ITEM_TEXTURE_FILTER_LINEAR , RS : : CANVAS_ITEM_TEXTURE_REPEAT_DISABLED ) ;
ids_ptr [ 2 ] = material_storage - > sampler_rd_get_default ( RS : : CANVAS_ITEM_TEXTURE_FILTER_NEAREST_WITH_MIPMAPS , RS : : CANVAS_ITEM_TEXTURE_REPEAT_DISABLED ) ;
ids_ptr [ 3 ] = material_storage - > sampler_rd_get_default ( RS : : CANVAS_ITEM_TEXTURE_FILTER_LINEAR_WITH_MIPMAPS , RS : : CANVAS_ITEM_TEXTURE_REPEAT_DISABLED ) ;
ids_ptr [ 4 ] = material_storage - > sampler_rd_get_default ( RS : : CANVAS_ITEM_TEXTURE_FILTER_NEAREST_WITH_MIPMAPS_ANISOTROPIC , RS : : CANVAS_ITEM_TEXTURE_REPEAT_DISABLED ) ;
ids_ptr [ 5 ] = material_storage - > sampler_rd_get_default ( RS : : CANVAS_ITEM_TEXTURE_FILTER_LINEAR_WITH_MIPMAPS_ANISOTROPIC , RS : : CANVAS_ITEM_TEXTURE_REPEAT_DISABLED ) ;
ids_ptr [ 6 ] = material_storage - > sampler_rd_get_default ( RS : : CANVAS_ITEM_TEXTURE_FILTER_NEAREST , RS : : CANVAS_ITEM_TEXTURE_REPEAT_ENABLED ) ;
ids_ptr [ 7 ] = material_storage - > sampler_rd_get_default ( RS : : CANVAS_ITEM_TEXTURE_FILTER_LINEAR , RS : : CANVAS_ITEM_TEXTURE_REPEAT_ENABLED ) ;
ids_ptr [ 8 ] = material_storage - > sampler_rd_get_default ( RS : : CANVAS_ITEM_TEXTURE_FILTER_NEAREST_WITH_MIPMAPS , RS : : CANVAS_ITEM_TEXTURE_REPEAT_ENABLED ) ;
ids_ptr [ 9 ] = material_storage - > sampler_rd_get_default ( RS : : CANVAS_ITEM_TEXTURE_FILTER_LINEAR_WITH_MIPMAPS , RS : : CANVAS_ITEM_TEXTURE_REPEAT_ENABLED ) ;
ids_ptr [ 10 ] = material_storage - > sampler_rd_get_default ( RS : : CANVAS_ITEM_TEXTURE_FILTER_NEAREST_WITH_MIPMAPS_ANISOTROPIC , RS : : CANVAS_ITEM_TEXTURE_REPEAT_ENABLED ) ;
ids_ptr [ 11 ] = material_storage - > 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 , 0 , ids ) ;
2021-02-13 13:08:08 +01:00
uniforms . push_back ( u ) ;
}
{
RD : : Uniform u ;
u . uniform_type = RD : : UNIFORM_TYPE_STORAGE_BUFFER ;
u . binding = 1 ;
2022-04-03 18:56:43 +02:00
u . append_id ( RendererRD : : MaterialStorage : : get_singleton ( ) - > global_shader_uniforms_get_storage_buffer ( ) ) ;
2021-02-13 13:08:08 +01:00
uniforms . push_back ( u ) ;
}
{
RD : : Uniform u ;
u . binding = 2 ;
u . uniform_type = RD : : UNIFORM_TYPE_UNIFORM_BUFFER ;
2022-03-06 12:57:09 +01:00
u . append_id ( sky_scene_state . uniform_buffer ) ;
2021-02-13 13:08:08 +01:00
uniforms . push_back ( u ) ;
}
{
RD : : Uniform u ;
u . binding = 3 ;
u . uniform_type = RD : : UNIFORM_TYPE_UNIFORM_BUFFER ;
2022-03-06 12:57:09 +01:00
u . append_id ( sky_scene_state . directional_light_buffer ) ;
2021-02-13 13:08:08 +01:00
uniforms . push_back ( u ) ;
}
sky_scene_state . uniform_set = RD : : get_singleton ( ) - > uniform_set_create ( uniforms , sky_shader . default_shader_rd , SKY_SET_UNIFORMS ) ;
}
{
Vector < RD : : Uniform > uniforms ;
{
RD : : Uniform u ;
u . binding = 0 ;
u . uniform_type = RD : : UNIFORM_TYPE_TEXTURE ;
2022-08-01 03:59:14 +02:00
RID vfog = texture_storage - > texture_rd_get_default ( RendererRD : : TextureStorage : : DEFAULT_RD_TEXTURE_3D_WHITE ) ;
2022-03-06 12:57:09 +01:00
u . append_id ( vfog ) ;
2021-02-13 13:08:08 +01:00
uniforms . push_back ( u ) ;
}
sky_scene_state . default_fog_uniform_set = RD : : get_singleton ( ) - > uniform_set_create ( uniforms , sky_shader . default_shader_rd , SKY_SET_FOG ) ;
}
{
// Need defaults for using fog with clear color
2022-03-21 12:25:25 +01:00
sky_scene_state . fog_shader = material_storage - > shader_allocate ( ) ;
material_storage - > shader_initialize ( sky_scene_state . fog_shader ) ;
2021-02-13 13:08:08 +01:00
2022-03-21 12:25:25 +01:00
material_storage - > shader_set_code ( sky_scene_state . fog_shader , R " (
2021-08-18 03:09:22 +02:00
// Default clear color sky shader.
2021-07-19 08:06:51 +02:00
shader_type sky ;
uniform vec4 clear_color ;
void sky ( ) {
COLOR = clear_color . rgb ;
}
) " );
2022-03-21 12:25:25 +01:00
sky_scene_state . fog_material = material_storage - > material_allocate ( ) ;
material_storage - > material_initialize ( sky_scene_state . fog_material ) ;
2021-02-13 13:08:08 +01:00
2022-03-21 12:25:25 +01:00
material_storage - > material_set_shader ( sky_scene_state . fog_material , sky_scene_state . fog_shader ) ;
2021-02-13 13:08:08 +01:00
Vector < RD : : Uniform > uniforms ;
{
RD : : Uniform u ;
u . uniform_type = RD : : UNIFORM_TYPE_TEXTURE ;
u . binding = 0 ;
2022-08-01 03:59:14 +02:00
u . append_id ( texture_storage - > texture_rd_get_default ( RendererRD : : TextureStorage : : DEFAULT_RD_TEXTURE_CUBEMAP_BLACK ) ) ;
2021-02-13 13:08:08 +01:00
uniforms . push_back ( u ) ;
}
{
RD : : Uniform u ;
u . uniform_type = RD : : UNIFORM_TYPE_TEXTURE ;
u . binding = 1 ;
2022-08-01 03:59:14 +02:00
u . append_id ( texture_storage - > texture_rd_get_default ( RendererRD : : TextureStorage : : DEFAULT_RD_TEXTURE_WHITE ) ) ;
2021-02-13 13:08:08 +01:00
uniforms . push_back ( u ) ;
}
{
RD : : Uniform u ;
u . uniform_type = RD : : UNIFORM_TYPE_TEXTURE ;
u . binding = 2 ;
2022-08-01 03:59:14 +02:00
u . append_id ( texture_storage - > texture_rd_get_default ( RendererRD : : TextureStorage : : DEFAULT_RD_TEXTURE_WHITE ) ) ;
2021-02-13 13:08:08 +01:00
uniforms . push_back ( u ) ;
}
sky_scene_state . fog_only_texture_uniform_set = RD : : get_singleton ( ) - > uniform_set_create ( uniforms , sky_shader . default_shader_rd , SKY_SET_TEXTURES ) ;
}
2021-06-22 08:24:09 +02:00
{ //create index array for copy shaders
Vector < uint8_t > pv ;
pv . resize ( 6 * 4 ) ;
{
uint8_t * w = pv . ptrw ( ) ;
int * p32 = ( int * ) w ;
p32 [ 0 ] = 0 ;
p32 [ 1 ] = 1 ;
p32 [ 2 ] = 2 ;
p32 [ 3 ] = 0 ;
p32 [ 4 ] = 2 ;
p32 [ 5 ] = 3 ;
}
index_buffer = RD : : get_singleton ( ) - > index_buffer_create ( 6 , RenderingDevice : : INDEX_BUFFER_FORMAT_UINT32 , pv ) ;
index_array = RD : : get_singleton ( ) - > index_array_create ( index_buffer , 0 , 6 ) ;
}
}
2022-07-19 06:17:58 +02:00
void SkyRD : : set_texture_format ( RD : : DataFormat p_texture_format ) {
2021-07-27 15:33:47 +02:00
texture_format = p_texture_format ;
}
2022-07-19 06:17:58 +02:00
SkyRD : : ~ SkyRD ( ) {
2022-03-21 12:25:25 +01:00
// cleanup anything created in init...
RendererRD : : MaterialStorage * material_storage = RendererRD : : MaterialStorage : : get_singleton ( ) ;
2022-08-01 03:59:14 +02:00
SkyMaterialData * md = static_cast < SkyMaterialData * > ( material_storage - > material_get_data ( sky_shader . default_material , RendererRD : : MaterialStorage : : SHADER_TYPE_SKY ) ) ;
2022-03-21 12:25:25 +01:00
sky_shader . shader . version_free ( md - > shader_data - > version ) ;
RD : : get_singleton ( ) - > free ( sky_scene_state . directional_light_buffer ) ;
RD : : get_singleton ( ) - > free ( sky_scene_state . uniform_buffer ) ;
memdelete_arr ( sky_scene_state . directional_lights ) ;
memdelete_arr ( sky_scene_state . last_frame_directional_lights ) ;
material_storage - > shader_free ( sky_shader . default_shader ) ;
material_storage - > material_free ( sky_shader . default_material ) ;
material_storage - > shader_free ( sky_scene_state . fog_shader ) ;
material_storage - > material_free ( sky_scene_state . fog_material ) ;
2021-06-22 08:24:09 +02:00
if ( RD : : get_singleton ( ) - > uniform_set_is_valid ( sky_scene_state . uniform_set ) ) {
RD : : get_singleton ( ) - > free ( sky_scene_state . uniform_set ) ;
}
if ( RD : : get_singleton ( ) - > uniform_set_is_valid ( sky_scene_state . default_fog_uniform_set ) ) {
RD : : get_singleton ( ) - > free ( sky_scene_state . default_fog_uniform_set ) ;
}
if ( RD : : get_singleton ( ) - > uniform_set_is_valid ( sky_scene_state . fog_only_texture_uniform_set ) ) {
RD : : get_singleton ( ) - > free ( sky_scene_state . fog_only_texture_uniform_set ) ;
}
RD : : get_singleton ( ) - > free ( index_buffer ) ; //array gets freed as dependency
2021-02-13 13:08:08 +01:00
}
2023-06-19 14:39:46 +02:00
void SkyRD : : setup_sky ( RID p_env , Ref < RenderSceneBuffersRD > p_render_buffers , const PagedArray < RID > & p_lights , RID p_camera_attributes , uint32_t p_view_count , const Projection * p_view_projections , const Vector3 * p_view_eye_offsets , const Transform3D & p_cam_transform , const Projection & p_cam_projection , const Size2i p_screen_size , RendererSceneRenderRD * p_scene_render ) {
2022-04-09 11:34:31 +02:00
RendererRD : : LightStorage * light_storage = RendererRD : : LightStorage : : get_singleton ( ) ;
2022-03-21 12:25:25 +01:00
RendererRD : : MaterialStorage * material_storage = RendererRD : : MaterialStorage : : get_singleton ( ) ;
2022-07-27 08:14:23 +02:00
ERR_FAIL_COND ( p_env . is_null ( ) ) ;
2021-02-13 13:08:08 +01:00
2022-12-15 12:20:06 +01:00
ERR_FAIL_COND ( p_render_buffers . is_null ( ) ) ;
// make sure we support our view count
ERR_FAIL_COND ( p_view_count = = 0 ) ;
ERR_FAIL_COND ( p_view_count > RendererSceneRender : : MAX_RENDER_VIEWS ) ;
2021-02-13 13:08:08 +01:00
SkyMaterialData * material = nullptr ;
2022-07-27 08:14:23 +02:00
Sky * sky = get_sky ( RendererSceneRenderRD : : get_singleton ( ) - > environment_get_sky ( p_env ) ) ;
2021-02-13 13:08:08 +01:00
RID sky_material ;
SkyShaderData * shader_data = nullptr ;
2021-10-07 06:46:07 +02:00
if ( sky ) {
2022-07-27 08:14:23 +02:00
sky_material = sky_get_material ( RendererSceneRenderRD : : get_singleton ( ) - > environment_get_sky ( p_env ) ) ;
2021-02-13 13:08:08 +01:00
if ( sky_material . is_valid ( ) ) {
2022-08-01 03:59:14 +02:00
material = static_cast < SkyMaterialData * > ( material_storage - > material_get_data ( sky_material , RendererRD : : MaterialStorage : : SHADER_TYPE_SKY ) ) ;
2021-02-13 13:08:08 +01:00
if ( ! material | | ! material - > shader_data - > valid ) {
material = nullptr ;
}
}
if ( ! material ) {
sky_material = sky_shader . default_material ;
2022-08-01 03:59:14 +02:00
material = static_cast < SkyMaterialData * > ( material_storage - > material_get_data ( sky_material , RendererRD : : MaterialStorage : : SHADER_TYPE_SKY ) ) ;
2021-02-13 13:08:08 +01:00
}
ERR_FAIL_COND ( ! material ) ;
shader_data = material - > shader_data ;
ERR_FAIL_COND ( ! shader_data ) ;
2022-12-16 01:07:00 +01:00
material - > set_as_used ( ) ;
2022-12-15 12:20:06 +01:00
// Save our screen size, our buffers will already have been cleared
sky - > screen_size . x = p_screen_size . x < 4 ? 4 : p_screen_size . x ;
sky - > screen_size . y = p_screen_size . y < 4 ? 4 : p_screen_size . y ;
2021-02-13 13:08:08 +01:00
2022-12-15 12:20:06 +01:00
// Trigger updating radiance buffers
if ( sky - > radiance . is_null ( ) ) {
2021-02-13 13:08:08 +01:00
invalidate_sky ( sky ) ;
update_dirty_skys ( ) ;
}
if ( shader_data - > uses_time & & p_scene_render - > time - sky - > prev_time > 0.00001 ) {
sky - > prev_time = p_scene_render - > time ;
sky - > reflection . dirty = true ;
RenderingServerDefault : : redraw_request ( ) ;
}
if ( material ! = sky - > prev_material ) {
sky - > prev_material = material ;
sky - > reflection . dirty = true ;
}
if ( material - > uniform_set_updated ) {
material - > uniform_set_updated = false ;
sky - > reflection . dirty = true ;
}
2022-12-15 12:20:06 +01:00
if ( ! p_cam_transform . origin . is_equal_approx ( sky - > prev_position ) & & shader_data - > uses_position ) {
sky - > prev_position = p_cam_transform . origin ;
2021-02-13 13:08:08 +01:00
sky - > reflection . dirty = true ;
}
2023-01-16 22:05:52 +01:00
sky_scene_state . ubo . directional_light_count = 0 ;
2021-02-13 13:08:08 +01:00
if ( shader_data - > uses_light ) {
2022-01-24 00:06:49 +01:00
// Run through the list of lights in the scene and pick out the Directional Lights.
// This can't be done in RenderSceneRenderRD::_setup lights because that needs to be called
// after the depth prepass, but this runs before the depth prepass
for ( int i = 0 ; i < ( int ) p_lights . size ( ) ; i + + ) {
2022-09-12 11:44:48 +02:00
if ( ! light_storage - > owns_light_instance ( p_lights [ i ] ) ) {
2022-01-24 00:06:49 +01:00
continue ;
}
2022-09-12 11:44:48 +02:00
RID base = light_storage - > light_instance_get_base_light ( p_lights [ i ] ) ;
2022-01-24 00:06:49 +01:00
ERR_CONTINUE ( base . is_null ( ) ) ;
2022-04-09 11:34:31 +02:00
RS : : LightType type = light_storage - > light_get_type ( base ) ;
if ( type = = RS : : LIGHT_DIRECTIONAL & & light_storage - > light_directional_get_sky_mode ( base ) ! = RS : : LIGHT_DIRECTIONAL_SKY_MODE_LIGHT_ONLY ) {
2022-01-24 00:06:49 +01:00
SkyDirectionalLightData & sky_light_data = sky_scene_state . directional_lights [ sky_scene_state . ubo . directional_light_count ] ;
2022-09-12 11:44:48 +02:00
Transform3D light_transform = light_storage - > light_instance_get_base_transform ( p_lights [ i ] ) ;
2022-01-24 00:06:49 +01:00
Vector3 world_direction = light_transform . basis . xform ( Vector3 ( 0 , 0 , 1 ) ) . normalized ( ) ;
sky_light_data . direction [ 0 ] = world_direction . x ;
sky_light_data . direction [ 1 ] = world_direction . y ;
2022-03-07 08:54:21 +01:00
sky_light_data . direction [ 2 ] = world_direction . z ;
2022-01-24 00:06:49 +01:00
2022-04-09 11:34:31 +02:00
float sign = light_storage - > light_is_negative ( base ) ? - 1 : 1 ;
sky_light_data . energy = sign * light_storage - > light_get_param ( base , RS : : LIGHT_PARAM_ENERGY ) ;
2022-01-24 00:06:49 +01:00
2022-08-01 01:20:24 +02:00
if ( p_scene_render - > is_using_physical_light_units ( ) ) {
sky_light_data . energy * = light_storage - > light_get_param ( base , RS : : LIGHT_PARAM_INTENSITY ) ;
}
if ( p_camera_attributes . is_valid ( ) ) {
sky_light_data . energy * = RSG : : camera_attributes - > camera_attributes_get_exposure_normalization_factor ( p_camera_attributes ) ;
}
2022-04-09 11:34:31 +02:00
Color linear_col = light_storage - > light_get_color ( base ) . srgb_to_linear ( ) ;
2022-01-24 00:06:49 +01:00
sky_light_data . color [ 0 ] = linear_col . r ;
sky_light_data . color [ 1 ] = linear_col . g ;
sky_light_data . color [ 2 ] = linear_col . b ;
sky_light_data . enabled = true ;
2022-04-09 11:34:31 +02:00
float angular_diameter = light_storage - > light_get_param ( base , RS : : LIGHT_PARAM_SIZE ) ;
2022-01-24 00:06:49 +01:00
if ( angular_diameter > 0.0 ) {
// I know tan(0) is 0, but let's not risk it with numerical precision.
// technically this will keep expanding until reaching the sun, but all we care
// is expand until we reach the radius of the near plane (there can't be more occluders than that)
2022-08-13 17:45:42 +02:00
angular_diameter = Math : : tan ( Math : : deg_to_rad ( angular_diameter ) ) ;
2022-01-24 00:06:49 +01:00
} else {
angular_diameter = 0.0 ;
}
sky_light_data . size = angular_diameter ;
sky_scene_state . ubo . directional_light_count + + ;
if ( sky_scene_state . ubo . directional_light_count > = sky_scene_state . max_directional_lights ) {
break ;
}
}
}
2021-02-13 13:08:08 +01:00
// Check whether the directional_light_buffer changes
2022-02-10 20:21:28 +01:00
bool light_data_dirty = false ;
2021-02-13 13:08:08 +01:00
2022-01-24 00:06:49 +01:00
// Light buffer is dirty if we have fewer or more lights
// If we have fewer lights, make sure that old lights are disabled
2021-02-13 13:08:08 +01:00
if ( sky_scene_state . ubo . directional_light_count ! = sky_scene_state . last_frame_directional_light_count ) {
light_data_dirty = true ;
for ( uint32_t i = sky_scene_state . ubo . directional_light_count ; i < sky_scene_state . max_directional_lights ; i + + ) {
sky_scene_state . directional_lights [ i ] . enabled = false ;
2022-09-14 17:30:35 +02:00
sky_scene_state . last_frame_directional_lights [ i ] . enabled = false ;
2021-02-13 13:08:08 +01:00
}
}
2022-01-24 00:06:49 +01:00
2021-02-13 13:08:08 +01:00
if ( ! light_data_dirty ) {
for ( uint32_t i = 0 ; i < sky_scene_state . ubo . directional_light_count ; i + + ) {
if ( sky_scene_state . directional_lights [ i ] . direction [ 0 ] ! = sky_scene_state . last_frame_directional_lights [ i ] . direction [ 0 ] | |
sky_scene_state . directional_lights [ i ] . direction [ 1 ] ! = sky_scene_state . last_frame_directional_lights [ i ] . direction [ 1 ] | |
sky_scene_state . directional_lights [ i ] . direction [ 2 ] ! = sky_scene_state . last_frame_directional_lights [ i ] . direction [ 2 ] | |
sky_scene_state . directional_lights [ i ] . energy ! = sky_scene_state . last_frame_directional_lights [ i ] . energy | |
sky_scene_state . directional_lights [ i ] . color [ 0 ] ! = sky_scene_state . last_frame_directional_lights [ i ] . color [ 0 ] | |
sky_scene_state . directional_lights [ i ] . color [ 1 ] ! = sky_scene_state . last_frame_directional_lights [ i ] . color [ 1 ] | |
sky_scene_state . directional_lights [ i ] . color [ 2 ] ! = sky_scene_state . last_frame_directional_lights [ i ] . color [ 2 ] | |
sky_scene_state . directional_lights [ i ] . enabled ! = sky_scene_state . last_frame_directional_lights [ i ] . enabled | |
sky_scene_state . directional_lights [ i ] . size ! = sky_scene_state . last_frame_directional_lights [ i ] . size ) {
light_data_dirty = true ;
break ;
}
}
}
if ( light_data_dirty ) {
RD : : get_singleton ( ) - > buffer_update ( sky_scene_state . directional_light_buffer , 0 , sizeof ( SkyDirectionalLightData ) * sky_scene_state . max_directional_lights , sky_scene_state . directional_lights ) ;
SkyDirectionalLightData * temp = sky_scene_state . last_frame_directional_lights ;
sky_scene_state . last_frame_directional_lights = sky_scene_state . directional_lights ;
sky_scene_state . directional_lights = temp ;
sky_scene_state . last_frame_directional_light_count = sky_scene_state . ubo . directional_light_count ;
sky - > reflection . dirty = true ;
}
}
}
//setup fog variables
sky_scene_state . ubo . volumetric_fog_enabled = false ;
if ( p_render_buffers . is_valid ( ) ) {
2022-08-04 10:40:39 +02:00
if ( p_render_buffers - > has_custom_data ( RB_SCOPE_FOG ) ) {
Ref < RendererRD : : Fog : : VolumetricFog > fog = p_render_buffers - > get_custom_data ( RB_SCOPE_FOG ) ;
2021-02-13 13:08:08 +01:00
sky_scene_state . ubo . volumetric_fog_enabled = true ;
2022-08-04 10:40:39 +02:00
float fog_end = fog - > length ;
2021-02-13 13:08:08 +01:00
if ( fog_end > 0.0 ) {
sky_scene_state . ubo . volumetric_fog_inv_length = 1.0 / fog_end ;
} else {
sky_scene_state . ubo . volumetric_fog_inv_length = 1.0 ;
}
2022-08-04 10:40:39 +02:00
float fog_detail_spread = fog - > spread ; //reverse lookup
2021-02-13 13:08:08 +01:00
if ( fog_detail_spread > 0.0 ) {
sky_scene_state . ubo . volumetric_fog_detail_spread = 1.0 / fog_detail_spread ;
} else {
sky_scene_state . ubo . volumetric_fog_detail_spread = 1.0 ;
}
2022-08-04 10:40:39 +02:00
sky_scene_state . fog_uniform_set = fog - > sky_uniform_set ;
2021-02-13 13:08:08 +01:00
}
}
2022-12-15 12:20:06 +01:00
sky_scene_state . view_count = p_view_count ;
sky_scene_state . cam_transform = p_cam_transform ;
2023-06-19 14:39:46 +02:00
sky_scene_state . cam_projection = p_cam_projection ; // We only use this when rendering a single view
2022-12-15 12:20:06 +01:00
// Our info in our UBO is only used if we're rendering stereo
for ( uint32_t i = 0 ; i < p_view_count ; i + + ) {
2023-06-19 14:39:46 +02:00
Projection view_inv_projection = p_view_projections [ i ] . inverse ( ) ;
if ( p_view_count > 1 ) {
RendererRD : : MaterialStorage : : store_camera ( p_cam_projection * view_inv_projection , sky_scene_state . ubo . combined_reprojection [ i ] ) ;
} else {
Projection ident ;
RendererRD : : MaterialStorage : : store_camera ( ident , sky_scene_state . ubo . combined_reprojection [ i ] ) ;
}
RendererRD : : MaterialStorage : : store_camera ( view_inv_projection , sky_scene_state . ubo . view_inv_projections [ i ] ) ;
2022-12-15 12:20:06 +01:00
sky_scene_state . ubo . view_eye_offsets [ i ] [ 0 ] = p_view_eye_offsets [ i ] . x ;
sky_scene_state . ubo . view_eye_offsets [ i ] [ 1 ] = p_view_eye_offsets [ i ] . y ;
sky_scene_state . ubo . view_eye_offsets [ i ] [ 2 ] = p_view_eye_offsets [ i ] . z ;
sky_scene_state . ubo . view_eye_offsets [ i ] [ 3 ] = 0.0 ;
}
sky_scene_state . ubo . z_far = p_view_projections [ 0 ] . get_z_far ( ) ; // Should be the same for all projection
2022-07-27 08:14:23 +02:00
sky_scene_state . ubo . fog_enabled = RendererSceneRenderRD : : get_singleton ( ) - > environment_get_fog_enabled ( p_env ) ;
sky_scene_state . ubo . fog_density = RendererSceneRenderRD : : get_singleton ( ) - > environment_get_fog_density ( p_env ) ;
sky_scene_state . ubo . fog_aerial_perspective = RendererSceneRenderRD : : get_singleton ( ) - > environment_get_fog_aerial_perspective ( p_env ) ;
Color fog_color = RendererSceneRenderRD : : get_singleton ( ) - > environment_get_fog_light_color ( p_env ) . srgb_to_linear ( ) ;
float fog_energy = RendererSceneRenderRD : : get_singleton ( ) - > environment_get_fog_light_energy ( p_env ) ;
2021-02-13 13:08:08 +01:00
sky_scene_state . ubo . fog_light_color [ 0 ] = fog_color . r * fog_energy ;
sky_scene_state . ubo . fog_light_color [ 1 ] = fog_color . g * fog_energy ;
sky_scene_state . ubo . fog_light_color [ 2 ] = fog_color . b * fog_energy ;
2022-07-27 08:14:23 +02:00
sky_scene_state . ubo . fog_sun_scatter = RendererSceneRenderRD : : get_singleton ( ) - > environment_get_fog_sun_scatter ( p_env ) ;
2021-02-13 13:08:08 +01:00
2022-02-23 23:54:06 +01:00
sky_scene_state . ubo . fog_sky_affect = RendererSceneRenderRD : : get_singleton ( ) - > environment_get_fog_sky_affect ( p_env ) ;
sky_scene_state . ubo . volumetric_fog_sky_affect = RendererSceneRenderRD : : get_singleton ( ) - > environment_get_volumetric_fog_sky_affect ( p_env ) ;
2021-02-13 13:08:08 +01:00
RD : : get_singleton ( ) - > buffer_update ( sky_scene_state . uniform_buffer , 0 , sizeof ( SkySceneState : : UBO ) , & sky_scene_state . ubo ) ;
}
2022-12-15 12:20:06 +01:00
void SkyRD : : update_radiance_buffers ( Ref < RenderSceneBuffersRD > p_render_buffers , RID p_env , const Vector3 & p_global_pos , double p_time , float p_luminance_multiplier ) {
ERR_FAIL_COND ( p_render_buffers . is_null ( ) ) ;
2022-03-21 12:25:25 +01:00
RendererRD : : MaterialStorage * material_storage = RendererRD : : MaterialStorage : : get_singleton ( ) ;
2022-07-27 08:14:23 +02:00
ERR_FAIL_COND ( p_env . is_null ( ) ) ;
2021-02-13 13:08:08 +01:00
2022-07-27 08:14:23 +02:00
Sky * sky = get_sky ( RendererSceneRenderRD : : get_singleton ( ) - > environment_get_sky ( p_env ) ) ;
2021-02-13 13:08:08 +01:00
ERR_FAIL_COND ( ! sky ) ;
2022-07-27 08:14:23 +02:00
RID sky_material = sky_get_material ( RendererSceneRenderRD : : get_singleton ( ) - > environment_get_sky ( p_env ) ) ;
2021-02-13 13:08:08 +01:00
SkyMaterialData * material = nullptr ;
if ( sky_material . is_valid ( ) ) {
2022-08-01 03:59:14 +02:00
material = static_cast < SkyMaterialData * > ( material_storage - > material_get_data ( sky_material , RendererRD : : MaterialStorage : : SHADER_TYPE_SKY ) ) ;
2021-02-13 13:08:08 +01:00
if ( ! material | | ! material - > shader_data - > valid ) {
material = nullptr ;
}
}
if ( ! material ) {
sky_material = sky_shader . default_material ;
2022-08-01 03:59:14 +02:00
material = static_cast < SkyMaterialData * > ( material_storage - > material_get_data ( sky_material , RendererRD : : MaterialStorage : : SHADER_TYPE_SKY ) ) ;
2021-02-13 13:08:08 +01:00
}
ERR_FAIL_COND ( ! material ) ;
SkyShaderData * shader_data = material - > shader_data ;
ERR_FAIL_COND ( ! shader_data ) ;
bool update_single_frame = sky - > mode = = RS : : SKY_MODE_REALTIME | | sky - > mode = = RS : : SKY_MODE_QUALITY ;
RS : : SkyMode sky_mode = sky - > mode ;
if ( sky_mode = = RS : : SKY_MODE_AUTOMATIC ) {
if ( shader_data - > uses_time | | shader_data - > uses_position ) {
update_single_frame = true ;
sky_mode = RS : : SKY_MODE_REALTIME ;
} else if ( shader_data - > uses_light | | shader_data - > ubo_size > 0 ) {
update_single_frame = false ;
sky_mode = RS : : SKY_MODE_INCREMENTAL ;
} else {
update_single_frame = true ;
sky_mode = RS : : SKY_MODE_QUALITY ;
}
}
if ( sky - > processing_layer = = 0 & & sky_mode = = RS : : SKY_MODE_INCREMENTAL ) {
// On the first frame after creating sky, rebuild in single frame
update_single_frame = true ;
sky_mode = RS : : SKY_MODE_QUALITY ;
}
int max_processing_layer = sky_use_cubemap_array ? sky - > reflection . layers . size ( ) : sky - > reflection . layers [ 0 ] . mipmaps . size ( ) ;
// Update radiance cubemap
if ( sky - > reflection . dirty & & ( sky - > processing_layer > = max_processing_layer | | update_single_frame ) ) {
static const Vector3 view_normals [ 6 ] = {
Vector3 ( + 1 , 0 , 0 ) ,
Vector3 ( - 1 , 0 , 0 ) ,
Vector3 ( 0 , + 1 , 0 ) ,
Vector3 ( 0 , - 1 , 0 ) ,
Vector3 ( 0 , 0 , + 1 ) ,
Vector3 ( 0 , 0 , - 1 )
} ;
static const Vector3 view_up [ 6 ] = {
Vector3 ( 0 , - 1 , 0 ) ,
Vector3 ( 0 , - 1 , 0 ) ,
Vector3 ( 0 , 0 , + 1 ) ,
Vector3 ( 0 , 0 , - 1 ) ,
Vector3 ( 0 , - 1 , 0 ) ,
Vector3 ( 0 , - 1 , 0 )
} ;
Implement Vector4, Vector4i, Projection
Implement built-in classes Vector4, Vector4i and Projection.
* Two versions of Vector4 (float and integer).
* A Projection class, which is a 4x4 matrix specialized in projection types.
These types have been requested for a long time, but given they were very corner case they were not added before.
Because in Godot 4, reimplementing parts of the rendering engine is now possible, access to these types (heavily used by the rendering code) becomes a necessity.
**Q**: Why Projection and not Matrix4?
**A**: Godot does not use Matrix2, Matrix3, Matrix4x3, etc. naming convention because, within the engine, these types always have a *purpose*. As such, Godot names them: Transform2D, Transform3D or Basis. In this case, this 4x4 matrix is _always_ used as a _Projection_, hence the naming.
2022-07-20 01:11:13 +02:00
Projection cm ;
2021-02-13 13:08:08 +01:00
cm . set_perspective ( 90 , 1 , 0.01 , 10.0 ) ;
Implement Vector4, Vector4i, Projection
Implement built-in classes Vector4, Vector4i and Projection.
* Two versions of Vector4 (float and integer).
* A Projection class, which is a 4x4 matrix specialized in projection types.
These types have been requested for a long time, but given they were very corner case they were not added before.
Because in Godot 4, reimplementing parts of the rendering engine is now possible, access to these types (heavily used by the rendering code) becomes a necessity.
**Q**: Why Projection and not Matrix4?
**A**: Godot does not use Matrix2, Matrix3, Matrix4x3, etc. naming convention because, within the engine, these types always have a *purpose*. As such, Godot names them: Transform2D, Transform3D or Basis. In this case, this 4x4 matrix is _always_ used as a _Projection_, hence the naming.
2022-07-20 01:11:13 +02:00
Projection correction ;
2021-02-13 13:08:08 +01:00
correction . set_depth_correction ( true ) ;
cm = correction * cm ;
2022-12-15 12:20:06 +01:00
// Note, we ignore environment_get_sky_orientation here as this is applied when we do our lookup in our scene shader.
2023-01-30 19:36:29 +01:00
if ( shader_data - > uses_quarter_res & & roughness_layers > = 3 ) {
2021-07-27 15:33:47 +02:00
RD : : get_singleton ( ) - > draw_command_begin_label ( " Render Sky to Quarter Res Cubemap " ) ;
2021-02-13 13:08:08 +01:00
PipelineCacheRD * pipeline = & shader_data - > pipelines [ SKY_VERSION_CUBEMAP_QUARTER_RES ] ;
Vector < Color > clear_colors ;
clear_colors . push_back ( Color ( 0.0 , 0.0 , 0.0 ) ) ;
RD : : DrawListID cubemap_draw_list ;
for ( int i = 0 ; i < 6 ; i + + ) {
2021-07-21 05:32:00 +02:00
Basis local_view = Basis : : looking_at ( view_normals [ i ] , view_up [ i ] ) ;
2022-12-15 12:20:06 +01:00
RID texture_uniform_set = sky - > get_textures ( SKY_TEXTURE_SET_CUBEMAP_QUARTER_RES , sky_shader . default_shader_rd , p_render_buffers ) ;
2021-02-13 13:08:08 +01:00
cubemap_draw_list = RD : : get_singleton ( ) - > draw_list_begin ( sky - > reflection . layers [ 0 ] . mipmaps [ 2 ] . framebuffers [ i ] , RD : : INITIAL_ACTION_KEEP , RD : : FINAL_ACTION_READ , RD : : INITIAL_ACTION_KEEP , RD : : FINAL_ACTION_DISCARD ) ;
2022-12-15 12:20:06 +01:00
_render_sky ( cubemap_draw_list , p_time , sky - > reflection . layers [ 0 ] . mipmaps [ 2 ] . framebuffers [ i ] , pipeline , material - > uniform_set , texture_uniform_set , cm , local_view , p_global_pos , p_luminance_multiplier ) ;
2021-02-13 13:08:08 +01:00
RD : : get_singleton ( ) - > draw_list_end ( ) ;
}
2021-07-27 15:33:47 +02:00
RD : : get_singleton ( ) - > draw_command_end_label ( ) ;
2023-01-30 19:36:29 +01:00
} else if ( shader_data - > uses_quarter_res & & roughness_layers < 3 ) {
ERR_PRINT_ED ( " Cannot use quarter res buffer in sky shader when roughness layers is less than 3. Please increase rendering/reflections/sky_reflections/roughness_layers. " ) ;
2021-02-13 13:08:08 +01:00
}
2023-01-30 19:36:29 +01:00
if ( shader_data - > uses_half_res & & roughness_layers > = 2 ) {
2021-07-27 15:33:47 +02:00
RD : : get_singleton ( ) - > draw_command_begin_label ( " Render Sky to Half Res Cubemap " ) ;
2021-02-13 13:08:08 +01:00
PipelineCacheRD * pipeline = & shader_data - > pipelines [ SKY_VERSION_CUBEMAP_HALF_RES ] ;
Vector < Color > clear_colors ;
clear_colors . push_back ( Color ( 0.0 , 0.0 , 0.0 ) ) ;
RD : : DrawListID cubemap_draw_list ;
for ( int i = 0 ; i < 6 ; i + + ) {
2021-07-21 05:32:00 +02:00
Basis local_view = Basis : : looking_at ( view_normals [ i ] , view_up [ i ] ) ;
2022-12-15 12:20:06 +01:00
RID texture_uniform_set = sky - > get_textures ( SKY_TEXTURE_SET_CUBEMAP_HALF_RES , sky_shader . default_shader_rd , p_render_buffers ) ;
2021-02-13 13:08:08 +01:00
cubemap_draw_list = RD : : get_singleton ( ) - > draw_list_begin ( sky - > reflection . layers [ 0 ] . mipmaps [ 1 ] . framebuffers [ i ] , RD : : INITIAL_ACTION_KEEP , RD : : FINAL_ACTION_READ , RD : : INITIAL_ACTION_KEEP , RD : : FINAL_ACTION_DISCARD ) ;
2022-12-15 12:20:06 +01:00
_render_sky ( cubemap_draw_list , p_time , sky - > reflection . layers [ 0 ] . mipmaps [ 1 ] . framebuffers [ i ] , pipeline , material - > uniform_set , texture_uniform_set , cm , local_view , p_global_pos , p_luminance_multiplier ) ;
2021-02-13 13:08:08 +01:00
RD : : get_singleton ( ) - > draw_list_end ( ) ;
}
2021-07-27 15:33:47 +02:00
RD : : get_singleton ( ) - > draw_command_end_label ( ) ;
2023-01-30 19:36:29 +01:00
} else if ( shader_data - > uses_half_res & & roughness_layers < 2 ) {
ERR_PRINT_ED ( " Cannot use half res buffer in sky shader when roughness layers is less than 2. Please increase rendering/reflections/sky_reflections/roughness_layers. " ) ;
2021-02-13 13:08:08 +01:00
}
RD : : DrawListID cubemap_draw_list ;
PipelineCacheRD * pipeline = & shader_data - > pipelines [ SKY_VERSION_CUBEMAP ] ;
2021-07-27 15:33:47 +02:00
RD : : get_singleton ( ) - > draw_command_begin_label ( " Render Sky Cubemap " ) ;
2021-02-13 13:08:08 +01:00
for ( int i = 0 ; i < 6 ; i + + ) {
2021-07-21 05:32:00 +02:00
Basis local_view = Basis : : looking_at ( view_normals [ i ] , view_up [ i ] ) ;
2022-12-15 12:20:06 +01:00
RID texture_uniform_set = sky - > get_textures ( SKY_TEXTURE_SET_CUBEMAP , sky_shader . default_shader_rd , p_render_buffers ) ;
2021-02-13 13:08:08 +01:00
cubemap_draw_list = RD : : get_singleton ( ) - > draw_list_begin ( sky - > reflection . layers [ 0 ] . mipmaps [ 0 ] . framebuffers [ i ] , RD : : INITIAL_ACTION_KEEP , RD : : FINAL_ACTION_READ , RD : : INITIAL_ACTION_KEEP , RD : : FINAL_ACTION_DISCARD ) ;
2022-12-15 12:20:06 +01:00
_render_sky ( cubemap_draw_list , p_time , sky - > reflection . layers [ 0 ] . mipmaps [ 0 ] . framebuffers [ i ] , pipeline , material - > uniform_set , texture_uniform_set , cm , local_view , p_global_pos , p_luminance_multiplier ) ;
2021-02-13 13:08:08 +01:00
RD : : get_singleton ( ) - > draw_list_end ( ) ;
}
2021-07-27 15:33:47 +02:00
RD : : get_singleton ( ) - > draw_command_end_label ( ) ;
2021-02-13 13:08:08 +01:00
if ( sky_mode = = RS : : SKY_MODE_REALTIME ) {
2022-06-21 02:08:33 +02:00
sky - > reflection . create_reflection_fast_filter ( sky_use_cubemap_array ) ;
2021-02-13 13:08:08 +01:00
if ( sky_use_cubemap_array ) {
2022-06-21 02:08:33 +02:00
sky - > reflection . update_reflection_mipmaps ( 0 , sky - > reflection . layers . size ( ) ) ;
2021-02-13 13:08:08 +01:00
}
} else {
if ( update_single_frame ) {
for ( int i = 1 ; i < max_processing_layer ; i + + ) {
2022-06-21 02:08:33 +02:00
sky - > reflection . create_reflection_importance_sample ( sky_use_cubemap_array , 10 , i , sky_ggx_samples_quality ) ;
2021-02-13 13:08:08 +01:00
}
if ( sky_use_cubemap_array ) {
2022-06-21 02:08:33 +02:00
sky - > reflection . update_reflection_mipmaps ( 0 , sky - > reflection . layers . size ( ) ) ;
2021-02-13 13:08:08 +01:00
}
} else {
if ( sky_use_cubemap_array ) {
// Multi-Frame so just update the first array level
2022-06-21 02:08:33 +02:00
sky - > reflection . update_reflection_mipmaps ( 0 , 1 ) ;
2021-02-13 13:08:08 +01:00
}
}
sky - > processing_layer = 1 ;
}
2022-08-01 01:20:24 +02:00
sky - > baked_exposure = p_luminance_multiplier ;
2021-02-13 13:08:08 +01:00
sky - > reflection . dirty = false ;
} else {
if ( sky_mode = = RS : : SKY_MODE_INCREMENTAL & & sky - > processing_layer < max_processing_layer ) {
2022-06-21 02:08:33 +02:00
sky - > reflection . create_reflection_importance_sample ( sky_use_cubemap_array , 10 , sky - > processing_layer , sky_ggx_samples_quality ) ;
2021-02-13 13:08:08 +01:00
if ( sky_use_cubemap_array ) {
2022-06-21 02:08:33 +02:00
sky - > reflection . update_reflection_mipmaps ( sky - > processing_layer , sky - > processing_layer + 1 ) ;
2021-02-13 13:08:08 +01:00
}
sky - > processing_layer + + ;
}
}
}
2022-12-15 12:20:06 +01:00
void SkyRD : : update_res_buffers ( Ref < RenderSceneBuffersRD > p_render_buffers , RID p_env , double p_time , float p_luminance_multiplier ) {
ERR_FAIL_COND ( p_render_buffers . is_null ( ) ) ;
2022-03-21 12:25:25 +01:00
RendererRD : : MaterialStorage * material_storage = RendererRD : : MaterialStorage : : get_singleton ( ) ;
2022-07-27 08:14:23 +02:00
ERR_FAIL_COND ( p_env . is_null ( ) ) ;
2021-02-13 13:08:08 +01:00
2022-07-27 08:14:23 +02:00
Sky * sky = get_sky ( RendererSceneRenderRD : : get_singleton ( ) - > environment_get_sky ( p_env ) ) ;
2021-02-13 13:08:08 +01:00
SkyMaterialData * material = nullptr ;
RID sky_material ;
2022-07-27 08:14:23 +02:00
RS : : EnvironmentBG background = RendererSceneRenderRD : : get_singleton ( ) - > environment_get_background ( p_env ) ;
2021-02-13 13:08:08 +01:00
if ( ! ( background = = RS : : ENV_BG_CLEAR_COLOR | | background = = RS : : ENV_BG_COLOR ) | | sky ) {
ERR_FAIL_COND ( ! sky ) ;
2022-07-27 08:14:23 +02:00
sky_material = sky_get_material ( RendererSceneRenderRD : : get_singleton ( ) - > environment_get_sky ( p_env ) ) ;
2021-02-13 13:08:08 +01:00
if ( sky_material . is_valid ( ) ) {
2022-08-01 03:59:14 +02:00
material = static_cast < SkyMaterialData * > ( material_storage - > material_get_data ( sky_material , RendererRD : : MaterialStorage : : SHADER_TYPE_SKY ) ) ;
2021-02-13 13:08:08 +01:00
if ( ! material | | ! material - > shader_data - > valid ) {
material = nullptr ;
}
}
if ( ! material ) {
sky_material = sky_shader . default_material ;
2022-08-01 03:59:14 +02:00
material = static_cast < SkyMaterialData * > ( material_storage - > material_get_data ( sky_material , RendererRD : : MaterialStorage : : SHADER_TYPE_SKY ) ) ;
2021-02-13 13:08:08 +01:00
}
}
if ( background = = RS : : ENV_BG_CLEAR_COLOR | | background = = RS : : ENV_BG_COLOR ) {
sky_material = sky_scene_state . fog_material ;
2022-08-01 03:59:14 +02:00
material = static_cast < SkyMaterialData * > ( material_storage - > material_get_data ( sky_material , RendererRD : : MaterialStorage : : SHADER_TYPE_SKY ) ) ;
2021-02-13 13:08:08 +01:00
}
ERR_FAIL_COND ( ! material ) ;
SkyShaderData * shader_data = material - > shader_data ;
ERR_FAIL_COND ( ! shader_data ) ;
2022-12-15 12:20:06 +01:00
if ( ! shader_data - > uses_quarter_res & & ! shader_data - > uses_half_res ) {
return ;
2021-02-13 13:08:08 +01:00
}
2022-12-16 01:07:00 +01:00
material - > set_as_used ( ) ;
2022-12-15 12:20:06 +01:00
RENDER_TIMESTAMP ( " Setup Sky Resolution Buffers " ) ;
RD : : get_singleton ( ) - > draw_command_begin_label ( " Setup Sky Resolution Buffers " ) ;
2022-07-27 08:14:23 +02:00
Basis sky_transform = RendererSceneRenderRD : : get_singleton ( ) - > environment_get_sky_orientation ( p_env ) ;
2021-06-26 12:49:25 +02:00
sky_transform . invert ( ) ;
2022-07-27 08:14:23 +02:00
float custom_fov = RendererSceneRenderRD : : get_singleton ( ) - > environment_get_sky_custom_fov ( p_env ) ;
2021-06-26 12:49:25 +02:00
// Camera
2022-12-15 12:20:06 +01:00
Projection projection = sky_scene_state . cam_projection ;
2021-06-26 12:49:25 +02:00
2022-12-15 12:20:06 +01:00
if ( custom_fov & & sky_scene_state . view_count = = 1 ) {
2021-06-26 12:49:25 +02:00
// With custom fov we don't support stereo...
2022-12-15 12:20:06 +01:00
float near_plane = projection . get_z_near ( ) ;
float far_plane = projection . get_z_far ( ) ;
float aspect = projection . get_aspect ( ) ;
2021-06-26 12:49:25 +02:00
2022-12-15 12:20:06 +01:00
projection . set_perspective ( custom_fov , aspect , near_plane , far_plane ) ;
2021-06-26 12:49:25 +02:00
}
2022-12-15 12:20:06 +01:00
sky_transform = sky_transform * sky_scene_state . cam_transform . basis ;
2021-06-26 12:49:25 +02:00
if ( shader_data - > uses_quarter_res ) {
2022-12-15 12:20:06 +01:00
PipelineCacheRD * pipeline = & shader_data - > pipelines [ sky_scene_state . view_count > 1 ? SKY_VERSION_QUARTER_RES_MULTIVIEW : SKY_VERSION_QUARTER_RES ] ;
// Grab texture and framebuffer from cache, create if needed...
uint32_t usage_bits = RD : : TEXTURE_USAGE_SAMPLING_BIT | RD : : TEXTURE_USAGE_COLOR_ATTACHMENT_BIT ;
Size2i quarter_size = sky - > screen_size / 4 ;
RID texture = p_render_buffers - > create_texture ( RB_SCOPE_SKY , RB_QUARTER_TEXTURE , texture_format , usage_bits , RD : : TEXTURE_SAMPLES_1 , quarter_size ) ;
RID framebuffer = FramebufferCacheRD : : get_singleton ( ) - > get_cache_multiview ( sky_scene_state . view_count , texture ) ;
2021-06-26 12:49:25 +02:00
2022-12-15 12:20:06 +01:00
RID texture_uniform_set = sky - > get_textures ( SKY_TEXTURE_SET_QUARTER_RES , sky_shader . default_shader_rd , p_render_buffers ) ;
2021-06-26 12:49:25 +02:00
Vector < Color > clear_colors ;
clear_colors . push_back ( Color ( 0.0 , 0.0 , 0.0 ) ) ;
2022-12-15 12:20:06 +01:00
RD : : DrawListID draw_list = RD : : get_singleton ( ) - > draw_list_begin ( framebuffer , RD : : INITIAL_ACTION_CLEAR , RD : : FINAL_ACTION_READ , RD : : INITIAL_ACTION_CLEAR , RD : : FINAL_ACTION_DISCARD , clear_colors ) ;
_render_sky ( draw_list , p_time , framebuffer , pipeline , material - > uniform_set , texture_uniform_set , projection , sky_transform , sky_scene_state . cam_transform . origin , p_luminance_multiplier ) ;
2021-06-26 12:49:25 +02:00
RD : : get_singleton ( ) - > draw_list_end ( ) ;
}
if ( shader_data - > uses_half_res ) {
2022-12-15 12:20:06 +01:00
PipelineCacheRD * pipeline = & shader_data - > pipelines [ sky_scene_state . view_count > 1 ? SKY_VERSION_HALF_RES_MULTIVIEW : SKY_VERSION_HALF_RES ] ;
2021-06-26 12:49:25 +02:00
2022-12-15 12:20:06 +01:00
// Grab texture and framebuffer from cache, create if needed...
uint32_t usage_bits = RD : : TEXTURE_USAGE_SAMPLING_BIT | RD : : TEXTURE_USAGE_COLOR_ATTACHMENT_BIT ;
Size2i half_size = sky - > screen_size / 2 ;
RID texture = p_render_buffers - > create_texture ( RB_SCOPE_SKY , RB_HALF_TEXTURE , texture_format , usage_bits , RD : : TEXTURE_SAMPLES_1 , half_size ) ;
RID framebuffer = FramebufferCacheRD : : get_singleton ( ) - > get_cache_multiview ( sky_scene_state . view_count , texture ) ;
RID texture_uniform_set = sky - > get_textures ( SKY_TEXTURE_SET_HALF_RES , sky_shader . default_shader_rd , p_render_buffers ) ;
2021-06-26 12:49:25 +02:00
Vector < Color > clear_colors ;
clear_colors . push_back ( Color ( 0.0 , 0.0 , 0.0 ) ) ;
2022-12-15 12:20:06 +01:00
RD : : DrawListID draw_list = RD : : get_singleton ( ) - > draw_list_begin ( framebuffer , RD : : INITIAL_ACTION_CLEAR , RD : : FINAL_ACTION_READ , RD : : INITIAL_ACTION_CLEAR , RD : : FINAL_ACTION_DISCARD , clear_colors ) ;
_render_sky ( draw_list , p_time , framebuffer , pipeline , material - > uniform_set , texture_uniform_set , projection , sky_transform , sky_scene_state . cam_transform . origin , p_luminance_multiplier ) ;
2021-06-26 12:49:25 +02:00
RD : : get_singleton ( ) - > draw_list_end ( ) ;
}
2022-12-15 12:20:06 +01:00
RD : : get_singleton ( ) - > draw_command_end_label ( ) ; // Setup Sky resolution buffers
2021-06-26 12:49:25 +02:00
}
2022-12-15 12:20:06 +01:00
void SkyRD : : draw_sky ( RD : : DrawListID p_draw_list , Ref < RenderSceneBuffersRD > p_render_buffers , RID p_env , RID p_fb , double p_time , float p_luminance_multiplier ) {
ERR_FAIL_COND ( p_render_buffers . is_null ( ) ) ;
2022-03-21 12:25:25 +01:00
RendererRD : : MaterialStorage * material_storage = RendererRD : : MaterialStorage : : get_singleton ( ) ;
2022-07-27 08:14:23 +02:00
ERR_FAIL_COND ( p_env . is_null ( ) ) ;
2021-06-26 12:49:25 +02:00
2022-07-27 08:14:23 +02:00
Sky * sky = get_sky ( RendererSceneRenderRD : : get_singleton ( ) - > environment_get_sky ( p_env ) ) ;
2021-06-26 12:49:25 +02:00
SkyMaterialData * material = nullptr ;
RID sky_material ;
2022-07-27 08:14:23 +02:00
RS : : EnvironmentBG background = RendererSceneRenderRD : : get_singleton ( ) - > environment_get_background ( p_env ) ;
2021-06-26 12:49:25 +02:00
if ( ! ( background = = RS : : ENV_BG_CLEAR_COLOR | | background = = RS : : ENV_BG_COLOR ) | | sky ) {
ERR_FAIL_COND ( ! sky ) ;
2022-07-27 08:14:23 +02:00
sky_material = sky_get_material ( RendererSceneRenderRD : : get_singleton ( ) - > environment_get_sky ( p_env ) ) ;
2021-06-26 12:49:25 +02:00
if ( sky_material . is_valid ( ) ) {
2022-08-01 03:59:14 +02:00
material = static_cast < SkyMaterialData * > ( material_storage - > material_get_data ( sky_material , RendererRD : : MaterialStorage : : SHADER_TYPE_SKY ) ) ;
2021-06-26 12:49:25 +02:00
if ( ! material | | ! material - > shader_data - > valid ) {
material = nullptr ;
}
}
if ( ! material ) {
sky_material = sky_shader . default_material ;
2022-08-01 03:59:14 +02:00
material = static_cast < SkyMaterialData * > ( material_storage - > material_get_data ( sky_material , RendererRD : : MaterialStorage : : SHADER_TYPE_SKY ) ) ;
2021-06-26 12:49:25 +02:00
}
}
if ( background = = RS : : ENV_BG_CLEAR_COLOR | | background = = RS : : ENV_BG_COLOR ) {
sky_material = sky_scene_state . fog_material ;
2022-08-01 03:59:14 +02:00
material = static_cast < SkyMaterialData * > ( material_storage - > material_get_data ( sky_material , RendererRD : : MaterialStorage : : SHADER_TYPE_SKY ) ) ;
2021-06-26 12:49:25 +02:00
}
ERR_FAIL_COND ( ! material ) ;
SkyShaderData * shader_data = material - > shader_data ;
ERR_FAIL_COND ( ! shader_data ) ;
2022-12-16 01:07:00 +01:00
material - > set_as_used ( ) ;
2022-07-27 08:14:23 +02:00
Basis sky_transform = RendererSceneRenderRD : : get_singleton ( ) - > environment_get_sky_orientation ( p_env ) ;
2021-06-26 12:49:25 +02:00
sky_transform . invert ( ) ;
2022-07-27 08:14:23 +02:00
float custom_fov = RendererSceneRenderRD : : get_singleton ( ) - > environment_get_sky_custom_fov ( p_env ) ;
2021-06-26 12:49:25 +02:00
// Camera
2022-12-15 12:20:06 +01:00
Projection projection = sky_scene_state . cam_projection ;
2021-06-26 12:49:25 +02:00
2022-12-15 12:20:06 +01:00
if ( custom_fov & & sky_scene_state . view_count = = 1 ) {
2021-06-26 12:49:25 +02:00
// With custom fov we don't support stereo...
2022-12-15 12:20:06 +01:00
float near_plane = projection . get_z_near ( ) ;
float far_plane = projection . get_z_far ( ) ;
float aspect = projection . get_aspect ( ) ;
2021-06-26 12:49:25 +02:00
2022-12-15 12:20:06 +01:00
projection . set_perspective ( custom_fov , aspect , near_plane , far_plane ) ;
2021-06-26 12:49:25 +02:00
}
2022-12-15 12:20:06 +01:00
sky_transform = sky_transform * sky_scene_state . cam_transform . basis ;
2021-06-26 12:49:25 +02:00
2022-12-15 12:20:06 +01:00
PipelineCacheRD * pipeline = & shader_data - > pipelines [ sky_scene_state . view_count > 1 ? SKY_VERSION_BACKGROUND_MULTIVIEW : SKY_VERSION_BACKGROUND ] ;
2021-06-26 12:49:25 +02:00
RID texture_uniform_set ;
if ( sky ) {
2022-12-15 12:20:06 +01:00
texture_uniform_set = sky - > get_textures ( SKY_TEXTURE_SET_BACKGROUND , sky_shader . default_shader_rd , p_render_buffers ) ;
2021-06-26 12:49:25 +02:00
} else {
texture_uniform_set = sky_scene_state . fog_only_texture_uniform_set ;
}
2022-12-15 12:20:06 +01:00
_render_sky ( p_draw_list , p_time , p_fb , pipeline , material - > uniform_set , texture_uniform_set , projection , sky_transform , sky_scene_state . cam_transform . origin , p_luminance_multiplier ) ;
2021-06-26 12:49:25 +02:00
}
2022-07-19 06:17:58 +02:00
void SkyRD : : invalidate_sky ( Sky * p_sky ) {
2021-02-13 13:08:08 +01:00
if ( ! p_sky - > dirty ) {
p_sky - > dirty = true ;
p_sky - > dirty_list = dirty_sky_list ;
dirty_sky_list = p_sky ;
}
}
2022-07-19 06:17:58 +02:00
void SkyRD : : update_dirty_skys ( ) {
2021-02-13 13:08:08 +01:00
Sky * sky = dirty_sky_list ;
while ( sky ) {
//update sky configuration if texture is missing
2022-12-15 12:20:06 +01:00
// TODO See if we can move this into `update_radiance_buffers` and remove our dirty_sky logic.
// As this is basically a duplicate of the logic in reflection probes we could move this logic
// into RenderSceneBuffersRD and use that from both places.
2021-02-13 13:08:08 +01:00
if ( sky - > radiance . is_null ( ) ) {
int mipmaps = Image : : get_image_required_mipmaps ( sky - > radiance_size , sky - > radiance_size , Image : : FORMAT_RGBAH ) + 1 ;
uint32_t w = sky - > radiance_size , h = sky - > radiance_size ;
int layers = roughness_layers ;
if ( sky - > mode = = RS : : SKY_MODE_REALTIME ) {
layers = 8 ;
if ( roughness_layers ! = 8 ) {
2022-11-29 02:42:19 +01:00
WARN_PRINT ( " When using the Real-Time sky update mode (or Automatic with a sky shader using \" TIME \" ), \" rendering/reflections/sky_reflections/roughness_layers \" should be set to 8 in the project settings for best quality reflections. " ) ;
2021-02-13 13:08:08 +01:00
}
}
if ( sky_use_cubemap_array ) {
//array (higher quality, 6 times more memory)
RD : : TextureFormat tf ;
tf . array_layers = layers * 6 ;
2021-07-27 15:33:47 +02:00
tf . format = texture_format ;
2021-02-13 13:08:08 +01:00
tf . texture_type = RD : : TEXTURE_TYPE_CUBE_ARRAY ;
tf . mipmaps = mipmaps ;
tf . width = w ;
tf . height = h ;
2023-01-23 21:38:09 +01:00
tf . usage_bits = RD : : TEXTURE_USAGE_COLOR_ATTACHMENT_BIT | RD : : TEXTURE_USAGE_SAMPLING_BIT ;
if ( RendererSceneRenderRD : : get_singleton ( ) - > _render_buffers_can_be_storage ( ) ) {
tf . usage_bits | = RD : : TEXTURE_USAGE_STORAGE_BIT ;
}
2021-02-13 13:08:08 +01:00
sky - > radiance = RD : : get_singleton ( ) - > texture_create ( tf , RD : : TextureView ( ) ) ;
2022-06-21 02:08:33 +02:00
sky - > reflection . update_reflection_data ( sky - > radiance_size , mipmaps , true , sky - > radiance , 0 , sky - > mode = = RS : : SKY_MODE_REALTIME , roughness_layers , texture_format ) ;
2021-02-13 13:08:08 +01:00
} else {
//regular cubemap, lower quality (aliasing, less memory)
RD : : TextureFormat tf ;
tf . array_layers = 6 ;
2021-07-27 15:33:47 +02:00
tf . format = texture_format ;
2021-02-13 13:08:08 +01:00
tf . texture_type = RD : : TEXTURE_TYPE_CUBE ;
tf . mipmaps = MIN ( mipmaps , layers ) ;
tf . width = w ;
tf . height = h ;
2023-01-25 20:31:53 +01:00
tf . usage_bits = RD : : TEXTURE_USAGE_COLOR_ATTACHMENT_BIT | RD : : TEXTURE_USAGE_SAMPLING_BIT ;
if ( RendererSceneRenderRD : : get_singleton ( ) - > _render_buffers_can_be_storage ( ) ) {
tf . usage_bits | = RD : : TEXTURE_USAGE_STORAGE_BIT ;
}
2021-02-13 13:08:08 +01:00
sky - > radiance = RD : : get_singleton ( ) - > texture_create ( tf , RD : : TextureView ( ) ) ;
2022-06-21 02:08:33 +02:00
sky - > reflection . update_reflection_data ( sky - > radiance_size , MIN ( mipmaps , layers ) , false , sky - > radiance , 0 , sky - > mode = = RS : : SKY_MODE_REALTIME , roughness_layers , texture_format ) ;
2021-02-13 13:08:08 +01:00
}
}
sky - > reflection . dirty = true ;
sky - > processing_layer = 0 ;
Sky * next = sky - > dirty_list ;
sky - > dirty_list = nullptr ;
sky - > dirty = false ;
sky = next ;
}
dirty_sky_list = nullptr ;
}
2022-07-19 06:17:58 +02:00
RID SkyRD : : sky_get_material ( RID p_sky ) const {
2021-02-13 13:08:08 +01:00
Sky * sky = get_sky ( p_sky ) ;
ERR_FAIL_COND_V ( ! sky , RID ( ) ) ;
return sky - > material ;
}
2022-08-01 01:20:24 +02:00
float SkyRD : : sky_get_baked_exposure ( RID p_sky ) const {
Sky * sky = get_sky ( p_sky ) ;
ERR_FAIL_COND_V ( ! sky , 1.0 ) ;
return sky - > baked_exposure ;
}
2022-07-19 06:17:58 +02:00
RID SkyRD : : allocate_sky_rid ( ) {
2021-02-13 13:08:08 +01:00
return sky_owner . allocate_rid ( ) ;
}
2022-07-19 06:17:58 +02:00
void SkyRD : : initialize_sky_rid ( RID p_rid ) {
2021-02-13 13:08:08 +01:00
sky_owner . initialize_rid ( p_rid , Sky ( ) ) ;
}
2022-07-19 06:17:58 +02:00
SkyRD : : Sky * SkyRD : : get_sky ( RID p_sky ) const {
2021-09-29 19:08:41 +02:00
return sky_owner . get_or_null ( p_sky ) ;
2021-02-13 13:08:08 +01:00
}
2022-07-19 06:17:58 +02:00
void SkyRD : : free_sky ( RID p_sky ) {
2021-02-13 13:08:08 +01:00
Sky * sky = get_sky ( p_sky ) ;
ERR_FAIL_COND ( ! sky ) ;
2022-06-21 02:08:33 +02:00
sky - > free ( ) ;
2021-02-13 13:08:08 +01:00
sky_owner . free ( p_sky ) ;
}
2022-07-19 06:17:58 +02:00
void SkyRD : : sky_set_radiance_size ( RID p_sky , int p_radiance_size ) {
2021-02-13 13:08:08 +01:00
Sky * sky = get_sky ( p_sky ) ;
ERR_FAIL_COND ( ! sky ) ;
if ( sky - > set_radiance_size ( p_radiance_size ) ) {
invalidate_sky ( sky ) ;
}
}
2022-07-19 06:17:58 +02:00
void SkyRD : : sky_set_mode ( RID p_sky , RS : : SkyMode p_mode ) {
2021-02-13 13:08:08 +01:00
Sky * sky = get_sky ( p_sky ) ;
ERR_FAIL_COND ( ! sky ) ;
if ( sky - > set_mode ( p_mode ) ) {
invalidate_sky ( sky ) ;
}
}
2022-07-19 06:17:58 +02:00
void SkyRD : : sky_set_material ( RID p_sky , RID p_material ) {
2021-02-13 13:08:08 +01:00
Sky * sky = get_sky ( p_sky ) ;
ERR_FAIL_COND ( ! sky ) ;
if ( sky - > set_material ( p_material ) ) {
invalidate_sky ( sky ) ;
}
}
2022-07-19 06:17:58 +02:00
Ref < Image > SkyRD : : sky_bake_panorama ( RID p_sky , float p_energy , bool p_bake_irradiance , const Size2i & p_size ) {
2021-02-13 13:08:08 +01:00
Sky * sky = get_sky ( p_sky ) ;
ERR_FAIL_COND_V ( ! sky , Ref < Image > ( ) ) ;
update_dirty_skys ( ) ;
2022-04-29 09:10:54 +02:00
return sky - > bake_panorama ( p_energy , p_bake_irradiance ? roughness_layers : 0 , p_size ) ;
2021-02-13 13:08:08 +01:00
}
2022-07-19 06:17:58 +02:00
RID SkyRD : : sky_get_radiance_texture_rd ( RID p_sky ) const {
2021-02-13 13:08:08 +01:00
Sky * sky = get_sky ( p_sky ) ;
ERR_FAIL_COND_V ( ! sky , RID ( ) ) ;
return sky - > radiance ;
}