Files
cup_edit/macos/include/filament/ToneMapper.h
2023-09-05 23:13:59 +08:00

228 lines
8.0 KiB
C++

/*
* Copyright (C) 2020 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef TNT_FILAMENT_TONEMAPPER_H
#define TNT_FILAMENT_TONEMAPPER_H
#include <utils/compiler.h>
#include <math/mathfwd.h>
namespace filament {
/**
* Interface for tone mapping operators. A tone mapping operator, or tone mapper,
* is responsible for compressing the dynamic range of the rendered scene to a
* dynamic range suitable for display.
*
* In Filament, tone mapping is a color grading step. ToneMapper instances are
* created and passed to the ColorGrading::Builder to produce a 3D LUT that will
* be used during post-processing to prepare the final color buffer for display.
*
* Filament provides several default tone mapping operators that fall into three
* categories:
*
* - Configurable tone mapping operators
* - GenericToneMapper
* - Fixed-aesthetic tone mapping operators
* - ACESToneMapper
* - ACESLegacyToneMapper
* - FilmicToneMapper
* - Debug/validation tone mapping operators
* - LinearToneMapper
* - DisplayRangeToneMapper
*
* You can create custom tone mapping operators by subclassing ToneMapper.
*/
struct UTILS_PUBLIC ToneMapper {
ToneMapper() noexcept;
virtual ~ToneMapper() noexcept;
/**
* Maps an open domain (or "scene referred" values) color value to display
* domain (or "display referred") color value. Both the input and output
* color values are defined in the Rec.2020 color space, with no transfer
* function applied ("linear Rec.2020").
*
* @param c Input color to tone map, in the Rec.2020 color space with no
* transfer function applied ("linear")
*
* @return A tone mapped color in the Rec.2020 color space, with no transfer
* function applied ("linear")
*/
virtual math::float3 operator()(math::float3 c) const noexcept = 0;
};
/**
* Linear tone mapping operator that returns the input color but clamped to
* the 0..1 range. This operator is mostly useful for debugging.
*/
struct UTILS_PUBLIC LinearToneMapper final : public ToneMapper {
LinearToneMapper() noexcept;
~LinearToneMapper() noexcept final;
math::float3 operator()(math::float3 c) const noexcept override;
};
/**
* ACES tone mapping operator. This operator is an implementation of the
* ACES Reference Rendering Transform (RRT) combined with the Output Device
* Transform (ODT) for sRGB monitors (dim surround, 100 nits).
*/
struct UTILS_PUBLIC ACESToneMapper final : public ToneMapper {
ACESToneMapper() noexcept;
~ACESToneMapper() noexcept final;
math::float3 operator()(math::float3 c) const noexcept override;
};
/**
* ACES tone mapping operator, modified to match the perceived brightness
* of FilmicToneMapper. This operator is the same as ACESToneMapper but
* applies a brightness multiplier of ~1.6 to the input color value to
* target brighter viewing environments.
*/
struct UTILS_PUBLIC ACESLegacyToneMapper final : public ToneMapper {
ACESLegacyToneMapper() noexcept;
~ACESLegacyToneMapper() noexcept final;
math::float3 operator()(math::float3 c) const noexcept override;
};
/**
* "Filmic" tone mapping operator. This tone mapper was designed to
* approximate the aesthetics of the ACES RRT + ODT for Rec.709
* and historically Filament's default tone mapping operator. It exists
* only for backward compatibility purposes and is not otherwise recommended.
*/
struct UTILS_PUBLIC FilmicToneMapper final : public ToneMapper {
FilmicToneMapper() noexcept;
~FilmicToneMapper() noexcept final;
math::float3 operator()(math::float3 x) const noexcept override;
};
/**
* Generic tone mapping operator that gives control over the tone mapping
* curve. This operator can be used to control the aesthetics of the final
* image. This operator also allows to control the dynamic range of the
* scene referred values.
*
* The tone mapping curve is defined by 5 parameters:
* - contrast: controls the contrast of the curve
* - midGrayIn: sets the input middle gray
* - midGrayOut: sets the output middle gray
* - hdrMax: defines the maximum input value that will be mapped to
* output white
*/
struct UTILS_PUBLIC GenericToneMapper final : public ToneMapper {
/**
* Builds a new generic tone mapper. The default values of the
* constructor parameters approximate an ACES tone mapping curve
* and the maximum input value is set to 10.0.
*
* @param contrast controls the contrast of the curve, must be > 0.0, values
* in the range 0.5..2.0 are recommended.
* @param midGrayIn sets the input middle gray, between 0.0 and 1.0.
* @param midGrayOut sets the output middle gray, between 0.0 and 1.0.
* @param hdrMax defines the maximum input value that will be mapped to
* output white. Must be >= 1.0.
*/
explicit GenericToneMapper(
float contrast = 1.55f,
float midGrayIn = 0.18f,
float midGrayOut = 0.215f,
float hdrMax = 10.0f
) noexcept;
~GenericToneMapper() noexcept final;
GenericToneMapper(GenericToneMapper const&) = delete;
GenericToneMapper& operator=(GenericToneMapper const&) = delete;
GenericToneMapper(GenericToneMapper&& rhs) noexcept;
GenericToneMapper& operator=(GenericToneMapper&& rhs) noexcept;
math::float3 operator()(math::float3 x) const noexcept override;
/** Returns the contrast of the curve as a strictly positive value. */
float getContrast() const noexcept;
/** Returns how fast scene referred values map to output white as a value between 0.0 and 1.0. */
float getShoulder() const noexcept;
/** Returns the middle gray point for input values as a value between 0.0 and 1.0. */
float getMidGrayIn() const noexcept;
/** Returns the middle gray point for output values as a value between 0.0 and 1.0. */
float getMidGrayOut() const noexcept;
/** Returns the maximum input value that will map to output white, as a value >= 1.0. */
float getHdrMax() const noexcept;
/** Sets the contrast of the curve, must be > 0.0, values in the range 0.5..2.0 are recommended. */
void setContrast(float contrast) noexcept;
/** Sets the input middle gray, between 0.0 and 1.0. */
void setMidGrayIn(float midGrayIn) noexcept;
/** Sets the output middle gray, between 0.0 and 1.0. */
void setMidGrayOut(float midGrayOut) noexcept;
/** Defines the maximum input value that will be mapped to output white. Must be >= 1.0. */
void setHdrMax(float hdrMax) noexcept;
private:
struct Options;
Options* mOptions;
};
/**
* A tone mapper that converts the input HDR RGB color into one of 16 debug colors
* that represent the pixel's exposure. When the output is cyan, the input color
* represents middle gray (18% exposure). Every exposure stop above or below middle
* gray causes a color shift.
*
* The relationship between exposures and colors is:
*
* - -5EV black
* - -4EV darkest blue
* - -3EV darker blue
* - -2EV dark blue
* - -1EV blue
* - OEV cyan
* - +1EV dark green
* - +2EV green
* - +3EV yellow
* - +4EV yellow-orange
* - +5EV orange
* - +6EV bright red
* - +7EV red
* - +8EV magenta
* - +9EV purple
* - +10EV white
*
* This tone mapper is useful to validate and tweak scene lighting.
*/
struct UTILS_PUBLIC DisplayRangeToneMapper final : public ToneMapper {
DisplayRangeToneMapper() noexcept;
~DisplayRangeToneMapper() noexcept override;
math::float3 operator()(math::float3 c) const noexcept override;
};
} // namespace filament
#endif // TNT_FILAMENT_TONEMAPPER_H