If expecting a bool and receiving anything other than true or false,
this is invalid and should fail. This change triggered a unit test
failure which uncovered several actual problems.
* New experimental tone mapper
The new tone mapper proposed in this change replaces Uchimura (see
below) and is composed of two distinct algorithms:
- The first is the customizable compression curve from Timothy Lotte
(from GDC 2015). The curve's default parameters were chosen to
match the overall appearance (contrast) of the ACES curves used
as our current default tone mapper. This was done to provide a
good migration path to making this new solution the default in
a future version of Filament.
The compression curve can be customized via its contrast, shoulder,
input middle gray, output middle gray, and maximum "HDR value"
(scene referred).
It is important to note that the compression is only applied to
the luminance of the input scene referred value.
- The second is a novel approach by Troy Sobotka called Exposure
Value Invariant Luminance Scaling (or EVILS). This solution works
on the largest chromatic channel of the input value as opposed
to mapping all RGB channels as we do in our other tone mappers.
The algorithm effectively scales all channel by a ratio that
depends on both the compressed luminance from the first stage
and the luminance of input value normalized by the largest
channel.
This new solution offers important benefits as it manages to
preserve chromaticity for high input values. It is also designed
to provide a desirable rolloff to white on overexposure. This
means that even without gamut mapping, this solution avoids many
hue skews (red to orange, blue to purple, etc.). The results
provided by this solution are much more natural and make using
other color grading tools much easier.
* Use std::pow instead of pow
* Fix Web builds
Shockingly there were no unit tests that did a simple write-then-read.
This is important because it's easy to forget details such as trailing
commas and the fact that uint8_t is a char.
* move the focus distance from DofOptions to Camera
The DofOption parameter is now deprecated, but will still work if the
focus distance is not set on Camera.
* A few new helper APIs on Camera
- getFocalLength() which returns the focal length used internally for
DoF computations.
- computeEffectiveFov() and computeEffectiveFocalLength() which can be
used to better simulate a real camera's FOV changes with the
focus distance.
Modified gltf_viewer so it uses the effective fov/focallendth when
DoF is active.
* simplify setLensProjection
We can call setProjection directly instead of converting to a fov
first, which ends up performing atan(tan(x)).
Also improve parameters names.
Currently the only NONE and MEDIAN are available options, at some
point we may add a "MAX" option which is cheaper.
There is no real practical uses for this option with these only two
choices, other than for debugging.
This adds a `material` key to `Settings`, as a sister to `view`.
Here's an example of an automation spec that manipulates material
parameters:
[{
"name": "metallic_vs_roughness",
"permute": {
"material.scalar.roughnessFactor": [0.0, 0.5, 1.0],
"material.scalar.metallicFactor": [0.0, 1.0]
}
}]
Currently this is limited to float, vec3, and vec4 parameters.
This lets us generate long lists of settings permutations by writing a
simple JSON spec. For example, the following spec would generate six
`Settings` objects, all of which have SSAO enabled. See the unit test
for a larger example.
```
{
"name": "viewopts",
"base": { "view.ssao.enabled": true }
"permute": {
"view.dithering": ["NONE", "TEMPORAL"],
"view.sampleCount": [1, 4, 8]
}
}
```
This introduces the `viewer::Settings` struct, and a JSON reader /
writer.
This will be used for automated testing and for client / server
communication.
Note that `viewer::Settings` is closely associated with the
`filament::View` API; when updating the latter we will often need to
update the former, as well as some serialization code. This increases
the maintenance burden and I think we should consider using a parser
library like libclang or a macro-based reflection utility.
This PR also migrates SimpleViewer into libs/viewer and un-inlines its
implementation. It does not belong in gltfio because it has an imgui
dependency.