From 51c70bc98cd9c71d8e55a4656f22d0229a0ef06e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rafa=C5=82=20Harabie=C5=84?= Date: Mon, 23 Oct 2023 14:45:18 +0200 Subject: [PATCH] Fix fog color being inaccurate (#10226) # Objective Fog color was passed to shaders without conversion from sRGB to linear color space. Because shaders expect colors in linear space this resulted in wrong color being used. This is most noticeable in open scenes with dark fog color and clear color set to the same color. In such case background/clear color (which is properly processed) is going to be darker than very far objects. Example: ![image](https://github.com/bevyengine/bevy/assets/160391/89b70d97-b2d0-4bc5-80f4-c9e8b8801c4c) [bevy-fog-color-bug.zip](https://github.com/bevyengine/bevy/files/13063718/bevy-fog-color-bug.zip) ## Solution Add missing conversion of fog color to linear color space. --- ## Changelog * Fixed conversion of fog color ## Migration Guide - Colors in `FogSettings` struct (`color` and `directional_light_color`) are now sent to the GPU in linear space. If you were using `Color::rgb()`/`Color::rgba()` and would like to retain the previous colors, you can quickly fix it by switching to `Color::rgb_linear()`/`Color::rgba_linear()`. --- crates/bevy_pbr/src/render/fog.rs | 28 ++++++++++++++++++++-------- examples/3d/atmospheric_fog.rs | 4 ++-- examples/3d/fog.rs | 2 +- 3 files changed, 23 insertions(+), 11 deletions(-) diff --git a/crates/bevy_pbr/src/render/fog.rs b/crates/bevy_pbr/src/render/fog.rs index 4df01418f1..1738b261b5 100644 --- a/crates/bevy_pbr/src/render/fog.rs +++ b/crates/bevy_pbr/src/render/fog.rs @@ -65,24 +65,33 @@ pub fn prepare_fog( match &fog.falloff { FogFalloff::Linear { start, end } => GpuFog { mode: GPU_FOG_MODE_LINEAR, - base_color: fog.color.into(), - directional_light_color: fog.directional_light_color.into(), + base_color: fog.color.as_linear_rgba_f32().into(), + directional_light_color: fog + .directional_light_color + .as_linear_rgba_f32() + .into(), directional_light_exponent: fog.directional_light_exponent, be: Vec3::new(*start, *end, 0.0), ..Default::default() }, FogFalloff::Exponential { density } => GpuFog { mode: GPU_FOG_MODE_EXPONENTIAL, - base_color: fog.color.into(), - directional_light_color: fog.directional_light_color.into(), + base_color: fog.color.as_linear_rgba_f32().into(), + directional_light_color: fog + .directional_light_color + .as_linear_rgba_f32() + .into(), directional_light_exponent: fog.directional_light_exponent, be: Vec3::new(*density, 0.0, 0.0), ..Default::default() }, FogFalloff::ExponentialSquared { density } => GpuFog { mode: GPU_FOG_MODE_EXPONENTIAL_SQUARED, - base_color: fog.color.into(), - directional_light_color: fog.directional_light_color.into(), + base_color: fog.color.as_linear_rgba_f32().into(), + directional_light_color: fog + .directional_light_color + .as_linear_rgba_f32() + .into(), directional_light_exponent: fog.directional_light_exponent, be: Vec3::new(*density, 0.0, 0.0), ..Default::default() @@ -92,8 +101,11 @@ pub fn prepare_fog( inscattering, } => GpuFog { mode: GPU_FOG_MODE_ATMOSPHERIC, - base_color: fog.color.into(), - directional_light_color: fog.directional_light_color.into(), + base_color: fog.color.as_linear_rgba_f32().into(), + directional_light_color: fog + .directional_light_color + .as_linear_rgba_f32() + .into(), directional_light_exponent: fog.directional_light_exponent, be: *extinction, bi: *inscattering, diff --git a/examples/3d/atmospheric_fog.rs b/examples/3d/atmospheric_fog.rs index a8cf9199f9..b29fc9adab 100644 --- a/examples/3d/atmospheric_fog.rs +++ b/examples/3d/atmospheric_fog.rs @@ -31,8 +31,8 @@ fn setup_camera_fog(mut commands: Commands) { ..default() }, FogSettings { - color: Color::rgba(0.1, 0.2, 0.4, 1.0), - directional_light_color: Color::rgba(1.0, 0.95, 0.75, 0.5), + color: Color::rgba(0.35, 0.48, 0.66, 1.0), + directional_light_color: Color::rgba(1.0, 0.95, 0.85, 0.5), directional_light_exponent: 30.0, falloff: FogFalloff::from_visibility_colors( 15.0, // distance in world units up to which objects retain visibility (>= 5% contrast) diff --git a/examples/3d/fog.rs b/examples/3d/fog.rs index 35d381ce0f..f2e3c58ef1 100644 --- a/examples/3d/fog.rs +++ b/examples/3d/fog.rs @@ -34,7 +34,7 @@ fn setup_camera_fog(mut commands: Commands) { commands.spawn(( Camera3dBundle::default(), FogSettings { - color: Color::rgba(0.05, 0.05, 0.05, 1.0), + color: Color::rgba(0.25, 0.25, 0.25, 1.0), falloff: FogFalloff::Linear { start: 5.0, end: 20.0,