Open cridenour opened 1 year ago
See discussion on Godot Contributors Chat: https://chat.godotengine.org/channel/rendering?msg=rssmQSemNovKWMxTD
diff --git a/servers/rendering/renderer_rd/environment/sky.cpp b/servers/rendering/renderer_rd/environment/sky.cpp
index 788ec1cee4..c15af5ce97 100644
--- a/servers/rendering/renderer_rd/environment/sky.cpp
+++ b/servers/rendering/renderer_rd/environment/sky.cpp
@@ -1428,7 +1428,7 @@ void SkyRD::update_res_buffers(Ref<RenderSceneBuffersRD> p_render_buffers, RID p
RS::EnvironmentBG background = RendererSceneRenderRD::get_singleton()->environment_get_background(p_env);
- if (!(background == RS::ENV_BG_CLEAR_COLOR || background == RS::ENV_BG_COLOR) || sky) {
+ if (!(background == RS::ENV_BG_CLEAR_COLOR || background == RS::ENV_BG_COLOR || background == RS::ENV_BG_CANVAS) || sky) {
ERR_FAIL_COND(!sky);
sky_material = sky_get_material(RendererSceneRenderRD::get_singleton()->environment_get_sky(p_env));
@@ -1445,7 +1445,7 @@ void SkyRD::update_res_buffers(Ref<RenderSceneBuffersRD> p_render_buffers, RID p
}
}
- if (background == RS::ENV_BG_CLEAR_COLOR || background == RS::ENV_BG_COLOR) {
+ if (background == RS::ENV_BG_CLEAR_COLOR || background == RS::ENV_BG_COLOR || background == RS::ENV_BG_CANVAS) {
sky_material = sky_scene_state.fog_material;
material = static_cast<SkyMaterialData *>(material_storage->material_get_data(sky_material, RendererRD::MaterialStorage::SHADER_TYPE_SKY));
}
@@ -1536,7 +1536,7 @@ void SkyRD::draw_sky(RD::DrawListID p_draw_list, Ref<RenderSceneBuffersRD> p_ren
RS::EnvironmentBG background = RendererSceneRenderRD::get_singleton()->environment_get_background(p_env);
- if (!(background == RS::ENV_BG_CLEAR_COLOR || background == RS::ENV_BG_COLOR) || sky) {
+ if (!(background == RS::ENV_BG_CLEAR_COLOR || background == RS::ENV_BG_COLOR || background == RS::ENV_BG_CANVAS) || sky) {
ERR_FAIL_COND(!sky);
sky_material = sky_get_material(RendererSceneRenderRD::get_singleton()->environment_get_sky(p_env));
@@ -1553,7 +1553,7 @@ void SkyRD::draw_sky(RD::DrawListID p_draw_list, Ref<RenderSceneBuffersRD> p_ren
}
}
- if (background == RS::ENV_BG_CLEAR_COLOR || background == RS::ENV_BG_COLOR) {
+ if (background == RS::ENV_BG_CLEAR_COLOR || background == RS::ENV_BG_COLOR || background == RS::ENV_BG_CANVAS) {
sky_material = sky_scene_state.fog_material;
material = static_cast<SkyMaterialData *>(material_storage->material_get_data(sky_material, RendererRD::MaterialStorage::SHADER_TYPE_SKY));
}
diff --git a/servers/rendering/renderer_rd/forward_clustered/render_forward_clustered.cpp b/servers/rendering/renderer_rd/forward_clustered/render_forward_clustered.cpp
index c7d85a3bbf..38feb848e5 100644
--- a/servers/rendering/renderer_rd/forward_clustered/render_forward_clustered.cpp
+++ b/servers/rendering/renderer_rd/forward_clustered/render_forward_clustered.cpp
@@ -1773,6 +1773,12 @@ void RenderForwardClustered::_render_scene(RenderDataRD *p_render_data, const Co
copy_effects->copy_to_fb_rect(texture, color_only_framebuffer, Rect2i(), false, false, false, false, RID(), false, false, true);
}
keep_color = true;
+
+ if ((rb->has_custom_data(RB_SCOPE_FOG)) || environment_get_fog_enabled(p_render_data->environment)) {
+ draw_sky_fog_only = true;
+ clear_color.a = 0.0;
+ RendererRD::MaterialStorage::get_singleton()->material_set_param(sky.sky_scene_state.fog_material, "clear_color", Variant(clear_color.srgb_to_linear()));
+ }
} break;
case RS::ENV_BG_KEEP: {
keep_color = true;
After a few attempts, this is as far as I got. It works in the editor and renders the fog correctly, but it seems to be clearing over the canvas, despite keep_color.
I've also tried changing RD::INITIAL_ACTION_CLEAR
to RD::INITIAL_ACTION_KEEP
in sky.cpp
with no luck.
@cridenour looks like the fog_material
ignores alpha.
shader_type sky;
uniform vec4 clear_color;
void sky() {
COLOR = clear_color.rgb;
}
Maybe the fix is as simple as adding ALPHA = clear_color.a
?
Maybe the fix is as simple as adding
ALPHA = clear_color.a
?
Unfortunately, no effect.
Looking into it further, ALPHA is only available in a subpass (half or quarter mode) - so the sky shader will always draw the clear color in the main pass. I assume this is for a reason, does anyone know why?
My first instinct is to say "performance"
For those who may find this later, there is a workaround, though I can't say I understand the downsides yet.
Render your background to a SubViewport
with Own World 3D
enabled and change your WorldEnvironment
to Sky
and use a ShaderMaterial
with the following shader:
shader_type sky;
uniform sampler2D viewport_texture : source_color;
void sky() {
COLOR = texture(viewport_texture, SCREEN_UV).rgb;
}
Make sure your ShaderMaterial
, Sky
and WorldEnvironment
are set to Local to scene
and sync up your SubViewport
size to your main scene's viewport size.
Godot version
v4.0.3.stable.official [5222a99f5]
System information
macOS 12.2.0 - Vulkan (Forward+) - integrated Apple M1 Max - Apple M1 Max (10 Threads)
Issue description
Noticed this in both 4.0.3 stable and master branch (tested on 116f783db).
When switching background mode to canvas, volumetric fog is not visible on the skybox. It will color the grid lines in the editor and objects behind it in game, but will never affect the sky.
Steps to reproduce
Minimal reproduction project
canvas-bg-fog.zip