* Implement grid-based world origin snapping in View
Implement a grid-based world origin snapping system in View to avoid
per-frame transform updates in the future. This will allow to
improve CPU performance and to enable future caching of acceleration
structures like BVH.
The feature is protected by the 'view.enable_grid_based_world_origin'
feature flag. The grid size can be set
manually via View::setGridSize or calculated automatically as 10%
of the camera's far plane distance.
A 50% hysteresis ratio is applied to prevent rapid origin flipping
near grid edges.
Exposed the new API to Java and JavaScript bindings and added
unit tests in filament_test.cpp.
BUGS=[504726278]
* Refine grid-based world origin snapping implementation
Refine the grid-based world origin snapping in View with several
improvements:
1. Support Orthographic Projections:
Calculate automatic grid size using projection matrix elements,
working for both perspective and ortho without assuming positive
near plane.
2. Stable Automatic Grid Size:
Only update effective grid size when a position snap occurs.
This prevents instability when frustum scale changes smoothly.
3. Immediate Manual Override:
Force an immediate snap when user manually changes grid size.
Added test cases for ortho and auto-grid size in filament_test.cpp.
Introduced the FILAMENT_ENABLE_EXCEPTIONS (default ON) and
FILAMENT_ENABLE_RTTI (default OFF) CMake options to control these
features globally. This replaces previous hardcoded, platform-specific
overrides.
Added a -E flag to build.sh to easily disable exceptions during
build configuration.
Removed hardcoded -fno-exceptions and -fno-rtti from
android/build.gradle to allow CMake to control these flags, but kept
-fno-rtti enabled by default for the Java/Android build as requested.
Documented in CMakeLists.txt and BUILDING.md that the JNI library
(Android/Java build) requires exceptions to be enabled.
Enabled RTTI specifically for the assimp target in
third_party/libassimp/tnt/CMakeLists.txt to fix compilation errors
caused by its use of dynamic_cast.
SIZEGUARD_BYPASS
* Filament Error Handling Remediation and noexcept Cleanup
- Replaced assert_invariant with FILAMENT_CHECK_PRECONDITION in
Renderer::beginFrame for caller bugs.
- Removed noexcept from Camera::setCustomProjection to allow precondition
checks to throw.
- Removed noexcept from Texture and InstanceBuffer methods using precondition
checks.
- Documented silent clamping in View::setBloomOptions.
- Clarified comment in FrameGraphResources regarding preconditions.
- Refined MaterialInstance::commit to split texture loop into check and update
passes, preventing partial state changes on precondition failure.
* backend: Propagate backend thread exceptions to the main thread.
Introduce a mechanism to catch exceptions thrown on the backend thread and
rethrow them on the main thread. This prevents deadlocks and allows the
application to handle fatal backend failures gracefully.
- Consolidate synchronization primitives in DriverBase.
- Add mHasUnrecoverableError flag to interrupt blocked fence waits.
- Optimize waitForFence to avoid extra atomic reads in common paths.
- Propagate FenceStatus::ERROR across all backends.
- CommandBufferQueue now stores a std::exception_ptr when the backend fails.
- The backend enters a "zombie" state on failure, skipping further command
execution but allowing clean shutdown.
- Public APIs in Renderer and Engine now check for stored exceptions and
rethrow them, documented with @throws.
- Guarded by __EXCEPTIONS to ensure no overhead when exceptions are disabled.
- Add unit test for fence interruption and document new APIs.
BUGS=[407545700]
* feat: harden backend exceptions and add hasUnrecoverableFailure API
- Update Renderer::beginFrame() and Renderer::shouldRenderFrame() to
return false early if an unrecoverable backend exception has been
delivered to the main thread.
- Document the new return behavior for beginFrame() and
shouldRenderFrame() in Renderer.h.
- Add Engine::hasUnrecoverableFailure() to the public API to allow
apps to check for fatal errors without relying on exceptions.
- Implement hasUnrecoverableFailure() in FEngine by delegating to
CommandBufferQueue.
- Expose Engine::hasUnrecoverableFailure() to Java bindings
(Engine.java and JNI).
- Expose Engine::hasUnrecoverableFailure() to JavaScript bindings
(jsbindings.cpp).
* java: propagate C++ Panics & exceptions to JAVA
- A triangle tracker under the progress bar to track the test
currently in view within the scroll view.
- Text label to indicate the current device under test when a
test is running.
- add filter intent arg
- Add Fox (animation, skinning) and TransmissionRoughnessTest
(transmission) to the test.
- Add applyAnimation to the ValidationRunner
- Make camera zoom in for default test and adjust tolerance
acoordingly
- Fix non-determinism of SSR by
- waiting for more frames
- account for false returned from beginFrame
- Clear frame history on new test entry
- Include Build.HARDWARE information into result
- Make results array more thread-safe
- Remove unused paths
- Adjust tolerance for two tests
Implemented the custom 3D LUT feature in the ColorGrading API, allowing
users to specify a custom LUT for final color mapping.
To test this feature, added a "Custom LUT" option to the color grading
settings in the gltf_viewer sample. This includes several procedurally
generated LUTs for testing purposes:
- Negative
- Grayscale
- Sepia
- Teal and Orange
Updated settings serialization (Settings.cpp) and the viewer UI
(ViewerGui.cpp) to support these options.
FIXES=[362596936]
- Update default_test.json with targeted test variants and documented
tolerance presets.
- Refactor test suite to cover distinct code paths while maintaining
multi-backend compatibility (OpenGL/Vulkan).
- Integrate TestProgressBar and UI summary text for better test progress
visualization.
- Enhance validation managers with dynamic naming, zip extraction/export,
and bundle creation.
- Update validation_app.py terminal UI to support multiple devices,
device switching, and local result serving.
* a new tribool type in libutils (header only)
* Support `Engine::compile` overload to generate view-dependent variants
Implemented an `Engine::compile()` method to infer and generate shader
permutations directly based on feature states from a provided `View`
alongside `tribool` settings (skinning, shadowReceiver).
- Added a new `Material::compile()` overload that directly accepts
a precalculated `FixedCapacityVector<Variant>`, decoupling the
Material compilation process from specific feature flag checks.
FIXES=[468058969]
This commit introduces several features:
- Backend Testing: Support testing across both OpenGL and Vulkan. Test
configurations expand per backend, and the Filament Engine alongside
ModelViewer is recreated dynamically when the backend switches to isolate
resources.
- UI Controls: Added a backend filter toggle and a test progress bar to the
main activity, themed appropriately using Material design.
- Memory Optimizations: Drastically reduced memory usage by displaying
scaled-down thumbnails (128x128) in the main list. Full-resolution images
are lazy-loaded from disk on demand when clicking a thumbnail to view, and
large bitmaps are aggressively recycled.
- Device Info Collection: ValidationResultManager now collects and reports
detailed GPU driver info for each instantiated backend in the output
results.json.
- Engine Teardown: Introduced an explicit destroy() method in ModelViewer to
ensure full resource cleanup during engine recreation.
* fp32 texture formats are not necessarily filterable
Mobile devices don't always support filtering of fp32 textures.
This PR adds a query at the driver level.
High precision EVSM is now conditional to this feature being supported.
* use MTLDevice supports32BitFloatFiltering if available
- Introduce `shiftRadius` to allow positional tolerances by searching
a local neighborhood, absorbing sub-pixel shifts and MSAA quirks.
- Introduce `blurRadius` to apply local area averaging, ignoring
high-frequency noise like hardware dithering.
- Enhance `ImageDiffResult` to include an `averageError` array and
a 10-bin `errorHistogram` for actionable failure debugging.
- Update Android JNI bindings (`ImageDiff.java` and `ImageDiff.cpp`)
to propagate the new error distribution statistics to Java callers.
- Update C++ unit tests to cover the new heuristic options.
- Document the new parameters and JSON result format in README.md.
- Add synthetic image generation tests in `tools/diffimg/tests/` to
validate the CLI tool's handling of spatial shifts and dithering.
Add the following information:
- Android build fingerprint, version
- GPU driver name, info, vendor name
- Time elapsed for test
- Rendered images (as oppose to diff image)
filament-utils:
- Add DeviceUtils to hook into Platform methods for reading out
strings about gpu vendor, driver.
Fix "tolerance" in test definition
- Add reset functionality to ModelViewer
- We use this reset in render-validation to not have to reload
the scene in runs that use the same model.
- Fix a bug where the camera manipulator is disabling setting
the camera via view config.
We add the ability for the maniuplator to be null. If it is null,
then the camera settings won't be determined by the manipulator.
This is useful for when we want to set the camera parameters
outside of the modelviewer, but still use it to do everything else.
- refactoring/clecanup to make some changes easier
- VSM mipmap generation was mistakenly disable when blur radius was 0
- analytic variance was disabled because the math only worked for VSM. Fixed the math.
- better handling of large blurs when using fp32
- implement EVSM equivalent of receiver plane normal bias
- use correct EVSM clearing color
- mipmapping with point lights works much better (no seams)
- min variance is computed automatically
- custom high precision mipmaping shader for VSM
Android App:
- Refactored activity_main.xml to use modern Material 3 components.
- Grouped Export/Help buttons logically and moved ADB instructions
to dedicated info icons.
- Added an in-app "Load Test" button to explicitly pick test bundles.
- Updated ValidationInputManager.kt to gracefully handle relative
zip_path intent execution via ADB targeting app external storage.
Tooling & Documentation:
- Added a Python Textual TUI (validation_app.py) to automate device
discovery, test execution, bundling, renaming, and
downloading/uploading.
- Added README.md in test/render-validation documenting ADB intent
parameter capabilities and TUI dashboard setup.
- Update UI
- Wait for resources to finish loading before testing
- Refactor validation to input/output
- Move assets to be generated from the repo
- Fix AutomationEngine java binding to add missing fields
- This is an initial implementation, not yet complete
- Goal of this sample is to run a series of offscreen single
frame captures, and capmre the result against a set of golden
images
- Uses existing scene description in libs/viewer and
test/renderdiff
- Uses existing image difference description/implementation in
libs/imagediff
- Add imagediff API to filament-utils-android
* implement some missing javascript bindings
DOCS_FORCE
* use exclusively javadoc comments in Options.h
This is because this file is currently used to generate java and
javascript bindings and doxygen can ingest javadoc.
And regenerate javascript and java bindings
* add missing java bindings
- Add new library to do tiff import/export. This library is
different from imageio in that it doesn't pull in additional
3p libraries. This reduces binary size and reduces
complexity in maintaining the android build (which depends
on libs/viewer).
- The encode() code has been moved from libs/viewer to
libs/imageio-lite
- encode/decode only handles the simplest case of uncompressed
rgba.
- Extended Settings to include properties for Camera, Animation, Lights,
and Render options.
- Moved camera options from Viewer options to Camera options
- Implemented generic JSON parsing for these new settings in Settings.cpp.
- Updated AutomationEngine to apply these settings, including dynamic
creation of lights.
- Fixed a JSON parsing bug in AutomationSpec that failed on nested objects.
- Updated gltf_viewer to use the new settings and correctly initialize
AutomationEngine context.
- Add test for new json changes
- Add README to libs/viewer
- Link libs/viewer/README.md to official doc
- Remove unused libs/viewer/schemas
- Updated remote web assets (because the viewer/settings json needs to
match)
The new tone mapper, dubbed "GT7" in the code, is based on
the Gran Turismo 7 tone mapper, as described in the SIGGRAPH
2025 presentation called "Driving Toward Reality: Physically
Based Tone Mapping and Perceptual Fidelity in Gran Turismo 7".
This tone mapper exhibits fewer hue skews than the other tone
mappers, at the exception of PBR Neutral. The GT7 tone mapper
is however better at preserving the perception of high
dynamic range.
The tone mapper, as implemented, targets an SDR paper white
of 250 nits, using 100 cd/m^2 as the reference luminance (for
values of 1.0 in the linear HDR framebuffer). This can result
in an overall darker image compared to the other tone mappers
but this can be controlled through camera settings, post-
processing exposure, or lighting intensity.
The GT7 tone mapper also allows to target HDR output, and
could be made customizable via APIs if desired. The current
implementation offers a fixed aesthetic solution.
This commit introduces a significant rework of the Temporal Anti-Aliasing (TAA) system, focusing on improving reconstruction quality, robustness, and introducing flexible upscaling.
Core TAA Algorithm improvements:
- Replaced the Catmull-Rom filter with a more efficient 5-tap Lanczos filter for history sampling, which includes deringing to reduce artifacts.
- The input color buffer is now properly "unjittered" using a Lanczos reconstruction filter.
- Improved the history rejection algorithm by skipping the expensive accurate clipping when the history sample is already within the neighborhood's color gamut.
- Added a new `hdr` option to properly handle HDR content by tonemapping colors before blending and untonemapping the result.
- Removed the ineffective `VARIANCE` only history rejection method.
- Added protection against negative numbers in `sqrt()` for increased stability.
TAA Upscaling:
- Replaced the boolean `upscaling` flag with a float factor, allowing for variable upscaling ratios (e.g., 1.5x, 2x).
- Upscaling now correctly adjusts viewport and projection settings.
- The TAA shader now receives viewport and resolution information to correctly handle upscaled rendering.
API and Configuration Changes:
- Deprecated the `filterWidth` TAA option as it no longer has an effect.
- Introduced the `upscaling` float property to `TemporalAntiAliasingOptions`.
- Added the `hdr` boolean property to `TemporalAntiAliasingOptions`.
Other Changes:
- Updated UI elements in the viewer and material sandbox to reflect the new TAA options.
- Updated Javascript bindings and TypeScript definitions for the new TAA settings.
- Refactored shader code for clarity and performance.