-
-
Notifications
You must be signed in to change notification settings - Fork 3.5k
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
Implement filmic color grading. #13121
Conversation
The generated |
01d6ecf
to
d87aa2d
Compare
This commit expands Bevy's existing tonemapping feature to a complete set of filmic color grading tools, matching those of engines like Unity, Unreal, and Godot. The following features are supported: * White point adjustment. This is inspired by Unity's implementation of the feature, but simplified and optimized. *Temperature* and *tint* control the adjustments to the *x* and *y* chromaticity values of [CIE 1931]. Following Unity, the adjustments are made relative to the [D65 standard illuminant] in the [LMS color space]. * Hue rotation. This simply converts the RGB value to [HSV], alters the hue, and converts back. * Color correction. This allows the *gamma*, *gain*, and *lift* values to be adjusted according to the standard [ASC CDL combined function]. * Separate color correction for shadows, midtones, and highlights. Blender's source code was used as a reference for the implementation of this. The midtone ranges can be adjusted by the user. To avoid abrupt color changes, a small crossfade is used between the different sections of the image, again following Blender's formulas. A new example, `color_grading`, has been added, offering a GUI to change all the color grading settings. It uses the same test scene as the existing `tonemapping` example, which has been factored out into a shared glTF scene. [CIE 1931]: https://en.wikipedia.org/wiki/CIE_1931_color_space [D65 standard illuminant]: https://en.wikipedia.org/wiki/Standard_illuminant#Illuminant_series_D [LMS color space]: https://en.wikipedia.org/wiki/LMS_color_space [HSV]: https://en.wikipedia.org/wiki/HSL_and_HSV [ASC CDL combined function]: https://en.wikipedia.org/wiki/ASC_CDL#Combined_Function
} | ||
|
||
impl Default for ColorGrading { | ||
/// The [`ColorGrading`] structure, packed into the most efficient form for the | ||
/// GPU. |
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.
Out of interest and learning, how/why is this most efficient?
I'm thinking it has to do with the fact that the fields of the struct are of decreasing size?
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.
Because:
(1) Shadows, midtones, and highlights are split out into struct-of-vectors instead of array-of-structs, turning the math into a series of dot products;
(2) White balance is baked into a 3x3 matrix ahead of time so the work doesn't have to be redone for every pixel.
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.
This is some of the highest quality and best documented code I've had the pleasure of reviewing. Color math looks right, the method seems solid.
I really appreciate the technical precision in the comments. Would that the entire engine was this exact with its color terminology.
I haven't played with this locally, but I plan to later today. Will report back if I find anything.
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.
I'm actually quite comfortable with this PR's contents! I've had a solid chance to get acquainted with the color math and basic concepts of color manipulation in the past, and the shaders are straightforward enough.
I'm very pleased with the end user API as well: clearly documented, intuitive parameters.
As expected, the code quality and documentation are both top notch.
Thank you to everyone involved with the authoring or reviewing of this PR! This work is relatively important and needs release notes! Head over to bevyengine/bevy-website#1360 if you'd like to help out. |
This commit expands Bevy's existing tonemapping feature to a complete set of filmic color grading tools, matching those of engines like Unity, Unreal, and Godot. The following features are supported:
White point adjustment. This is inspired by Unity's implementation of the feature, but simplified and optimized. Temperature and tint control the adjustments to the x and y chromaticity values of CIE 1931. Following Unity, the adjustments are made relative to the D65 standard illuminant in the LMS color space.
Hue rotation. This simply converts the RGB value to HSV, alters the hue, and converts back.
Color correction. This allows the gamma, gain, and lift values to be adjusted according to the standard ASC CDL combined function.
Separate color correction for shadows, midtones, and highlights. Blender's source code was used as a reference for the implementation of this. The midtone ranges can be adjusted by the user. To avoid abrupt color changes, a small crossfade is used between the different sections of the image, again following Blender's formulas.
A new example,
color_grading
, has been added, offering a GUI to change all the color grading settings. It uses the same test scene as the existingtonemapping
example, which has been factored out into a shared glTF scene.Changelog
Added
ColorGrading
component.Migration Guide
ColorGrading::gamma
andColorGrading::pre_saturation
are now set separately for theshadows
,midtones
, andhighlights
sections. You can migrate code with theColorGrading::all_sections
andColorGrading::all_sections_mut
functions, which access and/or update all sections at once.ColorGrading::post_saturation
andColorGrading::exposure
are now fields ofColorGrading::global
.Screenshots