This optimizes and cleans up some code from a 3P contributor.
When computing a bounding box, there was no need for an inner loop
through the entire skins array.
Tested using the torus model in #4973 and the `-r` flag in gltf_viewer.
- For completion, FilamentAsset now has getRenderableEntities(). This is
similar to sister methods getLightEntities() and getCameraEntities()
except there is no need to store a separate array.
- The web helmet demo does not need to enable shadows, they are already
enabled.
- The ViewerGui populateAsset() method was doing two things that are
now decoupled for clarity: setAsset() and populateAsset().
- The updateRootTransform() method is now called only when the autoscale
checkbox is toggled, instead of every frame.
- The getFooEntities() methods in Java now skip doing work for empty
lists. Actually these should not return arrays at all, but let's fix
that later, since it will break backwards compatibility.
The SimpleViewer C++ class was not viewer component like `ModelViewer`
and `<filament-viewer>`. It was actually just the UI builder used
in the `gltf_viewer` desktop app and the remote Android interface.
This adds a new implementation of the TextureProvider interface called
Ktx2Provider.
Tested using the KTX2 variant of the StainedGlassLamp model in the
Khronos samples repo.
Tested on WebGL 2.0 (Chrome v100), Android (Pixel 6 Pro), and Desktop
(Metal, OpenGL, and Vulkan via MoltenVK).
- add getUserViewMatrix() on CameraInfo, the "user" view matrix is the
view matrix before we apply the world origin transform, it is needed in
a few places, so we make it a method so that in the future we could
precompute it if we wanted to.
- remove worldOffset which is just the last column of worldOrigin
This allows clients to provide their own asynchronous texture decoders
for various mime-typed images. This is a plug-in component for gltfio,
in some ways similar to MaterialProvider.
There are two motivations for this: to decouple gltfio from STB and
to make it easier to integrate support for BasisU textures.
This also has the side effect of simplifying ResourceLoader, since the
texture decoding jobs have been moved out.
As part of this work, I made the "stb" CMake target into a traditional
static library. Previously we had several files called `Image.cpp`
whose sole purpose was to enable STB_IMAGE_IMPLEMENTATION.
mipgen can now emit basis-encoded KTX2 files. Both the desktop and
web "suzanne" samples use this as a test for compressed textures.
This PR does not add KTX2 support to glTF, but it's on the way.
`BasisEncoder` has a builder style API that calls the basis encoder to
create KTX2 files. This hides some low-level BasisU features that we are
not using, like file I/O and mipmap generation.
`Ktx2Reader` is an easy-to-use API for creating Filament textures from
KTX2 files. Its API primarily consists of these two methods:
bool requestFormat(Texture::InternalFormat format);
Filament::Texture* load(const uint8_t* data, size_t size);
The first method is used to build an ordered list of formats that are
supported by your hardware. The second method consumes the contents of a
basis-encoded KTX2 file and attempts to produce a Filament texture with
a preferred format.
IMPORTANT: Our tools still let you use KTX1 for non-compressed images
because it is useful for HDR, but you can no longer use KTX1 for
block-compressed data.
Partial fix for #4771.
The `g_linearized` variable was being used for two purposes: to denote
the linearity of the source format AND the linearity of the destination
format. This was confusing and is now split is `sourceIsLinear` and
`destIsLinear`.
This change has no effect on the the look of the suzanne demo.
Changes:
- Remove the strange header-only variant of libs/image
- Rename KtxBundle => Ktx1Bundle
- Move image/KtxUtility => ktxreader/Ktx1Reader
- Add unit test for Ktx1Reader and test stub for KTX2.
Notes:
- Ktx1Bundle does not depend on Filament and is used by cmgen
and mipgen to generate KTX files.
- Ktx1Reader has a dependency on Filament and should therefore live in
a separate library, which it now does.
In the past there was an API gotcha because users had to "get" the
animator before releasing the glTF source data. This could have been
surprising because it was a getter method, not a factory method.
This was due to overeager optimization on my part, I wanted to avoid
animator overhead for non-animated models, when in fact it has very
little overhead.
Moreover, the animator is conceivably useful even when there are no
pre-supplied animations (e.g. for applying skins), so let's just create
it unconditionally.
Motivated by #5299.
- move the control code out of FrameInfo and into
View itself. FrameInfo now just gathers information about the
frames instead of also doing part of the control.
- the control code has been refactored into a more formal PIDController.
- a few bugs were fixed in the control loop and default parameters
tuned.
The control loop itself now outputs a relative scale factor instead
of an absolute one. The relative scale factor seems easier to
control and is less jittery, and doesn't have to rely on the "integral"
term of the PID.
It's possible that more tuning is needed, but the scaling is now
more stable.
Statically link SDL2 to make our samples (glTF Viewer, etc.) completely
standalone, and include missing resources (fonts and default environment
map for the IBL).
Now that FSR scaling is cheap enough on mobile, we use it for quality
levels MEDIUM to ULTRA.
MEDIUM and HIGH use the mobile optimized version, which has a slightly
lower quality, ULTRA uses the original version.
Additionally the RCAS sharpening pass can always be disabled by setting
the sharpen value to 0.
Augment the TransformManager so it can maintain the 4th column as
double precision; we accomplish this by storing an extra float3 per matrix.
It's calculated as `doubleTranslation - float3{doubleTranslation}`.
We also add methods to set and get a transform as mat4, internally only
the 4th column is kept as double precision.
Finally when we calculate the worldTransform, we take this extra data into
account, but only for calculating the new 4th column, so the extra work
is small.
- Images with an alpha channel are now properly supported. Blending is implemented directly in the image material by blending against the known opaque background color.
- Non-EXR/HDR images were not applying the proper transfer function and were therefore displayed incorrectly.
Bring color grading back into the Rec.709 color space to match
previous behaviors. This change also implements an exact inverse
tone map function for the "Filmic" operator.
We now have an option for evaluating the bent normals from SSAO.
This is used to improve specular AO.
Currently these bent normals are not used for diffuse lighting because
they're "flat" (face normals), which is too distracting.
The bent normal buffer is stored in the SSAO texture, in a separate
layer. This is the first post processing effect that uses 2D array
in order to limit our sampler usage.
This CL also changes how we handle SPECULAR_AO_BENT_NORMALS when
material bent normals are not available: we're now using the "Cones"
algorithm with the regular normal, instead of Lagarde's approximation.
* WIP New tone mapper API
* Implement tone mapper constructors and destructors
* Add new genertic tone mapper
* Make the generic tone mapper available in our sample UIs
* Fix warnings and crashes
* Fix generic tone mapper and graph mappers in the UI
* Add Java APIs for ToneMapper
* Implement copy/move operators for GenericToneMapper
* Generalize luminance scaling in color grading
Previously the luminance scaling step was tied to a specific tone
mapping operator, called "EVILS" in the API. This was however
somewhat misleading as EVILS really is a color handling system
that's independent of what we call tone mapping.
This change splits the luminance scaling step from the tone mapping
step, allowing the use of luminance scaling (the LICH part of EVILS)
with any tone mapping operator.
As a result, the operator known as EVILS is currently mapped to the
linear operator and renamed to "RESERVED" until it is replaced by
a proper — configurable — operator.
* Update release notes
* Fix web build
Image loading errors are handled more gracefully by showing a
background color.
Added UI to set the background color.
Replaced fragment discards with solid background color.
* Add new sample app: image_viewer
This app shows how to load and visualize images. It's also useful to work
on color grading and other post-processing effects by just loading an HDR
or EXR image as a reference.
This change also adds a new exposure setting to the color grading LUT.
* Fix comments and build
* Fix Metal
* Use high precision for the UV coordinates
* Fix refactoring issue
We make better use of the framegraph, by using a pass per shadowmap,
instead of generating all shadowmaps in a single framegraph pass.
This allows us to use less temporary memory when blurring, but also
simplifies the code.
* 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