From 1630b86cd2e28b9e586968ae1e11627e82de13b1 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 4df01418f1d30..1738b261b578e 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 a8cf9199f9f93..b29fc9adabb9b 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 35d381ce0fced..f2e3c58ef1ea3 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,