Compare commits

...

208 Commits

Author SHA1 Message Date
Powei Feng
6cf499326e github: fix windows release version (#9671)
Use "call" to ensure execution continues after
the batch file.
2026-02-04 21:59:46 -08:00
rafadevai
8cdba6d12e VK: add back the removed vmaFlush for staging (#9674)
This line was removed by accident in the staging bypass
fix PR.
2026-02-03 13:51:14 -08:00
Eliza Velasquez
41923df669 engine: fix stereo and parallel shader compilation
Another thing that got lost in the sea of merge conflicts that plagued the
program cache feature...
2026-02-02 08:01:54 -08:00
Eliza Velasquez
51b59bd1c1 engine: fix TAA compilation failure 2026-02-02 08:01:44 -08:00
Powei Feng
9909fd1bf4 filamat: remove unnecessary std::decay_t (#9643) 2026-02-02 08:01:02 -08:00
haroonq
c9ed58733f Swap logic of how the EGL display is initialized. (#9634)
1. Iterate over system displays using eglQueryDevicesEXT and try to initialize them.
2. If no display initialized, then try to initialize the DEFAULT display.

FIXES=[478925865]
2026-02-02 08:00:40 -08:00
Serge Metral
e2c70201b5 External sampler bind index bug (#9664)
Patching a fix for the external sampler use case where the same sampler is bound to two different indices. As it stands, the code fails to differentiate between the two layouts.
2026-02-02 08:00:29 -08:00
Mathias Agopian
8d07604604 Fix possible buffer overflow in CommandStream (#9661)
Because of an improper boundary check caused a possible unsigned
integer overflow, it was possible to overrun the command stream
buffer in RenderPass::execute().

It would happen when the batch size was larger than the buffer
capacity (usually a few MB). 

FIXES=[474264976]
2026-01-29 11:22:12 -08:00
Benjamin Doherty
fafd8f8196 Bump version to 1.69.1 2026-01-27 14:50:29 -08:00
Benjamin Doherty
8d20d7abec Release Filament 1.69.0 2026-01-27 14:50:19 -08:00
Eliza
2f1266f7dd engine: add program cache (#9297)
* engine: add program cache

This is another chunky change.

The core of this change is to cache programs in MaterialCache according to a
"specialization" (ProgramSpecialization) which is defined as the program cache
ID (the same key used for the OpenGL binary blob cache), the variant, and the
set of spec constants.

As part of this change, a lot of the implementation details of shader
compilation were refactored from Material to MaterialDefinition. The resulting
flow is a lot cleaner and easier to reason about, since shader compilation is
now a pure function of the MaterialDefinition + ProgramSpecialization.

Since the global cache program lookups might take a bit of time to compute
hashes, etc, I left the set of cached programs in Material as well, which kind
of acts like an L1 cache. The effect is that prepareProgram() and getProgram()
should be no slower than HEAD, even with the more complex caching requirements.

I'm planning on writing a document about this (and all changes up until this
point), but I'm being asked to work on higher priority things and I wanted to
have this PR out for review in the meantime so it doesn't bitrot.

* engine: fix unit tests

* engine: fix spec constants intern pool memory leak

* engine: address program cache comments

* engine: address more program cache comments

* engine: matdbg support for program cache

* engine: reinstate descriptorLayout calls

* engine: address bitrot

* engine: add feature flag to disable program cache

* engine: use material CRC32 for program cache

The "cache ID" of a material is supposed to uniquely identify a shader program
and all its variants. This is true to a certain extent, but does not account for
the code generation that happens at runtime. Two materials may have "identical"
shader programs, but due to each material's differing unique metadata, the final
compiled programs may end up very different. Unfortunately, this means we cannot
rely on the "cache ID" alone to determine a shader program's reusability.

Ideally, we should hash this "cache ID" with the exact set of changes to each
shader program so that we could reuse programs across materials. Instead, as a
stopgap solution, use the material's CRC32 instead.

* engine: fix double-free in program cache

* engine: address comments

* engine: assert_invariant empty material cache
2026-01-27 13:09:42 -08:00
Benjamin Doherty
05be4b0acc Update filament-tools macOS classifier 2026-01-27 11:34:46 -08:00
Mathias Agopian
9d9c3d34f8 Fix a typo that corrupted the tags of descriptor sets and layouts (#9641)
- we were setting the tag of the descriptor set to its layout, so
  both tags were incorrect.

- added in debug build we now store the tag of the bound descriptor
  sets in the current bindings structure.
2026-01-27 10:44:04 -08:00
Powei Feng
491531c76b gltfio: fix possible overflow for meshopt decompression (#9637)
FIXES=478908360
2026-01-27 17:54:36 +00:00
Mathias Agopian
bf4ea771be AtlasAllocator: Implement free() and upgrade to Buddy Allocator (#9635)
This change upgrades AtlasAllocator from a simple linear allocator 
(reset-only) to a full Buddy Allocator capable of both allocation and 
deallocation. This enables persistent shadow map management where 
individual shadow maps can be updated or resized without rebuilding the 
entire atlas every frame.

Key changes:
- Implemented AtlasAllocator::free():
	- Uses the existing QuadTree structure to track allocations.
	- Automatically coalesces empty sibling nodes back into larger 
      parent blocks (standard Buddy Allocator behavior).
	- Optimized to be allocation-free and recursion-free, using direct 
      array indexing.

- Added comprehensive unit tests

Updated documentation.

The QuadTreeArray implementation remains unchanged but is now fully 
utilized for bidirectional tree traversal (down for alloc, up for free).

This change will later allow us to cache shadow-maps.
The AtlasAlocator is currently disabled by a feature flag.
2026-01-27 09:21:20 -08:00
Doris Wu
dd5882760b implement memory mapping for wgpu (#9632)
It is a zero effort implementation where it just calls `updateBufferObject` to update the data.
2026-01-27 03:05:46 +00:00
rafadevai
1707dda62a VK: Only bypass the staging buffer when is not in use (#9633)
In the cases where a frame takes more than the vsync
time, we start seeing some rendering artifacts because
we write to a buffer that is currently in flight.

Not 100% sure why the current approach fails but for
now, the staging buffer is bypassed only when the buffer
is not in use or referenced by any other resource.

FIXED=[445455050]
FIXED=[477305399]
2026-01-26 17:57:56 -08:00
Benjamin Doherty
c4d3eded72 Bump MATERIAL_VERSION to 69 2026-01-26 14:00:12 -08:00
Powei Feng
ca4b0650fa Re-commit "Generalize scene description for automated testing (#9627)"
Contains a fix to the default sunlight parameters that broke the
renderdiff tests.
2026-01-26 13:33:09 -08:00
Powei Feng
33d22b3146 Revert "[automated] Updating /docs due to commit 60b1951" and "Generalize scene description for automated testing (#9627)"
This reverts commit e2dd47bf42.
This reverts commit 60b1951f90.

renderdiff test breakage
2026-01-23 17:20:31 -08:00
Filament Bot
e2dd47bf42 [automated] Updating /docs due to commit 60b1951
Full commit hash is 60b1951f90

DOCS_ALLOW_DIRECT_EDITS
2026-01-24 00:04:44 +00:00
Powei Feng
60b1951f90 Generalize scene description for automated testing (#9627)
- 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)
2026-01-24 00:02:06 +00:00
Filament Bot
6ce06b1b60 [automated] Updating /docs due to commit e21d4a5
Full commit hash is e21d4a5326

DOCS_ALLOW_DIRECT_EDITS
2026-01-23 09:10:02 +00:00
Mathias Agopian
e21d4a5326 SimSky: Refine Stars, Water, and Heat Shimmer simulation (#9628)
- **Stars**:
  - Implemented procedural stars using hash-based noise.
  - Added UI controls for Star Density and Enable/Disable.
  - Tuned star brightness (reduced intensity) and refined twilight fade timing (visible during nautical twilight).
  - Improved compositing with aggressive cloud occlusion and non-linear fade.
  - Added star reflections to water, strictly masked to the horizon line.

- **Heat Shimmer**:
  - Fixed horizon artifacts by decoupling shimmer from atmospheric density (Mie scattering).
  - Implemented FBM-based view distortion for heat waves.
  - Added sun elevation fade (shimmer fades out as sun rises > 30°).

- **Water**:
  - Implemented Finite Difference normal calculation as a high-quality fallback when "Derivative Trick" is disabled.
  - Added "Octaves" parameter to control wave detail.
  - Refined reflection logic to handle stars and sun disk properly.

- **System**:
  - Updated [simulated_skybox.mat](cci:7://file:///Users/mathias/sources/git/filament/docs_src/src_raw/wip/sky/simulated_skybox.mat:0:0-0:0) with new material parameters (`starControl`, `waterControl`).
  - Refactored JS bindings in [SimulatedSkybox.js](cci:7://file:///Users/mathias/sources/git/filament/docs_src/src_raw/wip/sky/SimulatedSkybox.js:0:0-0:0) and organized `main.js` UI into logical folders.

DOCS_FORCE
2026-01-23 01:06:07 -08:00
Filament Bot
7fd9e728ae [automated] Updating /docs due to commit b66736b
Full commit hash is b66736b8cc

DOCS_ALLOW_DIRECT_EDITS
2026-01-22 23:23:09 +00:00
Powei Feng
b66736b8cc docs: move wip skybox demo to /docs_src/src_raw (#9626)
/docs content is overwritten by content in /docs_src

(This tag will force a regeneration)
DOCS_FORCE
2026-01-22 23:20:10 +00:00
Doris Wu
ea8f6a3c92 return empty string for es2 (#9623) 2026-01-22 14:49:54 -08:00
Doris Wu
adcdbb45f9 fix typo (#9625) 2026-01-22 14:49:38 -08:00
Mathias Agopian
cff958587d initialize VirtualMachineEnv on the right thread (#9624)
PerformanceHint manager needs a java thread during initialization,
so we need to attach a jvm to the thread that's going to be used.
That thread is the filament backend thread, not necessarily the thread 
the platform is created on.

So we make sure to do that from the backend thread.


FIXES=[427945768]
2026-01-22 10:24:39 -08:00
Mathias Agopian
9ab2326f15 some work in progress sample 2026-01-22 00:50:35 -08:00
Anish Goyal
8785acd352 Fix push constants with ext sampler (VK) (#9445)
Currently, in Vulkan, we set the pipeline layout when binding the
pipeline, which doesn't happen until draw time when external samplers
are present. In cases like that, we push constants with the layout
VK_NULL_HANDLE, which is not valid. Instead, we can wait until the
pipeline layout is known, and then flush all push constants.
2026-01-22 08:15:20 +00:00
Mathias Agopian
57767b7f27 Fix buffer overflow in RenderPass command batching (#9619)
The command batching logic in RenderPass::Executor::execute calculates a
conservative `maxCommandSizeInBytes` to determine how many commands can
safely fit in the driver's circular buffer.

However, this calculation failed to account for the dynamic memory
allocation incurred by the Per-Material descriptor set binding (via
`MaterialInstance::use`). This binding allocates a `DescriptorSetOffsetArray`
in the command stream, which was unbudgeted.

In scenarios with frequent material and scissor changes, the accumulated
deficit from these unbudgeted allocations could exceed the buffer 
capacity, leading to a crash.

This change:
1. Adds the missing accounting for the Per-Material dynamic allocation 
   to `maxCommandSizeInBytes`.
2. Adds a 20% safety margin to the calculated size to robustly handle
   alignment padding and worst-case scenarios.


FIXES=[474264976]
2026-01-21 21:03:49 -08:00
Powei Feng
febcfc8f2d fgviewer: add info in panel for render passes (#9618)
- Add plumbing to add more information about rendertargets
   (including discard flags and pass id) to the fgviewer pass
   struct.
 - Add UI to display information about a selected pass
 - Highlight a selected resource or pass
2026-01-22 03:39:20 +00:00
Filament Bot
c04c387a89 [automated] Updating /docs due to commit 78ac946
Full commit hash is 78ac9467f8

DOCS_ALLOW_DIRECT_EDITS
2026-01-22 03:05:41 +00:00
Sungun Park
78ac9467f8 Release Filament 1.68.5 2026-01-21 19:01:22 -08:00
Romain Guy
73b60d4db8 Add a new tone mapper (#9614)
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.
2026-01-21 17:31:27 -08:00
Ben Doherty
7266fd67db Add filament-tools subproject (#9622) 2026-01-21 15:22:39 -08:00
Filament Bot
469f2c94da [automated] Updating /docs due to commit d4e0d05
Full commit hash is d4e0d051b1

DOCS_ALLOW_DIRECT_EDITS
2026-01-21 22:26:09 +00:00
Powei Feng
d4e0d051b1 docs: make docs more consistent and complete (#9620)
- Add documentation for specgen along with proper math rendering
- Adjust the heading size, capitalization of various READMEs.
- Add backend test README to the doc
- Rename the CI related tests to have prefix "CI:"
2026-01-21 22:22:12 +00:00
Ben Doherty
df74a5a352 Re-enable iOS filamat builds (#9598) 2026-01-21 19:30:00 +00:00
Doris Wu
21fd32266a Add support for custom morphing (#9550)
BUGS=[443321184]
2026-01-21 17:11:35 +08:00
Sungun Park
cd7c7b369b Add helloasync sample (#9617)
Introduces a new sample application demonstrating asynchronous resource
management. It shows how to asynchronously create and update Filament
resources (Textures, VertexBuffers, IndexBuffers) and provides examples
of managing chains of asynchronous operations effectively.

BUGS=[442921995]
2026-01-21 00:38:08 +00:00
Powei Feng
65ed7099c0 fgviewer: UI updates (#9615)
- Pick a default view when database is filled.
 - Fix d3, d3-graphviz depdency.
 - reduce the size into a smaller table (to avoid scrolling)
 - slant the pass items to allow smaller cells for the table.
 - make subresource rendering the same as regular resource
   rendering with a color hint.
 - Use color-only to indicate resource/pass interaction (read,
   write, read-write, no-access)
 - add tooltip to indicate resource action
2026-01-20 21:02:23 +00:00
rafadevai
af34572883 VK: Add support for VK_KHR_global_priority (#9607)
Add support for application that want to change the
priority of GPU queues at a system level.
2026-01-20 19:53:55 +00:00
Anish Goyal
1f6a67b2a2 Fix race condition for cache prewarming (#9613)
Right now, if a material is destroyed just after creation, it's possible
for prewarm to attempt to use destroyed shader modules. This ensures
that the resources are kept until after any queued jobs have run.

While it is likely ideal to properly cancel the prewarm if the program
has been destroyed, this seems like a rare occurrence in practice.
2026-01-20 18:04:34 +00:00
Sungun Park
7701e7a65a Handle deferred destruction for asynchronous objects (#9604)
When an asynchronous object is destroyed immediately after creation, the
background creation process may still be active, holding a reference to
the object. We now defer destruction in these cases until the creation
process completes to ensure the reference remains valid.

Implementation details:
1. Add a mechanism to stop the ServiceThread to drain pending
   asynchronous tasks earlier. This ensures the mCreationComplete flag
   in the frontend object is set to true.
2. Later, the engine's terminate performs garbage collection for the
   deferred destruction. All of them must be successfully processed.

BUGS=[442921995]
2026-01-17 02:44:28 +00:00
Filament Bot
65a91832a8 [automated] Updating /docs due to commit acb47ff
Full commit hash is acb47ffed5

DOCS_ALLOW_DIRECT_EDITS
2026-01-16 00:26:35 +00:00
Powei Feng
acb47ffed5 Release Filament 1.68.4 2026-01-15 16:21:37 -08:00
Filament Bot
13c0304d84 [automated] Updating /docs due to commit febdf39
Full commit hash is febdf3974c

DOCS_ALLOW_DIRECT_EDITS
2026-01-15 23:24:29 +00:00
Powei Feng
febdf3974c docs: improve release and test documentation (#9609)
- Reorder the release-related documents into one heading.
 - Added CocoaPods README as part of the documentation.
 - Fixed typo for renderdiff doc
 - Added backend test doc
2026-01-15 23:22:00 +00:00
Powei Feng
390acec928 vk: add feature flag for acquiring swapchain in makeCurrent (#9610)
Removing this behavior in #9541 caused a breakage in one of our
clients. We use a feature flag to enable the old behavior.

BUGS=476144715
2026-01-15 22:48:12 +00:00
Powei Feng
ff806f8c3e Misc fixes to address old compiler errors (#9611)
Certain older compilers (e.g. clang in NDK 25.1.8937393) cannot
handle the c++ stylistic changes that were recently added
(though they are correct by spec).

 - In Engine.cpp, .find() cannot automatically infer the right type
   (std::string_view vs. utils::CString).
 - In fg/framegraph, various templated short-hands still require
   typename.
2026-01-15 20:27:26 +00:00
Powei Feng
06c4faabc3 vk: disable pushconstant backend test for CI
Due to flakiness.
2026-01-15 11:36:46 -08:00
Powei Feng
92aec16fa3 Add comment to indicate TextureFormat value (#9608)
This will help with debugging if we needed to print out a
TextureFormat value.
2026-01-15 19:21:39 +00:00
Mathias Agopian
f1ffb783d8 feat(engine): Add automatic frame skipping to manage CPU/GPU latency (#9595)
* feat(engine): Add automatic frame skipping to manage CPU/GPU latency

Introduces a new feature, disabled by default, that allows the engine to automatically skip frames when the CPU gets too far ahead of the display's refresh rate. This helps to reduce overall latency by preventing a backlog of frames from building up in the driver queue.

The feature can be enabled with the "engine.skip_frame_when_cpu_ahead_of_display" property.

To implement this, the compositor timing mechanism has been refactored. Instead of reporting an absolute `expectedPresentTime`, the backend now provides an `expectedPresentLatency` relative to vsync. This is more robust against synchronization issues with platform callbacks (like Android's Choreographer), as the latency is generally a constant value.

BUGS=[474599530]
2026-01-15 09:50:56 -08:00
Mathias Agopian
b708300586 Refactor implicit DriverApi dependency (#9606)
Removed implicit dependency on FEngine::getDriverApi() in critical 
rendering paths. This change makes the DriverApi dependency explicit by 
passing it as a parameter.


Key changes:

- FRenderer: Now accepts DriverApi& in renderInternal and renderJob. 
Caches feature levels and capability flags in the constructor.

- PostProcessManager: Caches feature flags and workaround flags in 
init(). Updated PostProcessMaterial and configure* methods to accept 
DriverApi&.

- FMaterial: Caches support flags (stereo, parallel shader compile) and
default material pointer in the constructor. 
Updated precacheDepthVariants and prepareProgram to rely on these 
cached values or passed parameters.

- ShadowMapManager: Caches workaround flags in the constructor.

- FEngine: Updated prepare() to accept DriverApi&.

- RenderPass: Updated to accept DriverApi& in constructor and 
appendCommands.

- Removed implicit DriverApi calls from hot paths to reduce overhead 
and improve safety.


One common pattern in this change is to cache getters in constructors
so that we don't need the DriverApi dependency later during rendering.
The intention here is to remove DriverApi& from as many places as
possible so that we can later have multithreading for command
recording.

This PR should not change any behavior.
2026-01-15 09:11:12 -08:00
HanYunChenLuo
f88d757d06 Add glibc check to support build filament on Linux musl-based distrib… (#9592) 2026-01-14 23:22:07 +00:00
Powei Feng
4d96f188d1 backend: CallbackHandler dstor inlined in header (#9605)
Defining the destructor in a cpp will break downstream clients.

The previous move to cpp was part of #9508.
2026-01-14 22:22:10 +00:00
Powei Feng
2d943f40bb vk: fix push constant implementation and test (#9588)
All stages share a push constant "block". We need to order
the fragment stage bytes to after the vertex stage if they
both exists.

FIXES=453776664
2026-01-14 18:18:04 +00:00
Doris Wu
92c058a736 fix gtao shader on mobile (#9591) 2026-01-13 14:11:34 +00:00
Mathias Agopian
ba819bcfca Docs: Improve documentation in public headers (#9603)
This commit clarifies and corrects documentation in several public header
files. The changes include fixing typos, improving wording, and adding
missing details to make the API easier to understand and use.

No functional changes are included in this commit.
2026-01-12 14:31:42 -08:00
Mathias Agopian
e22f1adfa7 make "native streams" deprecated (#9602)
Co-authored-by: Powei Feng <powei@google.com>
2026-01-12 14:31:15 -08:00
Anish Goyal
f2bca03360 Add external format to cache prewarming (#9558)
Provides logic to load and check for external format ids, and
build fake pipelines against them when relevant, to prevent
hitching when using external formats.

For now, we're going to use upto five likely types of YCbCr
conversions, which seem to cover all usecases encountered. This
means we might compile pipelines with external samplers a total of
4 additional times on top of the baseline (5 in total), or 3 additional
times on the devices we're currently testing (4 in total).

* Add base pipeline prewarm call for ext samplers

This is necessary because in some cases, a material that supports
external samplers will use RGB inputs instead of YCbCr inputs, and will
miss the cache.
2026-01-12 19:32:01 +00:00
Ben Doherty
5f07d701f0 Fix CocoaPods build (#9597) 2026-01-12 10:20:51 -08:00
Mathias Agopian
496a50bc89 make getWorldFromModelMatrix() accessible in fragment shader (#9584)
this requires to specify `apiLevel: 2` in the material.

FIXES=[474353927]
2026-01-12 09:32:23 -08:00
Mathias Agopian
6ccb6c4cce split FeatureFlagManager out of FEngine (#9596)
* split FeatureFlagManager out of FEngine

- Separate the Feature flags management from FEngine.
- Make FeatureFlagManager available to backends through DriverConfig
- add a way to override a feature flag value at runtime using
  environment variables or system properties (on Android).

e.g.:

```
env "feature.name=true" gltf_viewer
```
or 
```
adb shell setprop debug.feature.name true
```

Co-authored-by: Powei Feng <powei@google.com>
2026-01-12 09:31:51 -08:00
Powei Feng
42c78fd0a9 github: refactor postsubmit CI tasks into single yml (#9587) 2026-01-12 17:28:53 +00:00
Doris Wu
3d0e2923ae Fix VB-GTAO on remote webui (#9599) 2026-01-12 19:10:30 +09:00
Mathias Agopian
408b2371f0 allow FILAMENT_TRACING_CALL to take extra parameters (#9593) 2026-01-09 15:08:27 -08:00
Powei Feng
6ea08b40a8 gl: small fixes to push constant implementation and test (#9594)
- Add code for handling empty/null constant name
 - Use glUniform1ui() instead of glUniform1i() to workaround
   crash on macbook pro (m4).
 - Fully specify the constant name in the test (e.g.
   `pushConstantsF.red` instead of `red`).
 - Make sure that the uniform names are different between
   vertex and fragment in the test. This is due to different
   constant structs being defined between the two stages.

FIXES=453757504
2026-01-09 14:48:52 -08:00
Doris Wu
5eb0f7d3ec Fix the vbotest sample (#9581)
* set clear to true

* feedback
2026-01-09 10:15:44 +08:00
Powei Feng
d465d59c3a github: run filament tests in presbumit (#9586) 2026-01-08 21:25:58 +00:00
Filament Bot
af9a60d175 [automated] Updating /docs due to commit 8e0f0c9
Full commit hash is 8e0f0c92ce

DOCS_ALLOW_DIRECT_EDITS
2026-01-08 20:19:49 +00:00
Benjamin Doherty
8e0f0c92ce Release Filament 1.68.3 2026-01-08 12:14:07 -08:00
Anish Goyal
5a14fb4b5d Cache prewarm base case (#9552)
Prevents hitching for most pipelines, on certain devices with Turnip-based drivers

This does not address external samplers yet. This simply handles the
case where we want to prewarm a pipeline with the base configuration.

Refactor program's descriptor set layout bindings, clean up some leaking
resources
2026-01-08 11:43:32 -08:00
dependabot[bot]
22a1aacb21 Bump urllib3 in /docs_src/build in the pip group across 1 directory (#9585)
Bumps the pip group with 1 update in the /docs_src/build directory: [urllib3](https://github.com/urllib3/urllib3).


Updates `urllib3` from 2.6.0 to 2.6.3
- [Release notes](https://github.com/urllib3/urllib3/releases)
- [Changelog](https://github.com/urllib3/urllib3/blob/main/CHANGES.rst)
- [Commits](https://github.com/urllib3/urllib3/compare/2.6.0...2.6.3)

---
updated-dependencies:
- dependency-name: urllib3
  dependency-version: 2.6.3
  dependency-type: direct:production
  dependency-group: pip
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-01-08 18:48:08 +00:00
dependabot[bot]
e5b6c11399 Bump urllib3 in /test/renderdiff/src in the pip group across 1 directory (#9582)
Bumps the pip group with 1 update in the /test/renderdiff/src directory: [urllib3](https://github.com/urllib3/urllib3).


Updates `urllib3` from 2.6.0 to 2.6.3
- [Release notes](https://github.com/urllib3/urllib3/releases)
- [Changelog](https://github.com/urllib3/urllib3/blob/main/CHANGES.rst)
- [Commits](https://github.com/urllib3/urllib3/compare/2.6.0...2.6.3)

---
updated-dependencies:
- dependency-name: urllib3
  dependency-version: 2.6.3
  dependency-type: direct:production
  dependency-group: pip
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-01-08 10:28:15 -08:00
Mathias Agopian
85ebd67a28 feat(taa): Overhaul TAA implementation for improved quality and upscaling (#9573)
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.
2026-01-07 15:25:38 -08:00
Powei Feng
f33a779668 vk: move swapchain acquire() to as late as possible (#9541)
makeCurrent is not meant to acquire the swapchain; we should
do so at the momemnt we need it, to shorten the amount of time
a swapchain image/buffer needs to be held.
2026-01-07 18:36:54 +00:00
Sungun Park
1b5916b655 Rename AsyncCallbackType to AsyncCompletionCallback (#9579) 2026-01-07 18:18:49 +00:00
Anish Goyal
d8720cd858 Rename DescriptorSetLayoutBinding to DescriptorSetLayoutDescriptor (#9576)
Since the struct refers to descriptors as opposed to specifically
bindings (although they do contain binding information as well), this
name is more appropriate.
2026-01-07 16:52:50 +00:00
Doris Wu
44636bddaa Split Skinning out of Visibility struct (#9575) 2026-01-07 11:37:42 +08:00
Sungun Park
1741723687 Add user parameter to runCommandAsync (#9577) 2026-01-06 18:37:42 -08:00
Mathias Agopian
ad2c291d4a dispersion in XYZ space (#9572)
- spectral reconstructions with 4 samples
- unroll the whole dispersion computation to improve performance
  (batch texture fetches and reuse common values)
- tool to generate the matrices for spectral integration
2026-01-06 16:58:56 -08:00
Mathias Agopian
52ffd80041 Refactor FrameGraph pass API for flexibility (#9571)
This commit simplifies and unifies the FrameGraph's `addPass` API.
Key changes:
- The `addPass` method now uses a single, more flexible implementation
  that handles different lambda signatures for both the setup and
  execute stages.
- The execute lambda can now optionally omit the `DriverApi&` parameter,
  reducing boilerplate for simple passes.
- The `addTrivialSideEffectPass` helper has been removed.
  Side-effect-only passes can now be created directly with `addPass`
2026-01-06 14:20:47 -08:00
Doris Wu
44dde744ea Several optimizations for UBO batching (#9545) 2026-01-06 05:52:32 +00:00
Mathias Agopian
c18ddf929e Improve frame_generator sample tool (#9570)
- Add support for vector parameters (float2, float3, float4) in the 
  parameters file using `{x, y, z}` syntax.
- Allow comments (`#`, `//`) and empty lines in the parameters file.
- Make the end value optional in the parameters file 
  (defaults to start value).
- Add `--size` / `-S` option to specify viewport dimensions.
- Optimize rendering by pre-filtering active material parameters.
- Remove hardcoded default parameters and silently ignore missing 
  parameters to support shared configuration files.
- Add documentation for the parameters file format.
2026-01-05 20:28:04 -08:00
Mathias Agopian
5661365248 improved the dispersion computation (#9544)
- Split the function so that the 3-components loop is more apparent.
- Factored out the parts of the computation that don't depend on the
index of refraction, so they're only computed once.
- Moved the lod-from-roughness computation out of the loop as well. 
  It does depend on the IOR, but so little that it's not worth it.

The most important result of this change is that the code is now in
good shape if we wanted to change the implementation of dispersion for
these cases (for e.g.) :
- do the computation in the XYZ space
- use more than 3 wavelengths samples
- or use a stochastic approach, trading banding for noise

RDIFF_BRANCH=ma/better-dispersion
2026-01-05 20:27:34 -08:00
Powei Feng
bcb9d258c2 vk: fix broken android build (#9574)
Should use VK_NULL_HANDLE instead of nullptr where applicable
in VulkanPipelineCache.
2026-01-05 20:27:07 -08:00
Anish Goyal
53a94c4547 Add thread pool and callback manager / knobs for enabling + disabling prewarm (#9515)
* Update createPipeline to have pipeline key input
Right now, createPipeline in VulkanPipelineCache assumes that you are
building a pipeline using mPipelineRequirements as the key, and that it
should be stored in the cache. In the case of the pipeline prewarming
change, this is not going to be the case; sometimes, the pipeline will
be stored in the cache, and sometimes it will be deleted immediately.
Also, the prewarmed pipelines will be created using separately defined
keys.

* Add knobs for enabling / disabling prewarm

* Add thread pool to VulkanPipelineCache

* Fix dynamic rendering enablement check
Query device features to ensure it is supported / we don't just have the
extension. Also, proactively enable dynamic rendering when creating the
device.
2026-01-05 23:55:08 +00:00
Filament Bot
928ffe94a7 [automated] Updating /docs due to commit dcb78c7
Full commit hash is dcb78c7144

DOCS_ALLOW_DIRECT_EDITS
2026-01-05 21:56:49 +00:00
Mathias Agopian
dcb78c7144 update dispersion documentation (#9567)
* add dispersion parameter to material_sandbox

* frame_generator fixes

- fix skybox
- for baseColor to white (workaround)

* update dispersion documentation source
2026-01-05 13:54:24 -08:00
Sungun Park
43dd8fa1cc Fix MockDriver (#9569)
This is missing changes from
0eff54b807
2026-01-05 21:08:50 +00:00
Anish Goyal
91a5f00d30 Remove unnecessary log statement (#9568)
It is not an error for a device to not have this API.
2026-01-05 12:41:34 -08:00
Sungun Park
0eff54b807 Add async support check to backend (#9542)
BUGS=[442921995]
2026-01-05 20:10:36 +00:00
Lucas Leandro
68eb0ce3f1 Add java bindings for changing from default to screen-space reflection in real-time MaterialBuilder (#9548) 2026-01-05 11:44:54 -08:00
Benjamin Schulz
023318c08d Fixes "error: templates must have C++ linkage" when compiling with older clang versions. (#9562)
Co-authored-by: Sungun Park <sungunpark@google.com>
2026-01-05 11:43:54 -08:00
rafadevai
c0e3aa2b0a VK: In UMA, apply the staging bypass for everything (#9538)
Currently only uniform buffers benefit from the bypass,
but this can also be extended to others buffers too.

This also help trying to match the performance of the
GL backend in Android.

FIXES=[470138463]

Co-authored-by: Serge Metral <sergemetral@google.com>
2026-01-05 11:36:54 -08:00
Anish Goyal
a6d1b9188f Add descriptor set layouts to Program (#9522)
This will help later for parallel compilation
2026-01-05 18:59:07 +00:00
Sungun Park
43193c5ac5 Add missing async destruction for BufferObject and IndexBuffer (#9565)
As with Texture, now BufferObject and IndexBuffer will be destroyed via
the async queue if they were asynchronously created.

BUGS=[442921995]
2026-01-05 18:15:01 +00:00
Mathias Agopian
35c58047ee move the depth clear prepare into the framegraph (#9549)
depth clear prepare was done outside of the framegraph, it's now
moved into the colorpass prepare pass.
2026-01-03 15:04:51 -08:00
Mathias Agopian
2190f3544f fix build when FILAMENT_SUPPORTS_VULKAN is OFF (#9557) 2026-01-03 15:03:30 -08:00
Mathias Agopian
fd8ea78e04 Fix TAA (#9556)
TAA had been broken for a while, the jitter was no longer applied.

We now compute the jittered camera before we set it into the 
per frame UBO.
2026-01-03 15:03:06 -08:00
Emily Banerjee
7fc336a6d9 Fix GCC type mismatch error in Platform::debugUpdateStat (#9563) 2026-01-02 09:48:28 -08:00
yein
3cc6fae5c0 Add api level enforcement (#9561)
Api level is now enforced when generating code by appending #defines of client requested and unstable apis.
This ensures that the client can only use unstable apis when they explicitly add `apiLevel` in their .mat file.

FIXES=468340631
2025-12-29 13:38:02 -08:00
yein
f4f75da016 Fix garbage data getting added to the source material (#9553) 2025-12-26 09:29:13 -08:00
Filament Bot
bdeba1aa86 [automated] Updating /docs due to commit 8991be4
Full commit hash is 8991be4eea

DOCS_ALLOW_DIRECT_EDITS
2025-12-24 00:55:04 +00:00
Ben Doherty
8991be4eea Fix incorrect GLSL types in Materials documentation (#9555) 2025-12-23 16:52:27 -08:00
yein
940b93ceb8 Replace slog to LOG (#9554) 2025-12-23 13:45:42 -08:00
Filament Bot
00eb3d0d4f [automated] Updating /docs due to commit 7f61eb7
Full commit hash is 7f61eb7a0a

DOCS_ALLOW_DIRECT_EDITS
2025-12-23 19:44:04 +00:00
Benn Herrera
7f61eb7a0a GLTFIO Webp Texture Support (#9406) 2025-12-23 11:40:01 -08:00
yein
53f506670c Add apiLevel and add parsing logic (#9535) 2025-12-22 13:52:32 -08:00
Mathias Agopian
9fe7ab31ed Make FrameGraph resource management extensible (#9536)
* rename ResourceAllocator to TextureCache

This better represents what this class is for.

* Make FrameGraph resource management extensible

This refactors the FrameGraph's resource management to allow for 
user-defined custom resources.
 
A new `ResourceAllocator` template abstracts the creation and 
destruction of resources, with specializations for different resource 
types (e.g., generic, backend-dependent, textures). 
This removes hardcoded resource management logic from the `FrameGraph` 
execution loop.
 
A `ResourceCreationContext` is introduced to provide the necessary 
context for resource allocation.
 
Tests for generic and backend custom resources have been added to 
validate the new system.

* Update filament/src/fg/FrameGraphDummyLink.h

Co-authored-by: Powei Feng <powei@google.com>

---------

Co-authored-by: Powei Feng <powei@google.com>
2025-12-22 11:08:53 -08:00
Mathias Agopian
008534b8a2 Fix dispersion with uber-shaders (#9543)
Fixes #9540
2025-12-22 10:12:54 -08:00
Sungun Park
2c5842f908 Implement asynchronous resource management (#9508)
This commit introduces async methods and functions across both the
public and backend APIs, enabling non-blocking creation and updates for
Texture, VertexBuffer, and IndexBuffer resources.

Asynchronous resource management is disabled by default. Users should
enable this to use the feature.

Java bindings and a C++ code sample will follow in subsequent PRs.

BUGS=[442921995]
2025-12-19 21:18:32 -08:00
Powei Feng
a8ee9d473e android: fix texture rendertarget sample for vk (#9528)
- add a flag to run the sample using regular, non-external
   texture as render target.
 - Add a non-external version of the material
 - vk: fix y-flipping issue with uvToRenderTargetUV()
2025-12-19 22:15:22 +00:00
Mathias Agopian
1e3ab83e6a Remove the dependency of RenderPassBuilder on DriverApi (#9533)
The main goal of this CL is to break the dependency of RenderPassBuilder
on DriverApi. The dependency only existed for the auto-instancing 
feature, which needed to allocate and update a UBO on the fly.

We want to break that dependency so that RenderPassBuilder::build().
which is an expensive call, could run on a separate thread. In the
future this could allow, for example, shadow and ssao passes to 
run in parallel.

A new method RenderPass::finalize(DriverApi&) is added which *must* be 
called before calling getExecutor(), this is where the temporary
UBO is allocated and updated. We need a new method because this must be 
called on the main thread before a render pass is started.

This implementation stores the UBO data needed for instancing until
finalize() is called, if any.

We introduce a compact() utility that efficiently scans a range finding
"equivalent" consecutive objects and removes duplicates. The previous
code did that with an extra remove pass which invalidated all 
iterators.
2025-12-19 13:50:20 -08:00
yein
9720da2c68 Fix Json lexeme trying to allocate a string with a huge size due to underflow (#9539) 2025-12-19 13:29:01 -08:00
yein
ee74e2d50c Fix missing dep in CompressedStringChunk (#9534) 2025-12-18 13:35:49 -08:00
Powei Feng
6171009add test: fixing broken webgpu+android build (#9529)
The build was failing because the some tint libs are no longer
real dependencies

Fixes #9520
2025-12-18 18:16:21 +00:00
Mathias Agopian
d299a444fa don't limit FILAMENT_ENABLE_COVERAGE to DEBUG builds (#9532) 2025-12-18 09:24:19 -08:00
rafadevai
107276e9cc VK: Refactor platform Vulkan initialization (#9523)
* VK: Refactor platform Vulkan initialization

Refactor the platform code to allow overriding
how the vkInstance, vkPhysicalDevice and vkDevice
are created.

This refactor will also consolidate where the extensions
and features are enabled/disabled into VulkanPlatform,
instead of each platform doing its own individual setup
if needed. It also address knowing if a feature or
extension has been enabled, unless we keep adding
entries to the SharedContext which is not scalable.

The createDriver function now have a more defined structure,
mostly how and where features are queried and enabled.

- Get shared context data.
- Create instance if missing.
- Select physical device if missing.
- Query physical device support and set supported
engine features into the VulkanContext.
- Select the queues
- Create the device and queues

* Address review comments

Added some documentation on the new functions
Move the querying and config of features into its
own function.
2025-12-18 09:23:18 -08:00
Mathias Agopian
fe00cbf106 feature flags now default to const. (#9530)
This PR doesn't update most of the existing flags that are marked as
"mutable", they're probably wrong.
2025-12-17 10:34:31 -08:00
Filament Bot
02d0ddbcfe [automated] Updating /docs due to commit c4802f7
Full commit hash is c4802f7683

DOCS_ALLOW_DIRECT_EDITS
2025-12-16 23:01:53 +00:00
Sungun Park
c4802f7683 Release Filament 1.68.2 2025-12-16 14:57:34 -08:00
Ben Doherty
b582b2d64e Revert "Set the minimum required Metal version (#9425)" (#9527)
This reverts commit f5071b2aae.
2025-12-16 19:54:24 +00:00
Ben Doherty
9c4edf56ca Metal: fix compiler crash when running iOS apps under Mac Catalyst (#9524) 2025-12-16 10:41:14 -08:00
Mathias Agopian
e24fdb3a9d Workaround for harmless warning about descriptor sets (#9519)
* Workaround for harmless warning about descriptor sets

The proper fix is difficult and will be handled later. Here we simply
suppress the warning at FL0.


BUGS=[468072646]

* Apply suggestions from code review
2025-12-15 13:11:00 -08:00
Sungun Park
05f24516dd Fix Build.builder.feature() for Java bindings (#9517)
The "const char*" used for the string literal parameter of the `feature`
method becomes invalid once it passes outside the Java binding scope,
leading to invalid data access. This fix ensures the string is safely
stored.

Add support for heterogeneous lookup in associative containers that
use CString keys. Add conversion operators for std::string_view and
raw string literals to CString.
2025-12-15 21:04:36 +00:00
Mathias Agopian
a3708b2616 fix mat33 in UBOs at feature level 0 (#9510)
When emulating UBOs for feature level 0, we need to use packed
mat33 as source of glUniformMatrix3fv which doesn't expect the std140
alignments of UBOs.

FIXES=[468092808]
2025-12-15 12:43:25 -08:00
Powei Feng
ee514df722 docs: fix freezing when generating docs (#9521)
For reasons unknown, selenium will freeze when trying to make
request to the local server serving the markdown files. We add
a delay between the server and the selenium driver to hopefully
address this.

DOCS_FORCE
2025-12-15 10:50:00 -08:00
Run Yu
924c416644 webgpu: refactor WebGPUPlatform (#9516)
webgpu: refactors WebGPU Platform so each OS environment has its own WebGPU Platform 
class derived from the same base, and use virtual functions for their own implementations.
2025-12-12 19:24:41 -05:00
Powei Feng
597cf9a3ae docs: fix broken markdeep generation (#9514)
The breakage is due to breaking changes in the latest version.
We use the repo checked-in version instead.

Also make sure postsubmit.sh script exits on any error
2025-12-12 23:02:28 +00:00
Powei Feng
316c8376d3 Revert "[automated] Updating /docs due to commit f701c1e"
This reverts commit c300f77151.
2025-12-12 14:27:17 -08:00
Patrick Ribas
672ddddafc Added material name to createParser error logs (#9505) 2025-12-12 14:20:39 -08:00
Mathias Agopian
a8ee48c4b7 a series of CL to add RenderTarget support for external textures (#9504)
* add support for AHardwareBuffer to the java bindings

Texture.setEXternalIamge() now can take a AHArdwreBuffer Java object
as a parameter.

* add an API to set the priority of the Skybox

by default the skybox is always drawn last (priority 7) in order to
reduce overdraw. however, when depth culling is not enabled, it
needs to be drawn first. The new Builder::priority() allows to set
an arbitrary priority for the skybox.

* add rendertarget support for external textures

This was in fact mostly already supported, we just were artificially
preventing that usage. It is supported by the EGL_external_image
extension.

It's the responsibility of the caller/user to not attempt to use an
incompatible format, which has undefined behavior.

FIXES=[466395306]

* add a new android sample to test the AHardwareBuffer as render target

---------

Co-authored-by: Powei Feng <powei@google.com>
2025-12-12 14:15:58 -08:00
Filament Bot
c300f77151 [automated] Updating /docs due to commit f701c1e
Full commit hash is f701c1e1b5

DOCS_ALLOW_DIRECT_EDITS
2025-12-12 22:00:55 +00:00
Mathias Agopian
16734fc767 EMSCRIPTEN always supports fences, even at feature level 0 (#9507)
FIXES=[467783405]
2025-12-12 13:59:51 -08:00
Nemi
f701c1e1b5 Implement KHR_materials_dispersion (#9471)
This change adds support for the KHR_materials_dispersion glTF extension, which introduces a dispersion property for refractive materials.

The dispersion property controls the angular separation of colors transmitting through a refractive object, allowing for more realistic rendering of materials like glass and diamonds.

  Changes include:
   - Added a dispersion property to the material definition.
   - Updated the shaders to incorporate the dispersion effect in the refraction calculations.
   - Added a new test case for dispersion.
   - Updated the material documentation to include the new dispersion property.
2025-12-12 13:55:25 -08:00
Mathias Agopian
98cec207ce don't trigger an assert failure when getFenceStatus fails (#9511)
this is not an error that should warrant an assertion, since it's
possible for fences to not be supported at all.

FIXES=[467782111]

Co-authored-by: Powei Feng <powei@google.com>
2025-12-12 13:38:55 -08:00
Powei Feng
3ecdf71917 test: use backend NOOP for material tests 2025-12-12 13:04:17 -08:00
Powei Feng
ebba65e558 test: disable tests that tries to have a real backend 2025-12-12 12:40:06 -08:00
Powei Feng
177d23b3ac test: remove test_material_parser from CI
Seems to actually be initializing an engine

Failed with

reason: /Users/runner/work/filament/filament/filament/backend/src/opengl/platforms/PlatformCocoaGL.mm:177: failed assertion 'success == kCVReturnSuccess'
2025-12-12 12:19:39 -08:00
Powei Feng
cfd402f424 test: fix broken filament test again 2025-12-12 12:01:40 -08:00
Powei Feng
b7e492d674 test: fix missing dep filamat in test 2025-12-12 11:34:31 -08:00
Powei Feng
d7e0202f37 github: fix race condition for windows build (#9513)
A. Move filament_test_material.cpp to be part of test_filament
    (This won't be triggered during the windows build)
 B. Add chaining dependencies in third_party/draco/tnt so that
    there is no race in writing/reading generate.stamp

-------------
Failures
-------------
A.

C:\a\filament\filament\out\cmake-mtd\filament\test\resources\filament_test_resources.c(1,1): error C1083: Cannot open source file: 'C:\a\filament\filament\out\cmake-mtd\filament\test\resources\filament_test_resources.c': Permission denied [C:\a\filament\filament\out\cmake-mtd\filament\test\test_material_parser.vcxproj]

B.

CUSTOMBUILD : CMake error : Cannot restore timestamp "C:/a/filament/filament/out/cmake-mtd/third_party/draco/tnt/CMakeFiles/generate.stamp": Access is denied. [C:\a\filament\filament\out\cmake-mtd\third_party\draco\tnt\draco_compression_bit_coders.vcxproj]
2025-12-12 19:16:09 +00:00
Doris Wu
4227d04eb7 Add label for PlotLines calls (#9506)
Co-authored-by: Powei Feng <powei@google.com>
2025-12-12 16:32:41 +08:00
Powei Feng
272ed14737 github: fix brew dependency failure (#9512)
The failure is included below.  The reason for the failure is
because we caches ~/Library/Caches/Homebrew, but this might
present a mismatch with the latests homebrew.

We bump the cache version.

------------------------------------
failure
------------------------------------
Error: missing keywords: :date, :because
/opt/homebrew/Library/Homebrew/formula.rb:4631:in 'deprecate!'
/opt/homebrew/Library/Homebrew/formulary.rb:290:in 'block in Formulary.load_formula_from_json!'
/opt/homebrew/Library/Homebrew/formulary.rb:228:in 'Class#initialize'
/opt/homebrew/Library/Homebrew/formulary.rb:228:in 'Class#new'
/opt/homebrew/Library/Homebrew/formulary.rb:228:in 'Formulary.load_formula_from_json!'
/opt/homebrew/Library/Homebrew/formulary.rb:959:in 'Formulary::FromAPILoader#load_from_api'
/opt/homebrew/Library/Homebrew/formulary.rb:943:in 'Formulary::FromAPILoader#klass'
/opt/homebrew/Library/Homebrew/formulary.rb:524:in 'Formulary::FormulaLoader#get_formula'
/opt/homebrew/Library/Homebrew/formulary.rb:1045:in 'Formulary.factory'
/opt/homebrew/Library/Homebrew/formula.rb:2447:in 'Formula.[]'
/opt/homebrew/Library/Homebrew/formula.rb:671:in 'block in Formula#versioned_formulae'
/opt/homebrew/Library/Homebrew/formula.rb:670:in 'Array#each'
/opt/homebrew/Library/Homebrew/formula.rb:670:in 'Enumerable#filter_map'
/opt/homebrew/Library/Homebrew/formula.rb:670:in 'Formula#versioned_formulae'
/opt/homebrew/Library/Homebrew/unlink.rb:9:in 'Homebrew::Unlink.unlink_versioned_formulae'
/opt/homebrew/Library/Homebrew/formula_installer.rb:1166:in 'FormulaInstaller#link'
/opt/homebrew/Library/Homebrew/formula_installer.rb:955:in 'FormulaInstaller#finish'
/opt/homebrew/Library/Homebrew/formula_installer.rb:905:in 'FormulaInstaller#install_dependency'
/opt/homebrew/Library/Homebrew/formula_installer.rb:816:in 'block in FormulaInstaller#install_dependencies'
/opt/homebrew/Library/Homebrew/formula_installer.rb:816:in 'Array#each'
/opt/homebrew/Library/Homebrew/formula_installer.rb:816:in 'FormulaInstaller#install_dependencies'
/opt/homebrew/Library/Homebrew/formula_installer.rb:569:in 'FormulaInstaller#install'
/opt/homebrew/Library/Homebrew/install.rb:493:in 'Homebrew::Install.install_formula'
/opt/homebrew/Library/Homebrew/install.rb:420:in 'block in Homebrew::Install.install_formulae'
/opt/homebrew/Library/Homebrew/install.rb:417:in 'Array#each'
/opt/homebrew/Library/Homebrew/install.rb:417:in 'Homebrew::Install.install_formulae'
/opt/homebrew/Library/Homebrew/cmd/install.rb:396:in 'Homebrew::Cmd::InstallCmd#run'
/opt/homebrew/Library/Homebrew/brew.rb:101:in '<main>'
2025-12-12 01:26:06 +00:00
Powei Feng
223a754200 Revert "[automated] Updating /docs due to commit 32fcc1a"
This reverts commit 27c268f865.
2025-12-11 17:09:26 -08:00
Powei Feng
af480a58c4 Reapply "build: improve build.sh for Android with documentation (#9500)"
This reverts commit 192738ecb9.
2025-12-11 17:09:20 -08:00
Powei Feng
192738ecb9 Revert "build: improve build.sh for Android with documentation (#9500)"
This reverts commit 32fcc1a81b.
2025-12-11 16:55:49 -08:00
Filament Bot
27c268f865 [automated] Updating /docs due to commit 32fcc1a
Full commit hash is 32fcc1a81b

DOCS_ALLOW_DIRECT_EDITS
2025-12-12 00:52:05 +00:00
Powei Feng
32fcc1a81b build: improve build.sh for Android with documentation (#9500)
- Fix Android build in build.sh so that the tools dir are
   properly set to corresponding folders for debug vs. release.
 - Update/consolidate documentation to explain the Android Studio
   workflow better.
 - Move documentation from outdated apps folder to BUILDING.md
2025-12-12 00:46:00 +00:00
Powei Feng
621eca340e matdbg/matinfo: add column labels for output (#9502)
- Identify the columns that are being printed out when using
   matinfo to print out a material
- Add constant of blank space offset
2025-12-11 23:56:16 +00:00
Powei Feng
ee6c8c3e76 vk: unconditionally enable systrace for group markers (#9501) 2025-12-11 09:09:38 -08:00
Powei Feng
dcf7621c35 Revert "[automated] Updating /docs due to commit d4efef9"
This reverts commit 6a8193ea80.
2025-12-10 12:16:51 -08:00
Filament Bot
6a8193ea80 [automated] Updating /docs due to commit d4efef9
Full commit hash is d4efef9a9b

DOCS_ALLOW_DIRECT_EDITS
2025-12-10 19:12:21 +00:00
Benjamin Doherty
d4efef9a9b Release Filament 1.68.1 2025-12-10 11:04:56 -08:00
yein
cdffc9eaa0 Allow embedding material source in cmat (#9484)
* Allow embedding material source in cmat
* Compress material string
2025-12-10 10:31:51 -08:00
Sungun Park
a162a65dce Add JobQueue (#9480)
JobQueue is a thread-safe producer-consumer queue, which will be used
for asynchronous operations.
2025-12-10 18:00:58 +00:00
Ben Doherty
369bab4744 Implement setPresentationTime for Metal (#9470) 2025-12-09 14:54:06 -08:00
Powei Feng
c98038b2d7 vk: remove precondition for createStreamNative (#9497)
Keep it's original behavior of no-op
2025-12-09 13:48:38 -08:00
yrcloud
849c4bb8c5 webgpu: manage a pool of staging buffers for updateGPUBuffer (#9486)
- only MapAsync the staging buffers that are not being used by any command anymore (the commands have finished executing on GPU)
- additionally, in WebGPUQueueManager, create a blank new submission state when a new command encoder is generated instead of in submit()

BUGS=450620535
2025-12-09 12:20:03 -05:00
Mathias Agopian
ee64322d76 improve the memcpy benchmark (#9490)
- remove the multi-threaded tests, they added too much noise
- added a memset test
- make sure we allocate the buffer aligned to 16KB
2025-12-08 21:23:51 -08:00
Mathias Agopian
79d65a768a Fix(FrameInfo): fix typos and endFrame logic (#9499)
When the frame history's circular queue is full and the oldest
frame is not yet ready to be processed, we must skip the current
frame.

This change ensures that if `beginFrame` is skipped, the
corresponding `endFrame` is also skipped. This prevents data
corruption in the frame history.
2025-12-09 01:17:42 +00:00
Doris Wu
37610dc8f3 Unify zstd dependency for basisu (#9493) 2025-12-09 01:00:38 +00:00
Mathias Agopian
2e31dc20e4 Fix(FrameInfo): Improve robustness of frame info history management (#9496)
Address potential issues in FrameInfoImpl and FrameInfoManager:
 - Modify FrameInfoManager::beginFrame to handle cases where the 
   circular queue is full and the oldest frame is not yet ready, 
   logging a warning and skipping the frame. 
   This prevents potential use-after-free or data corruption by 
   ensuring only ready frames are removed from the history.

FIXES=[466081317]
2025-12-08 15:28:58 -08:00
Mathias Agopian
ae3d98fb47 fix use-after-free of the EGL swapchain (#9495)
PlatformEGLAndroid holds onto the current swapchain in order to use
it when beginFrame is called. Usually the swapchain is set just before
beginFrame is called. However, that's not the case for standalone
views. These are independent of the swapchain and doing "swapchain
stuff" for them is nonsensical.

So make sure that:

1. PlatfromEGLAndroid doesn't hold onto a dangling pointer when the 
   swapchain is destroyed. And add proper null checks.
2. Don't do the "swapchain stuff" when beginFrame is called in the
   context of a standalone view.
   We now reserve frameID 0 for that purpose (meaning the frameid is
   non sensical for these).

We're currently relying on frameID to not wrap-around. At 120 fps, 
that's about 1 year. This will be addressed in a later PR.

FIXES=[462827028, 461399487]
2025-12-08 14:54:34 -08:00
rafadevai
a938a790fa VK: Do memcpy if the uniform buffer is WRITE_SHARED (#9491)
With UBO batching, the frontend guarantees that
doing a memcpy to the buffer if safe.
2025-12-08 17:52:53 +00:00
dependabot[bot]
71d556dddf Bump urllib3 in /docs_src/build in the pip group across 1 directory (#9494)
Bumps the pip group with 1 update in the /docs_src/build directory: [urllib3](https://github.com/urllib3/urllib3).


Updates `urllib3` from 2.5.0 to 2.6.0
- [Release notes](https://github.com/urllib3/urllib3/releases)
- [Changelog](https://github.com/urllib3/urllib3/blob/main/CHANGES.rst)
- [Commits](https://github.com/urllib3/urllib3/compare/2.5.0...2.6.0)

---
updated-dependencies:
- dependency-name: urllib3
  dependency-version: 2.6.0
  dependency-type: direct:production
  dependency-group: pip
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Powei Feng <powei@google.com>
2025-12-08 17:35:27 +00:00
Powei Feng
d61227b2fd material: remove checked-in .filamat for transform name test (#9487)
filament_test_material should not need to depend on a "fixed"
(or checked in) material.

Now the dependent .filamat is generated as needed as is
packaged with the checked-in test_material.filamat as before.
2025-12-07 00:39:41 +00:00
dependabot[bot]
612a6b00e4 Bump urllib3 in /test/renderdiff/src in the pip group across 1 directory (#9492)
Bumps the pip group with 1 update in the /test/renderdiff/src directory: [urllib3](https://github.com/urllib3/urllib3).


Updates `urllib3` from 2.5.0 to 2.6.0
- [Release notes](https://github.com/urllib3/urllib3/releases)
- [Changelog](https://github.com/urllib3/urllib3/blob/main/CHANGES.rst)
- [Commits](https://github.com/urllib3/urllib3/compare/2.5.0...2.6.0)

---
updated-dependencies:
- dependency-name: urllib3
  dependency-version: 2.6.0
  dependency-type: direct:production
  dependency-group: pip
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-12-06 16:21:41 -08:00
Ben Doherty
b3353b518c Metal: ensure framebuffer fetch is only used on macOS 11.0+ (#9481) 2025-12-05 13:39:52 -08:00
Patrick Ribas
0b44761d43 Allow PlatformEGLHeadless to load GLES (#9488) 2025-12-05 13:37:51 -08:00
yein
c7979e4023 update test materials to 68 (#9485) 2025-12-05 12:20:48 -08:00
Mathias Agopian
e00904e100 Update NDK version to 29 (latest) (#9489)
also 
- update the android build script to pull the version from 
  build/common/versions

- remove the ability to specify your own ndk version (this was
  undocumented and not fully implemented)

The NDK version now needs to appear in two place (unfortunately):
1. build/common/versions
2. build/android/build.sh
2025-12-05 11:29:02 -08:00
Sungun Park
96e2366569 Add config option for asynchronous mode (#9462) 2025-12-05 02:48:22 +00:00
Mathias Agopian
e76624862d don't use the -mcpu compiler flag (#9483)
`-mcpu` is intended to target a specific CPU instruction set and
optimization. That's not what we want to do here. What we want is
target an architecture, specifically armv8-a. So we use `-march` 
instead.  On 64 bits builds, we tune for cortex-a78, which is the
df the Pixel7 era. This doesn't mater much, but might give a little
boost on newer CPU cores. The idea here is that we care "less" about
older CPUs.
2025-12-04 11:29:19 -08:00
Powei Feng
c5c83a61d3 vk: fix spurious VK_ERROR_OUT_OF_DATE_KHR on swapchain resize (#9482)
Fixes #9476
Fixes #8604
2025-12-04 19:24:29 +00:00
Powei Feng
ccf0d6205f Fix a couple of CI errors (#9477)
- Make sure that renderdiff fails when either building or
   rendering fails (the previous problem was in the use of &&
   that masked the non-zero exit).
 - Make sure that golden branch is properly parsed in
   postsubmit.yml
 - Disable vk loader debug by default
2025-12-04 18:40:05 +00:00
Powei Feng
f482c1d702 Fix texture leak in ImGuiHelper on shutdown (#9479) 2025-12-03 14:48:56 -08:00
Vignan Jitta
a4c056e822 Fix Wayland window data invalidation in NativeWindowHelperLinux (#9461) 2025-12-03 19:27:07 +00:00
Evan Mezeske
f5071b2aae Set the minimum required Metal version (#9425) 2025-12-03 19:10:00 +00:00
Sungun Park
0fa13ee43d Fix race condition with garbage collection (#9465)
This change fixes an intermittent crash caused by a thread race
condition.

The crash happened when a CallbackHandler::Callback (triggered by
engine.flush()) attempted to create an instance of a Structure of Arrays
(SoA) like TransformManager, which adds items to SoA) at the same time
that the garbage collection job (FEngine::gc, which removes items from
SoA) was running.

This conflict is resolved by modifying the logic to ensure that the
garbage collection task completes synchronously before the callback
operations begin.
2025-12-03 16:14:39 +00:00
Doris Wu
1d2b8a08fa Refactor the API usage for UBO batching (#9443) 2025-12-03 21:54:30 +08:00
rafadevai
0c06744450 Cleanup code related to stream transform matrix (#9464)
Clean up all the code related to setting a transform
matrix for a stream.
2025-12-03 00:47:56 -08:00
Powei Feng
4ada29fbc3 Revert "Add flag to guard camera near/far assertion (#9472)"
This reverts commit 3a92cdab3a.
2025-12-02 20:58:12 -08:00
Filament Bot
76182231dd [automated] Updating /docs due to commit 8cd6915
Full commit hash is 8cd6915b9d

DOCS_ALLOW_DIRECT_EDITS
2025-12-03 00:20:02 +00:00
Powei Feng
8cd6915b9d Release Filament 1.68.0 2025-12-02 16:17:24 -08:00
Mathias Agopian
f90de26bc2 fix disable_gpu_frame_complete_metric flag (#9473)
- set the flag to true (metrics disabled) until downstream is ready
- make sure to exit the JobQueue thread before destroying it

BUGS=[464370498]
2025-12-02 15:02:52 -08:00
Powei Feng
cc2e661aab Update ImGui to 1.92.5 (#9463) 2025-12-02 22:42:35 +00:00
Powei Feng
3a92cdab3a Add flag to guard camera near/far assertion (#9472)
BUGS=465516676
2025-12-02 22:22:38 +00:00
Powei Feng
b367982c23 platform: fix PlatformEGLAndroid include (#9469)
Only need AndroidNdk (already included) and not AndroidNativeWindow
2025-12-02 21:46:48 +00:00
Sungun Park
a4f4dc617e Support null initialization for Invocable (#9466)
This allows for code like:

Invocable<void()> inv = []() { /*do something*/ };
inv = nullptr;
2025-12-02 21:29:14 +00:00
dependabot[bot]
2eb0f11d05 Bump werkzeug (#9467)
Bumps the pip group with 1 update in the /test/renderdiff/src directory: [werkzeug](https://github.com/pallets/werkzeug).


Updates `werkzeug` from 3.1.3 to 3.1.4
- [Release notes](https://github.com/pallets/werkzeug/releases)
- [Changelog](https://github.com/pallets/werkzeug/blob/main/CHANGES.rst)
- [Commits](https://github.com/pallets/werkzeug/compare/3.1.3...3.1.4)

---
updated-dependencies:
- dependency-name: werkzeug
  dependency-version: 3.1.4
  dependency-type: direct:production
  dependency-group: pip
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-12-02 18:39:19 +00:00
Doris Wu
6694df991c Use vector instead of unordered_set in FenceManager (#9458) 2025-12-02 13:44:27 +08:00
imadr
8b2bfa7e9d Fix build on windows when vulkan is not supported (#9439)
Co-authored-by: Sungun Park <sungunpark@google.com>
2025-12-02 02:22:38 +00:00
Serge Metral
7386220325 Stream API Vulkan Backend (#9164)
* Adding the begin frame message for later xtrace post processing.

* First commit

* This is not needed

* Bypass the AHB* issue.

* Typo: Forgot to remove the function.

* Typo: No const specifier.

* Removing the const.

* no exception

* Feedback from discussions with Powei.

* Making the changes discussed with the team.

* Removing useless comments.

* Adding the required methods for allocation.

* Forgot one more switch case.

* Moving the resource to –fvkmemory::Resource type.

* Adding streamed set.

* Allocating every frame for streamed textures.

* Changing the binding logic.

* Proper checks for the streamed texture.

* Cleanup.

* Chaning the logic of the state tracking for streamed textures.

* Fixed full screen bug.

* Refactoring of the code.

* Typo.

* GitHub feedback.

* Github feedback

* feedback.

* Typo

* Feedback.

* Feedback.

* Feedback

* Feedback

* Feedback

* Fixing the Android path.

* Fixing the Android path.

* Feedback.

* feedback

* Feedback.

* Nit

* Feedback

* Feedback

* Feedback

* vk: fix update after bind (wrt descriptor set) validation error

In filament, once a descriptor set is bound, we no longer make updates
to it. However, this guarrantee was broken in the external sampler/image
because a colorspace change might necessitate a layout change, and
thereby a new descriptor needs to be generated with the appropriate
externally sampled image updated in the new set.

Another use case is the Stream API, where each frame we might be
getting a different AHardwareBuffer, meaning we need to update one
or multiple sampler bindings in a set that might have been bound in
a previous frame.

In this change, we always create a new set when there's a change
in the image currently bound to an existing set (while accounting for
whether we need to use a new externally sampled layout or not).

* Removing the decision on whether to use external format or not out of the streamed texture manager. The issue is that all textures are external, not all are using external format. But it's more robust to let the external format image manager rely on the AHB* to decide if the format is external or not. Regardless (because the memory is external) we need to send this to the external image manager.

* Fixing the validation layer in the Stream CL.

* Typo and comment clarification.

---------

Co-authored-by: Powei Feng <powei@google.com>
2025-12-01 11:13:47 -08:00
Sungun Park
000faeaca7 Fix bindVAO for OpenGL (#9453)
Currently bindVertexArray call generates an object for the default VAO,
which is not originally intended.
2025-12-01 18:55:02 +00:00
Powei Feng
3f9783ac02 Bump MATERIAL_VERSION to 68 2025-12-01 10:28:23 -08:00
rafadevai
4e6dc67ae8 VK: Disable depth testing in some cases (#9455)
Depth testing come with a cost, so when the depth
test is marked to always pass and writting to depth
buffer is disable, just disable the feature.

This will also match the GL backend behavior.
2025-12-01 09:40:26 -08:00
Doris Wu
666140bb73 Fix ios x86 build (#9459) 2025-12-01 09:04:09 -08:00
Doris Wu
56050de5cd metal: implement memory mapping (#9454) 2025-11-27 11:05:07 +08:00
Mathias Agopian
772136decd fix a typo/bad merge that broke setPresentationTime (#9452)
FIXES=[462533574]
2025-11-21 11:40:17 -08:00
Powei Feng
f664601c51 android: add readPixels callback for ModelViewer (#9440) 2025-11-21 19:33:36 +00:00
Ben Doherty
f06b27b7fb Fix getter methods (#9450) 2025-11-21 00:37:28 +00:00
Mathias Agopian
ef53ce88d4 don't assume compositor and frame timing are always available (#9449)
- this is not true fro headless swapchains
- and potentially some timings might not be available on a given nativewindow

Previously the code would handle these errors gracefully, but the 
errors were still generated. Now, we query the availability and only
make the calls  if supported.

Also on EGL, we don't attempt to use private APIs -- this code path
should never be used anyways.
2025-11-20 15:32:02 -08:00
Mathias Agopian
ef18030e1a frameId must be monotonic in the SwapChain (#9447)
The frameId coming from a Renderer must be monotonic when seen from
a SwapChain (Specifically a ANativeWindow on Android), if it's not
the case, we must clear that part of the history.

This can happen if a SwapChain is used with two different Renderer; at
this point that SwapChain's history is no longer connected to that
Renderer.
2025-11-20 13:23:58 -08:00
704 changed files with 63710 additions and 20979 deletions

View File

@@ -15,7 +15,7 @@ runs:
uses: actions/cache@v4 # Use a specific version
with:
path: ~/Library/Caches/Homebrew
key: ${{ runner.os }}-brew-20250424
key: ${{ runner.os }}-brew-20251211
- name: Install Mac Prerequisites
shell: bash
run: |

View File

@@ -1,25 +0,0 @@
name: Android
on:
push:
branches:
- main
- release
- rc/**
jobs:
build-android:
name: build-android
# We intentially use a larger runner here to enable larger disk space
# (standard linux runner will fail on disk space and faster build time).
runs-on: 'ubuntu-24.04-16core'
steps:
- uses: actions/checkout@v4.1.6
with:
fetch-depth: 0
- uses: ./.github/actions/linux-prereq
- name: Run Android Continuous
uses: ./.github/actions/android-continuous
with:
build-abi: armeabi-v7a,arm64-v8a,x86_64

View File

@@ -1,29 +0,0 @@
name: iOS
on:
push:
branches:
- main
- release
- rc/**
jobs:
build-ios:
name: build-ios
runs-on: macos-14-xlarge
steps:
- uses: actions/checkout@v4.1.6
with:
fetch-depth: 0
- uses: ./.github/actions/mac-prereq
- name: Run build script
run: |
cd build/ios && printf "y" | ./build.sh continuous
- uses: actions/upload-artifact@v4
with:
name: filament-ios
path: out/filament-release-ios.tgz
- name: Build iOS samples
run: |
cd build/ios && ./build-samples.sh continuous

View File

@@ -1,26 +0,0 @@
name: Linux
on:
push:
branches:
- main
- release
- rc/**
jobs:
build-linux:
name: build-linux
runs-on: 'ubuntu-24.04-16core'
steps:
- uses: actions/checkout@v4.1.6
with:
fetch-depth: 0
- uses: ./.github/actions/linux-prereq
- name: Run build script
run: |
cd build/linux && printf "y" | ./build.sh continuous
- uses: actions/upload-artifact@v4
with:
name: filament-linux
path: out/filament-release-linux.tgz

View File

@@ -1,29 +0,0 @@
name: macOS
on:
push:
branches:
- main
- release
- rc/**
jobs:
build-mac:
name: build-mac
runs-on: macos-14-xlarge
steps:
- uses: actions/checkout@v4.1.6
with:
fetch-depth: 0
- uses: ./.github/actions/mac-prereq
- name: Run build script
run: |
cd build/mac && printf "y" | ./build.sh continuous
- uses: actions/upload-artifact@v4
with:
name: filament-mac
path: out/filament-release-darwin.tgz
- name: Check public headers
run: |
test/check-headers/test.sh out/release/filament/include

59
.github/workflows/postsubmit-main.yml vendored Normal file
View File

@@ -0,0 +1,59 @@
name: 'Postsubmit Tasks'
on:
push:
branches:
- main
jobs:
update-renderdiff-goldens:
name: update-renderdiff-goldens
runs-on: 'ubuntu-24.04-4core'
steps:
- uses: actions/checkout@v4.1.6
with:
fetch-depth: 0
- uses: ./.github/actions/linux-prereq
- id: get_commit_msg
uses: ./.github/actions/get-commit-msg
- name: Prerequisites
run: pip install tifffile numpy
- name: Run update script
env:
GH_TOKEN: ${{ secrets.FILAMENTBOT_TOKEN }}
COMMIT_MESSAGE: ${{ steps.get_commit_msg.outputs.msg }}
run: |
GOLDEN_BRANCH=$(echo "${COMMIT_MESSAGE}" | python3 test/renderdiff/src/commit_msg.py)
COMMIT_HASH="${{ steps.get_commit_msg.outputs.hash }}"
if [[ "${GOLDEN_BRANCH}" != "main" ]]; then
git config --global user.email "filament.bot@gmail.com"
git config --global user.name "Filament Bot"
git config --global credential.helper cache
echo "branch==${GOLDEN_BRANCH}"
echo "hash==${COMMIT_HASH}"
python3 test/renderdiff/src/update_golden.py --branch=${GOLDEN_BRANCH} \
--merge-to-main --filament-tag=${COMMIT_HASH} --golden-repo-token=${GH_TOKEN}
fi
update-docs:
name: update-docs
runs-on: 'ubuntu-24.04-4core'
steps:
- uses: actions/checkout@v4.1.6
with:
fetch-depth: 0
- uses: ./.github/actions/linux-prereq
- id: get_commit_msg
uses: ./.github/actions/get-commit-msg
- name: Prerequisites
run: pip install selenium
- name: Run update script
env:
GH_TOKEN: ${{ secrets.FILAMENTBOT_TOKEN }}
run: |
bash docs_src/build/install_mdbook.sh && source ~/.bashrc
COMMIT_HASH="${{ steps.get_commit_msg.outputs.hash }}"
git config --global user.email "filament.bot@gmail.com"
git config --global user.name "Filament Bot"
git config --global credential.helper cache
bash docs_src/build/postsubmit.sh ${COMMIT_HASH} ${GH_TOKEN}

View File

@@ -1,58 +1,115 @@
name: 'Post-submit tasks'
name: 'Postsubmit CI'
on:
push:
branches:
- main
- release
- rc/**
jobs:
update-renderdiff-goldens:
name: update-renderdiff-goldens
runs-on: 'ubuntu-24.04-4core'
steps:
- uses: actions/checkout@v4.1.6
with:
fetch-depth: 0
- uses: ./.github/actions/linux-prereq
- id: get_commit_msg
uses: ./.github/actions/get-commit-msg
- name: Prerequisites
run: pip install tifffile numpy
- name: Run update script
env:
GH_TOKEN: ${{ secrets.FILAMENTBOT_TOKEN }}
run: |
GOLDEN_BRANCH=$(echo "${{ steps.get_commit_msg.outputs.msg }}" | python3 test/renderdiff/src/commit_msg.py)
COMMIT_HASH="${{ steps.get_commit_msg.outputs.hash }}"
if [[ "${GOLDEN_BRANCH}" != "main" ]]; then
git config --global user.email "filament.bot@gmail.com"
git config --global user.name "Filament Bot"
git config --global credential.helper cache
echo "branch==${GOLDEN_BRANCH}"
echo "hash==${COMMIT_HASH}"
python3 test/renderdiff/src/update_golden.py --branch=${GOLDEN_BRANCH} \
--merge-to-main --filament-tag=${COMMIT_HASH} --golden-repo-token=${GH_TOKEN}
fi
build-android:
name: build-android
# We intentially use a larger runner here to enable larger disk space
# (standard linux runner will fail on disk space and faster build time).
runs-on: 'ubuntu-24.04-16core'
update-docs:
name: update-docs
runs-on: 'ubuntu-24.04-4core'
steps:
- uses: actions/checkout@v4.1.6
with:
fetch-depth: 0
- uses: ./.github/actions/linux-prereq
- id: get_commit_msg
uses: ./.github/actions/get-commit-msg
- name: Prerequisites
run: pip install selenium
- name: Run update script
env:
GH_TOKEN: ${{ secrets.FILAMENTBOT_TOKEN }}
- name: Run Android Continuous
uses: ./.github/actions/android-continuous
with:
build-abi: armeabi-v7a,arm64-v8a,x86_64
build-ios:
name: build-ios
runs-on: macos-14-xlarge
steps:
- uses: actions/checkout@v4.1.6
with:
fetch-depth: 0
- uses: ./.github/actions/mac-prereq
- name: Run build script
run: |
bash docs_src/build/install_mdbook.sh && source ~/.bashrc
COMMIT_HASH="${{ steps.get_commit_msg.outputs.hash }}"
git config --global user.email "filament.bot@gmail.com"
git config --global user.name "Filament Bot"
git config --global credential.helper cache
bash docs_src/build/postsubmit.sh ${COMMIT_HASH} ${GH_TOKEN}
cd build/ios && printf "y" | ./build.sh continuous
- uses: actions/upload-artifact@v4
with:
name: filament-ios
path: out/filament-release-ios.tgz
- name: Build iOS samples
run: |
cd build/ios && ./build-samples.sh continuous
build-linux:
name: build-linux
runs-on: 'ubuntu-24.04-16core'
steps:
- uses: actions/checkout@v4.1.6
with:
fetch-depth: 0
- uses: ./.github/actions/linux-prereq
- name: Run build script
run: |
cd build/linux && printf "y" | ./build.sh continuous
- uses: actions/upload-artifact@v4
with:
name: filament-linux
path: out/filament-release-linux.tgz
build-mac:
name: build-mac
runs-on: macos-14-xlarge
steps:
- uses: actions/checkout@v4.1.6
with:
fetch-depth: 0
- uses: ./.github/actions/mac-prereq
- name: Run build script
run: |
cd build/mac && printf "y" | ./build.sh continuous
- uses: actions/upload-artifact@v4
with:
name: filament-mac
path: out/filament-release-darwin.tgz
- name: Check public headers
run: |
test/check-headers/test.sh out/release/filament/include
build-web:
name: build-web
runs-on: 'ubuntu-24.04-16core'
steps:
- uses: actions/checkout@v4.1.6
with:
fetch-depth: 0
- uses: ./.github/actions/linux-prereq
- uses: ./.github/actions/web-prereq
- name: Run build script
run: |
cd build/web && printf "y" | ./build.sh continuous
- uses: actions/upload-artifact@v4
with:
name: filament-web
path: out/filament-release-web.tgz
build-windows:
name: build-windows
runs-on: windows-2022-32core
steps:
- uses: actions/checkout@v4.1.6
- name: Run build script
run: |
build\windows\build-github.bat continuous
shell: cmd
- uses: actions/upload-artifact@v4
with:
name: filament-windows
path: out/filament-windows.tgz

View File

@@ -1,4 +1,4 @@
name: Presubmit
name: 'Presubmit CI'
on:
push:
@@ -19,7 +19,7 @@ jobs:
- uses: ./.github/actions/mac-prereq
- name: Run build script
run: |
cd build/mac && printf "y" | ./build.sh presubmit
cd build/mac && printf "y" | ./build.sh presubmit-with-test
- name: Test material parser
run: |
out/cmake-release/filament/test/test_material_parser
@@ -134,18 +134,17 @@ jobs:
env:
COMMIT_MESSAGE: ${{ steps.get_commit_msg.outputs.msg }}
run: |
ls ./gltf/Models
TEST_DIR=test/renderdiff
source ${TEST_DIR}/src/preamble.sh
start_
set -eux
GOLDEN_BRANCH=$(echo "${COMMIT_MESSAGE}" | python3 ${TEST_DIR}/src/commit_msg.py)
bash ${TEST_DIR}/generate.sh && \
python3 ${TEST_DIR}/src/golden_manager.py \
bash ${TEST_DIR}/generate.sh
python3 ${TEST_DIR}/src/golden_manager.py \
--branch=${GOLDEN_BRANCH} \
--output=${GOLDEN_OUTPUT_DIR}
# Note that we need to upload the output even if comparison fails, so we undo `set -ex`
end_
# Note that we need to upload the output even if comparison fails, so we undo `set -eux`
set +eux
python3 ${TEST_DIR}/src/compare.py \
--src=${GOLDEN_OUTPUT_DIR} \
@@ -158,6 +157,7 @@ jobs:
cat compare_output.txt >> "$GITHUB_OUTPUT"
echo "$DELIMITER" >> "$GITHUB_OUTPUT"
fi
shell: bash
- uses: actions/upload-artifact@v4
with:
name: presubmit-renderdiff-result

View File

@@ -245,7 +245,8 @@ jobs:
env:
TAG: ${{ steps.git_ref.outputs.tag }}
run: |
build\windows\build-github.bat release
@REMARK 'call' is required to ensure control returns to this script after the batch file finishes.
call build\windows\build-github.bat release
echo on
move out\filament-windows.tgz out\filament-%TAG%-windows.tgz
shell: cmd

View File

@@ -1,27 +0,0 @@
name: Web
on:
push:
branches:
- main
- release
- rc/**
jobs:
build-web:
name: build-web
runs-on: 'ubuntu-24.04-16core'
steps:
- uses: actions/checkout@v4.1.6
with:
fetch-depth: 0
- uses: ./.github/actions/linux-prereq
- uses: ./.github/actions/web-prereq
- name: Run build script
run: |
cd build/web && printf "y" | ./build.sh continuous
- uses: actions/upload-artifact@v4
with:
name: filament-web
path: out/filament-release-web.tgz

View File

@@ -1,24 +0,0 @@
name: Windows
on:
push:
branches:
- main
- release
- rc/**
jobs:
build-windows:
name: build-windows
runs-on: windows-2022-32core
steps:
- uses: actions/checkout@v4.1.6
- name: Run build script
run: |
build\windows\build-github.bat continuous
shell: cmd
- uses: actions/upload-artifact@v4
with:
name: filament-windows
path: out/filament-windows.tgz

View File

@@ -1,6 +1,6 @@
## Building Filament
# Building Filament
### Prerequisites
## Prerequisites
To build Filament, you must first install the following tools:
@@ -18,7 +18,7 @@ To build Filament for Android you must also install the following:
- Android NDK 25.1 or higher
- Java 17
### Environment variables
## Environment variables
To build Filament for Android, make sure the environment variable `ANDROID_HOME` points to the
location of your Android SDK.
@@ -30,7 +30,7 @@ When building for WebGL, you'll also need to set `EMSDK`. See [WebAssembly](#web
We recommend using CLion to develop for Filament. Simply open the root directory's CMakeLists.txt
in CLion to obtain a usable project.
### Easy build
## Easy build
Once the required OS specific dependencies listed below are installed, you can use the script
located in `build.sh` to build Filament easily on macOS and Linux.
@@ -67,7 +67,7 @@ For more specialized options, please also consider the following pages:
- `-t`: [`fgviewer`](https://google.github.io/filament/dup/fgviewer.html)
- `-b` and `-y`: [ASAN/UBSAN builds](https://google.github.io/filament/notes/asan_ubsan.html)
### Filament-specific CMake Options
## Filament-specific CMake Options
The following CMake options are boolean options specific to Filament:
@@ -89,7 +89,7 @@ cmake . -DOPTION=ON # Replace OPTION with the option name, set to ON / OFF
Options can also be set with the CMake GUI.
### Linux
## Linux
Make sure you've installed the following dependencies:
@@ -148,7 +148,7 @@ ninja
This will build Filament, its tests and samples, and various host tools.
### macOS
## macOS
To compile Filament you must have the most recent version of Xcode installed and you need to
make sure the command line tools are setup by running:
@@ -169,7 +169,7 @@ cmake -G Ninja -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=../release/fila
ninja
```
### iOS
## iOS
The easiest way to build Filament for iOS is to use `build.sh` and the
`-p ios` flag. For instance to build the debug target:
@@ -180,9 +180,9 @@ The easiest way to build Filament for iOS is to use `build.sh` and the
See [ios/samples/README.md](./ios/samples/README.md) for more information.
### Windows
## Windows
#### Building on Windows with Visual Studio 2019 or later
### Building on Windows with Visual Studio 2019 or later
Install the following components:
@@ -225,7 +225,7 @@ You can also use CMake to invoke the build without opening Visual Studio. For ex
cmake --build . --target gltf_viewer --config Release
```
### Android
## Android
Before building Filament for Android, make sure to build Filament for your host. Some of the
host tools are required to successfully build for Android.
@@ -242,7 +242,13 @@ foremost for `arm64-v8a`.
To build Android on Windows machines, see [android/Windows.md](android/Windows.md).
#### Easy Android build
### Important: SDK location
Either ensure your `ANDROID_HOME` environment variable is set or make sure the root project
contains a `local.properties` file with the `sdk.dir` property pointing to your installation of
the Android SDK.
### Easy Android build
The easiest way to build Filament for Android is to use `build.sh` and the
`-p android` flag. For instance to build the release target:
@@ -251,9 +257,46 @@ The easiest way to build Filament for Android is to use `build.sh` and the
./build.sh -p android release
```
To build a sample (such as `android/samples/sample-hello-triangle`) for an ARM 64-bit phone, you would run
```shell
./build.sh -p android -q arm64-v8a -k sample-hello-triangle release
```
The output APK can be found in `android/samples/sample-hello-triangle/build/outputs/apk/release/sample-hello-triangle-release-unsigned.apk`
Run `build.sh -h` for more information.
#### Manual builds
### Android Studio
You must use the latest stable release of Android Studio.
The Android build of filament is separated into java/kotlin client APIs, a layer of jni bindings
that bridges java/kotlin with native code, and Filament and other component code that have been compiled
into architecture-specific libraries. Our default Android Studio gradle setup can compile java/kotlin and
the jni bindings for you, but it will treat the filament libraries as already compiled and present on
the system.
Therefore, before compiling the sample app or any other targets, you must
make sure that the native filament libraries have been compiled and are located at a prescribed location
so that the jni bindings can link against them. You can do so by using the easy build script
```shell
./build.sh -p android release -q arm64-v8a
```
Note that the above step will also install host machine tools into prescribed locations. These tools are
required for compiling Filament assets such as materials and environment maps.
Now we are ready to compile the apps. To open the project, point Studio to the `android` folder.
After opening the project and syncing with Gradle, select the sample of your choice
using the drop-down widget in the toolbar. Additionally, you will need to select a deployment target.
By doing so, Android Studio will automatically try to compile the app only for that specific
device's architecture. So if you are targeting a new Pixel phone, make sure that the step above
(compiling the library) is targeting ARM 64-bit (`-q arm64-v8a` ), and if you are running the app on
an emulator on a Linux machine with an x86 64-bit chipset, you would indicate (`-q x86_64`) in the above step.
### Manual builds
Invoke CMake in a build directory of your choice, inside of filament's directory. The commands
below show how to build Filament for ARM 64-bit (`aarch64`).
@@ -281,7 +324,7 @@ This will generate Filament's Android binaries in `out/android-release`. This lo
to build the Android Studio projects located in `filament/android`. After install, the library
binaries should be found in `out/android-release/filament/lib/arm64-v8a`.
#### AAR
### AAR
Before you attempt to build the AAR, make sure you've compiled and installed the native libraries
as explained in the sections above. You must have the following ABIs built in
@@ -313,7 +356,7 @@ Alternatively you can build the AAR from the command line by executing the follo
The `-Pcom.google.android.filament.dist-dir` can be used to specify a different installation
directory (it must match the CMake install prefix used in the previous steps).
#### Using Filament's AAR
### Using Filament's AAR
Create a new module in your project and select _Import .JAR or .AAR Package_ when prompted. Make
sure to add the newly created module as a dependency to your application.
@@ -354,7 +397,7 @@ productFlavors {
}
```
### WebAssembly
## WebAssembly
The core Filament library can be cross-compiled to WebAssembly from either macOS or Linux. To get
started, follow the instructions for building Filament on your platform ([macOS](#macos) or

View File

@@ -10,6 +10,7 @@ cmake_minimum_required(VERSION 3.22.1)
# ==================================================================================================
# Toolchain configuration
# ==================================================================================================
# On iOS, the deployment target is set inside third_party/clang/ios.cmake
if (APPLE AND NOT IOS)
# This must be set before project() is called
set(CMAKE_OSX_DEPLOYMENT_TARGET 10.15 CACHE STRING "")
@@ -367,14 +368,22 @@ endif()
if (LINUX)
option(USE_STATIC_LIBCXX "Link against the static runtime libraries." ON)
# Add this step to support both glibc-based Linux distributions (e.g., Ubuntu, Debian)
# and musl-based distributions (e.g., Alpine).
include(CheckSymbolExists)
check_symbol_exists(__GLIBC__ "features.h" CLANG_WITH_GLIBC)
if (${USE_STATIC_LIBCXX})
if (FILAMENT_USING_GCC)
link_libraries("-static-libgcc -static-libstdc++")
else ()
elseif (CLANG_WITH_GLIBC)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -stdlib=libc++")
link_libraries("-static-libgcc -static-libstdc++")
link_libraries(libc++.a)
link_libraries(libc++abi.a)
else()
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -static")
endif()
endif()
@@ -473,7 +482,7 @@ endif()
set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} ${EXTRA_SANITIZE_OPTIONS}")
if (FILAMENT_ENABLE_COVERAGE)
set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -fprofile-instr-generate -fcoverage-mapping")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fprofile-instr-generate -fcoverage-mapping -Wno-pass-failed")
endif()
# Disable the stack check for macOS to workaround a known issue in clang 11.0.0.
@@ -563,6 +572,10 @@ if (FILAMENT_SUPPORTS_WEBGPU)
add_definitions(-DFILAMENT_SUPPORTS_WEBGPU)
endif()
if (FILAMENT_SUPPORTS_WEBP_TEXTURES)
add_definitions(-DFILAMENT_SUPPORTS_WEBP_TEXTURES)
endif()
# Build with Metal support on non-WebGL Apple platforms.
if (APPLE AND NOT WEBGL)
option(FILAMENT_SUPPORTS_METAL "Include the Metal backend" ON)
@@ -574,7 +587,7 @@ if (FILAMENT_SUPPORTS_METAL)
endif()
# Building filamat increases build times and isn't required for web, so turn it off by default.
if (NOT WEBGL AND NOT IOS)
if (NOT WEBGL)
option(FILAMENT_BUILD_FILAMAT "Build filamat and JNI buildings" ON)
else()
option(FILAMENT_BUILD_FILAMAT "Build filamat and JNI buildings" OFF)
@@ -872,7 +885,9 @@ add_subdirectory(${LIBRARIES}/utils)
add_subdirectory(${LIBRARIES}/viewer)
add_subdirectory(${FILAMENT}/shaders)
add_subdirectory(${EXTERNAL}/abseil/tnt)
add_subdirectory(${EXTERNAL}/basisu/tnt)
# Add zstd before basisu to force it to use the external zstd target,
# preventing a duplicate symbol conflict with its bundled version.
add_subdirectory(${EXTERNAL}/zstd/tnt)
add_subdirectory(${EXTERNAL}/civetweb/tnt)
add_subdirectory(${EXTERNAL}/imgui/tnt)
add_subdirectory(${EXTERNAL}/robin-map/tnt)
@@ -886,7 +901,7 @@ add_subdirectory(${EXTERNAL}/jsmn/tnt)
add_subdirectory(${EXTERNAL}/stb/tnt)
add_subdirectory(${EXTERNAL}/getopt)
add_subdirectory(${EXTERNAL}/perfetto/tnt)
add_subdirectory(${EXTERNAL}/zstd/tnt)
add_subdirectory(${EXTERNAL}/basisu/tnt)
# Note that this has to be placed after mikktspace in order for combine_static_libs to work.
@@ -913,7 +928,6 @@ endif()
if (FILAMENT_SUPPORTS_WEBP_TEXTURES)
add_subdirectory(${EXTERNAL}/libwebp/tnt)
add_definitions(-DFILAMENT_SUPPORTS_WEBP_TEXTURES)
endif()
if (FILAMENT_SUPPORTS_VULKAN)
@@ -971,6 +985,7 @@ if (IS_HOST_PLATFORM)
add_subdirectory(${TOOLS}/roughness-prefilter)
add_subdirectory(${TOOLS}/specular-color)
add_subdirectory(${TOOLS}/uberz)
add_subdirectory(${TOOLS}/specgen)
endif()
# Generate exported executables for cross-compiled builds (Android, WebGL, and iOS)

View File

@@ -6,3 +6,6 @@
appropriate header in [RELEASE_NOTES.md](./RELEASE_NOTES.md).
## Release notes for next branch cut
- engine: fix shader compilation failure in TAA material
- engine: fix stereo & parallel shader compilation

View File

@@ -31,7 +31,7 @@ repositories {
}
dependencies {
implementation 'com.google.android.filament:filament-android:1.67.1'
implementation 'com.google.android.filament:filament-android:1.69.1'
}
```
@@ -51,7 +51,7 @@ Here are all the libraries available in the group `com.google.android.filament`:
iOS projects can use CocoaPods to install the latest release:
```shell
pod 'Filament', '~> 1.67.1'
pod 'Filament', '~> 1.69.1'
```
## Documentation

View File

@@ -7,6 +7,33 @@ A new header is inserted each time a *tag* is created.
Instead, if you are authoring a PR for the main branch, add your release note to
[NEW_RELEASE_NOTES.md](./NEW_RELEASE_NOTES.md).
## v1.69.1
## v1.69.0
- engine: Support custom attributes morphing, and allow for omitting position and/or normal data. [⚠️ **Recompile Materials**]
## v1.68.5
- engine: "native" Streams are officially deprecated. Use "acquired" streams instead.
- engine: add "engine.skip_frame_when_cpu_ahead_of_display" feature [b/474599530]
## v1.68.4
- gltfio: Add optional support for webp textures (EXT_texture_webp), controlled via FILAMENT_SUPPORTS_WEBP_TEXTURES cmake option
## v1.68.3
- materials: added support for the glTF `KHR_materials_dispersion` extension, which adds dispersion for refractive objects
## v1.68.2
- Support `setPresentationTime` with the Metal backend.
## v1.68.1
## v1.68.0
- engine: add `View::getLastDynamicResolutionScale()` (b/457753622)

View File

@@ -100,7 +100,7 @@ buildscript {
'kotlin': '2.0.21',
'kotlin_coroutines': '1.9.0',
'buildTools': '35.0.0',
'ndk': '27.0.11718014',
'ndk': '29.0.14206865',
'androidx_core': '1.13.1',
'androidx_annotations': '1.9.0'
]
@@ -124,6 +124,7 @@ buildscript {
ext.cmakeArgs = [
"--no-warn-unused-cli",
"-DANDROID_WEAK_API_DEFS=ON",
"-DANDROID_PIE=ON",
"-DANDROID_PLATFORM=21",
"-DANDROID_STL=c++_static",
@@ -193,7 +194,7 @@ subprojects {
google()
}
if (!name.startsWith("sample")) {
if (!name.startsWith("sample") && name != "filament-tools") {
apply plugin: 'com.android.library'
android {

View File

@@ -335,6 +335,13 @@ Java_com_google_android_filament_filamat_MaterialBuilder_nMaterialBuilderRefract
builder->refractionMode((MaterialBuilder::RefractionMode) mode);
}
extern "C" JNIEXPORT void JNICALL
Java_com_google_android_filament_filamat_MaterialBuilder_nMaterialBuilderReflectionMode(JNIEnv* env,
jclass, jlong nativeBuilder, jint mode) {
auto builder = (MaterialBuilder*) nativeBuilder;
builder->reflectionMode((MaterialBuilder::ReflectionMode) mode);
}
extern "C" JNIEXPORT void JNICALL
Java_com_google_android_filament_filamat_MaterialBuilder_nMaterialBuilderRefractionType(JNIEnv* env,
jclass, jlong nativeBuilder, jint type) {

View File

@@ -177,6 +177,11 @@ public class MaterialBuilder {
SCREEN_SPACE
}
public enum ReflectionMode {
DEFAULT,
SCREEN_SPACE
}
public enum RefractionType {
SOLID,
THIN
@@ -403,6 +408,12 @@ public class MaterialBuilder {
return this;
}
@NonNull
public MaterialBuilder reflectionMode(ReflectionMode mode) {
nMaterialBuilderReflectionMode(mNativeObject, mode.ordinal());
return this;
}
@NonNull
public MaterialBuilder refractionType(RefractionType type) {
nMaterialBuilderRefractionType(mNativeObject, type.ordinal());
@@ -604,6 +615,7 @@ public class MaterialBuilder {
private static native void nMaterialBuilderSpecularAntiAliasingThreshold(long mNativeObject,
float threshold);
private static native void nMaterialBuilderRefractionMode(long nativeBuilder, int mode);
private static native void nMaterialBuilderReflectionMode(long nativeBuilder, int mode);
private static native void nMaterialBuilderRefractionType(long nativeBuilder, int type);
private static native void nMaterialBuilderClearCoatIorChange(long mNativeObject,
boolean clearCoatIorChange);

View File

@@ -134,6 +134,7 @@ target_include_directories(filament-jni PRIVATE
../../filament/backend/include
../../third_party/robin-map
../../third_party/perfetto
../../libs/bluevk/include
../../libs/utils/include)
# Ordering is significant in the following list. The PRIVATE qualifier prevents transitive deps.
@@ -167,3 +168,9 @@ target_link_libraries(filament-jni
# Force a relink when the version script is changed:
set_target_properties(filament-jni PROPERTIES LINK_DEPENDS ${VERSION_SCRIPT})
if (FILAMENT_SUPPORTS_VULKAN)
add_definitions(-DFILAMENT_SUPPORTS_VULKAN=1)
else()
add_definitions(-DFILAMENT_SUPPORTS_VULKAN=0)
endif()

View File

@@ -18,6 +18,7 @@
#include <filament/Camera.h>
#include <filament/Engine.h>
#include <filament/MorphTargetBuffer.h>
#include <utils/Entity.h>
#include <utils/EntityManager.h>
@@ -207,6 +208,14 @@ Java_com_google_android_filament_Engine_nDestroySkinningBuffer(JNIEnv*, jclass,
return engine->destroy(skinningBuffer);
}
extern "C" JNIEXPORT jboolean JNICALL
Java_com_google_android_filament_Engine_nDestroyMorphTargetBuffer(JNIEnv*, jclass,
jlong nativeEngine, jlong nativeMorphTargetBuffer) {
Engine* engine = (Engine*) nativeEngine;
MorphTargetBuffer* mtb = (MorphTargetBuffer*) nativeMorphTargetBuffer;
return engine->destroy(mtb);
}
extern "C" JNIEXPORT jboolean JNICALL
Java_com_google_android_filament_Engine_nDestroyIndirectLight(JNIEnv*, jclass,
jlong nativeEngine, jlong nativeIndirectLight) {
@@ -328,6 +337,13 @@ Java_com_google_android_filament_Engine_nIsValidSkinningBuffer(JNIEnv*, jclass,
return (jboolean)engine->isValid((SkinningBuffer*)nativeSkinningBuffer);
}
extern "C" JNIEXPORT jboolean JNICALL
Java_com_google_android_filament_Engine_nIsValidMorphTargetBuffer(JNIEnv*, jclass,
jlong nativeEngine, jlong nativeMorphTargetBuffer) {
Engine* engine = (Engine*) nativeEngine;
return (jboolean) engine->isValid((MorphTargetBuffer*) nativeMorphTargetBuffer);
}
extern "C" JNIEXPORT jboolean JNICALL
Java_com_google_android_filament_Engine_nIsValidIndirectLight(JNIEnv*, jclass,
jlong nativeEngine, jlong nativeIndirectLight) {

View File

@@ -25,7 +25,7 @@ using namespace filament;
extern "C" JNIEXPORT jlong JNICALL
Java_com_google_android_filament_Material_nBuilderBuild(JNIEnv *env, jclass,
jlong nativeEngine, jobject buffer_, jint size, jint shBandCount, jint shadowQuality) {
jlong nativeEngine, jobject buffer_, jint size, jint shBandCount, jint shadowQuality, jint uboBatchingMode) {
Engine* engine = (Engine*) nativeEngine;
AutoBuffer buffer(env, buffer_, size);
auto builder = Material::Builder();
@@ -33,6 +33,7 @@ Java_com_google_android_filament_Material_nBuilderBuild(JNIEnv *env, jclass,
builder.sphericalHarmonicsBandCount(shBandCount);
}
builder.shadowSamplingQuality((Material::Builder::ShadowSamplingQuality)shadowQuality);
builder.uboBatching((Material::UboBatchingMode)uboBatchingMode);
Material* material = builder
.package(buffer.getData(), buffer.getSize())
.build(*engine);

View File

@@ -58,6 +58,27 @@ Java_com_google_android_filament_MorphTargetBuffer_nBuilderCount(JNIEnv*, jclass
builder->count((size_t) count);
}
extern "C" JNIEXPORT void JNICALL
Java_com_google_android_filament_MorphTargetBuffer_nBuilderWithPositions(JNIEnv*, jclass,
jlong nativeBuilder, jboolean enabled) {
MorphTargetBuffer::Builder* builder = (MorphTargetBuffer::Builder*) nativeBuilder;
builder->withPositions(enabled);
}
extern "C" JNIEXPORT void JNICALL
Java_com_google_android_filament_MorphTargetBuffer_nBuilderWithTangents(JNIEnv*, jclass,
jlong nativeBuilder, jboolean enabled) {
MorphTargetBuffer::Builder* builder = (MorphTargetBuffer::Builder*) nativeBuilder;
builder->withTangents(enabled);
}
extern "C" JNIEXPORT void JNICALL
Java_com_google_android_filament_MorphTargetBuffer_nBuilderEnableCustomMorphing(JNIEnv*,
jclass, jlong nativeBuilder, jboolean enabled) {
MorphTargetBuffer::Builder* builder = (MorphTargetBuffer::Builder*) nativeBuilder;
builder->enableCustomMorphing(enabled);
}
extern "C"
JNIEXPORT jlong JNICALL
Java_com_google_android_filament_MorphTargetBuffer_nBuilderBuild(JNIEnv*, jclass,
@@ -112,3 +133,24 @@ Java_com_google_android_filament_MorphTargetBuffer_nGetCount(JNIEnv*, jclass,
MorphTargetBuffer *morphTargetBuffer = (MorphTargetBuffer *) nativeObject;
return (jint)morphTargetBuffer->getCount();
}
extern "C" JNIEXPORT jboolean JNICALL
Java_com_google_android_filament_MorphTargetBuffer_nHasPositions(JNIEnv*, jclass,
jlong nativeObject) {
MorphTargetBuffer* morphTargetBuffer = (MorphTargetBuffer*) nativeObject;
return (jboolean) morphTargetBuffer->hasPositions();
}
extern "C" JNIEXPORT jboolean JNICALL
Java_com_google_android_filament_MorphTargetBuffer_nHasTangents(JNIEnv*, jclass,
jlong nativeObject) {
MorphTargetBuffer* morphTargetBuffer = (MorphTargetBuffer*) nativeObject;
return (jboolean) morphTargetBuffer->hasTangents();
}
extern "C" JNIEXPORT jboolean JNICALL
Java_com_google_android_filament_MorphTargetBuffer_nIsCustomMorphingEnabled(JNIEnv*, jclass,
jlong nativeObject) {
MorphTargetBuffer* morphTargetBuffer = (MorphTargetBuffer*) nativeObject;
return (jboolean) morphTargetBuffer->isCustomMorphingEnabled();
}

View File

@@ -63,6 +63,14 @@ Java_com_google_android_filament_Skybox_nBuilderColor(JNIEnv *, jclass,
builder->color({r, g, b, a});
}
extern "C"
JNIEXPORT void JNICALL
Java_com_google_android_filament_Skybox_nBuilderPriority(JNIEnv *, jclass,
jlong nativeSkyBoxBuilder, jint priority) {
Skybox::Builder *builder = (Skybox::Builder *) nativeSkyBoxBuilder;
builder->priority(uint8_t(priority));
}
extern "C" JNIEXPORT jlong JNICALL
Java_com_google_android_filament_Skybox_nBuilderBuild(JNIEnv *env, jclass type,
jlong nativeSkyBoxBuilder, jlong nativeEngine) {

View File

@@ -21,6 +21,11 @@
#ifdef __ANDROID__
#include <android/bitmap.h>
#include <android/hardware_buffer_jni.h>
#include <backend/platforms/PlatformEGLAndroid.h>
# if FILAMENT_SUPPORTS_VULKAN
# include <backend/platforms/VulkanPlatformAndroid.h>
# endif
#endif
#include <filament/Engine.h>
@@ -388,6 +393,57 @@ Java_com_google_android_filament_Texture_nSetExternalImage(JNIEnv*, jclass, jlon
texture->setExternalImage(*engine, (void*)eglImage);
}
extern "C"
JNIEXPORT jboolean JNICALL
Java_com_google_android_filament_Texture_nSetExternalImageByAHB(JNIEnv *env, jclass clazz,
jlong nativeTexture, jlong nativeEngine, jobject ahb) {
Texture *texture = (Texture *) nativeTexture;
Engine *engine = (Engine *) nativeEngine;
#ifdef __ANDROID__
Platform* platform = engine->getPlatform();
AHardwareBuffer* nativeBuffer = nullptr;
if (__builtin_available(android 26, *)) {
nativeBuffer = AHardwareBuffer_fromHardwareBuffer(env, ahb);
}
if (!nativeBuffer) {
// either we're not on Android 26, or ahb wasn't a AHardwareBuffer
return JNI_FALSE;
}
if (engine->getBackend() == Backend::OPENGL) {
// CAVEAT: we assume that Backend::OPENGL on Android implies PlatformEGLAndroid.
#if UTILS_HAS_RTTI
if (!dynamic_cast<PlatformEGLAndroid*>(platform)) {
return JNI_FALSE;
}
#endif
auto* eglPlatform = (PlatformEGLAndroid*) platform;
auto ref = eglPlatform->createExternalImage(nativeBuffer, false);
texture->setExternalImage(*engine, ref);
}
#if FILAMENT_SUPPORTS_VULKAN
else if (engine->getBackend() == Backend::VULKAN) {
// CAVEAT: we assume that Backend::VULKAN on Android implies VulkanPlatformAndroid.
#if UTILS_HAS_RTTI
if (!dynamic_cast<VulkanPlatformAndroid*>(platform)) {
return JNI_FALSE;
}
#endif
auto* vulkanPlatform = (VulkanPlatformAndroid*) platform;
auto ref = vulkanPlatform->createExternalImage(nativeBuffer, false);
texture->setExternalImage(*engine, ref);
}
#endif // FILAMENT_SUPPORTS_VULKAN
// success!
return JNI_TRUE;
#else
// other platforms could come here
return JNI_FALSE;
#endif // __ANDROID__
}
extern "C" JNIEXPORT void JNICALL
Java_com_google_android_filament_Texture_nSetExternalStream(JNIEnv*, jclass,
jlong nativeTexture, jlong nativeEngine, jlong nativeStream) {
@@ -607,3 +663,4 @@ Java_com_google_android_filament_android_TextureHelper_nSetBitmapWithCallback(JN
}
#endif

View File

@@ -52,6 +52,11 @@ Java_com_google_android_filament_ToneMapper_nCreatePBRNeutralToneMapper(JNIEnv*,
return (jlong) new PBRNeutralToneMapper();
}
extern "C" JNIEXPORT jlong JNICALL
Java_com_google_android_filament_ToneMapper_nCreateGT7ToneMapper(JNIEnv*, jclass) {
return (jlong) new GT7ToneMapper();
}
extern "C" JNIEXPORT jlong JNICALL
Java_com_google_android_filament_ToneMapper_nCreateAgxToneMapper(JNIEnv*, jclass, jint look) {
return (jlong) new AgxToneMapper(AgxToneMapper::AgxLook(look));

View File

@@ -939,6 +939,15 @@ public class Engine {
return nIsValidSkinningBuffer(getNativeObject(), object.getNativeObject());
}
/**
* Returns whether the object is valid.
* @param object Object to check for validity
* @return returns true if the specified object is valid.
*/
public boolean isValidMorphTargetBuffer(@NonNull MorphTargetBuffer object) {
return nIsValidMorphTargetBuffer(getNativeObject(), object.getNativeObject());
}
/**
* Returns whether the object is valid.
* @param object Object to check for validity
@@ -1192,6 +1201,15 @@ public class Engine {
skinningBuffer.clearNativeObject();
}
/**
* Destroys a {@link MorphTargetBuffer} and frees all its associated resources.
* @param morphTargetBuffer the {@link MorphTargetBuffer} to destroy
*/
public void destroyMorphTargetBuffer(@NonNull MorphTargetBuffer morphTargetBuffer) {
assertDestroy(nDestroyMorphTargetBuffer(getNativeObject(), morphTargetBuffer.getNativeObject()));
morphTargetBuffer.clearNativeObject();
}
/**
* Destroys a {@link IndirectLight} and frees all its associated resources.
* @param ibl the {@link IndirectLight} to destroy
@@ -1483,6 +1501,7 @@ public class Engine {
private static native boolean nDestroyIndexBuffer(long nativeEngine, long nativeIndexBuffer);
private static native boolean nDestroyVertexBuffer(long nativeEngine, long nativeVertexBuffer);
private static native boolean nDestroySkinningBuffer(long nativeEngine, long nativeSkinningBuffer);
private static native boolean nDestroyMorphTargetBuffer(long nativeEngine, long nativeMorphTargetBuffer);
private static native boolean nDestroyIndirectLight(long nativeEngine, long nativeIndirectLight);
private static native boolean nDestroyMaterial(long nativeEngine, long nativeMaterial);
private static native boolean nDestroyMaterialInstance(long nativeEngine, long nativeMaterialInstance);
@@ -1499,6 +1518,7 @@ public class Engine {
private static native boolean nIsValidIndexBuffer(long nativeEngine, long nativeIndexBuffer);
private static native boolean nIsValidVertexBuffer(long nativeEngine, long nativeVertexBuffer);
private static native boolean nIsValidSkinningBuffer(long nativeEngine, long nativeSkinningBuffer);
private static native boolean nIsValidMorphTargetBuffer(long nativeEngine, long nativeMorphTargetBuffer);
private static native boolean nIsValidIndirectLight(long nativeEngine, long nativeIndirectLight);
private static native boolean nIsValidMaterial(long nativeEngine, long nativeMaterial);
private static native boolean nIsValidMaterialInstance(long nativeEngine, long nativeMaterial, long nativeMaterialInstance);

View File

@@ -261,6 +261,20 @@ public class Material {
LOW
}
/**
* Defines whether a material instance should use UBO batching or not.
*/
public enum UboBatchingMode {
/**
* For default, it follows the engine settings.
* If UBO batching is enabled on the engine and the material domain is SURFACE, it
* turns on the UBO batching. Otherwise, it turns off the UBO batching.
*/
DEFAULT,
/** Disable the Ubo Batching for this material */
DISABLED
}
public static class UserVariantFilterBit {
/** Directional lighting */
public static int DIRECTIONAL_LIGHTING = 0x01;
@@ -372,6 +386,7 @@ public class Material {
private int mSize;
private int mShBandCount = 0;
private ShadowSamplingQuality mShadowSamplingQuality = ShadowSamplingQuality.LOW;
private UboBatchingMode mUboBatchingMode = UboBatchingMode.DEFAULT;
/**
@@ -416,6 +431,17 @@ public class Material {
return this;
}
/**
* Set the batching mode of the instances created from this material.
* @param uboBatchingMode
* @return Reference to this Builder for chaining calls.
*/
@NonNull
public Builder uboBatching(UboBatchingMode mode) {
mUboBatchingMode = mode;
return this;
}
/**
* Creates and returns the Material object.
*
@@ -428,7 +454,7 @@ public class Material {
@NonNull
public Material build(@NonNull Engine engine) {
long nativeMaterial = nBuilderBuild(engine.getNativeObject(),
mBuffer, mSize, mShBandCount, mShadowSamplingQuality.ordinal());
mBuffer, mSize, mShBandCount, mShadowSamplingQuality.ordinal(), mUboBatchingMode.ordinal());
if (nativeMaterial == 0) throw new IllegalStateException("Couldn't create Material");
return new Material(nativeMaterial);
}
@@ -1094,7 +1120,7 @@ public class Material {
mNativeObject = 0;
}
private static native long nBuilderBuild(long nativeEngine, @NonNull Buffer buffer, int size, int shBandCount, int shadowQuality);
private static native long nBuilderBuild(long nativeEngine, @NonNull Buffer buffer, int size, int shBandCount, int shadowQuality, int uboBatchingMode);
private static native long nCreateInstance(long nativeMaterial);
private static native long nCreateInstanceWithName(long nativeMaterial, @NonNull String name);
private static native long nGetDefaultInstance(long nativeMaterial);

View File

@@ -64,6 +64,45 @@ public class MorphTargetBuffer {
return this;
}
/**
* Use this method to enable or disable the built-in position morphing buffer.
* Default is true.
*
* @param enabled true to enable, false to disable
* @return this <code>Builder</code> object for chaining calls
*/
@NonNull
public Builder withPositions(boolean enabled) {
nBuilderWithPositions(mNativeBuilder, enabled);
return this;
}
/**
* Use this method to enable or disable the built-in tangent morphing buffer.
* Default is true.
*
* @param enabled true to enable, false to disable
* @return this <code>Builder</code> object for chaining calls
*/
@NonNull
public Builder withTangents(boolean enabled) {
nBuilderWithTangents(mNativeBuilder, enabled);
return this;
}
/**
* Use this method to enable or disable custom morphing.
* Default is false.
*
* @param enabled true to enable, false to disable
* @return this <code>Builder</code> object for chaining calls
*/
@NonNull
public Builder enableCustomMorphing(boolean enabled) {
nBuilderEnableCustomMorphing(mNativeBuilder, enabled);
return this;
}
/**
* Creates and returns the <code>MorphTargetBuffer</code> object.
*
@@ -156,6 +195,27 @@ public class MorphTargetBuffer {
return nGetCount(mNativeObject);
}
/**
* @return true if this MorphTargetBuffer has a position buffer.
*/
public boolean hasPositions() {
return nHasPositions(mNativeObject);
}
/**
* @return true if this MorphTargetBuffer has a tangent buffer.
*/
public boolean hasTangents() {
return nHasTangents(mNativeObject);
}
/**
* @return true if custom morphing is enabled.
*/
public boolean isCustomMorphingEnabled() {
return nIsCustomMorphingEnabled(mNativeObject);
}
public long getNativeObject() {
if (mNativeObject == 0) {
throw new IllegalStateException("Calling method on destroyed MorphTargetBuffer");
@@ -171,10 +231,16 @@ public class MorphTargetBuffer {
private static native void nDestroyBuilder(long nativeBuilder);
private static native void nBuilderVertexCount(long nativeBuilder, int vertexCount);
private static native void nBuilderCount(long nativeBuilder, int count);
private static native void nBuilderWithPositions(long nativeBuilder, boolean enabled);
private static native void nBuilderWithTangents(long nativeBuilder, boolean enabled);
private static native void nBuilderEnableCustomMorphing(long nativeBuilder, boolean enabled);
private static native long nBuilderBuild(long nativeBuilder, long nativeEngine);
private static native int nSetPositionsAt(long nativeObject, long nativeEngine, int targetIndex, float[] positions, int count);
private static native int nSetTangentsAt(long nativeObject, long nativeEngine, int targetIndex, short[] tangents, int count);
private static native int nGetVertexCount(long nativeObject);
private static native int nGetCount(long nativeObject);
private static native boolean nHasPositions(long nativeObject);
private static native boolean nHasTangents(long nativeObject);
private static native boolean nIsCustomMorphingEnabled(long nativeObject);
}

View File

@@ -155,6 +155,24 @@ public class Skybox {
return this;
}
/**
* Set the rendering priority of the Skybox. By default, it is set to the lowest
* priority (7) such that the Skybox is always rendered after the opaque objects,
* to reduce overdraw when depth culling is enabled.
*
* @param priority clamped to the range [0..7], defaults to 4; 7 is lowest priority
* (rendered last).
*
* @return Builder reference for chaining calls.
*
* @see RenderableManager.Builder#priority
*/
@NonNull
public Builder priority(@IntRange(from = 0, to = 7) int priority) {
nBuilderPriority(mNativeBuilder, priority);
return this;
}
/**
* Creates a <code>Skybox</code> object
*
@@ -262,6 +280,7 @@ public class Skybox {
private static native void nBuilderShowSun(long nativeSkyboxBuilder, boolean show);
private static native void nBuilderIntensity(long nativeSkyboxBuilder, float intensity);
private static native void nBuilderColor(long nativeSkyboxBuilder, float r, float g, float b, float a);
private static native void nBuilderPriority(long nativeSkyboxBuilder, int priority);
private static native long nBuilderBuild(long nativeSkyboxBuilder, long nativeEngine);
private static native void nSetLayerMask(long nativeSkybox, int select, int value);
private static native int nGetLayerMask(long nativeSkybox);

View File

@@ -71,6 +71,16 @@ import static com.google.android.filament.Texture.Type.COMPRESSED;
* @see MaterialInstance#setParameter(String, Texture, TextureSampler)
*/
public class Texture {
private static Class<?> HardwareBufferClass = null;
static {
try {
HardwareBufferClass = Class.forName("android.hardware.HardwareBuffer");
} catch (ClassNotFoundException ignored) {
}
}
private static final Sampler[] sSamplerValues = Sampler.values();
private static final InternalFormat[] sInternalFormatValues = InternalFormat.values();
@@ -1172,6 +1182,38 @@ public class Texture {
nSetExternalImage(getNativeObject(), engine.getNativeObject(), eglImage);
}
/**
* Specifies the external image to associate with this <code>Texture</code>.
*
* <p>Typically, the external image is OS specific, and can be a video or camera frame.
* There are many restrictions when using an external image as a texture, such as:</p>
* <ul>
* <li> only the level of detail (lod) 0 can be specified</li>
* <li> only nearest or linear filtering is supported</li>
* <li> the size and format of the texture is defined by the external image</li>
* <li> only the CLAMP_TO_EDGE wrap mode is supported</li>
* </ul>
*
* @param engine {@link Engine} this texture is associated to. Must be the
* instance passed to {@link Builder#build Builder.build()}.
* @param externalImageRef An OS specific Object. On Android it must be a
* <code>android.hardware.HardwareBuffer</code>
*/
public void setExternalImage(@NonNull Engine engine, Object externalImageRef) {
if (HardwareBufferClass != null) {
if (!HardwareBufferClass.isInstance(externalImageRef)) {
throw new IllegalArgumentException("externalImageRef must be a AHardwareBuffer");
}
if (!nSetExternalImageByAHB(getNativeObject(), engine.getNativeObject(), externalImageRef)) {
throw new IllegalStateException("Error setting AHardwareBuffer as external image");
}
} else {
throw new UnsupportedOperationException(
"setExternalImage(Engine, Object) not supported on this platform");
}
}
/**
* Specifies the external stream to associate with this <code>Texture</code>.
*
@@ -1364,6 +1406,8 @@ public class Texture {
private static native void nSetExternalImage(
long nativeObject, long nativeEngine, long eglImage);
private static native boolean nSetExternalImageByAHB(long nativeTexture, long nativeObject, Object ahb);
private static native void nSetExternalStream(long nativeTexture,
long nativeEngine, long nativeStream);

View File

@@ -24,6 +24,7 @@ package com.google.android.filament;
* <li>ACESLegacyToneMapper</li>
* <li>FilmicToneMapper</li>
* <li>PBRNeutralToneMapper</li>
* <li>GT7ToneMapper</li>
* </ul>
* <li>Debug/validation tone mapping operators</li>
* <ul>
@@ -111,6 +112,19 @@ public class ToneMapper {
}
}
/**
* Gran Turismo 7 tone mapping operator. This tone mapper was designed
* to preserve the appearance of materials across lighting conditions while
* avoiding artifacts in the highlights in high dynamic range conditions.
* This tone mapper targets an SDR paper white value of 250 nits, with a
* reference luminance of 100 cd/m^2 (a value of 1.0 in the HDR framebuffer).
*/
public static class GT7ToneMapper extends ToneMapper {
public GT7ToneMapper() {
super(nCreateGT7ToneMapper());
}
}
/**
* AgX tone mapping operator.
*/
@@ -244,6 +258,7 @@ public class ToneMapper {
private static native long nCreateACESLegacyToneMapper();
private static native long nCreateFilmicToneMapper();
private static native long nCreatePBRNeutralToneMapper();
private static native long nCreateGT7ToneMapper();
private static native long nCreateAgxToneMapper(int look);
private static native long nCreateGenericToneMapper(
float contrast, float midGrayIn, float midGrayOut, float hdrMax);

View File

@@ -2041,10 +2041,6 @@ public class View {
* use an AABB neighborhood
*/
AABB,
/**
* use the variance of the neighborhood (not recommended)
*/
VARIANCE,
/**
* use both AABB and variance
*/
@@ -2075,7 +2071,7 @@ public class View {
}
/**
* reconstruction filter width typically between 1 (sharper) and 2 (smoother)
* @deprecated has no effect.
*/
public float filterWidth = 1.0f;
/**
@@ -2095,9 +2091,9 @@ public class View {
*/
public boolean enabled = false;
/**
* 4x TAA upscaling. Disables Dynamic Resolution. [BETA]
* Upscaling factor. Disables Dynamic Resolution. [BETA]
*/
public boolean upscaling = false;
public float upscaling = 1.0f;
/**
* whether to filter the history buffer
*/
@@ -2110,6 +2106,10 @@ public class View {
* whether to use the YcoCg color-space for history rejection
*/
public boolean useYCoCg = false;
/**
* set to true for HDR content
*/
public boolean hdr = true;
/**
* type of color gamut box
*/

12
android/filament-tools/.gitignore vendored Normal file
View File

@@ -0,0 +1,12 @@
*.iml
.gradle
/local.properties
/.idea/workspace.xml
/.idea/libraries
/.idea/caches
/.idea/gradle.xml
.DS_Store
/build
/captures
.externalNativeBuild
/.cxx

View File

@@ -0,0 +1,64 @@
plugins {
id "de.undercouch.download" version "5.6.0"
}
apply from: rootProject.file('gradle/gradle-mvn-push.gradle')
def tools = ['matc', 'cmgen']
def platforms = [
'mac': [classifier: 'osx-aarch_64', archive: "filament-v${VERSION_NAME}-mac.tgz", path: { t -> "filament/bin/${t}" }],
'linux': [classifier: 'linux-x86_64', archive: "filament-v${VERSION_NAME}-linux.tgz", path: { t -> "filament/bin/${t}" }],
'windows': [classifier: 'windows-x86_64', archive: "filament-v${VERSION_NAME}-windows.tgz", path: { t -> "bin/${t}.exe" }]
]
platforms.each { platform, config ->
def platformName = platform.capitalize()
def remoteUrl = "https://github.com/google/filament/releases/download/v${VERSION_NAME}/${config.archive}"
def downloadFile = file("${buildDir}/downloads/${config.archive}")
def extractDir = file("${buildDir}/extracted/filament-v${VERSION_NAME}-${platform}")
task "downloadRelease${platformName}"(type: Download) {
src remoteUrl
dest downloadFile
overwrite false
}
def extractionTask = task "extractTools${platformName}"(dependsOn: "downloadRelease${platformName}", type: Copy) {
group = "setup"
from tarTree(resources.gzip(downloadFile))
// Include specific tools based on platform pattern
include tools.collect { tool -> config.path(tool) }
// Flatten the path so it lands directly in 'into'
eachFile { fcd ->
fcd.relativePath = new RelativePath(true, fcd.name)
}
into extractDir
includeEmptyDirs = false
}
}
publishing {
publications {
tools.each { toolName ->
create(toolName, MavenPublication) {
artifactId = toolName
platforms.each { platform, config ->
def extractDir = file("${buildDir}/extracted/filament-v${VERSION_NAME}-${platform}")
def archivePath = config.path(toolName)
def exeName = new File(archivePath).name
artifact(new File(extractDir, exeName)) {
classifier = config.classifier
extension = "exe"
builtBy tasks.named("extractTools${platform.capitalize()}")
}
}
}
}
}
}

View File

@@ -0,0 +1,2 @@
POM_NAME=Filament
POM_PACKAGING=exe

View File

@@ -159,37 +159,50 @@ extern "C" JNIEXPORT void JNICALL
Java_com_google_android_filament_utils_AutomationEngine_nGetViewerOptions(JNIEnv* env, jclass,
jlong nativeObject, jobject result) {
AutomationEngine* automation = (AutomationEngine*) nativeObject;
auto options = automation->getViewerOptions();
const auto& settings = automation->getSettings();
const auto& options = settings.viewer;
const jclass klass = env->GetObjectClass(result);
const jfieldID cameraAperture = env->GetFieldID(klass, "cameraAperture", "F");
const jfieldID cameraSpeed = env->GetFieldID(klass, "cameraSpeed", "F");
const jfieldID cameraISO = env->GetFieldID(klass, "cameraISO", "F");
const jfieldID cameraNear = env->GetFieldID(klass, "cameraNear", "F");
const jfieldID cameraFar = env->GetFieldID(klass, "cameraFar", "F");
const jfieldID groundShadowStrength = env->GetFieldID(klass, "groundShadowStrength", "F");
const jfieldID groundPlaneEnabled = env->GetFieldID(klass, "groundPlaneEnabled", "Z");
const jfieldID skyboxEnabled = env->GetFieldID(klass, "skyboxEnabled", "Z");
const jfieldID cameraFocalLength = env->GetFieldID(klass, "cameraFocalLength", "F");
const jfieldID cameraFocusDistance = env->GetFieldID(klass, "cameraFocusDistance", "F");
const jfieldID autoScaleEnabled = env->GetFieldID(klass, "autoScaleEnabled", "Z");
const jfieldID autoInstancingEnabled = env->GetFieldID(klass, "autoInstancingEnabled", "Z");
env->SetFloatField(result, cameraAperture, options.cameraAperture);
env->SetFloatField(result, cameraSpeed, options.cameraSpeed);
env->SetFloatField(result, cameraISO, options.cameraISO);
env->SetFloatField(result, cameraNear, options.cameraNear);
env->SetFloatField(result, cameraFar, options.cameraFar);
env->SetFloatField(result, groundShadowStrength, options.groundShadowStrength);
env->SetBooleanField(result, groundPlaneEnabled, options.groundPlaneEnabled);
env->SetBooleanField(result, skyboxEnabled, options.skyboxEnabled);
env->SetFloatField(result, cameraFocalLength, options.cameraFocalLength);
env->SetFloatField(result, cameraFocusDistance, options.cameraFocusDistance);
env->SetBooleanField(result, autoScaleEnabled, options.autoScaleEnabled);
env->SetBooleanField(result, autoInstancingEnabled, options.autoInstancingEnabled);
}
extern "C" JNIEXPORT void JNICALL
Java_com_google_android_filament_utils_AutomationEngine_nGetCameraSettings(JNIEnv* env, jclass,
jlong nativeObject, jobject result) {
AutomationEngine* automation = (AutomationEngine*) nativeObject;
const auto& settings = automation->getSettings();
const auto& camera = settings.camera;
const jclass klass = env->GetObjectClass(result);
const jfieldID aperture = env->GetFieldID(klass, "aperture", "F");
const jfieldID shutterSpeed = env->GetFieldID(klass, "shutterSpeed", "F");
const jfieldID sensitivity = env->GetFieldID(klass, "sensitivity", "F");
const jfieldID near = env->GetFieldID(klass, "near", "F");
const jfieldID far = env->GetFieldID(klass, "far", "F");
const jfieldID focalLength = env->GetFieldID(klass, "focalLength", "F");
const jfieldID focusDistance = env->GetFieldID(klass, "focusDistance", "F");
env->SetFloatField(result, aperture, camera.aperture);
env->SetFloatField(result, shutterSpeed, camera.shutterSpeed);
env->SetFloatField(result, sensitivity, camera.sensitivity);
env->SetFloatField(result, near, camera.near);
env->SetFloatField(result, far, camera.far);
env->SetFloatField(result, focalLength, camera.focalLength);
env->SetFloatField(result, focusDistance, camera.focusDistance);
}
extern "C" JNIEXPORT jlong JNICALL
Java_com_google_android_filament_utils_AutomationEngine_nGetColorGrading(JNIEnv*, jclass,
jlong nativeObject, jlong nativeEngine) {

View File

@@ -94,20 +94,23 @@ public class AutomationEngine {
* Allows remote control for the viewer.
*/
public static class ViewerOptions {
public float cameraAperture = 16.0f;
public float cameraSpeed = 125.0f;
public float cameraISO = 100.0f;
public float cameraNear = 0.1f;
public float cameraFar = 100.0f;
public float groundShadowStrength = 0.75f;
public boolean groundPlaneEnabled = false;
public boolean skyboxEnabled = true;
public float cameraFocalLength = 28.0f;
public float cameraFocusDistance = 0.0f;
public boolean autoScaleEnabled = true;
public boolean autoInstancingEnabled = false;
}
public static class CameraSettings {
public float aperture = 16.0f;
public float shutterSpeed = 125.0f;
public float sensitivity = 100.0f;
public float near = 0.1f;
public float far = 100.0f;
public float focalLength = 28.0f;
public float focusDistance = 10.0f;
}
/**
* Creates an automation engine from a JSON specification.
*
@@ -229,6 +232,13 @@ public class AutomationEngine {
return result;
}
@NonNull
public CameraSettings getCameraSettings() {
CameraSettings result = new CameraSettings();
nGetCameraSettings(mNativeObject, result);
return result;
}
/**
* Gets a color grading object that corresponds to the latest settings.
*
@@ -280,6 +290,7 @@ public class AutomationEngine {
long[] materials, long ibl, int sunlight, int[] assetLights, long lightManager,
long scene, long renderer);
private static native void nGetViewerOptions(long nativeObject, Object result);
private static native void nGetCameraSettings(long nativeObject, Object result);
private static native long nGetColorGrading(long nativeObject, long nativeEngine);
private static native void nSignalBatchMode(long nativeObject);
private static native void nStopRunning(long nativeObject);

View File

@@ -16,6 +16,9 @@
package com.google.android.filament.utils
import android.graphics.Bitmap
import android.os.Handler
import android.os.Looper
import android.view.MotionEvent
import android.view.Surface
import android.view.SurfaceView
@@ -26,6 +29,7 @@ import com.google.android.filament.android.UiHelper
import com.google.android.filament.gltfio.*
import kotlinx.coroutines.*
import java.nio.Buffer
import java.nio.ByteBuffer
private const val kNearPlane = 0.05f // 5 cm
private const val kFarPlane = 1000.0f // 1 km
@@ -119,6 +123,8 @@ class ModelViewer(
private val target = DoubleArray(3)
private val upward = DoubleArray(3)
private var debugFrameCallback: ((Bitmap) -> Unit)? = null
init {
renderer = engine.createRenderer()
scene = engine.createScene()
@@ -305,10 +311,39 @@ class ModelViewer(
// Render the scene, unless the renderer wants to skip the frame.
if (renderer.beginFrame(swapChain!!, frameTimeNanos)) {
renderer.render(view)
debugFrameCallback?.let {
val viewport = view.viewport
val bitmap = Bitmap.createBitmap(viewport.width, viewport.height,
Bitmap.Config.ARGB_8888)
val buffer = ByteBuffer.allocateDirect(viewport.width * viewport.height * 4)
val handler = Handler(Looper.getMainLooper())
val pixelBufferDescriptor = Texture.PixelBufferDescriptor(buffer,
Texture.Format.RGBA, Texture.Type.UBYTE, 1, 0, 0, 0, handler) {
buffer.rewind()
bitmap.copyPixelsFromBuffer(buffer)
it(bitmap)
}
renderer.readPixels(viewport.left, viewport.bottom, viewport.width,
viewport.height, pixelBufferDescriptor)
debugFrameCallback = null
}
renderer.endFrame()
}
}
/*
* Sets a callback that will be invoked with the next rendered frame as a Bitmap. Note that this
* is a one-time callback.
*
* @param callback callback to be invoked with a rendered frame as [Bitmap]
*/
fun debugGetNextFrameCallback(callback: (Bitmap) -> Unit) {
debugFrameCallback = callback
}
private fun populateScene(asset: FilamentAsset) {
val rcm = engine.renderableManager
var count = 0

View File

@@ -6,6 +6,7 @@ option(FILAMENT_ENABLE_FGVIEWER "Enables Frame Graph Viewer" OFF)
option(FILAMENT_ENABLE_MATDBG "Enables Material debugger" OFF)
option(FILAMENT_DISABLE_MATOPT "Disables material optimizations" OFF)
option(FILAMENT_SUPPORTS_WEBGPU "Enables WebGPU on Android" OFF)
option(FILAMENT_SUPPORTS_WEBP_TEXTURES "Enable webp texture support on Android" OFF)
set(CMAKE_CXX_STANDARD 20)
@@ -30,6 +31,12 @@ add_library(stb STATIC IMPORTED)
set_target_properties(stb PROPERTIES IMPORTED_LOCATION
${FILAMENT_DIR}/lib/${ANDROID_ABI}/libstb.a)
if (FILAMENT_SUPPORTS_WEBP_TEXTURES)
add_library(webpdecoder STATIC IMPORTED)
set_target_properties(webpdecoder PROPERTIES IMPORTED_LOCATION
${FILAMENT_DIR}/lib/${ANDROID_ABI}/libwebpdecoder.a)
endif()
add_library(basis_transcoder STATIC IMPORTED)
set_target_properties(basis_transcoder PROPERTIES IMPORTED_LOCATION
${FILAMENT_DIR}/lib/${ANDROID_ABI}/libbasis_transcoder.a)
@@ -81,6 +88,10 @@ set(GLTFIO_INCLUDE_DIRS
../../libs/ktxreader/include
)
if (FILAMENT_SUPPORTS_WEBP_TEXTURES)
list(APPEND GLTFIO_INCLUDE_DIRS ../../third_party/libwebp/src)
endif()
add_library(gltfio-jni SHARED ${GLTFIO_SRCS})
target_compile_definitions(gltfio-jni PUBLIC GLTFIO_DRACO_SUPPORTED=1)
@@ -107,3 +118,6 @@ target_link_libraries(gltfio-jni
PRIVATE perfetto # needed only when FILAMENT_ENABLE_PERFETTO is defined
PRIVATE log # needed only when perfetto above is used
)
if (FILAMENT_SUPPORTS_WEBP_TEXTURES)
target_link_libraries(gltfio-jni PRIVATE webpdecoder)
endif()

View File

@@ -128,6 +128,18 @@ Java_com_google_android_filament_gltfio_ResourceLoader_nCreateKtx2Provider(JNIEn
return (jlong) createKtx2Provider(engine);
}
extern "C" JNIEXPORT jboolean JNICALL
Java_com_google_android_filament_gltfio_ResourceLoader_nIsWebpSupported(JNIEnv*, jclass) {
return (jboolean) isWebpSupported();
}
extern "C" JNIEXPORT jlong JNICALL
Java_com_google_android_filament_gltfio_ResourceLoader_nCreateWebpProvider(JNIEnv*, jclass,
jlong nativeEngine) {
Engine* engine = (Engine*) nativeEngine;
return (jlong) createWebpProvider(engine);
}
extern "C" JNIEXPORT void JNICALL
Java_com_google_android_filament_gltfio_ResourceLoader_nDestroyTextureProvider(JNIEnv*, jclass,
jlong nativeProvider) {

View File

@@ -37,6 +37,7 @@ public class ResourceLoader {
private final long mNativeObject;
private final long mNativeStbProvider;
private final long mNativeKtx2Provider;
private final long mNativeWebpProvider;
/**
* Constructs a resource loader tied to the given Filament engine.
@@ -50,9 +51,17 @@ public class ResourceLoader {
mNativeObject = nCreateResourceLoader(nativeEngine, false);
mNativeStbProvider = nCreateStbProvider(nativeEngine);
mNativeKtx2Provider = nCreateKtx2Provider(nativeEngine);
nAddTextureProvider(mNativeObject, "image/jpeg", mNativeStbProvider);
nAddTextureProvider(mNativeObject, "image/png", mNativeStbProvider);
nAddTextureProvider(mNativeObject, "image/ktx2", mNativeKtx2Provider);
if (nIsWebpSupported()) {
mNativeWebpProvider = nCreateWebpProvider(nativeEngine);
nAddTextureProvider(mNativeObject, "image/webp", mNativeWebpProvider);
}
else {
mNativeWebpProvider = 0;
}
}
/**
@@ -68,9 +77,17 @@ public class ResourceLoader {
mNativeObject = nCreateResourceLoader(nativeEngine, normalizeSkinningWeights);
mNativeStbProvider = nCreateStbProvider(nativeEngine);
mNativeKtx2Provider = nCreateKtx2Provider(nativeEngine);
nAddTextureProvider(mNativeObject, "image/jpeg", mNativeStbProvider);
nAddTextureProvider(mNativeObject, "image/png", mNativeStbProvider);
nAddTextureProvider(mNativeObject, "image/ktx2", mNativeKtx2Provider);
if (nIsWebpSupported()) {
mNativeWebpProvider = nCreateWebpProvider(nativeEngine);
nAddTextureProvider(mNativeObject, "image/webp", mNativeWebpProvider);
}
else {
mNativeWebpProvider = 0;
}
}
/**
@@ -80,6 +97,9 @@ public class ResourceLoader {
nDestroyResourceLoader(mNativeObject);
nDestroyTextureProvider(mNativeStbProvider);
nDestroyTextureProvider(mNativeKtx2Provider);
if (nIsWebpSupported()) {
nDestroyTextureProvider(mNativeWebpProvider);
}
}
/**
@@ -191,6 +211,9 @@ public class ResourceLoader {
private static native long nCreateStbProvider(long nativeEngine);
private static native long nCreateKtx2Provider(long nativeEngine);
private static native boolean nIsWebpSupported();
private static native long nCreateWebpProvider(long nativeEngine);
private static native void nAddTextureProvider(long nativeLoader, String url, long nativeProvider);
private static native void nDestroyTextureProvider(long nativeProvider);
}

View File

@@ -1,5 +1,5 @@
GROUP=com.google.android.filament
VERSION_NAME=1.67.1
VERSION_NAME=1.69.1
POM_DESCRIPTION=Real-time physically based rendering engine for Android.

View File

@@ -80,54 +80,12 @@ frame and the external texture are perfectly synchronized.
![Stream Test](../../docs/images/samples/sample_stream_test.jpg)
## Prerequisites
## Building Samples
Before you start, make sure to read [Filament's README](../../README.md). You need to be able to
compile Filament's native library and Filament's AAR for this project. The easiest way to proceed
is to install all the required dependencies and to run the following commands at the root of the
source tree:
source tree.
```shell
./build.sh -p desktop -i release
./build.sh -p android release
```
To build the samples, please follow the steps described in [BUILDING.md](../../BUILDING.md#android)
This will build all the native components and the AAR required by this sample application.
If you do not use the build script, you must set the `filament_tools_dir` property when invoking
Gradle, either from the command line or from `local.properties`. This property must point to the
distribution/install directory for desktop (produced by make/ninja install). This directory must
contain `bin/matc` and `bin/cmgen`.
Example:
```shell
./gradlew -Pfilament_tools_dir=../../dist-release assembleDebug
```
## Important: SDK location
Either ensure your `ANDROID_HOME` environment variable is set or make sure the root project
contains a `local.properties` file with the `sdk.dir` property pointing to your installation of
the Android SDK.
## Compiling
### Android Studio
You must use the latest stable release of Android Studio. To open the project, point Studio to the
`android` folder. After opening the project and syncing to gradle, select the sample of your choice
using the drop-down widget in the toolbar.
To compile and run each sample make sure you have selected the appropriate build variant
(arm7, arm8, x86 or x86_64). If you are not sure you can simply select the "universal"
variant which includes all the other ones.
### Command Line
From the `android` directory in the project root:
```shell
./gradlew :samples:sample-hello-triangle:installDebug
```
Replace `sample-hello-triangle` with your preferred project.

View File

@@ -389,9 +389,9 @@ class MainActivity : Activity() {
viewerContent.assetLights = modelViewer.asset?.lightEntities
automation.applySettings(modelViewer.engine, json, viewerContent)
modelViewer.view.colorGrading = automation.getColorGrading(modelViewer.engine)
modelViewer.cameraFocalLength = automation.viewerOptions.cameraFocalLength
modelViewer.cameraNear = automation.viewerOptions.cameraNear
modelViewer.cameraFar = automation.viewerOptions.cameraFar
modelViewer.cameraFocalLength = automation.cameraSettings.focalLength
modelViewer.cameraNear = automation.cameraSettings.near
modelViewer.cameraFar = automation.cameraSettings.far
updateRootTransform()
}

View File

@@ -0,0 +1,12 @@
*.iml
.gradle
/local.properties
/.idea/workspace.xml
/.idea/libraries
/.idea/caches
/.idea/gradle.xml
.DS_Store
/build
/captures
/src/main/assets
.externalNativeBuild

View File

@@ -0,0 +1,53 @@
plugins {
id 'com.android.application'
id 'kotlin-android'
id 'filament-tools-plugin'
}
project.ext.isSample = true
kotlin {
jvmToolchain(versions.jdk)
}
filamentTools {
materialInputDir = project.layout.projectDirectory.dir("src/main/materials")
materialOutputDir = project.layout.projectDirectory.dir("src/main/assets/materials")
}
clean.doFirst {
delete "src/main/assets"
}
android {
namespace 'com.google.android.filament.texturetarget'
compileSdkVersion versions.compileSdk
defaultConfig {
applicationId "com.google.android.filament.texturetarget"
minSdkVersion 26
targetSdkVersion versions.targetSdk
}
// NOTE: This is a workaround required because the AGP task collectReleaseDependencies
// is not configuration-cache friendly yet; this is only useful for Play publication
dependenciesInfo {
includeInApk = false
}
// We use the .filamat extension for materials compiled with matc
// Telling aapt to not compress them allows to load them efficiently
aaptOptions {
noCompress 'filamat', 'ktx'
}
compileOptions {
sourceCompatibility versions.jdk
targetCompatibility versions.jdk
}
}
dependencies {
implementation deps.kotlin
implementation project(':filament-android')
}

View File

@@ -0,0 +1,22 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/AppTheme">
<activity
android:exported="true"
android:name=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN"/>
<category android:name="android.intent.category.LAUNCHER"/>
</intent-filter>
</activity>
</application>
</manifest>

View File

@@ -0,0 +1,449 @@
/*
* Copyright (C) 2024 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.
*/
package com.google.android.filament.texturetarget
import android.animation.ValueAnimator
import android.app.Activity
import android.hardware.HardwareBuffer
import android.opengl.Matrix
import android.os.Bundle
import android.view.Choreographer
import android.view.Surface
import android.view.SurfaceView
import android.view.animation.LinearInterpolator
import com.google.android.filament.*
import com.google.android.filament.RenderableManager.PrimitiveType
import com.google.android.filament.VertexBuffer.AttributeType
import com.google.android.filament.VertexBuffer.VertexAttribute
import com.google.android.filament.android.DisplayHelper
import com.google.android.filament.android.FilamentHelper
import com.google.android.filament.android.UiHelper
import java.nio.ByteBuffer
import java.nio.ByteOrder
import java.nio.channels.Channels
import kotlin.math.PI
import kotlin.math.cos
import kotlin.math.sin
class MainActivity : Activity() {
companion object {
init {
Filament.init()
}
}
private lateinit var surfaceView: SurfaceView
private lateinit var uiHelper: UiHelper
private lateinit var displayHelper: DisplayHelper
private lateinit var choreographer: Choreographer
private lateinit var engine: Engine
private lateinit var renderer: Renderer
private lateinit var scene: Scene
private lateinit var view: View
private lateinit var camera: Camera
private lateinit var triangleMaterial: Material
private lateinit var texturedMaterial: Material
private lateinit var triangleVertexBuffer: VertexBuffer
private lateinit var triangleIndexBuffer: IndexBuffer
private lateinit var quadVertexBuffer: VertexBuffer
private lateinit var quadIndexBuffer: IndexBuffer
@Entity private var triangleRenderable = 0
@Entity private var quadRenderable = 0
private var swapChain: SwapChain? = null
private val frameScheduler = FrameCallback()
private val animator = ValueAnimator.ofFloat(0.0f, 360.0f)
private var hardwareBuffer: HardwareBuffer? = null
private var texture: Texture? = null
private var renderTarget: RenderTarget? = null
private var useExternalTexture = true
private lateinit var offscreenView: View
private lateinit var offscreenCamera: Camera
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
// To use set this flag with adb, run
// adb shell am start -n com.google.android.filament.texturetarget/.MainActivity --ez useExternalTexture false
useExternalTexture = intent.getBooleanExtra("useExternalTexture", true)
surfaceView = SurfaceView(this)
setContentView(surfaceView)
choreographer = Choreographer.getInstance()
displayHelper = DisplayHelper(this)
setupSurfaceView()
setupFilament()
setupView()
setupScene()
}
private fun setupSurfaceView() {
uiHelper = UiHelper(UiHelper.ContextErrorPolicy.DONT_CHECK)
uiHelper.renderCallback = SurfaceCallback()
uiHelper.attachTo(surfaceView)
}
private fun setupFilament() {
engine = Engine.create()
renderer = engine.createRenderer()
scene = engine.createScene()
view = engine.createView()
camera = engine.createCamera(engine.entityManager.create())
offscreenView = engine.createView()
offscreenCamera = engine.createCamera(engine.entityManager.create())
}
private fun setupView() {
scene.skybox = Skybox.Builder()
.priority(0)
.color(0.0f, 0.0f, 1.0f, 1.0f).build(engine)
// This is the view that will be drawn on screen.
view.camera = camera
view.scene = scene
view.isPostProcessingEnabled = false
// This is the view that will be rendered off-screen.
offscreenView.camera = offscreenCamera
offscreenView.scene = scene
offscreenView.isPostProcessingEnabled = false
}
private fun setupScene() {
loadMaterials()
createTriangleMesh()
createQuadMesh()
// layer 1: skybox
// layer 2: triangle
// layer 3: quad
triangleMaterial.defaultInstance.cullingMode = Material.CullingMode.NONE;
texturedMaterial.defaultInstance.cullingMode = Material.CullingMode.NONE;
// The triangle is a regular renderable.
triangleRenderable = EntityManager.get().create()
RenderableManager.Builder(1)
.geometry(0, PrimitiveType.TRIANGLES, triangleVertexBuffer, triangleIndexBuffer, 0, 3)
.material(0, triangleMaterial.defaultInstance)
.culling(false)
.castShadows(false)
.receiveShadows(false)
.layerMask(7, 2)
.build(engine, triangleRenderable)
// The quad is a regular renderable.
quadRenderable = EntityManager.get().create()
RenderableManager.Builder(1)
.geometry(0, PrimitiveType.TRIANGLES, quadVertexBuffer, quadIndexBuffer, 0, 6)
.material(0, texturedMaterial.defaultInstance)
.culling(false)
.castShadows(false)
.receiveShadows(false)
.layerMask(7, 4)
.build(engine, quadRenderable)
// We only want to render the triangle in the offscreen view.
offscreenView.setVisibleLayers(7, 3) // render skybox + triangle
// We only want to render the quad in the on-screen view.
view.setVisibleLayers(7, 4) // render quad only
scene.addEntity(triangleRenderable)
scene.addEntity(quadRenderable)
startAnimation()
}
private fun loadMaterials() {
readUncompressedAsset("materials/baked_color.filamat").let {
triangleMaterial = Material.Builder().payload(it, it.remaining()).build(engine)
}
if (useExternalTexture) {
readUncompressedAsset("materials/texturedExternal.filamat").let {
texturedMaterial = Material.Builder().payload(it, it.remaining()).build(engine)
}
} else {
readUncompressedAsset("materials/textured.filamat").let {
texturedMaterial = Material.Builder().payload(it, it.remaining()).build(engine)
}
}
}
private fun createTriangleMesh() {
val intSize = 4
val floatSize = 4
val shortSize = 2
val vertexSize = 3 * floatSize + intSize
data class Vertex(val x: Float, val y: Float, val z: Float, val color: Int)
fun ByteBuffer.put(v: Vertex): ByteBuffer {
putFloat(v.x)
putFloat(v.y)
putFloat(v.z)
putInt(v.color)
return this
}
val vertexCount = 3
val a1 = PI * 2.0 / 3.0
val a2 = PI * 4.0 / 3.0
val vertexData = ByteBuffer.allocate(vertexCount * vertexSize)
.order(ByteOrder.nativeOrder())
.put(Vertex(1.0f, 0.0f, 0.0f, 0xffff0000.toInt()))
.put(Vertex(cos(a1).toFloat(), sin(a1).toFloat(), 0.0f, 0xff00ff00.toInt()))
.put(Vertex(cos(a2).toFloat(), sin(a2).toFloat(), 0.0f, 0xff0000ff.toInt()))
.flip()
triangleVertexBuffer = VertexBuffer.Builder()
.bufferCount(1)
.vertexCount(vertexCount)
.attribute(VertexAttribute.POSITION, 0, AttributeType.FLOAT3, 0, vertexSize)
.attribute(VertexAttribute.COLOR, 0, AttributeType.UBYTE4, 3 * floatSize, vertexSize)
.normalized(VertexAttribute.COLOR)
.build(engine)
triangleVertexBuffer.setBufferAt(engine, 0, vertexData)
val indexData = ByteBuffer.allocate(vertexCount * shortSize)
.order(ByteOrder.nativeOrder())
.putShort(0)
.putShort(1)
.putShort(2)
.flip()
triangleIndexBuffer = IndexBuffer.Builder()
.indexCount(3)
.bufferType(IndexBuffer.Builder.IndexType.USHORT)
.build(engine)
triangleIndexBuffer.setBuffer(engine, indexData)
}
private fun createQuadMesh() {
val floatSize = 4
val shortSize = 2
val vertexSize = (2 * floatSize) + (2 * floatSize) // position + UV
data class Vertex(val x: Float, val y: Float, val u: Float, val v: Float)
fun ByteBuffer.put(v: Vertex): ByteBuffer {
putFloat(v.x)
putFloat(v.y)
putFloat(v.u)
putFloat(v.v)
return this
}
val vertexCount = 4
val vertexData = ByteBuffer.allocate(vertexCount * vertexSize)
.order(ByteOrder.nativeOrder())
.put(Vertex(-1.0f, -1.0f, 0.0f, 0.0f))
.put(Vertex( 1.0f, -1.0f, 1.0f, 0.0f))
.put(Vertex( 1.0f, 1.0f, 1.0f, 1.0f))
.put(Vertex(-1.0f, 1.0f, 0.0f, 1.0f))
.flip()
quadVertexBuffer = VertexBuffer.Builder()
.bufferCount(1)
.vertexCount(vertexCount)
.attribute(VertexAttribute.POSITION, 0, AttributeType.FLOAT2, 0, vertexSize)
.attribute(VertexAttribute.UV0, 0, AttributeType.FLOAT2, 2 * floatSize, vertexSize)
.build(engine)
quadVertexBuffer.setBufferAt(engine, 0, vertexData)
val indexData = ByteBuffer.allocate(6 * shortSize)
.order(ByteOrder.nativeOrder())
.putShort(0).putShort(1).putShort(2)
.putShort(0).putShort(2).putShort(3)
.flip()
quadIndexBuffer = IndexBuffer.Builder()
.indexCount(6)
.bufferType(IndexBuffer.Builder.IndexType.USHORT)
.build(engine)
quadIndexBuffer.setBuffer(engine, indexData)
}
private fun startAnimation() {
animator.interpolator = LinearInterpolator()
animator.duration = 4000
animator.repeatMode = ValueAnimator.RESTART
animator.repeatCount = ValueAnimator.INFINITE
animator.addUpdateListener { a ->
val transformMatrix = FloatArray(16)
Matrix.setRotateM(transformMatrix, 0, -(a.animatedValue as Float), 0.0f, 0.0f, 1.0f)
val tcm = engine.transformManager
tcm.setTransform(tcm.getInstance(triangleRenderable), transformMatrix)
}
animator.start()
}
override fun onResume() {
super.onResume()
choreographer.postFrameCallback(frameScheduler)
animator.start()
}
override fun onPause() {
super.onPause()
choreographer.removeFrameCallback(frameScheduler)
animator.cancel()
}
override fun onDestroy() {
super.onDestroy()
choreographer.removeFrameCallback(frameScheduler)
animator.cancel()
uiHelper.detach()
// Destroy all renderables.
scene.remove(triangleRenderable)
scene.remove(quadRenderable)
// Destroy all resources.
engine.destroyEntity(triangleRenderable)
engine.destroyEntity(quadRenderable)
engine.destroyRenderer(renderer)
engine.destroyVertexBuffer(triangleVertexBuffer)
engine.destroyIndexBuffer(triangleIndexBuffer)
engine.destroyVertexBuffer(quadVertexBuffer)
engine.destroyIndexBuffer(quadIndexBuffer)
engine.destroyMaterial(triangleMaterial)
engine.destroyMaterial(texturedMaterial)
engine.destroyView(view)
engine.destroyView(offscreenView)
engine.destroyScene(scene)
engine.destroyCameraComponent(camera.entity)
engine.destroyCameraComponent(offscreenCamera.entity)
renderTarget?.let { engine.destroyRenderTarget(it) }
texture?.let { engine.destroyTexture(it) }
hardwareBuffer?.close()
val entityManager = EntityManager.get()
entityManager.destroy(triangleRenderable)
entityManager.destroy(quadRenderable)
entityManager.destroy(camera.entity)
entityManager.destroy(offscreenCamera.entity)
engine.destroy()
}
inner class FrameCallback : Choreographer.FrameCallback {
override fun doFrame(frameTimeNanos: Long) {
choreographer.postFrameCallback(this)
if (uiHelper.isReadyToRender) {
if (renderer.beginFrame(swapChain!!, frameTimeNanos)) {
// Render the triangle to the texture.
renderer.render(offscreenView)
// Render the quad to the screen.
renderer.render(view)
renderer.endFrame()
}
}
}
}
inner class SurfaceCallback : UiHelper.RendererCallback {
override fun onNativeWindowChanged(surface: Surface) {
swapChain?.let { engine.destroySwapChain(it) }
swapChain = engine.createSwapChain(surface, uiHelper.swapChainFlags)
displayHelper.attach(renderer, surfaceView.display)
}
override fun onDetachedFromSurface() {
displayHelper.detach()
swapChain?.let {
engine.destroySwapChain(it)
engine.flushAndWait()
swapChain = null
}
}
override fun onResized(width: Int, height: Int) {
// On-screen camera
val zoom = 1.0
val aspect = width.toDouble() / height.toDouble()
camera.setProjection(Camera.Projection.ORTHO, -aspect * zoom, aspect * zoom, -zoom, zoom, 0.0, 10.0)
view.viewport = Viewport(0, 0, width, height)
// Off-screen camera
val offscreenZoom = 1.5
offscreenCamera.setProjection(Camera.Projection.ORTHO,
-aspect * offscreenZoom, aspect * offscreenZoom,
-offscreenZoom, offscreenZoom, 0.0, 10.0)
offscreenView.viewport = Viewport(0, 0, width, height)
// If we have a render target, destroy it.
renderTarget?.let { engine.destroyRenderTarget(it) }
texture?.let { engine.destroyTexture(it) }
hardwareBuffer?.close()
if (useExternalTexture) {
// Create a new render target.
hardwareBuffer = HardwareBuffer.create(width, height,
HardwareBuffer.RGBA_8888, 1,
HardwareBuffer.USAGE_GPU_SAMPLED_IMAGE or HardwareBuffer.USAGE_GPU_COLOR_OUTPUT)
texture = Texture.Builder()
.width(width)
.height(height)
.usage(Texture.Usage.COLOR_ATTACHMENT or Texture.Usage.SAMPLEABLE)
.sampler(Texture.Sampler.SAMPLER_EXTERNAL)
.format(Texture.InternalFormat.RGBA8)
.external()
.build(engine)
texture!!.setExternalImage(engine, hardwareBuffer!!)
} else {
texture = Texture.Builder()
.width(width)
.height(height)
.levels(1)
.usage(Texture.Usage.COLOR_ATTACHMENT or Texture.Usage.SAMPLEABLE)
.format(Texture.InternalFormat.RGBA8)
.build(engine)
}
renderTarget = RenderTarget.Builder()
.texture(RenderTarget.AttachmentPoint.COLOR, texture!!)
.build(engine)
offscreenView.renderTarget = renderTarget
// Set the texture on the quad material.
texturedMaterial.defaultInstance.setParameter("texture", texture!!,
TextureSampler(TextureSampler.MinFilter.LINEAR, TextureSampler.MagFilter.LINEAR,
TextureSampler.WrapMode.CLAMP_TO_EDGE))
FilamentHelper.synchronizePendingFrames(engine)
}
}
private fun readUncompressedAsset(assetName: String): ByteBuffer {
assets.openFd(assetName).use { fd ->
val input = fd.createInputStream()
val dst = ByteBuffer.allocate(fd.length.toInt())
val src = Channels.newChannel(input)
src.read(dst)
src.close()
return dst.apply { rewind() }
}
}
}

View File

@@ -0,0 +1,18 @@
material {
name : baked_color,
shadingModel : unlit,
requires : [
color
]
}
fragment {
void material(inout MaterialInputs material) {
// You must always call the prepareMaterial() function
prepareMaterial(material);
// We set the material's color to the color interpolated from
// the model's vertices
material.baseColor = getColor();
}
}

View File

@@ -0,0 +1,20 @@
material {
name : textured,
shadingModel : unlit,
parameters : [
{
type : sampler2d,
name : texture
}
],
requires: [
uv0
]
}
fragment {
void material(inout MaterialInputs material) {
prepareMaterial(material);
material.baseColor = texture(materialParams_texture, uvToRenderTargetUV(getUV0()));
}
}

View File

@@ -0,0 +1,20 @@
material {
name : textured,
shadingModel : unlit,
parameters : [
{
type : samplerExternal,
name : texture
}
],
requires: [
uv0
]
}
fragment {
void material(inout MaterialInputs material) {
prepareMaterial(material);
material.baseColor = texture(materialParams_texture, uvToRenderTargetUV(getUV0()));
}
}

View File

@@ -0,0 +1,34 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:aapt="http://schemas.android.com/aapt"
android:width="108dp"
android:height="108dp"
android:viewportHeight="108"
android:viewportWidth="108">
<path
android:fillType="evenOdd"
android:pathData="M32,64C32,64 38.39,52.99 44.13,50.95C51.37,48.37 70.14,49.57 70.14,49.57L108.26,87.69L108,109.01L75.97,107.97L32,64Z"
android:strokeColor="#00000000"
android:strokeWidth="1">
<aapt:attr name="android:fillColor">
<gradient
android:endX="78.5885"
android:endY="90.9159"
android:startX="48.7653"
android:startY="61.0927"
android:type="linear">
<item
android:color="#44000000"
android:offset="0.0"/>
<item
android:color="#00000000"
android:offset="1.0"/>
</gradient>
</aapt:attr>
</path>
<path
android:fillColor="#FFFFFF"
android:fillType="nonZero"
android:pathData="M66.94,46.02L66.94,46.02C72.44,50.07 76,56.61 76,64L32,64C32,56.61 35.56,50.11 40.98,46.06L36.18,41.19C35.45,40.45 35.45,39.3 36.18,38.56C36.91,37.81 38.05,37.81 38.78,38.56L44.25,44.05C47.18,42.57 50.48,41.71 54,41.71C57.48,41.71 60.78,42.57 63.68,44.05L69.11,38.56C69.84,37.81 70.98,37.81 71.71,38.56C72.44,39.3 72.44,40.45 71.71,41.19L66.94,46.02ZM62.94,56.92C64.08,56.92 65,56.01 65,54.88C65,53.76 64.08,52.85 62.94,52.85C61.8,52.85 60.88,53.76 60.88,54.88C60.88,56.01 61.8,56.92 62.94,56.92ZM45.06,56.92C46.2,56.92 47.13,56.01 47.13,54.88C47.13,53.76 46.2,52.85 45.06,52.85C43.92,52.85 43,53.76 43,54.88C43,56.01 43.92,56.92 45.06,56.92Z"
android:strokeColor="#00000000"
android:strokeWidth="1"/>
</vector>

View File

@@ -0,0 +1,171 @@
<?xml version="1.0" encoding="utf-8"?>
<vector
xmlns:android="http://schemas.android.com/apk/res/android"
android:width="108dp"
android:height="108dp"
android:viewportHeight="108"
android:viewportWidth="108">
<path
android:fillColor="#26A69A"
android:pathData="M0,0h108v108h-108z"/>
<path
android:fillColor="#00000000"
android:pathData="M9,0L9,108"
android:strokeColor="#33FFFFFF"
android:strokeWidth="0.8"/>
<path
android:fillColor="#00000000"
android:pathData="M19,0L19,108"
android:strokeColor="#33FFFFFF"
android:strokeWidth="0.8"/>
<path
android:fillColor="#00000000"
android:pathData="M29,0L29,108"
android:strokeColor="#33FFFFFF"
android:strokeWidth="0.8"/>
<path
android:fillColor="#00000000"
android:pathData="M39,0L39,108"
android:strokeColor="#33FFFFFF"
android:strokeWidth="0.8"/>
<path
android:fillColor="#00000000"
android:pathData="M49,0L49,108"
android:strokeColor="#33FFFFFF"
android:strokeWidth="0.8"/>
<path
android:fillColor="#00000000"
android:pathData="M59,0L59,108"
android:strokeColor="#33FFFFFF"
android:strokeWidth="0.8"/>
<path
android:fillColor="#00000000"
android:pathData="M69,0L69,108"
android:strokeColor="#33FFFFFF"
android:strokeWidth="0.8"/>
<path
android:fillColor="#00000000"
android:pathData="M79,0L79,108"
android:strokeColor="#33FFFFFF"
android:strokeWidth="0.8"/>
<path
android:fillColor="#00000000"
android:pathData="M89,0L89,108"
android:strokeColor="#33FFFFFF"
android:strokeWidth="0.8"/>
<path
android:fillColor="#00000000"
android:pathData="M99,0L99,108"
android:strokeColor="#33FFFFFF"
android:strokeWidth="0.8"/>
<path
android:fillColor="#00000000"
android:pathData="M0,9L108,9"
android:strokeColor="#33FFFFFF"
android:strokeWidth="0.8"/>
<path
android:fillColor="#00000000"
android:pathData="M0,19L108,19"
android:strokeColor="#33FFFFFF"
android:strokeWidth="0.8"/>
<path
android:fillColor="#00000000"
android:pathData="M0,29L108,29"
android:strokeColor="#33FFFFFF"
android:strokeWidth="0.8"/>
<path
android:fillColor="#00000000"
android:pathData="M0,39L108,39"
android:strokeColor="#33FFFFFF"
android:strokeWidth="0.8"/>
<path
android:fillColor="#00000000"
android:pathData="M0,49L108,49"
android:strokeColor="#33FFFFFF"
android:strokeWidth="0.8"/>
<path
android:fillColor="#00000000"
android:pathData="M0,59L108,59"
android:strokeColor="#33FFFFFF"
android:strokeWidth="0.8"/>
<path
android:fillColor="#00000000"
android:pathData="M0,69L108,69"
android:strokeColor="#33FFFFFF"
android:strokeWidth="0.8"/>
<path
android:fillColor="#00000000"
android:pathData="M0,79L108,79"
android:strokeColor="#33FFFFFF"
android:strokeWidth="0.8"/>
<path
android:fillColor="#00000000"
android:pathData="M0,89L108,89"
android:strokeColor="#33FFFFFF"
android:strokeWidth="0.8"/>
<path
android:fillColor="#00000000"
android:pathData="M0,99L108,99"
android:strokeColor="#33FFFFFF"
android:strokeWidth="0.8"/>
<path
android:fillColor="#00000000"
android:pathData="M19,29L89,29"
android:strokeColor="#33FFFFFF"
android:strokeWidth="0.8"/>
<path
android:fillColor="#00000000"
android:pathData="M19,39L89,39"
android:strokeColor="#33FFFFFF"
android:strokeWidth="0.8"/>
<path
android:fillColor="#00000000"
android:pathData="M19,49L89,49"
android:strokeColor="#33FFFFFF"
android:strokeWidth="0.8"/>
<path
android:fillColor="#00000000"
android:pathData="M19,59L89,59"
android:strokeColor="#33FFFFFF"
android:strokeWidth="0.8"/>
<path
android:fillColor="#00000000"
android:pathData="M19,69L89,69"
android:strokeColor="#33FFFFFF"
android:strokeWidth="0.8"/>
<path
android:fillColor="#00000000"
android:pathData="M19,79L89,79"
android:strokeColor="#33FFFFFF"
android:strokeWidth="0.8"/>
<path
android:fillColor="#00000000"
android:pathData="M29,19L29,89"
android:strokeColor="#33FFFFFF"
android:strokeWidth="0.8"/>
<path
android:fillColor="#00000000"
android:pathData="M39,19L39,89"
android:strokeColor="#33FFFFFF"
android:strokeWidth="0.8"/>
<path
android:fillColor="#00000000"
android:pathData="M49,19L49,89"
android:strokeColor="#33FFFFFF"
android:strokeWidth="0.8"/>
<path
android:fillColor="#00000000"
android:pathData="M59,19L59,89"
android:strokeColor="#33FFFFFF"
android:strokeWidth="0.8"/>
<path
android:fillColor="#00000000"
android:pathData="M69,19L69,89"
android:strokeColor="#33FFFFFF"
android:strokeWidth="0.8"/>
<path
android:fillColor="#00000000"
android:pathData="M79,19L79,89"
android:strokeColor="#33FFFFFF"
android:strokeWidth="0.8"/>
</vector>

View File

@@ -0,0 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
<background android:drawable="@drawable/ic_launcher_background"/>
<foreground android:drawable="@drawable/ic_launcher_foreground"/>
</adaptive-icon>

View File

@@ -0,0 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
<background android:drawable="@drawable/ic_launcher_background"/>
<foreground android:drawable="@drawable/ic_launcher_foreground"/>
</adaptive-icon>

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 10 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

View File

@@ -0,0 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<color name="colorPrimary">#3F51B5</color>
<color name="colorPrimaryDark">#303F9F</color>
<color name="colorAccent">#FF4081</color>
</resources>

View File

@@ -0,0 +1,3 @@
<resources>
<string name="app_name">Texture Target</string>
</resources>

View File

@@ -0,0 +1,8 @@
<resources>
<!-- Base application theme. -->
<style name="AppTheme" parent="android:Theme.Material.Light.DarkActionBar">
<!-- Customize your theme here. -->
</style>
</resources>

View File

@@ -3,6 +3,7 @@ include ':filament-android'
include ':filamat-android'
include ':gltfio-android'
include ':filament-utils-android'
include ':filament-tools'
// Samples
include ':samples:sample-gltf-viewer'
@@ -17,6 +18,7 @@ include ':samples:sample-multi-view'
include ':samples:sample-page-curl'
include ':samples:sample-stream-test'
include ':samples:sample-texture-view'
include ':samples:sample-texture-target'
include ':samples:sample-textured-object'
include ':samples:sample-transparent-view'

View File

@@ -158,7 +158,7 @@ function print_fgviewer_help {
}
# Unless explicitly specified, NDK version will be selected as highest available version within same major release chain
FILAMENT_NDK_VERSION=${FILAMENT_NDK_VERSION:-$(cat `dirname $0`/build/common/versions | grep GITHUB_NDK_VERSION | sed s/GITHUB_NDK_VERSION=//g | cut -f 1 -d ".")}
FILAMENT_NDK_VERSION=$(cat `dirname $0`/build/common/versions | grep GITHUB_NDK_VERSION | sed s/GITHUB_NDK_VERSION=//g | cut -f 1 -d ".")
# Internal variables
ISSUE_CLEAN=false
@@ -556,11 +556,14 @@ function build_android {
archive_android "Release"
fi
local root_dir=$(pwd)
pushd android > /dev/null
if [[ "${ISSUE_DEBUG_BUILD}" == "true" ]]; then
./gradlew \
-Pcom.google.android.filament.dist-dir=../out/android-debug/filament \
-Pcom.google.android.filament.tools-dir=${root_dir}/out/debug/filament \
-Pcom.google.android.filament.abis=${ABI_GRADLE_OPTION} \
${VULKAN_ANDROID_GRADLE_OPTION} \
${WEBGPU_ANDROID_GRADLE_OPTION} \
@@ -573,6 +576,7 @@ function build_android {
./gradlew \
-Pcom.google.android.filament.dist-dir=../out/android-debug/filament \
-Pcom.google.android.filament.tools-dir=${root_dir}/out/debug/filament \
-Pcom.google.android.filament.abis=${ABI_GRADLE_OPTION} \
${WEBGPU_ANDROID_GRADLE_OPTION} \
:filamat-android:assembleDebug
@@ -581,6 +585,7 @@ function build_android {
for sample in ${ANDROID_SAMPLES}; do
./gradlew \
-Pcom.google.android.filament.dist-dir=../out/android-debug/filament \
-Pcom.google.android.filament.tools-dir=${root_dir}/out/debug/filament \
-Pcom.google.android.filament.abis=${ABI_GRADLE_OPTION} \
${MATOPT_GRADLE_OPTION} \
:samples:${sample}:assembleDebug
@@ -613,6 +618,7 @@ function build_android {
if [[ "${ISSUE_RELEASE_BUILD}" == "true" ]]; then
./gradlew \
-Pcom.google.android.filament.dist-dir=../out/android-release/filament \
-Pcom.google.android.filament.tools-dir=${root_dir}/out/release/filament \
-Pcom.google.android.filament.abis=${ABI_GRADLE_OPTION} \
${VULKAN_ANDROID_GRADLE_OPTION} \
${WEBGPU_ANDROID_GRADLE_OPTION} \
@@ -625,6 +631,7 @@ function build_android {
./gradlew \
-Pcom.google.android.filament.dist-dir=../out/android-release/filament \
-Pcom.google.android.filament.tools-dir=${root_dir}/out/release/filament \
-Pcom.google.android.filament.abis=${ABI_GRADLE_OPTION} \
${WEBGPU_ANDROID_GRADLE_OPTION} \
:filamat-android:assembleRelease
@@ -633,6 +640,7 @@ function build_android {
for sample in ${ANDROID_SAMPLES}; do
./gradlew \
-Pcom.google.android.filament.dist-dir=../out/android-release/filament \
-Pcom.google.android.filament.tools-dir=${root_dir}/out/release/filament \
-Pcom.google.android.filament.abis=${ABI_GRADLE_OPTION} \
${MATOPT_GRADLE_OPTION} \
:samples:${sample}:assembleRelease

View File

@@ -18,8 +18,8 @@ if [[ "$GITHUB_WORKFLOW" ]]; then
fi
fi
# Unless explicitly specified, NDK version will be set to match exactly the required one
FILAMENT_NDK_VERSION=${GITHUB_NDK_VERSION:-27.0.11718014}
# Unless explicitly specified, NDK version will be selected as highest available version within same major release chain
FILAMENT_NDK_VERSION=$(cat `dirname $0`/../common/versions | grep GITHUB_NDK_VERSION | sed s/GITHUB_NDK_VERSION=//g)
(! grep "${FILAMENT_NDK_VERSION}" `dirname $0`/../../android/build.gradle > /dev/null) &&
echo "Mismatch of NDK versions: want ${FILAMENT_NDK_VERSION} and not found in android/build.gradle" &&

View File

@@ -34,6 +34,11 @@ if [[ "$TARGET" == "presubmit" ]]; then
BUILD_RELEASE=release
fi
if [[ "$TARGET" == "presubmit-with-test" ]]; then
BUILD_RELEASE=release
RUN_TESTS=-u
fi
if [[ "$TARGET" == "debug" ]]; then
BUILD_DEBUG=debug
GENERATE_ARCHIVES=-a

View File

@@ -1,6 +1,5 @@
libs/viewer/test_settings
filament/test/test_filament --gtest_filter=-FilamentTest.FroxelData:FilamentExposureWithEngineTest.SetExposure:FilamentExposureWithEngineTest.ComputeEV100:RenderingTest.*
filament/test/test_material_parser
libs/math/test_math
libs/image/test_image compare libs/image/tests/reference/
libs/utils/test_utils

View File

@@ -3,7 +3,7 @@ GITHUB_CMAKE_VERSION=3.22.1
GITHUB_NINJA_VERSION=1.10.2
GITHUB_MESA_VERSION=24.2.1
GITHUB_LLVM_VERSION=16
GITHUB_NDK_VERSION=27.0.11718014
GITHUB_NDK_VERSION=29.0.14206865
GITHUB_EMSDK_VERSION=3.1.60
GITHUB_VULKANSDK_VERSION=1.4.321.0
GITHUB_GLTF_SAMPLE_ASSETS_COMMIT=d441dfdb87413ff412c620849a649d61789a470f
GITHUB_GLTF_SAMPLE_ASSETS_COMMIT=d441dfdb87413ff412c620849a649d61789a470f

View File

@@ -75,7 +75,7 @@ set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)
# C_FLAGS += -Wl,-pie
# CXX_FLAGS += -lstdc++
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fPIE -mcpu=cortex-a57" CACHE STRING "Toolchain CFLAGS")
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fPIE -march=armv8-a -mtune=cortex-a78" CACHE STRING "Toolchain CFLAGS")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${CMAKE_C_FLAGS}" CACHE STRING "Toolchain CXXFLAGS")
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -fPIE -pie -static-libstdc++" CACHE STRING "Toolchain LDFLAGS")
set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -static-libstdc++" CACHE STRING "Toolchain LDFLAGS")

View File

@@ -87,7 +87,7 @@ set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)
# for hardfp: CFLAGS must have -mhard-float
# LDFLAGS must have -Wl,--no-warn-mismatch
#
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -mthumb -march=armv7-a -mcpu=cortex-a15 -mfloat-abi=softfp -mfpu=neon-vfpv4 -fPIE" CACHE STRING "Toolchain CFLAGS")
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -mthumb -march=armv7-a -mfloat-abi=softfp -mfpu=neon-vfpv4 -fPIE" CACHE STRING "Toolchain CFLAGS")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${CMAKE_C_FLAGS}" CACHE STRING "Toolchain CXXFLAGS")
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -march=armv7-a -Wl,--no-warn-mismatch -L${TOOLCHAIN}/arm-linux-androideabi/lib/armv7-a -static-libstdc++ -fPIE -pie" CACHE STRING "Toolchain LDFLAGS")
set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -march=armv7-a -Wl,--no-warn-mismatch -L${TOOLCHAIN}/arm-linux-androideabi/lib/armv7-a -static-libstdc++" CACHE STRING "Toolchain LDFLAGS")

View File

@@ -97,6 +97,7 @@ in table [standardProperties].
**transmission** | Defines how much of the diffuse light of a dielectric is transmitted through the object, in other words this defines how transparent an object is
**ior** | Index of refraction, either for refractive objects or as an alternative to reflectance
**microThickness** | Thickness of the thin layer of refractive objects
**dispersion** | Strength of the dispersion effect for refractive objects, specified as 20/Abbe number
**bentNormal** | A normal pointing in the average unoccluded direction. Can be used to improve indirect lighting quality
**shadowStrength** | Strength factor between 0 and 1 for all shadows received by this material
[Table [standardProperties]: Properties of the standard model]
@@ -126,6 +127,7 @@ The type and range of each property is described in table [standardPropertiesTyp
**absorption** | float3 | [0..n] |
**microThickness** | float | [0..n] |
**thickness** | float | [0..n] |
**dispersion** | float | [0..n] | Realistic values are between [0, 1], with the exception of Rutile, which has a value of 2.04
[Table [standardPropertiesTypes]: Range and type of the standard model's properties]
@@ -153,13 +155,14 @@ The type and range of each property is described in table [standardPropertiesTyp
as-is, which can lead to physically impossible materials, however, this might be desirable
for artistic reasons.
!!! Note: About `thickness` and `microThickness` for refraction
!!! Note: About `thickness`, `microThickness` and `dispersion` for refraction
`thickness` represents the thickness of solid objects in the direction of the normal, for
satisfactory results, this should be provided per fragment (e.g.: as a texture) or at least per
vertex. `microThickness` represent the thickness of the thin layer of an object, and can
generally be provided as a constant value. For example, a 1mm thin hollow sphere of radius 1m,
would have a `thickness` of 1 and a `microThickness` of 0.001. Currently `thickness` is not
used when `refractionType` is set to `thin`.
would have a `thickness` of 1 and a `microThickness` of 0.001. Dispersion controls the angular
separation of colors transmitting through a volume, and can be set by a constant value.
Currently `thickness` and `dispersion` are not used when `refractionType` is set to `thin`.
### Base color
@@ -651,6 +654,26 @@ the `refractionType` is set to `solid` and `absorption` coefficients are set.
![Figure [varyingThickness]: `thickness` varying from 0.0 at the top of the prism to 3.0 at the
bottom of the prism](images/material_thickness.png)
### Dispersion
The dispersion property controls the angular separation of colors transmitting through a relatively
clear volume. It can only be used when `refractionType` is set to `volume`.
Its value is specified as 20/Abbe number. When the value is zero, no dispersion is used.
Table [commonMatDispersion] describes acceptable dispersion values for various types of materials.
Material | Abbe Number (V) | Dispersion (20/V)
--------------------------:|:------------------:|:-----------------
Rutile | 9.8 | 2.04
Polycarbonate | 32 | 0.625
Diamond | 55 | 0.36
Water | 55 | 0.36
Crown Glass | 59 | 0.33
[Table [commonMatDispersion]: Dispersion of common materials]
![Figure [dispersionProperty]: `dispersion` varying from 0.0
(left) to 5.0 (right)](images/materials/dispersion.png)
## Subsurface model
### Thickness
@@ -2276,6 +2299,7 @@ struct MaterialInputs {
float3 absorption; // default float3(0.0, 0.0, 0.0)
float ior; // default: 1.5
float microThickness; // default: 0.0, not available with refractionType "solid"
float dispersion; // default: 0.0, not available with refractionType "thin"
}
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@@ -2456,9 +2480,9 @@ type aliases:
**uint2** | uvec2 | A vector of 2 unsigned integers
**uint3** | uvec3 | A vector of 3 unsigned integers
**uint4** | uvec4 | A vector of 4 unsigned integers
**float2** | float2 | A vector of 2 floats
**float3** | float3 | A vector of 3 floats
**float4** | float4 | A vector of 4 floats
**float2** | vec2 | A vector of 2 floats
**float3** | vec3 | A vector of 3 floats
**float4** | vec4 | A vector of 4 floats
**float4x4** | mat4 | A 4x4 float matrix
**float3x3** | mat3 | A 3x3 float matrix

View File

@@ -3,7 +3,7 @@
<head>
<!-- Book generated using mdBook -->
<meta charset="UTF-8">
<title>Build for Android on Windows - Filament</title>
<title>Android on Windows - Filament</title>
<!-- Custom HTML head -->
@@ -273,7 +273,7 @@ copy filament-android\build\outputs\aar\filament-android-release.aar ..\..\out\
<i class="fa fa-angle-left"></i>
</a>
<a rel="next prefetch" href="../build/maven_release.html" class="mobile-nav-chapters next" title="Next chapter" aria-label="Next chapter" aria-keyshortcuts="Right">
<a rel="next prefetch" href="../dup/contributing.html" class="mobile-nav-chapters next" title="Next chapter" aria-label="Next chapter" aria-keyshortcuts="Right">
<i class="fa fa-angle-right"></i>
</a>
@@ -287,7 +287,7 @@ copy filament-android\build\outputs\aar\filament-android-release.aar ..\..\out\
<i class="fa fa-angle-left"></i>
</a>
<a rel="next prefetch" href="../build/maven_release.html" class="nav-chapters next" title="Next chapter" aria-label="Next chapter" aria-keyshortcuts="Right">
<a rel="next prefetch" href="../dup/contributing.html" class="nav-chapters next" title="Next chapter" aria-label="Next chapter" aria-keyshortcuts="Right">
<i class="fa fa-angle-right"></i>
</a>
</nav>

255
docs/dup/backend_test.html Normal file
View File

@@ -0,0 +1,255 @@
<!DOCTYPE HTML>
<html lang="en" class="light sidebar-visible" dir="ltr">
<head>
<!-- Book generated using mdBook -->
<meta charset="UTF-8">
<title>backend - Filament</title>
<!-- Custom HTML head -->
<meta name="description" content="">
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta name="theme-color" content="#ffffff">
<link rel="shortcut icon" href="../favicon.png">
<link rel="stylesheet" href="../css/variables.css">
<link rel="stylesheet" href="../css/general.css">
<link rel="stylesheet" href="../css/chrome.css">
<!-- Fonts -->
<link rel="stylesheet" href="../FontAwesome/css/font-awesome.css">
<link rel="stylesheet" href="../fonts/fonts.css">
<!-- Highlight.js Stylesheets -->
<link rel="stylesheet" href="../highlight.css">
<link rel="stylesheet" href="../tomorrow-night.css">
<link rel="stylesheet" href="../ayu-highlight.css">
<!-- Custom theme stylesheets -->
<!-- MathJax -->
<script async src="https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.1/MathJax.js?config=TeX-AMS-MML_HTMLorMML"></script>
<!-- Provide site root to javascript -->
<script>
var path_to_root = "../";
var default_theme = window.matchMedia("(prefers-color-scheme: dark)").matches ? "light" : "light";
</script>
<!-- Start loading toc.js asap -->
<script src="../toc.js"></script>
</head>
<body>
<div id="body-container">
<!-- Work around some values being stored in localStorage wrapped in quotes -->
<script>
try {
var theme = localStorage.getItem('mdbook-theme');
var sidebar = localStorage.getItem('mdbook-sidebar');
if (theme.startsWith('"') && theme.endsWith('"')) {
localStorage.setItem('mdbook-theme', theme.slice(1, theme.length - 1));
}
if (sidebar.startsWith('"') && sidebar.endsWith('"')) {
localStorage.setItem('mdbook-sidebar', sidebar.slice(1, sidebar.length - 1));
}
} catch (e) { }
</script>
<!-- Set the theme before any content is loaded, prevents flash -->
<script>
var theme;
try { theme = localStorage.getItem('mdbook-theme'); } catch(e) { }
if (theme === null || theme === undefined) { theme = default_theme; }
const html = document.documentElement;
html.classList.remove('light')
html.classList.add(theme);
html.classList.add("js");
</script>
<input type="checkbox" id="sidebar-toggle-anchor" class="hidden">
<!-- Hide / unhide sidebar before it is displayed -->
<script>
var sidebar = null;
var sidebar_toggle = document.getElementById("sidebar-toggle-anchor");
if (document.body.clientWidth >= 1080) {
try { sidebar = localStorage.getItem('mdbook-sidebar'); } catch(e) { }
sidebar = sidebar || 'visible';
} else {
sidebar = 'hidden';
}
sidebar_toggle.checked = sidebar === 'visible';
html.classList.remove('sidebar-visible');
html.classList.add("sidebar-" + sidebar);
</script>
<nav id="sidebar" class="sidebar" aria-label="Table of contents">
<div style="display:flex;align-items:center;justify-content:center">
<img class="flogo" src="../images/filament_logo_small.png"></img>
</div>
<!-- populated by js -->
<mdbook-sidebar-scrollbox class="sidebar-scrollbox"></mdbook-sidebar-scrollbox>
<noscript>
<iframe class="sidebar-iframe-outer" src="../toc.html"></iframe>
</noscript>
<div id="sidebar-resize-handle" class="sidebar-resize-handle">
<div class="sidebar-resize-indicator"></div>
</div>
</nav>
<div id="page-wrapper" class="page-wrapper">
<div class="page">
<div id="menu-bar-hover-placeholder"></div>
<div id="menu-bar" class="menu-bar sticky">
<div class="left-buttons">
<label id="sidebar-toggle" class="icon-button" for="sidebar-toggle-anchor" title="Toggle Table of Contents" aria-label="Toggle Table of Contents" aria-controls="sidebar">
<i class="fa fa-bars"></i>
</label>
<!-- Filament: disable themes because the markdeep part does not look good for dark themes -->
<!--
<button id="theme-toggle" class="icon-button" type="button" title="Change theme" aria-label="Change theme" aria-haspopup="true" aria-expanded="false" aria-controls="theme-list">
<i class="fa fa-paint-brush"></i>
</button>
<ul id="theme-list" class="theme-popup" aria-label="Themes" role="menu">
<li role="none"><button role="menuitem" class="theme" id="light">Light</button></li>
<li role="none"><button role="menuitem" class="theme" id="rust">Rust</button></li>
<li role="none"><button role="menuitem" class="theme" id="coal">Coal</button></li>
<li role="none"><button role="menuitem" class="theme" id="navy">Navy</button></li>
<li role="none"><button role="menuitem" class="theme" id="ayu">Ayu</button></li>
</ul>
-->
<button id="search-toggle" class="icon-button" type="button" title="Search. (Shortkey: s)" aria-label="Toggle Searchbar" aria-expanded="false" aria-keyshortcuts="S" aria-controls="searchbar">
<i class="fa fa-search"></i>
</button>
</div>
<h1 class="menu-title">Filament</h1>
<div class="right-buttons">
<a href="https://github.com/google/filament" title="Git repository" aria-label="Git repository">
<i id="git-repository-button" class="fa fa-github"></i>
</a>
</div>
</div>
<div id="search-wrapper" class="hidden">
<form id="searchbar-outer" class="searchbar-outer">
<input type="search" id="searchbar" name="searchbar" placeholder="Search this book ..." aria-controls="searchresults-outer" aria-describedby="searchresults-header">
</form>
<div id="searchresults-outer" class="searchresults-outer hidden">
<div id="searchresults-header" class="searchresults-header"></div>
<ul id="searchresults">
</ul>
</div>
</div>
<!-- Apply ARIA attributes after the sidebar and the sidebar toggle button are added to the DOM -->
<script>
document.getElementById('sidebar-toggle').setAttribute('aria-expanded', sidebar === 'visible');
document.getElementById('sidebar').setAttribute('aria-hidden', sidebar !== 'visible');
Array.from(document.querySelectorAll('#sidebar a')).forEach(function(link) {
link.setAttribute('tabIndex', sidebar === 'visible' ? 0 : -1);
});
</script>
<div id="content" class="content">
<main>
<h1 id="backend-unit-tests"><a class="header" href="#backend-unit-tests">Backend Unit Tests</a></h1>
<p>These are tests that ensure the Filament backend is working properly on various operating systems
and graphics backends.</p>
<p>The majority of these tests generate images that are then compared against a known golden image.</p>
<h2 id="running-with-a-specific-graphics-library"><a class="header" href="#running-with-a-specific-graphics-library">Running with a specific graphics library</a></h2>
<p>Run with <code>-a&lt;backend&gt;</code> to run with a specific backend, such as <code>-avulkan</code> for vulkan or <code>-ametal</code>
for metal.</p>
<h2 id="image-comparisons"><a class="header" href="#image-comparisons">Image comparisons</a></h2>
<p>The expected images are stored as PNG files in the <code>expected_images</code> subdirectory of the test source
code. When cmake is run it will copy this directory to the build output creating
<code>images/expected_images</code> inside the same directory as the unit test binary.</p>
<p>The unit tests will then write their resulting images into <code>images/actual_images</code> in order to make
the tests easier to debug.</p>
<p>If an image comparison test fails, it writes a diff image to <code>images/diff_images</code> where each pixel of the diff is white (255,255,255) if the comparison for the corresponding pixel succeeds and black (0,0,0) of the comparison for the corresponding pixel fails.</p>
<h3 id="python-utility-for-updating-golden-images-and-comparing-results"><a class="header" href="#python-utility-for-updating-golden-images-and-comparing-results">Python utility for updating golden images and comparing results</a></h3>
<p>Inside the unit test source code directory there is a python script called
<code>move_actual_images_to_expected.py</code>.
It will display the actual and expected images side-by-side and copy the actual image into the
source tree's <code>expected_images</code> directory if the user approves the change.</p>
<h4 id="directories"><a class="header" href="#directories">Directories</a></h4>
<p>The <code>-r</code> flag is required and should be the directory where the test binary is.</p>
<p>If not running the script from the directory it's in, <code>-s</code> should be the source code's
<code>expected_images</code> directory.</p>
<h4 id="configuring-comparemove-behavior"><a class="header" href="#configuring-comparemove-behavior">Configuring compare/move behavior</a></h4>
<p>The <code>-c</code> flag has the tool display the actual and expected images side-by-side. By default it
does this by opening both with the OS's default behavior. <code>-p</code> can be used to specify a different
terminal program.</p>
<p>The <code>-m</code> flag has the tool move the actual image to overwrite the expected image in the source
tree. If the images are also being compared then the move will only happen if the user approves the
change.</p>
<p>After updating the expected images, cmake will need to be run again to copy them to the binary's
directory. Also, currently some platforms can't load images to compare and so have the hash
hardcoded into the test source code, so for now those need to be updated by running the test and
copying the value manually.</p>
<h4 id="picking-which-tests-to-compare"><a class="header" href="#picking-which-tests-to-compare">Picking which tests to compare</a></h4>
<p>The <code>-x</code> flag causes the tool to check the <code>test_detail.xml</code> file and only process the images who
failed a comparison. <code>--gtest_output=xml</code> needs to be passed to the test binary to generate this
file.</p>
<p>The <code>-t</code> argument takes a list of images to compare, provided as the file name without the <code>.png</code>
suffix.</p>
<h2 id="unsupported-tests"><a class="header" href="#unsupported-tests">Unsupported tests</a></h2>
<p>If a test depends on a feature that is unsupported by the current environment, it will start with
the <code>SKIP_IF</code> macro. This will cause the test to not be run.</p>
</main>
<nav class="nav-wrapper" aria-label="Page navigation">
<!-- Mobile navigation buttons -->
<a rel="prev" href="../notes/tests.html" class="mobile-nav-chapters previous" title="Previous chapter" aria-label="Previous chapter" aria-keyshortcuts="Left">
<i class="fa fa-angle-left"></i>
</a>
<a rel="next prefetch" href="../dup/test_ci_backend.html" class="mobile-nav-chapters next" title="Next chapter" aria-label="Next chapter" aria-keyshortcuts="Right">
<i class="fa fa-angle-right"></i>
</a>
<div style="clear: both"></div>
</nav>
</div>
</div>
<nav class="nav-wide-wrapper" aria-label="Page navigation">
<a rel="prev" href="../notes/tests.html" class="nav-chapters previous" title="Previous chapter" aria-label="Previous chapter" aria-keyshortcuts="Left">
<i class="fa fa-angle-left"></i>
</a>
<a rel="next prefetch" href="../dup/test_ci_backend.html" class="nav-chapters next" title="Next chapter" aria-label="Next chapter" aria-keyshortcuts="Right">
<i class="fa fa-angle-right"></i>
</a>
</nav>
</div>
<script>
window.playground_copyable = true;
</script>
<script src="../elasticlunr.min.js"></script>
<script src="../mark.min.js"></script>
<script src="../searcher.js"></script>
<script src="../clipboard.min.js"></script>
<script src="../highlight.js"></script>
<script src="../book.js"></script>
<!-- Custom JS scripts -->
</div>
</body>
</html>

View File

@@ -158,7 +158,8 @@
<div id="content" class="content">
<main>
<h2 id="updating-vulkan-headers"><a class="header" href="#updating-vulkan-headers">Updating Vulkan headers</a></h2>
<h1 id="bluevk"><a class="header" href="#bluevk">bluevk</a></h1>
<h2 id="updating-vulkan-headers"><a class="header" href="#updating-vulkan-headers">Updating Vulkan headers</a></h2>
<p>To update the Vulkan headers, perform the following steps.</p>
<p>First, find the latest version of the Vulkan headers here:
https://github.com/KhronosGroup/Vulkan-Headers/tags</p>

View File

@@ -158,8 +158,8 @@
<div id="content" class="content">
<main>
<h2 id="building-filament"><a class="header" href="#building-filament">Building Filament</a></h2>
<h3 id="prerequisites"><a class="header" href="#prerequisites">Prerequisites</a></h3>
<h1 id="building-filament"><a class="header" href="#building-filament">Building Filament</a></h1>
<h2 id="prerequisites"><a class="header" href="#prerequisites">Prerequisites</a></h2>
<p>To build Filament, you must first install the following tools:</p>
<ul>
<li>CMake 3.22.1 (or more recent)</li>
@@ -175,14 +175,14 @@ section below.</p>
<li>Android NDK 25.1 or higher</li>
<li>Java 17</li>
</ul>
<h3 id="environment-variables"><a class="header" href="#environment-variables">Environment variables</a></h3>
<h2 id="environment-variables"><a class="header" href="#environment-variables">Environment variables</a></h2>
<p>To build Filament for Android, make sure the environment variable <code>ANDROID_HOME</code> points to the
location of your Android SDK.</p>
<p>When building for WebGL, you'll also need to set <code>EMSDK</code>. See <a href="#webassembly">WebAssembly</a>.</p>
<h3 id="ide"><a class="header" href="#ide">IDE</a></h3>
<p>We recommend using CLion to develop for Filament. Simply open the root directory's CMakeLists.txt
in CLion to obtain a usable project.</p>
<h3 id="easy-build"><a class="header" href="#easy-build">Easy build</a></h3>
<h2 id="easy-build"><a class="header" href="#easy-build">Easy build</a></h2>
<p>Once the required OS specific dependencies listed below are installed, you can use the script
located in <code>build.sh</code> to build Filament easily on macOS and Linux.</p>
<p>This script can be invoked from anywhere and will produce build artifacts in the <code>out/</code> directory
@@ -206,7 +206,7 @@ The script offers more features described by executing <code>build.sh -h</code>.
<li><code>-t</code>: <a href="https://google.github.io/filament/dup/fgviewer.html"><code>fgviewer</code></a></li>
<li><code>-b</code> and <code>-y</code>: <a href="https://google.github.io/filament/notes/asan_ubsan.html">ASAN/UBSAN builds</a></li>
</ul>
<h3 id="filament-specific-cmake-options"><a class="header" href="#filament-specific-cmake-options">Filament-specific CMake Options</a></h3>
<h2 id="filament-specific-cmake-options"><a class="header" href="#filament-specific-cmake-options">Filament-specific CMake Options</a></h2>
<p>The following CMake options are boolean options specific to Filament:</p>
<ul>
<li><code>FILAMENT_ENABLE_LTO</code>: Enable link-time optimizations if supported by the compiler</li>
@@ -223,7 +223,7 @@ The script offers more features described by executing <code>build.sh -h</code>.
cmake . -DOPTION=ON # Replace OPTION with the option name, set to ON / OFF
</code></pre>
<p>Options can also be set with the CMake GUI.</p>
<h3 id="linux"><a class="header" href="#linux">Linux</a></h3>
<h2 id="linux"><a class="header" href="#linux">Linux</a></h2>
<p>Make sure you've installed the following dependencies:</p>
<ul>
<li><code>clang-16</code> or higher</li>
@@ -265,7 +265,7 @@ update-alternatives --install /usr/bin/c++ c++ /usr/bin/clang++ 100
<pre><code class="language-shell">ninja
</code></pre>
<p>This will build Filament, its tests and samples, and various host tools.</p>
<h3 id="macos"><a class="header" href="#macos">macOS</a></h3>
<h2 id="macos"><a class="header" href="#macos">macOS</a></h2>
<p>To compile Filament you must have the most recent version of Xcode installed and you need to
make sure the command line tools are setup by running:</p>
<pre><code class="language-shell">xcode-select --install
@@ -278,14 +278,14 @@ cd out/cmake-release
cmake -G Ninja -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=../release/filament ../..
ninja
</code></pre>
<h3 id="ios"><a class="header" href="#ios">iOS</a></h3>
<h2 id="ios"><a class="header" href="#ios">iOS</a></h2>
<p>The easiest way to build Filament for iOS is to use <code>build.sh</code> and the
<code>-p ios</code> flag. For instance to build the debug target:</p>
<pre><code class="language-shell">./build.sh -p ios debug
</code></pre>
<p>See <a href="./ios/samples/README.html">ios/samples/README.md</a> for more information.</p>
<h3 id="windows"><a class="header" href="#windows">Windows</a></h3>
<h4 id="building-on-windows-with-visual-studio-2019-or-later"><a class="header" href="#building-on-windows-with-visual-studio-2019-or-later">Building on Windows with Visual Studio 2019 or later</a></h4>
<h2 id="windows"><a class="header" href="#windows">Windows</a></h2>
<h3 id="building-on-windows-with-visual-studio-2019-or-later"><a class="header" href="#building-on-windows-with-visual-studio-2019-or-later">Building on Windows with Visual Studio 2019 or later</a></h3>
<p>Install the following components:</p>
<ul>
<li><a href="https://www.visualstudio.com/downloads">Visual Studio 2019 or later</a></li>
@@ -314,7 +314,7 @@ target in the <em>Solution Explorer</em> and choose <em>Build</em> to build a sp
<code>out</code> folder run the following command.</p>
<pre><code class="language-bat">cmake --build . --target gltf_viewer --config Release
</code></pre>
<h3 id="android"><a class="header" href="#android">Android</a></h3>
<h2 id="android"><a class="header" href="#android">Android</a></h2>
<p>Before building Filament for Android, make sure to build Filament for your host. Some of the
host tools are required to successfully build for Android.</p>
<p>Filament can be built for the following architectures:</p>
@@ -327,13 +327,42 @@ host tools are required to successfully build for Android.</p>
<p>Note that the main target is the ARM 64-bit target. Our implementation is optimized first and
foremost for <code>arm64-v8a</code>.</p>
<p>To build Android on Windows machines, see <a href="android/Windows.html">android/Windows.md</a>.</p>
<h4 id="easy-android-build"><a class="header" href="#easy-android-build">Easy Android build</a></h4>
<h3 id="important-sdk-location"><a class="header" href="#important-sdk-location">Important: SDK location</a></h3>
<p>Either ensure your <code>ANDROID_HOME</code> environment variable is set or make sure the root project
contains a <code>local.properties</code> file with the <code>sdk.dir</code> property pointing to your installation of
the Android SDK.</p>
<h3 id="easy-android-build"><a class="header" href="#easy-android-build">Easy Android build</a></h3>
<p>The easiest way to build Filament for Android is to use <code>build.sh</code> and the
<code>-p android</code> flag. For instance to build the release target:</p>
<pre><code class="language-shell">./build.sh -p android release
</code></pre>
<p>To build a sample (such as <code>android/samples/sample-hello-triangle</code>) for an ARM 64-bit phone, you would run</p>
<pre><code class="language-shell">./build.sh -p android -q arm64-v8a -k sample-hello-triangle release
</code></pre>
<p>The output APK can be found in <code>android/samples/sample-hello-triangle/build/outputs/apk/release/sample-hello-triangle-release-unsigned.apk</code></p>
<p>Run <code>build.sh -h</code> for more information.</p>
<h4 id="manual-builds"><a class="header" href="#manual-builds">Manual builds</a></h4>
<h3 id="android-studio"><a class="header" href="#android-studio">Android Studio</a></h3>
<p>You must use the latest stable release of Android Studio.</p>
<p>The Android build of filament is separated into java/kotlin client APIs, a layer of jni bindings
that bridges java/kotlin with native code, and Filament and other component code that have been compiled
into architecture-specific libraries. Our default Android Studio gradle setup can compile java/kotlin and
the jni bindings for you, but it will treat the filament libraries as already compiled and present on
the system.</p>
<p>Therefore, before compiling the sample app or any other targets, you must
make sure that the native filament libraries have been compiled and are located at a prescribed location
so that the jni bindings can link against them. You can do so by using the easy build script</p>
<pre><code class="language-shell">./build.sh -p android release -q arm64-v8a
</code></pre>
<p>Note that the above step will also install host machine tools into prescribed locations. These tools are
required for compiling Filament assets such as materials and environment maps.</p>
<p>Now we are ready to compile the apps. To open the project, point Studio to the <code>android</code> folder.
After opening the project and syncing with Gradle, select the sample of your choice
using the drop-down widget in the toolbar. Additionally, you will need to select a deployment target.
By doing so, Android Studio will automatically try to compile the app only for that specific
device's architecture. So if you are targeting a new Pixel phone, make sure that the step above
(compiling the library) is targeting ARM 64-bit (<code>-q arm64-v8a</code> ), and if you are running the app on
an emulator on a Linux machine with an x86 64-bit chipset, you would indicate (<code>-q x86_64</code>) in the above step.</p>
<h3 id="manual-builds"><a class="header" href="#manual-builds">Manual builds</a></h3>
<p>Invoke CMake in a build directory of your choice, inside of filament's directory. The commands
below show how to build Filament for ARM 64-bit (<code>aarch64</code>).</p>
<pre><code class="language-shell">mkdir out/android-build-release-aarch64
@@ -350,7 +379,7 @@ cmake -G Ninja -DCMAKE_TOOLCHAIN_FILE=../../build/toolchain-aarch64-linux-androi
<p>This will generate Filament's Android binaries in <code>out/android-release</code>. This location is important
to build the Android Studio projects located in <code>filament/android</code>. After install, the library
binaries should be found in <code>out/android-release/filament/lib/arm64-v8a</code>.</p>
<h4 id="aar"><a class="header" href="#aar">AAR</a></h4>
<h3 id="aar"><a class="header" href="#aar">AAR</a></h3>
<p>Before you attempt to build the AAR, make sure you've compiled and installed the native libraries
as explained in the sections above. You must have the following ABIs built in
<code>out/android-release/filament/lib/</code>:</p>
@@ -376,7 +405,7 @@ AAR.</p>
</code></pre>
<p>The <code>-Pcom.google.android.filament.dist-dir</code> can be used to specify a different installation
directory (it must match the CMake install prefix used in the previous steps).</p>
<h4 id="using-filaments-aar"><a class="header" href="#using-filaments-aar">Using Filament's AAR</a></h4>
<h3 id="using-filaments-aar"><a class="header" href="#using-filaments-aar">Using Filament's AAR</a></h3>
<p>Create a new module in your project and select <em>Import .JAR or .AAR Package</em> when prompted. Make
sure to add the newly created module as a dependency to your application.</p>
<p>If you do not wish to include all supported ABIs, make sure to create the appropriate flavors in
@@ -412,7 +441,7 @@ productFlavors {
}
}
</code></pre>
<h3 id="webassembly"><a class="header" href="#webassembly">WebAssembly</a></h3>
<h2 id="webassembly"><a class="header" href="#webassembly">WebAssembly</a></h2>
<p>The core Filament library can be cross-compiled to WebAssembly from either macOS or Linux. To get
started, follow the instructions for building Filament on your platform (<a href="#macos">macOS</a> or
<a href="#linux">linux</a>), which will ensure you have the proper dependencies installed.</p>

View File

@@ -209,7 +209,7 @@ as possible. The current external dependencies of the runtime library include:</
<nav class="nav-wrapper" aria-label="Page navigation">
<!-- Mobile navigation buttons -->
<a rel="prev" href="../build/maven_release.html" class="mobile-nav-chapters previous" title="Previous chapter" aria-label="Previous chapter" aria-keyshortcuts="Left">
<a rel="prev" href="../build/windows_android.html" class="mobile-nav-chapters previous" title="Previous chapter" aria-label="Previous chapter" aria-keyshortcuts="Left">
<i class="fa fa-angle-left"></i>
</a>
@@ -223,7 +223,7 @@ as possible. The current external dependencies of the runtime library include:</
</div>
<nav class="nav-wide-wrapper" aria-label="Page navigation">
<a rel="prev" href="../build/maven_release.html" class="nav-chapters previous" title="Previous chapter" aria-label="Previous chapter" aria-keyshortcuts="Left">
<a rel="prev" href="../build/windows_android.html" class="nav-chapters previous" title="Previous chapter" aria-label="Previous chapter" aria-keyshortcuts="Left">
<i class="fa fa-angle-left"></i>
</a>

View File

@@ -203,7 +203,7 @@ tree into <code>docs_src/src_mdbook/src/dup</code>. Moreover, to restore valid l
to perform a number of URL replacements in addition to the copy. These replacements are
described in <a href="https://github.com/google/filament/blob/main/docs_src/build/duplicates.json"><code>docs_src/build/duplicates.json</code></a>.</p>
<h3 id="core-concept-docs"><a class="header" href="#core-concept-docs">Core concept docs</a></h3>
<p>The primary design of Filament as a phyiscally-based renderer and details of its materials
<p>The primary design of Filament as a physically-based renderer and details of its materials
system are described in <code>Filament.md.html</code> and <code>Materials.md.html</code>, respectively. These two
documents are written in <a href="https://casual-effects.com/markdeep/"><code>markdeep</code></a>. To embed them into our book, we</p>
<ol>
@@ -253,7 +253,7 @@ add a link in <code>SUMMARY.md</code>, and perform the steps outlined in
<nav class="nav-wrapper" aria-label="Page navigation">
<!-- Mobile navigation buttons -->
<a rel="prev" href="../notes/release_guide.html" class="mobile-nav-chapters previous" title="Previous chapter" aria-label="Previous chapter" aria-keyshortcuts="Left">
<a rel="prev" href="../release/branching.html" class="mobile-nav-chapters previous" title="Previous chapter" aria-label="Previous chapter" aria-keyshortcuts="Left">
<i class="fa fa-angle-left"></i>
</a>
@@ -267,7 +267,7 @@ add a link in <code>SUMMARY.md</code>, and perform the steps outlined in
</div>
<nav class="nav-wide-wrapper" aria-label="Page navigation">
<a rel="prev" href="../notes/release_guide.html" class="nav-chapters previous" title="Previous chapter" aria-label="Previous chapter" aria-keyshortcuts="Left">
<a rel="prev" href="../release/branching.html" class="nav-chapters previous" title="Previous chapter" aria-label="Previous chapter" aria-keyshortcuts="Left">
<i class="fa fa-angle-left"></i>
</a>

View File

@@ -158,7 +158,7 @@
<div id="content" class="content">
<main>
<h1 id="filamesh"><a class="header" href="#filamesh">Filamesh</a></h1>
<h1 id="filamesh"><a class="header" href="#filamesh">filamesh</a></h1>
<p><code>filamesh</code> converts any mesh file supported by <code>assimp</code> (as configured in this source tree) into a
custom binary file format. The goal of this binary file format is to allow test applications to
easily and quickly load meshes.</p>
@@ -419,7 +419,7 @@ Mesh loadMeshFromFile(filament::Engine* engine, const utils::Path&amp; path,
<i class="fa fa-angle-left"></i>
</a>
<a rel="next prefetch" href="../dup/normal_blending.html" class="mobile-nav-chapters next" title="Next chapter" aria-label="Next chapter" aria-keyshortcuts="Right">
<a rel="next prefetch" href="../dup/matinfo.html" class="mobile-nav-chapters next" title="Next chapter" aria-label="Next chapter" aria-keyshortcuts="Right">
<i class="fa fa-angle-right"></i>
</a>
@@ -433,7 +433,7 @@ Mesh loadMeshFromFile(filament::Engine* engine, const utils::Path&amp; path,
<i class="fa fa-angle-left"></i>
</a>
<a rel="next prefetch" href="../dup/normal_blending.html" class="nav-chapters next" title="Next chapter" aria-label="Next chapter" aria-keyshortcuts="Right">
<a rel="next prefetch" href="../dup/matinfo.html" class="nav-chapters next" title="Next chapter" aria-label="Next chapter" aria-keyshortcuts="Right">
<i class="fa fa-angle-right"></i>
</a>
</nav>

View File

@@ -158,7 +158,7 @@
<div id="content" class="content">
<main>
<h1 id="description"><a class="header" href="#description">Description</a></h1>
<h1 id="gltfio"><a class="header" href="#gltfio">gltfio</a></h1>
<p><code>gltfio</code> is a loader library that consumes <code>gltf</code> or <code>glb</code> content and produces Filament
objects. For usage details, see the docstring for <code>AssetLoader</code>.</p>
<p>gltfio has two plug-in interfaces, <code>TextureProvider</code> and <code>MaterialProvider</code>. Filament ships with

View File

@@ -181,7 +181,7 @@ important for <code>matc</code> (material compiler).</p>
}
dependencies {
implementation 'com.google.android.filament:filament-android:1.67.1'
implementation 'com.google.android.filament:filament-android:1.68.5'
}
</code></pre>
<p>Here are all the libraries available in the group <code>com.google.android.filament</code>:</p>
@@ -196,7 +196,7 @@ dependencies {
</div>
<h3 id="ios"><a class="header" href="#ios">iOS</a></h3>
<p>iOS projects can use CocoaPods to install the latest release:</p>
<pre><code class="language-shell">pod 'Filament', '~&gt; 1.67.1'
<pre><code class="language-shell">pod 'Filament', '~&gt; 1.68.5'
</code></pre>
<h2 id="documentation"><a class="header" href="#documentation">Documentation</a></h2>
<ul>

View File

@@ -352,7 +352,7 @@ used to create the SPIR-V is not available.</p>
<i class="fa fa-angle-left"></i>
</a>
<a rel="next prefetch" href="../dup/uberz.html" class="mobile-nav-chapters next" title="Next chapter" aria-label="Next chapter" aria-keyshortcuts="Right">
<a rel="next prefetch" href="../dup/viewer.html" class="mobile-nav-chapters next" title="Next chapter" aria-label="Next chapter" aria-keyshortcuts="Right">
<i class="fa fa-angle-right"></i>
</a>
@@ -366,7 +366,7 @@ used to create the SPIR-V is not available.</p>
<i class="fa fa-angle-left"></i>
</a>
<a rel="next prefetch" href="../dup/uberz.html" class="nav-chapters next" title="Next chapter" aria-label="Next chapter" aria-keyshortcuts="Right">
<a rel="next prefetch" href="../dup/viewer.html" class="nav-chapters next" title="Next chapter" aria-label="Next chapter" aria-keyshortcuts="Right">
<i class="fa fa-angle-right"></i>
</a>
</nav>

View File

@@ -158,7 +158,7 @@
<div id="content" class="content">
<main>
<h1 id="matinfo"><a class="header" href="#matinfo">Matinfo</a></h1>
<h1 id="matinfo"><a class="header" href="#matinfo">matinfo</a></h1>
<p><code>matinfo</code> lists the content of a compiled material as output by <code>matc</code>. This tool is meant to be
used for debug purpose only.</p>
<h2 id="usage"><a class="header" href="#usage">Usage</a></h2>
@@ -169,11 +169,11 @@ used for debug purpose only.</p>
<nav class="nav-wrapper" aria-label="Page navigation">
<!-- Mobile navigation buttons -->
<a rel="prev" href="../dup/mipgen.html" class="mobile-nav-chapters previous" title="Previous chapter" aria-label="Previous chapter" aria-keyshortcuts="Left">
<a rel="prev" href="../dup/filamesh.html" class="mobile-nav-chapters previous" title="Previous chapter" aria-label="Previous chapter" aria-keyshortcuts="Left">
<i class="fa fa-angle-left"></i>
</a>
<a rel="next prefetch" href="../dup/roughness_prefilter.html" class="mobile-nav-chapters next" title="Next chapter" aria-label="Next chapter" aria-keyshortcuts="Right">
<a rel="next prefetch" href="../dup/mipgen.html" class="mobile-nav-chapters next" title="Next chapter" aria-label="Next chapter" aria-keyshortcuts="Right">
<i class="fa fa-angle-right"></i>
</a>
@@ -183,11 +183,11 @@ used for debug purpose only.</p>
</div>
<nav class="nav-wide-wrapper" aria-label="Page navigation">
<a rel="prev" href="../dup/mipgen.html" class="nav-chapters previous" title="Previous chapter" aria-label="Previous chapter" aria-keyshortcuts="Left">
<a rel="prev" href="../dup/filamesh.html" class="nav-chapters previous" title="Previous chapter" aria-label="Previous chapter" aria-keyshortcuts="Left">
<i class="fa fa-angle-left"></i>
</a>
<a rel="next prefetch" href="../dup/roughness_prefilter.html" class="nav-chapters next" title="Next chapter" aria-label="Next chapter" aria-keyshortcuts="Right">
<a rel="next prefetch" href="../dup/mipgen.html" class="nav-chapters next" title="Next chapter" aria-label="Next chapter" aria-keyshortcuts="Right">
<i class="fa fa-angle-right"></i>
</a>
</nav>

View File

@@ -169,11 +169,11 @@
<nav class="nav-wrapper" aria-label="Page navigation">
<!-- Mobile navigation buttons -->
<a rel="prev" href="../dup/normal_blending.html" class="mobile-nav-chapters previous" title="Previous chapter" aria-label="Previous chapter" aria-keyshortcuts="Left">
<a rel="prev" href="../dup/matinfo.html" class="mobile-nav-chapters previous" title="Previous chapter" aria-label="Previous chapter" aria-keyshortcuts="Left">
<i class="fa fa-angle-left"></i>
</a>
<a rel="next prefetch" href="../dup/matinfo.html" class="mobile-nav-chapters next" title="Next chapter" aria-label="Next chapter" aria-keyshortcuts="Right">
<a rel="next prefetch" href="../dup/normal_blending.html" class="mobile-nav-chapters next" title="Next chapter" aria-label="Next chapter" aria-keyshortcuts="Right">
<i class="fa fa-angle-right"></i>
</a>
@@ -183,11 +183,11 @@
</div>
<nav class="nav-wide-wrapper" aria-label="Page navigation">
<a rel="prev" href="../dup/normal_blending.html" class="nav-chapters previous" title="Previous chapter" aria-label="Previous chapter" aria-keyshortcuts="Left">
<a rel="prev" href="../dup/matinfo.html" class="nav-chapters previous" title="Previous chapter" aria-label="Previous chapter" aria-keyshortcuts="Left">
<i class="fa fa-angle-left"></i>
</a>
<a rel="next prefetch" href="../dup/matinfo.html" class="nav-chapters next" title="Next chapter" aria-label="Next chapter" aria-keyshortcuts="Right">
<a rel="next prefetch" href="../dup/normal_blending.html" class="nav-chapters next" title="Next chapter" aria-label="Next chapter" aria-keyshortcuts="Right">
<i class="fa fa-angle-right"></i>
</a>
</nav>

View File

@@ -167,11 +167,11 @@ correct results (as opposed to common techniques such as linear or overlay blend
<nav class="nav-wrapper" aria-label="Page navigation">
<!-- Mobile navigation buttons -->
<a rel="prev" href="../dup/filamesh.html" class="mobile-nav-chapters previous" title="Previous chapter" aria-label="Previous chapter" aria-keyshortcuts="Left">
<a rel="prev" href="../dup/mipgen.html" class="mobile-nav-chapters previous" title="Previous chapter" aria-label="Previous chapter" aria-keyshortcuts="Left">
<i class="fa fa-angle-left"></i>
</a>
<a rel="next prefetch" href="../dup/mipgen.html" class="mobile-nav-chapters next" title="Next chapter" aria-label="Next chapter" aria-keyshortcuts="Right">
<a rel="next prefetch" href="../dup/roughness_prefilter.html" class="mobile-nav-chapters next" title="Next chapter" aria-label="Next chapter" aria-keyshortcuts="Right">
<i class="fa fa-angle-right"></i>
</a>
@@ -181,11 +181,11 @@ correct results (as opposed to common techniques such as linear or overlay blend
</div>
<nav class="nav-wide-wrapper" aria-label="Page navigation">
<a rel="prev" href="../dup/filamesh.html" class="nav-chapters previous" title="Previous chapter" aria-label="Previous chapter" aria-keyshortcuts="Left">
<a rel="prev" href="../dup/mipgen.html" class="nav-chapters previous" title="Previous chapter" aria-label="Previous chapter" aria-keyshortcuts="Left">
<i class="fa fa-angle-left"></i>
</a>
<a rel="next prefetch" href="../dup/mipgen.html" class="nav-chapters next" title="Next chapter" aria-label="Next chapter" aria-keyshortcuts="Right">
<a rel="next prefetch" href="../dup/roughness_prefilter.html" class="nav-chapters next" title="Next chapter" aria-label="Next chapter" aria-keyshortcuts="Right">
<i class="fa fa-angle-right"></i>
</a>
</nav>

View File

@@ -167,11 +167,11 @@ be used to reduce shading aliasing.</p>
<nav class="nav-wrapper" aria-label="Page navigation">
<!-- Mobile navigation buttons -->
<a rel="prev" href="../dup/matinfo.html" class="mobile-nav-chapters previous" title="Previous chapter" aria-label="Previous chapter" aria-keyshortcuts="Left">
<a rel="prev" href="../dup/normal_blending.html" class="mobile-nav-chapters previous" title="Previous chapter" aria-label="Previous chapter" aria-keyshortcuts="Left">
<i class="fa fa-angle-left"></i>
</a>
<a rel="next prefetch" href="../dup/specular_color.html" class="mobile-nav-chapters next" title="Next chapter" aria-label="Next chapter" aria-keyshortcuts="Right">
<a rel="next prefetch" href="../dup/specgen.html" class="mobile-nav-chapters next" title="Next chapter" aria-label="Next chapter" aria-keyshortcuts="Right">
<i class="fa fa-angle-right"></i>
</a>
@@ -181,11 +181,11 @@ be used to reduce shading aliasing.</p>
</div>
<nav class="nav-wide-wrapper" aria-label="Page navigation">
<a rel="prev" href="../dup/matinfo.html" class="nav-chapters previous" title="Previous chapter" aria-label="Previous chapter" aria-keyshortcuts="Left">
<a rel="prev" href="../dup/normal_blending.html" class="nav-chapters previous" title="Previous chapter" aria-label="Previous chapter" aria-keyshortcuts="Left">
<i class="fa fa-angle-left"></i>
</a>
<a rel="next prefetch" href="../dup/specular_color.html" class="nav-chapters next" title="Next chapter" aria-label="Next chapter" aria-keyshortcuts="Right">
<a rel="next prefetch" href="../dup/specgen.html" class="nav-chapters next" title="Next chapter" aria-label="Next chapter" aria-keyshortcuts="Right">
<i class="fa fa-angle-right"></i>
</a>
</nav>

265
docs/dup/specgen.html Normal file
View File

@@ -0,0 +1,265 @@
<!DOCTYPE HTML>
<html lang="en" class="light sidebar-visible" dir="ltr">
<head>
<!-- Book generated using mdBook -->
<meta charset="UTF-8">
<title>specgen - Filament</title>
<!-- Custom HTML head -->
<meta name="description" content="">
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta name="theme-color" content="#ffffff">
<link rel="shortcut icon" href="../favicon.png">
<link rel="stylesheet" href="../css/variables.css">
<link rel="stylesheet" href="../css/general.css">
<link rel="stylesheet" href="../css/chrome.css">
<!-- Fonts -->
<link rel="stylesheet" href="../FontAwesome/css/font-awesome.css">
<link rel="stylesheet" href="../fonts/fonts.css">
<!-- Highlight.js Stylesheets -->
<link rel="stylesheet" href="../highlight.css">
<link rel="stylesheet" href="../tomorrow-night.css">
<link rel="stylesheet" href="../ayu-highlight.css">
<!-- Custom theme stylesheets -->
<!-- MathJax -->
<script async src="https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.1/MathJax.js?config=TeX-AMS-MML_HTMLorMML"></script>
<!-- Provide site root to javascript -->
<script>
var path_to_root = "../";
var default_theme = window.matchMedia("(prefers-color-scheme: dark)").matches ? "light" : "light";
</script>
<!-- Start loading toc.js asap -->
<script src="../toc.js"></script>
</head>
<body>
<div id="body-container">
<!-- Work around some values being stored in localStorage wrapped in quotes -->
<script>
try {
var theme = localStorage.getItem('mdbook-theme');
var sidebar = localStorage.getItem('mdbook-sidebar');
if (theme.startsWith('"') && theme.endsWith('"')) {
localStorage.setItem('mdbook-theme', theme.slice(1, theme.length - 1));
}
if (sidebar.startsWith('"') && sidebar.endsWith('"')) {
localStorage.setItem('mdbook-sidebar', sidebar.slice(1, sidebar.length - 1));
}
} catch (e) { }
</script>
<!-- Set the theme before any content is loaded, prevents flash -->
<script>
var theme;
try { theme = localStorage.getItem('mdbook-theme'); } catch(e) { }
if (theme === null || theme === undefined) { theme = default_theme; }
const html = document.documentElement;
html.classList.remove('light')
html.classList.add(theme);
html.classList.add("js");
</script>
<input type="checkbox" id="sidebar-toggle-anchor" class="hidden">
<!-- Hide / unhide sidebar before it is displayed -->
<script>
var sidebar = null;
var sidebar_toggle = document.getElementById("sidebar-toggle-anchor");
if (document.body.clientWidth >= 1080) {
try { sidebar = localStorage.getItem('mdbook-sidebar'); } catch(e) { }
sidebar = sidebar || 'visible';
} else {
sidebar = 'hidden';
}
sidebar_toggle.checked = sidebar === 'visible';
html.classList.remove('sidebar-visible');
html.classList.add("sidebar-" + sidebar);
</script>
<nav id="sidebar" class="sidebar" aria-label="Table of contents">
<div style="display:flex;align-items:center;justify-content:center">
<img class="flogo" src="../images/filament_logo_small.png"></img>
</div>
<!-- populated by js -->
<mdbook-sidebar-scrollbox class="sidebar-scrollbox"></mdbook-sidebar-scrollbox>
<noscript>
<iframe class="sidebar-iframe-outer" src="../toc.html"></iframe>
</noscript>
<div id="sidebar-resize-handle" class="sidebar-resize-handle">
<div class="sidebar-resize-indicator"></div>
</div>
</nav>
<div id="page-wrapper" class="page-wrapper">
<div class="page">
<div id="menu-bar-hover-placeholder"></div>
<div id="menu-bar" class="menu-bar sticky">
<div class="left-buttons">
<label id="sidebar-toggle" class="icon-button" for="sidebar-toggle-anchor" title="Toggle Table of Contents" aria-label="Toggle Table of Contents" aria-controls="sidebar">
<i class="fa fa-bars"></i>
</label>
<!-- Filament: disable themes because the markdeep part does not look good for dark themes -->
<!--
<button id="theme-toggle" class="icon-button" type="button" title="Change theme" aria-label="Change theme" aria-haspopup="true" aria-expanded="false" aria-controls="theme-list">
<i class="fa fa-paint-brush"></i>
</button>
<ul id="theme-list" class="theme-popup" aria-label="Themes" role="menu">
<li role="none"><button role="menuitem" class="theme" id="light">Light</button></li>
<li role="none"><button role="menuitem" class="theme" id="rust">Rust</button></li>
<li role="none"><button role="menuitem" class="theme" id="coal">Coal</button></li>
<li role="none"><button role="menuitem" class="theme" id="navy">Navy</button></li>
<li role="none"><button role="menuitem" class="theme" id="ayu">Ayu</button></li>
</ul>
-->
<button id="search-toggle" class="icon-button" type="button" title="Search. (Shortkey: s)" aria-label="Toggle Searchbar" aria-expanded="false" aria-keyshortcuts="S" aria-controls="searchbar">
<i class="fa fa-search"></i>
</button>
</div>
<h1 class="menu-title">Filament</h1>
<div class="right-buttons">
<a href="https://github.com/google/filament" title="Git repository" aria-label="Git repository">
<i id="git-repository-button" class="fa fa-github"></i>
</a>
</div>
</div>
<div id="search-wrapper" class="hidden">
<form id="searchbar-outer" class="searchbar-outer">
<input type="search" id="searchbar" name="searchbar" placeholder="Search this book ..." aria-controls="searchresults-outer" aria-describedby="searchresults-header">
</form>
<div id="searchresults-outer" class="searchresults-outer hidden">
<div id="searchresults-header" class="searchresults-header"></div>
<ul id="searchresults">
</ul>
</div>
</div>
<!-- Apply ARIA attributes after the sidebar and the sidebar toggle button are added to the DOM -->
<script>
document.getElementById('sidebar-toggle').setAttribute('aria-expanded', sidebar === 'visible');
document.getElementById('sidebar').setAttribute('aria-hidden', sidebar !== 'visible');
Array.from(document.querySelectorAll('#sidebar a')).forEach(function(link) {
link.setAttribute('tabIndex', sidebar === 'visible' ? 0 : -1);
});
</script>
<div id="content" class="content">
<main>
<h1 id="specgen-spectral-integration-matrix-generator-for-real-time-dispersion"><a class="header" href="#specgen-spectral-integration-matrix-generator-for-real-time-dispersion">SPECGEN: Spectral Integration Matrix Generator for Real-Time Dispersion</a></h1>
<h2 id="theoretical-background"><a class="header" href="#theoretical-background">Theoretical Background</a></h2>
<h3 id="1-spectral-rendering-in-rgb"><a class="header" href="#1-spectral-rendering-in-rgb">1. Spectral Rendering in RGB</a></h3>
<p>Real-time rendering typically operates in a tristimulus color space (like sRGB). However, physical phenomena like dispersion (refraction splitting light by wavelength) are inherently spectral. To simulate this in an RGB pipeline, we approximate the continuous spectral integration using a finite sum of weighted samples.</p>
<p>The fundamental equation for perceived color \(C\) is:</p>
<p>$$ C = \int L(\lambda) \cdot r(\lambda) d\lambda $$</p>
<p>where:</p>
<ul>
<li>\(L(\lambda)\) is the spectral radiance reaching the eye.</li>
<li>\(r(\lambda)\) is the sensor response function (e.g., CIE 1931 \(\bar{x}, \bar{y}, \bar{z}\) matching functions).</li>
</ul>
<h3 id="2-basis-transformation-strategy"><a class="header" href="#2-basis-transformation-strategy">2. Basis Transformation Strategy</a></h3>
<p>We assume the input light is defined in linear sRGB. To process it spectrally:</p>
<ol>
<li>Convert sRGB to CIE XYZ (D65 white point).</li>
<li>Assume the spectral distribution of the light is a sum of impulses or narrow bands weighted by the XYZ components (or simplified directly from sRGB).</li>
<li>Apply spectral effects (like wavelength-dependent refraction).</li>
<li>Integrate back to XYZ using the CIE Color Matching Functions (CMFs).</li>
<li>Convert final XYZ back to sRGB.</li>
</ol>
<p>This tool pre-calculates a set of matrices (\(K_n\)) that combine these steps. For a set of \(N\) sample wavelengths \({ \lambda_0, \dots, \lambda_{N-1} }\), the final color is:</p>
<p>$$ C_{final} = \sum_{n=0}^{N-1} (K_n \cdot C_{input}) $$</p>
<p>Each matrix \(K_n\) represents the contribution of the \(n\)-th spectral sample to the final image, accounting for the conversion to/from XYZ and the spectral weight of that sample.</p>
<p><strong>Derivation of \(K_n\):</strong></p>
<p>$$ K_n = M_{XYZ \to sRGB} \cdot \text{Diag}(W_n) \cdot M_{sRGB \to XYZ} $$</p>
<p>where \(W_n\) is the "spectral weight" vector \((x, y, z)\) for wavelength \(\lambda_n\):</p>
<p>$$ W_n = \text{CMF}(\lambda_n) \cdot \text{weight}_n $$</p>
<h3 id="3-normalization-energy-conservation"><a class="header" href="#3-normalization-energy-conservation">3. Normalization (Energy Conservation)</a></h3>
<p>To ensure that a white input \((1, 1, 1)\) results in a white output \((1, 1, 1)\) when no dispersion occurs (i.e., all samples land on the same pixel), we must normalize the weights.</p>
<p>We require: \(\sum K_n = I\)</p>
<p>This implies:</p>
<p>$$ \sum ( M_{XYZ \to sRGB} \cdot \text{Diag}(W_n) \cdot M_{sRGB \to XYZ} ) = I $$
$$ M_{XYZ \to sRGB} \cdot \sum \text{Diag}(W_n) \cdot M_{sRGB \to XYZ} = I $$
$$ \sum \text{Diag}(W_n) = M_{sRGB \to XYZ} \cdot I \cdot M_{XYZ \to sRGB} $$
$$ \sum \text{Diag}(W_n) = I $$
<em>(since \(M \cdot M^{-1} = I\))</em></p>
<p>Therefore, we normalize \(W_n\) such that:</p>
<p>$$ \sum W_{n,x} = 1.0, \quad \sum W_{n,y} = 1.0, \quad \sum W_{n,z} = 1.0 $$</p>
<p><strong>Note:</strong> We do <strong>NOT</strong> normalize to the D65 white point \((0.95047, 1.0, 1.08883)\). The \(M_{sRGB \to XYZ}\) matrix already handles the conversion from linear sRGB \((1, 1, 1)\) to D65 XYZ. If we normalized \(W_n\) to D65, we would effectively be applying the white point twice, resulting in a tinted image. By normalizing \(\sum W_n\) to \((1, 1, 1)\), we ensure that the energy is conserved through the spectral transformation pipeline.</p>
<p>In practice, we calculate the raw sum of \(W_n\) from the quadrature weights and CMFs, then compute a correction factor:</p>
<p>$$ \text{Correction} = \frac{1.0}{\sum W_{n,raw}} $$
$$ W_{n,final} = W_{n,raw} \cdot \text{Correction} $$</p>
<h3 id="4-dispersion-and-ior-offsets"><a class="header" href="#4-dispersion-and-ior-offsets">4. Dispersion and IOR Offsets</a></h3>
<p>The Index of Refraction (IOR) varies with wavelength. We use the Abbe number (\(V_d\)) to parameterize this variation relative to a base IOR (\(n_D\)) at 589.3nm.</p>
<p><strong>Cauchy Dispersion Model:</strong></p>
<p>$$ n(\lambda) = A + \frac{B}{\lambda^2} $$</p>
<p>Using the definition of Abbe number \(V_d = \frac{n_D - 1}{n_F - n_C}\), we can derive:</p>
<p>$$ n(\lambda) = n_D + \frac{n_D - 1}{V_d} \cdot \text{Offset}(\lambda) $$</p>
<p>Where \(\text{Offset}(\lambda)\) is pre-calculated by this tool:</p>
<p>$$ \text{Offset}(\lambda) = \frac{ \frac{1}{\lambda^2} - \frac{1}{\lambda_D^2} }{ \frac{1}{\lambda_F^2} - \frac{1}{\lambda_C^2} } $$</p>
<p>This allows the shader to compute the specific IOR for each sample efficiently:</p>
<pre><code class="language-glsl">float ior_n = baseIOR + dispersionFactor * offsets[n];
</code></pre>
</main>
<nav class="nav-wrapper" aria-label="Page navigation">
<!-- Mobile navigation buttons -->
<a rel="prev" href="../dup/roughness_prefilter.html" class="mobile-nav-chapters previous" title="Previous chapter" aria-label="Previous chapter" aria-keyshortcuts="Left">
<i class="fa fa-angle-left"></i>
</a>
<a rel="next prefetch" href="../dup/specular_color.html" class="mobile-nav-chapters next" title="Next chapter" aria-label="Next chapter" aria-keyshortcuts="Right">
<i class="fa fa-angle-right"></i>
</a>
<div style="clear: both"></div>
</nav>
</div>
</div>
<nav class="nav-wide-wrapper" aria-label="Page navigation">
<a rel="prev" href="../dup/roughness_prefilter.html" class="nav-chapters previous" title="Previous chapter" aria-label="Previous chapter" aria-keyshortcuts="Left">
<i class="fa fa-angle-left"></i>
</a>
<a rel="next prefetch" href="../dup/specular_color.html" class="nav-chapters next" title="Next chapter" aria-label="Next chapter" aria-keyshortcuts="Right">
<i class="fa fa-angle-right"></i>
</a>
</nav>
</div>
<script>
window.playground_copyable = true;
</script>
<script src="../elasticlunr.min.js"></script>
<script src="../mark.min.js"></script>
<script src="../searcher.js"></script>
<script src="../clipboard.min.js"></script>
<script src="../highlight.js"></script>
<script src="../book.js"></script>
<!-- Custom JS scripts -->
</div>
</body>
</html>

View File

@@ -182,7 +182,7 @@ grazing angles. See Hoffman 2019, "Fresnel Equations Considered Harmful".</p>
<nav class="nav-wrapper" aria-label="Page navigation">
<!-- Mobile navigation buttons -->
<a rel="prev" href="../dup/roughness_prefilter.html" class="mobile-nav-chapters previous" title="Previous chapter" aria-label="Previous chapter" aria-keyshortcuts="Left">
<a rel="prev" href="../dup/specgen.html" class="mobile-nav-chapters previous" title="Previous chapter" aria-label="Previous chapter" aria-keyshortcuts="Left">
<i class="fa fa-angle-left"></i>
</a>
@@ -196,7 +196,7 @@ grazing angles. See Hoffman 2019, "Fresnel Equations Considered Harmful".</p>
</div>
<nav class="nav-wide-wrapper" aria-label="Page navigation">
<a rel="prev" href="../dup/roughness_prefilter.html" class="nav-chapters previous" title="Previous chapter" aria-label="Previous chapter" aria-keyshortcuts="Left">
<a rel="prev" href="../dup/specgen.html" class="nav-chapters previous" title="Previous chapter" aria-label="Previous chapter" aria-keyshortcuts="Left">
<i class="fa fa-angle-left"></i>
</a>

View File

@@ -0,0 +1,230 @@
<!DOCTYPE HTML>
<html lang="en" class="light sidebar-visible" dir="ltr">
<head>
<!-- Book generated using mdBook -->
<meta charset="UTF-8">
<title>CI: backend - Filament</title>
<!-- Custom HTML head -->
<meta name="description" content="">
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta name="theme-color" content="#ffffff">
<link rel="shortcut icon" href="../favicon.png">
<link rel="stylesheet" href="../css/variables.css">
<link rel="stylesheet" href="../css/general.css">
<link rel="stylesheet" href="../css/chrome.css">
<!-- Fonts -->
<link rel="stylesheet" href="../FontAwesome/css/font-awesome.css">
<link rel="stylesheet" href="../fonts/fonts.css">
<!-- Highlight.js Stylesheets -->
<link rel="stylesheet" href="../highlight.css">
<link rel="stylesheet" href="../tomorrow-night.css">
<link rel="stylesheet" href="../ayu-highlight.css">
<!-- Custom theme stylesheets -->
<!-- MathJax -->
<script async src="https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.1/MathJax.js?config=TeX-AMS-MML_HTMLorMML"></script>
<!-- Provide site root to javascript -->
<script>
var path_to_root = "../";
var default_theme = window.matchMedia("(prefers-color-scheme: dark)").matches ? "light" : "light";
</script>
<!-- Start loading toc.js asap -->
<script src="../toc.js"></script>
</head>
<body>
<div id="body-container">
<!-- Work around some values being stored in localStorage wrapped in quotes -->
<script>
try {
var theme = localStorage.getItem('mdbook-theme');
var sidebar = localStorage.getItem('mdbook-sidebar');
if (theme.startsWith('"') && theme.endsWith('"')) {
localStorage.setItem('mdbook-theme', theme.slice(1, theme.length - 1));
}
if (sidebar.startsWith('"') && sidebar.endsWith('"')) {
localStorage.setItem('mdbook-sidebar', sidebar.slice(1, sidebar.length - 1));
}
} catch (e) { }
</script>
<!-- Set the theme before any content is loaded, prevents flash -->
<script>
var theme;
try { theme = localStorage.getItem('mdbook-theme'); } catch(e) { }
if (theme === null || theme === undefined) { theme = default_theme; }
const html = document.documentElement;
html.classList.remove('light')
html.classList.add(theme);
html.classList.add("js");
</script>
<input type="checkbox" id="sidebar-toggle-anchor" class="hidden">
<!-- Hide / unhide sidebar before it is displayed -->
<script>
var sidebar = null;
var sidebar_toggle = document.getElementById("sidebar-toggle-anchor");
if (document.body.clientWidth >= 1080) {
try { sidebar = localStorage.getItem('mdbook-sidebar'); } catch(e) { }
sidebar = sidebar || 'visible';
} else {
sidebar = 'hidden';
}
sidebar_toggle.checked = sidebar === 'visible';
html.classList.remove('sidebar-visible');
html.classList.add("sidebar-" + sidebar);
</script>
<nav id="sidebar" class="sidebar" aria-label="Table of contents">
<div style="display:flex;align-items:center;justify-content:center">
<img class="flogo" src="../images/filament_logo_small.png"></img>
</div>
<!-- populated by js -->
<mdbook-sidebar-scrollbox class="sidebar-scrollbox"></mdbook-sidebar-scrollbox>
<noscript>
<iframe class="sidebar-iframe-outer" src="../toc.html"></iframe>
</noscript>
<div id="sidebar-resize-handle" class="sidebar-resize-handle">
<div class="sidebar-resize-indicator"></div>
</div>
</nav>
<div id="page-wrapper" class="page-wrapper">
<div class="page">
<div id="menu-bar-hover-placeholder"></div>
<div id="menu-bar" class="menu-bar sticky">
<div class="left-buttons">
<label id="sidebar-toggle" class="icon-button" for="sidebar-toggle-anchor" title="Toggle Table of Contents" aria-label="Toggle Table of Contents" aria-controls="sidebar">
<i class="fa fa-bars"></i>
</label>
<!-- Filament: disable themes because the markdeep part does not look good for dark themes -->
<!--
<button id="theme-toggle" class="icon-button" type="button" title="Change theme" aria-label="Change theme" aria-haspopup="true" aria-expanded="false" aria-controls="theme-list">
<i class="fa fa-paint-brush"></i>
</button>
<ul id="theme-list" class="theme-popup" aria-label="Themes" role="menu">
<li role="none"><button role="menuitem" class="theme" id="light">Light</button></li>
<li role="none"><button role="menuitem" class="theme" id="rust">Rust</button></li>
<li role="none"><button role="menuitem" class="theme" id="coal">Coal</button></li>
<li role="none"><button role="menuitem" class="theme" id="navy">Navy</button></li>
<li role="none"><button role="menuitem" class="theme" id="ayu">Ayu</button></li>
</ul>
-->
<button id="search-toggle" class="icon-button" type="button" title="Search. (Shortkey: s)" aria-label="Toggle Searchbar" aria-expanded="false" aria-keyshortcuts="S" aria-controls="searchbar">
<i class="fa fa-search"></i>
</button>
</div>
<h1 class="menu-title">Filament</h1>
<div class="right-buttons">
<a href="https://github.com/google/filament" title="Git repository" aria-label="Git repository">
<i id="git-repository-button" class="fa fa-github"></i>
</a>
</div>
</div>
<div id="search-wrapper" class="hidden">
<form id="searchbar-outer" class="searchbar-outer">
<input type="search" id="searchbar" name="searchbar" placeholder="Search this book ..." aria-controls="searchresults-outer" aria-describedby="searchresults-header">
</form>
<div id="searchresults-outer" class="searchresults-outer hidden">
<div id="searchresults-header" class="searchresults-header"></div>
<ul id="searchresults">
</ul>
</div>
</div>
<!-- Apply ARIA attributes after the sidebar and the sidebar toggle button are added to the DOM -->
<script>
document.getElementById('sidebar-toggle').setAttribute('aria-expanded', sidebar === 'visible');
document.getElementById('sidebar').setAttribute('aria-hidden', sidebar !== 'visible');
Array.from(document.querySelectorAll('#sidebar a')).forEach(function(link) {
link.setAttribute('tabIndex', sidebar === 'visible' ? 0 : -1);
});
</script>
<div id="content" class="content">
<main>
<h1 id="backend-tests"><a class="header" href="#backend-tests">Backend Tests</a></h1>
<p>This directory (<code>/test/backend</code>) contains scripts to run Filament's backend tests using a software
rasterizer (Mesa). This is useful for running tests in a continuous integration environment where a
GPU might not be available.</p>
<p>The <code>test.sh</code> script will:</p>
<ol>
<li>Build Mesa if needed.</li>
<li>Build the backend tests.</li>
<li>Run the tests using the OpenGL and Vulkan backends with Mesa.</li>
</ol>
<h2 id="flags"><a class="header" href="#flags">Flags</a></h2>
<p>The <code>test.sh</code> script accepts the following flags:</p>
<ul>
<li><code>--gtest_filter</code>: Filters the tests that are run. This is passed directly to the underlying
gtest executable.</li>
<li><code>--backend</code>: Specifies which backend to test. Can be <code>opengl</code>, <code>vulkan</code>, or a comma-separated
list (e.g., <code>opengl,vulkan</code>). Defaults to both.</li>
</ul>
</main>
<nav class="nav-wrapper" aria-label="Page navigation">
<!-- Mobile navigation buttons -->
<a rel="prev" href="../dup/backend_test.html" class="mobile-nav-chapters previous" title="Previous chapter" aria-label="Previous chapter" aria-keyshortcuts="Left">
<i class="fa fa-angle-left"></i>
</a>
<a rel="next prefetch" href="../dup/test_ci_renderdiff.html" class="mobile-nav-chapters next" title="Next chapter" aria-label="Next chapter" aria-keyshortcuts="Right">
<i class="fa fa-angle-right"></i>
</a>
<div style="clear: both"></div>
</nav>
</div>
</div>
<nav class="nav-wide-wrapper" aria-label="Page navigation">
<a rel="prev" href="../dup/backend_test.html" class="nav-chapters previous" title="Previous chapter" aria-label="Previous chapter" aria-keyshortcuts="Left">
<i class="fa fa-angle-left"></i>
</a>
<a rel="next prefetch" href="../dup/test_ci_renderdiff.html" class="nav-chapters next" title="Next chapter" aria-label="Next chapter" aria-keyshortcuts="Right">
<i class="fa fa-angle-right"></i>
</a>
</nav>
</div>
<script>
window.playground_copyable = true;
</script>
<script src="../elasticlunr.min.js"></script>
<script src="../mark.min.js"></script>
<script src="../searcher.js"></script>
<script src="../clipboard.min.js"></script>
<script src="../highlight.js"></script>
<script src="../book.js"></script>
<!-- Custom JS scripts -->
</div>
</body>
</html>

View File

@@ -3,7 +3,7 @@
<head>
<!-- Book generated using mdBook -->
<meta charset="UTF-8">
<title>renderdiff - Filament</title>
<title>CI: renderdiff - Filament</title>
<!-- Custom HTML head -->
@@ -159,7 +159,8 @@
<div id="content" class="content">
<main>
<h1 id="rendering-difference-test"><a class="header" href="#rendering-difference-test">Rendering Difference Test</a></h1>
<p>This tool is a collections of scripts to run <code>gltf_viewer</code> and produce headless renderings.</p>
<p>This tool (<code>/test/renderdiff</code>) is a collections of scripts to run <code>gltf_viewer</code> and produce headless
renderings.</p>
<p>This is mainly useful for continuous integration where GPUs are generally not available on cloud
machines. To perform software rasterization, these scripts are centered around <a href="https://docs.mesa3d.org">Mesa</a>'s
software rasterizers, but nothing bars us from using another rasterizer like <a href="https://github.com/google/swiftshader">SwiftShader</a>.
@@ -251,7 +252,7 @@ git switch -c my-pr-branch-golden
</code></pre>
</li>
<li>In the commit message of your working branch on <code>filament</code>, add the following line
<pre><code>RDIFF_BBRANCH=my-pr-branch-golden
<pre><code>RDIFF_BRANCH=my-pr-branch-golden
</code></pre>
</li>
</ul>
@@ -292,7 +293,7 @@ the run number is <code>18023632663</code>.</p>
<nav class="nav-wrapper" aria-label="Page navigation">
<!-- Mobile navigation buttons -->
<a rel="prev" href="../notes/tests.html" class="mobile-nav-chapters previous" title="Previous chapter" aria-label="Previous chapter" aria-keyshortcuts="Left">
<a rel="prev" href="../dup/test_ci_backend.html" class="mobile-nav-chapters previous" title="Previous chapter" aria-label="Previous chapter" aria-keyshortcuts="Left">
<i class="fa fa-angle-left"></i>
</a>
@@ -306,7 +307,7 @@ the run number is <code>18023632663</code>.</p>
</div>
<nav class="nav-wide-wrapper" aria-label="Page navigation">
<a rel="prev" href="../notes/tests.html" class="nav-chapters previous" title="Previous chapter" aria-label="Previous chapter" aria-keyshortcuts="Left">
<a rel="prev" href="../dup/test_ci_backend.html" class="nav-chapters previous" title="Previous chapter" aria-label="Previous chapter" aria-keyshortcuts="Left">
<i class="fa fa-angle-left"></i>
</a>

View File

@@ -158,11 +158,7 @@
<div id="content" class="content">
<main>
<ul>
<li><a href="#ubershader-archive-files">Ubershader Archive Files</a></li>
<li><a href="#ubershader-spec-files">Ubershader Spec Files</a></li>
</ul>
<h1 id="ubershader-archive-files"><a class="header" href="#ubershader-archive-files">Ubershader Archive Files</a></h1>
<h1 id="uberz"><a class="header" href="#uberz">uberz</a></h1>
<p>An ubershader archive provides a way to bundle up a set of <code>filamat</code> files along with some metadata
that conveys which glTF features each material can handle. It is a file that has been compressed
with <code>zstd</code> and has an <code>.uberz</code> file extension. In uncompressed form, it has the following layout
@@ -240,7 +236,7 @@ mapping should be specified as an <code>optional</code> feature of the ubershade
<nav class="nav-wrapper" aria-label="Page navigation">
<!-- Mobile navigation buttons -->
<a rel="prev" href="../dup/matdbg.html" class="mobile-nav-chapters previous" title="Previous chapter" aria-label="Previous chapter" aria-keyshortcuts="Left">
<a rel="prev" href="../dup/viewer.html" class="mobile-nav-chapters previous" title="Previous chapter" aria-label="Previous chapter" aria-keyshortcuts="Left">
<i class="fa fa-angle-left"></i>
</a>
@@ -254,7 +250,7 @@ mapping should be specified as an <code>optional</code> feature of the ubershade
</div>
<nav class="nav-wide-wrapper" aria-label="Page navigation">
<a rel="prev" href="../dup/matdbg.html" class="nav-chapters previous" title="Previous chapter" aria-label="Previous chapter" aria-keyshortcuts="Left">
<a rel="prev" href="../dup/viewer.html" class="nav-chapters previous" title="Previous chapter" aria-label="Previous chapter" aria-keyshortcuts="Left">
<i class="fa fa-angle-left"></i>
</a>

333
docs/dup/viewer.html Normal file
View File

@@ -0,0 +1,333 @@
<!DOCTYPE HTML>
<html lang="en" class="light sidebar-visible" dir="ltr">
<head>
<!-- Book generated using mdBook -->
<meta charset="UTF-8">
<title>viewer - Filament</title>
<!-- Custom HTML head -->
<meta name="description" content="">
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta name="theme-color" content="#ffffff">
<link rel="shortcut icon" href="../favicon.png">
<link rel="stylesheet" href="../css/variables.css">
<link rel="stylesheet" href="../css/general.css">
<link rel="stylesheet" href="../css/chrome.css">
<!-- Fonts -->
<link rel="stylesheet" href="../FontAwesome/css/font-awesome.css">
<link rel="stylesheet" href="../fonts/fonts.css">
<!-- Highlight.js Stylesheets -->
<link rel="stylesheet" href="../highlight.css">
<link rel="stylesheet" href="../tomorrow-night.css">
<link rel="stylesheet" href="../ayu-highlight.css">
<!-- Custom theme stylesheets -->
<!-- MathJax -->
<script async src="https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.1/MathJax.js?config=TeX-AMS-MML_HTMLorMML"></script>
<!-- Provide site root to javascript -->
<script>
var path_to_root = "../";
var default_theme = window.matchMedia("(prefers-color-scheme: dark)").matches ? "light" : "light";
</script>
<!-- Start loading toc.js asap -->
<script src="../toc.js"></script>
</head>
<body>
<div id="body-container">
<!-- Work around some values being stored in localStorage wrapped in quotes -->
<script>
try {
var theme = localStorage.getItem('mdbook-theme');
var sidebar = localStorage.getItem('mdbook-sidebar');
if (theme.startsWith('"') && theme.endsWith('"')) {
localStorage.setItem('mdbook-theme', theme.slice(1, theme.length - 1));
}
if (sidebar.startsWith('"') && sidebar.endsWith('"')) {
localStorage.setItem('mdbook-sidebar', sidebar.slice(1, sidebar.length - 1));
}
} catch (e) { }
</script>
<!-- Set the theme before any content is loaded, prevents flash -->
<script>
var theme;
try { theme = localStorage.getItem('mdbook-theme'); } catch(e) { }
if (theme === null || theme === undefined) { theme = default_theme; }
const html = document.documentElement;
html.classList.remove('light')
html.classList.add(theme);
html.classList.add("js");
</script>
<input type="checkbox" id="sidebar-toggle-anchor" class="hidden">
<!-- Hide / unhide sidebar before it is displayed -->
<script>
var sidebar = null;
var sidebar_toggle = document.getElementById("sidebar-toggle-anchor");
if (document.body.clientWidth >= 1080) {
try { sidebar = localStorage.getItem('mdbook-sidebar'); } catch(e) { }
sidebar = sidebar || 'visible';
} else {
sidebar = 'hidden';
}
sidebar_toggle.checked = sidebar === 'visible';
html.classList.remove('sidebar-visible');
html.classList.add("sidebar-" + sidebar);
</script>
<nav id="sidebar" class="sidebar" aria-label="Table of contents">
<div style="display:flex;align-items:center;justify-content:center">
<img class="flogo" src="../images/filament_logo_small.png"></img>
</div>
<!-- populated by js -->
<mdbook-sidebar-scrollbox class="sidebar-scrollbox"></mdbook-sidebar-scrollbox>
<noscript>
<iframe class="sidebar-iframe-outer" src="../toc.html"></iframe>
</noscript>
<div id="sidebar-resize-handle" class="sidebar-resize-handle">
<div class="sidebar-resize-indicator"></div>
</div>
</nav>
<div id="page-wrapper" class="page-wrapper">
<div class="page">
<div id="menu-bar-hover-placeholder"></div>
<div id="menu-bar" class="menu-bar sticky">
<div class="left-buttons">
<label id="sidebar-toggle" class="icon-button" for="sidebar-toggle-anchor" title="Toggle Table of Contents" aria-label="Toggle Table of Contents" aria-controls="sidebar">
<i class="fa fa-bars"></i>
</label>
<!-- Filament: disable themes because the markdeep part does not look good for dark themes -->
<!--
<button id="theme-toggle" class="icon-button" type="button" title="Change theme" aria-label="Change theme" aria-haspopup="true" aria-expanded="false" aria-controls="theme-list">
<i class="fa fa-paint-brush"></i>
</button>
<ul id="theme-list" class="theme-popup" aria-label="Themes" role="menu">
<li role="none"><button role="menuitem" class="theme" id="light">Light</button></li>
<li role="none"><button role="menuitem" class="theme" id="rust">Rust</button></li>
<li role="none"><button role="menuitem" class="theme" id="coal">Coal</button></li>
<li role="none"><button role="menuitem" class="theme" id="navy">Navy</button></li>
<li role="none"><button role="menuitem" class="theme" id="ayu">Ayu</button></li>
</ul>
-->
<button id="search-toggle" class="icon-button" type="button" title="Search. (Shortkey: s)" aria-label="Toggle Searchbar" aria-expanded="false" aria-keyshortcuts="S" aria-controls="searchbar">
<i class="fa fa-search"></i>
</button>
</div>
<h1 class="menu-title">Filament</h1>
<div class="right-buttons">
<a href="https://github.com/google/filament" title="Git repository" aria-label="Git repository">
<i id="git-repository-button" class="fa fa-github"></i>
</a>
</div>
</div>
<div id="search-wrapper" class="hidden">
<form id="searchbar-outer" class="searchbar-outer">
<input type="search" id="searchbar" name="searchbar" placeholder="Search this book ..." aria-controls="searchresults-outer" aria-describedby="searchresults-header">
</form>
<div id="searchresults-outer" class="searchresults-outer hidden">
<div id="searchresults-header" class="searchresults-header"></div>
<ul id="searchresults">
</ul>
</div>
</div>
<!-- Apply ARIA attributes after the sidebar and the sidebar toggle button are added to the DOM -->
<script>
document.getElementById('sidebar-toggle').setAttribute('aria-expanded', sidebar === 'visible');
document.getElementById('sidebar').setAttribute('aria-hidden', sidebar !== 'visible');
Array.from(document.querySelectorAll('#sidebar a')).forEach(function(link) {
link.setAttribute('tabIndex', sidebar === 'visible' ? 0 : -1);
});
</script>
<div id="content" class="content">
<main>
<h1 id="viewer-library"><a class="header" href="#viewer-library">Viewer Library</a></h1>
<p>The <strong>Viewer Library</strong> (<code>libs/viewer</code>) provides a high-level abstraction for configuring and rendering Filament scenes. It is used by tools like <code>gltf_viewer</code> to load assets, manage settings, and drive the rendering loop.</p>
<h2 id="features"><a class="header" href="#features">Features</a></h2>
<ul>
<li><strong>Settings Management</strong>: Centralized configuration for View, Camera, Lights, and Materials via the <code>Settings</code> struct.</li>
<li><strong>JSON Serialization</strong>: Full support for loading and saving settings via JSON.</li>
<li><strong>Automation</strong>: <code>AutomationEngine</code> allows scripting the viewer with a sequence of JSON-based test cases (batch mode).</li>
<li><strong>GUI Integration</strong>: Built-in support for <code>imgui</code> via <code>ViewerGui</code> and <code>Settings</code> binding.</li>
</ul>
<h2 id="json-settings-schema"><a class="header" href="#json-settings-schema">JSON Settings Schema</a></h2>
<p>The viewer settings can be configured using a JSON object. This is used for <code>gltf_viewer --settings</code> or in automation specs.</p>
<h3 id="root-object"><a class="header" href="#root-object">Root Object</a></h3>
<p>The root object contains the following categories:</p>
<div class="table-wrapper"><table><thead><tr><th style="text-align: left">Key</th><th style="text-align: left">Type</th><th style="text-align: left">Description</th></tr></thead><tbody>
<tr><td style="text-align: left"><code>view</code></td><td style="text-align: left">Object</td><td style="text-align: left">Post-processing and rendering quality settings.</td></tr>
<tr><td style="text-align: left"><code>camera</code></td><td style="text-align: left">Object</td><td style="text-align: left"><strong>[NEW]</strong> Explicit camera control (pose, projection, exposure).</td></tr>
<tr><td style="text-align: left"><code>lighting</code></td><td style="text-align: left">Object</td><td style="text-align: left"><strong>[NEW]</strong> Environment and dynamic light settings.</td></tr>
<tr><td style="text-align: left"><code>viewer</code></td><td style="text-align: left">Object</td><td style="text-align: left">Global viewer options (skybox, background, scaling).</td></tr>
<tr><td style="text-align: left"><code>animation</code></td><td style="text-align: left">Object</td><td style="text-align: left"><strong>[NEW]</strong> Animation playback control.</td></tr>
<tr><td style="text-align: left"><code>material</code></td><td style="text-align: left">Object</td><td style="text-align: left">Material overrides.</td></tr>
</tbody></table>
</div>
<hr />
<h3 id="camera-settings-camera"><a class="header" href="#camera-settings-camera">Camera Settings (<code>camera</code>)</a></h3>
<p>Allows explicit control over the camera. If <code>enabled</code> is false, the viewer uses its default orbit camera logic (auto-scaling/centering).</p>
<pre><code class="language-json">"camera": {
"enabled": true, // Must be true to use these explicit settings
"projection": "PERSPECTIVE", // "PERSPECTIVE" or "ORTHO"
"center": [0, 0, 0], // World-space look-at point
"lookAt": [0, 0, -1], // World-space eye position (confusingly named 'lookAt' in internal legacy, often 'eye')
"up": [0, 1, 0], // Up vector
"near": 0.1, // Near plane
"far": 100.0, // Far plane
"focalLength": 28.0, // Focal length in mm (Perspective only)
"fov": 0.0, // Field of view in degrees (overrides focalLength if &gt; 0)
"aperture": 16.0, // f-stop
"shutterSpeed": 125.0, // 1/seconds
"sensitivity": 100.0, // ISO
"focusDistance": 10.0, // Focus distance in world units
"scaling": [1.0, 1.0], // Custom projection matrix scaling (mostly for Ortho)
"shift": [0.0, 0.0] // Custom projection matrix shift
}
</code></pre>
<h3 id="lighting-settings-lighting"><a class="header" href="#lighting-settings-lighting">Lighting Settings (<code>lighting</code>)</a></h3>
<p>Controls the Image Based Lighting (IBL), the Sun, and additional dynamic lights.</p>
<pre><code class="language-json">"lighting": {
"iblIntensity": 30000.0,
"iblRotation": 0.0, // Rotation in degrees
"enableSunlight": true,
"enableShadows": true,
"sunlight": { // **[NEW]** Nested sunlight properties
"intensity": 100000.0,
"color": [0.98, 0.92, 0.89],
"direction": [0.6, -1.0, -0.8],
"sunHaloSize": 10.0,
"sunHaloFalloff": 80.0,
"sunAngularRadius": 1.9,
"castShadows": true,
"shadowOptions": { // Per-light shadow options
"mapSize": 1024,
"shadowCascades": 1,
"stable": false
}
},
"lights": [ // **[NEW]** Array of custom lights
{
"type": "POINT", // "POINT", "SPOT", "FOCUSED_SPOT", "DIRECTIONAL", "SUN"
"position": [0, 2, 0],
"color": [1, 0, 0],
"intensity": 5000.0,
"falloff": 10.0,
"castShadows": true,
"shadowOptions": { "mapSize": 512 }
},
{
"type": "SPOT",
"position": [2, 5, 2],
"direction": [0, -1, 0],
"spotInner": 0.5, // Inner cone angle (radians)
"spotOuter": 0.8 // Outer cone angle (radians)
}
]
}
</code></pre>
<h3 id="view-settings-view"><a class="header" href="#view-settings-view">View Settings (<code>view</code>)</a></h3>
<p>Standard Filament view settings.</p>
<pre><code class="language-json">"view": {
"postProcessingEnabled": true,
"antiAliasing": "FXAA", // "NONE", "FXAA"
"msaa": {
"enabled": true,
"sampleCount": 4
},
"ssao": { "enabled": true, ... },
"bloom": { "enabled": true, ... },
"dof": { "enabled": false, ... },
"vignette": { "enabled": false, ... },
"colorGrading": {
"toneMapping": "ACES_LEGACY", // "LINEAR", "ACES", "FILMIC", "PBR_NEUTRAL", etc.
"exposure": 0.0,
"gamma": [1.0, 1.0, 1.0]
}
}
</code></pre>
<h3 id="viewer-options-viewer"><a class="header" href="#viewer-options-viewer">Viewer Options (<code>viewer</code>)</a></h3>
<p>General app-level settings.</p>
<pre><code class="language-json">"viewer": {
"skyboxEnabled": true,
"backgroundColor": [0, 0, 0], // Used if skybox is disabled
"autoScaleEnabled": true, // Fit model to unit cube
"groundPlaneEnabled": false
}
</code></pre>
<h3 id="animation-settings-animation"><a class="header" href="#animation-settings-animation">Animation Settings (<code>animation</code>)</a></h3>
<p>Control glTF animation playback.</p>
<pre><code class="language-json">"animation": {
"enabled": true,
"speed": 1.0,
"time": -1.0 // If &gt;= 0, forces animation to this specific time (seconds)
}
</code></pre>
</main>
<nav class="nav-wrapper" aria-label="Page navigation">
<!-- Mobile navigation buttons -->
<a rel="prev" href="../dup/matdbg.html" class="mobile-nav-chapters previous" title="Previous chapter" aria-label="Previous chapter" aria-keyshortcuts="Left">
<i class="fa fa-angle-left"></i>
</a>
<a rel="next prefetch" href="../dup/uberz.html" class="mobile-nav-chapters next" title="Next chapter" aria-label="Next chapter" aria-keyshortcuts="Right">
<i class="fa fa-angle-right"></i>
</a>
<div style="clear: both"></div>
</nav>
</div>
</div>
<nav class="nav-wide-wrapper" aria-label="Page navigation">
<a rel="prev" href="../dup/matdbg.html" class="nav-chapters previous" title="Previous chapter" aria-label="Previous chapter" aria-keyshortcuts="Left">
<i class="fa fa-angle-left"></i>
</a>
<a rel="next prefetch" href="../dup/uberz.html" class="nav-chapters next" title="Next chapter" aria-label="Next chapter" aria-keyshortcuts="Right">
<i class="fa fa-angle-right"></i>
</a>
</nav>
</div>
<script>
window.playground_copyable = true;
</script>
<script src="../elasticlunr.min.js"></script>
<script src="../mark.min.js"></script>
<script src="../searcher.js"></script>
<script src="../clipboard.min.js"></script>
<script src="../highlight.js"></script>
<script src="../book.js"></script>
<!-- Custom JS scripts -->
</div>
</body>
</html>

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.6 MiB

File diff suppressed because one or more lines are too long

Some files were not shown because too many files have changed in this diff Show More