Compare commits

...

381 Commits

Author SHA1 Message Date
Benjamin Doherty
18dab53920 All changes 2022-11-14 22:20:59 -08:00
Benjamin Doherty
b754b81e6f Almost all the changes 2022-11-14 22:16:58 -08:00
Benjamin Doherty
65bb66f90c Even more shader changes 2022-11-14 22:00:10 -08:00
Benjamin Doherty
a0af84d034 Some more shader changes 2022-11-14 21:56:50 -08:00
Benjamin Doherty
3cdaf3feeb ShadowMapManager.h changes 2022-11-14 17:18:00 -08:00
Benjamin Doherty
da7d1b6fa9 Update Scene.cpp 2022-11-14 17:09:55 -08:00
Benjamin Doherty
3129226839 Fix literal 0 2022-11-14 17:07:55 -08:00
Benjamin Doherty
6935acafff Changes to ShadowMapManager 2022-11-14 17:07:25 -08:00
Benjamin Doherty
d8103f4fd6 Update ShaderGenerator.cpp 2022-11-14 16:55:50 -08:00
Benjamin Doherty
09a13f4015 Some shadowing changes 2022-11-14 15:25:08 -08:00
Benjamin Doherty
e888023102 Some shader changes 2022-11-14 15:00:09 -08:00
Benjamin Doherty
f62f4736f0 Adjust LightsUib 2022-11-14 13:39:08 -08:00
Benjamin Doherty
a378272d56 Remove some more uniforms 2022-11-14 13:34:26 -08:00
Benjamin Doherty
3d61938fcf Remove lightFromWorldMatrix from PerViewUniforms 2022-11-14 13:30:54 -08:00
Benjamin Doherty
a9f3937da6 Trivial changes 2022-11-14 13:05:52 -08:00
Mathias Agopian
2dc8d6bcc0 minor cleanups, comment fixes
- update comments
- remove unused or unneeded methods
2022-11-08 15:25:33 -08:00
Balazs Vegh
08dc398452 Fix skipped depth bias set on Metal (#6276) 2022-11-07 11:26:53 -08:00
Benjamin Doherty
cd180c9a44 Update Python requirements.txt to fix CI 2022-11-04 11:35:10 -07:00
daemyung jang
0a7fe52124 Trim a whitespace (#6272) 2022-11-04 08:36:36 -07:00
Mathias Agopian
b71faf47cc fix shadow cascades
breakage was due to an uninitialized variable at the beginning of the
frame, caused by a recent change.

shadows would disappear when cascades were used with 'stable' shadows.
2022-11-03 13:48:09 -07:00
Ben Doherty
67babceb73 Fix backend_test to work with Metal arg buffers (#6135) 2022-11-03 11:04:29 -07:00
Ben Doherty
8e13fc86d5 Expose missing ColorGrading::Builder methods to JS (#6262) 2022-11-03 11:04:06 -07:00
Mathias Agopian
351c8e0972 fix spotlight attenuation
Spotlight attenuation was computed only when shadowing was enabled.
2022-11-03 10:34:39 -07:00
Benjamin Doherty
dc44e20be0 Fix RELEASE_NOTES 2022-11-03 09:57:21 -07:00
daemyung jang
e64b498d6e Update a comment about the range of morph target weight (#6265) 2022-11-03 09:19:01 -07:00
Mathias Agopian
31ab4a13c9 fix recently introduced crash on init
certain material properties can only be set if supported by the 
material.
2022-11-01 13:23:52 -07:00
Benjamin Doherty
e9728dcc8d Fix iOS build 2022-11-01 15:03:44 -04:00
Mathias Agopian
40a3644086 Reduce the size of ShadowMap to 40 bytes from 2KB+
ShadowMap had recently inflated due to its internal use of 
PerViewUniforms, which keeps a shadow copy of the uniform data. This
copy is not needed for ShadowMaps.
2022-11-01 11:58:28 -07:00
Mathias Agopian
41ef71abdf Add MaterialInstance getters for overridable properties (#6243)
In addition to the new getters, this change fixes the duplication of
a MaterialInstance, which didn't carry along the following states:
  - alpha mask threshold
  - specular AA threshold
  - specular AA variance
  - double sidedness

TODO: stencil state, polygon offset and scissor are stil not queryable
2022-11-01 11:22:01 -07:00
daemyung jang
3b40e52c98 Recompute bounding boxes with morph targets (#6246)
* Recompute bounding boxes with morph targets

* Reduce the number of heap allocation while recomputing bounding boxes

Co-authored-by: Romain Guy <romainguy@curious-creature.com>
2022-11-01 11:20:28 -07:00
daemyung jang
de8c7969f3 Return the correct permit type corresponding to the component type (#6255) 2022-11-01 11:03:27 -07:00
Benjamin Doherty
f2c049222b Release Filament 1.28.2 2022-11-01 13:01:13 -04:00
Ben Doherty
be30ac1fcb Fix G3 reported ubsan warning (#6257) 2022-11-01 12:50:27 -04:00
Ben Doherty
c5cc7fe26a Metal: generate argument buffer structures ourselves (#6242) 2022-11-01 12:44:42 -04:00
Ben Doherty
d04b0a5c73 Update Vulkan headers to v1.3.232 (#6256) 2022-11-01 12:38:23 -04:00
Mathias Agopian
72ab2aef0a fix UBO handle leak with ShadowMap
This wasn't a big issue because the "leak" would be cleaned when the
engine is destroyed.
2022-10-31 11:29:46 -07:00
Koncz Levente
1527bb7ad3 Preserve iOS stack traces (#6240) 2022-10-31 13:58:31 -04:00
daemyung jang
8cb26fc9ac Fix a build error on Android
The size of struct could be different on each architecture.
2022-10-30 20:52:56 -07:00
Matt Vera
c21794d0a0 Add Vulkan GGP platform. (#6235)
* Add GGP vulkan platform.

* Add release note for GGP support
2022-10-28 11:53:29 -07:00
daemyung jang
1a6338569a Calculate primitive's AABB correctly (#6232)
AABB of morph target is displacement data so it should be added to
primitive's base AABB.

Co-authored-by: Mathias Agopian <mathias@google.com>
2022-10-28 11:51:02 -07:00
Mathias Agopian
c5ebe1a88a skip primitives with FRONT_AND_BACK face culling 2022-10-28 11:50:21 -07:00
Mathias Agopian
a3f2028ae4 Reduce the size of PerViewUniforms by 24 bytes
This seems a bit pointless because PerViewUniforms has a 2KB field,
however, it adds up now that it's used by ShadowMap.
2022-10-28 11:49:55 -07:00
Mathias Agopian
c393ee4591 Each shadowmap now manages its own UBO
Instead of constantly reusing the View's UBO, each shadowmap now
manages it own. All UBOs for all shadow maps are updated together, 
then later during rendering, we're simply binding the correct UBO.
This change will be needed later so that we can update several
shadow maps in a single texture.

There are two main changes to achieve this:
1. ShadowMap now has PerViewUniforms object
2. For point lights, each face now has a ShadowMap object

One consequence is that ShadowMap is now very large (over 2KB). This
will be addressed later.
2022-10-28 11:49:55 -07:00
Mathias Agopian
83a82ae10e shadowing: store Executor instead of whole RenderPass
We didn't need to store the actual RenderPass for each shadowmap pass,
the executor is enough. This might prevent some mistakes later.
2022-10-28 11:47:12 -07:00
daemyung jang
676694e458 Fix glTF breaking issue (#6239) 2022-10-28 09:56:01 -07:00
Mathias Agopian
2ca218928f utils: get rid of GrowingSlice
it's just not used anywhere. change the implementation of Slice<> to
use two pointers.
2022-10-27 22:48:45 -07:00
Philip Rideout
776ce223fc Fix incorrect Vulkan documentation wrt layouts. 2022-10-26 19:18:32 -07:00
Philip Rideout
0d4d1f55c9 Updates to the Vulkan architecture doc. 2022-10-26 19:18:32 -07:00
Romain Guy
d6dba71ace Update docs 2022-10-26 12:28:56 -07:00
Mathias Agopian
61ee11ae6c fix the doubleSided property documentation (#6228)
* fix the `doubleSided` property documentation

* Update Materials.md.html

Co-authored-by: Romain Guy <romainguy@curious-creature.com>
2022-10-26 12:28:03 -07:00
Mathias Agopian
90f32e7277 A basic POT 2D allocator
This 2D allocator only supports power-of-two, square allocations. It
uses a quadtree to store the allocated regions.

The quadtree implementation currently has a fixed depth (templated).

The allocator does a best-fit match, but currently doesn't implement a
free method.
2022-10-26 11:02:17 -07:00
daemyung jang
b85d9afdb3 Remove an useless whitespace (#6226) 2022-10-26 00:10:33 -07:00
Mathias Agopian
4297d43d9a more improvements to RenderPass
- RenderPass::Executor now only executes the commands, it doesn't 
  create a backend render pass anymore. This is still done in the
  RenderPass::execute() helper.

- scissor and poloyon offset overrides are now set on Executor because
  they are not needed to generate the commands.
2022-10-25 14:38:56 -07:00
Mathias Agopian
cfcf714c21 Get rid of PrimitiveType::NONE 2022-10-25 14:38:08 -07:00
Benjamin Doherty
f7cfc6a65e Release Filament 1.28.1 2022-10-25 13:07:56 -04:00
Benjamin Doherty
4ead3bcebf Force spirv-cross to keep Metal argument buffer equal sized 2022-10-25 12:07:24 -04:00
Balazs Vegh
21e0677039 Check GPU support for depth resolve on Metal (#6220) 2022-10-25 11:55:17 -04:00
Ben Doherty
107b5a4854 Metal: fix microshadowing artifacts (#6221) 2022-10-24 19:12:14 -04:00
Balazs Vegh
9761b65137 Fix Metal unused variable warning (#6217) 2022-10-24 12:41:58 -04:00
Ben Doherty
b1831d2786 Fix, don't use encoder.device (#6212) 2022-10-20 13:05:07 -04:00
Benjamin Doherty
977d369e40 Fix unused variable warnings 2022-10-19 12:44:07 -04:00
Josh Faust
5cf5b25175 Add a function to reset internal GL backend state (#6105)
This allows bug-free integration with external renderers in WebGL

See https://github.com/google/filament/issues/6091
2022-10-19 09:31:11 -07:00
Ben Doherty
e75c3020c8 Initial support for Metal compute shaders / SSBOs (#6189) 2022-10-18 16:21:57 -04:00
k1rnt
aeb0a4008d fix(ci): replace set-output to GITHUB_OUTPUT (#6195) 2022-10-18 13:41:25 -04:00
Benjamin Doherty
2d43ad59ec Revert Android API_LEVEL change
glDispatchCompute requires Android API level 21, however bumping our
required minimum from 19 to 21 caused some clients' builds to fail.
Commenting-out that line for now to proceed with the 1.28.0 upgrade.
2022-10-18 13:34:50 -04:00
daemyung jang
f86ec07c45 Fix ios hello-gltf runtime errors 2022-10-18 10:19:22 -07:00
Ben Doherty
fc012d6d65 Metal: fix use-after-free ASAN error (#6203) 2022-10-17 19:13:36 -04:00
Philip Rideout
6b71232e38 matc / matinfo / filamesh: add vulnerability message 2022-10-17 15:49:35 -07:00
Philip Rideout
e157023fc1 Use mField style for fields in FFilamentInstance 2022-10-17 15:49:19 -07:00
Philip Rideout
6e38db882f Fix installed IBL location for desktop.
Fixes #6193
2022-10-17 12:30:11 -07:00
daemyung jang
09600699cb Update README.md 2022-10-17 09:57:58 -07:00
daemyung jang
6a5e74f031 Update README for meshoptimizer 2022-10-17 09:57:58 -07:00
daemyung jang
795bd1e995 Fix build errors in ios samples 2022-10-17 09:57:58 -07:00
daemyung jang
784416f658 Support glTF EXT_meshopt_compression 2022-10-17 09:57:58 -07:00
daemyung jang
b151afe567 Update meshoptimizer to version 0.18 2022-10-17 09:57:58 -07:00
Mathias Agopian
117ae1d648 RenderPass doesn't store an FEngine anymore 2022-10-14 15:59:03 -07:00
Mathias Agopian
7165d8aa54 fix a directional light shadowing issue
the shadow frustum could be be smaller than expected.
2022-10-14 13:16:14 -07:00
Ben Doherty
6b461b2d89 Metal: fix simulator regression due to arg buffers (#6181) 2022-10-13 14:34:33 -04:00
Benjamin Doherty
affc5be840 Release Filament 1.28.0 2022-10-13 12:35:45 -04:00
Ben Doherty
e3ff5616ef G3 fixes for 1.28.0 (#6174) 2022-10-11 17:02:46 -07:00
Mathias Agopian
d9a401d57e Reduce size of ShadowMap object
- remove mEngine from ShadowMap
- remove storage of ShadowMapInfo in ShadowMap
- ShadowMap::render should be on ShadowMapManager
- remove more attributes from ShadowMap

ShadowMap is now reduced to 32 bytes.
2022-10-10 13:03:36 -07:00
Mathias Agopian
acd5823953 Add support for point light shadows
[experimental]
2022-10-10 13:03:36 -07:00
Mathias Agopian
9b13565750 spotlight shadow map skipped if the scene is empty. 2022-10-10 13:03:36 -07:00
Mathias Agopian
734d8ff85c rename upcast() to downcast()
it was down casting all along!
2022-10-07 17:50:56 -07:00
Mathias Agopian
a02ef1a6c7 Remove the limit to 14 spot shadow maps, now 64.
Spotlight shadow maps are now limited only by h/w limits (UBO size and
2d array maximum layers), which works out to about 146 shadows.

In practice we hardcode the limite to 64, but this can be changed at
compile time. A higher maximum increases memory usage.

There used to be a bitfield per renderable with a bit for each shadow
map indicating if the renderable was "visible" from this light. The
limit to 14 came from that bitfield. All shadow maps used to be culled
first, setting the bitfield appropriately.

Instead, we are now processing spotlight shadows one at a time,
performing culling as we go. For this reason we don't need a bit per
shadow map.
2022-10-07 14:07:51 -07:00
Mathias Agopian
f13bf11d0f simplify command generation
No need to generate a sentinel command in the main loop when a 
command is canceled, this is now done automatically at a higher level.
The main benefit is that we can reject renderables that are not visible
a bit faster.
2022-10-07 14:07:51 -07:00
Ben Doherty
7d0b5fed8f Fix Metal argument buffer encoding (#6150) 2022-10-07 13:53:26 -07:00
Philip Rideout
e1f51f04c1 Vulkan: fix black screen regression
The VulkanProgram constructor was bailing out early and emitting a
warning because it saw that one of the stages wasn't fulfilled.
However it's okay for a pipeline to be missing a compute program.

Fixes regression that started with fabba73b1.
2022-10-04 10:47:16 -07:00
Philip Rideout
f6d74be123 Fix windows build. 2022-10-03 12:35:35 -07:00
Philip Rideout
50a1935b68 Vulkan performance improvements for readPixels. 2022-10-03 09:54:35 -07:00
Mathias Agopian
694ecce150 fix shadowing when the scene is outside the "shadow" view frustum
this case was causing uninitialized variables to be used creating a
false positive "shadows on" in the first cascade.

The main change here is to bail out as soon as we know there is no shadowing.
2022-09-30 16:12:36 -07:00
Mathias Agopian
3e3bd2722f fix lispsm when camera and light direction are aligned
in that case we have to revert to the ortho projection
2022-09-30 16:12:15 -07:00
Mathias Agopian
44fdf83e4c fix multiview mode in gltf_viewer
The "shadow" camera now works again.
2022-09-30 16:12:15 -07:00
Benjamin Doherty
99c4ce67e4 Print warning when Metal reaches memoryless geo limit 2022-09-30 13:59:49 -07:00
Balazs Vegh
71aceec4cf Memoryless storage mode with fallback (Metal) (#6124) 2022-09-30 13:54:54 -07:00
Philip Rideout
98e4cdbd4c gltfio ubershader mode: fix re-loading.
Fixes #6128
2022-09-30 13:54:36 -07:00
Mathias Agopian
86ef0109f4 use the correct gaussian blur shader
we attempted to select a shader which processed the required number of
component, but were always selecting the 4-components version.

this should improve blur performance for VSM.
2022-09-30 13:30:15 -07:00
Mathias Agopian
b4142261c2 trivial typo and ide warnings fixes 2022-09-30 13:30:15 -07:00
Mathias Agopian
359624e8eb Fix gaussian blur kernel computation
This improves significantly VSM shadows with blur,
 but will also improve SSR and the flare.
2022-09-30 13:30:15 -07:00
Mathias Agopian
5bcc11d9e8 fix typo that broke the VSM blur radius setting 2022-09-30 13:30:15 -07:00
Mathias Agopian
5aa414dd24 support for ELVSM and 32 bits xVSM
This basically adds two settings:
- highPrecision at the View level, which controls the bit depth
  of the vsm shadow texture used. This affects all shadowmaps.
- elvsm per shadowmap, which enables Exponential Layered VSM.

the main change in the shaders is that we now always output the 
"negative" EVSM, even when it's not enabled. If no shadowmap uses
ELVSM, then the texture is stil an RG texture and the calculation is
lost (with some luck culled by the shader compiler), either way it's
not a lot of math and it's done only once per shadow texel.

During the color pass, on the other hand, we compute the "negative"
EVSM only if enabled.
2022-09-30 12:04:27 -07:00
Mathias Agopian
1e51b03971 fix VSM 2nd moment calculation
the linear approximation only works with a linear depth, it fails
with our warped depth.
2022-09-30 12:04:27 -07:00
Mathias Agopian
fc484bd319 fix "stable" shadows
We were always adjusting the near/far of the view volume based on the
scene content for shadowing, which defeated the "stable" shadows.

Also changed the default cascade splits from a linear split to a
log2 split, because due to the perspective projection, the log2 split
actually looks linear. Also intuitively, it makes more sense to give
more resolution to the shadows close to the camera.
2022-09-30 12:00:02 -07:00
Mathias Agopian
9c4783142e matc: minor cleanup 2022-09-29 19:34:07 -07:00
Mathias Agopian
4dc03318e8 break circular dependency between Package and Flattener 2022-09-29 19:34:07 -07:00
Philip Rideout
15ba54c4c5 Update README wrt Android Studio Version. 2022-09-29 16:28:50 -07:00
Philip Rideout
342138aecb gltfio: Update Java API. 2022-09-29 16:28:50 -07:00
Philip Rideout
9f53c62e06 gltfio: Update Web API.
Java API changes will come next.
2022-09-29 16:28:50 -07:00
Philip Rideout
2d996033e3 gltfio API change part 2: remove asset-level animator 2022-09-29 16:28:50 -07:00
Philip Rideout
9fa6dc4131 gltfio API change part 1: move all MaterialInstance methods to FilamentInstance 2022-09-29 16:28:50 -07:00
daemyung jang
4930227743 Fix a crash by setting not exist material parameters on ubershader (#6122)
* Fix a crash by setting not exist material parameters on ubershader

* gltfio: add getFeatureMap, remove logic for dummy textures

Co-authored-by: Philip Rideout <philiprideout@gmail.com>
2022-09-29 15:51:35 -07:00
Benjamin Doherty
fbfcce563d Release Filament 1.27.2 2022-09-29 13:11:43 -07:00
Ben Doherty
7f5ad3743b Fixes for 1.27.2 release (#6125) 2022-09-29 13:08:00 -07:00
daemyung jang
981020e72b Get the morph target buffer to the given primitive 2022-09-29 13:01:42 -07:00
Mathias Agopian
7c1a705a07 reduce setSarameter(texture) calls 2022-09-28 22:10:27 -07:00
Mathias Agopian
3d53ae583f switch our min sdk from 19 to 21
this is so that we can support OpenGL ES3.1
2022-09-28 22:08:27 -07:00
Mathias Agopian
dc9f03cbd0 don't attempt to use more texture units than present
to emulate the bindless API in the gl backend we always used the highest
texture unit available. However at feature level 3, we support up to 62
textures, so the that max was bumped to 62 -- however, where we're not
on a feature level 2 device, that texture unit doesn't exist.

Instead we now always use binding 31, which is guaranteed to exist by 
EGL's minspec.
2022-09-28 22:05:05 -07:00
Philip Rideout
de7bca7ef8 gltfio: fix occlusion strength
Fixes #6106
2022-09-28 17:42:29 -07:00
Ben Doherty
f151f56a2e Metal: use argument buffers for SamplerGroups (#6093) 2022-09-28 16:50:11 -07:00
Ben Doherty
fe3d1713a4 Fix generic/Mutex.h not installed on Linux (#6117) 2022-09-28 16:36:38 -07:00
Joel Winarske
2cad3be7a3 Wayland FilamentApp
- move Wayland specific code into getNativeWindow
- make wayland struct static

Signed-off-by: Joel Winarske <joel.winarske@gmail.com>
2022-09-28 16:14:01 -07:00
Thomas Gorisse
5262512eea Fix JNI for TransformManager.getChildren() (#6116) 2022-09-28 11:27:35 -07:00
Mathias Agopian
fabba73b1e Initial support for compute
* minimal backend support for compute
- added api to dispatch a compute shader
- added api to create and bind a ssbo
- added api to read back a buffer
Only implemented in the gl backend

* Add a backend compute test suite
* basic support for compute shaders in matc
this is still very much work-in-progress.
We're not supporting images nor ssbo for now.

* rename UniformInterfaceBlock to BufferInterfaceBlock
* augment BufferInterfaceBlock to support ssbo features
- add support for std430
- add support for ssbo
- add support for variable-size array
- add support for memory qualifiers

* reformat MaterialBuilder
* material format: move subpasses outside of parameters
subpasses now are their own json property instead of being a
"parameter".

* refactor parameter() methods to match Buffer/SamplerInterfaceBlock
We're just shuffling the arguments.

* add support for buffers in .mat files
* filamat now generates buffer blocks (ssbo)
* take feature level into consideration when optimizing shaders
* don't store the 'uniform binding' chunk for level 2 materials
this includes some refactoring/cleanups of MaterialParser

* matinfo: fixes for compute
- separate subpasses from parameters
- don't attempt to print material properties
2022-09-27 15:52:40 -07:00
daemyung jang
d291ec739b Update cgltf to version 1.13 (#6099) 2022-09-23 11:52:57 -07:00
Mathias Agopian
0dc0bbd4f3 LiSPSM is now a user settable option 2022-09-22 09:35:45 -07:00
Mathias Agopian
984a029ce4 fix (again) the box-frustum intersection
it is not true that the whole box is inside the frustum if we have
8 vertices and some frustum vertices are in the box -- that's even
non-sensical.

We now test for this case by checking that we have all (8) vertices of
the box inside the frustum.

This caused some shadows to be missing.
2022-09-22 09:35:28 -07:00
Mathias Agopian
1cbc1f30a6 filamesh: handle empty meshes
empty meshes would cause a OOB read.

b/246719043
2022-09-20 16:45:45 -07:00
Mathias Agopian
08fb39a1e4 Fix buffer overflow in matc
b/247441389
2022-09-20 16:45:45 -07:00
Mathias Agopian
d8a71ce195 minor cleanup and IDE warning suppression 2022-09-20 16:45:45 -07:00
Mathias Agopian
13986c12bc fix out of bounds access in matc
b/247442731
2022-09-20 16:45:45 -07:00
Mathias Agopian
cc64704a82 fix buffer overflow filamat
b/247447117
2022-09-20 16:45:45 -07:00
Benjamin Doherty
df2ad99260 Release Filament 1.27.1 2022-09-20 11:04:07 -07:00
Mathias Agopian
fb1f277b9a attempt to fix android build again 2022-09-20 09:11:42 -07:00
Mathias Agopian
0388161464 fix android debug build 2022-09-19 23:03:12 -07:00
Ben Doherty
e989d5603f Add MetalRingBuffer for future argument buffer management (#6087) 2022-09-19 16:18:54 -07:00
Mathias Agopian
defaa0d008 use ES3.1 headers
We now compile with ES3.1 headers but we make sure we can still compile
with ES3.0 headers (still needed for iOS).
2022-09-18 20:37:43 -07:00
Mathias Agopian
e161ba80f2 cleanup: move string_view over string uses 2022-09-16 18:31:48 -07:00
Philip Rideout
034aaff56c gltfio: FilamentInstance owner is now const.
In the future, we will allow instances to be constructed from
immutable assets (this is a Google feature request) so this PR
prepares for that.
2022-09-16 16:32:49 -07:00
Mathias Agopian
b0fb52c5f4 matinfo: fix feature level print output 2022-09-16 16:22:25 -07:00
Philip Rideout
a05f9c172f gltfio: change instancing behavior for punctual lights 2022-09-16 15:32:18 -07:00
Ben Doherty
adde936d18 Update glslang to c0cf8ad87 (master) (#6076) 2022-09-16 12:29:56 -07:00
Philip Rideout
feda999eb3 matinfo and filamesh: misc ASAN fixes 2022-09-15 17:23:54 -07:00
Romain Guy
8dae181c2f Upgrade AGP and dependencies including plugins (#6078)
This moves to a new, maintained Maven publishing plugin.
2022-09-15 16:05:18 -07:00
Philip Rideout
8cdac431a6 Vk getFeatureLevel() should use maxPerStageDescriptorSamplers 2022-09-15 13:51:10 -07:00
Romain Guy
0ecf5118ba Update docs 2022-09-14 20:18:27 -07:00
Philip Rideout
f21638a1e2 gltfio: fix material-free assets 2022-09-14 16:54:27 -07:00
Mathias Agopian
8dc16494a7 introduce "feature level 3"
This is because most android devices only support 16 texture in the
shaders (94.4%), so we can't realistically have feature level 2 demand
that.

Instead feature level 2 enables compute/ES3.1 features.
2022-09-14 16:53:43 -07:00
Mathias Agopian
a8765b1dc0 fix some trivial ide warnings 2022-09-14 16:53:43 -07:00
Philip Rideout
d346b94b8a gltfio: fix regression with recomputeBoundingBoxes() 2022-09-14 16:53:20 -07:00
Philip Rideout
c4abe4f46a gltfio: allow zero-instance assets.
This is a feature request from Google. It allows users to "preload" an
asset, ie you can now create all VertexBuffer objects, Texture objects,
etc, without actually creating any entities or renderable components.

In the past we used TransformManager to help out with computing the big
asset-level bounding box, but now we use `gltf_node_transform_world()`
because entities might not yet exist.

One minor side effect is that `FilamentAsset::getBoundingBox()` now
returns the AABB that was determined at load time, and does not account
for instances. As a result, our `gltf_instances` sample app looks
slightly different but this is expected.
2022-09-14 16:40:47 -07:00
Philip Rideout
ad6a5eb4e1 Vulkan samplers: fit incorrect bitset logic.
In VulkanPipelineCache, `getShaderStageFlags()` and `getUsageFlags()`
are used to track which samplers are used in the VERTEX stage and which
are used in the FRAGMENT stage. The recent change I made was incorrect
because it did not account for samplers that are used in BOTH stages.

This fixes the recent regression where we see validation errors when
running `gltf_viewer` in ubershader mode.
2022-09-14 15:21:26 -07:00
Mathias Agopian
c84834d666 bump max sampler count to 62
This is needed for feature level 2.
2022-09-13 10:49:21 -07:00
Benjamin Doherty
334fe70d6c Release Filament 1.27.0 2022-09-13 10:14:02 -07:00
Philip Rideout
3b4fbaccc9 gltfio: fix regression when textures are "shared"
Some (poorly authored) glTF assets have several `image` elements
that all refer to the same URL or buffer view. When this occurs,
we create only 1 Filament Texture.

These assets regressed after PR 6051, which consolidated the texture
related fields in `FilamentAsset`, but did not include an ownership flag
in the new `TextureInfo` struct.
2022-09-12 16:00:24 -07:00
Mathias Agopian
58401e0b6e Fix FilamentApp multiview mode in gltf_viewer
- fix View::setVisibleLayers to match code. By default only layer 0
  is active, despite the documentation stating otherwise.

- add a helper to enable/disable layers more easily

- don't use layer 0,1,2 for the overdraw function as they were used by
  FilamentApp in "multi view" mode.
2022-09-12 15:55:16 -07:00
Mathias Agopian
3496f3a8ba rename ShaderType to ShaderStage 2022-09-12 15:54:07 -07:00
Mathias Agopian
441708ea12 Make ShaderStage an enum class 2022-09-12 15:54:07 -07:00
Mathias Agopian
ba8abb9031 scissor improvements
- improve scissor documentation, specify coordinate system and
  clipping behavior
- scissor now takes the guard bands into account
- on the backend side the scissor is no longer clipped to the viewport
- clipping to the viewport is now done on the filament side
- don't set scissor when material instance doesn't specify one
  (common case)
2022-09-12 12:45:36 -07:00
Ben Doherty
2718a22f64 Add return case to fix G3 compiler error (#6062) 2022-09-12 12:34:23 -07:00
Philip Rideout
85fb4be37e gltfio: use BitmaskFlags for sRGB
This PR also contains a small change in ResourceLoader::createTextures
that will permit zero-instance assets (an upcoming gltfio feature).
2022-09-12 12:27:01 -07:00
Mathias Agopian
f772c92eed fix typo in spotlight attenuation doc 2022-09-12 12:04:35 -07:00
Philip Rideout
cd58d39eb9 Vk cleanup: incorporate code review feedback. 2022-09-09 13:00:49 -07:00
Philip Rideout
2d730a4618 Vk cleanup: remove dummy samplers. 2022-09-09 13:00:49 -07:00
Philip Rideout
da6d17531c Vk: do not provide descriptors for unused samplers. 2022-09-09 13:00:49 -07:00
Philip Rideout
37b9b182b1 gltfio: prep step for allowing zero-instance assets
AssetLoader now loads assets in two passes:
- Pass 1 creates VertexBuffer objects, MorphTargetBuffer objects, etc.
- Pass 2 creates entities, renderables, etc (only if numInstances > 0)

This feature will help us integrate gltfio with an internal library at
Google.
2022-09-09 09:21:33 -07:00
Romain Guy
eaa86060e2 Fix memory leak (#6056)
This change fixes #6055
2022-09-08 20:57:46 -07:00
Philip Rideout
5e128214fa Vk: When the layout requirement change, the pipeline is "dirty".
Also, there's no such thing as a "bound layout".
2022-09-08 16:40:49 -07:00
Philip Rideout
9a7b967889 Rename mResult to mAsset. 2022-09-07 16:28:30 -07:00
Philip Rideout
5e498e7442 gltfio: big simplification for textures + add sRGB related assert.
The asset previously had three confusing fields related to textures:
mTextures, mTextureSlots, and mTextureBindings.

These are now consolidated into a single field, which simply has one top
level array item per `cgltf_texture`.

The memory footprint is smaller because we no longer bother to store
`TextureSampler` objects, instead we simply defer their construction
until calling setParameter.

Last but not least, we now assert in debug builds if the usages of a
particular texture have inconsistent sRGB flags. In the past,
inconsistent sRGB would be silently ignored.

In other words, we will now assert if you try to use the same texture
for `baseColor` and `normalMap`, whereas in the past we would simply
exhibit non-deterministic behavior in this situation (with respect to
sRGB semantics).
2022-09-07 16:28:30 -07:00
Mathias Agopian
25990ecd37 FilamentApp sets the feature level to highest allowed
There is also a new option to override the default with a lower
feature level. This is used in gltf_viewer only at the moment.
2022-09-07 15:32:58 -07:00
Mathias Agopian
ead5a97871 make AutomationEngine feature level aware
this basically just adds an Engine* parameter too all applySettings
methods
2022-09-07 15:32:58 -07:00
Mathias Agopian
a66495b2e0 fix setting spec constants in gl backend
a failure could happen if a comment contained the word `#extension`
2022-09-07 15:32:58 -07:00
Philip Rideout
f83172f9f9 gltfio MaterialProvider: add new method for getting Material
gltfio can now ask the material provider plugin which `Material` would
be used for a given set of requirements.  Prior to this change, gltfio
could only create a new `MaterialInstance`.

This method is necessary to support an upcoming gltfio feature.
2022-09-07 12:08:55 -07:00
Philip Rideout
80a957c1e3 gltfio: do not clear out the texture slots too early.
This broke asyncGetLoadProgress() and caused WebGL to crash reliably
because ResourceLoader got destroyed too soon.

Bug was introduced with de7dfc2ea6.

I intend to cherry pick this to rc/1.27.0, which is where it was
introduced, so there's no need to update the release notes.
2022-09-07 08:29:07 -07:00
Philip Rideout
e983169b35 gltfio: fix crash when material is unspecified 2022-09-07 08:28:36 -07:00
Mathias Agopian
b21d633c0c check that user materials don't exceed their allowed features (#6030)
* check that user materials don't exceed their allowed features

* backend sampler limits now take feature level into account


- in the backend, the constants are now in an array indexed by the 
  feature level

- samplerBindingMap now asserts only what it can.

- matc (filamat) now logs the user samplers when an error is detected.
2022-09-02 16:37:19 -07:00
Ben Doherty
f538d028d5 In debug builds, verify destroyed textures aren't in sampler groups (#6029) 2022-09-02 14:32:53 -04:00
Ben Doherty
4e15b7abc2 Add overdraw visualization to gltf_viewer (#6018) 2022-09-02 12:33:26 -04:00
Thomas Gorisse
e80ea5eae2 Add JNI for TransformManager.getChildCount(), TransformManager.getChildren() and Scene.hasEntity() (#6007)
* Add JNI for TransformManager.getChildCount(), TransformManager.getChildren() and scene.hasEntity()

* Update RELEASE_NOTES.md

* Fixes

* Change getChildren to take a nullable array

* Remove no params TransformManager.getChildren()

* Update RELEASE_NOTES.md

Co-authored-by: Ben Doherty <benjdoherty15@gmail.com>
Co-authored-by: Ben Doherty <bendoherty@google.com>
2022-09-01 11:22:44 -07:00
Mathias Agopian
6215050086 Fix a "dangling" texture in a SamplerGroup
One of the bloom texture ended-up dangling in the material's
SamplerGroup. That sampler group was never used to draw with, but was
made active which caused problem with the backends.


Also make sure the public API can unset a texture in a MaterialInstance
by passing nullptr for the texture.
2022-09-01 11:21:41 -07:00
Mathias Agopian
1fdb44ff42 graphvizify should only be implemented on debug builds 2022-08-31 17:17:38 -07:00
Ben Doherty
1768a2f8b7 Fix uberarchive not included in PodSpec (#6024) 2022-08-31 18:27:15 -04:00
Ben Doherty
2f26ef0873 Fix OpenGL stencil buffer writes (#6023) 2022-08-31 17:17:16 -04:00
Mathias Agopian
ac61fd7ba4 make a small optimization more explicit, fix typos 2022-08-31 09:11:25 -07:00
Benjamin Doherty
a886166489 Release Filament 1.26.0 2022-08-31 12:03:43 -04:00
Mathias Agopian
2073a9f3e5 cleanup Froxelizer comments
also fix typos, formatting.
2022-08-30 20:31:47 -07:00
Mathias Agopian
be12049a87 The default arena sizes in the makefile didn't match the code
Also added some ascii art to explain better how the various arenas are
used.
2022-08-30 16:48:30 -07:00
Philip Rideout
de7dfc2ea6 gltfio: Better behavior for releaseSourceData() 2022-08-30 16:00:11 -07:00
Philip Rideout
7337a467b9 gltfio cleanup: NodeMap is now a FixedCapacityVector, etc. 2022-08-30 15:57:30 -07:00
Philip Rideout
8118b4a774 gltfio: reset MaterialInstance cache for each instance.
For each "cgltf_material", we now create one "MaterialInstance", even
if a given asset has multiple instances. In the future, we might make
this behavior configurable to make better use of Filament's
auto-instancing feature.

This change is a feature request from Google, but also this behavior is
more consistent with the code comments.

Also some related cleanup:

(1) Use FixedCapacityVector instead of robin_map.

(2) Move the cache to move out of the asset and into the loader,
    because it is only used at load time.
2022-08-30 12:03:52 -07:00
Mathias Agopian
b295743330 Fix filamat internal state tracking
in a few places filamat loses the value of targetApi and targetLanguage
and attempt to guess it from other values, this lead to inconsistencies.

we now keep both targetApi and targetLanguage and use them appropriately.

in particular we don't use the optimization level to "guess" what 
targetLangage we're on.


In the end this resolve a prior unit test failure and allows us to not
have to use "spirv" rules when generating only GLSL.
2022-08-29 22:11:17 -07:00
Mathias Agopian
4f8d7092e0 fix typos and reformat code 2022-08-29 22:11:17 -07:00
Mathias Agopian
2701e57779 fix filamat unit tests
We use TargetLanguage::SPIRV instead of GLSL which affects how the
source GLSL is generated, in particular which version is used.

This change is not a problem for these unit tests, but is probably
exposing another problem -- we will address that separately.
2022-08-29 17:31:51 -07:00
Philip Rideout
f9375d5c33 gltfio: fix spotlight regression.
Spotlights were accidentally disabled in PR #5932.
2022-08-29 15:29:35 -07:00
Mathias Agopian
d04f049fa3 fix (again) frustum-box intersection
We were early-exiting too aggressively in the some case.
2022-08-29 14:55:49 -07:00
Mathias Agopian
8b8e724761 fix a use after free when setting a Program's uniform infos
We were keeping the list if uniform names in Material and passing
pointers to the backend. Unfortunately, HwProgram can outlive
Material because it is legal to destroy a Material once it's not
needed on the client side. e.g. just after rendering something.

This was happening with the IBLPrefilter code, but probably elsewhere
too.

We now just store CStrings in HwProgram.
2022-08-29 13:49:34 -07:00
Philip Rideout
45e8c57f77 gltfio: Innocuous comment fixes / renamings. 2022-08-29 13:06:13 -07:00
Philip Rideout
d01b3301d0 Vulkan: fix a warning, fix use-before-init. 2022-08-29 10:53:48 -07:00
Mathias Agopian
a7a55c7617 Specification constants support (#6001)
* Add support for specialization constants

* remove WebGL instancing count hack

use a specification constant instead

* update release notes
2022-08-29 09:38:23 -07:00
Philip Rideout
0695c12420 gltfio: Refactor skinning, fix duplicated data.
The immutable inverse bind matrices can be shared among instances, so
they are now stored in Asset, not in Instance.

Also, there are now two "load" phases for skinning data:

(1) storing the inverse bind matrices
(2) building the Entity mappings (for animation efficiency)

Phase 1 is done in `ResourceLoader` because inverse bind matrices can
live in an external bin file.

Phase 2 is done during Instance creation, because that's when entities
are created.
2022-08-29 09:18:17 -07:00
Mathias Agopian
4af533c010 material instanced property must be false by default.
this fix auto-instancing.
2022-08-26 14:43:52 -07:00
Balazs Vegh
6a28d2b81c Implement setThreadName() on Windows (#5999) 2022-08-26 13:29:42 -04:00
Philip Rideout
54769a2ad3 gltfio: Move the API for recomputeBoundingBoxes.
Prior to this change, `recomputeBoundingBoxes` was an opt-in config
parameter in ResourceLoader. It is now a method on FilamentInstance.

The old API did not work for dynamically created instances. Since this
is a relatively obscure feature, we considered removing it completely,
especially since the computation requires the presence of CPU-side
vertex data combined with the transform hierarchy.

Instead of removing the feature, we decided to move it to a better
place. This paves the way for some upcoming improvements, which include
reducing the memory footprint for assets. It also improves overall code
organization and separation of concerns.
2022-08-26 09:48:04 -07:00
Mathias Agopian
87cece8379 use separate enums for uniform and sampler binding points (#5984)
Co-authored-by: Benjamin Doherty <bendoherty@google.com>
2022-08-24 16:36:13 -07:00
Philip Rideout
fe3790cb9c WASM: Set CONFIG_MAX_INSTANCES to a small value + hack the GLSL.
Temporary fix until spec constants arrive.

Second attempt, fixes #5859.
2022-08-24 16:24:25 -07:00
gaborvalasek
39cb238065 Fix MSVC warnings (#5926)
* Fix warning C4146: unary minus operator applied to unsigned type, result still unsigned

* Fix warning C4068: unknown pragma 'nounroll'

* Fix warning C4068: unknown pragma 'unroll'

* Fix warning C4068: unknown pragma 'clang'

* Fix warning C4305: 'initializing': truncation from 'double' to 'float'

* Fix warning C4267: 'argument': conversion from 'size_t' to 'utils::FixedCapacityVector<filament::uberz::WritableArchive::Material,std::allocator<T>,true>::size_type', possible loss of data

* Fix warning C4267: 'argument': conversion from 'size_t' to 'uint32_t', possible loss of data

* Fix warning C4244: 'initializing': conversion from 'A' to 'T', possible loss of data

* Fix warning C4334: '<<': result of 32-bit shift implicitly converted to 64 bits (was 64-bit shift intended?)

* Fix warning C4293: '>>': shift count negative or too big, undefined behavior

* Fix diagnostic warning C4189: 'channels': local variable is initialized but not referenced

* Use [[maybe_unused]] where possible and revert aa79bd6fa8.

* Revert unary minus for non-MSVC compilers

* Add macro for enabling warnings temporarily

* Get rid of UTILS_HAS_CXX17

* Revisit warning related macros

Co-authored-by: Levente Koncz <levente.koncz@shapr3d.com>
2022-08-24 11:41:10 -07:00
Mathias Agopian
2182149b7a fix shadows when there is no receivers in the frustum
this case could cause an assert in debug builds. There was a few bugs:

- when computing the intersection between a box and a frustum, a special
  case test had a typo which would cause extra work in some case. Also,
  we were not detecting correctly when there was no intersection at all.
  This could result in some intersection point being found.

- Finally, we reject the intersection volume when it has only 3 vertices
  because that's not a volume.

Fixes #5933
2022-08-24 11:07:32 -07:00
Ben Doherty
006e0548c1 Adjust Metal buffer bindings in preparation for argument buffers (#5986) 2022-08-24 13:50:45 -04:00
Mathias Agopian
8257fbdbf3 Fix a merge that went bad 2022-08-23 17:16:56 -07:00
Mathias Agopian
f57224952a record sampler informations in the material file
The main goal of this change is to have "ugly" code only in filamat.
In particular, the sampler binding information is now recorded
into the material file and used on the filament side to inform the
backend.

This means that on the filament side we only have generic code with
all the "uglyness" in filamat. In particular SamplerBindingMap and
SibGenerator now only exist in filamat.

Files of greater interest:
Material.cpp, MaterialBuilder.cpp
2022-08-23 17:03:30 -07:00
Philip Rideout
3c982cae64 Revert "WASM: Set CONFIG_MAX_INSTANCES to a small value."
This reverts commit 7aa5d4a375.
2022-08-23 16:42:16 -07:00
Mathias Agopian
3ffe63c02c don't use std::is_pod which is soon to be deprecated
fixes #5980
2022-08-23 15:49:35 -07:00
Philip Rideout
7aa5d4a375 WASM: Set CONFIG_MAX_INSTANCES to a small value.
This is a workaround for the following Chrome issues:

https://crbug.com/1348017 Compiling GLSL is very slow with struct arrays
https://crbug.com/1348363 Lighting looks wrong with D3D11 but not OpenGL

This requires a rebuild of materials for WebGL users.

Fixes #5859.
2022-08-23 11:57:26 -07:00
Philip Rideout
1d06dd630a Add CONFIG for MaxInstanceCount. 2022-08-23 09:32:01 -07:00
Mathias Agopian
f630fb6732 'strict' field is no longer needed in Program::Sampler 2022-08-23 09:08:13 -07:00
Benjamin Doherty
df3ea47a3c Release Filament 1.25.6 2022-08-23 12:05:06 -04:00
Johnathon Selstad
6ceb122ae8 Set Frame Delay according to Monitor Refresh Rate (#5942) 2022-08-23 11:56:17 -04:00
Ben Doherty
ec92a0c458 Fix: Metal scissor calculation (#5896) 2022-08-23 11:54:32 -04:00
Ben Doherty
60294c2514 Add stencil API bindings for Java (#5949) 2022-08-23 11:54:09 -04:00
Ben Doherty
94f72ea137 Add stencil API bindings for web (#5976) 2022-08-23 11:53:27 -04:00
Mathias Agopian
9b7295fd8f remove unused mIsMobile attribute 2022-08-22 22:15:02 -07:00
Mathias Agopian
c93b49e714 It was a mistake to change Program's ctor
partially revert a recent change where Program needs a DriverApi in its
ctor. This was a misguided change. Backend API never take a DriverApi
as parameter.

Checking the feature level, for instance, should happen as a 
precondition, or in the backend as postcondition.
2022-08-22 22:15:02 -07:00
Philip Rideout
a81b9a0f09 CMake: fix wasm build on windows machines
Noticed this while trying to help with #5859.
2022-08-22 11:44:36 -07:00
Mathias Agopian
82d9d2a016 Program.h should be a backend public header 2022-08-22 09:36:12 -07:00
Mathias Agopian
d529a7514a DriverApiForward.h should a backend public header 2022-08-22 09:36:12 -07:00
Mathias Agopian
a5c91a6ed4 Cleanup SamplerGroup includes
SamplerGroup should be moved out of backend but it still lives there
for now because it's used as an implementation detail in metal and vk
backends.
2022-08-22 09:36:12 -07:00
Mathias Agopian
357000a0e7 Make ShaderStageFlags an enum class 2022-08-19 22:08:59 -07:00
Mathias Agopian
80e26ba4af Make BindingPoints an enum class 2022-08-19 22:08:59 -07:00
Mathias Agopian
6310a15650 keep only one entry point for specifying shaders on Program 2022-08-19 22:08:59 -07:00
Mathias Agopian
5909215967 keep only 1 entry point for UniformInterfaceBlock::add
add() now take a list of Uniforms, and is the only entry point.
At least clang generates much less code this way.
2022-08-19 16:23:39 -07:00
Mathias Agopian
f0eb1c59b1 don't hardcode uniform block bindings on filament side
GLES3.0 (and GL4.1) need informations about the uniform block bindings
because they don't allow to do that setup in the shaders. So we store
that information in the material blob and retrieve it on the filament
side in Material. This information is passed to Program so it can
create the bindings.

Prior to this change, this information was set by Material itself, but
this ment we had two places where these bindings were hardcoded.


The bulk of the change is to add a new material chunk which stores an
array of {name, binding}, retrieve it on the Material side and pass it
to Program.
2022-08-19 16:23:39 -07:00
Mathias Agopian
22aa429059 Program now needs a DriverApi
This will be needed soon so Program can check the feature level.
2022-08-19 16:23:39 -07:00
Mathias Agopian
3cc5f38da2 Program cleanup.
- remove Program::Shader, use ShaderType instead.
- unhardcode some array sizes
- remove unused code
2022-08-19 16:23:39 -07:00
Mathias Agopian
83985ba910 get rid of PlatformDummyGL
We can't use a compile time failure (e.g. #error) because another
backend (e.g. vulkan) might be supported.

Fixes #5948
2022-08-19 14:38:31 -07:00
Philip Rideout
263d4bfc1e Remove sampler check from VulkanDriver::draw 2022-08-19 12:25:10 -07:00
Philip Rideout
8c608cdce5 gltfio: add ownership query
Adding this getter lets us remove some duplicated state from an
internal client at Google.
2022-08-19 09:58:15 -07:00
Philip Rideout
ceea495da1 Android: prevent misc obfuscation for gltfio
Fixes #5944
2022-08-19 09:36:09 -07:00
Philip Rideout
a0af0a98cb gltfio: minor code cleanup 2022-08-18 13:46:52 -07:00
Mathias Agopian
9e99cfef61 cleanup SamplerBindingMap usages
- remove unused SamplerBindingMap parameter 
  In fact, the SamplerBindingMap is used, but it is passed inside the
  MaterialInfo structure, so it doesn't need to be passed as parameter.

- Don't create unneeded SamplerBindingMap temporaries
2022-08-18 11:00:25 -07:00
Ben Doherty
b6e6733361 Fix Metal GPU capture (#5939) 2022-08-18 12:25:06 -04:00
Ben Doherty
d3cf84680c Add stencil state APIs to MaterialInstance (#5938) 2022-08-18 12:24:42 -04:00
Philip Rideout
8dc6fde588 gltfio API change: assets are now always 'instanced' etc
This change was motivated by some internal work at Google and has the
benefit of simplifying the gltfio API and implementation. There are 2
major API changes:

(1) Consolidate separate loader entry points for GLB and GLTF.

The distinction between GLB and GLTF can be made from the file content
alone, because GLB has a 4-byte magic string in its header. There is no
need for separate entry points.  Clients do not (and should not) need
to check the file name extension.

(2) Remove the distinction between "instanced" and "non-instanced"
glTF assets.

In the new scheme, all assets have at least 1 instance.

Broadly speaking, in gltfio an "asset" is a collection of Filament
objects like textures and vertex buffers, while an "instance" is a
collection of entities and components (e.g. the transform hierarchy).

This API change makes life easier for clients because they no longer
need to decide a priori if they will ever need to add instances.

This change also moves some public-facing methods from FilamentAsset to
FilamentInstance:

    - getSkinCount, getSkinNameAt
    - getJointCountAt, getJointsAt
    - attachSkin, detachSkin
2022-08-18 08:58:24 -07:00
Johnathon Selstad
1938c8239a Add glslang/OSDependent to ThirdParty folder (#5941) 2022-08-17 17:48:50 -07:00
Mathias Agopian
bf43c61a05 fix incorrect assert when uploading cubemaps
this regression was introduced recently.
2022-08-17 16:18:04 -07:00
Johnathon Selstad
1e3ddd612e Organize Subprojects into Folders in the IDE (#5934)
* Begin Sorting SubProjects into Folders

* Add more subprojects to folders

* Add even more subprojects to folders

* Add further subprojects to folders

* Move the last two projects

* Move Resources to a Resources subfolder

* Remove spaces to be stylistically coherent

* Revert Improper CMake Modifications

* Revert erroneous line removals

* Only specify sdl2's folder on WIN32

* Add the shader subprojects to a Generated folder

* Move shaders to Filament/Shaders
2022-08-17 12:42:21 -07:00
Mathias Agopian
bb5d82fce9 fix MaterialBuilder tests 2022-08-17 11:19:39 -07:00
Mathias Agopian
b2ec57776d new feature level API for backends (#5784)
* new feature level API for backends

backend can now return a "feature level", each level corresponds to a
"bundle" of features.
Level1: ES3.0 capabilities
Level2: ES3.1 capabilities + 31 textures + cubemap arrays

Currently metal always returns level 1, GL and Vulkan return level 2
if 31 textures or more are supported.

* Add public APIs for feature levels

* Add infrastructure to check feature levels in materials

* validate material feature level on use

The validation is done when creating a renderable. If the engine doesn't
support the material's feature level, an exception is thrown (or assert
if exceptions are not enabled).

* material documentation

* activate ESSL 3.10 for feature level 2

also generate #defines to identify available feature levels

* support for cubemap arrays in the public API


if feature level 2 is supported, cubemap arrays can be used from the
public API.

* add release notes
2022-08-17 10:14:26 -07:00
Mathias Agopian
7c092a8714 both fragment and vertex shaders need material defines
Fixes #5917
2022-08-17 10:13:28 -07:00
Ben Doherty
53350bbec0 Add View API to enable the stencil buffer (#5886) 2022-08-17 09:25:33 -07:00
Mathias Agopian
c6502054e9 Fix guard bands and TAA with VERTEX_DOMAIN_DEVICE
With VERTEX_DOMAIN_DEVICE the vertex shader doesn't apply the 
projection (since the vertices are already in clip space), however,
both TAA and guard bands need to jitter/offset the clip space, and
it is done at the projection level.

We now store the clip space offset separately so that it can be applied
to VERTEX_DOMAIN_DEVICE vertices.

We also introduce a new material parameter, vertexDomainDeviceJittered,
a boolean that controls whether clip space offset (above) is applied.
This is because a VERTEX_DOMAIN_DEVICE material that uses the built-in
projection matrices generally ends-up with the jitter already applied,
this is the case with the Skybox for instance.

Fixes #5917
2022-08-16 15:32:33 -07:00
Mathias Agopian
35204faa6b use our custom mutex/condition only on ANDROID
For other linux distributions we use the generic C++ ones. I think this
is probably safer and more friendly to non-linux unixes.


Fixes #2861
2022-08-16 14:55:46 -07:00
Benjamin Doherty
9e87a312ab Release Filament 1.25.5 2022-08-16 10:59:05 -07:00
Ben Doherty
e1911eef3a Fix SamplerGroup update issue (#5928) 2022-08-16 10:46:35 -07:00
Philip Rideout
e0c11cfeed Add CONFIG_MINSPEC_UBO_SIZE and fix comment.
Fixed a comment that said "We store 64 bytes per bone.".  The actual
number is 32.

Developers who know their users have powerful devices may wish to exceed
ES3.0 minspec constraints to allow more bones and / or morph targets.

Fixes #5785.
2022-08-16 10:38:33 -07:00
Philip Rideout
b9efd4fbf0 gltfio Android: Fix double free error.
The custom release callback that I provided was in the wrong place; it
was only being used for a path string, not the actual buffer content.
The cgltf API is a bit awkward in this area.

No need to update RELEASE_NOTES because this will be cherry picked to
the RC branch, which is where the bug introduced.

Fixes #5918.
2022-08-15 16:02:31 -07:00
Mathias Agopian
38ca4ceb52 Fix Texture documentation
Fixes #5904
2022-08-15 12:38:57 -07:00
Philip Rideout
bfe8a8aa18 WASM: Allow clients to enable pthreads.
Filament does not yet fully support threads with WASM, but this is a
baby step in that direction.

To enable experimental pthreads support, enable the WEBGL_PTHREADS CMake
option. This will enable pthreads support in `gltfio` and `utils`, which
is known to work, but not when served with GitHub Pages.

The web server must emit COOP, COEP and CORP headers, so our build
instructions now recommend the use of `emrun` for local testing.

This also changes our demos so that they do not use unpkg, which
does not work when using `emrun`, due to cross-origin restrictions.
2022-08-12 15:43:00 -07:00
Philip Rideout
430f060db2 gltfio: concurrent texture downloading and decoding.
This feature can improve load time when textures are downloaded from the
web on non-filesystem platforms like Android.

More specifically, this allows downloaded texture assets to arrive after
the user calls asyncBeginLoad(), which means that decoding and
downloading can occur concurrently.

Prior to this PR, we already used JobSystem for decoding, but we did not
kick off any jobs until after all assets were downloaded.

Still TBD: add this feature for external vertex data.

Partial fix for #5909.
2022-08-11 15:45:29 -07:00
Philip Rideout
62cffc51bb gltfio: remove a memcpy via custom cgltf_file_options.
Earlier versions of cgltf did not support file reader customization.
This was fixed back in Dec 2019 but at the time I did not notice, so
we never bothered cleaning up our usage.

In the future we would like WebGL + Android builds to permit texture
downloads to occur concurrently with the texture decoder jobs. This PR
is basically a preparatory refactoring, but with the nice side effect of
removing a memcpy.
2022-08-11 11:18:12 -07:00
Philip Rideout
75004e9d3e gltfio: add 'detach' methods to allow ownership transfer
These new methods allow gltfio to be integrated into internal Google
libraries.
2022-08-09 14:28:15 -07:00
Mathias Agopian
efba9a636a Stencil reference value can be separate for front and back 2022-08-05 15:34:37 -07:00
Mathias Agopian
e2161fa3af Fix a small discard issue with the stencil buffer
In GL we need to track if a buffer is written at all so that later we
can decide to honor the discard flags or not (see b514b2e9).
2022-08-05 10:30:53 -07:00
Mathias Agopian
6d6e9f965b Remove mRasterState from OpenGLDriver
it was a duplicate state from the true gl state which could easily cause
problems. It only existed to optimize state updates when nothing changed
but we already have fine-grained tests for this.
2022-08-05 10:30:53 -07:00
Mathias Agopian
9307422e54 We don't need the union in StencilOperations anymore 2022-08-05 10:30:53 -07:00
Mathias Agopian
df5b763d33 Remove mStentilState from OpenGLDriver
It wasn't really needed because it's essentially a copy of the GL state.
2022-08-05 10:30:53 -07:00
Mathias Agopian
90ff85b04d StencilState can now use designated initializers
We just remove the custom default ctor.
2022-08-05 10:30:53 -07:00
Mathias Agopian
c1505f3513 improve GL backend stencil state updates
We separate stencilWrite from stencilFunc, which can lead to less
GL state changing.
2022-08-05 10:30:53 -07:00
Filip Henningsson
1bd4a15d5c Ensure UTILS_DEPRECATED is used in the public API 2022-08-05 10:27:48 -07:00
Ben Doherty
7a2ecf8435 Fix PrimitiveInfo size (#5883)
* Fix PrimitiveInfo size

* Make Command 64 bytes
2022-08-04 09:15:09 -07:00
Ben Doherty
3c7ff0ee19 Add additional state to StencilState (#5879)
Separate out stencil operations for back/front facing primitives and add read/write masks.
2022-08-03 18:55:59 -07:00
Mathias Agopian
d3073a8ebd The "Prepare Shadow Pass" was never executed
It was culled by the frame-graph because it didn't have "read" from 
any of its resource, only writes. However, it does set uniforms, so need
to be called.

fix #5874
2022-08-03 16:54:24 -07:00
Romain Guy
59e9f36e25 Update docs for sampler2D arrays 2022-08-03 16:08:28 -07:00
Mathias Agopian
7e21db1de1 Fix StructureOfArray alignments
StructureOfArray always aligned each array to the same alignment as
malloc (usually 8 bytes), but that was not enough if one of its type 
has stricter alignment requirements. 

StructureOfArray now always honors at least the alignment requirement
of each array.

Also removed dependency on EntityInstance.h

Fixes #5727
2022-08-03 14:40:27 -07:00
Mathias Agopian
1f451777b4 Return support for ASTC formats properly.
`Texture::isTextureFormatSupported` always returned `true` for ASTC, it
now queries the hardware as expected.


Fixes #5872
2022-08-03 11:52:35 -07:00
Ben Doherty
832442d092 Move stencil state out of RasterState (#5873) 2022-08-03 11:21:17 -07:00
Mathias Agopian
7101757bff Camera::getPosition() now returns a double3 2022-08-02 19:48:57 -07:00
Mathias Agopian
3090ed1523 make Camera::lookAt() take doubles instead of floats
this matches all the other Camera APIs
2022-08-02 19:48:57 -07:00
Mathias Agopian
1dd2b32a1f make all public API pre-condition violation fatal
We used to have a mix of fatal and non-fatal assertions for precondtions
errors. From now on, we always throw if exceptions are enabled or 
crash with a log otherwise.
2022-08-02 15:15:16 -07:00
Philip Rideout
f75e37cf83 gltfio: fix warning in release build. 2022-08-02 14:32:27 -07:00
Ben Doherty
3fba6754c5 Fix: OpenGL not clearing stencil buffer (#5870) 2022-08-02 14:19:24 -07:00
Benjamin Doherty
d4e2d7f07f Release Filament 1.25.4 2022-08-02 11:47:15 -07:00
Mathias Agopian
7917f74bc8 Fix derivation of SH trig terms recursion
Fixes #5866
2022-08-02 11:22:36 -07:00
Mathias Agopian
7d086beb3f Fix "angle sum trig identity" typo 2022-08-02 11:22:36 -07:00
Mathias Agopian
37cd7d6944 Fix typo in documentation
Fixes #5848
2022-08-02 11:22:36 -07:00
Mathias Agopian
5b71274fa5 get rid of utils::StaticString
In most places this is simply replaced by `std::string_view`.

We also change a few internal/private headers so they accept 
`std::string_view` instead of `utils::CString`.
2022-08-02 09:51:13 -07:00
Philip Rideout
971df18b3c Vulkan: add documentation for cmd buf manager. 2022-08-01 14:26:22 -07:00
Mathias Agopian
841ea86cea MaterialInstance public API friendly to std::string_view
Internally we use std::string_view and the public API is augmented
with APIs that take a length for strings, which makes them useable
with string_view parameters.

Also fix exception specification for all setParameter methods, which
can throw if exceptions are enabled (or exit the program otherwise).
2022-08-01 14:17:29 -07:00
Philip Rideout
f79e703861 Remove vestiges of old API from Stream. 2022-08-01 11:37:38 -07:00
Mathias Agopian
6f9d69e410 skip clear coat if material.clearCoat is null
This allows a material to have clear coat turned on/off dynamically
without paying too much of a price.
2022-08-01 10:22:03 -07:00
Mathias Agopian
e0eaaf4fb9 skip SSAO texture read if SSAO is disabled 2022-08-01 09:49:47 -07:00
Romain Guy
b9b4b7c64d Fix bluegl-gen.py
The comment about MSVC was not properly escaping backslash
sequences, eating some of the comment and generating an
interpreter error on \u.
2022-07-31 13:27:26 -07:00
Ben Doherty
47d58aa484 Metal: implement MSAA stencil buffers (#5834) 2022-07-29 16:22:22 -07:00
Benjamin Doherty
1e87c68435 Fix incorrect shader permutations in MaterialBuilder 2022-07-29 10:55:59 -07:00
MasTraER
54106962fe Fix incorrect precision restoration when computing accurate world translations
When FTransformManager computes accurate world transforms, it adds downcasted leftover to translation part to restore precision.
However, both transltation and leftover are given as float3 - simply adding them resut float3, so addling leftover become meaningless.
one or both should be upcasted first.
2022-07-29 10:54:04 -07:00
Philip Rideout
ec2fee7a4e Fix typo. 2022-07-29 09:19:18 -07:00
Alan Eneev
27aed0a951 Headless EGL: Fallback to a 24-bit depth buffer 2022-07-29 09:17:48 -07:00
Alan Eneev
ec5738c651 Fix PlatformEGLHeadless build and add a build.sh option to build EGL
I have disabled building SDL with headless EGL, because
SDL_config_minimal.h doesn't work with EGL, and I don't know how to
implement a an SDL config that would work with EGL.

I have verified that this works in a separate project, and that it
compiles in this project.

```
$ ./build.sh -e release
$ find ./out/ -name "*EGL*"
./out/cmake-release/filament/backend/CMakeFiles/backend.dir/src/opengl/platforms/PlatformEGL.cpp.o
./out/cmake-release/filament/backend/CMakeFiles/backend.dir/src/opengl/platforms/PlatformEGLHeadless.cpp.o
./out/cmake-release/libs/bluegl/CMakeFiles/bluegl.dir/src/BlueGLLinuxEGL.cpp.o
```
2022-07-29 09:17:07 -07:00
Mathias Agopian
050ffdd585 Fix DoF on WebGL
The issue was that WebGL2.0 doesn't support texture swizzle.


Fixes: #5828
2022-07-28 16:34:07 -07:00
Mathias Agopian
7169c4e386 better test for presence of unpackHalf2x16
This will actually reduce the binary size a bit on mobile.
2022-07-28 15:39:39 -07:00
Mathias Agopian
4b7fa63722 rename ShaderModel enums
GL_ES_30   becomes MOBILE
GL_CORE_41 becomes DESKTOP

ShaderModel controls which flavor of GLSL (GL or ES) is used both when 
reading and outputting materials.

It's also used to set default quality settings and the default precision
of all fragment shaders.

Technically, Vulkan and Metal don't need this distinction, but the GL
backend does.
2022-07-28 15:39:39 -07:00
Philip Rideout
bff0d1dcf4 Add IBL builder to TypeScript, fix #5805 2022-07-28 15:39:06 -07:00
Ben Doherty
1ac469f340 Metal: add initial support for stencil buffers (#5783) 2022-07-28 12:21:32 -07:00
Philip Rideout
3b4c10f952 Update public WebGL viewer to 1.25.3 2022-07-28 12:17:31 -07:00
Philip Rideout
07d2b5ce12 cgltf: enable validation asserts in debug builds 2022-07-28 12:13:06 -07:00
Mathias Agopian
fd2fc23885 updateSamplerGroup() now uses a BufferDescriptor
this is more in line with other APIs of the backend. This change is
complete for the GL backend, but for the metal/vulkan backend we still
use a SamplerGroup as the internal data structure, which is just 
temporary.

Eventually, SamplerGroup should becomes a "filament" only API (not
a backend API).
2022-07-28 10:51:42 -07:00
Mathias Agopian
bf051657ed SamplerGroup now uses a FixedCapacityVector<>
SamplerGroup itself is now a more "traditional" class where copy and
move ctor do what you'd expect. This actually removes a few copy of
the internal data in some cases and uses less memory, at the cost of
doing some heap allocations, but they should be rare and outside of
the main loop.
2022-07-28 10:51:42 -07:00
Mathias Agopian
baecec9a37 take advantage of HwSamplerGroup abstraction in GL backend
we mow do most of the work of validating the sampler parameters and
resolving to an actual GL sampler, when updating a SamplerGroup,
instead of doing this each time a program is made active.

A lot of cpu work is saved when the same samplergroup is reused with
multiple programs.
2022-07-28 10:51:42 -07:00
Mathias Agopian
805e7a10d1 move SamplerGroup out of HwSamplerGroup
this is the start at making HwSamplerGroup more "real". It shouldn't
keep a reference to the filament::SamplerGroup, which is just an object
to pass the data.

for now, we move the SamplerGroup reference into the concrete classes to
keep the same implementation. But now it becomes an "implementation
detail" of the respective backends.
2022-07-28 10:51:42 -07:00
Mathias Agopian
646dfa8b70 SamplerGroup cleanup
- remove the 2 argument version of setSampler
- use a bool instead of bitfield for the dirty state
- try to avoid setting dirty bit if setting same sampler
2022-07-28 10:51:42 -07:00
Philip Rideout
bf8b0d8843 Prevent proguard obfuscation for KTX1Loader. 2022-07-27 10:57:09 -07:00
Mathias Agopian
41b5b997a7 fix all warnings in OpenGLDriver.cpp 2022-07-27 10:50:38 -07:00
Mathias Agopian
881867be71 fix a use-after-move 2022-07-27 10:50:38 -07:00
Philip Rideout
4afd0c5456 Upgrade to emscripten 3.1.15 and remove workaround.
Starting with 3.1.14, embind started to support for `noexcept`
which caused multiple definition errors since we have a workaround
in place that alreadys supplies template instantiations for `noexcept`.

This change should not affect G3 since our JS bindings are not used
in G3.

The upstream fix is here:
https://github.com/emscripten-core/emscripten/pull/17140

Fixes #5789.
2022-07-27 09:10:29 -07:00
Mathias Agopian
ec74cc2d39 Add support for cubemap arrays in the backends
This is not intended to be used yet because we're not currently
checking that cubemap array are actually supported, however, if they
are, they should work.
2022-07-26 15:06:43 -07:00
Mathias Agopian
88b29b9eb7 Make filament and utils public headers -Wall -Wextra warning free
All warnings here where harmless unused parameters.
2022-07-26 11:54:54 -07:00
Mathias Agopian
3974a548d3 fix View::pick() callbacks
the handler parameter would be ignored for some overloads.
2022-07-26 11:54:54 -07:00
Benjamin Doherty
90f508e89d Release Filament 1.25.3 2022-07-26 09:55:54 -07:00
Ben Doherty
d70cee7fec Fix config object related build failures (#5814) 2022-07-26 09:52:19 -07:00
Mathias Agopian
9c542791ef fix max mipmap levels calculation for 3D textures
the depth of the texture wasn't taken into account. In practice this
would restrict the number of mip levels of a 3d texture that would have
a larger dimension in depth.
2022-07-25 11:30:27 -07:00
Mathias Agopian
2d1d6ffb2c fix cubemap uploading
There was a wrong assert in Texture::setImage() as well as a typo when
calling setImage() itself in the sample code.
2022-07-25 11:30:08 -07:00
Romain Guy
9cc7fe97c5 Upgrade Kotlin, AGP, NDK (#5804) 2022-07-22 13:46:13 -07:00
Mathias Agopian
61fb5a588e rework backend texture upload APIs
The main goal is to allow more flexibility, allow cubemap arrays in
the future and better match vk and metal apis.

Main changes:
- remove updateCubeImage
- remove update2DImage
- update3DImage is now the only texture upload backend API

cubemaps are now treated just like a 2D array of 6 layers.

For this reason, Texture::setImage(..., FaceOFfsets) is deprecated.
Additionally, the 2D versions of Texture::setImage() become inline
helpers.

A side effect of this change is that it is now possible to update only
a single face of a cubemap, but also a region of a face (or faces).
2022-07-21 11:12:05 -07:00
Ben Doherty
815d202f6d Use staging buffers to implement Metal buffer updates (#5795)
This PR changes how Metal handles buffer updates. Previously, Metal allocated a full new buffer each time an `updateBufferObject` command was issued; however, it did not copy the previous contents of the buffer over to the new buffer, so partial updates did not work correctly.

Now, Metal allocates a single, private GPU buffer and employs temporary staging buffers whose contents get blitted to the private buffer at each update.

There's still some room for optimizations, and I need to give more thought to how I want to implement `updateBufferObjectUnsynchronized`.
2022-07-18 18:08:00 -07:00
Benjamin Doherty
2b57ec476d Release Filament 1.25.2 2022-07-18 15:13:37 -07:00
Philip Rideout
eb1b700ef7 gltfio: minor fixups to prep for g3 integration. 2022-07-15 08:36:53 -07:00
Mathias Agopian
efc88fbc6f more Engine configuration cleanup
- move all froxel configuration constants out of Engine.h, unlike
  the previous todo/comment, these shouldn't be part of Engine::Config.

- same for irradiance map
2022-07-12 21:25:27 -07:00
hzzengxiaoqi
0ba0591e19 fix adreno driver crash related to morph target change. (#5754)
For some android gpu drivers, some uniform arrays should be initialized to be used in the shader, even if not used.

Co-authored-by: Mathias Agopian <mathias@google.com>
2022-07-12 16:24:19 -07:00
Mathias Agopian
385608648f cleanup comments/documentation and code 2022-07-12 15:58:18 -07:00
Benjamin Doherty
7d170ee391 Fix build 2022-07-12 10:55:34 -07:00
Mathias Agopian
5906d144dd code maintenance/cleanups
- try to help DataReshaper a bit
- fix some typos in comments
- address a few "todos"
- protect mActivePrograms with a lock, as it should
2022-07-12 10:37:40 -07:00
BStringhamVRSK
6a1cc3abe9 Add config object to engine initialization(#5556)
This code adds a config object, "ConfigParams," to Engine creation parameters for setting memory buffer sizes for command buffers and driver handle arena sizes. It will use #define values (FILAMENT_PER_FRAME_COMMANDS_SIZE_IN_MB, etc.) as defaults (and as minimum acceptable values) if the user does not provide values. It attempts to validate the values given to prevent the user from creating a unusable state.
2022-07-11 17:36:45 -07:00
Philip Rideout
6aa11e5ceb gltfio: use openLocalTransformTransaction API. 2022-07-11 16:17:52 -07:00
Benjamin Doherty
ce33fda6ec Release Filament 1.25.1 2022-07-11 15:49:29 -07:00
Mathias Agopian
88768e8003 Fix Conflict with glibc 2.35+ macro.
Fix #5720
2022-07-11 15:25:02 -07:00
Philip Rideout
4f1dd8b304 filamat: dictionaries now store each blob once, not twice.
BlobDictionary and LineDictionary were storing blobs as map keys to
achieve simple compression, but they also stored duplicates of
in a vector for index-based lookup.

Now, the vector is storage and the map has keys that are string_view.
2022-07-11 11:00:04 -07:00
Philip Rideout
42cae27992 filamat: remove more dead codelines. 2022-07-11 11:00:04 -07:00
Mathias Agopian
13f646025b Renderer::getUserTime() now returns seconds as documented
Fixes #5722
2022-07-11 10:53:12 -07:00
Philip Rideout
e7c9197d07 matdbg: rewrite ShaderReplacer to remove bespoke chunk i/o. 2022-07-11 10:09:16 -07:00
Mathias Agopian
7afd5e5963 Camera API and documentation improvements
- getNear() and getCullingFar() now return doubles
- updated documentation
- all setProjection() calls can now throw (when enabled) and will
  do so if preconditions are not met (instead of setting a default
  projection).
- Frustum can now be logged on debug builds
2022-07-11 09:56:41 -07:00
Philip Rideout
d73453863d Fix swallowed errors in MaterialParser.
If `ChunkContainer::parse` failed, then `MaterialParser::parse` was
returning SUCCESS.
2022-07-07 22:34:32 -07:00
Philip Rideout
8b88638232 filamat: remove some unused code. 2022-07-07 22:34:19 -07:00
Ben Doherty
677cdc1239 Add backend test for viewport and scissor (#5767) 2022-07-07 17:22:41 -07:00
MasTraER
a4d3ffe7d4 Metal: add support for scissor (#5644)
This patch enables user scissor in Metal backend; There was no implementation for it.
While the absence of the feature in Metal does not incur serious problem, many rendering glitches were found in apps using ImGui due to it.

Co-authored-by: Benjamin Doherty <bendoherty@google.com>
2022-07-07 13:37:43 -07:00
Philip Rideout
3ada971d8a matdbg: prep for removing bespoke chunk serializer
matdbg should use Flattener / Unflattener rather than imitating them,
this is phase 1.
2022-07-07 11:09:23 -07:00
Philip Rideout
6588cc30ea Use string_view for map lookups.
We can avoid construction of std::string by using std::map with a
special comparator. For some reason, this is not supported with
unordered_map.
2022-07-07 10:07:17 -07:00
Mathias Agopian
09f188659a fix typos in Camera documentation 2022-07-07 09:37:34 -07:00
Benjamin Doherty
ea3553ceb7 Release Filament 1.25.0 2022-07-06 19:07:22 -07:00
Mathias Agopian
a64b1eccdf add API to enable/disable auto-instancing globally.
auto-instancing can have some overhead, so when it is known that the
scene doesn't have identical primitives, it is better to disable it.
(disabled by default).

Also add some missing bindings for `enableAccurateTranslations`.
2022-07-06 15:51:41 -07:00
Mathias Agopian
eda2b7955d Basic automatic instancing. 2022-07-06 15:51:41 -07:00
Mathias Agopian
6bc0e032fc Access the object uniforms relative to gl_InstanceIndex 2022-07-06 15:51:41 -07:00
Ben Doherty
9ce797eee8 Fix destroyEntity documentation (#5760) 2022-07-06 13:17:19 -07:00
Benjamin Doherty
ab2a90374b Release Filament 1.24.0 2022-07-01 12:08:17 -07:00
Ben Doherty
10cf45dd6b Metal: Allow Filament to disregard MTLTexture pixelFormat when importing (#5753) 2022-06-30 16:04:01 -07:00
Philip Rideout
0ac9ecb823 "ShaderBuilder" does not need to exist, remove it.
We were mostly using this as a byte buffer, not a builder.
This PR removes ~200 LoC and 3 files.
2022-06-30 15:37:35 -07:00
Ben Doherty
4096a46547 CocoaPods: include uberz library (#5752) 2022-06-30 14:08:46 -07:00
Philip Rideout
a4ac9bf088 matc: add --template option.
This makes it easier to generate ubershaders without the fancy CMake
machinery available in its `configure_file` command.
2022-06-30 14:08:04 -07:00
Philip Rideout
ecede1e947 matdbg: fix 4x overallocation for SMOLV blobs 2022-06-30 12:06:53 -07:00
Philip Rideout
130053dfad ImGuiHelper: add support for Y flip. (#5748)
Reflects a change from Betty and should be cherry picked to v1.23.3

Users could customize the ImGuiHelper camera, but they had no control
over the scissor coordinates. This allows them to use vertically flipped
coordinates, which, unfortunately, is required for MediaPipe
integration.
2022-06-30 12:04:39 -07:00
Philip Rideout
e3932f6e65 uberz tool: add --append and --template arguments. (#5730) 2022-06-23 13:01:48 -07:00
Philip Rideout
05792fa5f4 Speed up debug builds. (#5735) 2022-06-23 11:22:48 -07:00
daemyung jang
3469e9f4a8 Check the font path is the file (#5734)
If the font path is the directory then it's undefined behavior.
2022-06-23 09:29:50 -07:00
LaiJF
c839a66958 Fix typo (#5728) 2022-06-22 14:48:05 -07:00
Philip Rideout
31757203eb Vulkan: fix VMA-related warning in GitHub builds. (#5729) 2022-06-22 14:41:48 -07:00
Philip Rideout
3f5ed476a6 Refactor the CMake script for gltfio ubershaders. (#5725) 2022-06-22 11:51:03 -07:00
Ben Doherty
97f8b8aa60 Vulkan: Support VMA_DYNAMIC_VULKAN_FUNCTIONS off (#5726) 2022-06-21 15:18:15 -07:00
Mathias Agopian
16af12b58c vulkan: first instance should be 0 not 1 2022-06-17 13:02:41 -07:00
Philip Rideout
1b11c90f2b Vk minor code cleanup. 2022-06-17 12:20:13 -07:00
Philip Rideout
3b71cb13b1 Quick repair to matdbg for alignment padding. (#5717)
This was too tricky, it highlights that we definitely need refactor this
to share code with the flattener / unflattener pipeline. I'll look at
that next.
2022-06-17 12:09:20 -07:00
Ben Doherty
439bcb59cf OpenGL: take mip level into account when checking attachment sizes (#5709) 2022-06-17 12:04:28 -07:00
Ben Doherty
0e9cbeb340 Metal: correctly compute viewport (#5710) 2022-06-17 12:04:09 -07:00
Rahul Sheth
f48a02949c Add EGL support for OpenGL on Linux (#5674) 2022-06-17 10:05:46 -07:00
Mathias Agopian
4eea8a5c07 fix the use of an uninitialized texture (#5711) 2022-06-17 09:57:25 -07:00
LaiJF
a9a420f0eb Fix typo (#5713) 2022-06-16 20:56:14 -07:00
Ben Doherty
b90cf971d9 Update RELEASE_GUIDE with info on re-running 2022-06-16 13:25:06 -07:00
Philip Rideout
1ac57038d9 smolv blobs are now 8-byte aligned in filamat. (breaks materials) (#5705) 2022-06-16 11:23:52 -07:00
Philip Rideout
fe3be06c2c Vk: remove slow allocations workaround, fix scaniverse models. (#5708)
The vkmemalloc performance workaround we implemented with #4128 for Mali
is no longer necessary. Removing this fixes #5432.
2022-06-16 11:19:59 -07:00
Philip Rideout
1ff57e66aa BlueVKDarwin: Simplify the build and loading process. (#5701)
* BlueVKDarwin: Simplify the build and loading process.

Some of our CMake logic was not necessary because we do not staticly
link against anything for Vulkan.  All entry points are dynamically
loaded.

Some of the load-time code was also needlessly complicated. In fact the
ICD environment variable that we were setting is now deprecated.

I tested this PR with:

- macOS + June LunarG SDK
- Android on a Pixel 6

* Fix up, further simplification.
2022-06-15 16:08:34 -07:00
Philip Rideout
036c1706f5 Vk: set ENUMERATE_PORTABILITY_BIT for MoltenVK. (#5699)
This lets us avoid the following validation error.

    Attempting to create a VkDevice from a VkPhysicalDevice which is
    from a portability driver without the
    VK_INSTANCE_CREATE_ENUMERATE_PORTABILITY_BIT_KHR bit in the
    VkInstanceCreateInfo flags being set...
2022-06-15 16:08:14 -07:00
Philip Rideout
467f0acdb4 Vk: do not raise SIGINT for validation errors. (#5700)
This was occasionally useful for debugging specific problems, but it is
much too intrusive to enable in all debug builds.
2022-06-15 16:07:58 -07:00
Philip Rideout
c910cab7a3 Fix bitrot in sample-page-curl (#5703) 2022-06-15 15:14:18 -07:00
Philip Rideout
74346d0046 Update instructions for Vulkan + macOS. (#5693) 2022-06-15 11:50:33 -07:00
844 changed files with 172084 additions and 118561 deletions

View File

@@ -39,8 +39,8 @@ jobs:
run: |
REF=${RELEASE_TAG:-${GITHUB_REF}}
TAG=${REF##*/}
echo ::set-output name=ref::${REF}
echo ::set-output name=tag::${TAG}
echo "ref=${REF}" >> $GITHUB_OUTPUT
echo "tag=${TAG}" >> $GITHUB_OUTPUT
- uses: actions/checkout@v2.0.0
with:
ref: ${{ steps.git_ref.outputs.ref }}
@@ -69,8 +69,8 @@ jobs:
run: |
REF=${RELEASE_TAG:-${GITHUB_REF}}
TAG=${REF##*/}
echo ::set-output name=ref::${REF}
echo ::set-output name=tag::${TAG}
echo "ref=${REF}" >> $GITHUB_OUTPUT
echo "tag=${TAG}" >> $GITHUB_OUTPUT
- uses: actions/checkout@v2.0.0
with:
ref: ${{ steps.git_ref.outputs.ref }}
@@ -97,8 +97,8 @@ jobs:
run: |
REF=${RELEASE_TAG:-${GITHUB_REF}}
TAG=${REF##*/}
echo ::set-output name=ref::${REF}
echo ::set-output name=tag::${TAG}
echo "ref=${REF}" >> $GITHUB_OUTPUT
echo "tag=${TAG}" >> $GITHUB_OUTPUT
- uses: actions/checkout@v2.0.0
with:
ref: ${{ steps.git_ref.outputs.ref }}
@@ -143,8 +143,8 @@ jobs:
run: |
REF=${RELEASE_TAG:-${GITHUB_REF}}
TAG=${REF##*/}
echo ::set-output name=ref::${REF}
echo ::set-output name=tag::${TAG}
echo "ref=${REF}" >> $GITHUB_OUTPUT
echo "tag=${TAG}" >> $GITHUB_OUTPUT
- uses: actions/checkout@v2.0.0
with:
ref: ${{ steps.git_ref.outputs.ref }}
@@ -171,8 +171,8 @@ jobs:
run: |
REF=${RELEASE_TAG:-${GITHUB_REF}}
TAG=${REF##*/}
echo ::set-output name=ref::${REF}
echo ::set-output name=tag::${TAG}
echo "ref=${REF}" >> $GITHUB_OUTPUT
echo "tag=${TAG}" >> $GITHUB_OUTPUT
shell: bash
- uses: actions/checkout@v2.0.0
with:

View File

@@ -15,7 +15,7 @@ To build Filament for Android you must also install the following:
- Android Studio Arctic Fox or more recent
- Android SDK
- Android NDK "side-by-side" 23.1 or higher
- Android NDK 25.1 or higher
### Environment variables
@@ -144,6 +144,9 @@ make sure the command line tools are setup by running:
$ xcode-select --install
```
If you wish to run the Vulkan backend instead of the default Metal backend, you must install
the LunarG SDK, enable "System Global Components", and reboot your machine.
Then run `cmake` and `ninja` to trigger a build:
```
@@ -349,7 +352,7 @@ same version that our continuous builds use.
```
cd <your chosen parent folder for the emscripten SDK>
curl -L https://github.com/emscripten-core/emsdk/archive/refs/tags/3.1.9.zip > emsdk.zip
curl -L https://github.com/emscripten-core/emsdk/archive/refs/tags/3.1.15.zip > emsdk.zip
unzip emsdk.zip ; mv emsdk-* emsdk ; cd emsdk
python ./emsdk.py install latest
python ./emsdk.py activate latest
@@ -365,13 +368,11 @@ export EMSDK=<your chosen home for the emscripten SDK>
The EMSDK variable is required so that the build script can find the Emscripten SDK. The build
creates a `samples` folder that can be used as the root of a simple static web server. Note that you
cannot open the HTML directly from the filesystem due to CORS. One way to deal with this is to
use Python to create a quick localhost server:
cannot open the HTML directly from the filesystem due to CORS. We recommend using the emrun tool
to create a quick localhost server:
```
cd out/cmake-webgl-release/web/samples
python3 -m http.server # Python 3
python -m SimpleHTTPServer # Python 2.7
emrun out/cmake-webgl-release/web/samples --no_browser --port 8000
```
You can then open http://localhost:8000/suzanne.html in your web browser.

View File

@@ -23,6 +23,8 @@ option(FILAMENT_SUPPORTS_XCB "Include XCB support in Linux builds" ON)
option(FILAMENT_SUPPORTS_XLIB "Include XLIB support in Linux builds" ON)
option(FILAMENT_SUPPORTS_EGL_ON_LINUX "Use EGL for OpenGL in Linux builds" OFF)
option(FILAMENT_SUPPORTS_WAYLAND "Include Wayland support in Linux builds" OFF)
option(FILAMENT_SKIP_SDL2 "Skip dependencies of SDL2, and SDL2" OFF)
@@ -33,16 +35,16 @@ set(FILAMENT_NDK_VERSION "" CACHE STRING
"Android NDK version or version prefix to be used when building for Android."
)
set(FILAMENT_PER_RENDER_PASS_ARENA_SIZE_IN_MB "2" CACHE STRING
"Per render pass arena size. Must be roughly 1 MB larger than FILAMENT_PER_FRAME_COMMANDS_SIZE_IN_MB, default 2."
set(FILAMENT_PER_RENDER_PASS_ARENA_SIZE_IN_MB "3" CACHE STRING
"Per render pass arena size. Must be roughly 1 MB larger than FILAMENT_PER_FRAME_COMMANDS_SIZE_IN_MB, default 3."
)
set(FILAMENT_PER_FRAME_COMMANDS_SIZE_IN_MB "1" CACHE STRING
"Size of the high-level draw commands buffer. Rule of thumb, 1 MB less than FILAMENT_PER_RENDER_PASS_ARENA_SIZE_IN_MB, default 1."
set(FILAMENT_PER_FRAME_COMMANDS_SIZE_IN_MB "2" CACHE STRING
"Size of the high-level draw commands buffer. Rule of thumb, 1 MB less than FILAMENT_PER_RENDER_PASS_ARENA_SIZE_IN_MB, default 2."
)
set(FILAMENT_MIN_COMMAND_BUFFERS_SIZE_IN_MB "1" CACHE STRING
"Size of the command-stream buffer. As a rule of thumb use the same value as FILAMENT_PER_FRRAME_COMMANDS_SIZE_IN_MB, default 1."
set(FILAMENT_MIN_COMMAND_BUFFERS_SIZE_IN_MB "2" CACHE STRING
"Size of the command-stream buffer. As a rule of thumb use the same value as FILAMENT_PER_FRRAME_COMMANDS_SIZE_IN_MB, default 2."
)
set(FILAMENT_OPENGL_HANDLE_ARENA_SIZE_IN_MB "4" CACHE STRING
@@ -103,6 +105,9 @@ if (LINUX)
if (FILAMENT_SUPPORTS_WAYLAND)
add_definitions(-DFILAMENT_SUPPORTS_WAYLAND)
set(FILAMENT_SUPPORTS_X11 FALSE)
elseif (FILAMENT_SUPPORTS_EGL_ON_LINUX)
add_definitions(-DFILAMENT_SUPPORTS_EGL_ON_LINUX)
set(FILAMENT_SUPPORTS_X11 FALSE)
else ()
if (FILAMENT_SUPPORTS_XCB)
add_definitions(-DFILAMENT_SUPPORTS_XCB)
@@ -275,6 +280,10 @@ if (FILAMENT_USE_EXTERNAL_GLES3)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DUSE_EXTERNAL_GLES3")
endif()
if (FILAMENT_SUPPORTS_EGL_ON_LINUX)
set(EGL TRUE)
endif()
if (FILAMENT_USE_SWIFTSHADER)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DFILAMENT_USE_SWIFTSHADER")
endif()
@@ -328,19 +337,23 @@ endif()
# ==================================================================================================
# Release compiler flags
# ==================================================================================================
if (NOT MSVC)
if (NOT MSVC AND NOT IOS)
# Omitting stack frame pointers prevents the generation of readable stack traces in crash reports on iOS
set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -fomit-frame-pointer")
# These aren't compatible with -fembed-bitcode (and seem to have no effect on Apple platforms anyway)
if (NOT IOS)
set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -ffunction-sections -fdata-sections")
endif()
set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -ffunction-sections -fdata-sections")
endif()
# On Android RELEASE builds, we disable exceptions and RTTI to save some space (about 75 KiB
# saved by -fno-exception and 10 KiB saved by -fno-rtti).
if (ANDROID OR IOS OR WEBGL)
set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -fno-exceptions -fno-unwind-tables -fno-asynchronous-unwind-tables -fno-rtti")
set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -fno-exceptions -fno-rtti")
if (ANDROID OR WEBGL)
# Omitting unwind info prevents the generation of readable stack traces in crash reports on iOS
set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -fno-unwind-tables -fno-asynchronous-unwind-tables")
endif()
endif()
# With WebGL, we disable RTTI even for debug builds because we pass emscripten::val back and forth
@@ -350,6 +363,10 @@ if (WEBGL)
set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -fno-rtti")
endif()
if (WEBGL_PTHREADS)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -pthread")
endif()
# ==================================================================================================
# Debug compiler flags
# ==================================================================================================
@@ -392,8 +409,8 @@ endif()
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} ${GC_SECTIONS}")
set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} ${GC_SECTIONS} ${B_SYMBOLIC_FUNCTIONS}")
if (WEBGL)
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -s USE_WEBGL2=1")
if (WEBGL_PTHREADS)
set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -pthread")
endif()
# ==================================================================================================
@@ -584,15 +601,6 @@ if (FILAMENT_USE_SWIFTSHADER)
find_library(SWIFTSHADER_VK NAMES vk_swiftshader HINTS "$ENV{SWIFTSHADER_LD_LIBRARY_PATH}")
message(STATUS "Found SwiftShader VK library in: ${SWIFTSHADER_VK}.")
add_definitions(-DFILAMENT_VKLIBRARY_PATH=\"${SWIFTSHADER_VK}\")
elseif (FILAMENT_SUPPORTS_VULKAN)
if (APPLE OR FILAMENT_LINUX_IS_MOBILE)
find_library(Vulkan_LIBRARY NAMES vulkan HINTS "$ENV{VULKAN_SDK}/lib" "$ENV{VULKAN_SDK}/macOS/lib")
if (Vulkan_LIBRARY)
set(Vulkan_FOUND ON)
message(STATUS "Found Vulkan library in SDK: ${Vulkan_LIBRARY}.")
add_definitions(-DFILAMENT_VKLIBRARY_PATH=\"${Vulkan_LIBRARY}\")
endif()
endif()
endif()
# ==================================================================================================
@@ -662,7 +670,7 @@ add_subdirectory(${EXTERNAL}/imgui/tnt)
add_subdirectory(${EXTERNAL}/robin-map/tnt)
add_subdirectory(${EXTERNAL}/smol-v/tnt)
add_subdirectory(${EXTERNAL}/benchmark/tnt)
add_subdirectory(${EXTERNAL}/meshoptimizer)
add_subdirectory(${EXTERNAL}/meshoptimizer/tnt)
add_subdirectory(${EXTERNAL}/cgltf/tnt)
add_subdirectory(${EXTERNAL}/draco/tnt)
add_subdirectory(${EXTERNAL}/jsmn/tnt)
@@ -699,7 +707,9 @@ if (IS_HOST_PLATFORM)
if (FILAMENT_SUPPORTS_OPENGL)
add_subdirectory(${LIBRARIES}/bluegl)
endif()
add_subdirectory(${LIBRARIES}/filamentapp)
if (NOT FILAMENT_SKIP_SDL2)
add_subdirectory(${LIBRARIES}/filamentapp)
endif()
add_subdirectory(${LIBRARIES}/imageio)
add_subdirectory(${FILAMENT}/samples)

View File

@@ -164,8 +164,7 @@ private:
### Strings
- Never use `std::string` in the Filament core renderer. Prefer `utils::CString` or
`utils::StaticString`.
- Never use `std::string` in the Filament core renderer. Prefer `utils::CString` or `std::string_view`.
- When using `std::string` in tools, always include the `std::` qualifier to disambiguate it
from other string types.

View File

@@ -31,7 +31,7 @@ repositories {
}
dependencies {
implementation 'com.google.android.filament:filament-android:1.23.2'
implementation 'com.google.android.filament:filament-android:1.28.2'
}
```
@@ -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:
```
pod 'Filament', '~> 1.23.2'
pod 'Filament', '~> 1.28.2'
```
### Snapshots
@@ -179,6 +179,7 @@ steps:
- [x] KHR_mesh_quantization
- [x] KHR_texture_basisu
- [x] KHR_texture_transform
- [x] EXT_meshopt_compression
## Rendering with Filament

View File

@@ -138,3 +138,34 @@ git push origin main
```
git push origin -u rc/$NEXT_RELEASE
```
## 11. Rebuild the GitHub release (if failed).
Sometimes the GitHub release job will fail. In this case, you can manually re-run the release job.
### Remove any assets uploaded to the release (if needed).
For example, if rebuilding the Mac release, ensure that the `filament-<version>-mac.tgz` artifact
is removed from the release assets.
### Update the release branch (if needed).
If you need to add one or more new commits to the release, perform the following:
First, push the new commit(s) to the `release` branch.
Then, with the release branch checked out with the new commit(s), run
```
git tag -f -a <release tagname>
git push origin -f <release tagname>
```
This will update and force push the tag.
### Re-run the GitHub release workflow
Navigate to [Filament's release
workflow](https://github.com/google/filament/actions/workflows/release.yml). Hit the _Run workflow_
dropdown. Modify _Platform to build_ and _Release tag to build_, then hit _Run workflow_. This will
initiate a new release run.

View File

@@ -5,8 +5,126 @@ A new header is inserted each time a *tag* is created.
## main branch
## v1.23.3
- gltfio: calculate primitive's AABB correctly.
- gltfio: recompute bounding boxes with morph targets
- engine: add missing getters on `MaterialInstance`
- WebGL: add missing `ColorGrading` JS bindings
- engine: improvements/cleanup of Shadow mapping code [⚠️ **Recompile Materials**]
## v1.28.3
- backend: add support for GGP platform
- engine: primitives with `CullingMode::FRONT_AND_BACK` are now skipped.
## v1.28.2
- gltfio: support EXT_meshopt_compression
- release packaging: fixed location of default IBL file
## v1.28.1
- gltfio: fix reloading crash in ubershader mode
- Vulkan: improve performance in the readPixels path
- engine: raise the spot shadows limit to 64, from 14.
- engine: add experimental support for point light shadows.
- gltfio: fix ubershader issues with assignment of dummy textures
- gltfio: material instances and variants are now accessed via `FilamentInstance` [⚠️ **API Change**]
- gltfio: the animator can now only be accessed via `FilamentInstance` [⚠️ **API Change**]
- engine: fix "stable" shadows and make the default cascade splits logarithmic.
- engine: Add new quality options to EVSM shadows + rendering fixes
## v1.28.0
- engine: LiSPSM is now a user settable option
- engine: get the morph target buffer to the given primitive
- Java: Fix TransformManager.getChildren()
- Metal: newer devices are no longer limited to 16 samplers per Material.
- gltfio: fix interpretation of occlusion strength
- engine: minsdk is now 21 instead of 19. This allows the use of OpenGL ES 3.1
- Vulkan: fix black screen regression
## v1.27.2
- gltfio: punctual lights are now duplicated when adding new asset instances
- gltfio: FilamentInstance getAsset method now returns an immutable asset
- gltfio: allow zero-instance assets
- gltfio: fix regression with meshes that have no material
- gltfio: fix regression with recomputeBoundingBoxes()
- filamesh / matinfo: fix minor ASAN issues
- engine: Added `Engine::resetBackendState()`, available only in WebGL builds
## v1.27.1
- Java: add methods for TransformManager.getChildCount(), TransformManager.getChildren() and Scene.hasEntity()
- engine: Fix stencil buffer writes with OpenGL backend.
- gltfio: add new virtual method to MaterialProvider that all plugins must implement
- gltfio: add an assert for inconsistent sRGB flags among usages of a particular texture
- engine: improve scissor documentation
- backend: scissor is no longer clipped to the viewport (done on filament side)
- samples: add debug overdraw visualization to gltf_viewer
## v1.27.0
- WebGL: reduce max instance count to work around Chrome issues [⚠️ **Recompile Materials**]
- engine: rework material/shader sampler binding code [⚠️ **Recompile Materials**]
- gltfio: move the API for `recomputeBoundingBoxes` [⚠️ **API Change**]
- engine: add support for specialization constants [⚠️ **Recompile Materials**]
- gltfio: fix spotlight regression
- gltfio: clear the MaterialInstance cache when creating new instances
## v1.26.0
- engine: new feature level APIs, see `Engine::getSupportedFeatureLevel()`
- engine: add new stencil API to `View` and stencil state APIs to `MaterialInstance` [**NEW API**].
- engine: Fix guard bands and TAA with `vertexDomain:Device` [⚠️ **Recompile Materials**]
- engine: `clipSpaceTransform` is now only available with `vertexDomain:Device` [⚠️ **API Change**]
- gltfio: add unified `AssetLoader::createAsset()` method [⚠️ **API Change**]
- gltfio: all assets are now "instanced" [⚠️ **API Change**]
## v1.25.6
- engine: Add `CONFIG_MINSPEC_UBO_SIZE` as a nicer way to allow exceeding the ES3.0 minspec.
- gltfio: minor efficiency improvement for Android and WebGL builds.
- gltfio: add support for concurrent texture downloading and decoding.
## v1.25.5
- WebGL: upgraded the JS bindings to work with emsdk 3.1.15
- WebGL: added missing IBL builder to TypeScript annotations
- engine: Fix incorrect precision restoration when computing accurate world translations
- engine: make `MaterialInstance` public API friendly to `std::string_view` parameters
- gltfio: add 'detach' methods to allow ownership transfer of entities and components
## v1.25.4
- backend: streamline texture upload APIs [⚠️ **API Change**]
## v1.25.3
- engine: Fix Adreno gpu crash introduced by gpu morph target change
- engine: Add optional memory configuration parameters to Engine initialization
## v1.25.2
- engine: `Camera::getNear()` and `Camera::getCullingFar()` now return `doubles`
- Metal: implement scissor support.
- engine: `Renderer::getUserTime()` now returns seconds as documented (#5722) [⚠️ **API Fix**]
## v1.25.1
- engine: add support for automatic instancing. Must be enabled with `Engine::setAutomaticInstancingEnabled(bool)`
## v1.25.0
- Vulkan: smol-v blobs are now 8-byte aligned within the filamat archive. [⚠️ **Recompile Materials**]
- backend: added support for EGL on linux (headless)
- uberz tool: add --append and --template arguments.
- matc tool: add --template argument.
## v1.24.0
- ImGuiHelper: add support for Y flip.
- Metal: ignore `MTLTexture` formatting when importing external textures.
- materials: add a new `instanced` material parameter that is now mandatory in order to call `getInstanceIndex()`
- gltfio: UbershaderProvider now takes the ubershader archive in its constructor [⚠️ **API Change**]
- gltfio: Fix morphing with sparse accessors.

View File

@@ -29,15 +29,12 @@
// Publishing to Maven Central:
// - Build and upload artifacts with ./gradlew publish
// - Close and release staging repo on Nexus with ./gradlew closeAndReleaseRepository
// - Close and release staging repo on Nexus with ./gradlew closeAndReleaseStagingRepository
//
// The following is needed in ~/gradle/gradle.properties:
//
// SONATYPE_NEXUS_USERNAME=nexus_user
// SONATYPE_NEXUS_PASSWORD=nexus_password
//
// nexusUsername=nexus_user
// nexusPassword=nexus_password
// sonatypeUsername=nexus_user
// sonatypePassword=nexus_password
//
// signing.keyId=pgp_key_id
// signing.password=pgp_key_password
@@ -47,7 +44,7 @@
buildscript {
def path = providers
.gradleProperty("com.google.android.filament.dist-dir")
.forUseAtConfigurationTime().get()
.get()
def directory = objects.fileProperty().fileValue(new File(path)).getAsFile().get()
def filamentPath = directory.absolutePath
@@ -59,18 +56,15 @@ buildscript {
// Warning: changing this property does not work well with incremental builds.
def excludeVulkan = providers
.gradleProperty("com.google.android.filament.exclude-vulkan")
.forUseAtConfigurationTime()
.isPresent()
def matdbg = providers
.gradleProperty("com.google.android.filament.matdbg")
.forUseAtConfigurationTime()
.isPresent()
def abis = ["arm64-v8a", "armeabi-v7a", "x86_64", "x86"]
def newAbis = providers
.gradleProperty("com.google.android.filament.abis")
.forUseAtConfigurationTime()
.get()
.split(',')
if (!newAbis.contains("all")) {
@@ -79,18 +73,20 @@ buildscript {
ext.versions = [
'minSdk': 19,
'targetSdk': 31,
'compileSdk': 31,
'kotlin': '1.6.21',
'targetSdk': 33,
'compileSdk': 33,
'kotlin': '1.7.10',
'kotlin_coroutines': '1.6.1',
'buildTools': '32.0.0',
'ndk': '24.0.8215888'
'buildTools': '33.0.0',
'ndk': '25.1.8937393',
'androidx_core': '1.9.0',
'androidx_annotations': '1.3.0'
]
ext.deps = [
'androidx': [
'annotations': "androidx.annotation:annotation:1.3.0",
'core': "androidx.core:core:1.7.0",
'annotations': "androidx.annotation:annotation:${versions.androidx_annotations}",
'core': "androidx.core:core:${versions.androidx_core}",
],
'kotlin': "org.jetbrains.kotlin:kotlin-stdlib-jdk8:${versions.kotlin}",
'coroutines': [
@@ -101,7 +97,7 @@ buildscript {
dependencies {
// NOTE: See TODO in gradle.properties once we move to Gradle 7.4
classpath 'com.android.tools.build:gradle:7.2.0'
classpath 'com.android.tools.build:gradle:7.3.0'
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:${versions.kotlin}"
}
@@ -148,14 +144,18 @@ buildscript {
}
plugins {
id 'io.codearte.nexus-staging' version '0.30.0'
id "io.github.gradle-nexus.publish-plugin" version "1.1.0"
}
// Nexus Staging configuration
// See https://github.com/Codearte/gradle-nexus-staging-plugin/
nexusStaging {
// See https://github.com/gradle-nexus/publish-plugin
// Publish to https://oss.sonatype.org/ (not s01)
nexusPublishing {
packageGroup = 'com.google.android'
stagingProfileId = '9a75a224a4f17b'
repositories {
sonatype {
stagingProfileId = '9a75a224a4f17b'
}
}
}
subprojects {

View File

@@ -126,8 +126,8 @@ Java_com_google_android_filament_filamat_MaterialBuilder_nMaterialBuilderUniform
JNIEnv* env, jclass, jlong nativeBuilder, jint uniformType, jint precision, jstring name_) {
auto builder = (MaterialBuilder*) nativeBuilder;
const char* name = env->GetStringUTFChars(name_, nullptr);
builder->parameter((MaterialBuilder::UniformType) uniformType,
(MaterialBuilder::ParameterPrecision) precision, name);
builder->parameter(name, (MaterialBuilder::UniformType) uniformType,
(MaterialBuilder::ParameterPrecision) precision);
env->ReleaseStringUTFChars(name_, name);
}
@@ -137,8 +137,8 @@ Java_com_google_android_filament_filamat_MaterialBuilder_nMaterialBuilderUniform
jstring name_) {
auto builder = (MaterialBuilder*) nativeBuilder;
const char* name = env->GetStringUTFChars(name_, nullptr);
builder->parameter((MaterialBuilder::UniformType) uniformType, (size_t) size,
(MaterialBuilder::ParameterPrecision) precision, name);
builder->parameter(name, (size_t) size, (MaterialBuilder::UniformType) uniformType,
(MaterialBuilder::ParameterPrecision) precision);
env->ReleaseStringUTFChars(name_, name);
}
@@ -148,9 +148,8 @@ Java_com_google_android_filament_filamat_MaterialBuilder_nMaterialBuilderSampler
jint precision, jstring name_) {
auto builder = (MaterialBuilder*) nativeBuilder;
const char* name = env->GetStringUTFChars(name_, nullptr);
builder->parameter((MaterialBuilder::SamplerType) samplerType,
(MaterialBuilder::SamplerFormat) format, (MaterialBuilder::ParameterPrecision) precision,
name);
builder->parameter(name, (MaterialBuilder::SamplerType) samplerType,
(MaterialBuilder::SamplerFormat) format, (MaterialBuilder::ParameterPrecision) precision);
env->ReleaseStringUTFChars(name_, name);
}

View File

@@ -84,13 +84,13 @@ Java_com_google_android_filament_Camera_nLookAt(JNIEnv*, jclass, jlong nativeCam
camera->lookAt({eye_x, eye_y, eye_z}, {center_x, center_y, center_z}, {up_x, up_y, up_z});
}
extern "C" JNIEXPORT jfloat JNICALL
extern "C" JNIEXPORT jdouble JNICALL
Java_com_google_android_filament_Camera_nGetNear(JNIEnv*, jclass, jlong nativeCamera) {
Camera *camera = (Camera *) nativeCamera;
return camera->getNear();
}
extern "C" JNIEXPORT jfloat JNICALL
extern "C" JNIEXPORT jdouble JNICALL
Java_com_google_android_filament_Camera_nGetCullingFar(JNIEnv*, jclass,
jlong nativeCamera) {
Camera *camera = (Camera *) nativeCamera;

View File

@@ -316,3 +316,36 @@ Java_com_google_android_filament_Engine_nGetEntityManager(JNIEnv*, jclass, jlong
Engine* engine = (Engine*) nativeEngine;
return (jlong) &engine->getEntityManager();
}
extern "C" JNIEXPORT void JNICALL
Java_com_google_android_filament_Engine_nSetAutomaticInstancingEnabled(JNIEnv*, jclass, jlong nativeEngine, jboolean enable) {
Engine* engine = (Engine*) nativeEngine;
engine->setAutomaticInstancingEnabled(enable);
}
extern "C" JNIEXPORT jboolean JNICALL
Java_com_google_android_filament_Engine_nIsAutomaticInstancingEnabled(JNIEnv*, jclass, jlong nativeEngine) {
Engine* engine = (Engine*) nativeEngine;
return (jboolean)engine->isAutomaticInstancingEnabled();
}
extern "C" JNIEXPORT jint JNICALL
Java_com_google_android_filament_Engine_nGetSupportedFeatureLevel(JNIEnv *, jclass,
jlong nativeEngine) {
Engine* engine = (Engine*) nativeEngine;
return (jint)engine->getSupportedFeatureLevel();
}
extern "C" JNIEXPORT jint JNICALL
Java_com_google_android_filament_Engine_nSetActiveFeatureLevel(JNIEnv *, jclass,
jlong nativeEngine, jint ordinal) {
Engine* engine = (Engine*) nativeEngine;
return (jint)engine->setActiveFeatureLevel((Engine::FeatureLevel)ordinal);
}
extern "C" JNIEXPORT jint JNICALL
Java_com_google_android_filament_Engine_nGetActiveFeatureLevel(JNIEnv *, jclass,
jlong nativeEngine) {
Engine* engine = (Engine*) nativeEngine;
return (jint)engine->getActiveFeatureLevel();
}

View File

@@ -76,10 +76,10 @@ extern "C" JNIEXPORT void JNICALL
Java_com_google_android_filament_LightManager_nBuilderShadowOptions(JNIEnv* env, jclass,
jlong nativeBuilder, jint mapSize, jint cascades, jfloatArray splitPositions,
jfloat constantBias, jfloat normalBias, jfloat shadowFar, jfloat shadowNearHint,
jfloat shadowFarHint, jboolean stable,
jfloat shadowFarHint, jboolean stable, jboolean lispsm,
jfloat polygonOffsetConstant, jfloat polygonOffsetSlope,
jboolean screenSpaceContactShadows, jint stepCount,
jfloat maxShadowDistance, jint vsmMsaaSamples, jfloat blurWidth, jfloat shadowBulbRadius) {
jfloat maxShadowDistance, jint vsmMsaaSamples, jboolean elvsm, jfloat blurWidth, jfloat shadowBulbRadius) {
LightManager::Builder *builder = (LightManager::Builder *) nativeBuilder;
LightManager::ShadowOptions shadowOptions {
.mapSize = (uint32_t)mapSize,
@@ -90,6 +90,7 @@ Java_com_google_android_filament_LightManager_nBuilderShadowOptions(JNIEnv* env,
.shadowNearHint = shadowNearHint,
.shadowFarHint = shadowFarHint,
.stable = (bool)stable,
.lispsm = (bool)lispsm,
.polygonOffsetConstant = polygonOffsetConstant,
.polygonOffsetSlope = polygonOffsetConstant,
.screenSpaceContactShadows = (bool)screenSpaceContactShadows,
@@ -97,6 +98,7 @@ Java_com_google_android_filament_LightManager_nBuilderShadowOptions(JNIEnv* env,
.maxShadowDistance = maxShadowDistance,
.vsm = {
.msaaSamples = (uint8_t) vsmMsaaSamples,
.elvsm = (bool)elvsm,
.blurWidth = blurWidth
},
.shadowBulbRadius = shadowBulbRadius

View File

@@ -341,6 +341,14 @@ Java_com_google_android_filament_MaterialInstance_nSetDepthWrite(JNIEnv*,
instance->setDepthWrite(enable);
}
extern "C"
JNIEXPORT void JNICALL
Java_com_google_android_filament_MaterialInstance_nSetStencilWrite(JNIEnv*, jclass,
jlong nativeMaterialInstance, jboolean enable) {
MaterialInstance* instance = (MaterialInstance*) nativeMaterialInstance;
instance->setStencilWrite(enable);
}
extern "C"
JNIEXPORT void JNICALL
Java_com_google_android_filament_MaterialInstance_nSetDepthCulling(JNIEnv*,
@@ -349,6 +357,70 @@ Java_com_google_android_filament_MaterialInstance_nSetDepthCulling(JNIEnv*,
instance->setDepthCulling(enable);
}
extern "C"
JNIEXPORT void JNICALL
Java_com_google_android_filament_MaterialInstance_nSetStencilCompareFunction(JNIEnv*, jclass,
jlong nativeMaterialInstance, jlong function, jlong face) {
MaterialInstance* instance = (MaterialInstance*) nativeMaterialInstance;
instance->setStencilCompareFunction(
static_cast<MaterialInstance::StencilCompareFunc>(function),
static_cast<MaterialInstance::StencilFace>(face));
}
extern "C"
JNIEXPORT void JNICALL
Java_com_google_android_filament_MaterialInstance_nSetStencilOpStencilFail(JNIEnv*, jclass,
jlong nativeMaterialInstance, jlong op, jlong face) {
MaterialInstance* instance = (MaterialInstance*) nativeMaterialInstance;
instance->setStencilOpStencilFail(
static_cast<MaterialInstance::StencilOperation>(op),
static_cast<MaterialInstance::StencilFace>(face));
}
extern "C"
JNIEXPORT void JNICALL
Java_com_google_android_filament_MaterialInstance_nSetStencilOpDepthFail(JNIEnv*, jclass,
jlong nativeMaterialInstance, jlong op, jlong face) {
MaterialInstance* instance = (MaterialInstance*) nativeMaterialInstance;
instance->setStencilOpDepthFail(
static_cast<MaterialInstance::StencilOperation>(op),
static_cast<MaterialInstance::StencilFace>(face));
}
extern "C"
JNIEXPORT void JNICALL
Java_com_google_android_filament_MaterialInstance_nSetStencilOpDepthStencilPass(JNIEnv*, jclass,
jlong nativeMaterialInstance, jlong op, jlong face) {
MaterialInstance* instance = (MaterialInstance*) nativeMaterialInstance;
instance->setStencilOpDepthStencilPass(
static_cast<MaterialInstance::StencilOperation>(op),
static_cast<MaterialInstance::StencilFace>(face));
}
extern "C"
JNIEXPORT void JNICALL
Java_com_google_android_filament_MaterialInstance_nSetStencilReferenceValue(JNIEnv*, jclass,
jlong nativeMaterialInstance, jint value, jlong face) {
MaterialInstance* instance = (MaterialInstance*) nativeMaterialInstance;
instance->setStencilReferenceValue(value, static_cast<MaterialInstance::StencilFace>(face));
}
extern "C"
JNIEXPORT void JNICALL
Java_com_google_android_filament_MaterialInstance_nSetStencilReadMask(JNIEnv*, jclass,
jlong nativeMaterialInstance, jint readMask, jlong face) {
MaterialInstance* instance = (MaterialInstance*) nativeMaterialInstance;
instance->setStencilReadMask(readMask, static_cast<MaterialInstance::StencilFace>(face));
}
extern "C"
JNIEXPORT void JNICALL
Java_com_google_android_filament_MaterialInstance_nSetStencilWriteMask(JNIEnv*, jclass,
jlong nativeMaterialInstance, jint writeMask, jlong face) {
MaterialInstance* instance = (MaterialInstance*) nativeMaterialInstance;
instance->setStencilWriteMask(writeMask, static_cast<MaterialInstance::StencilFace>(face));
}
extern "C"
JNIEXPORT jstring JNICALL
Java_com_google_android_filament_MaterialInstance_nGetName(JNIEnv* env, jclass,
@@ -380,3 +452,84 @@ Java_com_google_android_filament_MaterialInstance_nDuplicate(JNIEnv* env, jclass
}
return (jlong)mi;
}
extern "C"
JNIEXPORT jfloat JNICALL
Java_com_google_android_filament_MaterialInstance_nGetMaskThreshold(JNIEnv* env, jclass clazz,
jlong nativeMaterialInstance) {
// TODO: implement nGetMaskThreshold()
MaterialInstance* instance = (MaterialInstance*)nativeMaterialInstance;
return instance->getMaskThreshold();
}
extern "C"
JNIEXPORT jfloat JNICALL
Java_com_google_android_filament_MaterialInstance_nGetSpecularAntiAliasingVariance(JNIEnv* env,
jclass clazz, jlong nativeMaterialInstance) {
// TODO: implement nGetSpecularAntiAliasingVariance()
MaterialInstance* instance = (MaterialInstance*)nativeMaterialInstance;
return instance->getSpecularAntiAliasingVariance();
}
extern "C"
JNIEXPORT jfloat JNICALL
Java_com_google_android_filament_MaterialInstance_nGetSpecularAntiAliasingThreshold(JNIEnv* env,
jclass clazz, jlong nativeMaterialInstance) {
// TODO: implement nGetSpecularAntiAliasingThreshold()
MaterialInstance* instance = (MaterialInstance*)nativeMaterialInstance;
return instance->getSpecularAntiAliasingThreshold();
}
extern "C"
JNIEXPORT jboolean JNICALL
Java_com_google_android_filament_MaterialInstance_nIsDoubleSided(JNIEnv* env, jclass clazz,
jlong nativeMaterialInstance) {
// TODO: implement nIsDoubleSided()
MaterialInstance* instance = (MaterialInstance*)nativeMaterialInstance;
return instance->isDoubleSided();
}
extern "C"
JNIEXPORT jint JNICALL
Java_com_google_android_filament_MaterialInstance_nGetCullingMode(JNIEnv* env, jclass clazz,
jlong nativeMaterialInstance) {
// TODO: implement nGetCullingMode()
MaterialInstance* instance = (MaterialInstance*)nativeMaterialInstance;
return (jint)instance->getCullingMode();
}
extern "C"
JNIEXPORT jboolean JNICALL
Java_com_google_android_filament_MaterialInstance_nIsColorWriteEnabled(JNIEnv* env, jclass clazz,
jlong nativeMaterialInstance) {
// TODO: implement nIsColorWriteEnabled()
MaterialInstance* instance = (MaterialInstance*)nativeMaterialInstance;
return instance->isColorWriteEnabled();
}
extern "C"
JNIEXPORT jboolean JNICALL
Java_com_google_android_filament_MaterialInstance_nIsDepthWriteEnabled(JNIEnv* env, jclass clazz,
jlong nativeMaterialInstance) {
// TODO: implement nIsDepthWriteEnabled()
MaterialInstance* instance = (MaterialInstance*)nativeMaterialInstance;
return instance->isDepthWriteEnabled();
}
extern "C"
JNIEXPORT jboolean JNICALL
Java_com_google_android_filament_MaterialInstance_nIsStencilWriteEnabled(JNIEnv* env, jclass clazz,
jlong nativeMaterialInstance) {
// TODO: implement nIsStencilWriteEnabled()
MaterialInstance* instance = (MaterialInstance*)nativeMaterialInstance;
return instance->isStencilWriteEnabled();
}
extern "C"
JNIEXPORT jboolean JNICALL
Java_com_google_android_filament_MaterialInstance_nIsDepthCullingEnabled(JNIEnv* env, jclass clazz,
jlong nativeMaterialInstance) {
// TODO: implement nIsDepthCullingEnabled()
MaterialInstance* instance = (MaterialInstance*)nativeMaterialInstance;
return instance->isDepthCullingEnabled();
}

View File

@@ -83,3 +83,11 @@ Java_com_google_android_filament_Scene_nGetLightCount(JNIEnv *env, jclass type,
Scene* scene = (Scene*) nativeScene;
return (jint) scene->getLightCount();
}
extern "C" JNIEXPORT jboolean JNICALL
Java_com_google_android_filament_Scene_nHasEntity(JNIEnv *env, jclass type, jlong nativeScene,
jint entityId) {
Scene* scene = (Scene*) nativeScene;
Entity entity = Entity::import(entityId);
return (jboolean) scene->hasEntity(entity);
}

View File

@@ -188,69 +188,6 @@ Java_com_google_android_filament_Texture_nGetInternalFormat(JNIEnv*, jclass,
return (jint) texture->getFormat();
}
extern "C" JNIEXPORT jint JNICALL
Java_com_google_android_filament_Texture_nSetImage(JNIEnv* env, jclass, jlong nativeTexture,
jlong nativeEngine, jint level, jint xoffset, jint yoffset, jint width, jint height,
jobject storage, jint remaining,
jint left, jint top, jint type, jint alignment,
jint stride, jint format,
jobject handler, jobject runnable) {
Texture* texture = (Texture*) nativeTexture;
Engine* engine = (Engine*) nativeEngine;
size_t sizeInBytes = getTextureDataSize(texture, (size_t) level, (Texture::Format) format,
(Texture::Type) type, (size_t) stride, (size_t) height, (size_t) alignment);
AutoBuffer nioBuffer(env, storage, 0);
if (sizeInBytes > (size_t(remaining) << nioBuffer.getShift())) {
// BufferOverflowException
return -1;
}
void *buffer = nioBuffer.getData();
auto *callback = JniBufferCallback::make(engine, env, handler, runnable, std::move(nioBuffer));
Texture::PixelBufferDescriptor desc(buffer, sizeInBytes, (backend::PixelDataFormat) format,
(backend::PixelDataType) type, (uint8_t) alignment, (uint32_t) left, (uint32_t) top,
(uint32_t) stride,
callback->getHandler(), &JniBufferCallback::postToJavaAndDestroy, callback);
texture->setImage(*engine, (size_t) level, (uint32_t) xoffset, (uint32_t) yoffset,
(uint32_t) width, (uint32_t) height, std::move(desc));
return 0;
}
extern "C" JNIEXPORT jint JNICALL
Java_com_google_android_filament_Texture_nSetImageCompressed(JNIEnv *env, jclass,
jlong nativeTexture, jlong nativeEngine, jint level, jint xoffset, jint yoffset,
jint width, jint height, jobject storage, jint remaining,
jint, jint, jint, jint, jint compressedSizeInBytes, jint compressedFormat,
jobject handler, jobject runnable) {
Texture *texture = (Texture *) nativeTexture;
Engine *engine = (Engine *) nativeEngine;
size_t sizeInBytes = (size_t) compressedSizeInBytes;
AutoBuffer nioBuffer(env, storage, 0);
if (sizeInBytes > (size_t(remaining) << nioBuffer.getShift())) {
// BufferOverflowException
return -1;
}
void *buffer = nioBuffer.getData();
auto *callback = JniBufferCallback::make(engine, env, handler, runnable, std::move(nioBuffer));
Texture::PixelBufferDescriptor desc(buffer, sizeInBytes,
(backend::CompressedPixelDataType) compressedFormat, (uint32_t) compressedSizeInBytes,
callback->getHandler(), &JniBufferCallback::postToJavaAndDestroy, callback);
texture->setImage(*engine, (size_t) level, (uint32_t) xoffset, (uint32_t) yoffset,
(uint32_t) width, (uint32_t) height, std::move(desc));
return 0;
}
extern "C" JNIEXPORT jint JNICALL
Java_com_google_android_filament_Texture_nSetImage3D(JNIEnv* env, jclass, jlong nativeTexture,
jlong nativeEngine, jint level,
@@ -353,7 +290,10 @@ Java_com_google_android_filament_Texture_nSetImageCubemap(JNIEnv *env, jclass,
(uint32_t) stride,
callback->getHandler(), &JniBufferCallback::postToJavaAndDestroy, callback);
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wdeprecated-declarations"
texture->setImage(*engine, (size_t) level, std::move(desc), faceOffsets);
#pragma clang diagnostic pop
return 0;
}
@@ -388,7 +328,10 @@ Java_com_google_android_filament_Texture_nSetImageCubemapCompressed(JNIEnv *env,
(backend::CompressedPixelDataType) compressedFormat, (uint32_t) compressedSizeInBytes,
callback->getHandler(), &JniBufferCallback::postToJavaAndDestroy, callback);
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wdeprecated-declarations"
texture->setImage(*engine, (size_t) level, std::move(desc), faceOffsets);
#pragma clang diagnostic pop
return 0;
}

View File

@@ -110,6 +110,26 @@ Java_com_google_android_filament_TransformManager_nGetParent(JNIEnv*, jclass,
return tm->getParent((TransformManager::Instance) i).getId();
}
extern "C" JNIEXPORT jint JNICALL
Java_com_google_android_filament_TransformManager_nGetChildCount(JNIEnv*, jclass,
jlong nativeTransformManager, jint i) {
TransformManager* tm = (TransformManager*) nativeTransformManager;
return tm->getChildCount((TransformManager::Instance) i);
}
extern "C" JNIEXPORT void JNICALL
Java_com_google_android_filament_TransformManager_nGetChildren(JNIEnv* env,
jclass, jlong nativeTransformManager, jint i,
jintArray outEntities_, jint count) {
TransformManager* tm = (TransformManager*) nativeTransformManager;
jint* entities = env->GetIntArrayElements(outEntities_, nullptr);
// This is very very gross, we just pretend Entity is just like an jint
// (which it is), but still.
tm->getChildren((TransformManager::Instance) i,
reinterpret_cast<Entity *>(entities), (size_t) count);
env->ReleaseIntArrayElements(outEntities_, entities, 0);
}
extern "C" JNIEXPORT void JNICALL
Java_com_google_android_filament_TransformManager_nSetTransform(JNIEnv* env,
jclass, jlong nativeTransformManager, jint i,

View File

@@ -149,12 +149,13 @@ Java_com_google_android_filament_View_nSetShadowType(JNIEnv*, jclass, jlong nati
extern "C" JNIEXPORT void JNICALL
Java_com_google_android_filament_View_nSetVsmShadowOptions(JNIEnv*, jclass, jlong nativeView,
jint anisotropy, jboolean mipmapping, jfloat minVarianceScale,
jint anisotropy, jboolean mipmapping, jboolean highPrecision, jfloat minVarianceScale,
jfloat lightBleedReduction) {
View* view = (View*) nativeView;
View::VsmShadowOptions options;
options.anisotropy = (uint8_t)anisotropy;
options.mipmapping = (bool)mipmapping;
options.highPrecision = (bool)highPrecision;
options.minVarianceScale = minVarianceScale;
options.lightBleedReduction = lightBleedReduction;
view->setVsmShadowOptions(options);
@@ -462,6 +463,21 @@ Java_com_google_android_filament_View_nPick(JNIEnv* env, jclass,
}, callback->getHandler());
}
extern "C"
JNIEXPORT void JNICALL
Java_com_google_android_filament_View_nSetStencilBufferEnabled(JNIEnv *, jclass, jlong nativeView,
jboolean enabled) {
View* view = (View*) nativeView;
view->setStencilBufferEnabled(enabled);
}
extern "C"
JNIEXPORT jboolean JNICALL
Java_com_google_android_filament_View_nIsStencilBufferEnabled(JNIEnv *, jclass, jlong nativeView) {
View* view = (View*) nativeView;
return view->isStencilBufferEnabled();
}
extern "C"
JNIEXPORT void JNICALL
Java_com_google_android_filament_View_nSetGuardBandOptions(JNIEnv *, jclass,

View File

@@ -400,7 +400,7 @@ public class Camera {
}
/**
* Sets the camera's view matrix.
* Sets the camera's model matrix.
* <p>
* Helper method to set the camera's entity transform component.
* Remember that the Camera "looks" towards its -z axis.
@@ -412,29 +412,29 @@ public class Camera {
* engine.getTransformManager().getInstance(camera->getEntity()), viewMatrix);
* </pre>
*
* @param viewMatrix The camera position and orientation provided as a <b>rigid transform</b> matrix.
* @param modelMatrix The camera position and orientation provided as a <b>rigid transform</b> matrix.
*/
public void setModelMatrix(@NonNull @Size(min = 16) float[] viewMatrix) {
Asserts.assertMat4fIn(viewMatrix);
nSetModelMatrix(getNativeObject(), viewMatrix);
public void setModelMatrix(@NonNull @Size(min = 16) float[] modelMatrix) {
Asserts.assertMat4fIn(modelMatrix);
nSetModelMatrix(getNativeObject(), modelMatrix);
}
/**
* Sets the camera's view matrix.
* Sets the camera's model matrix.
* <p>
* Helper method to set the camera's entity transform component.
* Remember that the Camera "looks" towards its -z axis.
* <p>
*
* @param viewMatrix The camera position and orientation provided as a <b>rigid transform</b> matrix.
* @param modelMatrix The camera position and orientation provided as a <b>rigid transform</b> matrix.
*/
public void setModelMatrix(@NonNull @Size(min = 16) double[] viewMatrix) {
Asserts.assertMat4In(viewMatrix);
nSetModelMatrixFp64(getNativeObject(), viewMatrix);
public void setModelMatrix(@NonNull @Size(min = 16) double[] modelMatrix) {
Asserts.assertMat4In(modelMatrix);
nSetModelMatrixFp64(getNativeObject(), modelMatrix);
}
/**
* Sets the camera's view matrix.
* Sets the camera's model matrix.
*
* @param eyeX x-axis position of the camera in world space
* @param eyeY y-axis position of the camera in world space
@@ -456,7 +456,7 @@ public class Camera {
* @return Distance to the near plane
*/
public float getNear() {
return nGetNear(getNativeObject());
return (float)nGetNear(getNativeObject());
}
/**
@@ -464,7 +464,7 @@ public class Camera {
* @return Distance to the far plane
*/
public float getCullingFar() {
return nGetCullingFar(getNativeObject());
return (float)nGetCullingFar(getNativeObject());
}
/**
@@ -549,10 +549,10 @@ public class Camera {
/**
* Retrieves the camera's view matrix. The view matrix is the inverse of the model matrix.
*
* @param out A 16-float array where the model view will be stored, or null in which
* @param out A 16-float array where the view matrix will be stored, or null in which
* case a new array is allocated.
*
* @return A 16-float array containing the camera's view as a column-major matrix.
* @return A 16-float array containing the camera's column-major view matrix.
*/
@NonNull @Size(min = 16)
public float[] getViewMatrix(@Nullable @Size(min = 16) float[] out) {
@@ -567,7 +567,7 @@ public class Camera {
* @param out A 16-double array where the model view will be stored, or null in which
* case a new array is allocated.
*
* @return A 16-double array containing the camera's view as a column-major matrix.
* @return A 16-double array containing the camera's column-major view matrix.
*/
@NonNull @Size(min = 16)
public double[] getViewMatrix(@Nullable @Size(min = 16) double[] out) {
@@ -787,8 +787,8 @@ public class Camera {
private static native void nSetModelMatrix(long nativeCamera, float[] in);
private static native void nSetModelMatrixFp64(long nativeCamera, double[] in);
private static native void nLookAt(long nativeCamera, double eyeX, double eyeY, double eyeZ, double centerX, double centerY, double centerZ, double upX, double upY, double upZ);
private static native float nGetNear(long nativeCamera);
private static native float nGetCullingFar(long nativeCamera);
private static native double nGetNear(long nativeCamera);
private static native double nGetCullingFar(long nativeCamera);
private static native void nGetProjectionMatrix(long nativeCamera, double[] out);
private static native void nGetCullingProjectionMatrix(long nativeCamera, double[] out);
private static native void nGetScaling(long nativeCamera, double[] out);

View File

@@ -47,7 +47,7 @@ import com.google.android.filament.proguard.UsedByReflection;
* <pre>
* import com.google.android.filament.*
*
* Engin engine = Engine.create();
* Engine engine = Engine.create();
* SwapChain swapChain = engine.createSwapChain(nativeWindow);
* Renderer renderer = engine.createRenderer();
* Scene scene = engine.createScene();
@@ -107,6 +107,7 @@ import com.google.android.filament.proguard.UsedByReflection;
*/
public class Engine {
private static final Backend[] sBackendValues = Backend.values();
private static final FeatureLevel[] sFeatureLevelValues = FeatureLevel.values();
private long mNativeObject;
@@ -141,6 +142,18 @@ public class Engine {
NOOP,
}
/**
* Defines the backend's feature levels.
*/
public enum FeatureLevel {
/** Reserved, don't use */
FEATURE_LEVEL_0,
/** OpenGL ES 3.0 features (default) */
FEATURE_LEVEL_1,
/** OpenGL ES 3.1 features + 31 textures units + cubemap arrays */
FEATURE_LEVEL_2
};
private Engine(long nativeEngine) {
mNativeObject = nativeEngine;
mTransformManager = new TransformManager(nGetTransformManager(nativeEngine));
@@ -258,6 +271,88 @@ public class Engine {
return sBackendValues[(int) nGetBackend(getNativeObject())];
}
/**
* Helper to enable accurate translations.
* If you need this Engine to handle a very large world space, one way to achieve this
* automatically is to enable accurate translations in the TransformManager. This helper
* provides a convenient way of doing that.
* This is typically called once just after creating the Engine.
*/
public void enableAccurateTranslations() {
getTransformManager().setAccurateTranslationsEnabled(true);
}
/**
* Query the feature level supported by the selected backend.
*
* A specific feature level needs to be set before the corresponding features can be used.
*
* @return FeatureLevel supported the selected backend.
* @see #setActiveFeatureLevel
*/
@NonNull
public FeatureLevel getSupportedFeatureLevel() {
return sFeatureLevelValues[(int) nGetSupportedFeatureLevel(getNativeObject())];
}
/**
* Activate all features of a given feature level. By default FeatureLevel::FEATURE_LEVEL_1 is
* active. The selected feature level must not be higher than the value returned by
* getActiveFeatureLevel() and it's not possible lower the active feature level.
*
* @param featureLevel the feature level to activate. If featureLevel is lower than
* getActiveFeatureLevel(), the current (higher) feature level is kept.
* If featureLevel is higher than getSupportedFeatureLevel(), an exception
* is thrown, or the program is terminated if exceptions are disabled.
*
* @return the active feature level.
*
* @see #getSupportedFeatureLevel
* @see #getActiveFeatureLevel
*/
@NonNull
public FeatureLevel setActiveFeatureLevel(@NonNull FeatureLevel featureLevel) {
return sFeatureLevelValues[(int) nSetActiveFeatureLevel(getNativeObject(), featureLevel.ordinal())];
}
/**
* Returns the currently active feature level.
* @return currently active feature level
* @see #getSupportedFeatureLevel
* @see #setActiveFeatureLevel
*/
@NonNull
public FeatureLevel getActiveFeatureLevel() {
return sFeatureLevelValues[(int) nGetActiveFeatureLevel(getNativeObject())];
}
/**
* Enables or disables automatic instancing of render primitives. Instancing of render primitive
* can greatly reduce CPU overhead but requires the instanced primitives to be identical
* (i.e. use the same geometry) and use the same MaterialInstance. If it is known that the
* scene doesn't contain any identical primitives, automatic instancing can have some
* overhead and it is then best to disable it.
*
* Disabled by default.
*
* @param enable true to enable, false to disable automatic instancing.
*
* @see RenderableManager
* @see MaterialInstance
*/
public void setAutomaticInstancingEnabled(boolean enable) {
nSetAutomaticInstancingEnabled(getNativeObject(), enable);
}
/**
* @return true if automatic instancing is enabled, false otherwise.
* @see #setAutomaticInstancingEnabled
*/
public boolean isAutomaticInstancingEnabled() {
return nIsAutomaticInstancingEnabled(getNativeObject());
}
// SwapChain
/**
@@ -593,8 +688,11 @@ public class Engine {
}
/**
* Destroys an <code>entity</code> and all its components.
* Destroys all Filament-known components from this <code>entity</code>.
* <p>
* This method destroys Filament components only, not the <code>entity</code> itself. To destroy
* the <code>entity</code> use <code>EntityManager#destroy</code>.
*
* It is recommended to destroy components individually before destroying their
* <code>entity</code>, this gives more control as to when the destruction really happens.
* Otherwise, orphaned components are garbage collected, which can happen at a later time.
@@ -717,4 +815,9 @@ public class Engine {
private static native long nGetRenderableManager(long nativeEngine);
private static native long nGetJobSystem(long nativeEngine);
private static native long nGetEntityManager(long nativeEngine);
private static native void nSetAutomaticInstancingEnabled(long nativeEngine, boolean enable);
private static native boolean nIsAutomaticInstancingEnabled(long nativeEngine);
private static native int nGetSupportedFeatureLevel(long nativeEngine);
private static native int nSetActiveFeatureLevel(long nativeEngine, int ordinal);
private static native int nGetActiveFeatureLevel(long nativeEngine);
}

View File

@@ -240,7 +240,7 @@ public class LightManager {
*/
@NonNull
@Size(min = 3)
public float[] cascadeSplitPositions = { 0.25f, 0.50f, 0.75f };
public float[] cascadeSplitPositions = { 0.125f, 0.25f, 0.50f };
/** Constant bias in world units (e.g. meters) by which shadows are moved away from the
* light. 1mm by default.
@@ -280,9 +280,25 @@ public class LightManager {
* Controls whether the shadow map should be optimized for resolution or stability.
* When set to true, all resolution enhancing features that can affect stability are
* disabling, resulting in significantly lower resolution shadows, albeit stable ones.
*
* Setting this flag to true always disables LiSPSM (see below).
*/
public boolean stable = false;
/**
* LiSPSM, or light-space perspective shadow-mapping is a technique allowing to better
* optimize the use of the shadow-map texture. When enabled the effective resolution of
* shadows is greatly improved and yields result similar to using cascades without the
* extra cost. LiSPSM comes with some drawbacks however, in particular it is incompatible
* with blurring because it effectively affects the blur kernel size.
*
* Blurring is only an issue when using ShadowType.VSM with a large blur or with
* ShadowType.PCSS however.
*
* If these blurring artifacts become problematic, this flag can be used to disable LiSPSM.
*/
public boolean lispsm = false;
/**
* Constant bias in depth-resolution units by which shadows are moved away from the
* light. The default value of 0.5 is used to round depth values up.
@@ -346,6 +362,15 @@ public class LightManager {
@IntRange(from = 1)
public int vsmMsaaSamples = 1;
/**
* When elvsm is set to true, "Exponential Layered VSM without Layers" are used. It is
* an improvement to the default EVSM which suffers important light leaks. Enabling
* ELVSM for a single shadowmap doubles the memory usage of all shadow maps.
* ELVSM is mostly useful when large blurs are used.
*/
public boolean elvsm = false;
/**
* Blur width for the VSM blur. Zero do disable.
* The maximum value is 125.
@@ -470,11 +495,6 @@ public class LightManager {
/**
* Whether this Light casts shadows (disabled by default)
*
* <p>
* <b>warning:</b>
* {@link Type#POINT} lights cannot cast shadows.
* </p>
*
* @param enable Enables or disables casting shadows from this Light.
*
* @return This Builder, for chaining calls.
@@ -496,11 +516,11 @@ public class LightManager {
nBuilderShadowOptions(mNativeBuilder,
options.mapSize, options.shadowCascades, options.cascadeSplitPositions,
options.constantBias, options.normalBias, options.shadowFar, options.shadowNearHint,
options.shadowFarHint, options.stable,
options.shadowFarHint, options.stable, options.lispsm,
options.polygonOffsetConstant, options.polygonOffsetSlope,
options.screenSpaceContactShadows,
options.stepCount, options.maxShadowDistance, options.vsmMsaaSamples,
options.blurWidth, options.shadowBulbRadius);
options.elvsm, options.blurWidth, options.shadowBulbRadius);
return this;
}
@@ -1158,7 +1178,14 @@ public class LightManager {
private static native void nDestroyBuilder(long nativeBuilder);
private static native boolean nBuilderBuild(long nativeBuilder, long nativeEngine, int entity);
private static native void nBuilderCastShadows(long nativeBuilder, boolean enable);
private static native void nBuilderShadowOptions(long nativeBuilder, int mapSize, int cascades, float[] splitPositions, float constantBias, float normalBias, float shadowFar, float shadowNearHint, float shadowFarhint, boolean stable, float polygonOffsetConstant, float polygonOffsetSlope, boolean screenSpaceContactShadows, int stepCount, float maxShadowDistance, int vsmMsaaSamples, float blurWidth, float shadowBulbRadius);
private static native void nBuilderShadowOptions(long nativeBuilder, int mapSize,
int cascades, float[] splitPositions,
float constantBias, float normalBias,
float shadowFar, float shadowNearHint, float shadowFarhint,
boolean stable, boolean lispsm,
float polygonOffsetConstant, float polygonOffsetSlope,
boolean screenSpaceContactShadows, int stepCount, float maxShadowDistance,
int vsmMsaaSamples, boolean elvsm, float blurWidth, float shadowBulbRadius);
private static native void nBuilderCastLight(long nativeBuilder, boolean enabled);
private static native void nBuilderPosition(long nativeBuilder, float x, float y, float z);
private static native void nBuilderDirection(long nativeBuilder, float x, float y, float z);

View File

@@ -36,6 +36,7 @@ import java.util.Set;
*
* @see <a href="https://google.github.io/filament/Materials.html">Filament Materials Guide</a>
*/
@UsedByNative("AssetLoader.cpp")
public class Material {
static final class EnumCache {
private EnumCache() { }

View File

@@ -20,7 +20,11 @@ import androidx.annotation.IntRange;
import androidx.annotation.NonNull;
import androidx.annotation.Size;
import com.google.android.filament.proguard.UsedByNative;
@UsedByNative("AssetLoader.cpp")
public class MaterialInstance {
private static final Material.CullingMode[] sCullingModeValues = Material.CullingMode.values();
private Material mMaterial;
private String mName;
private long mNativeObject;
@@ -49,6 +53,54 @@ public class MaterialInstance {
MAT4
}
/**
* Operations that control how the stencil buffer is updated.
*/
public enum StencilOperation {
/**
* Keeps the current value.
*/
KEEP,
/**
* Sets the value to 0.
*/
ZERO,
/**
* Sets the value to the stencil reference value.
*/
REPLACE,
/**
* Increments the current value. Clamps to the maximum representable unsigned value.
*/
INCR_CLAMP,
/**
* Increments the current value. Wraps value to zero when incrementing the maximum
* representable unsigned value.
*/
INCR_WRAP,
/**
* Decrements the current value. Clamps to 0.
*/
DECR_CLAMP,
/**
* Decrements the current value. Wraps value to the maximum representable unsigned value
* when decrementing a value of zero.
*/
DECR_WRAP,
/**
* Bitwise inverts the current value.
*/
INVERT,
}
public enum StencilFace {
FRONT,
BACK,
FRONT_AND_BACK
}
// Converts the StencilFace enum ordinal to Filament's equivalent bit field.
static final int[] sStencilFaceMapping = {0x1, 0x2, 0x3};
public MaterialInstance(Engine engine, long nativeMaterialInstance) {
mNativeObject = nativeMaterialInstance;
mNativeMaterial = nGetMaterial(mNativeObject);
@@ -351,19 +403,40 @@ public class MaterialInstance {
}
/**
* Set up a custom scissor rectangle; by default this encompasses the View.
* Set-up a custom scissor rectangle; by default it is disabled.
*
* @param left left coordinate of the scissor box
* @param bottom bottom coordinate of the scissor box
* <p>
* The scissor rectangle gets clipped by the View's viewport, in other words, the scissor
* cannot affect fragments outside of the View's Viewport.
* </p>
*
* <p>
* Currently the scissor is not compatible with dynamic resolution and should always be
* disabled when dynamic resolution is used.
* </p>
*
* @param left left coordinate of the scissor box relative to the viewport
* @param bottom bottom coordinate of the scissor box relative to the viewport
* @param width width of the scissor box
* @param height height of the scissor box
*
* @see #unsetScissor
* @see View#setViewport
* @see View#setDynamicResolutionOptions
*/
public void setScissor(@IntRange(from = 0) int left, @IntRange(from = 0) int bottom,
@IntRange(from = 0) int width, @IntRange(from = 0) int height) {
nSetScissor(getNativeObject(), left, bottom, width, height);
}
/** Returns the scissor rectangle to its default setting, which encompasses the View. */
/**
* Returns the scissor rectangle to its default disabled setting.
* <p>
* Currently the scissor is not compatible with dynamic resolution and should always be
* disabled when dynamic resolution is used.
* </p>
* @see View#setDynamicResolutionOptions
*/
public void unsetScissor() {
nUnsetScissor(getNativeObject());
}
@@ -401,6 +474,14 @@ public class MaterialInstance {
nSetMaskThreshold(getNativeObject(), threshold);
}
/**
* Gets the minimum alpha value a fragment must have to not be discarded when the blend
* mode is MASKED
*/
public float getMaskThreshold() {
return nGetMaskThreshold(getNativeObject());
}
/**
* Sets the screen space variance of the filter kernel used when applying specular
* anti-aliasing. The default value is set to 0.15. The specified value should be between
@@ -414,6 +495,14 @@ public class MaterialInstance {
nSetSpecularAntiAliasingVariance(getNativeObject(), variance);
}
/**
* Gets the screen space variance of the filter kernel used when applying specular
* anti-aliasing.
*/
public float getSpecularAntiAliasingVariance() {
return nGetSpecularAntiAliasingVariance(getNativeObject());
}
/**
* Sets the clamping threshold used to suppress estimation errors when applying specular
* anti-aliasing. The default value is set to 0.2. The specified value should be between 0
@@ -427,6 +516,14 @@ public class MaterialInstance {
nSetSpecularAntiAliasingThreshold(getNativeObject(), threshold);
}
/**
* Gets the clamping threshold used to suppress estimation errors when applying specular
* anti-aliasing.
*/
public float getSpecularAntiAliasingThreshold() {
return nGetSpecularAntiAliasingThreshold(getNativeObject());
}
/**
* Enables or disables double-sided lighting if the parent Material has double-sided capability,
* otherwise prints a warning. If double-sided lighting is enabled, backface culling is
@@ -440,6 +537,14 @@ public class MaterialInstance {
nSetDoubleSided(getNativeObject(), doubleSided);
}
/**
* Returns whether double-sided lighting is enabled when the parent Material has double-sided
* capability.
*/
public boolean isDoubleSided() {
return nIsDoubleSided(getNativeObject());
}
/**
* Overrides the default triangle culling state that was set on the material.
*
@@ -447,10 +552,18 @@ public class MaterialInstance {
* <a href="https://google.github.io/filament/Materials.html#materialdefinitions/materialblock/rasterization:culling">
* Rasterization: culling</a>
*/
public void setCullingMode(Material.CullingMode mode) {
public void setCullingMode(@NonNull Material.CullingMode mode) {
nSetCullingMode(getNativeObject(), mode.ordinal());
}
/**
* Returns the face culling mode.
*/
@NonNull
public Material.CullingMode getCullingMode() {
return sCullingModeValues[nGetCullingMode(getNativeObject())];
}
/**
* Overrides the default color-buffer write state that was set on the material.
*
@@ -462,6 +575,13 @@ public class MaterialInstance {
nSetColorWrite(getNativeObject(), enable);
}
/**
* Returns whether color write is enabled.
*/
public boolean isColorWriteEnabled() {
return nIsColorWriteEnabled(getNativeObject());
}
/**
* Overrides the default depth-buffer write state that was set on the material.
*
@@ -473,6 +593,27 @@ public class MaterialInstance {
nSetDepthWrite(getNativeObject(), enable);
}
/**
* Returns whether depth write is enabled.
*/
public boolean isDepthWriteEnabled() {
return nIsDepthWriteEnabled(getNativeObject());
}
/**
* Enables or Disable stencil writes
*/
public void setStencilWrite(boolean enable) {
nSetStencilWrite(getNativeObject(), enable);
}
/**
* Returns whether stencil write is enabled.
*/
public boolean isStencilWriteEnabled() {
return nIsStencilWriteEnabled(getNativeObject());
}
/**
* Overrides the default depth testing state that was set on the material.
*
@@ -484,6 +625,215 @@ public class MaterialInstance {
nSetDepthCulling(getNativeObject(), enable);
}
/**
* Returns whether depth culling is enabled.
*/
public boolean isDepthCullingEnabled() {
return nIsDepthCullingEnabled(getNativeObject());
}
/**
* Sets the stencil comparison function (default is {@link TextureSampler.CompareFunction#ALWAYS}).
*
* <p>
* It's possible to set separate stencil comparison functions; one for front-facing polygons,
* and one for back-facing polygons. The face parameter determines the comparison function(s)
* updated by this call.
* </p>
*
* @param func the stencil comparison function
* @param face the faces to update the comparison function for
*/
public void setStencilCompareFunction(TextureSampler.CompareFunction func, StencilFace face) {
nSetStencilCompareFunction(getNativeObject(), func.ordinal(),
sStencilFaceMapping[face.ordinal()]);
}
/**
* Sets the stencil comparison function for both front and back-facing polygons.
* @see #setStencilCompareFunction(TextureSampler.CompareFunction, StencilFace)
*/
public void setStencilCompareFunction(TextureSampler.CompareFunction func) {
setStencilCompareFunction(func, StencilFace.FRONT_AND_BACK);
}
/**
* Sets the stencil fail operation (default is {@link StencilOperation#KEEP}).
*
* <p>
* The stencil fail operation is performed to update values in the stencil buffer when the
* stencil test fails.
* </p>
*
* <p>
* It's possible to set separate stencil fail operations; one for front-facing polygons, and one
* for back-facing polygons. The face parameter determines the stencil fail operation(s) updated
* by this call.
* </p>
*
* @param op the stencil fail operation
* @param face the faces to update the stencil fail operation for
*/
public void setStencilOpStencilFail(StencilOperation op, StencilFace face) {
nSetStencilOpStencilFail(getNativeObject(), op.ordinal(),
sStencilFaceMapping[face.ordinal()]);
}
/**
* Sets the stencil fail operation for both front and back-facing polygons.
* @see #setStencilOpStencilFail(StencilOperation, StencilFace)
*/
public void setStencilOpStencilFail(StencilOperation op) {
setStencilOpStencilFail(op, StencilFace.FRONT_AND_BACK);
}
/**
* Sets the depth fail operation (default is {@link StencilOperation#KEEP}).
*
* <p>
* The depth fail operation is performed to update values in the stencil buffer when the depth
* test fails.
* </p>
*
* <p>
* It's possible to set separate depth fail operations; one for front-facing polygons, and one
* for back-facing polygons. The face parameter determines the depth fail operation(s) updated
* by this call.
* </p>
*
* @param op the depth fail operation
* @param face the faces to update the depth fail operation for
*/
public void setStencilOpDepthFail(StencilOperation op, StencilFace face) {
nSetStencilOpDepthFail(getNativeObject(), op.ordinal(),
sStencilFaceMapping[face.ordinal()]);
}
/**
* Sets the depth fail operation for both front and back-facing polygons.
* @see #setStencilOpDepthFail(StencilOperation, StencilFace)
*/
public void setStencilOpDepthFail(StencilOperation op) {
setStencilOpDepthFail(op, StencilFace.FRONT_AND_BACK);
}
/**
* Sets the depth-stencil pass operation (default is {@link StencilOperation#KEEP}).
*
* <p>
* The depth-stencil pass operation is performed to update values in the stencil buffer when
* both the stencil test and depth test pass.
* </p>
*
* <p>
* It's possible to set separate depth-stencil pass operations; one for front-facing polygons,
* and one for back-facing polygons. The face parameter determines the depth-stencil pass
* operation(s) updated by this call.
* </p>
*
* @param op the depth-stencil pass operation
* @param face the faces to update the depth-stencil operation for
*/
public void setStencilOpDepthStencilPass(StencilOperation op, StencilFace face) {
nSetStencilOpDepthStencilPass(getNativeObject(), op.ordinal(),
sStencilFaceMapping[face.ordinal()]);
}
/**
* Sets the depth-stencil pass operation for both front and back-facing polygons.
* @see #setStencilOpDepthStencilPass(StencilOperation, StencilFace)
*/
public void setStencilOpDepthStencilPass(StencilOperation op) {
setStencilOpDepthStencilPass(op, StencilFace.FRONT_AND_BACK);
}
/**
* Sets the stencil reference value (default is 0).
*
* <p>
* The stencil reference value is the left-hand side for stencil comparison tests. It's also
* used as the replacement stencil value when {@link StencilOperation} is
* {@link StencilOperation#REPLACE}.
* </p>
*
* <p>
* It's possible to set separate stencil reference values; one for front-facing polygons, and
* one for back-facing polygons. The face parameter determines the reference value(s) updated by
* this call.
* </p>
*
* @param value the stencil reference value (only the least significant 8 bits are used)
* @param face the faces to update the reference value for
*/
public void setStencilReferenceValue(@IntRange(from = 0, to = 255) int value, StencilFace face) {
nSetStencilReferenceValue(getNativeObject(), value, sStencilFaceMapping[face.ordinal()]);
}
/**
* Sets the stencil reference value for both front and back-facing polygons.
* @see #setStencilReferenceValue(int, StencilFace)
*/
public void setStencilReferenceValue(@IntRange(from = 0, to = 255) int value) {
setStencilReferenceValue(value, StencilFace.FRONT_AND_BACK);
}
/**
* Sets the stencil read mask (default is 0xFF).
*
* <p>
* The stencil read mask masks the bits of the values participating in the stencil comparison
* test- both the value read from the stencil buffer and the reference value.
* </p>
*
* <p>
* It's possible to set separate stencil read masks; one for front-facing polygons, and one for
* back-facing polygons. The face parameter determines the stencil read mask(s) updated by this
* call.
* </p>
*
* @param readMask the read mask (only the least significant 8 bits are used)
* @param face the faces to update the read mask for
*/
public void setStencilReadMask(@IntRange(from = 0, to = 255) int readMask, StencilFace face) {
nSetStencilReadMask(getNativeObject(), readMask, sStencilFaceMapping[face.ordinal()]);
}
/**
* Sets the stencil read mask for both front and back-facing polygons.
* @see #setStencilReadMask(int, StencilFace)
*/
public void setStencilReadMask(@IntRange(from = 0, to = 255) int readMask) {
setStencilReadMask(readMask, StencilFace.FRONT_AND_BACK);
}
/**
* Sets the stencil write mask (default is 0xFF).
*
* <p>
* The stencil write mask masks the bits in the stencil buffer updated by stencil operations.
* </p>
*
* <p>
* It's possible to set separate stencil write masks; one for front-facing polygons, and one for
* back-facing polygons. The face parameter determines the stencil write mask(s) updated by this
* call.
* </p>
*
* @param writeMask the write mask (only the least significant 8 bits are used)
* @param face the faces to update the read mask for
*/
public void setStencilWriteMask(@IntRange(from = 0, to = 255) int writeMask, StencilFace face) {
nSetStencilWriteMask(getNativeObject(), writeMask, sStencilFaceMapping[face.ordinal()]);
}
/**
* Sets the stencil write mask for both front and back-facing polygons.
* @see #setStencilWriteMask(int, StencilFace)
*/
public void setStencilWriteMask(int writeMask) {
setStencilWriteMask(writeMask, StencilFace.FRONT_AND_BACK);
}
public long getNativeObject() {
if (mNativeObject == 0) {
throw new IllegalStateException("Calling method on destroyed MaterialInstance");
@@ -556,10 +906,37 @@ public class MaterialInstance {
private static native void nSetCullingMode(long nativeMaterialInstance, long mode);
private static native void nSetColorWrite(long nativeMaterialInstance, boolean enable);
private static native void nSetDepthWrite(long nativeMaterialInstance, boolean enable);
private static native void nSetStencilWrite(long nativeMaterialInstance, boolean enable);
private static native void nSetDepthCulling(long nativeMaterialInstance, boolean enable);
private static native void nSetStencilCompareFunction(long nativeMaterialInstance,
long function, long face);
private static native void nSetStencilOpStencilFail(long nativeMaterialInstance, long op,
long face);
private static native void nSetStencilOpDepthFail(long nativeMaterialInstance, long op,
long face);
private static native void nSetStencilOpDepthStencilPass(long nativeMaterialInstance, long op,
long face);
private static native void nSetStencilReferenceValue(long nativeMaterialInstance, int value,
long face);
private static native void nSetStencilReadMask(long nativeMaterialInstance, int readMask,
long face);
private static native void nSetStencilWriteMask(long nativeMaterialInstance, int writeMask,
long face);
private static native String nGetName(long nativeMaterialInstance);
private static native long nGetMaterial(long nativeMaterialInstance);
private static native long nDuplicate(long otherNativeMaterialInstance, String name);
private static native float nGetMaskThreshold(long nativeMaterialInstance);
private static native float nGetSpecularAntiAliasingVariance(long nativeMaterialInstance);
private static native float nGetSpecularAntiAliasingThreshold(long nativeMaterialInstance);
private static native boolean nIsDoubleSided(long nativeMaterialInstance);
private static native int nGetCullingMode(long nativeMaterialInstance);
private static native boolean nIsColorWriteEnabled(long nativeMaterialInstance);
private static native boolean nIsDepthWriteEnabled(long nativeMaterialInstance);
private static native boolean nIsStencilWriteEnabled(long nativeMaterialInstance);
private static native boolean nIsDepthCullingEnabled(long nativeMaterialInstance);
}

View File

@@ -163,6 +163,15 @@ public class Scene {
return nGetLightCount(getNativeObject());
}
/**
* Returns true if the given entity is in the Scene.
*
* @return Whether the given entity is in the Scene.
*/
public boolean hasEntity(@Entity int entity) {
return nHasEntity(getNativeObject(), entity);
}
public long getNativeObject() {
if (mNativeObject == 0) {
throw new IllegalStateException("Calling method on destroyed Scene");
@@ -182,4 +191,5 @@ public class Scene {
private static native void nRemoveEntities(long nativeScene, int[] entities);
private static native int nGetRenderableCount(long nativeScene);
private static native int nGetLightCount(long nativeScene);
private static native boolean nHasEntity(long nativeScene, int entity);
}

View File

@@ -29,7 +29,6 @@ import java.nio.ReadOnlyBufferException;
* Stream supports three different configurations:
*
* <dl>
* <dt>TEXTURE_ID</dt> <dd>takes an OpenGL texture ID and incurs a copy</dd>
* <dt>ACQUIRED</dt> <dd>connects to an Android AHardwareBuffer</dd>
* <dt>NATIVE</dt> <dd>connects to an Android SurfaceTexture</dd>
* </dl>
@@ -66,12 +65,6 @@ import java.nio.ReadOnlyBufferException;
* </ul>
*
* <p>
* The <b>TEXTURE_ID</b> configuration achieves synchronization automatically. In this mode,
* Filament performs a copy on the main thread during beginFrame by blitting the external image into
* an internal round-robin queue of images. This copy has a run-time cost.
* </p>
*
* <p>
* For <b>ACQUIRED</b> streams, there is no need to perform the copy because Filament explictly
* acquires the stream, then releases it later via a callback function. This configuration is
* especially useful when the Vulkan backend is enabled.
@@ -118,8 +111,7 @@ public class Stream {
* By default, Stream objects are {@link StreamType#ACQUIRED ACQUIRED} and must have external images pushed to them via
* {@link #setAcquiredImage}.
*
* To create a {@link StreamType#NATIVE NATIVE} stream, call one of the <pre>stream</pre> methods
* on the builder.
* To create a {@link StreamType#NATIVE NATIVE} stream, call the <pre>stream</pre> method on the builder.
*/
public static class Builder {
@SuppressWarnings({"FieldCanBeLocal", "UnusedDeclaration"}) // Keep to finalize native resources
@@ -211,7 +203,7 @@ public class Stream {
}
/**
* Indicates whether this <code>Stream</code> is NATIVE, TEXTURE_ID, or ACQUIRED.
* Indicates whether this <code>Stream</code> is NATIVE or ACQUIRED.
*/
public StreamType getStreamType() {
return sStreamTypeValues[nGetStreamType(getNativeObject())];
@@ -230,7 +222,7 @@ public class Stream {
* also where the callback is invoked. This method can only be used for streams that were
* constructed without calling the {@link Builder.stream} method.
*
* See {@link Stream} for more information about NATIVE, TEXTURE_ID, and ACQUIRED configurations.
* See {@link Stream} for more information about NATIVE and ACQUIRED configurations.
*
* @param hwbuffer {@link android.hardware.HardwareBuffer HardwareBuffer} (requires API level 26)
* @param handler {@link java.util.concurrent.Executor Executor} or {@link android.os.Handler Handler}.

View File

@@ -884,7 +884,7 @@ public class Texture {
// TODO: add a setImage() version that takes an android Bitmap
/**
* <code>setImage</code> is used to modify the whole content of the texure from a CPU-buffer.
* <code>setImage</code> is used to modify the whole content of the texture from a CPU-buffer.
*
* <p>This <code>Texture</code> instance must use {@link Sampler#SAMPLER_2D SAMPLER_2D} or
* {@link Sampler#SAMPLER_EXTERNAL SAMPLER_EXTERNAL}. If the later is specified
@@ -912,7 +912,7 @@ public class Texture {
public void setImage(@NonNull Engine engine,
@IntRange(from = 0) int level,
@NonNull PixelBufferDescriptor buffer) {
setImage(engine, level, 0, 0, getWidth(level), getHeight(level), buffer);
setImage(engine, level, 0, 0, 0, getWidth(level), getHeight(level), 1, buffer);
}
@@ -947,33 +947,15 @@ public class Texture {
@IntRange(from = 0) int xoffset, @IntRange(from = 0) int yoffset,
@IntRange(from = 0) int width, @IntRange(from = 0) int height,
@NonNull PixelBufferDescriptor buffer) {
int result;
if (buffer.type == COMPRESSED) {
result = nSetImageCompressed(getNativeObject(), engine.getNativeObject(), level,
xoffset, yoffset, width, height,
buffer.storage, buffer.storage.remaining(),
buffer.left, buffer.top, buffer.type.ordinal(), buffer.alignment,
buffer.compressedSizeInBytes, buffer.compressedFormat.ordinal(),
buffer.handler, buffer.callback);
} else {
result = nSetImage(getNativeObject(), engine.getNativeObject(), level,
xoffset, yoffset, width, height,
buffer.storage, buffer.storage.remaining(),
buffer.left, buffer.top, buffer.type.ordinal(), buffer.alignment,
buffer.stride, buffer.format.ordinal(),
buffer.handler, buffer.callback);
}
if (result < 0) {
throw new BufferOverflowException();
}
setImage(engine, level, xoffset, yoffset, 0, width, height, 1, buffer);
}
/**
* <code>setImage</code> is used to modify a sub-region of the 3D texture or 2D texture array
* from a CPU-buffer.
* <code>setImage</code> is used to modify a sub-region of a 3D texture, 2D texture array or
* cubemap from a CPU-buffer. Cubemaps are treated like a 2D array of six layers.
*
* <p>This <code>Texture</code> instance must use {@link Sampler#SAMPLER_2D_ARRAY SAMPLER_2D_ARRAY} or
* {@link Sampler#SAMPLER_3D SAMPLER_3D}.</p>
* <p>This <code>Texture</code> instance must use {@link Sampler#SAMPLER_2D_ARRAY SAMPLER_2D_ARRAY},
* {@link Sampler#SAMPLER_3D SAMPLER_3D} or {@link Sampler#SAMPLER_CUBEMAP SAMPLER_CUBEMAP}.</p>
*
* @param engine {@link Engine} this texture is associated to. Must be the
* instance passed to {@link Builder#build Builder.build()}.
@@ -1046,7 +1028,9 @@ public class Texture {
*
* @see Builder#sampler
* @see PixelBufferDescriptor
* @deprecated use {@link #setImage(Engine, int, int, int, int, int, int, int, PixelBufferDescriptor)}
*/
@Deprecated
public void setImage(@NonNull Engine engine, @IntRange(from = 0) int level,
@NonNull PixelBufferDescriptor buffer,
@NonNull @Size(min = 6) int[] faceOffsetsInBytes) {
@@ -1258,18 +1242,6 @@ public class Texture {
private static native int nGetTarget(long nativeTexture);
private static native int nGetInternalFormat(long nativeTexture);
private static native int nSetImage(long nativeTexture, long nativeEngine,
int level, int xoffset, int yoffset, int width, int height,
Buffer storage, int remaining, int left, int top, int type, int alignment,
int stride, int format,
Object handler, Runnable callback);
private static native int nSetImageCompressed(long nativeTexture, long nativeEngine,
int level, int xoffset, int yoffset, int width, int height,
Buffer storage, int remaining, int left, int top, int type, int alignment,
int compressedSizeInBytes, int compressedFormat,
Object handler, Runnable callback);
private static native int nSetImage3D(long nativeTexture, long nativeEngine,
int level, int xoffset, int yoffset, int zoffset, int width, int height, int depth,
Buffer storage, int remaining, int left, int top, int type, int alignment,

View File

@@ -16,6 +16,7 @@
package com.google.android.filament;
import androidx.annotation.IntRange;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.annotation.Size;
@@ -199,6 +200,36 @@ import androidx.annotation.Size;
return nGetParent(mNativeObject, i);
}
/**
* Returns the number of children of an {@link EntityInstance}.
*
* @param i the {@link EntityInstance} of the transform component to query.
* @return The number of children of the queried component.
*/
public int getChildCount(@EntityInstance int i) {
return nGetChildCount(mNativeObject, i);
}
/**
* Gets a list of children for a transform component.
*
* @param i the {@link EntityInstance} of the transform component to get the children
* from.
* @param outEntities array to receive the result sized to the maximum number of children to
* retrieve. If <code>null</code> is given, a new suitable array sized to
* {@link #getChildCount(int)} is allocated.
* @return Array of retrieved children {@link Entity}.
*/
public @Entity @NonNull int[] getChildren(@EntityInstance int i, @Nullable int[] outEntities) {
if (outEntities == null) {
outEntities = new int[getChildCount(i)];
}
if (outEntities.length > 0) {
nGetChildren(mNativeObject, i, outEntities, outEntities.length);
}
return outEntities;
}
/**
* Sets a local transform of a transform component.
* <p>This operation can be slow if the hierarchy of transform is too deep, and this
@@ -360,6 +391,8 @@ import androidx.annotation.Size;
private static native void nDestroy(long nativeTransformManager, int entity);
private static native void nSetParent(long nativeTransformManager, int i, int newParent);
private static native int nGetParent(long nativeTransformManager, int i);
private static native int nGetChildCount(long nativeTransformManager, int i);
private static native void nGetChildren(long nativeEntityManager, int i, int[] outEntities, int count);
private static native void nSetTransform(long nativeTransformManager, int i, float[] localTransform);
private static native void nSetTransformFp64(long nativeTransformManager, int i, double[] localTransform);
private static native void nGetTransform(long nativeTransformManager, int i, float[] outLocalTransform);

View File

@@ -793,7 +793,7 @@ public class View {
public void setVsmShadowOptions(@NonNull VsmShadowOptions options) {
mVsmShadowOptions = options;
nSetVsmShadowOptions(getNativeObject(), options.anisotropy, options.mipmapping,
options.minVarianceScale, options.lightBleedReduction);
options.highPrecision, options.minVarianceScale, options.lightBleedReduction);
}
/**
@@ -1011,6 +1011,45 @@ public class View {
return mDepthOfFieldOptions;
}
/**
* Enables use of the stencil buffer.
*
* <p>
* The stencil buffer is an 8-bit, per-fragment unsigned integer stored alongside the depth
* buffer. The stencil buffer is cleared at the beginning of a frame and discarded after the
* color pass.
* </p>
*
* <p>
* Each fragment's stencil value is set during rasterization by specifying stencil operations on
* a {@link Material}. The stencil buffer can be used as a mask for later rendering by setting a
* {@link Material}'s stencil comparison function and reference value. Fragments that don't pass
* the stencil test are then discarded.
* </p>
*
* <p>
* Post-processing must be enabled in order to use the stencil buffer.
* </p>
*
* <p>
* A renderable's priority (see {@link RenderableManager#setPriority(int, int)}) is useful to
* control the order in which primitives are drawn.
* </p>
*
* @param enabled True to enable the stencil buffer, false disables it (default)
*/
public void setStencilBufferEnabled(boolean enabled) {
nSetStencilBufferEnabled(getNativeObject(), enabled);
}
/**
* @return true if the stencil buffer is enabled.
* @see View#setStencilBufferEnabled(boolean)
*/
public boolean isStencilBufferEnabled() {
return nIsStencilBufferEnabled(getNativeObject());
}
/**
* A class containing the result of a picking query
*/
@@ -1105,7 +1144,7 @@ public class View {
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);
private static native void nSetVsmShadowOptions(long nativeView, int anisotropy, boolean mipmapping, float minVarianceScale, float lightBleedReduction);
private static native void nSetVsmShadowOptions(long nativeView, int anisotropy, boolean mipmapping, boolean highPrecision, float minVarianceScale, float lightBleedReduction);
private static native void nSetSoftShadowOptions(long nativeView, float penumbraScale, float penumbraRatioScale);
private static native void nSetColorGrading(long nativeView, long nativeColorGrading);
private static native void nSetPostProcessingEnabled(long nativeView, boolean enabled);
@@ -1131,6 +1170,8 @@ public class View {
private static native void nSetGuardBandOptions(long nativeView, boolean enabled);
private static native boolean nIsScreenSpaceRefractionEnabled(long nativeView);
private static native void nPick(long nativeView, int x, int y, Object handler, InternalOnPickCallback internalCallback);
private static native void nSetStencilBufferEnabled(long nativeView, boolean enabled);
private static native boolean nIsStencilBufferEnabled(long nativeView);
/**
* List of available ambient occlusion techniques.
@@ -1776,6 +1817,13 @@ public class View {
* Whether to generate mipmaps for all VSM shadow maps.
*/
public boolean mipmapping = false;
/**
* Whether to use a 32-bits or 16-bits texture format for VSM shadow maps. 32-bits
* precision is rarely needed, but it does reduces light leaks as well as "fading"
* of the shadows in some situations. Setting highPrecision to true for a single
* shadow map will double the memory usage of all shadow maps.
*/
public boolean highPrecision = false;
/**
* VSM minimum variance scale, must be positive.
*/

View File

@@ -70,7 +70,8 @@ Java_com_google_android_filament_utils_AutomationEngine_nStartBatchMode(JNIEnv*
extern "C" JNIEXPORT void JNICALL
Java_com_google_android_filament_utils_AutomationEngine_nTick(JNIEnv* env, jclass klass,
jlong nativeAutomation, jlong view, jlongArray materials, jlong renderer, jfloat deltaTime) {
jlong nativeAutomation, jlong nativeEngine,
jlong view, jlongArray materials, jlong renderer, jfloat deltaTime) {
using MaterialPointer = MaterialInstance*;
jsize materialCount = 0;
jlong* longMaterials = nullptr;
@@ -90,7 +91,8 @@ Java_com_google_android_filament_utils_AutomationEngine_nTick(JNIEnv* env, jclas
.materials = ptrMaterials,
.materialCount = (size_t) materialCount,
};
automation->tick(content, deltaTime);
Engine* engine = (Engine*)nativeEngine;
automation->tick(engine, content, deltaTime);
if (longMaterials) {
env->ReleaseLongArrayElements(materials, longMaterials, 0);
delete[] ptrMaterials;
@@ -99,7 +101,8 @@ Java_com_google_android_filament_utils_AutomationEngine_nTick(JNIEnv* env, jclas
extern "C" JNIEXPORT void JNICALL
Java_com_google_android_filament_utils_AutomationEngine_nApplySettings(JNIEnv* env, jclass klass,
jlong nativeAutomation, jstring json, jlong view, jlongArray materials, jlong nativeIbl,
jlong nativeAutomation, jlong nativeEngine,
jstring json, jlong view, jlongArray materials, jlong nativeIbl,
jint sunlightEntity, jintArray assetLights, jlong nativeLm, jlong scene, jlong renderer) {
using MaterialPointer = MaterialInstance*;
@@ -140,8 +143,8 @@ Java_com_google_android_filament_utils_AutomationEngine_nApplySettings(JNIEnv* e
.assetLights = (Entity*) intLights,
.assetLightCount = (size_t) lightCount,
};
automation->applySettings(nativeJson, jsonLength, content);
Engine* engine = (Engine*)nativeEngine;
automation->applySettings(engine, nativeJson, jsonLength, content);
env->ReleaseStringUTFChars(json, nativeJson);
if (longMaterials) {
env->ReleaseLongArrayElements(materials, longMaterials, 0);
@@ -169,6 +172,7 @@ Java_com_google_android_filament_utils_AutomationEngine_nGetViewerOptions(JNIEnv
const jfieldID cameraFocalLength = env->GetFieldID(klass, "cameraFocalLength", "F");
const jfieldID cameraFocusDistance = env->GetFieldID(klass, "cameraFocusDistance", "F");
const jfieldID autoScaleEnabled = env->GetFieldID(klass, "autoScaleEnabled", "Z");
const jfieldID autoInstancingEnabled = env->GetFieldID(klass, "autoInstancingEnabled", "Z");
env->SetFloatField(result, cameraAperture, options.cameraAperture);
env->SetFloatField(result, cameraSpeed, options.cameraSpeed);
@@ -179,6 +183,7 @@ Java_com_google_android_filament_utils_AutomationEngine_nGetViewerOptions(JNIEnv
env->SetFloatField(result, cameraFocalLength, options.cameraFocalLength);
env->SetFloatField(result, cameraFocusDistance, options.cameraFocusDistance);
env->SetBooleanField(result, autoScaleEnabled, options.autoScaleEnabled);
env->SetBooleanField(result, autoInstancingEnabled, options.autoInstancingEnabled);
}
extern "C" JNIEXPORT jlong JNICALL

View File

@@ -103,6 +103,7 @@ public class AutomationEngine {
public float cameraFocalLength = 28.0f;
public float cameraFocusDistance = 0.0f;
public boolean autoScaleEnabled = true;
public boolean autoInstancingEnabled = false;
}
/**
@@ -155,10 +156,11 @@ public class AutomationEngine {
* This is when settings get applied, screenshots are (optionally) exported, and the internal
* test counter is potentially incremented.
*
* @param engine The filament Engine of interest.
* @param content Contains the Filament View, Materials, and Renderer that get modified.
* @param deltaTime The amount of time that has passed since the previous tick in seconds.
*/
public void tick(@NonNull ViewerContent content, float deltaTime) {
public void tick(@NonNull Engine engine, @NonNull ViewerContent content, float deltaTime) {
if (content.view == null || content.renderer == null) {
throw new IllegalStateException("Must provide a View and Renderer");
}
@@ -171,7 +173,7 @@ public class AutomationEngine {
}
long nativeView = content.view.getNativeObject();
long nativeRenderer = content.renderer.getNativeObject();
nTick(mNativeObject, nativeView, nativeMaterialInstances, nativeRenderer, deltaTime);
nTick(mNativeObject, engine.getNativeObject(), nativeView, nativeMaterialInstances, nativeRenderer, deltaTime);
}
/**
@@ -183,10 +185,12 @@ public class AutomationEngine {
* This updates the stashed Settings object, then pushes those settings to the given
* Filament objects. Clients can optionally call getColorGrading() after calling this method.
*
* @param engine Filament Engine to use.
* @param settingsJson Contains the JSON string with a set of changes that need to be pushed.
* @param content Contains a set of Filament objects that you want to mutate.
*/
public void applySettings(@NonNull String settingsJson, @NonNull ViewerContent content) {
public void applySettings(@NonNull Engine engine, @NonNull String settingsJson,
@NonNull ViewerContent content) {
if (content.view == null || content.renderer == null) {
throw new IllegalStateException("Must provide a View and Renderer");
}
@@ -205,7 +209,8 @@ public class AutomationEngine {
long nativeLm = content.lightManager.getNativeObject();
long nativeScene = content.scene.getNativeObject();
long nativeRenderer = content.renderer.getNativeObject();
nApplySettings(mNativeObject, settingsJson, nativeView, nativeMaterialInstances,
nApplySettings(mNativeObject, engine.getNativeObject(),
settingsJson, nativeView, nativeMaterialInstances,
nativeIbl, content.sunlight, content.assetLights, nativeLm, nativeScene,
nativeRenderer);
}
@@ -266,9 +271,10 @@ public class AutomationEngine {
int minFrameCount, boolean verbose);
private static native void nStartRunning(long nativeObject);
private static native void nStartBatchMode(long nativeObject);
private static native void nTick(long nativeObject, long view, long[] materials, long renderer,
float deltaTime);
private static native void nApplySettings(long nativeObject, String jsonSettings, long view,
private static native void nTick(long nativeObject, long nativeEngine,
long view, long[] materials, long renderer, float deltaTime);
private static native void nApplySettings(long nativeObject, long nativeEngine,
String jsonSettings, long view,
long[] materials, long ibl, int sunlight, int[] assetLights, long lightManager,
long scene, long renderer);
private static native void nGetViewerOptions(long nativeObject, Object result);

View File

@@ -73,8 +73,6 @@ class ModelViewer(
get() = resourceLoader.asyncGetLoadProgress()
var normalizeSkinningWeights = true
var recomputeBoundingBoxes = false
var ignoreBindTransform = false
var cameraFocalLength = 28f
set(value) {
@@ -116,7 +114,7 @@ class ModelViewer(
materialProvider = UbershaderProvider(engine)
assetLoader = AssetLoader(engine, materialProvider, EntityManager.get())
resourceLoader = ResourceLoader(engine, normalizeSkinningWeights, recomputeBoundingBoxes, ignoreBindTransform)
resourceLoader = ResourceLoader(engine, normalizeSkinningWeights)
// Always add a direct light source since it is required for shadowing.
// We highly recommend adding an indirect light as well.
@@ -178,10 +176,10 @@ class ModelViewer(
*/
fun loadModelGlb(buffer: Buffer) {
destroyModel()
asset = assetLoader.createAssetFromBinary(buffer)
asset = assetLoader.createAsset(buffer)
asset?.let { asset ->
resourceLoader.asyncBeginLoad(asset)
animator = asset.animator
animator = asset.getInstance().animator
asset.releaseSourceData()
}
}
@@ -193,7 +191,7 @@ class ModelViewer(
*/
fun loadModelGltf(buffer: Buffer, callback: (String) -> Buffer?) {
destroyModel()
asset = assetLoader.createAssetFromJson(buffer)
asset = assetLoader.createAsset(buffer)
asset?.let { asset ->
for (uri in asset.resourceUris) {
val resourceBuffer = callback(uri)
@@ -204,7 +202,7 @@ class ModelViewer(
resourceLoader.addResourceData(uri, resourceBuffer)
}
resourceLoader.asyncBeginLoad(asset)
animator = asset.animator
animator = asset.getInstance().animator
asset.releaseSourceData()
}
}
@@ -216,7 +214,7 @@ class ModelViewer(
*/
fun loadModelGltfAsync(buffer: Buffer, callback: (String) -> Buffer) {
destroyModel()
asset = assetLoader.createAssetFromJson(buffer)
asset = assetLoader.createAsset(buffer)
fetchResourcesJob = CoroutineScope(Dispatchers.IO).launch {
fetchResources(asset!!, callback)
}
@@ -312,8 +310,8 @@ class ModelViewer(
private fun addDetachListener(view: android.view.View) {
view.addOnAttachStateChangeListener(object : android.view.View.OnAttachStateChangeListener {
override fun onViewAttachedToWindow(v: android.view.View?) {}
override fun onViewDetachedFromWindow(v: android.view.View?) {
override fun onViewAttachedToWindow(v: android.view.View) {}
override fun onViewDetachedFromWindow(v: android.view.View) {
uiHelper.detach()
destroyModel()
@@ -361,7 +359,7 @@ class ModelViewer(
resourceLoader.addResourceData(uri, buffer)
}
resourceLoader.asyncBeginLoad(asset)
animator = asset.animator
animator = asset.getInstance().animator
asset.releaseSourceData()
}
}

View File

@@ -11,6 +11,10 @@ add_library(dracodec STATIC IMPORTED)
set_target_properties(dracodec PROPERTIES IMPORTED_LOCATION
${FILAMENT_DIR}/lib/${ANDROID_ABI}/libdracodec.a)
add_library(meshoptimizer STATIC IMPORTED)
set_target_properties(meshoptimizer PROPERTIES IMPORTED_LOCATION
${FILAMENT_DIR}/lib/${ANDROID_ABI}/libmeshoptimizer.a)
add_library(ktxreader STATIC IMPORTED)
set_target_properties(ktxreader PROPERTIES IMPORTED_LOCATION
${FILAMENT_DIR}/lib/${ANDROID_ABI}/libktxreader.a)
@@ -76,7 +80,7 @@ set(GLTFIO_SRCS
${GLTFIO_DIR}/src/UbershaderProvider.cpp
${GLTFIO_DIR}/src/Wireframe.cpp
${GLTFIO_DIR}/src/Wireframe.h
${GLTFIO_DIR}/src/upcast.h
${GLTFIO_DIR}/src/downcast.h
src/main/cpp/Animator.cpp
src/main/cpp/AssetLoader.cpp
@@ -99,6 +103,7 @@ set(GLTFIO_INCLUDE_DIRS
../../libs/gltfio/include
../../third_party/basisu/zstd
../../third_party/cgltf
../../third_party/meshoptimizer/src
../../third_party/robin-map
../../third_party/hat-trie
../../third_party/stb
@@ -111,7 +116,7 @@ target_include_directories(gltfio-jni PRIVATE ${GLTFIO_INCLUDE_DIRS})
set_target_properties(gltfio-jni PROPERTIES LINK_DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/libgltfio-jni.symbols)
set_target_properties(gltfio-jni PROPERTIES LINK_DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/libgltfio-jni.map)
target_link_libraries(gltfio-jni filament-jni utils uberzlib log stb ktxreader basis_transcoder zstd uberarchive)
target_link_libraries(gltfio-jni dracodec)
target_link_libraries(gltfio-jni dracodec meshoptimizer)
target_compile_definitions(gltfio-jni PUBLIC GLTFIO_DRACO_SUPPORTED=1)
target_include_directories(gltfio-jni PRIVATE ${DRACO_DIR}/src)
target_include_directories(gltfio-jni PRIVATE ${DRACO_DIR}/tnt)

View File

@@ -14,5 +14,4 @@
limitations under the License.
-->
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.google.android.filament.gltfio" />
<manifest xmlns:android="http://schemas.android.com/apk/res/android" />

View File

@@ -42,6 +42,7 @@ class JavaMaterialProvider : public MaterialProvider {
jmethodID mMaterialKeyConstructor;
jmethodID mCreateMaterialInstance;
jmethodID mGetMaterial;
jmethodID mGetMaterials;
jmethodID mNeedsDummyData;
jmethodID mDestroyMaterials;
@@ -72,6 +73,10 @@ public:
"(L" JAVA_MATERIAL_KEY ";[ILjava/lang/String;Ljava/lang/String;)Lcom/google/android/filament/MaterialInstance;");
assert_invariant(mCreateMaterialInstance);
mGetMaterial = env->GetMethodID(providerClass, "getMaterial",
"(L" JAVA_MATERIAL_KEY ";[ILjava/lang/String;)Lcom/google/android/filament/Material;");
assert_invariant(mGetMaterial);
mGetMaterials = env->GetMethodID(providerClass, "getMaterials",
"()[Lcom/google/android/filament/Material;");
assert_invariant(mGetMaterials);
@@ -103,7 +108,7 @@ public:
jstring stringExtras = extras ? mEnv->NewStringUTF(extras) : nullptr;
// Allocate space for the output argument.
jintArray uvMapArray = mEnv->NewIntArray(8);
jintArray uvMapArray = mEnv->NewIntArray(uvmap->size());
// Call the Java-based material provider.
jobject materialInstance = mEnv->CallObjectMethod(mJavaProvider, mCreateMaterialInstance,
@@ -139,6 +144,49 @@ public:
return (MaterialInstance*) mEnv->CallLongMethod(materialInstance, mMaterialInstanceGetNativeObject);
}
Material* getMaterial(MaterialKey* config, UvMap* uvmap, const char* label) override {
// Create a Java object for the material key and copy the native fields into it.
jobject javaKey = mEnv->NewObject(mMaterialKeyClass, mMaterialKeyConstructor);
auto& helper = MaterialKeyHelper::get();
helper.copy(mEnv, javaKey, *config);
// Convert the optional label into a Java string.
jstring stringLabel = label ? mEnv->NewStringUTF(label) : nullptr;
// Allocate space for the output argument.
jintArray uvMapArray = mEnv->NewIntArray(uvmap->size());
// Call the Java-based material provider.
jobject material = mEnv->CallObjectMethod(mJavaProvider, mGetMaterial,
javaKey, uvMapArray, stringLabel);
// Copy the UvMap results from the JVM array into the native array.
if (uvmap) {
jint* elements = mEnv->GetIntArrayElements(uvMapArray, nullptr);
for (size_t i = 0; i < uvmap->size(); i++) {
(*uvmap)[i] = (UvSet) elements[i];
}
mEnv->ReleaseIntArrayElements(uvMapArray, elements, JNI_ABORT);
}
// The config parameter is an in-out parameter so we need to copy the results from Java.
helper.copy(mEnv, *config, javaKey);
mEnv->DeleteLocalRef(javaKey);
mEnv->DeleteLocalRef(uvMapArray);
if (stringLabel) {
mEnv->DeleteLocalRef(stringLabel);
}
if (material == nullptr) {
return nullptr;
}
return (Material*) mEnv->CallLongMethod(material, mMaterialGetNativeObject);
}
const Material* const* getMaterials() const noexcept override {
jobjectArray javaMaterials = (jobjectArray) mEnv->CallObjectMethod(mJavaProvider, mGetMaterials);
@@ -207,20 +255,11 @@ Java_com_google_android_filament_gltfio_AssetLoader_nDestroyAssetLoader(JNIEnv*,
}
extern "C" JNIEXPORT jlong JNICALL
Java_com_google_android_filament_gltfio_AssetLoader_nCreateAssetFromBinary(JNIEnv* env, jclass,
Java_com_google_android_filament_gltfio_AssetLoader_nCreateAsset(JNIEnv* env, jclass,
jlong nativeLoader, jobject javaBuffer, jint remaining) {
AssetLoader* loader = (AssetLoader*) nativeLoader;
AutoBuffer buffer(env, javaBuffer, remaining);
return (jlong) loader->createAssetFromBinary((const uint8_t *) buffer.getData(),
buffer.getSize());
}
extern "C" JNIEXPORT jlong JNICALL
Java_com_google_android_filament_gltfio_AssetLoader_nCreateAssetFromJson(JNIEnv* env, jclass,
jlong nativeLoader, jobject javaBuffer, jint remaining) {
AssetLoader* loader = (AssetLoader*) nativeLoader;
AutoBuffer buffer(env, javaBuffer, remaining);
return (jlong) loader->createAssetFromJson((const uint8_t *) buffer.getData(),
return (jlong) loader->createAsset((const uint8_t *) buffer.getData(),
buffer.getSize());
}

View File

@@ -172,27 +172,6 @@ Java_com_google_android_filament_gltfio_FilamentAsset_nGetCameraEntityCount(JNIE
return asset->getCameraEntityCount();
}
extern "C" JNIEXPORT jint JNICALL
Java_com_google_android_filament_gltfio_FilamentAsset_nGetMaterialInstanceCount(JNIEnv*, jclass,
jlong nativeAsset) {
FilamentAsset* asset = (FilamentAsset*) nativeAsset;
return asset->getMaterialInstanceCount();
}
extern "C" JNIEXPORT void JNICALL
Java_com_google_android_filament_gltfio_FilamentAsset_nGetMaterialInstances(JNIEnv* env, jclass,
jlong nativeAsset, jlongArray result) {
FilamentAsset* asset = (FilamentAsset*) nativeAsset;
jsize available = env->GetArrayLength(result);
jsize count = std::min(available, (jsize) asset->getMaterialInstanceCount());
jlong* dst = env->GetLongArrayElements(result, nullptr);
const MaterialInstance * const* src = asset->getMaterialInstances();
for (jsize i = 0; i < count; i++) {
dst[i] = (jlong) src[i];
}
env->ReleaseLongArrayElements(result, dst, 0);
}
extern "C" JNIEXPORT void JNICALL
Java_com_google_android_filament_gltfio_FilamentAsset_nGetBoundingBox(JNIEnv* env, jclass,
jlong nativeAsset, jfloatArray result) {
@@ -228,49 +207,11 @@ Java_com_google_android_filament_gltfio_FilamentAsset_nGetExtras(JNIEnv* env, jc
return val ? env->NewStringUTF(val) : nullptr;
}
extern "C" JNIEXPORT jint JNICALL
Java_com_google_android_filament_gltfio_FilamentAsset_nGetSkinCount(JNIEnv* , jclass,
jlong nativeAsset) {
FilamentAsset* asset = (FilamentAsset*) nativeAsset;
return (jint) asset->getSkinCount();
}
extern "C" JNIEXPORT void JNICALL
Java_com_google_android_filament_gltfio_FilamentAsset_nGetSkinNames(JNIEnv* env, jclass,
jlong nativeAsset, jobjectArray result) {
FilamentAsset* asset = (FilamentAsset*) nativeAsset;
jsize available = env->GetArrayLength(result);
for (int i = 0; i < available; ++i) {
const char* name = asset->getSkinNameAt(i);
if (name) {
env->SetObjectArrayElement(result, (jsize) i, env->NewStringUTF(name));
}
}
}
extern "C" JNIEXPORT jint JNICALL
Java_com_google_android_filament_gltfio_FilamentAsset_nGetJointCountAt(JNIEnv* , jclass,
jlong nativeAsset, jint skinIndex) {
FilamentAsset* asset = (FilamentAsset*) nativeAsset;
return (jint) asset->getJointCountAt(skinIndex);
}
extern "C" JNIEXPORT void JNICALL
Java_com_google_android_filament_gltfio_FilamentAsset_nGetJointsAt(JNIEnv* env, jclass,
jlong nativeAsset, jint skinIndex, jintArray result) {
FilamentAsset* asset = (FilamentAsset*) nativeAsset;
jsize available = env->GetArrayLength(result);
Entity* entities = (Entity*) env->GetIntArrayElements(result, nullptr);
std::copy_n(asset->getJointsAt(skinIndex),
std::min(available, (jsize) asset->getJointCountAt(skinIndex)), entities);
env->ReleaseIntArrayElements(result, (jint*) entities, 0);
}
extern "C" JNIEXPORT jlong JNICALL
Java_com_google_android_filament_gltfio_FilamentAsset_nGetAnimator(JNIEnv* , jclass,
Java_com_google_android_filament_gltfio_FilamentAsset_nGetInstance(JNIEnv* , jclass,
jlong nativeAsset) {
FilamentAsset* asset = (FilamentAsset*) nativeAsset;
return (jlong) asset->getAnimator();
return (jlong) asset->getInstance();
}
extern "C" JNIEXPORT jint JNICALL
@@ -310,49 +251,9 @@ Java_com_google_android_filament_gltfio_FilamentAsset_nGetMorphTargetNames(JNIEn
}
}
extern "C" JNIEXPORT jint JNICALL
Java_com_google_android_filament_gltfio_FilamentAsset_nGetMaterialVariantCount(JNIEnv*, jclass,
jlong nativeAsset) {
FilamentAsset* asset = (FilamentAsset*) nativeAsset;
return (jint) asset->getMaterialVariantCount();
}
extern "C" JNIEXPORT void JNICALL
Java_com_google_android_filament_gltfio_FilamentAsset_nGetMaterialVariantNames(JNIEnv* env, jclass,
jlong nativeAsset, jobjectArray result) {
FilamentAsset* asset = (FilamentAsset*) nativeAsset;
for (int i = 0; i < asset->getMaterialVariantCount(); ++i) {
const char* name = asset->getMaterialVariantName(i);
env->SetObjectArrayElement(result, (jsize) i, env->NewStringUTF(name));
}
}
extern "C" JNIEXPORT void JNICALL
Java_com_google_android_filament_gltfio_FilamentAsset_nApplyMaterialVariant(JNIEnv* env, jclass,
jlong nativeAsset, jint variantIndex) {
FilamentAsset* asset = (FilamentAsset*) nativeAsset;
asset->applyMaterialVariant(variantIndex);
}
extern "C" JNIEXPORT void JNICALL
Java_com_google_android_filament_gltfio_FilamentAsset_nReleaseSourceData(JNIEnv* env, jclass,
jlong nativeAsset) {
FilamentAsset* asset = (FilamentAsset*) nativeAsset;
asset->releaseSourceData();
}
extern "C" JNIEXPORT void JNICALL
Java_com_google_android_filament_gltfio_FilamentAsset_nAttachSkin(JNIEnv* env, jclass,
jlong nativeAsset, jint skinIndex, jint targetEntity) {
FilamentAsset* asset = (FilamentAsset*) nativeAsset;
Entity target = Entity::import(targetEntity);
asset->attachSkin(skinIndex, target);
}
extern "C" JNIEXPORT void JNICALL
Java_com_google_android_filament_gltfio_FilamentAsset_nDetachSkin(JNIEnv* env, jclass,
jlong nativeAsset, jint skinIndex, jint targetEntity) {
FilamentAsset* asset = (FilamentAsset*) nativeAsset;
Entity target = Entity::import(targetEntity);
asset->detachSkin(skinIndex, target);
}

View File

@@ -20,6 +20,7 @@
#include <algorithm>
using namespace filament;
using namespace filament::gltfio;
using namespace utils;
@@ -61,3 +62,95 @@ Java_com_google_android_filament_gltfio_FilamentInstance_nApplyMaterialVariant(J
FilamentInstance* instance = (FilamentInstance*) nativeInstance;
instance->applyMaterialVariant(variantIndex);
}
extern "C" JNIEXPORT jint JNICALL
Java_com_google_android_filament_gltfio_FilamentInstance_nGetMaterialVariantCount(JNIEnv*, jclass,
jlong nativeInstance) {
FilamentInstance* instance = (FilamentInstance*) nativeInstance;
return (jint) instance->getMaterialVariantCount();
}
extern "C" JNIEXPORT void JNICALL
Java_com_google_android_filament_gltfio_FilamentInstance_nGetMaterialVariantNames(JNIEnv* env, jclass,
jlong nativeInstance, jobjectArray result) {
FilamentInstance* instance = (FilamentInstance*) nativeInstance;
for (int i = 0; i < instance->getMaterialVariantCount(); ++i) {
const char* name = instance->getMaterialVariantName(i);
env->SetObjectArrayElement(result, (jsize) i, env->NewStringUTF(name));
}
}
extern "C" JNIEXPORT jint JNICALL
Java_com_google_android_filament_gltfio_FilamentInstance_nGetMaterialInstanceCount(JNIEnv*, jclass,
jlong nativeInstance) {
FilamentInstance* instance = (FilamentInstance*) nativeInstance;
return instance->getMaterialInstanceCount();
}
extern "C" JNIEXPORT void JNICALL
Java_com_google_android_filament_gltfio_FilamentInstance_nGetMaterialInstances(JNIEnv* env, jclass,
jlong nativeInstance, jlongArray result) {
FilamentInstance* instance = (FilamentInstance*) nativeInstance;
jsize available = env->GetArrayLength(result);
jsize count = std::min(available, (jsize) instance->getMaterialInstanceCount());
jlong* dst = env->GetLongArrayElements(result, nullptr);
const MaterialInstance * const* src = instance->getMaterialInstances();
for (jsize i = 0; i < count; i++) {
dst[i] = (jlong) src[i];
}
env->ReleaseLongArrayElements(result, dst, 0);
}
extern "C" JNIEXPORT void JNICALL
Java_com_google_android_filament_gltfio_FilamentInstance_nAttachSkin(JNIEnv* env, jclass,
jlong nativeInstance, jint skinIndex, jint targetEntity) {
FilamentInstance* instance = (FilamentInstance*) nativeInstance;
Entity target = Entity::import(targetEntity);
instance->attachSkin(skinIndex, target);
}
extern "C" JNIEXPORT void JNICALL
Java_com_google_android_filament_gltfio_FilamentInstance_nDetachSkin(JNIEnv* env, jclass,
jlong nativeInstance, jint skinIndex, jint targetEntity) {
FilamentInstance* instance = (FilamentInstance*) nativeInstance;
Entity target = Entity::import(targetEntity);
instance->detachSkin(skinIndex, target);
}
extern "C" JNIEXPORT jint JNICALL
Java_com_google_android_filament_gltfio_FilamentInstance_nGetSkinCount(JNIEnv* , jclass,
jlong nativeInstance) {
FilamentInstance* instance = (FilamentInstance*) nativeInstance;
return (jint) instance->getSkinCount();
}
extern "C" JNIEXPORT void JNICALL
Java_com_google_android_filament_gltfio_FilamentInstance_nGetSkinNames(JNIEnv* env, jclass,
jlong nativeInstance, jobjectArray result) {
FilamentInstance* instance = (FilamentInstance*) nativeInstance;
jsize available = env->GetArrayLength(result);
for (int i = 0; i < available; ++i) {
const char* name = instance->getSkinNameAt(i);
if (name) {
env->SetObjectArrayElement(result, (jsize) i, env->NewStringUTF(name));
}
}
}
extern "C" JNIEXPORT jint JNICALL
Java_com_google_android_filament_gltfio_FilamentInstance_nGetJointCountAt(JNIEnv* , jclass,
jlong nativeInstance, jint skinIndex) {
FilamentInstance* instance = (FilamentInstance*) nativeInstance;
return (jint) instance->getJointCountAt(skinIndex);
}
extern "C" JNIEXPORT void JNICALL
Java_com_google_android_filament_gltfio_FilamentInstance_nGetJointsAt(JNIEnv* env, jclass,
jlong nativeInstance, jint skinIndex, jintArray result) {
FilamentInstance* instance = (FilamentInstance*) nativeInstance;
jsize available = env->GetArrayLength(result);
Entity* entities = (Entity*) env->GetIntArrayElements(result, nullptr);
std::copy_n(instance->getJointsAt(skinIndex),
std::min(available, (jsize) instance->getJointCountAt(skinIndex)), entities);
env->ReleaseIntArrayElements(result, (jint*) entities, 0);
}

View File

@@ -36,11 +36,9 @@ static void destroy(void*, size_t, void *userData) {
extern "C" JNIEXPORT jlong JNICALL
Java_com_google_android_filament_gltfio_ResourceLoader_nCreateResourceLoader(JNIEnv*, jclass,
jlong nativeEngine, jboolean normalizeSkinningWeights, jboolean recomputeBoundingBoxes,
jboolean ignoreBindTransform) {
jlong nativeEngine, jboolean normalizeSkinningWeights) {
Engine* engine = (Engine*) nativeEngine;
return (jlong) new ResourceLoader({ engine, {}, (bool) normalizeSkinningWeights,
(bool) recomputeBoundingBoxes, (bool) ignoreBindTransform});
return (jlong) new ResourceLoader({ engine, {}, (bool) normalizeSkinningWeights});
}
extern "C" JNIEXPORT void JNICALL

View File

@@ -49,16 +49,19 @@ Java_com_google_android_filament_gltfio_UbershaderProvider_nDestroyMaterials(JNI
extern "C" JNIEXPORT long JNICALL
Java_com_google_android_filament_gltfio_UbershaderProvider_nCreateMaterialInstance(JNIEnv* env, jclass,
jlong nativeProvider, jobject materialKey, jintArray uvmap, jstring label) {
jlong nativeProvider, jobject materialKey, jintArray uvmap, jstring label, jstring extras) {
MaterialKey nativeKey = {};
auto& helper = MaterialKeyHelper::get();
helper.copy(env, nativeKey, materialKey);
const char* nativeLabel = label ? env->GetStringUTFChars(label, nullptr) : nullptr;
const char* nativeExtras = extras ? env->GetStringUTFChars(extras, nullptr) : nullptr;
UvMap nativeUvMap = {};
auto provider = (MaterialProvider*) nativeProvider;
MaterialInstance* instance = provider->createMaterialInstance(&nativeKey, &nativeUvMap, nativeLabel);
MaterialInstance* instance = provider->createMaterialInstance(&nativeKey, &nativeUvMap,
nativeLabel, nativeExtras);
// Copy the UvMap results from the native array into the JVM array.
jint* elements = env->GetIntArrayElements(uvmap, nullptr);
@@ -77,9 +80,47 @@ Java_com_google_android_filament_gltfio_UbershaderProvider_nCreateMaterialInstan
env->ReleaseStringUTFChars(label, nativeLabel);
}
if (extras) {
env->ReleaseStringUTFChars(extras, nativeExtras);
}
return (long) instance;
}
extern "C" JNIEXPORT long JNICALL
Java_com_google_android_filament_gltfio_UbershaderProvider_nGetMaterial(JNIEnv* env, jclass,
jlong nativeProvider, jobject materialKey, jintArray uvmap, jstring label) {
MaterialKey nativeKey = {};
auto& helper = MaterialKeyHelper::get();
helper.copy(env, nativeKey, materialKey);
const char* nativeLabel = label ? env->GetStringUTFChars(label, nullptr) : nullptr;
UvMap nativeUvMap = {};
auto provider = (MaterialProvider*) nativeProvider;
Material* material = provider->getMaterial(&nativeKey, &nativeUvMap, nativeLabel);
// Copy the UvMap results from the native array into the JVM array.
jint* elements = env->GetIntArrayElements(uvmap, nullptr);
if (elements) {
const size_t javaSize = env->GetArrayLength(uvmap);
for (int i = 0, n = std::min(javaSize, nativeUvMap.size()); i < n; ++i) {
elements[i] = nativeUvMap[i];
}
env->ReleaseIntArrayElements(uvmap, elements, 0);
}
// The config parameter is an in-out parameter so we need to copy the results back to Java.
helper.copy(env, materialKey, nativeKey);
if (label) {
env->ReleaseStringUTFChars(label, nativeLabel);
}
return (long) material;
}
extern "C" JNIEXPORT int JNICALL
Java_com_google_android_filament_gltfio_UbershaderProvider_nGetMaterialCount(JNIEnv*, jclass,
jlong nativeProvider) {

View File

@@ -26,8 +26,8 @@ import java.nio.Buffer;
/**
* Consumes a blob of glTF 2.0 content (either JSON or GLB) and produces a {@link FilamentAsset}
* object, which is a bundle of Filament entities, material instances, textures, vertex buffers,
* and index buffers.
* object, which is a bundle of Filament textures, vertex buffers, index buffers, etc. An asset is
* composed of 1 or more FilamentInstance objects which contain entities and components.
*
* <p>AssetLoader does not fetch external buffer data or create textures on its own. Clients can use
* the provided {@link ResourceLoader} class for this, which obtains the URI list from the asset.
@@ -51,7 +51,7 @@ import java.nio.Buffer;
* filamentAsset = assets.open("models/lucy.gltf").use { input -&gt;
* val bytes = ByteArray(input.available())
* input.read(bytes)
* assetLoader.createAssetFromJson(ByteBuffer.wrap(bytes))!!
* assetLoader.createAsset(ByteBuffer.wrap(bytes))!!
* }
*
* val resourceLoader = ResourceLoader(engine)
@@ -115,20 +115,11 @@ public class AssetLoader {
}
/**
* Creates a {@link FilamentAsset} from the contents of a GLB file.
* Creates a {@link FilamentAsset} from the contents of a GLB or GLTF file.
*/
@Nullable
public FilamentAsset createAssetFromBinary(@NonNull Buffer buffer) {
long nativeAsset = nCreateAssetFromBinary(mNativeObject, buffer, buffer.remaining());
return nativeAsset != 0 ? new FilamentAsset(mEngine, nativeAsset) : null;
}
/**
* Creates a {@link FilamentAsset} from the contents of a GLTF file.
*/
@Nullable
public FilamentAsset createAssetFromJson(@NonNull Buffer buffer) {
long nativeAsset = nCreateAssetFromJson(mNativeObject, buffer, buffer.remaining());
public FilamentAsset createAsset(@NonNull Buffer buffer) {
long nativeAsset = nCreateAsset(mNativeObject, buffer, buffer.remaining());
return nativeAsset != 0 ? new FilamentAsset(mEngine, nativeAsset) : null;
}
@@ -158,7 +149,7 @@ public class AssetLoader {
}
/**
* Adds a new instance to an instanced asset.
* Adds a new instance to the asset.
*
* Use this with caution. It is more efficient to pre-allocate a max number of instances, and
* gradually add them to the scene as needed. Instances can also be "recycled" by removing and
@@ -169,8 +160,6 @@ public class AssetLoader {
* create/destroy churn, as noted above.
*
* This cannot be called after FilamentAsset#releaseSourceData().
* This cannot be called on a non-instanced asset.
* Animation is not supported in new instances.
* See also AssetLoader#createInstancedAsset().
*/
@Nullable
@@ -202,8 +191,7 @@ public class AssetLoader {
private static native long nCreateAssetLoader(long nativeEngine, Object provider,
long nativeEntities);
private static native void nDestroyAssetLoader(long nativeLoader);
private static native long nCreateAssetFromBinary(long nativeLoader, Buffer buffer, int remaining);
private static native long nCreateAssetFromJson(long nativeLoader, Buffer buffer, int remaining);
private static native long nCreateAsset(long nativeLoader, Buffer buffer, int remaining);
private static native long nCreateInstancedAsset(long nativeLoader, Buffer buffer, int remaining,
long[] nativeInstances);
private static native long nCreateInstance(long nativeLoader, long nativeAsset);

View File

@@ -23,7 +23,6 @@ import androidx.annotation.Nullable;
import com.google.android.filament.Box;
import com.google.android.filament.Engine;
import com.google.android.filament.Entity;
import com.google.android.filament.MaterialInstance;
/**
* Owns a bundle of Filament objects that have been created by <code>AssetLoader</code>.
@@ -35,25 +34,32 @@ import com.google.android.filament.MaterialInstance;
* <code>NameComponentManager</code>, <code>RenderableManager</code>, and others.</p>
*
* <p>In addition to the aforementioned entities, an asset has strong ownership over a list of
* <code>VertexBuffer</code>, <code>IndexBuffer</code>, <code>MaterialInstance</code>, and
* <code>Texture</code>.</p>
* <code>VertexBuffer</code>, <code>IndexBuffer</code>, and <code>Texture</code>.</p>
*
* <p>Clients can use {@link ResourceLoader} to create textures, compute tangent quaternions, and
* upload data into vertex buffers and index buffers.</p>
*
* @see ResourceLoader
* @see Animator
* @see FilamentInstance
* @see AssetLoader
*/
public class FilamentAsset {
private long mNativeObject;
private Animator mAnimator;
private FilamentInstance mPrimaryInstance;
private Engine mEngine;
FilamentAsset(Engine engine, long nativeObject) {
mEngine = engine;
mNativeObject = nativeObject;
mAnimator = null;
}
public FilamentInstance getInstance() {
if (mPrimaryInstance != null) {
return mPrimaryInstance;
}
long nativeInstance = nGetInstance(getNativeObject());
mPrimaryInstance = new FilamentInstance(this, nativeInstance);
return mPrimaryInstance;
}
long getNativeObject() {
@@ -169,19 +175,11 @@ public class FilamentAsset {
return result;
}
public @NonNull MaterialInstance[] getMaterialInstances() {
final int count = nGetMaterialInstanceCount(mNativeObject);
MaterialInstance[] result = new MaterialInstance[count];
long[] natives = new long[count];
nGetMaterialInstances(mNativeObject, natives);
for (int i = 0; i < count; i++) {
result[i] = new MaterialInstance(mEngine, natives[i]);
}
return result;
}
/**
* Gets the bounding box computed from the supplied min / max values in glTF accessors.
*
* This does not return a bounding box over all FilamentInstance, it's just a straightforward
* AAAB that can be determined at load time from the asset data.
*/
public @NonNull Box getBoundingBox() {
float[] box = new float[6];
@@ -206,77 +204,6 @@ public class FilamentAsset {
return nGetExtras(mNativeObject, entity);
}
/**
* Retrieves the <code>Animator</code> interface for this asset.
*
* <p>When calling this for the first time, this must be called after
* {@link ResourceLoader#loadResources} or {@link ResourceLoader#asyncBeginLoad}. When the asset
* is destroyed, its animator becomes invalid.</p>
*/
public @NonNull Animator getAnimator() {
if (mAnimator != null) {
return mAnimator;
}
long nativeAnimator = nGetAnimator(getNativeObject());
if (nativeAnimator == 0) {
throw new IllegalStateException("Unable to create animator");
}
mAnimator = new Animator(nativeAnimator);
return mAnimator;
}
/**
* Gets the skin count of this asset.
*/
public int getSkinCount() {
return nGetSkinCount(getNativeObject());
}
/**
* Gets the skin name at skin index in this asset.
*/
public @NonNull String[] getSkinNames() {
String[] result = new String[getSkinCount()];
nGetSkinNames(getNativeObject(), result);
return result;
}
/**
* Attaches the given skin to the given node, which must have an associated mesh with
* BONE_INDICES and BONE_WEIGHTS attributes.
*
* This is a no-op if the given skin index or target is invalid.
*/
public void attachSkin(@IntRange(from = 0) int skinIndex, @Entity int target) {
nAttachSkin(getNativeObject(), skinIndex, target);
}
/**
* Attaches the given skin to the given node, which must have an associated mesh with
* BONE_INDICES and BONE_WEIGHTS attributes.
*
* This is a no-op if the given skin index or target is invalid.
*/
public void detachSkin(@IntRange(from = 0) int skinIndex, @Entity int target) {
nDetachSkin(getNativeObject(), skinIndex, target);
}
/**
* Gets the joint count at skin index in this asset.
*/
public int getJointCountAt(@IntRange(from = 0) int skinIndex) {
return nGetJointCountAt(getNativeObject(), skinIndex);
}
/**
* Gets joints at skin index in this asset.
*/
public @NonNull @Entity int[] getJointsAt(@IntRange(from = 0) int skinIndex) {
int[] result = new int[getJointCountAt(skinIndex)];
nGetJointsAt(getNativeObject(), skinIndex, result);
return result;
}
/**
* Gets the names of all morph targets in the given entity.
*/
@@ -295,31 +222,6 @@ public class FilamentAsset {
return uris;
}
/**
* Returns the names of all material variants.
*/
public @NonNull String[] getMaterialVariantNames() {
String[] names = new String[nGetMaterialVariantCount(mNativeObject)];
nGetMaterialVariantNames(mNativeObject, names);
return names;
}
/**
* Applies the given material variant to all primitives that it affects.
*
* This is efficient because it merely swaps around persistent MaterialInstances. If you change
* a material parameter while a certain variant is active, the updated value will be remembered
* after you re-apply that variant.
*
* If the asset is instanced, this affects all instances in the same way.
* To set the variant on an individual instance, use FilamentInstance#applyMaterialVariant.
*
* Ignored if variantIndex is out of bounds.
*/
public void applyMaterialVariant(@IntRange(from = 0) int variantIndex) {
nApplyMaterialVariant(getNativeObject(), variantIndex);
}
/**
* Reclaims CPU-side memory for URI strings, binding lists, and raw animation data.
*
@@ -331,8 +233,10 @@ public class FilamentAsset {
nReleaseSourceData(mNativeObject);
}
public Engine getEngine() { return mEngine; }
void clearNativeObject() {
if (mAnimator != null) mAnimator.clearNativeObject();
mPrimaryInstance = null;
mNativeObject = 0;
}
@@ -356,28 +260,17 @@ public class FilamentAsset {
private static native int nGetCameraEntityCount(long nativeAsset);
private static native void nGetCameraEntities(long nativeAsset, int[] result);
private static native int nGetMaterialInstanceCount(long nativeAsset);
private static native void nGetMaterialInstances(long nativeAsset, long[] nativeResults);
private static native int nGetMaterialVariantCount(long nativeAsset);
private static native void nGetMaterialVariantNames(long nativeAsset, String[] result);
private static native int nGetMorphTargetCount(long nativeAsset, int entity);
private static native void nGetMorphTargetNames(long nativeAsset, int entity, String[] result);
private static native void nAttachSkin(long nativeAsset, int skinIndex, int entity);
private static native void nDetachSkin(long nativeAsset, int skinIndex, int entity);
private static native void nGetBoundingBox(long nativeAsset, float[] box);
private static native String nGetName(long nativeAsset, int entity);
private static native String nGetExtras(long nativeAsset, int entity);
private static native long nGetAnimator(long nativeAsset);
private static native void nApplyMaterialVariant(long nativeAsset, int variantIndex);
private static native int nGetSkinCount(long nativeAsset);
private static native void nGetSkinNames(long nativeAsset, String[] result);
private static native int nGetJointCountAt(long nativeAsset, int skinIndex);
private static native void nGetJointsAt(long nativeAsset, int skinIndex, int[] result);
private static native long nGetInstance(long nativeAsset);
private static native int nGetResourceUriCount(long nativeAsset);
private static native void nGetResourceUris(long nativeAsset, String[] result);
private static native void nReleaseSourceData(long nativeAsset);
}

View File

@@ -19,7 +19,9 @@ package com.google.android.filament.gltfio;
import androidx.annotation.IntRange;
import androidx.annotation.NonNull;
import com.google.android.filament.Engine;
import com.google.android.filament.Entity;
import com.google.android.filament.MaterialInstance;
/**
* Provides access to a hierarchy of entities that have been instanced from a glTF asset.
@@ -85,6 +87,58 @@ public class FilamentInstance {
return mAnimator;
}
/**
* Gets the skin count of this instance.
*/
public int getSkinCount() {
return nGetSkinCount(getNativeObject());
}
/**
* Gets the skin name at skin index in this instance.
*/
public @NonNull String[] getSkinNames() {
String[] result = new String[getSkinCount()];
nGetSkinNames(getNativeObject(), result);
return result;
}
/**
* Attaches the given skin to the given node, which must have an associated mesh with
* BONE_INDICES and BONE_WEIGHTS attributes.
*
* This is a no-op if the given skin index or target is invalid.
*/
public void attachSkin(@IntRange(from = 0) int skinIndex, @Entity int target) {
nAttachSkin(getNativeObject(), skinIndex, target);
}
/**
* Attaches the given skin to the given node, which must have an associated mesh with
* BONE_INDICES and BONE_WEIGHTS attributes.
*
* This is a no-op if the given skin index or target is invalid.
*/
public void detachSkin(@IntRange(from = 0) int skinIndex, @Entity int target) {
nDetachSkin(getNativeObject(), skinIndex, target);
}
/**
* Gets the joint count at skin index in this instance.
*/
public int getJointCountAt(@IntRange(from = 0) int skinIndex) {
return nGetJointCountAt(getNativeObject(), skinIndex);
}
/**
* Gets joints at skin index in this instance.
*/
public @NonNull @Entity int[] getJointsAt(@IntRange(from = 0) int skinIndex) {
int[] result = new int[getJointCountAt(skinIndex)];
nGetJointsAt(getNativeObject(), skinIndex, result);
return result;
}
/**
* Applies the given material variant to all primitives in this instance.
*
@@ -94,9 +148,43 @@ public class FilamentInstance {
nApplyMaterialVariant(mNativeObject, variantIndex);
}
private static native int nGetRoot(long nativeAsset);
private static native int nGetEntityCount(long nativeAsset);
private static native void nGetEntities(long nativeAsset, int[] result);
private static native long nGetAnimator(long nativeAsset);
private static native void nApplyMaterialVariant(long nativeAsset, int variantIndex);
public @NonNull MaterialInstance[] getMaterialInstances() {
final int count = nGetMaterialInstanceCount(mNativeObject);
MaterialInstance[] result = new MaterialInstance[count];
long[] natives = new long[count];
nGetMaterialInstances(mNativeObject, natives);
Engine engine = mAsset.getEngine();
for (int i = 0; i < count; i++) {
result[i] = new MaterialInstance(engine, natives[i]);
}
return result;
}
/**
* Returns the names of all material variants.
*/
public @NonNull String[] getMaterialVariantNames() {
String[] names = new String[nGetMaterialVariantCount(mNativeObject)];
nGetMaterialVariantNames(mNativeObject, names);
return names;
}
private static native int nGetRoot(long nativeInstance);
private static native int nGetEntityCount(long nativeInstance);
private static native void nGetEntities(long nativeInstance, int[] result);
private static native long nGetAnimator(long nativeInstance);
private static native int nGetMaterialInstanceCount(long nativeAsset);
private static native void nGetMaterialInstances(long nativeAsset, long[] nativeResults);
private static native void nApplyMaterialVariant(long nativeInstance, int variantIndex);
private static native int nGetMaterialVariantCount(long nativeAsset);
private static native void nGetMaterialVariantNames(long nativeAsset, String[] result);
private static native void nGetJointsAt(long nativeInstance, int skinIndex, int[] result);
private static native int nGetSkinCount(long nativeInstance);
private static native void nGetSkinNames(long nativeInstance, String[] result);
private static native int nGetJointCountAt(long nativeInstance, int skinIndex);
private static native void nAttachSkin(long nativeInstance, int skinIndex, int entity);
private static native void nDetachSkin(long nativeInstance, int skinIndex, int entity);
}

View File

@@ -24,12 +24,16 @@ import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.annotation.Size;
import com.google.android.filament.proguard.UsedByNative;
@UsedByNative("AssetLoader.cpp")
public interface MaterialProvider {
/**
* MaterialKey specifies the requirements for a requested glTF material.
* The provider creates Filament materials that fulfill these requirements.
*/
@UsedByNative("MaterialKey.cpp")
public static class MaterialKey {
public boolean doubleSided;
public boolean unlit;
@@ -104,6 +108,12 @@ public interface MaterialProvider {
public @Nullable MaterialInstance createMaterialInstance(MaterialKey config,
@NonNull @Size(min = 8) int[] uvmap, @Nullable String label, @Nullable String extras);
/**
* Creates or fetches a compiled Filament material corresponding to the given config.
*/
public @Nullable Material getMaterial(MaterialKey config, @NonNull @Size(min = 8) int[] uvmap,
@Nullable String label);
/**
* Creates and returns an array containing all cached materials.
*/

View File

@@ -47,7 +47,7 @@ public class ResourceLoader {
*/
public ResourceLoader(@NonNull Engine engine) {
long nativeEngine = engine.getNativeObject();
mNativeObject = nCreateResourceLoader(nativeEngine, false, false, false);
mNativeObject = nCreateResourceLoader(nativeEngine, false);
mNativeStbProvider = nCreateStbProvider(nativeEngine);
mNativeKtx2Provider = nCreateKtx2Provider(nativeEngine);
nAddTextureProvider(mNativeObject, "image/jpeg", mNativeStbProvider);
@@ -60,16 +60,12 @@ public class ResourceLoader {
*
* @param engine the engine that gets passed to all builder methods
* @param normalizeSkinningWeights scale non-conformant skinning weights so they sum to 1
* @param recomputeBoundingBoxes use computed bounding boxes rather than the ones in the asset
* @param ignoreBindTransform ignore skinned primitives bind transform when compute bounding boxes
* @throws IllegalAccessException
* @throws InvocationTargetException
*/
public ResourceLoader(@NonNull Engine engine, boolean normalizeSkinningWeights,
boolean recomputeBoundingBoxes, boolean ignoreBindTransform) {
public ResourceLoader(@NonNull Engine engine, boolean normalizeSkinningWeights) {
long nativeEngine = engine.getNativeObject();
mNativeObject = nCreateResourceLoader(nativeEngine, normalizeSkinningWeights,
recomputeBoundingBoxes, ignoreBindTransform);
mNativeObject = nCreateResourceLoader(nativeEngine, normalizeSkinningWeights);
mNativeStbProvider = nCreateStbProvider(nativeEngine);
mNativeKtx2Provider = nCreateKtx2Provider(nativeEngine);
nAddTextureProvider(mNativeObject, "image/jpeg", mNativeStbProvider);
@@ -181,7 +177,7 @@ public class ResourceLoader {
}
private static native long nCreateResourceLoader(long nativeEngine,
boolean normalizeSkinningWeights, boolean recomputeBoundingBoxes, boolean ignoreBindTransform);
boolean normalizeSkinningWeights);
private static native void nDestroyResourceLoader(long nativeLoader);
private static native void nAddResourceData(long nativeLoader, String url, Buffer buffer,
int remaining);

View File

@@ -57,10 +57,16 @@ public class UbershaderProvider implements MaterialProvider {
public @Nullable MaterialInstance createMaterialInstance(MaterialKey config,
@NonNull @Size(min = 8) int[] uvmap, @Nullable String label, @Nullable String extras) {
long nativeMaterialInstance = nCreateMaterialInstance(mNativeObject, config, uvmap, label);
long nativeMaterialInstance = nCreateMaterialInstance(mNativeObject, config, uvmap, label, extras);
return nativeMaterialInstance == 0 ? null : new MaterialInstance(null, nativeMaterialInstance);
}
public @Nullable Material getMaterial(MaterialKey config, @NonNull @Size(min = 8) int[] uvmap,
@Nullable String label) {
long nativeMaterial = nGetMaterial(mNativeObject, config, uvmap, label);
return nativeMaterial == 0 ? null : new Material(nativeMaterial);
}
public @NonNull Material[] getMaterials() {
final int count = nGetMaterialCount(mNativeObject);
Material[] result = new Material[count];
@@ -96,6 +102,8 @@ public class UbershaderProvider implements MaterialProvider {
private static native void nDestroyUbershaderProvider(long nativeProvider);
private static native void nDestroyMaterials(long nativeProvider);
private static native long nCreateMaterialInstance(long nativeProvider,
MaterialKey config, int[] uvmap, String label, String extras);
private static native long nGetMaterial(long nativeProvider,
MaterialKey config, int[] uvmap, String label);
private static native int nGetMaterialCount(long nativeProvider);
private static native void nGetMaterials(long nativeProvider, long[] result);

View File

@@ -1,5 +1,5 @@
GROUP=com.google.android.filament
VERSION_NAME=1.23.2
VERSION_NAME=1.28.2
POM_DESCRIPTION=Real-time physically based rendering engine for Android.
@@ -19,10 +19,6 @@ org.gradle.jvmargs=-Xmx1536m
android.useAndroidX=true
org.gradle.unsafe.configuration-cache=true
# TODO: Remove this when we switch to Gradle 7.4
org.gradle.unsafe.configuration-cache.max-problems=3
com.google.android.filament.tools-dir=../../../out/release/filament
com.google.android.filament.dist-dir=../out/android-release/filament
com.google.android.filament.abis=all

View File

@@ -1,6 +1,6 @@
#Wed Nov 17 10:40:18 PST 2021
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-7.3.3-bin.zip
distributionUrl=https\://services.gradle.org/distributions/gradle-7.4-bin.zip
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists

View File

@@ -14,3 +14,17 @@
-keepclassmembers class * {
@com.google.android.filament.proguard.UsedBy* *;
}
# These classes is loaded via env->FindClass() from Utils.cpp
# They are in the utils namespace and therefore not covered by previous rules.
-keep class com.google.android.filament.utils.KTX1Loader
-keep class com.google.android.filament.utils.HDRLoader
# These native JNI methods are loaded via env->RegisterNatives() from Utils.cpp
-keepclassmembers class com.google.android.filament.utils.KTX1Loader {
native <methods>;
}
-keepclassmembers class com.google.android.filament.utils.HDRLoader {
native <methods>;
}

View File

@@ -112,9 +112,9 @@ the Android SDK.
## Android Studio
You must use Android Studio 3.6 RC 1 or higher. 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.
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.
## Compiling

View File

@@ -1,6 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.google.android.filament.gltf">
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
<uses-permission android:name="android.permission.INTERNET" />

View File

@@ -353,7 +353,7 @@ class MainActivity : Activity() {
fun loadSettings(message: RemoteServer.ReceivedMessage) {
val json = StandardCharsets.UTF_8.decode(message.buffer).toString()
viewerContent.assetLights = modelViewer.asset?.lightEntities
automation.applySettings(json, viewerContent)
automation.applySettings(modelViewer.engine, json, viewerContent)
modelViewer.view.colorGrading = automation.getColorGrading(modelViewer.engine)
modelViewer.cameraFocalLength = automation.viewerOptions.cameraFocalLength
updateRootTransform()
@@ -417,7 +417,7 @@ class MainActivity : Activity() {
// Just for testing purposes, this releases the current model and reloads the default model.
inner class DoubleTapListener : GestureDetector.SimpleOnGestureListener() {
override fun onDoubleTap(e: MotionEvent?): Boolean {
override fun onDoubleTap(e: MotionEvent): Boolean {
modelViewer.destroyModel()
createDefaultRenderables()
return super.onDoubleTap(e)

View File

@@ -16,8 +16,7 @@
limitations under the License.
-->
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.google.android.filament.hellocam">
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
<uses-permission android:name="android.permission.CAMERA" />

View File

@@ -1,6 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.google.android.filament.hellotriangle">
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
<application
android:allowBackup="true"

View File

@@ -1,6 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.google.android.filament.ibl">
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
<uses-permission android:name="android.permission.INTERNET" />

View File

@@ -1,6 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.google.android.filament.litcube">
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
<application
android:allowBackup="true"

View File

@@ -1,6 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.google.android.filament.livewallpaper">
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
<uses-feature android:name="android.software.live_wallpaper" />

View File

@@ -1,6 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.google.android.filament.material_builder">
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
<application
android:allowBackup="true"

View File

@@ -1,6 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.google.android.filament.multiview">
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
<application
android:allowBackup="true"

View File

@@ -1,6 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.google.android.filament.pagecurl">
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
<application
android:allowBackup="true"

View File

@@ -59,7 +59,7 @@ vertex {
vec3 p1 = deformPoint(theta, apex, uv.s + e, uv.t);
vec3 p2 = deformPoint(theta, apex, uv.s, uv.t + e);
vec3 normal = normalize(cross(p1 - p, p2 - p));
material.worldNormal = objectUniforms.worldFromModelNormalMatrix * normal;
material.worldNormal = getWorldFromModelNormalMatrix() * normal;
mat4 transform = getWorldFromModelMatrix();
material.worldPosition = mulMat4x4Float3(transform, p);
}

View File

@@ -16,8 +16,7 @@
limitations under the License.
-->
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.google.android.filament.streamtest">
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
<application
android:allowBackup="true"

View File

@@ -1,6 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.google.android.filament.textureview">
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
<application
android:allowBackup="true"

View File

@@ -1,6 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.google.android.filament.textured">
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
<application
android:allowBackup="true"

View File

@@ -1,6 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.google.android.filament.transparentrendering">
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
<application
android:allowBackup="true"

View File

@@ -44,6 +44,8 @@ function print_help {
echo " Add iOS simulator support to the iOS build."
echo " -t"
echo " Enable SwiftShader support for Vulkan in desktop builds."
echo " -e"
echo " Enable EGL on Linux support for desktop builds."
echo " -l"
echo " Build arm64/x86_64 universal libraries."
echo " For iOS, this builds universal binaries for devices and the simulator (implies -s)."
@@ -155,6 +157,8 @@ VULKAN_ANDROID_GRADLE_OPTION=""
SWIFTSHADER_OPTION="-DFILAMENT_USE_SWIFTSHADER=OFF"
EGL_ON_LINUX_OPTION="-DFILAMENT_SUPPORTS_EGL_ON_LINUX=OFF"
MATDBG_OPTION="-DFILAMENT_ENABLE_MATDBG=OFF"
MATDBG_GRADLE_OPTION=""
@@ -215,6 +219,7 @@ function build_desktop_target {
-DCMAKE_BUILD_TYPE="$1" \
-DCMAKE_INSTALL_PREFIX="../${lc_target}/filament" \
${SWIFTSHADER_OPTION} \
${EGL_ON_LINUX_OPTION} \
${MATDBG_OPTION} \
${deployment_target} \
${architectures} \
@@ -735,7 +740,7 @@ function run_tests {
pushd "$(dirname "$0")" > /dev/null
while getopts ":hacCfijmp:q:uvslwtdk:" opt; do
while getopts ":hacCfijmp:q:uvslwtedk:" opt; do
case ${opt} in
h)
print_help
@@ -842,6 +847,10 @@ while getopts ":hacCfijmp:q:uvslwtdk:" opt; do
SWIFTSHADER_OPTION="-DFILAMENT_USE_SWIFTSHADER=ON"
echo "SwiftShader support enabled."
;;
e)
EGL_ON_LINUX_OPTION="-DFILAMENT_SUPPORTS_EGL_ON_LINUX=ON -DFILAMENT_SKIP_SDL2=ON -DFILAMENT_SKIP_SAMPLES=ON"
echo "EGL on Linux support enabled; skipping SDL2."
;;
l)
IOS_BUILD_SIMULATOR=true
BUILD_UNIVERSAL_LIBRARIES=true

View File

@@ -1 +1 @@
24.0.8215888
25.1.8937393

View File

@@ -0,0 +1,99 @@
#!/usr/bin/env bash
set -e
function print_help {
local self_name=$(basename "$0")
echo "This tool verifies that every Metal shader in the given Filament material file(s) successfully compiles."
echo "Requires the matinfo tool and xcrun to be on the system PATH."
echo ""
echo "Usage:"
echo " $self_name [options] [<material> ...]"
echo ""
echo "Options:"
echo " -h"
echo " Print this help message."
echo " -w"
echo " Pass the -w flag to the Metal compiler, to disable warnings."
echo ""
}
COMP_FLAGS=""
while getopts ":hw" opt; do
case ${opt} in
h)
print_help
exit 1
;;
w)
COMP_FLAGS="${COMP_FLAGS} -w"
;;
esac
done
shift $((OPTIND - 1))
if [[ "$#" == "0" ]]; then
print_help
exit 1
fi
# Make sure matinfo and xcrun are available.
if [[ ! $(command -v matinfo) ]]; then
echo "Error: matinfo not on PATH."
exit 1
fi
if [[ ! $(command -v xcrun) ]]; then
echo "Error: xcrun not on PATH."
exit 1
fi
function check_material {
local material="$1"
tmpdir="$(mktemp -d /tmp/check_metal_shaders.XXXXX)"
# First check that the material is valid.
if [[ ! $(matinfo "${material}") ]]; then
echo "Invalid material file: ${material}"
exit 1
fi
echo "Checking that Metal shaders compile: ${material}"
set +e
local i=0
while true; do
# The file must have a .metal extension.
metalFile="${tmpdir}/${i}.metal"
# Extract shader i. matinfo will return a non-zero exit code if the shader doesn't exist,
# which means we're finished with this material.
matinfo --print-metal=${i} "${material}" > "${metalFile}" 2> /dev/null
if [[ "$?" -ne 0 ]]; then
break
fi
echo "Testing Metal shader ${i}"
# Attempt to compile the Metal shader.
xcrun -sdk macosx metal ${COMP_FLAGS} -c "${metalFile}" -o /dev/null
if [[ "$?" -ne 0 ]]; then
echo "Error compiling Metal shader: ${metalFile}"
exit 1
fi
((i++))
done
set -e
rm -r "${tmpdir}"
}
for material in "$@"
do
check_material "${material}"
done

View File

@@ -1,14 +1,14 @@
setuptools==40.6.2
setuptools==58.0.4
wheel==0.37.1
certifi==2021.10.8
cffi==1.15.0
charset-normalizer==2.0.12
certifi==2022.9.24
cffi==1.15.1
charset-normalizer==2.1.1
Deprecated==1.2.13
idna==3.3
idna==3.4
pycparser==2.21
PyGithub==1.55
PyJWT==2.4.0
PyGithub==1.56
PyJWT==2.6.0
PyNaCl==1.5.0
requests==2.27.1
urllib3==1.26.9
wrapt==1.14.0
requests==2.28.1
urllib3==1.26.12
wrapt==1.14.1

View File

@@ -17,7 +17,7 @@ export PATH="$PWD:$PATH"
# npm install -g typescript
# Install emscripten.
curl -L https://github.com/emscripten-core/emsdk/archive/refs/tags/3.1.9.zip > emsdk.zip
curl -L https://github.com/emscripten-core/emsdk/archive/refs/tags/3.1.15.zip > emsdk.zip
unzip emsdk.zip ; mv emsdk-* emsdk ; cd emsdk
./emsdk install latest
./emsdk activate latest

File diff suppressed because one or more lines are too long

View File

@@ -1143,7 +1143,7 @@ Where $F(v,h)$ is the Fresnel term of the cloth specular BRDF in equation $\ref{
Subsurface scattering is implemented using the wrapped diffuse lighting technique, in its energy conservative form:
$$\begin{equation}
f_{d}(v,h) = \frac{c_{diff}}{\pi}(1 - F(v,h)) \left< \NoL + \frac{w}{(1 + w)^2} \right> \left< c_{subsurface} + \NoL \right>
f_{d}(v,h) = \frac{c_{diff}}{\pi}(1 - F(v,h)) \left< \frac{\NoL + w}{(1 + w)^2} \right> \left< c_{subsurface} + \NoL \right>
\end{equation}$$
Where $w$ is a value between 0 and 1 defining by how much the diffuse light should wrap around the terminator. To avoid introducing another parameter, we fix $w = 0.5$. Note that with wrap diffuse lighting, the diffuse term must not be multiplied by $\NoL$. The effect of this cheap
@@ -1435,7 +1435,7 @@ The term $ \lambda(l) $ in equations $ \ref{spotAbsorber} $ and $ \ref{spotRefle
$ \ref{spotAngleAtt} $ below.
$$\begin{equation}\label{spotAngleAtt}
\lambda(l) = \frac{l \times spotDirection - cos\theta_{outer}}{cos\theta_{inner} - cos\theta_{outer}}
\lambda(l) = \frac{l \cdot spotDirection - cos\theta_{outer}}{cos\theta_{inner} - cos\theta_{outer}}
\end{equation}$$
#### Attenuation function
@@ -3682,7 +3682,7 @@ However we only need the real bases:
$$\begin{align*}
y^{m > 0}_l &= \sqrt{2} K^m_l cos(m \phi) P^m_l(cos \theta) \\
y^{m < 0}_l &= \sqrt{2} K^m_l sin(m \phi) P^{|m|}_l(cos \theta) \\
y^{m < 0}_l &= \sqrt{2} K^m_l sin(|m| \phi) P^{|m|}_l(cos \theta) \\
y^0_l &= K^0_l P^0_l(cos \theta)
\end{align*}$$
@@ -3716,19 +3716,18 @@ $l = 2$ | $y^{-2}_2$ $y^{-1}_2$ $y^0_2$ $y^1_2$ $y^2_2$
Its also fairly easy to compute the trigonometric terms recursively:
$$\begin{align*}
C_m &\equiv cos(m \phi) \\
S_m &\equiv sin(m \phi) \\
C_m &\equiv cos(m \phi)sin(\theta)^m \\
S_m &\equiv sin(m \phi)sin(\theta)^m \\
\{ x, y, z \} &= \{ cos \phi sin \theta, sin \phi sin \theta, cos \theta \}
\end{align*}$$
Using the angle sum trigonometric identities:
$$\begin{align*}
cos(m \phi + \phi) &= cos(m \phi) cos(\phi) - sin(m \phi) sin(\phi) \Leftrightarrow C_{m + 1} = \frac{(x C_m - y S_m)}{sin(\theta)^{|m + 1|}} \\
sin(m \phi + \phi) &= sin(m \phi) sin(\phi) + cos(m \phi) sin(\phi) \Leftrightarrow S_{m + 1} = \frac{(x S_m - y C_m)}{sin(\theta)^{|m + 1|}}
cos(m \phi + \phi) &= cos(m \phi) cos(\phi) - sin(m \phi) sin(\phi) \Leftrightarrow C_{m + 1} = x C_m - y S_m \\
sin(m \phi + \phi) &= sin(m \phi) cos(\phi) + cos(m \phi) sin(\phi) \Leftrightarrow S_{m + 1} = x S_m - y C_m
\end{align*}$$
The equations above have an extra term $sin(\theta)^{-|m + 1|}$ but we can compensate for that in the $P^{|m|}_l(z)$ recursion by multiplying $P^l_l(z)$ by $sin(\theta)^{|m + 1|}$ which greatly simplifies the third equation in $\ref{shRecursions}$ because $P^l_l(cos \theta) sin(\theta)^{-l} = (-1)^l(2l - 1)!!$.
Listing [nonNormalizedSHBasis] shows the C++ code to compute the non-normalized SH basis $\frac{y^m_l(s)}{\sqrt{2} K^m_l}$:

View File

@@ -86,36 +86,39 @@ counter-increment: h6;margin-right:10px}
&nbsp;&nbsp;&nbsp;&nbsp;<a href="#materialdefinitions/format/example" class="level3"><span class="tocNumber">4.1.2&nbsp; </span>Example</a><br>
&nbsp;&nbsp;<a href="#materialdefinitions/materialblock" class="level2"><span class="tocNumber">4.2&nbsp; </span>Material block</a><br>
&nbsp;&nbsp;&nbsp;&nbsp;<a href="#materialdefinitions/materialblock/general:name" class="level3"><span class="tocNumber">4.2.1&nbsp; </span>General: name</a><br>
&nbsp;&nbsp;&nbsp;&nbsp;<a href="#materialdefinitions/materialblock/general:shadingmodel" class="level3"><span class="tocNumber">4.2.2&nbsp; </span>General: shadingModel</a><br>
&nbsp;&nbsp;&nbsp;&nbsp;<a href="#materialdefinitions/materialblock/general:parameters" class="level3"><span class="tocNumber">4.2.3&nbsp; </span>General: parameters</a><br>
&nbsp;&nbsp;&nbsp;&nbsp;<a href="#materialdefinitions/materialblock/general:variantfilter" class="level3"><span class="tocNumber">4.2.4&nbsp; </span>General: variantFilter</a><br>
&nbsp;&nbsp;&nbsp;&nbsp;<a href="#materialdefinitions/materialblock/general:flipuv" class="level3"><span class="tocNumber">4.2.5&nbsp; </span>General: flipUV</a><br>
&nbsp;&nbsp;&nbsp;&nbsp;<a href="#materialdefinitions/materialblock/general:quality" class="level3"><span class="tocNumber">4.2.6&nbsp; </span>General: quality</a><br>
&nbsp;&nbsp;&nbsp;&nbsp;<a href="#materialdefinitions/materialblock/vertexandattributes:requires" class="level3"><span class="tocNumber">4.2.7&nbsp; </span>Vertex and attributes: requires</a><br>
&nbsp;&nbsp;&nbsp;&nbsp;<a href="#materialdefinitions/materialblock/vertexandattributes:variables" class="level3"><span class="tocNumber">4.2.8&nbsp; </span>Vertex and attributes: variables</a><br>
&nbsp;&nbsp;&nbsp;&nbsp;<a href="#materialdefinitions/materialblock/vertexandattributes:vertexdomain" class="level3"><span class="tocNumber">4.2.9&nbsp; </span>Vertex and attributes: vertexDomain</a><br>
&nbsp;&nbsp;&nbsp;&nbsp;<a href="#materialdefinitions/materialblock/vertexandattributes:interpolation" class="level3"><span class="tocNumber">4.2.10&nbsp; </span>Vertex and attributes: interpolation</a><br>
&nbsp;&nbsp;&nbsp;&nbsp;<a href="#materialdefinitions/materialblock/blendingandtransparency:blending" class="level3"><span class="tocNumber">4.2.11&nbsp; </span>Blending and transparency: blending</a><br>
&nbsp;&nbsp;&nbsp;&nbsp;<a href="#materialdefinitions/materialblock/blendingandtransparency:postlightingblending" class="level3"><span class="tocNumber">4.2.12&nbsp; </span>Blending and transparency: postLightingBlending</a><br>
&nbsp;&nbsp;&nbsp;&nbsp;<a href="#materialdefinitions/materialblock/blendingandtransparency:transparency" class="level3"><span class="tocNumber">4.2.13&nbsp; </span>Blending and transparency: transparency</a><br>
&nbsp;&nbsp;&nbsp;&nbsp;<a href="#materialdefinitions/materialblock/blendingandtransparency:maskthreshold" class="level3"><span class="tocNumber">4.2.14&nbsp; </span>Blending and transparency: maskThreshold</a><br>
&nbsp;&nbsp;&nbsp;&nbsp;<a href="#materialdefinitions/materialblock/blendingandtransparency:refractionmode" class="level3"><span class="tocNumber">4.2.15&nbsp; </span>Blending and transparency: refractionMode</a><br>
&nbsp;&nbsp;&nbsp;&nbsp;<a href="#materialdefinitions/materialblock/blendingandtransparency:refractiontype" class="level3"><span class="tocNumber">4.2.16&nbsp; </span>Blending and transparency: refractionType</a><br>
&nbsp;&nbsp;&nbsp;&nbsp;<a href="#materialdefinitions/materialblock/rasterization:culling" class="level3"><span class="tocNumber">4.2.17&nbsp; </span>Rasterization: culling</a><br>
&nbsp;&nbsp;&nbsp;&nbsp;<a href="#materialdefinitions/materialblock/rasterization:colorwrite" class="level3"><span class="tocNumber">4.2.18&nbsp; </span>Rasterization: colorWrite</a><br>
&nbsp;&nbsp;&nbsp;&nbsp;<a href="#materialdefinitions/materialblock/rasterization:depthwrite" class="level3"><span class="tocNumber">4.2.19&nbsp; </span>Rasterization: depthWrite</a><br>
&nbsp;&nbsp;&nbsp;&nbsp;<a href="#materialdefinitions/materialblock/rasterization:depthculling" class="level3"><span class="tocNumber">4.2.20&nbsp; </span>Rasterization: depthCulling</a><br>
&nbsp;&nbsp;&nbsp;&nbsp;<a href="#materialdefinitions/materialblock/rasterization:doublesided" class="level3"><span class="tocNumber">4.2.21&nbsp; </span>Rasterization: doubleSided</a><br>
&nbsp;&nbsp;&nbsp;&nbsp;<a href="#materialdefinitions/materialblock/lighting:reflections" class="level3"><span class="tocNumber">4.2.22&nbsp; </span>Lighting: reflections</a><br>
&nbsp;&nbsp;&nbsp;&nbsp;<a href="#materialdefinitions/materialblock/lighting:shadowmultiplier" class="level3"><span class="tocNumber">4.2.23&nbsp; </span>Lighting: shadowMultiplier</a><br>
&nbsp;&nbsp;&nbsp;&nbsp;<a href="#materialdefinitions/materialblock/lighting:transparentshadow" class="level3"><span class="tocNumber">4.2.24&nbsp; </span>Lighting: transparentShadow</a><br>
&nbsp;&nbsp;&nbsp;&nbsp;<a href="#materialdefinitions/materialblock/lighting:clearcoatiorchange" class="level3"><span class="tocNumber">4.2.25&nbsp; </span>Lighting: clearCoatIorChange</a><br>
&nbsp;&nbsp;&nbsp;&nbsp;<a href="#materialdefinitions/materialblock/lighting:multibounceambientocclusion" class="level3"><span class="tocNumber">4.2.26&nbsp; </span>Lighting: multiBounceAmbientOcclusion</a><br>
&nbsp;&nbsp;&nbsp;&nbsp;<a href="#materialdefinitions/materialblock/lighting:specularambientocclusion" class="level3"><span class="tocNumber">4.2.27&nbsp; </span>Lighting: specularAmbientOcclusion</a><br>
&nbsp;&nbsp;&nbsp;&nbsp;<a href="#materialdefinitions/materialblock/anti-aliasing:specularantialiasing" class="level3"><span class="tocNumber">4.2.28&nbsp; </span>Anti-aliasing: specularAntiAliasing</a><br>
&nbsp;&nbsp;&nbsp;&nbsp;<a href="#materialdefinitions/materialblock/anti-aliasing:specularantialiasingvariance" class="level3"><span class="tocNumber">4.2.29&nbsp; </span>Anti-aliasing: specularAntiAliasingVariance</a><br>
&nbsp;&nbsp;&nbsp;&nbsp;<a href="#materialdefinitions/materialblock/anti-aliasing:specularantialiasingthreshold" class="level3"><span class="tocNumber">4.2.30&nbsp; </span>Anti-aliasing: specularAntiAliasingThreshold</a><br>
&nbsp;&nbsp;&nbsp;&nbsp;<a href="#materialdefinitions/materialblock/shading:customsurfaceshading" class="level3"><span class="tocNumber">4.2.31&nbsp; </span>Shading: customSurfaceShading</a><br>
&nbsp;&nbsp;&nbsp;&nbsp;<a href="#materialdefinitions/materialblock/general:featurelevel" class="level3"><span class="tocNumber">4.2.2&nbsp; </span>General: featureLevel</a><br>
&nbsp;&nbsp;&nbsp;&nbsp;<a href="#materialdefinitions/materialblock/general:shadingmodel" class="level3"><span class="tocNumber">4.2.3&nbsp; </span>General: shadingModel</a><br>
&nbsp;&nbsp;&nbsp;&nbsp;<a href="#materialdefinitions/materialblock/general:parameters" class="level3"><span class="tocNumber">4.2.4&nbsp; </span>General: parameters</a><br>
&nbsp;&nbsp;&nbsp;&nbsp;<a href="#materialdefinitions/materialblock/general:variantfilter" class="level3"><span class="tocNumber">4.2.5&nbsp; </span>General: variantFilter</a><br>
&nbsp;&nbsp;&nbsp;&nbsp;<a href="#materialdefinitions/materialblock/general:flipuv" class="level3"><span class="tocNumber">4.2.6&nbsp; </span>General: flipUV</a><br>
&nbsp;&nbsp;&nbsp;&nbsp;<a href="#materialdefinitions/materialblock/general:quality" class="level3"><span class="tocNumber">4.2.7&nbsp; </span>General: quality</a><br>
&nbsp;&nbsp;&nbsp;&nbsp;<a href="#materialdefinitions/materialblock/general:instanced" class="level3"><span class="tocNumber">4.2.8&nbsp; </span>General: instanced</a><br>
&nbsp;&nbsp;&nbsp;&nbsp;<a href="#materialdefinitions/materialblock/general:vertexdomaindevicejittered" class="level3"><span class="tocNumber">4.2.9&nbsp; </span>General: vertexDomainDeviceJittered</a><br>
&nbsp;&nbsp;&nbsp;&nbsp;<a href="#materialdefinitions/materialblock/vertexandattributes:requires" class="level3"><span class="tocNumber">4.2.10&nbsp; </span>Vertex and attributes: requires</a><br>
&nbsp;&nbsp;&nbsp;&nbsp;<a href="#materialdefinitions/materialblock/vertexandattributes:variables" class="level3"><span class="tocNumber">4.2.11&nbsp; </span>Vertex and attributes: variables</a><br>
&nbsp;&nbsp;&nbsp;&nbsp;<a href="#materialdefinitions/materialblock/vertexandattributes:vertexdomain" class="level3"><span class="tocNumber">4.2.12&nbsp; </span>Vertex and attributes: vertexDomain</a><br>
&nbsp;&nbsp;&nbsp;&nbsp;<a href="#materialdefinitions/materialblock/vertexandattributes:interpolation" class="level3"><span class="tocNumber">4.2.13&nbsp; </span>Vertex and attributes: interpolation</a><br>
&nbsp;&nbsp;&nbsp;&nbsp;<a href="#materialdefinitions/materialblock/blendingandtransparency:blending" class="level3"><span class="tocNumber">4.2.14&nbsp; </span>Blending and transparency: blending</a><br>
&nbsp;&nbsp;&nbsp;&nbsp;<a href="#materialdefinitions/materialblock/blendingandtransparency:postlightingblending" class="level3"><span class="tocNumber">4.2.15&nbsp; </span>Blending and transparency: postLightingBlending</a><br>
&nbsp;&nbsp;&nbsp;&nbsp;<a href="#materialdefinitions/materialblock/blendingandtransparency:transparency" class="level3"><span class="tocNumber">4.2.16&nbsp; </span>Blending and transparency: transparency</a><br>
&nbsp;&nbsp;&nbsp;&nbsp;<a href="#materialdefinitions/materialblock/blendingandtransparency:maskthreshold" class="level3"><span class="tocNumber">4.2.17&nbsp; </span>Blending and transparency: maskThreshold</a><br>
&nbsp;&nbsp;&nbsp;&nbsp;<a href="#materialdefinitions/materialblock/blendingandtransparency:refractionmode" class="level3"><span class="tocNumber">4.2.18&nbsp; </span>Blending and transparency: refractionMode</a><br>
&nbsp;&nbsp;&nbsp;&nbsp;<a href="#materialdefinitions/materialblock/blendingandtransparency:refractiontype" class="level3"><span class="tocNumber">4.2.19&nbsp; </span>Blending and transparency: refractionType</a><br>
&nbsp;&nbsp;&nbsp;&nbsp;<a href="#materialdefinitions/materialblock/rasterization:culling" class="level3"><span class="tocNumber">4.2.20&nbsp; </span>Rasterization: culling</a><br>
&nbsp;&nbsp;&nbsp;&nbsp;<a href="#materialdefinitions/materialblock/rasterization:colorwrite" class="level3"><span class="tocNumber">4.2.21&nbsp; </span>Rasterization: colorWrite</a><br>
&nbsp;&nbsp;&nbsp;&nbsp;<a href="#materialdefinitions/materialblock/rasterization:depthwrite" class="level3"><span class="tocNumber">4.2.22&nbsp; </span>Rasterization: depthWrite</a><br>
&nbsp;&nbsp;&nbsp;&nbsp;<a href="#materialdefinitions/materialblock/rasterization:depthculling" class="level3"><span class="tocNumber">4.2.23&nbsp; </span>Rasterization: depthCulling</a><br>
&nbsp;&nbsp;&nbsp;&nbsp;<a href="#materialdefinitions/materialblock/rasterization:doublesided" class="level3"><span class="tocNumber">4.2.24&nbsp; </span>Rasterization: doubleSided</a><br>
&nbsp;&nbsp;&nbsp;&nbsp;<a href="#materialdefinitions/materialblock/lighting:reflections" class="level3"><span class="tocNumber">4.2.25&nbsp; </span>Lighting: reflections</a><br>
&nbsp;&nbsp;&nbsp;&nbsp;<a href="#materialdefinitions/materialblock/lighting:shadowmultiplier" class="level3"><span class="tocNumber">4.2.26&nbsp; </span>Lighting: shadowMultiplier</a><br>
&nbsp;&nbsp;&nbsp;&nbsp;<a href="#materialdefinitions/materialblock/lighting:transparentshadow" class="level3"><span class="tocNumber">4.2.27&nbsp; </span>Lighting: transparentShadow</a><br>
&nbsp;&nbsp;&nbsp;&nbsp;<a href="#materialdefinitions/materialblock/lighting:clearcoatiorchange" class="level3"><span class="tocNumber">4.2.28&nbsp; </span>Lighting: clearCoatIorChange</a><br>
&nbsp;&nbsp;&nbsp;&nbsp;<a href="#materialdefinitions/materialblock/lighting:multibounceambientocclusion" class="level3"><span class="tocNumber">4.2.29&nbsp; </span>Lighting: multiBounceAmbientOcclusion</a><br>
&nbsp;&nbsp;&nbsp;&nbsp;<a href="#materialdefinitions/materialblock/lighting:specularambientocclusion" class="level3"><span class="tocNumber">4.2.30&nbsp; </span>Lighting: specularAmbientOcclusion</a><br>
&nbsp;&nbsp;&nbsp;&nbsp;<a href="#materialdefinitions/materialblock/anti-aliasing:specularantialiasing" class="level3"><span class="tocNumber">4.2.31&nbsp; </span>Anti-aliasing: specularAntiAliasing</a><br>
&nbsp;&nbsp;&nbsp;&nbsp;<a href="#materialdefinitions/materialblock/anti-aliasing:specularantialiasingvariance" class="level3"><span class="tocNumber">4.2.32&nbsp; </span>Anti-aliasing: specularAntiAliasingVariance</a><br>
&nbsp;&nbsp;&nbsp;&nbsp;<a href="#materialdefinitions/materialblock/anti-aliasing:specularantialiasingthreshold" class="level3"><span class="tocNumber">4.2.33&nbsp; </span>Anti-aliasing: specularAntiAliasingThreshold</a><br>
&nbsp;&nbsp;&nbsp;&nbsp;<a href="#materialdefinitions/materialblock/shading:customsurfaceshading" class="level3"><span class="tocNumber">4.2.34&nbsp; </span>Shading: customSurfaceShading</a><br>
&nbsp;&nbsp;<a href="#materialdefinitions/vertexblock" class="level2"><span class="tocNumber">4.3&nbsp; </span>Vertex block</a><br>
&nbsp;&nbsp;&nbsp;&nbsp;<a href="#materialdefinitions/vertexblock/materialvertexinputs" class="level3"><span class="tocNumber">4.3.1&nbsp; </span>Material vertex inputs</a><br>
&nbsp;&nbsp;&nbsp;&nbsp;<a href="#materialdefinitions/vertexblock/customvertexattributes" class="level3"><span class="tocNumber">4.3.2&nbsp; </span>Custom vertex attributes</a><br>
@@ -775,7 +778,7 @@ and with (right)</span></center></div></center>
The <code>bentNormal</code> property defines the average unoccluded direction at a point on the surface. It is
used to improve the accuracy of indirect lighting. Bent normals can also improve the quality of
specular ambient occlusion (see section <a href="#toc4.2.27">4.2.27</a> about
specular ambient occlusion (see section <a href="#toc4.2.30">4.2.30</a> about
<code>specularAmbientOcclusion</code>).
</p><p>
@@ -890,7 +893,7 @@ light to bend further away from the initial path.
<p></p><p>
The appearance of a refractive material will greatly depend on the <code>refractionType</code> and
<code>refractionMode</code> settings of the material. Refer to section <a href="#toc4.2.16">4.2.16</a> and section <a href="#toc4.2.15">4.2.15</a>
<code>refractionMode</code> settings of the material. Refer to section <a href="#toc4.2.19">4.2.19</a> and section <a href="#toc4.2.18">4.2.18</a>
for more information.
</p><p>
@@ -1423,7 +1426,36 @@ non-shader data.
<span class="line">material {</span>
<span class="line"> name : <span class="hljs-string">"Wet pavement"</span></span>
<span class="line">}</span></code></pre>
<a class="target" name="general:shadingmodel">&nbsp;</a><a class="target" name="materialdefinitions/materialblock/general:shadingmodel">&nbsp;</a><a class="target" name="toc4.2.2">&nbsp;</a><h3>General: shadingModel</h3>
<a class="target" name="general:featurelevel">&nbsp;</a><a class="target" name="materialdefinitions/materialblock/general:featurelevel">&nbsp;</a><a class="target" name="toc4.2.2">&nbsp;</a><h3>General: featureLevel</h3>
<p>
</p><dl><table><tbody><tr valign="top"><td><dt>Type</dt></td><td><dd><p> <code>number</code>
</p></dd></td></tr><tr valign="top"><td><dt>Value</dt></td><td><dd><p> An integer value, either 1, 2 or 3. Defaults to 1.
</p></dd></td></tr></tbody></table></dl><div class="table">
<table class="table"><tbody><tr><th style="text-align:left"> Feature Level </th><th style="text-align:left"> Guaranteed features </th></tr>
<tr><td style="text-align:left"> 1 </td><td style="text-align:left"> 9 textures per material </td></tr>
<tr><td style="text-align:left"> 2 </td><td style="text-align:left"> 9 textures per material, cubemap arrays, ESSL 3.10 </td></tr>
<tr><td style="text-align:left"> 3 </td><td style="text-align:left"> 12 textures per material, cubemap arrays, ESSL 3.10 </td></tr>
</tbody></table><center><div class="tablecaption"><a class="target" name="table_featurelevels">&nbsp;</a><b style="font-style:normal;">Table&nbsp;13:</b> Feature levels</div></center></div>
<p></p><p>
</p><dl><dt>Description</dt><dd><p> Sets the feature level of the material. Each feature level defines a set of features the
material can use. If the material uses a feature not supported by the selected level, <code>matc</code>
will generate an error during compilation. A given feature level is guaranteed to support
all features of lower feature levels.
</p></dd></dl><p></p><pre class="listing tilde"><code><span class="line">material {</span>
<span class="line"> featureLevel : <span class="hljs-number">2</span></span>
<span class="line">}</span></code></pre><p>
</p><dl><table><tbody><tr valign="top"><td><dt>Bugs</dt></td><td><dd><p> <code>matc</code> doesn't verify that a material is not using features above its selected feature level.
</p></dd></td></tr></tbody></table></dl><p></p>
<a class="target" name="general:shadingmodel">&nbsp;</a><a class="target" name="materialdefinitions/materialblock/general:shadingmodel">&nbsp;</a><a class="target" name="toc4.2.3">&nbsp;</a><h3>General: shadingModel</h3>
<p>
@@ -1440,7 +1472,7 @@ non-shader data.
<span class="line">material {</span>
<span class="line"> shadingModel : <span class="hljs-string">"subsurface"</span></span>
<span class="line">}</span></code></pre>
<a class="target" name="general:parameters">&nbsp;</a><a class="target" name="materialdefinitions/materialblock/general:parameters">&nbsp;</a><a class="target" name="toc4.2.3">&nbsp;</a><h3>General: parameters</h3>
<a class="target" name="general:parameters">&nbsp;</a><a class="target" name="materialdefinitions/materialblock/general:parameters">&nbsp;</a><a class="target" name="toc4.2.4">&nbsp;</a><h3>General: parameters</h3>
<p>
@@ -1450,7 +1482,7 @@ non-shader data.
name must be a valid GLSL identifier. Entries also have an optional <code>precision</code>, which can be
one of <code>default</code> (best precision for the platform, typically <code>high</code> on desktop, <code>medium</code> on
mobile), <code>low</code>, <code>medium</code>, <code>high</code>. The type must be one of the types described in
<a href="#table_materialparamstypes">table&nbsp;13</a>.
<a href="#table_materialparamstypes">table&nbsp;14</a>.
</p></dd></dl><div class="table">
<table class="table"><tbody><tr><th style="text-align:left"> Type </th><th style="text-align:left"> Description </th></tr>
@@ -1473,9 +1505,10 @@ non-shader data.
<tr><td style="text-align:left"> float3×3 </td><td style="text-align:left"> Matrix of 3×3 floats </td></tr>
<tr><td style="text-align:left"> float4×4 </td><td style="text-align:left"> Matrix of 4×4 floats </td></tr>
<tr><td style="text-align:left"> sampler2d </td><td style="text-align:left"> 2D texture </td></tr>
<tr><td style="text-align:left"> sampler2dArray </td><td style="text-align:left"> Array of 2D textures </td></tr>
<tr><td style="text-align:left"> samplerExternal </td><td style="text-align:left"> External texture (platform-specific) </td></tr>
<tr><td style="text-align:left"> samplerCubemap </td><td style="text-align:left"> Cubemap texture </td></tr>
</tbody></table><center><div class="tablecaption"><a class="target" name="table_materialparamstypes">&nbsp;</a><b style="font-style:normal;">Table&nbsp;13:</b> Material parameter types</div></center></div>
</tbody></table><center><div class="tablecaption"><a class="target" name="table_materialparamstypes">&nbsp;</a><b style="font-style:normal;">Table&nbsp;14:</b> Material parameter types</div></center></div>
<p></p><p>
@@ -1484,7 +1517,7 @@ non-shader data.
</p></dd><dt>Arrays</dt><dd><p> A parameter can define an array of values by appending <code>[size]</code> after the type name, where
<code>size</code> is a positive integer. For instance: <code>float[9]</code> declares an array of nine <code>float</code>
values. Arrays of samplers are <em class="underscore">not</em> supported at the moment.
values. This syntax does not apply to samplers as arrays are treated as separate types.
</p></dd><dt>Description</dt><dd><p> Lists the parameters required by your material. These parameters can be set at runtime using
Filament's material API. Accessing parameters from the shaders varies depending on the type of
@@ -1531,7 +1564,7 @@ non-shader data.
<span class="line"> material.reflectance = materialParams.metallicReflectance.y;</span>
<span class="line"> }</span>
<span class="line">}</span></code></pre>
<a class="target" name="general:variantfilter">&nbsp;</a><a class="target" name="materialdefinitions/materialblock/general:variantfilter">&nbsp;</a><a class="target" name="toc4.2.4">&nbsp;</a><h3>General: variantFilter</h3>
<a class="target" name="general:variantfilter">&nbsp;</a><a class="target" name="materialdefinitions/materialblock/general:variantfilter">&nbsp;</a><a class="target" name="toc4.2.5">&nbsp;</a><h3>General: variantFilter</h3>
<p>
@@ -1573,7 +1606,7 @@ non-shader data.
<span class="line"> blending : transparent,</span>
<span class="line"> variantFilter : [ skinning ]</span>
<span class="line">}</span></code></pre>
<a class="target" name="general:flipuv">&nbsp;</a><a class="target" name="materialdefinitions/materialblock/general:flipuv">&nbsp;</a><a class="target" name="toc4.2.5">&nbsp;</a><h3>General: flipUV</h3>
<a class="target" name="general:flipuv">&nbsp;</a><a class="target" name="materialdefinitions/materialblock/general:flipuv">&nbsp;</a><a class="target" name="toc4.2.6">&nbsp;</a><h3>General: flipUV</h3>
<p>
@@ -1588,7 +1621,7 @@ non-shader data.
</p></dd></dl><p></p><pre class="listing tilde"><code><span class="line">material {</span>
<span class="line"> flipUV : <span class="hljs-literal">false</span></span>
<span class="line">}</span></code></pre>
<a class="target" name="general:quality">&nbsp;</a><a class="target" name="materialdefinitions/materialblock/general:quality">&nbsp;</a><a class="target" name="toc4.2.6">&nbsp;</a><h3>General: quality</h3>
<a class="target" name="general:quality">&nbsp;</a><a class="target" name="materialdefinitions/materialblock/general:quality">&nbsp;</a><a class="target" name="toc4.2.7">&nbsp;</a><h3>General: quality</h3>
<p>
@@ -1604,7 +1637,43 @@ non-shader data.
</p></dd></dl><p></p><pre class="listing tilde"><code><span class="line">material {</span>
<span class="line"> quality : default</span>
<span class="line">}</span></code></pre>
<a class="target" name="vertexandattributes:requires">&nbsp;</a><a class="target" name="materialdefinitions/materialblock/vertexandattributes:requires">&nbsp;</a><a class="target" name="toc4.2.7">&nbsp;</a><h3>Vertex and attributes: requires</h3>
<a class="target" name="general:instanced">&nbsp;</a><a class="target" name="materialdefinitions/materialblock/general:instanced">&nbsp;</a><a class="target" name="toc4.2.8">&nbsp;</a><h3>General: instanced</h3>
<p>
</p><dl><dt>Type</dt><dd><p> <code>boolean</code>
</p></dd><dt>Value</dt><dd><p> <code>true</code> or <code>false</code>. Defaults to <code>false</code>.
</p></dd><dt>Description</dt><dd><p> Allows a material to access the instance index (i.e.: <strong class="asterisk"><code>gl_InstanceIndex</code></strong>) of instanced
primitives using <code>getInstanceIndex()</code> in the material's shader code. Never use
<strong class="asterisk"><code>gl_InstanceIndex</code></strong> directly. This is typically used with
<code>RenderableManager::Builder::instances()</code>. <code>getInstanceIndex()</code> is available in both the
vertex and fragment shader.
</p></dd></dl><p></p><pre class="listing tilde"><code><span class="line">material {</span>
<span class="line"> instanced : <span class="hljs-literal">true</span></span>
<span class="line">}</span></code></pre>
<a class="target" name="general:vertexdomaindevicejittered">&nbsp;</a><a class="target" name="materialdefinitions/materialblock/general:vertexdomaindevicejittered">&nbsp;</a><a class="target" name="toc4.2.9">&nbsp;</a><h3>General: vertexDomainDeviceJittered</h3>
<p>
</p><dl><dt>Type</dt><dd><p> <code>boolean</code>
</p></dd><dt>Value</dt><dd><p> <code>true</code> or <code>false</code>. Defaults to <code>false</code>.
</p></dd><dt>Description</dt><dd><p> Only meaningful for <code>vertexDomain:Device</code> materials, this parameter specifies whether the
filament clip-space transforms need to be applied or not, which affects TAA and guard bands.
Generally it needs to be applied because by definition <code>vertexDomain:Device</code> materials
vertices are not transformed and used <em class="asterisk">as is</em>.
However, if the vertex shader uses for instance <code>getViewFromClipMatrix()</code> (or other
matrices based on the projection), the clip-space transform is already applied.
Setting this parameter incorrectly can prevent TAA or the guard bands to work correctly.
</p></dd></dl><p></p><pre class="listing tilde"><code><span class="line">material {</span>
<span class="line"> vertexDomainDeviceJittered : <span class="hljs-literal">true</span></span>
<span class="line">}</span></code></pre>
<a class="target" name="vertexandattributes:requires">&nbsp;</a><a class="target" name="materialdefinitions/materialblock/vertexandattributes:requires">&nbsp;</a><a class="target" name="toc4.2.10">&nbsp;</a><h3>Vertex and attributes: requires</h3>
<p>
@@ -1639,7 +1708,7 @@ non-shader data.
<span class="line"> material.baseColor.rgb *= getCustom0().rgb;</span>
<span class="line"> }</span>
<span class="line">}</span></code></pre>
<a class="target" name="vertexandattributes:variables">&nbsp;</a><a class="target" name="materialdefinitions/materialblock/vertexandattributes:variables">&nbsp;</a><a class="target" name="toc4.2.8">&nbsp;</a><h3>Vertex and attributes: variables</h3>
<a class="target" name="vertexandattributes:variables">&nbsp;</a><a class="target" name="materialdefinitions/materialblock/vertexandattributes:variables">&nbsp;</a><a class="target" name="toc4.2.11">&nbsp;</a><h3>Vertex and attributes: variables</h3>
<p>
@@ -1686,7 +1755,7 @@ non-shader data.
<span class="line"> material.eyeDirection.xyz = mulMat3x3Float3(getWorldFromViewMatrix(), u);</span>
<span class="line"> }</span>
<span class="line">}</span></code></pre>
<a class="target" name="vertexandattributes:vertexdomain">&nbsp;</a><a class="target" name="materialdefinitions/materialblock/vertexandattributes:vertexdomain">&nbsp;</a><a class="target" name="toc4.2.9">&nbsp;</a><h3>Vertex and attributes: vertexDomain</h3>
<a class="target" name="vertexandattributes:vertexdomain">&nbsp;</a><a class="target" name="materialdefinitions/materialblock/vertexandattributes:vertexdomain">&nbsp;</a><a class="target" name="toc4.2.12">&nbsp;</a><h3>Vertex and attributes: vertexDomain</h3>
<p>
@@ -1715,7 +1784,7 @@ non-shader data.
<p></p></dd></dl><p></p><pre class="listing tilde"><code><span class="line">material {</span>
<span class="line"> vertexDomain : device</span>
<span class="line">}</span></code></pre>
<a class="target" name="vertexandattributes:interpolation">&nbsp;</a><a class="target" name="materialdefinitions/materialblock/vertexandattributes:interpolation">&nbsp;</a><a class="target" name="toc4.2.10">&nbsp;</a><h3>Vertex and attributes: interpolation</h3>
<a class="target" name="vertexandattributes:interpolation">&nbsp;</a><a class="target" name="materialdefinitions/materialblock/vertexandattributes:interpolation">&nbsp;</a><a class="target" name="toc4.2.13">&nbsp;</a><h3>Vertex and attributes: interpolation</h3>
<p>
@@ -1731,7 +1800,7 @@ non-shader data.
</p></dd></dl><p></p><pre class="listing tilde"><code><span class="line">material {</span>
<span class="line"> interpolation : flat</span>
<span class="line">}</span></code></pre>
<a class="target" name="blendingandtransparency:blending">&nbsp;</a><a class="target" name="materialdefinitions/materialblock/blendingandtransparency:blending">&nbsp;</a><a class="target" name="toc4.2.11">&nbsp;</a><h3>Blending and transparency: blending</h3>
<a class="target" name="blendingandtransparency:blending">&nbsp;</a><a class="target" name="materialdefinitions/materialblock/blendingandtransparency:blending">&nbsp;</a><a class="target" name="toc4.2.14">&nbsp;</a><h3>Blending and transparency: blending</h3>
<p>
@@ -1772,7 +1841,7 @@ non-shader data.
<p></p></dd></dl><p></p><pre class="listing tilde"><code><span class="line">material {</span>
<span class="line"> blending : transparent</span>
<span class="line">}</span></code></pre>
<a class="target" name="blendingandtransparency:postlightingblending">&nbsp;</a><a class="target" name="materialdefinitions/materialblock/blendingandtransparency:postlightingblending">&nbsp;</a><a class="target" name="toc4.2.12">&nbsp;</a><h3>Blending and transparency: postLightingBlending</h3>
<a class="target" name="blendingandtransparency:postlightingblending">&nbsp;</a><a class="target" name="materialdefinitions/materialblock/blendingandtransparency:postlightingblending">&nbsp;</a><a class="target" name="toc4.2.15">&nbsp;</a><h3>Blending and transparency: postLightingBlending</h3>
<p>
@@ -1802,7 +1871,7 @@ non-shader data.
<p></p></dd></dl><p></p><pre class="listing tilde"><code><span class="line">material {</span>
<span class="line"> postLightingBlending : add</span>
<span class="line">}</span></code></pre>
<a class="target" name="blendingandtransparency:transparency">&nbsp;</a><a class="target" name="materialdefinitions/materialblock/blendingandtransparency:transparency">&nbsp;</a><a class="target" name="toc4.2.13">&nbsp;</a><h3>Blending and transparency: transparency</h3>
<a class="target" name="blendingandtransparency:transparency">&nbsp;</a><a class="target" name="materialdefinitions/materialblock/blendingandtransparency:transparency">&nbsp;</a><a class="target" name="toc4.2.16">&nbsp;</a><h3>Blending and transparency: transparency</h3>
<p>
@@ -1849,7 +1918,7 @@ and correctly sorted</span></center></div></center>
and sorting issues are minimized or eliminated</span></center></div></center>
<p></p>
<a class="target" name="blendingandtransparency:maskthreshold">&nbsp;</a><a class="target" name="materialdefinitions/materialblock/blendingandtransparency:maskthreshold">&nbsp;</a><a class="target" name="toc4.2.14">&nbsp;</a><h3>Blending and transparency: maskThreshold</h3>
<a class="target" name="blendingandtransparency:maskthreshold">&nbsp;</a><a class="target" name="materialdefinitions/materialblock/blendingandtransparency:maskthreshold">&nbsp;</a><a class="target" name="toc4.2.17">&nbsp;</a><h3>Blending and transparency: maskThreshold</h3>
<p>
@@ -1866,7 +1935,7 @@ and sorting issues are minimized or eliminated</span></center></div></center>
<span class="line"> blending : masked,</span>
<span class="line"> maskThreshold : <span class="hljs-number">0.5</span></span>
<span class="line">}</span></code></pre>
<a class="target" name="blendingandtransparency:refractionmode">&nbsp;</a><a class="target" name="materialdefinitions/materialblock/blendingandtransparency:refractionmode">&nbsp;</a><a class="target" name="toc4.2.15">&nbsp;</a><h3>Blending and transparency: refractionMode</h3>
<a class="target" name="blendingandtransparency:refractionmode">&nbsp;</a><a class="target" name="materialdefinitions/materialblock/blendingandtransparency:refractionmode">&nbsp;</a><a class="target" name="toc4.2.18">&nbsp;</a><h3>Blending and transparency: refractionMode</h3>
<p>
@@ -1887,7 +1956,7 @@ and sorting issues are minimized or eliminated</span></center></div></center>
</p></dd></dl><p></p><pre class="listing tilde"><code><span class="line">material {</span>
<span class="line"> refractionMode : cubemap,</span>
<span class="line">}</span></code></pre>
<a class="target" name="blendingandtransparency:refractiontype">&nbsp;</a><a class="target" name="materialdefinitions/materialblock/blendingandtransparency:refractiontype">&nbsp;</a><a class="target" name="toc4.2.16">&nbsp;</a><h3>Blending and transparency: refractionType</h3>
<a class="target" name="blendingandtransparency:refractiontype">&nbsp;</a><a class="target" name="materialdefinitions/materialblock/blendingandtransparency:refractiontype">&nbsp;</a><a class="target" name="toc4.2.19">&nbsp;</a><h3>Blending and transparency: refractionType</h3>
<p>
@@ -1906,7 +1975,7 @@ and sorting issues are minimized or eliminated</span></center></div></center>
<span class="line"> refractionMode : cubemap,</span>
<span class="line"> refractionType : thin,</span>
<span class="line">}</span></code></pre>
<a class="target" name="rasterization:culling">&nbsp;</a><a class="target" name="materialdefinitions/materialblock/rasterization:culling">&nbsp;</a><a class="target" name="toc4.2.17">&nbsp;</a><h3>Rasterization: culling</h3>
<a class="target" name="rasterization:culling">&nbsp;</a><a class="target" name="materialdefinitions/materialblock/rasterization:culling">&nbsp;</a><a class="target" name="toc4.2.20">&nbsp;</a><h3>Rasterization: culling</h3>
<p>
@@ -1920,7 +1989,7 @@ and sorting issues are minimized or eliminated</span></center></div></center>
</p></dd></td></tr></tbody></table></dl><p></p><pre class="listing tilde"><code><span class="line">material {</span>
<span class="line"> culling : none</span>
<span class="line">}</span></code></pre>
<a class="target" name="rasterization:colorwrite">&nbsp;</a><a class="target" name="materialdefinitions/materialblock/rasterization:colorwrite">&nbsp;</a><a class="target" name="toc4.2.18">&nbsp;</a><h3>Rasterization: colorWrite</h3>
<a class="target" name="rasterization:colorwrite">&nbsp;</a><a class="target" name="materialdefinitions/materialblock/rasterization:colorwrite">&nbsp;</a><a class="target" name="toc4.2.21">&nbsp;</a><h3>Rasterization: colorWrite</h3>
<p>
@@ -1933,7 +2002,7 @@ and sorting issues are minimized or eliminated</span></center></div></center>
</p></dd></td></tr></tbody></table></dl><p></p><pre class="listing tilde"><code><span class="line">material {</span>
<span class="line"> colorWrite : <span class="hljs-literal">false</span></span>
<span class="line">}</span></code></pre>
<a class="target" name="rasterization:depthwrite">&nbsp;</a><a class="target" name="materialdefinitions/materialblock/rasterization:depthwrite">&nbsp;</a><a class="target" name="toc4.2.19">&nbsp;</a><h3>Rasterization: depthWrite</h3>
<a class="target" name="rasterization:depthwrite">&nbsp;</a><a class="target" name="materialdefinitions/materialblock/rasterization:depthwrite">&nbsp;</a><a class="target" name="toc4.2.22">&nbsp;</a><h3>Rasterization: depthWrite</h3>
<p>
@@ -1946,7 +2015,7 @@ and sorting issues are minimized or eliminated</span></center></div></center>
</p></dd></td></tr></tbody></table></dl><p></p><pre class="listing tilde"><code><span class="line">material {</span>
<span class="line"> depthWrite : <span class="hljs-literal">false</span></span>
<span class="line">}</span></code></pre>
<a class="target" name="rasterization:depthculling">&nbsp;</a><a class="target" name="materialdefinitions/materialblock/rasterization:depthculling">&nbsp;</a><a class="target" name="toc4.2.20">&nbsp;</a><h3>Rasterization: depthCulling</h3>
<a class="target" name="rasterization:depthculling">&nbsp;</a><a class="target" name="materialdefinitions/materialblock/rasterization:depthculling">&nbsp;</a><a class="target" name="toc4.2.23">&nbsp;</a><h3>Rasterization: depthCulling</h3>
<p>
@@ -1960,7 +2029,7 @@ and sorting issues are minimized or eliminated</span></center></div></center>
</p></dd></dl><p></p><pre class="listing tilde"><code><span class="line">material {</span>
<span class="line"> depthCulling : <span class="hljs-literal">false</span></span>
<span class="line">}</span></code></pre>
<a class="target" name="rasterization:doublesided">&nbsp;</a><a class="target" name="materialdefinitions/materialblock/rasterization:doublesided">&nbsp;</a><a class="target" name="toc4.2.21">&nbsp;</a><h3>Rasterization: doubleSided</h3>
<a class="target" name="rasterization:doublesided">&nbsp;</a><a class="target" name="materialdefinitions/materialblock/rasterization:doublesided">&nbsp;</a><a class="target" name="toc4.2.24">&nbsp;</a><h3>Rasterization: doubleSided</h3>
<p>
@@ -1968,26 +2037,24 @@ and sorting issues are minimized or eliminated</span></center></div></center>
</p></dd><dt>Value</dt><dd><p> <code>true</code> or <code>false</code>. Defaults to <code>false</code>.
</p></dd><dt>Description</dt><dd><p> Only available in the <code>unlit</code> shading model. If this property is enabled, the final color
computed by the material is multiplied by the shadowing factor (or visibility). This allows to
create transparent shadow-receiving objects (for instance an invisible ground plane in AR).
This is only supported with shadows from directional lights.
</p></dd><dt>Description</dt><dd><p> Enables two-sided rendering and its capability to be toggled at run time. When set to <code>true</code>,
<code>culling</code> is automatically set to <code>none</code>; if the triangle is back-facing, the triangle's
normal is flipped to become front-facing. When explicitly set to <code>false</code>, this allows the
double-sidedness to be toggled at run time.
</p></dd></dl><p></p><pre class="listing tilde"><code><span class="line">material {</span>
<span class="line"> name : <span class="hljs-string">"Invisible shadow plane"</span>,</span>
<span class="line"> shadingModel : unlit,</span>
<span class="line"> shadowMultiplier : <span class="hljs-literal">true</span>,</span>
<span class="line"> blending : transparent</span>
<span class="line"> name : <span class="hljs-string">"Double sided material"</span>,</span>
<span class="line"> shadingModel : lit,</span>
<span class="line"> doubleSided : <span class="hljs-literal">true</span></span>
<span class="line">}</span>
<span class="line"></span>
<span class="line">fragment {</span>
<span class="line"> void material(inout MaterialInputs material) {</span>
<span class="line"> prepareMaterial(material);</span>
<span class="line"> <span class="hljs-comment">// baseColor defines the color and opacity of the final shadow</span></span>
<span class="line"> material.baseColor = vec4(0.0, 0.0, 0.0, 0.7);</span>
<span class="line"> material.baseColor = materialParams.albedo;</span>
<span class="line"> }</span>
<span class="line">}</span></code></pre>
<a class="target" name="lighting:reflections">&nbsp;</a><a class="target" name="materialdefinitions/materialblock/lighting:reflections">&nbsp;</a><a class="target" name="toc4.2.22">&nbsp;</a><h3>Lighting: reflections</h3>
<a class="target" name="lighting:reflections">&nbsp;</a><a class="target" name="materialdefinitions/materialblock/lighting:reflections">&nbsp;</a><a class="target" name="toc4.2.25">&nbsp;</a><h3>Lighting: reflections</h3>
<p>
@@ -2004,7 +2071,7 @@ and sorting issues are minimized or eliminated</span></center></div></center>
<span class="line"> name : <span class="hljs-string">"Glossy metal"</span>,</span>
<span class="line"> reflections : screenspace</span>
<span class="line">}</span></code></pre>
<a class="target" name="lighting:shadowmultiplier">&nbsp;</a><a class="target" name="materialdefinitions/materialblock/lighting:shadowmultiplier">&nbsp;</a><a class="target" name="toc4.2.23">&nbsp;</a><h3>Lighting: shadowMultiplier</h3>
<a class="target" name="lighting:shadowmultiplier">&nbsp;</a><a class="target" name="materialdefinitions/materialblock/lighting:shadowmultiplier">&nbsp;</a><a class="target" name="toc4.2.26">&nbsp;</a><h3>Lighting: shadowMultiplier</h3>
<p>
@@ -2031,7 +2098,7 @@ and sorting issues are minimized or eliminated</span></center></div></center>
<span class="line"> material.baseColor = vec4(0.0, 0.0, 0.0, 0.7);</span>
<span class="line"> }</span>
<span class="line">}</span></code></pre>
<a class="target" name="lighting:transparentshadow">&nbsp;</a><a class="target" name="materialdefinitions/materialblock/lighting:transparentshadow">&nbsp;</a><a class="target" name="toc4.2.24">&nbsp;</a><h3>Lighting: transparentShadow</h3>
<a class="target" name="lighting:transparentshadow">&nbsp;</a><a class="target" name="materialdefinitions/materialblock/lighting:transparentshadow">&nbsp;</a><a class="target" name="toc4.2.27">&nbsp;</a><h3>Lighting: transparentShadow</h3>
<p>
@@ -2065,7 +2132,7 @@ radius of 4. Model <a href="https://sketchfab.com/3d-models/bottle-of-water-48fd
by <a href="https://sketchfab.com/person-x">T-Art</a>.</span></center></div></center>
<p></p>
<a class="target" name="lighting:clearcoatiorchange">&nbsp;</a><a class="target" name="materialdefinitions/materialblock/lighting:clearcoatiorchange">&nbsp;</a><a class="target" name="toc4.2.25">&nbsp;</a><h3>Lighting: clearCoatIorChange</h3>
<a class="target" name="lighting:clearcoatiorchange">&nbsp;</a><a class="target" name="materialdefinitions/materialblock/lighting:clearcoatiorchange">&nbsp;</a><a class="target" name="toc4.2.28">&nbsp;</a><h3>Lighting: clearCoatIorChange</h3>
<p>
@@ -2087,7 +2154,7 @@ with <code>clearCoatIorChange</code> enabled (left) and disabled
(right).</span></center></div></center>
<p></p>
<a class="target" name="lighting:multibounceambientocclusion">&nbsp;</a><a class="target" name="materialdefinitions/materialblock/lighting:multibounceambientocclusion">&nbsp;</a><a class="target" name="toc4.2.26">&nbsp;</a><h3>Lighting: multiBounceAmbientOcclusion</h3>
<a class="target" name="lighting:multibounceambientocclusion">&nbsp;</a><a class="target" name="materialdefinitions/materialblock/lighting:multibounceambientocclusion">&nbsp;</a><a class="target" name="toc4.2.29">&nbsp;</a><h3>Lighting: multiBounceAmbientOcclusion</h3>
<p>
@@ -2116,7 +2183,7 @@ occclusion enabled (left) and disabled (right).</span></center></div></center>
occclusion enabled and disabled.</span></center></div></center>
<p></p>
<a class="target" name="lighting:specularambientocclusion">&nbsp;</a><a class="target" name="materialdefinitions/materialblock/lighting:specularambientocclusion">&nbsp;</a><a class="target" name="toc4.2.27">&nbsp;</a><h3>Lighting: specularAmbientOcclusion</h3>
<a class="target" name="lighting:specularambientocclusion">&nbsp;</a><a class="target" name="materialdefinitions/materialblock/lighting:specularambientocclusion">&nbsp;</a><a class="target" name="toc4.2.30">&nbsp;</a><h3>Lighting: specularAmbientOcclusion</h3>
<p>
@@ -2142,7 +2209,7 @@ occclusion enabled and disabled.</span></center></div></center>
particularly visible under the hose.</span></center></div></center>
<p></p>
<a class="target" name="anti-aliasing:specularantialiasing">&nbsp;</a><a class="target" name="materialdefinitions/materialblock/anti-aliasing:specularantialiasing">&nbsp;</a><a class="target" name="toc4.2.28">&nbsp;</a><h3>Anti-aliasing: specularAntiAliasing</h3>
<a class="target" name="anti-aliasing:specularantialiasing">&nbsp;</a><a class="target" name="materialdefinitions/materialblock/anti-aliasing:specularantialiasing">&nbsp;</a><a class="target" name="toc4.2.31">&nbsp;</a><h3>Anti-aliasing: specularAntiAliasing</h3>
<p>
@@ -2159,7 +2226,7 @@ particularly visible under the hose.</span></center></div></center>
</p></dd></dl><p></p><pre class="listing tilde"><code><span class="line">material {</span>
<span class="line"> specularAntiAliasing : <span class="hljs-literal">true</span></span>
<span class="line">}</span></code></pre>
<a class="target" name="anti-aliasing:specularantialiasingvariance">&nbsp;</a><a class="target" name="materialdefinitions/materialblock/anti-aliasing:specularantialiasingvariance">&nbsp;</a><a class="target" name="toc4.2.29">&nbsp;</a><h3>Anti-aliasing: specularAntiAliasingVariance</h3>
<a class="target" name="anti-aliasing:specularantialiasingvariance">&nbsp;</a><a class="target" name="materialdefinitions/materialblock/anti-aliasing:specularantialiasingvariance">&nbsp;</a><a class="target" name="toc4.2.32">&nbsp;</a><h3>Anti-aliasing: specularAntiAliasingVariance</h3>
<p>
@@ -2174,7 +2241,7 @@ particularly visible under the hose.</span></center></div></center>
</p></dd></dl><p></p><pre class="listing tilde"><code><span class="line">material {</span>
<span class="line"> specularAntiAliasingVariance : <span class="hljs-number">0.2</span></span>
<span class="line">}</span></code></pre>
<a class="target" name="anti-aliasing:specularantialiasingthreshold">&nbsp;</a><a class="target" name="materialdefinitions/materialblock/anti-aliasing:specularantialiasingthreshold">&nbsp;</a><a class="target" name="toc4.2.30">&nbsp;</a><h3>Anti-aliasing: specularAntiAliasingThreshold</h3>
<a class="target" name="anti-aliasing:specularantialiasingthreshold">&nbsp;</a><a class="target" name="materialdefinitions/materialblock/anti-aliasing:specularantialiasingthreshold">&nbsp;</a><a class="target" name="toc4.2.33">&nbsp;</a><h3>Anti-aliasing: specularAntiAliasingThreshold</h3>
<p>
@@ -2188,7 +2255,7 @@ particularly visible under the hose.</span></center></div></center>
</p></dd></dl><p></p><pre class="listing tilde"><code><span class="line">material {</span>
<span class="line"> specularAntiAliasingThreshold : <span class="hljs-number">0.1</span></span>
<span class="line">}</span></code></pre>
<a class="target" name="shading:customsurfaceshading">&nbsp;</a><a class="target" name="materialdefinitions/materialblock/shading:customsurfaceshading">&nbsp;</a><a class="target" name="toc4.2.31">&nbsp;</a><h3>Shading: customSurfaceShading</h3>
<a class="target" name="shading:customsurfaceshading">&nbsp;</a><a class="target" name="materialdefinitions/materialblock/shading:customsurfaceshading">&nbsp;</a><a class="target" name="toc4.2.34">&nbsp;</a><h3>Shading: customSurfaceShading</h3>
<p>
@@ -2252,7 +2319,7 @@ APIs listed in the <a href="#shaderpublicapis">Shader public APIs</a> section.
<span class="line"> float3 worldNormal; <span class="hljs-comment">// only if the shading model is not unlit</span></span>
<span class="line"> float4 worldPosition; <span class="hljs-comment">// always available (see note below about world-space)</span></span>
<span class="line"></span>
<span class="line"> <span class="hljs-type">mat4</span> clipSpaceTransform; <span class="hljs-comment">// default: identity, transforms the clip-space position</span></span>
<span class="line"> <span class="hljs-type">mat4</span> clipSpaceTransform; <span class="hljs-comment">// default: identity, transforms the clip-space position, only available for `vertexDomain:device`</span></span>
<span class="line"></span>
<span class="line"> <span class="hljs-comment">// variable* names are replaced with actual names</span></span>
<span class="line"> float4 variable0; <span class="hljs-comment">// if 1 or more variables is defined</span></span>
@@ -2747,7 +2814,7 @@ source material definition file.
<p>
The command line flags relevant to application development are described in <a href="#table_matcflags">table&nbsp;14</a>.
The command line flags relevant to application development are described in <a href="#table_matcflags">table&nbsp;15</a>.
</p><div class="table">
<table class="table"><tbody><tr><th style="text-align:right"> Flag </th><th style="text-align:center"> Value </th><th style="text-align:left"> Usage </th></tr>
<tr><td style="text-align:right"> <strong class="asterisk">-o</strong>, <strong class="asterisk">—output</strong> </td><td style="text-align:center"> [path] </td><td style="text-align:left"> Specify the output file path </td></tr>
@@ -2756,7 +2823,7 @@ The command line flags relevant to application development are described in <a h
<tr><td style="text-align:right"> <strong class="asterisk">-S</strong>, <strong class="asterisk">—optimize-size</strong> </td><td style="text-align:center"> N/A </td><td style="text-align:left"> Optimize compiled material for size instead of just performance </td></tr>
<tr><td style="text-align:right"> <strong class="asterisk">-r</strong>, <strong class="asterisk">—reflect</strong> </td><td style="text-align:center"> parameters </td><td style="text-align:left"> Outputs the specified metadata as JSON </td></tr>
<tr><td style="text-align:right"> <strong class="asterisk">-v</strong>, <strong class="asterisk">—variant-filter</strong> </td><td style="text-align:center"> [variant] </td><td style="text-align:left"> Filters out the specified, comma-separated variants </td></tr>
</tbody></table><center><div class="tablecaption"><a class="target" name="table_matcflags">&nbsp;</a><b style="font-style:normal;">Table&nbsp;14:</b> List of <code>matc</code> flags</div></center></div>
</tbody></table><center><div class="tablecaption"><a class="target" name="table_matcflags">&nbsp;</a><b style="font-style:normal;">Table&nbsp;15:</b> List of <code>matc</code> flags</div></center></div>
<p></p><p>

View File

@@ -932,6 +932,37 @@ material {
}
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
### General: featureLevel
Type
: `number`
Value
: An integer value, either 1, 2 or 3. Defaults to 1.
Feature Level | Guaranteed features
:----------------------|:---------------------------------
1 | 9 textures per material
2 | 9 textures per material, cubemap arrays, ESSL 3.10
3 | 12 textures per material, cubemap arrays, ESSL 3.10
[Table [featureLevels]: Feature levels]
Description
: Sets the feature level of the material. Each feature level defines a set of features the
material can use. If the material uses a feature not supported by the selected level, `matc`
will generate an error during compilation. A given feature level is guaranteed to support
all features of lower feature levels.
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ JSON
material {
featureLevel : 2
}
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Bugs
: `matc` doesn't verify that a material is not using features above its selected feature level.
### General: shadingModel
Type
@@ -986,6 +1017,7 @@ uint4 | Vector of 4 unsigned integers
float3x3 | Matrix of 3x3 floats
float4x4 | Matrix of 4x4 floats
sampler2d | 2D texture
sampler2dArray | Array of 2D textures
samplerExternal | External texture (platform-specific)
samplerCubemap | Cubemap texture
[Table [materialParamsTypes]: Material parameter types]
@@ -997,7 +1029,7 @@ Samplers
Arrays
: A parameter can define an array of values by appending `[size]` after the type name, where
`size` is a positive integer. For instance: `float[9]` declares an array of nine `float`
values. Arrays of samplers are _not_ supported at the moment.
values. This syntax does not apply to samplers as arrays are treated as separate types.
Description
: Lists the parameters required by your material. These parameters can be set at runtime using
@@ -1140,6 +1172,29 @@ material {
}
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
### General: vertexDomainDeviceJittered
Type
: `boolean`
Value
: `true` or `false`. Defaults to `false`.
Description
: Only meaningful for `vertexDomain:Device` materials, this parameter specifies whether the
filament clip-space transforms need to be applied or not, which affects TAA and guard bands.
Generally it needs to be applied because by definition `vertexDomain:Device` materials
vertices are not transformed and used *as is*.
However, if the vertex shader uses for instance `getViewFromClipMatrix()` (or other
matrices based on the projection), the clip-space transform is already applied.
Setting this parameter incorrectly can prevent TAA or the guard bands to work correctly.
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ JSON
material {
vertexDomainDeviceJittered : true
}
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
### Vertex and attributes: requires
Type
@@ -1527,24 +1582,22 @@ Value
: `true` or `false`. Defaults to `false`.
Description
: Only available in the `unlit` shading model. If this property is enabled, the final color
computed by the material is multiplied by the shadowing factor (or visibility). This allows to
create transparent shadow-receiving objects (for instance an invisible ground plane in AR).
This is only supported with shadows from directional lights.
: Enables two-sided rendering and its capability to be toggled at run time. When set to `true`,
`culling` is automatically set to `none`; if the triangle is back-facing, the triangle's
normal is flipped to become front-facing. When explicitly set to `false`, this allows the
double-sidedness to be toggled at run time.
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ JSON
material {
name : "Invisible shadow plane",
shadingModel : unlit,
shadowMultiplier : true,
blending : transparent
name : "Double sided material",
shadingModel : lit,
doubleSided : true
}
fragment {
void material(inout MaterialInputs material) {
prepareMaterial(material);
// baseColor defines the color and opacity of the final shadow
material.baseColor = vec4(0.0, 0.0, 0.0, 0.7);
material.baseColor = materialParams.albedo;
}
}
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@@ -1845,7 +1898,7 @@ struct MaterialVertexInputs {
float3 worldNormal; // only if the shading model is not unlit
float4 worldPosition; // always available (see note below about world-space)
mat4 clipSpaceTransform; // default: identity, transforms the clip-space position
mat4 clipSpaceTransform; // default: identity, transforms the clip-space position, only available for `vertexDomain:device`
// variable* names are replaced with actual names
float4 variable0; // if 1 or more variables is defined

View File

@@ -43,7 +43,7 @@ filament-viewer::part(canvas) {
</p>
</main>
<script src="https://unpkg.com/filament@1.22.0/filament.js"></script>
<script src="https://unpkg.com/filament@1.25.3/filament.js"></script>
<script src="https://unpkg.com/gltumble"></script>
<script src="filament-viewer.js" type="module"></script>
</body>

View File

@@ -48,6 +48,7 @@ set(PUBLIC_HDRS
)
set(SRCS
src/AtlasAllocator.cpp
src/Box.cpp
src/BufferObject.cpp
src/Camera.cpp
@@ -72,6 +73,7 @@ set(SRCS
src/MaterialParser.cpp
src/MorphTargetBuffer.cpp
src/PerViewUniforms.cpp
src/PerShadowMapUniforms.cpp
src/PostProcessManager.cpp
src/RenderPass.cpp
src/RenderPrimitive.cpp
@@ -145,6 +147,7 @@ set(PRIVATE_HDRS
src/Intersections.h
src/MaterialParser.h
src/PerViewUniforms.h
src/PerShadowMapUniforms.h
src/PIDController.h
src/PostProcessManager.h
src/RendererUtils.h
@@ -198,7 +201,7 @@ set(PRIVATE_HDRS
src/materials/fsr/ffx_a.h
src/materials/fsr/ffx_fsr1.h
src/materials/fsr/ffx_fsr1_mobile.fs
src/upcast.h
src/downcast.h
)
set(MATERIAL_SRCS
@@ -523,6 +526,9 @@ add_library(${TARGET} STATIC ${PRIVATE_HDRS} ${PUBLIC_HDRS} ${SRCS} ${DATA_BINS}
# specify where the public headers of this library are
target_include_directories(${TARGET} PUBLIC ${PUBLIC_HDR_DIR})
# add this subproject to the Filament folder
set_target_properties(${TARGET} PROPERTIES FOLDER Filament)
# ==================================================================================================
# Dependencies
# ==================================================================================================

View File

@@ -44,10 +44,8 @@ To link against debug builds of Filament, you must also link against:
- `matdbg`, Support library that adds an interactive web-based debugger to Filament
To use the Vulkan backend on macOS you must also make the following libraries available at runtime:
- `MoltenVK_icd.json`
- `libMoltenVK.dylib`
- `libvulkan.1.dylib`
To use the Vulkan backend on macOS you must install the LunarG SDK, enable "System Global
Components", and reboot your machine.
The easiest way to install those files is to use the macOS
[LunarG Vulkan SDK](https://www.lunarg.com/vulkan-sdk/) installer.

View File

@@ -11,11 +11,14 @@ set(GENERATION_ROOT ${CMAKE_CURRENT_BINARY_DIR})
set(PUBLIC_HDRS
include/backend/BufferDescriptor.h
include/backend/CallbackHandler.h
include/backend/DriverApiForward.h
include/backend/DriverEnums.h
include/backend/Handle.h
include/backend/PipelineState.h
include/backend/PixelBufferDescriptor.h
include/backend/Platform.h
include/backend/Program.h
include/backend/SamplerDescriptor.h
include/backend/TargetBufferInfo.h
)
@@ -46,9 +49,7 @@ set(PRIVATE_HDRS
include/private/backend/Driver.h
include/private/backend/DriverApi.h
include/private/backend/DriverAPI.inc
include/private/backend/DriverApiForward.h
include/private/backend/HandleAllocator.h
include/private/backend/Program.h
include/private/backend/SamplerGroup.h
src/CommandStreamDispatcher.h
src/DataReshaper.h
@@ -98,11 +99,11 @@ if (FILAMENT_SUPPORTS_OPENGL AND NOT FILAMENT_USE_EXTERNAL_GLES3 AND NOT FILAMEN
elseif (LINUX)
if (FILAMENT_SUPPORTS_X11)
list(APPEND SRCS src/opengl/platforms/PlatformGLX.cpp)
elseif (FILAMENT_SUPPORTS_EGL_ON_LINUX)
list(APPEND SRCS src/opengl/platforms/PlatformEGLHeadless.cpp)
endif()
elseif (WIN32)
list(APPEND SRCS src/opengl/platforms/PlatformWGL.cpp)
else()
list(APPEND SRCS src/opengl/platforms/PlatformDummyGL.cpp)
endif()
endif()
@@ -221,6 +222,9 @@ add_library(${TARGET} STATIC ${PRIVATE_HDRS} ${PUBLIC_HDRS} ${SRCS})
# specify where the public headers of this library are
target_include_directories(${TARGET} PUBLIC ${PUBLIC_HDR_DIR})
# add this subproject to the Filament folder
set_target_properties(${TARGET} PROPERTIES FOLDER Filament)
# ==================================================================================================
# Expose a header-only target to minimize dependencies.
# ==================================================================================================
@@ -266,6 +270,7 @@ set(DUMMY_SRC "${VKSHADERS_DIR}/dummy.c")
add_custom_command(OUTPUT ${DUMMY_SRC} COMMAND echo "//" > ${DUMMY_SRC})
add_library(vkshaders STATIC ${DUMMY_SRC} ${RESGEN_SOURCE})
set_target_properties(vkshaders PROPERTIES FOLDER Filament/Generated)
# ==================================================================================================
# Dependencies
@@ -304,6 +309,9 @@ endif()
if (LINUX)
target_link_libraries(${TARGET} PRIVATE dl)
if(FILAMENT_SUPPORTS_EGL_ON_LINUX)
target_link_libraries(${TARGET} PUBLIC EGL)
endif()
endif()
# ==================================================================================================
@@ -390,12 +398,14 @@ if (APPLE)
test/test_LoadImage.cpp
test/test_RenderExternalImage.cpp
test/test_StencilBuffer.cpp
test/test_Scissor.cpp
)
target_link_libraries(backend_test PRIVATE
backend
getopt
gtest
filamat
SPIRV
spirv-cross-glsl)
@@ -428,6 +438,8 @@ if (APPLE)
install(FILES "${BACKEND_TEST_COMBINED_OUTPUT}" DESTINATION lib/${DIST_DIR} RENAME ${BACKEND_TEST_LIB_NAME})
install(FILES test/PlatformRunner.h DESTINATION include/backend_test)
endif()
set_target_properties(backend_test PROPERTIES FOLDER Tests)
endif()
if (APPLE AND NOT IOS)
@@ -436,5 +448,26 @@ if (APPLE AND NOT IOS)
# Because each test case is a separate file, the -force_load flag is necessary to prevent the
# linker from removing "unused" symbols.
target_link_libraries(backend_test_mac PRIVATE -force_load backend_test)
set_target_properties(backend_test_mac PROPERTIES FOLDER Tests)
endif()
# ==================================================================================================
# Compute tests
if (NOT IOS AND NOT WEBGL)
add_executable(compute_test
test/ComputeTest.cpp
test/Arguments.cpp
test/test_ComputeBasic.cpp
)
target_link_libraries(compute_test PRIVATE
backend
getopt
gtest
)
set_target_properties(compute_test PROPERTIES FOLDER Tests)
endif()

View File

@@ -48,16 +48,37 @@ static constexpr uint64_t SWAP_CHAIN_CONFIG_ENABLE_XCB = 0x4;
static constexpr uint64_t SWAP_CHAIN_CONFIG_APPLE_CVPIXELBUFFER = 0x8;
static constexpr size_t MAX_VERTEX_ATTRIBUTE_COUNT = 16; // This is guaranteed by OpenGL ES.
static constexpr size_t MAX_VERTEX_SAMPLER_COUNT = 16; // This is guaranteed by OpenGL ES.
static constexpr size_t MAX_FRAGMENT_SAMPLER_COUNT = 16; // This is guaranteed by OpenGL ES.
static constexpr size_t MAX_SAMPLER_COUNT = 32; // This is guaranteed by OpenGL ES.
static constexpr size_t MAX_SAMPLER_COUNT = 62; // Maximum needed at feature level 3.
static constexpr size_t MAX_VERTEX_BUFFER_COUNT = 16; // Max number of bound buffer objects.
static constexpr size_t MAX_SSBO_COUNT = 4; // This is guaranteed by OpenGL ES.
// Per feature level caps
// Use (int)FeatureLevel to index this array
static constexpr struct {
const size_t MAX_VERTEX_SAMPLER_COUNT;
const size_t MAX_FRAGMENT_SAMPLER_COUNT;
} FEATURE_LEVEL_CAPS[4] = {
{ 0, 0 }, // do not use
{ 16, 16 }, // guaranteed by OpenGL ES, Vulkan and Metal
{ 16, 16 }, // guaranteed by OpenGL ES, Vulkan and Metal
{ 31, 31 }, // guaranteed by Metal
};
static_assert(MAX_VERTEX_BUFFER_COUNT <= MAX_VERTEX_ATTRIBUTE_COUNT,
"The number of buffer objects that can be attached to a VertexBuffer must be "
"less than or equal to the maximum number of vertex attributes.");
static constexpr size_t CONFIG_BINDING_COUNT = 12; // This is guaranteed by OpenGL ES.
static constexpr size_t CONFIG_UNIFORM_BINDING_COUNT = 10; // This is guaranteed by OpenGL ES.
static constexpr size_t CONFIG_SAMPLER_BINDING_COUNT = 4; // This is guaranteed by OpenGL ES.
/**
* Defines the backend's feature levels.
*/
enum class FeatureLevel : uint8_t {
FEATURE_LEVEL_1 = 1, //!< OpenGL ES 3.0 features (default)
FEATURE_LEVEL_2, //!< OpenGL ES 3.1 features + 16 textures units + cubemap arrays
FEATURE_LEVEL_3 //!< OpenGL ES 3.1 features + 31 textures units + cubemap arrays
};
/**
* Selects which driver a particular Engine should use.
@@ -177,16 +198,18 @@ static constexpr uint64_t FENCE_WAIT_FOR_EVER = uint64_t(-1);
/**
* Shader model.
*
* These enumerants are used across all backends and refer to a level of functionality, rather
* than to an OpenGL specific shader model.
* These enumerants are used across all backends and refer to a level of functionality and quality.
*
* For example, the OpenGL backend returns `MOBILE` if it supports OpenGL ES, or `DESKTOP` if it
* supports Desktop OpenGL, this is later used to select the proper shader.
*
* Shader quality vs. performance is also affected by ShaderModel.
*/
enum class ShaderModel : uint8_t {
//! For testing
UNKNOWN = 0,
GL_ES_30 = 1, //!< Mobile level functionality
GL_CORE_41 = 2, //!< Desktop level functionality
MOBILE = 1, //!< Mobile level functionality
DESKTOP = 2, //!< Desktop level functionality
};
static constexpr size_t SHADER_MODEL_COUNT = 3;
static constexpr size_t SHADER_MODEL_COUNT = 2;
/**
* Primitive types
@@ -197,8 +220,7 @@ enum class PrimitiveType : uint8_t {
LINES = 1, //!< lines
LINE_STRIP = 3, //!< line strip
TRIANGLES = 4, //!< triangles
TRIANGLE_STRIP = 5, //!< triangle strip
NONE = 0xFF
TRIANGLE_STRIP = 5 //!< triangle strip
};
/**
@@ -235,11 +257,12 @@ enum class Precision : uint8_t {
//! Texture sampler type
enum class SamplerType : uint8_t {
SAMPLER_2D, //!< 2D texture
SAMPLER_2D_ARRAY, //!< 2D array texture
SAMPLER_CUBEMAP, //!< Cube map texture
SAMPLER_EXTERNAL, //!< External texture
SAMPLER_3D, //!< 3D texture
SAMPLER_2D, //!< 2D texture
SAMPLER_2D_ARRAY, //!< 2D array texture
SAMPLER_CUBEMAP, //!< Cube map texture
SAMPLER_EXTERNAL, //!< External texture
SAMPLER_3D, //!< 3D texture
SAMPLER_CUBEMAP_ARRAY, //!< Cube map array texture (feature level 2)
};
//! Subpass type
@@ -290,7 +313,8 @@ enum class ElementType : uint8_t {
//! Buffer object binding type
enum class BufferObjectBinding : uint8_t {
VERTEX,
UNIFORM
UNIFORM,
SHADER_STORAGE
};
//! Face culling Mode
@@ -627,6 +651,10 @@ static constexpr bool isS3TCSRGBCompression(TextureFormat format) noexcept {
return format >= TextureFormat::DXT1_SRGB && format <= TextureFormat::DXT5_SRGBA;
}
static constexpr bool isASTCCompression(TextureFormat format) noexcept {
return format >= TextureFormat::RGBA_ASTC_4x4 && format <= TextureFormat::SRGB8_ALPHA8_ASTC_12x12;
}
//! Texture Cubemap Face
enum class TextureCubemapFace : uint8_t {
// don't change the enums values
@@ -638,54 +666,6 @@ enum class TextureCubemapFace : uint8_t {
NEGATIVE_Z = 5, //!< -z face
};
inline constexpr int operator +(TextureCubemapFace rhs) noexcept {
return int(rhs);
}
//! Face offsets for all faces of a cubemap
struct FaceOffsets {
using size_type = size_t;
union {
struct {
size_type px; //!< +x face offset in bytes
size_type nx; //!< -x face offset in bytes
size_type py; //!< +y face offset in bytes
size_type ny; //!< -y face offset in bytes
size_type pz; //!< +z face offset in bytes
size_type nz; //!< -z face offset in bytes
};
size_type offsets[6];
};
size_type operator[](size_t n) const noexcept { return offsets[n]; }
size_type& operator[](size_t n) { return offsets[n]; }
FaceOffsets() noexcept = default;
explicit FaceOffsets(size_type faceSize) noexcept {
px = faceSize * 0;
nx = faceSize * 1;
py = faceSize * 2;
ny = faceSize * 3;
pz = faceSize * 4;
nz = faceSize * 5;
}
FaceOffsets(const FaceOffsets& rhs) noexcept {
px = rhs.px;
nx = rhs.nx;
py = rhs.py;
ny = rhs.ny;
pz = rhs.pz;
nz = rhs.nz;
}
FaceOffsets& operator=(const FaceOffsets& rhs) noexcept {
px = rhs.px;
nx = rhs.nx;
py = rhs.py;
ny = rhs.ny;
pz = rhs.pz;
nz = rhs.nz;
return *this;
}
};
//! Sampler Wrap mode
enum class SamplerWrapMode : uint8_t {
CLAMP_TO_EDGE, //!< clamp-to-edge. The edge of the texture extends to infinity.
@@ -796,6 +776,13 @@ enum class StencilOperation : uint8_t {
INVERT, //!< Bitwise inverts the current value.
};
//! stencil faces
enum class StencilFace : uint8_t {
FRONT = 0x1, //!< Update stencil state for front-facing polygons.
BACK = 0x2, //!< Update stencil state for back-facing polygons.
FRONT_AND_BACK = FRONT | BACK, //!< Update stencil state for all polygons.
};
//! Stream for external textures
enum class StreamType {
NATIVE, //!< Not synchronized but copy-free. Good for video.
@@ -828,11 +815,9 @@ struct RasterState {
using DepthFunc = backend::SamplerCompareFunc;
using BlendEquation = backend::BlendEquation;
using BlendFunction = backend::BlendFunction;
using StencilFunction = backend::SamplerCompareFunc;
using StencilOperation = backend::StencilOperation;
RasterState() noexcept { // NOLINT
static_assert(sizeof(RasterState) == sizeof(uint64_t),
static_assert(sizeof(RasterState) == sizeof(uint32_t),
"RasterState size not what was intended");
culling = CullingMode::BACK;
blendEquationRGB = BlendEquation::ADD;
@@ -841,10 +826,6 @@ struct RasterState {
blendFunctionSrcAlpha = BlendFunction::ONE;
blendFunctionDstRGB = BlendFunction::ZERO;
blendFunctionDstAlpha = BlendFunction::ZERO;
stencilFunc = StencilFunction::A;
stencilOpStencilFail = StencilOperation::KEEP;
stencilOpDepthFail = StencilOperation::KEEP;
stencilOpDepthStencilPass = StencilOperation::KEEP;
}
bool operator == (RasterState rhs) const noexcept { return u == rhs.u; }
@@ -903,26 +884,10 @@ struct RasterState {
//! whether front face winding direction must be inverted
bool inverseFrontFaces : 1; // 31
//! Whether stencil-buffer writes are enabled
bool stencilWrite : 1; // 32
//! Stencil reference value
uint8_t stencilRef : 8; // 40
//! Stencil test function
StencilFunction stencilFunc : 3; // 43
//! Stencil operation when stencil test fails
StencilOperation stencilOpStencilFail : 3; // 46
//! padding, must be 0
uint8_t padding0 : 2; // 48
//! Stencil operation when stencil test passes but depth test fails
StencilOperation stencilOpDepthFail : 3; // 51
//! Stencil operation when both stencil and depth test pass
StencilOperation stencilOpDepthStencilPass : 3; // 54
//! padding, must be 0
uint8_t padding1 : 2; // 56
//! padding, must be 0
uint8_t padding2 : 8; // 64
uint8_t padding : 1; // 32
};
uint64_t u = 0;
uint32_t u = 0;
};
};
@@ -931,21 +896,31 @@ struct RasterState {
* \privatesection
*/
enum ShaderType : uint8_t {
enum class ShaderStage : uint8_t {
VERTEX = 0,
FRAGMENT = 1
FRAGMENT = 1,
COMPUTE = 2
};
static constexpr size_t PIPELINE_STAGE_COUNT = 2;
struct ShaderStageFlags {
bool vertex : 1;
bool fragment : 1;
bool hasShaderType(ShaderType type) const {
return (vertex && type == ShaderType::VERTEX) ||
(fragment && type == ShaderType::FRAGMENT);
}
static constexpr size_t PIPELINE_STAGE_COUNT = 2;
enum class ShaderStageFlags : uint8_t {
NONE = 0,
VERTEX = 0x1,
FRAGMENT = 0x2,
COMPUTE = 0x4,
ALL_SHADER_STAGE_FLAGS = VERTEX | FRAGMENT | COMPUTE
};
static constexpr ShaderStageFlags ALL_SHADER_STAGE_FLAGS = { true, true };
static inline constexpr bool hasShaderType(ShaderStageFlags flags, ShaderStage type) noexcept {
switch (type) {
case ShaderStage::VERTEX:
return bool(uint8_t(flags) & uint8_t(ShaderStageFlags::VERTEX));
case ShaderStage::FRAGMENT:
return bool(uint8_t(flags) & uint8_t(ShaderStageFlags::FRAGMENT));
case ShaderStage::COMPUTE:
return bool(uint8_t(flags) & uint8_t(ShaderStageFlags::COMPUTE));
}
}
/**
* Selects which buffers to clear at the beginning of the render pass, as well as which buffers
@@ -1016,6 +991,55 @@ struct PolygonOffset {
float constant = 0; // units in GL-speak
};
struct StencilState {
using StencilFunction = SamplerCompareFunc;
struct StencilOperations {
//! Stencil test function
StencilFunction stencilFunc : 3; // 3
//! Stencil operation when stencil test fails
StencilOperation stencilOpStencilFail : 3; // 6
uint8_t padding0 : 2; // 8
//! Stencil operation when stencil test passes but depth test fails
StencilOperation stencilOpDepthFail : 3; // 11
//! Stencil operation when both stencil and depth test pass
StencilOperation stencilOpDepthStencilPass : 3; // 14
uint8_t padding1 : 2; // 16
//! Reference value for stencil comparison tests and updates
uint8_t ref; // 24
//! Masks the bits of the stencil values participating in the stencil comparison test.
uint8_t readMask; // 32
//! Masks the bits of the stencil values updated by the stencil test.
uint8_t writeMask; // 40
};
//! Stencil operations for front-facing polygons
StencilOperations front = {
.stencilFunc = StencilFunction::A, .ref = 0, .readMask = 0xff, .writeMask = 0xff };
//! Stencil operations for back-facing polygons
StencilOperations back = {
.stencilFunc = StencilFunction::A, .ref = 0, .readMask = 0xff, .writeMask = 0xff };
//! Whether stencil-buffer writes are enabled
bool stencilWrite = false;
uint8_t padding = 0;
};
static_assert(sizeof(StencilState::StencilOperations) == 5u,
"StencilOperations size not what was intended");
static_assert(sizeof(StencilState) == 12u,
"StencilState size not what was intended");
using FrameScheduledCallback = void(*)(PresentCallable callable, void* user);
@@ -1026,16 +1050,25 @@ enum class Workaround : uint16_t {
SPLIT_EASU,
// Backend allows feedback loop with ancillary buffers (depth/stencil) as long as they're read-only for
// the whole render pass.
ALLOW_READ_ONLY_ANCILLARY_FEEDBACK_LOOP
ALLOW_READ_ONLY_ANCILLARY_FEEDBACK_LOOP,
// for some uniform arrays, it's needed to do an initialization to avoid crash on adreno gpu
ADRENO_UNIFORM_ARRAY_CRASH
};
} // namespace filament::backend
template<> struct utils::EnableBitMaskOperators<filament::backend::ShaderStageFlags>
: public std::true_type {};
template<> struct utils::EnableBitMaskOperators<filament::backend::TargetBufferFlags>
: public std::true_type {};
template<> struct utils::EnableBitMaskOperators<filament::backend::TextureUsage>
: public std::true_type {};
template<> struct utils::EnableBitMaskOperators<filament::backend::StencilFace>
: public std::true_type {};
template<> struct utils::EnableIntegerOperators<filament::backend::TextureCubemapFace>
: public std::true_type {};
template<> struct utils::EnableIntegerOperators<filament::backend::FeatureLevel>
: public std::true_type {};
#if !defined(NDEBUG)
utils::io::ostream& operator<<(utils::io::ostream& out, filament::backend::BufferUsage usage);
@@ -1061,7 +1094,6 @@ utils::io::ostream& operator<<(utils::io::ostream& out, filament::backend::Textu
utils::io::ostream& operator<<(utils::io::ostream& out, filament::backend::BufferObjectBinding binding);
utils::io::ostream& operator<<(utils::io::ostream& out, filament::backend::TextureSwizzle swizzle);
utils::io::ostream& operator<<(utils::io::ostream& out, const filament::backend::AttributeArray& type);
utils::io::ostream& operator<<(utils::io::ostream& out, const filament::backend::FaceOffsets& type);
utils::io::ostream& operator<<(utils::io::ostream& out, const filament::backend::PolygonOffset& po);
utils::io::ostream& operator<<(utils::io::ostream& out, const filament::backend::RasterState& rs);
utils::io::ostream& operator<<(utils::io::ostream& out, const filament::backend::RenderPassParams& b);

View File

@@ -31,6 +31,7 @@ namespace filament::backend {
struct PipelineState {
Handle<HwProgram> program;
RasterState rasterState;
StencilState stencilState;
PolygonOffset polygonOffset;
Viewport scissor{ 0, 0,
(uint32_t)std::numeric_limits<int32_t>::max(),

View File

@@ -280,7 +280,7 @@ public:
}
size_t bpr = bpp * stride;
size_t bprAligned = (bpr + (alignment - 1)) & -alignment;
size_t bprAligned = (bpr + (alignment - 1)) & (~alignment + 1);
return bprAligned * height;
}

View File

@@ -37,6 +37,10 @@ public:
uintptr_t image = 0;
};
struct DriverConfig {
size_t handleArenaSize = 0; // size of handle arena in bytes. Setting to 0 indicates default value is to be used. Driver clamps to valid values.
};
virtual ~Platform() noexcept;
/**
@@ -53,10 +57,12 @@ public:
* @param sharedContext an optional shared context. This is not meaningful with all graphic
* APIs and platforms.
* For EGL platforms, this is an EGLContext.
*
* @param driverConfig specifies driver initialization parameters
*
* @return nullptr on failure, or a pointer to the newly created driver.
*/
virtual backend::Driver* createDriver(void* sharedContext) noexcept = 0;
virtual backend::Driver* createDriver(void* sharedContext, const DriverConfig& driverConfig) noexcept = 0;
/**
* Processes the platform's event queue when called from its primary event-handling thread.

View File

@@ -27,39 +27,40 @@
#include <backend/DriverEnums.h>
#include <array>
#include <variant>
namespace filament::backend {
class Program {
public:
static constexpr size_t SHADER_TYPE_COUNT = 2;
static constexpr size_t BINDING_COUNT = CONFIG_BINDING_COUNT;
enum class Shader : uint8_t {
VERTEX = 0,
FRAGMENT = 1
};
static constexpr size_t SHADER_TYPE_COUNT = 3;
static constexpr size_t UNIFORM_BINDING_COUNT = CONFIG_UNIFORM_BINDING_COUNT;
static constexpr size_t SAMPLER_BINDING_COUNT = CONFIG_SAMPLER_BINDING_COUNT;
struct Sampler {
utils::CString name = {}; // name of the sampler in the shader
uint16_t binding = 0; // binding point of the sampler in the shader
bool strict = false; // if true, this sampler must always have a bound texture
uint32_t binding = 0; // binding point of the sampler in the shader
};
struct SamplerGroupData {
utils::FixedCapacityVector<Sampler> samplers;
ShaderStageFlags stageFlags = ALL_SHADER_STAGE_FLAGS;
ShaderStageFlags stageFlags = ShaderStageFlags::ALL_SHADER_STAGE_FLAGS;
};
using SamplerGroupInfo = std::array<SamplerGroupData, BINDING_COUNT>;
using UniformBlockInfo = std::array<utils::CString, BINDING_COUNT>;
using UniformBlockInfo = std::array<utils::CString, UNIFORM_BINDING_COUNT>;
using SamplerGroupInfo = std::array<SamplerGroupData, SAMPLER_BINDING_COUNT>;
using ShaderBlob = utils::FixedCapacityVector<uint8_t>;
using ShaderSource = std::array<ShaderBlob, SHADER_TYPE_COUNT>;
Program() noexcept;
Program(const Program& rhs) = delete;
Program& operator=(const Program& rhs) = delete;
Program(Program&& rhs) noexcept;
Program& operator=(Program&& rhs) noexcept;
~Program() noexcept;
// sets the material name and variant for diagnostic purposes only
@@ -69,15 +70,13 @@ public:
// sets one of the program's shader (e.g. vertex, fragment)
// string-based shaders are null terminated, consequently the size parameter must include the
// null terminating character.
Program& shader(Shader shader, void const* data, size_t size) noexcept;
Program& shader(ShaderStage shader, void const* data, size_t size);
// sets the 'bindingPoint' uniform block's name for this program.
//
// Note: This is only needed for GLES3.0 backends, because the layout(binding=) syntax is
// not permitted in glsl. The backend needs a way to associate a uniform block
// to a binding point.
//
Program& setUniformBlock(size_t bindingPoint, utils::CString uniformBlockName) noexcept;
Program& uniformBlockBindings(
utils::FixedCapacityVector<std::pair<utils::CString, uint8_t>> const& uniformBlockBindings) noexcept;
// sets the 'bindingPoint' sampler group descriptor for this program.
// 'samplers' can be destroyed after this call.
@@ -86,32 +85,33 @@ public:
Program& setSamplerGroup(size_t bindingPoint, ShaderStageFlags stageFlags,
Sampler const* samplers, size_t count) noexcept;
// string-based shaders are null terminated, consequently the size parameter must include the
// null terminating character.
Program& withVertexShader(void const* data, size_t size) {
return shader(Shader::VERTEX, data, size);
}
struct SpecializationConstant {
uint32_t id; // id set in glsl
std::variant<int32_t, float, bool> value; // value and type
};
Program& specializationConstants(
utils::FixedCapacityVector<SpecializationConstant> specConstants) noexcept;
// string-based shaders are null terminated, consequently the size parameter must include the
// null terminating character.
Program& withFragmentShader(void const* data, size_t size) {
return shader(Shader::FRAGMENT, data, size);
}
using ShaderBlob = utils::FixedCapacityVector<uint8_t>;
using ShaderSource = std::array<ShaderBlob, SHADER_TYPE_COUNT>;
ShaderSource const& getShadersSource() const noexcept { return mShadersSource; }
ShaderSource& getShadersSource() noexcept { return mShadersSource; }
UniformBlockInfo const& getUniformBlockInfo() const noexcept { return mUniformBlocks; }
UniformBlockInfo& getUniformBlockInfo() noexcept { return mUniformBlocks; }
UniformBlockInfo const& getUniformBlockBindings() const noexcept { return mUniformBlocks; }
UniformBlockInfo& getUniformBlockBindings() noexcept { return mUniformBlocks; }
SamplerGroupInfo const& getSamplerGroupInfo() const { return mSamplerGroups; }
SamplerGroupInfo& getSamplerGroupInfo() { return mSamplerGroups; }
const utils::CString& getName() const noexcept { return mName; }
utils::CString const& getName() const noexcept { return mName; }
utils::CString& getName() noexcept { return mName; }
bool hasSamplers() const noexcept { return mHasSamplers; }
utils::FixedCapacityVector<SpecializationConstant> const& getSpecializationConstants() const noexcept {
return mSpecializationConstants;
}
utils::FixedCapacityVector<SpecializationConstant>& getSpecializationConstants() noexcept {
return mSpecializationConstants;
}
private:
friend utils::io::ostream& operator<<(utils::io::ostream& out, const Program& builder);
@@ -119,9 +119,9 @@ private:
UniformBlockInfo mUniformBlocks = {};
SamplerGroupInfo mSamplerGroups = {};
ShaderSource mShadersSource;
bool mHasSamplers = false;
utils::CString mName;
utils::Invocable<utils::io::ostream&(utils::io::ostream& out)> mLogger;
utils::FixedCapacityVector<SpecializationConstant> mSpecializationConstants;
};
} // namespace filament::backend

View File

@@ -1,5 +1,5 @@
/*
* Copyright (C) 2017 The Android Open Source Project
* Copyright (C) 2022 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.
@@ -14,14 +14,26 @@
* limitations under the License.
*/
#include "PlatformDummyGL.h"
//! \file
#ifndef TNT_FILAMENT_BACKEND_SAMPLERDESCRIPTOR_H
#define TNT_FILAMENT_BACKEND_SAMPLERDESCRIPTOR_H
#include <backend/DriverEnums.h>
#include <backend/Handle.h>
#include <utils/compiler.h>
#include <stddef.h>
#include <stdint.h>
namespace filament::backend {
Driver* PlatformDummyGL::createDriver(void* const sharedGLContext) noexcept {
return nullptr;
}
struct UTILS_PUBLIC SamplerDescriptor {
Handle<HwTexture> t;
SamplerParams s{};
};
} // namespace filament::backend
// ---------------------------------------------------------------------------------------------
#endif // TNT_FILAMENT_BACKEND_SAMPLERDESCRIPTOR_H

View File

@@ -21,19 +21,16 @@
#include <backend/PixelBufferDescriptor.h>
#include <string_view>
#include <stddef.h>
#ifndef FILAMENT_MIN_COMMAND_BUFFERS_SIZE_IN_MB
# define FILAMENT_MIN_COMMAND_BUFFERS_SIZE_IN_MB 1
#endif
namespace filament {
namespace backend {
namespace filament::backend {
/**
* Returns true if the shader string requests the Google-style line directive extension.
*/
bool requestsGoogleLineDirectivesExtension(const char* shader, size_t length) noexcept;
bool requestsGoogleLineDirectivesExtension(std::string_view source) noexcept;
/**
* Edit a GLSL shader string in-place so any Google-style line directives are turned into regular
@@ -52,6 +49,11 @@ void removeGoogleLineDirectives(char* shader, size_t length) noexcept;
*/
size_t getFormatSize(TextureFormat format) noexcept;
/**
* Returns the number of component (1 to 4) for the given format.
*/
size_t getFormatComponentCount(TextureFormat format) noexcept;
/**
* For compressed texture formats, returns the number of horizontal texels per block. Otherwise
* returns 0.
@@ -69,7 +71,6 @@ size_t getBlockHeight(TextureFormat format) noexcept;
*/
bool reshape(const PixelBufferDescriptor& data, PixelBufferDescriptor& reshaped);
} // namespace backend
} // namespace filament
#endif // TNT_FILAMENT_BACKEND_PRIVATE_BACKENDUTILS_H

View File

@@ -17,13 +17,12 @@
#ifndef TNT_FILAMENT_BACKEND_PRIVATE_CIRCULARBUFFER_H
#define TNT_FILAMENT_BACKEND_PRIVATE_CIRCULARBUFFER_H
#include <utils/compiler.h>
#include <stddef.h>
#include <stdint.h>
#include <utils/compiler.h>
namespace filament {
namespace backend {
namespace filament::backend {
class CircularBuffer {
public:
@@ -85,7 +84,6 @@ private:
void* mHead = nullptr;
};
} // namespace backend
} // namespace filament
} // namespace filament::backend
#endif // TNT_FILAMENT_BACKEND_PRIVATE_CIRCULARBUFFER_H

View File

@@ -19,14 +19,13 @@
#include "private/backend/CircularBuffer.h"
#include "private/backend/Dispatcher.h"
#include "private/backend/Program.h"
#include "private/backend/SamplerGroup.h"
#include "private/backend/Driver.h"
#include <backend/BufferDescriptor.h>
#include <backend/DriverEnums.h>
#include <backend/Handle.h>
#include <backend/PipelineState.h>
#include <backend/Program.h>
#include <backend/PixelBufferDescriptor.h>
#include <backend/PresentCallable.h>
#include <backend/TargetBufferInfo.h>
@@ -37,9 +36,12 @@
#include <cstddef>
#include <functional>
#include <tuple>
#include <thread>
#include <utility>
#ifndef NDEBUG
#include <thread>
#endif
#include <assert.h>
#include <stddef.h>
#include <stdint.h>

View File

@@ -17,13 +17,12 @@
#ifndef TNT_FILAMENT_BACKEND_PRIVATE_DRIVER_H
#define TNT_FILAMENT_BACKEND_PRIVATE_DRIVER_H
#include <backend/DriverApiForward.h>
#include <backend/DriverEnums.h>
#include <backend/Handle.h>
#include <backend/PipelineState.h>
#include <backend/TargetBufferInfo.h>
#include "private/backend/DriverApiForward.h"
#include <utils/compiler.h>
#include <functional>
@@ -48,7 +47,6 @@ class BufferDescriptor;
class CallbackHandler;
class PixelBufferDescriptor;
class Program;
class SamplerGroup;
template<typename T>
class ConcreteDispatcher;

View File

@@ -158,6 +158,9 @@ DECL_DRIVER_API_0(flush)
// flush and wait for the effects to be done
DECL_DRIVER_API_0(finish)
// reset state tracking, if the driver does any state tracking (e.g. GL)
DECL_DRIVER_API_0(resetState)
/*
* Creating driver objects
* -----------------------
@@ -304,6 +307,7 @@ DECL_DRIVER_API_SYNCHRONOUS_N(void, cancelExternalImage, void*, image)
DECL_DRIVER_API_SYNCHRONOUS_N(bool, getTimerQueryValue, backend::TimerQueryHandle, query, uint64_t*, elapsedTime)
DECL_DRIVER_API_SYNCHRONOUS_N(backend::SyncStatus, getSyncStatus, backend::SyncHandle, sh)
DECL_DRIVER_API_SYNCHRONOUS_N(bool, isWorkaroundNeeded, backend::Workaround, workaround)
DECL_DRIVER_API_SYNCHRONOUS_0(backend::FeatureLevel, getFeatureLevel)
/*
* Updating driver objects
@@ -335,16 +339,7 @@ DECL_DRIVER_API_N(resetBufferObject,
DECL_DRIVER_API_N(updateSamplerGroup,
backend::SamplerGroupHandle, ubh,
backend::SamplerGroup&&, samplerGroup)
DECL_DRIVER_API_N(update2DImage,
backend::TextureHandle, th,
uint32_t, level,
uint32_t, xoffset,
uint32_t, yoffset,
uint32_t, width,
uint32_t, height,
backend::PixelBufferDescriptor&&, data)
backend::BufferDescriptor&&, data)
DECL_DRIVER_API_N(setMinMaxLevels,
backend::TextureHandle, th,
@@ -362,12 +357,6 @@ DECL_DRIVER_API_N(update3DImage,
uint32_t, depth,
backend::PixelBufferDescriptor&&, data)
DECL_DRIVER_API_N(updateCubeImage,
backend::TextureHandle, th,
uint32_t, level,
backend::PixelBufferDescriptor&&, data,
backend::FaceOffsets, faceOffsets)
DECL_DRIVER_API_N(generateMipmaps,
backend::TextureHandle, th)
@@ -420,12 +409,17 @@ DECL_DRIVER_API_N(bindUniformBuffer,
uint32_t, index,
backend::BufferObjectHandle, ubh)
DECL_DRIVER_API_N(bindUniformBufferRange,
DECL_DRIVER_API_N(bindBufferRange,
BufferObjectBinding, bindingType,
uint32_t, index,
backend::BufferObjectHandle, ubh,
uint32_t, offset,
uint32_t, size)
DECL_DRIVER_API_N(unbindBuffer,
BufferObjectBinding, bindingType,
uint32_t, index)
DECL_DRIVER_API_N(bindSamplers,
uint32_t, index,
backend::SamplerGroupHandle, sbh)
@@ -458,6 +452,12 @@ DECL_DRIVER_API_N(readPixels,
uint32_t, height,
backend::PixelBufferDescriptor&&, data)
DECL_DRIVER_API_N(readBufferSubData,
backend::BufferObjectHandle, src,
uint32_t, offset,
uint32_t, size,
backend::BufferDescriptor&&, data)
/*
* Rendering operations
* --------------------
@@ -476,6 +476,11 @@ DECL_DRIVER_API_N(draw,
backend::RenderPrimitiveHandle, rph,
uint32_t, instanceCount)
DECL_DRIVER_API_N(dispatchCompute,
backend::ProgramHandle, program,
math::uint3, workGroupCount)
#pragma clang diagnostic pop
#undef EXPAND

View File

@@ -17,7 +17,7 @@
#ifndef TNT_FILAMENT_BACKEND_PRIVATE_DRIVERAPI_H
#define TNT_FILAMENT_BACKEND_PRIVATE_DRIVERAPI_H
#include "private/backend/DriverApiForward.h"
#include "backend/DriverApiForward.h"
#include "private/backend/CommandStream.h"
#endif // TNT_FILAMENT_BACKEND_PRIVATE_DRIVERAPI_H

View File

@@ -29,7 +29,7 @@ class MetalPlatform : public DefaultPlatform {
public:
~MetalPlatform() override;
Driver* createDriver(void* sharedContext) noexcept override;
Driver* createDriver(void* sharedContext, const Platform::DriverConfig& driverConfig) noexcept override;
int getOSVersion() const noexcept override { return 0; }
/**

View File

@@ -33,7 +33,7 @@ protected:
* Derived classes can use this to instantiate the default OpenGLDriver backend.
* This is typically called from your implementation of createDriver()
*/
static Driver* createDefaultDriver(OpenGLPlatform* platform, void* sharedContext);
static Driver* createDefaultDriver(OpenGLPlatform* platform, void* sharedContext, const DriverConfig& driverConfig);
public:
~OpenGLPlatform() noexcept override;

View File

@@ -17,139 +17,77 @@
#ifndef TNT_FILAMENT_BACKEND_PRIVATE_SAMPLERGROUP_H
#define TNT_FILAMENT_BACKEND_PRIVATE_SAMPLERGROUP_H
#include "backend/DriverApiForward.h"
#include <utils/compiler.h>
#include <utils/bitset.h>
#include <utils/FixedCapacityVector.h>
#include <backend/DriverEnums.h>
#include <backend/Handle.h>
#include <array>
#include <memory>
#include <backend/SamplerDescriptor.h>
#include <stddef.h>
namespace filament::backend {
class BufferDescriptor;
/*
* FIXME: this should eventually be moved into Filament, outside of backend.
* (but it is currently used by metal/vulkan backens)
*/
class SamplerGroup {
public:
using SamplerParams = backend::SamplerParams;
struct Sampler {
Handle<HwTexture> t;
SamplerParams s{};
};
SamplerGroup() noexcept { } // NOLINT
SamplerGroup() noexcept {} // NOLINT
// create a sampler group
explicit SamplerGroup(size_t count) noexcept;
// can be copied -- this preserves dirty bits
// can be copied. Sets dirty flag.
SamplerGroup(const SamplerGroup& rhs) noexcept;
SamplerGroup& operator=(const SamplerGroup& rhs) noexcept;
// and moved -- this cleans rhs's dirty flags
SamplerGroup(SamplerGroup&& rhs) noexcept;
SamplerGroup& operator=(SamplerGroup&& rhs) noexcept;
// copy the rhs samplers into this group and sets the dirty flag
SamplerGroup& setSamplers(SamplerGroup const& rhs) noexcept;
// and moved. Leaves rhs empty, keep diry flag on new SamplerGroup.
SamplerGroup(SamplerGroup&& rhs) noexcept = default;
SamplerGroup& operator=(SamplerGroup&& rhs) = default;
~SamplerGroup() noexcept = default;
// Efficiently move a SamplerGroup to the command stream. Always use std::move() on the
// returned value, as in the future this might return SamplerGroup by value.
SamplerGroup& toCommandStream() const noexcept;
// pointer to the sampler group
Sampler const* getSamplers() const noexcept { return mBuffer.data(); }
BufferDescriptor toBufferDescriptor(DriverApi& driver) const noexcept;
// sampler count
size_t getSize() const noexcept { return mBuffer.size(); }
// return if any samplers has been changed
bool isDirty() const noexcept { return mDirty.any(); }
bool isDirty() const noexcept {
return mDirty;
}
// mark the whole group as clean (no modified uniforms)
void clean() const noexcept { mDirty.reset(); }
void clean() const noexcept { mDirty = false; }
// set sampler at given index
void setSampler(size_t index, Sampler sampler) noexcept;
void setSampler(size_t index, backend::SamplerDescriptor sampler) noexcept;
inline void setSampler(size_t index, Handle<HwTexture> t, SamplerParams s) {
setSampler(index, { t, s });
}
inline void clearSampler(size_t index) {
inline void clearSampler(size_t index) {
setSampler(index, {});
}
// FIXME: This is now [[deprecated]]. Currently it is only used by the Vulkan/Metal backends.
backend::SamplerDescriptor* data() noexcept { return mBuffer.data(); }
private:
#if !defined(NDEBUG)
friend utils::io::ostream& operator<<(utils::io::ostream& out, const SamplerGroup& rhs);
#endif
// This could probably be cleaned-up and moved to libutils
template<class T, size_t N>
class static_vector { //NOLINT
typename std::aligned_storage<sizeof(T), alignof(T)>::type mData[N];
uint32_t mSize = 0;
public:
static_vector() = default; //NOLINT
~static_vector() noexcept {
for (auto& elem : *this) {
elem.~T();
}
}
explicit static_vector(size_t count) noexcept : mSize(count) {
assert_invariant(count < N);
std::uninitialized_fill_n(begin(), count, T{});
}
static_vector(static_vector const& rhs) noexcept : mSize(rhs.mSize) {
std::uninitialized_copy(rhs.begin(), rhs.end(), begin());
}
size_t size() const noexcept { return mSize; }
T* data() noexcept { return reinterpret_cast<T*>(&mData[0]); }
T const* data() const noexcept { return reinterpret_cast<T const*>(&mData[0]); }
static_vector& operator=(static_vector const& rhs) noexcept {
if (this != &rhs) {
const size_t n = std::min(mSize, rhs.mSize);
std::copy_n(rhs.begin(), n, begin());
for (size_t pos = n, c = mSize; pos < c; ++pos) {
data()[pos].~T();
}
std::uninitialized_copy(rhs.begin() + n, rhs.end(), begin() + n);
mSize = rhs.mSize;
}
return *this;
}
const T& operator[](size_t pos) const noexcept {
assert_invariant(pos < mSize);
return data()[pos];
}
T& operator[](size_t pos) noexcept {
assert_invariant(pos < mSize);
return data()[pos];
}
T* begin() { return data(); }
T* end() { return data() + mSize; }
T const* begin() const { return data(); }
T const* end() const { return data() + mSize; }
};
static_vector<Sampler, backend::MAX_SAMPLER_COUNT> mBuffer; // 128 bytes
mutable utils::bitset32 mDirty;
utils::FixedCapacityVector<backend::SamplerDescriptor> mBuffer;
mutable bool mDirty = false;
};
} // namespace filament::backend

View File

@@ -22,12 +22,10 @@
#include <string_view>
namespace filament {
namespace backend {
namespace filament::backend {
bool requestsGoogleLineDirectivesExtension(const char* shader, size_t length) noexcept {
std::string_view s(shader, length);
return s.find("GL_GOOGLE_cpp_style_line_directive") != std::string_view::npos;
bool requestsGoogleLineDirectivesExtension(std::string_view source) noexcept {
return source.find("GL_GOOGLE_cpp_style_line_directive") != std::string_view::npos;
}
void removeGoogleLineDirectives(char* shader, size_t length) noexcept {
@@ -211,6 +209,129 @@ size_t getFormatSize(TextureFormat format) noexcept {
}
}
size_t getFormatComponentCount(TextureFormat format) noexcept {
switch (format) {
case TextureFormat::R8:
case TextureFormat::R8_SNORM:
case TextureFormat::R8UI:
case TextureFormat::R8I:
case TextureFormat::R16F:
case TextureFormat::R16UI:
case TextureFormat::R16I:
case TextureFormat::R32F:
case TextureFormat::R32I:
case TextureFormat::R32UI:
case TextureFormat::STENCIL8:
case TextureFormat::DEPTH16:
case TextureFormat::DEPTH24:
case TextureFormat::DEPTH32F:
return 1;
case TextureFormat::RG8:
case TextureFormat::RG8_SNORM:
case TextureFormat::RG8UI:
case TextureFormat::RG8I:
case TextureFormat::RG16F:
case TextureFormat::RG16UI:
case TextureFormat::RG16I:
case TextureFormat::RG32F:
case TextureFormat::RG32UI:
case TextureFormat::RG32I:
case TextureFormat::DEPTH24_STENCIL8:
case TextureFormat::DEPTH32F_STENCIL8:
return 2;
case TextureFormat::RGB565:
case TextureFormat::RGB8:
case TextureFormat::SRGB8:
case TextureFormat::RGB8_SNORM:
case TextureFormat::RGB8UI:
case TextureFormat::RGB8I:
case TextureFormat::R11F_G11F_B10F:
case TextureFormat::RGB16F:
case TextureFormat::RGB16UI:
case TextureFormat::RGB16I:
case TextureFormat::RGB32F:
case TextureFormat::RGB32UI:
case TextureFormat::RGB32I:
return 3;
case TextureFormat::RGB5_A1:
case TextureFormat::RGBA4:
case TextureFormat::RGB9_E5:
case TextureFormat::RGBA8:
case TextureFormat::SRGB8_A8:
case TextureFormat::RGBA8_SNORM:
case TextureFormat::RGB10_A2:
case TextureFormat::RGBA8UI:
case TextureFormat::RGBA8I:
case TextureFormat::RGBA16F:
case TextureFormat::RGBA16UI:
case TextureFormat::RGBA16I:
case TextureFormat::RGBA32F:
case TextureFormat::RGBA32UI:
case TextureFormat::RGBA32I:
return 4;
// Compressed formats ---------------------------------------------------------------------
case TextureFormat::EAC_R11:
case TextureFormat::EAC_R11_SIGNED:
return 1;
case TextureFormat::EAC_RG11:
case TextureFormat::EAC_RG11_SIGNED:
return 2;
case TextureFormat::ETC2_RGB8:
case TextureFormat::ETC2_SRGB8:
case TextureFormat::DXT1_RGB:
case TextureFormat::DXT1_SRGB:
return 3;
case TextureFormat::ETC2_EAC_RGBA8:
case TextureFormat::ETC2_EAC_SRGBA8:
case TextureFormat::ETC2_RGB8_A1:
case TextureFormat::ETC2_SRGB8_A1:
case TextureFormat::DXT1_RGBA:
case TextureFormat::DXT1_SRGBA:
case TextureFormat::DXT3_RGBA:
case TextureFormat::DXT3_SRGBA:
case TextureFormat::DXT5_RGBA:
case TextureFormat::DXT5_SRGBA:
case TextureFormat::RGBA_ASTC_4x4:
case TextureFormat::RGBA_ASTC_5x4:
case TextureFormat::RGBA_ASTC_5x5:
case TextureFormat::RGBA_ASTC_6x5:
case TextureFormat::RGBA_ASTC_6x6:
case TextureFormat::RGBA_ASTC_8x5:
case TextureFormat::RGBA_ASTC_8x6:
case TextureFormat::RGBA_ASTC_8x8:
case TextureFormat::RGBA_ASTC_10x5:
case TextureFormat::RGBA_ASTC_10x6:
case TextureFormat::RGBA_ASTC_10x8:
case TextureFormat::RGBA_ASTC_10x10:
case TextureFormat::RGBA_ASTC_12x10:
case TextureFormat::RGBA_ASTC_12x12:
case TextureFormat::SRGB8_ALPHA8_ASTC_4x4:
case TextureFormat::SRGB8_ALPHA8_ASTC_5x4:
case TextureFormat::SRGB8_ALPHA8_ASTC_5x5:
case TextureFormat::SRGB8_ALPHA8_ASTC_6x5:
case TextureFormat::SRGB8_ALPHA8_ASTC_6x6:
case TextureFormat::SRGB8_ALPHA8_ASTC_8x5:
case TextureFormat::SRGB8_ALPHA8_ASTC_8x6:
case TextureFormat::SRGB8_ALPHA8_ASTC_8x8:
case TextureFormat::SRGB8_ALPHA8_ASTC_10x5:
case TextureFormat::SRGB8_ALPHA8_ASTC_10x6:
case TextureFormat::SRGB8_ALPHA8_ASTC_10x8:
case TextureFormat::SRGB8_ALPHA8_ASTC_10x10:
case TextureFormat::SRGB8_ALPHA8_ASTC_12x10:
case TextureFormat::SRGB8_ALPHA8_ASTC_12x12:
return 4;
case TextureFormat::UNUSED:
return 0;
}
}
size_t getBlockWidth(TextureFormat format) noexcept {
switch (format) {
case TextureFormat::EAC_RG11:
@@ -380,60 +501,59 @@ bool reshape(const PixelBufferDescriptor& data, PixelBufferDescriptor& reshaped)
}
}
} // namespace backend
} // namespace filament
} // namespace backend::filament
namespace utils {
template<>
CString to_string<filament::backend::TextureUsage>(filament::backend::TextureUsage usage) noexcept {
CString to_string<filament::backend::TextureUsage>(filament::backend::TextureUsage value) noexcept {
using namespace filament::backend;
char string[7] = {'-', '-', '-', '-', '-', '-', 0};
if (any(usage & TextureUsage::UPLOADABLE)) {
if (any(value & TextureUsage::UPLOADABLE)) {
string[0]='U';
}
if (any(usage & TextureUsage::SAMPLEABLE)) {
if (any(value & TextureUsage::SAMPLEABLE)) {
string[1]='S';
}
if (any(usage & TextureUsage::COLOR_ATTACHMENT)) {
if (any(value & TextureUsage::COLOR_ATTACHMENT)) {
string[2]='c';
}
if (any(usage & TextureUsage::DEPTH_ATTACHMENT)) {
if (any(value & TextureUsage::DEPTH_ATTACHMENT)) {
string[3]='d';
}
if (any(usage & TextureUsage::STENCIL_ATTACHMENT)) {
if (any(value & TextureUsage::STENCIL_ATTACHMENT)) {
string[4] = 's';
}
if (any(usage & TextureUsage::SUBPASS_INPUT)) {
if (any(value & TextureUsage::SUBPASS_INPUT)) {
string[5]='f';
}
return CString(string, 6);
return { string, 6 };
}
template<>
CString to_string<filament::backend::TargetBufferFlags>(filament::backend::TargetBufferFlags flags) noexcept {
CString to_string<filament::backend::TargetBufferFlags>(filament::backend::TargetBufferFlags value) noexcept {
using namespace filament::backend;
char string[7] = {'-', '-', '-', '-', '-', '-', 0};
if (any(flags & TargetBufferFlags::COLOR0)) {
if (any(value & TargetBufferFlags::COLOR0)) {
string[0]='0';
}
if (any(flags & TargetBufferFlags::COLOR1)) {
if (any(value & TargetBufferFlags::COLOR1)) {
string[1]='1';
}
if (any(flags & TargetBufferFlags::COLOR2)) {
if (any(value & TargetBufferFlags::COLOR2)) {
string[2]='2';
}
if (any(flags & TargetBufferFlags::COLOR3)) {
if (any(value & TargetBufferFlags::COLOR3)) {
string[3]='3';
}
if (any(flags & TargetBufferFlags::DEPTH)) {
if (any(value & TargetBufferFlags::DEPTH)) {
string[4]='D';
}
if (any(flags & TargetBufferFlags::STENCIL)) {
if (any(value & TargetBufferFlags::STENCIL)) {
string[5]='S';
}
return CString(string, 6);
return { string, 6 };
}
} // namespace utils

View File

@@ -83,9 +83,9 @@ void CommandBufferQueue::flush() noexcept {
// circular buffer is too small, we corrupted the stream
ASSERT_POSTCONDITION(used <= mFreeSpace,
"Backend CommandStream overflow. Commands are corrupted and unrecoverable.\n"
"Please increase FILAMENT_MIN_COMMAND_BUFFERS_SIZE_IN_MB (currently %u MiB).\n"
"Please increase minCommandBufferSizeMB inside the Config passed to Engine::create.\n"
"Space used at this time: %u bytes",
(unsigned)FILAMENT_MIN_COMMAND_BUFFERS_SIZE_IN_MB, (unsigned)used);
(unsigned)used);
// wait until there is enough space in the buffer
mFreeSpace -= used;

View File

@@ -40,12 +40,13 @@ public:
// trailing channels. This is useful for platforms that only accept 4-component data, since
// users often wish to submit (or receive) 3-component data.
template<typename componentType, size_t srcChannelCount, size_t dstChannelCount>
static void reshape(void* dest, const void* src, size_t numSrcBytes) {
static void reshape(void* UTILS_RESTRICT dest, const void* UTILS_RESTRICT src,
size_t numSrcBytes) {
const componentType maxValue = getMaxValue<componentType>();
const componentType* in = (const componentType*) src;
componentType* out = (componentType*) dest;
const size_t width = (numSrcBytes / sizeof(componentType)) / srcChannelCount;
const int minChannelCount = filament::math::min(srcChannelCount, dstChannelCount);
constexpr size_t minChannelCount = math::min(srcChannelCount, dstChannelCount);
for (size_t column = 0; column < width; ++column) {
for (size_t channel = 0; channel < minChannelCount; ++channel) {
out[channel] = in[channel];
@@ -58,26 +59,43 @@ public:
}
}
static void copyImage(uint8_t* UTILS_RESTRICT dest,
const uint8_t* UTILS_RESTRICT src,
size_t srcBytesPerRow, size_t /*srcChannelCount*/,
size_t dstBytesPerRow, size_t /*dstChannelCount*/,
size_t /*width*/, size_t height, bool /*swizzle*/) {
if (srcBytesPerRow == dstBytesPerRow) {
std::memcpy(dest, src, height * srcBytesPerRow);
return;
}
const size_t minBytesPerRow = std::min(srcBytesPerRow, dstBytesPerRow);
for (size_t i = 0; i < height; ++i, src += srcBytesPerRow, dest += dstBytesPerRow) {
std::memcpy(dest, src, minBytesPerRow);
}
}
// Converts a n-channel image of UBYTE, INT, UINT, or FLOAT to a different type.
template<typename dstComponentType, typename srcComponentType>
static void reshapeImage(uint8_t* dest, const uint8_t* src, size_t srcBytesPerRow,
static void reshapeImage(uint8_t* UTILS_RESTRICT dest, const uint8_t* UTILS_RESTRICT src,
size_t srcBytesPerRow,
size_t srcChannelCount, size_t dstBytesPerRow, size_t dstChannelCount,
size_t width, size_t height, bool swizzle) {
const dstComponentType dstMaxValue = getMaxValue<dstComponentType>();
const srcComponentType srcMaxValue = getMaxValue<srcComponentType>();
const size_t minChannelCount = filament::math::min(srcChannelCount, dstChannelCount);
const size_t minChannelCount = math::min(srcChannelCount, dstChannelCount);
assert_invariant(minChannelCount <= 4);
const int inds[4] = {swizzle ? 2 : 0, 1, swizzle ? 0 : 2, 3};
UTILS_ASSUME(minChannelCount <= 4);
const int inds[4] = { swizzle ? 2 : 0, 1, swizzle ? 0 : 2, 3 };
for (size_t row = 0; row < height; ++row) {
const srcComponentType* in = (const srcComponentType*) src;
dstComponentType* out = (dstComponentType*) dest;
const srcComponentType* in = (const srcComponentType*)src;
dstComponentType* out = (dstComponentType*)dest;
for (size_t column = 0; column < width; ++column) {
for (size_t channel = 0; channel < minChannelCount; ++channel) {
if constexpr (std::is_same_v<dstComponentType, srcComponentType>) {
out[channel] = in[inds[channel]];
} else {
// TODO: beware of overflows in the multiply
// TODO: probably not correct for _INTEGER src/dst
// FIXME: beware of overflows in the multiply
// FIXME: probably not correct for _INTEGER src/dst
out[channel] = in[inds[channel]] * dstMaxValue / srcMaxValue;
}
}
@@ -93,9 +111,9 @@ public:
}
// Converts a n-channel image of UBYTE, INT, UINT, or FLOAT to a different type.
static bool reshapeImage(PixelBufferDescriptor* dst, PixelDataType srcType,
uint32_t srcChannelCount, const uint8_t* srcBytes, int srcBytesPerRow, int width,
int height, bool swizzle) {
static bool reshapeImage(PixelBufferDescriptor* UTILS_RESTRICT dst, PixelDataType srcType,
uint32_t srcChannelCount, const uint8_t* UTILS_RESTRICT srcBytes, int srcBytesPerRow,
int width, int height, bool swizzle) {
size_t dstChannelCount;
switch (dst->format) {
case PixelDataFormat::R_INTEGER: dstChannelCount = 1; break;
@@ -116,7 +134,13 @@ public:
switch (dst->type) {
case UBYTE:
switch (srcType) {
case UBYTE: reshaper = reshapeImage<uint8_t, uint8_t>; break;
case UBYTE:
reshaper = reshapeImage<uint8_t, uint8_t>;
if (dst->format == PixelDataFormat::RGBA &&
dstChannelCount == srcChannelCount && !swizzle) {
reshaper = copyImage;
}
break;
case FLOAT: reshaper = reshapeImage<uint8_t, float>; break;
case INT: reshaper = reshapeImage<uint8_t, int32_t>; break;
case UINT: reshaper = reshapeImage<uint8_t, uint32_t>; break;

View File

@@ -28,7 +28,6 @@
#include "private/backend/Dispatcher.h"
#include "private/backend/Driver.h"
#include "private/backend/SamplerGroup.h"
#include <condition_variable>
#include <memory>
@@ -104,10 +103,7 @@ struct HwProgram : public HwBase {
};
struct HwSamplerGroup : public HwBase {
// NOTE: we have to use out-of-line allocation here because the size of a Handle<> is limited
std::unique_ptr<SamplerGroup> sb; // FIXME: this shouldn't depend on filament::SamplerGroup
HwSamplerGroup() noexcept = default;
explicit HwSamplerGroup(size_t size) noexcept : sb(new SamplerGroup(size)) { }
};
struct HwTexture : public HwBase {

View File

@@ -42,7 +42,9 @@
#include "vulkan/PlatformVkCocoa.h"
#endif
#elif defined(__linux__)
#if defined(FILAMENT_SUPPORTS_WAYLAND)
#if defined(FILAMENT_SUPPORTS_GGP)
#include "vulkan/PlatformVkLinuxGGP.h"
#elif defined(FILAMENT_SUPPORTS_WAYLAND)
#if defined (FILAMENT_DRIVER_SUPPORTS_VULKAN)
#include "vulkan/PlatformVkLinuxWayland.h"
#endif
@@ -53,6 +55,10 @@
#if defined (FILAMENT_DRIVER_SUPPORTS_VULKAN)
#include "vulkan/PlatformVkLinuxX11.h"
#endif
#elif defined(FILAMENT_SUPPORTS_EGL_ON_LINUX)
#if defined(FILAMENT_SUPPORTS_OPENGL) && !defined(FILAMENT_USE_EXTERNAL_GLES3) && !defined(FILAMENT_USE_SWIFTSHADER)
#include "opengl/platforms/PlatformEGLHeadless.h"
#endif
#endif
#elif defined(WIN32)
#if defined(FILAMENT_SUPPORTS_OPENGL) && !defined(FILAMENT_USE_EXTERNAL_GLES3) && !defined(FILAMENT_USE_SWIFTSHADER)
@@ -63,10 +69,6 @@
#endif
#elif defined(__EMSCRIPTEN__)
#include "opengl/platforms/PlatformWebGL.h"
#else
#if defined(FILAMENT_SUPPORTS_OPENGL) && !defined(FILAMENT_USE_EXTERNAL_GLES3)
#include "opengl/platforms/PlatformDummyGL.h"
#endif
#endif
#if defined (FILAMENT_SUPPORTS_METAL)
@@ -77,8 +79,7 @@ filament::backend::DefaultPlatform* createDefaultMetalPlatform();
#include "noop/PlatformNoop.h"
namespace filament {
namespace backend {
namespace filament::backend {
// this generates the vtable in this translation unit
Platform::~Platform() noexcept = default;
@@ -121,7 +122,9 @@ DefaultPlatform* DefaultPlatform::create(Backend* backend) noexcept {
#elif defined(IOS)
return new PlatformVkCocoaTouch();
#elif defined(__linux__)
#if defined(FILAMENT_SUPPORTS_WAYLAND)
#if defined(FILAMENT_SUPPORTS_GGP)
return new PlatformVkLinuxGGP();
#elif defined(FILAMENT_SUPPORTS_WAYLAND)
return new PlatformVkLinuxWayland();
#elif defined(FILAMENT_SUPPORTS_X11)
return new PlatformVkLinuxX11();
@@ -147,6 +150,7 @@ DefaultPlatform* DefaultPlatform::create(Backend* backend) noexcept {
assert_invariant(*backend == Backend::OPENGL);
#if defined(FILAMENT_SUPPORTS_OPENGL)
#if defined(FILAMENT_USE_EXTERNAL_GLES3) || defined(FILAMENT_USE_SWIFTSHADER)
// Swiftshader OpenGLES support is deprecated and incomplete
return nullptr;
#elif defined(__ANDROID__)
return new PlatformEGLAndroid();
@@ -157,20 +161,22 @@ DefaultPlatform* DefaultPlatform::create(Backend* backend) noexcept {
#elif defined(__linux__)
#if defined(FILAMENT_SUPPORTS_X11)
return new PlatformGLX();
#elif defined(FILAMENT_SUPPORTS_EGL_ON_LINUX)
return new PlatformEGLHeadless();
#endif
#elif defined(WIN32)
return new PlatformWGL();
#elif defined(__EMSCRIPTEN__)
return new PlatformWebGL();
#else
return new PlatformDummyGL();
return nullptr;
#endif
#else
return nullptr;
#endif
}
// destroys an Platform create by create()
// destroys a Platform created by create()
void DefaultPlatform::destroy(DefaultPlatform** platform) noexcept {
delete *platform;
*platform = nullptr;
@@ -178,5 +184,4 @@ void DefaultPlatform::destroy(DefaultPlatform** platform) noexcept {
DefaultPlatform::~DefaultPlatform() noexcept = default;
} // namespace backend
} // namespace filament
} // namespace filament::backend

View File

@@ -14,34 +14,49 @@
* limitations under the License.
*/
#include "private/backend/Program.h"
using namespace utils;
#include "backend/Program.h"
namespace filament::backend {
// We want these in the .cpp file so they're not inlined (not worth it)
Program::Program() noexcept {} // = default; does not work with msvc because of noexcept
using namespace utils;
// We want these in the .cpp file, so they're not inlined (not worth it)
Program::Program() noexcept { // NOLINT(modernize-use-equals-default)
}
Program::Program(Program&& rhs) noexcept = default;
Program& Program::operator=(Program&& rhs) noexcept = default;
Program& Program::operator=(Program&& rhs) noexcept {
mUniformBlocks.operator=(rhs.mUniformBlocks);
mSamplerGroups.operator=(std::move(rhs.mSamplerGroups));
mShadersSource.operator=(std::move(rhs.mShadersSource));
mName.operator=(std::move(rhs.mName));
mLogger.operator=(std::move(rhs.mLogger));
return *this;
}
Program::~Program() noexcept = default;
Program& Program::diagnostics(utils::CString const& name,
utils::Invocable<io::ostream&(utils::io::ostream&)>&& logger) {
Program& Program::diagnostics(CString const& name,
Invocable<io::ostream&(io::ostream&)>&& logger) {
mName = name;
mLogger = std::move(logger);
return *this;
}
Program& Program::shader(Program::Shader shader, void const* data, size_t size) noexcept {
Program& Program::shader(ShaderStage shader, void const* data, size_t size) {
ShaderBlob blob(size);
std::copy_n((const uint8_t *)data, size, blob.data());
mShadersSource[size_t(shader)] = std::move(blob);
return *this;
}
Program& Program::setUniformBlock(size_t bindingPoint, utils::CString uniformBlockName) noexcept {
mUniformBlocks[bindingPoint] = std::move(uniformBlockName);
Program& Program::uniformBlockBindings(
FixedCapacityVector<std::pair<utils::CString, uint8_t>> const& uniformBlockBindings) noexcept {
for (auto const& item : uniformBlockBindings) {
assert_invariant(item.second < UNIFORM_BINDING_COUNT);
mUniformBlocks[item.second] = item.first;
}
return *this;
}
@@ -53,7 +68,12 @@ Program& Program::setSamplerGroup(size_t bindingPoint, ShaderStageFlags stageFla
samplerList.reserve(count);
samplerList.resize(count);
std::copy_n(samplers, count, samplerList.data());
mHasSamplers = true;
return *this;
}
Program& Program::specializationConstants(
FixedCapacityVector<SpecializationConstant> specConstants) noexcept {
mSpecializationConstants = std::move(specConstants);
return *this;
}
@@ -64,4 +84,5 @@ io::ostream& operator<<(io::ostream& out, const Program& builder) {
return out;
}
} // namespace filament::backend

View File

@@ -16,64 +16,53 @@
#include "private/backend/SamplerGroup.h"
namespace filament {
namespace backend {
#include "private/backend/DriverApi.h"
#include "backend/BufferDescriptor.h"
namespace filament::backend {
// create a sampler buffer
SamplerGroup::SamplerGroup(size_t count) noexcept
: mBuffer(count) {
}
SamplerGroup::SamplerGroup(const SamplerGroup& rhs) noexcept = default;
SamplerGroup::SamplerGroup(SamplerGroup&& rhs) noexcept
: mBuffer(rhs.mBuffer), mDirty(rhs.mDirty) {
rhs.clean();
SamplerGroup::SamplerGroup(const SamplerGroup& rhs) noexcept :
mBuffer(rhs.mBuffer), mDirty(true) {
}
SamplerGroup& SamplerGroup::operator=(const SamplerGroup& rhs) noexcept = default;
SamplerGroup& SamplerGroup::operator=(SamplerGroup&& rhs) noexcept {
SamplerGroup& SamplerGroup::operator=(const SamplerGroup& rhs) noexcept {
if (this != &rhs) {
mBuffer = rhs.mBuffer;
mDirty = rhs.mDirty;
rhs.clean();
mDirty = true;
}
return *this;
}
SamplerGroup& SamplerGroup::toCommandStream() const noexcept {
/*
* This works because our move ctor preserves the data and cleans the dirty flags.
* if we changed the implementation in the future to do a real move, we'd have to change
* this method to return SamplerGroup by value, e.g.:
* SamplerGroup copy(*this);
* this->clean();
* return copy;
*/
return const_cast<SamplerGroup&>(*this);
}
SamplerGroup& SamplerGroup::setSamplers(SamplerGroup const& rhs) noexcept {
if (this != &rhs) {
mBuffer = rhs.mBuffer;
mDirty.setValue((1u << rhs.mBuffer.size()) - 1u);
}
return *this;
}
void SamplerGroup::setSampler(size_t index, Sampler sampler) noexcept {
void SamplerGroup::setSampler(size_t index, SamplerDescriptor sampler) noexcept {
if (UTILS_LIKELY(index < mBuffer.size())) {
// We cannot compare two texture handles to determine if an update is needed. Texture
// handles are (quickly) recycled and therefore can't be used for that purpose. e.g. if a
// texture is destroyed, its handle could be reused quickly by another texture.
// TODO: find a way to avoid marking dirty if the texture does not change.
mBuffer[index] = sampler;
mDirty.set(index);
mDirty = true;
}
}
BufferDescriptor SamplerGroup::toBufferDescriptor(DriverApi& driver) const noexcept {
BufferDescriptor p;
p.size = mBuffer.size() * sizeof(SamplerDescriptor);
p.buffer = driver.allocate(p.size); // TODO: use out-of-line buffer if too large
memcpy(p.buffer, static_cast<const void*>(mBuffer.data()), p.size); // inlined
clean();
return p;
}
#if !defined(NDEBUG)
utils::io::ostream& operator<<(utils::io::ostream& out, const SamplerGroup& rhs) {
return out << "SamplerGroup(data=" << rhs.getSamplers() << ", size=" << rhs.getSize() << ")";
return out << "SamplerGroup(size=" << rhs.getSize() << ")";
}
#endif
} // namespace backend
} // namespace filament
} // namespace filament::backend

View File

@@ -91,12 +91,14 @@ blitterFrag(VertexOut in [[stage_in]],
{
FragmentOut out = {};
#if defined(BLIT_COLOR) || defined(BLIT_DEPTH)
// These coordinates match the Vulkan vkCmdBlitImage spec:
// https://www.khronos.org/registry/vulkan/specs/1.2-extensions/man/html/vkCmdBlitImage.html
float2 uvbase = in.position.xy; // unnormalized coordinates at center of texel: (1.5, 2.5, etc)
float2 uvoffset = uvbase - args->dstOffset;
float2 uvscaled = uvoffset * args->scale;
float2 uv = uvscaled + args->srcOffset;
#endif
#ifdef BLIT_COLOR
#ifdef MSAA_COLOR_SOURCE
@@ -365,7 +367,7 @@ void MetalBlitter::blitDepthPlane(id<MTLCommandBuffer> cmdBuffer, bool blitColor
[encoder setViewport:viewport];
DepthStencilState depthStencilState {
.compareFunction = MTLCompareFunctionAlways,
.depthCompare = MTLCompareFunctionAlways,
.depthWriteEnabled = blitDepth
};
id<MTLDepthStencilState> depthStencil =

View File

@@ -24,13 +24,18 @@
#include <Metal/Metal.h>
namespace filament {
namespace backend {
#include <utils/compiler.h>
#include <utility>
#include <memory>
namespace filament::backend {
class MetalBuffer {
public:
MetalBuffer(MetalContext& context, BufferUsage usage, size_t size, bool forceGpuBuffer = false);
MetalBuffer(MetalContext& context, BufferObjectBinding bindingType, BufferUsage usage,
size_t size, bool forceGpuBuffer = false);
~MetalBuffer();
MetalBuffer(const MetalBuffer& rhs) = delete;
@@ -52,39 +57,153 @@ public:
* @return The MTLBuffer representing the current state of the buffer to bind, or nil if there
* is no device allocation.
*
* For STREAM buffers, getGpuBufferStreamOffset() should be called to retrieve the correct
* buffer offset.
*
*/
id<MTLBuffer> getGpuBufferForDraw(id<MTLCommandBuffer> cmdBuffer) noexcept;
void* getCpuBuffer() const noexcept { return mCpuBuffer; }
enum Stage {
VERTEX = 1,
FRAGMENT = 2
enum Stage : uint8_t {
VERTEX = 1u << 0u,
FRAGMENT = 1u << 1u,
COMPUTE = 1u << 2u
};
/**
* Bind multiple buffers to pipeline stages.
*
* bindBuffers binds an array of buffers to the given stage(s) of a MTLRenderCommandEncoder's
* pipeline.
* bindBuffers binds an array of buffers to the given stage(s) of a MTLCommandEncoders's
* pipeline. The encoder must be either a MTLRenderCommandEncoder or a MTLComputeCommandEncoder.
* For MTLRenderCommandEncoders, only the VERTEX and FRAGMENT stages may be specified.
* For MTLComputeCommandEncoders, only the COMPUTE stage may be specified.
*/
static void bindBuffers(id<MTLCommandBuffer> cmdBuffer, id<MTLRenderCommandEncoder> encoder,
static void bindBuffers(id<MTLCommandBuffer> cmdBuffer, id<MTLCommandEncoder> encoder,
size_t bufferStart, uint8_t stages, MetalBuffer* const* buffers, size_t const* offsets,
size_t count);
private:
BufferUsage mUsage;
id<MTLBuffer> mBuffer = nil;
size_t mBufferSize = 0;
const MetalBufferPoolEntry* mBufferPoolEntry = nullptr;
void* mCpuBuffer = nullptr;
MetalContext& mContext;
};
} // namespace backend
} // namespace filament
template <typename TYPE>
static inline TYPE align(TYPE p, size_t alignment) noexcept {
// alignment must be a power-of-two
assert(alignment && !(alignment & alignment-1));
return (TYPE)((p + alignment - 1) & ~(alignment - 1));
}
/**
* Manages a single id<MTLBuffer>, allowing sub-allocations in a "ring" fashion. Each slot in the
* buffer has a fixed size. When a new allocation is made, previous allocations become available
* when the current id<MTLCommandBuffer> has finished executing on the GPU.
*
* If there are no slots available when a new allocation is requested, MetalRingBuffer falls back to
* allocating a new id<MTLBuffer> per allocation until a slot is freed.
*
* All methods must be called from the Metal backend thread.
*/
class MetalRingBuffer {
public:
// In practice, MetalRingBuffer is used for argument buffers, which are kept in the constant
// address space. Constant buffers have specific alignment requirements when specifying an
// offset.
#if defined(IOS)
#if TARGET_OS_SIMULATOR
// The iOS simulator has differing alignment requirements.
static constexpr auto METAL_CONSTANT_BUFFER_OFFSET_ALIGNMENT = 256;
#else
static constexpr auto METAL_CONSTANT_BUFFER_OFFSET_ALIGNMENT = 4;
#endif // TARGET_OS_SIMULATOR
#else
static constexpr auto METAL_CONSTANT_BUFFER_OFFSET_ALIGNMENT = 32;
#endif
static inline auto computeSlotSize(MTLSizeAndAlign layout) {
return align(align(layout.size, layout.align), METAL_CONSTANT_BUFFER_OFFSET_ALIGNMENT);
}
MetalRingBuffer(id<MTLDevice> device, MTLResourceOptions options, MTLSizeAndAlign layout,
NSUInteger slotCount)
: mDevice(device),
mAuxBuffer(nil),
mBufferOptions(options),
mSlotSizeBytes(computeSlotSize(layout)),
mSlotCount(slotCount) {
mBuffer = [device newBufferWithLength:mSlotSizeBytes * mSlotCount options:mBufferOptions];
assert_invariant(mBuffer);
}
/**
* Create a new allocation in the buffer.
* @param cmdBuffer When this command buffer has finished executing on the GPU, the previous
* ring buffer allocation will be freed.
* @return the id<MTLBuffer> and offset for the new allocation
*/
std::pair<id<MTLBuffer>, NSUInteger> createNewAllocation(id<MTLCommandBuffer> cmdBuffer) {
const auto occupiedSlots = mOccupiedSlots->load(std::memory_order_relaxed);
assert_invariant(occupiedSlots <= mSlotCount);
if (UTILS_UNLIKELY(occupiedSlots == mSlotCount)) {
// We don't have any room left, so we fall back to creating a one-off aux buffer.
// If we already have an aux buffer, it will get freed here, unless it has been retained
// by a MTLCommandBuffer. In that case, it will be freed when the command buffer
// finishes executing.
mAuxBuffer = [mDevice newBufferWithLength:mSlotSizeBytes options:mBufferOptions];
assert_invariant(mAuxBuffer);
return {mAuxBuffer, 0};
}
mCurrentSlot = (mCurrentSlot + 1) % mSlotCount;
mOccupiedSlots->fetch_add(1, std::memory_order_relaxed);
// Release the previous allocation.
if (UTILS_UNLIKELY(mAuxBuffer)) {
mAuxBuffer = nil;
} else {
// Capture the mOccupiedSlots var via a weak_ptr because the MetalRingBuffer could be
// destructed before the block executes.
std::weak_ptr<AtomicCounterType> slots = mOccupiedSlots;
[cmdBuffer addCompletedHandler:^(id<MTLCommandBuffer> buffer) {
if (auto s = slots.lock()) {
s->fetch_sub(1, std::memory_order_relaxed);
}
}];
}
return getCurrentAllocation();
}
/**
* Returns an allocation (buffer and offset) that is guaranteed not to be in use by the GPU.
* @param cmdBuffer When this command buffer has finished executing on the GPU, the previous
* ring buffer allocation will be freed.
* @return the id<MTLBuffer> and offset for the current allocation
*/
std::pair<id<MTLBuffer>, NSUInteger> getCurrentAllocation() const {
if (UTILS_UNLIKELY(mAuxBuffer)) {
return { mAuxBuffer, 0 };
}
return { mBuffer, mCurrentSlot * mSlotSizeBytes };
}
bool canAccomodateLayout(MTLSizeAndAlign layout) const {
return mSlotSizeBytes >= computeSlotSize(layout);
}
private:
id<MTLDevice> mDevice;
id<MTLBuffer> mBuffer;
id<MTLBuffer> mAuxBuffer;
MTLResourceOptions mBufferOptions;
NSUInteger mSlotSizeBytes;
NSUInteger mSlotCount;
NSUInteger mCurrentSlot = 0;
using AtomicCounterType = std::atomic<NSUInteger>;
std::shared_ptr<AtomicCounterType> mOccupiedSlots = std::make_shared<AtomicCounterType>(1);
};
} // namespace filament::backend
#endif

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