Color grading: add saturation and contrast (#2627)
* Add transforms for ACEScct and enabling/disabling color grading in sample * Add saturation and contrast adjustments * Rename ACES to ACES_LEGACY and introduce ACES ACES_LEGACY is ACES with a brightness boost to match our old tone mapping operator.
This commit is contained in:
@@ -586,9 +586,10 @@ static void gui(filament::Engine* engine, filament::View*) {
|
||||
}
|
||||
|
||||
if (ImGui::CollapsingHeader("Color grading")) {
|
||||
ImGui::Checkbox("Enabled##colorGradin", ¶ms.colorGrading);
|
||||
ImGui::Combo("Tone-mapping",
|
||||
reinterpret_cast<int*>(¶ms.colorGradingOptions.toneMapping),
|
||||
"Linear\0ACES\0Filmic\0Reinhard\0Display Range\0\0");
|
||||
"Linear\0ACES (legacy)\0ACES\0Filmic\0Reinhard\0Display Range\0\0");
|
||||
ImGui::Indent();
|
||||
if (ImGui::CollapsingHeader("While balance")) {
|
||||
ImGui::SliderInt("Temperature", ¶ms.colorGradingOptions.temperature, -100, 100);
|
||||
@@ -612,6 +613,10 @@ static void gui(filament::Engine* engine, filament::View*) {
|
||||
ImGui::PlotLines("Mid-tones curve", g_rangePlot + 1024, 1024);
|
||||
ImGui::PlotLines("Highlights curve", g_rangePlot + 2048, 1024);
|
||||
}
|
||||
if (ImGui::CollapsingHeader("Adjustments")) {
|
||||
ImGui::SliderFloat("Contrast", ¶ms.colorGradingOptions.contrast, 0.0f, 2.0f);
|
||||
ImGui::SliderFloat("Saturation", ¶ms.colorGradingOptions.saturation, 0.0f, 2.0f);
|
||||
}
|
||||
ImGui::Unindent();
|
||||
}
|
||||
|
||||
@@ -726,27 +731,34 @@ static void preRender(filament::Engine* engine, filament::View* view, filament::
|
||||
g_params.ssao ? View::AmbientOcclusion::SSAO : View::AmbientOcclusion::NONE);
|
||||
view->setAmbientOcclusionOptions(g_params.ssaoOptions);
|
||||
|
||||
if (memcmp(&g_params.colorGradingOptions, &g_lastColorGradingOptions, sizeof(ColorGradingOptions))) {
|
||||
ColorGradingOptions& options = g_params.colorGradingOptions;
|
||||
ColorGrading* colorGrading = ColorGrading::Builder()
|
||||
.whiteBalance(options.temperature / 100.0f, options.tint / 100.0f)
|
||||
.channelMixer(options.outRed, options.outGreen, options.outBlue)
|
||||
.shadowsMidtonesHighlights(
|
||||
Color::toLinear(options.shadows),
|
||||
Color::toLinear(options.midtones),
|
||||
Color::toLinear(options.highlights),
|
||||
options.ranges
|
||||
)
|
||||
.toneMapping(options.toneMapping)
|
||||
.build(*engine);
|
||||
view->setColorGrading(colorGrading);
|
||||
if (g_params.colorGrading) {
|
||||
if (memcmp(&g_params.colorGradingOptions, &g_lastColorGradingOptions,
|
||||
sizeof(ColorGradingOptions))) {
|
||||
ColorGradingOptions &options = g_params.colorGradingOptions;
|
||||
ColorGrading *colorGrading = ColorGrading::Builder()
|
||||
.whiteBalance(options.temperature / 100.0f, options.tint / 100.0f)
|
||||
.channelMixer(options.outRed, options.outGreen, options.outBlue)
|
||||
.shadowsMidtonesHighlights(
|
||||
Color::toLinear(options.shadows),
|
||||
Color::toLinear(options.midtones),
|
||||
Color::toLinear(options.highlights),
|
||||
options.ranges
|
||||
)
|
||||
.contrast(options.contrast)
|
||||
.saturation(options.saturation)
|
||||
.toneMapping(options.toneMapping)
|
||||
.build(*engine);
|
||||
|
||||
if (g_colorGrading) {
|
||||
engine->destroy(g_colorGrading);
|
||||
if (g_colorGrading) {
|
||||
engine->destroy(g_colorGrading);
|
||||
}
|
||||
|
||||
g_colorGrading = colorGrading;
|
||||
g_lastColorGradingOptions = options;
|
||||
}
|
||||
|
||||
g_colorGrading = colorGrading;
|
||||
g_lastColorGradingOptions = options;
|
||||
view->setColorGrading(g_colorGrading);
|
||||
} else {
|
||||
view->setColorGrading(nullptr);
|
||||
}
|
||||
|
||||
// Without an IBL, we must clear the swapchain to black before each frame.
|
||||
|
||||
Reference in New Issue
Block a user