Compare commits

..
Author SHA1 Message Date
Benjamin Doherty f172cac8f2 Fix web morphing sample 2023-03-15 13:02:50 -07:00
Benjamin Doherty 2a579c460f Merge branch 'rc/1.32.0' into release 2023-03-14 10:46:27 -07:00
Ben Doherty efdc801cff Vulkan: fix stack use-after-free (#6639) 2023-03-14 10:24:18 -07:00
Benjamin Doherty dd654c575a Bump MATERIAL_VERSION to 32 2023-03-13 14:04:13 -07:00
Benjamin Doherty 0c2599b6ca Bump version to 1.32.0 2023-03-09 10:40:39 -08:00
Benjamin Doherty 979d6742e0 Merge branch 'rc/1.31.7' into release 2023-03-09 10:39:41 -08:00
Mathias Agopian 4a7a033d04 Fix timer query breakage on webgl 2023-03-08 12:33:11 -08:00
Ben Doherty 5c2bbcb4a1 Remove compute shader assertion in GLProgram 2023-03-08 10:56:24 -08:00
Benjamin Doherty dec903a0ee Bump version to 1.31.7 2023-03-01 11:26:50 -08:00
Benjamin Doherty e9475b322b Merge branch 'rc/1.31.6' into release 2023-03-01 11:24:13 -08:00
Benjamin Doherty d9aead8aac Linux CI: use clang 14 2023-02-21 16:06:48 -08:00
Powei Feng ce148ebeb1 Update linux clang to version 10 (#6556) 2023-02-21 16:00:07 -08:00
Powei Feng e1315fbaa7 Update CI Ubuntu version 2023-02-21 15:57:00 -08:00
Benjamin Doherty 1690549392 Bump version to 1.31.6 2023-02-21 13:18:22 -08:00
Benjamin Doherty c73710e343 Merge branch 'rc/1.31.5' into release 2023-02-21 13:16:47 -08:00
Benjamin Doherty 092a0489da Bump version to 1.31.5 2023-02-13 11:53:24 -08:00
Benjamin Doherty 1c6279366f Merge branch 'rc/1.31.4' into release 2023-02-13 11:51:37 -08:00
Benjamin Doherty 2ac85049a9 Bump version to 1.31.4 2023-02-01 11:55:09 -08:00
Benjamin Doherty ea428a27d1 Merge branch 'rc/1.31.3' into release 2023-02-01 11:54:04 -08:00
Benjamin Doherty 3bef718238 Bump version to 1.31.3 2023-01-24 14:28:21 -08:00
Benjamin Doherty e9daaa0503 Merge branch 'rc/1.31.2' into release 2023-01-24 14:27:02 -08:00
Benjamin Doherty 6d3ea21993 Bump version to 1.31.2 2023-01-18 14:25:45 -08:00
Benjamin Doherty f39127605d Merge branch 'rc/1.31.1' into release 2023-01-18 14:23:59 -08:00
Ben Doherty db476f00f7 Vulkan: fix stack-use-after-scope ASAN error in VulkanContext.cpp (#6463) 2023-01-18 11:59:10 -08:00
Powei Feng e54d8ec0a4 [vulkan] enumerate: Returning size = 0 is ok (#6450) 2023-01-17 10:14:45 -08:00
Benjamin Doherty b95ac854b4 Bump version to 1.31.1 2023-01-10 12:52:49 -05:00
Benjamin Doherty 96443f6dac Merge branch 'rc/1.31.0' into release 2023-01-10 12:50:52 -05:00
Benjamin Doherty e5e3dff9fa Fix Windows CI build 2022-12-20 11:01:49 -07:00
Benjamin Doherty 31d9da38fd Fix CI build 2022-12-20 09:40:07 -07:00
Benjamin Doherty c5a59bb6b1 Bump version to 1.31.0 2022-12-19 11:14:41 -08:00
Benjamin Doherty e6854148d7 Merge branch 'rc/1.30.0' into release 2022-12-19 11:12:54 -08:00
Ben Doherty 001daf0350 Fix memory leak in Scene (#6387) 2022-12-16 14:38:38 -08:00
Mathias Agopian d26c48110d Fix Android continuous and presubmit builds
Since cmake 3.25 LINUX is automatically set based on CMAKE_SYSTEM_NAME, 
which the android cmake files are setting to "Linux". This created an
inconsistant state in our build system.
2022-12-15 11:54:33 -08:00
Mathias Agopian 15a070f0c9 Fix unused variables in release builds 2022-12-12 11:17:42 -08:00
Mathias Agopian 93230b06cf Fix Android continuous and presubmit builds
Since cmake 3.25 LINUX is automatically set based on CMAKE_SYSTEM_NAME, 
which the android cmake files are setting to "Linux". This created an
inconsistant state in our build system.
2022-12-12 10:44:49 -08:00
Mathias Agopian 4c55fc3c48 fix TransformManager high precision mode
The residual would be corrupted when using transactions.
2022-12-12 10:06:18 -08:00
Mathias Agopian a4797a631e Fix a WebGL program link failure
WebGL complained about:

Precisions of uniform block 'ShadowUniforms' member
'ShadowUniforms.shadows.texelSizeAtOneMeter' differ between VERTEX and
FRAGMENT shaders.


this field didn't have a precision qualifier, this might be specific to
WebGL or a Chrome bug, unsure. Either we fix it by specifying all
qualifiers.
2022-11-29 23:32:21 -08:00
Mathias Agopian 5868e857aa Fix a WebGL program link failure
WebGL complained about:

Precisions of uniform block 'ShadowUniforms' member 
'ShadowUniforms.shadows.texelSizeAtOneMeter' differ between VERTEX and 
FRAGMENT shaders.


this field didn't have a precision qualifier, this might be specific to
WebGL or a Chrome bug, unsure. Either we fix it by specifying all
qualifiers.
2022-11-29 23:31:03 -08:00
Benjamin Doherty 32ba063bd7 Fix CI build 2022-11-21 16:58:37 -08:00
Benjamin Doherty 02f0839f9b Bump version to 1.30.0 2022-11-21 15:45:27 -08:00
Benjamin Doherty e50f3c4c91 Merge branch 'rc/1.29.0' into release 2022-11-21 15:44:36 -08:00
Ben Doherty 7ca15bfc16 Use GitHub script for release asset upload (#6308) 2022-11-21 15:39:55 -08:00
Benjamin Doherty b7b7afb62a Bump version to 1.29.0 2022-11-09 16:43:08 -08:00
Benjamin Doherty b8ff6a9ad9 Merge branch 'rc/1.28.3' into release 2022-11-09 16:38:02 -08:00
Ben Doherty a1dcb4f259 Skip rendering renderables with missing geometry (#6281) 2022-11-09 16:35:31 -08:00
Benjamin Doherty c3501393fd Fix RELEASE_NOTES 2022-11-09 16:34:42 -08:00
Benjamin Doherty a03de75a4e Update Python requirements.txt to fix CI 2022-11-04 11:35:21 -07:00
Benjamin Doherty 0c3d59aba3 Update Python requirements.txt to fix CI 2022-11-03 16:15:29 -07:00
Benjamin Doherty ce1987f291 Fix iOS build 2022-11-01 15:10:57 -04:00
Benjamin Doherty 7eae926ed7 Bump version to 1.28.3 2022-11-01 13:03:19 -04:00
Benjamin Doherty 606af52eda Merge branch 'rc/1.28.2' into release 2022-11-01 13:02:05 -04:00
Benjamin Doherty 8ea30aea80 Update RELEASE_NOTES for 1.28.2 2022-11-01 13:00:04 -04:00
Ben Doherty 72dea695ba Fix G3 reported ubsan warning (#6257) 2022-11-01 12:52:10 -04:00
daemyung jang 1c0cf56ed0 Fix glTF breaking issue (#6239) 2022-10-28 13:08:50 -04:00
Benjamin Doherty bcb4eb35cd Bump version to 1.28.2 2022-10-25 13:09:21 -04:00
Benjamin Doherty bce2676335 Merge branch 'rc/1.28.1' into release 2022-10-25 13:08:12 -04:00
Benjamin Doherty 510097d722 Force spirv-cross to keep Metal argument buffer equal sized 2022-10-25 12:10:54 -04:00
Ben Doherty 5784118a12 Fix, don't use encoder.device (#6212) 2022-10-20 13:08:04 -04:00
Ben Doherty b5de0f2d23 Metal: fix simulator regression due to arg buffers (#6181) 2022-10-18 16:29:18 -04:00
Ben Doherty 04df3f4dad Metal: fix use-after-free ASAN error (#6203) 2022-10-18 16:29:12 -04:00
Benjamin Doherty 093ca4d623 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 16:28:58 -04:00
Mathias Agopian a3ed1558d3 fix a directional light shadowing issue
the shadow frustum could be be smaller than expected.
2022-10-14 15:42:03 -07:00
Benjamin Doherty fe379070ae Bump version to 1.28.1 2022-10-13 12:38:40 -04:00
Benjamin Doherty ead0a2f597 Merge branch 'rc/1.28.0' into release 2022-10-13 12:37:07 -04:00
Benjamin Doherty 5dbc593f90 Fix assertion in ShadowMap due to vertexCount 2022-10-12 18:16:53 -04:00
Ben Doherty d47dc12bf0 G3 fixes for 1.28.0 (#6174) 2022-10-12 14:48:37 -04:00
Philip Rideout 4392f63e57 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-12 14:48:25 -04:00
Ben Doherty f64b7aca79 Fix Metal argument buffer encoding (#6150) 2022-10-10 10:07:41 -07:00
Ben Doherty 3762ec5750 Fix Android release build (#6133) 2022-09-30 11:48:13 -07:00
Ben Doherty 4591fdd9c0 Fix Android release build (#6133) 2022-09-30 11:47:41 -07:00
Benjamin Doherty d3068d2a0e Bump version to 1.28.0 2022-09-29 13:13:18 -07:00
Benjamin Doherty ca0a4bc23a Merge branch 'rc/1.27.2' into release 2022-09-29 13:12:20 -07:00
Ben Doherty 433c163c61 Fixes for 1.27.2 release (#6125) 2022-09-29 13:08:39 -07:00
Mathias Agopian c867fda883 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-29 12:36:28 -07:00
Ben Doherty 566540ae6d Fix generic/Mutex.h not installed on Linux (#6117) 2022-09-28 16:49:03 -07:00
Benjamin Doherty 759f490dae Bump version to 1.27.2 2022-09-20 11:06:02 -07:00
Benjamin Doherty 867d4d44f5 Merge branch 'rc/1.27.1' into release 2022-09-20 11:04:58 -07:00
Ben Doherty 65747d5877 Update glslang to c0cf8ad87 (master) (#6076) 2022-09-19 12:38:05 -07:00
Benjamin Doherty bd357f6076 Bump version to 1.27.1 2022-09-13 10:15:12 -07:00
Benjamin Doherty 9e960b7d45 Merge branch 'rc/1.27.0' into release 2022-09-13 10:14:24 -07:00
Ben Doherty 0c54d4a6a1 Add return case to fix G3 compiler error (#6062) 2022-09-12 12:34:56 -07:00
Philip Rideout 526e846a81 gltfio: fix crash when material is unspecified 2022-09-06 22:13:19 -04:00
Philip Rideout 8bcfa373d4 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-06 22:09:25 -04:00
Ben Doherty db9a0f2c1f Fix uberarchive not included in PodSpec (#6024) 2022-09-01 12:18:20 -04:00
Benjamin Doherty 646b1e2193 Bump version to 1.27.0 2022-08-31 12:04:55 -04:00
Benjamin Doherty 41bd30f81d Merge branch 'rc/1.26.0' into release 2022-08-31 12:04:08 -04:00
Mathias Agopian bd626aea27 material instanced property must be false by default.
this fix auto-instancing.
2022-08-26 18:28:56 -04:00
Benjamin Doherty 8a03f75485 Bump version to 1.26.0 2022-08-23 12:07:33 -04:00
Benjamin Doherty dc9594fbdf Merge branch 'rc/1.25.6' into release 2022-08-23 12:05:44 -04:00
Benjamin Doherty fad0b533c0 Update RELEASE_NOTES for 1.25.6 2022-08-23 12:03:28 -04:00
Benjamin Doherty 4d773e9453 Bump version to 1.25.6 2022-08-16 11:03:07 -07:00
Benjamin Doherty e0c610b013 Merge branch 'rc/1.25.5' into release 2022-08-16 11:01:04 -07:00
Benjamin Doherty 0da4f36c33 Bump version to 1.25.5 2022-08-16 10:54:00 -07:00
Ben Doherty 11d17e1db3 Fix SamplerGroup update issue (#5928) 2022-08-16 10:47:18 -07:00
Philip Rideout b8c318d923 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:28 -07:00
Philip Rideout e563cc6f5e gltfio: add 'detach' methods to allow ownership transfer
These new methods allow gltfio to be integrated into internal Google
libraries.
2022-08-09 14:37:44 -07:00
Benjamin Doherty cb8914ab96 Merge branch 'rc/1.25.4' into release 2022-08-02 11:47:52 -07:00
Alan Eneev 2fecda7bdc Headless EGL: Fallback to a 24-bit depth buffer 2022-07-29 10:10:46 -07:00
Alan Eneev 543d8efb25 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 10:10:40 -07:00
Benjamin Doherty 396b1079a7 Bump version to 1.25.4 2022-07-26 09:57:34 -07:00
Benjamin Doherty eedcd9f8cb Merge branch 'rc/1.25.3' into release 2022-07-26 09:56:22 -07:00
Ben Doherty ab252b210c Fix config object related build failures (#5814) 2022-07-26 09:51:55 -07:00
Benjamin Doherty 1071b8ea90 Bump version to 1.25.3 2022-07-18 15:15:03 -07:00
Benjamin Doherty a9c5bbf185 Merge branch 'rc/1.25.2' into release 2022-07-18 15:14:02 -07:00
Philip Rideout 8dd4bff7a7 gltfio: minor fixups to prep for g3 integration. 2022-07-18 15:11:36 -07:00
Philip Rideout 77c54446af gltfio: use openLocalTransformTransaction API. 2022-07-18 15:11:30 -07:00
Benjamin Doherty 4a0bc0af57 Bump version to 1.25.2 2022-07-11 15:51:55 -07:00
Benjamin Doherty a171e75e70 Merge branch 'rc/1.25.1' into release 2022-07-11 15:50:10 -07:00
Benjamin Doherty f5ffa092fe Bump version to 1.25.1 2022-07-06 19:09:34 -07:00
Benjamin Doherty 8de5fdd551 Merge branch 'rc/1.25.0' into release 2022-07-06 19:07:42 -07:00
Benjamin Doherty ecca3abe98 Bump version to 1.25.0 2022-07-01 12:09:29 -07:00
Benjamin Doherty 8570e35224 Merge branch 'rc/1.24.0' into release 2022-07-01 12:08:48 -07:00
Benjamin Doherty 84df9f9a03 Update version to 1.24.0 2022-07-01 12:03:38 -07:00
Benjamin Doherty 5f93fb9613 Update RELEASE_NOTES for 1.24.0 2022-06-30 16:37:03 -07:00
Benjamin Doherty 75f77fdbdd Metal: Allow Filament to disregard MTLTexture pixelFormat when importing 2022-06-30 16:04:28 -07:00
Ben Doherty 7825d582c2 CocoaPods: include uberz library (#5752) 2022-06-30 14:07:55 -07:00
Ben Doherty 5deb0ba933 CocoaPods: include uberz library (#5752) 2022-06-30 14:04:02 -07:00
Philip Rideout 18e917aaf2 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:05:53 -07:00
Benjamin Doherty a165f3890a Vulkan: Support VMA_DYNAMIC_VULKAN_FUNCTIONS off 2022-06-21 15:09:26 -07:00
Philip Rideout f88b6d9c97 Do not trigger UB with string_view. 2022-06-20 21:11:52 -07:00
Mathias Agopian db8ecd9952 configure render primitive pool so it works with msvc
a 64 bytes pool seems to work with both clang and msvc, unfortunately,
c++ doesn't let us know the allocator object size at compile time
for map containers, so we have to guess.
2022-06-16 13:13:33 -07:00
Benjamin Doherty b5ec06c2d2 Fix build breakage 2022-06-15 17:05:53 -07:00
Benjamin Doherty dfbac8385e Merge branch 'rc/1.23.2' into release 2022-06-15 11:49:06 -07:00
Ben Doherty eaab737b2c NoopDriver: return unique handles (#5697) 2022-06-15 11:28:08 -07:00
Benjamin Doherty 45991cda0a Update RELEASE_NOTES for 1.23.2 2022-06-13 15:27:03 -07:00
Philip Rideout 09a016bb6f Remove an 'API Change' warning from one item. 2022-06-09 14:33:49 -07:00
Benjamin Doherty 31607d355d Bump version to 1.23.2 2022-06-06 15:18:57 -07:00
Benjamin Doherty a67d50b9e2 Merge branch 'rc/1.23.1' into release 2022-06-06 15:16:53 -07:00
Benjamin Doherty 8d42f53c80 Update RELEASE_NOTES for 1.23.1 2022-06-06 15:14:59 -07:00
Benjamin Doherty 5e21a55bce Revert "iOS: implement headleass swapchain (#5486)"
This reverts commit 0e5ba60cb6.

This causes issues in G3, still need to investigate the root cause.
2022-06-06 13:17:04 -07:00
Benjamin Doherty 85930ea2e8 Bump version to 1.23.1 2022-06-01 14:58:29 -07:00
Benjamin Doherty 4b3cde8b39 Merge branch 'rc/1.23.0' into release 2022-06-01 14:55:20 -07:00
Benjamin Doherty eedfa85355 Update RELEASE_NOTES for 1.23.0 2022-06-01 14:54:50 -07:00
Benjamin Doherty bb54c6c807 Release Filament 1.23.0 2022-06-01 14:53:48 -07:00
Benjamin Doherty c23f905858 Update RELEASE_NOTES for 1.23.0 2022-06-01 14:53:23 -07:00
Benjamin Doherty 8c7be0a1d0 Revert "iOS: implement headleass swapchain (#5486)"
This reverts commit 0e5ba60cb6.

This causes issues in G3, still need to investigate the root cause.
2022-05-31 11:29:38 -07:00
Benjamin Doherty 878497b3d5 Bump version to 1.23.0 2022-05-24 15:19:51 -07:00
Benjamin Doherty a155561769 Merge branch 'rc/1.22.2' into release 2022-05-24 15:17:55 -07:00
Benjamin Doherty 8b86a0ed2e Revert "iOS: implement headleass swapchain (#5486)"
This reverts commit 0e5ba60cb6.

This causes issues in G3, still need to investigate the root cause.
2022-05-24 20:13:10 +00:00
Benjamin Doherty 26f9a9b122 Update RELEASE_NOTES for 1.22.2 2022-05-23 12:40:47 -07:00
Ben Doherty 6e5f6978fb Add ktxreader and viewer libs to CocoaPods (#5573) 2022-05-18 16:24:51 -07:00
Ben Doherty 0d31d7b2de Add ktxreader and viewer libs to CocoaPods (#5573) 2022-05-18 16:13:26 -07:00
Benjamin Doherty dd862b7e0a Bump version to 1.22.2 2022-05-17 18:03:38 -07:00
Benjamin Doherty 52065f2cbd Merge branch 'rc/1.22.1' into release 2022-05-17 18:01:37 -07:00
Benjamin Doherty 77c02d5831 Update RELEASE_NOTES for 1.22.1 2022-05-17 17:51:37 -07:00
Ben Doherty f7e4c8d16d Add package name back to AndroidManifest.xml to fix G3 (#5569) 2022-05-17 17:51:21 -07:00
Philip Rideout b7410474ff Workaround: partially revert "don't issue a flush..."
This is a temporary workaround for a memory corruption issue observed on
some devices from a specific vendor. We will try to make this workaround
more targeted in a subequent change.

Partial revert for b2cdf9f2b4.
2022-05-16 10:39:55 -07:00
Benjamin Doherty 384cc4ebf6 Bump version to 1.22.1 2022-05-09 13:09:39 -07:00
Benjamin Doherty 7c0643f122 Merge branch 'rc/1.22.0' into release 2022-05-09 13:07:07 -07:00
Benjamin Doherty 58abae3067 Release Filament 1.22.0 2022-05-09 13:07:02 -07:00
Benjamin Doherty 4742693869 Update RELEASE_NOTES for 1.22.0 2022-05-09 13:04:55 -07:00
Benjamin Doherty 6c39e474ea Bump version to 1.22.0 2022-05-02 13:19:43 -04:00
Benjamin Doherty 5c8977c906 Merge branch 'rc/1.21.3' into release 2022-05-02 13:18:06 -04:00
Benjamin Doherty 6b3cc2e2f3 Update RELEASE_NOTES for 1.21.3 2022-05-02 13:12:51 -04:00
Ben Doherty 76b2edd6ea Move toCompressedFilamentEnum to Ktx1Reader header (#5493) 2022-04-29 14:50:24 -04:00
Benjamin Doherty 8ebb37d011 Bump version to 1.21.3 2022-04-25 16:58:19 -04:00
Benjamin Doherty 3366db83ef Merge branch 'rc/1.21.2' into release 2022-04-25 16:57:25 -04:00
Benjamin Doherty 5415254aac Update RELEASE_NOTES for 1.21.2 2022-04-25 16:50:53 -04:00
Benjamin Doherty caacc61602 Bump version to 1.21.2 2022-04-13 10:21:09 -06:00
Benjamin Doherty e902df19b2 Merge branch 'rc/1.21.1' into release 2022-04-13 10:15:50 -06:00
Benjamin Doherty 40b372dda7 Update RELEASE_NOTES for 1.21.1 2022-04-12 14:36:26 -06:00
Ben Doherty fd330a98aa Releases: specify Python dependencies in requirements.txt file (#5402) 2022-04-08 14:35:51 -07:00
Ben Doherty 90c23a7d5d Correctly prepare color grading as subpass programs (#5384) 2022-04-04 13:24:01 -07:00
Benjamin Doherty 5710304114 Bump version to 1.21.1 2022-04-04 13:03:39 -07:00
Benjamin Doherty 0f684820bc Merge branch 'rc/1.21.0' into release 2022-04-04 13:01:35 -07:00
Benjamin Doherty e1d2d6ade6 Update RELEASE_NOTES for 1.21.0 2022-04-04 12:58:54 -07:00
Mathias Agopian e0b6f2ca71 Change version number to 1.21.0 2022-04-04 12:41:38 -07:00
Benjamin Doherty 2a35ee279b Bump version to 1.20.6 2022-03-28 18:47:38 -07:00
Benjamin Doherty 5abf780360 Merge branch 'rc/1.20.5' into release 2022-03-28 18:45:34 -07:00
Benjamin Doherty 181f158ea9 Update RELEASE_NOTES for 1.20.5 2022-03-28 18:42:41 -07:00
Benjamin Doherty f4087fc81d Bump version to 1.20.5 2022-03-21 14:45:34 -07:00
Benjamin Doherty 82793f9b82 Merge branch 'rc/1.20.4' into release 2022-03-21 14:43:15 -07:00
Benjamin Doherty 537576e84a Update RELEASE_NOTES for 1.20.4 2022-03-21 14:42:35 -07:00
Benjamin Doherty 375d1f55e3 Release Filament 1.20.4 2022-03-21 14:38:14 -07:00
Benjamin Doherty 597218963f Update RELEASE_NOTES for 1.20.4 2022-03-21 14:37:17 -07:00
Philip Rideout 0d29b3ddc8 WebGL endFrame: restore additional default state. 2022-03-21 09:43:45 -07:00
Philip Rideout e0e3b42623 WebGL: reset VAO and texture bindings when frame ends. 2022-03-21 09:43:33 -07:00
Benjamin Doherty 0995ca6614 Bump version to 1.20.4 2022-03-14 14:19:36 -07:00
Benjamin Doherty 3d741fc8d4 Merge branch 'rc/1.20.3' into release 2022-03-14 14:17:54 -07:00
Benjamin Doherty c20772b458 Update RELEASE_NOTES for 1.20.3 2022-03-10 12:56:56 -08:00
Benjamin Doherty 4a6b659098 Bump version to 1.20.3 2022-03-07 14:12:28 -08:00
Benjamin Doherty 2b93f08ca5 Merge branch 'rc/1.20.2' into release 2022-03-07 14:10:07 -08:00
Benjamin Doherty fca62b8fff Update RELEASE_NOTES for 1.20.2 2022-03-07 14:08:41 -08:00
Benjamin Doherty dee6d9de2c Bump version to 1.20.2 2022-03-02 15:51:38 -08:00
Benjamin Doherty 574e3e7521 Merge branch 'rc/1.20.1' into release 2022-03-02 15:47:21 -08:00
Ben Doherty 29fdf82ac5 Make VulkanContext compatible with vk_mem_alloc dev 2022-03-02 12:10:20 -08:00
Benjamin Doherty c8cf2a54e8 Update RELEASE_NOTES for 1.20.1 2022-03-02 11:47:51 -08:00
Ben Doherty bfd32e67d4 Apply some clang-tidy fixes (#5281) 2022-03-02 11:43:51 -08:00
Benjamin Doherty 95915367fa Bump version to 1.20.1 2022-02-24 13:59:17 -08:00
Benjamin Doherty b769cfda62 Merge branch 'rc/1.20.0' into release 2022-02-24 13:57:10 -08:00
Benjamin Doherty 40ac88dfed Bump MATERIAL_VERSION to 20 2022-02-24 13:53:43 -08:00
Benjamin Doherty 6d96082f07 Bump version to 1.20.0 2022-02-24 13:53:43 -08:00
Benjamin Doherty 21f913db1c Update RELEASE_NOTES for 1.20.0 2022-02-24 13:53:42 -08:00
Ben Doherty 699a578966 Add SSR variant filter to matc (#5256) 2022-02-24 10:36:06 -08:00
Philip Rideout babbfa1394 Vulkan: remove layout checks from SwapChain.
These asserts will come back in the next Filament release, which has
much cleaner layout tracking.
2022-02-23 13:48:13 -08:00
Philip Rideout 73f0d58e10 Vulkan: fix backend tests (especially ReadPixels Y flip). 2022-02-23 11:18:29 -08:00
Philip Rideout 9cb4b74bbd Fix web apps that have multiple Filament viewers.
This fixes the emscripten binding errors that we've been seeing
with the <filament-viewer> test page, which prevented us from
including web in the last few Filament releases.

The binding errors were caused by double-initializing the emscripten
module.

I fixed this by allowing clients (e.g. FilamentViewer) to call
Filament.init() more than once. We now accumulate a list of "on ready"
callbacks that get triggered after the emscripten module becomes ready.

As far as I can tell, multiple canvases were actually always broken, and
the viewer test page worked in the past only because we got lucky.
2022-02-22 16:12:13 -08:00
Ben Doherty f2c8456971 Attempt to fix Windows CI builds (#5205) 2022-02-15 11:12:19 -08:00
Benjamin Doherty e571600c30 Bump version to 1.19.1 2022-02-14 13:48:59 -08:00
Benjamin Doherty e84c94d3eb Merge branch 'rc/1.19.0' into release 2022-02-14 13:46:45 -08:00
Benjamin Doherty e791d4818f Update RELEASE_NOTES for 1.19.0 2022-02-14 13:45:28 -08:00
Philip Rideout cdadb43e50 WebGL: another fix for BufferDescriptor bindings.
The previous code would convert each element of the source data
into 8 bit-per-element, but we wnat to preserve the original format
that the user provides.

The new solution is to use `slice()` which is a robust way to clone
all the data in a typed array.

This fixes the new regression with Triangle that Ben caught.
2022-02-09 15:44:26 -08:00
Philip Rideout edaff60fbf WebGL: remove buffer sharing optimization.
If emscripten grows the heap inside one of our BufferDescriptor binding
functions, then the old heap becomes "detached" and an error can
occur.

This fixes the issue seen with the Parquet demo that Ben caught.
2022-02-09 12:51:06 -08:00
Benjamin Doherty 3f64e46557 Bump version to 1.19.0 2022-02-08 09:27:14 -08:00
Benjamin Doherty 32dab23bc6 Update RELEASE_NOTES for 1.18.0 2022-02-08 09:25:41 -08:00
Benjamin Doherty 362de7dd31 Merge branch 'rc/1.18.0' into release 2022-02-08 09:22:21 -08:00
Benjamin Doherty 6b01fbb903 Correct version to 1.18.0 2022-02-08 09:08:49 -08:00
Philip Rideout 4934d9f7bc Vulkan: fix leak when apps do not draw anything. 2022-02-07 14:27:06 -08:00
Ben Doherty ed73955b00 Initialize useLegacyMorphing to fix MSAN warning (#5164) 2022-02-07 11:28:03 -08:00
Ben Doherty 3f1f2726c4 Add a MAX_LEGACY_MORPH_TARGETS definition (#5163) 2022-02-07 11:27:45 -08:00
Philip Rideout 1a7bd7ea8d Rewrite VulkanPipelineCache (without changing its API).
All three types of caches (descriptor sets, pipelines, and pipeline
layouts) are now managed in exactly the same way. They all use an LRU
eviction scheme that is based on a count of command buffer flush
events.

Vulkan objects can only be destroyed if there are no in-flight command
buffers that reference them, so an easy way to know when it is safe to
evict a given entry is to wait for "N" flushes after its last use, where
"N" is the number of command buffers in the command buffer ring.

Another big simplification is that there are no more dirty flags,
instead we store two sets of state vectors for each type of cache: the
"currently bound" state, and the "current requirements" state.
2022-02-03 17:37:40 -08:00
Ben Doherty 946ea43436 Fix sampler overflow check in SamplerBindingMap (#5143) 2022-02-02 11:04:48 -08:00
Philip Rideout 7f42385f5f VulkanPipelineCache: fix spurious SEGV.
Fixes #5142 by replacing unsafe pointers with map keys.

One of the differences between robin_map and unordered_map is the
following:

    pointers to keys or values in the map are invalidated in the same
    way as iterators to these keys-values

Therefore it is unsafe to track the pointer to a value that is stored
in a robin_map.
2022-02-01 16:34:34 -08:00
Philip Rideout 8845ac2b75 VulkanPipelineCache: code cleanup and minor fixes.
This is mostly just code cleanup. One actual bug was the fact that the
dummy sampler was re-created every time a new pipeline layout was
created.

It also felt strange to use `auto&` to refer to a C-style array. I
changed this into a `std::array` which is more consistent with other
fixed size arrays in this class.
2022-02-01 16:34:27 -08:00
Ben Doherty da85001d4d Support legacy morphing (#5129)
Support legacy morphing (morphing with targets supplied via VertexAttributes) for older clients. This gives clients more time to transition over to the new MorphTargetBuffer API.
2022-01-27 16:08:46 -08:00
Mathias Agopian 8d15079937 update material version to 18 2022-01-26 14:32:46 -08:00
adc542b5cd Bind samplers to specified shader stages (#5036)
Co-authored-by: Ben Doherty <bendoherty@google.com>
Co-authored-by: Mathias Agopian <mathias@google.com>
2022-01-26 14:31:30 -08:00
Philip Rideout 72feb044a3 Vulkan now supports offsets when uploading texture data.
This allows `MorphStressTest` to work on Vulkan.

However, `Horse` is still broken because it provides positions but not
tangents.  Separate fix for that is coming.

Partial fix for #5109.
2022-01-26 14:31:00 -08:00
Philip Rideout c0ba260ddf Vulkan: clean up image layout management.
This fixes validation errors and makes a first pass at simplification.
VulkanTexture now tracks image layout using RangeMap, which paves the
way for further simplification.
2022-01-26 14:30:45 -08:00
Philip Rideout 2da215e8e7 RangeMap: improve naming convention, etc. 2022-01-26 14:30:23 -08:00
Philip Rideout 4d0368b5f1 RangeMap: improve the auto-merge functionality. 2022-01-26 14:30:09 -08:00
Philip Rideout d11c78857d utils: introduce RangeMap container and unit test.
This will allow the Vulkan backend to efficiently track the subresource
image layouts for each texture.

This is a sparse container for a series of ordered non-overlapping
integer intervals, where each interval maps to a concrete value.
2022-01-26 14:29:45 -08:00
Mathias Agopian e829d90c4a A morphing buffer must be bound when skinning is active
This is because we're using the same program variant for skinning
and morphing, in the skinning-only case, the buffer won't be accessed
in the shader, but it must be present.

fixes #5085
2022-01-26 14:20:25 -08:00
Mathias Agopian a8006acd33 [GL backend] fix sampler binding bug
When a program had an unused SamplerInterfaceBlock, other samplers
could be bound to the wrong TMU

Fixes #5088
2022-01-26 14:20:12 -08:00
Benjamin Doherty 86ec502040 Bump version to 1.17.1 2022-01-24 12:52:22 -08:00
Benjamin Doherty b19a73cc50 Merge branch 'rc/1.17.0' into release 2022-01-24 12:50:22 -08:00
Benjamin Doherty a99c695932 Update RELEASE_NOTES for 1.17.0 2022-01-24 12:45:05 -08:00
Benjamin Doherty 8cd720b53a Bump version to 1.17.0 2022-01-18 13:54:40 -08:00
Benjamin Doherty 04df79e58f Merge branch 'rc/1.16.1' into release 2022-01-18 13:53:02 -08:00
Benjamin Doherty a4b3717762 Update RELEASE_NOTES for 1.16.1 2022-01-18 13:48:36 -08:00
Benjamin Doherty 1035e442ee Bump version to 1.16.1 2022-01-10 10:47:46 -08:00
Benjamin Doherty 60d3638f15 Merge branch 'rc/1.16.0' into release 2022-01-10 10:44:36 -08:00
Benjamin Doherty 3e7d3c9035 Update RELEASE_NOTES for 1.16.0 2022-01-10 10:41:14 -08:00
jeanlemotan eb360be2ad Fixed cubemap update 2022-01-10 10:34:49 -08:00
Benjamin Doherty 485ac8704d Bump version to 1.16.0 2022-01-04 11:55:19 -08:00
Benjamin Doherty dc74540423 Merge branch 'rc/1.15.2' into release 2022-01-04 11:53:02 -08:00
Benjamin Doherty 96219c22db Update RELEASE_NOTES for 1.15.2 2022-01-04 11:49:50 -08:00
Romain Guy f3b7048775 Add missing JNI impl (#4959) 2022-01-04 11:43:19 -08:00
Romain Guy aaed6fb376 Fix rounding math 2022-01-04 11:43:13 -08:00
Romain Guy 35a5d3310f Fix preprocessor test 2021-12-13 13:53:20 -07:00
Benjamin Doherty 9da79a1d2d Bump version to 1.15.2 2021-12-13 11:08:28 -07:00
Benjamin Doherty 595b355d1b Merge branch 'rc/1.15.1' into release 2021-12-13 11:06:45 -07:00
Benjamin Doherty 3a67d769f4 Update RELEASE_NOTES for 1.15.1 2021-12-06 16:54:28 -08:00
Benjamin Doherty 6fb536a937 Bump version to 1.15.1 2021-12-06 11:17:37 -08:00
Benjamin Doherty bb460d78d8 Merge branch 'rc/1.15.0' into release 2021-12-06 11:14:00 -08:00
Benjamin Doherty 838835a715 Update RELEASE_NOTES for 1.15.0 2021-12-02 11:52:04 -08:00
Romain Guy 63acd53e23 Use __ANDROID__ instead of ANDROID 2021-11-30 11:15:49 -08:00
Romain Guy fcd2d0457b Workaround for a build system issue 2021-11-30 11:15:42 -08:00
Benjamin Doherty 58fc26461b Bump version to 1.15.0 2021-11-29 14:08:28 -08:00
Benjamin Doherty fd82f6b04e Merge branch 'rc/1.14.2' into release 2021-11-29 14:07:03 -08:00
Benjamin Doherty cef3200533 Add additional RELEASE_NOTES for 1.14.2 2021-11-29 10:21:56 -08:00
Ben Doherty 634500c398 Fix, avoid divide-by-zero inside makeBone (#4889) 2021-11-24 16:29:33 -08:00
Ben Doherty b3e294ac54 Fix Metal depth comparison initialization (#4886) 2021-11-23 12:09:43 -08:00
Benjamin Doherty 2bf7535ad0 Update RELEASE_NOTES for 1.14.2 2021-11-22 10:16:00 -08:00
Benjamin Doherty 3315f75de9 Bump version to 1.14.2 2021-11-22 10:12:44 -08:00
Benjamin Doherty bbe7dbfa92 Merge branch 'rc/1.14.1' into release 2021-11-22 10:11:06 -08:00
Benjamin Doherty 5697922a65 Update RELEASE_NOTES for 1.14.1 2021-11-17 12:04:26 -08:00
Ben Doherty 4da83df2b9 Fix material compilation error with device vertex domain (#4865)
A recent refactor was causing the following error when the vertex domain
was set to `device`:
```
ERROR: main.vs:23: 'material' : undeclared identifier
ERROR: main.vs:23: 'materialVertex' : no matching overloaded function found
```
2021-11-17 12:03:55 -08:00
Ben Doherty 8f156d6588 Android: re-enable VSM cascade fix (#4863) 2021-11-17 10:19:09 -08:00
Benjamin Doherty cec0871c11 Bump version to 1.14.1 2021-11-15 10:09:45 -08:00
Benjamin Doherty 41a809368b Merge branch 'rc/1.14.0' into release 2021-11-15 10:07:56 -08:00
Romain Guy ea53eb9290 Skip task incompatible with configuration caching (#4831) 2021-11-09 15:56:00 -08:00
Benjamin Doherty 05875057c9 Update RELEASE_NOTES for 1.14.0 2021-11-09 15:51:13 -08:00
Benjamin Doherty 44125926d1 Disable configuration-cache 2021-11-08 17:05:34 -08:00
Benjamin Doherty 60734349de Bump version to 1.14.0 2021-11-08 11:52:50 -08:00
Benjamin Doherty fbfd5ec0ec Merge branch 'rc/1.13.0' into release 2021-11-08 11:50:19 -08:00
Ben Doherty a74a95cc65 Call VirtualMachineEnv::JNI_OnLoad for non-Android Java builds (better fix) (#4779) 2021-11-04 13:28:17 -07:00
Benjamin Doherty bc0ea16ff0 Update RELEASE_NOTES for 1.13.0 2021-11-02 13:15:53 -07:00
Mathias Agopian b2dc8aa84c Fix typo that broke the directional shadowmap 2021-11-02 13:11:44 -07:00
Benjamin Doherty 9987e8b6ab Bump version to 1.13.0 2021-11-01 14:59:11 -07:00
Benjamin Doherty 0d9bdcc008 Merge branch 'rc/1.12.11' into release 2021-11-01 14:55:58 -07:00
Benjamin Doherty b5c634045e Update RELEASE_NOTES for 1.12.11 2021-10-28 16:13:50 -07:00
Ben Doherty 1f05531d53 Call VirtualMachineEnv::JNI_OnLoad for non-Android Java builds (better fix) (#4779) 2021-10-28 16:02:23 -07:00
Benjamin Doherty 88f382f0e3 Revert "refactor colorgrading materials"
This reverts commit fb86a77cf8.
2021-10-28 15:56:50 -07:00
Benjamin Doherty 3e59925900 Remove problematic configuration-cache setting for release build 2021-10-28 15:56:26 -07:00
Benjamin Doherty ea404f8d4f Remove problematic configuration-cache setting for release build 2021-10-26 10:09:51 -07:00
Benjamin Doherty 602a550d93 Bump version to 1.12.11 2021-10-25 12:30:37 -07:00
Benjamin Doherty 12abbe2d23 Merge branch 'rc/1.12.10' into release 2021-10-25 11:06:18 -07:00
Benjamin Doherty fb0ee97588 Update RELEASE_NOTES for 1.12.10 2021-10-25 11:00:06 -07:00
Ben Doherty 56ef48c9c3 Fix, call VirtualMachineEnv::JNI_OnLoad for non-Android Java builds (#4749) 2021-10-25 10:39:24 -07:00
Benjamin Doherty 47c3dd3dd1 Revert "refactor colorgrading materials"
This reverts commit fb86a77cf8.
2021-10-25 10:37:52 -07:00
Benjamin Doherty c181648bfa Bump version to 1.12.10 2021-10-20 12:15:51 -07:00
Benjamin Doherty 0cf78b3abe Merge branch 'rc/1.12.9' into release 2021-10-20 12:12:33 -07:00
Ben Doherty 22889a7ad9 Fix VirtualMachineEnv.cpp with older JNI versions (#4752) 2021-10-20 11:16:55 -07:00
Ben Doherty a14451d0ac Fix, call VirtualMachineEnv::JNI_OnLoad for non-Android Java builds (#4749) 2021-10-20 10:41:34 -07:00
Benjamin Doherty 5dfdab10b7 Revert "refactor colorgrading materials"
This reverts commit fb86a77cf8.
2021-10-19 16:13:21 -07:00
Benjamin Doherty d6f2e3b8e9 Update RELEASE_NOTES for 1.12.9 2021-10-14 18:22:20 -07:00
Benjamin Doherty df30517743 Bump version to 1.12.9 2021-10-11 11:06:43 -07:00
Benjamin Doherty 8f80643c1a Merge branch 'rc/1.12.8' into release 2021-10-11 11:02:56 -07:00
Benjamin Doherty 5aea9be2fb Update RELEASE_NOTES for 1.12.8 2021-10-07 11:03:45 -07:00
Benjamin Doherty ad02e483d0 Bump version to 1.12.8 2021-10-04 10:26:57 -07:00
Benjamin Doherty f463d53036 Merge branch 'rc/1.12.7' into release 2021-10-04 10:21:42 -07:00
Benjamin Doherty b8d4408524 Update RELEASE_NOTES for 1.12.7 2021-10-04 10:18:56 -07:00
Benjamin Doherty fef70be848 Bump version to 1.12.7 2021-09-27 11:15:58 -07:00
Benjamin Doherty bdb12d9b24 Merge branch 'rc/1.12.6' into release 2021-09-27 11:12:42 -07:00
Ben Doherty 43ad283a83 Fix, missing call to setTransparencyMode (#4674) 2021-09-24 13:32:49 -07:00
Benjamin Doherty 2e4936afc4 Revert "fix a race in jobsystem"
This reverts commit 2feb0ad325.
2021-09-24 11:24:44 -07:00
Benjamin Doherty 891ffabd11 Update RELEASE_NOTES for 1.12.6 2021-09-23 17:25:25 -07:00
Ben Doherty e2c19498b4 Metal: don't call createTextureViewWithsSwizzle directly (#4662) 2021-09-23 11:28:04 -07:00
Ben Doherty c32630b265 Fix MetalBlitter crash when shader contains warnings (#4663) 2021-09-23 11:27:56 -07:00
Alexey Pelykh bf21e78d02 Podspec: include headers in nested directories (#4658) 2021-09-22 16:48:12 -07:00
Benjamin Doherty 525d4e08a3 Bump version to 1.12.6 2021-09-20 10:17:18 -07:00
Benjamin Doherty 2e9bf6d694 Merge branch 'rc/1.12.5' into release 2021-09-20 10:14:37 -07:00
Benjamin Doherty e845f01d85 Update RELEASE_NOTES for 1.12.5 2021-09-20 10:10:56 -07:00
Benjamin Doherty bef48be7b4 Bump version to 1.12.5 2021-09-13 10:47:09 -07:00
Benjamin Doherty b54fdc9e6e Merge branch 'rc/1.12.4' into release 2021-09-13 10:43:06 -07:00
Benjamin Doherty cedbf2e30b Update RELEASE_NOTES for 1.12.4 2021-09-13 10:40:55 -07:00
Benjamin Doherty 592f8d1b0d Bump version to 1.12.4 2021-09-08 11:05:44 -07:00
Benjamin Doherty 29612a684e Merge branch 'rc/1.12.3' into release 2021-09-08 11:03:53 -07:00
Benjamin Doherty e6d5807399 Bump version to 1.12.3 2021-08-30 11:46:51 -07:00
Benjamin Doherty fa2553251f Merge branch 'rc/1.12.2' into release 2021-08-30 11:44:00 -07:00
Benjamin Doherty 7387718852 Update RELEASE_NOTES for 1.12.2 2021-08-30 11:41:52 -07:00
Ben Doherty a503a6209a Fix regression with clipSpaceTransform (#4552) 2021-08-26 14:14:58 -07:00
Ben Doherty ce3e5f74e8 Fix Metal STREAM buffers (#4543) 2021-08-25 09:48:34 -07:00
Ben Doherty f37112358e Fix missing bookkeeping in bindUniformBufferRange (#4538) 2021-08-24 09:51:40 -07:00
Benjamin Doherty f368b14621 Bump version to 1.12.2 2021-08-23 12:41:33 -07:00
Benjamin Doherty 6960b1148a Merge branch 'rc/1.12.1' into release 2021-08-23 12:39:38 -07:00
Benjamin Doherty 3cc23aac25 Update RELEASE_NOTES for 1.12.1 2021-08-23 10:45:59 -07:00
Benjamin Doherty 11dc8740f2 Fix stack-use-after-scope error 2021-08-20 15:40:06 -07:00
Ben Doherty 4b797cff88 Windows: fix incorrect CRT flags with Visual Studio generators (#4516) 2021-08-20 10:56:41 -07:00
Ben Doherty fe1c1736cd Fix, potential null dereferences in MetalBlitter (#4481) 2021-08-10 16:30:11 -07:00
Benjamin Doherty 4058ef5f09 Bump version to 1.12.1 2021-08-09 12:06:47 -07:00
Benjamin Doherty d25ca01624 Merge branch 'rc/1.12.0' into release 2021-08-09 12:03:33 -07:00
Benjamin Doherty d96f87dbbf Update RELEASE_NOTES for 1.12.0 2021-08-09 12:01:46 -07:00
Ben Doherty 8a2e31023f Attempt to fix TSAN failure in ColorGrading.cpp (#4447) 2021-08-05 11:54:07 -07:00
Benjamin Doherty 1ea8e171d9 Bump version to 1.12.0 2021-08-03 11:18:56 -07:00
Benjamin Doherty e2be3dd0ac Merge branch 'rc/1.11.2' into release 2021-08-03 11:15:19 -07:00
Romain Guy 1c51164e7b Fix inverse tone mapping issues (#4437)
Bring color grading back into the Rec.709 color space to match
previous behaviors. This change also implements an exact inverse
tone map function for the "Filmic" operator.
2021-08-02 20:54:44 -07:00
Benjamin Doherty f190f03530 Update RELEASE_NOTES for 1.11.2 2021-08-02 11:17:42 -07:00
Ben Doherty 055fc7cbc1 Attempt to fix Windows CI by turning off concurrent builds (#4395) 2021-07-30 14:09:07 -07:00
Ben Doherty 9073fc3dc3 Attempt to fix Windows CI by turning off concurrent builds (#4395) 2021-07-28 10:49:37 -07:00
Ben Doherty 2409dc9bc4 Expose Engine::flush (#4385) 2021-07-26 15:09:14 -07:00
Benjamin Doherty 6586c8d70b Bump version to 1.11.2 2021-07-26 12:50:29 -07:00
Benjamin Doherty ac0c94da69 Merge branch 'rc/1.11.1' into release 2021-07-26 12:48:36 -07:00
Ben Doherty d19d6a72b0 Expose Engine::flush (#4385) 2021-07-26 12:10:19 -07:00
Benjamin Doherty c81b5d98ef Update RELEASE_NOTES for 1.11.1 2021-07-26 10:05:41 -07:00
Mathias Agopian 756866675f fix an issue where a sampler could fail to be updated
SamplerGroup was comparing texture handles to decide if a texture needed
to be updated, however, 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, if that texture 
is now set on the SamplerGroup, it will ignore it, thinking it's not
different.
2021-07-21 14:46:44 -07:00
Benjamin Doherty ebcd4925f7 Bump version to 1.11.1 2021-07-19 10:24:01 -07:00
Benjamin Doherty 13bed4fdf9 Merge branch 'rc/1.11.0' into release 2021-07-19 10:20:29 -07:00
Benjamin Doherty 1dae5c6b6c Update RELEASE_NOTES for 1.11.0 2021-07-19 10:18:07 -07:00
Benjamin Doherty 8e6663e4b0 Bump version to 1.11.0 2021-07-12 10:49:43 -07:00
Benjamin Doherty ba804444b8 Merge branch 'rc/1.10.7' into release 2021-07-12 10:47:12 -07:00
Benjamin Doherty 58cfb85004 Update RELEASE_NOTES for 1.10.7 2021-07-12 10:45:24 -07:00
Mathias Agopian ab46481b45 Fix colorgrading as subpass
We were inserting the colorgrading subpass command between the
refracted and blended objects, instead of after all of them.

Another bad side effect of this was to trigger the refraction pass for
no reason.
2021-07-12 10:35:01 -07:00
Mathias Agopian 4296782399 don't crash when refraction pass is empty 2021-07-12 09:53:37 -07:00
Benjamin Doherty ef375a7103 Bump version to 1.10.7 2021-07-07 11:02:30 -07:00
Benjamin Doherty fd258b7765 Merge branch 'rc/1.10.6' into release 2021-07-07 10:59:12 -07:00
Benjamin Doherty 147de8d372 Update RELEASE_NOTES for 1.10.6 2021-07-07 10:57:25 -07:00
Philip Rideout eb2a1928b6 ShadowMapManager: fix MSAN use-of-uninitialized-value.
The operator!= in std::array compares SPLIT_COUNT elements, which
is potentially greater than cascadeCount, which was the number of
initialized elements in splitPercentages.
2021-07-07 10:51:18 -07:00
Benjamin Doherty 35b033102f Bump version to 1.10.6 2021-06-28 12:07:58 -07:00
Benjamin Doherty 7bc65421a9 Merge branch 'rc/1.10.5' into release 2021-06-28 12:04:31 -07:00
Benjamin Doherty 736514cf37 Update RELEASE_NOTES for 1.10.5 2021-06-28 12:04:27 -07:00
Mathias Agopian db0158dae8 fix webgl build
we need to select opengl on webgl.
2021-06-28 08:27:46 -07:00
Benjamin Doherty e706695ed1 Bump version to 1.10.5 2021-06-21 11:18:26 -07:00
Benjamin Doherty e8877ffe2d Merge branch 'rc/1.10.4' into release 2021-06-21 11:16:10 -07:00
Benjamin Doherty 1fd5d9dae6 Update RELEASE_NOTES for 1.10.4 2021-06-21 11:14:35 -07:00
Ben Doherty cd48089318 filament-utils-android: fix string literal conversions (#4137) 2021-06-15 16:19:32 -06:00
Benjamin Doherty 6379ab22c9 Bump version to 1.10.4 2021-06-14 11:06:42 -06:00
Benjamin Doherty 0bf02b75d5 Merge branch 'rc/1.10.3' into release 2021-06-14 11:04:25 -06:00
Benjamin Doherty c4259b5598 Update RELEASE_NOTES for 1.10.3 2021-06-14 11:02:45 -06:00
Ben Doherty 6b3c1179bc Include sample-gltf-viewer with Android releases (#4099) 2021-06-08 10:41:48 -07:00
Philip Rideout c1a0e61e8e Fix FixedCapacityVector destructor.
std::allocator::deallocate() expects the same value that was given
during allocate().

Interestingly, this bug did not manifest any issues (even with ASAN) on
some platforms.
2021-06-07 15:56:33 -07:00
Benjamin Doherty fc06298ed4 Bump version to 1.10.3 2021-06-07 11:22:04 -07:00
Benjamin Doherty 4ca87b188c Merge branch 'rc/1.10.2' into release 2021-06-07 11:19:51 -07:00
Benjamin Doherty f1f60c3e0d Turn off warnings as errors for spirv-tools 2021-06-07 11:18:56 -07:00
Benjamin Doherty 76d21b56af Update RELEASE_NOTES for 1.10.2 2021-06-07 11:18:09 -07:00
Benjamin Doherty 0ab0e50a4f Turn off warnings as errors for spirv-tools 2021-06-02 11:16:42 -07:00
Benjamin Doherty 34f4c06a5c Bump version to 1.10.2 2021-06-01 11:17:32 -07:00
Benjamin Doherty 6de36f1e53 Merge branch 'rc/1.10.1' into release 2021-06-01 11:15:49 -07:00
Benjamin Doherty 2a9a3b1ac2 Update RELEASE_NOTES for 1.10.1 2021-06-01 11:13:04 -07:00
Benjamin Doherty 84b73a3770 Bump version to 1.10.1 2021-05-24 10:52:02 -07:00
Benjamin Doherty 662a10e273 Merge branch 'rc/1.10.0' into release 2021-05-24 10:49:10 -07:00
Benjamin Doherty ecce02502e Update RELEASE_NOTES for 1.10.0 2021-05-24 10:47:39 -07:00
Philip Rideout d17875aea1 ImGuiHelper: fix support for custom images.
The texture binding in the material instance needs to be restored to the
glyph atlas when a custom image is not in use.
2021-05-21 12:49:37 -07:00
Philip Rideout b8897a68f9 matc: detect missing end brace.
matc was failing to report certain kinds of syntax errors and would
read out-of-bounds memory.

This change casuses the flare material to fail.
2021-05-21 09:20:33 -07:00
Ben Doherty 84efd4871e API CHANGE: remove some Camera, Engine, and View deprecated APIs (#3965) 2021-05-19 12:02:13 -07:00
Benjamin Doherty 85ea5a6b70 Bump version to 1.10.0 2021-05-17 11:00:42 -07:00
Benjamin Doherty 77891acb92 Merge branch 'rc/1.9.25' into release 2021-05-17 10:57:30 -07:00
Benjamin Doherty 74fe102035 Update RELEASE_NOTES for 1.9.25 2021-05-17 10:54:38 -07:00
Philip Rideout 25cc554925 WASM: fix "Missing field" error for lensFlare. 2021-05-17 10:06:56 -07:00
Ben Doherty d787a521b5 Fix DIST_DIR setting for Windows builds (#3945) 2021-05-12 11:16:30 -07:00
Ben Doherty 46e52c71e1 Fix DIST_DIR setting for Windows builds (#3945) 2021-05-12 11:15:49 -07:00
Philip Rideout 1dad27a172 Repair WebGL and fix potential INVALID_OPERATION.
We should take care not to call glVertexAttribPointer when there is
no bound ARRAY_BUFFER (i.e. when its binding is zero).

This fixes the black screen seen with some WebGL samples after
the recent memory leak fix related to the new BufferObject API.
2021-05-10 13:38:56 -07:00
Benjamin Doherty 60d230b380 Bump version to 1.9.25 2021-05-07 21:42:48 -07:00
Benjamin Doherty d7cb38e706 Merge branch 'rc/1.9.24' into release 2021-05-07 21:39:17 -07:00
Benjamin Doherty ce00cca6ee Update RELEASE_NOTES for 1.9.24 2021-05-07 21:36:49 -07:00
Philip Rideout d627d57bad Second memory leak fix. (#3906)
Fixes #3888.
2021-05-06 14:25:46 -07:00
Philip Rideout 8ffc776f1c Fix horrible memory leak in the GL driver. (#3894)
This leak was introduced in the following PR on April 7.
https://github.com/google/filament/pull/3775

The guilty party has been contacted and properly admonished for his
transgression.

This was tested by adding the following code after applyAnimation in
gltf_viewer.cpp

        static int nframes = 0;
        if (!gpath.empty() && nframes++ > 100) {
            static int count = 0;
            printf("reloading %d\n", count++);
            nframes = 0;
            app.resourceLoader->asyncCancelLoad();
            app.resourceLoader->evictResourceData();
            app.viewer->removeAsset();
            app.assetLoader->destroyAsset(app.asset);
            loadAsset(gpath, app);
            loadResources(gpath, app);
        }
2021-05-04 18:22:08 -07:00
Benjamin Doherty be032b52c1 Bump version to 1.9.24 2021-05-03 10:42:19 -07:00
Benjamin Doherty 4388e81e5f Merge branch 'rc/1.9.23' into release 2021-05-03 10:40:49 -07:00
Benjamin Doherty 71a185d139 Update RELEASE_NOTES for 1.9.23 2021-05-03 10:38:59 -07:00
Benjamin Doherty d2cf5985ac Bump version to 1.9.23 2021-04-26 10:55:10 -07:00
Benjamin Doherty debcbb8e5c Merge branch 'rc/1.9.22' into release 2021-04-26 10:52:43 -07:00
Benjamin Doherty b9dd62c7d3 Update RELEASE_NOTES for 1.9.22 2021-04-26 10:47:11 -07:00
Benjamin Doherty dc2b430f34 Bump version to 1.9.22 2021-04-26 10:39:16 -07:00
Benjamin Doherty e5ef4e8868 Update RELEASE_NOTES for 1.9.21 2021-04-19 11:36:37 -07:00
Benjamin Doherty c0d6cd3ac3 Merge branch 'rc/1.9.21' into release 2021-04-19 11:34:23 -07:00
Benjamin Doherty b63ab2dc19 Update RELEASE_NOTES for 1.9.21 2021-04-19 11:32:31 -07:00
Benjamin Doherty 5d8dad561c Bump version to 1.9.21 2021-04-12 11:38:27 -07:00
Benjamin Doherty 8933be1ae2 Merge branch 'rc/1.9.20' into release 2021-04-12 11:36:17 -07:00
Benjamin Doherty 6b66b48b1d Update RELEASE_NOTES for 1.9.20 2021-04-12 11:35:45 -07:00
Benjamin Doherty 9c23eb6e33 Release Filament 1.9.20 2021-04-12 11:34:39 -07:00
Benjamin Doherty baea54a3fc Update RELEASE_NOTES for 1.9.20 2021-04-12 09:20:31 -07:00
Benjamin Doherty d9f800454c Bump version to 1.9.20 2021-04-05 11:14:17 -07:00
Benjamin Doherty f9ee0de07a Merge branch 'rc/1.9.19' into release 2021-04-05 11:11:13 -07:00
Benjamin Doherty 2786d0a9f7 Update RELEASE_NOTES for 1.9.19 2021-04-05 11:10:50 -07:00
Benjamin Doherty 491e8032e6 Release Filament 1.9.19 2021-04-05 11:10:20 -07:00
Benjamin Doherty ef3f13f5d3 Update RELEASE_NOTES for 1.9.19 2021-04-05 11:09:38 -07:00
Benjamin Doherty bcb5b2d790 Implement Metal BufferObjects 2021-04-05 11:01:36 -07:00
Ben Doherty 02de3f2e2a Fix, regression with Metal buffers (#3715) 2021-03-29 14:21:34 -07:00
Benjamin Doherty 0e7bb53c07 Bump version to 1.9.19 2021-03-29 11:09:32 -07:00
Benjamin Doherty 759109d478 Merge branch 'rc/1.9.18' into release 2021-03-29 11:06:55 -07:00
Benjamin Doherty 54d5af6edf Update RELEASE_NOTES for 1.9.18 2021-03-29 11:04:57 -07:00
Philip Rideout 38fbe47ced RenderTarget: fix NPE when depth is not present.
This fixes a recent regression that would occur when a RenderTarget
does not have a depth attachment.
2021-03-29 10:32:22 -07:00
Benjamin Doherty f066c925ba Bump version to 1.9.18 2021-03-22 10:16:34 -07:00
Benjamin Doherty 994fdf4e1d Merge branch 'rc/1.9.17' into release 2021-03-22 10:12:20 -07:00
Benjamin Doherty 50b50d65e3 Update RELEASE_NOTES for 1.9.17 2021-03-22 10:11:02 -07:00
Mathias Agopian 0aaa985649 Fix a hang in JobSystem
The hang was caused by a subtle race. When a job is completed, its 
thread must signal all the threads that might be waiting on this job.
The signaling code was attempting to signal only the minimum number
of threads -- this was important especially in the case where no threads
were waiting, then the call to notify() could be avoided.

Unfortunately, for performance reasons we're not calling notify() with
the condition lock held, this meant that between the time the number of 
waiting threads was latched and the time of the notify() call, more
threads could enter their condition variable wait(), and it would
then be possible for these threads to wake up, instead of the thread
we were trying to wake up (the one waiting on the job).

It would then get stuck forever.

This bug was introduced in 2df639133b


Also add some debugging code for this kind of failure (disabled)
2021-03-18 09:57:25 -07:00
Benjamin Doherty 29564f8eae Bump version to 1.9.17 2021-03-15 10:15:25 -07:00
Benjamin Doherty c15db68a5b Merge branch 'rc/1.9.16' into release 2021-03-15 10:12:56 -07:00
Benjamin Doherty 3452fb3e56 Update RELEASE_NOTES for 1.9.16 2021-03-15 10:10:40 -07:00
Mathias Agopian 35eb8e7be1 Revert GL backend handle tracking
This wasn't very useful in the first place because we're recycling
handles very quickly. Additionally there was a race condition
which cause false positives.

This reverts commit bc6acd5c5a.
This reverts commit 3a15756c78.
2021-03-12 13:02:55 -08:00
Mathias Agopian 834b774128 Fixes some issues with imported rendertargets
We were not declaring the attachments it was using.

Fixes #3628
2021-03-12 08:26:16 -08:00
Benjamin Doherty 5aa0eb9f9d Bump version to 1.9.16 2021-03-08 10:09:14 -08:00
Benjamin Doherty d9a6e2e649 Merge branch 'rc/1.9.15' into release 2021-03-08 10:07:00 -08:00
Benjamin Doherty cb823b16a1 Update RELEASE_NOTES for 1.9.15 2021-03-08 10:05:19 -08:00
Ben Doherty 0bd41e877e Downgrade Linux GitHub Actions environment to fix error (#3588) 2021-03-01 11:21:11 -08:00
Benjamin Doherty ecc3e73967 Bump version to 1.9.15 2021-03-01 11:13:44 -08:00
Benjamin Doherty 464b4c24f9 Merge branch 'rc/1.9.14' into release 2021-03-01 11:11:53 -08:00
Benjamin Doherty 32367516e8 Update RELEASE_NOTES for 1.9.14 2021-03-01 11:10:06 -08:00
Philip Rideout 1709a55606 filamat: Fix data race with SPIRV error registrations. 2021-02-26 10:34:36 -08:00
Benjamin Doherty 58b4455979 Bump version to 1.9.14 2021-02-22 10:32:56 -08:00
Benjamin Doherty ea1dede19c Merge branch 'rc/1.9.13' into release 2021-02-22 10:29:57 -08:00
Benjamin Doherty 20ea3381fa Update RELEASE_NOTES for 1.9.13 2021-02-22 10:28:21 -08:00
Philip Rideout 7aa6fccd7c Modernize Python print syntax to appease external codebase. 2021-02-19 11:38:18 -08:00
Philip Rideout adbd54f4f8 Change abs() to std::abs to appease external codebase. 2021-02-19 11:38:18 -08:00
Philip Rideout 9d54261f18 Move vk_mem_alloc to its own cpp.
This will improve parity between the GitHub repo and its sister codebase
within Google.
2021-02-19 11:38:18 -08:00
Philip Rideout a97757c9ae Avoid uninitialized reads in computeVisibilityMasks.
I verified that this code is not enabled in our GitHub builds, and I
verified that the MSAN error goes away.
2021-02-19 11:38:18 -08:00
Philip Rideout 7c79d9f89d Remove some Windows line endings.
These line endings cause annoying diffs when comparing Filament's GitHub
source with its twin sister within Google.
2021-02-19 11:38:18 -08:00
Benjamin Doherty bf0914f813 Bump version to 1.9.13 2021-02-16 10:48:24 -08:00
Benjamin Doherty b96bc30fbd Merge branch 'rc/1.9.12' into release 2021-02-16 10:44:13 -08:00
Benjamin Doherty 62b50eb8ba Update RELEASE_NOTES for 1.9.12 2021-02-16 10:42:41 -08:00
Ben Doherty b4932e384a matc: Use consistent params for semantic code analysis (#3524)
When running semantic analysis on a material, we were arbitrarily choosing the first code gen permutation to analyze. So, running matc with arguments --api metal versus --api all would run analysis on slightly different shader code. This causes bugs when flags passed to glslang differ during semantic analysis. This change updates all semantic analysis to always use the same shader code.
2021-02-08 14:06:47 -08:00
Benjamin Doherty 5e68dc5f8d Bump version to 1.9.12 2021-02-08 09:58:15 -08:00
Benjamin Doherty f222f1b925 Merge branch 'rc/1.9.11' into release 2021-02-08 09:51:08 -08:00
Ben Doherty 22e4a54782 Update RELEASE_NOTES for 1.9.11 2021-02-08 09:50:23 -08:00
Benjamin Doherty 1289922c5f Release Filament 1.9.11 2021-02-08 09:48:50 -08:00
Ben Doherty 2839c352b8 Update RELEASE_NOTES for 1.9.11 2021-02-08 09:47:18 -08:00
Ben Doherty 6a01cbc312 Draft: fix TSAN issue by using lock in ColorGrading constructor (#3510)
This is a second attempt to fix Google3 TSAN failures seen inside of the ColorGrading constructor.

Related first attempt: #3462
2021-02-05 14:06:40 -08:00
Benjamin Doherty 6193156556 Bump version to 1.9.11 2021-02-01 11:49:12 -08:00
Benjamin Doherty fe23aa917d Merge branch 'rc/1.9.10' into release 2021-02-01 11:45:47 -08:00
Benjamin Doherty eb8a29a332 Update RELEASE_NOTES for 1.9.10 2021-02-01 11:45:17 -08:00
Ben Doherty 0626902530 Fix sporatic data race warning seen in Google3 (#3462) 2021-01-27 16:40:16 -08:00
Philip Rideout 042bfe2597 Partial fix for MSVC build. 2020-12-14 12:15:06 -08:00
Ben Doherty 97133f3591 Fix Windows iterator issue in Zip2Iterator and StructureOfArrays (#3322) 2020-12-14 12:14:53 -08:00
Philip Rideout d06cc4390e filamat: minify struct fields.
This shrinks the arm64 so file by 24 KiB.
2020-12-14 11:19:43 -08:00
Philip Rideout 6047d3235f Remove VSM variant from Skybox material. 2020-12-14 11:19:31 -08:00
Philip Rideout 2cda6e35bd math: reduce template bloat for matrices
This does not change our API, it merely reduces the number of
non-inlined function instantiations appearing in non-optimized binaries.
2020-12-14 11:19:22 -08:00
Philip Rideout 8f8d51e17b Code review fixups for libibl_lite. 2020-12-14 11:19:16 -08:00
Philip Rideout 6919e3b274 libibl: use C callback for progress 2020-12-14 11:19:09 -08:00
Philip Rideout 10bf944410 Add libibl_lite. 2020-12-14 11:19:03 -08:00
Philip Rideout 9a2f6fdb53 Vulkan: change vkWaitForFences usage for SwiftShader.
When passing only 1 fence to vkWaitForFences, the `waitAll` argument
should not have any effect, but SwiftShader seems to skip the wait
when this argument is set to VK_FALSE.

More specifically, the failure to wait in `acquireWorkCommandBuffer`
causes the subsequent destruction of an in-use fence, which causes
a TSAN failure with Google's internal tests.

I am consulting with the SwiftShader team on a real fix, meanwhile
we can commit this easy workaround.

We have 5 usages of vkWaitForFences, one of which uses multiple fences
and should have used VK_TRUE anyway.
2020-11-20 09:37:54 -08:00
Philip Rideout 761977d385 Filament should always bind an IBL texture.
This prevents a SwiftShader crash and/or a slew of "no texture bound"
warnings that would appear when the client provides an IBL without
providing reflections texture, which should be a valid thing to do.

Note that it is okay to declare a sampler in GLSL that never gets bound,
as long as it is never sampled from. Since we always sample from the
IBL specular texture, we should always bind something to it.
2020-11-19 13:28:19 -08:00
Ben Doherty 21248f15b5 Fix, matc crash when building mobile materials (#3296) 2020-11-16 14:37:55 -08:00
Benjamin Doherty 4f32817f6d Bump version to 1.9.10 2020-11-16 12:37:49 -08:00
Benjamin Doherty cc9e05e711 Merge branch 'rc/1.9.9' into release 2020-11-16 12:34:13 -08:00
Benjamin Doherty 419d68d4db Update RELEASE_NOTES for 1.9.9 2020-11-16 12:17:02 -08:00
Philip Rideout 8450232448 Improve the "unbound texture" warnings.
With Vulkan, this warning would sometimes be a false positive. It could
trigger for internal samplers like `ssao` and `structure`, even though
they were not declared in SPIR-V.

With OpenGL, this warning would never be a false positive because it has
the luxury of calling `glGetUniformLocation`.

This adds a private attribute to our samplers called `strict` that
indicates whether or not a sampler should always have a bound texture.
For now the only strict samplers are the custom ones declared in the
user's material.

At some point I think we should consider adding `spirv-reflect` to our
tree to help with problems like this.
2020-11-12 16:21:13 -08:00
Philip Rideout cc51726590 Vulkan: improve robustness by providing 1x1 fallback. 2020-11-12 10:36:13 -08:00
Philip Rideout 318e22af51 Fix clear behavior with RenderTarget API.
This fixes a bug seen with client applications that use ClearOptions
instead of Skybox, and one or more offscreen RenderTarget objects.
These apps would see junk pixels because Filament would only clear the
first render target in the frame.

The fix is to factor some the flag-setting logic in `beginFrame()` into
a private method, and call this method from `render()` each time
the user-level RenderTarget has been changed.

I wrote a simple C++ demo to reproduce the issue and to verify that
this fix works.
2020-11-11 09:25:36 -08:00
Philip Rideout 68ac87dc24 NOOP backend should not care about GLSL vs SPIRV.
This fixes errors that would occur when using the NOOP backend with
materials that were built without OpenGL support.
2020-11-10 15:44:01 -08:00
Benjamin Doherty acb8f00075 Bump version to 1.9.9 2020-11-09 09:32:55 -08:00
Benjamin Doherty 06d9183aaa Merge branch 'rc/1.9.8' into release 2020-11-09 09:28:58 -08:00
Benjamin Doherty 75af25419d Update RELEASE_NOTES for 1.9.8 2020-11-09 09:26:27 -08:00
Benjamin Doherty f6b90d2a31 Bump version to 1.9.8 2020-11-09 09:21:36 -08:00
Philip Rideout a3822f4af0 Fix FENCE_WAIT_FOR_EVER in Linux.
The number of infinite nanoseconds was negative because we asked
chrono for a signed integer, so "wait forever" really meant "do not
wait at all".
2020-11-02 16:12:53 -08:00
Benjamin Doherty bcdad769ff Merge branch 'rc/1.9.7' into release 2020-11-02 11:03:57 -07:00
Benjamin Doherty be4fb4fdbb Update RELEASE_NOTES for 1.9.7 2020-11-02 10:59:19 -07:00
Benjamin Doherty 65394f6301 Bump version to 1.9.7 2020-10-26 11:34:20 -06:00
Benjamin Doherty b0beee03bc Merge branch 'rc/1.9.6' into release 2020-10-26 11:29:45 -06:00
Benjamin Doherty fe1de41b8e Update RELEASE_NOTES for 1.9.6 2020-10-26 11:25:31 -06:00
Benjamin Doherty a37b431e87 Bump version to 1.9.6 2020-10-19 11:55:13 -06:00
Benjamin Doherty 98107016b9 Merge branch 'rc/1.9.5' into release 2020-10-19 11:51:30 -06:00
Benjamin Doherty 8bccfc2863 Update RELEASE_NOTES for 1.9.5 2020-10-19 11:49:05 -06:00
Benjamin Doherty f54a0a3452 Fix CocoaPod version 2020-10-13 15:15:02 -06:00
Benjamin Doherty 6778ab0624 Fix CocoaPod version 2020-10-13 15:09:59 -06:00
Benjamin Doherty 269d636785 Bump version to 1.9.5 2020-10-12 12:03:29 -06:00
Benjamin Doherty 39862c91ce Merge branch 'rc/1.9.4' into release 2020-10-12 11:56:24 -06:00
Benjamin Doherty 523f4026b4 Update RELEASE_NOTES for 1.9.4 2020-10-12 11:52:01 -06:00
Benjamin Doherty a6bf162431 Bump version to 1.9.4 2020-10-07 16:06:23 -06:00
Benjamin Doherty 826e8d181c Merge branch 'rc/1.9.3' into release 2020-10-05 11:36:16 -06:00
Benjamin Doherty 16dfadbba0 Update RELEASE_NOTES for 1.9.3 2020-10-05 11:29:36 -06:00
Benjamin Doherty 5cbb97551f Bump version to 1.9.3 2020-09-28 11:40:31 -06:00
Benjamin Doherty defee767c3 Merge branch 'rc/1.9.2' into release 2020-09-28 11:27:47 -06:00
Benjamin Doherty 9560318521 Update RELEASE_NOTES for 1.9.2 2020-09-28 11:26:21 -06:00
Benjamin Doherty ef09feb048 Bump version to 1.9.2 2020-09-21 11:16:53 -06:00
Benjamin Doherty 39f323fe09 Merge branch 'rc/1.9.1' into release 2020-09-21 11:00:07 -06:00
Benjamin Doherty 11b95304ea Merge branch 'release' into rc/1.9.1 2020-09-21 10:59:52 -06:00
Benjamin Doherty b7c30a7916 Update RELEASE_NOTES for 1.9.1 2020-09-21 10:59:06 -06:00
Benjamin Doherty 4cae48fc77 Bump version to 1.9.1 2020-09-14 11:51:36 -07:00
Benjamin Doherty d1a93f0557 Update release notes for 1.9.0 2020-09-14 10:54:28 -07:00
Benjamin Doherty b93059fad7 Bump version to 1.9.0 2020-09-08 10:47:23 -07:00
2121 changed files with 196250 additions and 286784 deletions
+2 -4
View File
@@ -4,8 +4,6 @@ about: Create a report to help us improve
---
⚠️ **Issues not using this template will be systematically closed.**
**Describe the bug**
A clear and concise description of what the bug is.
@@ -20,8 +18,8 @@ A clear and concise description of what you expected to happen.
If applicable, add screenshots to help explain your problem.
**Logs**
If applicable, copy **full** logs from your console here. Please *do not*
use screenshots of logs, copy them as text, use gist or attach an *uncompressed* file.
If applicable, copy logs from your console here. Please *do not*
use screenshots of logs, copy them as text.
**Desktop (please complete the following information):**
- OS: [e.g. iOS]
-4
View File
@@ -14,10 +14,6 @@ jobs:
steps:
- uses: actions/checkout@v3.3.0
- uses: actions/setup-java@v3
with:
distribution: 'temurin'
java-version: '17'
- name: Run build script
run: |
cd build/android && printf "y" | ./build.sh continuous
-4
View File
@@ -44,10 +44,6 @@ jobs:
steps:
- uses: actions/checkout@v3.3.0
- uses: actions/setup-java@v3
with:
distribution: 'temurin'
java-version: '17'
- name: Run build script
run: |
cd build/android && printf "y" | ./build.sh presubmit
-4
View File
@@ -112,10 +112,6 @@ jobs:
- uses: actions/checkout@v3.3.0
with:
ref: ${{ steps.git_ref.outputs.ref }}
- uses: actions/setup-java@v3
with:
distribution: 'temurin'
java-version: '17'
- name: Run build script
env:
TAG: ${{ steps.git_ref.outputs.tag }}
+10 -11
View File
@@ -5,7 +5,7 @@
To build Filament, you must first install the following tools:
- CMake 3.19 (or more recent)
- clang 14.0 (or more recent)
- clang 7.0 (or more recent)
- [ninja 1.10](https://github.com/ninja-build/ninja/wiki/Pre-built-Ninja-packages) (or more recent)
Additional dependencies may be required for your operating system. Please refer to the appropriate
@@ -13,10 +13,9 @@ section below.
To build Filament for Android you must also install the following:
- Android Studio Flamingo or more recent
- Android Studio Arctic Fox or more recent
- Android SDK
- Android NDK 25.1 or higher
- Java 17
### Environment variables
@@ -78,7 +77,7 @@ To turn an option on or off:
```
$ cd <cmake-build-directory>
$ cmake . -DOPTION=ON # Replace OPTION with the option name, set to ON / OFF
$ cmake . -DOPTION=ON # Relace OPTION with the option name, set to ON / OFF
```
Options can also be set with the CMake GUI.
@@ -87,10 +86,10 @@ Options can also be set with the CMake GUI.
Make sure you've installed the following dependencies:
- `clang-14` or higher
- `clang-7` or higher
- `libglu1-mesa-dev`
- `libc++-14-dev` (`libcxx-devel` and `libcxx-static` on Fedora) or higher
- `libc++abi-14-dev` (`libcxxabi-static` on Fedora) or higher
- `libc++-7-dev` (`libcxx-devel` and `libcxx-static` on Fedora) or higher
- `libc++abi-7-dev` (`libcxxabi-static` on Fedora) or higher
- `ninja-build`
- `libxi-dev`
- `libxcomposite-dev` (`libXcomposite-devel` on Fedora)
@@ -114,7 +113,7 @@ Your Linux distribution might default to `gcc` instead of `clang`, if that's the
```
$ mkdir out/cmake-release
$ cd out/cmake-release
# Or use a specific version of clang, for instance /usr/bin/clang-14
# Or use a specific version of clang, for instance /usr/bin/clang-7
$ CC=/usr/bin/clang CXX=/usr/bin/clang++ CXXFLAGS=-stdlib=libc++ \
cmake -G Ninja -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=../release/filament ../..
```
@@ -124,8 +123,8 @@ solution is to use `update-alternatives` to both change the default compiler, an
specific version of clang:
```
$ update-alternatives --install /usr/bin/clang clang /usr/bin/clang-14 100
$ update-alternatives --install /usr/bin/clang++ clang++ /usr/bin/clang++-14 100
$ update-alternatives --install /usr/bin/clang clang /usr/bin/clang-7 100
$ update-alternatives --install /usr/bin/clang++ clang++ /usr/bin/clang++-7 100
$ update-alternatives --install /usr/bin/cc cc /usr/bin/clang 100
$ update-alternatives --install /usr/bin/c++ c++ /usr/bin/clang++ 100
```
@@ -181,7 +180,7 @@ Install the following components:
- [Python 3.7](https://www.python.org/ftp/python/3.7.0/python-3.7.0.exe)
- [CMake 3.14 or later](https://github.com/Kitware/CMake/releases/download/v3.14.7/cmake-3.14.7-win64-x64.msi)
The latest Windows SDK can also be installed by opening Visual Studio and selecting _Get Tools and
The latest Windows SDK can also by installed by opening Visual Studio and selecting _Get Tools and
Features..._ under the _Tools_ menu.
By default, Windows treats the file system as case insensitive. Please do not enable case
+1 -12
View File
@@ -124,16 +124,11 @@ if (LINUX)
add_definitions(-DFILAMENT_SUPPORTS_XCB)
endif()
# Default Swiftshader build does not enable the xlib extension
if (FILAMENT_SUPPORTS_XLIB AND FILAMENT_USE_SWIFTSHADER)
set(FILAMENT_SUPPORTS_XLIB OFF)
endif()
if (FILAMENT_SUPPORTS_XLIB)
add_definitions(-DFILAMENT_SUPPORTS_XLIB)
endif()
if (FILAMENT_SUPPORTS_XCB OR FILAMENT_SUPPORTS_XLIB)
if (FILAMENT_SUPPORTS_XCB OR FILAMENT_SUPORTS_XLIB)
add_definitions(-DFILAMENT_SUPPORTS_X11)
set(FILAMENT_SUPPORTS_X11 TRUE)
endif()
@@ -372,12 +367,6 @@ if (ANDROID OR IOS OR WEBGL)
endif()
endif()
# Turn off exceptions on iOS debug as well. This fixes an availability error we see when using
# std::visit, which is not supported on iOS 11.0 when exceptions are enabled.
if (IOS)
set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -fno-exceptions")
endif()
# With WebGL, we disable RTTI even for debug builds because we pass emscripten::val back and forth
# between C++ and JavaScript in order to efficiently access typed arrays, which are unbound.
# NOTE: This is not documented in emscripten so we should consider a different approach.
+1 -1
View File
@@ -187,7 +187,7 @@
same "printed page" as the copyright notice for easier
identification within third-party archives.
Copyright 2023 The Android Open Source Project
Copyright [yyyy] [name of copyright owner]
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
-6
View File
@@ -7,9 +7,3 @@ for next branch cut* header.
appropriate header in [RELEASE_NOTES.md](./RELEASE_NOTES.md).
## Release notes for next branch cut
- Fix possible NPE when updating fog options from Java/Kotlin
- The `emissive` property was not applied properly to `MASKED` materials, and could cause
dark fringes to appear (recompile materials)
- Allow glTF materials with transmission/volume extensions to choose their alpha mode
instead of forcing `MASKED`
+3 -3
View File
@@ -31,7 +31,7 @@ repositories {
}
dependencies {
implementation 'com.google.android.filament:filament-android:1.42.0'
implementation 'com.google.android.filament:filament-android:1.32.0'
}
```
@@ -40,8 +40,8 @@ Here are all the libraries available in the group `com.google.android.filament`:
| Artifact | Description |
| ------------- | ------------- |
| [![filament-android](https://maven-badges.herokuapp.com/maven-central/com.google.android.filament/filament-android/badge.svg?subject=filament-android)](https://maven-badges.herokuapp.com/maven-central/com.google.android.filament/filament-android) | The Filament rendering engine itself. |
| [![filament-android-debug](https://maven-badges.herokuapp.com/maven-central/com.google.android.filament/filament-android-debug/badge.svg?subject=filament-android-debug)](https://maven-badges.herokuapp.com/maven-central/com.google.android.filament/filament-android-debug) | Debug version of `filament-android`. |
| [![gltfio-android](https://maven-badges.herokuapp.com/maven-central/com.google.android.filament/gltfio-android/badge.svg?subject=gltfio-android)](https://maven-badges.herokuapp.com/maven-central/com.google.android.filament/gltfio-android) | A glTF 2.0 loader for Filament, depends on `filament-android`. |
| [![gltfio-android-lite](https://maven-badges.herokuapp.com/maven-central/com.google.android.filament/gltfio-android-lite/badge.svg?subject=gltfio-android-lite)](https://maven-badges.herokuapp.com/maven-central/com.google.android.filament/gltfio-android-lite) | Trimmed version of `gltfio` that does not support some glTF extensions. |
| [![filament-utils-android](https://maven-badges.herokuapp.com/maven-central/com.google.android.filament/filament-utils-android/badge.svg?subject=filament-utils-android)](https://maven-badges.herokuapp.com/maven-central/com.google.android.filament/filament-utils-android) | KTX loading, Kotlin math, and camera utilities, depends on `gltfio-android`. |
| [![filamat-android](https://maven-badges.herokuapp.com/maven-central/com.google.android.filament/filamat-android/badge.svg?subject=filamat-android)](https://maven-badges.herokuapp.com/maven-central/com.google.android.filament/filamat-android) | A runtime material builder/compiler. This library is large but contains a full shader compiler/validator/optimizer and supports both OpenGL and Vulkan. |
| [![filamat-android-lite](https://maven-badges.herokuapp.com/maven-central/com.google.android.filament/filamat-android-lite/badge.svg?subject=filamat-android-lite)](https://maven-badges.herokuapp.com/maven-central/com.google.android.filament/filamat-android-lite) | A much smaller alternative to `filamat-android` that can only generate OpenGL shaders. It does not provide validation or optimizations. |
@@ -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.42.0'
pod 'Filament', '~> 1.32.0'
```
### Snapshots
+59 -18
View File
@@ -9,15 +9,26 @@ Before starting, ensure that each of these branches is up-to-date with origin:
- rc/$RELEASE
- main
## 0. Check versions.
## 0. Make sure the rc/$RELEASE branch has the correct version.
Make sure the rc/$RELEASE branch has the correct Filament version. It should have the version
corresponding to its name, $RELEASE.
It should have the version corresponding to its name, $RELEASE.
Make sure `MATERIAL_VERSION` has been bumped to a new version if this is a MAJOR or MINOR release
(first two version numbers).
## 1. Update RELEASE_NOTES.md on the rc branch.
## 1. Bump Filament versions on main to $RELEASE.
Checkout the rc/$RELEASE branch. In RELEASE_NOTES.md, locate the header corresponding to $RELEASE
and write release notes. To see which commits make up the release, run:
```
build/common/release.sh -c rc/$RELEASE
```
Commit the changes to rc/$RELEASE with the title:
```
Update RELEASE_NOTES for $RELEASE
```
## 2. Bump versions on main to $RELEASE.
Checkout main and run the following command to bump Filament's version to $RELEASE:
@@ -33,19 +44,49 @@ Release Filament $RELEASE
Do not push to origin yet.
## 2. Update RELEASE_NOTES.md on main.
## 3. Cherry-pick RELEASE_NOTES change from rc branch to main.
Create a new header in RELEASE_NOTES.md for $NEXT_RELEASE. Copy the release notes in
NEW_RELEASE_NOTES.md to RELEASE_NOTES.md under the new header. Clear NEW_RELEASE_NOTES.md.
```
git cherry-pick rc/$RELEASE
```
Amend these changes to the "Release Filament $RELEASE" commit.
Update the headers. The "main branch" header becomes a header for $NEXT_RELEASE, and a new "main
branch" header is added.
For example, this:
```
## main branch
- foo
- bar
## v1.9.3
- baz
- bat
```
becomes:
```
## main branch
## v1.9.4
- foo
- bar
## v1.9.3
- baz
- bat
```
Ammend these changes to the cherry-picked change.
```
git add -u
git commit --amend --no-edit
```
## 3. Run release script.
## 4. Run release script.
```
build/common/release.sh rc/$RELEASE rc/$NEXT_RELEASE
@@ -54,18 +95,18 @@ build/common/release.sh rc/$RELEASE rc/$NEXT_RELEASE
This script will merge rc/$RELEASE into release, delete the rc branch, and create a new rc
branch called rc/$NEXT_RELEASE. Verify that everything looks okay locally.
## 4. Push the release branch.
## 5. Push the release branch.
```
git push origin release
```
## 5. Create the GitHub release.
## 6. Create the GitHub release.
Use the GitHub UI to create a GitHub release corresponding to $RELEASE version.
Make sure the target is set to the release branch.
## 6. Delete the old rc branch (optional).
## 7. Delete the old rc branch (optional).
This step is optional. The old rc branch may be left alive for a few weeks for posterity.
@@ -73,7 +114,7 @@ This step is optional. The old rc branch may be left alive for a few weeks for p
git push origin --delete rc/$RELEASE
```
## 7. Bump the version on the new rc branch to $NEXT_RELEASE.
## 8. Bump the version on the new rc branch to $NEXT_RELEASE.
```
git checkout rc/$NEXT_RELEASE
@@ -86,19 +127,19 @@ Commit the changes to rc/$NEXT_RELEASE with the title:
Bump version to $NEXT_RELEASE
```
## 8. Push main.
## 9. Push main.
```
git push origin main
```
## 9. Push the new rc branch.
## 10. Push the new rc branch.
```
git push origin -u rc/$NEXT_RELEASE
```
## 10. Rebuild the GitHub release (if failed).
## 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.
-110
View File
@@ -7,116 +7,6 @@ A new header is inserted each time a *tag* is created.
Instead, if you are authoring a PR for the main branch, add your release note to
[NEW_RELEASE_NOTES.md](./NEW_RELEASE_NOTES.md).
## v1.42.1
## v1.42.0
- engine: add preliminary support for instanced stereoscopic rendering [⚠️ **Recompile materials**]
## v1.41.0
- backend: fix #6997 : picking can fail on Adreno [⚠️ **New Material Version**]
- backend: A partial workaround for PowerVR devices (#5118, b/190221124) [⚠️ **Recompile Materials**]
## v1.40.5
- backend: Disable timer queries on all Mali GPUs (fixes b/233754398)
- engine: Add a way to query the validity of most filament objects (see `Engine::isValid`)
- opengl: fix b/290388359 : possible crash when shutting down the engine
- engine: Improve precision of frame time measurement when using emulated TimerQueries
- backend: Improve frame pacing on Android and Vulkan.
- backend: workaround b/291140208 (gltf_viewer crashes on Nexus 6P)
- engine: support `setDepthFunc` for `MaterialInstance`
- web: Added setDepthFunc()/getDepthFunc() to MaterialInstance
- android: Added setDepthFunc()/getDepthFunc() to MaterialInstance
## v1.40.4
- gltfio: fix crash when compute morph target without material
- matc: fix buggy `variant-filter` flag
- web: Added missing setMat3Parameter()/setMat4Parameter() to MaterialInstance
- opengl: fix b/290670707 : crash when using the blob cache
- engine: fix a crash with `Material::compile()` when a callback is specified
## v1.40.3
## v1.40.2
- rendering: dynamic resolution would not work with a translucent render target and quality > low
- Java/Kotlin: user callbacks were not invoked on successful texture upload
## v1.40.1
## v1.40.0
- matc: fix VSM high precision option on mobile [⚠️ **Recompile materials**]
- vulkan: support sRGB swap chain
- Add new `getMaxAutomaticInstances()` API on `Engine` to get max supported automatic instances.
- UiHelper: fix jank when a `TextureView` is resized (fixes b\282220665)
- backend: parallel shader compilation support. This breaks and improves the recent `Material::compile` API.
## v1.39.0
- matc: workaround a bug in spirv-tools causing vsm to fail [⚠️ **Recompile materials**]
## v1.38.0
- engine: a new feature to set a transform on the global-scale fog [⚠️ **Recompile materials**]
- engine: large-scale fog can now be opted-out on a per-renderable basis
- engine: improve froxelizer resource efficiency [⚠️ **Recompile materials**]
- matc: better accounting and validation of used samplers in user materials
- engine: add support for sampling fog color from a custom texture [⚠️ **Recompile materials**]
- vulkan: introduce new custom swapchain API
- vulkan: new context sharing API
## v1.37.0
- backend: added `Platform` blob cache APIs, typically used to cache programs [⚠️ **Recompile materials**]
## v1.36.0
- engine: a local transform can now be supplied for each GPU instance [⚠️ **Recompile materials**]
- everything: Add limited support for OpenGL ES 2.0 devices. [⚠️ **Recompile Materials**]
- platform: New virtual on `OpenGLPlatform` to preserve ancillary buffers
## v1.35.0
- materials: Materials can now access up to 4 global `vec4` visible by all materials [⚠️ **Recompile Materials**]
## v1.34.0
- materials: picking is done in float (prepare for ES2) [⚠️ **New Material Version**]
- materials: postLightingBlending is now applied before the fog [⚠️ **Recompile materials**]
- vulkan: fix adreno optimized material artifacts [⚠️ **Recompile Materials**]
## v1.33.0
- materials: prepare ES2 support [⚠️ **New Material Version**]
## v1.32.4
- engine: Add support for _constant parameters_, which are constants that can be specialized after material compilation.
- materials: improved size reduction of OpenGL/Metal shaders by ~65% when compiling materials with
size optimizations (`matc -S`) [⚠️ **Recompile Materials**]
- engine: fix potential crash on Metal devices with A8X GPU (iPad Air 2) [⚠️ **Recompile Materials**]
- opengl: support the external image on macOS
## v1.32.3
- fog: added an option to disable the fog after a certain distance [⚠️ **Recompile Materials**].
- fog: fog color now takes exposure and IBL intensity into account [⚠️ **Recompile Materials**].
- materials: implement cascades debugging as a post-process [⚠️ **Recompile Materials**].
- materials: use 9 digits or less for floats [⚠️ **Recompile Materials**].
- gltfio: fix skinning when objects are far from the origin
- materials: remove 4 unneeded variants from `unlit` materials [⚠️ **Recompile Materials**].
## v1.32.2
- lighting: the sun disc was computed in low/medium quality instead of high quality. This will
provide performance improvements to mobile devices [⚠️ **Recompile Materials**]
## v1.32.1
## v1.32.0
- fog: fixed fog height falloff and computation precision on mobile [⚠️ **Recompile Materials**]
+1 -1
View File
@@ -135,7 +135,7 @@ gradlew -Pcom.google.android.filament.dist-dir=..\out\android-release\filament a
If you're only interested in building SDK, you may skip samples build by passing a `com.google.android.filament.skip-samples` flag:
```
gradlew -Pcom.google.android.filament.dist-dir=..\out\android-release\filament assembleRelease -Pcom.google.android.filament.skip-samples
gradlew -Pcom.google.android.filament.dist-dir=..\out\android-release\filament assembleRelease -Pfilament_skip_samples
```
+9 -12
View File
@@ -79,16 +79,15 @@ buildscript {
}
ext.versions = [
'jdk': 17,
'minSdk': 19,
'targetSdk': 33,
'compileSdk': 33,
'kotlin': '1.9.0',
'kotlin_coroutines': '1.7.2',
'buildTools': '34.0.0',
'kotlin': '1.8.0',
'kotlin_coroutines': '1.6.4',
'buildTools': '33.0.1',
'ndk': '25.1.8937393',
'androidx_core': '1.10.1',
'androidx_annotations': '1.6.0'
'androidx_core': '1.9.0',
'androidx_annotations': '1.3.0'
]
ext.deps = [
@@ -104,7 +103,7 @@ buildscript {
]
dependencies {
classpath 'com.android.tools.build:gradle:8.1.0'
classpath 'com.android.tools.build:gradle:7.4.0'
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:${versions.kotlin}"
}
@@ -127,7 +126,6 @@ buildscript {
"-fno-asynchronous-unwind-tables",
"-fno-rtti",
"-ffast-math",
"-fno-finite-math-only",
"-ffp-contract=fast",
"-fvisibility-inlines-hidden",
"-fvisibility=hidden",
@@ -152,7 +150,7 @@ buildscript {
}
plugins {
id "io.github.gradle-nexus.publish-plugin" version "1.3.0"
id "io.github.gradle-nexus.publish-plugin" version "1.1.0"
}
// See https://github.com/gradle-nexus/publish-plugin
@@ -195,7 +193,6 @@ subprojects {
}
ndk {
//noinspection ChromeOsAbiSupport
abiFilters(*rootProject.ext.abis)
}
@@ -216,8 +213,8 @@ subprojects {
}
compileOptions {
sourceCompatibility versions.jdk
targetCompatibility versions.jdk
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
}
}
@@ -142,14 +142,6 @@ abstract class MaterialCompiler extends TaskWithBinary {
if (!exclude_vulkan) {
matcArgs += ['-a', 'vulkan']
}
def mat_no_opt = providers
.gradleProperty("com.google.android.filament.matnopt")
.forUseAtConfigurationTime().present
if (mat_no_opt) {
matcArgs += ['-g']
}
matcArgs += ['-a', 'opengl', '-p', 'mobile', '-o', getOutputFile(file), file]
exec.exec {
-11
View File
@@ -17,17 +17,6 @@ android {
}
}
}
publishing {
singleVariant("fullRelease") {
withSourcesJar()
withJavadocJar()
}
singleVariant("liteRelease") {
withSourcesJar()
withJavadocJar()
}
}
}
dependencies {
-7
View File
@@ -1,12 +1,5 @@
android {
namespace 'com.google.android.filament'
publishing {
singleVariant("release") {
withSourcesJar()
withJavadocJar()
}
}
}
dependencies {
@@ -278,112 +278,6 @@ Java_com_google_android_filament_Engine_nDestroyEntity(JNIEnv*, jclass,
engine->destroy(entity);
}
extern "C" JNIEXPORT jboolean JNICALL
Java_com_google_android_filament_Engine_nIsValidRenderer(JNIEnv*, jclass,
jlong nativeEngine, jlong nativeRenderer) {
Engine* engine = (Engine *)nativeEngine;
return (jboolean)engine->isValid((Renderer*)nativeRenderer);
}
extern "C" JNIEXPORT jboolean JNICALL
Java_com_google_android_filament_Engine_nIsValidView(JNIEnv*, jclass,
jlong nativeEngine, jlong nativeView) {
Engine* engine = (Engine *)nativeEngine;
return (jboolean)engine->isValid((View*)nativeView);
}
extern "C" JNIEXPORT jboolean JNICALL
Java_com_google_android_filament_Engine_nIsValidScene(JNIEnv*, jclass,
jlong nativeEngine, jlong nativeScene) {
Engine* engine = (Engine *)nativeEngine;
return (jboolean)engine->isValid((Scene*)nativeScene);
}
extern "C" JNIEXPORT jboolean JNICALL
Java_com_google_android_filament_Engine_nIsValidFence(JNIEnv*, jclass,
jlong nativeEngine, jlong nativeFence) {
Engine* engine = (Engine *)nativeEngine;
return (jboolean)engine->isValid((Fence*)nativeFence);
}
extern "C" JNIEXPORT jboolean JNICALL
Java_com_google_android_filament_Engine_nIsValidStream(JNIEnv*, jclass,
jlong nativeEngine, jlong nativeStream) {
Engine* engine = (Engine *)nativeEngine;
return (jboolean)engine->isValid((Stream*)nativeStream);
}
extern "C" JNIEXPORT jboolean JNICALL
Java_com_google_android_filament_Engine_nIsValidIndexBuffer(JNIEnv*, jclass,
jlong nativeEngine, jlong nativeIndexBuffer) {
Engine* engine = (Engine *)nativeEngine;
return (jboolean)engine->isValid((IndexBuffer*)nativeIndexBuffer);
}
extern "C" JNIEXPORT jboolean JNICALL
Java_com_google_android_filament_Engine_nIsValidVertexBuffer(JNIEnv*, jclass,
jlong nativeEngine, jlong nativeVertexBuffer) {
Engine* engine = (Engine *)nativeEngine;
return (jboolean)engine->isValid((VertexBuffer*)nativeVertexBuffer);
}
extern "C" JNIEXPORT jboolean JNICALL
Java_com_google_android_filament_Engine_nIsValidSkinningBuffer(JNIEnv*, jclass,
jlong nativeEngine, jlong nativeSkinningBuffer) {
Engine* engine = (Engine *)nativeEngine;
return (jboolean)engine->isValid((SkinningBuffer*)nativeSkinningBuffer);
}
extern "C" JNIEXPORT jboolean JNICALL
Java_com_google_android_filament_Engine_nIsValidIndirectLight(JNIEnv*, jclass,
jlong nativeEngine, jlong nativeIndirectLight) {
Engine* engine = (Engine *)nativeEngine;
return (jboolean)engine->isValid((IndirectLight*)nativeIndirectLight);
}
extern "C" JNIEXPORT jboolean JNICALL
Java_com_google_android_filament_Engine_nIsValidMaterial(JNIEnv*, jclass,
jlong nativeEngine, jlong nativeMaterial) {
Engine* engine = (Engine *)nativeEngine;
return (jboolean)engine->isValid((Material*)nativeMaterial);
}
extern "C" JNIEXPORT jboolean JNICALL
Java_com_google_android_filament_Engine_nIsValidSkybox(JNIEnv*, jclass,
jlong nativeEngine, jlong nativeSkybox) {
Engine* engine = (Engine *)nativeEngine;
return (jboolean)engine->isValid((Skybox*)nativeSkybox);
}
extern "C" JNIEXPORT jboolean JNICALL
Java_com_google_android_filament_Engine_nIsValidColorGrading(JNIEnv*, jclass,
jlong nativeEngine, jlong nativeColorGrading) {
Engine* engine = (Engine *)nativeEngine;
return (jboolean)engine->isValid((ColorGrading*)nativeColorGrading);
}
extern "C" JNIEXPORT jboolean JNICALL
Java_com_google_android_filament_Engine_nIsValidTexture(JNIEnv*, jclass,
jlong nativeEngine, jlong nativeTexture) {
Engine* engine = (Engine *)nativeEngine;
return (jboolean)engine->isValid((Texture*)nativeTexture);
}
extern "C" JNIEXPORT jboolean JNICALL
Java_com_google_android_filament_Engine_nIsValidRenderTarget(JNIEnv*, jclass,
jlong nativeEngine, jlong nativeTarget) {
Engine* engine = (Engine *)nativeEngine;
return (jboolean)engine->isValid((RenderTarget*)nativeTarget);
}
extern "C" JNIEXPORT jboolean JNICALL
Java_com_google_android_filament_Engine_nIsValidSwapChain(JNIEnv*, jclass,
jlong nativeEngine, jlong nativeSwapChain) {
Engine* engine = (Engine *)nativeEngine;
return (jboolean)engine->isValid((SwapChain*)nativeSwapChain);
}
extern "C" JNIEXPORT void JNICALL
Java_com_google_android_filament_Engine_nFlushAndWait(JNIEnv*, jclass,
jlong nativeEngine) {
@@ -246,21 +246,17 @@ Java_com_google_android_filament_MaterialInstance_nSetFloatParameterArray(JNIEnv
env->ReleaseStringUTFChars(name_, name);
}
// defined in TextureSampler.cpp
namespace filament::JniUtils {
TextureSampler from_long(jlong params) noexcept;
} // TextureSamplerJniUtils
extern "C"
JNIEXPORT void JNICALL
Java_com_google_android_filament_MaterialInstance_nSetParameterTexture(
JNIEnv *env, jclass, jlong nativeMaterialInstance, jstring name_,
jlong nativeTexture, jlong sampler_) {
jlong nativeTexture, jint sampler_) {
MaterialInstance* instance = (MaterialInstance*) nativeMaterialInstance;
Texture* texture = (Texture*) nativeTexture;
TextureSampler& sampler = reinterpret_cast<TextureSampler&>(sampler_);
const char *name = env->GetStringUTFChars(name_, 0);
instance->setParameter(name, texture, JniUtils::from_long(sampler_));
instance->setParameter(name, texture, sampler);
env->ReleaseStringUTFChars(name_, name);
}
@@ -361,14 +357,6 @@ Java_com_google_android_filament_MaterialInstance_nSetDepthCulling(JNIEnv*,
instance->setDepthCulling(enable);
}
extern "C"
JNIEXPORT void JNICALL
Java_com_google_android_filament_MaterialInstance_nSetDepthFunc(JNIEnv*,
jclass, jlong nativeMaterialInstance, jlong function) {
MaterialInstance* instance = (MaterialInstance*) nativeMaterialInstance;
instance->setDepthFunc(static_cast<MaterialInstance::DepthFunc>(function));
}
extern "C"
JNIEXPORT void JNICALL
Java_com_google_android_filament_MaterialInstance_nSetStencilCompareFunction(JNIEnv*, jclass,
@@ -536,11 +524,3 @@ Java_com_google_android_filament_MaterialInstance_nIsDepthCullingEnabled(JNIEnv*
MaterialInstance* instance = (MaterialInstance*)nativeMaterialInstance;
return instance->isDepthCullingEnabled();
}
extern "C"
JNIEXPORT jint JNICALL
Java_com_google_android_filament_MaterialInstance_nGetDepthFunc(JNIEnv* env, jclass clazz,
jlong nativeMaterialInstance) {
MaterialInstance* instance = (MaterialInstance*)nativeMaterialInstance;
return (jint)instance->getDepthFunc();
}
@@ -201,19 +201,12 @@ Java_com_google_android_filament_RenderableManager_nBuilderSkinning(JNIEnv*, jcl
}
extern "C" JNIEXPORT void JNICALL
Java_com_google_android_filament_RenderableManager_nBuilderEnableSkinningBuffers(JNIEnv*, jclass,
Java_com_google_android_filament_RenderableManager_nEnableSkinningBuffers(JNIEnv*, jclass,
jlong nativeBuilder, jboolean enabled) {
RenderableManager::Builder *builder = (RenderableManager::Builder *) nativeBuilder;
builder->enableSkinningBuffers(enabled);
}
extern "C" JNIEXPORT void JNICALL
Java_com_google_android_filament_RenderableManager_nBuilderFog(JNIEnv*, jclass,
jlong nativeBuilder, jboolean enabled) {
RenderableManager::Builder *builder = (RenderableManager::Builder *) nativeBuilder;
builder->fog(enabled);
}
extern "C" JNIEXPORT jint JNICALL
Java_com_google_android_filament_RenderableManager_nBuilderSkinningBones(JNIEnv* env, jclass,
jlong nativeBuilder, jint boneCount, jobject bones, jint remaining) {
@@ -367,20 +360,6 @@ Java_com_google_android_filament_RenderableManager_nSetCulling(JNIEnv*, jclass,
rm->setCulling((RenderableManager::Instance) i, enabled);
}
extern "C" JNIEXPORT void JNICALL
Java_com_google_android_filament_RenderableManager_nSetFogEnabled(JNIEnv*, jclass,
jlong nativeRenderableManager, jint i, jboolean enabled) {
RenderableManager *rm = (RenderableManager *) nativeRenderableManager;
rm->setFogEnabled((RenderableManager::Instance) i, enabled);
}
extern "C" JNIEXPORT jboolean JNICALL
Java_com_google_android_filament_RenderableManager_nGetFogEnabled(JNIEnv*, jclass,
jlong nativeRenderableManager, jint i) {
RenderableManager *rm = (RenderableManager *) nativeRenderableManager;
return (jboolean)rm->getFogEnabled((RenderableManager::Instance) i);
}
extern "C" JNIEXPORT void JNICALL
Java_com_google_android_filament_RenderableManager_nSetCastShadows(JNIEnv*, jclass,
jlong nativeRenderableManager, jint i, jboolean enabled) {
@@ -27,10 +27,11 @@ extern "C" JNIEXPORT void JNICALL
Java_com_google_android_filament_SwapChain_nSetFrameCompletedCallback(JNIEnv* env, jclass,
jlong nativeSwapChain, jobject handler, jobject runnable) {
SwapChain* swapChain = (SwapChain*) nativeSwapChain;
auto* callback = JniCallback::make(env, handler, runnable);
swapChain->setFrameCompletedCallback(nullptr, [callback](SwapChain* swapChain) {
auto *callback = JniCallback::make(env, handler, runnable);
swapChain->setFrameCompletedCallback([](void* user) {
JniCallback* callback = (JniCallback*)user;
JniCallback::postToJavaAndDestroy(callback);
});
}, callback);
}
extern "C" JNIEXPORT jboolean JNICALL
@@ -511,7 +511,9 @@ public:
private:
void* mData = nullptr;
jobject mBitmap{};
jobject mBitmap = nullptr;
jobject mHandler = nullptr;
jobject mCallback = nullptr;
AndroidBitmapInfo mInfo{};
};
@@ -18,139 +18,142 @@
#include <filament/TextureSampler.h>
#include <utils/algorithm.h>
using namespace filament;
namespace filament::JniUtils {
jlong to_long(TextureSampler const& sampler) noexcept {
return jlong(utils::bit_cast<uint32_t>(sampler.getSamplerParams()));
}
TextureSampler from_long(jlong params) noexcept {
return TextureSampler{
utils::bit_cast<backend::SamplerParams>(
static_cast<uint32_t>(params))};
}
} // namespace filament::JniUtils
using namespace JniUtils;
extern "C" JNIEXPORT jlong JNICALL
Java_com_google_android_filament_TextureSampler_nCreateSampler(JNIEnv *, jclass, jint min,
extern "C" JNIEXPORT jint JNICALL
Java_com_google_android_filament_TextureSampler_nCreateSampler(JNIEnv *env, jclass type, jint min,
jint max, jint s, jint t, jint r) {
TextureSampler sampler(static_cast<TextureSampler::MinFilter>(min),
static_cast<TextureSampler::MagFilter>(max),
static_cast<TextureSampler::WrapMode>(s),
static_cast<TextureSampler::WrapMode>(t),
static_cast<TextureSampler::WrapMode>(r));
return to_long(sampler);
return TextureSampler(static_cast<TextureSampler::MinFilter>(min),
static_cast<TextureSampler::MagFilter>(max), static_cast<TextureSampler::WrapMode>(s),
static_cast<TextureSampler::WrapMode>(t),
static_cast<TextureSampler::WrapMode>(r)).getSamplerParams().u;
}
extern "C" JNIEXPORT jlong JNICALL
Java_com_google_android_filament_TextureSampler_nCreateCompareSampler(JNIEnv *, jclass,
extern "C" JNIEXPORT jint JNICALL
Java_com_google_android_filament_TextureSampler_nCreateCompareSampler(JNIEnv *env, jclass type,
jint mode, jint function) {
TextureSampler sampler(static_cast<TextureSampler::CompareMode>(mode),
static_cast<TextureSampler::CompareFunc>(function));
return to_long(sampler);
return TextureSampler(static_cast<TextureSampler::CompareMode>(mode),
static_cast<TextureSampler::CompareFunc>(function)).getSamplerParams().u;
}
extern "C" JNIEXPORT jint JNICALL
Java_com_google_android_filament_TextureSampler_nGetMinFilter(JNIEnv *, jclass, jlong sampler) {
return static_cast<jint>(from_long(sampler).getMinFilter());
Java_com_google_android_filament_TextureSampler_nGetMinFilter(JNIEnv *env, jclass type,
jint sampler_) {
TextureSampler &sampler = reinterpret_cast<TextureSampler &>(sampler_);
return static_cast<jint>(sampler.getMinFilter());
}
extern "C" JNIEXPORT jlong JNICALL
Java_com_google_android_filament_TextureSampler_nSetMinFilter(JNIEnv *, jclass, jlong sampler_, jint filter) {
TextureSampler sampler{from_long(sampler_)};
extern "C" JNIEXPORT jint JNICALL
Java_com_google_android_filament_TextureSampler_nSetMinFilter(JNIEnv *env, jclass type,
jint sampler_, jint filter) {
TextureSampler &sampler = reinterpret_cast<TextureSampler &>(sampler_);
sampler.setMinFilter(static_cast<TextureSampler::MinFilter>(filter));
return to_long(sampler);
return sampler.getSamplerParams().u;
}
extern "C" JNIEXPORT jint JNICALL
Java_com_google_android_filament_TextureSampler_nGetMagFilter(JNIEnv *, jclass, jlong sampler) {
return static_cast<jint>(from_long(sampler).getMagFilter());
Java_com_google_android_filament_TextureSampler_nGetMagFilter(JNIEnv *env, jclass type,
jint sampler_) {
TextureSampler &sampler = reinterpret_cast<TextureSampler &>(sampler_);
return static_cast<jint>(sampler.getMagFilter());
}
extern "C" JNIEXPORT jlong JNICALL
Java_com_google_android_filament_TextureSampler_nSetMagFilter(JNIEnv *, jclass, jlong sampler_, jint filter) {
TextureSampler sampler{from_long(sampler_)};
extern "C" JNIEXPORT jint JNICALL
Java_com_google_android_filament_TextureSampler_nSetMagFilter(JNIEnv *env, jclass type,
jint sampler_, jint filter) {
TextureSampler &sampler = reinterpret_cast<TextureSampler &>(sampler_);
sampler.setMagFilter(static_cast<TextureSampler::MagFilter>(filter));
return to_long(sampler);
return sampler.getSamplerParams().u;
}
extern "C" JNIEXPORT jint JNICALL
Java_com_google_android_filament_TextureSampler_nGetWrapModeS(JNIEnv *, jclass, jlong sampler) {
return static_cast<jint>(from_long(sampler).getWrapModeS());
Java_com_google_android_filament_TextureSampler_nGetWrapModeS(JNIEnv *env, jclass type,
jint sampler_) {
TextureSampler &sampler = reinterpret_cast<TextureSampler &>(sampler_);
return static_cast<jint>(sampler.getWrapModeS());
}
extern "C" JNIEXPORT jlong JNICALL
Java_com_google_android_filament_TextureSampler_nSetWrapModeS(JNIEnv *, jclass, jlong sampler_, jint mode) {
TextureSampler sampler{from_long(sampler_)};
extern "C" JNIEXPORT jint JNICALL
Java_com_google_android_filament_TextureSampler_nSetWrapModeS(JNIEnv *env, jclass type,
jint sampler_, jint mode) {
TextureSampler &sampler = reinterpret_cast<TextureSampler &>(sampler_);
sampler.setWrapModeS(static_cast<TextureSampler::WrapMode>(mode));
return to_long(sampler);
return sampler.getSamplerParams().u;
}
extern "C" JNIEXPORT jint JNICALL
Java_com_google_android_filament_TextureSampler_nGetWrapModeT(JNIEnv *, jclass, jlong sampler) {
return static_cast<jint>(from_long(sampler).getWrapModeT());
Java_com_google_android_filament_TextureSampler_nGetWrapModeT(JNIEnv *env, jclass type,
jint sampler_) {
TextureSampler &sampler = reinterpret_cast<TextureSampler &>(sampler_);
return static_cast<jint>(sampler.getWrapModeT());
}
extern "C" JNIEXPORT jlong JNICALL
Java_com_google_android_filament_TextureSampler_nSetWrapModeT(JNIEnv *, jclass, jlong sampler_, jint mode) {
TextureSampler sampler{from_long(sampler_)};
extern "C" JNIEXPORT jint JNICALL
Java_com_google_android_filament_TextureSampler_nSetWrapModeT(JNIEnv *env, jclass type,
jint sampler_, jint mode) {
TextureSampler &sampler = reinterpret_cast<TextureSampler &>(sampler_);
sampler.setWrapModeT(static_cast<TextureSampler::WrapMode>(mode));
return to_long(sampler);
return sampler.getSamplerParams().u;
}
extern "C" JNIEXPORT jint JNICALL
Java_com_google_android_filament_TextureSampler_nGetWrapModeR(JNIEnv *, jclass, jlong sampler) {
return static_cast<jint>(from_long(sampler).getWrapModeR());
Java_com_google_android_filament_TextureSampler_nGetWrapModeR(JNIEnv *env, jclass type,
jint sampler_) {
TextureSampler &sampler = reinterpret_cast<TextureSampler &>(sampler_);
return static_cast<jint>(sampler.getWrapModeR());
}
extern "C" JNIEXPORT jlong JNICALL
Java_com_google_android_filament_TextureSampler_nSetWrapModeR(JNIEnv *, jclass, jlong sampler_, jint mode) {
TextureSampler sampler{from_long(sampler_)};
extern "C" JNIEXPORT jint JNICALL
Java_com_google_android_filament_TextureSampler_nSetWrapModeR(JNIEnv *env, jclass type,
jint sampler_, jint mode) {
TextureSampler &sampler = reinterpret_cast<TextureSampler &>(sampler_);
sampler.setWrapModeR(static_cast<TextureSampler::WrapMode>(mode));
return to_long(sampler);
return sampler.getSamplerParams().u;
}
extern "C" JNIEXPORT jint JNICALL
Java_com_google_android_filament_TextureSampler_nGetCompareMode(JNIEnv *, jclass, jlong sampler) {
return static_cast<jint>(from_long(sampler).getCompareMode());
Java_com_google_android_filament_TextureSampler_nGetCompareMode(JNIEnv *env, jclass type,
jint sampler_) {
TextureSampler &sampler = reinterpret_cast<TextureSampler &>(sampler_);
return static_cast<jint>(sampler.getCompareMode());
}
extern "C" JNIEXPORT jlong JNICALL
Java_com_google_android_filament_TextureSampler_nSetCompareMode(JNIEnv *, jclass, jlong sampler_, jint mode) {
TextureSampler sampler{from_long(sampler_)};
extern "C" JNIEXPORT jint JNICALL
Java_com_google_android_filament_TextureSampler_nSetCompareMode(JNIEnv *env, jclass type,
jint sampler_, jint mode) {
TextureSampler &sampler = reinterpret_cast<TextureSampler &>(sampler_);
sampler.setCompareMode(static_cast<TextureSampler::CompareMode>(mode),
sampler.getCompareFunc());
return to_long(sampler);
return sampler.getSamplerParams().u;
}
extern "C" JNIEXPORT jint JNICALL
Java_com_google_android_filament_TextureSampler_nGetCompareFunction(JNIEnv *, jclass, jlong sampler) {
return static_cast<jint>(from_long(sampler).getCompareFunc());
Java_com_google_android_filament_TextureSampler_nGetCompareFunction(JNIEnv *env, jclass type,
jint sampler_) {
TextureSampler &sampler = reinterpret_cast<TextureSampler &>(sampler_);
return static_cast<jint>(sampler.getCompareFunc());
}
extern "C" JNIEXPORT jlong JNICALL
Java_com_google_android_filament_TextureSampler_nSetCompareFunction(JNIEnv *, jclass, jlong sampler_, jint function) {
TextureSampler sampler{from_long(sampler_)};
extern "C" JNIEXPORT jint JNICALL
Java_com_google_android_filament_TextureSampler_nSetCompareFunction(JNIEnv *env, jclass type,
jint sampler_, jint function) {
TextureSampler &sampler = reinterpret_cast<TextureSampler &>(sampler_);
sampler.setCompareMode(sampler.getCompareMode(),
static_cast<TextureSampler::CompareFunc>(function));
return to_long(sampler);
return sampler.getSamplerParams().u;
}
extern "C" JNIEXPORT jfloat JNICALL
Java_com_google_android_filament_TextureSampler_nGetAnisotropy(JNIEnv *, jclass, jlong sampler) {
return from_long(sampler).getAnisotropy();
Java_com_google_android_filament_TextureSampler_nGetAnisotropy(JNIEnv *env, jclass type,
jint sampler_) {
TextureSampler &sampler = reinterpret_cast<TextureSampler &>(sampler_);
return sampler.getAnisotropy();
}
extern "C" JNIEXPORT jlong JNICALL
Java_com_google_android_filament_TextureSampler_nSetAnisotropy(JNIEnv *, jclass, jlong sampler_, jfloat anisotropy) {
TextureSampler sampler{from_long(sampler_)};
extern "C" JNIEXPORT jint JNICALL
Java_com_google_android_filament_TextureSampler_nSetAnisotropy(JNIEnv *env, jclass type,
jint sampler_, jfloat anisotropy) {
TextureSampler &sampler = reinterpret_cast<TextureSampler &>(sampler_);
sampler.setAnisotropy(anisotropy);
return to_long(sampler);
return sampler.getSamplerParams().u;
}
+3 -33
View File
@@ -315,14 +315,12 @@ Java_com_google_android_filament_View_nSetBloomOptions(JNIEnv*, jclass,
extern "C" JNIEXPORT void JNICALL
Java_com_google_android_filament_View_nSetFogOptions(JNIEnv *, jclass , jlong nativeView,
jfloat distance, jfloat maximumOpacity, jfloat height, jfloat heightFalloff, jfloat cutOffDistance,
jfloat r, jfloat g, jfloat b, jfloat density, jfloat inScatteringStart,
jfloat inScatteringSize, jboolean fogColorFromIbl, jlong skyColorNativeObject, jboolean enabled) {
jfloat distance, jfloat maximumOpacity, jfloat height, jfloat heightFalloff, jfloat r,
jfloat g, jfloat b, jfloat density, jfloat inScatteringStart,
jfloat inScatteringSize, jboolean fogColorFromIbl, jboolean enabled) {
View* view = (View*) nativeView;
Texture* skyColor = (Texture*) skyColorNativeObject;
View::FogOptions options = {
.distance = distance,
.cutOffDistance = cutOffDistance,
.maximumOpacity = maximumOpacity,
.height = height,
.heightFalloff = heightFalloff,
@@ -331,7 +329,6 @@ Java_com_google_android_filament_View_nSetFogOptions(JNIEnv *, jclass , jlong na
.inScatteringStart = inScatteringStart,
.inScatteringSize = inScatteringSize,
.fogColorFromIbl = (bool)fogColorFromIbl,
.skyColor = skyColor,
.enabled = (bool)enabled
};
view->setFogOptions(options);
@@ -488,30 +485,3 @@ Java_com_google_android_filament_View_nSetGuardBandOptions(JNIEnv *, jclass,
View* view = (View*) nativeView;
view->setGuardBandOptions({ .enabled = (bool)enabled });
}
extern "C"
JNIEXPORT void JNICALL
Java_com_google_android_filament_View_nSetMaterialGlobal(JNIEnv * , jclass, jlong nativeView,
jint index, jfloat x, jfloat y, jfloat z, jfloat w) {
View *view = (View *) nativeView;
view->setMaterialGlobal((uint32_t)index, { x, y, z, w });
}
extern "C"
JNIEXPORT void JNICALL
Java_com_google_android_filament_View_nGetMaterialGlobal(JNIEnv *env, jclass clazz,
jlong nativeView, jint index, jfloatArray out_) {
jfloat* out = env->GetFloatArrayElements(out_, nullptr);
View *view = (View *) nativeView;
auto result = view->getMaterialGlobal(index);
std::copy_n(result.v, 4, out);
env->ReleaseFloatArrayElements(out_, out, 0);
}
extern "C"
JNIEXPORT int JNICALL
Java_com_google_android_filament_View_nGetFogEntity(JNIEnv *env, jclass clazz,
jlong nativeView) {
View *view = (View *) nativeView;
return (jint)view->getFogEntity().getId();
}
@@ -118,7 +118,6 @@ public class ColorGrading {
*
* @deprecated Use {@link ColorGrading.Builder#toneMapper(ToneMapper)}
*/
@Deprecated
public enum ToneMapping {
/** Linear tone mapping (i.e. no tone mapping). */
LINEAR,
@@ -232,7 +231,6 @@ public class ColorGrading {
*
* @deprecated Use {@link #toneMapper(ToneMapper)}
*/
@Deprecated
public Builder toneMapping(ToneMapping toneMapping) {
nBuilderToneMapping(mNativeBuilder, toneMapping.ordinal());
return this;
@@ -449,141 +449,6 @@ public class Engine {
swapChain.clearNativeObject();
}
/**
* Returns whether the object is valid.
* @param object Object to check for validity
* @return returns true if the specified object is valid.
*/
public boolean isValidRenderer(@NonNull Renderer object) {
return nIsValidRenderer(getNativeObject(), object.getNativeObject());
}
/**
* Returns whether the object is valid.
* @param object Object to check for validity
* @return returns true if the specified object is valid.
*/
public boolean isValidView(@NonNull View object) {
return nIsValidView(getNativeObject(), object.getNativeObject());
}
/**
* Returns whether the object is valid.
* @param object Object to check for validity
* @return returns true if the specified object is valid.
*/
public boolean isValidScene(@NonNull Scene object) {
return nIsValidScene(getNativeObject(), object.getNativeObject());
}
/**
* Returns whether the object is valid.
* @param object Object to check for validity
* @return returns true if the specified object is valid.
*/
public boolean isValidFence(@NonNull Fence object) {
return nIsValidFence(getNativeObject(), object.getNativeObject());
}
/**
* Returns whether the object is valid.
* @param object Object to check for validity
* @return returns true if the specified object is valid.
*/
public boolean isValidStream(@NonNull Stream object) {
return nIsValidStream(getNativeObject(), object.getNativeObject());
}
/**
* Returns whether the object is valid.
* @param object Object to check for validity
* @return returns true if the specified object is valid.
*/
public boolean isValidIndexBuffer(@NonNull IndexBuffer object) {
return nIsValidIndexBuffer(getNativeObject(), object.getNativeObject());
}
/**
* Returns whether the object is valid.
* @param object Object to check for validity
* @return returns true if the specified object is valid.
*/
public boolean isValidVertexBuffer(@NonNull VertexBuffer object) {
return nIsValidVertexBuffer(getNativeObject(), object.getNativeObject());
}
/**
* Returns whether the object is valid.
* @param object Object to check for validity
* @return returns true if the specified object is valid.
*/
public boolean isValidSkinningBuffer(@NonNull SkinningBuffer object) {
return nIsValidSkinningBuffer(getNativeObject(), object.getNativeObject());
}
/**
* Returns whether the object is valid.
* @param object Object to check for validity
* @return returns true if the specified object is valid.
*/
public boolean isValidIndirectLight(@NonNull IndirectLight object) {
return nIsValidIndirectLight(getNativeObject(), object.getNativeObject());
}
/**
* Returns whether the object is valid.
* @param object Object to check for validity
* @return returns true if the specified object is valid.
*/
public boolean isValidMaterial(@NonNull Material object) {
return nIsValidMaterial(getNativeObject(), object.getNativeObject());
}
/**
* Returns whether the object is valid.
* @param object Object to check for validity
* @return returns true if the specified object is valid.
*/
public boolean isValidSkybox(@NonNull Skybox object) {
return nIsValidSkybox(getNativeObject(), object.getNativeObject());
}
/**
* Returns whether the object is valid.
* @param object Object to check for validity
* @return returns true if the specified object is valid.
*/
public boolean isValidColorGrading(@NonNull ColorGrading object) {
return nIsValidColorGrading(getNativeObject(), object.getNativeObject());
}
/**
* Returns whether the object is valid.
* @param object Object to check for validity
* @return returns true if the specified object is valid.
*/
public boolean isValidTexture(@NonNull Texture object) {
return nIsValidTexture(getNativeObject(), object.getNativeObject());
}
/**
* Returns whether the object is valid.
* @param object Object to check for validity
* @return returns true if the specified object is valid.
*/
public boolean isValidRenderTarget(@NonNull RenderTarget object) {
return nIsValidRenderTarget(getNativeObject(), object.getNativeObject());
}
/**
* Returns whether the object is valid.
* @param object Object to check for validity
* @return returns true if the specified object is valid.
*/
public boolean isValidSwapChain(@NonNull SwapChain object) {
return nIsValidSwapChain(getNativeObject(), object.getNativeObject());
}
// View
/**
@@ -920,17 +785,17 @@ public class Engine {
private static native long nCreateSwapChain(long nativeEngine, Object nativeWindow, long flags);
private static native long nCreateSwapChainHeadless(long nativeEngine, int width, int height, long flags);
private static native long nCreateSwapChainFromRawPointer(long nativeEngine, long pointer, long flags);
private static native boolean nDestroySwapChain(long nativeEngine, long nativeSwapChain);
private static native long nCreateView(long nativeEngine);
private static native boolean nDestroyView(long nativeEngine, long nativeView);
private static native long nCreateRenderer(long nativeEngine);
private static native boolean nDestroyRenderer(long nativeEngine, long nativeRenderer);
private static native long nCreateCamera(long nativeEngine, int entity);
private static native long nGetCameraComponent(long nativeEngine, int entity);
private static native void nDestroyCameraComponent(long nativeEngine, int entity);
private static native long nCreateScene(long nativeEngine);
private static native long nCreateFence(long nativeEngine);
private static native boolean nDestroyRenderer(long nativeEngine, long nativeRenderer);
private static native boolean nDestroyView(long nativeEngine, long nativeView);
private static native boolean nDestroyScene(long nativeEngine, long nativeScene);
private static native long nCreateFence(long nativeEngine);
private static native boolean nDestroyFence(long nativeEngine, long nativeFence);
private static native boolean nDestroyStream(long nativeEngine, long nativeStream);
private static native boolean nDestroyIndexBuffer(long nativeEngine, long nativeIndexBuffer);
@@ -943,22 +808,6 @@ public class Engine {
private static native boolean nDestroyColorGrading(long nativeEngine, long nativeColorGrading);
private static native boolean nDestroyTexture(long nativeEngine, long nativeTexture);
private static native boolean nDestroyRenderTarget(long nativeEngine, long nativeTarget);
private static native boolean nDestroySwapChain(long nativeEngine, long nativeSwapChain);
private static native boolean nIsValidRenderer(long nativeEngine, long nativeRenderer);
private static native boolean nIsValidView(long nativeEngine, long nativeView);
private static native boolean nIsValidScene(long nativeEngine, long nativeScene);
private static native boolean nIsValidFence(long nativeEngine, long nativeFence);
private static native boolean nIsValidStream(long nativeEngine, long nativeStream);
private static native boolean nIsValidIndexBuffer(long nativeEngine, long nativeIndexBuffer);
private static native boolean nIsValidVertexBuffer(long nativeEngine, long nativeVertexBuffer);
private static native boolean nIsValidSkinningBuffer(long nativeEngine, long nativeSkinningBuffer);
private static native boolean nIsValidIndirectLight(long nativeEngine, long nativeIndirectLight);
private static native boolean nIsValidMaterial(long nativeEngine, long nativeMaterial);
private static native boolean nIsValidSkybox(long nativeEngine, long nativeSkybox);
private static native boolean nIsValidColorGrading(long nativeEngine, long nativeColorGrading);
private static native boolean nIsValidTexture(long nativeEngine, long nativeTexture);
private static native boolean nIsValidRenderTarget(long nativeEngine, long nativeTarget);
private static native boolean nIsValidSwapChain(long nativeEngine, long nativeSwapChain);
private static native void nDestroyEntity(long nativeEngine, int entity);
private static native void nFlushAndWait(long nativeEngine);
private static native long nGetTransformManager(long nativeEngine);
@@ -625,15 +625,6 @@ public class MaterialInstance {
nSetDepthCulling(getNativeObject(), enable);
}
/**
* Sets the depth comparison function (default is {@link TextureSampler.CompareFunction#GE}).
*
* @param func the depth comparison function
*/
public void setDepthFunc(TextureSampler.CompareFunction func) {
nSetDepthFunc(getNativeObject(), func.ordinal());
}
/**
* Returns whether depth culling is enabled.
*/
@@ -641,13 +632,6 @@ public class MaterialInstance {
return nIsDepthCullingEnabled(getNativeObject());
}
/**
* Returns the depth comparison function.
*/
public TextureSampler.CompareFunction getDepthFunc() {
return TextureSampler.EnumCache.sCompareFunctionValues[nGetDepthFunc(getNativeObject())];
}
/**
* Sets the stencil comparison function (default is {@link TextureSampler.CompareFunction#ALWAYS}).
*
@@ -900,7 +884,7 @@ public class MaterialInstance {
@IntRange(from = 0) int offset, @IntRange(from = 1) int count);
private static native void nSetParameterTexture(long nativeMaterialInstance,
@NonNull String name, long nativeTexture, long sampler);
@NonNull String name, long nativeTexture, int sampler);
private static native void nSetScissor(long nativeMaterialInstance,
@IntRange(from = 0) int left, @IntRange(from = 0) int bottom,
@@ -924,7 +908,6 @@ public class MaterialInstance {
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 nSetDepthFunc(long nativeMaterialInstance, long function);
private static native void nSetStencilCompareFunction(long nativeMaterialInstance,
long function, long face);
@@ -956,5 +939,4 @@ public class MaterialInstance {
private static native boolean nIsDepthWriteEnabled(long nativeMaterialInstance);
private static native boolean nIsStencilWriteEnabled(long nativeMaterialInstance);
private static native boolean nIsDepthCullingEnabled(long nativeMaterialInstance);
private static native int nGetDepthFunc(long nativeMaterialInstance);
}
@@ -81,6 +81,8 @@ public class RenderTarget {
/**
* Sets a texture to a given attachment point.
*
* <p>All RenderTargets must have a non-null <code>COLOR</code> attachment.</p>
*
* @param attachment The attachment point of the texture.
* @param texture The associated texture object.
* @return A reference to this Builder for chaining calls.
@@ -356,16 +356,16 @@ public class RenderableManager {
/**
* Specifies the number of draw instance of this renderable. The default is 1 instance and
* the maximum number of instances allowed is 32767. 0 is invalid.
* the maximum number of instances allowed is 65535. 0 is invalid.
* All instances are culled using the same bounding box, so care must be taken to make
* sure all instances render inside the specified bounding box.
* The material can use getInstanceIndex() in the vertex shader to get the instance index and
* possibly adjust the position or transform.
*
* @param instanceCount the number of instances silently clamped between 1 and 32767.
* @param instanceCount the number of instances silently clamped between 1 and 65535.
*/
@NonNull
public Builder instances(@IntRange(from = 1, to = 32767) int instanceCount) {
public Builder instances(@IntRange(from = 1, to = 65535) int instanceCount) {
nBuilderInstances(mNativeBuilder, instanceCount);
return this;
}
@@ -417,19 +417,7 @@ public class RenderableManager {
*/
@NonNull
public Builder enableSkinningBuffers(boolean enabled) {
nBuilderEnableSkinningBuffers(mNativeBuilder, enabled);
return this;
}
/**
* Controls if this renderable is affected by the large-scale fog.
* @param enabled If true, enables large-scale fog on this object. Disables it otherwise.
* True by default.
* @return this <code>Builder</code> object for chaining calls
*/
@NonNull
public Builder fog(boolean enabled) {
nBuilderFog(mNativeBuilder, enabled);
nEnableSkinningBuffers(mNativeBuilder, enabled);
return this;
}
@@ -741,23 +729,6 @@ public class RenderableManager {
nSetCulling(mNativeObject, i, enabled);
}
/**
* Changes whether or not the large-scale fog is applied to this renderable
* @see Builder#fog
*/
public void setFogEnabled(@EntityInstance int i, boolean enabled) {
nSetFogEnabled(mNativeObject, i, enabled);
}
/**
* Returns whether large-scale fog is enabled for this renderable.
* @return True if fog is enabled for this renderable.
* @see Builder#fog
*/
public boolean getFogEnabled(@EntityInstance int i) {
return nGetFogEnabled(mNativeObject, i);
}
/**
* Enables or disables a light channel.
* Light channel 0 is enabled by default.
@@ -980,8 +951,7 @@ public class RenderableManager {
private static native void nBuilderSkinningBuffer(long nativeBuilder, long nativeSkinningBuffer, int boneCount, int offset);
private static native void nBuilderMorphing(long nativeBuilder, int targetCount);
private static native void nBuilderSetMorphTargetBufferAt(long nativeBuilder, int level, int primitiveIndex, long nativeMorphTargetBuffer, int offset, int count);
private static native void nBuilderEnableSkinningBuffers(long nativeBuilder, boolean enabled);
private static native void nBuilderFog(long nativeBuilder, boolean enabled);
private static native void nEnableSkinningBuffers(long nativeBuilder, boolean enabled);
private static native void nBuilderLightChannel(long nativeRenderableManager, int channel, boolean enable);
private static native void nBuilderInstances(long nativeRenderableManager, int instances);
@@ -996,8 +966,6 @@ public class RenderableManager {
private static native void nSetPriority(long nativeRenderableManager, int i, int priority);
private static native void nSetChannel(long nativeRenderableManager, int i, int channel);
private static native void nSetCulling(long nativeRenderableManager, int i, boolean enabled);
private static native void nSetFogEnabled(long nativeRenderableManager, int i, boolean enabled);
private static native boolean nGetFogEnabled(long nativeRenderableManager, int i);
private static native void nSetLightChannel(long nativeRenderableManager, int i, int channel, boolean enable);
private static native boolean nGetLightChannel(long nativeRenderableManager, int i, int channel);
private static native void nSetCastShadows(long nativeRenderableManager, int i, boolean enabled);
@@ -137,6 +137,10 @@ public class SwapChain {
* </p>
*
* <p>
* The FrameCompletedCallback is guaranteed to be called on the main Filament thread.
* </p>
*
* <p>
* Warning: Only Filament's Metal backend supports frame callbacks. Other backends ignore the
* callback (which will never be called) and proceed normally.
* </p>
@@ -126,7 +126,7 @@ public class TextureSampler {
NEVER
}
long mSampler = 0; // bit field used by native
int mSampler = 0; // bit field used by native
/**
* Initializes the <code>TextureSampler</code> with default values.
@@ -342,26 +342,26 @@ public class TextureSampler {
}
}
private static native long nCreateSampler(int min, int max, int s, int t, int r);
private static native long nCreateCompareSampler(int mode, int function);
private static native int nCreateSampler(int min, int max, int s, int t, int r);
private static native int nCreateCompareSampler(int mode, int function);
private static native int nGetMinFilter(long sampler);
private static native long nSetMinFilter(long sampler, int filter);
private static native int nGetMagFilter(long sampler);
private static native long nSetMagFilter(long sampler, int filter);
private static native int nGetMinFilter(int sampler);
private static native int nSetMinFilter(int sampler, int filter);
private static native int nGetMagFilter(int sampler);
private static native int nSetMagFilter(int sampler, int filter);
private static native int nGetWrapModeS(long sampler);
private static native long nSetWrapModeS(long sampler, int mode);
private static native int nGetWrapModeT(long sampler);
private static native long nSetWrapModeT(long sampler, int mode);
private static native int nGetWrapModeR(long sampler);
private static native long nSetWrapModeR(long sampler, int mode);
private static native int nGetWrapModeS(int sampler);
private static native int nSetWrapModeS(int sampler, int mode);
private static native int nGetWrapModeT(int sampler);
private static native int nSetWrapModeT(int sampler, int mode);
private static native int nGetWrapModeR(int sampler);
private static native int nSetWrapModeR(int sampler, int mode);
private static native int nGetCompareMode(long sampler);
private static native long nSetCompareMode(long sampler, int mode);
private static native int nGetCompareFunction(long sampler);
private static native long nSetCompareFunction(long sampler, int function);
private static native int nGetCompareMode(int sampler);
private static native int nSetCompareMode(int sampler, int mode);
private static native int nGetCompareFunction(int sampler);
private static native int nSetCompareFunction(int sampler, int function);
private static native float nGetAnisotropy(long sampler);
private static native long nSetAnisotropy(long sampler, float anisotropy);
private static native float nGetAnisotropy(int sampler);
private static native int nSetAnisotropy(int sampler, float anisotropy);
}
@@ -27,8 +27,6 @@ import static com.google.android.filament.Asserts.assertFloat3In;
import static com.google.android.filament.Asserts.assertFloat4In;
import static com.google.android.filament.Colors.LinearColor;
import com.google.android.filament.proguard.UsedByNative;
/**
* Encompasses all the state needed for rendering a {@link Scene}.
*
@@ -964,11 +962,9 @@ public class View {
assertFloat3In(options.color);
mFogOptions = options;
nSetFogOptions(getNativeObject(), options.distance, options.maximumOpacity, options.height,
options.heightFalloff, options.cutOffDistance,
options.color[0], options.color[1], options.color[2],
options.heightFalloff, options.color[0], options.color[1], options.color[2],
options.density, options.inScatteringStart, options.inScatteringSize,
options.fogColorFromIbl,
options.skyColor == null ? 0 : options.skyColor.getNativeObject(),
options.enabled);
}
@@ -1098,29 +1094,10 @@ public class View {
nPick(getNativeObject(), x, y, handler, internalCallback);
}
@UsedByNative("View.cpp")
private static class InternalOnPickCallback implements Runnable {
private final OnPickCallback mUserCallback;
private final PickingQueryResult mPickingQueryResult = new PickingQueryResult();
@UsedByNative("View.cpp")
@Entity
int mRenderable;
@UsedByNative("View.cpp")
float mDepth;
@UsedByNative("View.cpp")
float mFragCoordsX;
@UsedByNative("View.cpp")
float mFragCoordsY;
@UsedByNative("View.cpp")
float mFragCoordsZ;
public InternalOnPickCallback(OnPickCallback mUserCallback) {
this.mUserCallback = mUserCallback;
}
@Override
public void run() {
mPickingQueryResult.renderable = mRenderable;
@@ -1130,51 +1107,13 @@ public class View {
mPickingQueryResult.fragCoords[2] = mFragCoordsZ;
mUserCallback.onPick(mPickingQueryResult);
}
}
/**
* Set the value of material global variables. There are up-to four such variable each of
* type float4. These variables can be read in a user Material with
* `getMaterialGlobal{0|1|2|3}()`. All variable start with a default value of { 0, 0, 0, 1 }
*
* @param index index of the variable to set between 0 and 3.
* @param value new value for the variable.
* @see #getMaterialGlobal
*/
public void setMaterialGlobal(int index, @NonNull @Size(min = 4) float[] value) {
Asserts.assertFloat4In(value);
nSetMaterialGlobal(getNativeObject(), index, value[0], value[1], value[2], value[3]);
}
/**
* Get the value of the material global variables.
* All variable start with a default value of { 0, 0, 0, 1 }
*
* @param index index of the variable to set between 0 and 3.
* @param out A 4-float array where the value will be stored, or null in which case the array is
* allocated.
* @return A 4-float array containing the current value of the variable.
* @see #setMaterialGlobal
*/
@NonNull @Size(min = 4)
public float[] getMaterialGlobal(int index, @Nullable @Size(min = 4) float[] out) {
out = Asserts.assertFloat4(out);
nGetMaterialGlobal(getNativeObject(), index, out);
return out;
}
/**
* Get an Entity representing the large scale fog object.
* This entity is always inherited by the View's Scene.
*
* It is for example possible to create a TransformManager component with this
* Entity and apply a transformation globally on the fog.
*
* @return an Entity representing the large scale fog object.
*/
@Entity
public int getFogEntity() {
return nGetFogEntity(getNativeObject());
private final OnPickCallback mUserCallback;
private final PickingQueryResult mPickingQueryResult = new PickingQueryResult();
@Entity int mRenderable;
float mDepth;
float mFragCoordsX;
float mFragCoordsY;
float mFragCoordsZ;
}
public long getNativeObject() {
@@ -1218,7 +1157,7 @@ public class View {
private static native void nSetSSCTOptions(long nativeView, float ssctLightConeRad, float ssctStartTraceDistance, float ssctContactDistanceMax, float ssctIntensity, float v, float v1, float v2, float ssctDepthBias, float ssctDepthSlopeBias, int ssctSampleCount, int ssctRayCount, boolean ssctEnabled);
private static native void nSetBloomOptions(long nativeView, long dirtNativeObject, float dirtStrength, float strength, int resolution, float anamorphism, int levels, int blendMode, boolean threshold, boolean enabled, float highlight,
boolean lensFlare, boolean starburst, float chromaticAberration, int ghostCount, float ghostSpacing, float ghostThreshold, float haloThickness, float haloRadius, float haloThreshold);
private static native void nSetFogOptions(long nativeView, float distance, float maximumOpacity, float height, float heightFalloff, float cutOffDistance, float v, float v1, float v2, float density, float inScatteringStart, float inScatteringSize, boolean fogColorFromIbl, long skyColorNativeObject, boolean enabled);
private static native void nSetFogOptions(long nativeView, float distance, float maximumOpacity, float height, float heightFalloff, float v, float v1, float v2, float density, float inScatteringStart, float inScatteringSize, boolean fogColorFromIbl, boolean enabled);
private static native void nSetBlendMode(long nativeView, int blendMode);
private static native void nSetDepthOfFieldOptions(long nativeView, float cocScale, float maxApertureDiameter, boolean enabled, int filter,
boolean nativeResolution, int foregroundRingCount, int backgroundRingCount, int fastGatherRingCount, int maxForegroundCOC, int maxBackgroundCOC);
@@ -1233,10 +1172,6 @@ public class View {
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);
private static native void nSetMaterialGlobal(long nativeView, int index, float x, float y, float z, float w);
private static native void nGetMaterialGlobal(long nativeView, int index, float[] out);
private static native int nGetFogEntity(long nativeView);
/**
* List of available ambient occlusion techniques.
@@ -1392,13 +1327,13 @@ public class View {
/**
* resolution of vertical axis (2^levels to 2048)
*/
public int resolution = 384;
public int resolution = 360;
/**
* bloom x/y aspect-ratio (1/32 to 32)
*/
public float anamorphism = 1.0f;
/**
* number of blur levels (1 to 11)
* number of blur levels (3 to 11)
*/
public int levels = 6;
/**
@@ -1457,109 +1392,48 @@ public class View {
}
/**
* Options to control large-scale fog in the scene
* Options to control fog in the scene
*/
public static class FogOptions {
/**
* Distance in world units [m] from the camera to where the fog starts ( >= 0.0 )
* distance in world units from the camera where the fog starts ( >= 0.0 )
*/
public float distance = 0.0f;
/**
* Distance in world units [m] after which the fog calculation is disabled.
* This can be used to exclude the skybox, which is desirable if it already contains clouds or
* fog. The default value is +infinity which applies the fog to everything.
*
* Note: The SkyBox is typically at a distance of 1e19 in world space (depending on the near
* plane distance and projection used though).
*/
public float cutOffDistance = Float.POSITIVE_INFINITY;
/**
* fog's maximum opacity between 0 and 1
*/
public float maximumOpacity = 1.0f;
/**
* Fog's floor in world units [m]. This sets the "sea level".
* fog's floor in world units
*/
public float height = 0.0f;
/**
* How fast the fog dissipates with altitude. heightFalloff has a unit of [1/m].
* It can be expressed as 1/H, where H is the altitude change in world units [m] that causes a
* factor 2.78 (e) change in fog density.
*
* A falloff of 0 means the fog density is constant everywhere and may result is slightly
* faster computations.
* how fast fog dissipates with altitude
*/
public float heightFalloff = 1.0f;
/**
* Fog's color is used for ambient light in-scattering, a good value is
* to use the average of the ambient light, possibly tinted towards blue
* for outdoors environments. Color component's values should be between 0 and 1, values
* above one are allowed but could create a non energy-conservative fog (this is dependant
* on the IBL's intensity as well).
*
* We assume that our fog has no absorption and therefore all the light it scatters out
* becomes ambient light in-scattering and has lost all directionality, i.e.: scattering is
* isotropic. This somewhat simulates Rayleigh scattering.
*
* This value is used as a tint instead, when fogColorFromIbl is enabled.
*
* @see fogColorFromIbl
* fog's color (linear), see fogColorFromIbl
*/
@NonNull @Size(min = 3)
public float[] color = {1.0f, 1.0f, 1.0f};
public float[] color = {0.5f, 0.5f, 0.5f};
/**
* Extinction factor in [1/m] at altitude 'height'. The extinction factor controls how much
* light is absorbed and out-scattered per unit of distance. Each unit of extinction reduces
* the incoming light to 37% of its original value.
*
* Note: The extinction factor is related to the fog density, it's usually some constant K times
* the density at sea level (more specifically at fog height). The constant K depends on
* the composition of the fog/atmosphere.
*
* For historical reason this parameter is called `density`.
* fog's density at altitude given by 'height'
*/
public float density = 0.1f;
/**
* Distance in world units [m] from the camera where the Sun in-scattering starts.
* distance in world units from the camera where in-scattering starts
*/
public float inScatteringStart = 0.0f;
/**
* Very inaccurately simulates the Sun's in-scattering. That is, the light from the sun that
* is scattered (by the fog) towards the camera.
* Size of the Sun in-scattering (>0 to activate). Good values are >> 1 (e.g. ~10 - 100).
* Smaller values result is a larger scattering size.
* size of in-scattering (>0 to activate). Good values are >> 1 (e.g. ~10 - 100).
*/
public float inScatteringSize = -1.0f;
/**
* The fog color will be sampled from the IBL in the view direction and tinted by `color`.
* Depending on the scene this can produce very convincing results.
*
* This simulates a more anisotropic phase-function.
*
* `fogColorFromIbl` is ignored when skyTexture is specified.
*
* @see skyColor
* Fog color will be modulated by the IBL color in the view direction.
*/
public boolean fogColorFromIbl = false;
/**
* skyTexture must be a mipmapped cubemap. When provided, the fog color will be sampled from
* this texture, higher resolution mip levels will be used for objects at the far clip plane,
* and lower resolution mip levels for objects closer to the camera. The skyTexture should
* typically be heavily blurred; a typical way to produce this texture is to blur the base
* level with a strong gaussian filter or even an irradiance filter and then generate mip
* levels as usual. How blurred the base level is somewhat of an artistic decision.
*
* This simulates a more anisotropic phase-function.
*
* `fogColorFromIbl` is ignored when skyTexture is specified.
*
* @see Texture
* @see fogColorFromIbl
*/
@Nullable
public Texture skyColor = null;
/**
* Enable or disable large-scale fog
* enable or disable fog
*/
public boolean enabled = false;
}
@@ -1986,11 +1860,4 @@ public class View {
*/
public float penumbraRatioScale = 1.0f;
}
/**
* Options for stereoscopic (multi-eye) rendering.
*/
public static class StereoscopicOptions {
public boolean enabled = false;
}
}
@@ -1,60 +0,0 @@
/*
* Copyright (C) 2023 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.google.android.filament.android;
import com.google.android.filament.Engine;
import com.google.android.filament.Fence;
public class FilamentHelper {
/**
* Wait for all pending frames to be processed before returning. This is to avoid a race
* between the surface being resized before pending frames are rendered into it.
* <p>
* For {@link android.view.TextureView} this must be called before the texture's size is
* reconfigured, which unfortunately is done by the Android framework before
* {@link UiHelper} listeners are invoked. Therefore <code>synchronizePendingFrames</code>
* cannot be called from
* {@link android.view.TextureView.SurfaceTextureListener#onSurfaceTextureSizeChanged}; instead
* a subclass of {@link android.view.TextureView} must be used in order to call it from
* {@link android.view.TextureView#onSizeChanged}:
* </p>
* <pre>
* public class MyTextureView extends TextureView {
* private Engine engine;
* protected void onSizeChanged(int w, int h, int oldw, int oldh) {
* FilamentHelper.synchronizePendingFrames(engine);
* super.onSizeChanged(w, h, oldw, oldh);
* }
* }
* </pre>
*
* Otherwise, this is typically called from {@link UiHelper.RendererCallback#onResized},
* {@link android.view.SurfaceHolder.Callback#surfaceChanged}.
*
* @param engine Filament engine to synchronize
*
* @see UiHelper.RendererCallback#onResized
* @see android.view.SurfaceHolder.Callback#surfaceChanged
* @see android.view.TextureView#onSizeChanged
*/
static public void synchronizePendingFrames(Engine engine) {
Fence fence = engine.createFence();
fence.wait(Fence.Mode.FLUSH, Fence.WAIT_FOR_EVER);
engine.destroyFence(fence);
}
}
@@ -84,14 +84,6 @@ import com.google.android.filament.SwapChain;
* // The native surface has changed size. This is always called at least once
* // after the surface is created (after onNativeWindowChanged() is invoked).
* public void onResized(int width, int height) {
*
* // Wait for all pending frames to be processed before returning. This is to
* // avoid a race between the surface being resized before pending frames are
* // rendered into it.
* Fence fence = mEngine.createFence();
* fence.wait(Fence.Mode.FLUSH, Fence.WAIT_FOR_EVER);
* mEngine.destroyFence(fence);
*
* // Compute camera projection and set the viewport on the view
* }
* });
@@ -183,7 +175,7 @@ public class UiHelper {
}
private static class SurfaceViewHandler implements RenderSurface {
private final SurfaceView mSurfaceView;
private SurfaceView mSurfaceView;
SurfaceViewHandler(SurfaceView surface) {
mSurfaceView = surface;
@@ -200,7 +192,7 @@ public class UiHelper {
}
private static class SurfaceHolderHandler implements RenderSurface {
private final SurfaceHolder mSurfaceHolder;
private SurfaceHolder mSurfaceHolder;
SurfaceHolderHandler(SurfaceHolder surface) {
mSurfaceHolder = surface;
@@ -217,7 +209,7 @@ public class UiHelper {
}
private class TextureViewHandler implements RenderSurface {
private final TextureView mTextureView;
private TextureView mTextureView;
private Surface mSurface;
TextureViewHandler(TextureView surface) { mTextureView = surface; }
@@ -244,10 +236,6 @@ public class UiHelper {
}
mSurface = surface;
}
public Surface getSurface() {
return mSurface;
}
}
/**
@@ -493,14 +481,6 @@ public class UiHelper {
} else {
mRenderCallback.onResized(width, height);
}
// We must recreate the SwapChain to guarantee that it sees the new size.
// More precisely, for an EGL client, the EGLSurface must be recreated. For
// a Vulkan client, the SwapChain must be recreated. Calling
// onNativeWindowChanged() will accomplish that.
// This requirement comes from SurfaceTexture.setDefaultBufferSize()
// documentation.
TextureViewHandler textureViewHandler = (TextureViewHandler) mRenderSurface;
mRenderCallback.onNativeWindowChanged(textureViewHandler.getSurface());
}
@Override
+10 -8
View File
@@ -1,7 +1,4 @@
apply plugin: 'kotlin-android'
kotlin {
jvmToolchain(versions.jdk)
}
android {
namespace 'com.google.android.filament.utils'
@@ -24,11 +21,16 @@ android {
excludes += ['lib/*/libfilament-jni.so', 'lib/*/libgltfio-jni.so']
}
}
}
publishing {
singleVariant("release") {
withSourcesJar()
withJavadocJar()
configurations.all { config ->
// Hack to preserve the version of the dependencies
if (!config.name.endsWith('Publication')) {
resolutionStrategy {
dependencySubstitution {
substitute(module("com.google.android.filament:gltfio-android:${VERSION_NAME}")).with(project(":gltfio-android"))
substitute(module("com.google.android.filament:gltfio-android-lite:${VERSION_NAME}")).with(project(":gltfio-android"))
}
}
}
}
@@ -41,7 +43,7 @@ dependencies {
implementation deps.coroutines.android
api project(':filament-android')
api project(':gltfio-android')
api module("com.google.android.filament:gltfio-android:${VERSION_NAME}")
}
apply from: rootProject.file('gradle/gradle-mvn-push.gradle')
@@ -14,7 +14,7 @@
* limitations under the License.
*/
@file:Suppress("NOTHING_TO_INLINE", "unused")
@file:Suppress("unused")
package com.google.android.filament.utils
@@ -24,16 +24,8 @@ enum class MatrixColumn {
X, Y, Z, W
}
enum class RotationsOrder(
val yaw: VectorComponent,
val pitch: VectorComponent,
val roll: VectorComponent) {
XYZ(VectorComponent.X, VectorComponent.Y, VectorComponent.Z),
XZY(VectorComponent.X, VectorComponent.Z, VectorComponent.Y),
YXZ(VectorComponent.Y, VectorComponent.X, VectorComponent.Z),
YZX(VectorComponent.Y, VectorComponent.Z, VectorComponent.X),
ZXY(VectorComponent.Z, VectorComponent.X, VectorComponent.Y),
ZYX(VectorComponent.Z, VectorComponent.Y, VectorComponent.X);
enum class RotationsOrder {
XYZ, XZY, YXZ, YZX, ZXY, ZYX
}
data class Mat2(
@@ -85,12 +77,6 @@ data class Mat2(
operator fun minus(v: Float) = Mat2(x - v, y - v)
operator fun times(v: Float) = Mat2(x * v, y * v)
operator fun div(v: Float) = Mat2(x / v, y / v)
inline fun compareTo(v: Float, delta: Float = 0.0f) = Mat2(
x.compareTo(v, delta),
y.compareTo(v, delta)
)
inline fun equals(v: Float, delta: Float = 0.0f) = x.equals(v, delta) && y.equals(v, delta)
operator fun times(m: Mat2) = Mat2(
Float2(
@@ -103,18 +89,12 @@ data class Mat2(
)
)
inline fun compareTo(m: Mat2, delta: Float = 0.0f) = Mat2(
x.compareTo(m.x, delta),
y.compareTo(m.y, delta)
)
inline fun equals(m: Mat2, delta: Float = 0.0f) = x.equals(m.x, delta) && y.equals(m.y, delta)
operator fun times(v: Float2) = Float2(
x.x * v.x + y.x * v.y,
x.y * v.x + y.y * v.y,
)
fun toFloatArray() = floatArrayOf(
x.x, y.x,
x.y, y.y
@@ -126,6 +106,7 @@ data class Mat2(
|${x.y} ${y.y}|
""".trimIndent()
}
}
data class Mat3(
@@ -181,14 +162,6 @@ data class Mat3(
operator fun minus(v: Float) = Mat3(x - v, y - v, z - v)
operator fun times(v: Float) = Mat3(x * v, y * v, z * v)
operator fun div(v: Float) = Mat3(x / v, y / v, z / v)
inline fun compareTo(v: Float, delta: Float = 0.0f) = Mat3(
x.compareTo(v, delta),
y.compareTo(v, delta),
z.compareTo(v, delta)
)
inline fun equals(v: Float, delta: Float = 0.0f) =
x.equals(v, delta) && y.equals(v, delta) && z.equals(v, delta)
operator fun times(m: Mat3) = Mat3(
Float3(
@@ -208,15 +181,6 @@ data class Mat3(
)
)
inline fun compareTo(m: Mat3, delta: Float = 0.0f) = Mat3(
x.compareTo(m.x, delta),
y.compareTo(m.y, delta),
z.compareTo(m.z, delta)
)
inline fun equals(m: Mat3, delta: Float = 0.0f) =
x.equals(m.x, delta) && y.equals(m.y, delta) && z.equals(m.z, delta)
operator fun times(v: Float3) = Float3(
x.x * v.x + y.x * v.y + z.x * v.z,
x.y * v.x + y.y * v.y + z.y * v.z,
@@ -248,7 +212,6 @@ data class Mat4(
constructor(m: Mat4) : this(m.x.copy(), m.y.copy(), m.z.copy(), m.w.copy())
companion object {
fun of(vararg a: Float): Mat4 {
require(a.size >= 16)
return Mat4(
@@ -339,15 +302,6 @@ data class Mat4(
operator fun minus(v: Float) = Mat4(x - v, y - v, z - v, w - v)
operator fun times(v: Float) = Mat4(x * v, y * v, z * v, w * v)
operator fun div(v: Float) = Mat4(x / v, y / v, z / v, w / v)
inline fun compareTo(v: Float, delta: Float = 0.0f) = Mat4(
x.compareTo(v, delta),
y.compareTo(v, delta),
z.compareTo(v, delta),
w.compareTo(v, delta)
)
inline fun equals(v: Float, delta: Float = 0.0f) =
x.equals(v, delta) && y.equals(v, delta) && z.equals(v, delta) && w.equals(v, delta)
operator fun times(m: Mat4) = Mat4(
Float4(
@@ -376,16 +330,6 @@ data class Mat4(
)
)
inline fun compareTo(m: Mat4, delta: Float = 0.0f) = Mat4(
x.compareTo(m.x, delta),
y.compareTo(m.y, delta),
z.compareTo(m.z, delta),
w.compareTo(m.w, delta)
)
inline fun equals(m: Mat4, delta: Float = 0.0f) =
x.equals(m.x, delta) && y.equals(m.y, delta) && z.equals(m.z, delta) && w.equals(m.w, delta)
operator fun times(v: Float4) = Float4(
x.x * v.x + y.x * v.y + z.x * v.z+ w.x * v.w,
x.y * v.x + y.y * v.y + z.y * v.z+ w.y * v.w,
@@ -393,26 +337,6 @@ data class Mat4(
x.w * v.x + y.w * v.y + z.w * v.z+ w.w * v.w
)
/**
* Get the Euler angles in degrees from this rotation Matrix
*
* Don't forget to extract the rotation with [rotation] if this is a transposed matrix
*
* @param order The order in which to apply rotations.
* Default is [RotationsOrder.ZYX] which means that the object will first be rotated around its Z
* axis, then its Y axis and finally its X axis.
*
* @see eulerAngles
*/
fun toEulerAngles(order: RotationsOrder = RotationsOrder.ZYX) = eulerAngles(this, order)
/**
* Get the [Quaternion] from this rotation Matrix
*
* Don't forget to extract the rotation with [rotation] if this is a transposed matrix
*
* @see quaternion
*/
fun toQuaternion() = quaternion(this)
fun toFloatArray() = floatArrayOf(
@@ -432,78 +356,6 @@ data class Mat4(
}
}
inline fun equal(a: Mat2, b: Float, delta: Float = 0.0f) = Bool2(
a.x.equals(b, delta),
a.y.equals(b, delta)
)
inline fun equal(a: Mat2, b: Mat2, delta: Float = 0.0f) = Bool2(
a.x.equals(b.x, delta),
a.y.equals(b.y, delta)
)
inline fun notEqual(a: Mat2, b: Float, delta: Float = 0.0f) = Bool2(
!a.x.equals(b, delta),
!a.y.equals(b, delta)
)
inline fun notEqual(a: Mat2, b: Mat2, delta: Float = 0.0f) = Bool2(
!a.x.equals(b.x, delta),
!a.y.equals(b.y, delta)
)
inline fun equal(a: Mat3, b: Float, delta: Float = 0.0f) = Bool3(
a.x.equals(b, delta),
a.y.equals(b, delta),
a.z.equals(b, delta)
)
inline fun equal(a: Mat3, b: Mat3, delta: Float = 0.0f) = Bool3(
a.x.equals(b.x, delta),
a.y.equals(b.y, delta),
a.z.equals(b.z, delta)
)
inline fun notEqual(a: Mat3, b: Float, delta: Float = 0.0f) = Bool3(
!a.x.equals(b, delta),
!a.y.equals(b, delta),
!a.z.equals(b, delta)
)
inline fun notEqual(a: Mat3, b: Mat3, delta: Float = 0.0f) = Bool3(
!a.x.equals(b.x, delta),
!a.y.equals(b.y, delta),
!a.z.equals(b.z, delta)
)
inline fun equal(a: Mat4, b: Float, delta: Float = 0.0f) = Bool4(
a.x.equals(b, delta),
a.y.equals(b, delta),
a.z.equals(b, delta),
a.w.equals(b, delta)
)
inline fun equal(a: Mat4, b: Mat4, delta: Float = 0.0f) = Bool4(
a.x.equals(b.x, delta),
a.y.equals(b.y, delta),
a.z.equals(b.z, delta),
a.w.equals(b.w, delta)
)
inline fun notEqual(a: Mat4, b: Float, delta: Float = 0.0f) = Bool4(
!a.x.equals(b, delta),
!a.y.equals(b, delta),
!a.z.equals(b, delta),
!a.w.equals(b, delta)
)
inline fun notEqual(a: Mat4, b: Mat4, delta: Float = 0.0f) = Bool4(
!a.x.equals(b.x, delta),
!a.y.equals(b.y, delta),
!a.z.equals(b.z, delta),
!a.w.equals(b.w, delta)
)
fun transpose(m: Mat2) = Mat2(
Float2(m.x.x, m.y.x),
Float2(m.x.y, m.y.y)
@@ -642,7 +494,14 @@ fun rotation(m: Mat4) = Mat4(normalize(m.right), normalize(m.up), normalize(m.fo
*/
fun rotation(d: Float3, order: RotationsOrder = RotationsOrder.ZYX): Mat4 {
val r = transform(d, ::radians)
return rotation(r[order.yaw], r[order.pitch], r[order.roll], order)
return when(order) {
RotationsOrder.XZY -> rotation(r.x, r.z, r.y)
RotationsOrder.XYZ -> rotation(r.x, r.y, r.z)
RotationsOrder.YXZ -> rotation(r.y, r.x, r.z)
RotationsOrder.YZX -> rotation(r.y, r.z, r.x)
RotationsOrder.ZYX -> rotation(r.z, r.y, r.x)
RotationsOrder.ZXY -> rotation(r.z, r.x, r.y)
}
}
/**
@@ -740,93 +599,13 @@ fun rotation(quaternion: Quaternion): Mat4 {
Float4(
2.0f * (n.x * n.z + n.y * n.w),
2.0f * (n.y * n.z - n.x * n.w),
1.0f - 2.0f * (n.x * n.x + n.y * n.y)
1.0f - 2.0f * (n.x * n.x + n.y * n.y),
)
)
}
/**
* Get the Euler angles in degrees from a rotation Matrix
*
* @param m The rotation matrix.
* Don't forget to extract the rotation with [rotation] if it's transposed
* @param order The order in which to apply rotations.
* Default is [RotationsOrder.ZYX] which means that the object will first be rotated around its Z
* axis, then its Y axis and finally its X axis.
*/
fun eulerAngles(m: Mat4, order: RotationsOrder = RotationsOrder.ZYX): Float3 {
// We need to more simplify this with RotationsOrder VectorComponents mapped to MatrixColumn
return transform(Float3().apply {
when (order) {
RotationsOrder.XYZ -> {
this[order.pitch] = asin(clamp(m.z.x, -1.0f, 1.0f))
if (abs(m.z.x) < 0.9999999f) {
this[order.yaw] = atan2(-m.z.y, m.z.z)
this[order.roll] = atan2(-m.y.x, m.x.x)
} else {
this[order.yaw] = atan2(m.y.z, m.y.y)
this[order.roll] = 0.0f
}
}
RotationsOrder.XZY -> {
this[order.pitch] = asin(-clamp(m.y.x, -1.0f, 1.0f))
if (abs(m.y.x) < 0.9999999f) {
this[order.yaw] = atan2(m.y.z, m.y.y)
this[order.roll] = atan2(m.z.x, m.x.x)
} else {
this[order.yaw] = atan2(-m.z.y, m.z.z)
this[order.roll] = 0.0f
}
}
RotationsOrder.YXZ -> {
this[order.pitch] = asin(-clamp(m.z.y, -1.0f, 1.0f))
if (abs(m.z.y) < 0.9999999f) {
this[order.yaw] = atan2(m.z.x, m.z.z)
this[order.roll] = atan2(m.x.y, m.y.y)
} else {
this[order.yaw] = atan2(-m.x.z, m.x.x)
this[order.roll] = 0.0f
}
}
RotationsOrder.YZX -> {
this[order.pitch] = asin(clamp(m.x.y, -1.0f, 1.0f))
if (abs(m.x.y) < 0.9999999f) {
this[order.roll] = atan2(-m.z.y, m.y.y)
this[order.yaw] = atan2(-m.x.z, m.x.x)
} else {
this[order.roll] = 0.0f
this[order.yaw] = atan2(m.z.x, m.z.z)
}
}
RotationsOrder.ZXY -> {
this[order.pitch] = asin(clamp(m.y.z, -1.0f, 1.0f))
if (abs(m.y.z) < 0.9999999f) {
this[order.roll] = atan2(-m.x.z, m.z.z)
this[order.yaw] = atan2(-m.y.x, m.y.y)
} else {
this[order.roll] = 0.0f
this[order.yaw] = atan2(m.x.y, m.x.x)
}
}
RotationsOrder.ZYX -> {
this[order.pitch] = asin(-clamp(m.x.z, -1.0f, 1.0f))
if (abs(m.x.z) < 0.9999999f) {
this[order.roll] = atan2(m.y.z, m.z.z)
this[order.yaw] = atan2(m.x.y, m.x.x)
} else {
this[order.roll] = 0.0f
this[order.yaw] = atan2(-m.y.x, m.y.y)
}
}
}
}, ::degrees)
}
/**
* Get the [Quaternion] from a rotation Matrix
*
* @param m The rotation matrix.
* Don't forget to extract the rotation with [rotation] if it's transposed
* Extract Quaternion rotation from a Matrix
*/
fun quaternion(m: Mat4): Quaternion {
val trace = m.x.x + m.y.y + m.z.z
@@ -894,14 +673,9 @@ fun perspective(fov: Float, ratio: Float, near: Float, far: Float): Mat4 {
}
fun ortho(l: Float, r: Float, b: Float, t: Float, n: Float, f: Float) = Mat4(
Float4(x = 2.0f / (r - l)),
Float4(y = 2.0f / (t - b)),
Float4(z = -2.0f / (f - n)),
Float4(
-(r + l) / (r - l),
-(t + b) / (t - b),
-(f + n) / (f - n),
1.0f
)
Float4(x = 2.0f / (r - 1.0f)),
Float4(y = 2.0f / (t - b)),
Float4(z = -2.0f / (f - n)),
Float4(-(r + l) / (r - l), -(t + b) / (t - b), -(f + n) / (f - n), 1.0f)
)
@@ -191,7 +191,7 @@ class ModelViewer(
asset = assetLoader.createAsset(buffer)
asset?.let { asset ->
resourceLoader.asyncBeginLoad(asset)
animator = asset.instance.animator
animator = asset.getInstance().animator
asset.releaseSourceData()
}
}
@@ -214,7 +214,7 @@ class ModelViewer(
resourceLoader.addResourceData(uri, resourceBuffer)
}
resourceLoader.asyncBeginLoad(asset)
animator = asset.instance.animator
animator = asset.getInstance().animator
asset.releaseSourceData()
}
}
@@ -311,7 +311,7 @@ class ModelViewer(
var count = 0
val popRenderables = { count = asset.popRenderables(readyRenderables); count != 0 }
while (popRenderables()) {
for (i in 0 until count) {
for (i in 0..count - 1) {
val ri = rcm.getInstance(readyRenderables[i])
rcm.setScreenSpaceContactShadows(ri, true)
}
@@ -371,7 +371,7 @@ class ModelViewer(
resourceLoader.addResourceData(uri, buffer)
}
resourceLoader.asyncBeginLoad(asset)
animator = asset.instance.animator
animator = asset.getInstance().animator
asset.releaseSourceData()
}
}
@@ -405,19 +405,9 @@ class ModelViewer(
view.viewport = Viewport(0, 0, width, height)
cameraManipulator.setViewport(width, height)
updateCameraProjection()
synchronizePendingFrames(engine)
}
}
private fun synchronizePendingFrames(engine: Engine) {
// Wait for all pending frames to be processed before returning. This is to
// avoid a race between the surface being resized before pending frames are
// rendered into it.
val fence = engine.createFence()
fence.wait(Fence.Mode.FLUSH, Fence.WAIT_FOR_EVER)
engine.destroyFence(fence)
}
companion object {
private val kDefaultObjectPosition = Float3(0.0f, 0.0f, -4.0f)
}
@@ -33,9 +33,9 @@ data class Quaternion(
var x: Float = 0.0f,
var y: Float = 0.0f,
var z: Float = 0.0f,
var w: Float = 1.0f) {
var w: Float = 0.0f) {
constructor(v: Float3, w: Float = 1.0f) : this(v.x, v.y, v.z, w)
constructor(v: Float3, w: Float = 0.0f) : this(v.x, v.y, v.z, w)
constructor(v: Float4) : this(v.x, v.y, v.z, v.w)
constructor(q: Quaternion) : this(q.x, q.y, q.z, q.w)
@@ -52,84 +52,42 @@ data class Quaternion(
}
/**
* Construct a Quaternion from Euler angles using YPR around a specified order
* Construct a Quaternion from Euler angles using YPR around ZYX respectively
*
* Uses intrinsic Tait-Bryan angles. This means that rotations are performed with respect to
* the local coordinate system.
* That is, for order 'XYZ', the rotation is first around the X axis (which is the same as
* the world-X axis), then around local-Y (which may now be different from the world
* Y-axis), then local-Z (which may be different from the world Z-axis)
* The Euler angles are applied in ZYX order.
* i.e: a vector is first rotated about X (roll) then Y (pitch) and then Z (yaw).
*
* @param d Per axis Euler angles in degrees
* Yaw, pitch, roll (YPR) are taken accordingly to the rotations order input.
* @param order The order in which to apply rotations.
* Default is [RotationsOrder.ZYX] which means that the object will first be rotated around
* its Z axis, then its Y axis and finally its X axis.
*/
fun fromEuler(d: Float3, order: RotationsOrder = RotationsOrder.ZYX): Quaternion {
fun fromEuler(d: Float3): Quaternion {
val r = transform(d, ::radians)
return fromEuler(r[order.yaw], r[order.pitch], r[order.roll], order)
return fromEulerZYX(r.z, r.y, r.x)
}
/**
* Construct a Quaternion from Euler yaw, pitch, roll around a specified order.
* Construct a Quaternion from Euler angles using YPR around ZYX respectively
*
* @param roll about 1st rotation axis in radians. Z in case of ZYX order
* @param pitch about 2nd rotation axis in radians. Y in case of ZYX order
* @param yaw about 3rd rotation axis in radians. X in case of ZYX order
* @param order The order in which to apply rotations.
* Default is [RotationsOrder.ZYX] which means that the object will first be rotated around its Z
* axis, then its Y axis and finally its X axis.
* The Euler angles are applied in ZYX order.
* i.e: a vector is first rotated about X (roll) then Y (pitch) and then Z (yaw).
*
* @param roll about X axis in radians
* @param pitch about Y axis in radians
* @param yaw about Z axis in radians
*/
fun fromEuler(
yaw: Float = 0.0f,
pitch: Float = 0.0f,
roll: Float = 0.0f,
order: RotationsOrder = RotationsOrder.ZYX
): Quaternion {
val c1 = cos(yaw * 0.5f)
val s1 = sin(yaw * 0.5f)
val c2 = cos(pitch * 0.5f)
val s2 = sin(pitch * 0.5f)
val c3 = cos(roll * 0.5f)
val s3 = sin(roll * 0.5f)
return when (order) {
RotationsOrder.XZY -> Quaternion(
s1 * c2 * c3 - c1 * s2 * s3,
c1 * c2 * s3 - s1 * s2 * c3,
s1 * c2 * s3 + c1 * s2 * c3,
s1 * s2 * s3 + c1 * c2 * c3)
RotationsOrder.XYZ -> Quaternion(
s1 * c2 * c3 + s2 * s3 * c1,
s2 * c1 * c3 - s1 * s3 * c2,
s1 * s2 * c3 + s3 * c1 * c2,
c1 * c2 * c3 - s1 * s2 * s3
)
RotationsOrder.YXZ -> Quaternion(
s1 * c2 * s3 + c1 * s2 * c3,
s1 * c2 * c3 - c1 * s2 * s3,
c1 * c2 * s3 - s1 * s2 * c3,
s1 * s2 * s3 + c1 * c2 * c3
)
RotationsOrder.YZX -> Quaternion(
s1 * s2 * c3 + c1 * c2 * s3,
s1 * c2 * c3 + c1 * s2 * s3,
c1 * s2 * c3 - s1 * c2 * s3,
c1 * c2 * c3 - s1 * s2 * s3
)
RotationsOrder.ZYX -> Quaternion(
c1 * c2 * s3 - s1 * s2 * c3,
s1 * c2 * s3 + c1 * s2 * c3,
s1 * c2 * c3 - c1 * s2 * s3,
s1 * s2 * s3 + c1 * c2 * c3
)
RotationsOrder.ZXY -> Quaternion(
c1 * s2 * c3 - s1 * c2 * s3,
s1 * s2 * c3 + c1 * c2 * s3,
s1 * c2 * c3 + c1 * s2 * s3,
c1 * c2 * c3 - s1 * s2 * s3
)
}
fun fromEulerZYX(yaw: Float = 0.0f, pitch: Float = 0.0f, roll: Float = 0.0f): Quaternion {
val cy = cos(yaw * 0.5f)
val sy = sin(yaw * 0.5f)
val cp = cos(pitch * 0.5f)
val sp = sin(pitch * 0.5f)
val cr = cos(roll * 0.5f)
val sr = sin(roll * 0.5f)
return Quaternion(
sr * cp * cy - cr * sp * sy,
cr * sp * cy + sr * cp * sy,
cr * cp * sy - sr * sp * cy,
cr * cp * cy + sr * sp * sy
)
}
}
@@ -264,44 +222,16 @@ data class Quaternion(
inline operator fun minus(v: Float) = Quaternion(x - v, y - v, z - v, w - v)
inline operator fun times(v: Float) = Quaternion(x * v, y * v, z * v, w * v)
inline operator fun div(v: Float) = Quaternion(x / v, y / v, z / v, w / v)
inline fun compareTo(v: Float, delta: Float = 0.0f) = Float4(
x.compareTo(v, delta),
y.compareTo(v, delta),
z.compareTo(v, delta),
w.compareTo(v, delta)
)
inline fun equals(v: Float, delta: Float = 0.0f) = Bool4(
x.equals(v, delta),
y.equals(v, delta),
z.equals(v, delta),
w.equals(v, delta)
)
inline operator fun times(v: Float3) = (this * Quaternion(v, 0.0f) * inverse(this)).xyz
inline operator fun plus(q: Quaternion) = Quaternion(x + q.x, y + q.y, z + q.z, w + q.w)
inline operator fun minus(q: Quaternion) = Quaternion(x - q.x, y - q.y, z - q.z, w - q.w)
inline operator fun times(q: Quaternion) = Quaternion(
w * q.x + x * q.w + y * q.z - z * q.y,
w * q.y - x * q.z + y * q.w + z * q.x,
w * q.z + x * q.y - y * q.x + z * q.w,
w * q.w - x * q.x - y * q.y - z * q.z
)
inline fun compareTo(v: Float4, delta: Float = 0.0f) = Float4(
x.compareTo(v.x, delta),
y.compareTo(v.y, delta),
z.compareTo(v.z, delta),
w.compareTo(v.w, delta)
)
inline fun equals(v: Float4, delta: Float = 0.0f) = Bool4(
x.equals(v.x, delta),
y.equals(v.y, delta),
z.equals(v.z, delta),
w.equals(v.w, delta)
)
w * q.x + x * q.w + y * q.z - z * q.y,
w * q.y - x * q.z + y * q.w + z * q.x,
w * q.z + x * q.y - y * q.x + z * q.w,
w * q.w - x * q.x - y * q.y - z * q.z)
inline fun transform(block: (Float) -> Float): Quaternion {
x = block(x)
@@ -323,103 +253,6 @@ inline operator fun Float.minus(q: Quaternion) = Quaternion(this - q.x, this - q
inline operator fun Float.times(q: Quaternion) = Quaternion(this * q.x, this * q.y, this * q.z, this * q.w)
inline operator fun Float.div(q: Quaternion) = Quaternion(this / q.x, this / q.y, this / q.z, this / q.w)
inline fun lessThan(a: Quaternion, b: Float) = Bool4(
a.x < b,
a.y < b,
a.z < b,
a.w < b
)
inline fun lessThan(a: Quaternion, b: Quaternion) = Bool4(
a.x < b.x,
a.y < b.y,
a.z < b.z,
a.w < b.w
)
inline fun lessThanEqual(a: Quaternion, b: Float) = Bool4(
a.x <= b,
a.y <= b,
a.z <= b,
a.w <= b
)
inline fun lessThanEqual(a: Quaternion, b: Quaternion) = Bool4(
a.x <= b.x,
a.y <= b.y,
a.z <= b.z,
a.w <= b.w
)
inline fun greaterThan(a: Quaternion, b: Float) = Bool4(
a.x > b,
a.y > b,
a.z > b,
a.w > b
)
inline fun greaterThan(a: Quaternion, b: Quaternion) = Bool4(
a.x > b.y,
a.y > b.y,
a.z > b.z,
a.w > b.w
)
inline fun greaterThanEqual(a: Quaternion, b: Float) = Bool4(
a.x >= b,
a.y >= b,
a.z >= b,
a.w >= b
)
inline fun greaterThanEqual(a: Quaternion, b: Quaternion) = Bool4(
a.x >= b.x,
a.y >= b.y,
a.z >= b.z,
a.w >= b.w
)
inline fun equal(a: Quaternion, b: Float, delta: Float = 0.0f) = Bool4(
a.x.equals(b, delta),
a.y.equals(b, delta),
a.z.equals(b, delta),
a.w.equals(b, delta)
)
inline fun equal(a: Quaternion, b: Quaternion, delta: Float = 0.0f) = Bool4(
a.x.equals(b.x, delta),
a.y.equals(b.y, delta),
a.z.equals(b.z, delta),
a.w.equals(b.w, delta)
)
inline fun notEqual(a: Quaternion, b: Float, delta: Float = 0.0f) = Bool4(
!a.x.equals(b, delta),
!a.y.equals(b, delta),
!a.z.equals(b, delta),
!a.w.equals(b, delta)
)
inline fun notEqual(a: Quaternion, b: Quaternion, delta: Float = 0.0f) = Bool4(
!a.x.equals(b.x, delta),
!a.y.equals(b.y, delta),
!a.z.equals(b.z, delta),
!a.w.equals(b.w, delta)
)
inline infix fun Quaternion.lt(b: Float) = Bool4(x < b, y < b, z < b, w < b)
inline infix fun Quaternion.lt(b: Float4) = Bool4(x < b.x, y < b.y, z < b.z, w < b.w)
inline infix fun Quaternion.lte(b: Float) = Bool4(x <= b, y <= b, z <= b, w <= b)
inline infix fun Quaternion.lte(b: Float4) = Bool4(x <= b.x, y <= b.y, z <= b.z, w <= b.w)
inline infix fun Quaternion.gt(b: Float) = Bool4(x > b, y > b, z > b, w > b)
inline infix fun Quaternion.gt(b: Float4) = Bool4(x > b.x, y > b.y, z > b.z, w > b.w)
inline infix fun Quaternion.gte(b: Float) = Bool4(x >= b, y >= b, z >= b, w >= b)
inline infix fun Quaternion.gte(b: Float4) = Bool4(x >= b.x, y >= b.y, z >= b.z, w >= b.w)
inline infix fun Quaternion.eq(b: Float) = Bool4(x == b, y == b, z == b, w == b)
inline infix fun Quaternion.eq(b: Float4) = Bool4(x == b.x, y == b.y, z == b.z, w == b.w)
inline infix fun Quaternion.neq(b: Float) = Bool4(x != b, y != b, z != b, w != b)
inline infix fun Quaternion.neq(b: Float4) = Bool4(x != b.x, y != b.y, z != b.z, w != b.w)
inline fun abs(q: Quaternion) = Quaternion(abs(q.x), abs(q.y), abs(q.z), abs(q.w))
inline fun length(q: Quaternion) = sqrt(q.x * q.x + q.y * q.y + q.z * q.z + q.w * q.w)
inline fun length2(q: Quaternion) = q.x * q.x + q.y * q.y + q.z * q.z + q.w * q.w
@@ -445,10 +278,6 @@ fun cross(a: Quaternion, b: Quaternion): Quaternion {
return Quaternion(m.x, m.y, m.z, 0.0f)
}
fun angle(a: Quaternion, b: Quaternion): Float {
return 2.0f * acos(abs(clamp(dot(a, b), -1.0f, 1.0f)))
}
/**
* Spherical linear interpolation between two given orientations
*
@@ -458,38 +287,36 @@ fun angle(a: Quaternion, b: Quaternion): Float {
* @param a The beginning value
* @param b The ending value
* @param t The ratio between the two floats
* @param dotThreshold If the quaternion dot product is greater than this value
* (i.e. the quaternions are very close to each other), then the quaternions are
* linearly interpolated instead of spherically interpolated.
* @param valueEps Prevent blowing up when slerping between two quaternions that are very near each
* other. Linear interpolation (lerp) is returned in this case.
*
* @return Interpolated value between the two floats
*/
fun slerp(a: Quaternion, b: Quaternion, t: Float, dotThreshold: Float = 0.9995f): Quaternion {
fun slerp(a: Quaternion, b: Quaternion, t: Float, valueEps: Float = 0.0000000001f): Quaternion {
// could also be computed as: pow(q * inverse(p), t) * p;
var dot = dot(a, b)
var b1 = b
// If the dot product is negative, then the interpolation won't follow the shortest angular path
// between the two quaterions. In this case, invert the end quaternion to produce an equivalent
// rotation that will give us the path we want.
if (dot < 0.0f) {
dot = -dot
b1 = -b
}
val d = dot(a, b)
val absd = abs(d)
// Prevent blowing up when slerping between two quaternions that are very near each other.
return if (dot < dotThreshold) {
val angle = acos(dot)
val s = sin(angle)
a * sin((1.0f - t) * angle) / s + b1 * sin(t * angle) / s
} else {
// If the angle is too small, use linear interpolation
nlerp(a, b1, t)
if ((1.0f - absd) < valueEps) {
return normalize(lerp(if (d < 0.0f) -a else a, b, t))
}
val npq = sqrt(dot(a, a) * dot(b, b)) // ||p|| * ||q||
val acos = acos(clamp(absd / npq, -1.0f, 1.0f))
val acos0 = acos * (1.0f - t)
val acos1 = acos * t
val sina = sin(acos)
if (sina < valueEps) {
return normalize(lerp(a, b, t))
}
val isina = 1.0f / sina
val s0 = sin(acos0) * isina
val s1 = sin(acos1) * isina
// ensure we're taking the "short" side
return normalize(s0 * a + (if (d < 0.0f) -s1 else (s1)) * b)
}
fun lerp(a: Quaternion, b: Quaternion, t: Float): Quaternion {
return ((1.0f - t) * a) + (t * b)
return ((1 - t) * a) + (t * b)
}
fun nlerp(a: Quaternion, b: Quaternion, t: Float): Quaternion {
@@ -497,12 +324,19 @@ fun nlerp(a: Quaternion, b: Quaternion, t: Float): Quaternion {
}
/**
* Convert a Quaternion to Euler angles
* Convert a Quaternion to Euler angles using YPR around ZYX respectively
*
* @param order The order in which to apply rotations.
* Default is [RotationsOrder.ZYX] which means that the object will first be rotated around its Z
* axis, then its Y axis and finally its X axis.
* The Euler angles are applied in ZYX order
*/
fun eulerAngles(q: Quaternion, order: RotationsOrder = RotationsOrder.ZYX): Float3 {
return eulerAngles(rotation(q), order)
fun eulerAngles(q: Quaternion): Float3 {
val nq = normalize(q)
return Float3(
// roll (x-axis rotation)
degrees(atan2(2.0f * (nq.y * nq.z + nq.w * nq.x),
nq.w * nq.w - nq.x * nq.x - nq.y * nq.y + nq.z * nq.z)),
// pitch (y-axis rotation)
degrees(asin(-2.0f * (nq.x * nq.z - nq.w * nq.y))),
// yaw (z-axis rotation)
degrees(atan2(2.0f * (nq.x * nq.y + nq.w * nq.z),
nq.w * nq.w + nq.x * nq.x - nq.y * nq.y - nq.z * nq.z)))
}
@@ -28,21 +28,12 @@ const val INV_PI = 1.0f / FPI
const val INV_TWO_PI = INV_PI * 0.5f
const val INV_FOUR_PI = INV_PI * 0.25f
val HALF_ONE = Half(0x3c00.toUShort())
val HALF_TWO = Half(0x4000.toUShort())
inline fun clamp(x: Float, min: Float, max: Float) = if (x < min) min else (if (x > max) max else x)
inline fun clamp(x: Half, min: Half, max: Half) = if (x < min) min else (if (x > max) max else x)
inline fun clamp(x: Float, min: Float, max: Float)= if (x < min) min else (if (x > max) max else x)
inline fun saturate(x: Float) = clamp(x, 0.0f, 1.0f)
inline fun saturate(x: Half) = clamp(x, Half.POSITIVE_ZERO, HALF_ONE)
inline fun mix(a: Float, b: Float, x: Float) = a * (1.0f - x) + b * x
inline fun mix(a: Half, b: Half, x: Half) = a * (HALF_ONE - x) + b * x
inline fun degrees(v: Float) = v * (180.0f * INV_PI)
inline fun radians(v: Float) = v * (FPI / 180.0f)
@@ -51,6 +42,4 @@ inline fun fract(v: Float) = v % 1
inline fun sqr(v: Float) = v * v
inline fun sqr(v: Half) = v * v
inline fun pow(x: Float, y: Float) = (x.toDouble().pow(y.toDouble())).toFloat()
@@ -14,7 +14,7 @@
* limitations under the License.
*/
package com.google.android.filament.utils
package com.google.android.filament.textured
import android.content.res.Resources
import android.graphics.Bitmap
@@ -22,8 +22,6 @@ import kotlin.math.abs
import kotlin.math.max
import kotlin.math.min
import kotlin.math.sqrt
import kotlin.math.acos
import kotlin.math.absoluteValue
enum class VectorComponent {
X, Y, Z, W,
@@ -126,23 +124,11 @@ data class Float2(var x: Float = 0.0f, var y: Float = 0.0f) {
inline operator fun minus(v: Float) = Float2(x - v, y - v)
inline operator fun times(v: Float) = Float2(x * v, y * v)
inline operator fun div(v: Float) = Float2(x / v, y / v)
inline fun compareTo(v: Float, delta: Float = 0.0f) = Float2(
x.compareTo(v, delta),
y.compareTo(v, delta)
)
inline fun equals(v: Float, delta: Float = 0.0f) = x.equals(v, delta) && y.equals(v, delta)
inline operator fun plus(v: Float2) = Float2(x + v.x, y + v.y)
inline operator fun minus(v: Float2) = Float2(x - v.x, y - v.y)
inline operator fun times(v: Float2) = Float2(x * v.x, y * v.y)
inline operator fun div(v: Float2) = Float2(x / v.x, y / v.y)
inline fun compareTo(v: Float2, delta: Float = 0.0f) = Float2(
x.compareTo(v.x, delta),
y.compareTo(v.y, delta)
)
inline fun equals(v: Float2, delta: Float = 0.0f) = x.equals(v.x, delta) && y.equals(v.y, delta)
inline fun transform(block: (Float) -> Float): Float2 {
x = block(x)
@@ -305,14 +291,6 @@ data class Float3(var x: Float = 0.0f, var y: Float = 0.0f, var z: Float = 0.0f)
inline operator fun minus(v: Float) = Float3(x - v, y - v, z - v)
inline operator fun times(v: Float) = Float3(x * v, y * v, z * v)
inline operator fun div(v: Float) = Float3(x / v, y / v, z / v)
inline fun compareTo(v: Float, delta: Float = 0.0f) = Float3(
x.compareTo(v, delta),
y.compareTo(v, delta),
z.compareTo(v, delta)
)
inline fun equals(v: Float, delta: Float = 0.0f) =
x.equals(v, delta) && y.equals(v, delta) && z.equals(v, delta)
inline operator fun plus(v: Float2) = Float3(x + v.x, y + v.y, z)
inline operator fun minus(v: Float2) = Float3(x - v.x, y - v.y, z)
@@ -323,14 +301,6 @@ data class Float3(var x: Float = 0.0f, var y: Float = 0.0f, var z: Float = 0.0f)
inline operator fun minus(v: Float3) = Float3(x - v.x, y - v.y, z - v.z)
inline operator fun times(v: Float3) = Float3(x * v.x, y * v.y, z * v.z)
inline operator fun div(v: Float3) = Float3(x / v.x, y / v.y, z / v.z)
inline fun compareTo(v: Float3, delta: Float = 0.0f) = Float3(
x.compareTo(v.x, delta),
y.compareTo(v.y, delta),
z.compareTo(v.z, delta)
)
inline fun equals(v: Float3, delta: Float = 0.0f) =
x.equals(v.x, delta) && y.equals(v.y, delta) && z.equals(v.z, delta)
inline fun transform(block: (Float) -> Float): Float3 {
x = block(x)
@@ -564,15 +534,6 @@ data class Float4(
inline operator fun minus(v: Float) = Float4(x - v, y - v, z - v, w - v)
inline operator fun times(v: Float) = Float4(x * v, y * v, z * v, w * v)
inline operator fun div(v: Float) = Float4(x / v, y / v, z / v, w / v)
inline fun compareTo(v: Float, delta: Float = 0.0f) = Float4(
x.compareTo(v, delta),
y.compareTo(v, delta),
z.compareTo(v, delta),
w.compareTo(v, delta)
)
inline fun equals(v: Float, delta: Float = 0.0f) =
x.equals(v, delta) && y.equals(v, delta) && z.equals(v, delta) && w.equals(v, delta)
inline operator fun plus(v: Float2) = Float4(x + v.x, y + v.y, z, w)
inline operator fun minus(v: Float2) = Float4(x - v.x, y - v.y, z, w)
@@ -588,15 +549,6 @@ data class Float4(
inline operator fun minus(v: Float4) = Float4(x - v.x, y - v.y, z - v.z, w - v.w)
inline operator fun times(v: Float4) = Float4(x * v.x, y * v.y, z * v.z, w * v.w)
inline operator fun div(v: Float4) = Float4(x / v.x, y / v.y, z / v.z, w / v.w)
inline fun compareTo(v: Float4, delta: Float = 0.0f) = Float4(
x.compareTo(v.x, delta),
y.compareTo(v.y, delta),
z.compareTo(v.z, delta),
w.compareTo(v.w, delta)
)
inline fun equals(v: Float4, delta: Float = 0.0f) =
x.equals(v.x, delta) && y.equals(v.y, delta) && z.equals(v.z, delta) && w.equals(v.w, delta)
inline fun transform(block: (Float) -> Float): Float4 {
x = block(x)
@@ -614,12 +566,6 @@ inline operator fun Float.minus(v: Float2) = Float2(this - v.x, this - v.y)
inline operator fun Float.times(v: Float2) = Float2(this * v.x, this * v.y)
inline operator fun Float.div(v: Float2) = Float2(this / v.x, this / v.y)
inline fun Float.compareTo(v: Float, delta: Float): Float = when {
equals(v, delta) -> 0.0f
else -> compareTo(v).toFloat()
}
inline fun Float.equals(v: Float, delta: Float) = (this - v).absoluteValue < delta
inline fun abs(v: Float2) = Float2(abs(v.x), abs(v.y))
inline fun length(v: Float2) = sqrt(v.x * v.x + v.y * v.y)
inline fun length2(v: Float2) = v.x * v.x + v.y * v.y
@@ -637,11 +583,6 @@ fun refract(i: Float2, n: Float2, eta: Float): Float2 {
return if (k < 0.0f) Float2(0.0f) else eta * i - (eta * d + sqrt(k)) * n
}
inline fun angle(a: Float2, b: Float2): Float {
val l = length(a) * length(b)
return if (l == 0.0f) 0.0f else acos(clamp(dot(a, b) / l, -1.0f, 1.0f))
}
inline fun clamp(v: Float2, min: Float, max: Float): Float2 {
return Float2(
clamp(v.x, min, max),
@@ -685,25 +626,10 @@ inline fun greaterThan(a: Float2, b: Float) = Bool2(a.x > b, a.y > b)
inline fun greaterThan(a: Float2, b: Float2) = Bool2(a.x > b.y, a.y > b.y)
inline fun greaterThanEqual(a: Float2, b: Float) = Bool2(a.x >= b, a.y >= b)
inline fun greaterThanEqual(a: Float2, b: Float2) = Bool2(a.x >= b.x, a.y >= b.y)
inline fun equal(a: Float2, b: Float, delta: Float = 0.0f) = Bool2(
a.x.equals(b, delta),
a.y.equals(b, delta)
)
inline fun equal(a: Float2, b: Float2, delta: Float = 0.0f) = Bool2(
a.x.equals(b.x, delta),
a.y.equals(b.y, delta)
)
inline fun notEqual(a: Float2, b: Float, delta: Float = 0.0f) = Bool2(
!a.x.equals(b, delta),
!a.y.equals(b, delta)
)
inline fun notEqual(a: Float2, b: Float2, delta: Float = 0.0f) = Bool2(
!a.x.equals(b.x, delta),
!a.y.equals(b.y, delta)
)
inline fun equal(a: Float2, b: Float) = Bool2(a.x == b, a.y == b)
inline fun equal(a: Float2, b: Float2) = Bool2(a.x == b.x, a.y == b.y)
inline fun notEqual(a: Float2, b: Float) = Bool2(a.x != b, a.y != b)
inline fun notEqual(a: Float2, b: Float2) = Bool2(a.x != b.x, a.y != b.y)
inline infix fun Float2.lt(b: Float) = Bool2(x < b, y < b)
inline infix fun Float2.lt(b: Float2) = Bool2(x < b.x, y < b.y)
@@ -749,11 +675,6 @@ fun refract(i: Float3, n: Float3, eta: Float): Float3 {
return if (k < 0.0f) Float3(0.0f) else eta * i - (eta * d + sqrt(k)) * n
}
inline fun angle(a: Float3, b: Float3): Float {
val l = length(a) * length(b)
return if (l == 0.0f) 0.0f else acos(clamp(dot(a, b) / l, -1.0f, 1.0f))
}
inline fun clamp(v: Float3, min: Float, max: Float): Float3 {
return Float3(
clamp(v.x, min, max),
@@ -801,29 +722,10 @@ inline fun greaterThan(a: Float3, b: Float) = Bool3(a.x > b, a.y > b, a.z > b)
inline fun greaterThan(a: Float3, b: Float3) = Bool3(a.x > b.y, a.y > b.y, a.z > b.z)
inline fun greaterThanEqual(a: Float3, b: Float) = Bool3(a.x >= b, a.y >= b, a.z >= b)
inline fun greaterThanEqual(a: Float3, b: Float3) = Bool3(a.x >= b.x, a.y >= b.y, a.z >= b.z)
inline fun equal(a: Float3, b: Float, delta: Float = 0.0f) = Bool3(
a.x.equals(b, delta),
a.y.equals(b, delta),
a.z.equals(b, delta)
)
inline fun equal(a: Float3, b: Float3, delta: Float = 0.0f) = Bool3(
a.x.equals(b.x, delta),
a.y.equals(b.y, delta),
a.z.equals(b.z, delta)
)
inline fun notEqual(a: Float3, b: Float, delta: Float = 0.0f) = Bool3(
!a.x.equals(b, delta),
!a.y.equals(b, delta),
!a.z.equals(b, delta)
)
inline fun notEqual(a: Float3, b: Float3, delta: Float = 0.0f) = Bool3(
!a.x.equals(b.x, delta),
!a.y.equals(b.y, delta),
!a.z.equals(b.z, delta)
)
inline fun equal(a: Float3, b: Float) = Bool3(a.x == b, a.y == b, a.z == b)
inline fun equal(a: Float3, b: Float3) = Bool3(a.x == b.x, a.y == b.y, a.z == b.z)
inline fun notEqual(a: Float3, b: Float) = Bool3(a.x != b, a.y != b, a.z != b)
inline fun notEqual(a: Float3, b: Float3) = Bool3(a.x != b.x, a.y != b.y, a.z != b.z)
inline infix fun Float3.lt(b: Float) = Bool3(x < b, y < b, z < b)
inline infix fun Float3.lt(b: Float3) = Bool3(x < b.x, y < b.y, z < b.z)
@@ -905,44 +807,17 @@ inline fun transform(v: Float4, block: (Float) -> Float) = v.copy().transform(bl
inline fun lessThan(a: Float4, b: Float) = Bool4(a.x < b, a.y < b, a.z < b, a.w < b)
inline fun lessThan(a: Float4, b: Float4) = Bool4(a.x < b.x, a.y < b.y, a.z < b.z, a.w < b.w)
inline fun lessThanEqual(a: Float4, b: Float) = Bool4(a.x <= b, a.y <= b, a.z <= b, a.w <= b)
inline fun lessThanEqual(a: Float4, b: Float4) =
Bool4(a.x <= b.x, a.y <= b.y, a.z <= b.z, a.w <= b.w)
inline fun lessThanEqual(a: Float4, b: Float4) = Bool4(a.x <= b.x, a.y <= b.y, a.z <= b.z, a.w <= b.w)
inline fun greaterThan(a: Float4, b: Float) = Bool4(a.x > b, a.y > b, a.z > b, a.w > b)
inline fun greaterThan(a: Float4, b: Float4) = Bool4(a.x > b.y, a.y > b.y, a.z > b.z, a.w > b.w)
inline fun greaterThanEqual(a: Float4, b: Float) = Bool4(a.x >= b, a.y >= b, a.z >= b, a.w >= b)
inline fun greaterThanEqual(a: Float4, b: Float4) =
Bool4(a.x >= b.x, a.y >= b.y, a.z >= b.z, a.w >= b.w)
inline fun greaterThanEqual(a: Float4, b: Float4) = Bool4(a.x >= b.x, a.y >= b.y, a.z >= b.z, a.w >= b.w)
inline fun equal(a: Float4, b: Float) = Bool4(a.x == b, a.y == b, a.z == b, a.w == b)
inline fun equal(a: Float4, b: Float4) = Bool4(a.x == b.x, a.y == b.y, a.z == b.z, a.w == b.w)
inline fun notEqual(a: Float4, b: Float) = Bool4(a.x != b, a.y != b, a.z != b, a.w != b)
inline fun notEqual(a: Float4, b: Float4) = Bool4(a.x != b.x, a.y != b.y, a.z != b.z, a.w != b.w)
inline fun equal(a: Float4, b: Float, delta: Float = 0.0f) = Bool4(
a.x.equals(b, delta),
a.y.equals(b, delta),
a.z.equals(b, delta),
a.w.equals(b, delta)
)
inline fun equal(a: Float4, b: Float4, delta: Float = 0.0f) = Bool4(
a.x.equals(b.x, delta),
a.y.equals(b.y, delta),
a.z.equals(b.z, delta),
a.w.equals(b.w, delta)
)
inline fun notEqual(a: Float4, b: Float, delta: Float = 0.0f) = Bool4(
!a.x.equals(b, delta),
!a.y.equals(b, delta),
!a.z.equals(b, delta),
!a.w.equals(b, delta)
)
inline fun notEqual(a: Float4, b: Float4, delta: Float = 0.0f) = Bool4(
!a.x.equals(b.x, delta),
!a.y.equals(b.y, delta),
!a.z.equals(b.z, delta),
!a.w.equals(b.w, delta)
)
inline infix fun Float4.lt(b: Float) = Bool4(x < b, y < b, z < b, w < b)
inline infix fun Float4.lt(b: Float) = Bool4(x < b, y < b, z < b, a < b)
inline infix fun Float4.lt(b: Float4) = Bool4(x < b.x, y < b.y, z < b.z, w < b.w)
inline infix fun Float4.lte(b: Float) = Bool4(x <= b, y <= b, z <= b, w <= b)
inline infix fun Float4.lte(b: Float4) = Bool4(x <= b.x, y <= b.y, z <= b.z, w <= b.w)
@@ -1402,753 +1277,3 @@ data class Bool4(
set(index4, v)
}
}
data class Half2(var x: Half = Half.POSITIVE_ZERO, var y: Half = Half.POSITIVE_ZERO) {
constructor(v: Half) : this(v, v)
constructor(v: Half2) : this(v.x, v.y)
inline var r: Half
get() = x
set(value) {
x = value
}
inline var g: Half
get() = y
set(value) {
y = value
}
inline var s: Half
get() = x
set(value) {
x = value
}
inline var t: Half
get() = y
set(value) {
y = value
}
inline var xy: Half2
get() = Half2(x, y)
set(value) {
x = value.x
y = value.y
}
inline var rg: Half2
get() = Half2(x, y)
set(value) {
x = value.x
y = value.y
}
inline var st: Half2
get() = Half2(x, y)
set(value) {
x = value.x
y = value.y
}
operator fun get(index: VectorComponent) = when (index) {
VectorComponent.X, VectorComponent.R, VectorComponent.S -> x
VectorComponent.Y, VectorComponent.G, VectorComponent.T -> y
else -> throw IllegalArgumentException("index must be X, Y, R, G, S or T")
}
operator fun get(index1: VectorComponent, index2: VectorComponent): Half2 {
return Half2(get(index1), get(index2))
}
operator fun get(index: Int) = when (index) {
0 -> x
1 -> y
else -> throw IllegalArgumentException("index must be in 0..1")
}
operator fun get(index1: Int, index2: Int) = Half2(get(index1), get(index2))
inline operator fun invoke(index: Int) = get(index - 1)
operator fun set(index: Int, v: Half) = when (index) {
0 -> x = v
1 -> y = v
else -> throw IllegalArgumentException("index must be in 0..1")
}
operator fun set(index1: Int, index2: Int, v: Half) {
set(index1, v)
set(index2, v)
}
operator fun set(index: VectorComponent, v: Half) = when (index) {
VectorComponent.X, VectorComponent.R, VectorComponent.S -> x = v
VectorComponent.Y, VectorComponent.G, VectorComponent.T -> y = v
else -> throw IllegalArgumentException("index must be X, Y, R, G, S or T")
}
operator fun set(index1: VectorComponent, index2: VectorComponent, v: Half) {
set(index1, v)
set(index2, v)
}
operator fun unaryMinus() = Half2(-x, -y)
operator fun inc() = Half2(x++, y++)
operator fun dec() = Half2(x--, y--)
inline operator fun plus(v: Half) = Half2(x + v, y + v)
inline operator fun minus(v: Half) = Half2(x - v, y - v)
inline operator fun times(v: Half) = Half2(x * v, y * v)
inline operator fun div(v: Half) = Half2(x / v, y / v)
inline operator fun plus(v: Half2) = Half2(x + v.x, y + v.y)
inline operator fun minus(v: Half2) = Half2(x - v.x, y - v.y)
inline operator fun times(v: Half2) = Half2(x * v.x, y * v.y)
inline operator fun div(v: Half2) = Half2(x / v.x, y / v.y)
inline fun transform(block: (Half) -> Half): Half2 {
x = block(x)
y = block(y)
return this
}
fun toFloatArray() = floatArrayOf(x.toFloat(), y.toFloat())
}
data class Half3(
var x: Half = Half.POSITIVE_ZERO,
var y: Half = Half.POSITIVE_ZERO,
var z: Half = Half.POSITIVE_ZERO
) {
constructor(v: Half) : this(v, v, v)
constructor(v: Half2, z: Half = Half.POSITIVE_ZERO) : this(v.x, v.y, z)
constructor(v: Half3) : this(v.x, v.y, v.z)
inline var r: Half
get() = x
set(value) {
x = value
}
inline var g: Half
get() = y
set(value) {
y = value
}
inline var b: Half
get() = z
set(value) {
z = value
}
inline var s: Half
get() = x
set(value) {
x = value
}
inline var t: Half
get() = y
set(value) {
y = value
}
inline var p: Half
get() = z
set(value) {
z = value
}
inline var xy: Half2
get() = Half2(x, y)
set(value) {
x = value.x
y = value.y
}
inline var rg: Half2
get() = Half2(x, y)
set(value) {
x = value.x
y = value.y
}
inline var st: Half2
get() = Half2(x, y)
set(value) {
x = value.x
y = value.y
}
inline var rgb: Half3
get() = Half3(x, y, z)
set(value) {
x = value.x
y = value.y
z = value.z
}
inline var xyz: Half3
get() = Half3(x, y, z)
set(value) {
x = value.x
y = value.y
z = value.z
}
inline var stp: Half3
get() = Half3(x, y, z)
set(value) {
x = value.x
y = value.y
z = value.z
}
operator fun get(index: VectorComponent) = when (index) {
VectorComponent.X, VectorComponent.R, VectorComponent.S -> x
VectorComponent.Y, VectorComponent.G, VectorComponent.T -> y
VectorComponent.Z, VectorComponent.B, VectorComponent.P -> z
else -> throw IllegalArgumentException("index must be X, Y, Z, R, G, B, S, T or P")
}
operator fun get(index1: VectorComponent, index2: VectorComponent): Half2 {
return Half2(get(index1), get(index2))
}
operator fun get(
index1: VectorComponent, index2: VectorComponent, index3: VectorComponent): Half3 {
return Half3(get(index1), get(index2), get(index3))
}
operator fun get(index: Int) = when (index) {
0 -> x
1 -> y
2 -> z
else -> throw IllegalArgumentException("index must be in 0..2")
}
operator fun get(index1: Int, index2: Int) = Half2(get(index1), get(index2))
operator fun get(index1: Int, index2: Int, index3: Int): Half3 {
return Half3(get(index1), get(index2), get(index3))
}
inline operator fun invoke(index: Int) = get(index - 1)
operator fun set(index: Int, v: Half) = when (index) {
0 -> x = v
1 -> y = v
2 -> z = v
else -> throw IllegalArgumentException("index must be in 0..2")
}
operator fun set(index1: Int, index2: Int, v: Half) {
set(index1, v)
set(index2, v)
}
operator fun set(index1: Int, index2: Int, index3: Int, v: Half) {
set(index1, v)
set(index2, v)
set(index3, v)
}
operator fun set(index: VectorComponent, v: Half) = when (index) {
VectorComponent.X, VectorComponent.R, VectorComponent.S -> x = v
VectorComponent.Y, VectorComponent.G, VectorComponent.T -> y = v
VectorComponent.Z, VectorComponent.B, VectorComponent.P -> z = v
else -> throw IllegalArgumentException("index must be X, Y, Z, R, G, B, S, T or P")
}
operator fun set(index1: VectorComponent, index2: VectorComponent, v: Half) {
set(index1, v)
set(index2, v)
}
operator fun set(
index1: VectorComponent, index2: VectorComponent, index3: VectorComponent, v: Half) {
set(index1, v)
set(index2, v)
set(index3, v)
}
operator fun unaryMinus() = Half3(-x, -y, -z)
operator fun inc() = Half3(x++, y++, z++)
operator fun dec() = Half3(x--, y--, z--)
inline operator fun plus(v: Half) = Half3(x + v, y + v, z + v)
inline operator fun minus(v: Half) = Half3(x - v, y - v, z - v)
inline operator fun times(v: Half) = Half3(x * v, y * v, z * v)
inline operator fun div(v: Half) = Half3(x / v, y / v, z / v)
inline operator fun plus(v: Half2) = Half3(x + v.x, y + v.y, z)
inline operator fun minus(v: Half2) = Half3(x - v.x, y - v.y, z)
inline operator fun times(v: Half2) = Half3(x * v.x, y * v.y, z)
inline operator fun div(v: Half2) = Half3(x / v.x, y / v.y, z)
inline operator fun plus(v: Half3) = Half3(x + v.x, y + v.y, z + v.z)
inline operator fun minus(v: Half3) = Half3(x - v.x, y - v.y, z - v.z)
inline operator fun times(v: Half3) = Half3(x * v.x, y * v.y, z * v.z)
inline operator fun div(v: Half3) = Half3(x / v.x, y / v.y, z / v.z)
inline fun transform(block: (Half) -> Half): Half3 {
x = block(x)
y = block(y)
z = block(z)
return this
}
fun toFloatArray() = floatArrayOf(x.toFloat(), y.toFloat(), z.toFloat())
}
data class Half4(
var x: Half = Half.POSITIVE_ZERO,
var y: Half = Half.POSITIVE_ZERO,
var z: Half = Half.POSITIVE_ZERO,
var w: Half = Half.POSITIVE_ZERO
) {
constructor(v: Half) : this(v, v, v, v)
constructor(v: Half2, z: Half = Half.POSITIVE_ZERO, w: Half = Half.POSITIVE_ZERO) : this(v.x, v.y, z, w)
constructor(v: Half3, w: Half = Half.POSITIVE_ZERO) : this(v.x, v.y, v.z, w)
constructor(v: Half4) : this(v.x, v.y, v.z, v.w)
inline var r: Half
get() = x
set(value) {
x = value
}
inline var g: Half
get() = y
set(value) {
y = value
}
inline var b: Half
get() = z
set(value) {
z = value
}
inline var a: Half
get() = w
set(value) {
w = value
}
inline var s: Half
get() = x
set(value) {
x = value
}
inline var t: Half
get() = y
set(value) {
y = value
}
inline var p: Half
get() = z
set(value) {
z = value
}
inline var q: Half
get() = w
set(value) {
w = value
}
inline var xy: Half2
get() = Half2(x, y)
set(value) {
x = value.x
y = value.y
}
inline var rg: Half2
get() = Half2(x, y)
set(value) {
x = value.x
y = value.y
}
inline var st: Half2
get() = Half2(x, y)
set(value) {
x = value.x
y = value.y
}
inline var rgb: Half3
get() = Half3(x, y, z)
set(value) {
x = value.x
y = value.y
z = value.z
}
inline var xyz: Half3
get() = Half3(x, y, z)
set(value) {
x = value.x
y = value.y
z = value.z
}
inline var stp: Half3
get() = Half3(x, y, z)
set(value) {
x = value.x
y = value.y
z = value.z
}
inline var rgba: Half4
get() = Half4(x, y, z, w)
set(value) {
x = value.x
y = value.y
z = value.z
w = value.w
}
inline var xyzw: Half4
get() = Half4(x, y, z, w)
set(value) {
x = value.x
y = value.y
z = value.z
w = value.w
}
inline var stpq: Half4
get() = Half4(x, y, z, w)
set(value) {
x = value.x
y = value.y
z = value.z
w = value.w
}
operator fun get(index: VectorComponent) = when (index) {
VectorComponent.X, VectorComponent.R, VectorComponent.S -> x
VectorComponent.Y, VectorComponent.G, VectorComponent.T -> y
VectorComponent.Z, VectorComponent.B, VectorComponent.P -> z
VectorComponent.W, VectorComponent.A, VectorComponent.Q -> w
}
operator fun get(index1: VectorComponent, index2: VectorComponent): Half2 {
return Half2(get(index1), get(index2))
}
operator fun get(
index1: VectorComponent,
index2: VectorComponent,
index3: VectorComponent): Half3 {
return Half3(get(index1), get(index2), get(index3))
}
operator fun get(
index1: VectorComponent,
index2: VectorComponent,
index3: VectorComponent,
index4: VectorComponent): Half4 {
return Half4(get(index1), get(index2), get(index3), get(index4))
}
operator fun get(index: Int) = when (index) {
0 -> x
1 -> y
2 -> z
3 -> w
else -> throw IllegalArgumentException("index must be in 0..3")
}
operator fun get(index1: Int, index2: Int) = Half2(get(index1), get(index2))
operator fun get(index1: Int, index2: Int, index3: Int): Half3 {
return Half3(get(index1), get(index2), get(index3))
}
operator fun get(index1: Int, index2: Int, index3: Int, index4: Int): Half4 {
return Half4(get(index1), get(index2), get(index3), get(index4))
}
inline operator fun invoke(index: Int) = get(index - 1)
operator fun set(index: Int, v: Half) = when (index) {
0 -> x = v
1 -> y = v
2 -> z = v
3 -> w = v
else -> throw IllegalArgumentException("index must be in 0..3")
}
operator fun set(index1: Int, index2: Int, v: Half) {
set(index1, v)
set(index2, v)
}
operator fun set(index1: Int, index2: Int, index3: Int, v: Half) {
set(index1, v)
set(index2, v)
set(index3, v)
}
operator fun set(index1: Int, index2: Int, index3: Int, index4: Int, v: Half) {
set(index1, v)
set(index2, v)
set(index3, v)
set(index4, v)
}
operator fun set(index: VectorComponent, v: Half) = when (index) {
VectorComponent.X, VectorComponent.R, VectorComponent.S -> x = v
VectorComponent.Y, VectorComponent.G, VectorComponent.T -> y = v
VectorComponent.Z, VectorComponent.B, VectorComponent.P -> z = v
VectorComponent.W, VectorComponent.A, VectorComponent.Q -> w = v
}
operator fun set(index1: VectorComponent, index2: VectorComponent, v: Half) {
set(index1, v)
set(index2, v)
}
operator fun set(
index1: VectorComponent, index2: VectorComponent, index3: VectorComponent, v: Half) {
set(index1, v)
set(index2, v)
set(index3, v)
}
operator fun set(
index1: VectorComponent, index2: VectorComponent,
index3: VectorComponent, index4: VectorComponent, v: Half) {
set(index1, v)
set(index2, v)
set(index3, v)
set(index4, v)
}
operator fun unaryMinus() = Half4(-x, -y, -z, -w)
operator fun inc() = Half4(x++, y++, z++, w++)
operator fun dec() = Half4(x--, y--, z--, w--)
inline operator fun plus(v: Half) = Half4(x + v, y + v, z + v, w + v)
inline operator fun minus(v: Half) = Half4(x - v, y - v, z - v, w - v)
inline operator fun times(v: Half) = Half4(x * v, y * v, z * v, w * v)
inline operator fun div(v: Half) = Half4(x / v, y / v, z / v, w / v)
inline operator fun plus(v: Half2) = Half4(x + v.x, y + v.y, z, w)
inline operator fun minus(v: Half2) = Half4(x - v.x, y - v.y, z, w)
inline operator fun times(v: Half2) = Half4(x * v.x, y * v.y, z, w)
inline operator fun div(v: Half2) = Half4(x / v.x, y / v.y, z, w)
inline operator fun plus(v: Half3) = Half4(x + v.x, y + v.y, z + v.z, w)
inline operator fun minus(v: Half3) = Half4(x - v.x, y - v.y, z - v.z, w)
inline operator fun times(v: Half3) = Half4(x * v.x, y * v.y, z * v.z, w)
inline operator fun div(v: Half3) = Half4(x / v.x, y / v.y, z / v.z, w)
inline operator fun plus(v: Half4) = Half4(x + v.x, y + v.y, z + v.z, w + v.w)
inline operator fun minus(v: Half4) = Half4(x - v.x, y - v.y, z - v.z, w - v.w)
inline operator fun times(v: Half4) = Half4(x * v.x, y * v.y, z * v.z, w * v.w)
inline operator fun div(v: Half4) = Half4(x / v.x, y / v.y, z / v.z, w / v.w)
inline fun transform(block: (Half) -> Half): Half4 {
x = block(x)
y = block(y)
z = block(z)
w = block(w)
return this
}
fun toFloatArray() = floatArrayOf(x.toFloat(), y.toFloat(), z.toFloat(), w.toFloat())
}
inline fun min(v: Half2) = min(v.x, v.y)
inline fun min(a: Half2, b: Half2) = Half2(min(a.x, b.x), min(a.y, b.y))
inline fun max(v: Half2) = max(v.x, v.y)
inline fun max(a: Half2, b: Half2) = Half2(max(a.x, b.x), max(a.y, b.y))
inline fun transform(v: Half2, block: (Half) -> Half) = v.copy().transform(block)
inline fun lessThan(a: Half2, b: Half) = Bool2(a.x < b, a.y < b)
inline fun lessThan(a: Half2, b: Half2) = Bool2(a.x < b.x, a.y < b.y)
inline fun lessThanEqual(a: Half2, b: Half) = Bool2(a.x <= b, a.y <= b)
inline fun lessThanEqual(a: Half2, b: Half2) = Bool2(a.x <= b.x, a.y <= b.y)
inline fun greaterThan(a: Half2, b: Half) = Bool2(a.x > b, a.y > b)
inline fun greaterThan(a: Half2, b: Half2) = Bool2(a.x > b.y, a.y > b.y)
inline fun greaterThanEqual(a: Half2, b: Half) = Bool2(a.x >= b, a.y >= b)
inline fun greaterThanEqual(a: Half2, b: Half2) = Bool2(a.x >= b.x, a.y >= b.y)
inline fun equal(a: Half2, b: Half) = Bool2(a.x == b, a.y == b)
inline fun equal(a: Half2, b: Half2) = Bool2(a.x == b.x, a.y == b.y)
inline fun notEqual(a: Half2, b: Half) = Bool2(a.x != b, a.y != b)
inline fun notEqual(a: Half2, b: Half2) = Bool2(a.x != b.x, a.y != b.y)
inline infix fun Half2.lt(b: Half) = Bool2(x < b, y < b)
inline infix fun Half2.lt(b: Half2) = Bool2(x < b.x, y < b.y)
inline infix fun Half2.lte(b: Half) = Bool2(x <= b, y <= b)
inline infix fun Half2.lte(b: Half2) = Bool2(x <= b.x, y <= b.y)
inline infix fun Half2.gt(b: Half) = Bool2(x > b, y > b)
inline infix fun Half2.gt(b: Half2) = Bool2(x > b.x, y > b.y)
inline infix fun Half2.gte(b: Half) = Bool2(x >= b, y >= b)
inline infix fun Half2.gte(b: Half2) = Bool2(x >= b.x, y >= b.y)
inline infix fun Half2.eq(b: Half) = Bool2(x == b, y == b)
inline infix fun Half2.eq(b: Half2) = Bool2(x == b.x, y == b.y)
inline infix fun Half2.neq(b: Half) = Bool2(x != b, y != b)
inline infix fun Half2.neq(b: Half2) = Bool2(x != b.x, y != b.y)
inline operator fun Half.plus(v: Half3) = Half3(this + v.x, this + v.y, this + v.z)
inline operator fun Half.minus(v: Half3) = Half3(this - v.x, this - v.y, this - v.z)
inline operator fun Half.times(v: Half3) = Half3(this * v.x, this * v.y, this * v.z)
inline operator fun Half.div(v: Half3) = Half3(this / v.x, this / v.y, this / v.z)
inline fun abs(v: Half3) = Half3(abs(v.x), abs(v.y), abs(v.z))
inline fun length(v: Half3) = sqrt(v.x * v.x + v.y * v.y + v.z * v.z)
inline fun length2(v: Half3) = v.x * v.x + v.y * v.y + v.z * v.z
inline fun distance(a: Half3, b: Half3) = length(a - b)
inline fun dot(a: Half3, b: Half3) = a.x * b.x + a.y * b.y + a.z * b.z
inline fun cross(a: Half3, b: Half3): Half3 {
return Half3(a.y * b.z - a.z * b.y, a.z * b.x - a.x * b.z, a.x * b.y - a.y * b.x)
}
inline infix fun Half3.x(v: Half3): Half3 {
return Half3(y * v.z - z * v.y, z * v.x - x * v.z, x * v.y - y * v.x)
}
fun normalize(v: Half3): Half3 {
val l = HALF_ONE / length(v)
return Half3(v.x * l, v.y * l, v.z * l)
}
inline fun reflect(i: Half3, n: Half3) = i - HALF_TWO * dot(n, i) * n
fun refract(i: Half3, n: Half3, eta: Half): Half3 {
val d = dot(n, i)
val k = HALF_ONE - eta * eta * (HALF_ONE - sqr(d))
return if (k < Half.POSITIVE_ZERO) Half3() else eta * i - (eta * d + sqrt(k)) * n
}
inline fun clamp(v: Half3, min: Half, max: Half): Half3 {
return Half3(
clamp(v.x, min, max),
clamp(v.y, min, max),
clamp(v.z, min, max)
)
}
inline fun clamp(v: Half3, min: Half3, max: Half3): Half3 {
return Half3(
clamp(v.x, min.x, max.x),
clamp(v.y, min.y, max.y),
clamp(v.z, min.z, max.z)
)
}
inline fun mix(a: Half3, b: Half3, x: Half): Half3 {
return Half3(
mix(a.x, b.x, x),
mix(a.y, b.y, x),
mix(a.z, b.z, x)
)
}
inline fun mix(a: Half3, b: Half3, x: Half3): Half3 {
return Half3(
mix(a.x, b.x, x.x),
mix(a.y, b.y, x.y),
mix(a.z, b.z, x.z)
)
}
inline fun min(v: Half3) = min(v.x, min(v.y, v.z))
inline fun min(a: Half3, b: Half3) = Half3(min(a.x, b.x), min(a.y, b.y), min(a.z, b.z))
inline fun max(v: Half3) = max(v.x, max(v.y, v.z))
inline fun max(a: Half3, b: Half3) = Half3(max(a.x, b.x), max(a.y, b.y), max(a.z, b.z))
inline fun transform(v: Half3, block: (Half) -> Half) = v.copy().transform(block)
inline fun lessThan(a: Half3, b: Half) = Bool3(a.x < b, a.y < b, a.z < b)
inline fun lessThan(a: Half3, b: Half3) = Bool3(a.x < b.x, a.y < b.y, a.z < b.z)
inline fun lessThanEqual(a: Half3, b: Half) = Bool3(a.x <= b, a.y <= b, a.z <= b)
inline fun lessThanEqual(a: Half3, b: Half3) = Bool3(a.x <= b.x, a.y <= b.y, a.z <= b.z)
inline fun greaterThan(a: Half3, b: Half) = Bool3(a.x > b, a.y > b, a.z > b)
inline fun greaterThan(a: Half3, b: Half3) = Bool3(a.x > b.y, a.y > b.y, a.z > b.z)
inline fun greaterThanEqual(a: Half3, b: Half) = Bool3(a.x >= b, a.y >= b, a.z >= b)
inline fun greaterThanEqual(a: Half3, b: Half3) = Bool3(a.x >= b.x, a.y >= b.y, a.z >= b.z)
inline fun equal(a: Half3, b: Half) = Bool3(a.x == b, a.y == b, a.z == b)
inline fun equal(a: Half3, b: Half3) = Bool3(a.x == b.x, a.y == b.y, a.z == b.z)
inline fun notEqual(a: Half3, b: Half) = Bool3(a.x != b, a.y != b, a.z != b)
inline fun notEqual(a: Half3, b: Half3) = Bool3(a.x != b.x, a.y != b.y, a.z != b.z)
inline infix fun Half3.lt(b: Half) = Bool3(x < b, y < b, z < b)
inline infix fun Half3.lt(b: Half3) = Bool3(x < b.x, y < b.y, z < b.z)
inline infix fun Half3.lte(b: Half) = Bool3(x <= b, y <= b, z <= b)
inline infix fun Half3.lte(b: Half3) = Bool3(x <= b.x, y <= b.y, z <= b.z)
inline infix fun Half3.gt(b: Half) = Bool3(x > b, y > b, z > b)
inline infix fun Half3.gt(b: Half3) = Bool3(x > b.x, y > b.y, z > b.z)
inline infix fun Half3.gte(b: Half) = Bool3(x >= b, y >= b, z >= b)
inline infix fun Half3.gte(b: Half3) = Bool3(x >= b.x, y >= b.y, z >= b.z)
inline infix fun Half3.eq(b: Half) = Bool3(x == b, y == b, z == b)
inline infix fun Half3.eq(b: Half3) = Bool3(x == b.x, y == b.y, z == b.z)
inline infix fun Half3.neq(b: Half) = Bool3(x != b, y != b, z != b)
inline infix fun Half3.neq(b: Half3) = Bool3(x != b.x, y != b.y, z != b.z)
inline operator fun Half.plus(v: Half4) = Half4(this + v.x, this + v.y, this + v.z, this + v.w)
inline operator fun Half.minus(v: Half4) = Half4(this - v.x, this - v.y, this - v.z, this - v.w)
inline operator fun Half.times(v: Half4) = Half4(this * v.x, this * v.y, this * v.z, this * v.w)
inline operator fun Half.div(v: Half4) = Half4(this / v.x, this / v.y, this / v.z, this / v.w)
inline fun abs(v: Half4) = Half4(abs(v.x), abs(v.y), abs(v.z), abs(v.w))
inline fun length(v: Half4) = sqrt(v.x * v.x + v.y * v.y + v.z * v.z + v.w * v.w)
inline fun length2(v: Half4) = v.x * v.x + v.y * v.y + v.z * v.z + v.w * v.w
inline fun distance(a: Half4, b: Half4) = length(a - b)
inline fun dot(a: Half4, b: Half4) = a.x * b.x + a.y * b.y + a.z * b.z + a.w * b.w
fun normalize(v: Half4): Half4 {
val l = HALF_ONE / length(v)
return Half4(v.x * l, v.y * l, v.z * l, v.w * l)
}
inline fun clamp(v: Half4, min: Half, max: Half): Half4 {
return Half4(
clamp(v.x, min, max),
clamp(v.y, min, max),
clamp(v.z, min, max),
clamp(v.w, min, max)
)
}
inline fun clamp(v: Half4, min: Half4, max: Half4): Half4 {
return Half4(
clamp(v.x, min.x, max.x),
clamp(v.y, min.y, max.y),
clamp(v.z, min.z, max.z),
clamp(v.w, min.z, max.w)
)
}
inline fun mix(a: Half4, b: Half4, x: Half): Half4 {
return Half4(
mix(a.x, b.x, x),
mix(a.y, b.y, x),
mix(a.z, b.z, x),
mix(a.w, b.w, x)
)
}
inline fun mix(a: Half4, b: Half4, x: Half4): Half4 {
return Half4(
mix(a.x, b.x, x.x),
mix(a.y, b.y, x.y),
mix(a.z, b.z, x.z),
mix(a.w, b.w, x.w))
}
inline fun min(v: Half4) = min(v.x, min(v.y, min(v.z, v.w)))
inline fun min(a: Half4, b: Half4): Half4 {
return Half4(min(a.x, b.x), min(a.y, b.y), min(a.z, b.z), min(a.w, b.w))
}
inline fun max(v: Half4) = max(v.x, max(v.y, max(v.z, v.w)))
inline fun max(a: Half4, b: Half4): Half4 {
return Half4(max(a.x, b.x), max(a.y, b.y), max(a.z, b.z), max(a.w, b.w))
}
inline fun transform(v: Half4, block: (Half) -> Half) = v.copy().transform(block)
inline fun lessThan(a: Half4, b: Half) = Bool4(a.x < b, a.y < b, a.z < b, a.w < b)
inline fun lessThan(a: Half4, b: Half4) = Bool4(a.x < b.x, a.y < b.y, a.z < b.z, a.w < b.w)
inline fun lessThanEqual(a: Half4, b: Half) = Bool4(a.x <= b, a.y <= b, a.z <= b, a.w <= b)
inline fun lessThanEqual(a: Half4, b: Half4) = Bool4(a.x <= b.x, a.y <= b.y, a.z <= b.z, a.w <= b.w)
inline fun greaterThan(a: Half4, b: Half) = Bool4(a.x > b, a.y > b, a.z > b, a.w > b)
inline fun greaterThan(a: Half4, b: Half4) = Bool4(a.x > b.y, a.y > b.y, a.z > b.z, a.w > b.w)
inline fun greaterThanEqual(a: Half4, b: Half) = Bool4(a.x >= b, a.y >= b, a.z >= b, a.w >= b)
inline fun greaterThanEqual(a: Half4, b: Half4) = Bool4(a.x >= b.x, a.y >= b.y, a.z >= b.z, a.w >= b.w)
inline fun equal(a: Half4, b: Half) = Bool4(a.x == b, a.y == b, a.z == b, a.w == b)
inline fun equal(a: Half4, b: Half4) = Bool4(a.x == b.x, a.y == b.y, a.z == b.z, a.w == b.w)
inline fun notEqual(a: Half4, b: Half) = Bool4(a.x != b, a.y != b, a.z != b, a.w != b)
inline fun notEqual(a: Half4, b: Half4) = Bool4(a.x != b.x, a.y != b.y, a.z != b.z, a.w != b.w)
inline infix fun Half4.lt(b: Half) = Bool4(x < b, y < b, z < b, a < b)
inline infix fun Half4.lt(b: Half4) = Bool4(x < b.x, y < b.y, z < b.z, w < b.w)
inline infix fun Half4.lte(b: Half) = Bool4(x <= b, y <= b, z <= b, w <= b)
inline infix fun Half4.lte(b: Half4) = Bool4(x <= b.x, y <= b.y, z <= b.z, w <= b.w)
inline infix fun Half4.gt(b: Half) = Bool4(x > b, y > b, z > b, w > b)
inline infix fun Half4.gt(b: Half4) = Bool4(x > b.x, y > b.y, z > b.z, w > b.w)
inline infix fun Half4.gte(b: Half) = Bool4(x >= b, y >= b, z >= b, w >= b)
inline infix fun Half4.gte(b: Half4) = Bool4(x >= b.x, y >= b.y, z >= b.z, w >= b.w)
inline infix fun Half4.eq(b: Half) = Bool4(x == b, y == b, z == b, w == b)
inline infix fun Half4.eq(b: Half4) = Bool4(x == b.x, y == b.y, z == b.z, w == b.w)
inline infix fun Half4.neq(b: Half) = Bool4(x != b, y != b, z != b, w != b)
inline infix fun Half4.neq(b: Half4) = Bool4(x != b.x, y != b.y, z != b.z, w != b.w)
-7
View File
@@ -16,13 +16,6 @@ android {
excludes += ['lib/*/libfilament-jni.so']
}
}
publishing {
singleVariant("fullRelease") {
withSourcesJar()
withJavadocJar()
}
}
}
dependencies {
+1 -4
View File
@@ -1,5 +1,5 @@
GROUP=com.google.android.filament
VERSION_NAME=1.42.0
VERSION_NAME=1.32.0
POM_DESCRIPTION=Real-time physically based rendering engine for Android.
@@ -18,9 +18,6 @@ POM_DEVELOPER_NAME=Filament Team
org.gradle.jvmargs=-Xmx1536m
android.useAndroidX=true
android.defaults.buildfeatures.buildconfig=true
android.nonTransitiveRClass=false
android.nonFinalResIds=false
com.google.android.filament.tools-dir=../../../out/release/filament
com.google.android.filament.dist-dir=../out/android-release/filament
+53
View File
@@ -86,10 +86,63 @@ afterEvaluate { project ->
}
}
if (project.getPlugins().hasPlugin('com.android.application') ||
project.getPlugins().hasPlugin('com.android.library')) {
task androidJavadocs(type: Javadoc) {
source = android.sourceSets.main.java.source
classpath += project.files(android.getBootClasspath().join(File.pathSeparator))
excludes = ['**/*.kt']
}
task androidJavadocsJar(type: Jar, dependsOn: androidJavadocs) {
classifier = 'javadoc'
from androidJavadocs.destinationDir
}
task androidSourcesJar(type: Jar) {
classifier = 'sources'
from android.sourceSets.main.java.source
}
}
if (JavaVersion.current().isJava8Compatible()) {
allprojects {
tasks.withType(Javadoc) {
options.addStringOption('Xdoclint:none', '-quiet')
}
}
}
if (JavaVersion.current().isJava9Compatible()) {
allprojects {
tasks.withType(Javadoc) {
options.addBooleanOption('html5', true)
}
}
}
artifacts {
if (project.getPlugins().hasPlugin('com.android.application') ||
project.getPlugins().hasPlugin('com.android.library')) {
archives androidSourcesJar
archives androidJavadocsJar
}
}
android.libraryVariants.all { variant ->
tasks.androidJavadocs.doFirst {
classpath += files(variant.javaCompileProvider.get().classpath.files.join(File.pathSeparator))
}
}
publishing.publications.all { publication ->
publication.groupId = GROUP
publication.version = VERSION_NAME
publication.artifact androidSourcesJar
publication.artifact androidJavadocsJar
configurePom(publication.pom)
}
+1 -1
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-8.0-bin.zip
distributionUrl=https\://services.gradle.org/distributions/gradle-7.5-bin.zip
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
@@ -40,11 +40,6 @@ android {
dependenciesInfo {
includeInApk = false
}
compileOptions {
sourceCompatibility versions.jdk
targetCompatibility versions.jdk
}
}
dependencies {
@@ -28,7 +28,6 @@ import com.google.android.filament.Fence
import com.google.android.filament.IndirectLight
import com.google.android.filament.Skybox
import com.google.android.filament.View
import com.google.android.filament.View.OnPickCallback
import com.google.android.filament.utils.*
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
@@ -57,9 +56,7 @@ class MainActivity : Activity() {
private lateinit var modelViewer: ModelViewer
private lateinit var titlebarHint: TextView
private val doubleTapListener = DoubleTapListener()
private val singleTapListener = SingleTapListener()
private lateinit var doubleTapDetector: GestureDetector
private lateinit var singleTapDetector: GestureDetector
private var remoteServer: RemoteServer? = null
private var statusToast: Toast? = null
private var statusText: String? = null
@@ -80,7 +77,6 @@ class MainActivity : Activity() {
choreographer = Choreographer.getInstance()
doubleTapDetector = GestureDetector(applicationContext, doubleTapListener)
singleTapDetector = GestureDetector(applicationContext, singleTapListener)
modelViewer = ModelViewer(surfaceView)
viewerContent.view = modelViewer.view
@@ -92,7 +88,6 @@ class MainActivity : Activity() {
surfaceView.setOnTouchListener { _, event ->
modelViewer.onTouchEvent(event)
doubleTapDetector.onTouchEvent(event)
singleTapDetector.onTouchEvent(event)
true
}
@@ -234,7 +229,6 @@ class MainActivity : Activity() {
modelViewer.scene.skybox = sky
modelViewer.scene.indirectLight = ibl
viewerContent.indirectLight = ibl
}
}
}
@@ -343,11 +337,6 @@ class MainActivity : Activity() {
remoteServer?.close()
}
override fun onBackPressed() {
super.onBackPressed()
finish()
}
fun loadModelData(message: RemoteServer.ReceivedMessage) {
Log.i(TAG, "Downloaded model ${message.label} (${message.buffer.capacity()} bytes)")
clearStatusText()
@@ -436,19 +425,4 @@ class MainActivity : Activity() {
return super.onDoubleTap(e)
}
}
// Just for testing purposes
inner class SingleTapListener : GestureDetector.SimpleOnGestureListener() {
override fun onSingleTapUp(event: MotionEvent): Boolean {
modelViewer.view.pick(
event.x.toInt(),
surfaceView.height - event.y.toInt(),
surfaceView.handler, {
val name = modelViewer.asset!!.getName(it.renderable)
Log.v("Filament", "Picked ${it.renderable}: " + name)
},
)
return super.onSingleTapUp(event)
}
}
}
@@ -6,10 +6,6 @@ plugins {
project.ext.isSample = true
kotlin {
jvmToolchain(versions.jdk)
}
filamentTools {
materialInputDir = project.layout.projectDirectory.dir("src/main/materials")
materialOutputDir = project.layout.projectDirectory.dir("src/main/assets/materials")
@@ -40,11 +36,6 @@ android {
aaptOptions {
noCompress 'filamat', 'ktx'
}
compileOptions {
sourceCompatibility versions.jdk
targetCompatibility versions.jdk
}
}
dependencies {
@@ -30,7 +30,6 @@ import com.google.android.filament.*
import com.google.android.filament.RenderableManager.*
import com.google.android.filament.VertexBuffer.*
import com.google.android.filament.android.DisplayHelper
import com.google.android.filament.android.FilamentHelper
import com.google.android.filament.android.UiHelper
import java.nio.ByteBuffer
@@ -402,8 +401,6 @@ class MainActivity : Activity(), ActivityCompat.OnRequestPermissionsResultCallba
camera.setProjection(45.0, aspect, 0.1, 20.0, Camera.Fov.VERTICAL)
view.viewport = Viewport(0, 0, width, height)
FilamentHelper.synchronizePendingFrames(engine)
}
}
@@ -6,10 +6,6 @@ plugins {
project.ext.isSample = true
kotlin {
jvmToolchain(versions.jdk)
}
filamentTools {
materialInputDir = project.layout.projectDirectory.dir("src/main/materials")
materialOutputDir = project.layout.projectDirectory.dir("src/main/assets/materials")
@@ -40,11 +36,6 @@ android {
aaptOptions {
noCompress 'filamat', 'ktx'
}
compileOptions {
sourceCompatibility versions.jdk
targetCompatibility versions.jdk
}
}
dependencies {
@@ -1,8 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
<uses-permission android:name="android.permission.INTERNET" />
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
@@ -29,7 +29,6 @@ import com.google.android.filament.RenderableManager.PrimitiveType
import com.google.android.filament.VertexBuffer.AttributeType
import com.google.android.filament.VertexBuffer.VertexAttribute
import com.google.android.filament.android.DisplayHelper
import com.google.android.filament.android.FilamentHelper
import com.google.android.filament.android.UiHelper
import java.nio.ByteBuffer
import java.nio.ByteOrder
@@ -120,13 +119,8 @@ class MainActivity : Activity() {
private fun setupView() {
scene.skybox = Skybox.Builder().color(0.035f, 0.035f, 0.035f, 1.0f).build(engine)
if (engine.activeFeatureLevel == Engine.FeatureLevel.FEATURE_LEVEL_0) {
// post-processing is not supported at feature level 0
view.isPostProcessingEnabled = false
} else {
// NOTE: Try to disable post-processing (tone-mapping, etc.) to see the difference
// view.isPostProcessingEnabled = false
}
// NOTE: Try to disable post-processing (tone-mapping, etc.) to see the difference
// view.isPostProcessingEnabled = false
// Tell the view which camera we want to use
view.camera = camera
@@ -160,11 +154,7 @@ class MainActivity : Activity() {
}
private fun loadMaterial() {
var name = "materials/baked_color.filamat"
if (engine.activeFeatureLevel == Engine.FeatureLevel.FEATURE_LEVEL_0) {
name = "materials/baked_color_es2.filamat"
}
readUncompressedAsset(name).let {
readUncompressedAsset("materials/baked_color.filamat").let {
material = Material.Builder().payload(it, it.remaining()).build(engine)
}
}
@@ -314,17 +304,7 @@ class MainActivity : Activity() {
inner class SurfaceCallback : UiHelper.RendererCallback {
override fun onNativeWindowChanged(surface: Surface) {
swapChain?.let { engine.destroySwapChain(it) }
// at feature level 0, we don't have post-processing, so we need to set
// the colorspace to sRGB (FIXME: it's not supported everywhere!)
var flags = uiHelper.swapChainFlags
if (engine.activeFeatureLevel == Engine.FeatureLevel.FEATURE_LEVEL_0) {
if (SwapChain.isSRGBSwapChainSupported(engine)) {
flags = flags or SwapChain.CONFIG_SRGB_COLORSPACE
}
}
swapChain = engine.createSwapChain(surface, flags)
swapChain = engine.createSwapChain(surface, uiHelper.swapChainFlags)
displayHelper.attach(renderer, surfaceView.display);
}
@@ -347,8 +327,6 @@ class MainActivity : Activity() {
-aspect * zoom, aspect * zoom, -zoom, zoom, 0.0, 10.0)
view.viewport = Viewport(0, 0, width, height)
FilamentHelper.synchronizePendingFrames(engine)
}
}
@@ -17,7 +17,7 @@ material {
],
// This material disables all lighting
shadingModel : unlit
shadingModel : unlit,
}
fragment {
@@ -1,33 +0,0 @@
// Simple unlit material that uses the colors associated with each vertex.
//
// This source material must be compiled to a binary material using the matc tool.
// The command used to compile this material is:
// matc -p mobile -a opengl -o app/src/main/assets/baked_color.filamat app/src/materials/baked_color.mat
//
// See build.gradle for an example of how to compile materials automatically
// Please refer to the documentation for more information about matc and the materials system.
material {
name : baked_color,
// Lists the required vertex attributes
// Here we only need a color (RGBA)
requires : [
color
],
// This material disables all lighting
shadingModel : unlit,
featureLevel : 0
}
fragment {
void material(inout MaterialInputs material) {
// You must always call the prepareMaterial() function
prepareMaterial(material);
// We set the material's color to the color interpolated from
// the model's vertices
material.baseColor = getColor();
}
}
@@ -6,10 +6,6 @@ plugins {
project.ext.isSample = true
kotlin {
jvmToolchain(versions.jdk)
}
filamentTools {
materialInputDir = project.layout.projectDirectory.dir("src/main/materials")
materialOutputDir = project.layout.projectDirectory.dir("src/main/assets/materials")
@@ -46,11 +42,6 @@ android {
aaptOptions {
noCompress 'filamat', 'ktx'
}
compileOptions {
sourceCompatibility versions.jdk
targetCompatibility versions.jdk
}
}
dependencies {
@@ -26,7 +26,6 @@ import android.view.animation.LinearInterpolator
import com.google.android.filament.*
import com.google.android.filament.android.DisplayHelper
import com.google.android.filament.android.FilamentHelper
import com.google.android.filament.android.UiHelper
import java.nio.ByteBuffer
@@ -118,10 +117,9 @@ class MainActivity : Activity() {
}
private fun setupView() {
// ambient occlusion is the cheapest effect that adds a lot of quality
view.ambientOcclusionOptions = view.ambientOcclusionOptions.apply {
enabled = true
}
val ssaoOptions = view.ambientOcclusionOptions
ssaoOptions.enabled = true
view.ambientOcclusionOptions = ssaoOptions
// NOTE: Try to disable post-processing (tone-mapping, etc.) to see the difference
// view.isPostProcessingEnabled = false
@@ -305,8 +303,6 @@ class MainActivity : Activity() {
camera.setProjection(45.0, aspect, 0.1, 20.0, Camera.Fov.VERTICAL)
view.viewport = Viewport(0, 0, width, height)
FilamentHelper.synchronizePendingFrames(engine)
}
}
@@ -6,10 +6,6 @@ plugins {
project.ext.isSample = true
kotlin {
jvmToolchain(versions.jdk)
}
filamentTools {
materialInputDir = project.layout.projectDirectory.dir("src/main/materials")
materialOutputDir = project.layout.projectDirectory.dir("src/main/assets/materials")
@@ -39,11 +35,6 @@ android {
aaptOptions {
noCompress 'filamat', 'ktx'
}
compileOptions {
sourceCompatibility versions.jdk
targetCompatibility versions.jdk
}
}
dependencies {
@@ -29,7 +29,6 @@ import com.google.android.filament.*
import com.google.android.filament.RenderableManager.*
import com.google.android.filament.VertexBuffer.*
import com.google.android.filament.android.DisplayHelper
import com.google.android.filament.android.FilamentHelper
import com.google.android.filament.android.UiHelper
import java.nio.ByteBuffer
@@ -414,8 +413,6 @@ class MainActivity : Activity() {
camera.setProjection(45.0, aspect, 0.1, 20.0, Camera.Fov.VERTICAL)
view.viewport = Viewport(0, 0, width, height)
FilamentHelper.synchronizePendingFrames(engine)
}
}
@@ -3,10 +3,6 @@ apply plugin: 'kotlin-android'
project.ext.isSample = true
kotlin {
jvmToolchain(versions.jdk)
}
android {
namespace 'com.google.android.filament.livewallpaper'
@@ -22,11 +18,6 @@ android {
dependenciesInfo {
includeInApk = false
}
compileOptions {
sourceCompatibility versions.jdk
targetCompatibility versions.jdk
}
}
dependencies {
@@ -31,7 +31,6 @@ import android.view.animation.LinearInterpolator
import androidx.annotation.RequiresApi
import com.google.android.filament.*
import com.google.android.filament.android.DisplayHelper
import com.google.android.filament.android.FilamentHelper
import com.google.android.filament.android.UiHelper
class FilamentLiveWallpaper : WallpaperService() {
@@ -227,8 +226,6 @@ class FilamentLiveWallpaper : WallpaperService() {
camera.setProjection(45.0, aspect, 0.1, 20.0, Camera.Fov.VERTICAL)
view.viewport = Viewport(0, 0, width, height)
FilamentHelper.synchronizePendingFrames(engine)
}
}
}
@@ -6,10 +6,6 @@ plugins {
project.ext.isSample = true
kotlin {
jvmToolchain(versions.jdk)
}
filamentTools {
meshInputFile = project.layout.projectDirectory.file("../../../third_party/models/shader_ball/shader_ball.obj")
meshOutputDir = project.layout.projectDirectory.dir("src/main/assets/models")
@@ -50,11 +46,6 @@ android {
aaptOptions {
noCompress 'filamat'
}
compileOptions {
sourceCompatibility versions.jdk
targetCompatibility versions.jdk
}
}
dependencies {
@@ -26,7 +26,6 @@ import android.view.animation.LinearInterpolator
import com.google.android.filament.*
import com.google.android.filament.android.DisplayHelper
import com.google.android.filament.android.FilamentHelper
import com.google.android.filament.android.UiHelper
import com.google.android.filament.filamat.MaterialBuilder
@@ -344,8 +343,6 @@ class MainActivity : Activity() {
camera.setProjection(45.0, aspect, 0.1, 20.0, Camera.Fov.VERTICAL)
view.viewport = Viewport(0, 0, width, height)
FilamentHelper.synchronizePendingFrames(engine)
}
}
}
@@ -6,10 +6,6 @@ plugins {
project.ext.isSample = true
kotlin {
jvmToolchain(versions.jdk)
}
filamentTools {
materialInputDir = project.layout.projectDirectory.dir("src/main/materials")
materialOutputDir = project.layout.projectDirectory.dir("src/main/assets/materials")
@@ -39,11 +35,6 @@ android {
aaptOptions {
noCompress 'filamat', 'ktx'
}
compileOptions {
sourceCompatibility versions.jdk
targetCompatibility versions.jdk
}
}
dependencies {
@@ -30,7 +30,6 @@ import com.google.android.filament.RenderableManager.*
import com.google.android.filament.Renderer.ClearOptions
import com.google.android.filament.VertexBuffer.*
import com.google.android.filament.android.DisplayHelper
import com.google.android.filament.android.FilamentHelper
import com.google.android.filament.android.UiHelper
import java.nio.ByteBuffer
@@ -459,8 +458,6 @@ class MainActivity : Activity() {
view1.viewport = Viewport(width / 2, 0, width / 2, height / 2)
view2.viewport = Viewport(0, height / 2, width / 2, height / 2)
view4.viewport = Viewport(width / 4, height / 4, width / 2, height / 2)
FilamentHelper.synchronizePendingFrames(engine)
}
}
@@ -6,10 +6,6 @@ plugins {
project.ext.isSample = true
kotlin {
jvmToolchain(versions.jdk)
}
filamentTools {
iblInputFile = project.layout.projectDirectory.file("../../../third_party/environments/studio_small_02_2k.hdr")
iblOutputDir = project.layout.projectDirectory.dir("src/main/assets/envs")
@@ -42,11 +38,6 @@ android {
aaptOptions {
noCompress 'filamat'
}
compileOptions {
sourceCompatibility versions.jdk
targetCompatibility versions.jdk
}
}
dependencies {
@@ -37,7 +37,6 @@ import com.google.android.filament.Camera;
import com.google.android.filament.Engine;
import com.google.android.filament.Entity;
import com.google.android.filament.EntityManager;
import com.google.android.filament.Fence;
import com.google.android.filament.Filament;
import com.google.android.filament.IndirectLight;
import com.google.android.filament.LightManager;
@@ -50,7 +49,6 @@ import com.google.android.filament.TransformManager;
import com.google.android.filament.Viewport;
import com.google.android.filament.android.DisplayHelper;
import com.google.android.filament.android.FilamentHelper;
import com.google.android.filament.android.TextureHelper;
import com.google.android.filament.android.UiHelper;
@@ -109,7 +107,6 @@ public class MainActivity extends Activity
mCamera.setProjection(60.0, aspect, 1.0, 2000.0, Camera.Fov.HORIZONTAL);
}
mView.setViewport(new Viewport(0, 0, width, height));
FilamentHelper.synchronizePendingFrames(mEngine);
}
@Override
@@ -6,10 +6,6 @@ plugins {
project.ext.isSample = true
kotlin {
jvmToolchain(versions.jdk)
}
filamentTools {
materialInputDir = project.layout.projectDirectory.dir("src/main/materials")
materialOutputDir = project.layout.projectDirectory.dir("src/main/assets/materials")
@@ -40,11 +36,6 @@ android {
aaptOptions {
noCompress 'filamat', 'ktx'
}
compileOptions {
sourceCompatibility versions.jdk
targetCompatibility versions.jdk
}
}
dependencies {
@@ -38,7 +38,6 @@ import android.os.Build
import android.view.MotionEvent
import androidx.annotation.RequiresApi
import com.google.android.filament.android.DisplayHelper
import com.google.android.filament.android.FilamentHelper
class MainActivity : Activity(), ActivityCompat.OnRequestPermissionsResultCallback {
@@ -402,8 +401,6 @@ class MainActivity : Activity(), ActivityCompat.OnRequestPermissionsResultCallba
camera.setProjection(45.0, aspect, 0.1, 20.0, Camera.Fov.VERTICAL)
view.viewport = Viewport(0, 0, width, height)
FilamentHelper.synchronizePendingFrames(engine)
}
}
@@ -6,10 +6,6 @@ plugins {
project.ext.isSample = true
kotlin {
jvmToolchain(versions.jdk)
}
filamentTools {
materialInputDir = project.layout.projectDirectory.dir("src/main/materials")
materialOutputDir = project.layout.projectDirectory.dir("src/main/assets/materials")
@@ -40,11 +36,6 @@ android {
aaptOptions {
noCompress 'filamat', 'ktx'
}
compileOptions {
sourceCompatibility versions.jdk
targetCompatibility versions.jdk
}
}
dependencies {
@@ -29,7 +29,6 @@ import com.google.android.filament.RenderableManager.PrimitiveType
import com.google.android.filament.VertexBuffer.AttributeType
import com.google.android.filament.VertexBuffer.VertexAttribute
import com.google.android.filament.android.DisplayHelper
import com.google.android.filament.android.FilamentHelper
import com.google.android.filament.android.UiHelper
import java.nio.ByteBuffer
import java.nio.ByteOrder
@@ -328,8 +327,6 @@ class MainActivity : Activity() {
-aspect * zoom, aspect * zoom, -zoom, zoom, 0.0, 10.0)
view.viewport = Viewport(0, 0, width, height)
FilamentHelper.synchronizePendingFrames(engine)
}
}
@@ -6,10 +6,6 @@ plugins {
project.ext.isSample = true
kotlin {
jvmToolchain(versions.jdk)
}
filamentTools {
materialInputDir = project.layout.projectDirectory.dir("src/main/materials")
materialOutputDir = project.layout.projectDirectory.dir("src/main/assets/materials")
@@ -47,11 +43,6 @@ android {
aaptOptions {
noCompress 'filamat', 'ktx'
}
compileOptions {
sourceCompatibility versions.jdk
targetCompatibility versions.jdk
}
}
dependencies {
@@ -26,7 +26,6 @@ import android.view.animation.LinearInterpolator
import com.google.android.filament.*
import com.google.android.filament.android.DisplayHelper
import com.google.android.filament.android.FilamentHelper
import com.google.android.filament.utils.*
import com.google.android.filament.android.UiHelper
@@ -231,7 +230,7 @@ class MainActivity : Activity() {
animator.repeatCount = ValueAnimator.INFINITE
animator.addUpdateListener { a ->
val v = (a.animatedValue as Float)
camera.lookAt(cos(v) * 5.5, 1.5, sin(v) * 5.5, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0)
camera.lookAt(cos(v) * 4.5, 1.5, sin(v) * 4.5, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0)
}
animator.start()
}
@@ -253,7 +252,7 @@ class MainActivity : Activity() {
// Stop the animation and any pending frame
choreographer.removeFrameCallback(frameScheduler)
animator.cancel()
animator.cancel();
// Always detach the surface before destroying the engine
uiHelper.detach()
@@ -324,8 +323,6 @@ class MainActivity : Activity() {
camera.setProjection(45.0, aspect, 0.1, 20.0, Camera.Fov.VERTICAL)
view.viewport = Viewport(0, 0, width, height)
FilamentHelper.synchronizePendingFrames(engine)
}
}
@@ -6,10 +6,6 @@ plugins {
project.ext.isSample = true
kotlin {
jvmToolchain(versions.jdk)
}
filamentTools {
materialInputDir = project.layout.projectDirectory.dir("src/main/materials")
materialOutputDir = project.layout.projectDirectory.dir("src/main/assets/materials")
@@ -40,11 +36,6 @@ android {
aaptOptions {
noCompress 'filamat', 'ktx'
}
compileOptions {
sourceCompatibility versions.jdk
targetCompatibility versions.jdk
}
}
dependencies {
@@ -33,7 +33,6 @@ import com.google.android.filament.*
import com.google.android.filament.RenderableManager.*
import com.google.android.filament.VertexBuffer.*
import com.google.android.filament.android.DisplayHelper
import com.google.android.filament.android.FilamentHelper
import com.google.android.filament.android.UiHelper
import java.nio.ByteBuffer
@@ -140,9 +139,9 @@ class MainActivity : Activity() {
camera = engine.createCamera(engine.entityManager.create())
// clear the swapchain with transparent pixels
renderer.clearOptions = renderer.clearOptions.apply {
clear = true
}
val options = renderer.clearOptions
options.clear = true
renderer.clearOptions = options
}
private fun setupView() {
@@ -351,8 +350,6 @@ class MainActivity : Activity() {
-aspect * zoom, aspect * zoom, -zoom, zoom, 0.0, 10.0)
view.viewport = Viewport(0, 0, width, height)
FilamentHelper.synchronizePendingFrames(engine)
}
}
+3 -5
View File
@@ -90,8 +90,8 @@ function print_help {
echo " Desktop matc target, release build:"
echo " \$ ./$self_name release matc"
echo ""
echo " Build gltf_viewer:"
echo " \$ ./$self_name release gltf_viewer"
echo " Build gltf_viewer then immediately run it with no arguments:"
echo " \$ ./$self_name release run_gltf_viewer"
echo ""
}
@@ -491,7 +491,6 @@ function build_android {
./gradlew \
-Pcom.google.android.filament.dist-dir=../out/android-debug/filament \
-Pcom.google.android.filament.abis=${ABI_GRADLE_OPTION} \
${MATOPT_GRADLE_OPTION} \
:samples:${sample}:assembleDebug
done
fi
@@ -540,7 +539,6 @@ function build_android {
./gradlew \
-Pcom.google.android.filament.dist-dir=../out/android-release/filament \
-Pcom.google.android.filament.abis=${ABI_GRADLE_OPTION} \
${MATOPT_GRADLE_OPTION} \
:samples:${sample}:assembleRelease
done
fi
@@ -758,7 +756,7 @@ function run_tests {
pushd "$(dirname "$0")" > /dev/null
while getopts ":hacCfgijmp:q:uvslwtedk:b" opt; do
while getopts ":hacCfijmp:q:uvslwtedk:b" opt; do
case ${opt} in
h)
print_help
+2 -9
View File
@@ -44,20 +44,13 @@ elif [[ "$LC_UNAME" == "darwin" ]]; then
fi
source `dirname $0`/../common/build-common.sh
if [[ "$GITHUB_WORKFLOW" ]]; then
java_version=$(java -version 2>&1 | head -1 | cut -d'"' -f2 | sed '/^1\./s///' | cut -d'.' -f1)
if [[ "$java_version" < 17 ]]; then
echo "Android builds require Java 17, found version ${java_version} instead"
exit 0
fi
fi
# Unless explicitly specified, NDK version will be set to match exactly the required one
FILAMENT_NDK_VERSION=${FILAMENT_NDK_VERSION:-$(cat `dirname $0`/ndk.version)}
# Install the required NDK version specifically (if not present)
if [[ ! -d "${ANDROID_HOME}/ndk/$FILAMENT_NDK_VERSION" ]]; then
${ANDROID_HOME}/cmdline-tools/latest/bin/sdkmanager "ndk;$FILAMENT_NDK_VERSION" > /dev/null
# NOTE: We MUST use Java 1.8 to run sdkmanager currently, it fails starting with Java 11
JAVA_HOME=${JAVA_HOME_8_X64} ${ANDROID_HOME}/tools/bin/sdkmanager "ndk;$FILAMENT_NDK_VERSION" > /dev/null
fi
# Only build 1 64 bit target during presubmit to cut down build times during presubmit
+1 -10
View File
@@ -2,11 +2,6 @@
set -e
case "$(uname -s)" in
Darwin*) IS_DARWIN=1;;
*) ;;
esac
function print_help {
local SELF_NAME
SELF_NAME=$(basename "$0")
@@ -50,11 +45,7 @@ function replace {
FIND_STR="${1//\{\{VERSION\}\}/${VERSION_REGEX}}"
REPLACE_STR="${1//\{\{VERSION\}\}/${NEW_VERSION}}"
local FILE_NAME="$2"
if [ IS_DARWIN ]; then
sed -i '' -E "s/${FIND_STR}/${REPLACE_STR}/" "${FILE_NAME}"
else
sed -i -E "s/${FIND_STR}/${REPLACE_STR}/" "${FILE_NAME}"
fi
sed -i '' -E "s/${FIND_STR}/${REPLACE_STR}/" "${FILE_NAME}"
}
# The following are the canonical locations where the Filament version number is referenced.
+8
View File
@@ -3,4 +3,12 @@
if [[ "$GITHUB_WORKFLOW" ]]; then
echo "Running workflow $GITHUB_WORKFLOW (event: $GITHUB_EVENT_NAME, action: $GITHUB_ACTION)"
CONTINUOUS_INTEGRATION=true
# Force Java to be Java 11 minimum, it defaults to 8 in GitHub runners for some platforms
export JAVA_HOME=${JAVA_HOME_11_X64}
java_version=$(java -version 2>&1 | head -1 | cut -d'"' -f2 | sed '/^1\./s///' | cut -d'.' -f1)
if [[ "$java_version" < 11 ]]; then
echo "Android builds require Java 11, found version ${java_version} instead"
exit 0
fi
fi
+6 -6
View File
File diff suppressed because one or more lines are too long
+6 -6
View File
@@ -200,7 +200,7 @@ Energy conservation is one of the key components of a good BRDF for physically b
## Specular BRDF
For the specular term, $f_r$ is a mirror BRDF that can be modeled with the Fresnel law, noted $F$ in the Cook-Torrance approximation of the microfacet model integration:
For the specular term, $f_m$ is a mirror BRDF that can be modeled with the Fresnel law, noted $F$ in the Cook-Torrance approximation of the microfacet model integration:
$$\begin{equation}
f_r(v,l) = \frac{D(h, \alpha) G(v, l, \alpha) F(v, h, f0)}{4(\NoV)(\NoL)}
@@ -485,7 +485,7 @@ void BRDF(...) {
// perceptually linear roughness to roughness (see parameterization)
float roughness = perceptualRoughness * perceptualRoughness;
float D = D_GGX(NoH, roughness);
float D = D_GGX(NoH, a);
vec3 F = F_Schlick(LoH, f0);
float V = V_SmithGGXCorrelated(NoV, NoL, roughness);
@@ -2016,7 +2016,7 @@ I(f(n, v, \alpha)) \equiv \frac{1}{N}\sum_{\forall \, i \in image} f(l_i,
\end{equation}$$
However, in practice we're using _importance sampling_ which needs to take the $pdf$ of the distribution
into account and adds a term $\frac{4\left<\VoH\right>}{D(h_i, \alpha)\left<\NoH\right>}$.
into account and adds a term $\frac{\left<\VoH\right>}{D(h_i, \alpha)\left<\NoH\right>}$.
See Importance Sampling For The IBL section:
$$\begin{equation}\label{iblImportanceSampling}
@@ -3486,15 +3486,15 @@ The _important direction samples_ $l_i$ are calculated as the reflection of $v$
**do not** have the same PDF as $h_i$. The PDF of a transformed distribution is given by:
$$\begin{equation}
p(T_r(x)) = p(x) |J(T_r)|^{-1}
p(T_r(x)) = p(x) |J(T_r)|
\end{equation}$$
Where $|J(T_r)|$ is the determinant of the Jacobian of the transform. In our case we're considering
the transform from $h_i$ to $l_i$ and the determinant of its Jacobian is given in \ref{iblPDF}.
$$\begin{equation}\label{iblPDF}
p(l,v,\Theta) = D(h,\alpha) \left< \NoH \right> |J_{h \rightarrow l}|^{-1} \\
|J_{h \rightarrow l}| = 4 \left< \VoH \right>
p(l,v,\Theta) = D(h,\alpha) \left< \NoH \right> |J_{h \rightarrow l}| \\
|J_{h \rightarrow l}| = \frac{1}{4 \left< \VoH \right>}
\end{equation}$$
### Choosing important directions
+77 -169
View File
File diff suppressed because one or more lines are too long
+2 -92
View File
@@ -1076,71 +1076,13 @@ fragment {
}
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
### General: constants
Type
: array of constant objects
Value
: Each entry is an object with the properties `name` and `type`, both of `string` type. The name
must be a valid GLSL identifier. Entries also have an optional `default`, which can either be a
`bool` or `number`, depending on the `type` of the constant. The type must be one of the types
described in table [materialConstantsTypes].
Type | Description | Default
:----------------------|:-----------------------------------------|:------------------
int | A signed, 32 bit GLSL int | 0
float | A single-precision GLSL float | 0.0
bool | A GLSL bool | false
[Table [materialConstantsTypes]: Material constants types]
Description
: Lists the constant parameters accepted by your material. These constants can be set, or
"specialized", at runtime when loading a material package. Multiple materials can be loaded from
the same material package with differing constant parameter specializations. Once a material is
loaded from a material package, its constant parameters cannot be changed. Compared to regular
parameters, constant parameters allow the compiler to generate more efficient code. Access
constant parameters from the shader by prefixing the name with `materialConstant_`. For example,
a constant parameter named `myConstant` is accessed in the shader as
`materialConstant_myConstant`. If a constant parameter is not set at runtime, the default is
used.
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ JSON
material {
constants : [
{
name : overrideAlpha,
type : bool
},
{
name : customAlpha,
type : float,
default : 0.5
}
],
shadingModel : lit,
blending : transparent,
}
fragment {
void material(inout MaterialInputs material) {
prepareMaterial(material);
if (materialConstants_overrideAlpha) {
material.baseColor.a = materialConstants_customAlpha;
material.baseColor.rgb *= material.baseColor.a;
}
}
}
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
### General: variantFilter
Type
: array of `string`
Value
: Each entry must be any of `dynamicLighting`, `directionalLighting`, `shadowReceiver`,
`skinning`, `ssr`, or `stereo`.
: Each entry must be any of `dynamicLighting`, `directionalLighting`, `shadowReceiver`,`skinning` or `ssr`.
Description
: Used to specify a list of shader variants that the application guarantees will never be
@@ -1159,7 +1101,6 @@ Description of the variants:
- `fog`, used when global fog is applied to the scene
- `vsm`, used when VSM shadows are enabled and the object is a shadow receiver
- `ssr`, used when screen-space reflections are enabled in the View
- `stereo`, used when stereoscopic rendering is enabled in the View
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ JSON
material {
@@ -2365,7 +2306,7 @@ type aliases:
**getUserWorldFromWorldMatrix()** | float4x4 | Matrix that converts from world space to API-level (user) world space.
**getTime()** | float | Current time as a remainder of 1 second. Yields a value between 0 and 1
**getUserTime()** | float4 | Current time in seconds: `time`, `(double)time - time`, `0`, `0`
**getUserTimeMod(float m)** | float | Current time modulo m in seconds
**getUserTimeMode(float m)** | float | Current time modulo m in seconds
**getExposure()** | float | Photometric exposure of the camera
**getEV100()** | float | [Exposure value at ISO 100](https://en.wikipedia.org/wiki/Exposure_value) of the camera
@@ -2374,15 +2315,6 @@ type aliases:
match the API-level world space. To obtain the position of the API-level camera, custom
materials can use `getUserWorldFromWorldMatrix()` to transform `getWorldCameraPosition()`.
### Material globals
Name | Type | Description
:-----------------------------------|:--------:|:------------------------------------
**getMaterialGlobal0()** | float4 | A vec4 visible by all materials, its value is set by `View::setMaterialGlobal(0, float4)`. Its default value is {0,0,0,1}.
**getMaterialGlobal1()** | float4 | A vec4 visible by all materials, its value is set by `View::setMaterialGlobal(1, float4)`. Its default value is {0,0,0,1}.
**getMaterialGlobal2()** | float4 | A vec4 visible by all materials, its value is set by `View::setMaterialGlobal(2, float4)`. Its default value is {0,0,0,1}.
**getMaterialGlobal3()** | float4 | A vec4 visible by all materials, its value is set by `View::setMaterialGlobal(3, float4)`. Its default value is {0,0,0,1}.
### Vertex only
The following APIs are only available from the vertex block:
@@ -2595,26 +2527,4 @@ pre-multiplied ahead of time. On Android, any texture uploaded from a
[Bitmap](https://developer.android.com/reference/android/graphics/Bitmap.html) will be
pre-multiplied by default.
# Sampler usage in Materials
The number of usable sampler parameters (e.g.: type is `sampler2d`) in materials is limited and
depends on the material properties, shading model, feature level and variant filter.
## Feature level 1 and 2
`unlit` materials can use up to 12 samplers by default.
`lit` materials can use up to 9 samplers by default, however if `refractionMode` or `reflectionMode`
is set to `screenspace` that number is reduced to 8.
Finally if `variantFilter` contains the `fog` filter, an extra sampler is made available, such that
`unlit` materials can use up to 13 and `lit` materials up to 10 samplers by default.
## Feature level 3
16 samplers are available.
!!! TIP: external samplers
Be aware that `external` samplers account for 2 regular samplers.
<!-- Markdeep: --><style class="fallback">body{visibility:hidden;white-space:pre;font-family:monospace}</style><script src="../third_party/markdeep/markdeep.min.js"></script><script src="https://casual-effects.com/markdeep/latest/markdeep.min.js"></script><script>window.alreadyProcessedMarkdeep||(document.body.style.visibility="visible")</script>
File diff suppressed because one or more lines are too long
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
+3 -12
View File
File diff suppressed because one or more lines are too long
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
+145 -145
View File
@@ -44,7 +44,7 @@ fragment {
</pre></div>
<p>Next, invoke <code>matc</code> as follows.</p>
<div class="highlight" style="background: #f8f8f8"><pre style="line-height: 125%;"><span></span>matc -a opengl -p mobile -o plastic.filamat plastic.mat
<div class="highlight" style="background: #f8f8f8"><pre style="line-height: 125%;"><span></span>matc<span style="color: #bbbbbb"> </span>-a<span style="color: #bbbbbb"> </span>opengl<span style="color: #bbbbbb"> </span>-p<span style="color: #bbbbbb"> </span>mobile<span style="color: #bbbbbb"> </span>-o<span style="color: #bbbbbb"> </span>plastic.filamat<span style="color: #bbbbbb"> </span>plastic.mat
</pre></div>
<p>You should now have a material archive in your working directory, which we&#x27;ll use later in the
@@ -53,7 +53,7 @@ tutorial.</p>
<p>Next we&#x27;ll use Filament&#x27;s <code>cmgen</code> tool to consume a HDR environment map in latlong format, and
produce two cubemap files: a mipmapped IBL and a blurry skybox.</p>
<p>Download <a href="//github.com/google/filament/blob/main/third_party/environments/pillars_2k.hdr">pillars_2k.hdr</a>, then invoke the following command in your terminal.</p>
<div class="highlight" style="background: #f8f8f8"><pre style="line-height: 125%;"><span></span>cmgen -x pillars_2k --format<span style="color: #666666">=</span>ktx --size<span style="color: #666666">=256</span> --extract-blur<span style="color: #666666">=0</span>.1 pillars_2k.hdr
<div class="highlight" style="background: #f8f8f8"><pre style="line-height: 125%;"><span></span>cmgen<span style="color: #bbbbbb"> </span>-x<span style="color: #bbbbbb"> </span>pillars_2k<span style="color: #bbbbbb"> </span>--format<span style="color: #666666">=</span>ktx<span style="color: #bbbbbb"> </span>--size<span style="color: #666666">=256</span><span style="color: #bbbbbb"> </span>--extract-blur<span style="color: #666666">=0</span>.1<span style="color: #bbbbbb"> </span>pillars_2k.hdr
</pre></div>
<p>You should now have a <code>pillars_2k</code> folder containing a couple KTX files for the IBL and skybox, as
@@ -61,81 +61,81 @@ well as a text file with spherical harmonics coefficients. You can discard the t
IBL KTX contains these coefficients in its metadata.</p>
<h2>Create JavaScript</h2>
<p>Next, create <code>redball.js</code> with the following content.</p>
<div class="highlight" style="background: #f8f8f8"><pre style="line-height: 125%;"><span></span><span style="color: #008000; font-weight: bold">const</span><span style="color: #bbbbbb"> </span>environ<span style="color: #bbbbbb"> </span><span style="color: #666666">=</span><span style="color: #bbbbbb"> </span><span style="color: #BA2121">&#39;pillars_2k&#39;</span>;<span style="color: #bbbbbb"></span>
<span style="color: #008000; font-weight: bold">const</span><span style="color: #bbbbbb"> </span>ibl_url<span style="color: #bbbbbb"> </span><span style="color: #666666">=</span><span style="color: #bbbbbb"> </span><span style="color: #BA2121">`</span><span style="color: #A45A77; font-weight: bold">${</span>environ<span style="color: #A45A77; font-weight: bold">}</span><span style="color: #BA2121">/</span><span style="color: #A45A77; font-weight: bold">${</span>environ<span style="color: #A45A77; font-weight: bold">}</span><span style="color: #BA2121">_ibl.ktx`</span>;<span style="color: #bbbbbb"></span>
<span style="color: #008000; font-weight: bold">const</span><span style="color: #bbbbbb"> </span>sky_url<span style="color: #bbbbbb"> </span><span style="color: #666666">=</span><span style="color: #bbbbbb"> </span><span style="color: #BA2121">`</span><span style="color: #A45A77; font-weight: bold">${</span>environ<span style="color: #A45A77; font-weight: bold">}</span><span style="color: #BA2121">/</span><span style="color: #A45A77; font-weight: bold">${</span>environ<span style="color: #A45A77; font-weight: bold">}</span><span style="color: #BA2121">_skybox.ktx`</span>;<span style="color: #bbbbbb"></span>
<span style="color: #008000; font-weight: bold">const</span><span style="color: #bbbbbb"> </span>filamat_url<span style="color: #bbbbbb"> </span><span style="color: #666666">=</span><span style="color: #bbbbbb"> </span><span style="color: #BA2121">&#39;plastic.filamat&#39;</span><span style="color: #bbbbbb"></span>
<div class="highlight" style="background: #f8f8f8"><pre style="line-height: 125%;"><span></span><span style="color: #008000; font-weight: bold">const</span><span style="color: #bbbbbb"> </span>environ<span style="color: #bbbbbb"> </span><span style="color: #666666">=</span><span style="color: #bbbbbb"> </span><span style="color: #BA2121">&#39;pillars_2k&#39;</span>;
<span style="color: #008000; font-weight: bold">const</span><span style="color: #bbbbbb"> </span>ibl_url<span style="color: #bbbbbb"> </span><span style="color: #666666">=</span><span style="color: #bbbbbb"> </span><span style="color: #BA2121">`</span><span style="color: #A45A77; font-weight: bold">${</span>environ<span style="color: #A45A77; font-weight: bold">}</span><span style="color: #BA2121">/</span><span style="color: #A45A77; font-weight: bold">${</span>environ<span style="color: #A45A77; font-weight: bold">}</span><span style="color: #BA2121">_ibl.ktx`</span>;
<span style="color: #008000; font-weight: bold">const</span><span style="color: #bbbbbb"> </span>sky_url<span style="color: #bbbbbb"> </span><span style="color: #666666">=</span><span style="color: #bbbbbb"> </span><span style="color: #BA2121">`</span><span style="color: #A45A77; font-weight: bold">${</span>environ<span style="color: #A45A77; font-weight: bold">}</span><span style="color: #BA2121">/</span><span style="color: #A45A77; font-weight: bold">${</span>environ<span style="color: #A45A77; font-weight: bold">}</span><span style="color: #BA2121">_skybox.ktx`</span>;
<span style="color: #008000; font-weight: bold">const</span><span style="color: #bbbbbb"> </span>filamat_url<span style="color: #bbbbbb"> </span><span style="color: #666666">=</span><span style="color: #bbbbbb"> </span><span style="color: #BA2121">&#39;plastic.filamat&#39;</span>
Filament.init([<span style="color: #bbbbbb"> </span>filamat_url,<span style="color: #bbbbbb"> </span>ibl_url,<span style="color: #bbbbbb"> </span>sky_url<span style="color: #bbbbbb"> </span>],<span style="color: #bbbbbb"> </span>()<span style="color: #bbbbbb"> </span>=&gt;<span style="color: #bbbbbb"> </span>{<span style="color: #bbbbbb"></span>
<span style="color: #bbbbbb"> </span><span style="color: #3D7B7B; font-style: italic">// Create some global aliases to enums for convenience.</span><span style="color: #bbbbbb"></span>
<span style="color: #bbbbbb"> </span><span style="color: #008000">window</span>.VertexAttribute<span style="color: #bbbbbb"> </span><span style="color: #666666">=</span><span style="color: #bbbbbb"> </span>Filament.VertexAttribute;<span style="color: #bbbbbb"></span>
<span style="color: #bbbbbb"> </span><span style="color: #008000">window</span>.AttributeType<span style="color: #bbbbbb"> </span><span style="color: #666666">=</span><span style="color: #bbbbbb"> </span>Filament.VertexBuffer$AttributeType;<span style="color: #bbbbbb"></span>
<span style="color: #bbbbbb"> </span><span style="color: #008000">window</span>.PrimitiveType<span style="color: #bbbbbb"> </span><span style="color: #666666">=</span><span style="color: #bbbbbb"> </span>Filament.RenderableManager$PrimitiveType;<span style="color: #bbbbbb"></span>
<span style="color: #bbbbbb"> </span><span style="color: #008000">window</span>.IndexType<span style="color: #bbbbbb"> </span><span style="color: #666666">=</span><span style="color: #bbbbbb"> </span>Filament.IndexBuffer$IndexType;<span style="color: #bbbbbb"></span>
<span style="color: #bbbbbb"> </span><span style="color: #008000">window</span>.Fov<span style="color: #bbbbbb"> </span><span style="color: #666666">=</span><span style="color: #bbbbbb"> </span>Filament.Camera$Fov;<span style="color: #bbbbbb"></span>
<span style="color: #bbbbbb"> </span><span style="color: #008000">window</span>.LightType<span style="color: #bbbbbb"> </span><span style="color: #666666">=</span><span style="color: #bbbbbb"> </span>Filament.LightManager$Type;<span style="color: #bbbbbb"></span>
Filament.init([<span style="color: #bbbbbb"> </span>filamat_url,<span style="color: #bbbbbb"> </span>ibl_url,<span style="color: #bbbbbb"> </span>sky_url<span style="color: #bbbbbb"> </span>],<span style="color: #bbbbbb"> </span>()<span style="color: #bbbbbb"> </span>=&gt;<span style="color: #bbbbbb"> </span>{
<span style="color: #bbbbbb"> </span><span style="color: #3D7B7B; font-style: italic">// Create some global aliases to enums for convenience.</span>
<span style="color: #bbbbbb"> </span><span style="color: #008000">window</span>.VertexAttribute<span style="color: #bbbbbb"> </span><span style="color: #666666">=</span><span style="color: #bbbbbb"> </span>Filament.VertexAttribute;
<span style="color: #bbbbbb"> </span><span style="color: #008000">window</span>.AttributeType<span style="color: #bbbbbb"> </span><span style="color: #666666">=</span><span style="color: #bbbbbb"> </span>Filament.VertexBuffer$AttributeType;
<span style="color: #bbbbbb"> </span><span style="color: #008000">window</span>.PrimitiveType<span style="color: #bbbbbb"> </span><span style="color: #666666">=</span><span style="color: #bbbbbb"> </span>Filament.RenderableManager$PrimitiveType;
<span style="color: #bbbbbb"> </span><span style="color: #008000">window</span>.IndexType<span style="color: #bbbbbb"> </span><span style="color: #666666">=</span><span style="color: #bbbbbb"> </span>Filament.IndexBuffer$IndexType;
<span style="color: #bbbbbb"> </span><span style="color: #008000">window</span>.Fov<span style="color: #bbbbbb"> </span><span style="color: #666666">=</span><span style="color: #bbbbbb"> </span>Filament.Camera$Fov;
<span style="color: #bbbbbb"> </span><span style="color: #008000">window</span>.LightType<span style="color: #bbbbbb"> </span><span style="color: #666666">=</span><span style="color: #bbbbbb"> </span>Filament.LightManager$Type;
<span style="color: #bbbbbb"> </span><span style="color: #3D7B7B; font-style: italic">// Obtain the canvas DOM object and pass it to the App.</span><span style="color: #bbbbbb"></span>
<span style="color: #bbbbbb"> </span><span style="color: #008000; font-weight: bold">const</span><span style="color: #bbbbbb"> </span>canvas<span style="color: #bbbbbb"> </span><span style="color: #666666">=</span><span style="color: #bbbbbb"> </span><span style="color: #008000">document</span>.getElementsByTagName(<span style="color: #BA2121">&#39;canvas&#39;</span>)[<span style="color: #666666">0</span>];<span style="color: #bbbbbb"></span>
<span style="color: #bbbbbb"> </span><span style="color: #008000">window</span>.app<span style="color: #bbbbbb"> </span><span style="color: #666666">=</span><span style="color: #bbbbbb"> </span><span style="color: #AA22FF; font-weight: bold">new</span><span style="color: #bbbbbb"> </span>App(canvas);<span style="color: #bbbbbb"></span>
}<span style="color: #bbbbbb"> </span>);<span style="color: #bbbbbb"></span>
<span style="color: #bbbbbb"> </span><span style="color: #3D7B7B; font-style: italic">// Obtain the canvas DOM object and pass it to the App.</span>
<span style="color: #bbbbbb"> </span><span style="color: #008000; font-weight: bold">const</span><span style="color: #bbbbbb"> </span>canvas<span style="color: #bbbbbb"> </span><span style="color: #666666">=</span><span style="color: #bbbbbb"> </span><span style="color: #008000">document</span>.getElementsByTagName(<span style="color: #BA2121">&#39;canvas&#39;</span>)[<span style="color: #666666">0</span>];
<span style="color: #bbbbbb"> </span><span style="color: #008000">window</span>.app<span style="color: #bbbbbb"> </span><span style="color: #666666">=</span><span style="color: #bbbbbb"> </span><span style="color: #AA22FF; font-weight: bold">new</span><span style="color: #bbbbbb"> </span>App(canvas);
}<span style="color: #bbbbbb"> </span>);
<span style="color: #008000; font-weight: bold">class</span><span style="color: #bbbbbb"> </span>App<span style="color: #bbbbbb"> </span>{<span style="color: #bbbbbb"></span>
<span style="color: #bbbbbb"> </span><span style="color: #008000; font-weight: bold">constructor</span>(canvas)<span style="color: #bbbbbb"> </span>{<span style="color: #bbbbbb"></span>
<span style="color: #bbbbbb"> </span><span style="color: #008000; font-weight: bold">this</span>.canvas<span style="color: #bbbbbb"> </span><span style="color: #666666">=</span><span style="color: #bbbbbb"> </span>canvas;<span style="color: #bbbbbb"></span>
<span style="color: #bbbbbb"> </span><span style="color: #008000; font-weight: bold">const</span><span style="color: #bbbbbb"> </span>engine<span style="color: #bbbbbb"> </span><span style="color: #666666">=</span><span style="color: #bbbbbb"> </span><span style="color: #008000; font-weight: bold">this</span>.engine<span style="color: #bbbbbb"> </span><span style="color: #666666">=</span><span style="color: #bbbbbb"> </span>Filament.Engine.create(canvas);<span style="color: #bbbbbb"></span>
<span style="color: #bbbbbb"> </span><span style="color: #008000; font-weight: bold">const</span><span style="color: #bbbbbb"> </span>scene<span style="color: #bbbbbb"> </span><span style="color: #666666">=</span><span style="color: #bbbbbb"> </span>engine.createScene();<span style="color: #bbbbbb"></span>
<span style="color: #008000; font-weight: bold">class</span><span style="color: #bbbbbb"> </span>App<span style="color: #bbbbbb"> </span>{
<span style="color: #bbbbbb"> </span><span style="color: #008000; font-weight: bold">constructor</span>(canvas)<span style="color: #bbbbbb"> </span>{
<span style="color: #bbbbbb"> </span><span style="color: #008000; font-weight: bold">this</span>.canvas<span style="color: #bbbbbb"> </span><span style="color: #666666">=</span><span style="color: #bbbbbb"> </span>canvas;
<span style="color: #bbbbbb"> </span><span style="color: #008000; font-weight: bold">const</span><span style="color: #bbbbbb"> </span>engine<span style="color: #bbbbbb"> </span><span style="color: #666666">=</span><span style="color: #bbbbbb"> </span><span style="color: #008000; font-weight: bold">this</span>.engine<span style="color: #bbbbbb"> </span><span style="color: #666666">=</span><span style="color: #bbbbbb"> </span>Filament.Engine.create(canvas);
<span style="color: #bbbbbb"> </span><span style="color: #008000; font-weight: bold">const</span><span style="color: #bbbbbb"> </span>scene<span style="color: #bbbbbb"> </span><span style="color: #666666">=</span><span style="color: #bbbbbb"> </span>engine.createScene();
<span style="color: #bbbbbb"> </span><span style="color: #3D7B7B; font-style: italic">// TODO: create material</span><span style="color: #bbbbbb"></span>
<span style="color: #bbbbbb"> </span><span style="color: #3D7B7B; font-style: italic">// TODO: create sphere</span><span style="color: #bbbbbb"></span>
<span style="color: #bbbbbb"> </span><span style="color: #3D7B7B; font-style: italic">// TODO: create lights</span><span style="color: #bbbbbb"></span>
<span style="color: #bbbbbb"> </span><span style="color: #3D7B7B; font-style: italic">// TODO: create IBL</span><span style="color: #bbbbbb"></span>
<span style="color: #bbbbbb"> </span><span style="color: #3D7B7B; font-style: italic">// TODO: create skybox</span><span style="color: #bbbbbb"></span>
<span style="color: #bbbbbb"> </span><span style="color: #3D7B7B; font-style: italic">// TODO: create material</span>
<span style="color: #bbbbbb"> </span><span style="color: #3D7B7B; font-style: italic">// TODO: create sphere</span>
<span style="color: #bbbbbb"> </span><span style="color: #3D7B7B; font-style: italic">// TODO: create lights</span>
<span style="color: #bbbbbb"> </span><span style="color: #3D7B7B; font-style: italic">// TODO: create IBL</span>
<span style="color: #bbbbbb"> </span><span style="color: #3D7B7B; font-style: italic">// TODO: create skybox</span>
<span style="color: #bbbbbb"> </span><span style="color: #008000; font-weight: bold">this</span>.swapChain<span style="color: #bbbbbb"> </span><span style="color: #666666">=</span><span style="color: #bbbbbb"> </span>engine.createSwapChain();<span style="color: #bbbbbb"></span>
<span style="color: #bbbbbb"> </span><span style="color: #008000; font-weight: bold">this</span>.renderer<span style="color: #bbbbbb"> </span><span style="color: #666666">=</span><span style="color: #bbbbbb"> </span>engine.createRenderer();<span style="color: #bbbbbb"></span>
<span style="color: #bbbbbb"> </span><span style="color: #008000; font-weight: bold">this</span>.camera<span style="color: #bbbbbb"> </span><span style="color: #666666">=</span><span style="color: #bbbbbb"> </span>engine.createCamera(Filament.EntityManager.get().create());<span style="color: #bbbbbb"></span>
<span style="color: #bbbbbb"> </span><span style="color: #008000; font-weight: bold">this</span>.view<span style="color: #bbbbbb"> </span><span style="color: #666666">=</span><span style="color: #bbbbbb"> </span>engine.createView();<span style="color: #bbbbbb"></span>
<span style="color: #bbbbbb"> </span><span style="color: #008000; font-weight: bold">this</span>.view.setCamera(<span style="color: #008000; font-weight: bold">this</span>.camera);<span style="color: #bbbbbb"></span>
<span style="color: #bbbbbb"> </span><span style="color: #008000; font-weight: bold">this</span>.view.setScene(scene);<span style="color: #bbbbbb"></span>
<span style="color: #bbbbbb"> </span><span style="color: #008000; font-weight: bold">this</span>.resize();<span style="color: #bbbbbb"></span>
<span style="color: #bbbbbb"> </span><span style="color: #008000; font-weight: bold">this</span>.render<span style="color: #bbbbbb"> </span><span style="color: #666666">=</span><span style="color: #bbbbbb"> </span><span style="color: #008000; font-weight: bold">this</span>.render.bind(<span style="color: #008000; font-weight: bold">this</span>);<span style="color: #bbbbbb"></span>
<span style="color: #bbbbbb"> </span><span style="color: #008000; font-weight: bold">this</span>.resize<span style="color: #bbbbbb"> </span><span style="color: #666666">=</span><span style="color: #bbbbbb"> </span><span style="color: #008000; font-weight: bold">this</span>.resize.bind(<span style="color: #008000; font-weight: bold">this</span>);<span style="color: #bbbbbb"></span>
<span style="color: #bbbbbb"> </span><span style="color: #008000">window</span>.addEventListener(<span style="color: #BA2121">&#39;resize&#39;</span>,<span style="color: #bbbbbb"> </span><span style="color: #008000; font-weight: bold">this</span>.resize);<span style="color: #bbbbbb"></span>
<span style="color: #bbbbbb"> </span><span style="color: #008000">window</span>.requestAnimationFrame(<span style="color: #008000; font-weight: bold">this</span>.render);<span style="color: #bbbbbb"></span>
<span style="color: #bbbbbb"> </span>}<span style="color: #bbbbbb"></span>
<span style="color: #bbbbbb"> </span><span style="color: #008000; font-weight: bold">this</span>.swapChain<span style="color: #bbbbbb"> </span><span style="color: #666666">=</span><span style="color: #bbbbbb"> </span>engine.createSwapChain();
<span style="color: #bbbbbb"> </span><span style="color: #008000; font-weight: bold">this</span>.renderer<span style="color: #bbbbbb"> </span><span style="color: #666666">=</span><span style="color: #bbbbbb"> </span>engine.createRenderer();
<span style="color: #bbbbbb"> </span><span style="color: #008000; font-weight: bold">this</span>.camera<span style="color: #bbbbbb"> </span><span style="color: #666666">=</span><span style="color: #bbbbbb"> </span>engine.createCamera(Filament.EntityManager.get().create());
<span style="color: #bbbbbb"> </span><span style="color: #008000; font-weight: bold">this</span>.view<span style="color: #bbbbbb"> </span><span style="color: #666666">=</span><span style="color: #bbbbbb"> </span>engine.createView();
<span style="color: #bbbbbb"> </span><span style="color: #008000; font-weight: bold">this</span>.view.setCamera(<span style="color: #008000; font-weight: bold">this</span>.camera);
<span style="color: #bbbbbb"> </span><span style="color: #008000; font-weight: bold">this</span>.view.setScene(scene);
<span style="color: #bbbbbb"> </span><span style="color: #008000; font-weight: bold">this</span>.resize();
<span style="color: #bbbbbb"> </span><span style="color: #008000; font-weight: bold">this</span>.render<span style="color: #bbbbbb"> </span><span style="color: #666666">=</span><span style="color: #bbbbbb"> </span><span style="color: #008000; font-weight: bold">this</span>.render.bind(<span style="color: #008000; font-weight: bold">this</span>);
<span style="color: #bbbbbb"> </span><span style="color: #008000; font-weight: bold">this</span>.resize<span style="color: #bbbbbb"> </span><span style="color: #666666">=</span><span style="color: #bbbbbb"> </span><span style="color: #008000; font-weight: bold">this</span>.resize.bind(<span style="color: #008000; font-weight: bold">this</span>);
<span style="color: #bbbbbb"> </span><span style="color: #008000">window</span>.addEventListener(<span style="color: #BA2121">&#39;resize&#39;</span>,<span style="color: #bbbbbb"> </span><span style="color: #008000; font-weight: bold">this</span>.resize);
<span style="color: #bbbbbb"> </span><span style="color: #008000">window</span>.requestAnimationFrame(<span style="color: #008000; font-weight: bold">this</span>.render);
<span style="color: #bbbbbb"> </span>}
<span style="color: #bbbbbb"> </span>render()<span style="color: #bbbbbb"> </span>{<span style="color: #bbbbbb"></span>
<span style="color: #bbbbbb"> </span><span style="color: #008000; font-weight: bold">const</span><span style="color: #bbbbbb"> </span>eye<span style="color: #bbbbbb"> </span><span style="color: #666666">=</span><span style="color: #bbbbbb"> </span>[<span style="color: #666666">0</span>,<span style="color: #bbbbbb"> </span><span style="color: #666666">0</span>,<span style="color: #bbbbbb"> </span><span style="color: #666666">4</span>],<span style="color: #bbbbbb"> </span>center<span style="color: #bbbbbb"> </span><span style="color: #666666">=</span><span style="color: #bbbbbb"> </span>[<span style="color: #666666">0</span>,<span style="color: #bbbbbb"> </span><span style="color: #666666">0</span>,<span style="color: #bbbbbb"> </span><span style="color: #666666">0</span>],<span style="color: #bbbbbb"> </span>up<span style="color: #bbbbbb"> </span><span style="color: #666666">=</span><span style="color: #bbbbbb"> </span>[<span style="color: #666666">0</span>,<span style="color: #bbbbbb"> </span><span style="color: #666666">1</span>,<span style="color: #bbbbbb"> </span><span style="color: #666666">0</span>];<span style="color: #bbbbbb"></span>
<span style="color: #bbbbbb"> </span><span style="color: #008000; font-weight: bold">const</span><span style="color: #bbbbbb"> </span>radians<span style="color: #bbbbbb"> </span><span style="color: #666666">=</span><span style="color: #bbbbbb"> </span><span style="color: #008000">Date</span>.now()<span style="color: #bbbbbb"> </span><span style="color: #666666">/</span><span style="color: #bbbbbb"> </span><span style="color: #666666">10000</span>;<span style="color: #bbbbbb"></span>
<span style="color: #bbbbbb"> </span>vec3.rotateY(eye,<span style="color: #bbbbbb"> </span>eye,<span style="color: #bbbbbb"> </span>center,<span style="color: #bbbbbb"> </span>radians);<span style="color: #bbbbbb"></span>
<span style="color: #bbbbbb"> </span><span style="color: #008000; font-weight: bold">this</span>.camera.lookAt(eye,<span style="color: #bbbbbb"> </span>center,<span style="color: #bbbbbb"> </span>up);<span style="color: #bbbbbb"></span>
<span style="color: #bbbbbb"> </span><span style="color: #008000; font-weight: bold">this</span>.renderer.render(<span style="color: #008000; font-weight: bold">this</span>.swapChain,<span style="color: #bbbbbb"> </span><span style="color: #008000; font-weight: bold">this</span>.view);<span style="color: #bbbbbb"></span>
<span style="color: #bbbbbb"> </span><span style="color: #008000">window</span>.requestAnimationFrame(<span style="color: #008000; font-weight: bold">this</span>.render);<span style="color: #bbbbbb"></span>
<span style="color: #bbbbbb"> </span>}<span style="color: #bbbbbb"></span>
<span style="color: #bbbbbb"> </span>render()<span style="color: #bbbbbb"> </span>{
<span style="color: #bbbbbb"> </span><span style="color: #008000; font-weight: bold">const</span><span style="color: #bbbbbb"> </span>eye<span style="color: #bbbbbb"> </span><span style="color: #666666">=</span><span style="color: #bbbbbb"> </span>[<span style="color: #666666">0</span>,<span style="color: #bbbbbb"> </span><span style="color: #666666">0</span>,<span style="color: #bbbbbb"> </span><span style="color: #666666">4</span>],<span style="color: #bbbbbb"> </span>center<span style="color: #bbbbbb"> </span><span style="color: #666666">=</span><span style="color: #bbbbbb"> </span>[<span style="color: #666666">0</span>,<span style="color: #bbbbbb"> </span><span style="color: #666666">0</span>,<span style="color: #bbbbbb"> </span><span style="color: #666666">0</span>],<span style="color: #bbbbbb"> </span>up<span style="color: #bbbbbb"> </span><span style="color: #666666">=</span><span style="color: #bbbbbb"> </span>[<span style="color: #666666">0</span>,<span style="color: #bbbbbb"> </span><span style="color: #666666">1</span>,<span style="color: #bbbbbb"> </span><span style="color: #666666">0</span>];
<span style="color: #bbbbbb"> </span><span style="color: #008000; font-weight: bold">const</span><span style="color: #bbbbbb"> </span>radians<span style="color: #bbbbbb"> </span><span style="color: #666666">=</span><span style="color: #bbbbbb"> </span><span style="color: #008000">Date</span>.now()<span style="color: #bbbbbb"> </span><span style="color: #666666">/</span><span style="color: #bbbbbb"> </span><span style="color: #666666">10000</span>;
<span style="color: #bbbbbb"> </span>vec3.rotateY(eye,<span style="color: #bbbbbb"> </span>eye,<span style="color: #bbbbbb"> </span>center,<span style="color: #bbbbbb"> </span>radians);
<span style="color: #bbbbbb"> </span><span style="color: #008000; font-weight: bold">this</span>.camera.lookAt(eye,<span style="color: #bbbbbb"> </span>center,<span style="color: #bbbbbb"> </span>up);
<span style="color: #bbbbbb"> </span><span style="color: #008000; font-weight: bold">this</span>.renderer.render(<span style="color: #008000; font-weight: bold">this</span>.swapChain,<span style="color: #bbbbbb"> </span><span style="color: #008000; font-weight: bold">this</span>.view);
<span style="color: #bbbbbb"> </span><span style="color: #008000">window</span>.requestAnimationFrame(<span style="color: #008000; font-weight: bold">this</span>.render);
<span style="color: #bbbbbb"> </span>}
<span style="color: #bbbbbb"> </span>resize()<span style="color: #bbbbbb"> </span>{<span style="color: #bbbbbb"></span>
<span style="color: #bbbbbb"> </span><span style="color: #008000; font-weight: bold">const</span><span style="color: #bbbbbb"> </span>dpr<span style="color: #bbbbbb"> </span><span style="color: #666666">=</span><span style="color: #bbbbbb"> </span><span style="color: #008000">window</span>.devicePixelRatio;<span style="color: #bbbbbb"></span>
<span style="color: #bbbbbb"> </span><span style="color: #008000; font-weight: bold">const</span><span style="color: #bbbbbb"> </span>width<span style="color: #bbbbbb"> </span><span style="color: #666666">=</span><span style="color: #bbbbbb"> </span><span style="color: #008000; font-weight: bold">this</span>.canvas.width<span style="color: #bbbbbb"> </span><span style="color: #666666">=</span><span style="color: #bbbbbb"> </span><span style="color: #008000">window</span>.innerWidth<span style="color: #bbbbbb"> </span><span style="color: #666666">*</span><span style="color: #bbbbbb"> </span>dpr;<span style="color: #bbbbbb"></span>
<span style="color: #bbbbbb"> </span><span style="color: #008000; font-weight: bold">const</span><span style="color: #bbbbbb"> </span>height<span style="color: #bbbbbb"> </span><span style="color: #666666">=</span><span style="color: #bbbbbb"> </span><span style="color: #008000; font-weight: bold">this</span>.canvas.height<span style="color: #bbbbbb"> </span><span style="color: #666666">=</span><span style="color: #bbbbbb"> </span><span style="color: #008000">window</span>.innerHeight<span style="color: #bbbbbb"> </span><span style="color: #666666">*</span><span style="color: #bbbbbb"> </span>dpr;<span style="color: #bbbbbb"></span>
<span style="color: #bbbbbb"> </span><span style="color: #008000; font-weight: bold">this</span>.view.setViewport([<span style="color: #666666">0</span>,<span style="color: #bbbbbb"> </span><span style="color: #666666">0</span>,<span style="color: #bbbbbb"> </span>width,<span style="color: #bbbbbb"> </span>height]);<span style="color: #bbbbbb"></span>
<span style="color: #bbbbbb"> </span><span style="color: #008000; font-weight: bold">this</span>.camera.setProjectionFov(<span style="color: #666666">45</span>,<span style="color: #bbbbbb"> </span>width<span style="color: #bbbbbb"> </span><span style="color: #666666">/</span><span style="color: #bbbbbb"> </span>height,<span style="color: #bbbbbb"> </span><span style="color: #666666">1.0</span>,<span style="color: #bbbbbb"> </span><span style="color: #666666">10.0</span>,<span style="color: #bbbbbb"> </span>Fov.VERTICAL);<span style="color: #bbbbbb"></span>
<span style="color: #bbbbbb"> </span>}<span style="color: #bbbbbb"></span>
}<span style="color: #bbbbbb"></span>
<span style="color: #bbbbbb"> </span>resize()<span style="color: #bbbbbb"> </span>{
<span style="color: #bbbbbb"> </span><span style="color: #008000; font-weight: bold">const</span><span style="color: #bbbbbb"> </span>dpr<span style="color: #bbbbbb"> </span><span style="color: #666666">=</span><span style="color: #bbbbbb"> </span><span style="color: #008000">window</span>.devicePixelRatio;
<span style="color: #bbbbbb"> </span><span style="color: #008000; font-weight: bold">const</span><span style="color: #bbbbbb"> </span>width<span style="color: #bbbbbb"> </span><span style="color: #666666">=</span><span style="color: #bbbbbb"> </span><span style="color: #008000; font-weight: bold">this</span>.canvas.width<span style="color: #bbbbbb"> </span><span style="color: #666666">=</span><span style="color: #bbbbbb"> </span><span style="color: #008000">window</span>.innerWidth<span style="color: #bbbbbb"> </span><span style="color: #666666">*</span><span style="color: #bbbbbb"> </span>dpr;
<span style="color: #bbbbbb"> </span><span style="color: #008000; font-weight: bold">const</span><span style="color: #bbbbbb"> </span>height<span style="color: #bbbbbb"> </span><span style="color: #666666">=</span><span style="color: #bbbbbb"> </span><span style="color: #008000; font-weight: bold">this</span>.canvas.height<span style="color: #bbbbbb"> </span><span style="color: #666666">=</span><span style="color: #bbbbbb"> </span><span style="color: #008000">window</span>.innerHeight<span style="color: #bbbbbb"> </span><span style="color: #666666">*</span><span style="color: #bbbbbb"> </span>dpr;
<span style="color: #bbbbbb"> </span><span style="color: #008000; font-weight: bold">this</span>.view.setViewport([<span style="color: #666666">0</span>,<span style="color: #bbbbbb"> </span><span style="color: #666666">0</span>,<span style="color: #bbbbbb"> </span>width,<span style="color: #bbbbbb"> </span>height]);
<span style="color: #bbbbbb"> </span><span style="color: #008000; font-weight: bold">this</span>.camera.setProjectionFov(<span style="color: #666666">45</span>,<span style="color: #bbbbbb"> </span>width<span style="color: #bbbbbb"> </span><span style="color: #666666">/</span><span style="color: #bbbbbb"> </span>height,<span style="color: #bbbbbb"> </span><span style="color: #666666">1.0</span>,<span style="color: #bbbbbb"> </span><span style="color: #666666">10.0</span>,<span style="color: #bbbbbb"> </span>Fov.VERTICAL);
<span style="color: #bbbbbb"> </span>}
}
</pre></div>
<p>The above boilerplate should be familiar to you from the previous tutorial, although it loads in a
new set of assets. We also added some animation to the camera.</p>
<p>Next let&#x27;s create a material instance from the package that we built at the beginning the tutorial.
Replace the <strong>create material</strong> comment with the following snippet.</p>
<div class="highlight" style="background: #f8f8f8"><pre style="line-height: 125%;"><span></span><span style="color: #008000; font-weight: bold">const</span><span style="color: #bbbbbb"> </span>material<span style="color: #bbbbbb"> </span><span style="color: #666666">=</span><span style="color: #bbbbbb"> </span>engine.createMaterial(filamat_url);<span style="color: #bbbbbb"></span>
<span style="color: #008000; font-weight: bold">const</span><span style="color: #bbbbbb"> </span>matinstance<span style="color: #bbbbbb"> </span><span style="color: #666666">=</span><span style="color: #bbbbbb"> </span>material.createInstance();<span style="color: #bbbbbb"></span>
<div class="highlight" style="background: #f8f8f8"><pre style="line-height: 125%;"><span></span><span style="color: #008000; font-weight: bold">const</span><span style="color: #bbbbbb"> </span>material<span style="color: #bbbbbb"> </span><span style="color: #666666">=</span><span style="color: #bbbbbb"> </span>engine.createMaterial(filamat_url);
<span style="color: #008000; font-weight: bold">const</span><span style="color: #bbbbbb"> </span>matinstance<span style="color: #bbbbbb"> </span><span style="color: #666666">=</span><span style="color: #bbbbbb"> </span>material.createInstance();
<span style="color: #008000; font-weight: bold">const</span><span style="color: #bbbbbb"> </span>red<span style="color: #bbbbbb"> </span><span style="color: #666666">=</span><span style="color: #bbbbbb"> </span>[<span style="color: #666666">0.8</span>,<span style="color: #bbbbbb"> </span><span style="color: #666666">0.0</span>,<span style="color: #bbbbbb"> </span><span style="color: #666666">0.0</span>];<span style="color: #bbbbbb"></span>
matinstance.setColor3Parameter(<span style="color: #BA2121">&#39;baseColor&#39;</span>,<span style="color: #bbbbbb"> </span>Filament.RgbType.sRGB,<span style="color: #bbbbbb"> </span>red);<span style="color: #bbbbbb"></span>
matinstance.setFloatParameter(<span style="color: #BA2121">&#39;roughness&#39;</span>,<span style="color: #bbbbbb"> </span><span style="color: #666666">0.5</span>);<span style="color: #bbbbbb"></span>
matinstance.setFloatParameter(<span style="color: #BA2121">&#39;clearCoat&#39;</span>,<span style="color: #bbbbbb"> </span><span style="color: #666666">1.0</span>);<span style="color: #bbbbbb"></span>
matinstance.setFloatParameter(<span style="color: #BA2121">&#39;clearCoatRoughness&#39;</span>,<span style="color: #bbbbbb"> </span><span style="color: #666666">0.3</span>);<span style="color: #bbbbbb"></span>
<span style="color: #008000; font-weight: bold">const</span><span style="color: #bbbbbb"> </span>red<span style="color: #bbbbbb"> </span><span style="color: #666666">=</span><span style="color: #bbbbbb"> </span>[<span style="color: #666666">0.8</span>,<span style="color: #bbbbbb"> </span><span style="color: #666666">0.0</span>,<span style="color: #bbbbbb"> </span><span style="color: #666666">0.0</span>];
matinstance.setColor3Parameter(<span style="color: #BA2121">&#39;baseColor&#39;</span>,<span style="color: #bbbbbb"> </span>Filament.RgbType.sRGB,<span style="color: #bbbbbb"> </span>red);
matinstance.setFloatParameter(<span style="color: #BA2121">&#39;roughness&#39;</span>,<span style="color: #bbbbbb"> </span><span style="color: #666666">0.5</span>);
matinstance.setFloatParameter(<span style="color: #BA2121">&#39;clearCoat&#39;</span>,<span style="color: #bbbbbb"> </span><span style="color: #666666">1.0</span>);
matinstance.setFloatParameter(<span style="color: #BA2121">&#39;clearCoatRoughness&#39;</span>,<span style="color: #bbbbbb"> </span><span style="color: #666666">0.3</span>);
</pre></div>
<p>The next step is to create a renderable for the sphere. To help with this, we&#x27;ll use the <code>IcoSphere</code>
@@ -149,33 +149,33 @@ as quaternions.</li>
</ul>
<p>Let&#x27;s go ahead use these arrays to build the vertex buffer and index buffer. Replace <strong>create
sphere</strong> with the following snippet.</p>
<div class="highlight" style="background: #f8f8f8"><pre style="line-height: 125%;"><span></span><span style="color: #008000; font-weight: bold">const</span><span style="color: #bbbbbb"> </span>renderable<span style="color: #bbbbbb"> </span><span style="color: #666666">=</span><span style="color: #bbbbbb"> </span>Filament.EntityManager.get().create();<span style="color: #bbbbbb"></span>
scene.addEntity(renderable);<span style="color: #bbbbbb"></span>
<div class="highlight" style="background: #f8f8f8"><pre style="line-height: 125%;"><span></span><span style="color: #008000; font-weight: bold">const</span><span style="color: #bbbbbb"> </span>renderable<span style="color: #bbbbbb"> </span><span style="color: #666666">=</span><span style="color: #bbbbbb"> </span>Filament.EntityManager.get().create();
scene.addEntity(renderable);
<span style="color: #008000; font-weight: bold">const</span><span style="color: #bbbbbb"> </span>icosphere<span style="color: #bbbbbb"> </span><span style="color: #666666">=</span><span style="color: #bbbbbb"> </span><span style="color: #AA22FF; font-weight: bold">new</span><span style="color: #bbbbbb"> </span>Filament.IcoSphere(<span style="color: #666666">5</span>);<span style="color: #bbbbbb"></span>
<span style="color: #008000; font-weight: bold">const</span><span style="color: #bbbbbb"> </span>icosphere<span style="color: #bbbbbb"> </span><span style="color: #666666">=</span><span style="color: #bbbbbb"> </span><span style="color: #AA22FF; font-weight: bold">new</span><span style="color: #bbbbbb"> </span>Filament.IcoSphere(<span style="color: #666666">5</span>);
<span style="color: #008000; font-weight: bold">const</span><span style="color: #bbbbbb"> </span>vb<span style="color: #bbbbbb"> </span><span style="color: #666666">=</span><span style="color: #bbbbbb"> </span>Filament.VertexBuffer.Builder()<span style="color: #bbbbbb"></span>
<span style="color: #bbbbbb"> </span>.vertexCount(icosphere.vertices.length<span style="color: #bbbbbb"> </span><span style="color: #666666">/</span><span style="color: #bbbbbb"> </span><span style="color: #666666">3</span>)<span style="color: #bbbbbb"></span>
<span style="color: #bbbbbb"> </span>.bufferCount(<span style="color: #666666">2</span>)<span style="color: #bbbbbb"></span>
<span style="color: #bbbbbb"> </span>.attribute(VertexAttribute.POSITION,<span style="color: #bbbbbb"> </span><span style="color: #666666">0</span>,<span style="color: #bbbbbb"> </span>AttributeType.FLOAT3,<span style="color: #bbbbbb"> </span><span style="color: #666666">0</span>,<span style="color: #bbbbbb"> </span><span style="color: #666666">0</span>)<span style="color: #bbbbbb"></span>
<span style="color: #bbbbbb"> </span>.attribute(VertexAttribute.TANGENTS,<span style="color: #bbbbbb"> </span><span style="color: #666666">1</span>,<span style="color: #bbbbbb"> </span>AttributeType.SHORT4,<span style="color: #bbbbbb"> </span><span style="color: #666666">0</span>,<span style="color: #bbbbbb"> </span><span style="color: #666666">0</span>)<span style="color: #bbbbbb"></span>
<span style="color: #bbbbbb"> </span>.normalized(VertexAttribute.TANGENTS)<span style="color: #bbbbbb"></span>
<span style="color: #bbbbbb"> </span>.build(engine);<span style="color: #bbbbbb"></span>
<span style="color: #008000; font-weight: bold">const</span><span style="color: #bbbbbb"> </span>vb<span style="color: #bbbbbb"> </span><span style="color: #666666">=</span><span style="color: #bbbbbb"> </span>Filament.VertexBuffer.Builder()
<span style="color: #bbbbbb"> </span>.vertexCount(icosphere.vertices.length<span style="color: #bbbbbb"> </span><span style="color: #666666">/</span><span style="color: #bbbbbb"> </span><span style="color: #666666">3</span>)
<span style="color: #bbbbbb"> </span>.bufferCount(<span style="color: #666666">2</span>)
<span style="color: #bbbbbb"> </span>.attribute(VertexAttribute.POSITION,<span style="color: #bbbbbb"> </span><span style="color: #666666">0</span>,<span style="color: #bbbbbb"> </span>AttributeType.FLOAT3,<span style="color: #bbbbbb"> </span><span style="color: #666666">0</span>,<span style="color: #bbbbbb"> </span><span style="color: #666666">0</span>)
<span style="color: #bbbbbb"> </span>.attribute(VertexAttribute.TANGENTS,<span style="color: #bbbbbb"> </span><span style="color: #666666">1</span>,<span style="color: #bbbbbb"> </span>AttributeType.SHORT4,<span style="color: #bbbbbb"> </span><span style="color: #666666">0</span>,<span style="color: #bbbbbb"> </span><span style="color: #666666">0</span>)
<span style="color: #bbbbbb"> </span>.normalized(VertexAttribute.TANGENTS)
<span style="color: #bbbbbb"> </span>.build(engine);
<span style="color: #008000; font-weight: bold">const</span><span style="color: #bbbbbb"> </span>ib<span style="color: #bbbbbb"> </span><span style="color: #666666">=</span><span style="color: #bbbbbb"> </span>Filament.IndexBuffer.Builder()<span style="color: #bbbbbb"></span>
<span style="color: #bbbbbb"> </span>.indexCount(icosphere.triangles.length)<span style="color: #bbbbbb"></span>
<span style="color: #bbbbbb"> </span>.bufferType(IndexType.USHORT)<span style="color: #bbbbbb"></span>
<span style="color: #bbbbbb"> </span>.build(engine);<span style="color: #bbbbbb"></span>
<span style="color: #008000; font-weight: bold">const</span><span style="color: #bbbbbb"> </span>ib<span style="color: #bbbbbb"> </span><span style="color: #666666">=</span><span style="color: #bbbbbb"> </span>Filament.IndexBuffer.Builder()
<span style="color: #bbbbbb"> </span>.indexCount(icosphere.triangles.length)
<span style="color: #bbbbbb"> </span>.bufferType(IndexType.USHORT)
<span style="color: #bbbbbb"> </span>.build(engine);
vb.setBufferAt(engine,<span style="color: #bbbbbb"> </span><span style="color: #666666">0</span>,<span style="color: #bbbbbb"> </span>icosphere.vertices);<span style="color: #bbbbbb"></span>
vb.setBufferAt(engine,<span style="color: #bbbbbb"> </span><span style="color: #666666">1</span>,<span style="color: #bbbbbb"> </span>icosphere.tangents);<span style="color: #bbbbbb"></span>
ib.setBuffer(engine,<span style="color: #bbbbbb"> </span>icosphere.triangles);<span style="color: #bbbbbb"></span>
vb.setBufferAt(engine,<span style="color: #bbbbbb"> </span><span style="color: #666666">0</span>,<span style="color: #bbbbbb"> </span>icosphere.vertices);
vb.setBufferAt(engine,<span style="color: #bbbbbb"> </span><span style="color: #666666">1</span>,<span style="color: #bbbbbb"> </span>icosphere.tangents);
ib.setBuffer(engine,<span style="color: #bbbbbb"> </span>icosphere.triangles);
Filament.RenderableManager.Builder(<span style="color: #666666">1</span>)<span style="color: #bbbbbb"></span>
<span style="color: #bbbbbb"> </span>.boundingBox({<span style="color: #bbbbbb"> </span>center<span style="color: #666666">:</span><span style="color: #bbbbbb"> </span>[<span style="color: #666666">-1</span>,<span style="color: #bbbbbb"> </span><span style="color: #666666">-1</span>,<span style="color: #bbbbbb"> </span><span style="color: #666666">-1</span>],<span style="color: #bbbbbb"> </span>halfExtent<span style="color: #666666">:</span><span style="color: #bbbbbb"> </span>[<span style="color: #666666">1</span>,<span style="color: #bbbbbb"> </span><span style="color: #666666">1</span>,<span style="color: #bbbbbb"> </span><span style="color: #666666">1</span>]<span style="color: #bbbbbb"> </span>})<span style="color: #bbbbbb"></span>
<span style="color: #bbbbbb"> </span>.material(<span style="color: #666666">0</span>,<span style="color: #bbbbbb"> </span>matinstance)<span style="color: #bbbbbb"></span>
<span style="color: #bbbbbb"> </span>.geometry(<span style="color: #666666">0</span>,<span style="color: #bbbbbb"> </span>PrimitiveType.TRIANGLES,<span style="color: #bbbbbb"> </span>vb,<span style="color: #bbbbbb"> </span>ib)<span style="color: #bbbbbb"></span>
<span style="color: #bbbbbb"> </span>.build(engine,<span style="color: #bbbbbb"> </span>renderable);<span style="color: #bbbbbb"></span>
Filament.RenderableManager.Builder(<span style="color: #666666">1</span>)
<span style="color: #bbbbbb"> </span>.boundingBox({<span style="color: #bbbbbb"> </span>center<span style="color: #666666">:</span><span style="color: #bbbbbb"> </span>[<span style="color: #666666">-1</span>,<span style="color: #bbbbbb"> </span><span style="color: #666666">-1</span>,<span style="color: #bbbbbb"> </span><span style="color: #666666">-1</span>],<span style="color: #bbbbbb"> </span>halfExtent<span style="color: #666666">:</span><span style="color: #bbbbbb"> </span>[<span style="color: #666666">1</span>,<span style="color: #bbbbbb"> </span><span style="color: #666666">1</span>,<span style="color: #bbbbbb"> </span><span style="color: #666666">1</span>]<span style="color: #bbbbbb"> </span>})
<span style="color: #bbbbbb"> </span>.material(<span style="color: #666666">0</span>,<span style="color: #bbbbbb"> </span>matinstance)
<span style="color: #bbbbbb"> </span>.geometry(<span style="color: #666666">0</span>,<span style="color: #bbbbbb"> </span>PrimitiveType.TRIANGLES,<span style="color: #bbbbbb"> </span>vb,<span style="color: #bbbbbb"> </span>ib)
<span style="color: #bbbbbb"> </span>.build(engine,<span style="color: #bbbbbb"> </span>renderable);
</pre></div>
<p>At this point, the app is rendering a sphere, but it is black so it doesn&#x27;t show up. To prove that
@@ -185,94 +185,94 @@ did in the first tutorial.</p>
<p>In this section we will create some directional light sources, as well as an image-based light (IBL)
defined by one of the KTX files we built at the start of the demo. First, replace the <strong>create
lights</strong> comment with the following snippet.</p>
<div class="highlight" style="background: #f8f8f8"><pre style="line-height: 125%;"><span></span><span style="color: #008000; font-weight: bold">const</span><span style="color: #bbbbbb"> </span>sunlight<span style="color: #bbbbbb"> </span><span style="color: #666666">=</span><span style="color: #bbbbbb"> </span>Filament.EntityManager.get().create();<span style="color: #bbbbbb"></span>
scene.addEntity(sunlight);<span style="color: #bbbbbb"></span>
Filament.LightManager.Builder(LightType.SUN)<span style="color: #bbbbbb"></span>
<span style="color: #bbbbbb"> </span>.color([<span style="color: #666666">0.98</span>,<span style="color: #bbbbbb"> </span><span style="color: #666666">0.92</span>,<span style="color: #bbbbbb"> </span><span style="color: #666666">0.89</span>])<span style="color: #bbbbbb"></span>
<span style="color: #bbbbbb"> </span>.intensity(<span style="color: #666666">110000.0</span>)<span style="color: #bbbbbb"></span>
<span style="color: #bbbbbb"> </span>.direction([<span style="color: #666666">0.6</span>,<span style="color: #bbbbbb"> </span><span style="color: #666666">-1.0</span>,<span style="color: #bbbbbb"> </span><span style="color: #666666">-0.8</span>])<span style="color: #bbbbbb"></span>
<span style="color: #bbbbbb"> </span>.sunAngularRadius(<span style="color: #666666">1.9</span>)<span style="color: #bbbbbb"></span>
<span style="color: #bbbbbb"> </span>.sunHaloSize(<span style="color: #666666">10.0</span>)<span style="color: #bbbbbb"></span>
<span style="color: #bbbbbb"> </span>.sunHaloFalloff(<span style="color: #666666">80.0</span>)<span style="color: #bbbbbb"></span>
<span style="color: #bbbbbb"> </span>.build(engine,<span style="color: #bbbbbb"> </span>sunlight);<span style="color: #bbbbbb"></span>
<div class="highlight" style="background: #f8f8f8"><pre style="line-height: 125%;"><span></span><span style="color: #008000; font-weight: bold">const</span><span style="color: #bbbbbb"> </span>sunlight<span style="color: #bbbbbb"> </span><span style="color: #666666">=</span><span style="color: #bbbbbb"> </span>Filament.EntityManager.get().create();
scene.addEntity(sunlight);
Filament.LightManager.Builder(LightType.SUN)
<span style="color: #bbbbbb"> </span>.color([<span style="color: #666666">0.98</span>,<span style="color: #bbbbbb"> </span><span style="color: #666666">0.92</span>,<span style="color: #bbbbbb"> </span><span style="color: #666666">0.89</span>])
<span style="color: #bbbbbb"> </span>.intensity(<span style="color: #666666">110000.0</span>)
<span style="color: #bbbbbb"> </span>.direction([<span style="color: #666666">0.6</span>,<span style="color: #bbbbbb"> </span><span style="color: #666666">-1.0</span>,<span style="color: #bbbbbb"> </span><span style="color: #666666">-0.8</span>])
<span style="color: #bbbbbb"> </span>.sunAngularRadius(<span style="color: #666666">1.9</span>)
<span style="color: #bbbbbb"> </span>.sunHaloSize(<span style="color: #666666">10.0</span>)
<span style="color: #bbbbbb"> </span>.sunHaloFalloff(<span style="color: #666666">80.0</span>)
<span style="color: #bbbbbb"> </span>.build(engine,<span style="color: #bbbbbb"> </span>sunlight);
<span style="color: #008000; font-weight: bold">const</span><span style="color: #bbbbbb"> </span>backlight<span style="color: #bbbbbb"> </span><span style="color: #666666">=</span><span style="color: #bbbbbb"> </span>Filament.EntityManager.get().create();<span style="color: #bbbbbb"></span>
scene.addEntity(backlight);<span style="color: #bbbbbb"></span>
Filament.LightManager.Builder(LightType.DIRECTIONAL)<span style="color: #bbbbbb"></span>
<span style="color: #bbbbbb"> </span>.direction([<span style="color: #666666">-1</span>,<span style="color: #bbbbbb"> </span><span style="color: #666666">0</span>,<span style="color: #bbbbbb"> </span><span style="color: #666666">1</span>])<span style="color: #bbbbbb"></span>
<span style="color: #bbbbbb"> </span>.intensity(<span style="color: #666666">50000.0</span>)<span style="color: #bbbbbb"></span>
<span style="color: #bbbbbb"> </span>.build(engine,<span style="color: #bbbbbb"> </span>backlight);<span style="color: #bbbbbb"></span>
<span style="color: #008000; font-weight: bold">const</span><span style="color: #bbbbbb"> </span>backlight<span style="color: #bbbbbb"> </span><span style="color: #666666">=</span><span style="color: #bbbbbb"> </span>Filament.EntityManager.get().create();
scene.addEntity(backlight);
Filament.LightManager.Builder(LightType.DIRECTIONAL)
<span style="color: #bbbbbb"> </span>.direction([<span style="color: #666666">-1</span>,<span style="color: #bbbbbb"> </span><span style="color: #666666">0</span>,<span style="color: #bbbbbb"> </span><span style="color: #666666">1</span>])
<span style="color: #bbbbbb"> </span>.intensity(<span style="color: #666666">50000.0</span>)
<span style="color: #bbbbbb"> </span>.build(engine,<span style="color: #bbbbbb"> </span>backlight);
</pre></div>
<p>The <code>SUN</code> light source is similar to the <code>DIRECTIONAL</code> light source, but has some extra
parameters because Filament will automatically draw a disk into the skybox.</p>
<p>Next we need to create an <code>IndirectLight</code> object from the KTX IBL. One way of doing this is the
following (don&#x27;t type this out, there&#x27;s an easier way).</p>
<div class="highlight" style="background: #f8f8f8"><pre style="line-height: 125%;"><span></span><span style="color: #008000; font-weight: bold">const</span><span style="color: #bbbbbb"> </span>format<span style="color: #bbbbbb"> </span><span style="color: #666666">=</span><span style="color: #bbbbbb"> </span>Filament.PixelDataFormat.RGB;<span style="color: #bbbbbb"></span>
<span style="color: #008000; font-weight: bold">const</span><span style="color: #bbbbbb"> </span>datatype<span style="color: #bbbbbb"> </span><span style="color: #666666">=</span><span style="color: #bbbbbb"> </span>Filament.PixelDataType.UINT_10F_11F_11F_REV;<span style="color: #bbbbbb"></span>
<div class="highlight" style="background: #f8f8f8"><pre style="line-height: 125%;"><span></span><span style="color: #008000; font-weight: bold">const</span><span style="color: #bbbbbb"> </span>format<span style="color: #bbbbbb"> </span><span style="color: #666666">=</span><span style="color: #bbbbbb"> </span>Filament.PixelDataFormat.RGB;
<span style="color: #008000; font-weight: bold">const</span><span style="color: #bbbbbb"> </span>datatype<span style="color: #bbbbbb"> </span><span style="color: #666666">=</span><span style="color: #bbbbbb"> </span>Filament.PixelDataType.UINT_10F_11F_11F_REV;
<span style="color: #3D7B7B; font-style: italic">// Create a Texture object for the mipmapped cubemap.</span><span style="color: #bbbbbb"></span>
<span style="color: #008000; font-weight: bold">const</span><span style="color: #bbbbbb"> </span>ibl_package<span style="color: #bbbbbb"> </span><span style="color: #666666">=</span><span style="color: #bbbbbb"> </span>Filament.Buffer(Filament.assets[ibl_url]);<span style="color: #bbbbbb"></span>
<span style="color: #008000; font-weight: bold">const</span><span style="color: #bbbbbb"> </span>iblktx<span style="color: #bbbbbb"> </span><span style="color: #666666">=</span><span style="color: #bbbbbb"> </span><span style="color: #AA22FF; font-weight: bold">new</span><span style="color: #bbbbbb"> </span>Filament.Ktx1Bundle(ibl_package);<span style="color: #bbbbbb"></span>
<span style="color: #3D7B7B; font-style: italic">// Create a Texture object for the mipmapped cubemap.</span>
<span style="color: #008000; font-weight: bold">const</span><span style="color: #bbbbbb"> </span>ibl_package<span style="color: #bbbbbb"> </span><span style="color: #666666">=</span><span style="color: #bbbbbb"> </span>Filament.Buffer(Filament.assets[ibl_url]);
<span style="color: #008000; font-weight: bold">const</span><span style="color: #bbbbbb"> </span>iblktx<span style="color: #bbbbbb"> </span><span style="color: #666666">=</span><span style="color: #bbbbbb"> </span><span style="color: #AA22FF; font-weight: bold">new</span><span style="color: #bbbbbb"> </span>Filament.Ktx1Bundle(ibl_package);
<span style="color: #008000; font-weight: bold">const</span><span style="color: #bbbbbb"> </span>ibltex<span style="color: #bbbbbb"> </span><span style="color: #666666">=</span><span style="color: #bbbbbb"> </span>Filament.Texture.Builder()<span style="color: #bbbbbb"></span>
<span style="color: #bbbbbb"> </span>.width(iblktx.info().pixelWidth)<span style="color: #bbbbbb"></span>
<span style="color: #bbbbbb"> </span>.height(iblktx.info().pixelHeight)<span style="color: #bbbbbb"></span>
<span style="color: #bbbbbb"> </span>.levels(iblktx.getNumMipLevels())<span style="color: #bbbbbb"></span>
<span style="color: #bbbbbb"> </span>.sampler(Filament.Texture$Sampler.SAMPLER_CUBEMAP)<span style="color: #bbbbbb"></span>
<span style="color: #bbbbbb"> </span>.format(Filament.Texture$InternalFormat.RGBA8)<span style="color: #bbbbbb"></span>
<span style="color: #bbbbbb"> </span>.build(engine);<span style="color: #bbbbbb"></span>
<span style="color: #008000; font-weight: bold">const</span><span style="color: #bbbbbb"> </span>ibltex<span style="color: #bbbbbb"> </span><span style="color: #666666">=</span><span style="color: #bbbbbb"> </span>Filament.Texture.Builder()
<span style="color: #bbbbbb"> </span>.width(iblktx.info().pixelWidth)
<span style="color: #bbbbbb"> </span>.height(iblktx.info().pixelHeight)
<span style="color: #bbbbbb"> </span>.levels(iblktx.getNumMipLevels())
<span style="color: #bbbbbb"> </span>.sampler(Filament.Texture$Sampler.SAMPLER_CUBEMAP)
<span style="color: #bbbbbb"> </span>.format(Filament.Texture$InternalFormat.RGBA8)
<span style="color: #bbbbbb"> </span>.build(engine);
<span style="color: #008000; font-weight: bold">for</span><span style="color: #bbbbbb"> </span>(<span style="color: #008000; font-weight: bold">let</span><span style="color: #bbbbbb"> </span>level<span style="color: #bbbbbb"> </span><span style="color: #666666">=</span><span style="color: #bbbbbb"> </span><span style="color: #666666">0</span>;<span style="color: #bbbbbb"> </span>level<span style="color: #bbbbbb"> </span><span style="color: #666666">&lt;</span><span style="color: #bbbbbb"> </span>iblktx.getNumMipLevels();<span style="color: #bbbbbb"> </span><span style="color: #666666">++</span>level)<span style="color: #bbbbbb"> </span>{<span style="color: #bbbbbb"></span>
<span style="color: #bbbbbb"> </span><span style="color: #008000; font-weight: bold">const</span><span style="color: #bbbbbb"> </span>uint8array<span style="color: #bbbbbb"> </span><span style="color: #666666">=</span><span style="color: #bbbbbb"> </span>iblktx.getCubeBlob(level).getBytes();<span style="color: #bbbbbb"></span>
<span style="color: #bbbbbb"> </span><span style="color: #008000; font-weight: bold">const</span><span style="color: #bbbbbb"> </span>pixelbuffer<span style="color: #bbbbbb"> </span><span style="color: #666666">=</span><span style="color: #bbbbbb"> </span>Filament.PixelBuffer(uint8array,<span style="color: #bbbbbb"> </span>format,<span style="color: #bbbbbb"> </span>datatype);<span style="color: #bbbbbb"></span>
<span style="color: #bbbbbb"> </span>ibltex.setImageCube(engine,<span style="color: #bbbbbb"> </span>level,<span style="color: #bbbbbb"> </span>pixelbuffer);<span style="color: #bbbbbb"></span>
}<span style="color: #bbbbbb"></span>
<span style="color: #008000; font-weight: bold">for</span><span style="color: #bbbbbb"> </span>(<span style="color: #008000; font-weight: bold">let</span><span style="color: #bbbbbb"> </span>level<span style="color: #bbbbbb"> </span><span style="color: #666666">=</span><span style="color: #bbbbbb"> </span><span style="color: #666666">0</span>;<span style="color: #bbbbbb"> </span>level<span style="color: #bbbbbb"> </span><span style="color: #666666">&lt;</span><span style="color: #bbbbbb"> </span>iblktx.getNumMipLevels();<span style="color: #bbbbbb"> </span><span style="color: #666666">++</span>level)<span style="color: #bbbbbb"> </span>{
<span style="color: #bbbbbb"> </span><span style="color: #008000; font-weight: bold">const</span><span style="color: #bbbbbb"> </span>uint8array<span style="color: #bbbbbb"> </span><span style="color: #666666">=</span><span style="color: #bbbbbb"> </span>iblktx.getCubeBlob(level).getBytes();
<span style="color: #bbbbbb"> </span><span style="color: #008000; font-weight: bold">const</span><span style="color: #bbbbbb"> </span>pixelbuffer<span style="color: #bbbbbb"> </span><span style="color: #666666">=</span><span style="color: #bbbbbb"> </span>Filament.PixelBuffer(uint8array,<span style="color: #bbbbbb"> </span>format,<span style="color: #bbbbbb"> </span>datatype);
<span style="color: #bbbbbb"> </span>ibltex.setImageCube(engine,<span style="color: #bbbbbb"> </span>level,<span style="color: #bbbbbb"> </span>pixelbuffer);
}
<span style="color: #3D7B7B; font-style: italic">// Parse the spherical harmonics metadata.</span><span style="color: #bbbbbb"></span>
<span style="color: #008000; font-weight: bold">const</span><span style="color: #bbbbbb"> </span>shstring<span style="color: #bbbbbb"> </span><span style="color: #666666">=</span><span style="color: #bbbbbb"> </span>iblktx.getMetadata(<span style="color: #BA2121">&#39;sh&#39;</span>);<span style="color: #bbbbbb"></span>
<span style="color: #008000; font-weight: bold">const</span><span style="color: #bbbbbb"> </span>shfloats<span style="color: #bbbbbb"> </span><span style="color: #666666">=</span><span style="color: #bbbbbb"> </span>shstring.split(<span style="color: #A45A77">/\s/</span>,<span style="color: #bbbbbb"> </span><span style="color: #666666">9</span><span style="color: #bbbbbb"> </span><span style="color: #666666">*</span><span style="color: #bbbbbb"> </span><span style="color: #666666">3</span>).map(<span style="color: #008000">parseFloat</span>);<span style="color: #bbbbbb"></span>
<span style="color: #3D7B7B; font-style: italic">// Parse the spherical harmonics metadata.</span>
<span style="color: #008000; font-weight: bold">const</span><span style="color: #bbbbbb"> </span>shstring<span style="color: #bbbbbb"> </span><span style="color: #666666">=</span><span style="color: #bbbbbb"> </span>iblktx.getMetadata(<span style="color: #BA2121">&#39;sh&#39;</span>);
<span style="color: #008000; font-weight: bold">const</span><span style="color: #bbbbbb"> </span>shfloats<span style="color: #bbbbbb"> </span><span style="color: #666666">=</span><span style="color: #bbbbbb"> </span>shstring.split(<span style="color: #A45A77">/\s/</span>,<span style="color: #bbbbbb"> </span><span style="color: #666666">9</span><span style="color: #bbbbbb"> </span><span style="color: #666666">*</span><span style="color: #bbbbbb"> </span><span style="color: #666666">3</span>).map(<span style="color: #008000">parseFloat</span>);
<span style="color: #3D7B7B; font-style: italic">// Build the IBL object and insert it into the scene.</span><span style="color: #bbbbbb"></span>
<span style="color: #008000; font-weight: bold">const</span><span style="color: #bbbbbb"> </span>indirectLight<span style="color: #bbbbbb"> </span><span style="color: #666666">=</span><span style="color: #bbbbbb"> </span>Filament.IndirectLight.Builder()<span style="color: #bbbbbb"></span>
<span style="color: #bbbbbb"> </span>.reflections(ibltex)<span style="color: #bbbbbb"></span>
<span style="color: #bbbbbb"> </span>.irradianceSh(<span style="color: #666666">3</span>,<span style="color: #bbbbbb"> </span>shfloats)<span style="color: #bbbbbb"></span>
<span style="color: #bbbbbb"> </span>.intensity(<span style="color: #666666">50000.0</span>)<span style="color: #bbbbbb"></span>
<span style="color: #bbbbbb"> </span>.build(engine);<span style="color: #bbbbbb"></span>
<span style="color: #3D7B7B; font-style: italic">// Build the IBL object and insert it into the scene.</span>
<span style="color: #008000; font-weight: bold">const</span><span style="color: #bbbbbb"> </span>indirectLight<span style="color: #bbbbbb"> </span><span style="color: #666666">=</span><span style="color: #bbbbbb"> </span>Filament.IndirectLight.Builder()
<span style="color: #bbbbbb"> </span>.reflections(ibltex)
<span style="color: #bbbbbb"> </span>.irradianceSh(<span style="color: #666666">3</span>,<span style="color: #bbbbbb"> </span>shfloats)
<span style="color: #bbbbbb"> </span>.intensity(<span style="color: #666666">50000.0</span>)
<span style="color: #bbbbbb"> </span>.build(engine);
scene.setIndirectLight(indirectLight);<span style="color: #bbbbbb"></span>
scene.setIndirectLight(indirectLight);
</pre></div>
<p>Filament provides a JavaScript utility to make this simpler,
simply replace the <strong>create IBL</strong> comment with the following snippet.</p>
<div class="highlight" style="background: #f8f8f8"><pre style="line-height: 125%;"><span></span><span style="color: #008000; font-weight: bold">const</span><span style="color: #bbbbbb"> </span>indirectLight<span style="color: #bbbbbb"> </span><span style="color: #666666">=</span><span style="color: #bbbbbb"> </span>engine.createIblFromKtx1(ibl_url);<span style="color: #bbbbbb"></span>
indirectLight.setIntensity(<span style="color: #666666">50000</span>);<span style="color: #bbbbbb"></span>
scene.setIndirectLight(indirectLight);<span style="color: #bbbbbb"></span>
<div class="highlight" style="background: #f8f8f8"><pre style="line-height: 125%;"><span></span><span style="color: #008000; font-weight: bold">const</span><span style="color: #bbbbbb"> </span>indirectLight<span style="color: #bbbbbb"> </span><span style="color: #666666">=</span><span style="color: #bbbbbb"> </span>engine.createIblFromKtx1(ibl_url);
indirectLight.setIntensity(<span style="color: #666666">50000</span>);
scene.setIndirectLight(indirectLight);
</pre></div>
<h2>Add background</h2>
<p>At this point you can run the demo and you should see a red plastic ball against a black background.
Without a skybox, the reflections on the ball are not representative of its surroundings.
Here&#x27;s one way to create a texture for the skybox:</p>
<div class="highlight" style="background: #f8f8f8"><pre style="line-height: 125%;"><span></span><span style="color: #008000; font-weight: bold">const</span><span style="color: #bbbbbb"> </span>sky_package<span style="color: #bbbbbb"> </span><span style="color: #666666">=</span><span style="color: #bbbbbb"> </span>Filament.Buffer(Filament.assets[sky_url]);<span style="color: #bbbbbb"></span>
<span style="color: #008000; font-weight: bold">const</span><span style="color: #bbbbbb"> </span>skyktx<span style="color: #bbbbbb"> </span><span style="color: #666666">=</span><span style="color: #bbbbbb"> </span><span style="color: #AA22FF; font-weight: bold">new</span><span style="color: #bbbbbb"> </span>Filament.Ktx1Bundle(sky_package);<span style="color: #bbbbbb"></span>
<span style="color: #008000; font-weight: bold">const</span><span style="color: #bbbbbb"> </span>skytex<span style="color: #bbbbbb"> </span><span style="color: #666666">=</span><span style="color: #bbbbbb"> </span>Filament.Texture.Builder()<span style="color: #bbbbbb"></span>
<span style="color: #bbbbbb"> </span>.width(skyktx.info().pixelWidth)<span style="color: #bbbbbb"></span>
<span style="color: #bbbbbb"> </span>.height(skyktx.info().pixelHeight)<span style="color: #bbbbbb"></span>
<span style="color: #bbbbbb"> </span>.levels(<span style="color: #666666">1</span>)<span style="color: #bbbbbb"></span>
<span style="color: #bbbbbb"> </span>.sampler(Filament.Texture$Sampler.SAMPLER_CUBEMAP)<span style="color: #bbbbbb"></span>
<span style="color: #bbbbbb"> </span>.format(Filament.Texture$InternalFormat.RGBA8)<span style="color: #bbbbbb"></span>
<span style="color: #bbbbbb"> </span>.build(engine);<span style="color: #bbbbbb"></span>
<div class="highlight" style="background: #f8f8f8"><pre style="line-height: 125%;"><span></span><span style="color: #008000; font-weight: bold">const</span><span style="color: #bbbbbb"> </span>sky_package<span style="color: #bbbbbb"> </span><span style="color: #666666">=</span><span style="color: #bbbbbb"> </span>Filament.Buffer(Filament.assets[sky_url]);
<span style="color: #008000; font-weight: bold">const</span><span style="color: #bbbbbb"> </span>skyktx<span style="color: #bbbbbb"> </span><span style="color: #666666">=</span><span style="color: #bbbbbb"> </span><span style="color: #AA22FF; font-weight: bold">new</span><span style="color: #bbbbbb"> </span>Filament.Ktx1Bundle(sky_package);
<span style="color: #008000; font-weight: bold">const</span><span style="color: #bbbbbb"> </span>skytex<span style="color: #bbbbbb"> </span><span style="color: #666666">=</span><span style="color: #bbbbbb"> </span>Filament.Texture.Builder()
<span style="color: #bbbbbb"> </span>.width(skyktx.info().pixelWidth)
<span style="color: #bbbbbb"> </span>.height(skyktx.info().pixelHeight)
<span style="color: #bbbbbb"> </span>.levels(<span style="color: #666666">1</span>)
<span style="color: #bbbbbb"> </span>.sampler(Filament.Texture$Sampler.SAMPLER_CUBEMAP)
<span style="color: #bbbbbb"> </span>.format(Filament.Texture$InternalFormat.RGBA8)
<span style="color: #bbbbbb"> </span>.build(engine);
<span style="color: #008000; font-weight: bold">const</span><span style="color: #bbbbbb"> </span>uint8array<span style="color: #bbbbbb"> </span><span style="color: #666666">=</span><span style="color: #bbbbbb"> </span>skyktx.getCubeBlob(<span style="color: #666666">0</span>).getBytes();<span style="color: #bbbbbb"></span>
<span style="color: #008000; font-weight: bold">const</span><span style="color: #bbbbbb"> </span>pixelbuffer<span style="color: #bbbbbb"> </span><span style="color: #666666">=</span><span style="color: #bbbbbb"> </span>Filament.PixelBuffer(uint8array,<span style="color: #bbbbbb"> </span>format,<span style="color: #bbbbbb"> </span>datatype);<span style="color: #bbbbbb"></span>
skytex.setImageCube(engine,<span style="color: #bbbbbb"> </span><span style="color: #666666">0</span>,<span style="color: #bbbbbb"> </span>pixelbuffer);<span style="color: #bbbbbb"></span>
<span style="color: #008000; font-weight: bold">const</span><span style="color: #bbbbbb"> </span>uint8array<span style="color: #bbbbbb"> </span><span style="color: #666666">=</span><span style="color: #bbbbbb"> </span>skyktx.getCubeBlob(<span style="color: #666666">0</span>).getBytes();
<span style="color: #008000; font-weight: bold">const</span><span style="color: #bbbbbb"> </span>pixelbuffer<span style="color: #bbbbbb"> </span><span style="color: #666666">=</span><span style="color: #bbbbbb"> </span>Filament.PixelBuffer(uint8array,<span style="color: #bbbbbb"> </span>format,<span style="color: #bbbbbb"> </span>datatype);
skytex.setImageCube(engine,<span style="color: #bbbbbb"> </span><span style="color: #666666">0</span>,<span style="color: #bbbbbb"> </span>pixelbuffer);
</pre></div>
<p>Filament provides a Javascript utility to make this easier.
Replace <strong>create skybox</strong> with the following.</p>
<div class="highlight" style="background: #f8f8f8"><pre style="line-height: 125%;"><span></span><span style="color: #008000; font-weight: bold">const</span><span style="color: #bbbbbb"> </span>skybox<span style="color: #bbbbbb"> </span><span style="color: #666666">=</span><span style="color: #bbbbbb"> </span>engine.createSkyFromKtx1(sky_url);<span style="color: #bbbbbb"></span>
scene.setSkybox(skybox);<span style="color: #bbbbbb"></span>
<div class="highlight" style="background: #f8f8f8"><pre style="line-height: 125%;"><span></span><span style="color: #008000; font-weight: bold">const</span><span style="color: #bbbbbb"> </span>skybox<span style="color: #bbbbbb"> </span><span style="color: #666666">=</span><span style="color: #bbbbbb"> </span>engine.createSkyFromKtx1(sky_url);
scene.setSkybox(skybox);
</pre></div>
<p>That&#x27;s it, we now have a shiny red ball floating in an environment! The complete JavaScript file is
+108 -108
View File
@@ -15,7 +15,7 @@ we&#x27;ll also be using <code>filamesh</code> and <code>mipgen</code>.</p>
<p>Filament does not have an asset loading system, but it does provide a binary mesh format
called <code>filamesh</code> for simple use cases. Let&#x27;s create a compressed filamesh file for suzanne by
converting <a href="https://github.com/google/filament/blob/main/assets/models/monkey/monkey.obj">this OBJ file</a>:</p>
<div class="highlight" style="background: #f8f8f8"><pre style="line-height: 125%;"><span></span>filamesh --compress monkey.obj suzanne.filamesh
<div class="highlight" style="background: #f8f8f8"><pre style="line-height: 125%;"><span></span>filamesh<span style="color: #bbbbbb"> </span>--compress<span style="color: #bbbbbb"> </span>monkey.obj<span style="color: #bbbbbb"> </span>suzanne.filamesh
</pre></div>
<h2>Create mipmapped textures</h2>
@@ -23,26 +23,26 @@ converting <a href="https://github.com/google/filament/blob/main/assets/models/m
non-compressed variants for each texture, since not all platforms support the same compression
formats. First copy over the PNG files from the <a href="https://github.com/google/filament/blob/main/assets/models/monkey">monkey folder</a>, then do:</p>
<div class="highlight" style="background: #f8f8f8"><pre style="line-height: 125%;"><span></span><span style="color: #3D7B7B; font-style: italic"># Create mipmaps for base color and two compressed variants.</span>
mipgen albedo.png albedo.ktx
mipgen --compression<span style="color: #666666">=</span>astc_fast_ldr_4x4 albedo.png albedo_astc.ktx
mipgen --compression<span style="color: #666666">=</span>s3tc_rgb_dxt1 albedo.png albedo_s3tc_srgb.ktx
mipgen<span style="color: #bbbbbb"> </span>albedo.png<span style="color: #bbbbbb"> </span>albedo.ktx
mipgen<span style="color: #bbbbbb"> </span>--compression<span style="color: #666666">=</span>astc_fast_ldr_4x4<span style="color: #bbbbbb"> </span>albedo.png<span style="color: #bbbbbb"> </span>albedo_astc.ktx
mipgen<span style="color: #bbbbbb"> </span>--compression<span style="color: #666666">=</span>s3tc_rgb_dxt1<span style="color: #bbbbbb"> </span>albedo.png<span style="color: #bbbbbb"> </span>albedo_s3tc_srgb.ktx
<span style="color: #3D7B7B; font-style: italic"># Create mipmaps for the normal map and a compressed variant.</span>
mipgen --strip-alpha --kernel<span style="color: #666666">=</span>NORMALS --linear normal.png normal.ktx
mipgen --strip-alpha --kernel<span style="color: #666666">=</span>NORMALS --linear --compression<span style="color: #666666">=</span>etc_rgb8_normalxyz_40 <span style="color: #AA5D1F; font-weight: bold">\</span>
normal.png normal_etc.ktx
mipgen<span style="color: #bbbbbb"> </span>--strip-alpha<span style="color: #bbbbbb"> </span>--kernel<span style="color: #666666">=</span>NORMALS<span style="color: #bbbbbb"> </span>--linear<span style="color: #bbbbbb"> </span>normal.png<span style="color: #bbbbbb"> </span>normal.ktx
mipgen<span style="color: #bbbbbb"> </span>--strip-alpha<span style="color: #bbbbbb"> </span>--kernel<span style="color: #666666">=</span>NORMALS<span style="color: #bbbbbb"> </span>--linear<span style="color: #bbbbbb"> </span>--compression<span style="color: #666666">=</span>etc_rgb8_normalxyz_40<span style="color: #bbbbbb"> </span><span style="color: #AA5D1F; font-weight: bold">\</span>
<span style="color: #bbbbbb"> </span>normal.png<span style="color: #bbbbbb"> </span>normal_etc.ktx
<span style="color: #3D7B7B; font-style: italic"># Create mipmaps for the single-component roughness map and a compressed variant.</span>
mipgen --grayscale roughness.png roughness.ktx
mipgen --grayscale --compression<span style="color: #666666">=</span>etc_r11_numeric_40 roughness.png roughness_etc.ktx
mipgen<span style="color: #bbbbbb"> </span>--grayscale<span style="color: #bbbbbb"> </span>roughness.png<span style="color: #bbbbbb"> </span>roughness.ktx
mipgen<span style="color: #bbbbbb"> </span>--grayscale<span style="color: #bbbbbb"> </span>--compression<span style="color: #666666">=</span>etc_r11_numeric_40<span style="color: #bbbbbb"> </span>roughness.png<span style="color: #bbbbbb"> </span>roughness_etc.ktx
<span style="color: #3D7B7B; font-style: italic"># Create mipmaps for the single-component metallic map and a compressed variant.</span>
mipgen --grayscale metallic.png metallic.ktx
mipgen --grayscale --compression<span style="color: #666666">=</span>etc_r11_numeric_40 metallic.png metallic_etc.ktx
mipgen<span style="color: #bbbbbb"> </span>--grayscale<span style="color: #bbbbbb"> </span>metallic.png<span style="color: #bbbbbb"> </span>metallic.ktx
mipgen<span style="color: #bbbbbb"> </span>--grayscale<span style="color: #bbbbbb"> </span>--compression<span style="color: #666666">=</span>etc_r11_numeric_40<span style="color: #bbbbbb"> </span>metallic.png<span style="color: #bbbbbb"> </span>metallic_etc.ktx
<span style="color: #3D7B7B; font-style: italic"># Create mipmaps for the single-component occlusion map and a compressed variant.</span>
mipgen --grayscale ao.png ao.ktx
mipgen --grayscale --compression<span style="color: #666666">=</span>etc_r11_numeric_40 ao.png ao_etc.ktx
mipgen<span style="color: #bbbbbb"> </span>--grayscale<span style="color: #bbbbbb"> </span>ao.png<span style="color: #bbbbbb"> </span>ao.ktx
mipgen<span style="color: #bbbbbb"> </span>--grayscale<span style="color: #bbbbbb"> </span>--compression<span style="color: #666666">=</span>etc_r11_numeric_40<span style="color: #bbbbbb"> </span>ao.png<span style="color: #bbbbbb"> </span>ao_etc.ktx
</pre></div>
<p>For more information on mipgen&#x27;s arguments and supported formats, do <code>mipgen --help</code>.</p>
@@ -50,12 +50,12 @@ mipgen --grayscale --compression<span style="color: #666666">=</span>etc_r11_num
<h2>Bake environment map</h2>
<p>Much like the <a href="tutorial_redball.html">previous tutorial</a> we need to use Filament&#x27;s <code>cmgen</code> tool to produce cubemap files.</p>
<p>Download <a href="//github.com/google/filament/blob/main/third_party/environments/venetian_crossroads_2k.hdr">venetian_crossroads_2k.hdr</a>, then invoke the following commands in your terminal.</p>
<div class="highlight" style="background: #f8f8f8"><pre style="line-height: 125%;"><span></span>cmgen -x . --format<span style="color: #666666">=</span>ktx --size<span style="color: #666666">=64</span> --extract-blur<span style="color: #666666">=0</span>.1 venetian_crossroads_2k.hdr
<span style="color: #008000">cd</span> venetian* ; mv venetian*_ibl.ktx venetian_crossroads_2k_skybox_tiny.ktx ; <span style="color: #008000">cd</span> -
<div class="highlight" style="background: #f8f8f8"><pre style="line-height: 125%;"><span></span>cmgen<span style="color: #bbbbbb"> </span>-x<span style="color: #bbbbbb"> </span>.<span style="color: #bbbbbb"> </span>--format<span style="color: #666666">=</span>ktx<span style="color: #bbbbbb"> </span>--size<span style="color: #666666">=64</span><span style="color: #bbbbbb"> </span>--extract-blur<span style="color: #666666">=0</span>.1<span style="color: #bbbbbb"> </span>venetian_crossroads_2k.hdr
<span style="color: #008000">cd</span><span style="color: #bbbbbb"> </span>venetian*<span style="color: #bbbbbb"> </span>;<span style="color: #bbbbbb"> </span>mv<span style="color: #bbbbbb"> </span>venetian*_ibl.ktx<span style="color: #bbbbbb"> </span>venetian_crossroads_2k_skybox_tiny.ktx<span style="color: #bbbbbb"> </span>;<span style="color: #bbbbbb"> </span><span style="color: #008000">cd</span><span style="color: #bbbbbb"> </span>-
cmgen -x . --format<span style="color: #666666">=</span>ktx --size<span style="color: #666666">=256</span> --extract-blur<span style="color: #666666">=0</span>.1 venetian_crossroads_2k.hdr
cmgen -x . --format<span style="color: #666666">=</span>ktx --size<span style="color: #666666">=256</span> --extract-blur<span style="color: #666666">=0</span>.1 venetian_crossroads_2k.hdr
cmgen -x . --format<span style="color: #666666">=</span>ktx --size<span style="color: #666666">=256</span> --extract-blur<span style="color: #666666">=0</span>.1 venetian_crossroads_2k.hdr
cmgen<span style="color: #bbbbbb"> </span>-x<span style="color: #bbbbbb"> </span>.<span style="color: #bbbbbb"> </span>--format<span style="color: #666666">=</span>ktx<span style="color: #bbbbbb"> </span>--size<span style="color: #666666">=256</span><span style="color: #bbbbbb"> </span>--extract-blur<span style="color: #666666">=0</span>.1<span style="color: #bbbbbb"> </span>venetian_crossroads_2k.hdr
cmgen<span style="color: #bbbbbb"> </span>-x<span style="color: #bbbbbb"> </span>.<span style="color: #bbbbbb"> </span>--format<span style="color: #666666">=</span>ktx<span style="color: #bbbbbb"> </span>--size<span style="color: #666666">=256</span><span style="color: #bbbbbb"> </span>--extract-blur<span style="color: #666666">=0</span>.1<span style="color: #bbbbbb"> </span>venetian_crossroads_2k.hdr
cmgen<span style="color: #bbbbbb"> </span>-x<span style="color: #bbbbbb"> </span>.<span style="color: #bbbbbb"> </span>--format<span style="color: #666666">=</span>ktx<span style="color: #bbbbbb"> </span>--size<span style="color: #666666">=256</span><span style="color: #bbbbbb"> </span>--extract-blur<span style="color: #666666">=0</span>.1<span style="color: #bbbbbb"> </span>venetian_crossroads_2k.hdr
</pre></div>
<h2>Define textured material</h2>
@@ -91,7 +91,7 @@ fragment {
</pre></div>
<p>Next, invoke <code>matc</code> as follows.</p>
<div class="highlight" style="background: #f8f8f8"><pre style="line-height: 125%;"><span></span>matc -a opengl -p mobile -o textured.filamat textured.mat
<div class="highlight" style="background: #f8f8f8"><pre style="line-height: 125%;"><span></span>matc<span style="color: #bbbbbb"> </span>-a<span style="color: #bbbbbb"> </span>opengl<span style="color: #bbbbbb"> </span>-p<span style="color: #bbbbbb"> </span>mobile<span style="color: #bbbbbb"> </span>-o<span style="color: #bbbbbb"> </span>textured.filamat<span style="color: #bbbbbb"> </span>textured.mat
</pre></div>
<p>You should now have a material archive in your working directory. For the suzanne asset, the normal
@@ -101,62 +101,62 @@ materials, consult the official document describing the <a href="https://google.
<p>Create a text file called <code>suzanne.html</code> and copy over the HTML that we used in the <a href="tutorial_redball.html">previous
tutorial</a>. Change the last script tag from <code>redball.js</code> to <code>suzanne.js</code>. Next, create <code>suzanne.js</code>
with the following content.</p>
<div class="highlight" style="background: #f8f8f8"><pre style="line-height: 125%;"><span></span><span style="color: #3D7B7B; font-style: italic">// TODO: declare asset URLs</span><span style="color: #bbbbbb"></span>
<div class="highlight" style="background: #f8f8f8"><pre style="line-height: 125%;"><span></span><span style="color: #3D7B7B; font-style: italic">// TODO: declare asset URLs</span>
Filament.init([<span style="color: #bbbbbb"> </span>filamat_url,<span style="color: #bbbbbb"> </span>filamesh_url,<span style="color: #bbbbbb"> </span>sky_small_url,<span style="color: #bbbbbb"> </span>ibl_url<span style="color: #bbbbbb"> </span>],<span style="color: #bbbbbb"> </span>()<span style="color: #bbbbbb"> </span>=&gt;<span style="color: #bbbbbb"> </span>{<span style="color: #bbbbbb"></span>
<span style="color: #bbbbbb"> </span><span style="color: #008000">window</span>.app<span style="color: #bbbbbb"> </span><span style="color: #666666">=</span><span style="color: #bbbbbb"> </span><span style="color: #AA22FF; font-weight: bold">new</span><span style="color: #bbbbbb"> </span>App(<span style="color: #008000">document</span>.getElementsByTagName(<span style="color: #BA2121">&#39;canvas&#39;</span>)[<span style="color: #666666">0</span>]);<span style="color: #bbbbbb"></span>
});<span style="color: #bbbbbb"></span>
Filament.init([<span style="color: #bbbbbb"> </span>filamat_url,<span style="color: #bbbbbb"> </span>filamesh_url,<span style="color: #bbbbbb"> </span>sky_small_url,<span style="color: #bbbbbb"> </span>ibl_url<span style="color: #bbbbbb"> </span>],<span style="color: #bbbbbb"> </span>()<span style="color: #bbbbbb"> </span>=&gt;<span style="color: #bbbbbb"> </span>{
<span style="color: #bbbbbb"> </span><span style="color: #008000">window</span>.app<span style="color: #bbbbbb"> </span><span style="color: #666666">=</span><span style="color: #bbbbbb"> </span><span style="color: #AA22FF; font-weight: bold">new</span><span style="color: #bbbbbb"> </span>App(<span style="color: #008000">document</span>.getElementsByTagName(<span style="color: #BA2121">&#39;canvas&#39;</span>)[<span style="color: #666666">0</span>]);
});
<span style="color: #008000; font-weight: bold">class</span><span style="color: #bbbbbb"> </span>App<span style="color: #bbbbbb"> </span>{<span style="color: #bbbbbb"></span>
<span style="color: #bbbbbb"> </span><span style="color: #008000; font-weight: bold">constructor</span>(canvas)<span style="color: #bbbbbb"> </span>{<span style="color: #bbbbbb"></span>
<span style="color: #bbbbbb"> </span><span style="color: #008000; font-weight: bold">this</span>.canvas<span style="color: #bbbbbb"> </span><span style="color: #666666">=</span><span style="color: #bbbbbb"> </span>canvas;<span style="color: #bbbbbb"></span>
<span style="color: #bbbbbb"> </span><span style="color: #008000; font-weight: bold">this</span>.engine<span style="color: #bbbbbb"> </span><span style="color: #666666">=</span><span style="color: #bbbbbb"> </span>Filament.Engine.create(canvas);<span style="color: #bbbbbb"></span>
<span style="color: #bbbbbb"> </span><span style="color: #008000; font-weight: bold">this</span>.scene<span style="color: #bbbbbb"> </span><span style="color: #666666">=</span><span style="color: #bbbbbb"> </span><span style="color: #008000; font-weight: bold">this</span>.engine.createScene();<span style="color: #bbbbbb"></span>
<span style="color: #008000; font-weight: bold">class</span><span style="color: #bbbbbb"> </span>App<span style="color: #bbbbbb"> </span>{
<span style="color: #bbbbbb"> </span><span style="color: #008000; font-weight: bold">constructor</span>(canvas)<span style="color: #bbbbbb"> </span>{
<span style="color: #bbbbbb"> </span><span style="color: #008000; font-weight: bold">this</span>.canvas<span style="color: #bbbbbb"> </span><span style="color: #666666">=</span><span style="color: #bbbbbb"> </span>canvas;
<span style="color: #bbbbbb"> </span><span style="color: #008000; font-weight: bold">this</span>.engine<span style="color: #bbbbbb"> </span><span style="color: #666666">=</span><span style="color: #bbbbbb"> </span>Filament.Engine.create(canvas);
<span style="color: #bbbbbb"> </span><span style="color: #008000; font-weight: bold">this</span>.scene<span style="color: #bbbbbb"> </span><span style="color: #666666">=</span><span style="color: #bbbbbb"> </span><span style="color: #008000; font-weight: bold">this</span>.engine.createScene();
<span style="color: #bbbbbb"> </span><span style="color: #008000; font-weight: bold">const</span><span style="color: #bbbbbb"> </span>material<span style="color: #bbbbbb"> </span><span style="color: #666666">=</span><span style="color: #bbbbbb"> </span><span style="color: #008000; font-weight: bold">this</span>.engine.createMaterial(filamat_url);<span style="color: #bbbbbb"></span>
<span style="color: #bbbbbb"> </span><span style="color: #008000; font-weight: bold">this</span>.matinstance<span style="color: #bbbbbb"> </span><span style="color: #666666">=</span><span style="color: #bbbbbb"> </span>material.createInstance();<span style="color: #bbbbbb"></span>
<span style="color: #bbbbbb"> </span><span style="color: #008000; font-weight: bold">const</span><span style="color: #bbbbbb"> </span>material<span style="color: #bbbbbb"> </span><span style="color: #666666">=</span><span style="color: #bbbbbb"> </span><span style="color: #008000; font-weight: bold">this</span>.engine.createMaterial(filamat_url);
<span style="color: #bbbbbb"> </span><span style="color: #008000; font-weight: bold">this</span>.matinstance<span style="color: #bbbbbb"> </span><span style="color: #666666">=</span><span style="color: #bbbbbb"> </span>material.createInstance();
<span style="color: #bbbbbb"> </span><span style="color: #008000; font-weight: bold">const</span><span style="color: #bbbbbb"> </span>filamesh<span style="color: #bbbbbb"> </span><span style="color: #666666">=</span><span style="color: #bbbbbb"> </span><span style="color: #008000; font-weight: bold">this</span>.engine.loadFilamesh(filamesh_url,<span style="color: #bbbbbb"> </span><span style="color: #008000; font-weight: bold">this</span>.matinstance);<span style="color: #bbbbbb"></span>
<span style="color: #bbbbbb"> </span><span style="color: #008000; font-weight: bold">this</span>.suzanne<span style="color: #bbbbbb"> </span><span style="color: #666666">=</span><span style="color: #bbbbbb"> </span>filamesh.renderable;<span style="color: #bbbbbb"></span>
<span style="color: #bbbbbb"> </span><span style="color: #008000; font-weight: bold">const</span><span style="color: #bbbbbb"> </span>filamesh<span style="color: #bbbbbb"> </span><span style="color: #666666">=</span><span style="color: #bbbbbb"> </span><span style="color: #008000; font-weight: bold">this</span>.engine.loadFilamesh(filamesh_url,<span style="color: #bbbbbb"> </span><span style="color: #008000; font-weight: bold">this</span>.matinstance);
<span style="color: #bbbbbb"> </span><span style="color: #008000; font-weight: bold">this</span>.suzanne<span style="color: #bbbbbb"> </span><span style="color: #666666">=</span><span style="color: #bbbbbb"> </span>filamesh.renderable;
<span style="color: #bbbbbb"> </span><span style="color: #3D7B7B; font-style: italic">// TODO: create sky box and IBL</span><span style="color: #bbbbbb"></span>
<span style="color: #bbbbbb"> </span><span style="color: #3D7B7B; font-style: italic">// TODO: initialize gltumble</span><span style="color: #bbbbbb"></span>
<span style="color: #bbbbbb"> </span><span style="color: #3D7B7B; font-style: italic">// TODO: fetch larger assets</span><span style="color: #bbbbbb"></span>
<span style="color: #bbbbbb"> </span><span style="color: #3D7B7B; font-style: italic">// TODO: create sky box and IBL</span>
<span style="color: #bbbbbb"> </span><span style="color: #3D7B7B; font-style: italic">// TODO: initialize gltumble</span>
<span style="color: #bbbbbb"> </span><span style="color: #3D7B7B; font-style: italic">// TODO: fetch larger assets</span>
<span style="color: #bbbbbb"> </span><span style="color: #008000; font-weight: bold">this</span>.swapChain<span style="color: #bbbbbb"> </span><span style="color: #666666">=</span><span style="color: #bbbbbb"> </span><span style="color: #008000; font-weight: bold">this</span>.engine.createSwapChain();<span style="color: #bbbbbb"></span>
<span style="color: #bbbbbb"> </span><span style="color: #008000; font-weight: bold">this</span>.renderer<span style="color: #bbbbbb"> </span><span style="color: #666666">=</span><span style="color: #bbbbbb"> </span><span style="color: #008000; font-weight: bold">this</span>.engine.createRenderer();<span style="color: #bbbbbb"></span>
<span style="color: #bbbbbb"> </span><span style="color: #008000; font-weight: bold">this</span>.camera<span style="color: #bbbbbb"> </span><span style="color: #666666">=</span><span style="color: #bbbbbb"> </span><span style="color: #008000; font-weight: bold">this</span>.engine.createCamera(Filament.EntityManager.get().create());<span style="color: #bbbbbb"></span>
<span style="color: #bbbbbb"> </span><span style="color: #008000; font-weight: bold">this</span>.view<span style="color: #bbbbbb"> </span><span style="color: #666666">=</span><span style="color: #bbbbbb"> </span><span style="color: #008000; font-weight: bold">this</span>.engine.createView();<span style="color: #bbbbbb"></span>
<span style="color: #bbbbbb"> </span><span style="color: #008000; font-weight: bold">this</span>.view.setCamera(<span style="color: #008000; font-weight: bold">this</span>.camera);<span style="color: #bbbbbb"></span>
<span style="color: #bbbbbb"> </span><span style="color: #008000; font-weight: bold">this</span>.view.setScene(<span style="color: #008000; font-weight: bold">this</span>.scene);<span style="color: #bbbbbb"></span>
<span style="color: #bbbbbb"> </span><span style="color: #008000; font-weight: bold">this</span>.render<span style="color: #bbbbbb"> </span><span style="color: #666666">=</span><span style="color: #bbbbbb"> </span><span style="color: #008000; font-weight: bold">this</span>.render.bind(<span style="color: #008000; font-weight: bold">this</span>);<span style="color: #bbbbbb"></span>
<span style="color: #bbbbbb"> </span><span style="color: #008000; font-weight: bold">this</span>.resize<span style="color: #bbbbbb"> </span><span style="color: #666666">=</span><span style="color: #bbbbbb"> </span><span style="color: #008000; font-weight: bold">this</span>.resize.bind(<span style="color: #008000; font-weight: bold">this</span>);<span style="color: #bbbbbb"></span>
<span style="color: #bbbbbb"> </span><span style="color: #008000">window</span>.addEventListener(<span style="color: #BA2121">&#39;resize&#39;</span>,<span style="color: #bbbbbb"> </span><span style="color: #008000; font-weight: bold">this</span>.resize);<span style="color: #bbbbbb"></span>
<span style="color: #bbbbbb"> </span><span style="color: #008000; font-weight: bold">this</span>.swapChain<span style="color: #bbbbbb"> </span><span style="color: #666666">=</span><span style="color: #bbbbbb"> </span><span style="color: #008000; font-weight: bold">this</span>.engine.createSwapChain();
<span style="color: #bbbbbb"> </span><span style="color: #008000; font-weight: bold">this</span>.renderer<span style="color: #bbbbbb"> </span><span style="color: #666666">=</span><span style="color: #bbbbbb"> </span><span style="color: #008000; font-weight: bold">this</span>.engine.createRenderer();
<span style="color: #bbbbbb"> </span><span style="color: #008000; font-weight: bold">this</span>.camera<span style="color: #bbbbbb"> </span><span style="color: #666666">=</span><span style="color: #bbbbbb"> </span><span style="color: #008000; font-weight: bold">this</span>.engine.createCamera(Filament.EntityManager.get().create());
<span style="color: #bbbbbb"> </span><span style="color: #008000; font-weight: bold">this</span>.view<span style="color: #bbbbbb"> </span><span style="color: #666666">=</span><span style="color: #bbbbbb"> </span><span style="color: #008000; font-weight: bold">this</span>.engine.createView();
<span style="color: #bbbbbb"> </span><span style="color: #008000; font-weight: bold">this</span>.view.setCamera(<span style="color: #008000; font-weight: bold">this</span>.camera);
<span style="color: #bbbbbb"> </span><span style="color: #008000; font-weight: bold">this</span>.view.setScene(<span style="color: #008000; font-weight: bold">this</span>.scene);
<span style="color: #bbbbbb"> </span><span style="color: #008000; font-weight: bold">this</span>.render<span style="color: #bbbbbb"> </span><span style="color: #666666">=</span><span style="color: #bbbbbb"> </span><span style="color: #008000; font-weight: bold">this</span>.render.bind(<span style="color: #008000; font-weight: bold">this</span>);
<span style="color: #bbbbbb"> </span><span style="color: #008000; font-weight: bold">this</span>.resize<span style="color: #bbbbbb"> </span><span style="color: #666666">=</span><span style="color: #bbbbbb"> </span><span style="color: #008000; font-weight: bold">this</span>.resize.bind(<span style="color: #008000; font-weight: bold">this</span>);
<span style="color: #bbbbbb"> </span><span style="color: #008000">window</span>.addEventListener(<span style="color: #BA2121">&#39;resize&#39;</span>,<span style="color: #bbbbbb"> </span><span style="color: #008000; font-weight: bold">this</span>.resize);
<span style="color: #bbbbbb"> </span><span style="color: #008000; font-weight: bold">const</span><span style="color: #bbbbbb"> </span>eye<span style="color: #bbbbbb"> </span><span style="color: #666666">=</span><span style="color: #bbbbbb"> </span>[<span style="color: #666666">0</span>,<span style="color: #bbbbbb"> </span><span style="color: #666666">0</span>,<span style="color: #bbbbbb"> </span><span style="color: #666666">4</span>],<span style="color: #bbbbbb"> </span>center<span style="color: #bbbbbb"> </span><span style="color: #666666">=</span><span style="color: #bbbbbb"> </span>[<span style="color: #666666">0</span>,<span style="color: #bbbbbb"> </span><span style="color: #666666">0</span>,<span style="color: #bbbbbb"> </span><span style="color: #666666">0</span>],<span style="color: #bbbbbb"> </span>up<span style="color: #bbbbbb"> </span><span style="color: #666666">=</span><span style="color: #bbbbbb"> </span>[<span style="color: #666666">0</span>,<span style="color: #bbbbbb"> </span><span style="color: #666666">1</span>,<span style="color: #bbbbbb"> </span><span style="color: #666666">0</span>];<span style="color: #bbbbbb"></span>
<span style="color: #bbbbbb"> </span><span style="color: #008000; font-weight: bold">this</span>.camera.lookAt(eye,<span style="color: #bbbbbb"> </span>center,<span style="color: #bbbbbb"> </span>up);<span style="color: #bbbbbb"></span>
<span style="color: #bbbbbb"> </span><span style="color: #008000; font-weight: bold">const</span><span style="color: #bbbbbb"> </span>eye<span style="color: #bbbbbb"> </span><span style="color: #666666">=</span><span style="color: #bbbbbb"> </span>[<span style="color: #666666">0</span>,<span style="color: #bbbbbb"> </span><span style="color: #666666">0</span>,<span style="color: #bbbbbb"> </span><span style="color: #666666">4</span>],<span style="color: #bbbbbb"> </span>center<span style="color: #bbbbbb"> </span><span style="color: #666666">=</span><span style="color: #bbbbbb"> </span>[<span style="color: #666666">0</span>,<span style="color: #bbbbbb"> </span><span style="color: #666666">0</span>,<span style="color: #bbbbbb"> </span><span style="color: #666666">0</span>],<span style="color: #bbbbbb"> </span>up<span style="color: #bbbbbb"> </span><span style="color: #666666">=</span><span style="color: #bbbbbb"> </span>[<span style="color: #666666">0</span>,<span style="color: #bbbbbb"> </span><span style="color: #666666">1</span>,<span style="color: #bbbbbb"> </span><span style="color: #666666">0</span>];
<span style="color: #bbbbbb"> </span><span style="color: #008000; font-weight: bold">this</span>.camera.lookAt(eye,<span style="color: #bbbbbb"> </span>center,<span style="color: #bbbbbb"> </span>up);
<span style="color: #bbbbbb"> </span><span style="color: #008000; font-weight: bold">this</span>.resize();<span style="color: #bbbbbb"></span>
<span style="color: #bbbbbb"> </span><span style="color: #008000">window</span>.requestAnimationFrame(<span style="color: #008000; font-weight: bold">this</span>.render);<span style="color: #bbbbbb"></span>
<span style="color: #bbbbbb"> </span>}<span style="color: #bbbbbb"></span>
<span style="color: #bbbbbb"> </span><span style="color: #008000; font-weight: bold">this</span>.resize();
<span style="color: #bbbbbb"> </span><span style="color: #008000">window</span>.requestAnimationFrame(<span style="color: #008000; font-weight: bold">this</span>.render);
<span style="color: #bbbbbb"> </span>}
<span style="color: #bbbbbb"> </span>render()<span style="color: #bbbbbb"> </span>{<span style="color: #bbbbbb"></span>
<span style="color: #bbbbbb"> </span><span style="color: #3D7B7B; font-style: italic">// TODO: apply gltumble matrix</span><span style="color: #bbbbbb"></span>
<span style="color: #bbbbbb"> </span><span style="color: #008000; font-weight: bold">this</span>.renderer.render(<span style="color: #008000; font-weight: bold">this</span>.swapChain,<span style="color: #bbbbbb"> </span><span style="color: #008000; font-weight: bold">this</span>.view);<span style="color: #bbbbbb"></span>
<span style="color: #bbbbbb"> </span><span style="color: #008000">window</span>.requestAnimationFrame(<span style="color: #008000; font-weight: bold">this</span>.render);<span style="color: #bbbbbb"></span>
<span style="color: #bbbbbb"> </span>}<span style="color: #bbbbbb"></span>
<span style="color: #bbbbbb"> </span>render()<span style="color: #bbbbbb"> </span>{
<span style="color: #bbbbbb"> </span><span style="color: #3D7B7B; font-style: italic">// TODO: apply gltumble matrix</span>
<span style="color: #bbbbbb"> </span><span style="color: #008000; font-weight: bold">this</span>.renderer.render(<span style="color: #008000; font-weight: bold">this</span>.swapChain,<span style="color: #bbbbbb"> </span><span style="color: #008000; font-weight: bold">this</span>.view);
<span style="color: #bbbbbb"> </span><span style="color: #008000">window</span>.requestAnimationFrame(<span style="color: #008000; font-weight: bold">this</span>.render);
<span style="color: #bbbbbb"> </span>}
<span style="color: #bbbbbb"> </span>resize()<span style="color: #bbbbbb"> </span>{<span style="color: #bbbbbb"></span>
<span style="color: #bbbbbb"> </span><span style="color: #008000; font-weight: bold">const</span><span style="color: #bbbbbb"> </span>dpr<span style="color: #bbbbbb"> </span><span style="color: #666666">=</span><span style="color: #bbbbbb"> </span><span style="color: #008000">window</span>.devicePixelRatio;<span style="color: #bbbbbb"></span>
<span style="color: #bbbbbb"> </span><span style="color: #008000; font-weight: bold">const</span><span style="color: #bbbbbb"> </span>width<span style="color: #bbbbbb"> </span><span style="color: #666666">=</span><span style="color: #bbbbbb"> </span><span style="color: #008000; font-weight: bold">this</span>.canvas.width<span style="color: #bbbbbb"> </span><span style="color: #666666">=</span><span style="color: #bbbbbb"> </span><span style="color: #008000">window</span>.innerWidth<span style="color: #bbbbbb"> </span><span style="color: #666666">*</span><span style="color: #bbbbbb"> </span>dpr;<span style="color: #bbbbbb"></span>
<span style="color: #bbbbbb"> </span><span style="color: #008000; font-weight: bold">const</span><span style="color: #bbbbbb"> </span>height<span style="color: #bbbbbb"> </span><span style="color: #666666">=</span><span style="color: #bbbbbb"> </span><span style="color: #008000; font-weight: bold">this</span>.canvas.height<span style="color: #bbbbbb"> </span><span style="color: #666666">=</span><span style="color: #bbbbbb"> </span><span style="color: #008000">window</span>.innerHeight<span style="color: #bbbbbb"> </span><span style="color: #666666">*</span><span style="color: #bbbbbb"> </span>dpr;<span style="color: #bbbbbb"></span>
<span style="color: #bbbbbb"> </span><span style="color: #008000; font-weight: bold">this</span>.view.setViewport([<span style="color: #666666">0</span>,<span style="color: #bbbbbb"> </span><span style="color: #666666">0</span>,<span style="color: #bbbbbb"> </span>width,<span style="color: #bbbbbb"> </span>height]);<span style="color: #bbbbbb"></span>
<span style="color: #bbbbbb"> </span>resize()<span style="color: #bbbbbb"> </span>{
<span style="color: #bbbbbb"> </span><span style="color: #008000; font-weight: bold">const</span><span style="color: #bbbbbb"> </span>dpr<span style="color: #bbbbbb"> </span><span style="color: #666666">=</span><span style="color: #bbbbbb"> </span><span style="color: #008000">window</span>.devicePixelRatio;
<span style="color: #bbbbbb"> </span><span style="color: #008000; font-weight: bold">const</span><span style="color: #bbbbbb"> </span>width<span style="color: #bbbbbb"> </span><span style="color: #666666">=</span><span style="color: #bbbbbb"> </span><span style="color: #008000; font-weight: bold">this</span>.canvas.width<span style="color: #bbbbbb"> </span><span style="color: #666666">=</span><span style="color: #bbbbbb"> </span><span style="color: #008000">window</span>.innerWidth<span style="color: #bbbbbb"> </span><span style="color: #666666">*</span><span style="color: #bbbbbb"> </span>dpr;
<span style="color: #bbbbbb"> </span><span style="color: #008000; font-weight: bold">const</span><span style="color: #bbbbbb"> </span>height<span style="color: #bbbbbb"> </span><span style="color: #666666">=</span><span style="color: #bbbbbb"> </span><span style="color: #008000; font-weight: bold">this</span>.canvas.height<span style="color: #bbbbbb"> </span><span style="color: #666666">=</span><span style="color: #bbbbbb"> </span><span style="color: #008000">window</span>.innerHeight<span style="color: #bbbbbb"> </span><span style="color: #666666">*</span><span style="color: #bbbbbb"> </span>dpr;
<span style="color: #bbbbbb"> </span><span style="color: #008000; font-weight: bold">this</span>.view.setViewport([<span style="color: #666666">0</span>,<span style="color: #bbbbbb"> </span><span style="color: #666666">0</span>,<span style="color: #bbbbbb"> </span>width,<span style="color: #bbbbbb"> </span>height]);
<span style="color: #bbbbbb"> </span><span style="color: #008000; font-weight: bold">const</span><span style="color: #bbbbbb"> </span>aspect<span style="color: #bbbbbb"> </span><span style="color: #666666">=</span><span style="color: #bbbbbb"> </span>width<span style="color: #bbbbbb"> </span><span style="color: #666666">/</span><span style="color: #bbbbbb"> </span>height;<span style="color: #bbbbbb"></span>
<span style="color: #bbbbbb"> </span><span style="color: #008000; font-weight: bold">const</span><span style="color: #bbbbbb"> </span>Fov<span style="color: #bbbbbb"> </span><span style="color: #666666">=</span><span style="color: #bbbbbb"> </span>Filament.Camera$Fov,<span style="color: #bbbbbb"> </span>fov<span style="color: #bbbbbb"> </span><span style="color: #666666">=</span><span style="color: #bbbbbb"> </span>aspect<span style="color: #bbbbbb"> </span><span style="color: #666666">&lt;</span><span style="color: #bbbbbb"> </span><span style="color: #666666">1</span><span style="color: #bbbbbb"> </span><span style="color: #666666">?</span><span style="color: #bbbbbb"> </span>Fov.HORIZONTAL<span style="color: #bbbbbb"> </span><span style="color: #666666">:</span><span style="color: #bbbbbb"> </span>Fov.VERTICAL;<span style="color: #bbbbbb"></span>
<span style="color: #bbbbbb"> </span><span style="color: #008000; font-weight: bold">this</span>.camera.setProjectionFov(<span style="color: #666666">45</span>,<span style="color: #bbbbbb"> </span>aspect,<span style="color: #bbbbbb"> </span><span style="color: #666666">1.0</span>,<span style="color: #bbbbbb"> </span><span style="color: #666666">10.0</span>,<span style="color: #bbbbbb"> </span>fov);<span style="color: #bbbbbb"></span>
<span style="color: #bbbbbb"> </span>}<span style="color: #bbbbbb"></span>
}<span style="color: #bbbbbb"></span>
<span style="color: #bbbbbb"> </span><span style="color: #008000; font-weight: bold">const</span><span style="color: #bbbbbb"> </span>aspect<span style="color: #bbbbbb"> </span><span style="color: #666666">=</span><span style="color: #bbbbbb"> </span>width<span style="color: #bbbbbb"> </span><span style="color: #666666">/</span><span style="color: #bbbbbb"> </span>height;
<span style="color: #bbbbbb"> </span><span style="color: #008000; font-weight: bold">const</span><span style="color: #bbbbbb"> </span>Fov<span style="color: #bbbbbb"> </span><span style="color: #666666">=</span><span style="color: #bbbbbb"> </span>Filament.Camera$Fov,<span style="color: #bbbbbb"> </span>fov<span style="color: #bbbbbb"> </span><span style="color: #666666">=</span><span style="color: #bbbbbb"> </span>aspect<span style="color: #bbbbbb"> </span><span style="color: #666666">&lt;</span><span style="color: #bbbbbb"> </span><span style="color: #666666">1</span><span style="color: #bbbbbb"> </span><span style="color: #666666">?</span><span style="color: #bbbbbb"> </span>Fov.HORIZONTAL<span style="color: #bbbbbb"> </span><span style="color: #666666">:</span><span style="color: #bbbbbb"> </span>Fov.VERTICAL;
<span style="color: #bbbbbb"> </span><span style="color: #008000; font-weight: bold">this</span>.camera.setProjectionFov(<span style="color: #666666">45</span>,<span style="color: #bbbbbb"> </span>aspect,<span style="color: #bbbbbb"> </span><span style="color: #666666">1.0</span>,<span style="color: #bbbbbb"> </span><span style="color: #666666">10.0</span>,<span style="color: #bbbbbb"> </span>fov);
<span style="color: #bbbbbb"> </span>}
}
</pre></div>
<p>Our app will only require a subset of assets to be present for <code>App</code> construction. We&#x27;ll download
@@ -172,29 +172,29 @@ string -- which might be empty.</p>
<p>In our case, we know that our web server will have <code>astc</code> and <code>s3tc</code> variants for albedo, and <code>etc</code>
variants for the other textures. The uncompressed variants (empty string) are always available as a
last resort. Go ahead and replace the <strong>declare asset URLs</strong> comment with the following snippet.</p>
<div class="highlight" style="background: #f8f8f8"><pre style="line-height: 125%;"><span></span><span style="color: #008000; font-weight: bold">const</span><span style="color: #bbbbbb"> </span>albedo_suffix<span style="color: #bbbbbb"> </span><span style="color: #666666">=</span><span style="color: #bbbbbb"> </span>Filament.getSupportedFormatSuffix(<span style="color: #BA2121">&#39;astc s3tc_srgb&#39;</span>);<span style="color: #bbbbbb"></span>
<span style="color: #008000; font-weight: bold">const</span><span style="color: #bbbbbb"> </span>texture_suffix<span style="color: #bbbbbb"> </span><span style="color: #666666">=</span><span style="color: #bbbbbb"> </span>Filament.getSupportedFormatSuffix(<span style="color: #BA2121">&#39;etc&#39;</span>);<span style="color: #bbbbbb"></span>
<div class="highlight" style="background: #f8f8f8"><pre style="line-height: 125%;"><span></span><span style="color: #008000; font-weight: bold">const</span><span style="color: #bbbbbb"> </span>albedo_suffix<span style="color: #bbbbbb"> </span><span style="color: #666666">=</span><span style="color: #bbbbbb"> </span>Filament.getSupportedFormatSuffix(<span style="color: #BA2121">&#39;astc s3tc_srgb&#39;</span>);
<span style="color: #008000; font-weight: bold">const</span><span style="color: #bbbbbb"> </span>texture_suffix<span style="color: #bbbbbb"> </span><span style="color: #666666">=</span><span style="color: #bbbbbb"> </span>Filament.getSupportedFormatSuffix(<span style="color: #BA2121">&#39;etc&#39;</span>);
<span style="color: #008000; font-weight: bold">const</span><span style="color: #bbbbbb"> </span>environ<span style="color: #bbbbbb"> </span><span style="color: #666666">=</span><span style="color: #bbbbbb"> </span><span style="color: #BA2121">&#39;venetian_crossroads_2k&#39;</span><span style="color: #bbbbbb"></span>
<span style="color: #008000; font-weight: bold">const</span><span style="color: #bbbbbb"> </span>ibl_url<span style="color: #bbbbbb"> </span><span style="color: #666666">=</span><span style="color: #bbbbbb"> </span><span style="color: #BA2121">`</span><span style="color: #A45A77; font-weight: bold">${</span>environ<span style="color: #A45A77; font-weight: bold">}</span><span style="color: #BA2121">/</span><span style="color: #A45A77; font-weight: bold">${</span>environ<span style="color: #A45A77; font-weight: bold">}</span><span style="color: #BA2121">_ibl.ktx`</span>;<span style="color: #bbbbbb"></span>
<span style="color: #008000; font-weight: bold">const</span><span style="color: #bbbbbb"> </span>sky_small_url<span style="color: #bbbbbb"> </span><span style="color: #666666">=</span><span style="color: #bbbbbb"> </span><span style="color: #BA2121">`</span><span style="color: #A45A77; font-weight: bold">${</span>environ<span style="color: #A45A77; font-weight: bold">}</span><span style="color: #BA2121">/</span><span style="color: #A45A77; font-weight: bold">${</span>environ<span style="color: #A45A77; font-weight: bold">}</span><span style="color: #BA2121">_skybox_tiny.ktx`</span>;<span style="color: #bbbbbb"></span>
<span style="color: #008000; font-weight: bold">const</span><span style="color: #bbbbbb"> </span>sky_large_url<span style="color: #bbbbbb"> </span><span style="color: #666666">=</span><span style="color: #bbbbbb"> </span><span style="color: #BA2121">`</span><span style="color: #A45A77; font-weight: bold">${</span>environ<span style="color: #A45A77; font-weight: bold">}</span><span style="color: #BA2121">/</span><span style="color: #A45A77; font-weight: bold">${</span>environ<span style="color: #A45A77; font-weight: bold">}</span><span style="color: #BA2121">_skybox.ktx`</span>;<span style="color: #bbbbbb"></span>
<span style="color: #008000; font-weight: bold">const</span><span style="color: #bbbbbb"> </span>albedo_url<span style="color: #bbbbbb"> </span><span style="color: #666666">=</span><span style="color: #bbbbbb"> </span><span style="color: #BA2121">`albedo</span><span style="color: #A45A77; font-weight: bold">${</span>albedo_suffix<span style="color: #A45A77; font-weight: bold">}</span><span style="color: #BA2121">.ktx`</span>;<span style="color: #bbbbbb"></span>
<span style="color: #008000; font-weight: bold">const</span><span style="color: #bbbbbb"> </span>ao_url<span style="color: #bbbbbb"> </span><span style="color: #666666">=</span><span style="color: #bbbbbb"> </span><span style="color: #BA2121">`ao</span><span style="color: #A45A77; font-weight: bold">${</span>texture_suffix<span style="color: #A45A77; font-weight: bold">}</span><span style="color: #BA2121">.ktx`</span>;<span style="color: #bbbbbb"></span>
<span style="color: #008000; font-weight: bold">const</span><span style="color: #bbbbbb"> </span>metallic_url<span style="color: #bbbbbb"> </span><span style="color: #666666">=</span><span style="color: #bbbbbb"> </span><span style="color: #BA2121">`metallic</span><span style="color: #A45A77; font-weight: bold">${</span>texture_suffix<span style="color: #A45A77; font-weight: bold">}</span><span style="color: #BA2121">.ktx`</span>;<span style="color: #bbbbbb"></span>
<span style="color: #008000; font-weight: bold">const</span><span style="color: #bbbbbb"> </span>normal_url<span style="color: #bbbbbb"> </span><span style="color: #666666">=</span><span style="color: #bbbbbb"> </span><span style="color: #BA2121">`normal</span><span style="color: #A45A77; font-weight: bold">${</span>texture_suffix<span style="color: #A45A77; font-weight: bold">}</span><span style="color: #BA2121">.ktx`</span>;<span style="color: #bbbbbb"></span>
<span style="color: #008000; font-weight: bold">const</span><span style="color: #bbbbbb"> </span>roughness_url<span style="color: #bbbbbb"> </span><span style="color: #666666">=</span><span style="color: #bbbbbb"> </span><span style="color: #BA2121">`roughness</span><span style="color: #A45A77; font-weight: bold">${</span>texture_suffix<span style="color: #A45A77; font-weight: bold">}</span><span style="color: #BA2121">.ktx`</span>;<span style="color: #bbbbbb"></span>
<span style="color: #008000; font-weight: bold">const</span><span style="color: #bbbbbb"> </span>filamat_url<span style="color: #bbbbbb"> </span><span style="color: #666666">=</span><span style="color: #bbbbbb"> </span><span style="color: #BA2121">&#39;textured.filamat&#39;</span>;<span style="color: #bbbbbb"></span>
<span style="color: #008000; font-weight: bold">const</span><span style="color: #bbbbbb"> </span>filamesh_url<span style="color: #bbbbbb"> </span><span style="color: #666666">=</span><span style="color: #bbbbbb"> </span><span style="color: #BA2121">&#39;suzanne.filamesh&#39;</span>;<span style="color: #bbbbbb"></span>
<span style="color: #008000; font-weight: bold">const</span><span style="color: #bbbbbb"> </span>environ<span style="color: #bbbbbb"> </span><span style="color: #666666">=</span><span style="color: #bbbbbb"> </span><span style="color: #BA2121">&#39;venetian_crossroads_2k&#39;</span>
<span style="color: #008000; font-weight: bold">const</span><span style="color: #bbbbbb"> </span>ibl_url<span style="color: #bbbbbb"> </span><span style="color: #666666">=</span><span style="color: #bbbbbb"> </span><span style="color: #BA2121">`</span><span style="color: #A45A77; font-weight: bold">${</span>environ<span style="color: #A45A77; font-weight: bold">}</span><span style="color: #BA2121">/</span><span style="color: #A45A77; font-weight: bold">${</span>environ<span style="color: #A45A77; font-weight: bold">}</span><span style="color: #BA2121">_ibl.ktx`</span>;
<span style="color: #008000; font-weight: bold">const</span><span style="color: #bbbbbb"> </span>sky_small_url<span style="color: #bbbbbb"> </span><span style="color: #666666">=</span><span style="color: #bbbbbb"> </span><span style="color: #BA2121">`</span><span style="color: #A45A77; font-weight: bold">${</span>environ<span style="color: #A45A77; font-weight: bold">}</span><span style="color: #BA2121">/</span><span style="color: #A45A77; font-weight: bold">${</span>environ<span style="color: #A45A77; font-weight: bold">}</span><span style="color: #BA2121">_skybox_tiny.ktx`</span>;
<span style="color: #008000; font-weight: bold">const</span><span style="color: #bbbbbb"> </span>sky_large_url<span style="color: #bbbbbb"> </span><span style="color: #666666">=</span><span style="color: #bbbbbb"> </span><span style="color: #BA2121">`</span><span style="color: #A45A77; font-weight: bold">${</span>environ<span style="color: #A45A77; font-weight: bold">}</span><span style="color: #BA2121">/</span><span style="color: #A45A77; font-weight: bold">${</span>environ<span style="color: #A45A77; font-weight: bold">}</span><span style="color: #BA2121">_skybox.ktx`</span>;
<span style="color: #008000; font-weight: bold">const</span><span style="color: #bbbbbb"> </span>albedo_url<span style="color: #bbbbbb"> </span><span style="color: #666666">=</span><span style="color: #bbbbbb"> </span><span style="color: #BA2121">`albedo</span><span style="color: #A45A77; font-weight: bold">${</span>albedo_suffix<span style="color: #A45A77; font-weight: bold">}</span><span style="color: #BA2121">.ktx`</span>;
<span style="color: #008000; font-weight: bold">const</span><span style="color: #bbbbbb"> </span>ao_url<span style="color: #bbbbbb"> </span><span style="color: #666666">=</span><span style="color: #bbbbbb"> </span><span style="color: #BA2121">`ao</span><span style="color: #A45A77; font-weight: bold">${</span>texture_suffix<span style="color: #A45A77; font-weight: bold">}</span><span style="color: #BA2121">.ktx`</span>;
<span style="color: #008000; font-weight: bold">const</span><span style="color: #bbbbbb"> </span>metallic_url<span style="color: #bbbbbb"> </span><span style="color: #666666">=</span><span style="color: #bbbbbb"> </span><span style="color: #BA2121">`metallic</span><span style="color: #A45A77; font-weight: bold">${</span>texture_suffix<span style="color: #A45A77; font-weight: bold">}</span><span style="color: #BA2121">.ktx`</span>;
<span style="color: #008000; font-weight: bold">const</span><span style="color: #bbbbbb"> </span>normal_url<span style="color: #bbbbbb"> </span><span style="color: #666666">=</span><span style="color: #bbbbbb"> </span><span style="color: #BA2121">`normal</span><span style="color: #A45A77; font-weight: bold">${</span>texture_suffix<span style="color: #A45A77; font-weight: bold">}</span><span style="color: #BA2121">.ktx`</span>;
<span style="color: #008000; font-weight: bold">const</span><span style="color: #bbbbbb"> </span>roughness_url<span style="color: #bbbbbb"> </span><span style="color: #666666">=</span><span style="color: #bbbbbb"> </span><span style="color: #BA2121">`roughness</span><span style="color: #A45A77; font-weight: bold">${</span>texture_suffix<span style="color: #A45A77; font-weight: bold">}</span><span style="color: #BA2121">.ktx`</span>;
<span style="color: #008000; font-weight: bold">const</span><span style="color: #bbbbbb"> </span>filamat_url<span style="color: #bbbbbb"> </span><span style="color: #666666">=</span><span style="color: #bbbbbb"> </span><span style="color: #BA2121">&#39;textured.filamat&#39;</span>;
<span style="color: #008000; font-weight: bold">const</span><span style="color: #bbbbbb"> </span>filamesh_url<span style="color: #bbbbbb"> </span><span style="color: #666666">=</span><span style="color: #bbbbbb"> </span><span style="color: #BA2121">&#39;suzanne.filamesh&#39;</span>;
</pre></div>
<h2>Create skybox and IBL</h2>
<p>Next, let&#x27;s create the low-resolution skybox and IBL in the <code>App</code> constructor.</p>
<div class="highlight" style="background: #f8f8f8"><pre style="line-height: 125%;"><span></span><span style="color: #008000; font-weight: bold">this</span>.skybox<span style="color: #bbbbbb"> </span><span style="color: #666666">=</span><span style="color: #bbbbbb"> </span><span style="color: #008000; font-weight: bold">this</span>.engine.createSkyFromKtx1(sky_small_url);<span style="color: #bbbbbb"></span>
<span style="color: #008000; font-weight: bold">this</span>.scene.setSkybox(<span style="color: #008000; font-weight: bold">this</span>.skybox);<span style="color: #bbbbbb"></span>
<span style="color: #008000; font-weight: bold">this</span>.indirectLight<span style="color: #bbbbbb"> </span><span style="color: #666666">=</span><span style="color: #bbbbbb"> </span><span style="color: #008000; font-weight: bold">this</span>.engine.createIblFromKtx1(ibl_url);<span style="color: #bbbbbb"></span>
<span style="color: #008000; font-weight: bold">this</span>.indirectLight.setIntensity(<span style="color: #666666">100000</span>);<span style="color: #bbbbbb"></span>
<span style="color: #008000; font-weight: bold">this</span>.scene.setIndirectLight(<span style="color: #008000; font-weight: bold">this</span>.indirectLight);<span style="color: #bbbbbb"></span>
<div class="highlight" style="background: #f8f8f8"><pre style="line-height: 125%;"><span></span><span style="color: #008000; font-weight: bold">this</span>.skybox<span style="color: #bbbbbb"> </span><span style="color: #666666">=</span><span style="color: #bbbbbb"> </span><span style="color: #008000; font-weight: bold">this</span>.engine.createSkyFromKtx1(sky_small_url);
<span style="color: #008000; font-weight: bold">this</span>.scene.setSkybox(<span style="color: #008000; font-weight: bold">this</span>.skybox);
<span style="color: #008000; font-weight: bold">this</span>.indirectLight<span style="color: #bbbbbb"> </span><span style="color: #666666">=</span><span style="color: #bbbbbb"> </span><span style="color: #008000; font-weight: bold">this</span>.engine.createIblFromKtx1(ibl_url);
<span style="color: #008000; font-weight: bold">this</span>.indirectLight.setIntensity(<span style="color: #666666">100000</span>);
<span style="color: #008000; font-weight: bold">this</span>.scene.setIndirectLight(<span style="color: #008000; font-weight: bold">this</span>.indirectLight);
</pre></div>
<p>This allows users to see a reasonable background fairly quickly, before larger assets have finished
@@ -206,31 +206,31 @@ when the assets have finished downloading.</p>
<p>In our callback, we&#x27;ll make several <code>setTextureParameter</code> calls on the material instance, then we&#x27;ll
recreate the skybox using a higher-resolution texture. As a last step we unhide the renderable that
was created in the app constructor.</p>
<div class="highlight" style="background: #f8f8f8"><pre style="line-height: 125%;"><span></span>Filament.fetch([sky_large_url,<span style="color: #bbbbbb"> </span>albedo_url,<span style="color: #bbbbbb"> </span>roughness_url,<span style="color: #bbbbbb"> </span>metallic_url,<span style="color: #bbbbbb"> </span>normal_url,<span style="color: #bbbbbb"> </span>ao_url],<span style="color: #bbbbbb"> </span>()<span style="color: #bbbbbb"> </span>=&gt;<span style="color: #bbbbbb"> </span>{<span style="color: #bbbbbb"></span>
<span style="color: #bbbbbb"> </span><span style="color: #008000; font-weight: bold">const</span><span style="color: #bbbbbb"> </span>albedo<span style="color: #bbbbbb"> </span><span style="color: #666666">=</span><span style="color: #bbbbbb"> </span><span style="color: #008000; font-weight: bold">this</span>.engine.createTextureFromKtx1(albedo_url,<span style="color: #bbbbbb"> </span>{srgb<span style="color: #666666">:</span><span style="color: #bbbbbb"> </span><span style="color: #008000; font-weight: bold">true</span>});<span style="color: #bbbbbb"></span>
<span style="color: #bbbbbb"> </span><span style="color: #008000; font-weight: bold">const</span><span style="color: #bbbbbb"> </span>roughness<span style="color: #bbbbbb"> </span><span style="color: #666666">=</span><span style="color: #bbbbbb"> </span><span style="color: #008000; font-weight: bold">this</span>.engine.createTextureFromKtx1(roughness_url);<span style="color: #bbbbbb"></span>
<span style="color: #bbbbbb"> </span><span style="color: #008000; font-weight: bold">const</span><span style="color: #bbbbbb"> </span>metallic<span style="color: #bbbbbb"> </span><span style="color: #666666">=</span><span style="color: #bbbbbb"> </span><span style="color: #008000; font-weight: bold">this</span>.engine.createTextureFromKtx1(metallic_url);<span style="color: #bbbbbb"></span>
<span style="color: #bbbbbb"> </span><span style="color: #008000; font-weight: bold">const</span><span style="color: #bbbbbb"> </span>normal<span style="color: #bbbbbb"> </span><span style="color: #666666">=</span><span style="color: #bbbbbb"> </span><span style="color: #008000; font-weight: bold">this</span>.engine.createTextureFromKtx1(normal_url);<span style="color: #bbbbbb"></span>
<span style="color: #bbbbbb"> </span><span style="color: #008000; font-weight: bold">const</span><span style="color: #bbbbbb"> </span>ao<span style="color: #bbbbbb"> </span><span style="color: #666666">=</span><span style="color: #bbbbbb"> </span><span style="color: #008000; font-weight: bold">this</span>.engine.createTextureFromKtx1(ao_url);<span style="color: #bbbbbb"></span>
<div class="highlight" style="background: #f8f8f8"><pre style="line-height: 125%;"><span></span>Filament.fetch([sky_large_url,<span style="color: #bbbbbb"> </span>albedo_url,<span style="color: #bbbbbb"> </span>roughness_url,<span style="color: #bbbbbb"> </span>metallic_url,<span style="color: #bbbbbb"> </span>normal_url,<span style="color: #bbbbbb"> </span>ao_url],<span style="color: #bbbbbb"> </span>()<span style="color: #bbbbbb"> </span>=&gt;<span style="color: #bbbbbb"> </span>{
<span style="color: #bbbbbb"> </span><span style="color: #008000; font-weight: bold">const</span><span style="color: #bbbbbb"> </span>albedo<span style="color: #bbbbbb"> </span><span style="color: #666666">=</span><span style="color: #bbbbbb"> </span><span style="color: #008000; font-weight: bold">this</span>.engine.createTextureFromKtx1(albedo_url,<span style="color: #bbbbbb"> </span>{srgb<span style="color: #666666">:</span><span style="color: #bbbbbb"> </span><span style="color: #008000; font-weight: bold">true</span>});
<span style="color: #bbbbbb"> </span><span style="color: #008000; font-weight: bold">const</span><span style="color: #bbbbbb"> </span>roughness<span style="color: #bbbbbb"> </span><span style="color: #666666">=</span><span style="color: #bbbbbb"> </span><span style="color: #008000; font-weight: bold">this</span>.engine.createTextureFromKtx1(roughness_url);
<span style="color: #bbbbbb"> </span><span style="color: #008000; font-weight: bold">const</span><span style="color: #bbbbbb"> </span>metallic<span style="color: #bbbbbb"> </span><span style="color: #666666">=</span><span style="color: #bbbbbb"> </span><span style="color: #008000; font-weight: bold">this</span>.engine.createTextureFromKtx1(metallic_url);
<span style="color: #bbbbbb"> </span><span style="color: #008000; font-weight: bold">const</span><span style="color: #bbbbbb"> </span>normal<span style="color: #bbbbbb"> </span><span style="color: #666666">=</span><span style="color: #bbbbbb"> </span><span style="color: #008000; font-weight: bold">this</span>.engine.createTextureFromKtx1(normal_url);
<span style="color: #bbbbbb"> </span><span style="color: #008000; font-weight: bold">const</span><span style="color: #bbbbbb"> </span>ao<span style="color: #bbbbbb"> </span><span style="color: #666666">=</span><span style="color: #bbbbbb"> </span><span style="color: #008000; font-weight: bold">this</span>.engine.createTextureFromKtx1(ao_url);
<span style="color: #bbbbbb"> </span><span style="color: #008000; font-weight: bold">const</span><span style="color: #bbbbbb"> </span>sampler<span style="color: #bbbbbb"> </span><span style="color: #666666">=</span><span style="color: #bbbbbb"> </span><span style="color: #AA22FF; font-weight: bold">new</span><span style="color: #bbbbbb"> </span>Filament.TextureSampler(<span style="color: #bbbbbb"></span>
<span style="color: #bbbbbb"> </span>Filament.MinFilter.LINEAR_MIPMAP_LINEAR,<span style="color: #bbbbbb"></span>
<span style="color: #bbbbbb"> </span>Filament.MagFilter.LINEAR,<span style="color: #bbbbbb"></span>
<span style="color: #bbbbbb"> </span>Filament.WrapMode.CLAMP_TO_EDGE);<span style="color: #bbbbbb"></span>
<span style="color: #bbbbbb"> </span><span style="color: #008000; font-weight: bold">const</span><span style="color: #bbbbbb"> </span>sampler<span style="color: #bbbbbb"> </span><span style="color: #666666">=</span><span style="color: #bbbbbb"> </span><span style="color: #AA22FF; font-weight: bold">new</span><span style="color: #bbbbbb"> </span>Filament.TextureSampler(
<span style="color: #bbbbbb"> </span>Filament.MinFilter.LINEAR_MIPMAP_LINEAR,
<span style="color: #bbbbbb"> </span>Filament.MagFilter.LINEAR,
<span style="color: #bbbbbb"> </span>Filament.WrapMode.CLAMP_TO_EDGE);
<span style="color: #bbbbbb"> </span><span style="color: #008000; font-weight: bold">this</span>.matinstance.setTextureParameter(<span style="color: #BA2121">&#39;albedo&#39;</span>,<span style="color: #bbbbbb"> </span>albedo,<span style="color: #bbbbbb"> </span>sampler);<span style="color: #bbbbbb"></span>
<span style="color: #bbbbbb"> </span><span style="color: #008000; font-weight: bold">this</span>.matinstance.setTextureParameter(<span style="color: #BA2121">&#39;roughness&#39;</span>,<span style="color: #bbbbbb"> </span>roughness,<span style="color: #bbbbbb"> </span>sampler);<span style="color: #bbbbbb"></span>
<span style="color: #bbbbbb"> </span><span style="color: #008000; font-weight: bold">this</span>.matinstance.setTextureParameter(<span style="color: #BA2121">&#39;metallic&#39;</span>,<span style="color: #bbbbbb"> </span>metallic,<span style="color: #bbbbbb"> </span>sampler);<span style="color: #bbbbbb"></span>
<span style="color: #bbbbbb"> </span><span style="color: #008000; font-weight: bold">this</span>.matinstance.setTextureParameter(<span style="color: #BA2121">&#39;normal&#39;</span>,<span style="color: #bbbbbb"> </span>normal,<span style="color: #bbbbbb"> </span>sampler);<span style="color: #bbbbbb"></span>
<span style="color: #bbbbbb"> </span><span style="color: #008000; font-weight: bold">this</span>.matinstance.setTextureParameter(<span style="color: #BA2121">&#39;ao&#39;</span>,<span style="color: #bbbbbb"> </span>ao,<span style="color: #bbbbbb"> </span>sampler);<span style="color: #bbbbbb"></span>
<span style="color: #bbbbbb"> </span><span style="color: #008000; font-weight: bold">this</span>.matinstance.setTextureParameter(<span style="color: #BA2121">&#39;albedo&#39;</span>,<span style="color: #bbbbbb"> </span>albedo,<span style="color: #bbbbbb"> </span>sampler);
<span style="color: #bbbbbb"> </span><span style="color: #008000; font-weight: bold">this</span>.matinstance.setTextureParameter(<span style="color: #BA2121">&#39;roughness&#39;</span>,<span style="color: #bbbbbb"> </span>roughness,<span style="color: #bbbbbb"> </span>sampler);
<span style="color: #bbbbbb"> </span><span style="color: #008000; font-weight: bold">this</span>.matinstance.setTextureParameter(<span style="color: #BA2121">&#39;metallic&#39;</span>,<span style="color: #bbbbbb"> </span>metallic,<span style="color: #bbbbbb"> </span>sampler);
<span style="color: #bbbbbb"> </span><span style="color: #008000; font-weight: bold">this</span>.matinstance.setTextureParameter(<span style="color: #BA2121">&#39;normal&#39;</span>,<span style="color: #bbbbbb"> </span>normal,<span style="color: #bbbbbb"> </span>sampler);
<span style="color: #bbbbbb"> </span><span style="color: #008000; font-weight: bold">this</span>.matinstance.setTextureParameter(<span style="color: #BA2121">&#39;ao&#39;</span>,<span style="color: #bbbbbb"> </span>ao,<span style="color: #bbbbbb"> </span>sampler);
<span style="color: #bbbbbb"> </span><span style="color: #3D7B7B; font-style: italic">// Replace low-res skybox with high-res skybox.</span><span style="color: #bbbbbb"></span>
<span style="color: #bbbbbb"> </span><span style="color: #008000; font-weight: bold">this</span>.engine.destroySkybox(<span style="color: #008000; font-weight: bold">this</span>.skybox);<span style="color: #bbbbbb"></span>
<span style="color: #bbbbbb"> </span><span style="color: #008000; font-weight: bold">this</span>.skybox<span style="color: #bbbbbb"> </span><span style="color: #666666">=</span><span style="color: #bbbbbb"> </span><span style="color: #008000; font-weight: bold">this</span>.engine.createSkyFromKtx1(sky_large_url);<span style="color: #bbbbbb"></span>
<span style="color: #bbbbbb"> </span><span style="color: #008000; font-weight: bold">this</span>.scene.setSkybox(<span style="color: #008000; font-weight: bold">this</span>.skybox);<span style="color: #bbbbbb"></span>
<span style="color: #bbbbbb"> </span><span style="color: #3D7B7B; font-style: italic">// Replace low-res skybox with high-res skybox.</span>
<span style="color: #bbbbbb"> </span><span style="color: #008000; font-weight: bold">this</span>.engine.destroySkybox(<span style="color: #008000; font-weight: bold">this</span>.skybox);
<span style="color: #bbbbbb"> </span><span style="color: #008000; font-weight: bold">this</span>.skybox<span style="color: #bbbbbb"> </span><span style="color: #666666">=</span><span style="color: #bbbbbb"> </span><span style="color: #008000; font-weight: bold">this</span>.engine.createSkyFromKtx1(sky_large_url);
<span style="color: #bbbbbb"> </span><span style="color: #008000; font-weight: bold">this</span>.scene.setSkybox(<span style="color: #008000; font-weight: bold">this</span>.skybox);
<span style="color: #bbbbbb"> </span><span style="color: #008000; font-weight: bold">this</span>.scene.addEntity(<span style="color: #008000; font-weight: bold">this</span>.suzanne);<span style="color: #bbbbbb"></span>
});<span style="color: #bbbbbb"></span>
<span style="color: #bbbbbb"> </span><span style="color: #008000; font-weight: bold">this</span>.scene.addEntity(<span style="color: #008000; font-weight: bold">this</span>.suzanne);
});
</pre></div>
<h2>Introduce trackball rotation</h2>
@@ -241,13 +241,13 @@ listens for drag events and computes a rotation matrix.</p>
<p>Next, replace the <strong>initialize gltumble</strong> and <strong>apply gltumble matrix</strong> comments with the following
two code snippets.</p>
<div class="highlight" style="background: #f8f8f8"><pre style="line-height: 125%;"><span></span><span style="color: #008000; font-weight: bold">this</span>.trackball<span style="color: #bbbbbb"> </span><span style="color: #666666">=</span><span style="color: #bbbbbb"> </span><span style="color: #AA22FF; font-weight: bold">new</span><span style="color: #bbbbbb"> </span>Trackball(canvas,<span style="color: #bbbbbb"> </span>{startSpin<span style="color: #666666">:</span><span style="color: #bbbbbb"> </span><span style="color: #666666">0.035</span>});<span style="color: #bbbbbb"></span>
<div class="highlight" style="background: #f8f8f8"><pre style="line-height: 125%;"><span></span><span style="color: #008000; font-weight: bold">this</span>.trackball<span style="color: #bbbbbb"> </span><span style="color: #666666">=</span><span style="color: #bbbbbb"> </span><span style="color: #AA22FF; font-weight: bold">new</span><span style="color: #bbbbbb"> </span>Trackball(canvas,<span style="color: #bbbbbb"> </span>{startSpin<span style="color: #666666">:</span><span style="color: #bbbbbb"> </span><span style="color: #666666">0.035</span>});
</pre></div>
<div class="highlight" style="background: #f8f8f8"><pre style="line-height: 125%;"><span></span><span style="color: #008000; font-weight: bold">const</span><span style="color: #bbbbbb"> </span>tcm<span style="color: #bbbbbb"> </span><span style="color: #666666">=</span><span style="color: #bbbbbb"> </span><span style="color: #008000; font-weight: bold">this</span>.engine.getTransformManager();<span style="color: #bbbbbb"></span>
<span style="color: #008000; font-weight: bold">const</span><span style="color: #bbbbbb"> </span>inst<span style="color: #bbbbbb"> </span><span style="color: #666666">=</span><span style="color: #bbbbbb"> </span>tcm.getInstance(<span style="color: #008000; font-weight: bold">this</span>.suzanne);<span style="color: #bbbbbb"></span>
tcm.setTransform(inst,<span style="color: #bbbbbb"> </span><span style="color: #008000; font-weight: bold">this</span>.trackball.getMatrix());<span style="color: #bbbbbb"></span>
inst.<span style="color: #AA22FF; font-weight: bold">delete</span>();<span style="color: #bbbbbb"></span>
<div class="highlight" style="background: #f8f8f8"><pre style="line-height: 125%;"><span></span><span style="color: #008000; font-weight: bold">const</span><span style="color: #bbbbbb"> </span>tcm<span style="color: #bbbbbb"> </span><span style="color: #666666">=</span><span style="color: #bbbbbb"> </span><span style="color: #008000; font-weight: bold">this</span>.engine.getTransformManager();
<span style="color: #008000; font-weight: bold">const</span><span style="color: #bbbbbb"> </span>inst<span style="color: #bbbbbb"> </span><span style="color: #666666">=</span><span style="color: #bbbbbb"> </span>tcm.getInstance(<span style="color: #008000; font-weight: bold">this</span>.suzanne);
tcm.setTransform(inst,<span style="color: #bbbbbb"> </span><span style="color: #008000; font-weight: bold">this</span>.trackball.getMatrix());
inst.<span style="color: #AA22FF; font-weight: bold">delete</span>();
</pre></div>
<p>That&#x27;s it, we now have a fast-loading interactive demo. The complete JavaScript file is available

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