Compare commits

..

152 Commits

Author SHA1 Message Date
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
29983772ed Release Filament 1.31.5 2023-02-21 13:16:09 -08:00
ViktorHeisenberger
d100e628c2 Invoke ccache on Win+ninja. There is no support for ENV vars. (#6582) 2023-02-21 09:19:03 -08:00
Mathias Agopian
94f121f37d Add a camera near/far setting in gltf_viewer 2023-02-17 11:16:42 -08:00
Mathias Agopian
d9266ba61c fix a main camera far plane culling
we need to use the culling projection matrix for culling!
2023-02-16 15:40:32 -08:00
Ben Doherty
8389056d2d gltfio: Fix crash when a MIME type has no texture provider (#6569) 2023-02-16 14:21:26 -08:00
Powei Feng
26b8cb238a Add build.sh flag for ASAN/UBSAN (#6566) 2023-02-16 13:19:32 -08:00
Powei Feng
f8d4690cd8 Update linux-continuous.yml to use ubuntu-22.04 (#6559) 2023-02-14 16:47:02 -08:00
Benjamin Doherty
c2e2f80945 Fix RELEASE_NOTES.md 2023-02-14 14:10:40 -08:00
Powei Feng
e9efcdf191 -Werror for libfilament and backend (#6547) 2023-02-14 01:15:25 -08:00
Mathias Agopian
8ea159520d workaround our -ffast-math
We use isnan() to detect that the estimation of directional light
parameters from the IBL has failed, however isnan() always returns
false with -ffast-math, which we're using in release builds.
This works around that. The affected code is non essential, performance
is not a concern here.
2023-02-13 21:51:43 -08:00
Mathias Agopian
337e18051a The default render channel is now 2 instead of 0
This also fixes some potential issues with refraction when using
render channels.
2023-02-13 17:31:34 -08:00
Ben Doherty
3c4e094990 Rework how release notes work (#6557) 2023-02-13 14:54:07 -08:00
Powei Feng
71e6f3d037 Update linux clang to version 10 (#6556) 2023-02-13 14:49:45 -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
d2690bf75a Release Filament 1.31.4 2023-02-13 11:51:06 -08:00
Ben Doherty
44f002a5a1 gltfio: Fix race condition affecting mobile and web (#6548)
When loading a glTF file on platforms without a filesystem, a client
calls `addResourceData` to populate `ResourceLoader`'s cache with data.
For example, a web client might make HTTP fetch requests to fill in
buffer data. This internal cache of data is stored in
`ResourceLoader::Impl::mUriDataCache`.

This works well, except the cache must persist until after it has been
uploaded to the GPU.

There was already a mechanism (see `uploadUserdata`) in place to ensure
that glTF data persisted until after it had been uploaded to the GPU.
However, this mechanism did not extend to client-provided data. Thus, a
race occured between Filament's driver consuming the buffer and it
getting freed.
2023-02-13 10:44:22 -08:00
Powei Feng
f8442c9ec0 vulkan: Remove unused presentQueueFamilyIndex (#6545) 2023-02-10 12:41:00 -08:00
Powei Feng
b3513c7d1f geometry: Add TangentSpaceMesh implementations (#6530)
geometry: Add TangentSpaceMesh implementations

Added:
 - Hughes-Moller
 - Frisvad's method
 - Flat shading
2023-02-10 09:34:49 -08:00
Mathias Agopian
a82e813333 fix libmath streaming operators 2023-02-09 16:11:30 -08:00
Powei Feng
dd246aeee4 vulkan: Assert that graphics-QF is present-QF (#6540) 2023-02-09 13:31:29 -08:00
Ben Doherty
1653d3615b Fix Metal crash due to empty program names (#6537) 2023-02-09 12:11:04 -08:00
Mathias Agopian
4847b00f9e improve SoA a bit
Instead of storing the arrays into an array of void*, we use a 
tuple<> instead. This improves debugging because now the tuple<>
has pointer with the correct types.

It also improves most of the code except `push_back` which now
relies on a hack -- this is the only place where I'm not able to 
resolve the array strictly at compile time, even if in practice it is.
2023-02-08 16:22:00 -08:00
Igor Korobka
d613145c1a Fix JNI after minification is applied
UbershaderProvider.getNativeObject() is accessed from AssetLoader.cpp,
so it must be annotated with @UsedByNative("AssetLoader.cpp") to
avoid runtime crashes when minification is applied.

Fixes #5944
2023-02-08 15:29:55 -08:00
ritik619
a788f66e18 Fixed typographic error 2023-02-08 12:01:50 -08:00
Romain Guy
9ca3a7456c Fix JNI 2023-02-08 09:07:59 -08:00
Mathias Agopian
5cec001058 matdbg: direct SPIRV edit now supported 2023-02-03 13:57:44 -08:00
Mathias Agopian
2fb42f5144 matdbg: refresh spirv properly
we now refresh the spirv code properly after it's rebuilt from the
glsl tab.
2023-02-02 11:10:21 -08:00
Mathias Agopian
02c22a668c matdbg: make sure we use the same spirv parameters everywhere 2023-02-02 11:10:02 -08:00
Mathias Agopian
a7bf90f5be build.sh -d is now split in two options
`-d` now enables matdbg and adds debugging data, but doesn't affect 
 material optimization

`-g` disables material optimizations


A similar change is done with gradle options. The new proprety
`com.google.android.filament.matnopt` is used to disable material
optimizations.

These options mimic `matc` options.
2023-02-01 23:59:00 -08:00
Mathias Agopian
f71e90fae0 deduplicate spirv disassembly code 2023-02-01 21:12:53 -08:00
Mathias Agopian
8afb11128d move UibGenerator and SibGenerator to the shader folder
The shader folder is where we generate the glsl, so this is more
appropriate.
2023-02-01 21:12:53 -08:00
Mathias Agopian
2e0c238cc6 We now require Vulkan 1.1 for the vulkan backend 2023-02-01 21:10:26 -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
03b89b4327 Release Filament 1.31.3 2023-02-01 11:53:41 -08:00
Mathias Agopian
a878d1f39c improve sample_full_pbr
- -m option now works with "directory_*.png" or just "*.png"
- "color" replaced by "albedo" to mach other places in the source tree
- fixed warnings
- clear the background when IBL is not used
2023-02-01 10:04:02 -08:00
Mathias Agopian
4a09e13e9d fix a couple typos and consts.
make it easier to activate matdbg on android builds, by adding, but
commenting out the appropriate property.
2023-02-01 10:03:20 -08:00
Mathias Agopian
0b4d32bf98 matdbg: use GLSL 4.5 on desktop when debugging spirv
GLSL 4.5 is closer to spriv than 4.1 and since this is just to 
"interpret" the spirv, 4.5 is fine.

Set the default precision for GLES though.
2023-02-01 10:03:20 -08:00
Mathias Agopian
b940fc9c48 update remote ui 2023-01-31 20:55:23 -08:00
Koncz Levente
2eb0dd7153 Sample Full PBR fixes (#6490)
* Calculate view vector without using camera eye position

* Fix compilation error (during parsing the material when a height map is passed in)

* Add SUN light to the scene
2023-01-31 12:28:25 -08:00
Mathias Agopian
101c7db9a2 update remote ui 2023-01-31 09:52:37 -08:00
Mathias Agopian
032ace2051 Add output color space to ColorGrading settings 2023-01-31 09:46:22 -08:00
Mathias Agopian
5754b9907d Add support for sRGB swapchains
This change adds a 'SRGB' config flag when creating a SwapChain that
enables linear to sRGB conversion on write.

When using this flag, the linear->srgb conversion in the color grading
post processing should be disabled (or, the whole post-processing
stage should be disabled).

There is also a new query to determine if this flag is supported by
the underlaying platform.

On Metal, this happens automatically when the underlaying layer is sRGB.

This reverts commit 3799e219fc.
2023-01-31 09:29:02 -08:00
Mathias Agopian
ffb8203ae7 Fix typo in ColorSpace operator= 2023-01-30 21:35:51 -08:00
Powei Feng
906da033dd vulkan: Add fallback extent for swap chain sizing (#6495)
vulkan: Add fallback extent for swap chain sizing
2023-01-30 19:29:10 -08:00
daemyung danny jang
1077405bc1 Support Windows32 on bluegl as C backend (#6499) 2023-01-30 15:56:15 -08:00
daemyung danny jang
e37df8fc89 Include a header in alphabetical order (#6507) 2023-01-30 14:58:56 -08:00
Mathias Agopian
3799e219fc Revert "Add support for sRGB swapchains"
This reverts commit eab14da30e.

This broke macOS desktop (and maybe other GL platforms).
2023-01-30 11:20:18 -08:00
Mathias Agopian
eab14da30e Add support for sRGB swapchains
This change adds a 'SRGB' config flag when creating a SwapChain that
enables linear to sRGB conversion on write.

When using this flag, the linear->srgb conversion in the color grading
post processing should be disabled (or, the whole post-processing
stage should be disabled).

There is also a new query to determine if this flag is supported by
the underlaying platform.


On Metal, this happens automatically when the underlaying layer is sRGB.
2023-01-30 10:49:38 -08:00
Mathias Agopian
84e999fe57 cleanup PlatformEGL config selection code
We now structure the code to assume we have EGL_KHR_no_config_context,
which is the common case. This allows use to decouple context creation
from swapchain creation.

We still handle the case where the extension is not present by always
selecting a transparent config.
2023-01-30 10:49:38 -08:00
Mathias Agopian
f22ff6a340 the createSwapChain flag shouldn't be a reference 2023-01-30 10:49:38 -08:00
daemyung danny jang
d9d0b93306 Fix a build error (#6502) 2023-01-30 10:38:36 -08:00
Powei Feng
09248cd451 Destroy FilamentInstance's mRoot in EntityManager (#6500) 2023-01-27 16:05:42 -08:00
Koncz Levente
73880428dc Ortho shading fixes (#6453) 2023-01-27 09:36:56 -08:00
Ben Doherty
2a049d1324 Initialize object_uniforms in depth shader (#6492) 2023-01-26 16:23:14 -08:00
Powei Feng
51cbd74235 Add missing STL includes (#6496) 2023-01-26 16:07:58 -08:00
Powei Feng
45246b6109 geometry: Add TangentSpaceMesh class outline (#6476)
- Defined class with documentation in comments
 - Implemented algorithm selection
 - No actual algorithms written yet

Part of google/filament#6358
2023-01-26 14:39:48 -08:00
Ben Doherty
d3956adca8 matdbg: take desktop/mobile into account for SPIR-V to GLSL translation (#6488) 2023-01-26 11:30:51 -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
298e54c32a Release Filament 1.31.2 2023-01-24 14:26:22 -08:00
Ben Doherty
4c82f0259d Add systrace support on Apple platforms (#6480) 2023-01-23 14:11:47 -08:00
Mathias Agopian
d0c043c7ff implement draw command channels
There can be up to 4 channels drawing commands can be associated to. 
Channels work like "priorities" except it's the strongest command ordering 
key, in particular it takes precedence over the object's blending mode.
2023-01-23 13:47:41 -08:00
Powei Feng
20cbecfd7c vulkan: put getEnabledLayers behind VK_ENABLE_VALIDATION (#6474) 2023-01-18 18:38:53 -08:00
Powei Feng
194defdb1b vulkan: Fix readPixels memory leak (#6473) 2023-01-18 16:35:58 -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
Benjamin Doherty
5017cbe67e Release Filament 1.31.1 2023-01-18 14:23:21 -08:00
Ben Doherty
4c4201cb72 Update check-headers script to ignore platform headers (#6472) 2023-01-18 13:53:45 -08:00
Powei Feng
3ee635f8e4 Fix enabledLayers (#6467)
instanceCreateInfo should not take stack-allocated data
2023-01-18 13:50:10 -08:00
Ben Doherty
4c2dabffd6 Vulkan: fix stack-use-after-scope ASAN error in VulkanContext.cpp (#6463) 2023-01-18 12:00:08 -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
Mathias Agopian
185c83dae2 Fix a crash on Vulkan with some Adreno drivers
We were using a specialization constant to size an array inside an
UBO interface block, which caused the crash in the Vulkan driver.

However, this specialization constant was only used to workaround a
Chrome bug on WebGL. Additionally, specialized array size inside blocks
are not fully supported in spirv.

This workaround simply replaces the specialization constant by a 
constant on Vulkan.

Fix #6444
2023-01-18 10:36:43 -08:00
Mathias Agopian
15d124b225 disable KHR_debug messages
there were never useful and in fact harmful, because confusing to our
users.
2023-01-18 10:35:48 -08:00
Mathias Agopian
9c474c5b08 remove too verbose log when auto-instancing 2023-01-18 10:35:31 -08:00
Mathias Agopian
f92f283e00 Fix a typo with auto instancing
fixes b/265831206
2023-01-17 16:42:26 -08:00
Mathias Agopian
f6b94614e8 Make all OpenGLPlatform related interfaces public
- Remove DefaultPlatform from public headers
DefaultPlatform is now PlatormFactory and is just an implementation
detail.

- VulkanPlatform is now public
- Improvements to the OpenGLPlatform interface
- Cleanup PlatformEGL and PlatformEGLAndroid

Also:

- reworked how external image worked so that all the implementation
  is contained in the Platform and no dependency to the backend is
  needed.

- MetalPlatform is now entirely private and final

This is because MetalPlatform wasn't an interface. We probably need one
so it could be customized in the future. But as it stands now it's
better to be private.
2023-01-17 16:39:44 -08:00
Powei Feng
e54d8ec0a4 [vulkan] enumerate: Returning size = 0 is ok (#6450) 2023-01-17 10:14:45 -08:00
Ben Doherty
978517b057 Update actions/checkout version (#6454) 2023-01-17 09:59:19 -08:00
Levente Koncz
d911640809 Attempt to fix skybox shader in ORTHO view 2023-01-13 16:29:08 -08:00
Mathias Agopian
473e610430 reenable compute in the GL backend
We do some shenanigans so it works with API < 21 on android.
2023-01-13 16:00:56 -08:00
Mathias Agopian
3b9b725406 fix dynamic lighting with custom projections
Forxelization made many assumptions about the shape of the projection
matrix, the gist of these fixes is to remove those assumptions.

Fix #6390
2023-01-13 11:36:44 -08:00
Mathias Agopian
fa742bc6bf fix typos 2023-01-13 11:36:44 -08:00
Romain Guy
6a02dd0993 Update to Android Studio Electric Eel and AGP 7.4.0 (#6456) 2023-01-13 08:21:03 -08:00
Powei Feng
243d10f864 [vulkan] enumerate: Returning size = 0 is ok (#6450) 2023-01-12 12:56:34 -08:00
Romain Guy
bbe46071f3 Update Android dependencies (#6452) 2023-01-12 10:02:18 -08:00
Ben Doherty
8ded184ea3 Metal: add labels to aid debugging (#6451) 2023-01-12 09:55:43 -08:00
Romain Guy
ce407ba844 Fix typo 2023-01-11 08:48:04 -08:00
Powei Feng
ddb6a7fa93 Update Linux build instructions (#6438) 2023-01-10 16:42:44 -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
72bba47880 Release Filament 1.31.0 2023-01-10 12:50:17 -05:00
Ben Doherty
0c38b1e3f9 Add SPIR-V debugging guide (#6405) 2023-01-09 13:15:41 -08:00
Powei Feng
8de3de235b Refactor VulkanContext/Driver initialization (#6429)
* Refactor VulkanContext/Driver initialization

Move the initialization of VulkanContext fields to the class
itself. This will clean up how the various extension support
flags are deteremined.

Also disable debugUtils extension for Mesa driver (#6192).
2023-01-09 12:51:49 -08:00
Romain Guy
24e1eef56e Fix glTF volumes 2023-01-05 17:38:16 -08:00
Powei Feng
378fb92434 Re-land #1 "[vulkan] Refactor vkEnumerate methods (#6423)" (#6426)
* Re-land #1 "[vulkan] Refactor vkEnumerate methods (#6423)"

This reverts commit 6f7d203adb.
The above commit (6f7d20) is the revert of #6423. Commit
6f7d20 is PR #6425.

"[vulkan] Refactor vkEnumerate methods (#6423)" failed [here] due to
a missing function attribute (VKAPI_ATTR in bluevk) for ARM64
compilers.

[here]: https://github.com/google/filament/actions/runs/3841550984
2023-01-05 11:45:25 -08:00
daemyung danny jang
c7c184d952 Make a small optimization on drop event at filament app (#6424) 2023-01-05 08:38:28 -08:00
Powei Feng
6f7d203adb Revert "[vulkan] Refactor vkEnumerate methods (#6423)" (#6425)
This reverts commit 8d608830d4.

Reason: broke Android build -> https://github.com/google/filament/actions/runs/3841550984
2023-01-04 15:16:23 -08:00
Po
8d608830d4 [vulkan] Refactor vkEnumerate methods (#6423)
* [vulkan] Refactor vkEnumerate methods

Use templates to help clean up the enumeration a bit.
2023-01-04 12:58:18 -08:00
daemyung danny jang
6734dc6f43 Create a path from a string view (#6406) 2023-01-03 09:36:41 -08:00
Po
5343d504c4 [vulkan] Break when desired layer is found (#6403) 2022-12-21 13:29:26 -08:00
Nick Fisher
f8684beba2 expose joint inverse bind matrices via method on FilamentInstance (#6388)
* expose joint inverse bind matrices via method on FilamentInstance

* change const pointer refs, add asserts and update release notes

Co-authored-by: Mathias Agopian <mathias@google.com>
2022-12-20 15:19:19 -08:00
Po
c88277a898 [filamesh] Add option to skip secondary UV coords (#6398)
Also added error and exit for when there's a mismatch in the
number of vertices vs. the number of UV coords (either primary or
secondary).
2022-12-20 14:14:31 -08:00
Romain Guy
1f0b988472 Add Filamesh template for Hex Fiend 2022-12-20 10:07:33 -08:00
Romain Guy
60c264a2e7 Add Hex Fiend template for filamesh files 2022-12-20 10:01:56 -08:00
Benjamin Doherty
e5e3dff9fa Fix Windows CI build 2022-12-20 11:01:49 -07:00
Benjamin Doherty
7724219f1e Fix Windows CI build 2022-12-20 11:01:10 -07:00
Ben Doherty
1d5ce4d1c2 Update spirv-tools to 025ea89 (#6393) 2022-12-19 15:42:42 -08:00
Mathias Agopian
9ff4a311ef fix typos 2022-12-19 15:22:49 -08:00
Benjamin Doherty
c5a59bb6b1 Bump version to 1.31.0 2022-12-19 11:14:41 -08:00
Benjamin Doherty
2f0bdd9c39 Release Filament 1.30.0 2022-12-19 11:11:45 -08:00
Ben Doherty
e1ba37b910 Fix memory leak in Scene (#6387) 2022-12-16 14:39:01 -08:00
Mathias Agopian
7448e7c3c5 CMakeLists minor cleanup 2022-12-15 15:19:31 -08:00
Mathias Agopian
ee6612ecfa Workaround for a bug in Adreno's shader compiler
At least some adreno compilers don't like returning an element of a
UBO array that is a structure in the vertex shader.
To work this around we have to copy the each of the structure fields.

Fixes #6355
2022-12-14 15:39:18 -08:00
Mathias Agopian
aa5504aad3 auto instancing wasn't applied in Settings. 2022-12-14 00:52:37 -08:00
Mathias Agopian
1523edd519 attempt to fix helmet web sample 2022-12-14 00:11:18 -08:00
Mathias Agopian
190d6faa67 attempt to fix web demos #4 2022-12-13 23:17:44 -08:00
Mathias Agopian
9f97ff4ced 3rd attempt at fixing web demos 2022-12-13 23:08:22 -08:00
Mathias Agopian
989e6c9198 2nd attempt at fixing the web demos 2022-12-13 22:54:29 -08:00
Mathias Agopian
9c19e746a4 attempt to fix webgl demos 2022-12-13 22:38:00 -08:00
Mathias Agopian
0a20be7097 update docs/remote 2022-12-13 22:25:17 -08:00
Mathias Agopian
0d72a0904b getNormalizedViewportCoord() now returns the logical viewport coords
This is a better user-facing API because materials don't need to know
about the physical viewport.
2022-12-13 16:37:49 -08:00
Romain Guy
7f9e7a4566 Update Web demos 2022-12-13 15:04:12 -08:00
Mathias Agopian
48d9f44291 Handle Vulkan and Metal shadow coordinates in the same way
Vulkan and Metal should be handled exactly the same within filament,
when it comes to texture-space and clip-space because filament
always transforms vulkan's clip-space to gl's/metal's).

Our shadow code took different paths, both equivalent though, but it's
confusing.
2022-12-12 15:21:35 -08:00
Mathias Agopian
b5d197dfe3 Fix unused variables in release builds 2022-12-12 12:30:33 -08:00
Mathias Agopian
1d387d04fd add a debug option for Renderer's buffer padding 2022-12-12 11:18:17 -08:00
Mathias Agopian
4215ba6476 code cleanup
fix new code quality warnings enabled by CLion
2022-12-09 11:05:26 -08:00
Mathias Agopian
5b2a92a5c4 fix a typo that caused a wrong allocation size
this only affect the WebGL build's readPixels.
2022-12-09 10:52:24 -08:00
Mathias Agopian
9661cd4c3a fix a race condition with acquired streams
The race coud lead to user after free and crashes.

We now keep a list of acquired streams with pending images on the 
main thread, and use that to update the streams synchronously in
beginFrame. We can then enqueue a command for the driver thread that
will look for that stream in the active list of textures with stream
attached. Race avoided.


The previous code used the later list from both threads.
2022-12-08 16:19:11 -08:00
Balazs Vegh
cc2580230f Add fallback return to uintToColorDebug() (#6364) 2022-12-08 09:00:23 -08:00
Romain Guy
2a69a892b0 Add TS definition for Engine.destroy (#6359)
* Add TS definition for Engine.destroy

* Update release notes
2022-12-07 16:18:45 -08:00
Mathias Agopian
34e5865941 fix TransformManager high precision mode
The residual would be corrupted when using transactions.
2022-12-06 14:18:33 -08:00
Mathias Agopian
07464c967b Add missing Scene::getIndirectLight()
Also add missing getSkybox in js bindings
2022-12-06 11:19:43 -08:00
Koncz Levente
c2fcaf7a6b Add RGTC + BPTC support (#6320)
* Add RGTC support
* Add BPTC support
2022-12-06 11:18:35 -08:00
Mathias Agopian
d8c9391498 fix clear options
When more than one view was used, only the first view was cleared with
the ClearOption. This was actually intended when the views are rendering
into the swapchain (e.g. post process disabled), but that's incorrect 
when the views render into intermediate buffers.

The clear flags are now associated with the actual rendertarget.
2022-12-02 15:24:40 -08:00
Romain Guy
78554d2319 Add new outputColorSpace() API to ColorGrading (#6342)
* Add new outputColorSpace() API to ColorGrading

This allows the application to select the desired output color space.
The default is set to Rec709-sRGB-D65 ("sRGB") but can be changed to
Rec709-Linear-D65.

Currently only the transfer function is taken into account and must
be either sRGB or Linear. Future updates will add support for
different gamuts and white points.

* Update release notes
2022-12-01 17:00:30 -08:00
Mathias Agopian
c2711d643e minor code cleanup 2022-12-01 09:37:10 -08:00
Mathias Agopian
913e3d32ee fix viewtest
- it didn't clear the swapchain
- added support for `-a` option
2022-12-01 09:36:46 -08:00
Mathias Agopian
f0b9c5fff4 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:27:55 -08:00
ThomasGorisse
fe67404fd5 Fix typo in LightManager documentation 2022-11-28 14:56:22 -08:00
ThomasGorisse
555ed96918 Fix confusing typo in Camera documentation 2022-11-28 14:56:22 -08:00
Mathias Agopian
fc74154ffe 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-11-28 14:07:04 -08:00
Mathias Agopian
74e8ddaf95 Directional shadow improvements
Use a much more precise way to calculate the directional shadow frustum.
With very large scenes, we were losing the precision on the direction
of the light, and in some case even producing NaN in the matrix.

This partially addresses #6293
2022-11-28 10:25:06 -08:00
Benjamin Doherty
f05c7f1141 Fix CI build 2022-11-22 13:49:59 -08:00
ViktorHeisenberger
565d385132 Use Frisvad's method to compute tangent space from normals-only mesh input (#6313)
* Change tangent basis computation for normals-only to Frisvad's method

* Update RELEASE_NOTES.md
2022-11-22 09:30:37 -08:00
961 changed files with 161449 additions and 126892 deletions

View File

@@ -13,7 +13,7 @@ jobs:
runs-on: macos-latest
steps:
- uses: actions/checkout@v2.0.0
- uses: actions/checkout@v3.3.0
- name: Run build script
run: |
cd build/android && printf "y" | ./build.sh continuous

View File

@@ -13,7 +13,7 @@ jobs:
runs-on: macos-latest
steps:
- uses: actions/checkout@v2.0.0
- uses: actions/checkout@v3.3.0
- name: Run build script
run: |
cd build/ios && printf "y" | ./build.sh continuous

View File

@@ -10,10 +10,10 @@ on:
jobs:
build-linux:
name: build-linux
runs-on: ubuntu-18.04
runs-on: ubuntu-22.04
steps:
- uses: actions/checkout@v2.0.0
- uses: actions/checkout@v3.3.0
- name: Run build script
run: |
cd build/linux && printf "y" | ./build.sh continuous

View File

@@ -13,7 +13,7 @@ jobs:
runs-on: macos-latest
steps:
- uses: actions/checkout@v2.0.0
- uses: actions/checkout@v3.3.0
- name: Run build script
run: |
cd build/mac && printf "y" | ./build.sh continuous

View File

@@ -15,10 +15,10 @@ jobs:
strategy:
matrix:
os: [macos-latest, ubuntu-18.04]
os: [macos-latest, ubuntu-22.04]
steps:
- uses: actions/checkout@v2.0.0
- uses: actions/checkout@v3.3.0
- name: Run build script
run: |
WORKFLOW_OS=`echo \`uname\` | sed "s/Darwin/mac/" | tr [:upper:] [:lower:]`
@@ -32,7 +32,7 @@ jobs:
runs-on: windows-2019
steps:
- uses: actions/checkout@v2.0.0
- uses: actions/checkout@v3.3.0
- name: Run build script
run: |
build\windows\build-github.bat presubmit
@@ -43,7 +43,7 @@ jobs:
runs-on: macos-latest
steps:
- uses: actions/checkout@v2.0.0
- uses: actions/checkout@v3.3.0
- name: Run build script
run: |
cd build/android && printf "y" | ./build.sh presubmit
@@ -53,7 +53,7 @@ jobs:
runs-on: macos-latest
steps:
- uses: actions/checkout@v2.0.0
- uses: actions/checkout@v3.3.0
- name: Run build script
run: |
cd build/ios && printf "y" | ./build.sh presubmit
@@ -66,7 +66,7 @@ jobs:
runs-on: macos-latest
steps:
- uses: actions/checkout@v2.0.0
- uses: actions/checkout@v3.3.0
- name: Run build script
run: |
cd build/web && printf "y" | ./build.sh presubmit

View File

@@ -31,7 +31,7 @@ jobs:
strategy:
matrix:
os: [macos-latest, ubuntu-18.04]
os: [macos-latest, ubuntu-22.04]
steps:
- name: Decide Git ref
@@ -41,7 +41,7 @@ jobs:
TAG=${REF##*/}
echo "ref=${REF}" >> $GITHUB_OUTPUT
echo "tag=${TAG}" >> $GITHUB_OUTPUT
- uses: actions/checkout@v2.0.0
- uses: actions/checkout@v3.3.0
with:
ref: ${{ steps.git_ref.outputs.ref }}
- name: Run build script
@@ -76,7 +76,7 @@ jobs:
TAG=${REF##*/}
echo "ref=${REF}" >> $GITHUB_OUTPUT
echo "tag=${TAG}" >> $GITHUB_OUTPUT
- uses: actions/checkout@v2.0.0
- uses: actions/checkout@v3.3.0
with:
ref: ${{ steps.git_ref.outputs.ref }}
- name: Run build script
@@ -109,7 +109,7 @@ jobs:
TAG=${REF##*/}
echo "ref=${REF}" >> $GITHUB_OUTPUT
echo "tag=${TAG}" >> $GITHUB_OUTPUT
- uses: actions/checkout@v2.0.0
- uses: actions/checkout@v3.3.0
with:
ref: ${{ steps.git_ref.outputs.ref }}
- name: Run build script
@@ -160,7 +160,7 @@ jobs:
TAG=${REF##*/}
echo "ref=${REF}" >> $GITHUB_OUTPUT
echo "tag=${TAG}" >> $GITHUB_OUTPUT
- uses: actions/checkout@v2.0.0
- uses: actions/checkout@v3.3.0
with:
ref: ${{ steps.git_ref.outputs.ref }}
- name: Run build script
@@ -194,7 +194,7 @@ jobs:
echo "ref=${REF}" >> $GITHUB_OUTPUT
echo "tag=${TAG}" >> $GITHUB_OUTPUT
shell: bash
- uses: actions/checkout@v2.0.0
- uses: actions/checkout@v3.3.0
with:
ref: ${{ steps.git_ref.outputs.ref }}
- name: Run build script

View File

@@ -24,3 +24,4 @@ jobs:
with:
repo-token: ${{ secrets.GITHUB_TOKEN }}
pull-request-number: ${{ github.event.pull_request.number }}
release-notes-file: 'NEW_RELEASE_NOTES.md'

View File

@@ -13,7 +13,7 @@ jobs:
runs-on: macos-latest
steps:
- uses: actions/checkout@v2.0.0
- uses: actions/checkout@v3.3.0
- name: Run build script
run: |
cd build/web && printf "y" | ./build.sh continuous

View File

@@ -13,7 +13,7 @@ jobs:
runs-on: windows-2019
steps:
- uses: actions/checkout@v2.0.0
- uses: actions/checkout@v3.3.0
- name: Run build script
run: |
build\windows\build-github.bat continuous

View File

@@ -92,6 +92,8 @@ Make sure you've installed the following dependencies:
- `libc++abi-7-dev` (`libcxxabi-static` on Fedora) or higher
- `ninja-build`
- `libxi-dev`
- `libxcomposite-dev` (`libXcomposite-devel` on Fedora)
- `libxxf86vm-dev` (`libXxf86vm-devel` on Fedora)
After dependencies have been installed, we highly recommend using the [easy build](#easy-build)
script.

View File

@@ -31,6 +31,8 @@ option(FILAMENT_SKIP_SDL2 "Skip dependencies of SDL2, and SDL2" OFF)
option(FILAMENT_LINUX_IS_MOBILE "Treat Linux as Mobile" OFF)
option(FILAMENT_ENABLE_ASAN_UBSAN "Enable Address and Undefined Behavior Sanitizers" OFF)
set(FILAMENT_NDK_VERSION "" CACHE STRING
"Android NDK version or version prefix to be used when building for Android."
)
@@ -67,25 +69,30 @@ endif()
# ==================================================================================================
find_program(CCACHE_PROGRAM ccache)
if (CCACHE_PROGRAM)
set(C_LAUNCHER "${CCACHE_PROGRAM}")
set(CXX_LAUNCHER "${CCACHE_PROGRAM}")
configure_file(build/launch-c.in launch-c)
configure_file(build/launch-cxx.in launch-cxx)
execute_process(COMMAND chmod a+rx
"${CMAKE_CURRENT_BINARY_DIR}/launch-c"
"${CMAKE_CURRENT_BINARY_DIR}/launch-cxx"
)
if (CMAKE_GENERATOR STREQUAL "Xcode")
set(CMAKE_XCODE_ATTRIBUTE_CC "${CMAKE_CURRENT_BINARY_DIR}/launch-c")
set(CMAKE_XCODE_ATTRIBUTE_CXX "${CMAKE_CURRENT_BINARY_DIR}/launch-cxx")
set(CMAKE_XCODE_ATTRIBUTE_LD "${CMAKE_CURRENT_BINARY_DIR}/launch-c")
set(CMAKE_XCODE_ATTRIBUTE_LDPLUSPLUS "${CMAKE_CURRENT_BINARY_DIR}/launch-cxx")
if (WIN32)
set(CMAKE_C_COMPILER_LAUNCHER "${CCACHE_PROGRAM}")
set(CMAKE_CXX_COMPILER_LAUNCHER "${CCACHE_PROGRAM}")
else()
set(CMAKE_C_COMPILER_LAUNCHER "${CMAKE_CURRENT_BINARY_DIR}/launch-c")
set(CMAKE_CXX_COMPILER_LAUNCHER "${CMAKE_CURRENT_BINARY_DIR}/launch-cxx")
set(C_LAUNCHER "${CCACHE_PROGRAM}")
set(CXX_LAUNCHER "${CCACHE_PROGRAM}")
configure_file(build/launch-c.in launch-c)
configure_file(build/launch-cxx.in launch-cxx)
execute_process(COMMAND chmod a+rx
"${CMAKE_CURRENT_BINARY_DIR}/launch-c"
"${CMAKE_CURRENT_BINARY_DIR}/launch-cxx"
)
if (CMAKE_GENERATOR STREQUAL "Xcode")
set(CMAKE_XCODE_ATTRIBUTE_CC "${CMAKE_CURRENT_BINARY_DIR}/launch-c")
set(CMAKE_XCODE_ATTRIBUTE_CXX "${CMAKE_CURRENT_BINARY_DIR}/launch-cxx")
set(CMAKE_XCODE_ATTRIBUTE_LD "${CMAKE_CURRENT_BINARY_DIR}/launch-c")
set(CMAKE_XCODE_ATTRIBUTE_LDPLUSPLUS "${CMAKE_CURRENT_BINARY_DIR}/launch-cxx")
else()
set(CMAKE_C_COMPILER_LAUNCHER "${CMAKE_CURRENT_BINARY_DIR}/launch-c")
set(CMAKE_CXX_COMPILER_LAUNCHER "${CMAKE_CURRENT_BINARY_DIR}/launch-cxx")
endif()
endif()
endif()
@@ -374,10 +381,10 @@ endif()
# ==================================================================================================
# Debug compiler flags
# ==================================================================================================
# ASAN is deactivated for now because:
# -fsanitize=undefined causes extremely long link times
# -fsanitize=address causes a crash with assimp, which we can't explain for now
#set(EXTRA_SANITIZE_OPTIONS "-fsanitize=undefined -fsanitize=address")
if (FILAMENT_ENABLE_ASAN_UBSAN)
set(EXTRA_SANITIZE_OPTIONS "-fsanitize=address -fsanitize=undefined")
endif()
if (NOT MSVC AND NOT WEBGL)
set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -fstack-protector")
endif()
@@ -497,9 +504,14 @@ if (FILAMENT_SUPPORTS_METAL)
set(MATC_API_FLAGS ${MATC_API_FLAGS} -a metal)
endif()
# Disable optimizations and enable debug info (preserves names in SPIR-V)
# Enable debug info (preserves names in SPIR-V)
if (FILAMENT_ENABLE_MATDBG)
set(MATC_OPT_FLAGS ${MATC_OPT_FLAGS} -d)
endif()
# Disable optimizations
if (FILAMENT_DISABLE_MATOPT)
set(MATC_OPT_FLAGS -gd)
set(MATC_OPT_FLAGS ${MATC_OPT_FLAGS} -g)
endif()
set(MATC_BASE_FLAGS ${MATC_API_FLAGS} -p ${MATC_TARGET} ${MATC_OPT_FLAGS})
@@ -554,7 +566,7 @@ function(list_licenses OUTPUT MODULES)
endif()
endforeach()
configure_file(${FILAMENT}/build/licenses.inc.in ${OUTPUT})
endfunction(list_licenses)
endfunction()
set(COMBINE_SCRIPT "${CMAKE_CURRENT_SOURCE_DIR}/build/linux/combine-static-libs.sh")
if (WIN32)

10
NEW_RELEASE_NOTES.md Normal file
View File

@@ -0,0 +1,10 @@
# Filament Release Notes log
**If you are merging a PR into main**: please add the release note below, under the *Release notes
for next branch cut* header.
**If you are cherry-picking a commit into an rc/ branch**: add the release note under the
appropriate header in [RELEASE_NOTES.md](./RELEASE_NOTES.md).
## Release notes for next branch cut

View File

@@ -31,7 +31,7 @@ repositories {
}
dependencies {
implementation 'com.google.android.filament:filament-android:1.30.0'
implementation 'com.google.android.filament:filament-android:1.31.6'
}
```
@@ -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.30.0'
pod 'Filament', '~> 1.31.6'
```
### Snapshots

View File

@@ -3,7 +3,49 @@
This file contains one line summaries of commits that are worthy of mentioning in release notes.
A new header is inserted each time a *tag* is created.
## main branch
**Do not edit this file unless you are performing a release or cherry-picking into an rc/ branch.**
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.31.6
- engine: the default render channel is now 2 instead of 0
- gltfio: Fix crash when a MIME type has no texture provider
## v1.31.5
- gltfio: fix potential early freeing of data provided with `ResourceLoader::addResourceData`.
## v1.31.4
- engine: fix broken picking [⚠️ **Recompile Materials to get the fix**]
- engine: added support for sRGB swapchains. See `SwapChain.h`
- bluegl: support Windows32
## v1.31.3
- vulkan: fix memory leak in readPixels
- engine: added support for draw-commands channels (stronger ordering of commands/renderables)
## v1.31.2
## v1.31.1
- gltfio: expose joint inverse bind matrices via method on FilamentInstance
- filamesh: add error when uv coords size does not match num of vertices. (#6351)
## v1.31.0
- java: fix confusing typo in Camera documentation
- engine: the output color space can be set on `ColorGrading`. This API currently has limitations,
please refer to the documentation for more details
- Support for RGTC and BPTC texture compression
- engine: fix TransformManager high precision mode when using transactions
- web: added TypeScript definition for `Engine.destroy`
- materials: `getNormalizedViewportCoord()` now returns the logical (i.e. user) viewport
normalized position and keeps z reversed [⚠️ **Recompile Materials**]
- backend: workaround Adreno shader compiler bug (#6355) [⚠️ **Recompile Materials**]
- geometry: change computing tangent basis from normal vector to use Frisvad's method
## v1.30.0
@@ -21,6 +63,7 @@ A new header is inserted each time a *tag* is created.
## v1.28.3
- backend: add support for GGP platform
- engine: primitives with `CullingMode::FRONT_AND_BACK` are now skipped.

View File

@@ -12,7 +12,10 @@
// When set, support for Vulkan will be excluded.
//
// com.google.android.filament.matdbg
// When set, enables matdbg, disables shader optimizations
// When set, enables matdbg
//
// com.google.android.filament.matnopt
// When set, disable shader optimizations.
//
// com.google.android.filament.skip-samples
// Exclude samples from the project. Useful to speed up compilation.
@@ -62,6 +65,10 @@ buildscript {
.gradleProperty("com.google.android.filament.matdbg")
.isPresent()
def matnopt = providers
.gradleProperty("com.google.android.filament.matnopt")
.isPresent()
def abis = ["arm64-v8a", "armeabi-v7a", "x86_64", "x86"]
def newAbis = providers
.gradleProperty("com.google.android.filament.abis")
@@ -75,9 +82,9 @@ buildscript {
'minSdk': 19,
'targetSdk': 33,
'compileSdk': 33,
'kotlin': '1.7.10',
'kotlin_coroutines': '1.6.1',
'buildTools': '33.0.0',
'kotlin': '1.8.0',
'kotlin_coroutines': '1.6.4',
'buildTools': '33.0.1',
'ndk': '25.1.8937393',
'androidx_core': '1.9.0',
'androidx_annotations': '1.3.0'
@@ -96,8 +103,7 @@ buildscript {
]
dependencies {
// NOTE: See TODO in gradle.properties once we move to Gradle 7.4
classpath 'com.android.tools.build:gradle:7.3.0'
classpath 'com.android.tools.build:gradle:7.4.0'
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:${versions.kotlin}"
}
@@ -109,7 +115,7 @@ buildscript {
"-DFILAMENT_DIST_DIR=${filamentPath}".toString(),
"-DFILAMENT_SUPPORTS_VULKAN=${excludeVulkan ? 'OFF' : 'ON'}".toString(),
"-DFILAMENT_ENABLE_MATDBG=${matdbg ? 'ON' : 'OFF'}".toString(),
"-DFILAMENT_DISABLE_MATOPT=${matdbg ? 'ON' : 'OFF'}".toString()
"-DFILAMENT_DISABLE_MATOPT=${matnopt ? 'ON' : 'OFF'}".toString()
]
ext.cppFlags = [

View File

@@ -150,6 +150,13 @@ Java_com_google_android_filament_RenderableManager_nBuilderPriority(JNIEnv*, jcl
builder->priority((uint8_t) priority);
}
extern "C" JNIEXPORT void JNICALL
Java_com_google_android_filament_RenderableManager_nBuilderChannel(JNIEnv*, jclass,
jlong nativeBuilder, jint channel) {
RenderableManager::Builder *builder = (RenderableManager::Builder *) nativeBuilder;
builder->channel((uint8_t) channel);
}
extern "C" JNIEXPORT void JNICALL
Java_com_google_android_filament_RenderableManager_nBuilderCulling(JNIEnv*, jclass,
jlong nativeBuilder, jboolean enabled) {
@@ -339,6 +346,13 @@ Java_com_google_android_filament_RenderableManager_nSetPriority(JNIEnv*, jclass,
rm->setPriority((RenderableManager::Instance) i, (uint8_t) priority);
}
extern "C" JNIEXPORT void JNICALL
Java_com_google_android_filament_RenderableManager_nSetChannel(JNIEnv*, jclass,
jlong nativeRenderableManager, jint i, jint channel) {
RenderableManager *rm = (RenderableManager *) nativeRenderableManager;
rm->setChannel((RenderableManager::Instance) i, (uint8_t) channel);
}
extern "C" JNIEXPORT void JNICALL
Java_com_google_android_filament_RenderableManager_nSetCulling(JNIEnv*, jclass,
jlong nativeRenderableManager, jint i, jboolean enabled) {

View File

@@ -16,6 +16,7 @@
#include <jni.h>
#include <filament/Engine.h>
#include <filament/SwapChain.h>
#include "common/CallbackUtils.h"
@@ -32,3 +33,9 @@ Java_com_google_android_filament_SwapChain_nSetFrameCompletedCallback(JNIEnv* en
JniCallback::postToJavaAndDestroy(callback);
}, callback);
}
extern "C" JNIEXPORT jboolean JNICALL
Java_com_google_android_filament_SwapChain_nIsSRGBSwapChainSupported(JNIEnv *, jclass, jlong nativeEngine) {
Engine* engine = (Engine*) nativeEngine;
return (bool)SwapChain::isSRGBSwapChainSupported(*engine);
}

View File

@@ -365,7 +365,7 @@ public class Camera {
* By default, this is an identity matrix.
* </p>
*
* @param scaling diagonal of the scaling matrix to be applied after the projection matrix.
* @param inScaling diagonal of the scaling matrix to be applied after the projection matrix.
*
* @see Camera#setProjection
* @see Camera#setLensProjection
@@ -409,7 +409,7 @@ public class Camera {
*
* <pre>
* engine.getTransformManager().setTransform(
* engine.getTransformManager().getInstance(camera->getEntity()), viewMatrix);
* engine.getTransformManager().getInstance(camera->getEntity()), modelMatrix);
* </pre>
*
* @param modelMatrix The camera position and orientation provided as a <b>rigid transform</b> matrix.

View File

@@ -1004,8 +1004,6 @@ public class LightManager {
* lightbulbs.
*
* @param efficiency Efficiency in percent. This depends on the type of lightbulb used.
*
* @return This Builder, for chaining calls.
*/
public void setIntensity(@EntityInstance int i, float watts, float efficiency) {
nSetIntensity(mNativeObject, i , watts, efficiency);

View File

@@ -257,23 +257,79 @@ public class RenderableManager {
* Provides coarse-grained control over draw order.
*
* <p>In general Filament reserves the right to re-order renderables to allow for efficient
* rendering. However clients can control ordering at a coarse level using <em>priority</em>.</p>
* rendering. However clients can control ordering at a coarse level using \em priority.
* The priority is applied separately for opaque and translucent objects, that is, opaque
* objects are always drawn before translucent objects regardless of the priority.</p>
*
* <p>For example, this could be used to draw a semitransparent HUD, if a client wishes to
* avoid using a separate View for the HUD. Note that priority is completely orthogonal to
* {@link Builder#layerMask}, which merely controls visibility.</p>
* <p>The Skybox always using the lowest priority, so it's drawn last, which may improve
* performance.</p>
*
* <p>The priority is clamped to the range [0..7], defaults to 4; 7 is lowest priority
* (rendered last).</p>
*
* @see Builder#blendOrder
*/
/**
* Provides coarse-grained control over draw order.
*
* <p>In general Filament reserves the right to re-order renderables to allow for efficient
* rendering. However clients can control ordering at a coarse level using priority.
* The priority is applied separately for opaque and translucent objects, that is, opaque
* objects are always drawn before translucent objects regardless of the priority.</p>
*
* <p>For example, this could be used to draw a semitransparent HUD, if a client wishes to
* avoid using a separate View for the HUD. Note that priority is completely orthogonal to
* {@link Builder#layerMask}, which merely controls visibility.</p>
* <p>The Skybox always using the lowest priority, so it's drawn last, which may improve
* performance.</p>
*
* @param priority clamped to the range [0..7], defaults to 4; 7 is lowest priority
* (rendered last).
*
* @return Builder reference for chaining calls.
*
* @see Builder#channel
* @see Builder#blendOrder
* @see #setPriority
* @see #setBlendOrderAt
*/
@NonNull
public Builder priority(@IntRange(from = 0, to = 7) int priority) {
nBuilderPriority(mNativeBuilder, priority);
return this;
}
/**
* Set the channel this renderable is associated to. There can be 4 channels.
*
* <p>All renderables in a given channel are rendered together, regardless of anything else.
* They are sorted as usual within a channel.</p>
* <p>Channels work similarly to priorities, except that they enforce the strongest
* ordering.</p>
*
* <p>Channels 0 and 1 may not have render primitives using a material with `refractionType`
* set to `screenspace`.</p>
*
* @param channel clamped to the range [0..3], defaults to 2.
*
* @return Builder reference for chaining calls.
*
* @see Builder::blendOrder()
* @see Builder::priority()
* @see RenderableManager::setBlendOrderAt()
*/
@NonNull
public Builder channel(@IntRange(from = 0, to = 3) int channel) {
nBuilderChannel(mNativeBuilder, channel);
return this;
}
/**
* Controls frustum culling, true by default.
*
@@ -655,6 +711,15 @@ public class RenderableManager {
nSetPriority(mNativeObject, i, priority);
}
/**
* Changes the channel of a renderable
*
* @see Builder#channel
*/
public void setChannel(@EntityInstance int i, @IntRange(from = 0, to = 3) int channel) {
nSetChannel(mNativeObject, i, channel);
}
/**
* Changes whether or not frustum culling is on.
*
@@ -876,6 +941,7 @@ public class RenderableManager {
private static native void nBuilderBoundingBox(long nativeBuilder, float cx, float cy, float cz, float ex, float ey, float ez);
private static native void nBuilderLayerMask(long nativeBuilder, int select, int value);
private static native void nBuilderPriority(long nativeBuilder, int priority);
private static native void nBuilderChannel(long nativeBuilder, int channel);
private static native void nBuilderCulling(long nativeBuilder, boolean enabled);
private static native void nBuilderCastShadows(long nativeBuilder, boolean enabled);
private static native void nBuilderReceiveShadows(long nativeBuilder, boolean enabled);
@@ -898,6 +964,7 @@ public class RenderableManager {
private static native void nSetAxisAlignedBoundingBox(long nativeRenderableManager, int i, float cx, float cy, float cz, float ex, float ey, float ez);
private static native void nSetLayerMask(long nativeRenderableManager, int i, int select, int value);
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 nSetLightChannel(long nativeRenderableManager, int i, int channel, boolean enable);
private static native boolean nGetLightChannel(long nativeRenderableManager, int i, int channel);

View File

@@ -124,7 +124,24 @@ public class Renderer {
*/
public static class ClearOptions {
/**
* Color to use to clear the SwapChain
* Color (sRGB linear) to use to clear the RenderTarget (typically the SwapChain).
*
* The RenderTarget is cleared using this color, which won't be tone-mapped since
* tone-mapping is part of View rendering (this is not).
*
* When a View is rendered, there are 3 scenarios to consider:
* - Pixels rendered by the View replace the clear color (or blend with it in
* `BlendMode.TRANSLUCENT` mode).
*
* - With blending mode set to `BlendMode.TRANSLUCENT`, Pixels untouched by the View
* are considered fulling transparent and let the clear color show through.
*
* - With blending mode set to `BlendMode.OPAQUE`, Pixels untouched by the View
* are set to the clear color. However, because it is now used in the context of a View,
* it will go through the post-processing stage, which includes tone-mapping.
*
* For consistency, it is recommended to always use a Skybox to clear an opaque View's
* background, or to use black or fully-transparent (i.e. {0,0,0,0}) as the clear color.
*/
@NonNull
public float[] clearColor = { 0.0f, 0.0f, 0.0f, 0.0f };

View File

@@ -91,11 +91,34 @@ public class SwapChain {
*/
public static final long CONFIG_ENABLE_XCB = 0x4;
/**
* Indicates that the SwapChain must automatically perform linear to sRGB encoding.
*
* This flag is ignored if isSRGBSwapChainSupported() is false.
*
* When using this flag, post-processing should be disabled.
*
* @see SwapChain#isSRGBSwapChainSupported
* @see View#setPostProcessingEnabled
*/
public static final long CONFIG_SRGB_COLORSPACE = 0x10;
SwapChain(long nativeSwapChain, Object surface) {
mNativeObject = nativeSwapChain;
mSurface = surface;
}
/**
* Return whether createSwapChain supports the SWAP_CHAIN_CONFIG_SRGB_COLORSPACE flag.
* The default implementation returns false.
*
* @param engine A reference to the filament Engine
* @return true if SWAP_CHAIN_CONFIG_SRGB_COLORSPACE is supported, false otherwise.
*/
public static boolean isSRGBSwapChainSupported(@NonNull Engine engine) {
return nIsSRGBSwapChainSupported(engine.getNativeObject());
}
/**
* @return the native <code>Object</code> this <code>SwapChain</code> was created from or null
* for a headless SwapChain.
@@ -141,4 +164,5 @@ public class SwapChain {
}
private static native void nSetFrameCompletedCallback(long nativeSwapChain, Object handler, Runnable callback);
private static native boolean nIsSRGBSwapChainSupported(long nativeEngine);
}

View File

@@ -250,7 +250,19 @@ public class Texture {
SRGB8_ALPHA8_ASTC_10x8,
SRGB8_ALPHA8_ASTC_10x10,
SRGB8_ALPHA8_ASTC_12x10,
SRGB8_ALPHA8_ASTC_12x12
SRGB8_ALPHA8_ASTC_12x12,
// RGTC formats available with a GLES extension
RED_RGTC1, // BC4 unsigned
SIGNED_RED_RGTC1, // BC4 signed
RED_GREEN_RGTC2, // BC5 unsigned
SIGNED_RED_GREEN_RGTC2, // BC5 signed
// BPTC formats available with a GLES extension
RGB_BPTC_SIGNED_FLOAT, // BC6H signed
RGB_BPTC_UNSIGNED_FLOAT,// BC6H unsigned
RGBA_BPTC_UNORM, // BC7
SRGB_ALPHA_BPTC_UNORM // BC7 sRGB
}
/**
@@ -296,7 +308,19 @@ public class Texture {
SRGB8_ALPHA8_ASTC_10x8,
SRGB8_ALPHA8_ASTC_10x10,
SRGB8_ALPHA8_ASTC_12x10,
SRGB8_ALPHA8_ASTC_12x12
SRGB8_ALPHA8_ASTC_12x12,
// RGTC formats available with a GLES extension
RED_RGTC1, // BC4 unsigned
SIGNED_RED_RGTC1, // BC4 signed
RED_GREEN_RGTC2, // BC5 unsigned
SIGNED_RED_GREEN_RGTC2, // BC5 signed
// BPTC formats available with a GLES extension
RGB_BPTC_SIGNED_FLOAT, // BC6H signed
RGB_BPTC_UNSIGNED_FLOAT,// BC6H unsigned
RGBA_BPTC_UNORM, // BC7
SRGB_ALPHA_BPTC_UNORM // BC7 sRGB
}
/**

View File

@@ -276,7 +276,7 @@ public class TextureSampler {
}
/**
* Sets the wrapping mode in the t (depth) direction.
* Sets the wrapping mode in the r (depth) direction.
* @param mode wrapping mode
*/
public void setWrapModeR(WrapMode mode) {

View File

@@ -166,6 +166,8 @@ Java_com_google_android_filament_utils_AutomationEngine_nGetViewerOptions(JNIEnv
const jfieldID cameraAperture = env->GetFieldID(klass, "cameraAperture", "F");
const jfieldID cameraSpeed = env->GetFieldID(klass, "cameraSpeed", "F");
const jfieldID cameraISO = env->GetFieldID(klass, "cameraISO", "F");
const jfieldID cameraNear = env->GetFieldID(klass, "cameraNear", "F");
const jfieldID cameraFar = env->GetFieldID(klass, "cameraFar", "F");
const jfieldID groundShadowStrength = env->GetFieldID(klass, "groundShadowStrength", "F");
const jfieldID groundPlaneEnabled = env->GetFieldID(klass, "groundPlaneEnabled", "Z");
const jfieldID skyboxEnabled = env->GetFieldID(klass, "skyboxEnabled", "Z");
@@ -177,6 +179,8 @@ Java_com_google_android_filament_utils_AutomationEngine_nGetViewerOptions(JNIEnv
env->SetFloatField(result, cameraAperture, options.cameraAperture);
env->SetFloatField(result, cameraSpeed, options.cameraSpeed);
env->SetFloatField(result, cameraISO, options.cameraISO);
env->SetFloatField(result, cameraNear, options.cameraNear);
env->SetFloatField(result, cameraFar, options.cameraFar);
env->SetFloatField(result, groundShadowStrength, options.groundShadowStrength);
env->SetBooleanField(result, groundPlaneEnabled, options.groundPlaneEnabled);
env->SetBooleanField(result, skyboxEnabled, options.skyboxEnabled);

View File

@@ -97,6 +97,8 @@ public class AutomationEngine {
public float cameraAperture = 16.0f;
public float cameraSpeed = 125.0f;
public float cameraISO = 100.0f;
public float cameraNear = 0.1f;
public float cameraFar = 100.0f;
public float groundShadowStrength = 0.75f;
public boolean groundPlaneEnabled = false;
public boolean skyboxEnabled = true;

View File

@@ -27,8 +27,8 @@ import com.google.android.filament.gltfio.*
import kotlinx.coroutines.*
import java.nio.Buffer
private const val kNearPlane = 0.05 // 5 cm
private const val kFarPlane = 1000.0 // 1 km
private const val kNearPlane = 0.05f // 5 cm
private const val kFarPlane = 1000.0f // 1 km
private const val kAperture = 16f
private const val kShutterSpeed = 1f / 125f
private const val kSensitivity = 100f
@@ -80,6 +80,18 @@ class ModelViewer(
updateCameraProjection()
}
var cameraNear = kNearPlane
set(value) {
field = value
updateCameraProjection()
}
var cameraFar = kFarPlane
set(value) {
field = value
updateCameraProjection()
}
val scene: Scene
val view: View
val camera: Camera
@@ -368,7 +380,8 @@ class ModelViewer(
val width = view.viewport.width
val height = view.viewport.height
val aspect = width.toDouble() / height.toDouble()
camera.setLensProjection(cameraFocalLength.toDouble(), aspect, kNearPlane, kFarPlane)
camera.setLensProjection(cameraFocalLength.toDouble(), aspect,
cameraNear.toDouble(), cameraFar.toDouble())
}
inner class SurfaceCallback : UiHelper.RendererCallback {

View File

@@ -28,47 +28,81 @@ import com.google.android.filament.proguard.UsedByNative;
@UsedByNative("AssetLoader.cpp")
public interface MaterialProvider {
/**
* MaterialKey specifies the requirements for a requested glTF material.
* The provider creates Filament materials that fulfill these requirements.
*/
@UsedByNative("MaterialKey.cpp")
public static class MaterialKey {
@UsedByNative("MaterialKey.cpp")
public boolean doubleSided;
@UsedByNative("MaterialKey.cpp")
public boolean unlit;
@UsedByNative("MaterialKey.cpp")
public boolean hasVertexColors;
@UsedByNative("MaterialKey.cpp")
public boolean hasBaseColorTexture;
@UsedByNative("MaterialKey.cpp")
public boolean hasNormalTexture;
@UsedByNative("MaterialKey.cpp")
public boolean hasOcclusionTexture;
@UsedByNative("MaterialKey.cpp")
public boolean hasEmissiveTexture;
@UsedByNative("MaterialKey.cpp")
public boolean useSpecularGlossiness;
@UsedByNative("MaterialKey.cpp")
public int alphaMode; // 0 = OPAQUE, 1 = MASK, 2 = BLEND
@UsedByNative("MaterialKey.cpp")
public boolean enableDiagnostics;
@UsedByNative("MaterialKey.cpp")
public boolean hasMetallicRoughnessTexture; // piggybacks with specularRoughness
@UsedByNative("MaterialKey.cpp")
public int metallicRoughnessUV; // piggybacks with specularRoughness
@UsedByNative("MaterialKey.cpp")
public int baseColorUV;
@UsedByNative("MaterialKey.cpp")
public boolean hasClearCoatTexture;
@UsedByNative("MaterialKey.cpp")
public int clearCoatUV;
@UsedByNative("MaterialKey.cpp")
public boolean hasClearCoatRoughnessTexture;
@UsedByNative("MaterialKey.cpp")
public int clearCoatRoughnessUV;
@UsedByNative("MaterialKey.cpp")
public boolean hasClearCoatNormalTexture;
@UsedByNative("MaterialKey.cpp")
public int clearCoatNormalUV;
@UsedByNative("MaterialKey.cpp")
public boolean hasClearCoat;
@UsedByNative("MaterialKey.cpp")
public boolean hasTransmission;
@UsedByNative("MaterialKey.cpp")
public boolean hasTextureTransforms;
@UsedByNative("MaterialKey.cpp")
public int emissiveUV;
@UsedByNative("MaterialKey.cpp")
public int aoUV;
@UsedByNative("MaterialKey.cpp")
public int normalUV;
@UsedByNative("MaterialKey.cpp")
public boolean hasTransmissionTexture;
@UsedByNative("MaterialKey.cpp")
public int transmissionUV;
@UsedByNative("MaterialKey.cpp")
public boolean hasSheenColorTexture;
@UsedByNative("MaterialKey.cpp")
public int sheenColorUV;
@UsedByNative("MaterialKey.cpp")
public boolean hasSheenRoughnessTexture;
@UsedByNative("MaterialKey.cpp")
public int sheenRoughnessUV;
@UsedByNative("MaterialKey.cpp")
public boolean hasVolumeThicknessTexture;
@UsedByNative("MaterialKey.cpp")
public int volumeThicknessUV;
@UsedByNative("MaterialKey.cpp")
public boolean hasSheen;
@UsedByNative("MaterialKey.cpp")
public boolean hasIOR;
public MaterialKey() {}

View File

@@ -20,6 +20,7 @@ import com.google.android.filament.Engine;
import com.google.android.filament.MaterialInstance;
import com.google.android.filament.Material;
import com.google.android.filament.VertexBuffer;
import com.google.android.filament.proguard.UsedByNative;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
@@ -94,6 +95,7 @@ public class UbershaderProvider implements MaterialProvider {
nDestroyMaterials(mNativeObject);
}
@UsedByNative("AssetLoader.cpp")
public long getNativeObject() {
return mNativeObject;
}

View File

@@ -1,5 +1,5 @@
GROUP=com.google.android.filament
VERSION_NAME=1.30.0
VERSION_NAME=1.31.6
POM_DESCRIPTION=Real-time physically based rendering engine for Android.
@@ -22,3 +22,5 @@ android.useAndroidX=true
com.google.android.filament.tools-dir=../../../out/release/filament
com.google.android.filament.dist-dir=../out/android-release/filament
com.google.android.filament.abis=all
#com.google.android.filament.matdbg
#com.google.android.filament.matnopt

View File

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

View File

@@ -356,6 +356,8 @@ class MainActivity : Activity() {
automation.applySettings(modelViewer.engine, json, viewerContent)
modelViewer.view.colorGrading = automation.getColorGrading(modelViewer.engine)
modelViewer.cameraFocalLength = automation.viewerOptions.cameraFocalLength
modelViewer.cameraNear = automation.viewerOptions.cameraNear
modelViewer.cameraFar = automation.viewerOptions.cameraFar
updateRootTransform()
}

View File

@@ -27,6 +27,7 @@ import android.view.animation.LinearInterpolator
import com.google.android.filament.*
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.UiHelper
@@ -64,7 +65,6 @@ class MainActivity : Activity() {
private lateinit var view0: View
private lateinit var view1: View
private lateinit var view2: View
private lateinit var view3: View
private lateinit var view4: View
// We need skybox to set the background color
private lateinit var skybox: Skybox
@@ -119,15 +119,19 @@ class MainActivity : Activity() {
view0 = engine.createView()
view1 = engine.createView()
view2 = engine.createView()
view3 = engine.createView()
view4 = engine.createView()
view0.setName("view0");
view1.setName("view1");
view2.setName("view2");
view3.setName("view3");
view4.setName("view4");
// Useful for debugging issues
// view0.isPostProcessingEnabled = false
// view1.isPostProcessingEnabled = false
// view2.isPostProcessingEnabled = false
// view4.isPostProcessingEnabled = false
view4.blendMode = View.BlendMode.TRANSLUCENT;
skybox = Skybox.Builder().build(engine);
@@ -140,13 +144,11 @@ class MainActivity : Activity() {
view0.camera = camera
view1.camera = camera
view2.camera = camera
view3.camera = camera
view4.camera = camera
view0.scene = scene
view1.scene = scene
view2.scene = scene
view3.scene = scene
view4.scene = scene
}
@@ -379,7 +381,6 @@ class MainActivity : Activity() {
engine.destroyView(view0)
engine.destroyView(view1)
engine.destroyView(view2)
engine.destroyView(view3)
engine.destroyView(view4)
engine.destroySkybox(skybox)
engine.destroyScene(scene)
@@ -407,19 +408,18 @@ class MainActivity : Activity() {
// If beginFrame() returns false you should skip the frame
// This means you are sending frames too quickly to the GPU
if (renderer.beginFrame(swapChain!!, frameTimeNanos)) {
skybox.setColor(0.035f, 0.035f, 0.035f, 1.0f);
scene.skybox = skybox
skybox.setColor(0.35f, 0.35f, 0.35f, 1.0f);
renderer.render(view0)
skybox.setColor(1.0f, 0.0f, 0.0f, 1.0f);
skybox.setColor(1.0f, 1.0f, 0.0f, 1.0f);
renderer.render(view1)
skybox.setColor(0.0f, 1.0f, 0.0f, 1.0f);
scene.skybox = null
renderer.render(view2)
skybox.setColor(0.0f, 0.0f, 1.0f, 1.0f);
renderer.render(view3)
skybox.setColor(0.0f, 0.0f, 0.0f, 0.0f);
renderer.render(view4)
renderer.endFrame()
@@ -433,6 +433,10 @@ class MainActivity : Activity() {
swapChain?.let { engine.destroySwapChain(it) }
swapChain = engine.createSwapChain(surface)
renderer.setDisplayInfo(DisplayHelper.getDisplayInfo(surfaceView.display, Renderer.DisplayInfo()))
renderer.clearOptions = renderer.clearOptions.apply {
clear = true
clearColor = floatArrayOf( 0.0f, 0.0f, 1.0f, 0.0f )
}
}
override fun onDetachedFromSurface() {
@@ -453,7 +457,6 @@ class MainActivity : Activity() {
view0.viewport = Viewport(0, 0, width / 2, height / 2)
view1.viewport = Viewport(width / 2, 0, width / 2, height / 2)
view2.viewport = Viewport(0, height / 2, width / 2, height / 2)
view3.viewport = Viewport(width / 2, height / 2, width / 2, height / 2)
view4.viewport = Viewport(width / 4, height / 4, width / 2, height / 2)
}
}

View File

Before

Width:  |  Height:  |  Size: 848 KiB

After

Width:  |  Height:  |  Size: 848 KiB

View File

@@ -22,9 +22,11 @@ function print_help {
echo " All (and only) git-ignored files under android/ are deleted."
echo " This is sometimes needed instead of -c (which still misses some clean steps)."
echo " -d"
echo " Enable matdbg and disable material optimization."
echo " Enable matdbg."
echo " -f"
echo " Always invoke CMake before incremental builds."
echo " -g"
echo " Disable material optimization."
echo " -i"
echo " Install build output"
echo " -m"
@@ -56,6 +58,9 @@ function print_help {
echo " When building for Android, also build select sample APKs."
echo " sampleN is an Android sample, e.g., sample-gltf-viewer."
echo " This automatically performs a partial desktop build and install."
echo " -b"
echo " Enable Address and Undefined Behavior Sanitizers (asan/ubsan) for debugging."
echo " This is only for the desktop build."
echo ""
echo "Build types:"
echo " release"
@@ -162,6 +167,11 @@ EGL_ON_LINUX_OPTION="-DFILAMENT_SUPPORTS_EGL_ON_LINUX=OFF"
MATDBG_OPTION="-DFILAMENT_ENABLE_MATDBG=OFF"
MATDBG_GRADLE_OPTION=""
MATOPT_OPTION=""
MATOPT_GRADLE_OPTION=""
ASAN_UBSAN_OPTION=""
IOS_BUILD_SIMULATOR=false
BUILD_UNIVERSAL_LIBRARIES=false
@@ -221,6 +231,8 @@ function build_desktop_target {
${SWIFTSHADER_OPTION} \
${EGL_ON_LINUX_OPTION} \
${MATDBG_OPTION} \
${MATOPT_OPTION} \
${ASAN_UBSAN_OPTION} \
${deployment_target} \
${architectures} \
../..
@@ -347,6 +359,7 @@ function build_android_target {
-DCMAKE_INSTALL_PREFIX="../android-${lc_target}/filament" \
-DCMAKE_TOOLCHAIN_FILE="../../build/toolchain-${arch}-linux-android.cmake" \
${MATDBG_OPTION} \
${MATOPT_OPTION} \
${VULKAN_ANDROID_OPTION} \
../..
fi
@@ -463,6 +476,7 @@ function build_android {
-Pcom.google.android.filament.abis=${ABI_GRADLE_OPTION} \
${VULKAN_ANDROID_GRADLE_OPTION} \
${MATDBG_GRADLE_OPTION} \
${MATOPT_GRADLE_OPTION} \
:filament-android:assembleDebug \
:gltfio-android:assembleDebug \
:filament-utils-android:assembleDebug
@@ -510,6 +524,7 @@ function build_android {
-Pcom.google.android.filament.abis=${ABI_GRADLE_OPTION} \
${VULKAN_ANDROID_GRADLE_OPTION} \
${MATDBG_GRADLE_OPTION} \
${MATOPT_GRADLE_OPTION} \
:filament-android:assembleRelease \
:gltfio-android:assembleRelease \
:filament-utils-android:assembleRelease
@@ -576,6 +591,7 @@ function build_ios_target {
-DIOS=1 \
-DCMAKE_TOOLCHAIN_FILE=../../third_party/clang/iOS.cmake \
${MATDBG_OPTION} \
${MATOPT_OPTION} \
../..
fi
@@ -740,7 +756,7 @@ function run_tests {
pushd "$(dirname "$0")" > /dev/null
while getopts ":hacCfijmp:q:uvslwtedk:" opt; do
while getopts ":hacCfijmp:q:uvslwtedk:b" opt; do
case ${opt} in
h)
print_help
@@ -758,12 +774,16 @@ while getopts ":hacCfijmp:q:uvslwtedk:" opt; do
;;
d)
PRINT_MATDBG_HELP=true
MATDBG_OPTION="-DFILAMENT_ENABLE_MATDBG=ON, -DFILAMENT_DISABLE_MATOPT=ON, -DFILAMENT_BUILD_FILAMAT=ON"
MATDBG_OPTION="-DFILAMENT_ENABLE_MATDBG=ON, -DFILAMENT_BUILD_FILAMAT=ON"
MATDBG_GRADLE_OPTION="-Pcom.google.android.filament.matdbg"
;;
f)
ISSUE_CMAKE_ALWAYS=true
;;
g)
MATOPT_OPTION="-DFILAMENT_DISABLE_MATOPT=ON"
MATOPT_GRADLE_OPTION="-Pcom.google.android.filament.matnopt"
;;
i)
INSTALL_COMMAND=install
;;
@@ -863,6 +883,9 @@ while getopts ":hacCfijmp:q:uvslwtedk:" opt; do
BUILD_ANDROID_SAMPLES=true
ANDROID_SAMPLES=$(echo "${OPTARG}" | tr ',' '\n')
;;
b) ASAN_UBSAN_OPTION="-DFILAMENT_ENABLE_ASAN_UBSAN=ON"
echo "Enabled ASAN/UBSAN"
;;
\?)
echo "Invalid option: -${OPTARG}" >&2
echo ""

View File

@@ -44,6 +44,10 @@ FILAMENT_HEADERS="$1"
includes=()
pushd "$FILAMENT_HEADERS" >/dev/null
for f in $(find . -name '*.h'); do
# Ignore platform headers. These may contain platform-specific includes.
if [[ "$f" == *backend/platforms/* ]]; then
continue
fi
include_path="${f#./}" # strip leading ./
includes+=("${include_path}")
done

View File

@@ -1,7 +1,7 @@
#!/bin/bash
# version of clang we want to use
GITHUB_CLANG_VERSION=8
GITHUB_CLANG_VERSION=14
# version of CMake to use instead of the default one
CMAKE_VERSION=3.19.5
# version of ninja to use

View File

@@ -3821,7 +3821,7 @@ Since $\left< cos \theta \right>$ does not depend on $\phi$ (azimuthal independe
$$\begin{align*}
C^0_l &= 2\pi \int_0^{\pi} \left< cos \theta \right> y^0_l(\theta) sin \theta d\theta \\
C^0_l &= 2\pi K^)_l \int_0^{\frac{\pi}{2}} P^0_l(cos \theta) cos \theta sin \theta d\theta \\
C^0_l &= 2\pi K^m_l \int_0^{\frac{\pi}{2}} P^0_l(cos \theta) cos \theta sin \theta d\theta \\
C^m_l &= 0, m != 0
\end{align*}$$

View File

@@ -2263,7 +2263,7 @@ type aliases:
Name | Type | Description
:-----------------------------------|:--------:|:------------------------------------
**getResolution()** | float4 | Dimensions of the view's effective viewport in pixels: `width`, `height`, `1 / width`, `1 / height`. This might be different from `View::getViewport()` for instance because of added rendering guard-bands. This can be used in conjunction with `getNormalizedViewportCoord()` to generate pixel coordinates.
**getResolution()** | float4 | Dimensions of the view's effective (physical) viewport in pixels: `width`, `height`, `1 / width`, `1 / height`. This might be different from `View::getViewport()` for instance because of added rendering guard-bands.
**getWorldCameraPosition()** | float3 | Position of the camera/eye in world space
**getWorldOffset()** | float3 | The shift required to obtain API-level world space
**getTime()** | float | Current time as a remainder of 1 second. Yields a value between 0 and 1
@@ -2301,7 +2301,7 @@ The following APIs are only available from the fragment block:
**getWorldNormalVector()** | float3 | Normalized normal in world space, after bump mapping (must be used after `prepareMaterial()`)
**getWorldGeometricNormalVector()** | float3 | Normalized normal in world space, before bump mapping (can be used before `prepareMaterial()`)
**getWorldReflectedVector()** | float3 | Reflection of the view vector about the normal (must be used after `prepareMaterial()`)
**getNormalizedViewportCoord()** | float3 | Normalized viewport position (i.e. NDC coordinates normalized to [0, 1], can be used before `prepareMaterial()`)
**getNormalizedViewportCoord()** | float3 | Normalized user viewport position (i.e. NDC coordinates normalized to [0, 1] for the position, [1, 0] for the depth), can be used before `prepareMaterial()`). Because the user viewport is smaller than the actual physical viewport, these coordinates can be negative or superior to 1 in the non-visible area of the physical viewport.
**getNdotV()** | float | The result of `dot(normal, view)`, always strictly greater than 0 (must be used after `prepareMaterial()`)
**getColor()** | float4 | Interpolated color of the fragment, if the color attribute is required
**getUV0()** | float2 | First interpolated set of UV coordinates, only available if the uv0 attribute is required

File diff suppressed because one or more lines are too long

Binary file not shown.

View File

@@ -261,7 +261,7 @@ class App {
this.renderer.setClearOptions({clearColor: kBackgroundColor, clear: true});
this.render = this.render.bind(this);
this.simpleViewer = new Filament.SimpleViewer(engine, scene, view, kInitialSidebarWidth);
this.simpleViewer = new Filament.ViewerGui(engine, scene, view, kInitialSidebarWidth);
this.mouseX = -1;
this.mouseY = -1;

File diff suppressed because one or more lines are too long

Binary file not shown.

1
docs/webgl/gltumble.min.js vendored Normal file

File diff suppressed because one or more lines are too long

View File

@@ -10,7 +10,7 @@ html, body { height: 100%; }
body { margin: 0; overflow: hidden; }
#container { position: relative; height: 100%; }
canvas { position: absolute; width: 100%; height: 100%; }
#messages { position: absolute; width: 100%; height: 100%; padding-left: 10px; color:white; }
#messages { position: absolute; width: 100%; height: 100%; padding-left: 10px; color:blue; pointer-events: none; }
</style>
</head>
<body>
@@ -20,7 +20,7 @@ canvas { position: absolute; width: 100%; height: 100%; }
</div>
<script src="filament.js"></script>
<script src="gl-matrix-min.js"></script>
<script src="https://unpkg.com/gltumble"></script>
<script src="gltumble.min.js"></script>
<script>
const env = 'default_env';
@@ -43,7 +43,19 @@ class App {
const scene = this.scene = engine.createScene();
this.trackball = new Trackball(canvas, {startSpin: 0.035});
const indirectLight = this.ibl = engine.createIblFromKtx(ibl_url);
const messages = document.getElementById('messages');
canvas.addEventListener('pointerdown', evt => {
const x = evt.clientX;
const y = this.canvas.getBoundingClientRect().height - 1 - evt.clientY;
const dpr = window.devicePixelRatio;
this.view.pick(x * dpr, y * dpr, (results) => {
const name = this.asset.getName(results.renderable);
messages.innerText = name ? ('Picked ' + name) : '';
});
});
const indirectLight = this.ibl = engine.createIblFromKtx1(ibl_url);
this.scene.setIndirectLight(indirectLight);
const iblDirection = IndirectLight.getDirectionEstimate(indirectLight.shfloats);
@@ -58,7 +70,7 @@ class App {
mat3.fromRotation(mat, radians, [0, 1, 0]);
indirectLight.setRotation(mat);
const skybox = engine.createSkyFromKtx(sky_url);
const skybox = engine.createSkyFromKtx1(sky_url);
this.scene.setSkybox(skybox);
const sunlight = Filament.EntityManager.get().create();
@@ -76,28 +88,17 @@ class App {
const loader = this.loader = engine.createAssetLoader();
this.allowRefresh = false;
const asset = this.asset = loader.createAssetFromJson(mesh_url);
const asset = this.asset = loader.createAsset(mesh_url);
this.assetRoot = this.asset.getRoot();
const messages = document.getElementById('messages');
// Crudely indicate progress by printing the URI of each resource as it is loaded.
const onFetched = (uri) => messages.innerText += `Downloaded ${uri}\n`;
const onDone = () => {
this.allowRefresh = true;
// Enable shadows on every renderable.
const entities = asset.getEntities();
const rm = engine.getRenderableManager();
for (const entity of entities) {
const instance = rm.getInstance(entity);
rm.setCastShadows(instance, true);
instance.delete();
}
// Hide the HUD.
messages.remove();
// Clear the progress indication messages.
messages.innerText = "";
};
asset.loadResources(onDone, onFetched);
@@ -137,7 +138,7 @@ class App {
this.allowRefresh = false;
this.scene.removeEntities(this.asset.getEntities());
this.loader.destroyAsset(this.asset);
this.asset = this.loader.createAssetFromJson(mesh_url);
this.asset = this.loader.createAsset(mesh_url);
const onDone = () => { this.allowRefresh = true; }
this.asset.loadResources(onDone);
}
@@ -149,7 +150,7 @@ class App {
tcm.setTransform(inst, this.trackball.getMatrix());
inst.delete();
// Add renderable entities to the scene as they become ready.
// Gradually add renderables to the scene as their textures become ready.
let entity;
const popRenderable = () => {
entity = this.asset.popRenderable();

Binary file not shown.

View File

@@ -54,14 +54,14 @@ class App {
.build(engine, sunlight);
this.scene.addEntity(sunlight);
const indirectLight = this.ibl = engine.createIblFromKtx(iblfile);
const indirectLight = this.ibl = engine.createIblFromKtx1(iblfile);
this.scene.setIndirectLight(indirectLight);
const radians = 1.0;
indirectLight.setRotation(mat3.fromRotation(mat3.create(), radians, [0, 1, 0]))
indirectLight.setIntensity(10000);
const skybox = engine.createSkyFromKtx(skyfile);
const skybox = engine.createSkyFromKtx1(skyfile);
this.scene.setSkybox(skybox);
const material = engine.createMaterial('parquet.filamat');

Binary file not shown.

View File

@@ -49,7 +49,7 @@
</tr>
<tr>
<td align="left"><a href="#EntityManager">EntityManager</a></td>
<td align="left">Singleton used for constructing entities in Filament's ECS.</td>
<td align="left">Singleton used for constructing entities in Filament&#x27;s ECS.</td>
</tr>
<tr>
<td align="left"><a href="#Frustum">Frustum</a></td>
@@ -69,7 +69,7 @@
</tr>
<tr>
<td align="left"><a href="#KtxInfo">KtxInfo</a></td>
<td align="left">Property accessor for KTX header.</td>
<td align="left">Property accessor for KTX1 header.</td>
</tr>
<tr>
<td align="left"><a href="#LightManager%24Instance">LightManager$Instance</a></td>
@@ -89,7 +89,7 @@
</tr>
<tr>
<td align="left"><a href="#Renderer">Renderer</a></td>
<td align="left">Represents the platform's native window.</td>
<td align="left">Represents the platform&#x27;s native window.</td>
</tr>
<tr>
<td align="left"><a href="#Scene">Scene</a></td>
@@ -97,7 +97,7 @@
</tr>
<tr>
<td align="left"><a href="#SwapChain">SwapChain</a></td>
<td align="left">Represents the platform's native rendering surface.</td>
<td align="left">Represents the platform&#x27;s native rendering surface.</td>
</tr>
<tr>
<td align="left"><a href="#Texture">Texture</a></td>
@@ -190,6 +190,10 @@
<td align="left"></td>
</tr>
<tr>
<td align="left"><a href="#ColorGrading%24LutFormat">ColorGrading$LutFormat</a></td>
<td align="left"></td>
</tr>
<tr>
<td align="left"><a href="#ColorGrading%24QualityLevel">ColorGrading$QualityLevel</a></td>
<td align="left"></td>
</tr>
@@ -214,6 +218,10 @@
<td align="left"></td>
</tr>
<tr>
<td align="left"><a href="#FeatureLevel">FeatureLevel</a></td>
<td align="left"></td>
</tr>
<tr>
<td align="left"><a href="#Frustum%24Plane">Frustum$Plane</a></td>
<td align="left"></td>
</tr>
@@ -222,6 +230,14 @@
<td align="left"></td>
</tr>
<tr>
<td align="left"><a href="#Ktx2Reader%24Result">Ktx2Reader$Result</a></td>
<td align="left"></td>
</tr>
<tr>
<td align="left"><a href="#Ktx2Reader%24TransferFunction">Ktx2Reader$TransferFunction</a></td>
<td align="left"></td>
</tr>
<tr>
<td align="left"><a href="#LightManager%24Type">LightManager$Type</a></td>
<td align="left"></td>
</tr>
@@ -258,6 +274,14 @@
<td align="left"></td>
</tr>
<tr>
<td align="left"><a href="#StencilFace">StencilFace</a></td>
<td align="left"></td>
</tr>
<tr>
<td align="left"><a href="#StencilOperation">StencilOperation</a></td>
<td align="left"></td>
</tr>
<tr>
<td align="left"><a href="#Texture%24CubemapFace">Texture$CubemapFace</a></td>
<td align="left"></td>
</tr>
@@ -274,6 +298,10 @@
<td align="left"></td>
</tr>
<tr>
<td align="left"><a href="#TransparencyMode">TransparencyMode</a></td>
<td align="left"></td>
</tr>
<tr>
<td align="left"><a href="#VertexAttribute">VertexAttribute</a></td>
<td align="left"></td>
</tr>
@@ -286,26 +314,6 @@
<td align="left"></td>
</tr>
<tr>
<td align="left"><a href="#View%24AntiAliasing">View$AntiAliasing</a></td>
<td align="left"></td>
</tr>
<tr>
<td align="left"><a href="#View%24BlendMode">View$BlendMode</a></td>
<td align="left"></td>
</tr>
<tr>
<td align="left"><a href="#View%24BloomOptions%24BlendMode">View$BloomOptions$BlendMode</a></td>
<td align="left"></td>
</tr>
<tr>
<td align="left"><a href="#View%24DepthOfFieldOptions%24Filter">View$DepthOfFieldOptions$Filter</a></td>
<td align="left"></td>
</tr>
<tr>
<td align="left"><a href="#View%24QualityLevel">View$QualityLevel</a></td>
<td align="left"></td>
</tr>
<tr>
<td align="left"><a href="#WrapMode">WrapMode</a></td>
<td align="left"></td>
</tr>
@@ -371,7 +379,7 @@
<li><em>returns</em> an instance of <a href="#Camera">Camera</a></li>
</ul>
</li>
<li><strong>engine.createIblFromKtx(buffer, options)</strong>
<li><strong>engine.createIblFromKtx1(buffer, options)</strong>
<ul>
<li>Utility that creates an [IndirectLight] from a KTX file.</li>
<li><em>buffer</em> asset string, or Uint8Array, or <a href="#Buffer">Buffer</a> with KTX file contents</li>
@@ -395,7 +403,7 @@
<li><em>returns</em> an instance of <a href="#Scene">Scene</a></li>
</ul>
</li>
<li><strong>engine.createSkyFromKtx(buffer, options)</strong>
<li><strong>engine.createSkyFromKtx1(buffer, options)</strong>
<ul>
<li>Utility function that creates a [Skybox] from a KTX file.</li>
<li><em>buffer</em> asset string, or Uint8Array, or <a href="#Buffer">Buffer</a> with KTX file contents</li>
@@ -416,10 +424,18 @@
<li><em>returns</em> <a href="#Texture">Texture</a></li>
</ul>
</li>
<li><strong>engine.createTextureFromKtx(buffer, options)</strong>
<li><strong>engine.createTextureFromKtx1(buffer, options)</strong>
<ul>
<li>Utility function that creates a [Texture] from a KTX file.</li>
<li><em>buffer</em> asset string, or Uint8Array, or <a href="#Buffer">Buffer</a> with KTX file contents</li>
<li>Utility function that creates a [Texture] from a KTX1 file.</li>
<li><em>buffer</em> asset string, or Uint8Array, or <a href="#Buffer">Buffer</a> with KTX1 file contents</li>
<li><em>options</em> Options dictionary.</li>
<li><em>returns</em> <a href="#Texture">Texture</a></li>
</ul>
</li>
<li><strong>engine.createTextureFromKtx2(buffer, options)</strong>
<ul>
<li>Utility function that creates a [Texture] from a KTX2 file.</li>
<li><em>buffer</em> asset string, or Uint8Array, or <a href="#Buffer">Buffer</a> with KTX2 file contents</li>
<li><em>options</em> Options dictionary.</li>
<li><em>returns</em> <a href="#Texture">Texture</a></li>
</ul>
@@ -553,57 +569,26 @@
<li><em>entities</em> array of entities</li>
</ul>
</li>
<li><strong>engine.setAmbientOcclusionOptions(overrides)</strong>
<ul>
<li><em>overrides</em> Dictionary with one or more of the following properties: radius, power, bias, resolution, intensity, quality.</li>
</ul>
</li>
<li><strong>engine.setBloomOptions(overrides)</strong>
<ul>
<li><em>overrides</em> Dictionary with one or more of the following properties: enabled, strength, resolution, anomorphism, levels, blendMode, threshold, highlight.</li>
</ul>
</li>
<li><strong>engine.setAmbientOcclusionOptions()</strong></li>
<li><strong>engine.setBloomOptions()</strong></li>
<li><strong>engine.setClearOptions(overrides)</strong>
<ul>
<li><em>overrides</em> Dictionary with one or more of the following properties: clearColor, clear, discard.</li>
</ul>
</li>
<li><strong>engine.setDepthOfFieldOptions(overrides)</strong>
<ul>
<li><em>overrides</em> Dictionary with one or more of the following properties: cocScale, maxApertureDiameter, enabled.</li>
</ul>
</li>
<li><strong>engine.setFogOptions(overrides)</strong>
<ul>
<li><em>overrides</em> Dictionary with one or more of the following properties: distance, maximumOpacity, height, heightFalloff, color, density, inScatteringStart,</li>
</ul>
</li>
<li><strong>engine.setMultiSampleAntiAliasingOptions(overrides)</strong>
<ul>
<li><em>overrides</em> Dictionary with one or more of the following properties: enabled, sampleCount, customResolve.</li>
</ul>
</li>
<li><strong>engine.setScreenSpaceReflectionsOptions(overrides)</strong>
<ul>
<li><em>overrides</em> Dictionary with one or more of the following properties: thickness, bias, maxDistance, stride, enabled.</li>
</ul>
</li>
<li><strong>engine.setDepthOfFieldOptions()</strong></li>
<li><strong>engine.setFogOptions()</strong></li>
<li><strong>engine.setGuardBandOptions()</strong></li>
<li><strong>engine.setMultiSampleAntiAliasingOptions()</strong></li>
<li><strong>engine.setScreenSpaceReflectionsOptions()</strong></li>
<li><strong>engine.setShadowOptions(instance, overrides)</strong>
<ul>
<li><em>instance</em> Instance of a light component obtained from <code>getInstance</code>.</li>
<li><em>overrides</em> Dictionary with one or more of the following properties: mapSize, shadowCascades, constantBias, normalBias, shadowFar, shadowNearHint, shadowFarHint, stable, polygonOffsetConstant, polygonOffsetSlope, \</li>
</ul>
</li>
<li><strong>engine.setTemporalAntiAliasingOptions(overrides)</strong>
<ul>
<li><em>overrides</em> Dictionary with one or more of the following properties: filterWidth, feedback, enabled.</li>
</ul>
</li>
<li><strong>engine.setVignetteOptions(overrides)</strong>
<ul>
<li><em>overrides</em> Dictionary with one or more of the following properties: midPoint, roundness, feather, color, enabled.</li>
</ul>
</li>
<li><strong>engine.setTemporalAntiAliasingOptions()</strong></li>
<li><strong>engine.setVignetteOptions()</strong></li>
</ul>
</div>
<div class='classdoc'>
@@ -618,11 +603,11 @@
</ul>
<p>To create an entity with no components, use <a href="#EntityManager">EntityManager</a>.
TODO: It would be better to expose these as JS numbers rather than as JS objects.
This would also be more consistent with Filament's Java bindings.</p>
This would also be more consistent with Filament&#x27;s Java bindings.</p>
</div>
<div class='classdoc'>
<h2>class <a id='EntityManager' href='#EntityManager'>EntityManager</a></h2>
<p>Singleton used for constructing entities in Filament's ECS.</p>
<p>Singleton used for constructing entities in Filament&#x27;s ECS.</p>
<ul>
<li><strong>entityManager.create()</strong>
<ul>
@@ -727,15 +712,9 @@ wrapper rather than interacting with <code>Ktx1Bundle</code> directly.</p>
</div>
<div class='classdoc'>
<h2>class <a id='KtxInfo' href='#KtxInfo'>KtxInfo</a></h2>
<p>Property accessor for KTX header.</p>
<p>Property accessor for KTX1 header.</p>
<ul>
<li><strong>ktxInfo.createAssetFromBinary(buffer)</strong>
<ul>
<li><em>buffer</em> asset string, or Uint8Array, or <a href="#Buffer">Buffer</a></li>
<li><em>returns</em> an instance of <a href="#FilamentAsset">FilamentAsset</a></li>
</ul>
</li>
<li><strong>ktxInfo.createAssetFromJson(buffer)</strong>
<li><strong>ktxInfo.createAsset(buffer)</strong>
<ul>
<li><em>buffer</em> asset string, or Uint8Array, or <a href="#Buffer">Buffer</a></li>
<li><em>returns</em> an instance of <a href="#FilamentAsset">FilamentAsset</a></li>
@@ -762,7 +741,7 @@ properties.</p>
</ul>
</li>
</ul>
<p>Be sure to call the instance's <code>delete</code> method when you're done with it.</p>
<p>Be sure to call the instance&#x27;s <code>delete</code> method when you&#x27;re done with it.</p>
</div>
<div class='classdoc'>
<h2>class <a id='PixelBufferDescriptor' href='#PixelBufferDescriptor'>PixelBufferDescriptor</a></h2>
@@ -800,11 +779,11 @@ properties.</p>
</ul>
</li>
</ul>
<p>Be sure to call the instance's <code>delete</code> method when you're done with it.</p>
<p>Be sure to call the instance&#x27;s <code>delete</code> method when you&#x27;re done with it.</p>
</div>
<div class='classdoc'>
<h2>class <a id='Renderer' href='#Renderer'>Renderer</a></h2>
<p>Represents the platform's native window.</p>
<p>Represents the platform&#x27;s native window.</p>
<ul>
<li><strong>renderer.render(swapChain, view)</strong>
<ul>
@@ -823,7 +802,7 @@ properties.</p>
</div>
<div class='classdoc'>
<h2>class <a id='SwapChain' href='#SwapChain'>SwapChain</a></h2>
<p>Represents the platform's native rendering surface.</p>
<p>Represents the platform&#x27;s native rendering surface.</p>
<p>See also the <a href="#Engine">Engine</a> methods <code>createSwapChain</code> and <code>destroySwapChain</code>.</p>
</div>
<div class='classdoc'>
@@ -867,7 +846,7 @@ properties.</p>
</ul>
</li>
</ul>
<p>Be sure to call the instance's <code>delete</code> method when you're done with it.</p>
<p>Be sure to call the instance&#x27;s <code>delete</code> method when you&#x27;re done with it.</p>
</div>
<div class='classdoc'>
<h2>class <a id='VertexBuffer' href='#VertexBuffer'>VertexBuffer</a></h2>
@@ -964,7 +943,7 @@ See also the <a href="#Engine">Engine</a> methods <code>createView</code> and <c
<ul>
<li><strong>assets</strong>
<ul>
<li>Array of strings containing URL's of required assets.</li>
<li>Array of strings containing URL&#x27;s of required assets.</li>
</ul>
</li>
<li><strong>onDone</strong>
@@ -974,7 +953,7 @@ See also the <a href="#Engine">Engine</a> methods <code>createView</code> and <c
</li>
<li><strong>onFetched</strong>
<ul>
<li>optional callback that's invoked after each asset is downloaded.</li>
<li>optional callback that&#x27;s invoked after each asset is downloaded.</li>
</ul>
</li>
</ul>
@@ -1021,7 +1000,7 @@ useful for compressed textures. For example, some platforms accept ETC and other
<ul>
<li><strong>assets</strong>
<ul>
<li>Array of strings containing URL's of required assets.</li>
<li>Array of strings containing URL&#x27;s of required assets.</li>
</ul>
</li>
<li><strong>onready</strong>
@@ -1030,12 +1009,12 @@ useful for compressed textures. For example, some platforms accept ETC and other
</ul>
</li>
</ul>
<p>All JavaScript clients must call the init function, passing in a list of asset URL's and a
<p>All JavaScript clients must call the init function, passing in a list of asset URL&#x27;s and a
callback. This callback gets invoked only after all assets have been downloaded and the Filament
WebAssembly module has been loaded. Clients should only pass asset URL's that absolutely must
WebAssembly module has been loaded. Clients should only pass asset URL&#x27;s that absolutely must
be ready at initialization time.
When the callback is called, each downloaded asset is available in the <code>Filament.assets</code> global
object, which contains a mapping from URL's to Uint8Array objects.</p>
object, which contains a mapping from URL&#x27;s to Uint8Array objects.</p>
</div>
<div class='funcdoc'>
<h2>function <a id='loadMathExtensions' href='#loadMathExtensions'>loadMathExtensions</a>()</h2>
@@ -1085,6 +1064,13 @@ This defines the following functions:</p>
</ul>
</div>
<div class='enumdoc'>
<h2>enum <a id='ColorGrading$LutFormat' href='#ColorGrading$LutFormat'>ColorGrading$LutFormat</a></h2>
<ul>
<li>INTEGER</li>
<li>FLOAT</li>
</ul>
</div>
<div class='enumdoc'>
<h2>enum <a id='ColorGrading$QualityLevel' href='#ColorGrading$QualityLevel'>ColorGrading$QualityLevel</a></h2>
<ul>
<li>LOW</li>
@@ -1140,6 +1126,10 @@ This defines the following functions:</p>
<li>DXT1_RGBA</li>
<li>DXT3_RGBA</li>
<li>DXT5_RGBA</li>
<li>DXT1_SRGB</li>
<li>DXT1_SRGBA</li>
<li>DXT3_SRGBA</li>
<li>DXT5_SRGBA</li>
<li>RGBA_ASTC_4x4</li>
<li>RGBA_ASTC_5x4</li>
<li>RGBA_ASTC_5x5</li>
@@ -1180,6 +1170,13 @@ This defines the following functions:</p>
</ul>
</div>
<div class='enumdoc'>
<h2>enum <a id='FeatureLevel' href='#FeatureLevel'>FeatureLevel</a></h2>
<ul>
<li>FEATURE_LEVEL_1</li>
<li>FEATURE_LEVEL_2</li>
</ul>
</div>
<div class='enumdoc'>
<h2>enum <a id='Frustum$Plane' href='#Frustum$Plane'>Frustum$Plane</a></h2>
<ul>
<li>LEFT</li>
@@ -1198,6 +1195,23 @@ This defines the following functions:</p>
</ul>
</div>
<div class='enumdoc'>
<h2>enum <a id='Ktx2Reader$Result' href='#Ktx2Reader$Result'>Ktx2Reader$Result</a></h2>
<ul>
<li>SUCCESS</li>
<li>COMPRESSED_TRANSCODE_FAILURE</li>
<li>UNCOMPRESSED_TRANSCODE_FAILURE</li>
<li>FORMAT_UNSUPPORTED</li>
<li>FORMAT_ALREADY_REQUESTED</li>
</ul>
</div>
<div class='enumdoc'>
<h2>enum <a id='Ktx2Reader$TransferFunction' href='#Ktx2Reader$TransferFunction'>Ktx2Reader$TransferFunction</a></h2>
<ul>
<li>LINEAR</li>
<li>sRGB</li>
</ul>
</div>
<div class='enumdoc'>
<h2>enum <a id='LightManager$Type' href='#LightManager$Type'>LightManager$Type</a></h2>
<ul>
<li>SUN</li>
@@ -1275,7 +1289,6 @@ This defines the following functions:</p>
<li>LINE_STRIP</li>
<li>TRIANGLES</li>
<li>TRIANGLE_STRIP</li>
<li>NONE</li>
</ul>
</div>
<div class='enumdoc'>
@@ -1295,6 +1308,27 @@ This defines the following functions:</p>
</ul>
</div>
<div class='enumdoc'>
<h2>enum <a id='StencilFace' href='#StencilFace'>StencilFace</a></h2>
<ul>
<li>FRONT</li>
<li>BACK</li>
<li>FRONT_AND_BACK</li>
</ul>
</div>
<div class='enumdoc'>
<h2>enum <a id='StencilOperation' href='#StencilOperation'>StencilOperation</a></h2>
<ul>
<li>KEEP</li>
<li>ZERO</li>
<li>REPLACE</li>
<li>INCR_CLAMP</li>
<li>INCR_WRAP</li>
<li>DECR_CLAMP</li>
<li>DECR_WRAP</li>
<li>INVERT</li>
</ul>
</div>
<div class='enumdoc'>
<h2>enum <a id='Texture$CubemapFace' href='#Texture$CubemapFace'>Texture$CubemapFace</a></h2>
<ul>
<li>POSITIVE_X</li>
@@ -1377,6 +1411,10 @@ This defines the following functions:</p>
<li>DXT1_RGBA</li>
<li>DXT3_RGBA</li>
<li>DXT5_RGBA</li>
<li>DXT1_SRGB</li>
<li>DXT1_SRGBA</li>
<li>DXT3_SRGBA</li>
<li>DXT5_SRGBA</li>
<li>RGBA_ASTC_4x4</li>
<li>RGBA_ASTC_5x4</li>
<li>RGBA_ASTC_5x5</li>
@@ -1428,6 +1466,14 @@ This defines the following functions:</p>
</ul>
</div>
<div class='enumdoc'>
<h2>enum <a id='TransparencyMode' href='#TransparencyMode'>TransparencyMode</a></h2>
<ul>
<li>DEFAULT</li>
<li>TWO_PASSES_ONE_SIDE</li>
<li>TWO_PASSES_TWO_SIDES</li>
</ul>
</div>
<div class='enumdoc'>
<h2>enum <a id='VertexAttribute' href='#VertexAttribute'>VertexAttribute</a></h2>
<ul>
<li>POSITION</li>
@@ -1494,43 +1540,6 @@ This defines the following functions:</p>
</ul>
</div>
<div class='enumdoc'>
<h2>enum <a id='View$AntiAliasing' href='#View$AntiAliasing'>View$AntiAliasing</a></h2>
<ul>
<li>NONE</li>
<li>FXAA</li>
</ul>
</div>
<div class='enumdoc'>
<h2>enum <a id='View$BlendMode' href='#View$BlendMode'>View$BlendMode</a></h2>
<ul>
<li>OPAQUE</li>
<li>TRANSLUCENT</li>
</ul>
</div>
<div class='enumdoc'>
<h2>enum <a id='View$BloomOptions$BlendMode' href='#View$BloomOptions$BlendMode'>View$BloomOptions$BlendMode</a></h2>
<ul>
<li>ADD</li>
<li>INTERPOLATE</li>
</ul>
</div>
<div class='enumdoc'>
<h2>enum <a id='View$DepthOfFieldOptions$Filter' href='#View$DepthOfFieldOptions$Filter'>View$DepthOfFieldOptions$Filter</a></h2>
<ul>
<li>NONE</li>
<li>MEDIAN</li>
</ul>
</div>
<div class='enumdoc'>
<h2>enum <a id='View$QualityLevel' href='#View$QualityLevel'>View$QualityLevel</a></h2>
<ul>
<li>LOW</li>
<li>MEDIUM</li>
<li>HIGH</li>
<li>ULTRA</li>
</ul>
</div>
<div class='enumdoc'>
<h2>enum <a id='WrapMode' href='#WrapMode'>WrapMode</a></h2>
<ul>
<li>CLAMP_TO_EDGE</li>

Binary file not shown.

View File

@@ -16,17 +16,14 @@ canvas { touch-action: none; width: 100%; height: 100%; }
<script src="gl-matrix-min.js"></script>
<script>
const albedo_suffix = Filament.getSupportedFormatSuffix('astc s3tc_srgb');
const texture_suffix = Filament.getSupportedFormatSuffix('etc');
const env = 'default_env'
const ibl_url = `${env}/${env}_ibl.ktx`;
const sky_url = `${env}/${env}_skybox.ktx`;
const albedo_url = `albedo${albedo_suffix}.ktx`;
const ao_url = `ao${texture_suffix}.ktx`;
const metallic_url = `metallic${texture_suffix}.ktx`;
const normal_url = `normal${texture_suffix}.ktx`;
const roughness_url = `roughness${texture_suffix}.ktx`;
const albedo_url = `albedo.ktx2`;
const ao_url = `ao.ktx2`;
const metallic_url = `metallic.ktx2`;
const normal_url = `normal.ktx2`;
const roughness_url = `roughness.ktx2`;
const filamat_url = 'textured.filamat';
const filamesh_url = 'suzanne.filamesh';
@@ -41,12 +38,13 @@ Filament.init([
ibl_url,
sky_url
], () => {
window.VertexAttribute = Filament.VertexAttribute;
window.AttributeType = Filament.VertexBuffer$AttributeType;
window.PrimitiveType = Filament.RenderableManager$PrimitiveType;
window.IndexType = Filament.IndexBuffer$IndexType;
window.Format = Filament.Texture$InternalFormat;
window.Fov = Filament.Camera$Fov;
window.IndexType = Filament.IndexBuffer$IndexType;
window.LightType = Filament.LightManager$Type;
window.PrimitiveType = Filament.RenderableManager$PrimitiveType;
window.VertexAttribute = Filament.VertexAttribute;
window.app = new App(document.getElementsByTagName('canvas')[0]);
});
@@ -68,11 +66,11 @@ class App {
.build(engine, sunlight);
this.scene.addEntity(sunlight);
const indirectLight = this.ibl = engine.createIblFromKtx(ibl_url);
const indirectLight = this.ibl = engine.createIblFromKtx1(ibl_url);
this.scene.setIndirectLight(indirectLight);
indirectLight.setIntensity(80000);
const skybox = engine.createSkyFromKtx(sky_url);
const skybox = engine.createSkyFromKtx1(sky_url);
this.scene.setSkybox(skybox);
const material = engine.createMaterial(filamat_url);
@@ -83,11 +81,20 @@ class App {
Filament.MagFilter.LINEAR,
Filament.WrapMode.CLAMP_TO_EDGE);
const albedo = engine.createTextureFromKtx(albedo_url, {srgb: true});
const roughness = engine.createTextureFromKtx(roughness_url);
const metallic = engine.createTextureFromKtx(metallic_url);
const normal = engine.createTextureFromKtx(normal_url);
const ao = engine.createTextureFromKtx(ao_url);
// Filament requests support for the following extensions, but none are guaranteed.
// WEBGL_compressed_texture_s3tc, WEBGL_compressed_texture_s3tc_srgb
// WEBGL_compressed_texture_astc, WEBGL_compressed_texture_etc
const albedo = engine.createTextureFromKtx2(albedo_url, {
srgb: true,
formats: [ Format.DXT5_RGBA, Format.DXT5_SRGBA, Format.ETC2_EAC_SRGBA8 ]
});
console.assert(albedo, "Unable to create albedo texture.")
const roughness = engine.createTextureFromKtx2(roughness_url);
const metallic = engine.createTextureFromKtx2(metallic_url);
const ao = engine.createTextureFromKtx2(ao_url);
const normal = engine.createTextureFromKtx2(normal_url);
matinstance.setTextureParameter('albedo', albedo, sampler)
matinstance.setTextureParameter('roughness', roughness, sampler)

Binary file not shown.

Binary file not shown.

View File

@@ -10,7 +10,7 @@
textures.</p>
<p>For starters, create a text file called <code>redball.html</code> and copy over the HTML that we used in the
<a href="tutorial_triangle.html">previous tutorial</a>. Change the last script tag from <code>triangle.js</code> to <code>redball.js</code>.</p>
<p>Next you'll need to get a couple command-line tools: <code>matc</code> and <code>cmgen</code>. You can find these in the
<p>Next you&#x27;ll need to get a couple command-line tools: <code>matc</code> and <code>cmgen</code>. You can find these in the
appropriate <a href="//github.com/google/filament/releases">Filament release</a>. You should choose the
archive that corresponds to your development machine rather than the one for web, and the version
that matches the <code>unpkg.com/filament@x.x.x</code> url in the script tag of <code>redball.html</code> (you may check
@@ -19,7 +19,7 @@ out the last available release of <a href="https://www.npmjs.com/package/filamen
<p>The <code>matc</code> tool consumes a text file containing a high-level description of a PBR material, and
produces a binary material package that contains shader code and associated metadata. For more
information, see the official document describing the <a href="https://google.github.io/filament/Materials.md.html">Filament Material System</a>.</p>
<p>Let's try out <code>matc</code>. Create the following file in your favorite text editor and call it
<p>Let&#x27;s try out <code>matc</code>. Create the following file in your favorite text editor and call it
<code>plastic.mat</code>.</p>
<div class="highlight" style="background: #f8f8f8"><pre style="line-height: 125%;"><span></span>material {
name : Lit,
@@ -47,10 +47,10 @@ fragment {
<div class="highlight" style="background: #f8f8f8"><pre style="line-height: 125%;"><span></span>matc -a opengl -p mobile -o plastic.filamat plastic.mat
</pre></div>
<p>You should now have a material archive in your working directory, which we'll use later in the
<p>You should now have a material archive in your working directory, which we&#x27;ll use later in the
tutorial.</p>
<h2>Bake environment map</h2>
<p>Next we'll use Filament's <code>cmgen</code> tool to consume a HDR environment map in latlong format, and
<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
@@ -61,84 +61,84 @@ 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> environ <span style="color: #666666">=</span> <span style="color: #BA2121">&#39;pillars_2k&#39;</span>;
<span style="color: #008000; font-weight: bold">const</span> ibl_url <span style="color: #666666">=</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> sky_url <span style="color: #666666">=</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> filamat_url <span style="color: #666666">=</span> <span style="color: #BA2121">&#39;plastic.filamat&#39;</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: #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>
Filament.init([ filamat_url, ibl_url, sky_url ], () =&gt; {
<span style="color: #3D7B7B; font-style: italic">// Create some global aliases to enums for convenience.</span>
<span style="color: #008000">window</span>.VertexAttribute <span style="color: #666666">=</span> Filament.VertexAttribute;
<span style="color: #008000">window</span>.AttributeType <span style="color: #666666">=</span> Filament.VertexBuffer$AttributeType;
<span style="color: #008000">window</span>.PrimitiveType <span style="color: #666666">=</span> Filament.RenderableManager$PrimitiveType;
<span style="color: #008000">window</span>.IndexType <span style="color: #666666">=</span> Filament.IndexBuffer$IndexType;
<span style="color: #008000">window</span>.Fov <span style="color: #666666">=</span> Filament.Camera$Fov;
<span style="color: #008000">window</span>.LightType <span style="color: #666666">=</span> Filament.LightManager$Type;
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>
<span style="color: #3D7B7B; font-style: italic">// Obtain the canvas DOM object and pass it to the App.</span>
<span style="color: #008000; font-weight: bold">const</span> canvas <span style="color: #666666">=</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: #008000">window</span>.app <span style="color: #666666">=</span> <span style="color: #AA22FF; font-weight: bold">new</span> App(canvas);
} );
<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: #008000; font-weight: bold">class</span> App {
<span style="color: #008000; font-weight: bold">constructor</span>(canvas) {
<span style="color: #008000; font-weight: bold">this</span>.canvas <span style="color: #666666">=</span> canvas;
<span style="color: #008000; font-weight: bold">const</span> engine <span style="color: #666666">=</span> <span style="color: #008000; font-weight: bold">this</span>.engine <span style="color: #666666">=</span> Filament.Engine.create(canvas);
<span style="color: #008000; font-weight: bold">const</span> scene <span style="color: #666666">=</span> engine.createScene();
<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: #3D7B7B; font-style: italic">// TODO: create material</span>
<span style="color: #3D7B7B; font-style: italic">// TODO: create sphere</span>
<span style="color: #3D7B7B; font-style: italic">// TODO: create lights</span>
<span style="color: #3D7B7B; font-style: italic">// TODO: create IBL</span>
<span style="color: #3D7B7B; font-style: italic">// TODO: create skybox</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: #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: #008000; font-weight: bold">this</span>.swapChain <span style="color: #666666">=</span> engine.createSwapChain();
<span style="color: #008000; font-weight: bold">this</span>.renderer <span style="color: #666666">=</span> engine.createRenderer();
<span style="color: #008000; font-weight: bold">this</span>.camera <span style="color: #666666">=</span> engine.createCamera(Filament.EntityManager.get().create());
<span style="color: #008000; font-weight: bold">this</span>.view <span style="color: #666666">=</span> engine.createView();
<span style="color: #008000; font-weight: bold">this</span>.view.setCamera(<span style="color: #008000; font-weight: bold">this</span>.camera);
<span style="color: #008000; font-weight: bold">this</span>.view.setScene(scene);
<span style="color: #008000; font-weight: bold">this</span>.resize();
<span style="color: #008000; font-weight: bold">this</span>.render <span style="color: #666666">=</span> <span style="color: #008000; font-weight: bold">this</span>.render.bind(<span style="color: #008000; font-weight: bold">this</span>);
<span style="color: #008000; font-weight: bold">this</span>.resize <span style="color: #666666">=</span> <span style="color: #008000; font-weight: bold">this</span>.resize.bind(<span style="color: #008000; font-weight: bold">this</span>);
<span style="color: #008000">window</span>.addEventListener(<span style="color: #BA2121">&#39;resize&#39;</span>, <span style="color: #008000; font-weight: bold">this</span>.resize);
<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: #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>
render() {
<span style="color: #008000; font-weight: bold">const</span> eye <span style="color: #666666">=</span> [<span style="color: #666666">0</span>, <span style="color: #666666">0</span>, <span style="color: #666666">4</span>], center <span style="color: #666666">=</span> [<span style="color: #666666">0</span>, <span style="color: #666666">0</span>, <span style="color: #666666">0</span>], up <span style="color: #666666">=</span> [<span style="color: #666666">0</span>, <span style="color: #666666">1</span>, <span style="color: #666666">0</span>];
<span style="color: #008000; font-weight: bold">const</span> radians <span style="color: #666666">=</span> <span style="color: #008000">Date</span>.now() <span style="color: #666666">/</span> <span style="color: #666666">10000</span>;
vec3.rotateY(eye, eye, center, radians);
<span style="color: #008000; font-weight: bold">this</span>.camera.lookAt(eye, center, up);
<span style="color: #008000; font-weight: bold">this</span>.renderer.render(<span style="color: #008000; font-weight: bold">this</span>.swapChain, <span style="color: #008000; font-weight: bold">this</span>.view);
<span style="color: #008000">window</span>.requestAnimationFrame(<span style="color: #008000; font-weight: bold">this</span>.render);
}
<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>
resize() {
<span style="color: #008000; font-weight: bold">const</span> dpr <span style="color: #666666">=</span> <span style="color: #008000">window</span>.devicePixelRatio;
<span style="color: #008000; font-weight: bold">const</span> width <span style="color: #666666">=</span> <span style="color: #008000; font-weight: bold">this</span>.canvas.width <span style="color: #666666">=</span> <span style="color: #008000">window</span>.innerWidth <span style="color: #666666">*</span> dpr;
<span style="color: #008000; font-weight: bold">const</span> height <span style="color: #666666">=</span> <span style="color: #008000; font-weight: bold">this</span>.canvas.height <span style="color: #666666">=</span> <span style="color: #008000">window</span>.innerHeight <span style="color: #666666">*</span> dpr;
<span style="color: #008000; font-weight: bold">this</span>.view.setViewport([<span style="color: #666666">0</span>, <span style="color: #666666">0</span>, width, height]);
<span style="color: #008000; font-weight: bold">this</span>.camera.setProjectionFov(<span style="color: #666666">45</span>, width <span style="color: #666666">/</span> height, <span style="color: #666666">1.0</span>, <span style="color: #666666">10.0</span>, Fov.VERTICAL);
}
}
<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>
</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's create a material instance from the package that we built at the beginning the tutorial.
<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> material <span style="color: #666666">=</span> engine.createMaterial(filamat_url);
<span style="color: #008000; font-weight: bold">const</span> matinstance <span style="color: #666666">=</span> material.createInstance();
<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>
<span style="color: #008000; font-weight: bold">const</span> red <span style="color: #666666">=</span> [<span style="color: #666666">0.8</span>, <span style="color: #666666">0.0</span>, <span style="color: #666666">0.0</span>];
matinstance.setColor3Parameter(<span style="color: #BA2121">&#39;baseColor&#39;</span>, Filament.RgbType.sRGB, red);
matinstance.setFloatParameter(<span style="color: #BA2121">&#39;roughness&#39;</span>, <span style="color: #666666">0.5</span>);
matinstance.setFloatParameter(<span style="color: #BA2121">&#39;clearCoat&#39;</span>, <span style="color: #666666">1.0</span>);
matinstance.setFloatParameter(<span style="color: #BA2121">&#39;clearCoatRoughness&#39;</span>, <span style="color: #666666">0.3</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>];<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>
</pre></div>
<p>The next step is to create a renderable for the sphere. To help with this, we'll use the <code>IcoSphere</code>
<p>The next step is to create a renderable for the sphere. To help with this, we&#x27;ll use the <code>IcoSphere</code>
utility class, whose constructor takes a LOD. Its job is to subdivide an icosadedron, producing
three arrays:</p>
<ul>
@@ -147,137 +147,137 @@ three arrays:</p>
as quaternions.</li>
<li><code>icosphere.triangles</code> Uint16Array with triangle indices.</li>
</ul>
<p>Let's go ahead use these arrays to build the vertex buffer and index buffer. Replace <strong>create
<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> renderable <span style="color: #666666">=</span> Filament.EntityManager.get().create();
scene.addEntity(renderable);
<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>
<span style="color: #008000; font-weight: bold">const</span> icosphere <span style="color: #666666">=</span> <span style="color: #AA22FF; font-weight: bold">new</span> Filament.IcoSphere(<span style="color: #666666">5</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: #bbbbbb"></span>
<span style="color: #008000; font-weight: bold">const</span> vb <span style="color: #666666">=</span> Filament.VertexBuffer.Builder()
.vertexCount(icosphere.vertices.length <span style="color: #666666">/</span> <span style="color: #666666">3</span>)
.bufferCount(<span style="color: #666666">2</span>)
.attribute(VertexAttribute.POSITION, <span style="color: #666666">0</span>, AttributeType.FLOAT3, <span style="color: #666666">0</span>, <span style="color: #666666">0</span>)
.attribute(VertexAttribute.TANGENTS, <span style="color: #666666">1</span>, AttributeType.SHORT4, <span style="color: #666666">0</span>, <span style="color: #666666">0</span>)
.normalized(VertexAttribute.TANGENTS)
.build(engine);
<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> ib <span style="color: #666666">=</span> Filament.IndexBuffer.Builder()
.indexCount(icosphere.triangles.length)
.bufferType(IndexType.USHORT)
.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>
vb.setBufferAt(engine, <span style="color: #666666">0</span>, icosphere.vertices);
vb.setBufferAt(engine, <span style="color: #666666">1</span>, icosphere.tangents);
ib.setBuffer(engine, icosphere.triangles);
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>
Filament.RenderableManager.Builder(<span style="color: #666666">1</span>)
.boundingBox({ center<span style="color: #666666">:</span> [<span style="color: #666666">-1</span>, <span style="color: #666666">-1</span>, <span style="color: #666666">-1</span>], halfExtent<span style="color: #666666">:</span> [<span style="color: #666666">1</span>, <span style="color: #666666">1</span>, <span style="color: #666666">1</span>] })
.material(<span style="color: #666666">0</span>, matinstance)
.geometry(<span style="color: #666666">0</span>, PrimitiveType.TRIANGLES, vb, ib)
.build(engine, renderable);
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>
</pre></div>
<p>At this point, the app is rendering a sphere, but it is black so it doesn't show up. To prove that
<p>At this point, the app is rendering a sphere, but it is black so it doesn&#x27;t show up. To prove that
the sphere is there, you can try changing the background color to blue via <code>setClearColor</code>, like we
did in the first tutorial.</p>
<h2>Add lighting</h2>
<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> sunlight <span style="color: #666666">=</span> Filament.EntityManager.get().create();
scene.addEntity(sunlight);
Filament.LightManager.Builder(LightType.SUN)
.color([<span style="color: #666666">0.98</span>, <span style="color: #666666">0.92</span>, <span style="color: #666666">0.89</span>])
.intensity(<span style="color: #666666">110000.0</span>)
.direction([<span style="color: #666666">0.6</span>, <span style="color: #666666">-1.0</span>, <span style="color: #666666">-0.8</span>])
.sunAngularRadius(<span style="color: #666666">1.9</span>)
.sunHaloSize(<span style="color: #666666">10.0</span>)
.sunHaloFalloff(<span style="color: #666666">80.0</span>)
.build(engine, sunlight);
<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>
<span style="color: #008000; font-weight: bold">const</span> backlight <span style="color: #666666">=</span> Filament.EntityManager.get().create();
scene.addEntity(backlight);
Filament.LightManager.Builder(LightType.DIRECTIONAL)
.direction([<span style="color: #666666">-1</span>, <span style="color: #666666">0</span>, <span style="color: #666666">1</span>])
.intensity(<span style="color: #666666">50000.0</span>)
.build(engine, backlight);
<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>
</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't type this out, there'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> format <span style="color: #666666">=</span> Filament.PixelDataFormat.RGB;
<span style="color: #008000; font-weight: bold">const</span> datatype <span style="color: #666666">=</span> Filament.PixelDataType.UINT_10F_11F_11F_REV;
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>
<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> ibl_package <span style="color: #666666">=</span> Filament.Buffer(Filament.assets[ibl_url]);
<span style="color: #008000; font-weight: bold">const</span> iblktx <span style="color: #666666">=</span> <span style="color: #AA22FF; font-weight: bold">new</span> Filament.Ktx1Bundle(ibl_package);
<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: #008000; font-weight: bold">const</span> ibltex <span style="color: #666666">=</span> Filament.Texture.Builder()
.width(iblktx.info().pixelWidth)
.height(iblktx.info().pixelHeight)
.levels(iblktx.getNumMipLevels())
.sampler(Filament.Texture$Sampler.SAMPLER_CUBEMAP)
.format(Filament.Texture$InternalFormat.RGBA8)
.build(engine);
<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">for</span> (<span style="color: #008000; font-weight: bold">let</span> level <span style="color: #666666">=</span> <span style="color: #666666">0</span>; level <span style="color: #666666">&lt;</span> iblktx.getNumMipLevels(); <span style="color: #666666">++</span>level) {
<span style="color: #008000; font-weight: bold">const</span> uint8array <span style="color: #666666">=</span> iblktx.getCubeBlob(level).getBytes();
<span style="color: #008000; font-weight: bold">const</span> pixelbuffer <span style="color: #666666">=</span> Filament.PixelBuffer(uint8array, format, datatype);
ibltex.setImageCube(engine, level, pixelbuffer);
}
<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: #3D7B7B; font-style: italic">// Parse the spherical harmonics metadata.</span>
<span style="color: #008000; font-weight: bold">const</span> shstring <span style="color: #666666">=</span> iblktx.getMetadata(<span style="color: #BA2121">&#39;sh&#39;</span>);
<span style="color: #008000; font-weight: bold">const</span> shfloats <span style="color: #666666">=</span> shstring.split(<span style="color: #A45A77">/\s/</span>, <span style="color: #666666">9</span> <span style="color: #666666">*</span> <span style="color: #666666">3</span>).map(<span style="color: #008000">parseFloat</span>);
<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">// Build the IBL object and insert it into the scene.</span>
<span style="color: #008000; font-weight: bold">const</span> indirectLight <span style="color: #666666">=</span> Filament.IndirectLight.Builder()
.reflections(ibltex)
.irradianceSh(<span style="color: #666666">3</span>, shfloats)
.intensity(<span style="color: #666666">50000.0</span>)
.build(engine);
<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>
scene.setIndirectLight(indirectLight);
scene.setIndirectLight(indirectLight);<span style="color: #bbbbbb"></span>
</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> indirectLight <span style="color: #666666">=</span> engine.createIblFromKtx(ibl_url);
indirectLight.setIntensity(<span style="color: #666666">50000</span>);
scene.setIndirectLight(indirectLight);
<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>
</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'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> sky_package <span style="color: #666666">=</span> Filament.Buffer(Filament.assets[sky_url]);
<span style="color: #008000; font-weight: bold">const</span> skyktx <span style="color: #666666">=</span> <span style="color: #AA22FF; font-weight: bold">new</span> Filament.Ktx1Bundle(sky_package);
<span style="color: #008000; font-weight: bold">const</span> skytex <span style="color: #666666">=</span> Filament.Texture.Builder()
.width(skyktx.info().pixelWidth)
.height(skyktx.info().pixelHeight)
.levels(<span style="color: #666666">1</span>)
.sampler(Filament.Texture$Sampler.SAMPLER_CUBEMAP)
.format(Filament.Texture$InternalFormat.RGBA8)
.build(engine);
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>
<span style="color: #008000; font-weight: bold">const</span> uint8array <span style="color: #666666">=</span> skyktx.getCubeBlob(<span style="color: #666666">0</span>).getBytes();
<span style="color: #008000; font-weight: bold">const</span> pixelbuffer <span style="color: #666666">=</span> Filament.PixelBuffer(uint8array, format, datatype);
skytex.setImageCube(engine, <span style="color: #666666">0</span>, pixelbuffer);
<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>
</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> skybox <span style="color: #666666">=</span> engine.createSkyFromKtx(sky_url);
scene.setSkybox(skybox);
<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>
</pre></div>
<p>That's it, we now have a shiny red ball floating in an environment! The complete JavaScript file is
<p>That&#x27;s it, we now have a shiny red ball floating in an environment! The complete JavaScript file is
available <a href="tutorial_redball.js">here</a>.</p>
<p>In the <a href="tutorial_suzanne.html">next tutorial</a>, we'll take a closer look at textures and interaction.</p>
<p>In the <a href="tutorial_suzanne.html">next tutorial</a>, we&#x27;ll take a closer look at textures and interaction.</p>
</body>
</html>

View File

@@ -70,10 +70,10 @@ class App {
.direction([-1, 0, 1])
.intensity(50000.0)
.build(engine, backlight);
const indirectLight = engine.createIblFromKtx(ibl_url);
const indirectLight = engine.createIblFromKtx1(ibl_url);
indirectLight.setIntensity(50000);
scene.setIndirectLight(indirectLight);
const skybox = engine.createSkyFromKtx(sky_url);
const skybox = engine.createSkyFromKtx1(sky_url);
scene.setSkybox(skybox);
this.swapChain = engine.createSwapChain();
this.renderer = engine.createRenderer();

View File

@@ -8,18 +8,18 @@
<div class="demo_frame"><iframe src="demo_suzanne.html"></iframe><a href="demo_suzanne.html">&#x1F517;</a></div>
<p>This tutorial will describe how to create the <strong>suzanne</strong> demo, introducing you to compressed
textures, mipmap generation, asynchronous texture loading, and trackball rotation.</p>
<p>Much like the <a href="tutorial_redball.html">previous tutorial</a>, you'll need to use the command-line tools that can be found in
<p>Much like the <a href="tutorial_redball.html">previous tutorial</a>, you&#x27;ll need to use the command-line tools that can be found in
the appropriate <a href="//github.com/google/filament/releases">Filament release</a> for your development machine. In addition to <code>matc</code> and <code>cmgen</code>,
we'll also be using <code>filamesh</code> and <code>mipgen</code>.</p>
we&#x27;ll also be using <code>filamesh</code> and <code>mipgen</code>.</p>
<h2>Create filamesh file</h2>
<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's create a compressed filamesh file for suzanne by
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
</pre></div>
<h2>Create mipmapped textures</h2>
<p>Next, let's create mipmapped KTX files using filament's <code>mipgen</code> tool. We'll create compressed and
<p>Next, let&#x27;s create mipmapped KTX files using filament&#x27;s <code>mipgen</code> tool. We&#x27;ll create compressed and
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>
@@ -45,10 +45,10 @@ mipgen --grayscale ao.png ao.ktx
mipgen --grayscale --compression<span style="color: #666666">=</span>etc_r11_numeric_40 ao.png ao_etc.ktx
</pre></div>
<p>For more information on mipgen's arguments and supported formats, do <code>mipgen --help</code>.</p>
<p>In a production setting, you'd want to invoke these commands with a script or build system.</p>
<p>For more information on mipgen&#x27;s arguments and supported formats, do <code>mipgen --help</code>.</p>
<p>In a production setting, you&#x27;d want to invoke these commands with a script or build system.</p>
<h2>Bake environment map</h2>
<p>Much like the <a href="tutorial_redball.html">previous tutorial</a> we need to use Filament's <code>cmgen</code> tool to produce cubemap files.</p>
<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> -
@@ -60,7 +60,7 @@ cmgen -x . --format<span style="color: #666666">=</span>ktx --size<span style="c
<h2>Define textured material</h2>
<p>You might recall the <code>filamat</code> file we generated in the previous tutorial for red plastic. For this
demo, we'll create a material that uses textures for several parameters.</p>
demo, we&#x27;ll create a material that uses textures for several parameters.</p>
<p>Create the following text file and call it <code>textured.mat</code>. Note that our material definition now
requires a <code>uv0</code> attribute.</p>
<div class="highlight" style="background: #f8f8f8"><pre style="line-height: 125%;"><span></span>material {
@@ -101,65 +101,65 @@ 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>
<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>
Filament.init([ filamat_url, filamesh_url, sky_small_url, ibl_url ], () =&gt; {
<span style="color: #008000">window</span>.app <span style="color: #666666">=</span> <span style="color: #AA22FF; font-weight: bold">new</span> App(<span style="color: #008000">document</span>.getElementsByTagName(<span style="color: #BA2121">&#39;canvas&#39;</span>)[<span style="color: #666666">0</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>
<span style="color: #008000; font-weight: bold">class</span> App {
<span style="color: #008000; font-weight: bold">constructor</span>(canvas) {
<span style="color: #008000; font-weight: bold">this</span>.canvas <span style="color: #666666">=</span> canvas;
<span style="color: #008000; font-weight: bold">this</span>.engine <span style="color: #666666">=</span> Filament.Engine.create(canvas);
<span style="color: #008000; font-weight: bold">this</span>.scene <span style="color: #666666">=</span> <span style="color: #008000; font-weight: bold">this</span>.engine.createScene();
<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">const</span> material <span style="color: #666666">=</span> <span style="color: #008000; font-weight: bold">this</span>.engine.createMaterial(filamat_url);
<span style="color: #008000; font-weight: bold">this</span>.matinstance <span style="color: #666666">=</span> material.createInstance();
<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: #008000; font-weight: bold">const</span> filamesh <span style="color: #666666">=</span> <span style="color: #008000; font-weight: bold">this</span>.engine.loadFilamesh(filamesh_url, <span style="color: #008000; font-weight: bold">this</span>.matinstance);
<span style="color: #008000; font-weight: bold">this</span>.suzanne <span style="color: #666666">=</span> filamesh.renderable;
<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: #3D7B7B; font-style: italic">// TODO: create sky box and IBL</span>
<span style="color: #3D7B7B; font-style: italic">// TODO: initialize gltumble</span>
<span style="color: #3D7B7B; font-style: italic">// TODO: fetch larger assets</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: #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: #008000; font-weight: bold">this</span>.swapChain <span style="color: #666666">=</span> <span style="color: #008000; font-weight: bold">this</span>.engine.createSwapChain();
<span style="color: #008000; font-weight: bold">this</span>.renderer <span style="color: #666666">=</span> <span style="color: #008000; font-weight: bold">this</span>.engine.createRenderer();
<span style="color: #008000; font-weight: bold">this</span>.camera <span style="color: #666666">=</span> <span style="color: #008000; font-weight: bold">this</span>.engine.createCamera(Filament.EntityManager.get().create());
<span style="color: #008000; font-weight: bold">this</span>.view <span style="color: #666666">=</span> <span style="color: #008000; font-weight: bold">this</span>.engine.createView();
<span style="color: #008000; font-weight: bold">this</span>.view.setCamera(<span style="color: #008000; font-weight: bold">this</span>.camera);
<span style="color: #008000; font-weight: bold">this</span>.view.setScene(<span style="color: #008000; font-weight: bold">this</span>.scene);
<span style="color: #008000; font-weight: bold">this</span>.render <span style="color: #666666">=</span> <span style="color: #008000; font-weight: bold">this</span>.render.bind(<span style="color: #008000; font-weight: bold">this</span>);
<span style="color: #008000; font-weight: bold">this</span>.resize <span style="color: #666666">=</span> <span style="color: #008000; font-weight: bold">this</span>.resize.bind(<span style="color: #008000; font-weight: bold">this</span>);
<span style="color: #008000">window</span>.addEventListener(<span style="color: #BA2121">&#39;resize&#39;</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>.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: #008000; font-weight: bold">const</span> eye <span style="color: #666666">=</span> [<span style="color: #666666">0</span>, <span style="color: #666666">0</span>, <span style="color: #666666">4</span>], center <span style="color: #666666">=</span> [<span style="color: #666666">0</span>, <span style="color: #666666">0</span>, <span style="color: #666666">0</span>], up <span style="color: #666666">=</span> [<span style="color: #666666">0</span>, <span style="color: #666666">1</span>, <span style="color: #666666">0</span>];
<span style="color: #008000; font-weight: bold">this</span>.camera.lookAt(eye, center, up);
<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: #008000; font-weight: bold">this</span>.resize();
<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: #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>
render() {
<span style="color: #3D7B7B; font-style: italic">// TODO: apply gltumble matrix</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: #008000; font-weight: bold">this</span>.view);
<span style="color: #008000">window</span>.requestAnimationFrame(<span style="color: #008000; font-weight: bold">this</span>.render);
}
<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>
resize() {
<span style="color: #008000; font-weight: bold">const</span> dpr <span style="color: #666666">=</span> <span style="color: #008000">window</span>.devicePixelRatio;
<span style="color: #008000; font-weight: bold">const</span> width <span style="color: #666666">=</span> <span style="color: #008000; font-weight: bold">this</span>.canvas.width <span style="color: #666666">=</span> <span style="color: #008000">window</span>.innerWidth <span style="color: #666666">*</span> dpr;
<span style="color: #008000; font-weight: bold">const</span> height <span style="color: #666666">=</span> <span style="color: #008000; font-weight: bold">this</span>.canvas.height <span style="color: #666666">=</span> <span style="color: #008000">window</span>.innerHeight <span style="color: #666666">*</span> dpr;
<span style="color: #008000; font-weight: bold">this</span>.view.setViewport([<span style="color: #666666">0</span>, <span style="color: #666666">0</span>, width, height]);
<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: #008000; font-weight: bold">const</span> aspect <span style="color: #666666">=</span> width <span style="color: #666666">/</span> height;
<span style="color: #008000; font-weight: bold">const</span> Fov <span style="color: #666666">=</span> Filament.Camera$Fov, fov <span style="color: #666666">=</span> aspect <span style="color: #666666">&lt;</span> <span style="color: #666666">1</span> <span style="color: #666666">?</span> Fov.HORIZONTAL <span style="color: #666666">:</span> Fov.VERTICAL;
<span style="color: #008000; font-weight: bold">this</span>.camera.setProjectionFov(<span style="color: #666666">45</span>, aspect, <span style="color: #666666">1.0</span>, <span style="color: #666666">10.0</span>, fov);
}
}
<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>
</pre></div>
<p>Our app will only require a subset of assets to be present for <code>App</code> construction. We'll download
<p>Our app will only require a subset of assets to be present for <code>App</code> construction. We&#x27;ll download
the other assets after construction. By using a progressive loading strategy, we can reduce the
perceived load time.</p>
<p>Next we need to supply the URLs for various assets. This is actually a bit tricky, because different
@@ -172,65 +172,65 @@ 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> albedo_suffix <span style="color: #666666">=</span> Filament.getSupportedFormatSuffix(<span style="color: #BA2121">&#39;astc s3tc_srgb&#39;</span>);
<span style="color: #008000; font-weight: bold">const</span> texture_suffix <span style="color: #666666">=</span> Filament.getSupportedFormatSuffix(<span style="color: #BA2121">&#39;etc&#39;</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: #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>
<span style="color: #008000; font-weight: bold">const</span> environ <span style="color: #666666">=</span> <span style="color: #BA2121">&#39;venetian_crossroads_2k&#39;</span>
<span style="color: #008000; font-weight: bold">const</span> ibl_url <span style="color: #666666">=</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> sky_small_url <span style="color: #666666">=</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> sky_large_url <span style="color: #666666">=</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> albedo_url <span style="color: #666666">=</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> ao_url <span style="color: #666666">=</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> metallic_url <span style="color: #666666">=</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> normal_url <span style="color: #666666">=</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> roughness_url <span style="color: #666666">=</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> filamat_url <span style="color: #666666">=</span> <span style="color: #BA2121">&#39;textured.filamat&#39;</span>;
<span style="color: #008000; font-weight: bold">const</span> filamesh_url <span style="color: #666666">=</span> <span style="color: #BA2121">&#39;suzanne.filamesh&#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>
</pre></div>
<h2>Create skybox and IBL</h2>
<p>Next, let'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: #666666">=</span> <span style="color: #008000; font-weight: bold">this</span>.engine.createSkyFromKtx(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: #666666">=</span> <span style="color: #008000; font-weight: bold">this</span>.engine.createIblFromKtx(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);
<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>
</pre></div>
<p>This allows users to see a reasonable background fairly quickly, before larger assets have finished
loading in.</p>
<h2>Fetch assets asychronously</h2>
<p>Next we'll invoke the <code>Filament.fetch</code> function from within the app constructor. This function is
<p>Next we&#x27;ll invoke the <code>Filament.fetch</code> function from within the app constructor. This function is
very similar to <code>Filament.init</code>. It takes a list of asset URLs and a callback function that triggers
when the assets have finished downloading.</p>
<p>In our callback, we'll make several <code>setTextureParameter</code> calls on the material instance, then we'll
<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, albedo_url, roughness_url, metallic_url, normal_url, ao_url], () =&gt; {
<span style="color: #008000; font-weight: bold">const</span> albedo <span style="color: #666666">=</span> <span style="color: #008000; font-weight: bold">this</span>.engine.createTextureFromKtx(albedo_url, {srgb<span style="color: #666666">:</span> <span style="color: #008000; font-weight: bold">true</span>});
<span style="color: #008000; font-weight: bold">const</span> roughness <span style="color: #666666">=</span> <span style="color: #008000; font-weight: bold">this</span>.engine.createTextureFromKtx(roughness_url);
<span style="color: #008000; font-weight: bold">const</span> metallic <span style="color: #666666">=</span> <span style="color: #008000; font-weight: bold">this</span>.engine.createTextureFromKtx(metallic_url);
<span style="color: #008000; font-weight: bold">const</span> normal <span style="color: #666666">=</span> <span style="color: #008000; font-weight: bold">this</span>.engine.createTextureFromKtx(normal_url);
<span style="color: #008000; font-weight: bold">const</span> ao <span style="color: #666666">=</span> <span style="color: #008000; font-weight: bold">this</span>.engine.createTextureFromKtx(ao_url);
<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>
<span style="color: #008000; font-weight: bold">const</span> sampler <span style="color: #666666">=</span> <span style="color: #AA22FF; font-weight: bold">new</span> Filament.TextureSampler(
Filament.MinFilter.LINEAR_MIPMAP_LINEAR,
Filament.MagFilter.LINEAR,
Filament.WrapMode.CLAMP_TO_EDGE);
<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: #008000; font-weight: bold">this</span>.matinstance.setTextureParameter(<span style="color: #BA2121">&#39;albedo&#39;</span>, albedo, sampler);
<span style="color: #008000; font-weight: bold">this</span>.matinstance.setTextureParameter(<span style="color: #BA2121">&#39;roughness&#39;</span>, roughness, sampler);
<span style="color: #008000; font-weight: bold">this</span>.matinstance.setTextureParameter(<span style="color: #BA2121">&#39;metallic&#39;</span>, metallic, sampler);
<span style="color: #008000; font-weight: bold">this</span>.matinstance.setTextureParameter(<span style="color: #BA2121">&#39;normal&#39;</span>, normal, sampler);
<span style="color: #008000; font-weight: bold">this</span>.matinstance.setTextureParameter(<span style="color: #BA2121">&#39;ao&#39;</span>, ao, sampler);
<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: #3D7B7B; font-style: italic">// Replace low-res skybox with high-res skybox.</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: #008000; font-weight: bold">this</span>.skybox <span style="color: #666666">=</span> <span style="color: #008000; font-weight: bold">this</span>.engine.createSkyFromKtx(sky_large_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: #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: #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: #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>
</pre></div>
<h2>Introduce trackball rotation</h2>
@@ -241,16 +241,16 @@ 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: #666666">=</span> <span style="color: #AA22FF; font-weight: bold">new</span> Trackball(canvas, {startSpin<span style="color: #666666">:</span> <span style="color: #666666">0.035</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>});<span style="color: #bbbbbb"></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> tcm <span style="color: #666666">=</span> <span style="color: #008000; font-weight: bold">this</span>.engine.getTransformManager();
<span style="color: #008000; font-weight: bold">const</span> inst <span style="color: #666666">=</span> tcm.getInstance(<span style="color: #008000; font-weight: bold">this</span>.suzanne);
tcm.setTransform(inst, <span style="color: #008000; font-weight: bold">this</span>.trackball.getMatrix());
inst.<span style="color: #AA22FF; font-weight: bold">delete</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: #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>
</pre></div>
<p>That's it, we now have a fast-loading interactive demo. The complete JavaScript file is available
<p>That&#x27;s it, we now have a fast-loading interactive demo. The complete JavaScript file is available
<a href="tutorial_suzanne.js">here</a>.</p>
</body>

View File

@@ -23,9 +23,9 @@ class App {
this.matinstance = material.createInstance();
const filamesh = this.engine.loadFilamesh(filamesh_url, this.matinstance);
this.suzanne = filamesh.renderable;
this.skybox = this.engine.createSkyFromKtx(sky_small_url);
this.skybox = this.engine.createSkyFromKtx1(sky_small_url);
this.scene.setSkybox(this.skybox);
this.indirectLight = this.engine.createIblFromKtx(ibl_url);
this.indirectLight = this.engine.createIblFromKtx1(ibl_url);
this.indirectLight.setIntensity(100000);
this.scene.setIndirectLight(this.indirectLight);
this.trackball = new Trackball(canvas, {
@@ -33,13 +33,13 @@ class App {
});
Filament.fetch([sky_large_url, albedo_url, roughness_url, metallic_url, normal_url, ao_url],
() => {
const albedo = this.engine.createTextureFromKtx(albedo_url, {
const albedo = this.engine.createTextureFromKtx1(albedo_url, {
srgb: true
});
const roughness = this.engine.createTextureFromKtx(roughness_url);
const metallic = this.engine.createTextureFromKtx(metallic_url);
const normal = this.engine.createTextureFromKtx(normal_url);
const ao = this.engine.createTextureFromKtx(ao_url);
const roughness = this.engine.createTextureFromKtx1(roughness_url);
const metallic = this.engine.createTextureFromKtx1(metallic_url);
const normal = this.engine.createTextureFromKtx1(normal_url);
const ao = this.engine.createTextureFromKtx1(ao_url);
const sampler = new Filament.TextureSampler(Filament.MinFilter.LINEAR_MIPMAP_LINEAR,
Filament.MagFilter.LINEAR, Filament.WrapMode.CLAMP_TO_EDGE);
this.matinstance.setTextureParameter('albedo', albedo, sampler);
@@ -49,7 +49,7 @@ class App {
this.matinstance.setTextureParameter('ao', ao, sampler);
// Replace low-res skybox with high-res skybox.
this.engine.destroySkybox(this.skybox);
this.skybox = this.engine.createSkyFromKtx(sky_large_url);
this.skybox = this.engine.createSkyFromKtx1(sky_large_url);
this.scene.setSkybox(this.skybox);
this.scene.addEntity(this.suzanne);
});

View File

@@ -8,9 +8,9 @@
<div class="demo_frame"><iframe src="demo_triangle.html"></iframe><a href="demo_triangle.html">&#x1F517;</a></div>
<h2>Literate programming</h2>
<p>The markdown source for this tutorial is not only used to generate this
web page, it's also used to generate the JavaScript for the above demo.
web page, it&#x27;s also used to generate the JavaScript for the above demo.
We use a small Python script for weaving (generating HTML) and tangling
(generating JS). In the code samples, you'll often see
(generating JS). In the code samples, you&#x27;ll often see
<code>// TODO: &lt;some task&gt;</code>. These are special markers that get replaced by
subsequent code blocks.</p>
<h2>Start your project</h2>
@@ -48,36 +48,36 @@ a mobile-friendly page with a full-screen canvas.</p>
<li><code>triangle.js</code> will contain your application code.</li>
</ul>
<p>Go ahead and create <code>triangle.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">class</span> App {
<span style="color: #008000; font-weight: bold">constructor</span>() {
<span style="color: #3D7B7B; font-style: italic">// TODO: create entities</span>
<span style="color: #008000; font-weight: bold">this</span>.render <span style="color: #666666">=</span> <span style="color: #008000; font-weight: bold">this</span>.render.bind(<span style="color: #008000; font-weight: bold">this</span>);
<span style="color: #008000; font-weight: bold">this</span>.resize <span style="color: #666666">=</span> <span style="color: #008000; font-weight: bold">this</span>.resize.bind(<span style="color: #008000; font-weight: bold">this</span>);
<span style="color: #008000">window</span>.addEventListener(<span style="color: #BA2121">&#39;resize&#39;</span>, <span style="color: #008000; font-weight: bold">this</span>.resize);
<span style="color: #008000">window</span>.requestAnimationFrame(<span style="color: #008000; font-weight: bold">this</span>.render);
}
render() {
<span style="color: #3D7B7B; font-style: italic">// TODO: render scene</span>
<span style="color: #008000">window</span>.requestAnimationFrame(<span style="color: #008000; font-weight: bold">this</span>.render);
}
resize() {
<span style="color: #3D7B7B; font-style: italic">// TODO: adjust viewport and canvas</span>
}
}
<div class="highlight" style="background: #f8f8f8"><pre style="line-height: 125%;"><span></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>()<span style="color: #bbbbbb"> </span>{<span style="color: #bbbbbb"></span>
<span style="color: #bbbbbb"> </span><span style="color: #3D7B7B; font-style: italic">// TODO: create entities</span><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>render()<span style="color: #bbbbbb"> </span>{<span style="color: #bbbbbb"></span>
<span style="color: #bbbbbb"> </span><span style="color: #3D7B7B; font-style: italic">// TODO: render scene</span><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>resize()<span style="color: #bbbbbb"> </span>{<span style="color: #bbbbbb"></span>
<span style="color: #bbbbbb"> </span><span style="color: #3D7B7B; font-style: italic">// TODO: adjust viewport and canvas</span><span style="color: #bbbbbb"></span>
<span style="color: #bbbbbb"> </span>}<span style="color: #bbbbbb"></span>
}<span style="color: #bbbbbb"></span>
Filament.init([<span style="color: #BA2121">&#39;triangle.filamat&#39;</span>], () =&gt; { <span style="color: #008000">window</span>.app <span style="color: #666666">=</span> <span style="color: #AA22FF; font-weight: bold">new</span> App() } );
Filament.init([<span style="color: #BA2121">&#39;triangle.filamat&#39;</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: #bbbbbb"> </span>}<span style="color: #bbbbbb"> </span>);<span style="color: #bbbbbb"></span>
</pre></div>
<p>The two calls to <code>bind()</code> allow us to pass instance methods as callbacks for animation and resize
events.</p>
<p><code>Filament.init()</code> consumes two things: a list of asset URLs and a callback.</p>
<p>The callback will be triggered only after all assets finish downloading and the Filament module has
become ready. In our callback, we simply instantiated the <code>App</code> object, since we'll do most of the
become ready. In our callback, we simply instantiated the <code>App</code> object, since we&#x27;ll do most of the
work in its constructor. We also set the app instance into a <code>Window</code> property to make it accessible
from the developer console.</p>
<p>Go ahead and download <a href="triangle.filamat">triangle.filamat</a> and place it in your project folder.
This is a <em>material package</em>, which is a binary file that contains shaders and other bits of data
that define a PBR material. We'll learn more about material packages in the next tutorial.</p>
that define a PBR material. We&#x27;ll learn more about material packages in the next tutorial.</p>
<h2>Spawn a local server</h2>
<p>Because of CORS restrictions, your web app cannot fetch the material package directly from the
file system. One way around this is to create a temporary server using Python or node:</p>
@@ -88,23 +88,23 @@ npx http-server -p <span style="color: #666666">8000</span> <span style="colo
<p>To see if this works, navigate to <a href="http://localhost:8000">http://localhost:8000</a> and check if you
can load the page without any errors appearing in the developer console.</p>
<p>Take care not to use Python's simple server in production since it does not serve WebAssembly files
<p>Take care not to use Python&#x27;s simple server in production since it does not serve WebAssembly files
with the correct MIME type.</p>
<h2>Create the Engine and Scene</h2>
<p>We now have a basic skeleton that can respond to paint and resize events. Let's start adding
<p>We now have a basic skeleton that can respond to paint and resize events. Let&#x27;s start adding
Filament objects to the app. Insert the following code into the top of the app constructor.</p>
<div class="highlight" style="background: #f8f8f8"><pre style="line-height: 125%;"><span></span><span style="color: #008000; font-weight: bold">this</span>.canvas <span style="color: #666666">=</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: #008000; font-weight: bold">const</span> engine <span style="color: #666666">=</span> <span style="color: #008000; font-weight: bold">this</span>.engine <span style="color: #666666">=</span> Filament.Engine.create(<span style="color: #008000; font-weight: bold">this</span>.canvas);
<div class="highlight" style="background: #f8f8f8"><pre style="line-height: 125%;"><span></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><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; 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(<span style="color: #008000; font-weight: bold">this</span>.canvas);<span style="color: #bbbbbb"></span>
</pre></div>
<p>The above snippet creates the <code>Engine</code> by passing it a canvas DOM object. The engine needs the
canvas in order to create a WebGL 2.0 context in its contructor.</p>
<p>The engine is a factory for many Filament entities, including <code>Scene</code>, which is a flat container of
entities. Let's go ahead and create a scene, then add a blank entity called <code>triangle</code> into the
entities. Let&#x27;s go ahead and create a scene, then add a blank entity called <code>triangle</code> into the
scene.</p>
<div class="highlight" style="background: #f8f8f8"><pre style="line-height: 125%;"><span></span><span style="color: #008000; font-weight: bold">this</span>.scene <span style="color: #666666">=</span> engine.createScene();
<span style="color: #008000; font-weight: bold">this</span>.triangle <span style="color: #666666">=</span> Filament.EntityManager.get().create();
<span style="color: #008000; font-weight: bold">this</span>.scene.addEntity(<span style="color: #008000; font-weight: bold">this</span>.triangle);
<div class="highlight" style="background: #f8f8f8"><pre style="line-height: 125%;"><span></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>engine.createScene();<span style="color: #bbbbbb"></span>
<span style="color: #008000; font-weight: bold">this</span>.triangle<span style="color: #bbbbbb"> </span><span style="color: #666666">=</span><span style="color: #bbbbbb"> </span>Filament.EntityManager.get().create();<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>.triangle);<span style="color: #bbbbbb"></span>
</pre></div>
<p>Filament uses an <a href="//en.wikipedia.org/wiki/Entity-component-system">Entity-Component System</a>.
@@ -112,30 +112,30 @@ The triangle entity in the above snippet does not yet have an associated compone
tutorial we will make it into a <em>renderable</em>. Renderables are entities that have associated draw
calls.</p>
<h2>Construct typed arrays</h2>
<p>Next we'll create two typed arrays: a positions array with XY coordinates for each vertex, and a
<p>Next we&#x27;ll create two typed arrays: a positions array with XY coordinates for each vertex, and a
colors array with a 32-bit word for each vertex.</p>
<div class="highlight" style="background: #f8f8f8"><pre style="line-height: 125%;"><span></span><span style="color: #008000; font-weight: bold">const</span> TRIANGLE_POSITIONS <span style="color: #666666">=</span> <span style="color: #AA22FF; font-weight: bold">new</span> <span style="color: #008000">Float32Array</span>([
<span style="color: #666666">1</span>, <span style="color: #666666">0</span>,
<span style="color: #008000">Math</span>.cos(<span style="color: #008000">Math</span>.PI <span style="color: #666666">*</span> <span style="color: #666666">2</span> <span style="color: #666666">/</span> <span style="color: #666666">3</span>), <span style="color: #008000">Math</span>.sin(<span style="color: #008000">Math</span>.PI <span style="color: #666666">*</span> <span style="color: #666666">2</span> <span style="color: #666666">/</span> <span style="color: #666666">3</span>),
<span style="color: #008000">Math</span>.cos(<span style="color: #008000">Math</span>.PI <span style="color: #666666">*</span> <span style="color: #666666">4</span> <span style="color: #666666">/</span> <span style="color: #666666">3</span>), <span style="color: #008000">Math</span>.sin(<span style="color: #008000">Math</span>.PI <span style="color: #666666">*</span> <span style="color: #666666">4</span> <span style="color: #666666">/</span> <span style="color: #666666">3</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>TRIANGLE_POSITIONS<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><span style="color: #008000">Float32Array</span>([<span style="color: #bbbbbb"></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">Math</span>.cos(<span style="color: #008000">Math</span>.PI<span style="color: #bbbbbb"> </span><span style="color: #666666">*</span><span style="color: #bbbbbb"> </span><span style="color: #666666">2</span><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: #008000">Math</span>.sin(<span style="color: #008000">Math</span>.PI<span style="color: #bbbbbb"> </span><span style="color: #666666">*</span><span style="color: #bbbbbb"> </span><span style="color: #666666">2</span><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><span style="color: #008000">Math</span>.cos(<span style="color: #008000">Math</span>.PI<span style="color: #bbbbbb"> </span><span style="color: #666666">*</span><span style="color: #bbbbbb"> </span><span style="color: #666666">4</span><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: #008000">Math</span>.sin(<span style="color: #008000">Math</span>.PI<span style="color: #bbbbbb"> </span><span style="color: #666666">*</span><span style="color: #bbbbbb"> </span><span style="color: #666666">4</span><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>
<span style="color: #008000; font-weight: bold">const</span> TRIANGLE_COLORS <span style="color: #666666">=</span> <span style="color: #AA22FF; font-weight: bold">new</span> <span style="color: #008000">Uint32Array</span>([<span style="color: #666666">0xffff0000</span>, <span style="color: #666666">0xff00ff00</span>, <span style="color: #666666">0xff0000ff</span>]);
<span style="color: #008000; font-weight: bold">const</span><span style="color: #bbbbbb"> </span>TRIANGLE_COLORS<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><span style="color: #008000">Uint32Array</span>([<span style="color: #666666">0xffff0000</span>,<span style="color: #bbbbbb"> </span><span style="color: #666666">0xff00ff00</span>,<span style="color: #bbbbbb"> </span><span style="color: #666666">0xff0000ff</span>]);<span style="color: #bbbbbb"></span>
</pre></div>
<p>Next we'll use the positions and colors buffers to create a single <code>VertexBuffer</code> object.</p>
<div class="highlight" style="background: #f8f8f8"><pre style="line-height: 125%;"><span></span><span style="color: #008000; font-weight: bold">const</span> VertexAttribute <span style="color: #666666">=</span> Filament.VertexAttribute;
<span style="color: #008000; font-weight: bold">const</span> AttributeType <span style="color: #666666">=</span> Filament.VertexBuffer$AttributeType;
<span style="color: #008000; font-weight: bold">this</span>.vb <span style="color: #666666">=</span> Filament.VertexBuffer.Builder()
.vertexCount(<span style="color: #666666">3</span>)
.bufferCount(<span style="color: #666666">2</span>)
.attribute(VertexAttribute.POSITION, <span style="color: #666666">0</span>, AttributeType.FLOAT2, <span style="color: #666666">0</span>, <span style="color: #666666">8</span>)
.attribute(VertexAttribute.COLOR, <span style="color: #666666">1</span>, AttributeType.UBYTE4, <span style="color: #666666">0</span>, <span style="color: #666666">4</span>)
.normalized(VertexAttribute.COLOR)
.build(engine);
<p>Next we&#x27;ll use the positions and colors buffers to create a single <code>VertexBuffer</code> object.</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>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; font-weight: bold">const</span><span style="color: #bbbbbb"> </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; font-weight: bold">this</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(<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.FLOAT2,<span style="color: #bbbbbb"> </span><span style="color: #666666">0</span>,<span style="color: #bbbbbb"> </span><span style="color: #666666">8</span>)<span style="color: #bbbbbb"></span>
<span style="color: #bbbbbb"> </span>.attribute(VertexAttribute.COLOR,<span style="color: #bbbbbb"> </span><span style="color: #666666">1</span>,<span style="color: #bbbbbb"> </span>AttributeType.UBYTE4,<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>
<span style="color: #bbbbbb"> </span>.normalized(VertexAttribute.COLOR)<span style="color: #bbbbbb"></span>
<span style="color: #bbbbbb"> </span>.build(engine);<span style="color: #bbbbbb"></span>
<span style="color: #008000; font-weight: bold">this</span>.vb.setBufferAt(engine, <span style="color: #666666">0</span>, TRIANGLE_POSITIONS);
<span style="color: #008000; font-weight: bold">this</span>.vb.setBufferAt(engine, <span style="color: #666666">1</span>, TRIANGLE_COLORS);
<span style="color: #008000; font-weight: bold">this</span>.vb.setBufferAt(engine,<span style="color: #bbbbbb"> </span><span style="color: #666666">0</span>,<span style="color: #bbbbbb"> </span>TRIANGLE_POSITIONS);<span style="color: #bbbbbb"></span>
<span style="color: #008000; font-weight: bold">this</span>.vb.setBufferAt(engine,<span style="color: #bbbbbb"> </span><span style="color: #666666">1</span>,<span style="color: #bbbbbb"> </span>TRIANGLE_COLORS);<span style="color: #bbbbbb"></span>
</pre></div>
<p>The above snippet first creates aliases for two enum types, then constructs the vertex buffer using
@@ -147,74 +147,74 @@ self-documenting.</p>
<p>Our app sets up two buffer slots in the vertex buffer, and each slot is associated with a single
attribute. Alternatively, we could have interleaved or concatenated these attributes into a single
buffer slot.</p>
<p>Next we'll construct an index buffer. The index buffer for our triangle is trivial: it simply holds
<p>Next we&#x27;ll construct an index buffer. The index buffer for our triangle is trivial: it simply holds
the integers 0,1,2.</p>
<div class="highlight" style="background: #f8f8f8"><pre style="line-height: 125%;"><span></span><span style="color: #008000; font-weight: bold">this</span>.ib <span style="color: #666666">=</span> Filament.IndexBuffer.Builder()
.indexCount(<span style="color: #666666">3</span>)
.bufferType(Filament.IndexBuffer$IndexType.USHORT)
.build(engine);
<div class="highlight" style="background: #f8f8f8"><pre style="line-height: 125%;"><span></span><span style="color: #008000; font-weight: bold">this</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(<span style="color: #666666">3</span>)<span style="color: #bbbbbb"></span>
<span style="color: #bbbbbb"> </span>.bufferType(Filament.IndexBuffer$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">this</span>.ib.setBuffer(engine, <span style="color: #AA22FF; font-weight: bold">new</span> <span style="color: #008000">Uint16Array</span>([<span style="color: #666666">0</span>, <span style="color: #666666">1</span>, <span style="color: #666666">2</span>]));
<span style="color: #008000; font-weight: bold">this</span>.ib.setBuffer(engine,<span style="color: #bbbbbb"> </span><span style="color: #AA22FF; font-weight: bold">new</span><span style="color: #bbbbbb"> </span><span style="color: #008000">Uint16Array</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">2</span>]));<span style="color: #bbbbbb"></span>
</pre></div>
<p>Note that constructing an index buffer is similar to constructing a vertex buffer, but it only has
one buffer slot, and it can only contain two types of data (USHORT or UINT).</p>
<h2>Finish up initialization</h2>
<p>Next let's construct an actual <code>Material</code> from the material package that was downloaded (the
<p>Next let&#x27;s construct an actual <code>Material</code> from the material package that was downloaded (the
material is an object; the package is just a binary blob), then extract the default
<code>MaterialInstance</code> from the material object. Material instances have concrete values for their
parameters, and they can be bound to renderables. We'll learn more about material instances in the
parameters, and they can be bound to renderables. We&#x27;ll learn more about material instances in the
next tutorial.</p>
<p>After extracting the material instance, we can finally create a renderable component for the
triangle by setting up a bounding box and passing in the vertex and index buffers.</p>
<div class="highlight" style="background: #f8f8f8"><pre style="line-height: 125%;"><span></span><span style="color: #008000; font-weight: bold">const</span> mat <span style="color: #666666">=</span> engine.createMaterial(<span style="color: #BA2121">&#39;triangle.filamat&#39;</span>);
<span style="color: #008000; font-weight: bold">const</span> matinst <span style="color: #666666">=</span> mat.getDefaultInstance();
Filament.RenderableManager.Builder(<span style="color: #666666">1</span>)
.boundingBox({ center<span style="color: #666666">:</span> [<span style="color: #666666">-1</span>, <span style="color: #666666">-1</span>, <span style="color: #666666">-1</span>], halfExtent<span style="color: #666666">:</span> [<span style="color: #666666">1</span>, <span style="color: #666666">1</span>, <span style="color: #666666">1</span>] })
.material(<span style="color: #666666">0</span>, matinst)
.geometry(<span style="color: #666666">0</span>, Filament.RenderableManager$PrimitiveType.TRIANGLES, <span style="color: #008000; font-weight: bold">this</span>.vb, <span style="color: #008000; font-weight: bold">this</span>.ib)
.build(engine, <span style="color: #008000; font-weight: bold">this</span>.triangle);
<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>mat<span style="color: #bbbbbb"> </span><span style="color: #666666">=</span><span style="color: #bbbbbb"> </span>engine.createMaterial(<span style="color: #BA2121">&#39;triangle.filamat&#39;</span>);<span style="color: #bbbbbb"></span>
<span style="color: #008000; font-weight: bold">const</span><span style="color: #bbbbbb"> </span>matinst<span style="color: #bbbbbb"> </span><span style="color: #666666">=</span><span style="color: #bbbbbb"> </span>mat.getDefaultInstance();<span style="color: #bbbbbb"></span>
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>matinst)<span style="color: #bbbbbb"></span>
<span style="color: #bbbbbb"> </span>.geometry(<span style="color: #666666">0</span>,<span style="color: #bbbbbb"> </span>Filament.RenderableManager$PrimitiveType.TRIANGLES,<span style="color: #bbbbbb"> </span><span style="color: #008000; font-weight: bold">this</span>.vb,<span style="color: #bbbbbb"> </span><span style="color: #008000; font-weight: bold">this</span>.ib)<span style="color: #bbbbbb"></span>
<span style="color: #bbbbbb"> </span>.build(engine,<span style="color: #bbbbbb"> </span><span style="color: #008000; font-weight: bold">this</span>.triangle);<span style="color: #bbbbbb"></span>
</pre></div>
<p>Next let's wrap up the initialization routine by creating the swap chain, renderer, camera, and
<p>Next let&#x27;s wrap up the initialization routine by creating the swap chain, renderer, camera, and
view.</p>
<div class="highlight" style="background: #f8f8f8"><pre style="line-height: 125%;"><span></span><span style="color: #008000; font-weight: bold">this</span>.swapChain <span style="color: #666666">=</span> engine.createSwapChain();
<span style="color: #008000; font-weight: bold">this</span>.renderer <span style="color: #666666">=</span> engine.createRenderer();
<span style="color: #008000; font-weight: bold">this</span>.camera <span style="color: #666666">=</span> engine.createCamera(Filament.EntityManager.get().create());
<span style="color: #008000; font-weight: bold">this</span>.view <span style="color: #666666">=</span> engine.createView();
<span style="color: #008000; font-weight: bold">this</span>.view.setCamera(<span style="color: #008000; font-weight: bold">this</span>.camera);
<span style="color: #008000; font-weight: bold">this</span>.view.setScene(<span style="color: #008000; font-weight: bold">this</span>.scene);
<div class="highlight" style="background: #f8f8f8"><pre style="line-height: 125%;"><span></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(<span style="color: #008000; font-weight: bold">this</span>.scene);<span style="color: #bbbbbb"></span>
<span style="color: #3D7B7B; font-style: italic">// Set up a blue-green background:</span>
<span style="color: #008000; font-weight: bold">this</span>.renderer.setClearOptions({clearColor<span style="color: #666666">:</span> [<span style="color: #666666">0.0</span>, <span style="color: #666666">0.1</span>, <span style="color: #666666">0.2</span>, <span style="color: #666666">1.0</span>], clear<span style="color: #666666">:</span> <span style="color: #008000; font-weight: bold">true</span>});
<span style="color: #3D7B7B; font-style: italic">// Set up a blue-green background:</span><span style="color: #bbbbbb"></span>
<span style="color: #008000; font-weight: bold">this</span>.renderer.setClearOptions({clearColor<span style="color: #666666">:</span><span style="color: #bbbbbb"> </span>[<span style="color: #666666">0.0</span>,<span style="color: #bbbbbb"> </span><span style="color: #666666">0.1</span>,<span style="color: #bbbbbb"> </span><span style="color: #666666">0.2</span>,<span style="color: #bbbbbb"> </span><span style="color: #666666">1.0</span>],<span style="color: #bbbbbb"> </span>clear<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: #3D7B7B; font-style: italic">// Adjust the initial viewport:</span>
<span style="color: #008000; font-weight: bold">this</span>.resize();
<span style="color: #3D7B7B; font-style: italic">// Adjust the initial viewport:</span><span style="color: #bbbbbb"></span>
<span style="color: #008000; font-weight: bold">this</span>.resize();<span style="color: #bbbbbb"></span>
</pre></div>
<p>At this point, we're done creating all Filament entities, and the code should run without errors.
<p>At this point, we&#x27;re done creating all Filament entities, and the code should run without errors.
However the canvas is still blank!</p>
<h2>Render and resize handlers</h2>
<p>Recall that our App class has a skeletal render method, which the browser calls every time it needs
to repaint. Often this is 60 times a second.</p>
<div class="highlight" style="background: #f8f8f8"><pre style="line-height: 125%;"><span></span>render() {
<span style="color: #3D7B7B; font-style: italic">// TODO: render scene</span>
<span style="color: #008000">window</span>.requestAnimationFrame(<span style="color: #008000; font-weight: bold">this</span>.render);
}
<div class="highlight" style="background: #f8f8f8"><pre style="line-height: 125%;"><span></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: render scene</span><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>
</pre></div>
<p>Let's flesh this out by rotating the triangle and invoking the Filament renderer. Add the following
<p>Let&#x27;s flesh this out by rotating the triangle and invoking the Filament renderer. Add the following
code to the top of the render method.</p>
<div class="highlight" style="background: #f8f8f8"><pre style="line-height: 125%;"><span></span><span style="color: #3D7B7B; font-style: italic">// Rotate the triangle.</span>
<span style="color: #008000; font-weight: bold">const</span> radians <span style="color: #666666">=</span> <span style="color: #008000">Date</span>.now() <span style="color: #666666">/</span> <span style="color: #666666">1000</span>;
<span style="color: #008000; font-weight: bold">const</span> transform <span style="color: #666666">=</span> mat4.fromRotation(mat4.create(), radians, [<span style="color: #666666">0</span>, <span style="color: #666666">0</span>, <span style="color: #666666">1</span>]);
<span style="color: #008000; font-weight: bold">const</span> tcm <span style="color: #666666">=</span> <span style="color: #008000; font-weight: bold">this</span>.engine.getTransformManager();
<span style="color: #008000; font-weight: bold">const</span> inst <span style="color: #666666">=</span> tcm.getInstance(<span style="color: #008000; font-weight: bold">this</span>.triangle);
tcm.setTransform(inst, transform);
inst.<span style="color: #AA22FF; font-weight: bold">delete</span>();
<div class="highlight" style="background: #f8f8f8"><pre style="line-height: 125%;"><span></span><span style="color: #3D7B7B; font-style: italic">// Rotate the triangle.</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">1000</span>;<span style="color: #bbbbbb"></span>
<span style="color: #008000; font-weight: bold">const</span><span style="color: #bbbbbb"> </span>transform<span style="color: #bbbbbb"> </span><span style="color: #666666">=</span><span style="color: #bbbbbb"> </span>mat4.fromRotation(mat4.create(),<span style="color: #bbbbbb"> </span>radians,<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">1</span>]);<span style="color: #bbbbbb"></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>.triangle);<span style="color: #bbbbbb"></span>
tcm.setTransform(inst,<span style="color: #bbbbbb"> </span>transform);<span style="color: #bbbbbb"></span>
inst.<span style="color: #AA22FF; font-weight: bold">delete</span>();<span style="color: #bbbbbb"></span>
<span style="color: #3D7B7B; font-style: italic">// Render the frame.</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: #008000; font-weight: bold">this</span>.view);
<span style="color: #3D7B7B; font-style: italic">// Render the frame.</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>
</pre></div>
<p>The first half of our render method obtains the transform component of the triangle entity and uses
@@ -225,19 +225,19 @@ that it wants to skip a frame, hence the <code>if</code> statement.</p>
<p>One last step. Add the following code to the resize method. This adjusts the resolution of the
rendering surface when the window size changes, taking <code>devicePixelRatio</code> into account for high-DPI
displays. It also adjusts the camera frustum accordingly.</p>
<div class="highlight" style="background: #f8f8f8"><pre style="line-height: 125%;"><span></span><span style="color: #008000; font-weight: bold">const</span> dpr <span style="color: #666666">=</span> <span style="color: #008000">window</span>.devicePixelRatio;
<span style="color: #008000; font-weight: bold">const</span> width <span style="color: #666666">=</span> <span style="color: #008000; font-weight: bold">this</span>.canvas.width <span style="color: #666666">=</span> <span style="color: #008000">window</span>.innerWidth <span style="color: #666666">*</span> dpr;
<span style="color: #008000; font-weight: bold">const</span> height <span style="color: #666666">=</span> <span style="color: #008000; font-weight: bold">this</span>.canvas.height <span style="color: #666666">=</span> <span style="color: #008000">window</span>.innerHeight <span style="color: #666666">*</span> dpr;
<span style="color: #008000; font-weight: bold">this</span>.view.setViewport([<span style="color: #666666">0</span>, <span style="color: #666666">0</span>, width, height]);
<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>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> aspect <span style="color: #666666">=</span> width <span style="color: #666666">/</span> height;
<span style="color: #008000; font-weight: bold">const</span> Projection <span style="color: #666666">=</span> Filament.Camera$Projection;
<span style="color: #008000; font-weight: bold">this</span>.camera.setProjection(Projection.ORTHO, <span style="color: #666666">-</span>aspect, aspect, <span style="color: #666666">-1</span>, <span style="color: #666666">1</span>, <span style="color: #666666">0</span>, <span style="color: #666666">1</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>Projection<span style="color: #bbbbbb"> </span><span style="color: #666666">=</span><span style="color: #bbbbbb"> </span>Filament.Camera$Projection;<span style="color: #bbbbbb"></span>
<span style="color: #008000; font-weight: bold">this</span>.camera.setProjection(Projection.ORTHO,<span style="color: #bbbbbb"> </span><span style="color: #666666">-</span>aspect,<span style="color: #bbbbbb"> </span>aspect,<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">0</span>,<span style="color: #bbbbbb"> </span><span style="color: #666666">1</span>);<span style="color: #bbbbbb"></span>
</pre></div>
<p>You should now have a spinning triangle! The completed JavaScript is available
<a href="tutorial_triangle.js">here</a>.</p>
<p>In the <a href="tutorial_redball.html">next tutorial</a>, we'll take a closer look at Filament materials and 3D rendering.</p>
<p>In the <a href="tutorial_redball.html">next tutorial</a>, we&#x27;ll take a closer look at Filament materials and 3D rendering.</p>
</body>
</html>

View File

@@ -17,6 +17,7 @@ set(PUBLIC_HDRS
include/filament/Camera.h
include/filament/Color.h
include/filament/ColorGrading.h
include/filament/ColorSpace.h
include/filament/DebugRegistry.h
include/filament/Engine.h
include/filament/Exposure.h
@@ -53,7 +54,7 @@ set(SRCS
src/BufferObject.cpp
src/Camera.cpp
src/Color.cpp
src/ColorSpace.cpp
src/ColorSpaceUtils.cpp
src/Culler.cpp
src/DFG.cpp
src/DebugRegistry.cpp
@@ -135,7 +136,7 @@ set(SRCS
set(PRIVATE_HDRS
src/Allocators.h
src/BufferPoolAllocator.h
src/ColorSpace.h
src/ColorSpaceUtils.h
src/Culler.h
src/DFG.h
src/FilamentAPI-impl.h
@@ -588,6 +589,7 @@ else()
-Wgnu-conditional-omitted-operand
-Wweak-vtables -Wnon-virtual-dtor -Wclass-varargs -Wimplicit-fallthrough
-Wover-aligned
-Werror
)
endif()

View File

@@ -9,6 +9,7 @@ set(GENERATION_ROOT ${CMAKE_CURRENT_BINARY_DIR})
# Sources and headers
# ==================================================================================================
set(PUBLIC_HDRS
include/backend/AcquiredImage.h
include/backend/BufferDescriptor.h
include/backend/CallbackHandler.h
include/backend/DriverApiForward.h
@@ -36,12 +37,12 @@ set(SRCS
src/noop/NoopDriver.cpp
src/noop/PlatformNoop.cpp
src/Platform.cpp
src/PlatformFactory.cpp
src/Program.cpp
src/SamplerGroup.cpp
)
set(PRIVATE_HDRS
include/private/backend/AcquiredImage.h
include/private/backend/CircularBuffer.h
include/private/backend/CommandBufferQueue.h
include/private/backend/CommandStream.h
@@ -50,6 +51,7 @@ set(PRIVATE_HDRS
include/private/backend/DriverApi.h
include/private/backend/DriverAPI.inc
include/private/backend/HandleAllocator.h
include/private/backend/PlatformFactory.h
include/private/backend/SamplerGroup.h
src/CommandStreamDispatcher.h
src/DataReshaper.h
@@ -62,6 +64,7 @@ set(PRIVATE_HDRS
if (FILAMENT_SUPPORTS_OPENGL AND NOT FILAMENT_USE_EXTERNAL_GLES3 AND NOT FILAMENT_USE_SWIFTSHADER)
list(APPEND SRCS
include/backend/platforms/OpenGLPlatform.h
src/opengl/gl_headers.cpp
src/opengl/gl_headers.h
src/opengl/GLUtils.cpp
@@ -76,7 +79,6 @@ if (FILAMENT_SUPPORTS_OPENGL AND NOT FILAMENT_USE_EXTERNAL_GLES3 AND NOT FILAMEN
src/opengl/OpenGLPlatform.cpp
src/opengl/OpenGLTimerQuery.cpp
src/opengl/OpenGLTimerQuery.h
include/private/backend/OpenGLPlatform.h
)
if (EGL)
list(APPEND SRCS src/opengl/platforms/PlatformEGL.cpp)
@@ -112,7 +114,7 @@ endif()
# ==================================================================================================
if (FILAMENT_SUPPORTS_METAL)
set(METAL_SRCS
set(METAL_OBJC_SRCS
src/metal/MetalBlitter.mm
src/metal/MetalBuffer.mm
src/metal/MetalBufferPool.mm
@@ -122,18 +124,21 @@ if (FILAMENT_SUPPORTS_METAL)
src/metal/MetalExternalImage.mm
src/metal/MetalHandles.mm
src/metal/MetalPlatform.mm
src/metal/MetalResourceTracker.cpp
src/metal/MetalState.mm
src/metal/MetalTimerQuery.mm
src/metal/MetalUtils.mm
)
list(APPEND SRCS ${METAL_SRCS})
set(METAL_CPP_SRCS
src/metal/MetalResourceTracker.cpp
)
list(APPEND SRCS ${METAL_OBJC_SRCS} ${METAL_CPP_SRCS})
if (IOS)
# Objective-C++ sources need an additional compiler flag on iOS to disable exceptions.
set_property(SOURCE
${METAL_SRCS}
${METAL_OBJC_SRCS}
src/opengl/platforms/PlatformCocoaTouchGL.mm
src/opengl/platforms/CocoaTouchExternalImage.mm
src/opengl/platforms/PlatformCocoaGL.mm
@@ -150,6 +155,7 @@ endif()
# See root CMakeLists.txt for platforms that support Vulkan
if (FILAMENT_SUPPORTS_VULKAN)
list(APPEND SRCS
include/backend/platforms/VulkanPlatform.h
src/vulkan/VulkanBlitter.cpp
src/vulkan/VulkanBlitter.h
src/vulkan/VulkanBuffer.cpp
@@ -173,7 +179,6 @@ if (FILAMENT_SUPPORTS_VULKAN)
src/vulkan/VulkanPipelineCache.cpp
src/vulkan/VulkanPipelineCache.h
src/vulkan/VulkanPlatform.cpp
src/vulkan/VulkanPlatform.h
src/vulkan/VulkanSamplerCache.cpp
src/vulkan/VulkanSamplerCache.h
src/vulkan/VulkanStagePool.cpp
@@ -348,6 +353,7 @@ else()
-Wgnu-conditional-omitted-operand
-Wweak-vtables -Wnon-virtual-dtor -Wclass-varargs -Wimplicit-fallthrough
-Wover-aligned
-Werror
)
endif()

View File

@@ -42,11 +42,42 @@
*/
namespace filament::backend {
/**
* Requests a SwapChain with an alpha channel.
*/
static constexpr uint64_t SWAP_CHAIN_CONFIG_TRANSPARENT = 0x1;
/**
* This flag indicates that the swap chain may be used as a source surface
* for reading back render results. This config flag must be set when creating
* any SwapChain that will be used as the source for a blit operation.
*/
static constexpr uint64_t SWAP_CHAIN_CONFIG_READABLE = 0x2;
/**
* Indicates that the native X11 window is an XCB window rather than an XLIB window.
* This is ignored on non-Linux platforms and in builds that support only one X11 API.
*/
static constexpr uint64_t SWAP_CHAIN_CONFIG_ENABLE_XCB = 0x4;
/**
* Indicates that the native window is a CVPixelBufferRef.
*
* This is only supported by the Metal backend. The CVPixelBuffer must be in the
* kCVPixelFormatType_32BGRA format.
*
* It is not necessary to add an additional retain call before passing the pixel buffer to
* Filament. Filament will call CVPixelBufferRetain during Engine::createSwapChain, and
* CVPixelBufferRelease when the swap chain is destroyed.
*/
static constexpr uint64_t SWAP_CHAIN_CONFIG_APPLE_CVPIXELBUFFER = 0x8;
/**
* Indicates that the SwapChain must automatically perform linear to srgb encoding.
*/
static constexpr uint64_t SWAP_CHAIN_CONFIG_SRGB_COLORSPACE = 0x10;
static constexpr size_t MAX_VERTEX_ATTRIBUTE_COUNT = 16; // This is guaranteed by OpenGL ES.
static constexpr size_t MAX_SAMPLER_COUNT = 62; // Maximum needed at feature level 3.
static constexpr size_t MAX_VERTEX_BUFFER_COUNT = 16; // Max number of bound buffer objects.
@@ -398,6 +429,18 @@ enum class CompressedPixelDataType : uint16_t {
SRGB8_ALPHA8_ASTC_10x10,
SRGB8_ALPHA8_ASTC_12x10,
SRGB8_ALPHA8_ASTC_12x12,
// RGTC formats available with a GLES extension
RED_RGTC1, // BC4 unsigned
SIGNED_RED_RGTC1, // BC4 signed
RED_GREEN_RGTC2, // BC5 unsigned
SIGNED_RED_GREEN_RGTC2, // BC5 signed
// BPTC formats available with a GLES extension
RGB_BPTC_SIGNED_FLOAT, // BC6H signed
RGB_BPTC_UNSIGNED_FLOAT,// BC6H unsigned
RGBA_BPTC_UNORM, // BC7
SRGB_ALPHA_BPTC_UNORM, // BC7 sRGB
};
/** Supported texel formats
@@ -552,6 +595,18 @@ enum class TextureFormat : uint16_t {
SRGB8_ALPHA8_ASTC_10x10,
SRGB8_ALPHA8_ASTC_12x10,
SRGB8_ALPHA8_ASTC_12x12,
// RGTC formats available with a GLES extension
RED_RGTC1, // BC4 unsigned
SIGNED_RED_RGTC1, // BC4 signed
RED_GREEN_RGTC2, // BC5 unsigned
SIGNED_RED_GREEN_RGTC2, // BC5 signed
// BPTC formats available with a GLES extension
RGB_BPTC_SIGNED_FLOAT, // BC6H signed
RGB_BPTC_UNSIGNED_FLOAT,// BC6H unsigned
RGBA_BPTC_UNORM, // BC7
SRGB_ALPHA_BPTC_UNORM, // BC7 sRGB
};
//! Bitmask describing the intended Texture Usage
@@ -632,7 +687,7 @@ static constexpr bool isSignedIntFormat(TextureFormat format) {
}
}
//! returns whether this format a compressed format
//! returns whether this format is a compressed format
static constexpr bool isCompressedFormat(TextureFormat format) noexcept {
return format >= TextureFormat::EAC_R11;
}
@@ -642,7 +697,7 @@ static constexpr bool isETC2Compression(TextureFormat format) noexcept {
return format >= TextureFormat::EAC_R11 && format <= TextureFormat::ETC2_EAC_SRGBA8;
}
//! returns whether this format is an ETC3 compressed format
//! returns whether this format is an S3TC compressed format
static constexpr bool isS3TCCompression(TextureFormat format) noexcept {
return format >= TextureFormat::DXT1_RGB && format <= TextureFormat::DXT5_SRGBA;
}
@@ -651,6 +706,16 @@ static constexpr bool isS3TCSRGBCompression(TextureFormat format) noexcept {
return format >= TextureFormat::DXT1_SRGB && format <= TextureFormat::DXT5_SRGBA;
}
//! returns whether this format is an RGTC compressed format
static constexpr bool isRGTCCompression(TextureFormat format) noexcept {
return format >= TextureFormat::RED_RGTC1 && format <= TextureFormat::SIGNED_RED_GREEN_RGTC2;
}
//! returns whether this format is an BPTC compressed format
static constexpr bool isBPTCCompression(TextureFormat format) noexcept {
return format >= TextureFormat::RGB_BPTC_SIGNED_FLOAT && format <= TextureFormat::SRGB_ALPHA_BPTC_UNORM;
}
static constexpr bool isASTCCompression(TextureFormat format) noexcept {
return format >= TextureFormat::RGBA_ASTC_4x4 && format <= TextureFormat::SRGB8_ALPHA8_ASTC_12x12;
}

View File

@@ -23,22 +23,28 @@
#include <utils/compiler.h>
namespace filament {
namespace backend {
namespace filament::backend {
class Driver;
/**
* Platform is an interface that abstracts how the backend (also referred to as Driver) is
* created. The backend provides several common Platform concrete implementations, which are
* selected automatically. It is possible however to provide a custom Platform when creating
* the filament Engine.
*/
class UTILS_PUBLIC Platform {
public:
struct SwapChain {};
struct Fence {};
struct Stream {};
struct ExternalTexture {
uintptr_t image = 0;
};
struct DriverConfig {
size_t handleArenaSize = 0; // size of handle arena in bytes. Setting to 0 indicates default value is to be used. Driver clamps to valid values.
/*
* size of handle arena in bytes. Setting to 0 indicates default value is to be used.
* Driver clamps to valid values.
*/
size_t handleArenaSize = 0;
};
virtual ~Platform() noexcept;
@@ -62,7 +68,8 @@ public:
*
* @return nullptr on failure, or a pointer to the newly created driver.
*/
virtual backend::Driver* createDriver(void* sharedContext, const DriverConfig& driverConfig) noexcept = 0;
virtual backend::Driver* createDriver(void* sharedContext,
const DriverConfig& driverConfig) noexcept = 0;
/**
* Processes the platform's event queue when called from its primary event-handling thread.
@@ -71,39 +78,9 @@ public:
* on platforms that need it, such as macOS + OpenGL. Returns false if this is not the main
* thread, or if the platform does not need to perform any special processing.
*/
virtual bool pumpEvents() noexcept { return false; }
virtual bool pumpEvents() noexcept;
};
class UTILS_PUBLIC DefaultPlatform : public Platform {
public:
~DefaultPlatform() noexcept override;
/**
* Creates a Platform configured for the requested backend if available
*
* @param backendHint Preferred backend, if not available the backend most suitable for the
* underlying platform is returned and \p backendHint is updated
* accordingly. Can't be nullptr.
*
* @return A pointer to the Platform object.
*
* @see destroy
*/
static DefaultPlatform* create(backend::Backend* backendHint) noexcept;
/**
* Destroys a Platform object returned by create()
*
* @param platform a reference (as a pointer) to the DefaultPlatform pointer to destroy.
* \p platform is cleared upon return.
*
* @see create
*/
static void destroy(DefaultPlatform** platform) noexcept;
};
} // namespace backend
} // namespace filament
#endif // TNT_FILAMENT_BACKEND_PLATFORM_H

View File

@@ -0,0 +1,4 @@
# include/backend Headers
Headers in `include/backend/` are fully public, in particular they can be included in filament's
public headers.

View File

@@ -0,0 +1,261 @@
/*
* Copyright (C) 2015 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.
*/
#ifndef TNT_FILAMENT_BACKEND_PRIVATE_OPENGLPLATFORM_H
#define TNT_FILAMENT_BACKEND_PRIVATE_OPENGLPLATFORM_H
#include <backend/AcquiredImage.h>
#include <backend/Platform.h>
namespace filament::backend {
class Driver;
/**
* A Platform interface that creates an OpenGL backend.
*
* WARNING: None of the methods below are allowed to change the GL state and must restore it
* upon return.
*
*/
class OpenGLPlatform : public Platform {
protected:
/*
* Derived classes can use this to instantiate the default OpenGLDriver backend.
* This is typically called from your implementation of createDriver()
*/
static Driver* createDefaultDriver(OpenGLPlatform* platform,
void* sharedContext, const DriverConfig& driverConfig);
~OpenGLPlatform() noexcept override;
public:
struct ExternalTexture {
unsigned int target; // GLenum target
unsigned int id; // GLuint id
};
/**
* Called by the driver to destroy the OpenGL context. This should clean up any windows
* or buffers from initialization. This is for instance where `eglDestroyContext` would be
* called.
*/
virtual void terminate() noexcept = 0;
/**
* Called by the driver to create a SwapChain for this driver.
*
* @param nativeWindow a token representing the native window. See concrete implementation
* for details.
* @param flags extra flags used by the implementation, see filament::SwapChain
* @return The driver's SwapChain object.
*
*/
virtual SwapChain* createSwapChain(void* nativeWindow, uint64_t flags) noexcept = 0;
/**
* Return whether createSwapChain supports the SWAP_CHAIN_CONFIG_SRGB_COLORSPACE flag.
* The default implementation returns false.
*
* @return true if SWAP_CHAIN_CONFIG_SRGB_COLORSPACE is supported, false otherwise.
*/
virtual bool isSRGBSwapChainSupported() const noexcept;
/**
* Called by the driver create a headless SwapChain.
*
* @param width width of the buffer
* @param height height of the buffer
* @param flags extra flags used by the implementation, see filament::SwapChain
* @return The driver's SwapChain object.
*
* TODO: we need a more generic way of passing construction parameters
* A void* might be enough.
*/
virtual SwapChain* createSwapChain(uint32_t width, uint32_t height, uint64_t flags) noexcept = 0;
/**
* Called by the driver to destroys the SwapChain
* @param swapChain SwapChain to be destroyed.
*/
virtual void destroySwapChain(SwapChain* swapChain) noexcept = 0;
/**
* Called by the driver to establish the default FBO. The default implementation returns 0.
* @return a GLuint casted to a uint32_t that is an OpenGL framebuffer object.
*/
virtual uint32_t createDefaultRenderTarget() noexcept;
/**
* Called by the driver to make the OpenGL context active on the calling thread and bind
* the drawSwapChain to the default render target (FBO) created with createDefaultRenderTarget.
* @param drawSwapChain SwapChain to draw to. It must be bound to the default FBO.
* @param readSwapChain SwapChain to read from (for operation like `glBlitFramebuffer`)
*/
virtual void makeCurrent(SwapChain* drawSwapChain, SwapChain* readSwapChain) noexcept = 0;
/**
* Called by the driver once the current frame finishes drawing. Typically, this should present
* the drawSwapChain. This is for example where `eglMakeCurrent()` would be called.
* @param swapChain the SwapChain to present.
*/
virtual void commit(SwapChain* swapChain) noexcept = 0;
/**
* Set the time the next committed buffer should be presented to the user at.
*
* @param presentationTimeInNanosecond time in the future in nanosecond. The clock used depends
* on the concrete platform implementation.
*/
virtual void setPresentationTime(int64_t presentationTimeInNanosecond) noexcept;
// --------------------------------------------------------------------------------------------
// Fence support
/**
* Can this implementation create a Fence.
* @return true if supported, false otherwise. The default implementation returns false.
*/
virtual bool canCreateFence() noexcept;
/**
* Creates a Fence (e.g. eglCreateSyncKHR). This must be implemented if `canCreateFence`
* returns true. Fences are used for frame pacing.
*
* @return A Fence object. The default implementation returns nullptr.
*/
virtual Fence* createFence() noexcept;
/**
* Destroys a Fence object. The default implementation does nothing.
*
* @param fence Fence to destroy.
*/
virtual void destroyFence(Fence* fence) noexcept;
/**
* Waits on a Fence.
*
* @param fence Fence to wait on.
* @param timeout Timeout.
* @return Whether the fence signaled or timed out. See backend::FenceStatus.
* The default implementation always return backend::FenceStatus::ERROR.
*/
virtual backend::FenceStatus waitFence(Fence* fence, uint64_t timeout) noexcept;
// --------------------------------------------------------------------------------------------
// Streaming support
/**
* Creates a Stream from a native Stream.
*
* WARNING: This is called synchronously from the application thread (NOT the Driver thread)
*
* @param nativeStream The native stream, this parameter depends on the concrete implementation.
* @return A new Stream object.
*/
virtual Stream* createStream(void* nativeStream) noexcept;
/**
* Destroys a Stream.
* @param stream Stream to destroy.
*/
virtual void destroyStream(Stream* stream) noexcept;
/**
* The specified stream takes ownership of the texture (tname) object
* Once attached, the texture is automatically updated with the Stream's content, which
* could be a video stream for instance.
*
* @param stream Stream to take ownership of the texture
* @param tname GL texture id to "bind" to the Stream.
*/
virtual void attach(Stream* stream, intptr_t tname) noexcept;
/**
* Destroys the texture associated to the stream
* @param stream Stream to detach from its texture
*/
virtual void detach(Stream* stream) noexcept;
/**
* Updates the content of the texture attached to the stream.
* @param stream Stream to update
* @param timestamp Output parameter: Timestamp of the image bound to the texture.
*/
virtual void updateTexImage(Stream* stream, int64_t* timestamp) noexcept;
// --------------------------------------------------------------------------------------------
// External Image support
/**
* Creates an external texture handle. External textures don't have any parameters because
* these are undefined until setExternalImage() is called.
* @return a pointer to an ExternalTexture structure filled with valid token. However, the
* implementation could just return { 0, GL_TEXTURE_2D } at this point. The actual
* values can be delayed until setExternalImage.
*/
virtual ExternalTexture *createExternalImageTexture() noexcept;
/**
* Destroys an external texture handle and associated data.
* @param texture a pointer to the handle to destroy.
*/
virtual void destroyExternalImage(ExternalTexture* texture) noexcept;
// called on the application thread to allow Filament to take ownership of the image
/**
* Takes ownership of the externalImage. The externalImage parameter depends on the Platform's
* concrete implementation. Ownership is released when destroyExternalImage() is called.
*
* WARNING: This is called synchronously from the application thread (NOT the Driver thread)
*
* @param externalImage A token representing the platform's external image.
* @see destroyExternalImage
*/
virtual void retainExternalImage(void* externalImage) noexcept;
/**
* Called to bind the platform-specific externalImage to an ExternalTexture.
* ExternalTexture::id is guaranteed to be bound when this method is called and ExternalTexture
* is updated with new values for id/target if necessary.
*
* WARNING: this method is not allowed to change the bound texture, or must restore the previous
* binding upon return. This is to avoid problem with a backend doing state caching.
*
* @param externalImage The platform-specific external image.
* @param texture an in/out pointer to ExternalTexture, id and target can be updated if necessary.
* @return true on success, false on error.
*/
virtual bool setExternalImage(void* externalImage, ExternalTexture* texture) noexcept;
/**
* The method allows platforms to convert a user-supplied external image object into a new type
* (e.g. HardwareBuffer => EGLImage). The default implementation returns source.
* @param source Image to transform.
* @return Transformed image.
*/
virtual AcquiredImage transformAcquiredImage(AcquiredImage source) noexcept;
};
} // namespace filament
#endif // TNT_FILAMENT_BACKEND_PRIVATE_OPENGLPLATFORM_H

View File

@@ -0,0 +1,67 @@
/*
* Copyright (C) 2017 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.
*/
#ifndef TNT_FILAMENT_BACKEND_OPENGL_OPENGL_PLATFORM_COCOA_GL_H
#define TNT_FILAMENT_BACKEND_OPENGL_OPENGL_PLATFORM_COCOA_GL_H
#include <stdint.h>
#include <backend/platforms/OpenGLPlatform.h>
#include <backend/DriverEnums.h>
namespace filament::backend {
struct PlatformCocoaGLImpl;
/**
* A concrete implementation of OpenGLPlatform that supports macOS's Cocoa.
*/
class PlatformCocoaGL : public OpenGLPlatform {
public:
PlatformCocoaGL();
~PlatformCocoaGL() noexcept override;
protected:
// --------------------------------------------------------------------------------------------
// Platform Interface
Driver* createDriver(void* sharedContext,
const Platform::DriverConfig& driverConfig) noexcept override;
// Currently returns 0
int getOSVersion() const noexcept override;
bool pumpEvents() noexcept override;
// --------------------------------------------------------------------------------------------
// OpenGLPlatform Interface
void terminate() noexcept override;
SwapChain* createSwapChain(void* nativewindow, uint64_t flags) noexcept override;
SwapChain* createSwapChain(uint32_t width, uint32_t height, uint64_t flags) noexcept override;
void destroySwapChain(SwapChain* swapChain) noexcept override;
void makeCurrent(SwapChain* drawSwapChain, SwapChain* readSwapChain) noexcept override;
void commit(SwapChain* swapChain) noexcept override;
private:
PlatformCocoaGLImpl* pImpl = nullptr;
};
} // namespace filament::backend
#endif // TNT_FILAMENT_BACKEND_OPENGL_OPENGL_PLATFORM_COCOA_GL_H

View File

@@ -0,0 +1,69 @@
/*
* Copyright (C) 2017 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.
*/
#ifndef TNT_FILAMENT_BACKEND_OPENGL_OPENGL_PLATFORM_COCOA_TOUCH_GL_H
#define TNT_FILAMENT_BACKEND_OPENGL_OPENGL_PLATFORM_COCOA_TOUCH_GL_H
#include <stdint.h>
#include <backend/platforms/OpenGLPlatform.h>
#include <backend/DriverEnums.h>
namespace filament::backend {
struct PlatformCocoaTouchGLImpl;
class PlatformCocoaTouchGL : public OpenGLPlatform {
public:
PlatformCocoaTouchGL();
~PlatformCocoaTouchGL() noexcept;
// --------------------------------------------------------------------------------------------
// Platform Interface
Driver* createDriver(void* sharedGLContext,
const Platform::DriverConfig& driverConfig) noexcept override;
int getOSVersion() const noexcept final { return 0; }
// --------------------------------------------------------------------------------------------
// OpenGLPlatform Interface
void terminate() noexcept override;
uint32_t createDefaultRenderTarget() noexcept override;
SwapChain* createSwapChain(void* nativewindow, uint64_t flags) noexcept override;
SwapChain* createSwapChain(uint32_t width, uint32_t height, uint64_t flags) noexcept override;
void destroySwapChain(SwapChain* swapChain) noexcept override;
void makeCurrent(SwapChain* drawSwapChain, SwapChain* readSwapChain) noexcept override;
void commit(SwapChain* swapChain) noexcept override;
OpenGLPlatform::ExternalTexture* createExternalImageTexture() noexcept override;
void destroyExternalImage(ExternalTexture* texture) noexcept override;
void retainExternalImage(void* externalImage) noexcept override;
bool setExternalImage(void* externalImage, ExternalTexture* texture) noexcept override;
private:
PlatformCocoaTouchGLImpl* pImpl = nullptr;
};
using ContextManager = PlatformCocoaTouchGL;
} // namespace filament::backend
#endif // TNT_FILAMENT_BACKEND_OPENGL_OPENGL_PLATFORM_COCOA_TOUCH_GL_H

View File

@@ -22,65 +22,97 @@
#include <EGL/egl.h>
#include <EGL/eglext.h>
#include <backend/DriverEnums.h>
#include <backend/platforms/OpenGLPlatform.h>
#include "private/backend/OpenGLPlatform.h"
#include <backend/DriverEnums.h>
namespace filament::backend {
/**
* A concrete implementation of OpenGLPlatform that supports EGL.
*/
class PlatformEGL : public OpenGLPlatform {
public:
PlatformEGL() noexcept;
Driver* createDriver(void* sharedContext, const Platform::DriverConfig& driverConfig) noexcept override;
protected:
// --------------------------------------------------------------------------------------------
// Platform Interface
/**
* Initializes EGL, creates the OpenGL context and returns a concrete Driver implementation
* that supports OpenGL/OpenGL ES.
*/
Driver* createDriver(void* sharedContext,
const Platform::DriverConfig& driverConfig) noexcept override;
/**
* This returns zero. This method can be overridden to return something more useful.
* @return zero
*/
int getOSVersion() const noexcept override;
// --------------------------------------------------------------------------------------------
// OpenGLPlatform Interface
void terminate() noexcept override;
SwapChain* createSwapChain(void* nativewindow, uint64_t& flags) noexcept override;
SwapChain* createSwapChain(uint32_t width, uint32_t height, uint64_t& flags) noexcept override;
bool isSRGBSwapChainSupported() const noexcept override;
SwapChain* createSwapChain(void* nativewindow, uint64_t flags) noexcept override;
SwapChain* createSwapChain(uint32_t width, uint32_t height, uint64_t flags) noexcept override;
void destroySwapChain(SwapChain* swapChain) noexcept override;
void makeCurrent(SwapChain* drawSwapChain, SwapChain* readSwapChain) noexcept override;
void commit(SwapChain* swapChain) noexcept override;
bool canCreateFence() noexcept override { return true; }
bool canCreateFence() noexcept override;
Fence* createFence() noexcept override;
void destroyFence(Fence* fence) noexcept override;
FenceStatus waitFence(Fence* fence, uint64_t timeout) noexcept override;
void createExternalImageTexture(void* texture) noexcept override;
void destroyExternalImage(void* texture) noexcept override;
OpenGLPlatform::ExternalTexture* createExternalImageTexture() noexcept override;
void destroyExternalImage(ExternalTexture* texture) noexcept override;
bool setExternalImage(void* externalImage, ExternalTexture* texture) noexcept override;
/* default no-op implementations... */
int getOSVersion() const noexcept override { return 0; }
void setPresentationTime(int64_t presentationTimeInNanosecond) noexcept override {}
Stream* createStream(void* nativeStream) noexcept override { return nullptr; }
void destroyStream(Stream* stream) noexcept override {}
void attach(Stream* stream, intptr_t tname) noexcept override {}
void detach(Stream* stream) noexcept override {}
void updateTexImage(Stream* stream, int64_t* timestamp) noexcept override {}
protected:
/**
* Logs glGetError() to slog.e
* @param name a string giving some context on the error. Typically __func__.
*/
static void logEglError(const char* name) noexcept;
/**
* Calls glGetError() to clear the current error flags. logs a warning to log.w if
* an error was pending.
*/
static void clearGlError() noexcept;
/**
* Always use this instead of eglMakeCurrent().
*/
EGLBoolean makeCurrent(EGLSurface drawSurface, EGLSurface readSurface) noexcept;
void initializeGlExtensions() noexcept;
// TODO: this should probably use getters instead.
EGLDisplay mEGLDisplay = EGL_NO_DISPLAY;
EGLContext mEGLContext = EGL_NO_CONTEXT;
EGLSurface mCurrentDrawSurface = EGL_NO_SURFACE;
EGLSurface mCurrentReadSurface = EGL_NO_SURFACE;
EGLSurface mEGLDummySurface = EGL_NO_SURFACE;
EGLConfig mEGLConfig = EGL_NO_CONFIG_KHR;
EGLConfig mEGLTransparentConfig = EGL_NO_CONFIG_KHR;
// supported extensions detected at runtime
struct {
bool OES_EGL_image_external_essl3 = false;
struct {
bool OES_EGL_image_external_essl3 = false;
} gl;
struct {
bool KHR_no_config_context = false;
bool KHR_gl_colorspace = false;
} egl;
} ext;
private:
void initializeGlExtensions() noexcept;
EGLConfig findSwapChainConfig(uint64_t flags) const;
};
} // namespace filament::backend

View File

@@ -0,0 +1,82 @@
/*
* Copyright (C) 2017 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.
*/
#ifndef TNT_FILAMENT_BACKEND_OPENGL_OPENGL_PLATFORM_EGL_ANDROID_H
#define TNT_FILAMENT_BACKEND_OPENGL_OPENGL_PLATFORM_EGL_ANDROID_H
#include <backend/platforms/PlatformEGL.h>
namespace filament::backend {
class ExternalStreamManagerAndroid;
/**
* A concrete implementation of OpenGLPlatform and subclass of PlatformEGL that supports
* EGL on Android. It adds Android streaming functionality to PlatformEGL.
*/
class PlatformEGLAndroid : public PlatformEGL {
public:
PlatformEGLAndroid() noexcept;
~PlatformEGLAndroid() noexcept override;
protected:
// --------------------------------------------------------------------------------------------
// Platform Interface
/**
* Returns the Android SDK version.
* @return Android SDK version.
*/
int getOSVersion() const noexcept override;
Driver* createDriver(void* sharedContext,
const Platform::DriverConfig& driverConfig) noexcept override;
// --------------------------------------------------------------------------------------------
// OpenGLPlatform Interface
void terminate() noexcept override;
/**
* Set the presentation time using `eglPresentationTimeANDROID`
* @param presentationTimeInNanosecond
*/
void setPresentationTime(int64_t presentationTimeInNanosecond) noexcept override;
Stream* createStream(void* nativeStream) noexcept override;
void destroyStream(Stream* stream) noexcept override;
void attach(Stream* stream, intptr_t tname) noexcept override;
void detach(Stream* stream) noexcept override;
void updateTexImage(Stream* stream, int64_t* timestamp) noexcept override;
/**
* Converts a AHardwareBuffer to EGLImage
* @param source source.image is a AHardwareBuffer
* @return source.image contains an EGLImage
*/
AcquiredImage transformAcquiredImage(AcquiredImage source) noexcept override;
private:
int mOSVersion;
ExternalStreamManagerAndroid& mExternalStreamManager;
};
} // namespace filament::backend
#endif // TNT_FILAMENT_BACKEND_OPENGL_OPENGL_PLATFORM_EGL_ANDROID_H

View File

@@ -21,16 +21,15 @@
namespace filament::backend {
class PlatformEGLHeadless final : public PlatformEGL {
/**
* A concrete implementation of OpenGLPlatform that supports EGL with only headless swapchains.
*/
class PlatformEGLHeadless : public PlatformEGL {
public:
PlatformEGLHeadless() noexcept;
Driver* createDriver(void* sharedContext, const Platform::DriverConfig& driverConfig) noexcept final;
void createExternalImageTexture(void* texture) noexcept final {}
void destroyExternalImage(void* texture) noexcept final {}
Driver* createDriver(void* sharedContext,
const Platform::DriverConfig& driverConfig) noexcept override;
};
} // namespace filament

View File

@@ -19,44 +19,41 @@
#include <stdint.h>
#include <bluegl/BlueGL.h>
#include "bluegl/BlueGL.h"
#include <GL/glx.h>
#include <backend/DriverEnums.h>
#include <backend/platforms/OpenGLPlatform.h>
#include "private/backend/OpenGLPlatform.h"
#include <backend/DriverEnums.h>
#include <vector>
namespace filament::backend {
class PlatformGLX final : public OpenGLPlatform {
public:
/**
* A concrete implementation of OpenGLPlatform that supports GLX.
*/
class PlatformGLX : public OpenGLPlatform {
protected:
// --------------------------------------------------------------------------------------------
// Platform Interface
Driver* createDriver(void* const sharedGLContext, const DriverConfig& driverConfig) noexcept override;
Driver* createDriver(void* sharedGLContext,
const DriverConfig& driverConfig) noexcept override;
int getOSVersion() const noexcept final override { return 0; }
// --------------------------------------------------------------------------------------------
// OpenGLPlatform Interface
void terminate() noexcept override;
SwapChain* createSwapChain(void* nativewindow, uint64_t& flags) noexcept override;
SwapChain* createSwapChain(uint32_t width, uint32_t height, uint64_t& flags) noexcept override;
SwapChain* createSwapChain(void* nativewindow, uint64_t flags) noexcept override;
SwapChain* createSwapChain(uint32_t width, uint32_t height, uint64_t flags) noexcept override;
void destroySwapChain(SwapChain* swapChain) noexcept override;
void makeCurrent(SwapChain* drawSwapChain, SwapChain* readSwapChain) noexcept override;
void commit(SwapChain* swapChain) noexcept override;
Fence* createFence() noexcept override;
void destroyFence(Fence* fence) noexcept override;
FenceStatus waitFence(Fence* fence, uint64_t timeout) noexcept override;
void setPresentationTime(int64_t time) noexcept final override {}
Stream* createStream(void* nativeStream) noexcept final override { return nullptr; }
void destroyStream(Stream* stream) noexcept final override {}
void attach(Stream* stream, intptr_t tname) noexcept final override {}
void detach(Stream* stream) noexcept final override {}
void updateTexImage(Stream* stream, int64_t* timestamp) noexcept final override {}
int getOSVersion() const noexcept final override { return 0; }
private:
Display *mGLXDisplay;
GLXContext mGLXContext;

View File

@@ -20,40 +20,39 @@
#include <stdint.h>
#include <windows.h>
#include <utils/unwindows.h>
#include "utils/unwindows.h"
#include <backend/platforms/OpenGLPlatform.h>
#include <backend/DriverEnums.h>
#include "private/backend/OpenGLPlatform.h"
namespace filament::backend {
class PlatformWGL final : public OpenGLPlatform {
public:
Driver* createDriver(void* const sharedGLContext, const Platform::DriverConfig& driverConfig) noexcept override;
/**
* A concrete implementation of OpenGLPlatform that supports WGL.
*/
class PlatformWGL : public OpenGLPlatform {
protected:
// --------------------------------------------------------------------------------------------
// Platform Interface
Driver* createDriver(void* sharedGLContext,
const Platform::DriverConfig& driverConfig) noexcept override;
int getOSVersion() const noexcept final override { return 0; }
// --------------------------------------------------------------------------------------------
// OpenGLPlatform Interface
void terminate() noexcept override;
SwapChain* createSwapChain(void* nativewindow, uint64_t& flags) noexcept override;
SwapChain* createSwapChain(uint32_t width, uint32_t height, uint64_t& flags) noexcept override;
SwapChain* createSwapChain(void* nativewindow, uint64_t flags) noexcept override;
SwapChain* createSwapChain(uint32_t width, uint32_t height, uint64_t flags) noexcept override;
void destroySwapChain(SwapChain* swapChain) noexcept override;
void makeCurrent(SwapChain* drawSwapChain, SwapChain* readSwapChain) noexcept override;
void commit(SwapChain* swapChain) noexcept override;
Fence* createFence() noexcept override;
void destroyFence(Fence* fence) noexcept override;
FenceStatus waitFence(Fence* fence, uint64_t timeout) noexcept override;
void setPresentationTime(int64_t time) noexcept final override {}
Stream* createStream(void* nativeStream) noexcept final override { return nullptr; }
void destroyStream(Stream* stream) noexcept final override {}
void attach(Stream* stream, intptr_t tname) noexcept final override {}
void detach(Stream* stream) noexcept final override {}
void updateTexImage(Stream* stream, int64_t* timestamp) noexcept final override {}
int getOSVersion() const noexcept final override { return 0; }
private:
protected:
HGLRC mContext = NULL;
HWND mHWnd = NULL;
HDC mWhdc = NULL;

View File

@@ -0,0 +1,55 @@
/*
* Copyright (C) 2018 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.
*/
#ifndef TNT_FILAMENT_BACKEND_OPENGL_OPENGL_PLATFORM_WEBGL_H
#define TNT_FILAMENT_BACKEND_OPENGL_OPENGL_PLATFORM_WEBGL_H
#include <stdint.h>
#include <backend/platforms/OpenGLPlatform.h>
#include <backend/DriverEnums.h>
namespace filament::backend {
/**
* A concrete implementation of OpenGLPlatform that supports WebGL.
*/
class PlatformWebGL : public OpenGLPlatform {
protected:
// --------------------------------------------------------------------------------------------
// Platform Interface
Driver* createDriver(void* sharedGLContext,
const Platform::DriverConfig& driverConfig) noexcept override;
int getOSVersion() const noexcept override;
// --------------------------------------------------------------------------------------------
// OpenGLPlatform Interface
void terminate() noexcept override;
SwapChain* createSwapChain(void* nativewindow, uint64_t flags) noexcept override;
SwapChain* createSwapChain(uint32_t width, uint32_t height, uint64_t flags) noexcept override;
void destroySwapChain(SwapChain* swapChain) noexcept override;
void makeCurrent(SwapChain* drawSwapChain, SwapChain* readSwapChain) noexcept override;
void commit(SwapChain* swapChain) noexcept override;
};
} // namespace filament::backend
#endif // TNT_FILAMENT_BACKEND_OPENGL_OPENGL_PLATFORM_WEBGL_H

View File

@@ -14,21 +14,36 @@
* limitations under the License.
*/
#ifndef TNT_FILAMENT_BACKEND_VULKANPLATFORM_H
#define TNT_FILAMENT_BACKEND_VULKANPLATFORM_H
#ifndef TNT_FILAMENT_BACKEND_PLATFORMS_VULKANPLATFORM_H
#define TNT_FILAMENT_BACKEND_PLATFORMS_VULKANPLATFORM_H
#include <backend/Platform.h>
namespace filament::backend {
class VulkanPlatform : public DefaultPlatform {
/**
* A Platform interface that creates a Vulkan backend.
*/
class VulkanPlatform : public Platform {
public:
struct SurfaceBundle {
void* surface;
// On certain platforms, the extent of the surface cannot be queried from Vulkan. In those
// situations, we allow the frontend to pass in the extent to use in creating the swap
// chains. Platform implementation should set extent to 0 if they do not expect to set the
// swap chain extent.
uint32_t width;
uint32_t height;
};
// Given a Vulkan instance and native window handle, creates the platform-specific surface.
virtual void* createVkSurfaceKHR(void* nativeWindow, void* instance, uint64_t flags) noexcept = 0;
virtual SurfaceBundle createVkSurfaceKHR(void* nativeWindow, void* instance,
uint64_t flags) noexcept = 0;
~VulkanPlatform() override;
};
} // namespace filament::backend
#endif //TNT_FILAMENT_BACKEND_VULKANPLATFORM_H
#endif //TNT_FILAMENT_BACKEND_PLATFORMS_VULKANPLATFORM_H

View File

@@ -299,11 +299,11 @@ DECL_DRIVER_API_SYNCHRONOUS_0(bool, isFrameBufferFetchSupported)
DECL_DRIVER_API_SYNCHRONOUS_0(bool, isFrameBufferFetchMultiSampleSupported)
DECL_DRIVER_API_SYNCHRONOUS_0(bool, isFrameTimeSupported)
DECL_DRIVER_API_SYNCHRONOUS_0(bool, isAutoDepthResolveSupported)
DECL_DRIVER_API_SYNCHRONOUS_0(bool, isSRGBSwapChainSupported)
DECL_DRIVER_API_SYNCHRONOUS_0(uint8_t, getMaxDrawBuffers)
DECL_DRIVER_API_SYNCHRONOUS_0(math::float2, getClipSpaceParams)
DECL_DRIVER_API_SYNCHRONOUS_0(bool, canGenerateMipmaps)
DECL_DRIVER_API_SYNCHRONOUS_N(void, setupExternalImage, void*, image)
DECL_DRIVER_API_SYNCHRONOUS_N(void, cancelExternalImage, void*, image)
DECL_DRIVER_API_SYNCHRONOUS_N(bool, getTimerQueryValue, backend::TimerQueryHandle, query, uint64_t*, elapsedTime)
DECL_DRIVER_API_SYNCHRONOUS_N(backend::SyncStatus, getSyncStatus, backend::SyncHandle, sh)
DECL_DRIVER_API_SYNCHRONOUS_N(bool, isWorkaroundNeeded, backend::Workaround, workaround)

View File

@@ -1,111 +0,0 @@
/*
* Copyright (C) 2015 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.
*/
#ifndef TNT_FILAMENT_BACKEND_PRIVATE_OPENGLPLATFORM_H
#define TNT_FILAMENT_BACKEND_PRIVATE_OPENGLPLATFORM_H
#include <backend/Platform.h>
#include "private/backend/AcquiredImage.h"
namespace filament {
namespace backend {
class Driver;
class OpenGLPlatform : public DefaultPlatform {
protected:
/*
* Derived classes can use this to instantiate the default OpenGLDriver backend.
* This is typically called from your implementation of createDriver()
*/
static Driver* createDefaultDriver(OpenGLPlatform* platform, void* sharedContext, const DriverConfig& driverConfig);
public:
~OpenGLPlatform() noexcept override;
// Called to destroy the OpenGL context. This should clean up any windows
// or buffers from initialization.
virtual void terminate() noexcept = 0;
virtual SwapChain* createSwapChain(void* nativeWindow, uint64_t& flags) noexcept = 0;
// headless swapchain
virtual SwapChain* createSwapChain(uint32_t width, uint32_t height, uint64_t& flags) noexcept = 0;
virtual void destroySwapChain(SwapChain* swapChain) noexcept = 0;
virtual void createDefaultRenderTarget(uint32_t& framebuffer, uint32_t& colorbuffer,
uint32_t& depthbuffer) noexcept {
framebuffer = 0;
colorbuffer = 0;
depthbuffer = 0;
}
// Called to make the OpenGL context active on the calling thread.
virtual void makeCurrent(SwapChain* drawSwapChain, SwapChain* readSwapChain) noexcept = 0;
// Called once the current frame finishes drawing. Typically this should
// swap draw buffers (i.e. for double-buffered rendering).
virtual void commit(SwapChain* swapChain) noexcept = 0;
virtual void setPresentationTime(int64_t presentationTimeInNanosecond) noexcept = 0;
virtual bool canCreateFence() noexcept { return false; }
virtual Fence* createFence() noexcept = 0;
virtual void destroyFence(Fence* fence) noexcept = 0;
virtual backend::FenceStatus waitFence(Fence* fence, uint64_t timeout) noexcept = 0;
// this is called synchronously in the application thread (NOT the Driver thread)
virtual Stream* createStream(void* nativeStream) noexcept = 0;
virtual void destroyStream(Stream* stream) noexcept = 0;
// attach takes ownership of the texture (tname) object
virtual void attach(Stream* stream, intptr_t tname) noexcept = 0;
// detach destroys the texture associated to the stream
virtual void detach(Stream* stream) noexcept = 0;
virtual void updateTexImage(Stream* stream, int64_t* timestamp) noexcept = 0;
// The method allows platforms to convert a user-supplied external image object into a new type
// (e.g. HardwareBuffer => EGLImage). It makes sense for the default implementation to do nothing.
virtual AcquiredImage transformAcquiredImage(AcquiredImage source) noexcept { return source; }
// called to bind the platform-specific externalImage to a texture
// texture points to a OpenGLDriver::GLTexture
virtual bool setExternalImage(void* externalImage, void* texture) noexcept {
return false;
}
// called on the application thread to allow Filament to take ownership of the image
virtual void retainExternalImage(void* externalImage) noexcept {}
// called to release ownership of the image
virtual void releaseExternalImage(void* externalImage) noexcept {}
// called once when a new SAMPLER_EXTERNAL texture is created.
virtual void createExternalImageTexture(void* texture) noexcept {}
// called once before a SAMPLER_EXTERNAL texture is destroyed.
virtual void destroyExternalImage(void* texture) noexcept {}
};
} // namespace backend
} // namespace filament
#endif // TNT_FILAMENT_BACKEND_PRIVATE_OPENGLPLATFORM_H

View File

@@ -0,0 +1,59 @@
/*
* Copyright (C) 2022 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* 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.
*/
//! \file
#ifndef TNT_FILAMENT_BACKEND_PLATFORM_FACTORY_H
#define TNT_FILAMENT_BACKEND_PLATFORM_FACTORY_H
#include "backend/DriverEnums.h"
#include "utils/compiler.h"
namespace filament::backend {
class Platform;
class UTILS_PUBLIC PlatformFactory {
public:
/**
* Creates a Platform configured for the requested backend if available
*
* @param backendHint Preferred backend, if not available the backend most suitable for the
* underlying platform is returned and \p backendHint is updated
* accordingly. Can't be nullptr.
*
* @return A pointer to the Platform object.
*
* @see destroy
*/
static Platform* create(backend::Backend* backendHint) noexcept;
/**
* Destroys a Platform object returned by create()
*
* @param platform a reference (as a pointer) to the Platform pointer to destroy.
* \p platform is cleared upon return.
*
* @see create
*/
static void destroy(Platform** platform) noexcept;
};
} // namespace filament
#endif // TNT_FILAMENT_BACKEND_PLATFORM_FACTORY_H

View File

@@ -0,0 +1,3 @@
# include/private/backend Headers
Headers in `include/private/backend/` are only public to filament and cannot be used by end-users.

View File

@@ -29,7 +29,7 @@ bool requestsGoogleLineDirectivesExtension(std::string_view source) noexcept {
}
void removeGoogleLineDirectives(char* shader, size_t length) noexcept {
std::string_view s(shader, length);
std::string_view const s{ shader, length };
size_t pos = 0;
while (true) {
@@ -173,6 +173,20 @@ size_t getFormatSize(TextureFormat format) noexcept {
case TextureFormat::DXT5_SRGBA:
return 16;
case TextureFormat::RED_RGTC1:
case TextureFormat::SIGNED_RED_RGTC1:
return 8;
case TextureFormat::RED_GREEN_RGTC2:
case TextureFormat::SIGNED_RED_GREEN_RGTC2:
return 16;
case TextureFormat::RGB_BPTC_SIGNED_FLOAT:
case TextureFormat::RGB_BPTC_UNSIGNED_FLOAT:
case TextureFormat::RGBA_BPTC_UNORM:
case TextureFormat::SRGB_ALPHA_BPTC_UNORM:
return 16;
// The block size for ASTC compression is always 16 bytes.
case TextureFormat::RGBA_ASTC_4x4:
case TextureFormat::RGBA_ASTC_5x4:
@@ -276,16 +290,22 @@ size_t getFormatComponentCount(TextureFormat format) noexcept {
// Compressed formats ---------------------------------------------------------------------
case TextureFormat::EAC_R11:
case TextureFormat::EAC_R11_SIGNED:
case TextureFormat::RED_RGTC1:
case TextureFormat::SIGNED_RED_RGTC1:
return 1;
case TextureFormat::EAC_RG11:
case TextureFormat::EAC_RG11_SIGNED:
case TextureFormat::RED_GREEN_RGTC2:
case TextureFormat::SIGNED_RED_GREEN_RGTC2:
return 2;
case TextureFormat::ETC2_RGB8:
case TextureFormat::ETC2_SRGB8:
case TextureFormat::DXT1_RGB:
case TextureFormat::DXT1_SRGB:
case TextureFormat::RGB_BPTC_SIGNED_FLOAT:
case TextureFormat::RGB_BPTC_UNSIGNED_FLOAT:
return 3;
case TextureFormat::ETC2_EAC_RGBA8:
@@ -298,6 +318,8 @@ size_t getFormatComponentCount(TextureFormat format) noexcept {
case TextureFormat::DXT3_SRGBA:
case TextureFormat::DXT5_RGBA:
case TextureFormat::DXT5_SRGBA:
case TextureFormat::RGBA_BPTC_UNORM:
case TextureFormat::SRGB_ALPHA_BPTC_UNORM:
case TextureFormat::RGBA_ASTC_4x4:
case TextureFormat::RGBA_ASTC_5x4:
case TextureFormat::RGBA_ASTC_5x5:
@@ -356,6 +378,18 @@ size_t getBlockWidth(TextureFormat format) noexcept {
case TextureFormat::DXT5_SRGBA:
return 4;
case TextureFormat::RED_RGTC1:
case TextureFormat::SIGNED_RED_RGTC1:
case TextureFormat::RED_GREEN_RGTC2:
case TextureFormat::SIGNED_RED_GREEN_RGTC2:
return 4;
case TextureFormat::RGB_BPTC_SIGNED_FLOAT:
case TextureFormat::RGB_BPTC_UNSIGNED_FLOAT:
case TextureFormat::RGBA_BPTC_UNORM:
case TextureFormat::SRGB_ALPHA_BPTC_UNORM:
return 4;
case TextureFormat::RGBA_ASTC_4x4:
case TextureFormat::SRGB8_ALPHA8_ASTC_4x4:
return 4;
@@ -455,7 +489,8 @@ bool reshape(const PixelBufferDescriptor& data, PixelBufferDescriptor& reshaped)
return false;
}
const auto freeFunc = [](void* buffer, size_t size, void* user) { free(buffer); };
const auto freeFunc = [](void* buffer,
UTILS_UNUSED size_t size, UTILS_UNUSED void* user) { free(buffer); };
const size_t reshapedSize = 4 * data.size / 3;
const PixelDataFormat reshapedFormat =
data.format == PixelDataFormat::RGB ? PixelDataFormat::RGBA : PixelDataFormat::RGBA_INTEGER;

View File

@@ -19,8 +19,7 @@
#include <utils/Panic.h>
#include <utils/debug.h>
namespace filament {
namespace backend {
namespace filament::backend {
PresentCallable::PresentCallable(PresentFn fn, void* user) noexcept
: mPresentFn(fn), mUser(user) {
@@ -35,5 +34,4 @@ void PresentCallable::operator()(bool presentFrame) noexcept {
mPresentFn = nullptr;
}
} // namespace backend
} // namespace filament
} // namespace filament::backend

View File

@@ -62,7 +62,7 @@ void* CircularBuffer::alloc(size_t size) noexcept {
void* vaddr = MAP_FAILED;
void* vaddr_shadow = MAP_FAILED;
void* vaddr_guard = MAP_FAILED;
int fd = ashmem_create_region("filament::CircularBuffer", size + BLOCK_SIZE);
int const fd = ashmem_create_region("filament::CircularBuffer", size + BLOCK_SIZE);
if (fd >= 0) {
// reserve/find enough address space
void* reserve_vaddr = mmap(nullptr, size * 2 + BLOCK_SIZE,

View File

@@ -26,8 +26,7 @@
using namespace utils;
namespace filament {
namespace backend {
namespace filament::backend {
CommandBufferQueue::CommandBufferQueue(size_t requiredSize, size_t bufferSize)
: mRequiredSize((requiredSize + CircularBuffer::BLOCK_MASK) & ~CircularBuffer::BLOCK_MASK),
@@ -41,13 +40,13 @@ CommandBufferQueue::~CommandBufferQueue() {
}
void CommandBufferQueue::requestExit() {
std::lock_guard<utils::Mutex> lock(mLock);
std::lock_guard<utils::Mutex> const lock(mLock);
mExitRequested = EXIT_REQUESTED;
mCondition.notify_one();
}
bool CommandBufferQueue::isExitRequested() const {
std::lock_guard<utils::Mutex> lock(mLock);
std::lock_guard<utils::Mutex> const lock(mLock);
ASSERT_PRECONDITION( mExitRequested == 0 || mExitRequested == EXIT_REQUESTED,
"mExitRequested is corrupted (value = 0x%08x)!", mExitRequested);
return (bool)mExitRequested;
@@ -73,7 +72,7 @@ void CommandBufferQueue::flush() noexcept {
void* const tail = circularBuffer.getTail();
// size of this slice
uint32_t used = uint32_t(intptr_t(head) - intptr_t(tail));
uint32_t const used = uint32_t(intptr_t(head) - intptr_t(tail));
circularBuffer.circularize();
@@ -125,10 +124,9 @@ std::vector<CommandBufferQueue::Slice> CommandBufferQueue::waitForCommands() con
}
void CommandBufferQueue::releaseBuffer(CommandBufferQueue::Slice const& buffer) {
std::lock_guard<utils::Mutex> lock(mLock);
std::lock_guard<utils::Mutex> const lock(mLock);
mFreeSpace += uintptr_t(buffer.end) - uintptr_t(buffer.begin);
mCondition.notify_one();
}
} // namespace backend
} // namespace filament
} // namespace filament::backend

View File

@@ -16,7 +16,10 @@
#include "private/backend/CommandStream.h"
#if DEBUG_COMMAND_STREAM
#include <utils/CallStack.h>
#endif
#include <utils/Log.h>
#include <utils/Profiler.h>
#include <utils/Systrace.h>
@@ -34,7 +37,7 @@ namespace filament::backend {
// ------------------------------------------------------------------------------------------------
// A few utility functions for debugging...
inline void printParameterPack(io::ostream& out) { }
inline void printParameterPack(io::ostream&) { }
template<typename LAST>
static void printParameterPack(io::ostream& out, const LAST& t) { out << t; }
@@ -95,7 +98,7 @@ void CommandStream::execute(void* buffer) {
if (UTILS_UNLIKELY(mUsePerformanceCounter)) {
// we want to remove all this when tracing is completely disabled
profiler.stop();
UTILS_UNUSED Profiler::Counters counters = profiler.readCounters();
UTILS_UNUSED Profiler::Counters const counters = profiler.readCounters();
SYSTRACE_VALUE32("GLThread (I)", counters.getInstructions());
SYSTRACE_VALUE32("GLThread (C)", counters.getCpuCycles());
SYSTRACE_VALUE32("GLThread (CPI x10)", counters.getCPI() * 10);

View File

@@ -14,22 +14,21 @@
* limitations under the License.
*/
#include "private/backend/Driver.h"
#include "DriverBase.h"
#include "private/backend/AcquiredImage.h"
#include "private/backend/Driver.h"
#include "private/backend/CommandStream.h"
#include "DriverBase.h"
#include <backend/AcquiredImage.h>
#include <backend/BufferDescriptor.h>
#include <utils/Systrace.h>
#include <math/half.h>
#include <math/vec2.h>
#include <math/vec3.h>
#include <math/vec4.h>
#include <backend/BufferDescriptor.h>
#include <utils/Systrace.h>
using namespace utils;
using namespace filament::math;

View File

@@ -16,172 +16,13 @@
#include <backend/Platform.h>
#include <utils/Systrace.h>
#include <utils/debug.h>
#if defined(__ANDROID__)
#include <sys/system_properties.h>
#if defined(FILAMENT_SUPPORTS_OPENGL) && !defined(FILAMENT_USE_EXTERNAL_GLES3)
#include "opengl/platforms/PlatformEGLAndroid.h"
#endif
#if defined(FILAMENT_DRIVER_SUPPORTS_VULKAN)
#include "vulkan/PlatformVkAndroid.h"
#endif
#elif defined(IOS)
#if defined(FILAMENT_SUPPORTS_OPENGL) && !defined(FILAMENT_USE_EXTERNAL_GLES3)
#include "opengl/platforms/PlatformCocoaTouchGL.h"
#endif
#if defined(FILAMENT_DRIVER_SUPPORTS_VULKAN)
#include "vulkan/PlatformVkCocoaTouch.h"
#endif
#elif defined(__APPLE__)
#if defined(FILAMENT_SUPPORTS_OPENGL) && !defined(FILAMENT_USE_EXTERNAL_GLES3) && !defined(FILAMENT_USE_SWIFTSHADER)
#include "opengl/platforms/PlatformCocoaGL.h"
#endif
#if defined(FILAMENT_DRIVER_SUPPORTS_VULKAN)
#include "vulkan/PlatformVkCocoa.h"
#endif
#elif defined(__linux__)
#if defined(FILAMENT_SUPPORTS_GGP)
#include "vulkan/PlatformVkLinuxGGP.h"
#elif defined(FILAMENT_SUPPORTS_WAYLAND)
#if defined (FILAMENT_DRIVER_SUPPORTS_VULKAN)
#include "vulkan/PlatformVkLinuxWayland.h"
#endif
#elif defined(FILAMENT_SUPPORTS_X11)
#if defined(FILAMENT_SUPPORTS_OPENGL) && !defined(FILAMENT_USE_EXTERNAL_GLES3) && !defined(FILAMENT_USE_SWIFTSHADER)
#include "opengl/platforms/PlatformGLX.h"
#endif
#if defined (FILAMENT_DRIVER_SUPPORTS_VULKAN)
#include "vulkan/PlatformVkLinuxX11.h"
#endif
#elif defined(FILAMENT_SUPPORTS_EGL_ON_LINUX)
#if defined(FILAMENT_SUPPORTS_OPENGL) && !defined(FILAMENT_USE_EXTERNAL_GLES3) && !defined(FILAMENT_USE_SWIFTSHADER)
#include "opengl/platforms/PlatformEGLHeadless.h"
#endif
#endif
#elif defined(WIN32)
#if defined(FILAMENT_SUPPORTS_OPENGL) && !defined(FILAMENT_USE_EXTERNAL_GLES3) && !defined(FILAMENT_USE_SWIFTSHADER)
#include "opengl/platforms/PlatformWGL.h"
#endif
#if defined(FILAMENT_DRIVER_SUPPORTS_VULKAN)
#include "vulkan/PlatformVkWindows.h"
#endif
#elif defined(__EMSCRIPTEN__)
#include "opengl/platforms/PlatformWebGL.h"
#endif
#if defined (FILAMENT_SUPPORTS_METAL)
namespace filament::backend {
filament::backend::DefaultPlatform* createDefaultMetalPlatform();
}
#endif
#include "noop/PlatformNoop.h"
namespace filament::backend {
// this generates the vtable in this translation unit
Platform::~Platform() noexcept = default;
// Creates the platform-specific Platform object. The caller takes ownership and is
// responsible for destroying it. Initialization of the backend API is deferred until
// createDriver(). The passed-in backend hint is replaced with the resolved backend.
DefaultPlatform* DefaultPlatform::create(Backend* backend) noexcept {
SYSTRACE_CALL();
assert_invariant(backend);
#if defined(__ANDROID__)
char scratch[PROP_VALUE_MAX + 1];
int length = __system_property_get("debug.filament.backend", scratch);
if (length > 0) {
*backend = Backend(atoi(scratch));
}
#endif
if (*backend == Backend::DEFAULT) {
#if defined(__EMSCRIPTEN__)
*backend = Backend::OPENGL;
#elif defined(__ANDROID__)
*backend = Backend::OPENGL;
#elif defined(IOS) || defined(__APPLE__)
*backend = Backend::METAL;
#elif defined(FILAMENT_DRIVER_SUPPORTS_VULKAN)
*backend = Backend::VULKAN;
#else
* backend = Backend::OPENGL;
#endif
}
if (*backend == Backend::NOOP) {
return new PlatformNoop();
}
if (*backend == Backend::VULKAN) {
#if defined(FILAMENT_DRIVER_SUPPORTS_VULKAN)
#if defined(__ANDROID__)
return new PlatformVkAndroid();
#elif defined(IOS)
return new PlatformVkCocoaTouch();
#elif defined(__linux__)
#if defined(FILAMENT_SUPPORTS_GGP)
return new PlatformVkLinuxGGP();
#elif defined(FILAMENT_SUPPORTS_WAYLAND)
return new PlatformVkLinuxWayland();
#elif defined(FILAMENT_SUPPORTS_X11)
return new PlatformVkLinuxX11();
#endif
#elif defined(__APPLE__)
return new PlatformVkCocoa();
#elif defined(WIN32)
return new PlatformVkWindows();
#else
return nullptr;
#endif
#else
return nullptr;
#endif
}
if (*backend == Backend::METAL) {
#if defined(FILAMENT_SUPPORTS_METAL)
return createDefaultMetalPlatform();
#else
return nullptr;
#endif
}
assert_invariant(*backend == Backend::OPENGL);
#if defined(FILAMENT_SUPPORTS_OPENGL)
#if defined(FILAMENT_USE_EXTERNAL_GLES3) || defined(FILAMENT_USE_SWIFTSHADER)
// Swiftshader OpenGLES support is deprecated and incomplete
return nullptr;
#elif defined(__ANDROID__)
return new PlatformEGLAndroid();
#elif defined(IOS)
return new PlatformCocoaTouchGL();
#elif defined(__APPLE__)
return new PlatformCocoaGL();
#elif defined(__linux__)
#if defined(FILAMENT_SUPPORTS_X11)
return new PlatformGLX();
#elif defined(FILAMENT_SUPPORTS_EGL_ON_LINUX)
return new PlatformEGLHeadless();
#endif
#elif defined(WIN32)
return new PlatformWGL();
#elif defined(__EMSCRIPTEN__)
return new PlatformWebGL();
#else
return nullptr;
#endif
#else
return nullptr;
#endif
bool Platform::pumpEvents() noexcept {
return false;
}
// destroys a Platform created by create()
void DefaultPlatform::destroy(DefaultPlatform** platform) noexcept {
delete *platform;
*platform = nullptr;
}
DefaultPlatform::~DefaultPlatform() noexcept = default;
} // namespace filament::backend

View File

@@ -0,0 +1,182 @@
/*
* Copyright (C) 2018 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.
*/
#include <private/backend/PlatformFactory.h>
#include <utils/Systrace.h>
#include <utils/debug.h>
#if defined(__ANDROID__)
#include <sys/system_properties.h>
#if defined(FILAMENT_SUPPORTS_OPENGL) && !defined(FILAMENT_USE_EXTERNAL_GLES3)
#include "backend/platforms/PlatformEGLAndroid.h"
#endif
#if defined(FILAMENT_DRIVER_SUPPORTS_VULKAN)
#include "vulkan/PlatformVkAndroid.h"
#endif
#elif defined(IOS)
#if defined(FILAMENT_SUPPORTS_OPENGL) && !defined(FILAMENT_USE_EXTERNAL_GLES3)
#include "backend/platforms/PlatformCocoaTouchGL.h"
#endif
#if defined(FILAMENT_DRIVER_SUPPORTS_VULKAN)
#include "vulkan/PlatformVkCocoaTouch.h"
#endif
#elif defined(__APPLE__)
#if defined(FILAMENT_SUPPORTS_OPENGL) && !defined(FILAMENT_USE_EXTERNAL_GLES3) && !defined(FILAMENT_USE_SWIFTSHADER)
#include <backend/platforms/PlatformCocoaGL.h>
#endif
#if defined(FILAMENT_DRIVER_SUPPORTS_VULKAN)
#include "vulkan/PlatformVkCocoa.h"
#endif
#elif defined(__linux__)
#if defined(FILAMENT_SUPPORTS_GGP)
#include "vulkan/PlatformVkLinuxGGP.h"
#elif defined(FILAMENT_SUPPORTS_WAYLAND)
#if defined (FILAMENT_DRIVER_SUPPORTS_VULKAN)
#include "vulkan/PlatformVkLinuxWayland.h"
#endif
#elif defined(FILAMENT_SUPPORTS_X11)
#if defined(FILAMENT_SUPPORTS_OPENGL) && !defined(FILAMENT_USE_EXTERNAL_GLES3) && !defined(FILAMENT_USE_SWIFTSHADER)
#include "backend/platforms/PlatformGLX.h"
#endif
#if defined (FILAMENT_DRIVER_SUPPORTS_VULKAN)
#include "vulkan/PlatformVkLinuxX11.h"
#endif
#elif defined(FILAMENT_SUPPORTS_EGL_ON_LINUX)
#if defined(FILAMENT_SUPPORTS_OPENGL) && !defined(FILAMENT_USE_EXTERNAL_GLES3) && !defined(FILAMENT_USE_SWIFTSHADER)
#include "backend/platforms/PlatformEGLHeadless.h"
#endif
#endif
#elif defined(WIN32)
#if defined(FILAMENT_SUPPORTS_OPENGL) && !defined(FILAMENT_USE_EXTERNAL_GLES3) && !defined(FILAMENT_USE_SWIFTSHADER)
#include "backend/platforms/PlatformWGL.h"
#endif
#if defined(FILAMENT_DRIVER_SUPPORTS_VULKAN)
#include "vulkan/PlatformVkWindows.h"
#endif
#elif defined(__EMSCRIPTEN__)
#include "backend/platforms/PlatformWebGL.h"
#endif
#if defined (FILAMENT_SUPPORTS_METAL)
namespace filament::backend {
filament::backend::Platform* createDefaultMetalPlatform();
}
#endif
#include "noop/PlatformNoop.h"
namespace filament::backend {
// Creates the platform-specific Platform object. The caller takes ownership and is
// responsible for destroying it. Initialization of the backend API is deferred until
// createDriver(). The passed-in backend hint is replaced with the resolved backend.
Platform* PlatformFactory::create(Backend* backend) noexcept {
SYSTRACE_CALL();
assert_invariant(backend);
#if defined(__ANDROID__)
char scratch[PROP_VALUE_MAX + 1];
int length = __system_property_get("debug.filament.backend", scratch);
if (length > 0) {
*backend = Backend(atoi(scratch));
}
#endif
if (*backend == Backend::DEFAULT) {
#if defined(__EMSCRIPTEN__)
*backend = Backend::OPENGL;
#elif defined(__ANDROID__)
*backend = Backend::OPENGL;
#elif defined(IOS) || defined(__APPLE__)
*backend = Backend::METAL;
#elif defined(FILAMENT_DRIVER_SUPPORTS_VULKAN)
*backend = Backend::VULKAN;
#else
* backend = Backend::OPENGL;
#endif
}
if (*backend == Backend::NOOP) {
return new PlatformNoop();
}
if (*backend == Backend::VULKAN) {
#if defined(FILAMENT_DRIVER_SUPPORTS_VULKAN)
#if defined(__ANDROID__)
return new PlatformVkAndroid();
#elif defined(IOS)
return new PlatformVkCocoaTouch();
#elif defined(__linux__)
#if defined(FILAMENT_SUPPORTS_GGP)
return new PlatformVkLinuxGGP();
#elif defined(FILAMENT_SUPPORTS_WAYLAND)
return new PlatformVkLinuxWayland();
#elif defined(FILAMENT_SUPPORTS_X11)
return new PlatformVkLinuxX11();
#endif
#elif defined(__APPLE__)
return new PlatformVkCocoa();
#elif defined(WIN32)
return new PlatformVkWindows();
#else
return nullptr;
#endif
#else
return nullptr;
#endif
}
if (*backend == Backend::METAL) {
#if defined(FILAMENT_SUPPORTS_METAL)
return createDefaultMetalPlatform();
#else
return nullptr;
#endif
}
assert_invariant(*backend == Backend::OPENGL);
#if defined(FILAMENT_SUPPORTS_OPENGL)
#if defined(FILAMENT_USE_EXTERNAL_GLES3) || defined(FILAMENT_USE_SWIFTSHADER)
// Swiftshader OpenGLES support is deprecated and incomplete
return nullptr;
#elif defined(__ANDROID__)
return new PlatformEGLAndroid();
#elif defined(IOS)
return new PlatformCocoaTouchGL();
#elif defined(__APPLE__)
return new PlatformCocoaGL();
#elif defined(__linux__)
#if defined(FILAMENT_SUPPORTS_X11)
return new PlatformGLX();
#elif defined(FILAMENT_SUPPORTS_EGL_ON_LINUX)
return new PlatformEGLHeadless();
#endif
#elif defined(WIN32)
return new PlatformWGL();
#elif defined(__EMSCRIPTEN__)
return new PlatformWebGL();
#else
return nullptr;
#endif
#else
return nullptr;
#endif
}
// destroys a Platform created by create()
void PlatformFactory::destroy(Platform** platform) noexcept {
delete *platform;
*platform = nullptr;
}
} // namespace filament::backend

View File

@@ -68,7 +68,7 @@ public:
}
};
void blit(id<MTLCommandBuffer> cmdBuffer, const BlitArgs& args);
void blit(id<MTLCommandBuffer> cmdBuffer, const BlitArgs& args, const char* label);
/**
* Free resources. Should be called at least once per process when no further calls to blit will
@@ -112,11 +112,12 @@ private:
};
void blitFastPath(id<MTLCommandBuffer> cmdBuffer, bool& blitColor, bool& blitDepth,
const BlitArgs& args);
const BlitArgs& args, const char* label);
void blitSlowPath(id<MTLCommandBuffer> cmdBuffer, bool& blitColor, bool& blitDepth,
const BlitArgs& args);
const BlitArgs& args, const char* label);
void blitDepthPlane(id<MTLCommandBuffer> cmdBuffer, bool blitColor, bool blitDepth,
const BlitArgs& args, uint32_t depthPlaneSource, uint32_t depthPlaneDest);
const BlitArgs& args, uint32_t depthPlaneSource, uint32_t depthPlaneDest,
const char* label);
id<MTLTexture> createIntermediateTexture(id<MTLTexture> t, MTLSize size);
id<MTLFunction> compileFragmentFunction(BlitFunctionKey key);
id<MTLFunction> getBlitVertexFunction();

View File

@@ -143,7 +143,7 @@ MetalBlitter::MetalBlitter(MetalContext& context) noexcept : mContext(context) {
#define MTLSizeEqual(a, b) (a.width == b.width && a.height == b.height && a.depth == b.depth)
void MetalBlitter::blit(id<MTLCommandBuffer> cmdBuffer, const BlitArgs& args) {
void MetalBlitter::blit(id<MTLCommandBuffer> cmdBuffer, const BlitArgs& args, const char* label) {
bool blitColor = args.blitColor();
bool blitDepth = args.blitDepth();
@@ -164,7 +164,7 @@ void MetalBlitter::blit(id<MTLCommandBuffer> cmdBuffer, const BlitArgs& args) {
// Determine if the blit for color or depth are eligible to use a MTLBlitCommandEncoder.
// blitColor and / or blitDepth are set to false upon success, to indicate that no more work is
// necessary for that attachment.
blitFastPath(cmdBuffer, blitColor, blitDepth, args);
blitFastPath(cmdBuffer, blitColor, blitDepth, args, label);
if (!blitColor && !blitDepth) {
return;
@@ -207,21 +207,22 @@ void MetalBlitter::blit(id<MTLCommandBuffer> cmdBuffer, const BlitArgs& args) {
slowBlit.destination.region = finalBlit.source.region = sourceRegionNoOffset;
}
blitSlowPath(cmdBuffer, blitColor, blitDepth, slowBlit);
blitSlowPath(cmdBuffer, blitColor, blitDepth, slowBlit, label);
bool finalBlitColor = intermediateColor != nil;
bool finalBlitDepth = intermediateDepth != nil;
blitFastPath(cmdBuffer, finalBlitColor, finalBlitDepth, finalBlit);
blitFastPath(cmdBuffer, finalBlitColor, finalBlitDepth, finalBlit, label);
}
void MetalBlitter::blitFastPath(id<MTLCommandBuffer> cmdBuffer, bool& blitColor, bool& blitDepth,
const BlitArgs& args) {
const BlitArgs& args, const char* label) {
if (blitColor) {
if (args.source.color.sampleCount == args.destination.color.sampleCount &&
args.source.color.pixelFormat == args.destination.color.pixelFormat &&
MTLSizeEqual(args.source.region.size, args.destination.region.size)) {
id<MTLBlitCommandEncoder> blitEncoder = [cmdBuffer blitCommandEncoder];
blitEncoder.label = @(label);
[blitEncoder copyFromTexture:args.source.color
sourceSlice:args.source.slice
sourceLevel:args.source.level
@@ -243,6 +244,7 @@ void MetalBlitter::blitFastPath(id<MTLCommandBuffer> cmdBuffer, bool& blitColor,
MTLSizeEqual(args.source.region.size, args.destination.region.size)) {
id<MTLBlitCommandEncoder> blitEncoder = [cmdBuffer blitCommandEncoder];
blitEncoder.label = @(label);
[blitEncoder copyFromTexture:args.source.depth
sourceSlice:args.source.slice
sourceLevel:args.source.level
@@ -260,7 +262,7 @@ void MetalBlitter::blitFastPath(id<MTLCommandBuffer> cmdBuffer, bool& blitColor,
}
void MetalBlitter::blitSlowPath(id<MTLCommandBuffer> cmdBuffer, bool& blitColor, bool& blitDepth,
const BlitArgs& args) {
const BlitArgs& args, const char* label) {
uint32_t depthPlaneSource = args.source.region.origin.z;
uint32_t depthPlaneDest = args.destination.region.origin.z;
@@ -268,7 +270,8 @@ void MetalBlitter::blitSlowPath(id<MTLCommandBuffer> cmdBuffer, bool& blitColor,
assert_invariant(args.source.region.size.depth == args.destination.region.size.depth);
uint32_t depthPlaneCount = args.source.region.size.depth;
for (NSUInteger d = 0; d < depthPlaneCount; d++) {
blitDepthPlane(cmdBuffer, blitColor, blitDepth, args, depthPlaneSource++, depthPlaneDest++);
blitDepthPlane(cmdBuffer, blitColor, blitDepth, args, depthPlaneSource++, depthPlaneDest++,
label);
}
blitColor = false;
@@ -276,7 +279,8 @@ void MetalBlitter::blitSlowPath(id<MTLCommandBuffer> cmdBuffer, bool& blitColor,
}
void MetalBlitter::blitDepthPlane(id<MTLCommandBuffer> cmdBuffer, bool blitColor, bool blitDepth,
const BlitArgs& args, uint32_t depthPlaneSource, uint32_t depthPlaneDest) {
const BlitArgs& args, uint32_t depthPlaneSource, uint32_t depthPlaneDest,
const char* label) {
MTLRenderPassDescriptor* descriptor = [MTLRenderPassDescriptor renderPassDescriptor];
if (blitColor) {
@@ -288,7 +292,7 @@ void MetalBlitter::blitDepthPlane(id<MTLCommandBuffer> cmdBuffer, bool blitColor
}
id<MTLRenderCommandEncoder> encoder = [cmdBuffer renderCommandEncoderWithDescriptor:descriptor];
encoder.label = @"Blit";
encoder.label = @(label);
BlitFunctionKey key;
key.blitColor = blitColor;

View File

@@ -69,6 +69,7 @@ void MetalBuffer::copyIntoBuffer(void* src, size_t size, size_t byteOffset) {
// Encode a blit from the staging buffer into the private GPU buffer.
id<MTLCommandBuffer> cmdBuffer = getPendingCommandBuffer(&mContext);
id<MTLBlitCommandEncoder> blitEncoder = [cmdBuffer blitCommandEncoder];
blitEncoder.label = @"Buffer upload blit";
[blitEncoder copyFromBuffer:staging->buffer
sourceOffset:0
toBuffer:mBuffer

View File

@@ -27,7 +27,7 @@
#include "MetalState.h"
#include "MetalTimerQuery.h"
#include "private/backend/MetalPlatform.h"
#include "MetalPlatform.h"
#include <CoreVideo/CVMetalTexture.h>
#include <CoreVideo/CVPixelBuffer.h>
@@ -706,6 +706,11 @@ bool MetalDriver::isAutoDepthResolveSupported() {
return mContext->supportsAutoDepthResolve;
}
bool MetalDriver::isSRGBSwapChainSupported() {
// the SWAP_CHAIN_CONFIG_SRGB_COLORSPACE flag is not supported
return false;
}
bool MetalDriver::isWorkaroundNeeded(Workaround workaround) {
switch (workaround) {
case Workaround::SPLIT_EASU:
@@ -803,11 +808,6 @@ void MetalDriver::setupExternalImage(void* image) {
CVPixelBufferRetain(pixelBuffer);
}
void MetalDriver::cancelExternalImage(void* image) {
CVPixelBufferRef pixelBuffer = (CVPixelBufferRef) image;
CVPixelBufferRelease(pixelBuffer);
}
void MetalDriver::setExternalImage(Handle<HwTexture> th, void* image) {
ASSERT_PRECONDITION(!isInRenderPass(mContext),
"setExternalImage must be called outside of a render pass.");
@@ -1263,7 +1263,7 @@ void MetalDriver::readPixels(Handle<HwRenderTarget> src, uint32_t x, uint32_t y,
args.source.color = srcTexture;
args.destination.color = readPixelsTexture;
mContext->blitter->blit(getPendingCommandBuffer(mContext), args);
mContext->blitter->blit(getPendingCommandBuffer(mContext), args, "readPixels blit");
#if !defined(IOS)
// Managed textures on macOS require explicit synchronization between GPU / CPU.
@@ -1347,7 +1347,7 @@ void MetalDriver::blit(TargetBufferFlags buffers,
args.destination.level = dstColorAttachment.level;
args.source.slice = srcColorAttachment.layer;
args.destination.slice = dstColorAttachment.layer;
mContext->blitter->blit(getPendingCommandBuffer(mContext), args);
mContext->blitter->blit(getPendingCommandBuffer(mContext), args, "Color blit");
}
}
@@ -1370,7 +1370,7 @@ void MetalDriver::blit(TargetBufferFlags buffers,
args.destination.level = dstDepthAttachment.level;
args.source.slice = srcDepthAttachment.layer;
args.destination.slice = dstDepthAttachment.layer;
mContext->blitter->blit(getPendingCommandBuffer(mContext), args);
mContext->blitter->blit(getPendingCommandBuffer(mContext), args, "Depth blit");
}
}
}

View File

@@ -198,6 +198,16 @@ MTLPixelFormat getMetalFormat(MetalContext* context, TextureFormat format) noexc
case TextureFormat::DXT1_RGB: return MTLPixelFormatInvalid;
case TextureFormat::DXT1_SRGB: return MTLPixelFormatInvalid;
case TextureFormat::RED_RGTC1: return MTLPixelFormatBC4_RUnorm;
case TextureFormat::SIGNED_RED_RGTC1: return MTLPixelFormatBC4_RSnorm;
case TextureFormat::RED_GREEN_RGTC2: return MTLPixelFormatBC5_RGUnorm;
case TextureFormat::SIGNED_RED_GREEN_RGTC2: return MTLPixelFormatBC5_RGSnorm;
case TextureFormat::RGB_BPTC_SIGNED_FLOAT: return MTLPixelFormatBC6H_RGBFloat;
case TextureFormat::RGB_BPTC_UNSIGNED_FLOAT: return MTLPixelFormatBC6H_RGBUfloat;
case TextureFormat::RGBA_BPTC_UNORM: return MTLPixelFormatBC7_RGBAUnorm;
case TextureFormat::SRGB_ALPHA_BPTC_UNORM: return MTLPixelFormatBC7_RGBAUnorm_sRGB;
default: break;
}
}

View File

@@ -391,6 +391,9 @@ MetalProgram::MetalProgram(id<MTLDevice> device, const Program& program) noexcep
id<MTLFunction> function = [library newFunctionWithName:@"main0"
constantValues:constants
error:&error];
if (!program.getName().empty()) {
function.label = @(program.getName().c_str());
}
assert_invariant(function);
*shaderFunctions[i] = function;
}
@@ -720,6 +723,7 @@ void MetalTexture::loadWithCopyBuffer(uint32_t level, uint32_t slice, MTLRegion
stagingBufferSize);
id<MTLCommandBuffer> blitCommandBuffer = getPendingCommandBuffer(&context);
id<MTLBlitCommandEncoder> blitCommandEncoder = [blitCommandBuffer blitCommandEncoder];
blitCommandEncoder.label = @"Texture upload buffer blit";
[blitCommandEncoder copyFromBuffer:entry->buffer
sourceOffset:0
sourceBytesPerRow:shape.bytesPerRow
@@ -792,7 +796,7 @@ void MetalTexture::loadWithBlit(uint32_t level, uint32_t slice, MTLRegion region
args.destination.region = region;
args.source.color = stagingTexture;
args.destination.color = destinationTexture;
context.blitter->blit(getPendingCommandBuffer(&context), args);
context.blitter->blit(getPendingCommandBuffer(&context), args, "Texture upload blit");
}
void MetalTexture::updateLodRange(uint32_t level) {

View File

@@ -22,10 +22,9 @@
#import <Metal/Metal.h>
namespace filament {
namespace backend {
namespace filament::backend {
class MetalPlatform : public DefaultPlatform {
class MetalPlatform final : public Platform {
public:
~MetalPlatform() override;
@@ -60,7 +59,6 @@ private:
};
} // namespace backend
} // namespace filament
} // namespace filament::backend
#endif // TNT_FILAMENT_BACKEND_PRIVATE_METALPLATFORM_H

View File

@@ -14,7 +14,7 @@
* limitations under the License.
*/
#include "private/backend/MetalPlatform.h"
#include "MetalPlatform.h"
#include "MetalDriverFactory.h"
@@ -22,16 +22,15 @@
#import <Foundation/Foundation.h>
namespace filament {
namespace backend {
namespace filament::backend {
DefaultPlatform* createDefaultMetalPlatform() {
Platform* createDefaultMetalPlatform() {
return new MetalPlatform();
}
MetalPlatform::~MetalPlatform() = default;
Driver* MetalPlatform::createDriver(void* sharedContext, const Platform::DriverConfig& driverConfig) noexcept {
Driver* MetalPlatform::createDriver(void* /*sharedContext*/, const Platform::DriverConfig& driverConfig) noexcept {
return MetalDriverFactory::create(this, driverConfig);
}
@@ -75,5 +74,4 @@ id<MTLCommandBuffer> MetalPlatform::createAndEnqueueCommandBuffer() noexcept {
return commandBuffer;
}
} // namespace backend
} // namespace filament

View File

@@ -173,7 +173,11 @@ bool NoopDriver::isAutoDepthResolveSupported() {
return true;
}
bool NoopDriver::isWorkaroundNeeded(Workaround workaround) {
bool NoopDriver::isSRGBSwapChainSupported() {
return false;
}
bool NoopDriver::isWorkaroundNeeded(Workaround) {
return false;
}
@@ -224,9 +228,6 @@ void NoopDriver::update3DImage(Handle<HwTexture> th,
void NoopDriver::setupExternalImage(void* image) {
}
void NoopDriver::cancelExternalImage(void* image) {
}
bool NoopDriver::getTimerQueryValue(Handle<HwTimerQuery> tqh, uint64_t* elapsedTime) {
return false;
}

View File

@@ -22,7 +22,7 @@
namespace filament::backend {
class PlatformNoop final : public DefaultPlatform {
class PlatformNoop final : public Platform {
public:
int getOSVersion() const noexcept final { return 0; }

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