summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--doc/classes/Environment.xml47
-rw-r--r--doc/classes/RenderingServer.xml2
-rw-r--r--drivers/dummy/rasterizer_dummy.h2
-rw-r--r--scene/resources/environment.cpp69
-rw-r--r--scene/resources/environment.h9
-rw-r--r--servers/rendering/rasterizer.h2
-rw-r--r--servers/rendering/rasterizer_rd/rasterizer_effects_rd.cpp32
-rw-r--r--servers/rendering/rasterizer_rd/rasterizer_effects_rd.h10
-rw-r--r--servers/rendering/rasterizer_rd/rasterizer_scene_high_end_rd.cpp7
-rw-r--r--servers/rendering/rasterizer_rd/rasterizer_scene_rd.cpp22
-rw-r--r--servers/rendering/rasterizer_rd/rasterizer_scene_rd.h4
-rw-r--r--servers/rendering/rasterizer_rd/shaders/copy.glsl123
-rw-r--r--servers/rendering/rasterizer_rd/shaders/scene_high_end.glsl26
-rw-r--r--servers/rendering/rasterizer_rd/shaders/sky.glsl5
-rw-r--r--servers/rendering/rasterizer_rd/shaders/tonemap.glsl32
-rw-r--r--servers/rendering/rendering_server_raster.h2
-rw-r--r--servers/rendering/rendering_server_wrap_mt.h2
-rw-r--r--servers/rendering/shader_types.cpp4
-rw-r--r--servers/rendering_server.cpp2
-rw-r--r--servers/rendering_server.h2
20 files changed, 243 insertions, 161 deletions
diff --git a/doc/classes/Environment.xml b/doc/classes/Environment.xml
index 1fe5bca66c..8c4f9374ab 100644
--- a/doc/classes/Environment.xml
+++ b/doc/classes/Environment.xml
@@ -18,24 +18,24 @@
<link title="Third Person Shooter Demo">https://godotengine.org/asset-library/asset/678</link>
</tutorials>
<methods>
- <method name="is_glow_level_enabled" qualifiers="const">
- <return type="bool">
+ <method name="get_glow_level" qualifiers="const">
+ <return type="float">
</return>
<argument index="0" name="idx" type="int">
</argument>
<description>
- Returns [code]true[/code] if the glow level [code]idx[/code] is specified, [code]false[/code] otherwise.
+ Returns the intensity of the glow level [code]idx[/code].
</description>
</method>
- <method name="set_glow_level_enabled">
+ <method name="set_glow_level">
<return type="void">
</return>
<argument index="0" name="idx" type="int">
</argument>
- <argument index="1" name="enabled" type="bool">
+ <argument index="1" name="intensity" type="float">
</argument>
<description>
- Enables or disables the glow level at index [code]idx[/code]. Each level relies on the previous level. This means that enabling higher glow levels will slow down the glow effect rendering, even if previous levels aren't enabled.
+ Sets the intensity of the glow level [code]idx[/code]. A value above [code]0.0[/code] enables the level. Each level relies on the previous level. This means that enabling higher glow levels will slow down the glow effect rendering, even if previous levels aren't enabled.
</description>
</method>
</methods>
@@ -136,33 +136,36 @@
The lower threshold of the HDR glow. When using the GLES2 renderer (which doesn't support HDR), this needs to be below [code]1.0[/code] for glow to be visible. A value of [code]0.9[/code] works well in this case.
</member>
<member name="glow_intensity" type="float" setter="set_glow_intensity" getter="get_glow_intensity" default="0.8">
- The glow intensity. When using the GLES2 renderer, this should be increased to 1.5 to compensate for the lack of HDR rendering.
+ The overall brightness multiplier of the glow effect. When using the GLES2 renderer, this should be increased to 1.5 to compensate for the lack of HDR rendering.
</member>
- <member name="glow_levels/1" type="bool" setter="set_glow_level_enabled" getter="is_glow_level_enabled" default="false">
- If [code]true[/code], the 1st level of glow is enabled. This is the most "local" level (least blurry).
+ <member name="glow_levels/1" type="float" setter="set_glow_level" getter="get_glow_level" default="0.0">
+ The intensity of the 1st level of glow. This is the most "local" level (least blurry).
</member>
- <member name="glow_levels/2" type="bool" setter="set_glow_level_enabled" getter="is_glow_level_enabled" default="false">
- If [code]true[/code], the 2th level of glow is enabled.
+ <member name="glow_levels/2" type="float" setter="set_glow_level" getter="get_glow_level" default="0.0">
+ The intensity of the 2nd level of glow.
</member>
- <member name="glow_levels/3" type="bool" setter="set_glow_level_enabled" getter="is_glow_level_enabled" default="true">
- If [code]true[/code], the 3th level of glow is enabled.
+ <member name="glow_levels/3" type="float" setter="set_glow_level" getter="get_glow_level" default="1.0">
+ The intensity of the 3rd level of glow.
</member>
- <member name="glow_levels/4" type="bool" setter="set_glow_level_enabled" getter="is_glow_level_enabled" default="false">
- If [code]true[/code], the 4th level of glow is enabled.
+ <member name="glow_levels/4" type="float" setter="set_glow_level" getter="get_glow_level" default="0.0">
+ The intensity of the 4th level of glow.
</member>
- <member name="glow_levels/5" type="bool" setter="set_glow_level_enabled" getter="is_glow_level_enabled" default="true">
- If [code]true[/code], the 5th level of glow is enabled.
+ <member name="glow_levels/5" type="float" setter="set_glow_level" getter="get_glow_level" default="1.0">
+ The intensity of the 5th level of glow.
</member>
- <member name="glow_levels/6" type="bool" setter="set_glow_level_enabled" getter="is_glow_level_enabled" default="false">
- If [code]true[/code], the 6th level of glow is enabled.
+ <member name="glow_levels/6" type="float" setter="set_glow_level" getter="get_glow_level" default="0.0">
+ The intensity of the 6th level of glow.
</member>
- <member name="glow_levels/7" type="bool" setter="set_glow_level_enabled" getter="is_glow_level_enabled" default="false">
- If [code]true[/code], the 7th level of glow is enabled. This is the most "global" level (blurriest).
+ <member name="glow_levels/7" type="float" setter="set_glow_level" getter="get_glow_level" default="0.0">
+ The intensity of the 7th level of glow. This is the most "global" level (blurriest).
</member>
<member name="glow_mix" type="float" setter="set_glow_mix" getter="get_glow_mix" default="0.05">
</member>
+ <member name="glow_normalized" type="bool" setter="set_glow_normalized" getter="is_glow_normalized" default="false">
+ If [code]true[/code], glow levels will be normalized so that summed together their intensities equal [code]1.0[/code].
+ </member>
<member name="glow_strength" type="float" setter="set_glow_strength" getter="get_glow_strength" default="1.0">
- The glow strength. When using the GLES2 renderer, this should be increased to 1.3 to compensate for the lack of HDR rendering.
+ The strength of the glow effect. This applies as the glow is blurred across the screen and increases the distance and intensity of the blur. When using the GLES2 renderer, this should be increased to 1.3 to compensate for the lack of HDR rendering.
</member>
<member name="reflected_light_source" type="int" setter="set_reflection_source" getter="get_reflection_source" enum="Environment.ReflectionSource" default="0">
</member>
diff --git a/doc/classes/RenderingServer.xml b/doc/classes/RenderingServer.xml
index 07f6d4a1a4..4a70d28691 100644
--- a/doc/classes/RenderingServer.xml
+++ b/doc/classes/RenderingServer.xml
@@ -718,7 +718,7 @@
</argument>
<argument index="1" name="enable" type="bool">
</argument>
- <argument index="2" name="level_flags" type="int">
+ <argument index="2" name="levels" type="PackedFloat32Array">
</argument>
<argument index="3" name="intensity" type="float">
</argument>
diff --git a/drivers/dummy/rasterizer_dummy.h b/drivers/dummy/rasterizer_dummy.h
index f472377b4d..95e21c35c1 100644
--- a/drivers/dummy/rasterizer_dummy.h
+++ b/drivers/dummy/rasterizer_dummy.h
@@ -80,7 +80,7 @@ public:
void environment_set_canvas_max_layer(RID p_env, int p_max_layer) override {}
void environment_set_ambient_light(RID p_env, const Color &p_color, RS::EnvironmentAmbientSource p_ambient = RS::ENV_AMBIENT_SOURCE_BG, float p_energy = 1.0, float p_sky_contribution = 0.0, RS::EnvironmentReflectionSource p_reflection_source = RS::ENV_REFLECTION_SOURCE_BG, const Color &p_ao_color = Color()) override {}
- void environment_set_glow(RID p_env, bool p_enable, int p_level_flags, float p_intensity, float p_strength, float p_mix, float p_bloom_threshold, RS::EnvironmentGlowBlendMode p_blend_mode, float p_hdr_bleed_threshold, float p_hdr_bleed_scale, float p_hdr_luminance_cap) override {}
+ void environment_set_glow(RID p_env, bool p_enable, Vector<float> p_levels, float p_intensity, float p_strength, float p_mix, float p_bloom_threshold, RS::EnvironmentGlowBlendMode p_blend_mode, float p_hdr_bleed_threshold, float p_hdr_bleed_scale, float p_hdr_luminance_cap) override {}
void environment_glow_set_use_bicubic_upscale(bool p_enable) override {}
void environment_glow_set_use_high_quality(bool p_enable) override {}
diff --git a/scene/resources/environment.cpp b/scene/resources/environment.cpp
index 027042a161..63122ee98d 100644
--- a/scene/resources/environment.cpp
+++ b/scene/resources/environment.cpp
@@ -561,22 +561,28 @@ bool Environment::is_glow_enabled() const {
return glow_enabled;
}
-void Environment::set_glow_level_enabled(int p_level, bool p_enabled) {
+void Environment::set_glow_level(int p_level, float p_intensity) {
ERR_FAIL_INDEX(p_level, RS::MAX_GLOW_LEVELS);
- if (p_enabled) {
- glow_levels |= (1 << p_level);
- } else {
- glow_levels &= ~(1 << p_level);
- }
+ glow_levels.write[p_level] = p_intensity;
_update_glow();
}
-bool Environment::is_glow_level_enabled(int p_level) const {
+float Environment::get_glow_level(int p_level) const {
ERR_FAIL_INDEX_V(p_level, RS::MAX_GLOW_LEVELS, false);
- return glow_levels & (1 << p_level);
+ return glow_levels[p_level];
+}
+
+void Environment::set_glow_normalized(bool p_normalized) {
+ glow_normalize_levels = p_normalized;
+
+ _update_glow();
+}
+
+bool Environment::is_glow_normalized() const {
+ return glow_normalize_levels;
}
void Environment::set_glow_intensity(float p_intensity) {
@@ -653,10 +659,24 @@ float Environment::get_glow_hdr_luminance_cap() const {
}
void Environment::_update_glow() {
+ Vector<float> normalized_levels;
+ if (glow_normalize_levels) {
+ normalized_levels.resize(7);
+ float size = 0.0;
+ for (int i = 0; i < glow_levels.size(); i++) {
+ size += glow_levels[i];
+ }
+ for (int i = 0; i < glow_levels.size(); i++) {
+ normalized_levels.write[i] = glow_levels[i] / size;
+ }
+ } else {
+ normalized_levels = glow_levels;
+ }
+
RS::get_singleton()->environment_set_glow(
environment,
glow_enabled,
- glow_levels,
+ normalized_levels,
glow_intensity,
glow_strength,
glow_mix,
@@ -1154,8 +1174,10 @@ void Environment::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_glow_enabled", "enabled"), &Environment::set_glow_enabled);
ClassDB::bind_method(D_METHOD("is_glow_enabled"), &Environment::is_glow_enabled);
- ClassDB::bind_method(D_METHOD("set_glow_level_enabled", "idx", "enabled"), &Environment::set_glow_level_enabled);
- ClassDB::bind_method(D_METHOD("is_glow_level_enabled", "idx"), &Environment::is_glow_level_enabled);
+ ClassDB::bind_method(D_METHOD("set_glow_level", "idx", "intensity"), &Environment::set_glow_level);
+ ClassDB::bind_method(D_METHOD("get_glow_level", "idx"), &Environment::get_glow_level);
+ ClassDB::bind_method(D_METHOD("set_glow_normalized", "normalize"), &Environment::set_glow_normalized);
+ ClassDB::bind_method(D_METHOD("is_glow_normalized"), &Environment::is_glow_normalized);
ClassDB::bind_method(D_METHOD("set_glow_intensity", "intensity"), &Environment::set_glow_intensity);
ClassDB::bind_method(D_METHOD("get_glow_intensity"), &Environment::get_glow_intensity);
ClassDB::bind_method(D_METHOD("set_glow_strength", "strength"), &Environment::set_glow_strength);
@@ -1175,13 +1197,14 @@ void Environment::_bind_methods() {
ADD_GROUP("Glow", "glow_");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "glow_enabled"), "set_glow_enabled", "is_glow_enabled");
- ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "glow_levels/1"), "set_glow_level_enabled", "is_glow_level_enabled", 0);
- ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "glow_levels/2"), "set_glow_level_enabled", "is_glow_level_enabled", 1);
- ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "glow_levels/3"), "set_glow_level_enabled", "is_glow_level_enabled", 2);
- ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "glow_levels/4"), "set_glow_level_enabled", "is_glow_level_enabled", 3);
- ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "glow_levels/5"), "set_glow_level_enabled", "is_glow_level_enabled", 4);
- ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "glow_levels/6"), "set_glow_level_enabled", "is_glow_level_enabled", 5);
- ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "glow_levels/7"), "set_glow_level_enabled", "is_glow_level_enabled", 6);
+ ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "glow_levels/1", PROPERTY_HINT_RANGE, "0,16,0.01,or_greater"), "set_glow_level", "get_glow_level", 0);
+ ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "glow_levels/2", PROPERTY_HINT_RANGE, "0,16,0.01,or_greater"), "set_glow_level", "get_glow_level", 1);
+ ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "glow_levels/3", PROPERTY_HINT_RANGE, "0,16,0.01,or_greater"), "set_glow_level", "get_glow_level", 2);
+ ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "glow_levels/4", PROPERTY_HINT_RANGE, "0,16,0.01,or_greater"), "set_glow_level", "get_glow_level", 3);
+ ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "glow_levels/5", PROPERTY_HINT_RANGE, "0,16,0.01,or_greater"), "set_glow_level", "get_glow_level", 4);
+ ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "glow_levels/6", PROPERTY_HINT_RANGE, "0,16,0.01,or_greater"), "set_glow_level", "get_glow_level", 5);
+ ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "glow_levels/7", PROPERTY_HINT_RANGE, "0,16,0.01,or_greater"), "set_glow_level", "get_glow_level", 6);
+ ADD_PROPERTY(PropertyInfo(Variant::BOOL, "glow_normalized"), "set_glow_normalized", "is_glow_normalized");
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "glow_intensity", PROPERTY_HINT_RANGE, "0.0,8.0,0.01"), "set_glow_intensity", "get_glow_intensity");
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "glow_strength", PROPERTY_HINT_RANGE, "0.0,2.0,0.01"), "set_glow_strength", "get_glow_strength");
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "glow_mix", PROPERTY_HINT_RANGE, "0.0,1.0,0.001"), "set_glow_mix", "get_glow_mix");
@@ -1320,6 +1343,16 @@ Environment::Environment() {
environment = RS::get_singleton()->environment_create();
set_camera_feed_id(bg_camera_feed_id);
+
+ glow_levels.resize(7);
+ glow_levels.write[0] = 0.0;
+ glow_levels.write[1] = 0.0;
+ glow_levels.write[2] = 1.0;
+ glow_levels.write[3] = 0.0;
+ glow_levels.write[4] = 1.0;
+ glow_levels.write[5] = 0.0;
+ glow_levels.write[6] = 0.0;
+
_update_ambient_light();
_update_tonemap();
_update_ssr();
diff --git a/scene/resources/environment.h b/scene/resources/environment.h
index 2c9b94f145..8c69ee0f31 100644
--- a/scene/resources/environment.h
+++ b/scene/resources/environment.h
@@ -162,7 +162,8 @@ private:
// Glow
bool glow_enabled = false;
- int glow_levels = (1 << 2) | (1 << 4);
+ Vector<float> glow_levels;
+ bool glow_normalize_levels = false;
float glow_intensity = 0.8;
float glow_strength = 1.0;
float glow_mix = 0.05;
@@ -321,8 +322,10 @@ public:
// Glow
void set_glow_enabled(bool p_enabled);
bool is_glow_enabled() const;
- void set_glow_level_enabled(int p_level, bool p_enabled);
- bool is_glow_level_enabled(int p_level) const;
+ void set_glow_level(int p_level, float p_intensity);
+ float get_glow_level(int p_level) const;
+ void set_glow_normalized(bool p_normalized);
+ bool is_glow_normalized() const;
void set_glow_intensity(float p_intensity);
float get_glow_intensity() const;
void set_glow_strength(float p_strength);
diff --git a/servers/rendering/rasterizer.h b/servers/rendering/rasterizer.h
index 2919ef07c8..f3b68b74cf 100644
--- a/servers/rendering/rasterizer.h
+++ b/servers/rendering/rasterizer.h
@@ -84,7 +84,7 @@ public:
virtual void environment_set_camera_feed_id(RID p_env, int p_camera_feed_id) = 0;
#endif
- virtual void environment_set_glow(RID p_env, bool p_enable, int p_level_flags, float p_intensity, float p_strength, float p_mix, float p_bloom_threshold, RS::EnvironmentGlowBlendMode p_blend_mode, float p_hdr_bleed_threshold, float p_hdr_bleed_scale, float p_hdr_luminance_cap) = 0;
+ virtual void environment_set_glow(RID p_env, bool p_enable, Vector<float> p_levels, float p_intensity, float p_strength, float p_mix, float p_bloom_threshold, RS::EnvironmentGlowBlendMode p_blend_mode, float p_hdr_bleed_threshold, float p_hdr_bleed_scale, float p_hdr_luminance_cap) = 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;
diff --git a/servers/rendering/rasterizer_rd/rasterizer_effects_rd.cpp b/servers/rendering/rasterizer_rd/rasterizer_effects_rd.cpp
index cfcd2e4534..f8997bc441 100644
--- a/servers/rendering/rasterizer_rd/rasterizer_effects_rd.cpp
+++ b/servers/rendering/rasterizer_rd/rasterizer_effects_rd.cpp
@@ -389,14 +389,14 @@ void RasterizerEffectsRD::gaussian_blur(RID p_source_rd_texture, RID p_texture,
RD::get_singleton()->compute_list_end();
}
-void RasterizerEffectsRD::gaussian_glow(RID p_source_rd_texture, RID p_texture, RID p_back_texture, const Size2i &p_size, float p_strength, bool p_high_quality, bool p_first_pass, float p_luminance_cap, float p_exposure, float p_bloom, float p_hdr_bleed_treshold, float p_hdr_bleed_scale, RID p_auto_exposure, float p_auto_exposure_grey) {
+void RasterizerEffectsRD::gaussian_glow(RID p_source_rd_texture, RID p_back_texture, const Size2i &p_size, float p_strength, bool p_high_quality, bool p_first_pass, float p_luminance_cap, float p_exposure, float p_bloom, float p_hdr_bleed_treshold, float p_hdr_bleed_scale, RID p_auto_exposure, float p_auto_exposure_grey) {
zeromem(&copy.push_constant, sizeof(CopyPushConstant));
CopyMode copy_mode = p_first_pass && p_auto_exposure.is_valid() ? COPY_MODE_GAUSSIAN_GLOW_AUTO_EXPOSURE : COPY_MODE_GAUSSIAN_GLOW;
uint32_t base_flags = 0;
- int32_t x_groups = (p_size.width - 1) / 8 + 1;
- int32_t y_groups = (p_size.height - 1) / 8 + 1;
+ int32_t x_groups = (p_size.width + 7) / 8;
+ int32_t y_groups = (p_size.height + 7) / 8;
copy.push_constant.section[2] = p_size.x;
copy.push_constant.section[3] = p_size.y;
@@ -411,29 +411,15 @@ void RasterizerEffectsRD::gaussian_glow(RID p_source_rd_texture, RID p_texture,
copy.push_constant.glow_auto_exposure_grey = p_auto_exposure_grey; //unused also
- //HORIZONTAL
RD::ComputeListID compute_list = RD::get_singleton()->compute_list_begin();
RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, copy.pipelines[copy_mode]);
RD::get_singleton()->compute_list_bind_uniform_set(compute_list, _get_compute_uniform_set_from_texture(p_source_rd_texture), 0);
- RD::get_singleton()->compute_list_bind_uniform_set(compute_list, _get_uniform_set_from_image(p_texture), 3);
+ RD::get_singleton()->compute_list_bind_uniform_set(compute_list, _get_uniform_set_from_image(p_back_texture), 3);
if (p_auto_exposure.is_valid() && p_first_pass) {
RD::get_singleton()->compute_list_bind_uniform_set(compute_list, _get_compute_uniform_set_from_texture(p_auto_exposure), 1);
}
- copy.push_constant.flags = base_flags | COPY_FLAG_HORIZONTAL | (p_first_pass ? COPY_FLAG_GLOW_FIRST_PASS : 0) | (p_high_quality ? COPY_FLAG_HIGH_QUALITY_GLOW : 0);
- RD::get_singleton()->compute_list_set_push_constant(compute_list, &copy.push_constant, sizeof(CopyPushConstant));
-
- RD::get_singleton()->compute_list_dispatch(compute_list, x_groups, y_groups, 1);
- RD::get_singleton()->compute_list_add_barrier(compute_list);
-
- copy_mode = COPY_MODE_GAUSSIAN_GLOW;
-
- //VERTICAL
- RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, copy.pipelines[copy_mode]);
- RD::get_singleton()->compute_list_bind_uniform_set(compute_list, _get_compute_uniform_set_from_texture(p_texture), 0);
- RD::get_singleton()->compute_list_bind_uniform_set(compute_list, _get_uniform_set_from_image(p_back_texture), 3);
-
- copy.push_constant.flags = base_flags;
+ copy.push_constant.flags = base_flags | (p_first_pass ? COPY_FLAG_GLOW_FIRST_PASS : 0) | (p_high_quality ? COPY_FLAG_HIGH_QUALITY_GLOW : 0);
RD::get_singleton()->compute_list_set_push_constant(compute_list, &copy.push_constant, sizeof(CopyPushConstant));
RD::get_singleton()->compute_list_dispatch(compute_list, x_groups, y_groups, 1);
@@ -692,7 +678,13 @@ void RasterizerEffectsRD::tonemapper(RID p_source_color, RID p_dst_framebuffer,
tonemap.push_constant.use_glow = p_settings.use_glow;
tonemap.push_constant.glow_intensity = p_settings.glow_intensity;
- tonemap.push_constant.glow_level_flags = p_settings.glow_level_flags;
+ tonemap.push_constant.glow_levels[0] = p_settings.glow_levels[0]; // clean this up to just pass by pointer or something
+ tonemap.push_constant.glow_levels[1] = p_settings.glow_levels[1];
+ tonemap.push_constant.glow_levels[2] = p_settings.glow_levels[2];
+ tonemap.push_constant.glow_levels[3] = p_settings.glow_levels[3];
+ tonemap.push_constant.glow_levels[4] = p_settings.glow_levels[4];
+ tonemap.push_constant.glow_levels[5] = p_settings.glow_levels[5];
+ tonemap.push_constant.glow_levels[6] = p_settings.glow_levels[6];
tonemap.push_constant.glow_texture_size[0] = p_settings.glow_texture_size.x;
tonemap.push_constant.glow_texture_size[1] = p_settings.glow_texture_size.y;
tonemap.push_constant.glow_mode = p_settings.glow_mode;
diff --git a/servers/rendering/rasterizer_rd/rasterizer_effects_rd.h b/servers/rendering/rasterizer_rd/rasterizer_effects_rd.h
index 2b3d2f124b..4331441502 100644
--- a/servers/rendering/rasterizer_rd/rasterizer_effects_rd.h
+++ b/servers/rendering/rasterizer_rd/rasterizer_effects_rd.h
@@ -176,14 +176,16 @@ class RasterizerEffectsRD {
uint32_t tonemapper;
uint32_t glow_texture_size[2];
-
float glow_intensity;
- uint32_t glow_level_flags;
+ uint32_t pad3;
+
uint32_t glow_mode;
+ float glow_levels[7];
float exposure;
float white;
float auto_exposure_grey;
+ uint32_t pad2;
float pixel_size[2];
uint32_t use_fxaa;
@@ -596,7 +598,7 @@ public:
void copy_depth_to_rect_and_linearize(RID p_source_rd_texture, RID p_dest_texture, const Rect2i &p_rect, bool p_flip_y, float p_z_near, float p_z_far);
void copy_to_atlas_fb(RID p_source_rd_texture, RID p_dest_framebuffer, const Rect2 &p_uv_rect, RD::DrawListID p_draw_list, bool p_flip_y = false, bool p_panorama = false);
void gaussian_blur(RID p_source_rd_texture, RID p_texture, RID p_back_texture, const Rect2i &p_region, bool p_8bit_dst = false);
- void gaussian_glow(RID p_source_rd_texture, RID p_texture, RID p_back_texture, const Size2i &p_size, float p_strength = 1.0, bool p_high_quality = false, bool p_first_pass = false, float p_luminance_cap = 16.0, float p_exposure = 1.0, float p_bloom = 0.0, float p_hdr_bleed_treshold = 1.0, float p_hdr_bleed_scale = 1.0, RID p_auto_exposure = RID(), float p_auto_exposure_grey = 1.0);
+ void gaussian_glow(RID p_source_rd_texture, RID p_back_texture, const Size2i &p_size, float p_strength = 1.0, bool p_high_quality = false, bool p_first_pass = false, float p_luminance_cap = 16.0, float p_exposure = 1.0, float p_bloom = 0.0, float p_hdr_bleed_treshold = 1.0, float p_hdr_bleed_scale = 1.0, RID p_auto_exposure = RID(), float p_auto_exposure_grey = 1.0);
void cubemap_roughness(RID p_source_rd_texture, RID p_dest_framebuffer, uint32_t p_face_id, uint32_t p_sample_count, float p_roughness, float p_size);
void make_mipmap(RID p_source_rd_texture, RID p_dest_texture, const Size2i &p_size);
@@ -616,7 +618,7 @@ public:
GlowMode glow_mode = GLOW_MODE_ADD;
float glow_intensity = 1.0;
- uint32_t glow_level_flags = 0;
+ float glow_levels[7] = { 0.0, 0.0, 1.0, 0.0, 1.0, 0.0, 0.0 };
Vector2i glow_texture_size;
bool glow_use_bicubic_upscale = false;
RID glow_texture;
diff --git a/servers/rendering/rasterizer_rd/rasterizer_scene_high_end_rd.cpp b/servers/rendering/rasterizer_rd/rasterizer_scene_high_end_rd.cpp
index fe275914f0..35b0591289 100644
--- a/servers/rendering/rasterizer_rd/rasterizer_scene_high_end_rd.cpp
+++ b/servers/rendering/rasterizer_rd/rasterizer_scene_high_end_rd.cpp
@@ -2762,6 +2762,9 @@ RasterizerSceneHighEndRD::RasterizerSceneHighEndRD(RasterizerStorageRD *p_storag
actions.renames["NORMAL_ROUGHNESS_TEXTURE"] = "normal_roughness_buffer";
actions.renames["DEPTH"] = "gl_FragDepth";
actions.renames["OUTPUT_IS_SRGB"] = "true";
+ actions.renames["FOG"] = "custom_fog";
+ actions.renames["RADIANCE"] = "custom_radiance";
+ actions.renames["IRRADIANCE"] = "custom_irradiance";
//for light
actions.renames["VIEW"] = "view";
@@ -2799,6 +2802,10 @@ RasterizerSceneHighEndRD::RasterizerSceneHighEndRD(RasterizerStorageRD *p_storag
actions.usage_defines["DIFFUSE_LIGHT"] = "#define USE_LIGHT_SHADER_CODE\n";
actions.usage_defines["SPECULAR_LIGHT"] = "#define USE_LIGHT_SHADER_CODE\n";
+ actions.usage_defines["FOG"] = "#define CUSTOM_FOG_USED\n";
+ actions.usage_defines["RADIANCE"] = "#define CUSTOM_RADIANCE_USED\n";
+ actions.usage_defines["IRRADIANCE"] = "#define CUSTOM_IRRADIANCE_USED\n";
+
actions.render_mode_defines["skip_vertex_transform"] = "#define SKIP_TRANSFORM_USED\n";
actions.render_mode_defines["world_vertex_coords"] = "#define VERTEX_WORLD_COORDS_USED\n";
actions.render_mode_defines["ensure_correct_normals"] = "#define ENSURE_CORRECT_NORMALS\n";
diff --git a/servers/rendering/rasterizer_rd/rasterizer_scene_rd.cpp b/servers/rendering/rasterizer_rd/rasterizer_scene_rd.cpp
index 3afb82d168..0d341581a6 100644
--- a/servers/rendering/rasterizer_rd/rasterizer_scene_rd.cpp
+++ b/servers/rendering/rasterizer_rd/rasterizer_scene_rd.cpp
@@ -2933,11 +2933,12 @@ void RasterizerSceneRD::environment_set_tonemap(RID p_env, RS::EnvironmentToneMa
env->auto_exp_scale = p_auto_exp_scale;
}
-void RasterizerSceneRD::environment_set_glow(RID p_env, bool p_enable, int p_level_flags, float p_intensity, float p_strength, float p_mix, float p_bloom_threshold, RS::EnvironmentGlowBlendMode p_blend_mode, float p_hdr_bleed_threshold, float p_hdr_bleed_scale, float p_hdr_luminance_cap) {
+void RasterizerSceneRD::environment_set_glow(RID p_env, bool p_enable, Vector<float> p_levels, float p_intensity, float p_strength, float p_mix, float p_bloom_threshold, RS::EnvironmentGlowBlendMode p_blend_mode, float p_hdr_bleed_threshold, float p_hdr_bleed_scale, float p_hdr_luminance_cap) {
Environment *env = environment_owner.getornull(p_env);
ERR_FAIL_COND(!env);
+ ERR_FAIL_COND_MSG(p_levels.size() != 7, "Size of array of glow levels must be 7");
env->glow_enabled = p_enable;
- env->glow_levels = p_level_flags;
+ env->glow_levels = p_levels;
env->glow_intensity = p_intensity;
env->glow_strength = p_strength;
env->glow_mix = p_mix;
@@ -5313,25 +5314,21 @@ void RasterizerSceneRD::_render_buffers_post_process_and_tonemap(RID p_render_bu
}
int max_glow_level = -1;
- int glow_mask = 0;
if (can_use_effects && env && env->glow_enabled) {
/* see that blur textures are allocated */
- if (rb->blur[0].texture.is_null()) {
+ if (rb->blur[1].texture.is_null()) {
_allocate_blur_textures(rb);
_render_buffers_uniform_set_changed(p_render_buffers);
}
for (int i = 0; i < RS::MAX_GLOW_LEVELS; i++) {
- if (env->glow_levels & (1 << i)) {
+ if (env->glow_levels[i] > 0.0) {
if (i >= rb->blur[1].mipmaps.size()) {
max_glow_level = rb->blur[1].mipmaps.size() - 1;
- glow_mask |= 1 << max_glow_level;
-
} else {
max_glow_level = i;
- glow_mask |= (1 << i);
}
}
}
@@ -5345,9 +5342,9 @@ void RasterizerSceneRD::_render_buffers_post_process_and_tonemap(RID p_render_bu
if (env->auto_exposure && rb->luminance.current.is_valid()) {
luminance_texture = rb->luminance.current;
}
- storage->get_effects()->gaussian_glow(rb->texture, rb->blur[0].mipmaps[i + 1].texture, rb->blur[1].mipmaps[i].texture, Size2i(vp_w, vp_h), env->glow_strength, glow_high_quality, true, env->glow_hdr_luminance_cap, env->exposure, env->glow_bloom, env->glow_hdr_bleed_threshold, env->glow_hdr_bleed_scale, luminance_texture, env->auto_exp_scale);
+ storage->get_effects()->gaussian_glow(rb->texture, rb->blur[1].mipmaps[i].texture, Size2i(vp_w, vp_h), env->glow_strength, glow_high_quality, true, env->glow_hdr_luminance_cap, env->exposure, env->glow_bloom, env->glow_hdr_bleed_threshold, env->glow_hdr_bleed_scale, luminance_texture, env->auto_exp_scale);
} else {
- storage->get_effects()->gaussian_glow(rb->blur[1].mipmaps[i - 1].texture, rb->blur[0].mipmaps[i + 1].texture, rb->blur[1].mipmaps[i].texture, Size2i(vp_w, vp_h), env->glow_strength, glow_high_quality);
+ storage->get_effects()->gaussian_glow(rb->blur[1].mipmaps[i - 1].texture, rb->blur[1].mipmaps[i].texture, Size2i(vp_w, vp_h), env->glow_strength, glow_high_quality);
}
}
}
@@ -5370,7 +5367,9 @@ void RasterizerSceneRD::_render_buffers_post_process_and_tonemap(RID p_render_bu
tonemap.use_glow = true;
tonemap.glow_mode = RasterizerEffectsRD::TonemapSettings::GlowMode(env->glow_blend_mode);
tonemap.glow_intensity = env->glow_blend_mode == RS::ENV_GLOW_BLEND_MODE_MIX ? env->glow_mix : env->glow_intensity;
- tonemap.glow_level_flags = glow_mask;
+ for (int i = 0; i < RS::MAX_GLOW_LEVELS; i++) {
+ tonemap.glow_levels[i] = env->glow_levels[i];
+ }
tonemap.glow_texture_size.x = rb->blur[1].mipmaps[0].width;
tonemap.glow_texture_size.y = rb->blur[1].mipmaps[0].height;
tonemap.glow_use_bicubic_upscale = glow_bicubic_upscale;
@@ -8068,6 +8067,7 @@ RasterizerSceneRD::RasterizerSceneRD(RasterizerStorageRD *p_storage) {
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";
diff --git a/servers/rendering/rasterizer_rd/rasterizer_scene_rd.h b/servers/rendering/rasterizer_rd/rasterizer_scene_rd.h
index c24f62d9de..65f2a1d157 100644
--- a/servers/rendering/rasterizer_rd/rasterizer_scene_rd.h
+++ b/servers/rendering/rasterizer_rd/rasterizer_scene_rd.h
@@ -723,7 +723,7 @@ private:
/// Glow
bool glow_enabled = false;
- int glow_levels = (1 << 2) | (1 << 4);
+ Vector<float> glow_levels;
float glow_intensity = 0.8;
float glow_strength = 1.0;
float glow_bloom = 0.0;
@@ -1537,7 +1537,7 @@ public:
bool is_environment(RID p_env) const;
- void environment_set_glow(RID p_env, bool p_enable, int p_level_flags, float p_intensity, float p_strength, float p_mix, float p_bloom_threshold, RS::EnvironmentGlowBlendMode p_blend_mode, float p_hdr_bleed_threshold, float p_hdr_bleed_scale, float p_hdr_luminance_cap);
+ void environment_set_glow(RID p_env, bool p_enable, Vector<float> p_levels, float p_intensity, float p_strength, float p_mix, float p_bloom_threshold, RS::EnvironmentGlowBlendMode p_blend_mode, float p_hdr_bleed_threshold, float p_hdr_bleed_scale, float p_hdr_luminance_cap);
void environment_glow_set_use_bicubic_upscale(bool p_enable);
void environment_glow_set_use_high_quality(bool p_enable);
diff --git a/servers/rendering/rasterizer_rd/shaders/copy.glsl b/servers/rendering/rasterizer_rd/shaders/copy.glsl
index e565bd8e3d..355a2b9d75 100644
--- a/servers/rendering/rasterizer_rd/shaders/copy.glsl
+++ b/servers/rendering/rasterizer_rd/shaders/copy.glsl
@@ -58,12 +58,20 @@ layout(rgba8, set = 3, binding = 0) uniform restrict writeonly image2D dest_buff
layout(rgba32f, set = 3, binding = 0) uniform restrict writeonly image2D dest_buffer;
#endif
+#ifdef MODE_GAUSSIAN_GLOW
+shared vec4 local_cache[256];
+shared vec4 temp_cache[128];
+#endif
+
void main() {
// Pixel being shaded
ivec2 pos = ivec2(gl_GlobalInvocationID.xy);
+
+#ifndef MODE_GAUSSIAN_GLOW // Glow needs the extra threads
if (any(greaterThanEqual(pos, params.section.zw))) { //too large, do nothing
return;
}
+#endif
#ifdef MODE_MIPMAP
@@ -104,70 +112,69 @@ void main() {
#ifdef MODE_GAUSSIAN_GLOW
- //Glow uses larger sigma 1 for a more rounded blur effect
+ // First pass copy texture into 16x16 local memory for every 8x8 thread block
+ vec2 quad_center_uv = clamp(vec2(gl_GlobalInvocationID.xy + gl_LocalInvocationID.xy - 3.5) / params.section.zw, vec2(0.5 / params.section.zw), vec2(1.0 - 1.5 / params.section.zw));
+ uint dest_index = gl_LocalInvocationID.x * 2 + gl_LocalInvocationID.y * 2 * 16;
+
+ if (bool(params.flags & FLAG_HIGH_QUALITY_GLOW)) {
+ vec2 quad_offset_uv = clamp((vec2(gl_GlobalInvocationID.xy + gl_LocalInvocationID.xy - 3.0)) / params.section.zw, vec2(0.5 / params.section.zw), vec2(1.0 - 1.5 / params.section.zw));
-#define GLOW_ADD(m_ofs, m_mult) \
- { \
- ivec2 ofs = base_pos + m_ofs; \
- if (all(greaterThanEqual(ofs, section_begin)) && all(lessThan(ofs, section_end))) { \
- color += texelFetch(source_color, ofs, 0) * m_mult; \
- } \
+ local_cache[dest_index] = (textureLod(source_color, quad_center_uv, 0) + textureLod(source_color, quad_offset_uv, 0)) * 0.5;
+ local_cache[dest_index + 1] = (textureLod(source_color, quad_center_uv + vec2(1.0 / params.section.z, 0.0), 0) + textureLod(source_color, quad_offset_uv + vec2(1.0 / params.section.z, 0.0), 0)) * 0.5;
+ local_cache[dest_index + 16] = (textureLod(source_color, quad_center_uv + vec2(0.0, 1.0 / params.section.w), 0) + textureLod(source_color, quad_offset_uv + vec2(0.0, 1.0 / params.section.w), 0)) * 0.5;
+ local_cache[dest_index + 16 + 1] = (textureLod(source_color, quad_center_uv + vec2(1.0 / params.section.zw), 0) + textureLod(source_color, quad_offset_uv + vec2(1.0 / params.section.zw), 0)) * 0.5;
+ } else {
+ local_cache[dest_index] = textureLod(source_color, quad_center_uv, 0);
+ local_cache[dest_index + 1] = textureLod(source_color, quad_center_uv + vec2(1.0 / params.section.z, 0.0), 0);
+ local_cache[dest_index + 16] = textureLod(source_color, quad_center_uv + vec2(0.0, 1.0 / params.section.w), 0);
+ local_cache[dest_index + 16 + 1] = textureLod(source_color, quad_center_uv + vec2(1.0 / params.section.zw), 0);
}
+ memoryBarrierShared();
+ barrier();
+
+ // Horizontal pass. Needs to copy into 8x16 chunk of local memory so vertical pass has full resolution
+ uint read_index = gl_LocalInvocationID.x + gl_LocalInvocationID.y * 32 + 4;
+ vec4 color_top = vec4(0.0);
+ color_top += local_cache[read_index] * 0.174938;
+ color_top += local_cache[read_index + 1] * 0.165569;
+ color_top += local_cache[read_index + 2] * 0.140367;
+ color_top += local_cache[read_index + 3] * 0.106595;
+ color_top += local_cache[read_index - 1] * 0.165569;
+ color_top += local_cache[read_index - 2] * 0.140367;
+ color_top += local_cache[read_index - 3] * 0.106595;
+
+ vec4 color_bottom = vec4(0.0);
+ color_bottom += local_cache[read_index + 16] * 0.174938;
+ color_bottom += local_cache[read_index + 1 + 16] * 0.165569;
+ color_bottom += local_cache[read_index + 2 + 16] * 0.140367;
+ color_bottom += local_cache[read_index + 3 + 16] * 0.106595;
+ color_bottom += local_cache[read_index - 1 + 16] * 0.165569;
+ color_bottom += local_cache[read_index - 2 + 16] * 0.140367;
+ color_bottom += local_cache[read_index - 3 + 16] * 0.106595;
+
+ // rotate samples to take advantage of cache coherency
+ uint write_index = gl_LocalInvocationID.y * 2 + gl_LocalInvocationID.x * 16;
+
+ temp_cache[write_index] = color_top;
+ temp_cache[write_index + 1] = color_bottom;
+
+ memoryBarrierShared();
+ barrier();
+
+ // Vertical pass
+ uint index = gl_LocalInvocationID.y + gl_LocalInvocationID.x * 16 + 4;
vec4 color = vec4(0.0);
- if (bool(params.flags & FLAG_HORIZONTAL)) {
- ivec2 base_pos = ((pos + params.section.xy) << 1) + ivec2(1);
- ivec2 section_begin = params.section.xy << 1;
- ivec2 section_end = section_begin + (params.section.zw << 1);
-
- if (bool(params.flags & FLAG_HIGH_QUALITY_GLOW)) {
- //Sample from two lines to capture single pixel features
- GLOW_ADD(ivec2(0, 0), 0.152781);
- GLOW_ADD(ivec2(1, 0), 0.144599);
- GLOW_ADD(ivec2(2, 0), 0.122589);
- GLOW_ADD(ivec2(3, 0), 0.093095);
- GLOW_ADD(ivec2(4, 0), 0.063327);
- GLOW_ADD(ivec2(-1, 0), 0.144599);
- GLOW_ADD(ivec2(-2, 0), 0.122589);
- GLOW_ADD(ivec2(-3, 0), 0.093095);
- GLOW_ADD(ivec2(-4, 0), 0.063327);
-
- GLOW_ADD(ivec2(0, 1), 0.152781);
- GLOW_ADD(ivec2(1, 1), 0.144599);
- GLOW_ADD(ivec2(2, 1), 0.122589);
- GLOW_ADD(ivec2(3, 1), 0.093095);
- GLOW_ADD(ivec2(4, 1), 0.063327);
- GLOW_ADD(ivec2(-1, 1), 0.144599);
- GLOW_ADD(ivec2(-2, 1), 0.122589);
- GLOW_ADD(ivec2(-3, 1), 0.093095);
- GLOW_ADD(ivec2(-4, 1), 0.063327);
- color *= 0.5;
- } else {
- GLOW_ADD(ivec2(0, 0), 0.174938);
- GLOW_ADD(ivec2(1, 0), 0.165569);
- GLOW_ADD(ivec2(2, 0), 0.140367);
- GLOW_ADD(ivec2(3, 0), 0.106595);
- GLOW_ADD(ivec2(-1, 0), 0.165569);
- GLOW_ADD(ivec2(-2, 0), 0.140367);
- GLOW_ADD(ivec2(-3, 0), 0.106595);
- }
-
- color *= params.glow_strength;
- } else {
- ivec2 base_pos = pos + params.section.xy;
- ivec2 section_begin = params.section.xy;
- ivec2 section_end = section_begin + params.section.zw;
-
- GLOW_ADD(ivec2(0, 0), 0.288713);
- GLOW_ADD(ivec2(0, 1), 0.233062);
- GLOW_ADD(ivec2(0, 2), 0.122581);
- GLOW_ADD(ivec2(0, -1), 0.233062);
- GLOW_ADD(ivec2(0, -2), 0.122581);
- color *= params.glow_strength;
- }
+ color += temp_cache[index] * 0.174938;
+ color += temp_cache[index + 1] * 0.165569;
+ color += temp_cache[index + 2] * 0.140367;
+ color += temp_cache[index + 3] * 0.106595;
+ color += temp_cache[index - 1] * 0.165569;
+ color += temp_cache[index - 2] * 0.140367;
+ color += temp_cache[index - 3] * 0.106595;
-#undef GLOW_ADD
+ color *= params.glow_strength;
if (bool(params.flags & FLAG_GLOW_FIRST_PASS)) {
#ifdef GLOW_USE_AUTO_EXPOSURE
diff --git a/servers/rendering/rasterizer_rd/shaders/scene_high_end.glsl b/servers/rendering/rasterizer_rd/shaders/scene_high_end.glsl
index a16b14e551..182d1cdfa6 100644
--- a/servers/rendering/rasterizer_rd/shaders/scene_high_end.glsl
+++ b/servers/rendering/rasterizer_rd/shaders/scene_high_end.glsl
@@ -1692,6 +1692,15 @@ void main() {
float clearcoat_gloss = 0.0;
float anisotropy = 0.0;
vec2 anisotropy_flow = vec2(1.0, 0.0);
+#if defined(CUSTOM_FOG_USED)
+ vec4 custom_fog = vec4(0.0);
+#endif
+#if defined(CUSTOM_RADIANCE_USED)
+ vec4 custom_radiance = vec4(0.0);
+#endif
+#if defined(CUSTOM_IRRADIANCE_USED)
+ vec4 custom_irradiance = vec4(0.0);
+#endif
#if defined(AO_USED)
float ao = 1.0;
@@ -1909,6 +1918,10 @@ FRAGMENT_SHADER_CODE
specular_light *= scene_data.ambient_light_color_energy.a;
}
+#if defined(CUSTOM_RADIANCE_USED)
+ specular_light = mix(specular_light, custom_radiance.rgb, custom_radiance.a);
+#endif
+
#ifndef USE_LIGHTMAP
//lightmap overrides everything
if (scene_data.use_ambient_light) {
@@ -1926,7 +1939,9 @@ FRAGMENT_SHADER_CODE
}
}
#endif // USE_LIGHTMAP
-
+#if defined(CUSTOM_IRRADIANCE_USED)
+ ambient_light = mix(specular_light, custom_irradiance.rgb, custom_irradiance.a);
+#endif
#endif //!defined(MODE_RENDER_DEPTH) && !defined(MODE_UNSHADED)
//radiance
@@ -2755,6 +2770,11 @@ FRAGMENT_SHADER_CODE
specular_buffer.rgb = mix(specular_buffer.rgb, vec3(0.0), fog.a);
}
+#if defined(CUSTOM_FOG_USED)
+ diffuse_buffer.rgb = mix(diffuse_buffer.rgb, custom_fog.rgb, custom_fog.a);
+ specular_buffer.rgb = mix(specular_buffer.rgb, vec3(0.0), custom_fog.a);
+#endif //CUSTOM_FOG_USED
+
#else //MODE_MULTIPLE_RENDER_TARGETS
#ifdef MODE_UNSHADED
@@ -2775,6 +2795,10 @@ FRAGMENT_SHADER_CODE
frag_color.rgb = mix(frag_color.rgb, fog.rgb, fog.a);
}
+#if defined(CUSTOM_FOG_USED)
+ frag_color.rgb = mix(frag_color.rgb, custom_fog.rgb, custom_fog.a);
+#endif //CUSTOM_FOG_USED
+
#endif //MODE_MULTIPLE_RENDER_TARGETS
#endif //MODE_RENDER_DEPTH
diff --git a/servers/rendering/rasterizer_rd/shaders/sky.glsl b/servers/rendering/rasterizer_rd/shaders/sky.glsl
index f1a31d3486..6c985e1f5c 100644
--- a/servers/rendering/rasterizer_rd/shaders/sky.glsl
+++ b/servers/rendering/rasterizer_rd/shaders/sky.glsl
@@ -182,6 +182,7 @@ void main() {
float alpha = 1.0; // Only available to subpasses
vec4 half_res_color = vec4(1.0);
vec4 quarter_res_color = vec4(1.0);
+ vec4 custom_fog = vec4(0.0);
#ifdef USE_CUBEMAP_PASS
vec3 inverted_cube_normal = cube_normal;
@@ -235,6 +236,10 @@ FRAGMENT_SHADER_CODE
frag_color.rgb = mix(frag_color.rgb, fog.rgb, fog.a);
}
+ if (custom_fog.a > 0.0) {
+ frag_color.rgb = mix(frag_color.rgb, custom_fog.rgb, custom_fog.a);
+ }
+
#endif // DISABLE_FOG
// Blending is disabled for Sky, so alpha doesn't blend
diff --git a/servers/rendering/rasterizer_rd/shaders/tonemap.glsl b/servers/rendering/rasterizer_rd/shaders/tonemap.glsl
index b7c46a7d0e..74449496f6 100644
--- a/servers/rendering/rasterizer_rd/shaders/tonemap.glsl
+++ b/servers/rendering/rasterizer_rd/shaders/tonemap.glsl
@@ -37,12 +37,14 @@ layout(push_constant, binding = 1, std430) uniform Params {
uvec2 glow_texture_size;
float glow_intensity;
- uint glow_level_flags;
+ uint pad3;
uint glow_mode;
+ float glow_levels[7];
float exposure;
float white;
float auto_exposure_grey;
+ uint pad2;
vec2 pixel_size;
bool use_fxaa;
@@ -186,32 +188,32 @@ vec3 apply_tonemapping(vec3 color, float white) { // inputs are LINEAR, always o
vec3 gather_glow(sampler2D tex, vec2 uv) { // sample all selected glow levels
vec3 glow = vec3(0.0f);
- if (bool(params.glow_level_flags & (1 << 0))) {
- glow += GLOW_TEXTURE_SAMPLE(tex, uv, 0).rgb;
+ if (params.glow_levels[0] > 0.0001) {
+ glow += GLOW_TEXTURE_SAMPLE(tex, uv, 0).rgb * params.glow_levels[0];
}
- if (bool(params.glow_level_flags & (1 << 1))) {
- glow += GLOW_TEXTURE_SAMPLE(tex, uv, 1).rgb;
+ if (params.glow_levels[1] > 0.0001) {
+ glow += GLOW_TEXTURE_SAMPLE(tex, uv, 1).rgb * params.glow_levels[1];
}
- if (bool(params.glow_level_flags & (1 << 2))) {
- glow += GLOW_TEXTURE_SAMPLE(tex, uv, 2).rgb;
+ if (params.glow_levels[2] > 0.0001) {
+ glow += GLOW_TEXTURE_SAMPLE(tex, uv, 2).rgb * params.glow_levels[2];
}
- if (bool(params.glow_level_flags & (1 << 3))) {
- glow += GLOW_TEXTURE_SAMPLE(tex, uv, 3).rgb;
+ if (params.glow_levels[3] > 0.0001) {
+ glow += GLOW_TEXTURE_SAMPLE(tex, uv, 3).rgb * params.glow_levels[3];
}
- if (bool(params.glow_level_flags & (1 << 4))) {
- glow += GLOW_TEXTURE_SAMPLE(tex, uv, 4).rgb;
+ if (params.glow_levels[4] > 0.0001) {
+ glow += GLOW_TEXTURE_SAMPLE(tex, uv, 4).rgb * params.glow_levels[4];
}
- if (bool(params.glow_level_flags & (1 << 5))) {
- glow += GLOW_TEXTURE_SAMPLE(tex, uv, 5).rgb;
+ if (params.glow_levels[5] > 0.0001) {
+ glow += GLOW_TEXTURE_SAMPLE(tex, uv, 5).rgb * params.glow_levels[5];
}
- if (bool(params.glow_level_flags & (1 << 6))) {
- glow += GLOW_TEXTURE_SAMPLE(tex, uv, 6).rgb;
+ if (params.glow_levels[6] > 0.0001) {
+ glow += GLOW_TEXTURE_SAMPLE(tex, uv, 6).rgb * params.glow_levels[6];
}
return glow;
diff --git a/servers/rendering/rendering_server_raster.h b/servers/rendering/rendering_server_raster.h
index 3df8c4ed33..1bafe7a91d 100644
--- a/servers/rendering/rendering_server_raster.h
+++ b/servers/rendering/rendering_server_raster.h
@@ -581,7 +581,7 @@ public:
BIND7(environment_set_ssao, RID, bool, float, float, int, float, float)
BIND5(environment_set_ssao_settings, EnvironmentSSAOQuality, bool, float, float, float)
- BIND11(environment_set_glow, RID, bool, int, float, float, float, float, EnvironmentGlowBlendMode, float, float, float)
+ BIND11(environment_set_glow, RID, bool, Vector<float>, float, float, float, float, EnvironmentGlowBlendMode, float, float, float)
BIND1(environment_glow_set_use_bicubic_upscale, bool)
BIND1(environment_glow_set_use_high_quality, bool)
diff --git a/servers/rendering/rendering_server_wrap_mt.h b/servers/rendering/rendering_server_wrap_mt.h
index 998a2366ef..3c2b0b9475 100644
--- a/servers/rendering/rendering_server_wrap_mt.h
+++ b/servers/rendering/rendering_server_wrap_mt.h
@@ -492,7 +492,7 @@ public:
FUNC1(environment_set_sdfgi_ray_count, EnvironmentSDFGIRayCount)
FUNC1(environment_set_sdfgi_frames_to_converge, EnvironmentSDFGIFramesToConverge)
- FUNC11(environment_set_glow, RID, bool, int, float, float, float, float, EnvironmentGlowBlendMode, float, float, float)
+ FUNC11(environment_set_glow, RID, bool, Vector<float>, float, float, float, float, EnvironmentGlowBlendMode, float, float, float)
FUNC1(environment_glow_set_use_bicubic_upscale, bool)
FUNC1(environment_glow_set_use_high_quality, bool)
diff --git a/servers/rendering/shader_types.cpp b/servers/rendering/shader_types.cpp
index f1209d9d6d..48eaf1dd13 100644
--- a/servers/rendering/shader_types.cpp
+++ b/servers/rendering/shader_types.cpp
@@ -129,6 +129,9 @@ ShaderTypes::ShaderTypes() {
shader_modes[RS::SHADER_SPATIAL].functions["fragment"].built_ins["PROJECTION_MATRIX"] = constt(ShaderLanguage::TYPE_MAT4);
shader_modes[RS::SHADER_SPATIAL].functions["fragment"].built_ins["INV_PROJECTION_MATRIX"] = constt(ShaderLanguage::TYPE_MAT4);
shader_modes[RS::SHADER_SPATIAL].functions["fragment"].built_ins["VIEWPORT_SIZE"] = constt(ShaderLanguage::TYPE_VEC2);
+ shader_modes[RS::SHADER_SPATIAL].functions["fragment"].built_ins["FOG"] = ShaderLanguage::TYPE_VEC4; // TODO consider adding to light shader
+ shader_modes[RS::SHADER_SPATIAL].functions["fragment"].built_ins["RADIANCE"] = ShaderLanguage::TYPE_VEC4;
+ shader_modes[RS::SHADER_SPATIAL].functions["fragment"].built_ins["IRRADIANCE"] = ShaderLanguage::TYPE_VEC4;
shader_modes[RS::SHADER_SPATIAL].functions["fragment"].can_discard = true;
shader_modes[RS::SHADER_SPATIAL].functions["light"].built_ins["WORLD_MATRIX"] = constt(ShaderLanguage::TYPE_MAT4);
@@ -353,6 +356,7 @@ ShaderTypes::ShaderTypes() {
shader_modes[RS::SHADER_SKY].functions["fragment"].built_ins["SKY_COORDS"] = constt(ShaderLanguage::TYPE_VEC2);
shader_modes[RS::SHADER_SKY].functions["fragment"].built_ins["HALF_RES_COLOR"] = constt(ShaderLanguage::TYPE_VEC4);
shader_modes[RS::SHADER_SKY].functions["fragment"].built_ins["QUARTER_RES_COLOR"] = constt(ShaderLanguage::TYPE_VEC4);
+ shader_modes[RS::SHADER_SKY].functions["fragment"].built_ins["FOG"] = ShaderLanguage::TYPE_VEC4;
shader_modes[RS::SHADER_SKY].modes.push_back("use_half_res_pass");
shader_modes[RS::SHADER_SKY].modes.push_back("use_quarter_res_pass");
diff --git a/servers/rendering_server.cpp b/servers/rendering_server.cpp
index f88dd07ef4..dc018b0a3d 100644
--- a/servers/rendering_server.cpp
+++ b/servers/rendering_server.cpp
@@ -1746,7 +1746,7 @@ void RenderingServer::_bind_methods() {
ClassDB::bind_method(D_METHOD("environment_set_bg_energy", "env", "energy"), &RenderingServer::environment_set_bg_energy);
ClassDB::bind_method(D_METHOD("environment_set_canvas_max_layer", "env", "max_layer"), &RenderingServer::environment_set_canvas_max_layer);
ClassDB::bind_method(D_METHOD("environment_set_ambient_light", "env", "color", "ambient", "energy", "sky_contibution", "reflection_source", "ao_color"), &RenderingServer::environment_set_ambient_light, DEFVAL(RS::ENV_AMBIENT_SOURCE_BG), DEFVAL(1.0), DEFVAL(0.0), DEFVAL(RS::ENV_REFLECTION_SOURCE_BG), DEFVAL(Color()));
- ClassDB::bind_method(D_METHOD("environment_set_glow", "env", "enable", "level_flags", "intensity", "strength", "mix", "bloom_threshold", "blend_mode", "hdr_bleed_threshold", "hdr_bleed_scale", "hdr_luminance_cap"), &RenderingServer::environment_set_glow);
+ ClassDB::bind_method(D_METHOD("environment_set_glow", "env", "enable", "levels", "intensity", "strength", "mix", "bloom_threshold", "blend_mode", "hdr_bleed_threshold", "hdr_bleed_scale", "hdr_luminance_cap"), &RenderingServer::environment_set_glow);
ClassDB::bind_method(D_METHOD("environment_set_tonemap", "env", "tone_mapper", "exposure", "white", "auto_exposure", "min_luminance", "max_luminance", "auto_exp_speed", "auto_exp_grey"), &RenderingServer::environment_set_tonemap);
ClassDB::bind_method(D_METHOD("environment_set_adjustment", "env", "enable", "brightness", "contrast", "saturation", "ramp"), &RenderingServer::environment_set_adjustment);
ClassDB::bind_method(D_METHOD("environment_set_ssr", "env", "enable", "max_steps", "fade_in", "fade_out", "depth_tolerance"), &RenderingServer::environment_set_ssr);
diff --git a/servers/rendering_server.h b/servers/rendering_server.h
index 6e51bf540f..045b8ca168 100644
--- a/servers/rendering_server.h
+++ b/servers/rendering_server.h
@@ -832,7 +832,7 @@ public:
ENV_GLOW_BLEND_MODE_MIX,
};
- virtual void environment_set_glow(RID p_env, bool p_enable, int p_level_flags, float p_intensity, float p_strength, float p_mix, float p_bloom_threshold, EnvironmentGlowBlendMode p_blend_mode, float p_hdr_bleed_threshold, float p_hdr_bleed_scale, float p_hdr_luminance_cap) = 0;
+ virtual void environment_set_glow(RID p_env, bool p_enable, Vector<float> p_levels, float p_intensity, float p_strength, float p_mix, float p_bloom_threshold, EnvironmentGlowBlendMode p_blend_mode, float p_hdr_bleed_threshold, float p_hdr_bleed_scale, float p_hdr_luminance_cap) = 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;