For details on how this tone mapper was developed and what problems it solves, please see the write-up, complete with interactive graphics. You can also test it interactively against other tone mappers with your own GLBs and HDR lighting here. Included files:
- pbrNeutral.glsl a sample implementation of this tone mapping function.
- config.ocio an OpenColorIO configuration defining an approximation of this tone mapper.
- pbrNeutral.cube the LUT referenced by config.ocio.
- lut-writer.mjs a script for generating the pbrNeutral.cube LUT and verifying the analytical inverse function.
Currently this tone mapper only supports output to sRGB (two flavors), but the goal is to expand that in the future. This tone mapper does not apply any gamut mapping, as it is assumed the PBR workflow uses Rec. 709 gamut for both input color textures and lighting (as in glTF), and thus the linear output is already contained within Rec. 709.
The included OCIO configuration makes it easy to use PBR Neutral tone mapping in your existing workflows before they have adopted it natively. Most popular 3D artist tools have a way to supply a custom OpenColorIO config, where you can insert ours.
Example documentation:
Note that all the following entities will be non-negative for all non-negative input.
Notes regarding these equations:
-
$\mathbf c_{out}=\mathbf c_{in}-F_{90}$ for all input colors where$0.08\leq R\leq 0.8$ ,$0.08\leq G\leq 0.8$ , and$0.08\leq B\leq 0.8$ . This gives the range of base colors for which the guarantee holds that the base color will be exactly reproduced in the output render for a shiny dielectric material facing the camera under unitary-white lighting. - For all input colors, there are no hue shifts (angle around the white axis), as the only changes are within the plane defined by the input color and the white axis (
$[1, 1, 1]$ ). - All partial derivatives of
$\mathbf c_{out}$ with respect to$\mathbf c_{in}$ are continuous over the entire domain, vanishing at the boundaries, which is what reduces visual artifacts. - This mapping is 1:1 and analytically invertible.