Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add fixed fog to the sky in the Compatibility renderer #95662

Merged
merged 1 commit into from
Aug 19, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 10 additions & 2 deletions drivers/gles3/rasterizer_scene_gles3.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -777,7 +777,6 @@ void RasterizerSceneGLES3::_draw_sky(RID p_env, const Projection &p_projection,
ERR_FAIL_COND(p_env.is_null());

Sky *sky = sky_owner.get_or_null(environment_get_sky(p_env));
ERR_FAIL_NULL(sky);
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

When doing a custom sky pass for fog we can continue without the sky. This is used when you have fog, but are using a custom color background.


GLES3::SkyMaterialData *material_data = nullptr;
RID sky_material;
Expand Down Expand Up @@ -851,6 +850,15 @@ void RasterizerSceneGLES3::_draw_sky(RID p_env, const Projection &p_projection,
material_storage->shaders.sky_shader.version_set_uniform(SkyShaderGLES3::SKY_ENERGY_MULTIPLIER, p_sky_energy_multiplier, shader_data->version, SkyShaderGLES3::MODE_BACKGROUND, spec_constants);
material_storage->shaders.sky_shader.version_set_uniform(SkyShaderGLES3::LUMINANCE_MULTIPLIER, p_luminance_multiplier, shader_data->version, SkyShaderGLES3::MODE_BACKGROUND, spec_constants);

Color fog_color = environment_get_fog_light_color(p_env).srgb_to_linear() * environment_get_fog_light_energy(p_env);
material_storage->shaders.sky_shader.version_set_uniform(SkyShaderGLES3::FOG_ENABLED, environment_get_fog_enabled(p_env), shader_data->version, SkyShaderGLES3::MODE_BACKGROUND, spec_constants);
material_storage->shaders.sky_shader.version_set_uniform(SkyShaderGLES3::FOG_AERIAL_PERSPECTIVE, environment_get_fog_aerial_perspective(p_env), shader_data->version, SkyShaderGLES3::MODE_BACKGROUND, spec_constants);
material_storage->shaders.sky_shader.version_set_uniform(SkyShaderGLES3::FOG_LIGHT_COLOR, fog_color, shader_data->version, SkyShaderGLES3::MODE_BACKGROUND, spec_constants);
material_storage->shaders.sky_shader.version_set_uniform(SkyShaderGLES3::FOG_SUN_SCATTER, environment_get_fog_sun_scatter(p_env), shader_data->version, SkyShaderGLES3::MODE_BACKGROUND, spec_constants);
material_storage->shaders.sky_shader.version_set_uniform(SkyShaderGLES3::FOG_DENSITY, environment_get_fog_density(p_env), shader_data->version, SkyShaderGLES3::MODE_BACKGROUND, spec_constants);
material_storage->shaders.sky_shader.version_set_uniform(SkyShaderGLES3::FOG_SKY_AFFECT, environment_get_fog_sky_affect(p_env), shader_data->version, SkyShaderGLES3::MODE_BACKGROUND, spec_constants);
material_storage->shaders.sky_shader.version_set_uniform(SkyShaderGLES3::DIRECTIONAL_LIGHT_COUNT, sky_globals.directional_light_count, shader_data->version, SkyShaderGLES3::MODE_BACKGROUND, spec_constants);

if (p_use_multiview) {
glBindBufferBase(GL_UNIFORM_BUFFER, SKY_MULTIVIEW_UNIFORM_LOCATION, scene_state.multiview_buffer);
glBindBuffer(GL_UNIFORM_BUFFER, 0);
Expand Down Expand Up @@ -2587,7 +2595,7 @@ void RasterizerSceneGLES3::render_scene(const Ref<RenderSceneBuffers> &p_render_

scene_state.enable_gl_depth_draw(false);

if (draw_sky) {
if (draw_sky || draw_sky_fog_only) {
RENDER_TIMESTAMP("Render Sky");

scene_state.enable_gl_depth_test(true);
Expand Down
37 changes: 35 additions & 2 deletions drivers/gles3/shaders/sky.glsl
Original file line number Diff line number Diff line change
Expand Up @@ -108,11 +108,11 @@ uniform float sky_energy_multiplier;
uniform float luminance_multiplier;

uniform float fog_aerial_perspective;
uniform vec3 fog_light_color;
uniform vec4 fog_light_color;
uniform float fog_sun_scatter;
uniform bool fog_enabled;
uniform float fog_density;
uniform float z_far;
uniform float fog_sky_affect;
uniform uint directional_light_count;

#ifdef USE_MULTIVIEW
Expand All @@ -135,6 +135,24 @@ vec3 interleaved_gradient_noise(vec2 pos) {
}
#endif

#if !defined(DISABLE_FOG)
vec4 fog_process(vec3 view, vec3 sky_color) {
vec3 fog_color = mix(fog_light_color.rgb, sky_color, fog_aerial_perspective);

if (fog_sun_scatter > 0.001) {
vec4 sun_scatter = vec4(0.0);
float sun_total = 0.0;
for (uint i = 0u; i < directional_light_count; i++) {
vec3 light_color = directional_lights.data[i].color_size.xyz * directional_lights.data[i].direction_energy.w;
float light_amount = pow(max(dot(view, directional_lights.data[i].direction_energy.xyz), 0.0), 8.0);
fog_color += light_color * light_amount * fog_sun_scatter;
}
}

return vec4(fog_color, 1.0);
}
#endif // !DISABLE_FOG

void main() {
vec3 cube_normal;
#ifdef USE_MULTIVIEW
Expand Down Expand Up @@ -203,6 +221,21 @@ void main() {

// Convert to Linear for tonemapping so color matches scene shader better
color = srgb_to_linear(color);

#if !defined(DISABLE_FOG) && !defined(USE_CUBEMAP_PASS)

// Draw "fixed" fog before volumetric fog to ensure volumetric fog can appear in front of the sky.
if (fog_enabled) {
vec4 fog = fog_process(cube_normal, color.rgb);
color.rgb = mix(color.rgb, fog.rgb, fog.a * fog_sky_affect);
}

if (custom_fog.a > 0.0) {
color.rgb = mix(color.rgb, custom_fog.rgb, custom_fog.a);
}

#endif // DISABLE_FOG

color *= exposure;
#ifdef APPLY_TONEMAPPING
color = apply_tonemapping(color, white);
Expand Down
8 changes: 4 additions & 4 deletions servers/rendering/renderer_rd/shaders/environment/sky.glsl
Original file line number Diff line number Diff line change
Expand Up @@ -255,10 +255,6 @@ void main() {
frag_color.rgb = color;
frag_color.a = alpha;

// For mobile renderer we're multiplying by 0.5 as we're using a UNORM buffer.
// For both mobile and clustered, we also bake in the exposure value for the environment and camera.
frag_color.rgb = frag_color.rgb * params.luminance_multiplier;

#if !defined(DISABLE_FOG) && !defined(USE_CUBEMAP_PASS)

// Draw "fixed" fog before volumetric fog to ensure volumetric fog can appear in front of the sky.
Expand All @@ -278,6 +274,10 @@ void main() {

#endif // DISABLE_FOG

// For mobile renderer we're multiplying by 0.5 as we're using a UNORM buffer.
// For both mobile and clustered, we also bake in the exposure value for the environment and camera.
frag_color.rgb = frag_color.rgb * params.luminance_multiplier;

// Blending is disabled for Sky, so alpha doesn't blend.
// Alpha is used for subsurface scattering so make sure it doesn't get applied to Sky.
if (!AT_CUBEMAP_PASS && !AT_HALF_RES_PASS && !AT_QUARTER_RES_PASS) {
Expand Down
Loading