-
-
Notifications
You must be signed in to change notification settings - Fork 3.6k
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
Fix fog color being inaccurate #10226
Conversation
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. Fix it by adding missing conversion.
Welcome, new contributor! Please make sure you've read our contributing guide and we look forward to reviewing your pull request shortly ✨ |
I think @coreh should comment on whether fog colour is supposed to be specified as non-linear sRGB or linear. If it is meant to be specified as linear then no conversion should be done. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hey, nice catch! I think what got me confused when setting this up originally is that with hdr: false
the clear color is not tonemapped, only the meshes, so I could never get the fog to match it, and assumed the issue was with the clear color and not the fog. But for hdr: true
it should now match perfectly.
Before we merge this, can you update the examples, so that they don't look darker with the new (correct) color format being sent to the GPU?
It should be as simple as replacing Color::rgb
and Color::rgba
with Color::rgb_linear
and Color::rgba_linear
.
examples/fog.rs
FogSettings {
color: Color::rgba_linear(0.05, 0.05, 0.05, 1.0),
falloff: FogFalloff::Linear {
start: 5.0,
end: 20.0,
},
..default()
},
examples/atmospheric_fog.rs
FogSettings {
color: Color::rgba_linear(0.1, 0.2, 0.4, 1.0),
directional_light_color: Color::rgba_linear(1.0, 0.95, 0.75, 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)
Color::rgb(0.35, 0.5, 0.66), // atmospheric extinction color (after light is lost due to absorption by atmospheric particles)
Color::rgb(0.8, 0.844, 1.0), // atmospheric inscattering color (light gained due to scattering from the sun)
),
},
(I double checked it and in this second one, we don't need to change the values in FogFalloff
since it was already correctly using linear space internally to calculate extinction
and inscattering
.
I believe we also need a migration guide for this. Something like: “Fog 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()
.”
It looks like your PR is a breaking change, but you didn't provide a migration guide. Could you add some context on what users should update when this change get released in a new version of Bevy? |
Make examples look the same as before fog color conversion was fixed.
Great work, thank you very much :) And thanks @coreh for the high quality review! |
I adjusted configuration in examples to match the previous look and added migration info. I agree it may be helpful. |
# Objective - Fixes #10248 ## Solution - Update fog color values matching the update to the values for [atmospheric_fog.rs](https://github.com/bevyengine/bevy/pull/10226/files#diff-d43c34c9cf52e7ee72b56f8c4fc99ed86e9a1ec2f83642b839c4e75e1dd24f87) in #10226 After this update: ![image](https://github.com/bevyengine/bevy/assets/33357138/5924f97d-e12b-496e-90fa-160d20b82a2e)
# 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()`.
# Objective - Fixes bevyengine#10248 ## Solution - Update fog color values matching the update to the values for [atmospheric_fog.rs](https://github.com/bevyengine/bevy/pull/10226/files#diff-d43c34c9cf52e7ee72b56f8c4fc99ed86e9a1ec2f83642b839c4e75e1dd24f87) in bevyengine#10226 After this update: ![image](https://github.com/bevyengine/bevy/assets/33357138/5924f97d-e12b-496e-90fa-160d20b82a2e)
# 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()`.
# Objective - Fixes bevyengine#10248 ## Solution - Update fog color values matching the update to the values for [atmospheric_fog.rs](https://github.com/bevyengine/bevy/pull/10226/files#diff-d43c34c9cf52e7ee72b56f8c4fc99ed86e9a1ec2f83642b839c4e75e1dd24f87) in bevyengine#10226 After this update: ![image](https://github.com/bevyengine/bevy/assets/33357138/5924f97d-e12b-496e-90fa-160d20b82a2e)
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:
bevy-fog-color-bug.zip
Solution
Add missing conversion of fog color to linear color space.
Changelog
Migration Guide
FogSettings
struct (color
anddirectional_light_color
) are now sent to the GPU in linear space. If you were usingColor::rgb()
/Color::rgba()
and would like to retain the previous colors, you can quickly fix it by switching toColor::rgb_linear()
/Color::rgba_linear()
.