Simplify Volumetric Fog
-Always use temporal reproject, it just loos way better than any other filter. -By always using termporal reproject, the shadowmap reduction can be done away with, massively improving performance. -Disadvantage of temporal reproject is update latency so.. -Made sure a gaussian filter runs in XY after fog, this allows to keep stability and lower latency.
This commit is contained in:
parent
fa2f7693bb
commit
8faf23b52b
|
@ -123,11 +123,9 @@ public:
|
||||||
void environment_set_adjustment(RID p_env, bool p_enable, float p_brightness, float p_contrast, float p_saturation, bool p_use_1d_color_correction, RID p_color_correction) override {}
|
void environment_set_adjustment(RID p_env, bool p_enable, float p_brightness, float p_contrast, float p_saturation, bool p_use_1d_color_correction, RID p_color_correction) override {}
|
||||||
|
|
||||||
void environment_set_fog(RID p_env, bool p_enable, const Color &p_light_color, float p_light_energy, float p_sun_scatter, float p_density, float p_height, float p_height_density, float p_aerial_perspective) override {}
|
void environment_set_fog(RID p_env, bool p_enable, const Color &p_light_color, float p_light_energy, float p_sun_scatter, float p_density, float p_height, float p_height_density, float p_aerial_perspective) override {}
|
||||||
void environment_set_volumetric_fog(RID p_env, bool p_enable, float p_density, const Color &p_light, float p_light_energy, float p_length, float p_detail_spread, float p_gi_inject, RS::EnvVolumetricFogShadowFilter p_shadow_filter) override {}
|
void environment_set_volumetric_fog(RID p_env, bool p_enable, float p_density, const Color &p_light, float p_light_energy, float p_length, float p_detail_spread, float p_gi_inject) override {}
|
||||||
void environment_set_volumetric_fog_volume_size(int p_size, int p_depth) override {}
|
void environment_set_volumetric_fog_volume_size(int p_size, int p_depth) override {}
|
||||||
void environment_set_volumetric_fog_filter_active(bool p_enable) override {}
|
void environment_set_volumetric_fog_filter_active(bool p_enable) override {}
|
||||||
void environment_set_volumetric_fog_directional_shadow_shrink_size(int p_shrink_size) override {}
|
|
||||||
void environment_set_volumetric_fog_positional_shadow_shrink_size(int p_shrink_size) override {}
|
|
||||||
|
|
||||||
Ref<Image> environment_bake_panorama(RID p_env, bool p_bake_irradiance, const Size2i &p_size) override { return Ref<Image>(); }
|
Ref<Image> environment_bake_panorama(RID p_env, bool p_bake_irradiance, const Size2i &p_size) override { return Ref<Image>(); }
|
||||||
|
|
||||||
|
|
|
@ -517,8 +517,6 @@ void EditorNode::_notification(int p_what) {
|
||||||
RS::get_singleton()->gi_probe_set_quality(gi_probe_quality);
|
RS::get_singleton()->gi_probe_set_quality(gi_probe_quality);
|
||||||
RS::get_singleton()->environment_set_volumetric_fog_volume_size(GLOBAL_GET("rendering/volumetric_fog/volume_size"), GLOBAL_GET("rendering/volumetric_fog/volume_depth"));
|
RS::get_singleton()->environment_set_volumetric_fog_volume_size(GLOBAL_GET("rendering/volumetric_fog/volume_size"), GLOBAL_GET("rendering/volumetric_fog/volume_depth"));
|
||||||
RS::get_singleton()->environment_set_volumetric_fog_filter_active(bool(GLOBAL_GET("rendering/volumetric_fog/use_filter")));
|
RS::get_singleton()->environment_set_volumetric_fog_filter_active(bool(GLOBAL_GET("rendering/volumetric_fog/use_filter")));
|
||||||
RS::get_singleton()->environment_set_volumetric_fog_directional_shadow_shrink_size(GLOBAL_GET("rendering/volumetric_fog/directional_shadow_shrink"));
|
|
||||||
RS::get_singleton()->environment_set_volumetric_fog_positional_shadow_shrink_size(GLOBAL_GET("rendering/volumetric_fog/positional_shadow_shrink"));
|
|
||||||
RS::get_singleton()->canvas_set_shadow_texture_size(GLOBAL_GET("rendering/quality/2d_shadow_atlas/size"));
|
RS::get_singleton()->canvas_set_shadow_texture_size(GLOBAL_GET("rendering/quality/2d_shadow_atlas/size"));
|
||||||
|
|
||||||
bool use_half_res_gi = GLOBAL_DEF("rendering/quality/gi/use_half_resolution", false);
|
bool use_half_res_gi = GLOBAL_DEF("rendering/quality/gi/use_half_resolution", false);
|
||||||
|
|
|
@ -351,7 +351,7 @@ Light3D::Light3D(RenderingServer::LightType p_type) {
|
||||||
set_param(PARAM_SHADOW_BIAS, 0.02);
|
set_param(PARAM_SHADOW_BIAS, 0.02);
|
||||||
set_param(PARAM_SHADOW_NORMAL_BIAS, 1.0);
|
set_param(PARAM_SHADOW_NORMAL_BIAS, 1.0);
|
||||||
set_param(PARAM_TRANSMITTANCE_BIAS, 0.05);
|
set_param(PARAM_TRANSMITTANCE_BIAS, 0.05);
|
||||||
set_param(PARAM_SHADOW_VOLUMETRIC_FOG_FADE, 1.0);
|
set_param(PARAM_SHADOW_VOLUMETRIC_FOG_FADE, 0.1);
|
||||||
set_param(PARAM_SHADOW_FADE_START, 1);
|
set_param(PARAM_SHADOW_FADE_START, 1);
|
||||||
set_disable_scale(true);
|
set_disable_scale(true);
|
||||||
}
|
}
|
||||||
|
|
|
@ -797,7 +797,7 @@ void Environment::_update_fog() {
|
||||||
// Volumetric Fog
|
// Volumetric Fog
|
||||||
|
|
||||||
void Environment::_update_volumetric_fog() {
|
void Environment::_update_volumetric_fog() {
|
||||||
RS::get_singleton()->environment_set_volumetric_fog(environment, volumetric_fog_enabled, volumetric_fog_density, volumetric_fog_light, volumetric_fog_light_energy, volumetric_fog_length, volumetric_fog_detail_spread, volumetric_fog_gi_inject, RS::EnvVolumetricFogShadowFilter(volumetric_fog_shadow_filter), volumetric_fog_temporal_reproject, volumetric_fog_temporal_reproject_amount);
|
RS::get_singleton()->environment_set_volumetric_fog(environment, volumetric_fog_enabled, volumetric_fog_density, volumetric_fog_light, volumetric_fog_light_energy, volumetric_fog_length, volumetric_fog_detail_spread, volumetric_fog_gi_inject, volumetric_fog_temporal_reproject, volumetric_fog_temporal_reproject_amount);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Environment::set_volumetric_fog_enabled(bool p_enable) {
|
void Environment::set_volumetric_fog_enabled(bool p_enable) {
|
||||||
|
@ -870,15 +870,6 @@ float Environment::get_volumetric_fog_temporal_reprojection_amount() const {
|
||||||
return volumetric_fog_temporal_reproject_amount;
|
return volumetric_fog_temporal_reproject_amount;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Environment::set_volumetric_fog_shadow_filter(VolumetricFogShadowFilter p_filter) {
|
|
||||||
volumetric_fog_shadow_filter = p_filter;
|
|
||||||
_update_volumetric_fog();
|
|
||||||
}
|
|
||||||
|
|
||||||
Environment::VolumetricFogShadowFilter Environment::get_volumetric_fog_shadow_filter() const {
|
|
||||||
return volumetric_fog_shadow_filter;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Adjustment
|
// Adjustment
|
||||||
|
|
||||||
void Environment::set_adjustment_enabled(bool p_enabled) {
|
void Environment::set_adjustment_enabled(bool p_enabled) {
|
||||||
|
@ -1333,8 +1324,6 @@ void Environment::_bind_methods() {
|
||||||
ClassDB::bind_method(D_METHOD("get_volumetric_fog_detail_spread"), &Environment::get_volumetric_fog_detail_spread);
|
ClassDB::bind_method(D_METHOD("get_volumetric_fog_detail_spread"), &Environment::get_volumetric_fog_detail_spread);
|
||||||
ClassDB::bind_method(D_METHOD("set_volumetric_fog_gi_inject", "gi_inject"), &Environment::set_volumetric_fog_gi_inject);
|
ClassDB::bind_method(D_METHOD("set_volumetric_fog_gi_inject", "gi_inject"), &Environment::set_volumetric_fog_gi_inject);
|
||||||
ClassDB::bind_method(D_METHOD("get_volumetric_fog_gi_inject"), &Environment::get_volumetric_fog_gi_inject);
|
ClassDB::bind_method(D_METHOD("get_volumetric_fog_gi_inject"), &Environment::get_volumetric_fog_gi_inject);
|
||||||
ClassDB::bind_method(D_METHOD("set_volumetric_fog_shadow_filter", "shadow_filter"), &Environment::set_volumetric_fog_shadow_filter);
|
|
||||||
ClassDB::bind_method(D_METHOD("get_volumetric_fog_shadow_filter"), &Environment::get_volumetric_fog_shadow_filter);
|
|
||||||
ClassDB::bind_method(D_METHOD("set_volumetric_fog_temporal_reprojection_enabled", "enabled"), &Environment::set_volumetric_fog_temporal_reprojection_enabled);
|
ClassDB::bind_method(D_METHOD("set_volumetric_fog_temporal_reprojection_enabled", "enabled"), &Environment::set_volumetric_fog_temporal_reprojection_enabled);
|
||||||
ClassDB::bind_method(D_METHOD("is_volumetric_fog_temporal_reprojection_enabled"), &Environment::is_volumetric_fog_temporal_reprojection_enabled);
|
ClassDB::bind_method(D_METHOD("is_volumetric_fog_temporal_reprojection_enabled"), &Environment::is_volumetric_fog_temporal_reprojection_enabled);
|
||||||
ClassDB::bind_method(D_METHOD("set_volumetric_fog_temporal_reprojection_amount", "temporal_reprojection_amount"), &Environment::set_volumetric_fog_temporal_reprojection_amount);
|
ClassDB::bind_method(D_METHOD("set_volumetric_fog_temporal_reprojection_amount", "temporal_reprojection_amount"), &Environment::set_volumetric_fog_temporal_reprojection_amount);
|
||||||
|
@ -1348,7 +1337,6 @@ void Environment::_bind_methods() {
|
||||||
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "volumetric_fog_gi_inject", PROPERTY_HINT_EXP_RANGE, "0.00,16,0.01"), "set_volumetric_fog_gi_inject", "get_volumetric_fog_gi_inject");
|
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "volumetric_fog_gi_inject", PROPERTY_HINT_EXP_RANGE, "0.00,16,0.01"), "set_volumetric_fog_gi_inject", "get_volumetric_fog_gi_inject");
|
||||||
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "volumetric_fog_length", PROPERTY_HINT_RANGE, "0,1024,0.01,or_greater"), "set_volumetric_fog_length", "get_volumetric_fog_length");
|
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "volumetric_fog_length", PROPERTY_HINT_RANGE, "0,1024,0.01,or_greater"), "set_volumetric_fog_length", "get_volumetric_fog_length");
|
||||||
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "volumetric_fog_detail_spread", PROPERTY_HINT_EXP_EASING, "0.01,16,0.01"), "set_volumetric_fog_detail_spread", "get_volumetric_fog_detail_spread");
|
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "volumetric_fog_detail_spread", PROPERTY_HINT_EXP_EASING, "0.01,16,0.01"), "set_volumetric_fog_detail_spread", "get_volumetric_fog_detail_spread");
|
||||||
ADD_PROPERTY(PropertyInfo(Variant::INT, "volumetric_fog_shadow_filter", PROPERTY_HINT_ENUM, "Disabled,Low,Medium,High"), "set_volumetric_fog_shadow_filter", "get_volumetric_fog_shadow_filter");
|
|
||||||
ADD_SUBGROUP("Temporal Reprojection", "volumetric_fog_temporal_reprojection_");
|
ADD_SUBGROUP("Temporal Reprojection", "volumetric_fog_temporal_reprojection_");
|
||||||
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "volumetric_fog_temporal_reprojection_enabled"), "set_volumetric_fog_temporal_reprojection_enabled", "is_volumetric_fog_temporal_reprojection_enabled");
|
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "volumetric_fog_temporal_reprojection_enabled"), "set_volumetric_fog_temporal_reprojection_enabled", "is_volumetric_fog_temporal_reprojection_enabled");
|
||||||
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "volumetric_fog_temporal_reprojection_amount", PROPERTY_HINT_RANGE, "0.0,0.999,0.001"), "set_volumetric_fog_temporal_reprojection_amount", "get_volumetric_fog_temporal_reprojection_amount");
|
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "volumetric_fog_temporal_reprojection_amount", PROPERTY_HINT_RANGE, "0.0,0.999,0.001"), "set_volumetric_fog_temporal_reprojection_amount", "get_volumetric_fog_temporal_reprojection_amount");
|
||||||
|
|
|
@ -196,10 +196,9 @@ private:
|
||||||
float volumetric_fog_light_energy = 1.0;
|
float volumetric_fog_light_energy = 1.0;
|
||||||
float volumetric_fog_length = 64.0;
|
float volumetric_fog_length = 64.0;
|
||||||
float volumetric_fog_detail_spread = 2.0;
|
float volumetric_fog_detail_spread = 2.0;
|
||||||
VolumetricFogShadowFilter volumetric_fog_shadow_filter = VOLUMETRIC_FOG_SHADOW_FILTER_LOW;
|
|
||||||
float volumetric_fog_gi_inject = 0.0;
|
float volumetric_fog_gi_inject = 0.0;
|
||||||
bool volumetric_fog_temporal_reproject = false;
|
bool volumetric_fog_temporal_reproject = true;
|
||||||
float volumetric_fog_temporal_reproject_amount = 0.95;
|
float volumetric_fog_temporal_reproject_amount = 0.9;
|
||||||
void _update_volumetric_fog();
|
void _update_volumetric_fog();
|
||||||
|
|
||||||
// Adjustment
|
// Adjustment
|
||||||
|
@ -387,8 +386,6 @@ public:
|
||||||
float get_volumetric_fog_length() const;
|
float get_volumetric_fog_length() const;
|
||||||
void set_volumetric_fog_detail_spread(float p_detail_spread);
|
void set_volumetric_fog_detail_spread(float p_detail_spread);
|
||||||
float get_volumetric_fog_detail_spread() const;
|
float get_volumetric_fog_detail_spread() const;
|
||||||
void set_volumetric_fog_shadow_filter(VolumetricFogShadowFilter p_filter);
|
|
||||||
VolumetricFogShadowFilter get_volumetric_fog_shadow_filter() const;
|
|
||||||
void set_volumetric_fog_gi_inject(float p_gi_inject);
|
void set_volumetric_fog_gi_inject(float p_gi_inject);
|
||||||
float get_volumetric_fog_gi_inject() const;
|
float get_volumetric_fog_gi_inject() const;
|
||||||
void set_volumetric_fog_temporal_reprojection_enabled(bool p_enable);
|
void set_volumetric_fog_temporal_reprojection_enabled(bool p_enable);
|
||||||
|
|
|
@ -1423,60 +1423,6 @@ void EffectsRD::resolve_gi(RID p_source_depth, RID p_source_normal_roughness, RI
|
||||||
RD::get_singleton()->compute_list_end(p_barrier);
|
RD::get_singleton()->compute_list_end(p_barrier);
|
||||||
}
|
}
|
||||||
|
|
||||||
void EffectsRD::reduce_shadow(RID p_source_shadow, RID p_dest_shadow, const Size2i &p_source_size, const Rect2i &p_source_rect, int p_shrink_limit, RD::ComputeListID compute_list) {
|
|
||||||
uint32_t push_constant[8] = { (uint32_t)p_source_size.x, (uint32_t)p_source_size.y, (uint32_t)p_source_rect.position.x, (uint32_t)p_source_rect.position.y, (uint32_t)p_shrink_limit, 0, 0, 0 };
|
|
||||||
|
|
||||||
uint32_t height = p_source_rect.size.height;
|
|
||||||
if (true) { // subgroup support, @TODO must detect them
|
|
||||||
RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, shadow_reduce.pipelines[p_shrink_limit == 1 ? SHADOW_REDUCE_REDUCE_SUBGROUPS_8 : SHADOW_REDUCE_REDUCE_SUBGROUPS]);
|
|
||||||
height /= 2; //cause kernel is 8x4
|
|
||||||
} else {
|
|
||||||
RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, shadow_reduce.pipelines[SHADOW_REDUCE_REDUCE]);
|
|
||||||
}
|
|
||||||
RD::get_singleton()->compute_list_bind_uniform_set(compute_list, _get_compute_uniform_set_from_texture(p_source_shadow), 0);
|
|
||||||
RD::get_singleton()->compute_list_bind_uniform_set(compute_list, _get_uniform_set_from_image(p_dest_shadow), 1);
|
|
||||||
RD::get_singleton()->compute_list_set_push_constant(compute_list, &push_constant, sizeof(uint32_t) * 8);
|
|
||||||
|
|
||||||
RD::get_singleton()->compute_list_dispatch_threads(compute_list, p_source_rect.size.width, height, 1);
|
|
||||||
}
|
|
||||||
void EffectsRD::filter_shadow(RID p_shadow, RID p_backing_shadow, const Size2i &p_source_size, const Rect2i &p_source_rect, RenderingServer::EnvVolumetricFogShadowFilter p_filter, RD::ComputeListID compute_list, bool p_vertical, bool p_horizontal) {
|
|
||||||
uint32_t push_constant[8] = { (uint32_t)p_source_size.x, (uint32_t)p_source_size.y, (uint32_t)p_source_rect.position.x, (uint32_t)p_source_rect.position.y, 0, 0, 0, 0 };
|
|
||||||
|
|
||||||
switch (p_filter) {
|
|
||||||
case RS::ENV_VOLUMETRIC_FOG_SHADOW_FILTER_DISABLED:
|
|
||||||
case RS::ENV_VOLUMETRIC_FOG_SHADOW_FILTER_LOW: {
|
|
||||||
push_constant[5] = 0;
|
|
||||||
} break;
|
|
||||||
case RS::ENV_VOLUMETRIC_FOG_SHADOW_FILTER_MEDIUM: {
|
|
||||||
push_constant[5] = 9;
|
|
||||||
} break;
|
|
||||||
case RS::ENV_VOLUMETRIC_FOG_SHADOW_FILTER_HIGH: {
|
|
||||||
push_constant[5] = 18;
|
|
||||||
} break;
|
|
||||||
}
|
|
||||||
|
|
||||||
RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, shadow_reduce.pipelines[SHADOW_REDUCE_FILTER]);
|
|
||||||
if (p_vertical) {
|
|
||||||
push_constant[6] = 1;
|
|
||||||
push_constant[7] = 0;
|
|
||||||
RD::get_singleton()->compute_list_bind_uniform_set(compute_list, _get_uniform_set_from_image(p_shadow), 0);
|
|
||||||
RD::get_singleton()->compute_list_bind_uniform_set(compute_list, _get_uniform_set_from_image(p_backing_shadow), 1);
|
|
||||||
RD::get_singleton()->compute_list_set_push_constant(compute_list, &push_constant, sizeof(uint32_t) * 8);
|
|
||||||
RD::get_singleton()->compute_list_dispatch_threads(compute_list, p_source_rect.size.width, p_source_rect.size.height, 1);
|
|
||||||
}
|
|
||||||
if (p_vertical && p_horizontal) {
|
|
||||||
RD::get_singleton()->compute_list_add_barrier(compute_list);
|
|
||||||
}
|
|
||||||
if (p_horizontal) {
|
|
||||||
push_constant[6] = 0;
|
|
||||||
push_constant[7] = 1;
|
|
||||||
RD::get_singleton()->compute_list_bind_uniform_set(compute_list, _get_uniform_set_from_image(p_backing_shadow), 0);
|
|
||||||
RD::get_singleton()->compute_list_bind_uniform_set(compute_list, _get_uniform_set_from_image(p_shadow), 1);
|
|
||||||
RD::get_singleton()->compute_list_set_push_constant(compute_list, &push_constant, sizeof(uint32_t) * 8);
|
|
||||||
RD::get_singleton()->compute_list_dispatch_threads(compute_list, p_source_rect.size.width, p_source_rect.size.height, 1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void EffectsRD::sort_buffer(RID p_uniform_set, int p_size) {
|
void EffectsRD::sort_buffer(RID p_uniform_set, int p_size) {
|
||||||
Sort::PushConstant push_constant;
|
Sort::PushConstant push_constant;
|
||||||
push_constant.total_elements = p_size;
|
push_constant.total_elements = p_size;
|
||||||
|
@ -1972,22 +1918,6 @@ EffectsRD::EffectsRD() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
|
||||||
Vector<String> shadow_reduce_modes;
|
|
||||||
shadow_reduce_modes.push_back("\n#define MODE_REDUCE\n");
|
|
||||||
shadow_reduce_modes.push_back("\n#define MODE_REDUCE_SUBGROUP\n");
|
|
||||||
shadow_reduce_modes.push_back("\n#define MODE_REDUCE_SUBGROUP\n#define MODE_REDUCE_8\n");
|
|
||||||
shadow_reduce_modes.push_back("\n#define MODE_FILTER\n");
|
|
||||||
|
|
||||||
shadow_reduce.shader.initialize(shadow_reduce_modes);
|
|
||||||
|
|
||||||
shadow_reduce.shader_version = shadow_reduce.shader.version_create();
|
|
||||||
|
|
||||||
for (int i = 0; i < SHADOW_REDUCE_MAX; i++) {
|
|
||||||
shadow_reduce.pipelines[i] = RD::get_singleton()->compute_pipeline_create(shadow_reduce.shader.version_get_shader(shadow_reduce.shader_version, i));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
{
|
{
|
||||||
Vector<String> sort_modes;
|
Vector<String> sort_modes;
|
||||||
sort_modes.push_back("\n#define MODE_SORT_BLOCK\n");
|
sort_modes.push_back("\n#define MODE_SORT_BLOCK\n");
|
||||||
|
@ -2076,5 +2006,4 @@ EffectsRD::~EffectsRD() {
|
||||||
ssr_scale.shader.version_free(ssr_scale.shader_version);
|
ssr_scale.shader.version_free(ssr_scale.shader_version);
|
||||||
sss.shader.version_free(sss.shader_version);
|
sss.shader.version_free(sss.shader_version);
|
||||||
tonemap.shader.version_free(tonemap.shader_version);
|
tonemap.shader.version_free(tonemap.shader_version);
|
||||||
shadow_reduce.shader.version_free(shadow_reduce.shader_version);
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -46,7 +46,6 @@
|
||||||
#include "servers/rendering/renderer_rd/shaders/screen_space_reflection.glsl.gen.h"
|
#include "servers/rendering/renderer_rd/shaders/screen_space_reflection.glsl.gen.h"
|
||||||
#include "servers/rendering/renderer_rd/shaders/screen_space_reflection_filter.glsl.gen.h"
|
#include "servers/rendering/renderer_rd/shaders/screen_space_reflection_filter.glsl.gen.h"
|
||||||
#include "servers/rendering/renderer_rd/shaders/screen_space_reflection_scale.glsl.gen.h"
|
#include "servers/rendering/renderer_rd/shaders/screen_space_reflection_scale.glsl.gen.h"
|
||||||
#include "servers/rendering/renderer_rd/shaders/shadow_reduce.glsl.gen.h"
|
|
||||||
#include "servers/rendering/renderer_rd/shaders/sort.glsl.gen.h"
|
#include "servers/rendering/renderer_rd/shaders/sort.glsl.gen.h"
|
||||||
#include "servers/rendering/renderer_rd/shaders/specular_merge.glsl.gen.h"
|
#include "servers/rendering/renderer_rd/shaders/specular_merge.glsl.gen.h"
|
||||||
#include "servers/rendering/renderer_rd/shaders/ssao.glsl.gen.h"
|
#include "servers/rendering/renderer_rd/shaders/ssao.glsl.gen.h"
|
||||||
|
@ -597,20 +596,6 @@ class EffectsRD {
|
||||||
RID pipelines[RESOLVE_MODE_MAX]; //3 quality levels
|
RID pipelines[RESOLVE_MODE_MAX]; //3 quality levels
|
||||||
} resolve;
|
} resolve;
|
||||||
|
|
||||||
enum ShadowReduceMode {
|
|
||||||
SHADOW_REDUCE_REDUCE,
|
|
||||||
SHADOW_REDUCE_REDUCE_SUBGROUPS,
|
|
||||||
SHADOW_REDUCE_REDUCE_SUBGROUPS_8,
|
|
||||||
SHADOW_REDUCE_FILTER,
|
|
||||||
SHADOW_REDUCE_MAX
|
|
||||||
};
|
|
||||||
|
|
||||||
struct ShadowReduce {
|
|
||||||
ShadowReduceShaderRD shader;
|
|
||||||
RID shader_version;
|
|
||||||
RID pipelines[SHADOW_REDUCE_MAX];
|
|
||||||
} shadow_reduce;
|
|
||||||
|
|
||||||
enum SortMode {
|
enum SortMode {
|
||||||
SORT_MODE_BLOCK,
|
SORT_MODE_BLOCK,
|
||||||
SORT_MODE_STEP,
|
SORT_MODE_STEP,
|
||||||
|
@ -767,9 +752,6 @@ public:
|
||||||
|
|
||||||
void resolve_gi(RID p_source_depth, RID p_source_normal_roughness, RID p_source_giprobe, RID p_dest_depth, RID p_dest_normal_roughness, RID p_dest_giprobe, Vector2i p_screen_size, int p_samples, uint32_t p_barrier = RD::BARRIER_MASK_ALL);
|
void resolve_gi(RID p_source_depth, RID p_source_normal_roughness, RID p_source_giprobe, RID p_dest_depth, RID p_dest_normal_roughness, RID p_dest_giprobe, Vector2i p_screen_size, int p_samples, uint32_t p_barrier = RD::BARRIER_MASK_ALL);
|
||||||
|
|
||||||
void reduce_shadow(RID p_source_shadow, RID p_dest_shadow, const Size2i &p_source_size, const Rect2i &p_source_rect, int p_shrink_limit, RenderingDevice::ComputeListID compute_list);
|
|
||||||
void filter_shadow(RID p_shadow, RID p_backing_shadow, const Size2i &p_source_size, const Rect2i &p_source_rect, RS::EnvVolumetricFogShadowFilter p_filter, RenderingDevice::ComputeListID compute_list, bool p_vertical = true, bool p_horizontal = true);
|
|
||||||
|
|
||||||
void sort_buffer(RID p_uniform_set, int p_size);
|
void sort_buffer(RID p_uniform_set, int p_size);
|
||||||
|
|
||||||
EffectsRD();
|
EffectsRD();
|
||||||
|
|
|
@ -3151,7 +3151,7 @@ float RendererSceneRenderRD::environment_get_fog_aerial_perspective(RID p_env) c
|
||||||
return env->fog_aerial_perspective;
|
return env->fog_aerial_perspective;
|
||||||
}
|
}
|
||||||
|
|
||||||
void RendererSceneRenderRD::environment_set_volumetric_fog(RID p_env, bool p_enable, float p_density, const Color &p_light, float p_light_energy, float p_length, float p_detail_spread, float p_gi_inject, RenderingServer::EnvVolumetricFogShadowFilter p_shadow_filter, bool p_temporal_reprojection, float p_temporal_reprojection_amount) {
|
void RendererSceneRenderRD::environment_set_volumetric_fog(RID p_env, bool p_enable, float p_density, const Color &p_light, float p_light_energy, float p_length, float p_detail_spread, float p_gi_inject, bool p_temporal_reprojection, float p_temporal_reprojection_amount) {
|
||||||
Environment *env = environment_owner.getornull(p_env);
|
Environment *env = environment_owner.getornull(p_env);
|
||||||
ERR_FAIL_COND(!env);
|
ERR_FAIL_COND(!env);
|
||||||
|
|
||||||
|
@ -3165,7 +3165,6 @@ void RendererSceneRenderRD::environment_set_volumetric_fog(RID p_env, bool p_ena
|
||||||
env->volumetric_fog_light_energy = p_light_energy;
|
env->volumetric_fog_light_energy = p_light_energy;
|
||||||
env->volumetric_fog_length = p_length;
|
env->volumetric_fog_length = p_length;
|
||||||
env->volumetric_fog_detail_spread = p_detail_spread;
|
env->volumetric_fog_detail_spread = p_detail_spread;
|
||||||
env->volumetric_fog_shadow_filter = p_shadow_filter;
|
|
||||||
env->volumetric_fog_gi_inject = p_gi_inject;
|
env->volumetric_fog_gi_inject = p_gi_inject;
|
||||||
env->volumetric_fog_temporal_reprojection = p_temporal_reprojection;
|
env->volumetric_fog_temporal_reprojection = p_temporal_reprojection;
|
||||||
env->volumetric_fog_temporal_reprojection_amount = p_temporal_reprojection_amount;
|
env->volumetric_fog_temporal_reprojection_amount = p_temporal_reprojection_amount;
|
||||||
|
@ -3179,25 +3178,6 @@ void RendererSceneRenderRD::environment_set_volumetric_fog_volume_size(int p_siz
|
||||||
void RendererSceneRenderRD::environment_set_volumetric_fog_filter_active(bool p_enable) {
|
void RendererSceneRenderRD::environment_set_volumetric_fog_filter_active(bool p_enable) {
|
||||||
volumetric_fog_filter_active = p_enable;
|
volumetric_fog_filter_active = p_enable;
|
||||||
}
|
}
|
||||||
void RendererSceneRenderRD::environment_set_volumetric_fog_directional_shadow_shrink_size(int p_shrink_size) {
|
|
||||||
p_shrink_size = nearest_power_of_2_templated(p_shrink_size);
|
|
||||||
if (volumetric_fog_directional_shadow_shrink == (uint32_t)p_shrink_size) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
_clear_shadow_shrink_stages(directional_shadow.shrink_stages);
|
|
||||||
}
|
|
||||||
void RendererSceneRenderRD::environment_set_volumetric_fog_positional_shadow_shrink_size(int p_shrink_size) {
|
|
||||||
p_shrink_size = nearest_power_of_2_templated(p_shrink_size);
|
|
||||||
if (volumetric_fog_positional_shadow_shrink == (uint32_t)p_shrink_size) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (uint32_t i = 0; i < shadow_atlas_owner.get_rid_count(); i++) {
|
|
||||||
ShadowAtlas *sa = shadow_atlas_owner.get_ptr_by_index(i);
|
|
||||||
_clear_shadow_shrink_stages(sa->shrink_stages);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void RendererSceneRenderRD::environment_set_sdfgi_ray_count(RS::EnvironmentSDFGIRayCount p_ray_count) {
|
void RendererSceneRenderRD::environment_set_sdfgi_ray_count(RS::EnvironmentSDFGIRayCount p_ray_count) {
|
||||||
sdfgi_ray_count = p_ray_count;
|
sdfgi_ray_count = p_ray_count;
|
||||||
|
@ -3649,7 +3629,6 @@ void RendererSceneRenderRD::shadow_atlas_set_size(RID p_atlas, int p_size, bool
|
||||||
if (shadow_atlas->depth.is_valid()) {
|
if (shadow_atlas->depth.is_valid()) {
|
||||||
RD::get_singleton()->free(shadow_atlas->depth);
|
RD::get_singleton()->free(shadow_atlas->depth);
|
||||||
shadow_atlas->depth = RID();
|
shadow_atlas->depth = RID();
|
||||||
_clear_shadow_shrink_stages(shadow_atlas->shrink_stages);
|
|
||||||
}
|
}
|
||||||
for (int i = 0; i < 4; i++) {
|
for (int i = 0; i < 4; i++) {
|
||||||
//clear subdivisions
|
//clear subdivisions
|
||||||
|
@ -3948,7 +3927,6 @@ void RendererSceneRenderRD::directional_shadow_atlas_set_size(int p_size, bool p
|
||||||
|
|
||||||
if (directional_shadow.depth.is_valid()) {
|
if (directional_shadow.depth.is_valid()) {
|
||||||
RD::get_singleton()->free(directional_shadow.depth);
|
RD::get_singleton()->free(directional_shadow.depth);
|
||||||
_clear_shadow_shrink_stages(directional_shadow.shrink_stages);
|
|
||||||
directional_shadow.depth = RID();
|
directional_shadow.depth = RID();
|
||||||
_base_uniforms_changed();
|
_base_uniforms_changed();
|
||||||
}
|
}
|
||||||
|
@ -6480,8 +6458,6 @@ void RendererSceneRenderRD::_setup_lights(const PagedArray<RID> &p_lights, const
|
||||||
LightInstance *li = (i < cluster.omni_light_count) ? cluster.omni_light_sort[index].instance : cluster.spot_light_sort[index].instance;
|
LightInstance *li = (i < cluster.omni_light_count) ? cluster.omni_light_sort[index].instance : cluster.spot_light_sort[index].instance;
|
||||||
RID base = li->light;
|
RID base = li->light;
|
||||||
|
|
||||||
cluster.lights_instances[i] = li->self;
|
|
||||||
|
|
||||||
Transform light_transform = li->transform;
|
Transform light_transform = li->transform;
|
||||||
|
|
||||||
float sign = storage->light_is_negative(base) ? -1 : 1;
|
float sign = storage->light_is_negative(base) ? -1 : 1;
|
||||||
|
@ -6820,49 +6796,6 @@ void RendererSceneRenderRD::_volumetric_fog_erase(RenderBuffers *rb) {
|
||||||
rb->volumetric_fog = nullptr;
|
rb->volumetric_fog = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
void RendererSceneRenderRD::_allocate_shadow_shrink_stages(RID p_base, int p_base_size, Vector<ShadowShrinkStage> &shrink_stages, uint32_t p_target_size) {
|
|
||||||
//create fog mipmaps
|
|
||||||
uint32_t fog_texture_size = p_target_size;
|
|
||||||
uint32_t base_texture_size = p_base_size;
|
|
||||||
|
|
||||||
ShadowShrinkStage first;
|
|
||||||
first.size = base_texture_size;
|
|
||||||
first.texture = p_base;
|
|
||||||
shrink_stages.push_back(first); //put depth first in case we dont find smaller ones
|
|
||||||
|
|
||||||
while (fog_texture_size < base_texture_size) {
|
|
||||||
base_texture_size = MAX(base_texture_size / 8, fog_texture_size);
|
|
||||||
|
|
||||||
ShadowShrinkStage s;
|
|
||||||
s.size = base_texture_size;
|
|
||||||
|
|
||||||
RD::TextureFormat tf;
|
|
||||||
tf.format = RD::DATA_FORMAT_R16_UNORM;
|
|
||||||
tf.width = base_texture_size;
|
|
||||||
tf.height = base_texture_size;
|
|
||||||
tf.usage_bits = RD::TEXTURE_USAGE_STORAGE_BIT;
|
|
||||||
|
|
||||||
if (base_texture_size == fog_texture_size) {
|
|
||||||
s.filter_texture = RD::get_singleton()->texture_create(tf, RD::TextureView());
|
|
||||||
tf.usage_bits |= RD::TEXTURE_USAGE_SAMPLING_BIT;
|
|
||||||
}
|
|
||||||
|
|
||||||
s.texture = RD::get_singleton()->texture_create(tf, RD::TextureView());
|
|
||||||
|
|
||||||
shrink_stages.push_back(s);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void RendererSceneRenderRD::_clear_shadow_shrink_stages(Vector<ShadowShrinkStage> &shrink_stages) {
|
|
||||||
for (int i = 1; i < shrink_stages.size(); i++) {
|
|
||||||
RD::get_singleton()->free(shrink_stages[i].texture);
|
|
||||||
if (shrink_stages[i].filter_texture.is_valid()) {
|
|
||||||
RD::get_singleton()->free(shrink_stages[i].filter_texture);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
shrink_stages.clear();
|
|
||||||
}
|
|
||||||
|
|
||||||
void RendererSceneRenderRD::_update_volumetric_fog(RID p_render_buffers, RID p_environment, const CameraMatrix &p_cam_projection, const Transform &p_cam_transform, RID p_shadow_atlas, int p_directional_light_count, bool p_use_directional_shadows, int p_positional_light_count, int p_gi_probe_count) {
|
void RendererSceneRenderRD::_update_volumetric_fog(RID p_render_buffers, RID p_environment, const CameraMatrix &p_cam_projection, const Transform &p_cam_transform, RID p_shadow_atlas, int p_directional_light_count, bool p_use_directional_shadows, int p_positional_light_count, int p_gi_probe_count) {
|
||||||
RenderBuffers *rb = render_buffers_owner.getornull(p_render_buffers);
|
RenderBuffers *rb = render_buffers_owner.getornull(p_render_buffers);
|
||||||
ERR_FAIL_COND(!rb);
|
ERR_FAIL_COND(!rb);
|
||||||
|
@ -6926,173 +6859,6 @@ void RendererSceneRenderRD::_update_volumetric_fog(RID p_render_buffers, RID p_e
|
||||||
rb->volumetric_fog->sky_uniform_set = RD::get_singleton()->uniform_set_create(uniforms, sky_shader.default_shader_rd, SKY_SET_FOG);
|
rb->volumetric_fog->sky_uniform_set = RD::get_singleton()->uniform_set_create(uniforms, sky_shader.default_shader_rd, SKY_SET_FOG);
|
||||||
}
|
}
|
||||||
|
|
||||||
//update directional shadow
|
|
||||||
|
|
||||||
RENDER_TIMESTAMP("Downsample Shadows");
|
|
||||||
|
|
||||||
if (p_use_directional_shadows) {
|
|
||||||
RD::get_singleton()->draw_command_begin_label("Downsample Directional Shadows");
|
|
||||||
|
|
||||||
if (directional_shadow.shrink_stages.is_empty()) {
|
|
||||||
if (rb->volumetric_fog->uniform_set.is_valid() && RD::get_singleton()->uniform_set_is_valid(rb->volumetric_fog->uniform_set)) {
|
|
||||||
//invalidate uniform set, we will need a new one
|
|
||||||
RD::get_singleton()->free(rb->volumetric_fog->uniform_set);
|
|
||||||
rb->volumetric_fog->uniform_set = RID();
|
|
||||||
}
|
|
||||||
_allocate_shadow_shrink_stages(directional_shadow.depth, directional_shadow.size, directional_shadow.shrink_stages, volumetric_fog_directional_shadow_shrink);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (directional_shadow.shrink_stages.size() > 1) {
|
|
||||||
RD::ComputeListID compute_list = RD::get_singleton()->compute_list_begin();
|
|
||||||
for (int i = 1; i < directional_shadow.shrink_stages.size(); i++) {
|
|
||||||
int32_t src_size = directional_shadow.shrink_stages[i - 1].size;
|
|
||||||
int32_t dst_size = directional_shadow.shrink_stages[i].size;
|
|
||||||
Rect2i r(0, 0, src_size, src_size);
|
|
||||||
int32_t shrink_limit = 8 / (src_size / dst_size);
|
|
||||||
|
|
||||||
storage->get_effects()->reduce_shadow(directional_shadow.shrink_stages[i - 1].texture, directional_shadow.shrink_stages[i].texture, Size2i(src_size, src_size), r, shrink_limit, compute_list);
|
|
||||||
RD::get_singleton()->compute_list_add_barrier(compute_list);
|
|
||||||
if (env->volumetric_fog_shadow_filter != RS::ENV_VOLUMETRIC_FOG_SHADOW_FILTER_DISABLED && directional_shadow.shrink_stages[i].filter_texture.is_valid()) {
|
|
||||||
Rect2i rf(0, 0, dst_size, dst_size);
|
|
||||||
storage->get_effects()->filter_shadow(directional_shadow.shrink_stages[i].texture, directional_shadow.shrink_stages[i].filter_texture, Size2i(dst_size, dst_size), rf, env->volumetric_fog_shadow_filter, compute_list);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
RD::get_singleton()->compute_list_end();
|
|
||||||
}
|
|
||||||
RD::get_singleton()->draw_command_end_label();
|
|
||||||
}
|
|
||||||
|
|
||||||
ShadowAtlas *shadow_atlas = shadow_atlas_owner.getornull(p_shadow_atlas);
|
|
||||||
|
|
||||||
if (shadow_atlas) {
|
|
||||||
//shrink shadows that need to be shrunk
|
|
||||||
|
|
||||||
RD::get_singleton()->draw_command_begin_label("Downsample Positional Shadows");
|
|
||||||
|
|
||||||
bool force_shrink_shadows = false;
|
|
||||||
|
|
||||||
if (shadow_atlas->shrink_stages.is_empty()) {
|
|
||||||
if (rb->volumetric_fog->uniform_set.is_valid() && RD::get_singleton()->uniform_set_is_valid(rb->volumetric_fog->uniform_set)) {
|
|
||||||
//invalidate uniform set, we will need a new one
|
|
||||||
RD::get_singleton()->free(rb->volumetric_fog->uniform_set);
|
|
||||||
rb->volumetric_fog->uniform_set = RID();
|
|
||||||
}
|
|
||||||
_allocate_shadow_shrink_stages(shadow_atlas->depth, shadow_atlas->size, shadow_atlas->shrink_stages, volumetric_fog_positional_shadow_shrink);
|
|
||||||
force_shrink_shadows = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (rb->volumetric_fog->last_shadow_filter != env->volumetric_fog_shadow_filter) {
|
|
||||||
//if shadow filter changed, invalidate caches
|
|
||||||
rb->volumetric_fog->last_shadow_filter = env->volumetric_fog_shadow_filter;
|
|
||||||
force_shrink_shadows = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
cluster.lights_shadow_rect_cache_count = 0;
|
|
||||||
|
|
||||||
for (uint32_t i = 0; i < cluster.omni_light_count + cluster.spot_light_count; i++) {
|
|
||||||
Cluster::LightData &ld = i < cluster.omni_light_count ? cluster.omni_lights[i] : cluster.spot_lights[i - cluster.omni_light_count];
|
|
||||||
|
|
||||||
if (ld.shadow_enabled != 0) {
|
|
||||||
RID li = cluster.lights_instances[i];
|
|
||||||
|
|
||||||
ERR_CONTINUE(!shadow_atlas->shadow_owners.has(li));
|
|
||||||
|
|
||||||
uint32_t key = shadow_atlas->shadow_owners[li];
|
|
||||||
|
|
||||||
uint32_t quadrant = (key >> ShadowAtlas::QUADRANT_SHIFT) & 0x3;
|
|
||||||
uint32_t shadow = key & ShadowAtlas::SHADOW_INDEX_MASK;
|
|
||||||
|
|
||||||
ERR_CONTINUE((int)shadow >= shadow_atlas->quadrants[quadrant].shadows.size());
|
|
||||||
|
|
||||||
ShadowAtlas::Quadrant::Shadow &s = shadow_atlas->quadrants[quadrant].shadows.write[shadow];
|
|
||||||
|
|
||||||
if (!force_shrink_shadows && s.fog_version == s.version) {
|
|
||||||
continue; //do not update, no need
|
|
||||||
}
|
|
||||||
|
|
||||||
s.fog_version = s.version;
|
|
||||||
|
|
||||||
uint32_t quadrant_size = shadow_atlas->size >> 1;
|
|
||||||
|
|
||||||
Rect2i atlas_rect;
|
|
||||||
|
|
||||||
atlas_rect.position.x = (quadrant & 1) * quadrant_size;
|
|
||||||
atlas_rect.position.y = (quadrant >> 1) * quadrant_size;
|
|
||||||
|
|
||||||
uint32_t shadow_size = (quadrant_size / shadow_atlas->quadrants[quadrant].subdivision);
|
|
||||||
atlas_rect.position.x += (shadow % shadow_atlas->quadrants[quadrant].subdivision) * shadow_size;
|
|
||||||
atlas_rect.position.y += (shadow / shadow_atlas->quadrants[quadrant].subdivision) * shadow_size;
|
|
||||||
|
|
||||||
atlas_rect.size.x = shadow_size;
|
|
||||||
atlas_rect.size.y = shadow_size;
|
|
||||||
|
|
||||||
cluster.lights_shadow_rect_cache[cluster.lights_shadow_rect_cache_count] = atlas_rect;
|
|
||||||
|
|
||||||
cluster.lights_shadow_rect_cache_count++;
|
|
||||||
|
|
||||||
if (cluster.lights_shadow_rect_cache_count == cluster.max_lights * 2) {
|
|
||||||
break; //light limit reached
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (cluster.lights_shadow_rect_cache_count > 0) {
|
|
||||||
//there are shadows to be shrunk, try to do them in parallel
|
|
||||||
RD::ComputeListID compute_list = RD::get_singleton()->compute_list_begin();
|
|
||||||
|
|
||||||
for (int i = 1; i < shadow_atlas->shrink_stages.size(); i++) {
|
|
||||||
int32_t base_size = shadow_atlas->shrink_stages[0].size;
|
|
||||||
int32_t src_size = shadow_atlas->shrink_stages[i - 1].size;
|
|
||||||
int32_t dst_size = shadow_atlas->shrink_stages[i].size;
|
|
||||||
|
|
||||||
uint32_t rect_divisor = base_size / src_size;
|
|
||||||
|
|
||||||
int32_t shrink_limit = 8 / (src_size / dst_size);
|
|
||||||
|
|
||||||
//shrink in parallel for more performance
|
|
||||||
for (uint32_t j = 0; j < cluster.lights_shadow_rect_cache_count; j++) {
|
|
||||||
Rect2i src_rect = cluster.lights_shadow_rect_cache[j];
|
|
||||||
|
|
||||||
src_rect.position /= rect_divisor;
|
|
||||||
src_rect.size /= rect_divisor;
|
|
||||||
|
|
||||||
storage->get_effects()->reduce_shadow(shadow_atlas->shrink_stages[i - 1].texture, shadow_atlas->shrink_stages[i].texture, Size2i(src_size, src_size), src_rect, shrink_limit, compute_list);
|
|
||||||
}
|
|
||||||
|
|
||||||
RD::get_singleton()->compute_list_add_barrier(compute_list);
|
|
||||||
|
|
||||||
if (env->volumetric_fog_shadow_filter != RS::ENV_VOLUMETRIC_FOG_SHADOW_FILTER_DISABLED && shadow_atlas->shrink_stages[i].filter_texture.is_valid()) {
|
|
||||||
uint32_t filter_divisor = base_size / dst_size;
|
|
||||||
|
|
||||||
//filter in parallel for more performance
|
|
||||||
for (uint32_t j = 0; j < cluster.lights_shadow_rect_cache_count; j++) {
|
|
||||||
Rect2i dst_rect = cluster.lights_shadow_rect_cache[j];
|
|
||||||
|
|
||||||
dst_rect.position /= filter_divisor;
|
|
||||||
dst_rect.size /= filter_divisor;
|
|
||||||
|
|
||||||
storage->get_effects()->filter_shadow(shadow_atlas->shrink_stages[i].texture, shadow_atlas->shrink_stages[i].filter_texture, Size2i(dst_size, dst_size), dst_rect, env->volumetric_fog_shadow_filter, compute_list, true, false);
|
|
||||||
}
|
|
||||||
|
|
||||||
RD::get_singleton()->compute_list_add_barrier(compute_list);
|
|
||||||
|
|
||||||
for (uint32_t j = 0; j < cluster.lights_shadow_rect_cache_count; j++) {
|
|
||||||
Rect2i dst_rect = cluster.lights_shadow_rect_cache[j];
|
|
||||||
|
|
||||||
dst_rect.position /= filter_divisor;
|
|
||||||
dst_rect.size /= filter_divisor;
|
|
||||||
|
|
||||||
storage->get_effects()->filter_shadow(shadow_atlas->shrink_stages[i].texture, shadow_atlas->shrink_stages[i].filter_texture, Size2i(dst_size, dst_size), dst_rect, env->volumetric_fog_shadow_filter, compute_list, false, true);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
RD::get_singleton()->compute_list_end(RD::BARRIER_MASK_COMPUTE);
|
|
||||||
}
|
|
||||||
|
|
||||||
RD::get_singleton()->draw_command_end_label();
|
|
||||||
}
|
|
||||||
|
|
||||||
//update volumetric fog
|
//update volumetric fog
|
||||||
|
|
||||||
if (rb->volumetric_fog->uniform_set.is_null() || !RD::get_singleton()->uniform_set_is_valid(rb->volumetric_fog->uniform_set)) {
|
if (rb->volumetric_fog->uniform_set.is_null() || !RD::get_singleton()->uniform_set_is_valid(rb->volumetric_fog->uniform_set)) {
|
||||||
|
@ -7104,10 +6870,11 @@ void RendererSceneRenderRD::_update_volumetric_fog(RID p_render_buffers, RID p_e
|
||||||
RD::Uniform u;
|
RD::Uniform u;
|
||||||
u.uniform_type = RD::UNIFORM_TYPE_TEXTURE;
|
u.uniform_type = RD::UNIFORM_TYPE_TEXTURE;
|
||||||
u.binding = 1;
|
u.binding = 1;
|
||||||
if (shadow_atlas == nullptr || shadow_atlas->shrink_stages.size() == 0) {
|
ShadowAtlas *shadow_atlas = shadow_atlas_owner.getornull(p_shadow_atlas);
|
||||||
|
if (shadow_atlas == nullptr || shadow_atlas->depth.is_null()) {
|
||||||
u.ids.push_back(storage->texture_rd_get_default(RendererStorageRD::DEFAULT_RD_TEXTURE_BLACK));
|
u.ids.push_back(storage->texture_rd_get_default(RendererStorageRD::DEFAULT_RD_TEXTURE_BLACK));
|
||||||
} else {
|
} else {
|
||||||
u.ids.push_back(shadow_atlas->shrink_stages[shadow_atlas->shrink_stages.size() - 1].texture);
|
u.ids.push_back(shadow_atlas->depth);
|
||||||
}
|
}
|
||||||
|
|
||||||
uniforms.push_back(u);
|
uniforms.push_back(u);
|
||||||
|
@ -7117,10 +6884,10 @@ void RendererSceneRenderRD::_update_volumetric_fog(RID p_render_buffers, RID p_e
|
||||||
RD::Uniform u;
|
RD::Uniform u;
|
||||||
u.uniform_type = RD::UNIFORM_TYPE_TEXTURE;
|
u.uniform_type = RD::UNIFORM_TYPE_TEXTURE;
|
||||||
u.binding = 2;
|
u.binding = 2;
|
||||||
if (directional_shadow.shrink_stages.size() == 0) {
|
if (directional_shadow.depth.is_valid()) {
|
||||||
u.ids.push_back(storage->texture_rd_get_default(RendererStorageRD::DEFAULT_RD_TEXTURE_BLACK));
|
u.ids.push_back(directional_shadow.depth);
|
||||||
} else {
|
} else {
|
||||||
u.ids.push_back(directional_shadow.shrink_stages[directional_shadow.shrink_stages.size() - 1].texture);
|
u.ids.push_back(storage->texture_rd_get_default(RendererStorageRD::DEFAULT_RD_TEXTURE_BLACK));
|
||||||
}
|
}
|
||||||
uniforms.push_back(u);
|
uniforms.push_back(u);
|
||||||
}
|
}
|
||||||
|
@ -9079,10 +8846,6 @@ RendererSceneRenderRD::RendererSceneRenderRD(RendererStorageRD *p_storage) {
|
||||||
cluster.spot_light_sort = memnew_arr(Cluster::InstanceSort<LightInstance>, cluster.max_lights);
|
cluster.spot_light_sort = memnew_arr(Cluster::InstanceSort<LightInstance>, cluster.max_lights);
|
||||||
//defines += "\n#define MAX_LIGHT_DATA_STRUCTS " + itos(cluster.max_lights) + "\n";
|
//defines += "\n#define MAX_LIGHT_DATA_STRUCTS " + itos(cluster.max_lights) + "\n";
|
||||||
|
|
||||||
//used for volumetric fog shrinking
|
|
||||||
cluster.lights_instances = memnew_arr(RID, cluster.max_lights * 2);
|
|
||||||
cluster.lights_shadow_rect_cache = memnew_arr(Rect2i, cluster.max_lights * 2);
|
|
||||||
|
|
||||||
cluster.max_directional_lights = MAX_DIRECTIONAL_LIGHTS;
|
cluster.max_directional_lights = MAX_DIRECTIONAL_LIGHTS;
|
||||||
uint32_t directional_light_buffer_size = cluster.max_directional_lights * sizeof(Cluster::DirectionalLightData);
|
uint32_t directional_light_buffer_size = cluster.max_directional_lights * sizeof(Cluster::DirectionalLightData);
|
||||||
cluster.directional_lights = memnew_arr(Cluster::DirectionalLightData, cluster.max_directional_lights);
|
cluster.directional_lights = memnew_arr(Cluster::DirectionalLightData, cluster.max_directional_lights);
|
||||||
|
@ -9134,8 +8897,6 @@ RendererSceneRenderRD::RendererSceneRenderRD(RendererStorageRD *p_storage) {
|
||||||
|
|
||||||
environment_set_volumetric_fog_volume_size(GLOBAL_GET("rendering/volumetric_fog/volume_size"), GLOBAL_GET("rendering/volumetric_fog/volume_depth"));
|
environment_set_volumetric_fog_volume_size(GLOBAL_GET("rendering/volumetric_fog/volume_size"), GLOBAL_GET("rendering/volumetric_fog/volume_depth"));
|
||||||
environment_set_volumetric_fog_filter_active(GLOBAL_GET("rendering/volumetric_fog/use_filter"));
|
environment_set_volumetric_fog_filter_active(GLOBAL_GET("rendering/volumetric_fog/use_filter"));
|
||||||
environment_set_volumetric_fog_directional_shadow_shrink_size(GLOBAL_GET("rendering/volumetric_fog/directional_shadow_shrink"));
|
|
||||||
environment_set_volumetric_fog_positional_shadow_shrink_size(GLOBAL_GET("rendering/volumetric_fog/positional_shadow_shrink"));
|
|
||||||
|
|
||||||
cull_argument.set_page_pool(&cull_argument_pool);
|
cull_argument.set_page_pool(&cull_argument_pool);
|
||||||
|
|
||||||
|
@ -9197,8 +8958,6 @@ RendererSceneRenderRD::~RendererSceneRenderRD() {
|
||||||
memdelete_arr(cluster.spot_lights);
|
memdelete_arr(cluster.spot_lights);
|
||||||
memdelete_arr(cluster.omni_light_sort);
|
memdelete_arr(cluster.omni_light_sort);
|
||||||
memdelete_arr(cluster.spot_light_sort);
|
memdelete_arr(cluster.spot_light_sort);
|
||||||
memdelete_arr(cluster.lights_shadow_rect_cache);
|
|
||||||
memdelete_arr(cluster.lights_instances);
|
|
||||||
memdelete_arr(cluster.reflections);
|
memdelete_arr(cluster.reflections);
|
||||||
memdelete_arr(cluster.reflection_sort);
|
memdelete_arr(cluster.reflection_sort);
|
||||||
memdelete_arr(cluster.decals);
|
memdelete_arr(cluster.decals);
|
||||||
|
|
|
@ -591,8 +591,6 @@ private:
|
||||||
RID fb; //for copying
|
RID fb; //for copying
|
||||||
|
|
||||||
Map<RID, uint32_t> shadow_owners;
|
Map<RID, uint32_t> shadow_owners;
|
||||||
|
|
||||||
Vector<ShadowShrinkStage> shrink_stages;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
RID_Owner<ShadowAtlas> shadow_atlas_owner;
|
RID_Owner<ShadowAtlas> shadow_atlas_owner;
|
||||||
|
@ -626,13 +624,8 @@ private:
|
||||||
bool use_16_bits = false;
|
bool use_16_bits = false;
|
||||||
int current_light = 0;
|
int current_light = 0;
|
||||||
|
|
||||||
Vector<ShadowShrinkStage> shrink_stages;
|
|
||||||
|
|
||||||
} directional_shadow;
|
} directional_shadow;
|
||||||
|
|
||||||
void _allocate_shadow_shrink_stages(RID p_base, int p_base_size, Vector<ShadowShrinkStage> &shrink_stages, uint32_t p_target_size);
|
|
||||||
void _clear_shadow_shrink_stages(Vector<ShadowShrinkStage> &shrink_stages);
|
|
||||||
|
|
||||||
void _update_directional_shadow_atlas();
|
void _update_directional_shadow_atlas();
|
||||||
|
|
||||||
/* SHADOW CUBEMAPS */
|
/* SHADOW CUBEMAPS */
|
||||||
|
@ -743,10 +736,9 @@ private:
|
||||||
float volumetric_fog_light_energy = 0.0;
|
float volumetric_fog_light_energy = 0.0;
|
||||||
float volumetric_fog_length = 64.0;
|
float volumetric_fog_length = 64.0;
|
||||||
float volumetric_fog_detail_spread = 2.0;
|
float volumetric_fog_detail_spread = 2.0;
|
||||||
RS::EnvVolumetricFogShadowFilter volumetric_fog_shadow_filter = RS::ENV_VOLUMETRIC_FOG_SHADOW_FILTER_LOW;
|
|
||||||
float volumetric_fog_gi_inject = 0.0;
|
float volumetric_fog_gi_inject = 0.0;
|
||||||
bool volumetric_fog_temporal_reprojection = false;
|
bool volumetric_fog_temporal_reprojection = true;
|
||||||
float volumetric_fog_temporal_reprojection_amount = 0.95;
|
float volumetric_fog_temporal_reprojection_amount = 0.9;
|
||||||
|
|
||||||
/// Glow
|
/// Glow
|
||||||
|
|
||||||
|
@ -1471,10 +1463,6 @@ private:
|
||||||
uint32_t omni_light_count = 0;
|
uint32_t omni_light_count = 0;
|
||||||
uint32_t spot_light_count = 0;
|
uint32_t spot_light_count = 0;
|
||||||
|
|
||||||
RID *lights_instances;
|
|
||||||
Rect2i *lights_shadow_rect_cache;
|
|
||||||
uint32_t lights_shadow_rect_cache_count = 0;
|
|
||||||
|
|
||||||
DirectionalLightData *directional_lights;
|
DirectionalLightData *directional_lights;
|
||||||
uint32_t max_directional_lights;
|
uint32_t max_directional_lights;
|
||||||
RID directional_light_buffer;
|
RID directional_light_buffer;
|
||||||
|
@ -1594,9 +1582,7 @@ private:
|
||||||
|
|
||||||
uint32_t volumetric_fog_depth = 128;
|
uint32_t volumetric_fog_depth = 128;
|
||||||
uint32_t volumetric_fog_size = 128;
|
uint32_t volumetric_fog_size = 128;
|
||||||
bool volumetric_fog_filter_active = false;
|
bool volumetric_fog_filter_active = true;
|
||||||
uint32_t volumetric_fog_directional_shadow_shrink = 512;
|
|
||||||
uint32_t volumetric_fog_positional_shadow_shrink = 512;
|
|
||||||
|
|
||||||
void _volumetric_fog_erase(RenderBuffers *rb);
|
void _volumetric_fog_erase(RenderBuffers *rb);
|
||||||
void _update_volumetric_fog(RID p_render_buffers, RID p_environment, const CameraMatrix &p_cam_projection, const Transform &p_cam_transform, RID p_shadow_atlas, int p_directional_light_count, bool p_use_directional_shadows, int p_positional_light_count, int p_gi_probe_count);
|
void _update_volumetric_fog(RID p_render_buffers, RID p_environment, const CameraMatrix &p_cam_projection, const Transform &p_cam_transform, RID p_shadow_atlas, int p_directional_light_count, bool p_use_directional_shadows, int p_positional_light_count, int p_gi_probe_count);
|
||||||
|
@ -1721,12 +1707,10 @@ public:
|
||||||
float environment_get_fog_height_density(RID p_env) const;
|
float environment_get_fog_height_density(RID p_env) const;
|
||||||
float environment_get_fog_aerial_perspective(RID p_env) const;
|
float environment_get_fog_aerial_perspective(RID p_env) const;
|
||||||
|
|
||||||
void environment_set_volumetric_fog(RID p_env, bool p_enable, float p_density, const Color &p_light, float p_light_energy, float p_length, float p_detail_spread, float p_gi_inject, RS::EnvVolumetricFogShadowFilter p_shadow_filter, bool p_temporal_reprojection, float p_temporal_reprojection_amount);
|
void environment_set_volumetric_fog(RID p_env, bool p_enable, float p_density, const Color &p_light, float p_light_energy, float p_length, float p_detail_spread, float p_gi_inject, bool p_temporal_reprojection, float p_temporal_reprojection_amount);
|
||||||
|
|
||||||
virtual void environment_set_volumetric_fog_volume_size(int p_size, int p_depth);
|
virtual void environment_set_volumetric_fog_volume_size(int p_size, int p_depth);
|
||||||
virtual void environment_set_volumetric_fog_filter_active(bool p_enable);
|
virtual void environment_set_volumetric_fog_filter_active(bool p_enable);
|
||||||
virtual void environment_set_volumetric_fog_directional_shadow_shrink_size(int p_shrink_size);
|
|
||||||
virtual void environment_set_volumetric_fog_positional_shadow_shrink_size(int p_shrink_size);
|
|
||||||
|
|
||||||
void environment_set_ssr(RID p_env, bool p_enable, int p_max_steps, float p_fade_int, float p_fade_out, float p_depth_tolerance);
|
void environment_set_ssr(RID p_env, bool p_enable, int p_max_steps, float p_fade_int, float p_fade_out, float p_depth_tolerance);
|
||||||
void environment_set_ssao(RID p_env, bool p_enable, float p_radius, float p_intensity, float p_power, float p_detail, float p_horizon, float p_sharpness, float p_light_affect, float p_ao_channel_affect);
|
void environment_set_ssao(RID p_env, bool p_enable, float p_radius, float p_intensity, float p_power, float p_detail, float p_horizon, float p_sharpness, float p_light_affect, float p_ao_channel_affect);
|
||||||
|
|
|
@ -5371,7 +5371,7 @@ RID RendererStorageRD::light_create(RS::LightType p_type) {
|
||||||
light.param[RS::LIGHT_PARAM_SHADOW_BIAS] = 0.02;
|
light.param[RS::LIGHT_PARAM_SHADOW_BIAS] = 0.02;
|
||||||
light.param[RS::LIGHT_PARAM_SHADOW_BLUR] = 0;
|
light.param[RS::LIGHT_PARAM_SHADOW_BLUR] = 0;
|
||||||
light.param[RS::LIGHT_PARAM_SHADOW_PANCAKE_SIZE] = 20.0;
|
light.param[RS::LIGHT_PARAM_SHADOW_PANCAKE_SIZE] = 20.0;
|
||||||
light.param[RS::LIGHT_PARAM_SHADOW_VOLUMETRIC_FOG_FADE] = 1.0;
|
light.param[RS::LIGHT_PARAM_SHADOW_VOLUMETRIC_FOG_FADE] = 0.1;
|
||||||
light.param[RS::LIGHT_PARAM_TRANSMITTANCE_BIAS] = 0.05;
|
light.param[RS::LIGHT_PARAM_TRANSMITTANCE_BIAS] = 0.05;
|
||||||
|
|
||||||
return light_owner.make_rid(light);
|
return light_owner.make_rid(light);
|
||||||
|
|
|
@ -39,7 +39,6 @@ if "RD_GLSL" in env["BUILDERS"]:
|
||||||
env.RD_GLSL("sdfgi_debug.glsl")
|
env.RD_GLSL("sdfgi_debug.glsl")
|
||||||
env.RD_GLSL("sdfgi_debug_probes.glsl")
|
env.RD_GLSL("sdfgi_debug_probes.glsl")
|
||||||
env.RD_GLSL("volumetric_fog.glsl")
|
env.RD_GLSL("volumetric_fog.glsl")
|
||||||
env.RD_GLSL("shadow_reduce.glsl")
|
|
||||||
env.RD_GLSL("particles.glsl")
|
env.RD_GLSL("particles.glsl")
|
||||||
env.RD_GLSL("particles_copy.glsl")
|
env.RD_GLSL("particles_copy.glsl")
|
||||||
env.RD_GLSL("sort.glsl")
|
env.RD_GLSL("sort.glsl")
|
||||||
|
|
|
@ -1,163 +0,0 @@
|
||||||
#[compute]
|
|
||||||
|
|
||||||
#version 450
|
|
||||||
|
|
||||||
VERSION_DEFINES
|
|
||||||
|
|
||||||
#define BLOCK_SIZE 8
|
|
||||||
|
|
||||||
#ifdef MODE_REDUCE_SUBGROUP
|
|
||||||
|
|
||||||
#extension GL_KHR_shader_subgroup_ballot : enable
|
|
||||||
#extension GL_KHR_shader_subgroup_arithmetic : enable
|
|
||||||
|
|
||||||
//nvidia friendly, max 32
|
|
||||||
layout(local_size_x = 8, local_size_y = 4, local_size_z = 1) in;
|
|
||||||
|
|
||||||
#else
|
|
||||||
|
|
||||||
layout(local_size_x = BLOCK_SIZE, local_size_y = BLOCK_SIZE, local_size_z = 1) in;
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef MODE_REDUCE
|
|
||||||
|
|
||||||
shared float tmp_data[BLOCK_SIZE * BLOCK_SIZE];
|
|
||||||
const uint swizzle_table[BLOCK_SIZE] = uint[](0, 4, 2, 6, 1, 5, 3, 7);
|
|
||||||
const uint unswizzle_table[BLOCK_SIZE] = uint[](0, 0, 0, 1, 0, 2, 1, 3);
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if defined(MODE_REDUCE) || defined(MODE_REDUCE_SUBGROUP)
|
|
||||||
layout(set = 0, binding = 0) uniform sampler2D source_depth;
|
|
||||||
#else
|
|
||||||
layout(r16, set = 0, binding = 0) uniform restrict readonly image2D source_depth;
|
|
||||||
#endif
|
|
||||||
layout(r16, set = 1, binding = 0) uniform restrict writeonly image2D dst_depth;
|
|
||||||
|
|
||||||
layout(push_constant, binding = 1, std430) uniform Params {
|
|
||||||
ivec2 source_size;
|
|
||||||
ivec2 source_offset;
|
|
||||||
uint min_size;
|
|
||||||
uint gaussian_kernel_version;
|
|
||||||
ivec2 filter_dir;
|
|
||||||
}
|
|
||||||
params;
|
|
||||||
|
|
||||||
void main() {
|
|
||||||
#ifdef MODE_REDUCE_SUBGROUP
|
|
||||||
|
|
||||||
uvec2 local_pos = gl_LocalInvocationID.xy;
|
|
||||||
ivec2 image_offset = params.source_offset;
|
|
||||||
ivec2 image_pos = image_offset + ivec2(gl_GlobalInvocationID.xy * ivec2(1, 2));
|
|
||||||
|
|
||||||
float depth = texelFetch(source_depth, min(image_pos, params.source_size - ivec2(1)), 0).r;
|
|
||||||
depth += texelFetch(source_depth, min(image_pos + ivec2(0, 1), params.source_size - ivec2(1)), 0).r;
|
|
||||||
depth *= 0.5;
|
|
||||||
|
|
||||||
#ifdef MODE_REDUCE_8
|
|
||||||
//fast version, reduce all
|
|
||||||
float depth_average = subgroupAdd(depth) / 32.0;
|
|
||||||
if (local_pos == uvec2(0)) {
|
|
||||||
imageStore(dst_depth, image_pos / 8, vec4(depth_average));
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
//bit slower version, reduce by regions
|
|
||||||
uint group_size = (8 / params.min_size);
|
|
||||||
uvec2 group_id = local_pos / (8 / params.min_size);
|
|
||||||
|
|
||||||
uvec4 mask;
|
|
||||||
float depth_average = 0;
|
|
||||||
|
|
||||||
while (true) {
|
|
||||||
uvec2 first = subgroupBroadcastFirst(group_id);
|
|
||||||
mask = subgroupBallot(first == group_id);
|
|
||||||
if (first == group_id) {
|
|
||||||
depth_average = subgroupAdd(depth);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
depth_average /= float(group_size * group_size);
|
|
||||||
|
|
||||||
if (local_pos == group_id) {
|
|
||||||
imageStore(dst_depth, image_pos / int(group_size), vec4(depth_average));
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef MODE_REDUCE
|
|
||||||
|
|
||||||
uvec2 pos = gl_LocalInvocationID.xy;
|
|
||||||
|
|
||||||
ivec2 image_offset = params.source_offset;
|
|
||||||
ivec2 image_pos = image_offset + ivec2(gl_GlobalInvocationID.xy);
|
|
||||||
uint dst_t = swizzle_table[pos.y] * BLOCK_SIZE + swizzle_table[pos.x];
|
|
||||||
tmp_data[dst_t] = texelFetch(source_depth, min(image_pos, params.source_size - ivec2(1)), 0).r;
|
|
||||||
ivec2 image_size = params.source_size;
|
|
||||||
|
|
||||||
uint t = pos.y * BLOCK_SIZE + pos.x;
|
|
||||||
|
|
||||||
//neighbours
|
|
||||||
uint size = BLOCK_SIZE;
|
|
||||||
|
|
||||||
do {
|
|
||||||
groupMemoryBarrier();
|
|
||||||
barrier();
|
|
||||||
|
|
||||||
size >>= 1;
|
|
||||||
image_size >>= 1;
|
|
||||||
image_offset >>= 1;
|
|
||||||
|
|
||||||
if (all(lessThan(pos, uvec2(size)))) {
|
|
||||||
uint nx = t + size;
|
|
||||||
uint ny = t + (BLOCK_SIZE * size);
|
|
||||||
uint nxy = ny + size;
|
|
||||||
|
|
||||||
tmp_data[t] += tmp_data[nx];
|
|
||||||
tmp_data[t] += tmp_data[ny];
|
|
||||||
tmp_data[t] += tmp_data[nxy];
|
|
||||||
tmp_data[t] /= 4.0;
|
|
||||||
}
|
|
||||||
|
|
||||||
} while (size > params.min_size);
|
|
||||||
|
|
||||||
if (all(lessThan(pos, uvec2(size)))) {
|
|
||||||
image_pos = ivec2(unswizzle_table[size + pos.x], unswizzle_table[size + pos.y]);
|
|
||||||
image_pos += image_offset + ivec2(gl_WorkGroupID.xy) * int(size);
|
|
||||||
|
|
||||||
image_size = max(ivec2(1), image_size); //in case image size became 0
|
|
||||||
|
|
||||||
if (all(lessThan(image_pos, uvec2(image_size)))) {
|
|
||||||
imageStore(dst_depth, image_pos, vec4(tmp_data[t]));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef MODE_FILTER
|
|
||||||
|
|
||||||
ivec2 image_pos = params.source_offset + ivec2(gl_GlobalInvocationID.xy);
|
|
||||||
if (any(greaterThanEqual(image_pos, params.source_size))) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
ivec2 clamp_min = ivec2(params.source_offset);
|
|
||||||
ivec2 clamp_max = ivec2(params.source_size) - 1;
|
|
||||||
|
|
||||||
//gaussian kernel, size 9, sigma 4
|
|
||||||
const int kernel_size = 9;
|
|
||||||
const float gaussian_kernel[kernel_size * 3] = float[](
|
|
||||||
0.000229, 0.005977, 0.060598, 0.241732, 0.382928, 0.241732, 0.060598, 0.005977, 0.000229,
|
|
||||||
0.028532, 0.067234, 0.124009, 0.179044, 0.20236, 0.179044, 0.124009, 0.067234, 0.028532,
|
|
||||||
0.081812, 0.101701, 0.118804, 0.130417, 0.134535, 0.130417, 0.118804, 0.101701, 0.081812);
|
|
||||||
float accum = 0.0;
|
|
||||||
for (int i = 0; i < kernel_size; i++) {
|
|
||||||
ivec2 ofs = clamp(image_pos + params.filter_dir * (i - kernel_size / 2), clamp_min, clamp_max);
|
|
||||||
accum += imageLoad(source_depth, ofs).r * gaussian_kernel[params.gaussian_kernel_version + i];
|
|
||||||
}
|
|
||||||
|
|
||||||
imageStore(dst_depth, image_pos, vec4(accum));
|
|
||||||
|
|
||||||
#endif
|
|
||||||
}
|
|
|
@ -122,12 +122,10 @@ public:
|
||||||
virtual void environment_glow_set_use_bicubic_upscale(bool p_enable) = 0;
|
virtual void environment_glow_set_use_bicubic_upscale(bool p_enable) = 0;
|
||||||
virtual void environment_glow_set_use_high_quality(bool p_enable) = 0;
|
virtual void environment_glow_set_use_high_quality(bool p_enable) = 0;
|
||||||
|
|
||||||
virtual void environment_set_volumetric_fog(RID p_env, bool p_enable, float p_density, const Color &p_light, float p_light_energy, float p_length, float p_detail_spread, float p_gi_inject, RS::EnvVolumetricFogShadowFilter p_shadow_filter, bool p_temporal_reprojection, float p_temporal_reprojection_amount) = 0;
|
virtual void environment_set_volumetric_fog(RID p_env, bool p_enable, float p_density, const Color &p_light, float p_light_energy, float p_length, float p_detail_spread, float p_gi_inject, bool p_temporal_reprojection, float p_temporal_reprojection_amount) = 0;
|
||||||
|
|
||||||
virtual void environment_set_volumetric_fog_volume_size(int p_size, int p_depth) = 0;
|
virtual void environment_set_volumetric_fog_volume_size(int p_size, int p_depth) = 0;
|
||||||
virtual void environment_set_volumetric_fog_filter_active(bool p_enable) = 0;
|
virtual void environment_set_volumetric_fog_filter_active(bool p_enable) = 0;
|
||||||
virtual void environment_set_volumetric_fog_directional_shadow_shrink_size(int p_shrink_size) = 0;
|
|
||||||
virtual void environment_set_volumetric_fog_positional_shadow_shrink_size(int p_shrink_size) = 0;
|
|
||||||
|
|
||||||
virtual void environment_set_ssr(RID p_env, bool p_enable, int p_max_steps, float p_fade_int, float p_fade_out, float p_depth_tolerance) = 0;
|
virtual void environment_set_ssr(RID p_env, bool p_enable, int p_max_steps, float p_fade_int, float p_fade_out, float p_depth_tolerance) = 0;
|
||||||
virtual void environment_set_ssr_roughness_quality(RS::EnvironmentSSRRoughnessQuality p_quality) = 0;
|
virtual void environment_set_ssr_roughness_quality(RS::EnvironmentSSRRoughnessQuality p_quality) = 0;
|
||||||
|
|
|
@ -991,12 +991,10 @@ public:
|
||||||
PASS7(environment_set_adjustment, RID, bool, float, float, float, bool, RID)
|
PASS7(environment_set_adjustment, RID, bool, float, float, float, bool, RID)
|
||||||
|
|
||||||
PASS9(environment_set_fog, RID, bool, const Color &, float, float, float, float, float, float)
|
PASS9(environment_set_fog, RID, bool, const Color &, float, float, float, float, float, float)
|
||||||
PASS11(environment_set_volumetric_fog, RID, bool, float, const Color &, float, float, float, float, RS::EnvVolumetricFogShadowFilter, bool, float)
|
PASS10(environment_set_volumetric_fog, RID, bool, float, const Color &, float, float, float, float, bool, float)
|
||||||
|
|
||||||
PASS2(environment_set_volumetric_fog_volume_size, int, int)
|
PASS2(environment_set_volumetric_fog_volume_size, int, int)
|
||||||
PASS1(environment_set_volumetric_fog_filter_active, bool)
|
PASS1(environment_set_volumetric_fog_filter_active, bool)
|
||||||
PASS1(environment_set_volumetric_fog_directional_shadow_shrink_size, int)
|
|
||||||
PASS1(environment_set_volumetric_fog_positional_shadow_shrink_size, int)
|
|
||||||
|
|
||||||
PASS11(environment_set_sdfgi, RID, bool, RS::EnvironmentSDFGICascades, float, RS::EnvironmentSDFGIYScale, bool, bool, bool, float, float, float)
|
PASS11(environment_set_sdfgi, RID, bool, RS::EnvironmentSDFGICascades, float, RS::EnvironmentSDFGIYScale, bool, bool, bool, float, float, float)
|
||||||
PASS1(environment_set_sdfgi_ray_count, RS::EnvironmentSDFGIRayCount)
|
PASS1(environment_set_sdfgi_ray_count, RS::EnvironmentSDFGIRayCount)
|
||||||
|
|
|
@ -117,12 +117,9 @@ public:
|
||||||
virtual void environment_glow_set_use_bicubic_upscale(bool p_enable) = 0;
|
virtual void environment_glow_set_use_bicubic_upscale(bool p_enable) = 0;
|
||||||
virtual void environment_glow_set_use_high_quality(bool p_enable) = 0;
|
virtual void environment_glow_set_use_high_quality(bool p_enable) = 0;
|
||||||
|
|
||||||
virtual void environment_set_volumetric_fog(RID p_env, bool p_enable, float p_density, const Color &p_light, float p_light_energy, float p_length, float p_detail_spread, float p_gi_inject, RS::EnvVolumetricFogShadowFilter p_shadow_filter, bool p_temporal_reprojection, float p_temporal_reprojection_amount) = 0;
|
virtual void environment_set_volumetric_fog(RID p_env, bool p_enable, float p_density, const Color &p_light, float p_light_energy, float p_length, float p_detail_spread, float p_gi_inject, bool p_temporal_reprojection, float p_temporal_reprojection_amount) = 0;
|
||||||
|
|
||||||
virtual void environment_set_volumetric_fog_volume_size(int p_size, int p_depth) = 0;
|
virtual void environment_set_volumetric_fog_volume_size(int p_size, int p_depth) = 0;
|
||||||
virtual void environment_set_volumetric_fog_filter_active(bool p_enable) = 0;
|
virtual void environment_set_volumetric_fog_filter_active(bool p_enable) = 0;
|
||||||
virtual void environment_set_volumetric_fog_directional_shadow_shrink_size(int p_shrink_size) = 0;
|
|
||||||
virtual void environment_set_volumetric_fog_positional_shadow_shrink_size(int p_shrink_size) = 0;
|
|
||||||
|
|
||||||
virtual void environment_set_ssr(RID p_env, bool p_enable, int p_max_steps, float p_fade_int, float p_fade_out, float p_depth_tolerance) = 0;
|
virtual void environment_set_ssr(RID p_env, bool p_enable, int p_max_steps, float p_fade_int, float p_fade_out, float p_depth_tolerance) = 0;
|
||||||
virtual void environment_set_ssr_roughness_quality(RS::EnvironmentSSRRoughnessQuality p_quality) = 0;
|
virtual void environment_set_ssr_roughness_quality(RS::EnvironmentSSRRoughnessQuality p_quality) = 0;
|
||||||
|
|
|
@ -615,12 +615,10 @@ public:
|
||||||
BIND7(environment_set_adjustment, RID, bool, float, float, float, bool, RID)
|
BIND7(environment_set_adjustment, RID, bool, float, float, float, bool, RID)
|
||||||
|
|
||||||
BIND9(environment_set_fog, RID, bool, const Color &, float, float, float, float, float, float)
|
BIND9(environment_set_fog, RID, bool, const Color &, float, float, float, float, float, float)
|
||||||
BIND11(environment_set_volumetric_fog, RID, bool, float, const Color &, float, float, float, float, EnvVolumetricFogShadowFilter, bool, float)
|
BIND10(environment_set_volumetric_fog, RID, bool, float, const Color &, float, float, float, float, bool, float)
|
||||||
|
|
||||||
BIND2(environment_set_volumetric_fog_volume_size, int, int)
|
BIND2(environment_set_volumetric_fog_volume_size, int, int)
|
||||||
BIND1(environment_set_volumetric_fog_filter_active, bool)
|
BIND1(environment_set_volumetric_fog_filter_active, bool)
|
||||||
BIND1(environment_set_volumetric_fog_directional_shadow_shrink_size, int)
|
|
||||||
BIND1(environment_set_volumetric_fog_positional_shadow_shrink_size, int)
|
|
||||||
|
|
||||||
BIND11(environment_set_sdfgi, RID, bool, EnvironmentSDFGICascades, float, EnvironmentSDFGIYScale, bool, bool, bool, float, float, float)
|
BIND11(environment_set_sdfgi, RID, bool, EnvironmentSDFGICascades, float, EnvironmentSDFGIYScale, bool, bool, bool, float, float, float)
|
||||||
BIND1(environment_set_sdfgi_ray_count, EnvironmentSDFGIRayCount)
|
BIND1(environment_set_sdfgi_ray_count, EnvironmentSDFGIRayCount)
|
||||||
|
|
|
@ -520,12 +520,10 @@ public:
|
||||||
|
|
||||||
FUNC9(environment_set_fog, RID, bool, const Color &, float, float, float, float, float, float)
|
FUNC9(environment_set_fog, RID, bool, const Color &, float, float, float, float, float, float)
|
||||||
|
|
||||||
FUNC11(environment_set_volumetric_fog, RID, bool, float, const Color &, float, float, float, float, EnvVolumetricFogShadowFilter, bool, float)
|
FUNC10(environment_set_volumetric_fog, RID, bool, float, const Color &, float, float, float, float, bool, float)
|
||||||
|
|
||||||
FUNC2(environment_set_volumetric_fog_volume_size, int, int)
|
FUNC2(environment_set_volumetric_fog_volume_size, int, int)
|
||||||
FUNC1(environment_set_volumetric_fog_filter_active, bool)
|
FUNC1(environment_set_volumetric_fog_filter_active, bool)
|
||||||
FUNC1(environment_set_volumetric_fog_directional_shadow_shrink_size, int)
|
|
||||||
FUNC1(environment_set_volumetric_fog_positional_shadow_shrink_size, int)
|
|
||||||
|
|
||||||
FUNC3R(Ref<Image>, environment_bake_panorama, RID, bool, const Size2i &)
|
FUNC3R(Ref<Image>, environment_bake_panorama, RID, bool, const Size2i &)
|
||||||
|
|
||||||
|
|
|
@ -2371,12 +2371,8 @@ RenderingServer::RenderingServer() {
|
||||||
ProjectSettings::get_singleton()->set_custom_property_info("rendering/volumetric_fog/volume_size", PropertyInfo(Variant::INT, "rendering/volumetric_fog/volume_size", PROPERTY_HINT_RANGE, "16,512,1"));
|
ProjectSettings::get_singleton()->set_custom_property_info("rendering/volumetric_fog/volume_size", PropertyInfo(Variant::INT, "rendering/volumetric_fog/volume_size", PROPERTY_HINT_RANGE, "16,512,1"));
|
||||||
GLOBAL_DEF("rendering/volumetric_fog/volume_depth", 128);
|
GLOBAL_DEF("rendering/volumetric_fog/volume_depth", 128);
|
||||||
ProjectSettings::get_singleton()->set_custom_property_info("rendering/volumetric_fog/volume_depth", PropertyInfo(Variant::INT, "rendering/volumetric_fog/volume_depth", PROPERTY_HINT_RANGE, "16,512,1"));
|
ProjectSettings::get_singleton()->set_custom_property_info("rendering/volumetric_fog/volume_depth", PropertyInfo(Variant::INT, "rendering/volumetric_fog/volume_depth", PROPERTY_HINT_RANGE, "16,512,1"));
|
||||||
GLOBAL_DEF("rendering/volumetric_fog/use_filter", 0);
|
GLOBAL_DEF("rendering/volumetric_fog/use_filter", 1);
|
||||||
ProjectSettings::get_singleton()->set_custom_property_info("rendering/volumetric_fog/use_filter", PropertyInfo(Variant::INT, "rendering/volumetric_fog/use_filter", PROPERTY_HINT_ENUM, "No (Faster),Yes (Higher Quality)"));
|
ProjectSettings::get_singleton()->set_custom_property_info("rendering/volumetric_fog/use_filter", PropertyInfo(Variant::INT, "rendering/volumetric_fog/use_filter", PROPERTY_HINT_ENUM, "No (Faster),Yes (Higher Quality)"));
|
||||||
GLOBAL_DEF("rendering/volumetric_fog/directional_shadow_shrink", 512);
|
|
||||||
ProjectSettings::get_singleton()->set_custom_property_info("rendering/volumetric_fog/directional_shadow_shrink", PropertyInfo(Variant::INT, "rendering/volumetric_fog/directional_shadow_shrink", PROPERTY_HINT_RANGE, "32,2048,1"));
|
|
||||||
GLOBAL_DEF("rendering/volumetric_fog/positional_shadow_shrink", 512);
|
|
||||||
ProjectSettings::get_singleton()->set_custom_property_info("rendering/volumetric_fog/positional_shadow_shrink", PropertyInfo(Variant::INT, "rendering/volumetric_fog/positional_shadow_shrink", PROPERTY_HINT_RANGE, "32,2048,1"));
|
|
||||||
|
|
||||||
GLOBAL_DEF("rendering/spatial_indexer/update_iterations_per_frame", 10);
|
GLOBAL_DEF("rendering/spatial_indexer/update_iterations_per_frame", 10);
|
||||||
ProjectSettings::get_singleton()->set_custom_property_info("rendering/spatial_indexer/update_iterations_per_frame", PropertyInfo(Variant::INT, "rendering/spatial_indexer/update_iterations_per_frame", PROPERTY_HINT_RANGE, "0,1024,1"));
|
ProjectSettings::get_singleton()->set_custom_property_info("rendering/spatial_indexer/update_iterations_per_frame", PropertyInfo(Variant::INT, "rendering/spatial_indexer/update_iterations_per_frame", PROPERTY_HINT_RANGE, "0,1024,1"));
|
||||||
|
|
|
@ -1025,18 +1025,9 @@ public:
|
||||||
|
|
||||||
virtual void environment_set_fog(RID p_env, bool p_enable, const Color &p_light_color, float p_light_energy, float p_sun_scatter, float p_density, float p_height, float p_height_density, float p_aerial_perspective) = 0;
|
virtual void environment_set_fog(RID p_env, bool p_enable, const Color &p_light_color, float p_light_energy, float p_sun_scatter, float p_density, float p_height, float p_height_density, float p_aerial_perspective) = 0;
|
||||||
|
|
||||||
enum EnvVolumetricFogShadowFilter {
|
virtual void environment_set_volumetric_fog(RID p_env, bool p_enable, float p_density, const Color &p_light, float p_light_energy, float p_length, float p_detail_spread, float p_gi_inject, bool p_temporal_reprojection, float p_temporal_reprojection_amount) = 0;
|
||||||
ENV_VOLUMETRIC_FOG_SHADOW_FILTER_DISABLED,
|
|
||||||
ENV_VOLUMETRIC_FOG_SHADOW_FILTER_LOW,
|
|
||||||
ENV_VOLUMETRIC_FOG_SHADOW_FILTER_MEDIUM,
|
|
||||||
ENV_VOLUMETRIC_FOG_SHADOW_FILTER_HIGH,
|
|
||||||
};
|
|
||||||
|
|
||||||
virtual void environment_set_volumetric_fog(RID p_env, bool p_enable, float p_density, const Color &p_light, float p_light_energy, float p_length, float p_detail_spread, float p_gi_inject, EnvVolumetricFogShadowFilter p_shadow_filter, bool p_temporal_reprojection, float p_temporal_reprojection_amount) = 0;
|
|
||||||
virtual void environment_set_volumetric_fog_volume_size(int p_size, int p_depth) = 0;
|
virtual void environment_set_volumetric_fog_volume_size(int p_size, int p_depth) = 0;
|
||||||
virtual void environment_set_volumetric_fog_filter_active(bool p_enable) = 0;
|
virtual void environment_set_volumetric_fog_filter_active(bool p_enable) = 0;
|
||||||
virtual void environment_set_volumetric_fog_directional_shadow_shrink_size(int p_shrink_size) = 0;
|
|
||||||
virtual void environment_set_volumetric_fog_positional_shadow_shrink_size(int p_shrink_size) = 0;
|
|
||||||
|
|
||||||
virtual Ref<Image> environment_bake_panorama(RID p_env, bool p_bake_irradiance, const Size2i &p_size) = 0;
|
virtual Ref<Image> environment_bake_panorama(RID p_env, bool p_bake_irradiance, const Size2i &p_size) = 0;
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue