Compare commits

...

230 Commits

Author SHA1 Message Date
Sungun Park
7017bde04d Optimize thread variables in ServiceThread
Wraps thread-related member variables in preprocessor checks to ensure
they are excluded when multithreading is not supported. Previously,
these variables were declared unconditionally, leading to unnecessary
memory usage for platforms that don't support multithreading.
2026-01-20 07:42:15 -08: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
Doris Wu
f07176c0a2 Try to fix test_UboBatching (#9448) 2025-11-20 15:14:19 +08:00
Doris Wu
15db141c7a Add some unit tests for UboManager (#9446) 2025-11-20 14:28:13 +08:00
Doris Wu
d4bbb7c591 buffer update opt: Some optimizations (#9438) 2025-11-20 00:52:04 +00:00
Sungun Park
92e620d2ad Simplify buffer object creation (#9436)
Simplify the buffer object creation logic to streamline and help make
the future integration of asynchronous features easier.
2025-11-19 22:03:05 +00:00
Mathias Agopian
311104da97 update google benchmark library to 1.9.4 (#9441)
* benchmark: update README and add update script

* update google benchmark library to 1.9.4

* update tnt CMakeLists to match the library new version
2025-11-19 11:50:34 -08:00
Filament Bot
3127632f96 [automated] Updating /docs due to commit 59f611b
Full commit hash is 59f611bfde

DOCS_ALLOW_DIRECT_EDITS
2025-11-19 19:32:56 +00:00
Sungun Park
59f611bfde Release Filament 1.67.1 2025-11-19 11:30:16 -08:00
Sungun Park
2d556bdca2 Workaround for screen space reflections artifacts fix (#9444)
This is a workaround for Samsung Galaxy S24 device failing to link this change.
ea608d409e
2025-11-19 19:03:00 +00:00
Ben Doherty
65e7dba8b8 Log GPU errors through Platform debugStat API (#9434) 2025-11-19 10:42:42 -08:00
Mathias Agopian
6550a63056 Fix android helper header usage (#9442)
These headers are private but were used by public headers. 
Refactor the platform code so that these headers stay private.

AndroidNdk.h is treated differently, it is now made public because
it simplifies a lot of things to be able to have the platform concrete
implementation derive from it.
2025-11-19 10:20:37 -08:00
Doris Wu
aa4e2c56b5 buffer update opt: Skip releaseFreeSlots when no frees are pending (#9437) 2025-11-15 10:23:27 +08:00
Powei Feng
aa4f1910b8 android: add static annotation for Utils.init() (#9435)
This allows for static call from java, e.g.:

```
static {
    Utils.init();
}
```
2025-11-13 22:01:49 +00:00
Mathias Agopian
223a4b18a8 Fix several problems with RenderPass descriptor sets (#9431)
The root of the problem is that in the main rendering loop we need
to set the correct per-view descriptor-set based on the material and
variants.

But we have two cases, either the descriptor set is always constant, 
which is the case with ssr, structure, shadows and postfx passes, or
it need to be dynamically changed based on the material & variant.

In the 2nd case, where was a problem where the postfx descriptor set
could be used, which is wrong (e.g. while rendering shadows we need
the shadow UBO, even with a postfx material), and would corrupt the
correct descriptor set, which would never be set back.

Another issue was related to running a custom command, it could 
change the state without updating the local copy, causing corruptions
or validation errors.

In this CL we:
- use the same descriptorsetlayout for both postfx and depth
- invalidate the state after a custom command
- only switch to postfx descriptor set in dynamic mode (color pass)


This fixes setChannelDepthClearEnabled() which could cause 
validation error, corruption or crashes.

FIXES=[459567258]
2025-11-13 12:07:16 -08:00
rafadevai
57ef534acd VK: Add support for getting pipeline creation stats (#9422)
* VK: Add support for getting pipeline creation stats

When debugging is pipeline compilation related hitches
is useful to know more information about what happened
when building a new pipeline.

By levering the VK_EXT_pipeline_creation_feedback
extension, we can know if the pipeline creation was
speed up because of a cache hit, how much time it spent
creating it and also the stats related to each
pipeline stage.

This is only available when using the debug flag
FVK_DEBUG_SHADER_MODULE.

* Fix the unused build error
2025-11-13 09:01:02 -08:00
rafadevai
719914fb84 VK: Better support for renderdoc captures (#9423)
Doing a renderdoc capture when using transient memory
or importing AHardwareBuffers into Vulkan, makes it fail,
crash or not replay properly.

To improve the capture support, added a new constant to let the
backend know when renderdoc is expected to be used and configure
things appropietly.

- In the case of transient attachments that uses lazy allocated
memory, it will be disabled.
- In the case of AHardwareBuffers, a more robust memory heap
selection algorithm will be used.

Also a new VulkanPlatform function will be added, to let other
subclasses know that the transient attachments are enabled or not.
2025-11-13 07:40:51 -08:00
Powei Feng
080f958da3 android: remove checked in asset (#9426)
For sample-gltf-viewer, an asset was checked into the source tree.
But other assets are generated or copied from asset directories.

We remove the checked in gltf and copy the asset over during
build (as with other existing files).
2025-11-13 06:29:45 +00:00
Doris Wu
7547aa3807 buffer update opt: Integrate UboManager into the engine (#9397) 2025-11-13 02:19:48 +00:00
Sungun Park
67a0c6e0e1 fix a typo in VertexBuffer (#9427) 2025-11-12 15:31:55 -08:00
Ben Doherty
37cb842993 Fix possible null string crash inside TextWriter (#9428) 2025-11-12 12:07:16 -08:00
Doris Wu
ad27d48fd3 buffer update opt: refactor UboManager and introduce FenceManager (#9418) 2025-11-11 16:56:06 +08:00
Mathias Agopian
3a503976c8 add View::getLastDynamicResolutionScale() (#9419)
* add View::getLastDynamicResolutionScale()

This method return the last dynamic resolution scaling factor used
by the view.

FIXES=[457753622]
2025-11-10 14:49:23 -08:00
Mathias Agopian
ce6fa82026 improve camera precondition checks and default state (#9420)
* improve camera precondition checks and default state

- Camera is now initialized with a default projection matrix with
left/right, top/bottom set to (-1,1) and near/far set to (0.1,1).

- setLensProjection() and setProjection(FOV) now check the near/far
precondition (near>0 and far>near).

- sanitize user's light near/far to avoid infs and nans during
  froxelization

- finally froxelizer asserts that near>0 and far>near on debug builds.

FIXES=[458030186]
2025-11-10 14:48:48 -08:00
Mathias Agopian
e8349ab5cc AndroidNativeWindow must also work on 32-bits architectures (#9424) 2025-11-10 14:44:52 -08:00
yein
4773fc4647 Move the include resolution functionality to matp (#9414)
* Move the include resolution functionality to matp

- matp::MaterialParser now has a function resolveIncludes that returns a pair of status and resolve string.
- all the include resolution classes are moved to matp private src.
- matp::resolveIncludes is renamed to matp::resolveIncludesRecursively and only used internally.
- added insertLineDirectives and insertLineDirectiveChecks in Config; add those in the CommandlineConfig.
- moved output format to public use.

Note: MaterialParser::resolveIncludes could take a includer instead of the materialFilePath, but i decided
to go with the materialFilePath because the most common use case is resolving from the file's directory.
This allows the parser to just create the default DirIncluder internally, and we don't need to expose it publicly.

* add const to the buffer param
2025-11-07 15:23:54 -08:00
Rafael Marinho de Araújo
d47a69a529 add overload of loadTexture that loads bitmap from ByteArray (#9416)
Co-authored-by: rma6 <rafaelmarinhoa@gmail.com>
2025-11-07 10:11:23 -08:00
Powei Feng
d3b74e96b4 vk: fix thread-safety wrt queryFrameTimestamps() (#9415)
queryFrameTimestamps() and queryCompositorTiming() are both
synchronous APIs, but VuklanSwapchain is not a thread-safe
ref-counted handle (i.e. fvkmemory::ThreadSafeResource). We move
the Platform::SwapChain* pointers to a thread-safe map that is
mapped by the handle id.
2025-11-07 18:00:01 +00:00
Mathias Agopian
209d3f7550 Fix a race condition when tearing down FrameInfo (#9413)
* HandleAllocator::deallocate() was unsafe

It needs to know the concrete type to call the proper destructor, so
if it was given a base type handle (e.g. Handle<HwFoo>) it would not
destroy it properly.

* add AsyncJobQueue::cancelAll()

* Fix a race condition when tearing down FrameInfo

It is actually invalid to destroy a Handle<HwFence> while inside
fenceWait().

Updated the HwFence implementations so that they don't pretend they can
handle being destroyed during fenceWait(), they can't.

FrameInfo now cancels all the pending callbacks and waits for the 
currently executing one to terminate, *before* destroying the
handles.

Reenable the gpuFrameComplete metric, as it should be working now.
2025-11-06 16:50:08 -08:00
Mathias Agopian
92e65cb3fd Properly use SDK 26+ APIs (#9417)
With minSDK less than 26, it's unsafe to use APIs in nativewindow.h 
that appeared at API 26 or more, even when using the weak symbol
technique. This is because pre 26, libnativewindow.h didn't exist and
therefore the build system cannot link against it.

Currently Filament's minSdk is 21, which means we should never use
nativewindow.h API after 26.

In this PR we chose the strategy at compile time; either the more
modern weak symbol or the old way with dlsym based on __ANDROID_API__.
2025-11-06 16:49:28 -08:00
Powei Feng
a4945939de vk: fix leaking swapchains again (#9410)
- Adjust order of destroy call in both headless and platform
   swapchains.  We need to be careful of the order due to
   assumptions made by the base class's destroy().
 - remove `=0` since VulkanPlatformSwapChainBase::destroy() has
   an implementation.

Fixes #9403
2025-11-05 22:10:05 -08:00
Benjamin Doherty
086760b307 Add missing mutex header 2025-11-05 15:35:29 -08:00
Powei Feng
ce1b63ce38 gltf_viewer: fix accidentally removed FilamentAppVulkanPlatform 2025-11-05 15:26:47 -08:00
Mathias Agopian
b7b8983653 add a feature flag for FrameInfo::gpuFrameComplete (#9409)
There are several race conditions caused by this feature. So we add
this flag and disable it by default, for now.
2025-11-05 15:22:43 -08:00
Powei Feng
d52fb1f4fd vk: refactor to use polymorphism for platform specialization (#9398)
We refactor VulkanPlatform so that getSwapchainInstanceExtensions()
and createVkSurfaceKHR() are virtual functions that are implemented
by each platform. This will enable the use of polymorphism for
platform-dependent bits.
2025-11-05 19:44:39 +00:00
Powei Feng
901c87761b gltfio: add null check for when image is not provided (#9407)
Fixes #9402
2025-11-05 19:26:24 +00:00
Benjamin Doherty
081fe6a434 Bump MATERIAL_VERSION to 67 2025-11-05 10:35:14 -08:00
Benjamin Doherty
b84c6ace8d Release Filament 1.67.0 2025-11-05 10:33:15 -08:00
yein
2113e04aba Support returning a .mat file from matc (#9399) 2025-11-05 10:17:55 -08:00
Doris Wu
84fdf36ed9 buffer update opt: New android sample for material instance stress test (#9396) 2025-11-05 03:24:56 +00:00
Doris Wu
dc1de994e0 buffer update opt: Initialize UboManager class (#9331) 2025-11-05 02:47:28 +00:00
Mathias Agopian
7c6479020e use choreographer to access the system's expected present time (#9393)
* use choreographer to access the system's expected present time

* more Android specific code into VulkanPlatformAndroid

* Fix race-condition between init() and terminate()

it was possible for the thread to not have been ready by the time
we call terminate.

* fix build and minor fixes
2025-11-04 14:17:50 -08:00
yein
a5f949d30c Move resolving #includes from MaterialBuilder to MaterialCompiler (#9374)
* Move resolving #includes from MaterialBuilder to MaterialCompiler, before parsing the material.

- resolving #includes was happening after parsing, now moving before parsing.
this is because we could offload this resolution at build time for RuntimeMaterialCompiler
- filamat::resolveIncludes used to have an assumption where the given text was already
a shader block. this assumption is now broken so it finds the line offset internally.
thus the line offset field is removed from IncludeResult.

* Move include related classes to matc
2025-11-04 14:14:43 -08:00
haroonq
6c867c692b Add flags for supporting externally defined dependencies. (#9355) 2025-11-04 13:36:01 -08:00
Benn Herrera
bd735fbab8 updated cgltf to 1.15 and broke out commands from README into utility script. (#9369) 2025-11-04 13:35:21 -08:00
Benn Herrera
b4c4ce9e17 Add Optional Inclusion of libwebp in Third Party Libaries (#9371)
* adds third_party/libwebp and cmake option to enable building it.

* disable simd and default disable pthreads for webgl builds.

* ensure non-empty config var value

* Added notes on libwebp change to NEW_RELEASE_NOTES.md

* Update NEW_RELEASE_NOTES.md
2025-11-04 13:34:57 -08:00
rafadevai
138cc55d3b Don't always associate transformName to a stream (#9404)
Before the transformName field was expected to be
used together with the stream API, that is not the
case anymore.

In the scenario that isn't using the stream API,
filament will try to associate the transformName
field to a stream that doesn't exist, causing a
crash.
2025-11-04 13:34:14 -08:00
Powei Feng
3d6db313bd vk: swapchain destroy must call through to base class (#9405)
Fixes #9403
2025-11-04 20:15:52 +00:00
Powei Feng
faa565c3ff vk: remove unused shaders (#9394)
The BlitDepth shaders were no longer referenced in the blit code
and hence are removed.
2025-11-04 17:45:57 +00:00
yrcloud
2a2caad1bf webgpu: use staging buffers for updateGPUBuffer (#9360)
BUGS=450620535
2025-11-03 17:28:59 -05:00
Anish Goyal
804ee87356 Check for null fences to avoid segfault in tests (#9389)
* Check for null fences to avoid segfault in tests

In some test environments, creating a sync or fence backed by an Android
fence returns null. In order to avoid NPEs, cover this scenario with a
null check.

* Address PR - add log statement

Log that native fences are not supported when unable to create a native
sync fence.
2025-11-03 19:28:15 +00:00
Filament Bot
f5c9d973dc [automated] Updating /docs due to commit 778cbe0
Full commit hash is 778cbe09d1

DOCS_ALLOW_DIRECT_EDITS
2025-10-31 22:25:27 +00:00
Powei Feng
778cbe09d1 build: allow building tools separately (#9384)
Building tools separately is necessary for the existing
cross-complation usecase.  We generalize this by introducing
two cmake vars that enable exporting and importing
prebuilt tools.

The intended usecase is to enable ASAN-built filament without
having to run ASAN-built matc (which is prohibitively slow).

build.sh has been modified to add a `-y` flag forprebuilding
tools.
2025-10-31 22:23:15 +00:00
Mathias Agopian
bf6c51bae6 Fix GLES2 UBO emulation (#9392)
The binding cache didn't take into account the UBO offset.

FIXES=[456802974]
2025-10-31 14:28:45 -07:00
Powei Feng
cb3933b349 Guard MonotonicRingMap.MonotonicityDeathTest with GTEST_HAS_DEATH_TEST (#9388) 2025-10-31 20:45:32 +00:00
Mathias Agopian
4e9d691d9d fix transparent picking (#9390)
FIXES=[456489383]
2025-10-31 13:39:31 -07:00
Mathias Agopian
fe5f8547f7 Add frame history support to the Vulkan backend on Android (#9386) 2025-10-31 13:13:48 -07:00
Powei Feng
3207c31721 renderdiff: disable webgpu + bloom due to flake (#9368)
WebGPU's rendering of bloom sems to be non-deterministic.  This
is not expected.  For now, we disable bloom+webgpu to avoid
hitting flakes in our CI.

This required a slight refactoring of the test configuration
parsing and execution scripts.

RDIFF_BRANCH=pf/renderdiff-disable-bloom-webgpu
2025-10-31 06:55:44 +00:00
Mathias Agopian
236d650ed7 Add display present time as well as compositor timings to FrameInfo (#9378)
* Use a custom, non-allocating map for frame ids

* use memory_order_relaxed for the id of heap allocated handles

* Added displayPresent time to FrameInfo

To do this, we added support for queryFrameTiming() to the backend,
as a synchronous API. Then FrameInfo uses it to update the
corresponding history entry.

displayPresent time can be used to detect "buffer stuffing", i.e.
when the GPU gets too much ahead of the display. Currently
the information is returned to the user only. Eventually filament will
make use of it to determine if a frame skip is mandated.

* API BREAK: rename frameTime to gpuFrameDuration

* FrameInfo now contains compositor timings

- the presentation deadline
- the refresh rate from the display
- the composition-display latency

* set FrameInfo data to INVALID if feature is not supported

report presentDeadline properly.
2025-10-30 15:33:26 -07:00
Mathias Agopian
294b79b321 vkWaitForFences() must be called with the read-lock held (#9385) 2025-10-30 15:31:05 -07:00
Ben Doherty
0dc392a760 Refactor Metal command buffer error logging (#9383) 2025-10-30 15:03:09 -07:00
Ben Doherty
06fa370491 Metal: support MSAA SwapChain flag (#9361) 2025-10-30 11:08:08 -07:00
Mathias Agopian
6fdd7398b6 fix a possible deadlock on exit (#9377)
The deadlock happened because FrameInfoManager needs to wait that all
fences have signaled before it can be destroyed. 

The fix here is simply to destroy the fence without waiting (for safety
we do wait after we destroy them).

This uncovered another problem where all backends didn't handle this 
correctly.

We now explicitly handle this when destroying a fence: we make sure it
unblocks all the waiters and returns an error.
2025-10-30 09:30:27 -07:00
Mathias Agopian
32a89a9017 Disable producer throttling on Vulkan (#9381)
This allows vkPresentKHR to not block.
2025-10-30 09:30:02 -07:00
Mathias Agopian
ddb2d89e6c creating a cubemap with mip levels was incorrect (#9382)
the miplevels where not specified with the correct size.
2025-10-30 09:29:33 -07:00
Mathias Agopian
ea608d409e fix artifacts with screen space reflections (#9380)
on mobile h/w, strong highlights generated by the lighting stages can
turn into +inf and eventually to NaN if more math is performed on them.
Some h/w will kill a while tile or even primitive when that happens,
resulting in strong visual artifacts.

We fix this by clamping to MEDIUMP_FLT_MAX.
2025-10-29 17:00:49 -07:00
rafadevai
494e454f38 GL: Fix importing non srgb using the external image API (#9343)
* GL: Fix importing non srgb using the external image API

When importing a non srgb AHB but setting the srgb as true,
makes the eglCreateImageKHR function to fail because it tries
to set the colorspace as srgb for non srgb formats.

Example:
createExternalImage(yuv_ahardwaredbuffer, /*sRGB=*/true);

The fix is to only make sure that flag is set to true
if the corresponding filament format requires sRGB and
false otherwise.

* Fix mapToFilamentFormat to return the correct srgb formats

* fix build error on android

---------

Co-authored-by: Serge Metral <sergemetral@google.com>
2025-10-29 15:50:03 -07:00
Filament Bot
a9bbb0bf3b [automated] Updating /docs due to commit 21c7fa6
Full commit hash is 21c7fa6253

DOCS_ALLOW_DIRECT_EDITS
2025-10-29 18:13:20 +00:00
1220 changed files with 199826 additions and 23518 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
@@ -179,7 +179,7 @@ jobs:
fetch-depth: 0
- uses: ./.github/actions/linux-prereq
- name: Run build script
run: ./build.sh -W debug test_filamat filament
run: ./build.sh -W debug test_filamat filament gltf_viewer
- name: Run test
run: ./out/cmake-debug/libs/filamat/test_filamat --gtest_filter=MaterialCompiler.Wgsl*

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

@@ -62,6 +62,11 @@ force a clean build by adding the `-c` flag in that case.
To install the libraries and executables in `out/debug/` and `out/release/`, add the `-i` flag.
The script offers more features described by executing `build.sh -h`.
For more specialized options, please also consider the following pages:
- `-d`: [`matdbg`](https://google.github.io/filament/dup/matdbg.html)
- `-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
The following CMake options are boolean options specific to Filament:
@@ -237,6 +242,12 @@ foremost for `arm64-v8a`.
To build Android on Windows machines, see [android/Windows.md](android/Windows.md).
#### 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
@@ -246,8 +257,45 @@ 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.
#### 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

View File

@@ -58,6 +58,8 @@ option(FILAMENT_USE_ABSEIL_LOGGING "Use Abseil to log, may increase binary size"
option(FILAMENT_ENABLE_EXPERIMENTAL_GCC_SUPPORT "Enable GCC support (unsupported)" OFF)
option(FILAMENT_SUPPORTS_WEBP_TEXTURES "Enable webp texture support for Filament (builds libwebp when ON)" OFF)
# This is to disable GTAO for the short-term while we investigate a way to better manage size increases.
# On the regular filament build (where size is of less concern), we enable GTAO by default.
option(FILAMENT_DISABLE_GTAO "Disable GTAO" OFF)
@@ -365,14 +367,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()
@@ -471,7 +481,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.
@@ -561,6 +571,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)
@@ -753,12 +767,61 @@ function(combine_static_libs TARGET OUTPUT DEPS)
endfunction()
# ==================================================================================================
# Configuration for CMAKE_CROSSCOMPILING.
# Configuration importing/exporting prebuilt "/tools" executables
# ==================================================================================================
# In certain cases, we want the ability to separate the build type/flags (release, debug) of tools
# (matc, resgen, etc...) from filament. Cross compilation is one such case (e.g. building material
# with matc running on host while building filament for Android) [1]. Another example is when client
# wants to enable ASAN for filament but not the tool [2].
#
# Here are the varibles that are used to determine behavior is such flows:
# - CMAKE_CROSSCOMPILING : Set by cmake to indicate the build's target platform is different
# from the host platform.
# - IMPORT_EXECUTABLES_DIR : This is the directory containing the /ImportExecutables-type.cmake
# which are then included in other CMakeLists.txt to enable finding targets that have been
# prebuilt. This is set by the client in their `cmake` invocation.
# - IMPORT_EXECUTABLES : Path to a file to for 1) exporting the prebuilt targets or 2)
# importing a previously exported targets. (Used internally and should not be set by client).
# - FILAMENT_EXPORT_PREBUILT_EXECUTABLES_DIR : A path set by the client to indicate that
# they wish to export the tools as prebuilts, and the corresponding targets will be recorded
# in a cmake file (i.e IMPORT_EXECUTABLES). IMPORT_EXECUTABLES will be set relative to the the
# given path. This will set FILAMENT_EXPORT_PREBUILT_EXECUTABLES=ON.
# - FILAMENT_IMPORT_PREBUILT_EXECUTABLES_DIR : A path set by the client to indicate that they wish
# to import the tools as prebuilts from a .cmake file. The location (IMPORT_EXECUTABLES) of the
# file is relative to the path given. This will set FILAMENT_IMPORT_PREBUILT_EXECUTABLES=ON.
# - IMPORT_PREBUILT_EXECUTABLES and EXPORT_PREBUILT_EXECUTABLES are internal booleans set to
# ON based on the prescence of FILAMENT_IMPORT_PREBUILT_EXECUTABLES_DIR and
# FILAMENT_EXPORT_PREBUILT_EXECUTABLES_DIR.
#
# In conclusion, for cases
# - [1] (crosscompiling), the client must set IMPORT_EXECUTABLES_DIR for both when they are building
# the tools and when they are building the target-platform filament.
# - [2] (all other instances), the client must set FILAMENT_EXPORT_PREBUILT_EXECUTABLES_DIR in
# the prebuilt exporting step, and set FILAMENT_IMPORT_PREBUILT_EXECUTABLES_DIR in the importing
# step.
# TODO: Fold the cross compilation case into the more general FILAMENT_IMPORT/EXPORT variables.
if (FILAMENT_EXPORT_PREBUILT_EXECUTABLES_DIR)
set(FILAMENT_EXPORT_PREBUILT_EXECUTABLES ON)
set(IMPORT_EXECUTABLES_DIR ${FILAMENT_EXPORT_PREBUILT_EXECUTABLES_DIR})
endif()
if (FILAMENT_IMPORT_PREBUILT_EXECUTABLES_DIR)
set(FILAMENT_IMPORT_PREBUILT_EXECUTABLES ON)
set(IMPORT_EXECUTABLES_DIR ${FILAMENT_IMPORT_PREBUILT_EXECUTABLES_DIR})
endif()
if (WEBGL)
set(IMPORT_EXECUTABLES ${FILAMENT}/${IMPORT_EXECUTABLES_DIR}/ImportExecutables-Release.cmake)
else()
set(IMPORT_EXECUTABLES ${FILAMENT}/${IMPORT_EXECUTABLES_DIR}/ImportExecutables-${CMAKE_BUILD_TYPE}.cmake)
if (FILAMENT_EXPORT_PREBUILT_EXECUTABLES OR FILAMENT_IMPORT_PREBUILT_EXECUTABLES)
set(IMPORT_EXECUTABLES_BUILD_TYPE Prebuilt)
else()
set(IMPORT_EXECUTABLES_BUILD_TYPE ${CMAKE_BUILD_TYPE})
endif()
set(IMPORT_EXECUTABLES ${FILAMENT}/${IMPORT_EXECUTABLES_DIR}/ImportExecutables-${IMPORT_EXECUTABLES_BUILD_TYPE}.cmake)
endif()
# ==================================================================================================
@@ -821,7 +884,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)
@@ -835,7 +900,8 @@ 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.
add_subdirectory(${LIBRARIES}/geometry)
@@ -859,6 +925,10 @@ if (FILAMENT_ENABLE_FGVIEWER)
add_subdirectory(${LIBRARIES}/fgviewer)
endif()
if (FILAMENT_SUPPORTS_WEBP_TEXTURES)
add_subdirectory(${EXTERNAL}/libwebp/tnt)
endif()
if (FILAMENT_SUPPORTS_VULKAN)
add_subdirectory(${LIBRARIES}/bluevk)
add_subdirectory(${EXTERNAL}/vkmemalloc/tnt)
@@ -914,9 +984,10 @@ 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)
if (NOT CMAKE_CROSSCOMPILING)
if ((NOT CMAKE_CROSSCOMPILING AND NOT FILAMENT_IMPORT_PREBUILT_EXECUTABLES) OR FILAMENT_EXPORT_PREBUILT_EXECUTABLES)
export(TARGETS matc cmgen filamesh mipgen resgen uberz glslminifier FILE ${IMPORT_EXECUTABLES})
endif()

View File

@@ -31,7 +31,7 @@ repositories {
}
dependencies {
implementation 'com.google.android.filament:filament-android:1.66.2'
implementation 'com.google.android.filament:filament-android:1.68.4'
}
```
@@ -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.66.2'
pod 'Filament', '~> 1.68.4'
```
## Documentation

View File

@@ -7,6 +7,39 @@ 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.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)
- Metal: report GPU errors to the platform via `debugUpdateStat` (b/431665753).
- materials: Make Material Instances' UBO descriptor use dynamic offsets. [⚠️ **Recompile Materials**]
## v1.67.1
- Metal: Add support for the `SwapChain::CONFIG_MSAA_4_SAMPLES` flag.
- third_party: Optionally add libwebp to build
- controlled by cmake flag FILAMENT_SUPPORTS_WEBP_TEXTURES, defaults to OFF
- actual webp texture support for libs/gltfio coming in subsequent change
## v1.67.0
- materials: Add a new API getParameterTransformName that will return the value of the transformName field of a sampler

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",

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

@@ -51,10 +51,6 @@ add_library(bluevk STATIC IMPORTED)
set_target_properties(bluevk PROPERTIES IMPORTED_LOCATION
${FILAMENT_DIR}/lib/${ANDROID_ABI}/libbluevk.a)
add_library(vkshaders STATIC IMPORTED)
set_target_properties(vkshaders PROPERTIES IMPORTED_LOCATION
${FILAMENT_DIR}/lib/${ANDROID_ABI}/libvkshaders.a)
if (FILAMENT_SUPPORTS_WEBGPU)
add_library(webgpu_dawn STATIC IMPORTED)
set_target_properties(webgpu_dawn PROPERTIES IMPORTED_LOCATION
@@ -138,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.
@@ -165,10 +162,15 @@ target_link_libraries(filament-jni
PRIVATE $<$<STREQUAL:${FILAMENT_ENABLE_MATDBG},ON>:matdbg>
PRIVATE $<$<STREQUAL:${FILAMENT_ENABLE_MATDBG},ON>:filamat>
PRIVATE $<$<STREQUAL:${FILAMENT_SUPPORTS_VULKAN},ON>:bluevk>
PRIVATE $<$<STREQUAL:${FILAMENT_SUPPORTS_VULKAN},ON>:vkshaders>
PRIVATE $<$<STREQUAL:${FILAMENT_SUPPORTS_VULKAN},ON>:smol-v>
PRIVATE $<$<STREQUAL:${FILAMENT_SUPPORTS_WEBGPU},ON>:webgpu_dawn>
)
# 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

@@ -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

@@ -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

@@ -147,6 +147,15 @@ Java_com_google_android_filament_View_nSetDynamicResolutionOptions(JNIEnv*, jcla
view->setDynamicResolutionOptions(options);
}
extern "C" JNIEXPORT void JNICALL
Java_com_google_android_filament_View_nGetLastDynamicResolutionScale(JNIEnv *env, jclass, jlong nativeView, jfloatArray out_) {
jfloat* out = env->GetFloatArrayElements(out_, nullptr);
View *view = (View *) nativeView;
math::float2 result = view->getLastDynamicResolutionScale();
std::copy_n(result.v, 2, out);
env->ReleaseFloatArrayElements(out_, out, 0);
}
extern "C" JNIEXPORT void JNICALL
Java_com_google_android_filament_View_nSetShadowType(JNIEnv*, jclass, jlong nativeView, jint type) {
View* view = (View*) nativeView;

View File

@@ -99,6 +99,15 @@ final class Asserts {
}
}
@NonNull @Size(min = 2)
static float[] assertFloat2(@Nullable float[] out) {
if (out == null) out = new float[2];
else if (out.length < 2) {
throw new ArrayIndexOutOfBoundsException("Array length must be at least 2");
}
return out;
}
@NonNull @Size(min = 4)
static float[] assertFloat4(@Nullable float[] out) {
if (out == null) out = new float[4];

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

@@ -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

@@ -25,7 +25,6 @@ import java.util.EnumSet;
import static com.google.android.filament.Asserts.assertFloat3In;
import static com.google.android.filament.Asserts.assertFloat4In;
import static com.google.android.filament.Colors.LinearColor;
import com.google.android.filament.proguard.UsedByNative;
@@ -674,6 +673,21 @@ public class View {
return mDynamicResolution;
}
/**
* Returns the last dynamic resolution scale factor used by this view. This value is updated
* when Renderer::render(View*) is called
* @param out A 2-float array where the value will be stored, or null in which case the array is
* allocated.
* @return A 2-float array containing the horizontal and the vertical scale factors
* @see Renderer#render(View)
*/
@NonNull @Size(min = 2)
public float[] getLastDynamicResolutionScale(@Nullable @Size(min = 2) float[] out) {
out = Asserts.assertFloat2(out);
nGetLastDynamicResolutionScale(getNativeObject(), out);
return out;
}
/**
* Sets the rendering quality for this view (e.g. color precision).
*
@@ -1317,6 +1331,7 @@ public class View {
private static native void nSetDithering(long nativeView, int dithering);
private static native int nGetDithering(long nativeView);
private static native void nSetDynamicResolutionOptions(long nativeView, boolean enabled, boolean homogeneousScaling, float minScale, float maxScale, float sharpness, int quality);
private static native void nGetLastDynamicResolutionScale(long nativeView, float[] out);
private static native void nSetRenderQuality(long nativeView, int hdrColorBufferQuality);
private static native void nSetDynamicLightingOptions(long nativeView, float zLightNear, float zLightFar);
private static native void nSetShadowType(long nativeView, int type);
@@ -2026,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
*/
@@ -2060,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;
/**
@@ -2080,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
*/
@@ -2095,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
*/

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

@@ -40,7 +40,21 @@ fun loadTexture(engine: Engine, resources: Resources, resourceId: Int, type: Tex
options.inPremultiplied = type == TextureType.COLOR
val bitmap = BitmapFactory.decodeResource(resources, resourceId, options)
return buildTexture(engine, bitmap, type)
}
fun loadTexture(engine: Engine, bytes: ByteArray, type: TextureType, offset: Int = 0, length: Int = bytes.size): Texture {
val options = BitmapFactory.Options()
// Color is the only type of texture we want to pre-multiply with the alpha channel
// Pre-multiplication is the default behavior, so we need to turn it off here
options.inPremultiplied = type == TextureType.COLOR
val bitmap = BitmapFactory.decodeByteArray(bytes, offset, length, options)
return buildTexture(engine, bitmap, type)
}
private fun buildTexture(engine: Engine, bitmap: Bitmap, type: TextureType): Texture {
val texture = Texture.Builder()
.width(bitmap.width)
.height(bitmap.height)

View File

@@ -22,6 +22,7 @@ object Utils {
/**
* Initializes the utils JNI layer. Must be called before using any utils functionality.
*/
@JvmStatic
fun init() {
// Load Filament first to ensure that the NioUtils Java class is available in the JNIEnv.
Filament.init()

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.66.2
VERSION_NAME=1.68.4
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

@@ -17,12 +17,20 @@ filamentTools {
}
// don't forget to update MainACtivity.kt when/if changing this.
tasks.register('copyMesh', Copy) {
tasks.register('copyDamagedHelmetGltf', Copy) {
from file("../../../third_party/models/DamagedHelmet/DamagedHelmet.glb")
into file("src/main/assets/models")
rename {String fileName -> "helmet.glb"}
}
// don't forget to update MainACtivity.kt when/if changing this.
tasks.register('copyBusterGltf', Copy) {
from "../../../third_party/models/BusterDrone"
into "src/main/assets/models"
}
preBuild.dependsOn copyMesh
preBuild.dependsOn copyDamagedHelmetGltf
preBuild.dependsOn copyBusterGltf
clean.doFirst {
delete "src/main/assets"

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,52 @@
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.materialinstancestress'
compileSdkVersion versions.compileSdk
defaultConfig {
applicationId "com.google.android.filament.materialinstancestress"
minSdkVersion versions.minSdk
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,532 @@
/*
* Copyright (C) 2025 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.materialinstancestress
import android.animation.ValueAnimator
import android.app.Activity
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.*
import com.google.android.filament.VertexBuffer.*
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.cos
import kotlin.math.sin
class MainActivity : Activity() {
// Make sure to initialize Filament first
// This loads the JNI library needed by most API calls
companion object {
init {
Filament.init()
}
private const val NUM_CUBES = 1000
private const val GRID_SIZE = 10
private const val SPACING = 2.5f
}
// The View we want to render into
private lateinit var surfaceView: SurfaceView
// UiHelper is provided by Filament to manage SurfaceView and SurfaceTexture
private lateinit var uiHelper: UiHelper
// DisplayHelper is provided by Filament to manage the display
private lateinit var displayHelper: DisplayHelper
// Choreographer is used to schedule new frames
private lateinit var choreographer: Choreographer
// Engine creates and destroys Filament resources
// Each engine must be accessed from a single thread of your choosing
// Resources cannot be shared across engines
private lateinit var engine: Engine
// A renderer instance is tied to a single surface (SurfaceView, TextureView, etc.)
private lateinit var renderer: Renderer
// A scene holds all the renderable, lights, etc. to be drawn
private lateinit var scene: Scene
// A view defines a viewport, a scene and a camera for rendering
private lateinit var view: View
// Should be pretty obvious :)
private lateinit var camera: Camera
private lateinit var material: Material
private lateinit var vertexBuffer: VertexBuffer
private lateinit var indexBuffer: IndexBuffer
// Filament entity representing a renderable object
@Entity private val renderables = IntArray(NUM_CUBES)
private val materialInstances = arrayOfNulls<MaterialInstance>(NUM_CUBES)
private val translationMatrices = Array(NUM_CUBES) { FloatArray(16) }
@Entity private var light = 0
// A swap chain is Filament's representation of a surface
private var swapChain: SwapChain? = null
private var cameraRadius = 42.7f // Initial distance (calculated from original 15Y, 40Z)
private var cameraTheta = 0.0f // Azimuth (horizontal) in radians
private var cameraPhi = 0.358f // Elevation (vertical) in radians (from original 15Y, 40Z)
private var mLastX = 0.0f
private var mLastY = 0.0f
private val DRAG_SPEED = 0.005f
// Performs the rendering and schedules new frames
private val frameScheduler = FrameCallback()
private val animator = ValueAnimator.ofFloat(0.0f, 360.0f)
private val animatorListener = object : ValueAnimator.AnimatorUpdateListener {
// Pre-allocate matrix to avoid GC churn
private val transformMatrix = FloatArray(16)
override fun onAnimationUpdate(a: ValueAnimator) {
val tcm = engine.transformManager
val time = a.animatedFraction // 0.0 to 1.0
// Calculate the sine wave scale factor.
// sin(time * 2 * PI) oscillates between -1.0 and 1.0.
// We multiply by 0.5f (so it's -0.5 to 0.5) and add 1.0f.
// This makes the final 'scale' oscillate between 0.5 and 1.5.
val scale = 1.0f + sin(time * 2.0 * Math.PI).toFloat() * 0.5f
val localScale = (scale - 0.5f) * 0.5f + 0.5f
for (i in 0 until NUM_CUBES) {
val inst = tcm.getInstance(renderables[i])
val materialInst = materialInstances[i] ?: continue
// Get the cube's base position from its stored matrix
// The translation is in elements 12 (x), 13 (y), and 14 (z)
val baseX = translationMatrices[i][12]
val baseY = translationMatrices[i][13]
val baseZ = translationMatrices[i][14]
// Set the transformMatrix to a new translation matrix,
// scaled from the center (0,0,0)
Matrix.setIdentityM(transformMatrix, 0)
Matrix.translateM(transformMatrix, 0,
baseX * scale,
baseY * scale,
baseZ * scale)
Matrix.scaleM(transformMatrix, 0, localScale, localScale, localScale)
tcm.setTransform(inst, transformMatrix)
// Vary roughness
val roughness = 0.5f + 0.5f * sin(time * 2.0 * Math.PI + i * 0.1).toFloat()
materialInst.setParameter("roughness", roughness)
// Vary color (using linear RGB)
val r = 0.5f + 0.5f * cos(time * 2.0 * Math.PI + i * 0.5).toFloat()
val g = 0.5f + 0.5f * sin(time * 2.0 * Math.PI + i * 0.3).toFloat()
val b = 0.5f + 0.5f * cos(time * 2.0 * Math.PI + i * 0.1).toFloat()
materialInst.setParameter("baseColor", Colors.RgbType.LINEAR, r, g, b)
}
}
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
surfaceView = SurfaceView(this)
setContentView(surfaceView)
surfaceView.setOnTouchListener(touchListener)
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())
}
private fun setupView() {
scene.skybox = Skybox.Builder().color(0.035f, 0.035f, 0.035f, 1.0f).build(engine)
view.camera = camera
view.scene = scene
}
private fun setupScene() {
loadMaterial()
createMesh()
val tcm = engine.transformManager
val center = (GRID_SIZE - 1) * 0.5f
for (i in 0 until NUM_CUBES) {
// Calculate grid position
val x = (i % GRID_SIZE) - center
val y = ((i / GRID_SIZE) % GRID_SIZE) - center
val z = (i / (GRID_SIZE * GRID_SIZE)) - center
val posX = x * SPACING
val posY = y * SPACING
val posZ = z * SPACING
// Create material instance for this cube
materialInstances[i] = material.createInstance()
// Set initial parameters (will be overwritten by animator, but good practice)
materialInstances[i]?.setParameter("baseColor", Colors.RgbType.SRGB, 1.0f, 0.85f, 0.57f)
materialInstances[i]?.setParameter("metallic", 0.0f)
materialInstances[i]?.setParameter("roughness", 0.3f)
// Create the renderable entity
renderables[i] = EntityManager.get().create()
// Create the renderable component
RenderableManager.Builder(1)
.boundingBox(Box(0.0f, 0.0f, 0.0f, 1.0f, 1.0f, 1.0f))
.geometry(0, PrimitiveType.TRIANGLES, vertexBuffer, indexBuffer, 0, 6 * 6)
.material(0, materialInstances[i]!!)
.build(engine, renderables[i])
// Add to scene
scene.addEntity(renderables[i])
// Set its initial transform
// Store the base translation matrix
Matrix.setIdentityM(translationMatrices[i], 0)
Matrix.translateM(translationMatrices[i], 0, posX, posY, posZ)
// Get the transform component instance
val inst = tcm.getInstance(renderables[i])
tcm.setTransform(inst, translationMatrices[i])
}
// We now need a light, let's create a directional light
light = EntityManager.get().create()
val (r, g, b) = Colors.cct(5_500.0f)
LightManager.Builder(LightManager.Type.DIRECTIONAL)
.color(r, g, b)
.intensity(110_000.0f)
.direction(0.0f, -0.5f, -1.0f)
.castShadows(true)
.build(engine, light)
scene.addEntity(light)
camera.setExposure(16.0f, 1.0f / 125.0f, 100.0f)
updateCamera()
startAnimation()
}
private fun loadMaterial() {
readUncompressedAsset("materials/lit.filamat").let {
material = Material.Builder().payload(it, it.remaining()).build(engine)
}
}
private fun createMesh() {
val floatSize = 4
val shortSize = 2
val vertexSize = 3 * floatSize + 4 * floatSize
// A vertex is a position + a tangent frame:
// 3 floats for XYZ position, 4 floats for normal+tangents (quaternion)
@Suppress("ArrayInDataClass")
data class Vertex(val x: Float, val y: Float, val z: Float, val tangents: FloatArray)
fun ByteBuffer.put(v: Vertex): ByteBuffer {
putFloat(v.x)
putFloat(v.y)
putFloat(v.z)
v.tangents.forEach { putFloat(it) }
return this
}
// 6 faces, 4 vertices per face
val vertexCount = 6 * 4
// Create tangent frames, one per face
val tfPX = FloatArray(4)
val tfNX = FloatArray(4)
val tfPY = FloatArray(4)
val tfNY = FloatArray(4)
val tfPZ = FloatArray(4)
val tfNZ = FloatArray(4)
MathUtils.packTangentFrame( 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, -1.0f, 1.0f, 0.0f, 0.0f, tfPX)
MathUtils.packTangentFrame( 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, -1.0f, -1.0f, 0.0f, 0.0f, tfNX)
MathUtils.packTangentFrame(-1.0f, 0.0f, 0.0f, 0.0f, 0.0f, -1.0f, 0.0f, 1.0f, 0.0f, tfPY)
MathUtils.packTangentFrame(-1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, -1.0f, 0.0f, tfNY)
MathUtils.packTangentFrame( 0.0f, 1.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, tfPZ)
MathUtils.packTangentFrame( 0.0f, -1.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, -1.0f, tfNZ)
val vertexData = ByteBuffer.allocate(vertexCount * vertexSize)
// It is important to respect the native byte order
.order(ByteOrder.nativeOrder())
// Face -Z
.put(Vertex(-1.0f, -1.0f, -1.0f, tfNZ))
.put(Vertex(-1.0f, 1.0f, -1.0f, tfNZ))
.put(Vertex( 1.0f, 1.0f, -1.0f, tfNZ))
.put(Vertex( 1.0f, -1.0f, -1.0f, tfNZ))
// Face +X
.put(Vertex( 1.0f, -1.0f, -1.0f, tfPX))
.put(Vertex( 1.0f, 1.0f, -1.0f, tfPX))
.put(Vertex( 1.0f, 1.0f, 1.0f, tfPX))
.put(Vertex( 1.0f, -1.0f, 1.0f, tfPX))
// Face +Z
.put(Vertex(-1.0f, -1.0f, 1.0f, tfPZ))
.put(Vertex( 1.0f, -1.0f, 1.0f, tfPZ))
.put(Vertex( 1.0f, 1.0f, 1.0f, tfPZ))
.put(Vertex(-1.0f, 1.0f, 1.0f, tfPZ))
// Face -X
.put(Vertex(-1.0f, -1.0f, 1.0f, tfNX))
.put(Vertex(-1.0f, 1.0f, 1.0f, tfNX))
.put(Vertex(-1.0f, 1.0f, -1.0f, tfNX))
.put(Vertex(-1.0f, -1.0f, -1.0f, tfNX))
// Face -Y
.put(Vertex(-1.0f, -1.0f, 1.0f, tfNY))
.put(Vertex(-1.0f, -1.0f, -1.0f, tfNY))
.put(Vertex( 1.0f, -1.0f, -1.0f, tfNY))
.put(Vertex( 1.0f, -1.0f, 1.0f, tfNY))
// Face +Y
.put(Vertex(-1.0f, 1.0f, -1.0f, tfPY))
.put(Vertex(-1.0f, 1.0f, 1.0f, tfPY))
.put(Vertex( 1.0f, 1.0f, 1.0f, tfPY))
.put(Vertex( 1.0f, 1.0f, -1.0f, tfPY))
// Make sure the cursor is pointing in the right place in the byte buffer
.flip()
// Declare the layout of our mesh
vertexBuffer = VertexBuffer.Builder()
.bufferCount(1)
.vertexCount(vertexCount)
// Because we interleave position and color data we must specify offset and stride
// We could use de-interleaved data by declaring two buffers and giving each
// attribute a different buffer index
.attribute(VertexAttribute.POSITION, 0, AttributeType.FLOAT3, 0, vertexSize)
.attribute(VertexAttribute.TANGENTS, 0, AttributeType.FLOAT4, 3 * floatSize, vertexSize)
.build(engine)
// Feed the vertex data to the mesh
// We only set 1 buffer because the data is interleaved
vertexBuffer.setBufferAt(engine, 0, vertexData)
// Create the indices
val indexData = ByteBuffer.allocate(6 * 2 * 3 * shortSize)
.order(ByteOrder.nativeOrder())
repeat(6) {
val i = (it * 4).toShort()
indexData
.putShort(i).putShort((i + 1).toShort()).putShort((i + 2).toShort())
.putShort(i).putShort((i + 2).toShort()).putShort((i + 3).toShort())
}
indexData.flip()
// 6 faces, 2 triangles per face,
indexBuffer = IndexBuffer.Builder()
.indexCount(vertexCount * 2)
.bufferType(IndexBuffer.Builder.IndexType.USHORT)
.build(engine)
indexBuffer.setBuffer(engine, indexData)
}
private fun updateCamera() {
// Calculate eye position from spherical coordinates
val eyeY = cameraRadius * sin(cameraPhi)
val horizontalRadius = cameraRadius * cos(cameraPhi)
val eyeX = horizontalRadius * sin(cameraTheta)
val eyeZ = horizontalRadius * cos(cameraTheta)
// Point the camera at the center (0,0,0)
camera.lookAt(eyeX.toDouble(), eyeY.toDouble(), eyeZ.toDouble(), // eye
0.0, 0.0, 0.0, // center
0.0, 1.0, 0.0) // up
}
private val touchListener = object : android.view.View.OnTouchListener {
override fun onTouch(v: android.view.View?, event: android.view.MotionEvent?): Boolean {
if (event == null) return false
when (event.action) {
android.view.MotionEvent.ACTION_DOWN -> {
mLastX = event.x
mLastY = event.y
return true
}
android.view.MotionEvent.ACTION_MOVE -> {
val dx = event.x - mLastX
val dy = event.y - mLastY
cameraTheta -= dx * DRAG_SPEED
cameraPhi += dy * DRAG_SPEED
// Clamp vertical angle to avoid flipping over
cameraPhi = cameraPhi.coerceIn(-1.5f, 1.5f)
updateCamera()
mLastX = event.x
mLastY = event.y
return true
}
}
return v?.onTouchEvent(event) ?: false
}
}
private fun startAnimation() {
animator.interpolator = LinearInterpolator()
animator.duration = 6000
animator.repeatMode = ValueAnimator.RESTART
animator.repeatCount = ValueAnimator.INFINITE
animator.addUpdateListener(animatorListener)
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()
// Stop the animation and any pending frame
choreographer.removeFrameCallback(frameScheduler)
animator.cancel();
// Always detach the surface before destroying the engine
uiHelper.detach()
// Cleanup all resources
engine.destroyEntity(light)
// Destroy all 1000 entities and material instances
for (i in 0 until NUM_CUBES) {
engine.destroyEntity(renderables[i])
materialInstances[i]?.let { engine.destroyMaterialInstance(it) }
}
engine.destroyRenderer(renderer)
engine.destroyVertexBuffer(vertexBuffer)
engine.destroyIndexBuffer(indexBuffer)
engine.destroyMaterial(material)
engine.destroyView(view)
engine.destroyScene(scene)
engine.destroyCameraComponent(camera.entity)
// Engine.destroyEntity() destroys Filament related resources only
// (components), not the entity itself
val entityManager = EntityManager.get()
entityManager.destroy(light)
for (entity in renderables) {
entityManager.destroy(entity)
}
entityManager.destroy(camera.entity)
// Destroying the engine will free up any resource you may have forgotten
// to destroy, but it's recommended to do the cleanup properly
engine.destroy()
}
inner class FrameCallback : Choreographer.FrameCallback {
override fun doFrame(frameTimeNanos: Long) {
// Schedule the next frame
choreographer.postFrameCallback(this)
// This check guarantees that we have a swap chain
if (uiHelper.isReadyToRender) {
// If beginFrame() returns false you should skip the frame
// This means you are sending frames too quickly to the GPU
if (renderer.beginFrame(swapChain!!, frameTimeNanos)) {
renderer.render(view)
renderer.endFrame()
}
}
}
}
inner class SurfaceCallback : UiHelper.RendererCallback {
override fun onNativeWindowChanged(surface: Surface) {
swapChain?.let { engine.destroySwapChain(it) }
swapChain = engine.createSwapChain(surface)
displayHelper.attach(renderer, surfaceView.display)
}
override fun onDetachedFromSurface() {
displayHelper.detach()
swapChain?.let {
engine.destroySwapChain(it)
// Required to ensure we don't return before Filament is done executing the
// destroySwapChain command, otherwise Android might destroy the Surface
// too early
engine.flushAndWait()
swapChain = null
}
}
override fun onResized(width: Int, height: Int) {
val aspect = width.toDouble() / height.toDouble()
camera.setProjection(45.0, aspect, 0.1, 100.0, Camera.Fov.VERTICAL)
view.viewport = Viewport(0, 0, width, height)
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,53 @@
// Simple lit material that defines 3 parameters:
// - baseColor
// - roughness
// - metallic
//
// These parameters can be used by the application to change the appearance of the material.
//
// This source material must be compiled to a binary material using the matc tool.
// The command used to compile this material is:
// matc -p mobile -a opengl -o app/src/main/assets/lit.filamat app/src/materials/lit.mat
//
// See build.gradle for an example of how to compile materials automatically
// Please refer to the documentation for more information about matc and the materials system.
material {
name : lit,
// Dynamic lighting is enabled on this material
shadingModel : lit,
// We don't need to declare a "requires" array, lit materials
// always requires the "tangents" vertex attribute (the normal
// is required for lighting, tangent/bitangent for normal mapping
// and anisotropy)
// List of parameters exposed by this material
parameters : [
// The color must be passed in linear space, not sRGB
{
type : float3,
name : baseColor
},
{
type : float,
name : roughness
},
{
type : float,
name : metallic
}
],
}
fragment {
void material(inout MaterialInputs material) {
prepareMaterial(material);
// Nothing fancy here, we simply copy the parameters
material.baseColor.rgb = materialParams.baseColor;
material.roughness = materialParams.roughness;
material.metallic = materialParams.metallic;
}
}

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">Material Instance Stress</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

@@ -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

@@ -12,10 +12,12 @@ include ':samples:sample-image-based-lighting'
include ':samples:sample-lit-cube'
include ':samples:sample-live-wallpaper'
include ':samples:sample-material-builder'
include ':samples:sample-material-instance-stress'
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

@@ -77,6 +77,10 @@ function print_help {
echo " meant for building the samples."
echo " -P"
echo " Enable perfetto traces on Android. Disabled by default on the Release build, enabled otherwise."
echo " -y build_type"
echo " Build the filament dependent tools (matc, resgen) separately from the project. This will set"
echo " the tools as prebuilts that filament target will then use to build. The built_type option"
echo " (debug|release) is meant to indicate the type of build of the resulting prebuilts."
echo ""
echo "Build types:"
echo " release"
@@ -154,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
@@ -217,6 +221,11 @@ OSMESA_OPTION=""
IOS_BUILD_SIMULATOR=false
BUILD_UNIVERSAL_LIBRARIES=false
ISSUE_SPLIT_BUILD=false
SPLIT_BUILD_TYPE=""
PREBUILT_TOOLS_DIR=""
IMPORT_EXECUTABLES_DIR_OPTION="-DIMPORT_EXECUTABLES_DIR=out"
BUILD_GENERATOR=Ninja
BUILD_COMMAND=ninja
BUILD_CUSTOM_TARGETS=
@@ -242,6 +251,37 @@ function build_clean_aggressive {
git clean -qfX android
}
function build_tools_for_split_build {
local build_type_arg=$1
local lc_build_type=$(echo "${build_type_arg}" | tr '[:upper:]' '[:lower:]')
PREBUILT_TOOLS_DIR="out/prebuilt-tools-${lc_build_type}"
echo "Building tools for split build (${lc_build_type}) in ${PREBUILT_TOOLS_DIR}..."
mkdir -p "${PREBUILT_TOOLS_DIR}"
pushd "${PREBUILT_TOOLS_DIR}" > /dev/null
local lc_name=$(echo "${UNAME}" | tr '[:upper:]' '[:lower:]')
local architectures=""
if [[ "${lc_name}" == "darwin" ]]; then
if [[ "${BUILD_UNIVERSAL_LIBRARIES}" == "true" ]]; then
architectures="-DCMAKE_OSX_ARCHITECTURES=arm64;x86_64"
fi
fi
cmake \
-G "${BUILD_GENERATOR}" \
-DFILAMENT_EXPORT_PREBUILT_EXECUTABLES_DIR=${PREBUILT_TOOLS_DIR} \
-DCMAKE_BUILD_TYPE="${build_type_arg}" \
${WEBGPU_OPTION} \
${architectures} \
../..
${BUILD_COMMAND} ${WEB_HOST_TOOLS}
popd > /dev/null
}
function build_desktop_target {
local lc_target=$(echo "$1" | tr '[:upper:]' '[:lower:]')
local build_targets=$2
@@ -265,7 +305,7 @@ function build_desktop_target {
if [[ ! -d "CMakeFiles" ]] || [[ "${ISSUE_CMAKE_ALWAYS}" == "true" ]]; then
cmake \
-G "${BUILD_GENERATOR}" \
-DIMPORT_EXECUTABLES_DIR=out \
${IMPORT_EXECUTABLES_DIR_OPTION} \
-DCMAKE_BUILD_TYPE="$1" \
-DCMAKE_INSTALL_PREFIX="../${lc_target}/filament" \
${EGL_ON_LINUX_OPTION} \
@@ -331,7 +371,7 @@ function build_webgl_with_target {
source "${EMSDK}/emsdk_env.sh"
cmake \
-G "${BUILD_GENERATOR}" \
-DIMPORT_EXECUTABLES_DIR=out \
${IMPORT_EXECUTABLES_DIR_OPTION} \
-DCMAKE_TOOLCHAIN_FILE="${EMSDK}/upstream/emscripten/cmake/Modules/Platform/Emscripten.cmake" \
-DCMAKE_BUILD_TYPE="$1" \
-DCMAKE_INSTALL_PREFIX="../webgl-${lc_target}/filament" \
@@ -404,7 +444,7 @@ function build_android_target {
if [[ ! -d "CMakeFiles" ]] || [[ "${ISSUE_CMAKE_ALWAYS}" == "true" ]]; then
cmake \
-G "${BUILD_GENERATOR}" \
-DIMPORT_EXECUTABLES_DIR=out \
${IMPORT_EXECUTABLES_DIR_OPTION} \
-DCMAKE_BUILD_TYPE="$1" \
-DFILAMENT_NDK_VERSION="${FILAMENT_NDK_VERSION}" \
-DCMAKE_INSTALL_PREFIX="../android-${lc_target}/filament" \
@@ -516,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} \
@@ -533,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
@@ -541,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
@@ -573,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} \
@@ -585,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
@@ -593,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
@@ -638,7 +686,7 @@ function build_ios_target {
if [[ ! -d "CMakeFiles" ]] || [[ "${ISSUE_CMAKE_ALWAYS}" == "true" ]]; then
cmake \
-G "${BUILD_GENERATOR}" \
-DIMPORT_EXECUTABLES_DIR=out \
${IMPORT_EXECUTABLES_DIR_OPTION} \
-DCMAKE_BUILD_TYPE="$1" \
-DCMAKE_INSTALL_PREFIX="../ios-${lc_target}/filament" \
-DIOS_ARCH="${arch}" \
@@ -810,7 +858,7 @@ function check_debug_release_build {
pushd "$(dirname "$0")" > /dev/null
while getopts ":hacCfgimp:q:uvWslwedtk:bVx:S:X:P" opt; do
while getopts ":hacCfgimp:q:uvWslwedtk:bVx:S:X:Py:" opt; do
case ${opt} in
h)
print_help
@@ -979,6 +1027,20 @@ while getopts ":hacCfgimp:q:uvWslwedtk:bVx:S:X:P" opt; do
;;
X) OSMESA_OPTION="-DFILAMENT_OSMESA_PATH=${OPTARG}"
;;
y)
ISSUE_SPLIT_BUILD=true
SPLIT_BUILD_TYPE=${OPTARG}
case $(echo "${SPLIT_BUILD_TYPE}" | tr '[:upper:]' '[:lower:]') in
debug|release)
;;
*)
echo "Unknown build type for -y: ${SPLIT_BUILD_TYPE}"
echo "Build type must be one of [debug|release]"
echo ""
exit 1
;;
esac
;;
\?)
echo "Invalid option: -${OPTARG}" >&2
echo ""
@@ -1013,6 +1075,13 @@ done
validate_build_command
if [[ "${ISSUE_SPLIT_BUILD}" == "true" ]]; then
# Capitalize first letter of SPLIT_BUILD_TYPE
SPLIT_BUILD_TYPE_CAPITALIZED="$(echo ${SPLIT_BUILD_TYPE:0:1} | tr '[:lower:]' '[:upper:]')${SPLIT_BUILD_TYPE:1}"
build_tools_for_split_build "${SPLIT_BUILD_TYPE_CAPITALIZED}"
IMPORT_EXECUTABLES_DIR_OPTION="-DFILAMENT_IMPORT_PREBUILT_EXECUTABLES_DIR=${PREBUILT_TOOLS_DIR}"
fi
if [[ "${ISSUE_CLEAN}" == "true" ]]; then
build_clean
fi

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>

View File

@@ -180,7 +180,7 @@ rm -r Vulkan-Headers-1.3.232 v1.3.232.zip
<i class="fa fa-angle-left"></i>
</a>
<a rel="next prefetch" href="../dup/filamat.html" class="mobile-nav-chapters next" title="Next chapter" aria-label="Next chapter" aria-keyshortcuts="Right">
<a rel="next prefetch" href="../dup/fgviewer.html" class="mobile-nav-chapters next" title="Next chapter" aria-label="Next chapter" aria-keyshortcuts="Right">
<i class="fa fa-angle-right"></i>
</a>
@@ -194,7 +194,7 @@ rm -r Vulkan-Headers-1.3.232 v1.3.232.zip
<i class="fa fa-angle-left"></i>
</a>
<a rel="next prefetch" href="../dup/filamat.html" class="nav-chapters next" title="Next chapter" aria-label="Next chapter" aria-keyshortcuts="Right">
<a rel="next prefetch" href="../dup/fgviewer.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

@@ -200,6 +200,12 @@ inside the Filament source tree.</p>
force a clean build by adding the <code>-c</code> flag in that case.</p>
<p>To install the libraries and executables in <code>out/debug/</code> and <code>out/release/</code>, add the <code>-i</code> flag.
The script offers more features described by executing <code>build.sh -h</code>.</p>
<p>For more specialized options, please also consider the following pages:</p>
<ul>
<li><code>-d</code>: <a href="https://google.github.io/filament/dup/matdbg.html"><code>matdbg</code></a></li>
<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>
<p>The following CMake options are boolean options specific to Filament:</p>
<ul>
@@ -321,12 +327,41 @@ 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="important-sdk-location"><a class="header" href="#important-sdk-location">Important: SDK location</a></h4>
<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>
<h4 id="easy-android-build"><a class="header" href="#easy-android-build">Easy Android build</a></h4>
<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="android-studio"><a class="header" href="#android-studio">Android Studio</a></h4>
<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>
<h4 id="manual-builds"><a class="header" href="#manual-builds">Manual builds</a></h4>
<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>

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>

345
docs/dup/fgviewer.html Normal file
View File

@@ -0,0 +1,345 @@
<!DOCTYPE HTML>
<html lang="en" class="light sidebar-visible" dir="ltr">
<head>
<!-- Book generated using mdBook -->
<meta charset="UTF-8">
<title>fgviewer - 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="fgviewer"><a class="header" href="#fgviewer">fgviewer</a></h1>
<ol>
<li><a href="#capabilities">Capabilities</a></li>
<li><a href="#setup-for-desktop">Setup for Desktop</a></li>
<li><a href="#setup-for-android">Setup for Android</a></li>
<li><a href="#debugger-usage">Debugger Usage</a></li>
<li><a href="#architecture-overview">Architecture Overview</a></li>
<li><a href="#c-server">C++ Server</a></li>
<li><a href="#javascript-client">JavaScript Client</a></li>
<li><a href="#http-requests">HTTP Requests</a></li>
<li><a href="#wish-list">Wish List</a></li>
</ol>
<h2 id="capabilities"><a class="header" href="#capabilities">Capabilities</a></h2>
<p>fgviewer is a library and web application for real-time visualization of the frame graph in Filament.
It displays active passes and resource usage, providing insights into the rendering pipeline.</p>
<h2 id="setup-for-desktop"><a class="header" href="#setup-for-desktop">Setup for Desktop</a></h2>
<p>When using the easy build script, include the <code>-t</code> argument. For example:</p>
<pre><code>./build.sh -ft debug gltf_viewer
</code></pre>
<p>The <code>t</code> enables a CMake option called <code>FILAMENT_ENABLE_FGVIEWER</code> and the <code>f</code> ensures that CMake gets
re-run so that the option is honored.</p>
<p>Next, set an environment variable as follows. In Windows, use <code>set</code> instead of <code>export</code>.</p>
<pre><code>export FILAMENT_FGVIEWER_PORT=8050
</code></pre>
<p>Next, launch any app that links against a debug build of a Filament and point your web browser to
http://localhost:8050. Skip ahead to <strong>Debugger Usage</strong>.</p>
<h2 id="setup-for-android"><a class="header" href="#setup-for-android">Setup for Android</a></h2>
<p>Rebuild Filament for Android after enabling a CMake option called <code>FILAMENT_ENABLE_FGVIEWER</code>. Note that
CMake is invoked from several places for Android (both gradle and our easy build script), so one
pragmatic and reliable way of doing this is to simply hack <code>CMakeLists.txt</code> and
<code>filament-android/CMakeLists.txt</code> by unconditionally setting <code>FILAMENT_ENABLE_FGVIEWER</code> to <code>ON</code>.</p>
<p>After rebuilding Filament with the option enabled, ensure that internet permissions are enabled in
your app by adding the following into your manifest as a child of the <code>&lt;manifest&gt;</code> element.</p>
<pre><code>&lt;uses-permission android:name="android.permission.INTERNET" /&gt;
</code></pre>
<p>Now launch your app as usual. The Filament Engine sets up a server that is hardcoded to listen to
port <code>8085</code>. Next, you will need to forward your device's TCP port <code>8085</code> to your host port of choice.
For example, to forward the fgviewer server on your device to port <code>8085</code> on your host machine, do the
following:</p>
<pre><code>adb forward tcp:8085 tcp:8085
</code></pre>
<p>This lets you go to http://localhost:8085 in Chrome on your host machine.</p>
<h2 id="debugger-usage"><a class="header" href="#debugger-usage">Debugger Usage</a></h2>
<p>After opening the fgviewer page in your browser, you can see the active views are on the left panel.
Then you can select any of them to see the active passes and resources for that view.</p>
<p align="center">
<img width="600px" src=https://github.com/user-attachments/assets/2d31767f-fc25-4f17-8c14-528fe5c6b698>
</p>
<h2 id="architecture-overview"><a class="header" href="#architecture-overview">Architecture Overview</a></h2>
<p align="center">
<img width="450" src=https://github.com/user-attachments/assets/537ebb89-6ad0-4b93-bbeb-207d4fe9ec5a>
</p>
<p>The fgviewer library has two parts: a C++ server and a JavaScript client. The C++ server is
responsible for instancing a <a href="https://github.com/civetweb/civetweb">civetweb</a> context that handles HTTP requests. The
JavaScript client is a small web app that contains a view into an in-browser database of framegraphs.</p>
<p>When a new connection is established, the client asks the server for a list of framegraphs
in order to populate its in-browser database. If the connection is lost (e.g. if the app crashes),
then the database stays intact and the web app is still functional.</p>
<h2 id="c-server"><a class="header" href="#c-server">C++ Server</a></h2>
<p>The civetweb server is wrapped by our <code>DebugServer</code> class, which provides a public interface consisting of
a few methods invoked by the Filament engine.</p>
<p>Since each view corresponds to a frame graph, the engine should notify <code>DebugServer</code> of any changes to the views
on the engine side.</p>
<ul>
<li><strong>createView</strong> Notifies the debugger that a new view has been created.</li>
<li><strong>updateView</strong> Notifies the debugger of updates to an existing view.</li>
<li><strong>destroyView</strong> Notifies the debugger that a view is being removed.</li>
</ul>
<h2 id="javascript-client"><a class="header" href="#javascript-client">JavaScript Client</a></h2>
<p>The web app is built using LitElement, a lightweight library for creating Web Components. Our goal is to keep the code simple and modern, avoiding frameworks like React or Angular.</p>
<p>The app presents a view over a pseudo-database, which is essentially a global variable holding a dictionary that maps frame graph ids to objects following the JSON structure described below.</p>
<h2 id="http-requests"><a class="header" href="#http-requests">HTTP requests</a></h2>
<p>The server responds to the following GET requests by returning a JSON blob. The <code>{id}</code> in these
requests is a concept specific to fgviewer (not Filament) which is an 8-digit hex string for identifying frame graphs.</p>
<hr />
<p><code>/api/framegraphs</code></p>
<p>Returns an array containing all framegraphs in an app. Example:</p>
<pre><code class="language-json">[{
"fgid": "00000000",
"viewName": "Main View",
"passes": [{
"name": "shadow pass",
"reads": [],
"writes": ["0"]
}],
"resources": [{
"id": "0",
"name": "shadowmap",
"properties": [{"resolution": "256x256"}, {"is_subresource": "false"}]
}]
},
{
"fgid": "00000001",
"viewName": "UI view",
...
}]
</code></pre>
<hr />
<p><code>/api/framegraph?fg={id}</code></p>
<p>Returns a specific framegraph info. Example:</p>
<pre><code class="language-json">{
"fgid": "00000000",
"viewName": "Main View",
"passes": [{
"name": "shadow pass",
"reads": [],
"writes": ["0"]
}],
"resources": [{
"id": "0",
"name": "shadowmap",
"properties": [{"resolution": "256x256"}, {"is_subresource": "false"}]
}]
}
</code></pre>
<hr />
<p><code>/api/status</code></p>
<p>Returns one of the below:</p>
<ul>
<li><code>0</code>: first time connected</li>
<li><code>1</code>: no-op</li>
<li><code>{fgid}</code>: the corresponding frame graph has an update
<ul>
<li>Then the web view can request for the actual info using the previous api</li>
</ul>
</li>
</ul>
<p>If the request gets timeout, the web page show disconnected to the user.</p>
<hr />
<h2 id="wish-list"><a class="header" href="#wish-list">Wish List</a></h2>
<ul>
<li>Display the texture contents on the webview</li>
</ul>
</main>
<nav class="nav-wrapper" aria-label="Page navigation">
<!-- Mobile navigation buttons -->
<a rel="prev" href="../dup/bluevk.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/filamat.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/bluevk.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/filamat.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

@@ -336,7 +336,7 @@ void material(inout MaterialInputs material) {
<nav class="nav-wrapper" aria-label="Page navigation">
<!-- Mobile navigation buttons -->
<a rel="prev" href="../dup/bluevk.html" class="mobile-nav-chapters previous" title="Previous chapter" aria-label="Previous chapter" aria-keyshortcuts="Left">
<a rel="prev" href="../dup/fgviewer.html" class="mobile-nav-chapters previous" title="Previous chapter" aria-label="Previous chapter" aria-keyshortcuts="Left">
<i class="fa fa-angle-left"></i>
</a>
@@ -350,7 +350,7 @@ void material(inout MaterialInputs material) {
</div>
<nav class="nav-wide-wrapper" aria-label="Page navigation">
<a rel="prev" href="../dup/bluevk.html" class="nav-chapters previous" title="Previous chapter" aria-label="Previous chapter" aria-keyshortcuts="Left">
<a rel="prev" href="../dup/fgviewer.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

@@ -181,7 +181,7 @@ important for <code>matc</code> (material compiler).</p>
}
dependencies {
implementation 'com.google.android.filament:filament-android:1.66.1'
implementation 'com.google.android.filament:filament-android:1.68.4'
}
</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.66.1'
<pre><code class="language-shell">pod 'Filament', '~&gt; 1.68.4'
</code></pre>
<h2 id="documentation"><a class="header" href="#documentation">Documentation</a></h2>
<ul>

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