Compare commits

..

289 Commits

Author SHA1 Message Date
Benjamin Doherty
f222f1b925 Merge branch 'rc/1.9.11' into release 2021-02-08 09:51:08 -08:00
Ben Doherty
2839c352b8 Update RELEASE_NOTES for 1.9.11 2021-02-08 09:47:18 -08:00
Ben Doherty
6a01cbc312 Draft: fix TSAN issue by using lock in ColorGrading constructor (#3510)
This is a second attempt to fix Google3 TSAN failures seen inside of the ColorGrading constructor.

Related first attempt: #3462
2021-02-05 14:06:40 -08:00
Benjamin Doherty
6193156556 Bump version to 1.9.11 2021-02-01 11:49:12 -08:00
Benjamin Doherty
fe23aa917d Merge branch 'rc/1.9.10' into release 2021-02-01 11:45:47 -08:00
Benjamin Doherty
eb8a29a332 Update RELEASE_NOTES for 1.9.10 2021-02-01 11:45:17 -08:00
Benjamin Doherty
6eec2cde81 Release Filament 1.9.10 2021-02-01 11:44:33 -08:00
Philip Rideout
98ae61ffe5 gltfio: Fix "_maskThreshold not found" error.
MaterialGenerator selects a custom blend mode for transmissive models,
therefore the AssetLoader should look at the material's blend mode when
it sets up properties, not the one requested by the glTF file.

Fixes #3444.
2021-02-01 09:52:06 -08:00
Romain Guy
adb489c77a Compile Android libraries with fPIC (#3473)
* Compile Android libraries with fPIC

* Rmove warning
2021-01-29 15:23:34 -08:00
Philip Rideout
eeccfed8e4 Rewrite and enhance test_FeedbackLoops.
Previously this test was actually finding a ReadPixels failure on Intel
GPU's, rather than a failure of feedback loop behavior. This was due to
the fact that it was calling ReadPixels on a non-zero miplevel, which
seems to be unsupported on Intel GPU's.

The test now follows the downsample phase with an upsample phase, just
like the real bloom effect. This allows us to issue ReadPixels on the
base level, thus making the test more targetted to rendering feedback
loops.
2021-01-29 15:06:57 -08:00
Philip Rideout
893ed861e9 gltfio on Java: free material cache in AssetLoader#destroy
Fixes #3469
2021-01-29 14:42:54 -08:00
Romain Guy
411ae23512 Update Kotlin, Gradle and NDK dependencies (#3470)
* Update Kotlin, Gradle and NDK dependencies

* Update CI build
2021-01-29 12:09:08 -08:00
Romain Guy
8f05984551 Update release notes 2021-01-29 09:31:36 -08:00
Romain Guy
4567b01c1d Multi-thread shaders generation when compiling materials (#3464)
* Stop using members as globals between methods

* Multi-thread shaders generation with JobSystem

* Pass JobSystem to MaterialBuilder::build()

* Fix MeshAssimp to use the new API

* Allow the Java API to pass a job system via Engine

* Update docs

* Apply suggestions from code review

Co-authored-by: Philip Rideout <philiprideout@gmail.com>
2021-01-29 09:30:37 -08:00
Philip Rideout
29315f9a1b gltfio: fix crash during async texture decode.
Recall that we now use shared_ptr to simplify lifetime management of
cgltf source data (#3413).

Before this commit, we were only using shared_ptr to retain the source
data during buffer uploads. After this commit, we are using it to retain
source data during texture decoding.

Fixes #3428.
2021-01-29 09:06:32 -08:00
Ben Doherty
0626902530 Fix sporatic data race warning seen in Google3 (#3462) 2021-01-27 16:40:16 -08:00
Ben Doherty
d4a2d30a1c Fix sporatic data race warning seen in Google3 (#3462) 2021-01-27 16:38:38 -08:00
Philip Rideout
cec5f3e988 gltfio: disable shader optimizations by default
Note that ubershaders (which are always used on Android and WebGL) are
still optimized by default.
2021-01-27 11:40:51 -08:00
Romain Guy
02501c6e60 Modulate emissive by alpha on blended objects (#3459)
This prevents light from being emitted from completely
transparent pixels.
2021-01-26 16:35:49 -08:00
Ben Doherty
4d8da14c1f Update universal library option in build.sh for Apple silicon (#3458) 2021-01-26 16:34:46 -08:00
Philip Rideout
4fae917fb5 Introduce optional ping-ping bloom implementation.
Second attempt after abandoning #3451.

Feedback loops do not work with Chrome or Intel GPU's, so we now have an
optional ping-pong implementation of Bloom.

Issue #2338.
2021-01-26 15:08:39 -08:00
Philip Rideout
c84036c8c4 Update JavaScript bindings and demo to prep for Bloom workaround. 2021-01-26 13:18:03 -08:00
Philip Rideout
34429f5490 Add unit test for feedback loops.
This test passes on my Radeon GPU MacBook but fails with an Intel GPU.
2021-01-26 13:12:46 -08:00
Philip Rideout
59c2d5bef3 Plumbing for disabling feedback loops on Intel.
This is a follow-on to #3451, which adds optional ping-pong support to
the bloom generator.
2021-01-26 13:12:24 -08:00
Ben Doherty
a3412c4f45 Remove shadow cascade visualization from unlit variants (#3455) 2021-01-26 11:20:54 -08:00
Philip Rideout
564d846be5 Repair backend unit tests on macOS.
This fixes "illegal hardware instruction" seen on my MacBook, which
is the same as #1839, but triggered only in a test environment where
the main thread is the same as the driver thread, and filament is built
with HAS_THREADING enabled.
2021-01-26 08:57:16 -08:00
Romain Guy
41186340c9 Change visibility of a few color grading options 2021-01-25 08:49:25 -08:00
Ben Doherty
96bba71739 Update combine-static-libs.sh script to work with universal binaries (#3447) 2021-01-22 15:57:43 -08:00
Adrian Perez
5ab7a9e3ab Add swap() methods to Allocator.h (#3445)
* Add swap() methods to Allocator.h

This allows StructureOfArraysBase's move constructor to compile.
Removed an apparent workaround in SingleInstanceComponentManager.

* swap can be noexcept

* Add swap() methods to Allocator.h

This allows StructureOfArraysBase's move constructor to compile.

Co-authored-by: Mathias Agopian <pixelflinger@gmail.com>
2021-01-22 15:45:20 -08:00
Mathias Agopian
4c30067dac fix missing froxel
Fix a possible out-of-bound access when reading the x-planes array. 
Also account for the fact that the loops filling the froxels assume
stl-like iterators (1-past the end on the right), while the indices
themselves were right-inclusive.

fixes #3142
2021-01-19 17:31:43 -08:00
Philip Rideout
243ba77025 gltfio: support animation in dynamically-added instances.
I tested this by viewing CesiumMan with our `gltf_instances` sample app.

There is now a need for some general refactoring in gltfio. I feel that
the high-level objects have become too tightly coupled to each other.

Fixes #3137.
2021-01-19 16:37:54 -08:00
Mathias Agopian
229f1f6d95 make sure the ResourceAllocator stays below the cache size limit
Only items older than a certain value were purged from the cache,
this allowed the cache to grow unbounded before this age limit was
reached.

We now purge the cache at each frame if it's above the size threshold.

Fixes #3381
2021-01-19 15:20:37 -08:00
Mathias Agopian
bc2eae2ecd fix filament_test on aarch64 mac
don't use slog from a static variable, because it might not have been
constructed yet, due to static initialized order.
For some reason, this happens on aarch64 macs, but this was actually
a real problem.
2021-01-19 15:20:11 -08:00
Philip Rideout
e468ec91b7 Metal: honor inverseFrontFaces RasterState.
Fixes #3402.
2021-01-19 10:35:14 -08:00
Philip Rideout
ca2829461a Add options to planar reflection demo.
By default, the demo now reflects the camera instead of the renderable.
However this can be changed via the command line. Users can now change
the backend too.
2021-01-19 09:16:50 -08:00
Philip Rideout
7805687f7a Update emsdk version in README. 2021-01-16 09:17:56 -08:00
Mathias Agopian
af82aaa0fc remove unused code that causes warnings 2021-01-15 14:38:01 -08:00
Mathias Agopian
410ecfd014 support for Apple Silicon macs
- add darwin-aarch64 support to bluegl
- remove all aarch64 conditions in our cmakefiles, the architecture
  is better handled in the source files (to allow fat binaries later)
2021-01-15 14:02:19 -08:00
Mathias Agopian
0df1f9fcce hack libfilament_jni to compile on Apple Silicon
The problem is that we're trying to link against an x86 jdk and that
fails, in turn preventing the library to link.
2021-01-15 14:02:19 -08:00
Mirsfang
45f7e07832 fix material use (#3417)
* fix material use

* Update filament/src/PostProcessManager.cpp

Co-authored-by: Mathias Agopian <pixelflinger@gmail.com>
2021-01-15 13:59:09 -08:00
Mathias Agopian
1aefe741b2 update libpng to 1.6.37 2021-01-15 12:10:03 -08:00
Mathias Agopian
d1842919cf update zlib to 1.2.11 2021-01-15 12:10:03 -08:00
Philip Rideout
6473771f1e Update Draco to 1.4.1
Tested with gltf_viewer release macOS on:

- CesiumMan/glTF-Draco/CesiumMan.gltf
- MorphPrimitivesTest/glTF-Draco/MorphPrimitivesTest.gltf
2021-01-15 11:03:29 -08:00
Philip Rideout
2d57a82b49 Add simple RenderTarget demo (planar reflection)
When we removed the old "ghetto bloom" demo, we ceased to have any
samples demonstrating the RenderTarget API. This demo is a fairly simple
demonstration of planar reflection.
2021-01-14 16:27:18 -08:00
Romain Guy
dc2d55c409 Update static documentation 2021-01-14 10:29:38 -08:00
Romain Guy
c0b8e98a93 Update documentation to fix broken links 2021-01-14 10:28:56 -08:00
Philip Rideout
8252bbe512 gltf_viewer: fix very sporadic crash when exiting.
This could occur when trying to exit the app while textures
are still being decoded.
2021-01-13 09:48:36 -08:00
Philip Rideout
a4817f3e2a Simplify lifetime management of cgltf_data.
The gltfio API allows users to destroy ResourceLoader or FilamentAsset
even when various asynchronous work (e.g. uploading buffers to the GPU)
has not yet been completed. This was achieved in an error-prone manner
using manual reference counting and an internal management object called
AssetPool.

This PR refactors gltfio by wrapping cgltf_data in shared_ptr, which I
usually try to avoid. However in this case it provides the precisely the
functionality that is needed.

I tested this PR for memory leaks and crashes by hacking gltf_viewer
and monitoring memory usage in Activity Monitor.

This fixes #3383 and makes it easier to implement some missing features,
such as animation support for instanced assets.
2021-01-13 09:44:56 -08:00
Philip Rideout
fa879b4bd0 gltf_viewer: call asyncCancelLoad in drop handler
Relates to #3383
2021-01-08 09:40:39 -08:00
Ben Doherty
005e4ba2ec Fix Filament RenderingTest (#3407) 2021-01-07 12:10:53 -08:00
Romain Guy
d2299c4502 List supported glTF 2.0 features 2021-01-06 14:20:46 -08:00
Philip Rideout
5c666c254e gltfio: Improve robustness when decoding textures.
Bad texture files would cause the background decoder thread to never
finish and would generate textures with 0x0 dimensions, which eventually
triggers GL_INVALID_VALUE.

To recap, gltfio texture loading has two phases: the first phase is
synchronous and uses stbi_info to gather texture info. The second phase
is asynchronous and uses stbi_load to do the actual decoding.

During the first phase, we now check the return code from stbi_info
rather than assuming that it worked.  :)

Fixes #3344
2021-01-05 12:00:29 -08:00
ritwik
a09c17bd4f Make install gltfio_resources and gltfio_resources_lite for desktop builds also 2021-01-05 10:35:13 -08:00
Ben Doherty
57df4481e9 Update Material query API to work with subpasses (#3203)
* Update Material query API to work with subpasses

* Add JNI binding
2020-12-23 13:27:04 -08:00
Ben Doherty
47af85aed1 Remove libSPIRV-Tools-shared from spirv-tools (#3390) 2020-12-23 13:26:14 -08:00
Ben Doherty
44fc295913 Unbind texture from all sampler groups upon destroy (#3386) 2020-12-22 11:34:05 -08:00
Philip Rideout
6878b0be36 build.sh: Add TypeScript bindings to the tgz file.
This makes the tgz consistent with the npm package. Fixes #3268.

Note that we already stopped packaging the old HTML docs. Going forward,
we would like to use the TS declarations as documentation because they
must be kept up to date anyway, and they already contain type
information. This was discussed in #3250.
2020-12-21 17:27:46 -08:00
Romain Guy
6c222bf4e3 Update README 2020-12-15 14:48:38 -08:00
Philip Rideout
042bfe2597 Partial fix for MSVC build. 2020-12-14 12:15:06 -08:00
Ben Doherty
97133f3591 Fix Windows iterator issue in Zip2Iterator and StructureOfArrays (#3322) 2020-12-14 12:14:53 -08:00
Philip Rideout
d06cc4390e filamat: minify struct fields.
This shrinks the arm64 so file by 24 KiB.
2020-12-14 11:19:43 -08:00
Philip Rideout
6047d3235f Remove VSM variant from Skybox material. 2020-12-14 11:19:31 -08:00
Philip Rideout
2cda6e35bd math: reduce template bloat for matrices
This does not change our API, it merely reduces the number of
non-inlined function instantiations appearing in non-optimized binaries.
2020-12-14 11:19:22 -08:00
Philip Rideout
8f8d51e17b Code review fixups for libibl_lite. 2020-12-14 11:19:16 -08:00
Philip Rideout
6919e3b274 libibl: use C callback for progress 2020-12-14 11:19:09 -08:00
Philip Rideout
10bf944410 Add libibl_lite. 2020-12-14 11:19:03 -08:00
Romain Guy
eb70fd5dee Sample the proper channel for sheenRoughness 2020-12-12 18:05:02 -08:00
Romain Guy
986a3869cc Fix struct initialization 2020-12-12 17:40:48 -08:00
Romain Guy
9ad3d88d74 Fix build breakage.
We were declaring one too many material properties which would
lead to out of bounds writes/reads.
2020-12-12 12:04:24 -08:00
Romain Guy
a3bfdb89fa Update release notes 2020-12-12 11:09:28 -08:00
Romain Guy
2895530e09 Add support for sheenColor and sheenRoughness (#3358)
* Add support for sheenColor and sheenRoughness

This work is necessary to support the glTF extension KHR_materials_sheen.
This change effectively adds the specular lobe from the cloth material
model to the base material model. The cloth model remains useful for
its extra subsurface color feature but also because it's cheaper.

* Add support for KHR_materials_sheen to gltfio

* Update documentation

* Document default shading values
2020-12-12 11:07:40 -08:00
Romain Guy
f8069aa99f Update to cgltf 1.9 (#3361) 2020-12-11 16:42:36 -08:00
Philip Rideout
b70eea9556 filamat: minify struct fields.
This shrinks the arm64 so file by 24 KiB.
2020-12-10 11:20:14 -08:00
Philip Rideout
44a8da6a8e Remove VSM variant from Skybox material. 2020-12-10 11:20:01 -08:00
Philip Rideout
3bd066f993 math: reduce template bloat for matrices
This does not change our API, it merely reduces the number of
non-inlined function instantiations appearing in non-optimized binaries.
2020-12-10 11:19:46 -08:00
Philip Rideout
1b10afa9e6 Code review fixups for libibl_lite. 2020-12-10 11:19:36 -08:00
Philip Rideout
024910ba8e libibl: use C callback for progress 2020-12-10 11:19:36 -08:00
Philip Rideout
f2e3a132db Add libibl_lite. 2020-12-10 11:19:36 -08:00
Philip Rideout
87abd1f8bc Fix RenderableManager docs for "index"
I also double-checked the backends, they indeed treat it as an index
count.

Fixes #3351
2020-12-10 10:11:46 -08:00
Philip Rideout
57662c52f2 matdbg / matinfo: fix post-process variant string
Also some minor HTML stuff:

- Hide "Required attributes" header when there are none.
- Remove legend for variants (takes too much space).
2020-12-09 14:44:27 -08:00
Philip Rideout
a50cd1f8c8 zbloat now includes chunk sizes 2020-12-06 21:54:37 -08:00
Philip Rideout
fe907398d4 resgen / zbloat fixups 2020-12-06 15:25:08 -08:00
Philip Rideout
8b6ddfe97a Add zbloat tool.
This tool makes it easy to analyze the composition of Android
applications that use Filament.

- Filament materials are shown in the treemap if `resgen --json` was
  used in the build.
- The input path can be a so file, folder, or zip archive (apk or aar).
- If the path is a zip or folder, helps you find the file to analyze.
- The generated web report is a self-contained HTML file.
- Reports the gzipped size of all Filament materials.

For example, from a mac, you can generate a self-contained HTML file by
typing this from the Filament repo root:

    ./tools/zbloat/zbloat.py ./android/filament-android
    open index.html

This tool uses Python, `nm`, and `objdump`.

The `nm` tool works slightly differently between macOS and Linux, so a
`Dockerfile` is provided that installs dependencies inside a Linux
container. This is also convenient if you do not have both versions of
Python on your system.

The easy way to use docker is to invoke the helper bash script. Simply
type `zbloat.sh [args...]` instead of `zbloat.py [args...]`. The first
time you run it, it will be slow but subsequent times will be fast.

Many thanks to Evan Martin for his interactive treemap widget.
2020-12-06 14:36:25 -08:00
Philip Rideout
3226b20ece resgen: add --json option.
This option embeds a small JSON string inside the resgen blob that lists
all materials and their respective sizes. This is useful when analyzing
the footprint of the binary executable.
2020-12-06 14:36:13 -08:00
MasTraER
61d473887f Fix clearing Rendertarget multiple times
This fixes a bug Renderer clearing a render target multiple times when the first time and back again.

Usually the default RenderTarget is unintentionally cleared/discarded in the current behavior.
1) Renderer renders a view without custom RenderTarget having full-screen viewport,
2) Renderer renders a view with custom RenderTarget
3) And Renderer renders an another view without custom RenderTarget having different viewport from 1)
You may see junk or empty pixels in outside of the viewport of the view 3), depending on ClearOptions and the backend.

This fix make Renderer put cleared RenderTargets into a set and check them to be cleared only for the first time, instead of comparing the previous RenderTarget to the current RenderTarget.
2020-12-06 14:35:26 -08:00
cjsliuj
b3d7819e78 Fix computeTangents 2020-12-05 15:24:34 -08:00
Philip Rideout
de6220594d WebGL: RGB16F is not color renderable.
This was problematic with Chrome's ANGLE backend; more information at:
https://bugs.chromium.org/p/chromium/issues/detail?id=941671#c10

Fixes #3308
2020-12-02 14:31:19 -08:00
Philip Rideout
d9dfe69a81 Android: do not export internal symbols.
We now export only two groups of symbols: (1) JNI and (2) dynamic linker
symbols used by the companion libraries.

This commit has the following impact:

- Shrinks the arm64 so from 1024 KiB to 954 KiB.
- Shrinks the arm64 aar from 560 KiB to 538 KiB.

Note that the patterns in the map file are tested against mangled names
and therefore should not be used to match the double-colon operator.
2020-12-02 13:11:38 -08:00
Ben Doherty
22d4e63787 Fix Windows iterator issue in Zip2Iterator and StructureOfArrays (#3322) 2020-12-01 14:05:15 -08:00
Philip Rideout
f033799a43 Fix incorrect JNI binding for destroyColorGrading. 2020-12-01 09:02:51 -08:00
Ben Doherty
30e150c016 Fix Metal assertion when loading into texture arrays (#3314) 2020-11-24 10:46:16 -08:00
Ben Doherty
f5f27749a4 Update native window documentation (#3315) 2020-11-23 14:03:10 -08:00
Philip Rideout
b5f95213db Partial fix for MSVC build. 2020-11-20 14:18:08 -08:00
Philip Rideout
9a2f6fdb53 Vulkan: change vkWaitForFences usage for SwiftShader.
When passing only 1 fence to vkWaitForFences, the `waitAll` argument
should not have any effect, but SwiftShader seems to skip the wait
when this argument is set to VK_FALSE.

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

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

We have 5 usages of vkWaitForFences, one of which uses multiple fences
and should have used VK_TRUE anyway.
2020-11-20 09:37:54 -08:00
Philip Rideout
d42865373d Vulkan: change vkWaitForFences usage for SwiftShader.
When passing only 1 fence to vkWaitForFences, the `waitAll` argument
should not have any effect, but SwiftShader seems to skip the wait
when this argument is set to VK_FALSE.

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

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

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

Note that it is okay to declare a sampler in GLSL that never gets bound,
as long as it is never sampled from. Since we always sample from the
IBL specular texture, we should always bind something to it.
2020-11-19 13:28:19 -08:00
Philip Rideout
f83eb114bc Filament should always bind an IBL texture.
This prevents a SwiftShader crash and/or a slew of "no texture bound"
warnings that would appear when the client provides an IBL without
providing reflections texture, which should be a valid thing to do.

Note that it is okay to declare a sampler in GLSL that never gets bound,
as long as it is never sampled from. Since we always sample from the
IBL specular texture, we should always bind something to it.
2020-11-19 10:22:45 -08:00
Philip Rideout
9c20294e4b gltfio: Fix animator crash for orphaned nodes.
Fixes #3285
2020-11-18 11:26:39 -08:00
Ben Doherty
40e7a86f5f Fix, matc crash when building mobile materials (#3296) 2020-11-16 14:41:15 -08:00
Ben Doherty
21248f15b5 Fix, matc crash when building mobile materials (#3296) 2020-11-16 14:37:55 -08:00
Ben Doherty
34707431f7 Fix spirv-tools CMake warning (#3289) 2020-11-16 14:30:06 -08:00
Benjamin Doherty
4f32817f6d Bump version to 1.9.10 2020-11-16 12:37:49 -08:00
Benjamin Doherty
cc9e05e711 Merge branch 'rc/1.9.9' into release 2020-11-16 12:34:13 -08:00
Benjamin Doherty
5e585496b2 Update RELEASE_NOTES for 1.9.9 2020-11-16 12:33:43 -08:00
Benjamin Doherty
1e501eb00b Release Filament 1.9.9 2020-11-16 12:32:38 -08:00
Benjamin Doherty
419d68d4db Update RELEASE_NOTES for 1.9.9 2020-11-16 12:17:02 -08:00
Ben Doherty
fdc28801a2 Silence spirv-opt warnings in release builds (#3288) 2020-11-13 13:55:19 -08:00
Ben Doherty
c008109335 Update Android building instructions on Windows 2020-11-13 11:04:24 -08:00
Philip Rideout
8450232448 Improve the "unbound texture" warnings.
With Vulkan, this warning would sometimes be a false positive. It could
trigger for internal samplers like `ssao` and `structure`, even though
they were not declared in SPIR-V.

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

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

At some point I think we should consider adding `spirv-reflect` to our
tree to help with problems like this.
2020-11-12 16:21:13 -08:00
Philip Rideout
99c5fc7388 Improve the "unbound texture" warnings.
With Vulkan, this warning would sometimes be a false positive. It could
trigger for internal samplers like `ssao` and `structure`, even though
they were not declared in SPIR-V.

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

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

At some point I think we should consider adding `spirv-reflect` to our
tree to help with problems like this.
2020-11-12 16:02:32 -08:00
Ben Doherty
90c156ebef Add fog variant filter to matc (#3286) 2020-11-12 12:47:42 -08:00
Ben Doherty
2df02d81d3 Add setFrameCompletedCallback JNI binding (#3275) 2020-11-12 12:24:41 -08:00
Ben Doherty
8019b11589 Update glslang and friends (#3277) 2020-11-12 12:23:51 -08:00
Philip Rideout
cc51726590 Vulkan: improve robustness by providing 1x1 fallback. 2020-11-12 10:36:13 -08:00
Philip Rideout
16454e0de6 Vulkan: improve robustness by providing 1x1 fallback. 2020-11-12 10:35:50 -08:00
Philip Rideout
318e22af51 Fix clear behavior with RenderTarget API.
This fixes a bug seen with client applications that use ClearOptions
instead of Skybox, and one or more offscreen RenderTarget objects.
These apps would see junk pixels because Filament would only clear the
first render target in the frame.

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

I wrote a simple C++ demo to reproduce the issue and to verify that
this fix works.
2020-11-11 09:25:36 -08:00
Philip Rideout
3bf934f5d7 Fix clear behavior with RenderTarget API.
This fixes a bug seen with client applications that use ClearOptions
instead of Skybox, and one or more offscreen RenderTarget objects.
These apps would see junk pixels because Filament would only clear the
first render target in the frame.

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

I wrote a simple C++ demo to reproduce the issue and to verify that
this fix works.
2020-11-11 09:25:07 -08:00
Philip Rideout
68ac87dc24 NOOP backend should not care about GLSL vs SPIRV.
This fixes errors that would occur when using the NOOP backend with
materials that were built without OpenGL support.
2020-11-10 15:44:01 -08:00
Ben Doherty
b4a6d0a83e Add callback API to SwapChain (#3270) 2020-11-10 14:52:04 -08:00
Ben Doherty
a09037cec0 Revert "macOS: fix headless rendering." (#3273) 2020-11-10 12:02:12 -08:00
Philip Rideout
50a61984ec NOOP backend should not care about GLSL vs SPIRV.
This fixes errors that would occur when using the NOOP backend with
materials that were built without OpenGL support.
2020-11-09 11:11:12 -08:00
Romain Guy
6486eba7e2 Fix typo in docs 2020-11-09 09:37:10 -08:00
Benjamin Doherty
acb8f00075 Bump version to 1.9.9 2020-11-09 09:32:55 -08:00
Benjamin Doherty
06d9183aaa Merge branch 'rc/1.9.8' into release 2020-11-09 09:28:58 -08:00
Benjamin Doherty
c92d13c0c9 Update RELEASE_NOTES for 1.9.8 2020-11-09 09:28:15 -08:00
Benjamin Doherty
bd9aba35f6 Release Filament 1.9.8 2020-11-09 09:27:06 -08:00
Benjamin Doherty
75af25419d Update RELEASE_NOTES for 1.9.8 2020-11-09 09:26:27 -08:00
Benjamin Doherty
f6b90d2a31 Bump version to 1.9.8 2020-11-09 09:21:36 -08:00
Philip Rideout
7fbd00e59b Repair Windows build, maybe. 2020-11-09 08:35:43 -08:00
Philip Rideout
f814138f83 Regenerate BlueVK, use a C++ namespace.
This moves all Vulkan entry points into the bluevk namespace
to avoid conflicts with other Vulkan loaders.

This also updates the header files and loader code to version 1.2.159 of
the Vulkan spec, which is currently available at the following links.

https://khronos.org/registry/vulkan/specs/1.2/html/vkspec.html
87451c55aa
2020-11-09 08:35:43 -08:00
Philip Rideout
96d3f2f16b More fixes for signed integer overflow.
Fence.cpp:

My previous fix to the fix was insufficient because a signed integer
overflow could still occur as follows (this was observed in an internal
test at Google).

If the conditional on line 87 is true, then a clamped value is passed
into `wait`, which causes the conditional on line 133 to fail, which
causes `wait_for` to be called inappropriately, which is where an
overflow would occur.

MetalHandles.mm:

This is more theoretical, but to prevent potential integer overflow
within STL, I think we should call `wait()` rather than `wait_for()`
when an infinite timeout is desired.

This is our fourth fix to fences in since November 2; see also dcca236,
e9c9e45, and 8969416.  :)
2020-11-09 08:35:17 -08:00
Philip Rideout
89694168a6 Another fix for FENCE_WAIT_FOR_EVER.
FFence::wait() has some logic that tests if "timeout" is equal to
FENCE_WAIT_FOR_EVER, which is actually impossible because it would
be modified by the clamp in this situation.

In practice I think this oversight would not cause any problems. I
noticed it while reviewing the code.

To recap why the clamp exists: according to the ISO C++ spec, the
"nanoseconds" duration in chrono is at least a signed 64-bit type, but
our sentinel constant might not (and does not) fit within this range.
2020-11-05 17:24:44 -08:00
Romain Guy
63d5698a78 Update Gradle, AGP, and other dependencies (#3257)
* Update Gradle and AGP

* Update other dependencies
2020-11-05 10:47:12 -08:00
Romain Guy
24ca2bf181 Fix JNI binding 2020-11-04 13:01:16 -08:00
Ben Doherty
f37a3e9497 Support CVPixelBuffer SwapChains with Metal (#3251) 2020-11-04 11:05:45 -07:00
Ben Doherty
90ad9b457a Implement copyFrame for Metal (#3249) 2020-11-03 12:25:29 -07:00
Ben Doherty
30f5a97ea1 Consolidate surface-related functionality into MetalSwapChain (#3246) 2020-11-03 12:00:03 -07:00
Philip Rideout
964a1bd7f2 BlueVK: improved error messaging. 2020-11-03 10:23:06 -08:00
Philip Rideout
a3822f4af0 Fix FENCE_WAIT_FOR_EVER in Linux.
The number of infinite nanoseconds was negative because we asked
chrono for a signed integer, so "wait forever" really meant "do not
wait at all".
2020-11-02 16:12:53 -08:00
Philip Rideout
e9c9e45ac9 Fix FENCE_WAIT_FOR_EVER in Linux.
The number of infinite nanoseconds was negative because we asked
chrono for a signed integer, so "wait forever" really meant "do not
wait at all".
2020-11-02 16:02:27 -08:00
Philip Rideout
fb831dec0a Vulkan: adjust usage flags to allow DEPTH blits. 2020-11-02 11:00:57 -08:00
Benjamin Doherty
bcdad769ff Merge branch 'rc/1.9.7' into release 2020-11-02 11:03:57 -07:00
Benjamin Doherty
dc1c5529c0 Update RELEASE_NOTES for 1.9.7 2020-11-02 11:00:55 -07:00
Benjamin Doherty
8b8d563b0f Bump version to 1.9.7 2020-11-02 11:00:09 -07:00
Benjamin Doherty
be4fb4fdbb Update RELEASE_NOTES for 1.9.7 2020-11-02 10:59:19 -07:00
Ben Doherty
dcca236f60 Fix bug with Fence timeouts (#3243) 2020-11-02 10:47:28 -07:00
Philip Rideout
70dba2398e gltfio: add createInstance() to AssetLoader.
Note that this API is on the loader rather than the asset. This is
because the loader knows how to create Filament entities by traversing
a cgltf node hierarchy.

Animation on dynamically added instances is not yet supported.

We did not add destroyInstance() because gltfio favors flat arrays for
long term storage of entity lists and instance lists, which would be
slow to shift. We also wish to discourage create/destroy churn since it
is more efficient to pre-allocate instances and selectively add them
into the scene.

Fixes #3137.
2020-11-02 09:47:14 -08:00
Philip Rideout
47521d70a1 gltfio: fix ASAN issue when consuming invalid animation.
Release builds do not call cgltf_validate() so it was possible to
read out-of-bounds animation data when encountering a badly formed glTF
file with mismatched counts between sampler inputs and outputs.
2020-10-31 15:17:15 -07:00
Philip Rideout
468992f4cd gltfio: do not segfault on invalid primitives. 2020-10-31 13:28:13 -07:00
Philip Rideout
0db7057983 Vulkan: disable unreliable blit diagnostics. 2020-10-31 12:37:42 -07:00
Philip Rideout
8a63834607 Vulkan: fix layout mismatch after blitting to swap chain. 2020-10-31 12:37:42 -07:00
Philip Rideout
4e4d4f9ee3 Vulkan: add blit support for depth and MRT. 2020-10-31 10:29:25 -07:00
Philip Rideout
6abef94d95 mathio: add ostream operator for quaternions. 2020-10-29 17:04:03 -07:00
Philip Rideout
4b1c557bb1 Vulkan: fix color attachment list in first subpass.
This fixes a slew of validation warnings and errors seen when multiple
subpasses are enabled, starting with:

    Attachment 1 not written by fragment shader; undefined values will
    be written to attachment

The Vulkan driver was using the same color attachment list for both
subpasses, so the first subpass had unused attachments.

Note that Vulkan makes a distinction between color attachments and input
attachments and requires separate lists to be supplied for each subpass,
but our Driver API consolidates everything into a single list. This
should perhaps be refactored at a later date.
2020-10-29 15:03:34 -07:00
Philip Rideout
94a1eb27b4 Do not declare unused fragColor in GLSL.
This fixes a Vulkan validation warning when building a pipeline that
does not have a color attachment.
2020-10-29 11:08:13 -07:00
Philip Rideout
a9754273b0 Vulkan: minor fix for diagnostic output. 2020-10-28 15:41:07 -07:00
Philip Rideout
2fe4f6cbe7 AutomationEngine: fix regression with screenshots. 2020-10-28 12:58:54 -07:00
Philip Rideout
1159435d47 gltfio: add safety checks to getAnimator. 2020-10-28 11:51:06 -07:00
Philip Rideout
a6f364e0f3 gltfio: fix segfault when consuming invalid file. 2020-10-28 11:50:54 -07:00
Philip Rideout
c6942a52e6 gltfio: refactor the instancing cache.
This prepares for #3137 by moving the mesh cache and material instance
cache out of the loader (where they were transient anyway) and into the
actual asset. This paves the way for a `createInstance()` API.
2020-10-27 10:30:18 -07:00
Philip Rideout
c65dc99771 Fix colorGradingAsSubpass when dithering is off.
This fixes the blank screen seen with Vulkan when all view options are
disabled.
2020-10-26 15:33:42 -07:00
Benjamin Doherty
65394f6301 Bump version to 1.9.7 2020-10-26 11:34:20 -06:00
Benjamin Doherty
b0beee03bc Merge branch 'rc/1.9.6' into release 2020-10-26 11:29:45 -06:00
Benjamin Doherty
6971b3b6b0 Update RELEASE_NOTES for 1.9.6 2020-10-26 11:28:06 -06:00
Benjamin Doherty
4270384661 Bump version to 1.9.6 2020-10-26 11:27:08 -06:00
Benjamin Doherty
fe1de41b8e Update RELEASE_NOTES for 1.9.6 2020-10-26 11:25:31 -06:00
Philip Rideout
82cb13936c Vulkan: warn instead of panic for sampler overflow.
This makes behavior in release builds similar to the OpenGL backend.

In debug builds, we will still assert.
2020-10-23 11:11:35 -07:00
Philip Rideout
212b64ea5f Vulkan: make ReadPixels synchronous.
This makes it so that the PixelBufferDescriptor callback triggers at a
time consistent with other backends.

ReadPixels is still asynchronous in the sense that the callback is
triggered on the main thread. However, it is now guaranteed to trigger
during (or before) flushAndWait(), which is less surprising behavior.
2020-10-22 17:42:07 -07:00
Philip Rideout
2849dc6a2a Fix iOS build break. 2020-10-22 17:03:06 -07:00
Philip Rideout
d84bb82e44 Merge duplicated implementations of toLinear(). 2020-10-22 17:03:06 -07:00
Philip Rideout
5746532b7c Add PNG output to test_ReadPixels. 2020-10-22 17:03:06 -07:00
Philip Rideout
2e10fe6680 PlatformVkLinux now supports all combos of XLIB and XCB.
You can now build Filament with support for both X11 APIs, or neither.
If both are supported, run-time selection is achieved using a SwapChain
flag.

Supporting only one API at build time (or neither) is useful because our
list of "required" VkInstance extensions can vary according to which
API's are supported. During VkInstance creation, we do not have a priori
knowledge about what kinds of swap chains will be created. (headless vs
non-headless, XCB vs XLIB, etc)

Note that some Vulkan implementation (e.g. some builds of SwiftShader)
only support XCB.
2020-10-22 16:55:25 -07:00
Philip Rideout
f55c9ee437 Fix Windows build. 2020-10-22 13:08:09 -07:00
Philip Rideout
06e639ae91 Vulkan: fix destroy-while-used for UBOs. 2020-10-22 11:43:16 -07:00
Philip Rideout
8de19cb582 Vulkan: fix leak with headless swap chain. 2020-10-22 11:43:16 -07:00
Philip Rideout
47b1ece804 Vulkan: Improve refcounting for vertex buffers.
This avoids the following validation error when clients create then
immediately destroy vertex buffers, index buffers, and uniform buffers.

        VUID-vkDestroyBuffer-buffer-00922

        Cannot free VkBuffer that is in use by a command buffer.

Buffers that are used across multiple frames were fine, but
create-and-destroy scenarios were problematic.
2020-10-22 11:39:57 -07:00
Philip Rideout
d47189536f Vulkan: fix thread safety regression in Disposer.
This fixes a regression introduced by 548b28c6e manifesting as
intermittent assertions. The VulkanDisposer gc() should only be called
from the driver thread.
2020-10-22 11:39:46 -07:00
dsternfeld7
4533a42a6f Makes it possible to have multiple instances of ImGuiHelper at the same time
This change fixes an issue where ImGuiHelper would crash on destruction if you created more than one instance at the same time.

This crash occurred when ImGui::DestroyContext() was called, because when the second instance was destroyed there was no current context causing it to crash.

This fixes it by making ImGuiHelper store and manage it's own context.

Having two instances of ImGuiHelper is useful in cases where you want to use imgui with multiple views.
2020-10-22 11:39:33 -07:00
Philip Rideout
853247f32f Vulkan: ReadPixels y-flip workaround. 2020-10-21 17:42:46 -07:00
Philip Rideout
5f6cbc779a Allow test_ReadPixels with SwiftShader. 2020-10-21 16:24:27 -07:00
Philip Rideout
548b28c6e2 Vulkan: improve the ReadPixels implementation.
This adds support for more format conversions and removes a bogus
assert that prevented ReadPixels within beginFrame / endFrame.
This was tested with:

    backend_test_mac --api vulkan --gtest_filter=BackendTest.ReadPixels
2020-10-21 16:04:31 -07:00
Ben Doherty
239246e221 Add ability to specify post-process material output location (#3205) 2020-10-21 12:19:46 -06:00
Philip Rideout
75c4f36f96 Add Dockerfile and test script for SwiftShader.
This adds a Dockerfile and a new bash script that makes it
east to invoke the appopriate Docker commands.

This does not yet enable a GitHub Action because of intermittent
issues that we have not yet ironed out.
2020-10-21 10:50:25 -07:00
Philip Rideout
7260bab7b3 Fix TypeScript binding for TextureUsage. 2020-10-20 14:09:05 -07:00
Ben Doherty
e7250571e7 Add subpass parameter type to materials (#3193) 2020-10-19 16:28:26 -06:00
Philip Rideout
c68d0a4e46 Vulkan: add missing field to VmaVulkanFunctions. 2020-10-19 11:57:37 -07:00
Benjamin Doherty
a37b431e87 Bump version to 1.9.6 2020-10-19 11:55:13 -06:00
Benjamin Doherty
98107016b9 Merge branch 'rc/1.9.5' into release 2020-10-19 11:51:30 -06:00
Benjamin Doherty
37d080dfd1 Update RELEASE_NOTES for 1.9.5 2020-10-19 11:50:54 -06:00
Benjamin Doherty
de75b9d125 Bump version to 1.9.5 2020-10-19 11:49:57 -06:00
Benjamin Doherty
8bccfc2863 Update RELEASE_NOTES for 1.9.5 2020-10-19 11:49:05 -06:00
Philip Rideout
07fd883f9a Vulkan + Android: fix build break.
Fixes #3200.
2020-10-19 09:36:12 -07:00
Philip Rideout
5ceb9fc5d5 Add optional XCB support to PlatformVkLinux.
This allows clients to build the Vulkan backend with either XLIB or XCB
support. I did a quick smoke test of the XCB option, but for now we are
continuing to default to XLIB. Note that the native window type used to
create the swap chain differs between these two API's.
2020-10-19 09:24:13 -07:00
Ben Doherty
d14ba856a7 matc: fix some compilation failures still exit with code 0 (#3192) 2020-10-15 14:11:46 -06:00
Ben Doherty
7eec70276e Add release scripts and RELEASE_GUIDE (#3191) 2020-10-15 12:57:38 -06:00
Ben Doherty
4f58a7e5fb Fix Vulkan black screen on Windows with NVIDIA hardware (#3190) 2020-10-15 12:00:42 -06:00
Ben Doherty
30565a5afc Add capture frame button to gltf_viewer (#3189) 2020-10-14 12:43:05 -06:00
Ben Doherty
62d06592d3 VSM: add support for mipmaps and anisotropic sampling (#3185) 2020-10-14 11:48:23 -06:00
Benjamin Doherty
e74e583b97 Fix CocoaPod version 2020-10-13 15:16:25 -06:00
Benjamin Doherty
f54a0a3452 Fix CocoaPod version 2020-10-13 15:15:02 -06:00
Benjamin Doherty
6778ab0624 Fix CocoaPod version 2020-10-13 15:09:59 -06:00
Philip Rideout
37768ed9e1 Various changes to help clients upgrade Filament.
The non-const getSkybox() method is especially useful to client code
that needs to change the clear color, but does not have direct
access to the Renderer object.
2020-10-13 10:10:59 -07:00
Philip Rideout
20abfec7d3 Minor change to adhere to CODE_STYLE. 2020-10-12 11:15:45 -07:00
Benjamin Doherty
269d636785 Bump version to 1.9.5 2020-10-12 12:03:29 -06:00
Benjamin Doherty
39862c91ce Merge branch 'rc/1.9.4' into release 2020-10-12 11:56:24 -06:00
Benjamin Doherty
03df97d0e3 Update RELEASE_NOTES for 1.9.4 2020-10-12 11:55:39 -06:00
Benjamin Doherty
40e10817dd Bump version to 1.9.4 2020-10-12 11:52:49 -06:00
Benjamin Doherty
523f4026b4 Update RELEASE_NOTES for 1.9.4 2020-10-12 11:52:01 -06:00
Philip Rideout
b82dca4fac JobSystem: work around hang on 2-CPU machines
If hardware_concurrency() returned 2 while UTILS_HAS_HYPER_THREADING was
enabled, `mThreadCount` was resulting in zero, so jobs (such as texture
decoding) would simply never start. This problem was noticed with
GitHub Actions.

I tested this fix locally by replacing `hardware_concurrency()` with
fixed values like 1 or 2, and verified that the hang went away.
2020-10-09 16:14:50 -07:00
Philip Rideout
5ebc6bce04 Add schema for automation specs.
This can help when authoring a spec using your favorite text editor.
2020-10-09 10:23:27 -07:00
Benjamin Doherty
a6bf162431 Bump version to 1.9.4 2020-10-07 16:06:23 -06:00
Ben Doherty
bd625e42e9 Fix Vulkan crash when using shadow cascades (#3172) 2020-10-07 15:36:45 -06:00
Philip Rideout
7471237178 Linux fixes for headless SwiftShader. 2020-10-07 11:24:33 -07:00
Ben Doherty
52698aab14 Destroy dummyOneTextureArray in PostProcessManager (#3171)
* Destroy dummyOneTextureArray in PostProcessManager

Fixes #3166

* Update RELEASE_NOTES.md
2020-10-07 12:19:02 -06:00
Philip Rideout
3d121eb873 Vulkan ReadPixels: fix platforms that use BGRA.
Fixes a color issue seen with SwiftShader in non-headless mode.
2020-10-06 15:22:14 -07:00
Ben Doherty
1dd7b06e6f Fix null pointer dereference in FIndirectLight (#3163) 2020-10-06 15:27:28 -06:00
Philip Rideout
d2ca1c79d2 Fix Windows build by avoiding nested initializers.
Note that designated initializers are technically a C++20 feature so we
should not be using them. However they are really nice for Vulkan code.
2020-10-06 13:45:26 -07:00
Philip Rideout
52913e685e Vulkan: support readPixels and headless swap chains.
This adds support for headless rendering as well as readPixels. These
features are necessary for automated testing.

NOTE: invoking readPixels with a non-headless SwapChain seems to fail
with MoltenVK. I will investigate this later.
2020-10-06 13:45:26 -07:00
Benjamin Doherty
f30332b12b Fix RELEASE_NOTES 2020-10-06 11:17:30 -06:00
Ben Doherty
f31eb09ca0 Add Live Wallpaper Android sample (#3161) 2020-10-06 11:03:55 -06:00
Ben Doherty
0bec65701a VSM: render both shadow casters and receivers (#3147) 2020-10-05 17:03:10 -06:00
Ben Doherty
59ef044ce0 Add support to UiHelper for SurfaceHolder (#3155) 2020-10-05 12:04:05 -06:00
Benjamin Doherty
826e8d181c Merge branch 'rc/1.9.3' into release 2020-10-05 11:36:16 -06:00
Benjamin Doherty
76f1e91fd2 Update RELEASE_NOTES for 1.9.3 2020-10-05 11:35:44 -06:00
Benjamin Doherty
d72d3533e6 Bump version to 1.9.3 2020-10-05 11:34:19 -06:00
Benjamin Doherty
16dfadbba0 Update RELEASE_NOTES for 1.9.3 2020-10-05 11:29:36 -06:00
Yixing Lao
9ce2c319a9 ARM64 support for bluegl (#3150)
* ARM64 support for bluegl

* Detect arch with uname

* Use register x16
2020-10-05 10:19:05 -07:00
Philip Rideout
4fe5832333 gltf_viewer: add --headless option.
This should only be used in combination with --batch. Users are
admonished if they try using it on its own.
2020-10-04 10:02:10 -07:00
Philip Rideout
79f1744823 Automation: fix segfault when closing the app early.
The Filament View that gets passed to tick() is retained briefly when
screenshots are enabled, but it may be destroyed by the time the
PixelBufferDescriptor callback is invoked. So, we needed a way of
notifying the AutomationEngine.
2020-10-04 10:01:43 -07:00
Philip Rideout
e352542e24 Automation: add support for materials.
This adds a `material` key to `Settings`, as a sister to `view`.

Here's an example of an automation spec that manipulates material
parameters:

    [{
      "name": "metallic_vs_roughness",
      "permute": {
          "material.scalar.roughnessFactor": [0.0, 0.5, 1.0],
          "material.scalar.metallicFactor": [0.0, 1.0]
      }
    }]

Currently this is limited to float, vec3, and vec4 parameters.
2020-10-02 11:57:23 -07:00
Philip Rideout
5938242d61 gltf_viewer: Add automation UI and functionality.
This adds `AutomationEngine` to libs/viewer, which iterates through
`Settings` instances that were generated from a JSON spec and applies
them to a Filament `View`. It can be configured to sleep between tests
using a time delay or a frame count.

This also adds command line arguments and user-interface elements to
`gltf_viewer` for automated testing.
2020-10-02 11:00:26 -07:00
Philip Rideout
cfddd5b273 Rename AutomationList to AutomationSpec. 2020-10-01 19:07:24 -07:00
Philip Rideout
8a865e531e gltf_viewer: minor refactoring 2020-10-01 17:15:25 -07:00
Philip Rideout
d05fb52ebf gltf_viewer: use integers for Temperature / Tint. 2020-10-01 16:41:24 -07:00
Philip Rideout
fd142b9b84 gltf_viewer: add --settings, prep for automation. 2020-10-01 16:41:24 -07:00
Philip Rideout
6658283617 FilamentApp: Do not call postRender when skipping. 2020-10-01 16:41:24 -07:00
Pixelflinger
8b3caeffb9 ssct: decouple shadow distance from sample count 2020-10-01 10:20:38 -07:00
Philip Rideout
5fae33bde5 Automation: simplify API by flattening the test cases. 2020-09-30 16:17:23 -07:00
Philip Rideout
43cc5f9906 Automation: add a built-in default spec. 2020-09-30 16:17:23 -07:00
Philip Rideout
902eb32e3c Fix typo in copyright headers. 2020-09-30 16:17:23 -07:00
Philip Rideout
08f7973d0c Refactor Automation API. 2020-09-30 16:17:23 -07:00
Philip Rideout
a736b8b018 Rename parse.h to jsonParseUtils. 2020-09-30 16:17:23 -07:00
Philip Rideout
094e7169cc Introduce a configurable test case generator.
This lets us generate long lists of settings permutations by writing a
simple JSON spec. For example, the following spec would generate six
`Settings` objects, all of which have SSAO enabled. See the unit test
for a larger example.

```
{
    "name": "viewopts",
    "base": { "view.ssao.enabled": true }
    "permute": {
        "view.dithering": ["NONE", "TEMPORAL"],
        "view.sampleCount": [1, 4, 8]
    }
}
```
2020-09-30 16:17:23 -07:00
Ben Doherty
44d4694c29 Add JNI binding for vsm msaa samples (#3139) 2020-09-30 16:12:45 -06:00
Ben Doherty
42862ddcde Fix RELEASE_NOTES 2020-09-30 14:53:01 -06:00
Ben Doherty
236ed9680c Add MSAA option to VSM (#3084) 2020-09-30 14:51:40 -06:00
Ben Doherty
229fdc9be5 Add View::setShadowType JNI binding (#3094) 2020-09-30 13:20:39 -06:00
Ben Doherty
4af0cdfd4d Use light space Z as VSM depth metric (#3131) 2020-09-30 12:31:03 -06:00
Philip Rideout
451fac7d7b Fix writeJson() for vectors and enums. 2020-09-30 11:12:10 -07:00
Philip Rideout
617dc932bb Fix unit test failure. 2020-09-29 19:59:53 -07:00
Pixelflinger
583c1c07cf SSCT optimizations and fixes
- Use lower depth LOD as the cone radius increases.
  This is the same technique we use for SAO.
  The better cache access significantly improve performance.
  On a test on Pixel4 at 585MHz, SAO pass improves by 30%.
  This also helps the algorithm scale with the shadow distance.

- Shadow direction/length no longer dependent on aspect-ratio and camera
  orientation.
  This is fixed by doing all the computations in screen-space instead of 
  normalized screen space.

- Shadow parameters are no longer dependent on the field of view.

- Also rename dominantLightShadowing.fs to ssct.fs

- remove zoom parameter, it wasn't very useful.
2020-09-29 17:00:32 -07:00
Benjamin Doherty
9e01348dd5 Fix CocoaPod Podspec for Xcode 12 2020-09-29 12:25:13 -06:00
Philip Rideout
ec2579bad5 Viewer Settings: remove SSCT scale. 2020-09-29 10:47:35 -07:00
Philip Rideout
e5a9a259de Fix build break. 2020-09-29 10:47:35 -07:00
Philip Rideout
6472f645fc viewer: add SCCT to JSON serializer. 2020-09-29 10:47:35 -07:00
Philip Rideout
e9ace4e5fb Add jsmn to third_party. 2020-09-29 10:47:35 -07:00
Philip Rideout
c119f9bdca gltf_viewer: Re-use ViewSettings structs. 2020-09-29 10:47:35 -07:00
Philip Rideout
7997e4aa21 Introduce libs/viewer and serializable view settings.
This introduces the `viewer::Settings` struct, and a JSON reader /
writer.

This will be used for automated testing and for client / server
communication.

Note that `viewer::Settings` is closely associated with the
`filament::View` API; when updating the latter we will often need to
update the former, as well as some serialization code. This increases
the maintenance burden and I think we should consider using a parser
library like libclang or a macro-based reflection utility.

This PR also migrates SimpleViewer into libs/viewer and un-inlines its
implementation. It does not belong in gltfio because it has an imgui
dependency.
2020-09-29 10:47:35 -07:00
Pixelflinger
cdb0f20c6c Save some ALU by assuming the shape of the projection matrix 2020-09-28 10:53:30 -07:00
Pixelflinger
4da58ecb29 Fix mediump issue on mobile 2020-09-28 10:53:30 -07:00
Pixelflinger
075486724f Add JNI support for SSCT 2020-09-28 10:53:30 -07:00
Pixelflinger
530f41c29c fix light vector transform 2020-09-28 10:53:30 -07:00
Pixelflinger
5cbd80136c control the number of rays per pixel 2020-09-28 10:53:30 -07:00
Pixelflinger
bfd1de809a Implement screen space cone tracing (SSCT)
This is a technique from Naughty Dog used in TLOU2, where we compute
the "ambient" shadowing of a dominant light in screen-space.

This is currently integrated to the SSAO pass.
2020-09-28 10:53:30 -07:00
Pixelflinger
0f2993aec7 Decouple SSAO bilateral filter from quality setting 2020-09-28 10:53:30 -07:00
Pixelflinger
e8bb895c58 refactor SSAO shader a bit
the main change here is that we now have ssaoUtils which contains
utilities that will soon be shared with other "ambiant" effects.
2020-09-28 10:53:30 -07:00
Benjamin Doherty
5cbb97551f Bump version to 1.9.3 2020-09-28 11:40:31 -06:00
Benjamin Doherty
f7fc2a0af6 Update RELEASE_NOTES for 1.9.2 2020-09-28 11:34:32 -06:00
Benjamin Doherty
42733c10b7 Bump version to 1.9.2 2020-09-28 11:34:32 -06:00
Philip Rideout
d8c7bba403 gltfio: Fix animation by clamping the per-channel interpolant.
Tested with the model in #3124 as well as Fox, BusterDrone, CesiumMan,
InterpolationTest, and VC.

Fixes #3124.
2020-09-26 09:26:40 -07:00
Romain Guy
50e5db4347 Add tasks to manage Sonatype releases (#3127)
* Add tasks to manage Sonatype releases

* Edit comments
2020-09-25 16:07:12 -07:00
Philip Rideout
7019629bcb Vulkan: fix final image barrier used for swap chain.
The image barrier must wait until all write operations are complete;
this was not set up correctly but somehow did not cause problems.
Also tried to document this better, since using an image barrier for
the swap chain seems to be an unusual thing to do (e.g. the Sascha
Willems demos do not do this).
2020-09-25 09:40:12 -07:00
Philip Rideout
5549adc020 JavaScript bindings: fix TextureUsage bitmask.
There's no really good solution, so this just keeps it simple and makes
is so that embind consumes an integer rather than an embind enum object.

Tested by hacking _createTextureFromImageFile.

Fixes #3028.
2020-09-24 15:53:20 -07:00
Philip Rideout
947d178f2b matdbg: stable ordering for anonymous materials.
For example, this makes it so that the primary material in Sponza
is *always* "untitled 0", which makes it easier to figure out which
material to modify.
2020-09-24 10:23:58 -07:00
Philip Rideout
29cd7bb6b4 matdbg: use Shift+Ctrl for navigation.
This avoids interference with both the default VSCode bindings and
Mission Control.
2020-09-24 09:54:19 -07:00
Philip Rideout
eb5d346e60 matdbg: repair keyboard navigation.
Recall that Ctrl + Up / Down navigates between materials while
Left / Right navigates between variants.

- Make this behavior more explicit in the documentation.
- Shortcuts now use the same ordering as the displayed list.
- Shortcuts now use Cmd on macOS instead of Ctrl to avoid conflict with
  Mission Control defaults.
2020-09-24 09:54:19 -07:00
Philip Rideout
1afb0e2ea4 matdbg: allow edits without trailing newline. 2020-09-24 09:54:11 -07:00
Philip Rideout
89485ae0ae matdbg: fix edits for large shaders.
If the websocket message exceeds a certain size, we might receive it
in chunks and civetweb does not auto-consolidate for us.

Fixed this by adding a length prefix to the edit command.
2020-09-24 09:53:59 -07:00
Philip Rideout
92e1e91261 matdbg: warn user when editing unused variant. 2020-09-24 09:53:59 -07:00
Philip Rideout
ac07719414 CString should allow arbitrary data. 2020-09-24 09:53:59 -07:00
Philip Rideout
4a604c2513 matdbg: do not hide anonymous materials
This change also makes it so that matdbg shows a numeric suffix to help
with duplicated names, and fixes a bug with names that start with
non-alpha characters.
2020-09-23 16:03:03 -07:00
Philip Rideout
22312b2090 cmgen / mipgen: add opt-in for ASTC / ETC support.
Block compression is currently only used when we invoke mipgen for the
suzanne demo. This PR makes it easy to disable.

Block compression is still enabled in our CMake build, but other build
systems can simply omit BlockCompression.{h,cpp} from imageio (as well
as the two third_party libs) and it will "just work".
2020-09-23 11:17:27 -07:00
Philip Rideout
1ebdb18eae gltfio: add async cancellation API 2020-09-23 10:53:55 -07:00
Philip Rideout
450fe214f9 Flip the shading normal when det < 0.
This was tested by replacing the node 0 scale in BusterDrone with
[-1, 1, 1].

For future reference, commit f728776 shows when we switched from
transpose(inverse()) to cof(). This was a good change, but before that
particular change, we had a "two wrongs made a right" situation for
mirrored normals.

Fixes #3001.
2020-09-22 16:54:44 -07:00
Philip Rideout
97c1f99cab gltfio: Fix "uniform not found" errors.
The equality operator for MaterialKey was missing some fields (also, its
ordering was inconsistent with the struct), which caused faulty behavior
in the material cache.

I ran into this bug when testing against a Blender-exported model that
has some materials with texture transforms, and some without.
2020-09-22 14:12:47 -07:00
Romain Guy
9830925a96 Disable clear coat layer IOR change in glTF files (#3104)
The glTF spec doesn't call for this and there are extensions
to deal with this manually.
2020-09-21 20:40:35 -07:00
Pixelflinger
c3975f2640 APIs to enable/disable screen space refraction
Just like with shadows, this is a toggle to entirely disable
screen space refraction.

Added missing getters, and minor refactoring.
2020-09-21 16:30:56 -07:00
Pixelflinger
6c8e134d01 Random engine should be owned by Engine
This way it can be used elsewhere.
2020-09-21 11:01:58 -07:00
Benjamin Doherty
a0fb396ba4 Update RELEASE_NOTES headings 2020-09-21 11:08:57 -06:00
2325 changed files with 321251 additions and 51181 deletions

4
.gitignore vendored
View File

@@ -12,3 +12,7 @@ filament/docs/html/**
*tmp*.png
civetweb.txt
/TAGS
settings.json
test*.png
test*.json
results

View File

@@ -27,55 +27,3 @@ Bugs are defined as one of the following _introduced since the prior release_:
- unintentional public API changes
For example, a long-standing crash just recently discovered would not necessitate a bug fix PR.
## Creating a GitHub Release
Be sure to choose the *release* branch when drafting a GitHub release.
## Git Commands
These commands assume a release candidate branch called *rc/1.9.0*.
### Creating a Release Candidate Branch
```
$ git checkout main
$ git pull
$ git branch rc/1.9.0
$ git push origin rc/1.9.0
```
### Merging the Release Candidate Branch Into Release
There may be temporary hotfixes in the release branch that should be overriden by the new release
candidate. To accomplish this, we first merge release into rc using the _ours_ strategy. Then we
merge rc into release.
```
$ git checkout rc/1.9.0
$ git pull
$ git fetch origin release:release
$ git merge -s ours release
$ git checkout release
$ git merge --no-ff rc/1.9.0
$ git push origin release
```
### Deleting the Release Candidate Branch
```
$ git branch -d rc/1.9.0
$ git push origin --delete rc/1.9.0
```
### See a History of the Release Branch
```
$ git log --oneline --first-parent
442b061 (HEAD -> release) Merge branch 'rc/1.9.2' into release
ac50d21 Hotfix
94dc2f7 Hotfix
b34ed5b Merge branch 'rc/1.9.1' into release
aeef498 Merge branch 'rc/1.9.0' into release
```

View File

@@ -17,9 +17,9 @@ section below.
To build Filament for Android you must also install the following:
- Android Studio 4.0.1 or more recent
- Android Studio 4.1.0 or more recent
- Android SDK
- Android NDK "side-by-side" 21.3 or higher
- Android NDK "side-by-side" 22.0 or higher
### Environment variables
@@ -375,7 +375,7 @@ same version that our continuous builds use.
```
cd <your chosen parent folder for the emscripten SDK>
curl -L https://github.com/emscripten-core/emsdk/archive/1.39.19.zip > emsdk.zip
curl -L https://github.com/emscripten-core/emsdk/archive/2.0.12.zip > emsdk.zip
unzip emsdk.zip ; mv emsdk-* emsdk ; cd emsdk
python ./emsdk.py install latest
python ./emsdk.py activate latest
@@ -468,3 +468,19 @@ export SWIFTSHADER_LD_LIBRARY_PATH=`pwd`
```
Next, go to your Filament repo and use the [easy build](#easy-build) script with `-t`.
## SwiftShader for CI
Continuous testing turnaround can be quite slow if you need to build SwiftShader from scratch, so we
provide an Ubuntu-based Docker image that has it already built. The Docker image also includes
everything necessary for building Filament. You can fetch and run the image as follows:
```
docker pull ghcr.io/filament-assets/swiftshader
docker run -it ghcr.io/filament-assets/swiftshader
```
To do more with the container, see the helper script at `build/swiftshader/test.sh`.
If you are a team member, you can update the public image to the latest SwiftShader by
following the instructions at the top of `build/swiftshader/Dockerfile`.

View File

@@ -21,6 +21,10 @@ option(FILAMENT_ENABLE_LTO "Enable link-time optimizations if supported by the c
option(FILAMENT_SKIP_SAMPLES "Don't build samples" OFF)
option(FILAMENT_SUPPORTS_XCB "Include XCB support in Linux builds" ON)
option(FILAMENT_SUPPORTS_XLIB "Include XLIB support in Linux builds" ON)
set(FILAMENT_PER_RENDER_PASS_ARENA_SIZE_IN_MB "2" CACHE STRING
"Per render pass arena size. Must be roughly 1 MB larger than FILAMENT_PER_FRAME_COMMANDS_SIZE_IN_MB, default 2."
)
@@ -83,6 +87,16 @@ if (UNIX AND NOT APPLE AND NOT ANDROID AND NOT WEBGL)
set(LINUX TRUE)
endif()
if (LINUX)
if (FILAMENT_SUPPORTS_XCB)
add_definitions(-DFILAMENT_SUPPORTS_XCB)
endif()
if (FILAMENT_SUPPORTS_XLIB)
add_definitions(-DFILAMENT_SUPPORTS_XLIB)
endif()
endif()
if (ANDROID OR WEBGL OR IOS)
set(IS_MOBILE_TARGET TRUE)
endif()
@@ -248,7 +262,10 @@ if (LINUX)
# /usr/bin/ld: ../bluegl/libbluegl.a(BlueGL.cpp.o): relocation R_X86_64_32S
# against `.bss' can not be used when making a shared object; recompile with -fPIC
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fPIC")
endif()
if (ANDROID)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fPIC")
endif()
if (CYGWIN)
@@ -418,7 +435,18 @@ set(MATC_BASE_FLAGS ${MATC_API_FLAGS} -p ${MATC_TARGET} ${MATC_OPT_FLAGS})
# ==================================================================================================
# choose where to put the objects in the dist folder
if (NOT DIST_ARCH)
set(DIST_ARCH x86_64)
# On Apple silicon, the value of CMAKE_HOST_SYSTEM_PROCESSOR varies based on the CMake process's
# own architecture. Because of this, running a x86_64 CMake binary on Apple silicon will cause
# DIST_ARCH to be set incorrectly.
set(DIST_ARCH "${CMAKE_HOST_SYSTEM_PROCESSOR}")
if (CMAKE_OSX_ARCHITECTURES MATCHES ".*;.*")
set(DIST_ARCH "universal")
else()
if (NOT CMAKE_OSX_ARCHITECTURES STREQUAL "")
set(DIST_ARCH "${CMAKE_OSX_ARCHITECTURES}")
endif()
endif()
endif()
if (NOT DIST_DIR)
set(DIST_DIR "${DIST_ARCH}")
@@ -593,7 +621,6 @@ set(FILAMENT_SAMPLES_BINARY_DIR ${PROJECT_BINARY_DIR}/samples)
if (WEBGL)
add_subdirectory(web/filament-js)
add_subdirectory(web/samples)
add_subdirectory(${EXTERNAL}/imgui/tnt)
endif()
if (IS_HOST_PLATFORM)
@@ -601,6 +628,7 @@ if (IS_HOST_PLATFORM)
add_subdirectory(${LIBRARIES}/filamentapp)
add_subdirectory(${LIBRARIES}/filagui)
add_subdirectory(${LIBRARIES}/imageio)
add_subdirectory(${LIBRARIES}/viewer)
add_subdirectory(${FILAMENT}/java/filamat)
add_subdirectory(${FILAMENT}/java/filament)
@@ -611,6 +639,7 @@ if (IS_HOST_PLATFORM)
add_subdirectory(${EXTERNAL}/astcenc/tnt)
add_subdirectory(${EXTERNAL}/etc2comp)
add_subdirectory(${EXTERNAL}/imgui/tnt)
add_subdirectory(${EXTERNAL}/jsmn/tnt)
add_subdirectory(${EXTERNAL}/libassimp/tnt)
add_subdirectory(${EXTERNAL}/libpng/tnt)
add_subdirectory(${EXTERNAL}/libsdl2/tnt)

View File

@@ -31,7 +31,7 @@ repositories {
}
dependencies {
implementation 'com.google.android.filament:filament-android:1.9.2'
implementation 'com.google.android.filament:filament-android:1.9.11'
}
```
@@ -63,7 +63,7 @@ A much smaller alternative to `filamat-android` that can only generate OpenGL sh
iOS projects can use CocoaPods to install the latest release:
```
pod 'Filament', '~> 1.9.2'
pod 'Filament', '~> 1.9.11'
```
### Snapshots
@@ -136,7 +136,7 @@ Here are a few screenshots of applications that use Filament in production:
- Clear coat
- Anisotropic lighting
- Approximated translucent (subsurface) materials
- Cloth shading
- Cloth/fabric/sheen shading
- Normal mapping & ambient occlusion mapping
- Image-based lighting
- Physically-based camera (shutter speed, sensitivity and aperture)
@@ -157,6 +157,41 @@ Here are a few screenshots of applications that use Filament in production:
- TAA, FXAA, MSAA and specular anti-aliasing
- Dynamic resolution
### glTF 2.0
- Encodings
- [x] Embeded
- [x] Binary
- Primitive Types
- [x] Points
- [x] Lines
- [ ] Line Loop
- [ ] Line Strip
- [x] Triangles
- [ ] Triangle Strip
- [ ] Triangle Fan
- Animation
- [x] Transform animation
- [x] Linear interpolation
- [x] Morph animation
- [x] Sparse accessor
- [x] Skin animation
- [x] Joint animation
- Extensions
- [x] KHR_draco_mesh_compression
- [x] KHR_lights_punctual
- [x] KHR_materials_clearcoat
- [x] KHR_materials_pbrSpecularGlossiness
- [x] KHR_materials_sheen
- [x] KHR_materials_transmission
- [x] KHR_materials_unlit
- [x] KHR_mesh_quantization
- [x] KHR_texture_transform
## Rendering with Filament
### Native Linux, macOS and Windows

138
RELEASE_GUIDE.md Normal file
View File

@@ -0,0 +1,138 @@
# Filament Release Guide
This guide makes use of some "environment variables":
- $RELEASE = the new version of Filament we are releasing today. (e.g., 1.9.3)
- $NEXT_RELEASE = the version we plan to release next week (e.g., 1.9.4)
Before starting, ensure that each of these branches is up-to-date with origin:
- release
- rc/$RELEASE
- main
## 0. Make sure the rc/$RELEASE branch has the correct version.
It should have the version corresponding to its name, $RELEASE.
## 1. Update RELEASE_NOTES.md on the rc branch.
Checkout the rc/$RELEASE branch. In RELEASE_NOTES.md, locate the header corresponding to $RELEASE
and write release notes. To see which commits make up the release, run:
```
build/common/release.sh -c rc/$RELEASE
```
Commit the changes to rc/$RELEASE with the title:
```
Update RELEASE_NOTES for $RELEASE
```
## 2. Bump versions on main to $RELEASE.
Checkout main and run the following command to bump Filament's version to $RELEASE:
```
build/common/bump-version.sh $RELEASE
```
Commit changes to main with the title:
```
Bump version to $RELEASE
```
Do not push to origin yet.
## 3. Cherry-pick RELEASE_NOTES change from rc branch to main.
```
git cherry-pick rc/$RELEASE
```
Update the headers. The "Next release" header becomes a header for $NEXT_RELEASE, and a new "Next
release" header is added.
For example, this:
```
## Next release (main branch)
- foo
- bar
## v1.9.3
- baz
- bat
```
becomes:
```
## Next release (main branch)
## v1.9.4
- foo
- bar
## v1.9.3
- baz
- bat
```
Ammend these changes to the cherry-picked change.
```
git add -u
git commit --amend --no-edit
```
## 4. Run release script.
```
build/common/release.sh rc/$RELEASE rc/$NEXT_RELEASE
```
This script will merge rc/$RELEASE into release, delete the rc branch, and create a new rc
branch called rc/$NEXT_RELEASE. Verify that everything looks okay locally.
## 5. Push the release branch.
```
git push origin release
```
## 6. Create the GitHub release.
Use the GitHub UI to create a GitHub release corresponding to $RELEASE version.
Make sure the target is set to the release branch.
## 7. Delete the old rc branch.
```
git push origin --delete rc/$RELEASE
```
## 8. Bump the version on the new rc branch to $NEXT_RELEASE.
```
git checkout rc/$NEXT_RELEASE
build/common/bump-version.sh $NEXT_RELEASE
```
Commit the changes to rc/$NEXT_RELEASE with the title:
```
Bump version to $NEXT_RELEASE
```
## 9. Push main.
```
git push origin main
```
## 10. Push the new rc branch.
```
git push origin rc/$NEXT_RELEASE
```

View File

@@ -3,6 +3,129 @@
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.
## Next release (main branch)
## v1.9.11
- Added support for Apple silicon Macs. build.sh can now be used to build on either Apple silicon or
Intel-based Macs. Pass the `-l` flag to build universal binaries.
- Added `sheenColor` and `sheenRoughness` properties to materials to create cloth/fabric.
- Materials generation using `libfilamat` is now multi-threaded.
- `MaterialBuilder::build()` now expects a reference to a `JobSystem` to multi-thread shaders
generation. A `JobSystem` can be obtained with `Engine::getJobSystem()` when using Filament,
or created directly otherwise. (⚠️ **API change**)
- Add planar reflection RenderTarget demo.
- Metal: honor inverseFrontFaces RasterState.
- Metal: Fix crash when switching between views with shadowing enabled.
- Metal: Fix crash when calling Texture::setImage() on SAMPLER_2D_ARRAY texture.
- gltfio: added support for `KHR_materials_sheen`.
- gltfio: shader optimizations are now disabled by default, unless opting in or using ubershaders.
- gltfio: Fix "_maskThreshold not found" error.
- gltfio on Java: fix potential memory leak in AssetLoader#destroy.
- gltfio: fix crash during async texture decode.
- gltfio: support animation in dynamically-added instances.
- gltfio: Improve robustness when decoding textures.
- gltfio: Fix animator crash for orphaned nodes.
- gltfio: fix tangents with morphing.
- gltf_viewer: fix very sporadic crash when exiting.
- gltf_viewer: fix crash when rapidly switching between glTF models.
- WebGL: Fix samples erroring on Windows with Chrome.
- WebGL: Support `highlight` for setBloomOptions in JavaScript.
- WebGL: Include TypeScript bindings in releases.
- engine: Fix, punctual lights get clipped at certain angles.
- engine: Fix memory leak when calling `View::setViewport` frequently.
- engine: Fix, materials not working on some Qualcomm devices.
- engine: Modulate emissive by alpha on blended objects.
- engine: Fix, RenderTarget cleared multiple times.
- Java: Fix JNI bindings for color grading.
- Android: reduced binary size.
## v1.9.10
- Introduce `libibl_lite` library.
- engine: Fix `EXC_BAD_INSTRUCTION` seen when using headless SwapChains on macOS with OpenGL.
- engine: Add new callback API to `SwapChain`.
- engine: Fix SwiftShader crash when using an IBL without a reflections texture.
- filamat: Shrink internal `Skybox` material size.
- filamat: improvements to generated material size.
- filamat: silence spirv-opt warnings in release builds.
- matc: Add fog variant filter.
- matc: Fix crash when building mobile materials.
- math: reduce template bloat for matrices.
## v1.9.9
- Vulkan: internal robustness improvements
- Metal: Support CVPixelBuffer SwapChains
- Metal: Support copyFrame
- Fix clear behavior with RenderTarget API.
- Fix GetRefractionMode JNI binding
- Additional fixes for Fence bug
## v1.9.8
- Fix a few Fence-related bugs
- gltfio: add createInstance() to AssetLoader.
- gltfio: fix ASAN issue when consuming invalid animation.
- gltfio: do not segfault on invalid primitives.
- gltfio: add safety checks to getAnimator.
- gltfio: fix segfault when consuming invalid file.
- Vulkan: various internal refactoring and improvements
- mathio: add ostream operator for quaternions.
- Fix color grading not applied when dithering is off.
## v1.9.7
- Vulkan: improvements to the ReadPixels implementation.
- Vulkan: warn instead of panic for sampler overflow.
- Vulkan: fix leak with headless swap chain.
- PlatformVkLinux now supports all combos of XLIB and XCB.
- Fix TypeScript binding for TextureUsage.
## v1.9.6
- Added View::setVsmShadowOptions (experimental)
- Add anisotropic shadow map sampling with VSM (experimental)
- matc: fixed bug where some compilation failures still exited with code 0
- Vulkan + Android: fix build break
- Add optional XCB support to PlatformVkLinux
- Fix Vulkan black screen on Windows with NVIDIA hardware
## v1.9.5
- Added a new Live Wallpaper Android sample
- `UiHelper` now supports managing a `SurfaceHolder`
- Fix: an internal texture resource was never destroyed
- Fix: hang on 2-CPU machines
- Fix: Vulkan crash when using shadow cascades
- Linux fixes for headless SwiftShader
- Fix null pointer dereference in `FIndirectLight`
- Fix Windows build by avoiding nested initializers
- Vulkan: support readPixels and headless swap chains
- VSM improvements
## v1.9.4
- Add screen space cone tracing (SSCT)
- Improvements to VSM shadow quality
- New `ShadowOptions` control to render Variance Shadow Maps (VSM) with MSAA (experimental)
- Improvements and fixes to screen-space ambient occlusion
- gltf_viewer: add --headless option
- gltf_viewer: Add new automation UI and functionality
## v1.9.3
- engine: Added new APIs to enable/disable screen space refraction
- engine: Fix, flip the shading normal when det < 0.
- gltfio: Fix animation by clamping the per-channel interpolant.
- gltfio: add async cancellation API
- gltfio: Fix "uniform not found" errors.
- gltfio: Disable clear coat layer IOR change in glTF files (#3104)
- Vulkan: fix final image barrier used for swap chain.
- matdbg: Various improvements
- JavaScript bindings: fix TextureUsage bitmask.
- cmgen / mipgen: add opt-in for ASTC / ETC support.
## v1.9.2
- Fixes / improvements for contact shadows, fog, and DOF

View File

@@ -6,11 +6,29 @@ In addition to the requirements for [building Filament on Windows](../BUILDING.m
need the Android SDK and NDK. See [Getting Started with the
NDK](https://developer.android.com/ndk/guides/) for detailed installation instructions.
You'll also need [Ninja 1.8](https://github.com/ninja-build/ninja/wiki/Pre-built-Ninja-packages) (or
more recent) and [Git for Windows](https://git-scm.com/download/win) to clone the repository and run
Bash scripts.
Ensure the `%ANDROID_HOME%` environment variable is set to your Android SDK installation location.
On Windows, we require VS2019 for building the host tools. All of the following commands should be
executed in a *Visual Studio x64 Native Tools Command Prompt for VS 2019*.
### A Note About Python 3
Python 3 is required. If CMake errors because it cannot find Python 3:
```
Could NOT find PythonInterp: Found unsuitable version "1.4", but required is at least "3"
```
then add the following flag to the CMake invocations:
```
-DPYTHON_EXECUTABLE:FILEPATH=\path\to\python3
```
## Desktop Tools
First, a few Filament tools need to be compiled for desktop.

View File

@@ -22,6 +22,23 @@
// Example:
// ./gradlew -Pfilament_dist_dir=../dist-android-release assembleRelease -Pfilament_abis=x86
// Publishing to Maven Central:
// - Build and upload artifacts with ./gradlew publish
// - Close and release staging repo on Nexus with ./gradlew closeAndReleaseRepository
//
// The following is needed in ~/gradle/gradle.properties:
//
// SONATYPE_NEXUS_USERNAME=nexus_user
// SONATYPE_NEXUS_PASSWORD=nexus_password
//
// nexusUsername=nexus_user
// nexusPassword=nexus_password
//
// signing.keyId=pgp_key_id
// signing.password=pgp_key_password
// signing.secretKeyRingFile=/Users/user/.gnupg/maven_signing.key
//
buildscript {
def filamentPath = file("../out/android-release/filament").absolutePath
if (project.hasProperty("filament_dist_dir")) {
@@ -45,11 +62,11 @@ buildscript {
// Our minSdkVersion is 19.
ext.versions = [
'minSdk': 19,
'targetSdk': 29,
'compileSdk': 29,
'kotlin': '1.3.72',
'buildTools': '30.0.1',
'ndk': '21.3.6528147'
'targetSdk': 30,
'compileSdk': 30,
'kotlin': '1.4.21',
'buildTools': '30.0.3',
'ndk': '22.0.7026061'
]
ext.deps = [
@@ -61,7 +78,7 @@ buildscript {
]
dependencies {
classpath 'com.android.tools.build:gradle:4.0.1'
classpath 'com.android.tools.build:gradle:4.1.2'
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:${versions.kotlin}"
}
@@ -103,6 +120,17 @@ buildscript {
}
}
plugins {
id 'io.codearte.nexus-staging' version '0.22.0'
}
// Nexus Staging configuration
// See https://github.com/Codearte/gradle-nexus-staging-plugin/
nexusStaging {
packageGroup = 'com.google.android'
stagingProfileId = '9a75a224a4f17b'
}
subprojects {
group = GROUP
version = VERSION_NAME

View File

@@ -95,3 +95,25 @@ void JniImageCallback::invoke(void*, void* user) {
JniImageCallback* data = reinterpret_cast<JniImageCallback*>(user);
delete data;
}
// -----------------------------------------------------------------------------------------------
JniCallback* JniCallback::make(JNIEnv* env, jobject handler, jobject callback) {
return new JniCallback(env, handler, callback);
}
JniCallback::JniCallback(JNIEnv* env, jobject handler, jobject callback)
: mEnv(env)
, mHandler(env->NewGlobalRef(handler))
, mCallback(env->NewGlobalRef(callback)) {
acquireCallbackJni(env, mCallbackUtils);
}
JniCallback::~JniCallback() {
releaseCallbackJni(mEnv, mCallbackUtils, mHandler, mCallback);
}
void JniCallback::invoke(void* user) {
JniCallback* data = reinterpret_cast<JniCallback*>(user);
delete data;
}

View File

@@ -62,8 +62,8 @@ struct JniImageCallback {
private:
JniImageCallback(JNIEnv* env, jobject handler, jobject runnable, long image);
JniImageCallback(JniBufferCallback const &) = delete;
JniImageCallback(JniBufferCallback&&) = delete;
JniImageCallback(JniImageCallback const &) = delete;
JniImageCallback(JniImageCallback&&) = delete;
~JniImageCallback();
JNIEnv* mEnv;
@@ -72,3 +72,20 @@ private:
long mImage;
CallbackJni mCallbackUtils;
};
struct JniCallback {
static JniCallback* make(JNIEnv* env, jobject handler, jobject runnable);
static void invoke(void* user);
private:
JniCallback(JNIEnv* env, jobject handler, jobject runnable);
JniCallback(JniCallback const &) = delete;
JniCallback(JniCallback&&) = delete;
~JniCallback();
JNIEnv* mEnv;
jobject mHandler;
jobject mCallback;
CallbackJni mCallbackUtils;
};

View File

@@ -33,13 +33,16 @@ add_library(shaders STATIC IMPORTED)
set_target_properties(shaders PROPERTIES IMPORTED_LOCATION
${FILAMENT_DIR}/lib/${ANDROID_ABI}/libshaders.a)
set(FILAMAT_INCLUDE_DIRS
../../libs/utils/include
)
include_directories(${FILAMENT_DIR}/include)
set(CMAKE_SHARED_LINKER_FLAGS_RELEASE "${CMAKE_SHARED_LINKER_FLAGS_RELEASE} -Wl,--version-script=${CMAKE_SOURCE_DIR}/libfilamat-jni.map")
add_library(filamat-jni SHARED
src/main/cpp/MaterialBuilder.cpp
)
add_library(filamat-jni SHARED src/main/cpp/MaterialBuilder.cpp)
target_include_directories(filamat-jni PRIVATE ${FILAMAT_INCLUDE_DIRS})
target_link_libraries(filamat-jni
${FILAMAT_FLAVOR}

View File

@@ -18,6 +18,8 @@
#include <filamat/MaterialBuilder.h>
#include <utils/JobSystem.h>
using namespace filament;
using namespace filamat;
@@ -45,9 +47,23 @@ Java_com_google_android_filament_filamat_MaterialBuilder_nDestroyMaterialBuilder
extern "C" JNIEXPORT jlong JNICALL
Java_com_google_android_filament_filamat_MaterialBuilder_nBuilderBuild(JNIEnv*, jclass,
jlong nativeBuilder) {
jlong nativeBuilder, jlong nativeJobSystem) {
auto builder = (MaterialBuilder*) nativeBuilder;
return (jlong) new Package(builder->build());
auto jobSystem = (utils::JobSystem*) nativeJobSystem;
if (nativeJobSystem == 0) {
jobSystem = new utils::JobSystem;
jobSystem->adopt();
}
jlong result = (jlong) new Package(builder->build(*jobSystem));
if (nativeJobSystem == 0) {
jobSystem->emancipate();
delete jobSystem;
}
return result;
}
extern "C" JNIEXPORT jbyteArray JNICALL

View File

@@ -17,17 +17,29 @@
package com.google.android.filament.filamat;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.nio.ByteBuffer;
public class MaterialBuilder {
@SuppressWarnings({"FieldCanBeLocal", "UnusedDeclaration"})
// Keep to finalize native resources
private final BuilderFinalizer mFinalizer;
private final long mNativeObject;
private static Class<?> sEngineClass = null;
private static Method sGetNativeJobSystemMethod = null;
static {
System.loadLibrary("filamat-jni");
try {
sEngineClass = Class.forName("com.google.android.filament.Engine");
sGetNativeJobSystemMethod = sEngineClass.getDeclaredMethod("getNativeJobSystem");
} catch (ClassNotFoundException | NoSuchMethodException e) {
// It's okay if we don't find it, this is to avoid creating dependencies
}
}
public enum Shading {
@@ -421,9 +433,55 @@ public class MaterialBuilder {
return this;
}
/**
* Validates, builds, and returns the compiled material. While this method never
* returns null, the returned {@link MaterialPackage} may be invalid. Call
* {@link MaterialPackage#isValid()} before using it.
*
* Calling this method is equivalent to calling {@link #build(Object)} and passing
* <code>null</code> as the job system provider.
*
* @see #build(Object)
*/
@NonNull
public MaterialPackage build() {
long nativePackage = nBuilderBuild(mNativeObject);
return build(null);
}
/**
* Validates, builds, and returns the compiled material. While this method never
* returns null, the returned {@link MaterialPackage} may be invalid. Call
* {@link MaterialPackage#isValid()} before using it.
*
* You can pass a job system provider to this method, or null. When passing null
* or an invalid job system provider, a temporary job system will be created which
* is less efficient than reusing an existing job system.
*
* Currently the only valid type of job system provider is an <code>Engine</code>
* instance from the main Filament library (<code>com.google.android.filament.Engine</code>).
*
* If you are using Filament and the filamat library together you <em>must</em> pass an
* <code>Engine</code> as the job system provider, <em>or</em> invoke
* <code>MaterialBuilder</code> from a thread other than the thread used to invoke Filament
* APIs.
*
* @param jobSystemProvider An <code>Engine</code> instance or null
*/
@NonNull
public MaterialPackage build(@Nullable Object jobSystemProvider) {
long nativeJobSystem = 0;
if (jobSystemProvider != null && sEngineClass != null) {
if (sEngineClass.isInstance(jobSystemProvider) && sGetNativeJobSystemMethod != null) {
try {
//noinspection ConstantConditions
nativeJobSystem = (Long) sGetNativeJobSystemMethod.invoke(jobSystemProvider);
} catch (IllegalAccessException | InvocationTargetException e) {
// Ignore
}
}
}
long nativePackage = nBuilderBuild(mNativeObject, nativeJobSystem);
byte[] data = nGetPackageBytes(nativePackage);
MaterialPackage result =
new MaterialPackage(ByteBuffer.wrap(data), nGetPackageIsValid(nativePackage));
@@ -455,7 +513,7 @@ public class MaterialBuilder {
private static native long nCreateMaterialBuilder();
private static native void nDestroyMaterialBuilder(long nativeBuilder);
private static native long nBuilderBuild(long nativeBuilder);
private static native long nBuilderBuild(long nativeBuilder, long nativeJobSystem);
private static native byte[] nGetPackageBytes(long nativePackage);
private static native boolean nGetPackageIsValid(long nativePackage);
private static native void nDestroyPackage(long nativePackage);

View File

@@ -17,9 +17,9 @@ add_library(utils STATIC IMPORTED)
set_target_properties(utils PROPERTIES IMPORTED_LOCATION
${FILAMENT_DIR}/lib/${ANDROID_ABI}/libutils.a)
add_library(ibl STATIC IMPORTED)
set_target_properties(ibl PROPERTIES IMPORTED_LOCATION
${FILAMENT_DIR}/lib/${ANDROID_ABI}/libibl.a)
add_library(ibl-lite STATIC IMPORTED)
set_target_properties(ibl-lite PROPERTIES IMPORTED_LOCATION
${FILAMENT_DIR}/lib/${ANDROID_ABI}/libibl-lite.a)
add_library(filaflat STATIC IMPORTED)
set_target_properties(filaflat PROPERTIES IMPORTED_LOCATION
@@ -70,6 +70,7 @@ add_library(filament-jni SHARED
src/main/cpp/SkyBox.cpp
src/main/cpp/Stream.cpp
src/main/cpp/SurfaceOrientation.cpp
src/main/cpp/SwapChain.cpp
src/main/cpp/Texture.cpp
src/main/cpp/TextureSampler.cpp
src/main/cpp/TransformManager.cpp
@@ -91,7 +92,7 @@ target_link_libraries(filament-jni
PRIVATE filaflat
PRIVATE filabridge
PRIVATE geometry
PRIVATE ibl
PRIVATE ibl-lite
PRIVATE log
PRIVATE GLESv3
PRIVATE EGL

View File

@@ -1,4 +1,20 @@
LIBFILAMENT {
global: *filament*; JNI*;
global:
Java_com_google_android_filament_*;
JNI*;
*filament*Camera*;
*filament*Skybox*;
*filament*Engine*;
*filament*RenderableManager*;
*filament*Aabb*;
*filament*IndirectLight*;
*filament*LightManager*;
*filament*Transform*;
*filament*Material*;
*filament*IndexBuffer*;
*filament*VertexBuffer*;
*filament*Texture*;
*filament*geometry*;
local: *;
};

View File

@@ -306,3 +306,9 @@ Java_com_google_android_filament_Engine_nGetRenderableManager(JNIEnv*, jclass,
Engine* engine = (Engine*) nativeEngine;
return (jlong) &engine->getRenderableManager();
}
extern "C" JNIEXPORT jlong JNICALL
Java_com_google_android_filament_Engine_nGetJobSystem(JNIEnv*, jclass, jlong nativeEngine) {
Engine* engine = (Engine*) nativeEngine;
return (jlong) &engine->getJobSystem();
}

View File

@@ -77,7 +77,7 @@ Java_com_google_android_filament_LightManager_nBuilderShadowOptions(JNIEnv* env,
jlong nativeBuilder, jint mapSize, jint cascades, jfloatArray splitPositions,
jfloat constantBias, jfloat normalBias, jfloat shadowFar, jfloat shadowNearHint,
jfloat shadowFarHint, jboolean stable, jboolean screenSpaceContactShadows, jint stepCount,
jfloat maxShadowDistance) {
jfloat maxShadowDistance, jint vsmMsaaSamples) {
LightManager::Builder *builder = (LightManager::Builder *) nativeBuilder;
LightManager::ShadowOptions shadowOptions {
.mapSize = (uint32_t)mapSize,
@@ -90,7 +90,10 @@ Java_com_google_android_filament_LightManager_nBuilderShadowOptions(JNIEnv* env,
.stable = (bool)stable,
.screenSpaceContactShadows = (bool)screenSpaceContactShadows,
.stepCount = uint8_t(stepCount),
.maxShadowDistance = maxShadowDistance
.maxShadowDistance = maxShadowDistance,
.vsm = {
.msaaSamples = (uint8_t) vsmMsaaSamples
}
};
jfloat *nativeSplits = env->GetFloatArrayElements(splitPositions, NULL);
const jsize splitCount = std::min((jsize) 3, env->GetArrayLength(splitPositions));

View File

@@ -91,7 +91,7 @@ Java_com_google_android_filament_Material_nGetBlendingMode(JNIEnv*, jclass,
extern "C"
JNIEXPORT jint JNICALL
Java_com_google_android_filament_Material_nGetRefraction(JNIEnv*, jclass,
Java_com_google_android_filament_Material_nGetRefractionMode(JNIEnv*, jclass,
jlong nativeMaterial) {
Material* material = (Material*) nativeMaterial;
return (jint)material->getRefractionMode();
@@ -204,9 +204,20 @@ Java_com_google_android_filament_Material_nGetParameters(JNIEnv* env, jclass,
jfieldID parameterSamplerOffset = env->GetStaticFieldID(parameterClass,
"SAMPLER_OFFSET", "I");
jfieldID parameterSubpassOffset = env->GetStaticFieldID(parameterClass,
"SUBPASS_OFFSET", "I");
jint offset = env->GetStaticIntField(parameterClass, parameterSamplerOffset);
jint subpassOffset = env->GetStaticIntField(parameterClass, parameterSubpassOffset);
for (size_t i = 0; i < received; i++) {
jint type = info[i].isSampler ? (jint) info[i].samplerType + offset : (jint) info[i].type;
jint type;
if (info[i].isSampler) {
type = (jint) info[i].samplerType + offset;
} else if (info[i].isSubpass) {
type = subpassOffset;
} else {
type = (jint) info[i].type;
}
env->CallStaticVoidMethod(
parameterClass, parameterAdd,

View File

@@ -0,0 +1,31 @@
/*
* Copyright (C) 2020 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 <jni.h>
#include <filament/SwapChain.h>
#include "common/CallbackUtils.h"
using namespace filament;
extern "C" JNIEXPORT void JNICALL
Java_com_google_android_filament_SwapChain_nSetFrameCompletedCallback(JNIEnv* env, jclass,
jlong nativeSwapChain, jobject handler, jobject runnable) {
SwapChain* swapChain = (SwapChain*) nativeSwapChain;
auto *callback = JniCallback::make(env, handler, runnable);
swapChain->setFrameCompletedCallback(&JniCallback::invoke, callback);
}

View File

@@ -67,9 +67,9 @@ Java_com_google_android_filament_View_nSetVisibleLayers(JNIEnv*, jclass, jlong n
}
extern "C" JNIEXPORT void JNICALL
Java_com_google_android_filament_View_nSetShadowsEnabled(JNIEnv*, jclass, jlong nativeView, jboolean enabled) {
Java_com_google_android_filament_View_nSetShadowingEnabled(JNIEnv*, jclass, jlong nativeView, jboolean enabled) {
View* view = (View*) nativeView;
view->setShadowsEnabled(enabled);
view->setShadowingEnabled(enabled);
}
extern "C" JNIEXPORT void JNICALL
@@ -130,6 +130,21 @@ Java_com_google_android_filament_View_nSetDynamicResolutionOptions(JNIEnv*, jcla
view->setDynamicResolutionOptions(options);
}
extern "C" JNIEXPORT void JNICALL
Java_com_google_android_filament_View_nSetShadowType(JNIEnv*, jclass, jlong nativeView, jint type) {
View* view = (View*) nativeView;
view->setShadowType((View::ShadowType) type);
}
extern "C" JNIEXPORT void JNICALL
Java_com_google_android_filament_View_nSetVsmShadowOptions(JNIEnv*, jclass, jlong nativeView,
jint anisotropy) {
View* view = (View*) nativeView;
View::VsmShadowOptions options;
options.anisotropy = (uint8_t) anisotropy;
view->setVsmShadowOptions(options);
}
extern "C"
JNIEXPORT void JNICALL
Java_com_google_android_filament_View_nSetRenderQuality(JNIEnv*, jclass,
@@ -196,19 +211,41 @@ Java_com_google_android_filament_View_nGetAmbientOcclusion(JNIEnv*, jclass, jlon
extern "C" JNIEXPORT void JNICALL
Java_com_google_android_filament_View_nSetAmbientOcclusionOptions(JNIEnv*, jclass,
jlong nativeView, jfloat radius, jfloat bias, jfloat power, jfloat resolution, jfloat intensity,
jint quality, jint upsampling, jboolean enabled, jfloat minHorizonAngleRad) {
jint quality, jint lowPassFilter, jint upsampling, jboolean enabled, jfloat minHorizonAngleRad) {
View* view = (View*) nativeView;
View::AmbientOcclusionOptions options = {
.radius = radius,
.power = power,
.bias = bias,
.resolution = resolution,
.intensity = intensity,
.quality = (View::QualityLevel)quality,
.upsampling = (View::QualityLevel)upsampling,
.enabled = (bool)enabled,
.minHorizonAngleRad = minHorizonAngleRad
};
View::AmbientOcclusionOptions options = view->getAmbientOcclusionOptions();
options.radius = radius;
options.power = power;
options.bias = bias;
options.resolution = resolution;
options.intensity = intensity;
options.quality = (View::QualityLevel)quality;
options.lowPassFilter = (View::QualityLevel)lowPassFilter;
options.upsampling = (View::QualityLevel)upsampling;
options.enabled = (bool)enabled;
options.minHorizonAngleRad = minHorizonAngleRad;
view->setAmbientOcclusionOptions(options);
}
extern "C" JNIEXPORT void JNICALL
Java_com_google_android_filament_View_nSetSSCTOptions(JNIEnv *, jclass, jlong nativeView,
jfloat ssctLightConeRad, jfloat ssctStartTraceDistance, jfloat ssctContactDistanceMax,
jfloat ssctIntensity, jfloat ssctLightDirX, jfloat ssctLightDirY, jfloat ssctLightDirZ,
jfloat ssctDepthBias, jfloat ssctDepthSlopeBias, jint ssctSampleCount,
jint ssctRayCount, jboolean ssctEnabled) {
View* view = (View*) nativeView;
View::AmbientOcclusionOptions options = view->getAmbientOcclusionOptions();
options.ssct.lightConeRad = ssctLightConeRad;
options.ssct.shadowDistance = ssctStartTraceDistance;
options.ssct.contactDistanceMax = ssctContactDistanceMax;
options.ssct.intensity = ssctIntensity;
options.ssct.lightDirection = math::float3{ ssctLightDirX, ssctLightDirY, ssctLightDirZ };
options.ssct.depthBias = ssctDepthBias;
options.ssct.depthSlopeBias = ssctDepthSlopeBias;
options.ssct.sampleCount = (uint8_t)ssctSampleCount;
options.ssct.rayCount = (uint8_t)ssctRayCount;
options.ssct.enabled = (bool)ssctEnabled;
view->setAmbientOcclusionOptions(options);
}
@@ -286,3 +323,26 @@ Java_com_google_android_filament_View_nSetTemporalAntiAliasingOptions(JNIEnv *,
view->setTemporalAntiAliasingOptions({
.filterWidth = filterWidth, .feedback = feedback, .enabled = (bool) enabled});
}
extern "C"
JNIEXPORT jboolean JNICALL
Java_com_google_android_filament_View_nIsShadowingEnabled(JNIEnv *, jclass, jlong nativeView) {
View* view = (View*) nativeView;
return (jboolean)view->isShadowingEnabled();
}
extern "C"
JNIEXPORT void JNICALL
Java_com_google_android_filament_View_nSetScreenSpaceRefractionEnabled(JNIEnv *, jclass,
jlong nativeView, jboolean enabled) {
View* view = (View*) nativeView;
view->setScreenSpaceRefractionEnabled((bool)enabled);
}
extern "C"
JNIEXPORT jboolean JNICALL
Java_com_google_android_filament_View_nIsScreenSpaceRefractionEnabled(JNIEnv *, jclass,
jlong nativeView) {
View* view = (View*) nativeView;
return (jboolean)view->isScreenSpaceRefractionEnabled();
}

View File

@@ -38,7 +38,14 @@ bool acquireDrawingSurface(JNIEnv* env, jobject surface,
jboolean foundJawt = JNI_FALSE;
for (int jawtVersion : jawtVersions) {
awt.version = jawtVersion;
#if defined(__APPLE__) && defined(__aarch64__)
// FIXME: enable Apple Silicon build. The problem here is that we attempt to link an x86 jdk and that fails
// so JAWT_GetAWT doesn't exist at link time.
#warning "FIXME: JAWT_GetAWT() not supported"
foundJawt = {};
#else
foundJawt = JAWT_GetAWT(env, &awt);
#endif
if (foundJawt == JNI_TRUE) {
#ifndef NDEBUG
printf("Found valid AWT v%08x.\n", jawtVersion);

View File

@@ -270,7 +270,7 @@ public class ColorGrading {
*
* @return This Builder, for chaining calls
*/
Builder shadowsMidtonesHighlights(
public Builder shadowsMidtonesHighlights(
@NonNull @Size(min = 4) float[] shadows,
@NonNull @Size(min = 4) float[] midtones,
@NonNull @Size(min = 4) float[] highlights,
@@ -309,7 +309,7 @@ public class ColorGrading {
*
* @return This Builder, for chaining calls
*/
Builder slopeOffsetPower(
public Builder slopeOffsetPower(
@NonNull @Size(min = 3) float[] slope,
@NonNull @Size(min = 3) float[] offset,
@NonNull @Size(min = 3) float[] power) {
@@ -360,7 +360,7 @@ public class ColorGrading {
*
* @return This Builder, for chaining calls
*/
Builder vibrance(float vibrance) {
public Builder vibrance(float vibrance) {
nBuilderVibrance(mNativeBuilder, vibrance);
return this;
}

View File

@@ -568,7 +568,7 @@ public class Engine {
* Destroys a {@link ColorGrading} and frees all its associated resources.
* @param colorGrading the {@link ColorGrading} to destroy
*/
public void destroySkybox(@NonNull ColorGrading colorGrading) {
public void destroyColorGrading(@NonNull ColorGrading colorGrading) {
assertDestroy(nDestroyColorGrading(getNativeObject(), colorGrading.getNativeObject()));
colorGrading.clearNativeObject();
}
@@ -654,13 +654,21 @@ public class Engine {
return mNativeObject;
}
@UsedByReflection("MaterialBuilder.java")
public long getNativeJobSystem() {
if (mNativeObject == 0) {
throw new IllegalStateException("Calling method on destroyed Engine");
}
return nGetJobSystem(getNativeObject());
}
private void clearNativeObject() {
mNativeObject = 0;
}
private static void assertDestroy(boolean success) {
if (!success) {
throw new IllegalStateException("Object couldn't be destoyed (double destroy()?)");
throw new IllegalStateException("Object couldn't be destroyed (double destroy()?)");
}
}
@@ -698,4 +706,5 @@ public class Engine {
private static native long nGetTransformManager(long nativeEngine);
private static native long nGetLightManager(long nativeEngine);
private static native long nGetRenderableManager(long nativeEngine);
private static native long nGetJobSystem(long nativeEngine);
}

View File

@@ -305,6 +305,25 @@ public class LightManager {
*</p>
*/
public float maxShadowDistance = 0.3f;
/*
* Options prefixed with 'vsm' are available when the View's ShadowType is set to VSM.
*
* @see View#setShadowType
*/
/**
* The number of MSAA samples to use when rendering VSM shadow maps.
* Must be a power-of-two and greater than or equal to 1. A value of 1 effectively turns
* off MSAA.
* Higher values may not be available depending on the underlying hardware.
*
* <p>
* <strong>Warning: This API is still experimental and subject to change.</strong>
* </p>
*/
@IntRange(from = 1)
public int vsmMsaaSamples = 1;
}
public static class ShadowCascades {
@@ -433,7 +452,7 @@ public class LightManager {
options.mapSize, options.shadowCascades, options.cascadeSplitPositions,
options.constantBias, options.normalBias, options.shadowFar, options.shadowNearHint,
options.shadowFarHint, options.stable, options.screenSpaceContactShadows,
options.stepCount, options.maxShadowDistance);
options.stepCount, options.maxShadowDistance, options.vsmMsaaSamples);
return this;
}
@@ -1059,7 +1078,7 @@ public class LightManager {
private static native void nDestroyBuilder(long nativeBuilder);
private static native boolean nBuilderBuild(long nativeBuilder, long nativeEngine, int entity);
private static native void nBuilderCastShadows(long nativeBuilder, boolean enable);
private static native void nBuilderShadowOptions(long nativeBuilder, int mapSize, int cascades, float[] splitPositions, float constantBias, float normalBias, float shadowFar, float shadowNearHint, float shadowFarhint, boolean stable, boolean screenSpaceContactShadows, int stepCount, float maxShadowDistance);
private static native void nBuilderShadowOptions(long nativeBuilder, int mapSize, int cascades, float[] splitPositions, float constantBias, float normalBias, float shadowFar, float shadowNearHint, float shadowFarhint, boolean stable, boolean screenSpaceContactShadows, int stepCount, float maxShadowDistance, int vsmMsaaSamples);
private static native void nBuilderCastLight(long nativeBuilder, boolean enabled);
private static native void nBuilderPosition(long nativeBuilder, float x, float y, float z);
private static native void nBuilderDirection(long nativeBuilder, float x, float y, float z);

View File

@@ -233,7 +233,8 @@ public class Material {
SAMPLER_2D_ARRAY,
SAMPLER_CUBEMAP,
SAMPLER_EXTERNAL,
SAMPLER_3D
SAMPLER_3D,
SUBPASS_INPUT
}
public enum Precision {
@@ -247,6 +248,10 @@ public class Material {
@UsedByNative("Material.cpp")
private static final int SAMPLER_OFFSET = Type.MAT4.ordinal() + 1;
@SuppressWarnings("unused")
@UsedByNative("Material.cpp")
private static final int SUBPASS_OFFSET = Type.SAMPLER_3D.ordinal() + 1;
@NonNull
public final String name;
@NonNull

View File

@@ -131,7 +131,7 @@ public class RenderableManager {
* @param type specifies the topology of the primitive (e.g., PrimitiveType.TRIANGLES)
* @param vertices specifies the vertex buffer, which in turn specifies a set of attributes
* @param indices specifies the index buffer (either u16 or u32)
* @param offset specifies where in the index buffer to start reading (expressed as a number of bytes)
* @param offset specifies where in the index buffer to start reading (expressed as a number of indices)
* @param minIndex specifies the minimum index contained in the index buffer
* @param maxIndex specifies the maximum index contained in the index buffer
* @param count number of indices to read (for triangles, this should be a multiple of 3)
@@ -268,6 +268,14 @@ public class RenderableManager {
/**
* Controls if this renderable casts shadows, false by default.
*
* If the View's shadow type is set to {@link View.ShadowType#VSM}, castShadows should only
* be disabled if either is true:
* <ul>
* <li>{@link RenderableManager#setReceiveShadows} is also disabled</li>
* <li>the object is guaranteed to not cast shadows on itself or other objects (for
* example, a ground plane)</li>
* </ul>
*/
@NonNull
public Builder castShadows(boolean enabled) {

View File

@@ -85,6 +85,12 @@ public class SwapChain {
*/
public static final long 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.
*/
public static final long CONFIG_ENABLE_XCB = 0x4;
SwapChain(long nativeSwapChain, Object surface) {
mNativeObject = nativeSwapChain;
mSurface = surface;
@@ -98,6 +104,31 @@ public class SwapChain {
return mSurface;
}
/**
* FrameCompletedCallback is a callback function that notifies an application when a frame's
* contents have completed rendering on the GPU.
*
* <p>
* Use setFrameCompletedCallback to set a callback on an individual SwapChain. Each time a frame
* completes GPU rendering, the callback will be called.
* </p>
*
* <p>
* The FrameCompletedCallback is guaranteed to be called on the main Filament thread.
* </p>
*
* <p>
* Warning: Only Filament's Metal backend supports frame callbacks. Other backends ignore the
* callback (which will never be called) and proceed normally.
* </p>
*
* @param handler A {@link java.util.concurrent.Executor Executor}.
* @param callback The Runnable callback to invoke.
*/
public void setFrameCompletedCallback(@NonNull Object handler, @NonNull Runnable callback) {
nSetFrameCompletedCallback(getNativeObject(), handler, callback);
}
public long getNativeObject() {
if (mNativeObject == 0) {
throw new IllegalStateException("Calling method on destroyed SwapChain");
@@ -108,4 +139,6 @@ public class SwapChain {
void clearNativeObject() {
mNativeObject = 0;
}
private static native void nSetFrameCompletedCallback(long nativeSwapChain, Object handler, Runnable callback);
}

View File

@@ -75,6 +75,7 @@ public class View {
private VignetteOptions mVignetteOptions;
private ColorGrading mColorGrading;
private TemporalAntiAliasingOptions mTemporalAntiAliasingOptions;
private VsmShadowOptions mVsmShadowOptions;
/**
* Generic quality level.
@@ -176,6 +177,14 @@ public class View {
@NonNull
public QualityLevel quality = QualityLevel.LOW;
/**
* The lowPassFilter setting controls the quality of the low pass filter applied to
* AO estimation. The default is QualityLevel.MEDIUM which is sufficient for most mobile
* applications. QualityLevel.LOW disables the filter entirely.
*/
@NonNull
public QualityLevel lowPassFilter = QualityLevel.MEDIUM;
/**
* The upsampling setting controls the quality of the ambient occlusion buffer upsampling.
* The default is QualityLevel.LOW and uses bilinear filtering, a value of
@@ -195,6 +204,64 @@ public class View {
* For e.g. a good values to try could be around 0.2.
*/
public float minHorizonAngleRad = 0.0f;
/**
* Full cone angle in radian, between 0 and pi/2. This affects the softness of the shadows,
* as well as how far they are cast. A smaller angle yields to sharper and shorter shadows.
* The default angle is about 60 degrees.
*/
public float ssctLightConeRad = 1.0f;
/**
* Distance from where tracing starts.
* This affects how far shadows are cast.
*/
public float ssctStartTraceDistance = 0.01f;
/**
* Maximum contact distance with the cone. Intersections between the traced cone and
* geometry samller than this distance are ignored.
*/
public float ssctContactDistanceMax = 1.0f;
/**
* Intensity of the shadows.
*/
public float ssctIntensity = 0.8f;
/**
* Light direction.
*/
@NonNull @Size(min = 3)
public float[] ssctLightDirection = { 0, -1, 0 };
/**
* Depth bias in world units (mitigate self shadowing)
*/
public float ssctDepthBias = 0.01f;
/**
* Depth slope bias (mitigate self shadowing)
*/
public float ssctDepthSlopeBias = 0.01f;
/**
* Tracing sample count, between 1 and 255. This affects the quality as well as the
* distance of the shadows.
*/
public int ssctSampleCount = 4;
/**
* Numbers of rays to trace, between 1 and 255. This affects the noise of the shadows.
* Performance degrades quickly with this value.
*/
public int ssctRayCount = 1;
/**
* Enables or disables SSCT.
*/
public boolean ssctEnabled = false;
}
/**
@@ -499,6 +566,42 @@ public class View {
TEMPORAL
}
/**
* List of available shadow mapping techniques.
*
* @see #setShadowType
*/
public enum ShadowType {
/**
* Percentage-closer filtered shadows (default).
*/
PCF,
/**
* Variance shadows.
*/
VSM
}
/**
* View-level options for VSM shadowing.
*
* @see View#setVsmShadowOptions
*/
public static class VsmShadowOptions {
/**
* Sets the number of anisotropic samples to use when sampling a VSM shadow map. If greater
* than 0, mipmaps will automatically be generated each frame for all lights.
*
* <p>
* The number of anisotropic samples = 2 ^ vsmAnisotropy.
* </p>
*
* <strong>Warning: This API is still experimental and subject to change.</strong>
*/
public int anisotropy = 0;
}
/**
* Used to select buffers.
*/
@@ -723,8 +826,41 @@ public class View {
* @see RenderableManager.Builder#receiveShadows
* @see RenderableManager.Builder#castShadows
*/
public void setShadowingEnabled(boolean enabled) {
nSetShadowingEnabled(getNativeObject(), enabled);
}
/**
* Enables or disables shadow mapping. Enabled by default.
*
* @deprecated Use {@link #setShadowingEnabled}
*/
@Deprecated
public void setShadowsEnabled(boolean enabled) {
nSetShadowsEnabled(getNativeObject(), enabled);
setShadowingEnabled(enabled);
}
/**
* @return whether shadowing is enabled
*/
boolean isShadowingEnabled() {
return nIsShadowingEnabled(getNativeObject());
}
/**
* Enables or disables screen space refraction. Enabled by default.
*
* @param enabled true enables screen space refraction, false disables it.
*/
public void setScreenSpaceRefractionEnabled(boolean enabled) {
nSetScreenSpaceRefractionEnabled(getNativeObject(), enabled);
}
/**
* @return whether screen space refraction is enabled
*/
boolean isScreenSpaceRefractionEnabled() {
return nIsScreenSpaceRefractionEnabled(getNativeObject());
}
/**
@@ -1047,6 +1183,56 @@ public class View {
nSetDynamicLightingOptions(getNativeObject(), zLightNear, zLightFar);
}
/**
* Sets the shadow mapping technique this View uses.
*
* The ShadowType affects all the shadows seen within the View.
*
* <p>
* {@link ShadowType#VSM} imposes a restriction on marking renderables as only shadow receivers
* (but not casters). To ensure correct shadowing with VSM, all shadow participant renderables
* should be marked as both receivers and casters. Objects that are guaranteed to not cast
* shadows on themselves or other objects (such as flat ground planes) can be set to not cast
* shadows, which might improve shadow quality.
* </p>
*
* <strong>Warning: This API is still experimental and subject to change.</strong>
*/
public void setShadowType(ShadowType type) {
nSetShadowType(getNativeObject(), type.ordinal());
}
/**
* Sets VSM shadowing options that apply across the entire View.
*
* Additional light-specific VSM options can be set with
* {@link LightManager.Builder#shadowOptions}.
*
* Only applicable when shadow type is set to ShadowType::VSM.
*
* <strong>Warning: This API is still experimental and subject to change.</strong>
*
* @param options Options for shadowing.
* @see #setShadowType
*/
public void setVsmShadowOptions(@NonNull VsmShadowOptions options) {
mVsmShadowOptions = options;
nSetVsmShadowOptions(getNativeObject(), options.anisotropy);
}
/**
* Gets the VSM shadowing options.
* @see #setVsmShadowOptions
* @return VSM shadow options currently set.
*/
@NonNull
public VsmShadowOptions getVsmShadowOptions() {
if (mVsmShadowOptions == null) {
mVsmShadowOptions = new VsmShadowOptions();
}
return mVsmShadowOptions;
}
/**
* Activates or deactivates ambient occlusion.
* @see #setAmbientOcclusionOptions
@@ -1076,8 +1262,12 @@ public class View {
public void setAmbientOcclusionOptions(@NonNull AmbientOcclusionOptions options) {
mAmbientOcclusionOptions = options;
nSetAmbientOcclusionOptions(getNativeObject(), options.radius, options.bias, options.power,
options.resolution, options.intensity, options.quality.ordinal(), options.upsampling.ordinal(),
options.resolution, options.intensity, options.quality.ordinal(), options.lowPassFilter.ordinal(), options.upsampling.ordinal(),
options.enabled, options.minHorizonAngleRad);
nSetSSCTOptions(getNativeObject(), options.ssctLightConeRad, options.ssctStartTraceDistance, options.ssctContactDistanceMax, options.ssctIntensity,
options.ssctLightDirection[0], options.ssctLightDirection[1], options.ssctLightDirection[2],
options.ssctDepthBias, options.ssctDepthSlopeBias, options.ssctSampleCount,
options.ssctRayCount, options.ssctEnabled);
}
/**
@@ -1223,7 +1413,7 @@ public class View {
private static native void nSetCamera(long nativeView, long nativeCamera);
private static native void nSetViewport(long nativeView, int left, int bottom, int width, int height);
private static native void nSetVisibleLayers(long nativeView, int select, int value);
private static native void nSetShadowsEnabled(long nativeView, boolean enabled);
private static native void nSetShadowingEnabled(long nativeView, boolean enabled);
private static native void nSetRenderTarget(long nativeView, long nativeRenderTarget);
private static native void nSetSampleCount(long nativeView, int count);
private static native int nGetSampleCount(long nativeView);
@@ -1234,6 +1424,8 @@ public class View {
private static native void nSetDynamicResolutionOptions(long nativeView, boolean enabled, boolean homogeneousScaling, float minScale, float maxScale, int quality);
private static native void nSetRenderQuality(long nativeView, int hdrColorBufferQuality);
private static native void nSetDynamicLightingOptions(long nativeView, float zLightNear, float zLightFar);
private static native void nSetShadowType(long nativeView, int type);
private static native void nSetVsmShadowOptions(long nativeView, int anisotropy);
private static native void nSetColorGrading(long nativeView, long nativeColorGrading);
private static native void nSetPostProcessingEnabled(long nativeView, boolean enabled);
private static native boolean nIsPostProcessingEnabled(long nativeView);
@@ -1241,11 +1433,15 @@ public class View {
private static native boolean nIsFrontFaceWindingInverted(long nativeView);
private static native void nSetAmbientOcclusion(long nativeView, int ordinal);
private static native int nGetAmbientOcclusion(long nativeView);
private static native void nSetAmbientOcclusionOptions(long nativeView, float radius, float bias, float power, float resolution, float intensity, int quality, int upsampling, boolean enabled, float minHorizonAngleRad);
private static native void nSetAmbientOcclusionOptions(long nativeView, float radius, float bias, float power, float resolution, float intensity, int quality, int lowPassFilter, int upsampling, boolean enabled, float minHorizonAngleRad);
private static native void nSetSSCTOptions(long nativeView, float ssctLightConeRad, float ssctStartTraceDistance, float ssctContactDistanceMax, float ssctIntensity, float v, float v1, float v2, float ssctDepthBias, float ssctDepthSlopeBias, int ssctSampleCount, int ssctRayCount, boolean ssctEnabled);
private static native void nSetBloomOptions(long nativeView, long dirtNativeObject, float dirtStrength, float strength, int resolution, float anamorphism, int levels, int blendMode, boolean threshold, boolean enabled, float highlight);
private static native void nSetFogOptions(long nativeView, float distance, float maximumOpacity, float height, float heightFalloff, float v, float v1, float v2, float density, float inScatteringStart, float inScatteringSize, boolean fogColorFromIbl, boolean enabled);
private static native void nSetBlendMode(long nativeView, int blendMode);
private static native void nSetDepthOfFieldOptions(long nativeView, float focusDistance, float cocScale, float maxApertureDiameter, boolean enabled);
private static native void nSetVignetteOptions(long nativeView, float midPoint, float roundness, float feather, float r, float g, float b, float a, boolean enabled);
private static native void nSetTemporalAntiAliasingOptions(long nativeView, float feedback, float filterWidth, boolean enabled);
private static native boolean nIsShadowingEnabled(long nativeView);
private static native void nSetScreenSpaceRefractionEnabled(long nativeView, boolean enabled);
private static native boolean nIsScreenSpaceRefractionEnabled(long nativeView);
}

View File

@@ -30,8 +30,8 @@ import android.view.TextureView;
import com.google.android.filament.SwapChain;
/**
* UiHelper is a simple class that can manage either a SurfaceView or a TextureView so it can
* be used to render into with Filament.
* UiHelper is a simple class that can manage either a SurfaceView, TextureView, or a SurfaceHolder
* so it can be used to render into with Filament.
*
* Here is a simple example with a SurfaceView. The code would be exactly the same with a
* TextureView:
@@ -191,6 +191,23 @@ public class UiHelper {
}
}
private static class SurfaceHolderHandler implements RenderSurface {
private SurfaceHolder mSurfaceHolder;
SurfaceHolderHandler(SurfaceHolder surface) {
mSurfaceHolder = surface;
}
@Override
public void resize(int width, int height) {
mSurfaceHolder.setFixedSize(width, height);
}
@Override
public void detach() {
}
}
private class TextureViewHandler implements RenderSurface {
private TextureView mTextureView;
private Surface mSurface;
@@ -258,8 +275,8 @@ public class UiHelper {
}
/**
* Free resources associated to the native window specified in {@link #attachTo(SurfaceView)}
* or {@link #attachTo(TextureView)}.
* Free resources associated to the native window specified in {@link #attachTo(SurfaceView)},
* {@link #attachTo(TextureView)}, or {@link #attachTo(SurfaceHolder)}.
*/
public void detach() {
destroySwapChain();
@@ -315,8 +332,8 @@ public class UiHelper {
* Controls whether the render target (SurfaceView or TextureView) is opaque or not.
* The render target is considered opaque by default.
*
* Must be called before calling {@link #attachTo(SurfaceView)}
* or {@link #attachTo(TextureView)}.
* Must be called before calling {@link #attachTo(SurfaceView)}, {@link #attachTo(TextureView)},
* or {@link #attachTo(SurfaceHolder)}.
*
* @param opaque Indicates whether the render target should be opaque. True by default.
*/
@@ -341,6 +358,8 @@ public class UiHelper {
* Must be called before calling {@link #attachTo(SurfaceView)}
* or {@link #attachTo(TextureView)}.
*
* Has no effect when using {@link #attachTo(SurfaceHolder)}.
*
* @param overlay Indicates whether the render target should be rendered below the activity's
* surface when transparent.
*/
@@ -403,7 +422,9 @@ public class UiHelper {
SurfaceHolder holder = view.getHolder();
holder.addCallback(callback);
holder.setFixedSize(mDesiredWidth, mDesiredHeight);
if (mDesiredWidth > 0 && mDesiredHeight > 0) {
holder.setFixedSize(mDesiredWidth, mDesiredHeight);
}
// in case the SurfaceView's surface already existed
final Surface surface = holder.getSurface();
@@ -483,6 +504,55 @@ public class UiHelper {
}
}
/**
* Associate UiHelper with a SurfaceHolder.
*
* As soon as a Surface is created, we'll create the
* EGL resources needed, and call user callbacks if needed.
*/
public void attachTo(@NonNull SurfaceHolder holder) {
if (attach(holder)) {
int format = isOpaque() ? PixelFormat.OPAQUE : PixelFormat.TRANSLUCENT;
holder.setFormat(format);
mRenderSurface = new SurfaceHolderHandler(holder);
final SurfaceHolder.Callback callback = new SurfaceHolder.Callback() {
@Override
public void surfaceCreated(SurfaceHolder surfaceHolder) {
if (LOGGING) Log.d(LOG_TAG, "surfaceCreated()");
createSwapChain(holder.getSurface());
}
@Override
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
// Note: this is always called at least once after surfaceCreated()
if (LOGGING) Log.d(LOG_TAG, "surfaceChanged(" + width + ", " + height + ")");
mRenderCallback.onResized(width, height);
}
@Override
public void surfaceDestroyed(SurfaceHolder surfaceHolder) {
if (LOGGING) Log.d(LOG_TAG, "surfaceDestroyed()");
destroySwapChain();
}
};
holder.addCallback(callback);
if (mDesiredWidth > 0 && mDesiredHeight > 0) {
holder.setFixedSize(mDesiredWidth, mDesiredHeight);
}
// in case the SurfaceHolder's surface already existed
final Surface surface = holder.getSurface();
if (surface != null && surface.isValid()) {
callback.surfaceCreated(holder);
callback.surfaceChanged(holder, format,
holder.getSurfaceFrame().width(), holder.getSurfaceFrame().height());
}
}
}
private boolean attach(@NonNull Object nativeWindow) {
if (mNativeWindow != null) {
// we are already attached to a native window

View File

@@ -1,5 +1,4 @@
apply plugin: 'kotlin-android'
apply plugin: 'kotlin-android-extensions'
android {
flavorDimensions "functionality"

View File

@@ -220,6 +220,7 @@ class ModelViewer(val engine: Engine) : android.view.View.OnTouchListener {
*/
fun destroyModel() {
fetchResourcesJob?.cancel()
resourceLoader.asyncCancelLoad()
asset?.let { asset ->
this.scene.removeEntities(asset.entities)
assetLoader.destroyAsset(asset)

View File

@@ -29,7 +29,6 @@ set(GLTFIO_SRCS
${GLTFIO_DIR}/include/gltfio/AssetLoader.h
${GLTFIO_DIR}/include/gltfio/MaterialProvider.h
${GLTFIO_DIR}/include/gltfio/ResourceLoader.h
${GLTFIO_DIR}/include/gltfio/SimpleViewer.h
${GLTFIO_DIR}/include/gltfio/FilamentAsset.h
${GLTFIO_DIR}/include/gltfio/FilamentInstance.h

View File

@@ -34,3 +34,10 @@ Java_com_google_android_filament_gltfio_MaterialProvider_nDestroyMaterialProvide
auto provider = (MaterialProvider*) nativeProvider;
delete provider;
}
extern "C" JNIEXPORT void JNICALL
Java_com_google_android_filament_gltfio_MaterialProvider_nDestroyMaterials(JNIEnv*, jclass,
jlong nativeProvider) {
auto provider = (MaterialProvider*) nativeProvider;
provider->destroyMaterials();
}

View File

@@ -99,3 +99,10 @@ Java_com_google_android_filament_gltfio_ResourceLoader_nAsyncUpdateLoad(JNIEnv*,
ResourceLoader* loader = (ResourceLoader*) nativeLoader;
loader->asyncUpdateLoad();
}
extern "C" JNIEXPORT void JNICALL
Java_com_google_android_filament_gltfio_ResourceLoader_nAsyncCancelLoad(JNIEnv*, jclass,
jlong nativeLoader) {
ResourceLoader* loader = (ResourceLoader*) nativeLoader;
loader->asyncCancelLoad();
}

View File

@@ -78,9 +78,10 @@ import java.nio.Buffer;
public class AssetLoader {
private long mNativeObject;
private Engine mEngine;
private MaterialProvider mMaterialCache;
/**
* Constructs an <code>AssetLoader </code>that can be used to create and destroy instances of
* Constructs an <code>AssetLoader</code> that can be used to create and destroy instances of
* {@link FilamentAsset}.
*
* @param engine the engine that the loader should pass to builder objects
@@ -100,6 +101,7 @@ public class AssetLoader {
}
mEngine = engine;
mMaterialCache = generator;
}
/**
@@ -107,6 +109,7 @@ public class AssetLoader {
*/
public void destroy() {
nDestroyAssetLoader(mNativeObject);
mMaterialCache.destroyMaterials();
mNativeObject = 0;
}
@@ -152,6 +155,32 @@ public class AssetLoader {
return new FilamentAsset(mEngine, nativeAsset);
}
/**
* Adds a new instance to an instanced asset.
*
* Use this with caution. It is more efficient to pre-allocate a max number of instances, and
* gradually add them to the scene as needed. Instances can also be "recycled" by removing and
* re-adding them to the scene.
*
* NOTE: destroyInstance() does not exist because gltfio favors flat arrays for storage of
* entity lists and instance lists, which would be slow to shift. We also wish to discourage
* create/destroy churn, as noted above.
*
* This cannot be called after FilamentAsset#releaseSourceData().
* This cannot be called on a non-instanced asset.
* Animation is not supported in new instances.
* See also AssetLoader#createInstancedAsset().
*/
@Nullable
@SuppressWarnings("unused")
public FilamentInstance createInstance(@NonNull FilamentAsset asset) {
long nativeInstance = nCreateInstance(mNativeObject, asset.getNativeObject());
if (nativeInstance == 0) {
return null;
}
return new FilamentInstance(nativeInstance);
}
/**
* Allows clients to enable diagnostic shading on newly-loaded assets.
*/
@@ -175,6 +204,7 @@ public class AssetLoader {
private static native long nCreateAssetFromJson(long nativeLoader, Buffer buffer, int remaining);
private static native long nCreateInstancedAsset(long nativeLoader, Buffer buffer, int remaining,
long[] nativeInstances);
private static native long nCreateInstance(long nativeLoader, long nativeAsset);
private static native void nEnableDiagnostics(long nativeLoader, boolean enable);
private static native void nDestroyAsset(long nativeLoader, long nativeAsset);
}

View File

@@ -197,7 +197,11 @@ public class FilamentAsset {
if (mAnimator != null) {
return mAnimator;
}
mAnimator = new Animator(nGetAnimator(getNativeObject()));
long nativeAnimator = nGetAnimator(getNativeObject());
if (nativeAnimator == 0) {
throw new IllegalStateException("Unable to create animator");
}
mAnimator = new Animator(nativeAnimator);
return mAnimator;
}
@@ -215,6 +219,7 @@ public class FilamentAsset {
*
* This should only be called after ResourceLoader#loadResources().
* If using Animator, this should be called after getAnimator().
* If this is an instanced asset, this prevents creation of new instances.
*/
public void releaseSourceData() {
nReleaseSourceData(mNativeObject);

View File

@@ -47,10 +47,21 @@ public class MaterialProvider {
mNativeObject = 0;
}
/**
* Destroys all cached materials.
*
* This is not called automatically when MaterialProvider is destroyed, which allows
* clients to take ownership of the cache if desired.
*/
public void destroyMaterials() {
nDestroyMaterials(mNativeObject);
}
long getNativeObject() {
return mNativeObject;
}
private static native long nCreateMaterialProvider(long nativeEngine);
private static native void nDestroyMaterialProvider(long nativeProvider);
private static native void nDestroyMaterials(long nativeProvider);
}

View File

@@ -146,6 +146,16 @@ public class ResourceLoader {
nAsyncUpdateLoad(mNativeObject);
}
/**
* Cancels pending decoder jobs and frees all CPU-side texel data.
*
* Calling this is only necessary if the asyncBeginLoad API was used
* and cancellation is required before progress reaches 100%.
*/
public void asyncCancelLoad() {
nAsyncCancelLoad(mNativeObject);
}
private static native long nCreateResourceLoader(long nativeEngine,
boolean normalizeSkinningWeights, boolean recomputeBoundingBoxes);
private static native void nDestroyResourceLoader(long nativeLoader);
@@ -156,4 +166,5 @@ public class ResourceLoader {
private static native boolean nAsyncBeginLoad(long nativeLoader, long nativeAsset);
private static native float nAsyncGetLoadProgress(long nativeLoader);
private static native void nAsyncUpdateLoad(long nativeLoader);
private static native void nAsyncCancelLoad(long nativeLoader);
}

View File

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

View File

@@ -21,7 +21,7 @@ version = VERSION_NAME
group = GROUP
def isReleaseBuild() {
return VERSION_NAME.contains("SNAPSHOT") == false
return !VERSION_NAME.contains("SNAPSHOT")
}
def getReleaseRepositoryUrl() {

View File

@@ -1,6 +1,6 @@
#Fri Jan 10 16:04:09 PST 2020
#Thu Nov 05 09:33:02 PST 2020
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-6.3-all.zip
distributionUrl=https\://services.gradle.org/distributions/gradle-6.5-all.zip

View File

@@ -15,6 +15,12 @@ Demonstrates how to create a light and a mesh with the attributes required for l
![Lit Cube](../../docs/images/samples/sample_lit_cube.jpg)
### `live-wallpaper`
Demonstrates how to use Filament as renderer for an Android Live Wallpaper.
![Live Wallpaper](../../docs/images/samples/example_live_wallpaper.jpg)
### `image-based-lighting`
Demonstrates how to create image-based lights and load complex meshes:

View File

@@ -1,6 +1,5 @@
apply plugin: 'com.android.application'
apply plugin: 'kotlin-android'
apply plugin: 'kotlin-android-extensions'
apply plugin: FilamentToolsPlugin
project.ext.isSample = true

View File

@@ -1,6 +1,5 @@
apply plugin: 'com.android.application'
apply plugin: 'kotlin-android'
apply plugin: 'kotlin-android-extensions'
apply plugin: FilamentToolsPlugin
project.ext.isSample = true

View File

@@ -1,6 +1,5 @@
apply plugin: 'com.android.application'
apply plugin: 'kotlin-android'
apply plugin: 'kotlin-android-extensions'
apply plugin: FilamentToolsPlugin
project.ext.isSample = true

View File

@@ -1,6 +1,5 @@
apply plugin: 'com.android.application'
apply plugin: 'kotlin-android'
apply plugin: 'kotlin-android-extensions'
apply plugin: FilamentToolsPlugin
project.ext.isSample = true

View File

@@ -1,6 +1,5 @@
apply plugin: 'com.android.application'
apply plugin: 'kotlin-android'
apply plugin: 'kotlin-android-extensions'
apply plugin: FilamentToolsPlugin
project.ext.isSample = true

View File

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

View File

@@ -0,0 +1,18 @@
apply plugin: 'com.android.application'
apply plugin: 'kotlin-android'
project.ext.isSample = true
android {
compileSdkVersion versions.compileSdk
defaultConfig {
applicationId "com.google.android.filament.livewallpaper"
minSdkVersion versions.minSdk
targetSdkVersion versions.targetSdk
}
}
dependencies {
implementation deps.kotlin
implementation project(':filament-android')
}

View File

@@ -0,0 +1,25 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.google.android.filament.livewallpaper">
<uses-feature android:name="android.software.live_wallpaper" />
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/wallpaper_label"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/AppTheme">
<service
android:name=".FilamentLiveWallpaper"
android:label="@string/wallpaper_label"
android:permission="android.permission.BIND_WALLPAPER">
<intent-filter>
<action android:name="android.service.wallpaper.WallpaperService" />
</intent-filter>
<meta-data android:name="android.service.wallpaper" android:resource="@xml/wallpaper" />
</service>
</application>
</manifest>

View File

@@ -0,0 +1,224 @@
/*
* Copyright (C) 2020 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.google.android.filament.livewallpaper
import android.animation.ValueAnimator
import android.app.Service
import android.graphics.Color
import android.graphics.PixelFormat
import android.service.wallpaper.WallpaperService
import android.view.Choreographer
import android.view.Surface
import android.view.SurfaceHolder
import android.view.WindowManager
import android.view.animation.LinearInterpolator
import com.google.android.filament.*
import com.google.android.filament.android.DisplayHelper
import com.google.android.filament.android.UiHelper
class FilamentLiveWallpaper : WallpaperService() {
// Make sure to initialize Filament first
// This loads the JNI library needed by most API calls
companion object {
init {
Filament.init()
}
}
override fun onCreateEngine(): Engine {
return FilamentWallpaperEngine()
}
private inner class FilamentWallpaperEngine : Engine() {
// UiHelper is provided by Filament to manage SurfaceHolder
private lateinit var uiHelper: UiHelper
// DisplayHelper is provided by Filament to manage the display
private lateinit var displayHelper: DisplayHelper
// Choreographer is used to schedule new frames
private lateinit var choreographer: Choreographer
// Engine creates and destroys Filament resources
// Each engine must be accessed from a single thread of your choosing
// Resources cannot be shared across engines
private lateinit var engine: com.google.android.filament.Engine
// A renderer instance is tied to a single surface (SurfaceView, TextureView, etc.)
private lateinit var renderer: Renderer
// A scene holds all the renderable, lights, etc. to be drawn
private lateinit var scene: Scene
// A view defines a viewport, a scene and a camera for rendering
private lateinit var view: View
// Should be pretty obvious :)
private lateinit var camera: Camera
// A swap chain is Filament's representation of a surface
private var swapChain: SwapChain? = null
// Performs the rendering and schedules new frames
private val frameScheduler = FrameCallback()
// We'll use this ValueAnimator to smoothly cycle the background between hues.
private val animator = ValueAnimator.ofFloat(0.0f, 360.0f)
override fun onCreate(surfaceHolder: SurfaceHolder) {
super.onCreate(surfaceHolder)
surfaceHolder.setSizeFromLayout()
surfaceHolder.setFormat(PixelFormat.RGBA_8888)
choreographer = Choreographer.getInstance()
displayHelper = DisplayHelper(this@FilamentLiveWallpaper)
setupUiHelper()
setupFilament()
setupView()
setupScene()
}
private fun setupUiHelper() {
uiHelper = UiHelper(UiHelper.ContextErrorPolicy.DONT_CHECK)
uiHelper.renderCallback = SurfaceCallback()
uiHelper.attachTo(surfaceHolder)
}
private fun setupFilament() {
engine = com.google.android.filament.Engine.create()
renderer = engine.createRenderer()
scene = engine.createScene()
view = engine.createView()
camera = engine.createCamera()
}
private fun setupView() {
scene.skybox = Skybox.Builder().build(engine)
// NOTE: Try to disable post-processing (tone-mapping, etc.) to see the difference
// view.isPostProcessingEnabled = false
// Tell the view which camera we want to use
view.camera = camera
// Tell the view which scene we want to render
view.scene = scene
}
private fun setupScene() {
// Set the exposure on the camera, this exposure follows the sunny f/16 rule
camera.setExposure(16.0f, 1.0f / 125.0f, 100.0f)
startAnimation()
}
private fun startAnimation() {
// Animate the color of the Skybox.
animator.interpolator = LinearInterpolator()
animator.duration = 10000
animator.repeatMode = ValueAnimator.RESTART
animator.repeatCount = ValueAnimator.INFINITE
animator.addUpdateListener { a ->
val hue = a.animatedValue as Float
val color = Color.HSVToColor(floatArrayOf(hue, 1.0f, 1.0f))
scene.skybox?.setColor(floatArrayOf(
Color.red(color) / 255.0f,
Color.green(color) / 255.0f,
Color.blue(color) / 255.0f,
1.0f))
}
animator.start()
}
override fun onVisibilityChanged(visible: Boolean) {
super.onVisibilityChanged(visible)
if (visible) {
choreographer.postFrameCallback(frameScheduler)
animator.start()
} else {
choreographer.removeFrameCallback(frameScheduler)
animator.cancel()
}
}
override fun onDestroy() {
super.onDestroy()
// Stop the animation and any pending frame
choreographer.removeFrameCallback(frameScheduler)
animator.cancel()
// Always detach the surface before destroying the engine
uiHelper.detach()
// Cleanup all resources
engine.destroyRenderer(renderer)
engine.destroyView(view)
engine.destroyScene(scene)
engine.destroyCamera(camera)
// Destroying the engine will free up any resource you may have forgotten
// to destroy, but it's recommended to do the cleanup properly
engine.destroy()
}
inner class FrameCallback : Choreographer.FrameCallback {
override fun doFrame(frameTimeNanos: Long) {
// Schedule the next frame
choreographer.postFrameCallback(this)
// This check guarantees that we have a swap chain
if (uiHelper.isReadyToRender) {
// If beginFrame() returns false you should skip the frame
// This means you are sending frames too quickly to the GPU
if (renderer.beginFrame(swapChain!!, frameTimeNanos)) {
renderer.render(view)
renderer.endFrame()
}
}
}
}
inner class SurfaceCallback : UiHelper.RendererCallback {
override fun onNativeWindowChanged(surface: Surface) {
swapChain?.let { engine.destroySwapChain(it) }
swapChain = engine.createSwapChain(surface)
val display =
(application.getSystemService(Service.WINDOW_SERVICE) as WindowManager)
.defaultDisplay
displayHelper.attach(renderer, display)
}
override fun onDetachedFromSurface() {
displayHelper.detach()
swapChain?.let {
engine.destroySwapChain(it)
// Required to ensure we don't return before Filament is done executing the
// destroySwapChain command, otherwise Android might destroy the Surface
// too early
engine.flushAndWait()
swapChain = null
}
}
override fun onResized(width: Int, height: Int) {
val aspect = width.toDouble() / height.toDouble()
camera.setProjection(45.0, aspect, 0.1, 20.0, Camera.Fov.VERTICAL)
view.viewport = Viewport(0, 0, width, height)
}
}
}
}

View File

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

View File

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

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

View File

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

View File

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

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 10 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

View File

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

View File

@@ -0,0 +1,4 @@
<resources>
<string name="wallpaper_label">Filament Sample Live Wallpaper</string>
<string name="wallpaper_author">Google</string>
</resources>

View File

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

View File

@@ -0,0 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<wallpaper xmlns:android="http://schemas.android.com/apk/res/android"
android:author="@string/wallpaper_author"
android:thumbnail="@drawable/wallpaper_thumb" />

View File

@@ -1,6 +1,5 @@
apply plugin: 'com.android.application'
apply plugin: 'kotlin-android'
apply plugin: 'kotlin-android-extensions'
apply plugin: FilamentToolsPlugin
project.ext.isSample = true

View File

@@ -216,7 +216,9 @@ class MainActivity : Activity() {
// variant of the filamat library.
.optimization(MaterialBuilder.Optimization.NONE)
.build()
// When compiling more than one material variant, it is more efficient to pass an Engine
// instance to reuse the Engine's job system
.build(engine)
if (matPackage.isValid) {
val buffer = matPackage.buffer

View File

@@ -1,6 +1,5 @@
apply plugin: 'com.android.application'
apply plugin: 'kotlin-android'
apply plugin: 'kotlin-android-extensions'
apply plugin: FilamentToolsPlugin
project.ext.isSample = true

View File

@@ -1,6 +1,5 @@
apply plugin: 'com.android.application'
apply plugin: 'kotlin-android'
apply plugin: 'kotlin-android-extensions'
apply plugin: FilamentToolsPlugin
project.ext.isSample = true

View File

@@ -1,6 +1,5 @@
apply plugin: 'com.android.application'
apply plugin: 'kotlin-android'
apply plugin: 'kotlin-android-extensions'
apply plugin: FilamentToolsPlugin
project.ext.isSample = true

View File

@@ -1,6 +1,5 @@
apply plugin: 'com.android.application'
apply plugin: 'kotlin-android'
apply plugin: 'kotlin-android-extensions'
apply plugin: FilamentToolsPlugin
project.ext.isSample = true

View File

@@ -1,6 +1,5 @@
apply plugin: 'com.android.application'
apply plugin: 'kotlin-android'
apply plugin: 'kotlin-android-extensions'
apply plugin: FilamentToolsPlugin
project.ext.isSample = true

View File

@@ -10,6 +10,7 @@ include ':samples:sample-hello-camera'
include ':samples:sample-hello-triangle'
include ':samples:sample-image-based-lighting'
include ':samples:sample-lit-cube'
include ':samples:sample-live-wallpaper'
include ':samples:sample-material-builder'
include ':samples:sample-multi-view'
include ':samples:sample-page-curl'

View File

@@ -41,7 +41,9 @@ function print_help {
echo " -t"
echo " Enable SwiftShader support for Vulkan in desktop builds."
echo " -l"
echo " Combine iOS arm64 and x86_64 into universal libraries (implies -s)."
echo " Build arm64/x86_64 universal libraries."
echo " For iOS, this builds universal binaries for devices and the simulator (implies -s)."
echo " For macOS, this builds universal binaries for both Apple silicon and Intel-based Macs."
echo " -w"
echo " Build Web documents (compiles .md.html files to .html)."
echo ""
@@ -121,7 +123,7 @@ VULKAN_ANDROID_GRADLE_OPTION=""
SWIFTSHADER_OPTION="-DFILAMENT_USE_SWIFTSHADER=OFF"
IOS_BUILD_SIMULATOR=false
IOS_CREATE_UNIVERSAL_LIBRARIES=false
BUILD_UNIVERSAL_LIBRARIES=false
BUILD_GENERATOR=Ninja
BUILD_COMMAND=ninja
@@ -158,6 +160,10 @@ function build_desktop_target {
local lc_name=$(echo "${UNAME}" | tr '[:upper:]' '[:lower:]')
if [[ "${lc_name}" == "darwin" ]]; then
local deployment_target="-DCMAKE_OSX_DEPLOYMENT_TARGET=10.14"
if [[ "${BUILD_UNIVERSAL_LIBRARIES}" == "true" ]]; then
local architectures="-DCMAKE_OSX_ARCHITECTURES=arm64;x86_64"
fi
fi
if [[ ! -d "CMakeFiles" ]] || [[ "${ISSUE_CMAKE_ALWAYS}" == "true" ]]; then
@@ -169,6 +175,7 @@ function build_desktop_target {
-DFILAMENT_ENABLE_JAVA="${FILAMENT_ENABLE_JAVA}" \
${SWIFTSHADER_OPTION} \
${deployment_target} \
${architectures} \
../..
fi
${BUILD_COMMAND} ${build_targets}
@@ -241,14 +248,10 @@ function build_webgl_with_target {
if [[ "${ISSUE_ARCHIVES}" == "true" ]]; then
echo "Generating out/filament-${lc_target}-web.tgz..."
# The web archive has the following subfolders:
# dist...core WASM module and accompanying JS file.
# docs...HTML tutorials for the JS API, accompanying demos, and a reference page.
cd web
tar -cvf "../../filament-${lc_target}-web.tar" -s /^filament-js/dist/ \
filament-js/filament.js
tar -rvf "../../filament-${lc_target}-web.tar" -s /^filament-js/dist/ \
filament-js/filament.wasm
cd web/filament-js
tar -cvf "../../../filament-${lc_target}-web.tar" filament.js
tar -rvf "../../../filament-${lc_target}-web.tar" filament.wasm
tar -rvf "../../../filament-${lc_target}-web.tar" filament.d.ts
cd -
gzip -c "../filament-${lc_target}-web.tar" > "../filament-${lc_target}-web.tgz"
rm "../filament-${lc_target}-web.tar"
@@ -525,7 +528,7 @@ function build_ios {
build_ios_target "Debug" "x86_64" "iphonesimulator"
fi
if [[ "${IOS_CREATE_UNIVERSAL_LIBRARIES}" == "true" ]]; then
if [[ "${BUILD_UNIVERSAL_LIBRARIES}" == "true" ]]; then
build/ios/create-universal-libs.sh \
-o out/ios-debug/filament/lib/universal \
out/ios-debug/filament/lib/arm64 \
@@ -543,7 +546,7 @@ function build_ios {
build_ios_target "Release" "x86_64" "iphonesimulator"
fi
if [[ "${IOS_CREATE_UNIVERSAL_LIBRARIES}" == "true" ]]; then
if [[ "${BUILD_UNIVERSAL_LIBRARIES}" == "true" ]]; then
build/ios/create-universal-libs.sh \
-o out/ios-release/filament/lib/universal \
out/ios-release/filament/lib/arm64 \
@@ -756,9 +759,8 @@ while getopts ":hacfijmp:q:uvslwt" opt; do
;;
l)
IOS_BUILD_SIMULATOR=true
IOS_CREATE_UNIVERSAL_LIBRARIES=true
echo "iOS simulator support enabled."
echo "Creating iOS universal libraries."
BUILD_UNIVERSAL_LIBRARIES=true
echo "Building universal libraries."
;;
w)
ISSUE_WEB_DOCS=true

View File

@@ -8,8 +8,8 @@
#
# The default is release
NDK_VERSION="ndk;21.3.6528147"
ANDROID_NDK_VERSION=21
NDK_VERSION="ndk;22.0.7026061"
ANDROID_NDK_VERSION=22
# Exclude Vulkan from CI builds for Android. (It is enabled for other platforms.)
EXCLUDE_VULKAN=-v

75
build/common/bump-version.sh Executable file
View File

@@ -0,0 +1,75 @@
#!/usr/bin/env bash
set -e
function print_help {
local SELF_NAME
SELF_NAME=$(basename "$0")
echo "$SELF_NAME. Update the Filament version number."
echo ""
echo "Usage:"
echo " $SELF_NAME <new version>"
echo ""
echo "<new version> should be a 3 part semantic version, such as 1.9.3"
echo ""
echo "This script does not interface with git. It is up to the user to commit the change."
echo ""
echo "Options:"
echo " -h"
echo " Print this help message and exit."
}
while getopts "h" opt; do
case ${opt} in
h)
print_help
exit 0
;;
*)
print_help
exit 1
;;
esac
done
shift $((OPTIND - 1))
if [[ "$#" -ne 1 ]]; then
print_help
exit 1
fi
VERSION_REGEX="[[:digit:]]+.[[:digit:]]+.[[:digit:]]+"
NEW_VERSION="$1"
function replace {
FIND_STR="${1//\{\{VERSION\}\}/${VERSION_REGEX}}"
REPLACE_STR="${1//\{\{VERSION\}\}/${NEW_VERSION}}"
local FILE_NAME="$2"
sed -i '' -E "s/${FIND_STR}/${REPLACE_STR}/" "${FILE_NAME}"
}
# The following are the canonical locations where the Filament version number is referenced.
replace \
"implementation 'com.google.android.filament:filament-android:{{VERSION}}'" \
README.md
replace \
"pod 'Filament', '~> {{VERSION}}'" \
README.md
replace \
"VERSION_NAME={{VERSION}}" \
android/gradle.properties
replace \
"spec.version = \"{{VERSION}}\"" \
ios/CocoaPods/Filament.podspec
replace \
":http => \"https:\/\/github.com\/google\/filament\/releases\/download\/v{{VERSION}}\/filament-v{{VERSION}}-ios.tgz\" }" \
ios/CocoaPods/Filament.podspec
replace \
"\"version\": \"{{VERSION}}\"" \
web/filament-js/package.json

175
build/common/release.sh Executable file
View File

@@ -0,0 +1,175 @@
#!/usr/bin/env bash
set -e
function print_help {
local SELF_NAME
SELF_NAME=$(basename "$0")
echo "$SELF_NAME. Merge the release candidate (rc) branch into release and cut a new rc branch."
echo ""
echo "Usage:"
echo " $SELF_NAME [options] <current rc branch new> <new rc branch name>"
echo " $SELF_NAME -c <current rc branch new>"
echo ""
echo "current rc branch name should be the name of an existing rc/* branch"
echo "new rc branch name should be the new rc branch name and should not exist"
echo ""
echo "Example:"
echo " $SELF_NAME rc/1.9.3 rc/1.9.4"
echo ""
echo "Options:"
echo " -c"
echo " List the commits that make up a release and exit."
echo " -h"
echo " Print this help message and exit."
echo " -p"
echo " Automatically push changes to origin (dangerous)."
}
function list_commits {
git log --oneline release.."$1"
}
PUSH_CHANGES=false
LIST_COMMITS=false
while getopts "hpc" opt; do
case ${opt} in
h)
print_help
exit 0
;;
p)
PUSH_CHANGES=true
;;
c)
LIST_COMMITS=true
;;
*)
print_help
exit 1
;;
esac
done
shift $((OPTIND - 1))
if [[ "${LIST_COMMITS}" == "true" ]]; then
if [[ "$#" -ne 1 ]]; then
print_help
exit 1
fi
RC_BRANCH=$1
list_commits "${RC_BRANCH}"
exit 0
fi
if [[ "$#" -ne 2 ]]; then
print_help
exit 1
fi
RC_BRANCH=$1
NEW_RC_BRANCH=$2
####################################################################################################
# Preamble
####################################################################################################
# Check that the RC_BRANCH is a real branch.
git show-branch "${RC_BRANCH}" >/dev/null 2>&1 || {
echo "Branch ${RC_BRANCH} does not exist (try running git fetch first)."
exit 1
}
# Ensure no staged or working changes
if [ ! -z "$(git status --untracked-files=no --porcelain)" ]; then
echo "You have uncommited changes. Please stash or commit before running."
exit 1
fi
# Make sure release, main, and the release candidate branch are up-to-date.
git checkout main
git pull origin main --rebase
git checkout "${RC_BRANCH}"
git pull origin "${RC_BRANCH}" --rebase
git checkout release
git pull origin release --rebase
####################################################################################################
# Merge rc branch into release
####################################################################################################
# We need to merge rc into release in a somewhat roundabout way because we want the merge to always
# favor the changes on the rc branch. Any commits *only* on the release branch should be lost. These
# abandonded commits should only ever be temporary hotfixes.
# See the last part of https://stackoverflow.com/a/27338013/2671441 for more details.
# The benefit of this strategy is that we'll never get any merge conflicts. All of these commands
# can run without human intervention.
git checkout release
# Do a merge commit. The content of this commit does not matter, so we use a strategy that never
# fails. This advances release.
git merge --no-edit -s ours "${RC_BRANCH}"
# Change working tree and index to desired content.
# --detach ensures rc branch will not move when doing the reset in the next step.
git checkout --detach "${RC_BRANCH}"
# Move HEAD to release without changing contents of working tree and index.
git reset --soft release
# 'attach' HEAD to release.
# This ensures release will move when doing 'commit --amend'.
git checkout release
# Change content of merge commit to current index (i.e. content of rc branch).
git commit --amend -C HEAD
####################################################################################################
# Cut a new release candidate branch
####################################################################################################
git checkout main
git branch --track "${NEW_RC_BRANCH}"
####################################################################################################
# Delete the old release candidate branch
####################################################################################################
git branch -D "${RC_BRANCH}"
####################################################################################################
# Push changes
####################################################################################################
if [[ "${PUSH_CHANGES}" == "true" ]]; then
# Push the release branch
git push origin release
# Delete the old rc branch remotely
git push origin --delete "${RC_BRANCH}"
# Push the new rc branch
git push origin "${NEW_RC_BRANCH}"
else
echo ""
echo "Done."
echo ""
echo "Changes have not been pushed."
echo "If everything looks good locally, run the following:"
echo "---------------------------------------------------------"
echo "git push origin release"
echo "git push origin --delete ${RC_BRANCH}"
echo "git push origin ${NEW_RC_BRANCH}"
echo "---------------------------------------------------------"
echo "Or, to undo everything:"
echo "---------------------------------------------------------"
echo "git checkout release && git reset --hard origin/release"
echo "git branch -D ${NEW_RC_BRANCH}"
echo "git checkout --track origin/rc/${RC_BRANCH}"
echo "---------------------------------------------------------"
fi

View File

@@ -1,3 +1,4 @@
libs/viewer/test_settings
filament/test/test_filament --gtest_filter=-FilamentTest.FroxelData:FilamentExposureWithEngineTest.SetExposure:FilamentExposureWithEngineTest.ComputeEV100:RenderingTest.*
filament/test/test_material_parser
libs/math/test_math

View File

@@ -1,8 +1,9 @@
#!/usr/bin/env bash
set -e
SELF_NAME=$(basename "$0")
function print_help {
local SELF_NAME=`basename $0`
echo "$SELF_NAME. Combine multiple static libraries using an archiver tool."
echo ""
echo "Usage:"
@@ -10,7 +11,9 @@ function print_help {
echo ""
echo "Notes:"
echo " <archives> must be a list of absolute paths to static library archives."
echo " This script creates a temporary working directory inside the current directory."
echo " Mach-O universal binaries are supported, but all archives must be homogeneous: either"
echo " all universal, or none."
echo " This script creates temporary working directories inside the current directory."
}
if [[ "$#" -lt 3 ]]; then
@@ -22,43 +25,118 @@ AR_TOOL="$1"
shift
OUTPUT_PATH="$1"
shift
ARCHIVES="$@"
ARCHIVES=("$@")
# Create a temporary working directory named after the destination library.
TEMP_DIR="${OUTPUT_PATH##*/}" # remove leading path, if any
TEMP_DIR="_${TEMP_DIR%.a}" # remove '.a' extension
mkdir -p "${TEMP_DIR}"
function combine_static_libs {
local output_path="$1"
shift
local archives=("$@")
pushd "${TEMP_DIR}" >/dev/null
# Create a temporary working directory named after the destination library.
local temp_dir="${output_path##*/}" # remove leading path, if any
temp_dir="_${temp_dir%.a}" # remove '.a' extension
mkdir -p "${temp_dir}"
for a in ${ARCHIVES}; do
# Create a separate directory for each archive to combine. This is necessary to avoid overriding
# object files from seprate archives that have the same name.
DIR_NAME="${a##*/}" # remove leading path, if any
DIR_NAME="${DIR_NAME%.a}" # remove '.a' extension
mkdir -p "${DIR_NAME}"
pushd "${temp_dir}" >/dev/null
pushd "${DIR_NAME}" >/dev/null
for a in "${archives[@]}"; do
# Create a separate directory for each archive to combine. This is necessary to avoid
# overriding object files from seprate archives that have the same name.
dir_name="${a##*/}" # remove leading path, if any
dir_name="${dir_name%.a}" # remove '.a' extension
mkdir -p "${dir_name}"
# Extract object files from each archive.
"${AR_TOOL}" -x "$a"
pushd "${dir_name}" >/dev/null
# Prepend the library name to the object file to ensure each object file has a unique name.
for o in *.o; do
mv "$o" "${DIR_NAME}_${o}"
# Extract object files from each archive.
"${AR_TOOL}" -x "$a"
# Prepend the library name to the object file to ensure each object file has a unique name.
for o in *.o; do
mv "$o" "${dir_name}_${o}"
done
popd >/dev/null
done
popd >/dev/null
# Combine the library files into a single static library archive.
rm -f "${output_path}"
"${AR_TOOL}" -qc "${output_path}" $(find "${temp_dir}" -iname '*.o')
# Clean up. Delete objects in the temporary working directory. In theory we could leave the
# directory as a "cache" of extracted object files, but it complicates the logic to handle cases
# where object files are removed from a library.
find "${temp_dir}" -iname "*.o" -delete
}
function universal_error {
echo "Error: archives passed to $SELF_NAME must be either all universal, or all non-universal."
echo "Archives: ${ARCHIVES[*]}"
exit 1
}
# Determine if the archives are Mach-O universal binaries.
has_universal=""
for a in "${ARCHIVES[@]}"; do
if file "$a" | grep -q 'Mach-O universal'; then
if [[ "${has_universal}" == "false" ]]; then
universal_error
fi
has_universal=true
else
if [[ "${has_universal}" == "true" ]]; then
universal_error
fi
has_universal=false
fi
done
popd >/dev/null
if [[ "${has_universal}" == "true" ]]; then
# If the archives are universal libraries, we have to do some extra work:
# - "thin" each archive into its individual architectures
# - for each architecture, combine the single-architecture static libraries
# - create a final universal binary from the static libraries
# Combine the library files into a single static library archive.
rm -f "${OUTPUT_PATH}"
"${AR_TOOL}" -qc "${OUTPUT_PATH}" $(find "${TEMP_DIR}" -iname '*.o')
archs_temp_dir="${OUTPUT_PATH##*/}" # remove leading path, if any
archs_temp_dir="_${archs_temp_dir%.a}_archs" # remove '.a' extension
# Clean up. Delete objects in the temporary working directory. In theory we could leave the
# directory as a "cache" of extracted object files, but it complicates the logic to handle cases
# where object files are removed from a library.
find "${TEMP_DIR}" -iname "*.o" -delete
mkdir -p "${archs_temp_dir}"
pushd "${archs_temp_dir}" >/dev/null
# Thin each archive into its architectures.
for a in "${ARCHIVES[@]}"; do
# Determine which architectures are present in the archive.
archs=$(lipo -archs "${a}")
for arch in ${archs}; do
mkdir -p "${arch}"
lipo -thin "${arch}" -output "${arch}/${a##*/}" "$a"
done
done
popd >/dev/null
# Combine each set of single-architecture archives.
arch_outputs=()
for arch_dir in "${archs_temp_dir}"/*/ ; do
arch=$(basename "$arch_dir")
arch_output="${OUTPUT_PATH%.a}_${arch}.a"
arch_outputs+=("$arch_output")
combine_static_libs "$arch_output" $(find "$(pwd)/${archs_temp_dir}/${arch}" -iname '*.a')
done
# Finally, combine the single-architecture archives into a universal binary.
lipo -create "${arch_outputs[@]}" -output "${OUTPUT_PATH}"
# Clean up.
rm "${arch_outputs[@]}"
find "${archs_temp_dir}" -iname "*.a" -delete
else
combine_static_libs "${OUTPUT_PATH}" "${ARCHIVES[@]}"
fi

View File

@@ -0,0 +1,53 @@
# Build the image:
# docker build --no-cache --tag ssfilament -f build/swiftshader/Dockerfile .
# docker tag ssfilament ghcr.io/filament-assets/swiftshader
#
# Publish the image:
# docker login ghcr.io --username <user> --password <token>
# docker push ghcr.io/filament-assets/swiftshader
#
# Run the image and mount the current directory:
# docker run -it -v `pwd`:/trees/filament -t ssfilament
FROM ubuntu:focal
WORKDIR /trees
ARG DEBIAN_FRONTEND=noninteractive
ENV SWIFTSHADER_LD_LIBRARY_PATH=/trees/swiftshader/build
ENV CXXFLAGS='-fno-builtin -Wno-pass-failed'
RUN apt-get update && \
apt-get --no-install-recommends install -y \
apt-transport-https \
apt-utils \
build-essential \
cmake \
ca-certificates \
git \
ninja-build \
python \
python3 \
xorg-dev \
clang-7 \
libc++-7-dev \
libc++abi-7-dev \
lldb
# Ensure that clang is used instead of gcc.
RUN set -eux ;\
update-alternatives --install /usr/bin/clang clang /usr/bin/clang-7 100 ;\
update-alternatives --install /usr/bin/clang++ clang++ /usr/bin/clang++-7 100 ;\
update-alternatives --install /usr/bin/cc cc /usr/bin/clang 100 ;\
update-alternatives --install /usr/bin/c++ c++ /usr/bin/clang++ 100
# Get patch files from the local Filament tree.
COPY build/swiftshader/*.diff .
# Clone SwiftShader, apply patches, and build it.
RUN set -eux ;\
git clone https://swiftshader.googlesource.com/SwiftShader swiftshader ;\
cd swiftshader ;\
git checkout 139f5c3 ;\
git apply /trees/*.diff ;\
cd build ;\
cmake .. -GNinja -DCMAKE_BUILD_TYPE=Release ;\
ninja

56
build/swiftshader/gallery.py Executable file
View File

@@ -0,0 +1,56 @@
#!/usr/bin/env python3
from pathlib import Path
import os
spath = os.path.dirname(os.path.realpath(__file__))
path = Path(spath)
folder = "../../results/"
images = list(path.glob(folder + '*.png'))
images.sort()
gallery = open(path.absolute().joinpath(folder + 'index.html'), 'w')
gallery.write("""<html>
<head>
<script type="module" src="https://unpkg.com/img-comparison-slider@latest/dist/component/component.esm.js"></script>
<script nomodule="" src="https://unpkg.com/img-comparison-slider@latest/dist/component/component.js"></script>
<link rel="stylesheet" href="https://unpkg.com/img-comparison-slider@latest/dist/collection/styles/initial.css"/>
<style>
h2 {
font-weight: normal;
margin-top: 150px;
margin-bottom: 20px;
}
a {
text-decoration: none;
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
color: blue;
}
a:hover {
font-weight: bold;
}
</style>
</head>
<body>
""")
tag = ''
for image in images:
group = image.stem.rstrip('0123456789')
before = f'https://filament-assets.github.io/golden/{group}/{image.name}'
after = image.name
gallery.write('\n')
gallery.write(f'<h2><a href="{image.stem}.json">{image.stem}.json</a></h2>\n')
gallery.write('<img-comparison-slider>\n')
gallery.write(f'<img slot="before" src="{before}" /> <img slot="after" src="{after}" />\n')
gallery.write('</img-comparison-slider>\n')
gallery.write("""</body>
</html>
""")

View File

@@ -0,0 +1,62 @@
diff --git a/src/Vulkan/VkPipeline.cpp b/src/Vulkan/VkPipeline.cpp
index 86913ec72..3b35345af 100644
--- a/src/Vulkan/VkPipeline.cpp
+++ b/src/Vulkan/VkPipeline.cpp
@@ -71,7 +71,56 @@ std::vector<uint32_t> preprocessSpirv(
if(optimize)
{
// Full optimization list taken from spirv-opt.
- opt.RegisterPerformancePasses();
+
+ // We have removed CreateRedundancyEliminationPass because it segfaults when encountering:
+ // %389 = OpCompositeConstruct %7 %386 %387 %388 %86
+ // When inserting an entry into instruction_to_value_ (which is an unordered_map)
+ // This could perhaps be investigated further with help from asan.
+
+ using namespace spvtools;
+ opt.RegisterPass(CreateWrapOpKillPass())
+ .RegisterPass(CreateDeadBranchElimPass())
+ .RegisterPass(CreateMergeReturnPass())
+ .RegisterPass(CreateInlineExhaustivePass())
+ .RegisterPass(CreateAggressiveDCEPass())
+ .RegisterPass(CreatePrivateToLocalPass())
+ .RegisterPass(CreateLocalSingleBlockLoadStoreElimPass())
+ .RegisterPass(CreateLocalSingleStoreElimPass())
+ .RegisterPass(CreateAggressiveDCEPass())
+ .RegisterPass(CreateScalarReplacementPass())
+ .RegisterPass(CreateLocalAccessChainConvertPass())
+ .RegisterPass(CreateLocalSingleBlockLoadStoreElimPass())
+ .RegisterPass(CreateLocalSingleStoreElimPass())
+ .RegisterPass(CreateAggressiveDCEPass())
+ .RegisterPass(CreateLocalMultiStoreElimPass())
+ .RegisterPass(CreateAggressiveDCEPass())
+ .RegisterPass(CreateCCPPass())
+ .RegisterPass(CreateAggressiveDCEPass())
+ .RegisterPass(CreateLoopUnrollPass(true))
+ .RegisterPass(CreateDeadBranchElimPass())
+ .RegisterPass(CreateRedundancyEliminationPass()) // workaround for SEGFAULT
+ .RegisterPass(CreateCombineAccessChainsPass())
+ .RegisterPass(CreateSimplificationPass())
+ .RegisterPass(CreateScalarReplacementPass())
+ .RegisterPass(CreateLocalAccessChainConvertPass())
+ .RegisterPass(CreateLocalSingleBlockLoadStoreElimPass())
+ .RegisterPass(CreateLocalSingleStoreElimPass())
+ .RegisterPass(CreateAggressiveDCEPass())
+ .RegisterPass(CreateSSARewritePass())
+ .RegisterPass(CreateAggressiveDCEPass())
+ .RegisterPass(CreateVectorDCEPass())
+ .RegisterPass(CreateDeadInsertElimPass())
+ .RegisterPass(CreateDeadBranchElimPass())
+ .RegisterPass(CreateSimplificationPass())
+ .RegisterPass(CreateIfConversionPass())
+ .RegisterPass(CreateCopyPropagateArraysPass())
+ .RegisterPass(CreateReduceLoadSizePass())
+ .RegisterPass(CreateAggressiveDCEPass())
+ .RegisterPass(CreateBlockMergePass())
+ .RegisterPass(CreateRedundancyEliminationPass()) // workaround for SEGFAULT
+ .RegisterPass(CreateDeadBranchElimPass())
+ .RegisterPass(CreateBlockMergePass())
+ .RegisterPass(CreateSimplificationPass());
}
std::vector<uint32_t> optimized;

127
build/swiftshader/test.sh Executable file
View File

@@ -0,0 +1,127 @@
#!/bin/bash
set -e
function print_help {
local self_name=$(basename "$0")
echo "This script issues docker commands for testing Filament with SwiftShader."
echo "The usual sequence of commands is: fetch, start, build filament release, and run."
echo ""
echo "Usage:"
echo " $self_name [command]"
echo ""
echo "Commands:"
echo " build filament [debug | release]"
echo " Use the container to build Filament."
echo " build swiftshader [debug | release]"
echo " Use the container to do a clean rebuild of SwiftShader."
echo " (Note that the container already has SwiftShader built.)"
echo " fetch"
echo " Download the docker image from the central repository."
echo " help"
echo " Print this help message."
echo " logs"
echo " Print messages from the container's kernel ring buffer."
echo " This is useful for diagnosing OOM issues."
echo " run [lldb]"
echo " Launch a test inside the container, optionally via lldb."
echo " shell"
echo " Interact with a bash prompt in the container."
echo " start"
echo " Start a container from the image."
echo " stop"
echo " Stop the container."
echo ""
}
# Change the current working directory to the Filament root.
pushd "$(dirname "$0")/../.." > /dev/null
if [[ "$1" == "build" ]] && [[ "$2" == "filament" ]]; then
docker exec runner filament/build.sh -t $3 gltf_viewer
exit $?
fi
if [[ "$1" == "build" ]] && [[ "$2" == "swiftshader" ]]; then
BUILD_TYPE="$3"
BUILD_TYPE="$(tr '[:lower:]' '[:upper:]' <<< ${BUILD_TYPE:0:1})${BUILD_TYPE:1}"
docker exec --workdir /trees/swiftshader runner rm -rf build
docker exec --workdir /trees/swiftshader runner mkdir build
docker exec --workdir /trees/swiftshader/build runner cmake -GNinja -DCMAKE_BUILD_TYPE="$BUILD_TYPE" ..
docker exec --workdir /trees/swiftshader/build runner ninja
exit $?
fi
if [[ "$1" == "fetch" ]]; then
docker pull ghcr.io/filament-assets/swiftshader:latest
docker tag ghcr.io/filament-assets/swiftshader:latest ssfilament
exit $?
fi
if [[ "$1" == "help" ]]; then
print_help
exit 0
fi
if [[ "$1" == "logs" ]]; then
docker exec runner dmesg --human --read-clear
exit $?
fi
if [[ "$1" == "run" ]] && [[ "$2" == "lldb" ]]; then
docker exec -i --workdir /trees/filament/results runner \
lldb --batch -o run -o bt -- \
../out/cmake-release/samples/gltf_viewer \
--headless \
--batch ../libs/viewer/tests/basic.json \
--api vulkan
docker exec runner /trees/filament/build/swiftshader/gallery.py
exit $?
fi
if [[ "$1" == "run" ]]; then
docker exec --tty --workdir /trees/filament/results runner \
/usr/bin/catchsegv \
../out/cmake-release/samples/gltf_viewer \
--headless \
--batch ../libs/viewer/tests/basic.json \
--api vulkan
docker exec runner /trees/filament/build/swiftshader/gallery.py
exit $?
fi
if [[ "$1" == "shell" ]]; then
docker exec --interactive --tty runner /bin/bash
exit $?
fi
# Notes on options being passed to docker's run command:
#
# - The memory constraint seems to prevent an OOM signal in GitHub Actions.
# - The cap / security args allow use of lldb and creation of core dumps.
# - The privileged arg allows use of dmesg for examining OOM logs.
#
# Currently, a GitHub Actions VM has 2 CPUs, 7 GB RAM, and 14 GB of SSD disk space.
#
# Please be aware that Docker Desktop might impose additional resource constraints, and that those
# settings can only be controlled with its GUI. We recommend at least 7 GB of memory and 2 GB swap.
if [[ "$1" == "start" ]]; then
mkdir -p results
docker run --tty --rm --detach --privileged \
--memory 6.5g \
--name runner \
--cap-add=SYS_PTRACE \
--security-opt seccomp=unconfined \
--security-opt apparmor=unconfined \
--volume `pwd`:/trees/filament \
--workdir /trees \
ssfilament
exit $?
fi
if [[ "$1" == "stop" ]]; then
docker container rm runner --force
exit $?
fi
print_help
exit 1

View File

@@ -42,20 +42,22 @@ counter-increment: h6;margin-right:10px}</style><style>.hljs{display:block;overf
&#xA0;&#xA0;&#xA0;&#xA0;<a href="#materialmodels/litmodel/metals" class="level3"><span class="tocNumber">3.1.5&#xA0; </span>Metals</a><br>
&#xA0;&#xA0;&#xA0;&#xA0;<a href="#materialmodels/litmodel/refraction" class="level3"><span class="tocNumber">3.1.6&#xA0; </span>Refraction</a><br>
&#xA0;&#xA0;&#xA0;&#xA0;<a href="#materialmodels/litmodel/reflectance" class="level3"><span class="tocNumber">3.1.7&#xA0; </span>Reflectance</a><br>
&#xA0;&#xA0;&#xA0;&#xA0;<a href="#materialmodels/litmodel/clearcoat" class="level3"><span class="tocNumber">3.1.8&#xA0; </span>Clear coat</a><br>
&#xA0;&#xA0;&#xA0;&#xA0;<a href="#materialmodels/litmodel/clearcoatroughness" class="level3"><span class="tocNumber">3.1.9&#xA0; </span>Clear coat roughness</a><br>
&#xA0;&#xA0;&#xA0;&#xA0;<a href="#materialmodels/litmodel/anisotropy" class="level3"><span class="tocNumber">3.1.10&#xA0; </span>Anisotropy</a><br>
&#xA0;&#xA0;&#xA0;&#xA0;<a href="#materialmodels/litmodel/anisotropydirection" class="level3"><span class="tocNumber">3.1.11&#xA0; </span>Anisotropy direction</a><br>
&#xA0;&#xA0;&#xA0;&#xA0;<a href="#materialmodels/litmodel/ambientocclusion" class="level3"><span class="tocNumber">3.1.12&#xA0; </span>Ambient occlusion</a><br>
&#xA0;&#xA0;&#xA0;&#xA0;<a href="#materialmodels/litmodel/normal" class="level3"><span class="tocNumber">3.1.13&#xA0; </span>Normal</a><br>
&#xA0;&#xA0;&#xA0;&#xA0;<a href="#materialmodels/litmodel/bentnormal" class="level3"><span class="tocNumber">3.1.14&#xA0; </span>Bent normal</a><br>
&#xA0;&#xA0;&#xA0;&#xA0;<a href="#materialmodels/litmodel/clearcoatnormal" class="level3"><span class="tocNumber">3.1.15&#xA0; </span>Clear coat normal</a><br>
&#xA0;&#xA0;&#xA0;&#xA0;<a href="#materialmodels/litmodel/emissive" class="level3"><span class="tocNumber">3.1.16&#xA0; </span>Emissive</a><br>
&#xA0;&#xA0;&#xA0;&#xA0;<a href="#materialmodels/litmodel/post-lightingcolor" class="level3"><span class="tocNumber">3.1.17&#xA0; </span>Post-lighting color</a><br>
&#xA0;&#xA0;&#xA0;&#xA0;<a href="#materialmodels/litmodel/indexofrefraction" class="level3"><span class="tocNumber">3.1.18&#xA0; </span>Index of refraction</a><br>
&#xA0;&#xA0;&#xA0;&#xA0;<a href="#materialmodels/litmodel/transmission" class="level3"><span class="tocNumber">3.1.19&#xA0; </span>Transmission</a><br>
&#xA0;&#xA0;&#xA0;&#xA0;<a href="#materialmodels/litmodel/absorption" class="level3"><span class="tocNumber">3.1.20&#xA0; </span>Absorption</a><br>
&#xA0;&#xA0;&#xA0;&#xA0;<a href="#materialmodels/litmodel/micro-thicknessandthickness" class="level3"><span class="tocNumber">3.1.21&#xA0; </span>Micro-thickness and thickness</a><br>
&#xA0;&#xA0;&#xA0;&#xA0;<a href="#materialmodels/litmodel/sheencolor" class="level3"><span class="tocNumber">3.1.8&#xA0; </span>Sheen color</a><br>
&#xA0;&#xA0;&#xA0;&#xA0;<a href="#materialmodels/litmodel/sheenroughness" class="level3"><span class="tocNumber">3.1.9&#xA0; </span>Sheen roughness</a><br>
&#xA0;&#xA0;&#xA0;&#xA0;<a href="#materialmodels/litmodel/clearcoat" class="level3"><span class="tocNumber">3.1.10&#xA0; </span>Clear coat</a><br>
&#xA0;&#xA0;&#xA0;&#xA0;<a href="#materialmodels/litmodel/clearcoatroughness" class="level3"><span class="tocNumber">3.1.11&#xA0; </span>Clear coat roughness</a><br>
&#xA0;&#xA0;&#xA0;&#xA0;<a href="#materialmodels/litmodel/anisotropy" class="level3"><span class="tocNumber">3.1.12&#xA0; </span>Anisotropy</a><br>
&#xA0;&#xA0;&#xA0;&#xA0;<a href="#materialmodels/litmodel/anisotropydirection" class="level3"><span class="tocNumber">3.1.13&#xA0; </span>Anisotropy direction</a><br>
&#xA0;&#xA0;&#xA0;&#xA0;<a href="#materialmodels/litmodel/ambientocclusion" class="level3"><span class="tocNumber">3.1.14&#xA0; </span>Ambient occlusion</a><br>
&#xA0;&#xA0;&#xA0;&#xA0;<a href="#materialmodels/litmodel/normal" class="level3"><span class="tocNumber">3.1.15&#xA0; </span>Normal</a><br>
&#xA0;&#xA0;&#xA0;&#xA0;<a href="#materialmodels/litmodel/bentnormal" class="level3"><span class="tocNumber">3.1.16&#xA0; </span>Bent normal</a><br>
&#xA0;&#xA0;&#xA0;&#xA0;<a href="#materialmodels/litmodel/clearcoatnormal" class="level3"><span class="tocNumber">3.1.17&#xA0; </span>Clear coat normal</a><br>
&#xA0;&#xA0;&#xA0;&#xA0;<a href="#materialmodels/litmodel/emissive" class="level3"><span class="tocNumber">3.1.18&#xA0; </span>Emissive</a><br>
&#xA0;&#xA0;&#xA0;&#xA0;<a href="#materialmodels/litmodel/post-lightingcolor" class="level3"><span class="tocNumber">3.1.19&#xA0; </span>Post-lighting color</a><br>
&#xA0;&#xA0;&#xA0;&#xA0;<a href="#materialmodels/litmodel/indexofrefraction" class="level3"><span class="tocNumber">3.1.20&#xA0; </span>Index of refraction</a><br>
&#xA0;&#xA0;&#xA0;&#xA0;<a href="#materialmodels/litmodel/transmission" class="level3"><span class="tocNumber">3.1.21&#xA0; </span>Transmission</a><br>
&#xA0;&#xA0;&#xA0;&#xA0;<a href="#materialmodels/litmodel/absorption" class="level3"><span class="tocNumber">3.1.22&#xA0; </span>Absorption</a><br>
&#xA0;&#xA0;&#xA0;&#xA0;<a href="#materialmodels/litmodel/micro-thicknessandthickness" class="level3"><span class="tocNumber">3.1.23&#xA0; </span>Micro-thickness and thickness</a><br>
&#xA0;&#xA0;<a href="#materialmodels/subsurfacemodel" class="level2"><span class="tocNumber">3.2&#xA0; </span>Subsurface model</a><br>
&#xA0;&#xA0;&#xA0;&#xA0;<a href="#materialmodels/subsurfacemodel/thickness" class="level3"><span class="tocNumber">3.2.1&#xA0; </span>Thickness</a><br>
&#xA0;&#xA0;&#xA0;&#xA0;<a href="#materialmodels/subsurfacemodel/subsurfacecolor" class="level3"><span class="tocNumber">3.2.2&#xA0; </span>Subsurface color</a><br>
@@ -135,7 +137,7 @@ This document is part of the <a href="https://github.com/google/filament">Filame
</p><ul>
<li class="minus"><a href="https://github.com/romainguy">Romain Guy</a>, <a href="https://twitter.com/romainguy">@romainguy</a>
</li>
<li class="minus"><a href="https://github.com/pixelflinger">Mathias Agopian</a>, <a href="https://twitter.com/darthmoosious">@romainguy</a></li></ul>
<li class="minus"><a href="https://github.com/pixelflinger">Mathias Agopian</a>, <a href="https://twitter.com/darthmoosious">@darthmoosious</a></li></ul>
<p></p>
<a class="target" name="overview">&#xA0;</a><a class="target" name="overview">&#xA0;</a><a class="target" name="toc2">&#xA0;</a><h1>Overview</h1>
@@ -231,6 +233,8 @@ in <a href="#table_standardproperties">table&#xA0;1</a>.
<tr><td style="text-align:right"> <strong class="asterisk">metallic</strong> </td><td style="text-align:left"> Whether a surface appears to be dielectric (0.0) or conductor (1.0). Often used as a binary value (0 or 1) </td></tr>
<tr><td style="text-align:right"> <strong class="asterisk">roughness</strong> </td><td style="text-align:left"> Perceived smoothness (1.0) or roughness (0.0) of a surface. Smooth surfaces exhibit sharp reflections </td></tr>
<tr><td style="text-align:right"> <strong class="asterisk">reflectance</strong> </td><td style="text-align:left"> Fresnel reflectance at normal incidence for dielectric surfaces. This directly controls the strength of the reflections </td></tr>
<tr><td style="text-align:right"> <strong class="asterisk">sheenColor</strong> </td><td style="text-align:left"> Strength of the sheen layer </td></tr>
<tr><td style="text-align:right"> <strong class="asterisk">sheenRoughness</strong> </td><td style="text-align:left"> Perceived smoothness or roughness of the sheen layer </td></tr>
<tr><td style="text-align:right"> <strong class="asterisk">clearCoat</strong> </td><td style="text-align:left"> Strength of the clear coat layer </td></tr>
<tr><td style="text-align:right"> <strong class="asterisk">clearCoatRoughness</strong> </td><td style="text-align:left"> Perceived smoothness or roughness of the clear coat layer </td></tr>
<tr><td style="text-align:right"> <strong class="asterisk">anisotropy</strong> </td><td style="text-align:left"> Amount of anisotropy in either the tangent or bitangent direction </td></tr>
@@ -257,6 +261,8 @@ The type and range of each property is described in <a href="#table_standardprop
<tr><td style="text-align:right"> <strong class="asterisk">metallic</strong> </td><td style="text-align:center"> float </td><td style="text-align:center"> [0..1] </td><td style="text-align:left"> Should be 0 or 1 </td></tr>
<tr><td style="text-align:right"> <strong class="asterisk">roughness</strong> </td><td style="text-align:center"> float </td><td style="text-align:center"> [0..1] </td><td style="text-align:left"> &#xA0; </td></tr>
<tr><td style="text-align:right"> <strong class="asterisk">reflectance</strong> </td><td style="text-align:center"> float </td><td style="text-align:center"> [0..1] </td><td style="text-align:left"> Prefer values &gt; 0.35 </td></tr>
<tr><td style="text-align:right"> <strong class="asterisk">sheenColor</strong> </td><td style="text-align:center"> float3 </td><td style="text-align:center"> [0..1] </td><td style="text-align:left"> Linear RGB </td></tr>
<tr><td style="text-align:right"> <strong class="asterisk">sheenRoughness</strong> </td><td style="text-align:center"> float </td><td style="text-align:center"> [0..1] </td><td style="text-align:left"> &#xA0; </td></tr>
<tr><td style="text-align:right"> <strong class="asterisk">clearCoat</strong> </td><td style="text-align:center"> float </td><td style="text-align:center"> [0..1] </td><td style="text-align:left"> Should be 0 or 1 </td></tr>
<tr><td style="text-align:right"> <strong class="asterisk">clearCoatRoughness</strong> </td><td style="text-align:center"> float </td><td style="text-align:center"> [0..1] </td><td style="text-align:left"> &#xA0; </td></tr>
<tr><td style="text-align:right"> <strong class="asterisk">anisotropy</strong> </td><td style="text-align:center"> float </td><td style="text-align:center"> [&#x2212;1..1] </td><td style="text-align:left"> Anisotropy is in the tangent direction when this value is positive </td></tr>
@@ -517,11 +523,59 @@ it easy to define from a texture.
</p><p>
See the Index of <a href="#refraction">refraction</a> section for more information about the <code>ior</code> property and refractive
See section <a href="#toc3.1.20">3.1.20</a> for more information about the <code>ior</code> property and refractive
indices.
</p>
<a class="target" name="clearcoat">&#xA0;</a><a class="target" name="materialmodels/litmodel/clearcoat">&#xA0;</a><a class="target" name="toc3.1.8">&#xA0;</a><h3>Clear coat</h3>
<a class="target" name="sheencolor">&#xA0;</a><a class="target" name="materialmodels/litmodel/sheencolor">&#xA0;</a><a class="target" name="toc3.1.8">&#xA0;</a><h3>Sheen color</h3>
<p>
The sheen color controls the color appearance and strength of an optional sheen layer on top of the
base layer described by the properties above. The sheen layer always sits below the clear coat layer
if such a layer is present.
</p><p>
The sheen layer can be used to represent cloth and fabric materials. Please refer to
section <a href="#toc3.3">3.3</a> for more information about cloth and fabric materials.
</p><p>
The effect of <code>sheenColor</code> is shown in <a href="#figure_materialsheencolor">figure&#xA0;7</a>
(click on the image to see a larger version).
</p><p>
</p><center><div class="image" style><a href="images/screenshot_sheen_color.png" target="_blank"><img class="markdeep" src="images/screenshot_sheen_color.png"></a><div class="imagecaption"><a class="target" name="figure_materialsheencolor">&#xA0;</a><b style="font-style:normal;">Figure&#xA0;7:</b> Different sheen colors</div></div></center>
<p></p><p>
</p><div class="admonition note">If you do not need the other properties offered by the standard lit material model but want to
create a cloth-like or fabric-like appearance, it is more efficient to use the dedicated cloth
model described in section <a href="#toc3.3">3.3</a>.</div>
<p></p>
<a class="target" name="sheenroughness">&#xA0;</a><a class="target" name="materialmodels/litmodel/sheenroughness">&#xA0;</a><a class="target" name="toc3.1.9">&#xA0;</a><h3>Sheen roughness</h3>
<p>
The <code>sheenRoughness</code> property is similar to the <code>roughness</code> property but applies only to the
sheen layer.
</p><p>
The effect of <code>sheenRoughness</code> on a rough metal is shown in <a href="#figure_sheenroughnessproperty">figure&#xA0;8</a>
(click on the image to see a larger version). In this picture, the base layer is a dark blue, with
<code>metallic</code> set to <code>0.0</code> and <code>roughness</code> set to <code>1.0</code>.
</p><p>
</p><center><div class="image" style><a href="images/materials/sheen_roughness.png" target="_blank"><img class="markdeep" src="images/materials/sheen_roughness.png"></a><div class="imagecaption"><a class="target" name="figure_sheenroughnessproperty">&#xA0;</a><b style="font-style:normal;">Figure&#xA0;8:</b> <code>sheenRoughness</code> varying from 0.0
(left) to 1.0 (right)</div></div></center>
<p></p>
<a class="target" name="clearcoat">&#xA0;</a><a class="target" name="materialmodels/litmodel/clearcoat">&#xA0;</a><a class="target" name="toc3.1.10">&#xA0;</a><h3>Clear coat</h3>
<p>
@@ -536,7 +590,7 @@ will always be isotropic and dielectric.
</p><p>
</p><center><div class="image" style><a href="images/material_carbon_fiber.png" target="_blank"><img class="markdeep" src="images/material_carbon_fiber.png"></a><div class="imagecaption"><a class="target" name="figure_clearcoat">&#xA0;</a><b style="font-style:normal;">Figure&#xA0;7:</b> Comparison of a carbon-fiber material under the standard material model
</p><center><div class="image" style><a href="images/material_carbon_fiber.png" target="_blank"><img class="markdeep" src="images/material_carbon_fiber.png"></a><div class="imagecaption"><a class="target" name="figure_clearcoat">&#xA0;</a><b style="font-style:normal;">Figure&#xA0;9:</b> Comparison of a carbon-fiber material under the standard material model
(left) and the clear coat model (right)</div></div></center>
<p></p><p>
@@ -547,12 +601,12 @@ parts of the surface that have a clear coat layers and parts that don&apos;t.
</p><p>
The effect of <code>clearCoat</code> on a rough metal is shown in <a href="#figure_clearcoatproperty">figure&#xA0;8</a>
The effect of <code>clearCoat</code> on a rough metal is shown in <a href="#figure_clearcoatproperty">figure&#xA0;10</a>
(click on the image to see a larger version).
</p><p>
</p><center><div class="image" style><a href="images/materials/clear_coat.png" target="_blank"><img class="markdeep" src="images/materials/clear_coat.png"></a><div class="imagecaption"><a class="target" name="figure_clearcoatproperty">&#xA0;</a><b style="font-style:normal;">Figure&#xA0;8:</b> <code>clearCoat</code> varying from 0.0
</p><center><div class="image" style><a href="images/materials/clear_coat.png" target="_blank"><img class="markdeep" src="images/materials/clear_coat.png"></a><div class="imagecaption"><a class="target" name="figure_clearcoatproperty">&#xA0;</a><b style="font-style:normal;">Figure&#xA0;10:</b> <code>clearCoat</code> varying from 0.0
(left) to 1.0 (right)</div></div></center>
<p></p><p>
@@ -560,8 +614,12 @@ The effect of <code>clearCoat</code> on a rough metal is shown in <a href="#figu
</p><div class="admonition warning">The clear coat layer effectively doubles the cost of specular computations. Do not assign a
value, even 0.0, to the clear coat property if you don&apos;t need this second layer.</div>
<p></p><p>
</p><div class="admonition note">The clear coat layer is added on top of the sheen layer if present.</div>
<p></p>
<a class="target" name="clearcoatroughness">&#xA0;</a><a class="target" name="materialmodels/litmodel/clearcoatroughness">&#xA0;</a><a class="target" name="toc3.1.9">&#xA0;</a><h3>Clear coat roughness</h3>
<a class="target" name="clearcoatroughness">&#xA0;</a><a class="target" name="materialmodels/litmodel/clearcoatroughness">&#xA0;</a><a class="target" name="toc3.1.11">&#xA0;</a><h3>Clear coat roughness</h3>
<p>
@@ -570,16 +628,16 @@ clear coat layer.
</p><p>
The effect of <code>clearCoatRoughness</code> on a rough metal is shown in <a href="#figure_clearcoatroughnessproperty">figure&#xA0;9</a>
The effect of <code>clearCoatRoughness</code> on a rough metal is shown in <a href="#figure_clearcoatroughnessproperty">figure&#xA0;11</a>
(click on the image to see a larger version).
</p><p>
</p><center><div class="image" style><a href="images/materials/clear_coat_roughness.png" target="_blank"><img class="markdeep" src="images/materials/clear_coat_roughness.png"></a><div class="imagecaption"><a class="target" name="figure_clearcoatroughnessproperty">&#xA0;</a><b style="font-style:normal;">Figure&#xA0;9:</b> <code>clearCoatRoughness</code> varying from 0.0
</p><center><div class="image" style><a href="images/materials/clear_coat_roughness.png" target="_blank"><img class="markdeep" src="images/materials/clear_coat_roughness.png"></a><div class="imagecaption"><a class="target" name="figure_clearcoatroughnessproperty">&#xA0;</a><b style="font-style:normal;">Figure&#xA0;11:</b> <code>clearCoatRoughness</code> varying from 0.0
(left) to 1.0 (right)</div></div></center>
<p></p>
<a class="target" name="anisotropy">&#xA0;</a><a class="target" name="materialmodels/litmodel/anisotropy">&#xA0;</a><a class="target" name="toc3.1.10">&#xA0;</a><h3>Anisotropy</h3>
<a class="target" name="anisotropy">&#xA0;</a><a class="target" name="materialmodels/litmodel/anisotropy">&#xA0;</a><a class="target" name="toc3.1.12">&#xA0;</a><h3>Anisotropy</h3>
<p>
@@ -589,28 +647,28 @@ model by using the <code>anisotropy</code> property.
</p><p>
</p><center><div class="image" style><a href="images/material_anisotropic.png" target="_blank"><img class="markdeep" src="images/material_anisotropic.png"></a><div class="imagecaption"><a class="target" name="figure_anisotropic">&#xA0;</a><b style="font-style:normal;">Figure&#xA0;10:</b> Comparison of isotropic material
</p><center><div class="image" style><a href="images/material_anisotropic.png" target="_blank"><img class="markdeep" src="images/material_anisotropic.png"></a><div class="imagecaption"><a class="target" name="figure_anisotropic">&#xA0;</a><b style="font-style:normal;">Figure&#xA0;12:</b> Comparison of isotropic material
(left) and anistropic material (right)</div></div></center>
<p></p><p>
The effect of <code>anisotropy</code> on a rough metal is shown in <a href="#figure_anisotropyproperty">figure&#xA0;11</a>
The effect of <code>anisotropy</code> on a rough metal is shown in <a href="#figure_anisotropyproperty">figure&#xA0;13</a>
(click on the image to see a larger version).
</p><p>
</p><center><div class="image" style><a href="images/materials/anisotropy.png" target="_blank"><img class="markdeep" src="images/materials/anisotropy.png"></a><div class="imagecaption"><a class="target" name="figure_anisotropyproperty">&#xA0;</a><b style="font-style:normal;">Figure&#xA0;11:</b> <code>anisotropy</code> varying from 0.0
</p><center><div class="image" style><a href="images/materials/anisotropy.png" target="_blank"><img class="markdeep" src="images/materials/anisotropy.png"></a><div class="imagecaption"><a class="target" name="figure_anisotropyproperty">&#xA0;</a><b style="font-style:normal;">Figure&#xA0;13:</b> <code>anisotropy</code> varying from 0.0
(left) to 1.0 (right)</div></div></center>
<p></p><p>
The <a href="#figure_anisotropydir">figure&#xA0;12</a> below shows how the direction of the anisotropic highlights can be
The <a href="#figure_anisotropydir">figure&#xA0;14</a> below shows how the direction of the anisotropic highlights can be
controlled by using either positive or negative values: positive values define anisotropy in the
tangent direction and negative values in the bitangent direction.
</p><p>
</p><center><div class="image" style><a href="images/screenshot_anisotropy_direction.png" target="_blank"><img class="markdeep" src="images/screenshot_anisotropy_direction.png"></a><div class="imagecaption"><a class="target" name="figure_anisotropydir">&#xA0;</a><b style="font-style:normal;">Figure&#xA0;12:</b> Positive (left) vs negative
</p><center><div class="image" style><a href="images/screenshot_anisotropy_direction.png" target="_blank"><img class="markdeep" src="images/screenshot_anisotropy_direction.png"></a><div class="imagecaption"><a class="target" name="figure_anisotropydir">&#xA0;</a><b style="font-style:normal;">Figure&#xA0;14:</b> Positive (left) vs negative
(right) <code>anisotropy</code> values</div></div></center>
<p></p><p>
@@ -619,7 +677,7 @@ tangent direction and negative values in the bitangent direction.
not assign a value (even 0.0) to the <code>anisotropy</code> property if you don&apos;t need anisotropy.</div>
<p></p>
<a class="target" name="anisotropydirection">&#xA0;</a><a class="target" name="materialmodels/litmodel/anisotropydirection">&#xA0;</a><a class="target" name="toc3.1.11">&#xA0;</a><h3>Anisotropy direction</h3>
<a class="target" name="anisotropydirection">&#xA0;</a><a class="target" name="materialmodels/litmodel/anisotropydirection">&#xA0;</a><a class="target" name="toc3.1.13">&#xA0;</a><h3>Anisotropy direction</h3>
<p>
@@ -629,25 +687,25 @@ come from a texture, encoding the directions local to the surface.
</p><p>
The effect of <code>anisotropyDirection</code> on a metal is shown in <a href="#figure_anisotropydirectionproperty">figure&#xA0;14</a>
The effect of <code>anisotropyDirection</code> on a metal is shown in <a href="#figure_anisotropydirectionproperty">figure&#xA0;16</a>
(click on the image to see a larger version).
</p><p>
</p><center><div class="image" style><a href="images/screenshot_anisotropy.png" target="_blank"><img class="markdeep" src="images/screenshot_anisotropy.png"></a><div class="imagecaption"><a class="target" name="figure_anisotropydirectionproperty">&#xA0;</a><b style="font-style:normal;">Figure&#xA0;13:</b> Anisotropic metal rendered
</p><center><div class="image" style><a href="images/screenshot_anisotropy.png" target="_blank"><img class="markdeep" src="images/screenshot_anisotropy.png"></a><div class="imagecaption"><a class="target" name="figure_anisotropydirectionproperty">&#xA0;</a><b style="font-style:normal;">Figure&#xA0;15:</b> Anisotropic metal rendered
with a direction map</div></div></center>
<p></p><p>
The result shown in <a href="#figure_anisotropydirectionproperty">figure&#xA0;14</a> was obtained using the direction map shown
in <a href="#figure_anisotropydirectionproperty">figure&#xA0;14</a>.
The result shown in <a href="#figure_anisotropydirectionproperty">figure&#xA0;16</a> was obtained using the direction map shown
in <a href="#figure_anisotropydirectionproperty">figure&#xA0;16</a>.
</p><p>
</p><center><div class="image" style><a href="images/screenshot_anisotropy_map.jpg" target="_blank"><img class="markdeep" src="images/screenshot_anisotropy_map.jpg"></a><div class="imagecaption"><a class="target" name="figure_anisotropydirectionproperty">&#xA0;</a><b style="font-style:normal;">Figure&#xA0;14:</b> Example of a direction map</div></div></center>
</p><center><div class="image" style><a href="images/screenshot_anisotropy_map.jpg" target="_blank"><img class="markdeep" src="images/screenshot_anisotropy_map.jpg"></a><div class="imagecaption"><a class="target" name="figure_anisotropydirectionproperty">&#xA0;</a><b style="font-style:normal;">Figure&#xA0;16:</b> Example of a direction map</div></div></center>
<p></p>
<a class="target" name="ambientocclusion">&#xA0;</a><a class="target" name="materialmodels/litmodel/ambientocclusion">&#xA0;</a><a class="target" name="toc3.1.12">&#xA0;</a><h3>Ambient occlusion</h3>
<a class="target" name="ambientocclusion">&#xA0;</a><a class="target" name="materialmodels/litmodel/ambientocclusion">&#xA0;</a><a class="target" name="toc3.1.14">&#xA0;</a><h3>Ambient occlusion</h3>
<p>
@@ -658,11 +716,11 @@ directional, point and spot lights, nor specular lighting.
</p><p>
</p><center><div class="image" style><a href="images/screenshot_ao.jpg" target="_blank"><img class="markdeep" src="images/screenshot_ao.jpg"></a><div class="imagecaption"><a class="target" name="figure_aoexample">&#xA0;</a><b style="font-style:normal;">Figure&#xA0;15:</b> Comparison of materials without diffuse ambient occlusion
</p><center><div class="image" style><a href="images/screenshot_ao.jpg" target="_blank"><img class="markdeep" src="images/screenshot_ao.jpg"></a><div class="imagecaption"><a class="target" name="figure_aoexample">&#xA0;</a><b style="font-style:normal;">Figure&#xA0;17:</b> Comparison of materials without diffuse ambient occlusion
(left) and with (right)</div></div></center>
<p></p>
<a class="target" name="normal">&#xA0;</a><a class="target" name="materialmodels/litmodel/normal">&#xA0;</a><a class="target" name="toc3.1.13">&#xA0;</a><h3>Normal</h3>
<a class="target" name="normal">&#xA0;</a><a class="target" name="materialmodels/litmodel/normal">&#xA0;</a><a class="target" name="toc3.1.15">&#xA0;</a><h3>Normal</h3>
<p>
@@ -675,7 +733,7 @@ space, which means that +Z points outside of the surface.
For example, let&apos;s imagine that we want to render a piece of furniture covered in tufted leather.
Modeling the geometry to accurately represent the tufted pattern would require too many triangles
so we instead bake a high-poly mesh into a normal map. Once the base map is applied to a simplified
mesh, we get the result in <a href="#figure_normalmapped">figure&#xA0;16</a>.
mesh, we get the result in <a href="#figure_normalmapped">figure&#xA0;18</a>.
</p><p>
@@ -683,7 +741,7 @@ Note that the <code>normal</code> property affects the <em class="underscore">ba
</p><p>
</p><center><div class="image" style><a href="images/screenshot_normal_mapping.jpg" target="_blank"><img class="markdeep" src="images/screenshot_normal_mapping.jpg"></a><div class="imagecaption"><a class="target" name="figure_normalmapped">&#xA0;</a><b style="font-style:normal;">Figure&#xA0;16:</b> Low-poly mesh without normal mapping (left)
</p><center><div class="image" style><a href="images/screenshot_normal_mapping.jpg" target="_blank"><img class="markdeep" src="images/screenshot_normal_mapping.jpg"></a><div class="imagecaption"><a class="target" name="figure_normalmapped">&#xA0;</a><b style="font-style:normal;">Figure&#xA0;18:</b> Low-poly mesh without normal mapping (left)
and with (right)</div></div></center>
<p></p><p>
@@ -691,7 +749,7 @@ and with (right)</div></div></center>
</p><div class="admonition warning">Using a normal map increases the runtime cost of the material model.</div>
<p></p>
<a class="target" name="bentnormal">&#xA0;</a><a class="target" name="materialmodels/litmodel/bentnormal">&#xA0;</a><a class="target" name="toc3.1.14">&#xA0;</a><h3>Bent normal</h3>
<a class="target" name="bentnormal">&#xA0;</a><a class="target" name="materialmodels/litmodel/bentnormal">&#xA0;</a><a class="target" name="toc3.1.16">&#xA0;</a><h3>Bent normal</h3>
<p>
@@ -703,16 +761,16 @@ specular ambient occlusion (see section <a href="#toc4.2.24">4.2.24</a> about
</p><p>
Bent normals can greatly increase the visual fidelity of an asset with various cavities and concave
areas, as shown in <a href="#figure_bentnormalmapped">figure&#xA0;17</a>. See the areas of the ears, nostrils and eyes for
areas, as shown in <a href="#figure_bentnormalmapped">figure&#xA0;19</a>. See the areas of the ears, nostrils and eyes for
instance.
</p><p>
</p><center><div class="image" style><a href="images/material_bent_normal.gif" target="_blank"><img class="markdeep" src="images/material_bent_normal.gif"></a><div class="imagecaption"><a class="target" name="figure_bentnormalmapped">&#xA0;</a><b style="font-style:normal;">Figure&#xA0;17:</b> Example of a model rendered with and without a bent normal map. Both
</p><center><div class="image" style><a href="images/material_bent_normal.gif" target="_blank"><img class="markdeep" src="images/material_bent_normal.gif"></a><div class="imagecaption"><a class="target" name="figure_bentnormalmapped">&#xA0;</a><b style="font-style:normal;">Figure&#xA0;19:</b> Example of a model rendered with and without a bent normal map. Both
versions use the same ambient occlusion map.</div></div></center>
<p></p>
<a class="target" name="clearcoatnormal">&#xA0;</a><a class="target" name="materialmodels/litmodel/clearcoatnormal">&#xA0;</a><a class="target" name="toc3.1.15">&#xA0;</a><h3>Clear coat normal</h3>
<a class="target" name="clearcoatnormal">&#xA0;</a><a class="target" name="materialmodels/litmodel/clearcoatnormal">&#xA0;</a><a class="target" name="toc3.1.17">&#xA0;</a><h3>Clear coat normal</h3>
<p>
@@ -721,7 +779,7 @@ behaves otherwise like the <code>normal</code> property.
</p><p>
</p><center><div class="image" style><a href="images/screenshot_clear_coat_normal.jpg" target="_blank"><img class="markdeep" src="images/screenshot_clear_coat_normal.jpg"></a><div class="imagecaption"><a class="target" name="figure_clearcoatnormalmapped">&#xA0;</a><b style="font-style:normal;">Figure&#xA0;18:</b> A material with a clear coat normal
</p><center><div class="image" style><a href="images/screenshot_clear_coat_normal.jpg" target="_blank"><img class="markdeep" src="images/screenshot_clear_coat_normal.jpg"></a><div class="imagecaption"><a class="target" name="figure_clearcoatnormalmapped">&#xA0;</a><b style="font-style:normal;">Figure&#xA0;20:</b> A material with a clear coat normal
map and a surface normal map</div></div></center>
<p></p><p>
@@ -729,7 +787,7 @@ map and a surface normal map</div></div></center>
</p><div class="admonition warning">Using a clear coat normal map increases the runtime cost of the material model.</div>
<p></p>
<a class="target" name="emissive">&#xA0;</a><a class="target" name="materialmodels/litmodel/emissive">&#xA0;</a><a class="target" name="toc3.1.16">&#xA0;</a><h3>Emissive</h3>
<a class="target" name="emissive">&#xA0;</a><a class="target" name="materialmodels/litmodel/emissive">&#xA0;</a><a class="target" name="toc3.1.18">&#xA0;</a><h3>Emissive</h3>
<p>
@@ -757,7 +815,7 @@ not affected by the camera exposure. When the weight is set to 1, the intensity
the camera exposure like with any regular light.
</p>
<a class="target" name="post-lightingcolor">&#xA0;</a><a class="target" name="materialmodels/litmodel/post-lightingcolor">&#xA0;</a><a class="target" name="toc3.1.17">&#xA0;</a><h3>Post-lighting color</h3>
<a class="target" name="post-lightingcolor">&#xA0;</a><a class="target" name="materialmodels/litmodel/post-lightingcolor">&#xA0;</a><a class="target" name="toc3.1.19">&#xA0;</a><h3>Post-lighting color</h3>
<p>
@@ -778,7 +836,7 @@ this option for more information.
<code>postLightingBlending</code> to <code>add</code> and by providing an RGB color with alpha set to <code>0.0</code>.</div>
<p></p>
<a class="target" name="indexofrefraction">&#xA0;</a><a class="target" name="materialmodels/litmodel/indexofrefraction">&#xA0;</a><a class="target" name="toc3.1.18">&#xA0;</a><h3>Index of refraction</h3>
<a class="target" name="indexofrefraction">&#xA0;</a><a class="target" name="materialmodels/litmodel/indexofrefraction">&#xA0;</a><a class="target" name="toc3.1.20">&#xA0;</a><h3>Index of refraction</h3>
<p>
@@ -811,27 +869,28 @@ light to bend further away from the initial path.
<p></p><p>
The appearance of a refractive material will greatly depend on the <code>refractionType</code> and
<code>refractionMode</code> settings of the material. Refer to the <a href="#blendingandtransparency:refractiontype">Blending and transparency: refractionType</a> section and the <a href="#blendingandtransparency:refractionmode">Blending and transparency: refractionMode</a> section for more information.
<code>refractionMode</code> settings of the material. Refer to section <a href="#toc4.2.15">4.2.15</a> and section <a href="#toc4.2.14">4.2.14</a>
for more information.
</p><p>
The effect of <code>ior</code> when <code>refractionMode</code> is set to <code>cubemap</code> and <code>refractionType</code> is set to <code>solid</code>
can be seen in <a href="#figure_iorproperty2">figure&#xA0;19</a> (click on the image to see a larger version).
can be seen in <a href="#figure_iorproperty2">figure&#xA0;21</a> (click on the image to see a larger version).
</p><p>
</p><center><div class="image" style><a href="images/materials/ior.png" target="_blank"><img class="markdeep" src="images/materials/ior.png"></a><div class="imagecaption"><a class="target" name="figure_iorproperty2">&#xA0;</a><b style="font-style:normal;">Figure&#xA0;19:</b> <code>transmission</code> varying from 1.0
</p><center><div class="image" style><a href="images/materials/ior.png" target="_blank"><img class="markdeep" src="images/materials/ior.png"></a><div class="imagecaption"><a class="target" name="figure_iorproperty2">&#xA0;</a><b style="font-style:normal;">Figure&#xA0;21:</b> <code>transmission</code> varying from 1.0
(left) to 1.5 (right)</div></div></center>
<p></p><p>
<a href="#figure_iorproperty">Figure&#xA0;20</a> shows the comparison of a sphere of <code>ior</code> 1.0 with a sphere of <code>ior</code> 1.33, with
<a href="#figure_iorproperty">Figure&#xA0;22</a> shows the comparison of a sphere of <code>ior</code> 1.0 with a sphere of <code>ior</code> 1.33, with
the <code>refractionMode</code> set to <code>screenspace</code> and the <code>refractionType</code> set to <code>solid</code>
(click on the image to see a larger version).
</p><p>
</p><center><div class="image" style><a href="images/material_ior.png" target="_blank"><img class="markdeep" src="images/material_ior.png"></a><div class="imagecaption"><a class="target" name="figure_iorproperty">&#xA0;</a><b style="font-style:normal;">Figure&#xA0;20:</b> <code>ior</code> of 1.0 (left) and 1.33 (right)</div></div></center>
</p><center><div class="image" style><a href="images/material_ior.png" target="_blank"><img class="markdeep" src="images/material_ior.png"></a><div class="imagecaption"><a class="target" name="figure_iorproperty">&#xA0;</a><b style="font-style:normal;">Figure&#xA0;22:</b> <code>ior</code> of 1.0 (left) and 1.33 (right)</div></div></center>
<p></p><p>
@@ -852,7 +911,7 @@ See the <a href="#reflectance">Reflectance</a> section for more information on t
glass, certain plastics, etc.</div>
<p></p>
<a class="target" name="transmission">&#xA0;</a><a class="target" name="materialmodels/litmodel/transmission">&#xA0;</a><a class="target" name="toc3.1.19">&#xA0;</a><h3>Transmission</h3>
<a class="target" name="transmission">&#xA0;</a><a class="target" name="materialmodels/litmodel/transmission">&#xA0;</a><a class="target" name="toc3.1.21">&#xA0;</a><h3>Transmission</h3>
<p>
@@ -869,12 +928,12 @@ diffuse component is not visible anymore, only the specular component is.
</p><p>
The effect of <code>transmission</code> on a glossy dielectric (<code>ior</code> of 1.5, <code>refractionMode</code> set to
<code>cubemap</code>, <code>refractionType</code> set to <code>solid</code>) is shown in <a href="#figure_transmissionproperty">figure&#xA0;21</a>
<code>cubemap</code>, <code>refractionType</code> set to <code>solid</code>) is shown in <a href="#figure_transmissionproperty">figure&#xA0;23</a>
(click on the image to see a larger version).
</p><p>
</p><center><div class="image" style><a href="images/materials/transmission.png" target="_blank"><img class="markdeep" src="images/materials/transmission.png"></a><div class="imagecaption"><a class="target" name="figure_transmissionproperty">&#xA0;</a><b style="font-style:normal;">Figure&#xA0;21:</b> <code>transmission</code> varying from 0.0
</p><center><div class="image" style><a href="images/materials/transmission.png" target="_blank"><img class="markdeep" src="images/materials/transmission.png"></a><div class="imagecaption"><a class="target" name="figure_transmissionproperty">&#xA0;</a><b style="font-style:normal;">Figure&#xA0;23:</b> <code>transmission</code> varying from 0.0
(left) to 1.0 (right)</div></div></center>
<p></p><p>
@@ -883,17 +942,17 @@ The effect of <code>transmission</code> on a glossy dielectric (<code>ior</code>
materials.</div>
<p></p>
<a class="target" name="absorption">&#xA0;</a><a class="target" name="materialmodels/litmodel/absorption">&#xA0;</a><a class="target" name="toc3.1.20">&#xA0;</a><h3>Absorption</h3>
<a class="target" name="absorption">&#xA0;</a><a class="target" name="materialmodels/litmodel/absorption">&#xA0;</a><a class="target" name="toc3.1.22">&#xA0;</a><h3>Absorption</h3>
<p>
The <code>absorption</code> property defines the absorption coefficients of light transmitted through the
material. <a href="#figure_absorptionexample">Figure&#xA0;22</a> shows the effect of <code>absorption</code> on a refracting object with
material. <a href="#figure_absorptionexample">Figure&#xA0;24</a> shows the effect of <code>absorption</code> on a refracting object with
an index of refraction of 1.5 and a base color set to white.
</p><p>
</p><center><div class="image" style><a href="images/material_absorption.png" target="_blank"><img class="markdeep" src="images/material_absorption.png"></a><div class="imagecaption"><a class="target" name="figure_absorptionexample">&#xA0;</a><b style="font-style:normal;">Figure&#xA0;22:</b> Refracting object without (left)
</p><center><div class="image" style><a href="images/material_absorption.png" target="_blank"><img class="markdeep" src="images/material_absorption.png"></a><div class="imagecaption"><a class="target" name="figure_absorptionexample">&#xA0;</a><b style="font-style:normal;">Figure&#xA0;24:</b> Refracting object without (left)
and with (right) absorption</div></div></center>
<p></p><p>
@@ -917,13 +976,13 @@ $$color \cdot (1 - absorption)$$
</p><p>
The effect of varying the <code>absorption</code> coefficients is shown in <a href="#figure_absorptionproperty">figure&#xA0;23</a>
The effect of varying the <code>absorption</code> coefficients is shown in <a href="#figure_absorptionproperty">figure&#xA0;25</a>
(click on the image to see a larger version). In this picture, the object has a fixed <code>thickness</code>
of 4.5 and an index of refraction set to 1.3.
</p><p>
</p><center><div class="image" style><a href="images/materials/absorption.png" target="_blank"><img class="markdeep" src="images/materials/absorption.png"></a><div class="imagecaption"><a class="target" name="figure_absorptionproperty">&#xA0;</a><b style="font-style:normal;">Figure&#xA0;23:</b> <code>absorption</code> varying from (0.0, 0.02, 0.14)
</p><center><div class="image" style><a href="images/materials/absorption.png" target="_blank"><img class="markdeep" src="images/materials/absorption.png"></a><div class="imagecaption"><a class="target" name="figure_absorptionproperty">&#xA0;</a><b style="font-style:normal;">Figure&#xA0;25:</b> <code>absorption</code> varying from (0.0, 0.02, 0.14)
(left) to (0.0, 0.36, 2.3) (right)</div></div></center>
<p></p><p>
@@ -943,7 +1002,7 @@ While this computation can be done in the material itself we recommend doing it
possible. Filament provides an API for this purpose, <code>Color::absorptionAtDistance()</code>.
</p>
<a class="target" name="micro-thicknessandthickness">&#xA0;</a><a class="target" name="materialmodels/litmodel/micro-thicknessandthickness">&#xA0;</a><a class="target" name="toc3.1.21">&#xA0;</a><h3>Micro-thickness and thickness</h3>
<a class="target" name="micro-thicknessandthickness">&#xA0;</a><a class="target" name="materialmodels/litmodel/micro-thicknessandthickness">&#xA0;</a><a class="target" name="toc3.1.23">&#xA0;</a><h3>Micro-thickness and thickness</h3>
<p>
@@ -973,23 +1032,23 @@ rays are refracted.
</p><p>
The effect <code>thickness</code> in a solid volume with <code>refractionMode</code> set to <code>screenSpace</code> is shown in
<a href="#figure_thicknessproperty">figure&#xA0;24</a> (click on the image to see a larger version). Note how the <code>thickness</code>
<a href="#figure_thicknessproperty">figure&#xA0;26</a> (click on the image to see a larger version). Note how the <code>thickness</code>
value not only changes the effect of <code>absorption</code> but also modifies the direction of the refracted
light.
</p><p>
</p><center><div class="image" style><a href="images/materials/thickness.png" target="_blank"><img class="markdeep" src="images/materials/thickness.png"></a><div class="imagecaption"><a class="target" name="figure_thicknessproperty">&#xA0;</a><b style="font-style:normal;">Figure&#xA0;24:</b> <code>thickness</code> varying from 0.0
</p><center><div class="image" style><a href="images/materials/thickness.png" target="_blank"><img class="markdeep" src="images/materials/thickness.png"></a><div class="imagecaption"><a class="target" name="figure_thicknessproperty">&#xA0;</a><b style="font-style:normal;">Figure&#xA0;26:</b> <code>thickness</code> varying from 0.0
(left) to 2.0 (right)</div></div></center>
<p></p><p>
<a href="#figure_varyingthickness">Figure&#xA0;25</a> shows what a prism with spatially varying <code>thickness</code> looks like when
<a href="#figure_varyingthickness">Figure&#xA0;27</a> shows what a prism with spatially varying <code>thickness</code> looks like when
the <code>refractionType</code> is set to <code>solid</code> and <code>absorption</code> coefficients are set.
</p><p>
</p><center><div class="image" style><a href="images/material_thickness.png" target="_blank"><img class="markdeep" src="images/material_thickness.png"></a><div class="imagecaption"><a class="target" name="figure_varyingthickness">&#xA0;</a><b style="font-style:normal;">Figure&#xA0;25:</b> <code>thickness</code> varying from 0.0 at the top of the prism to 3.0 at the
</p><center><div class="image" style><a href="images/material_thickness.png" target="_blank"><img class="markdeep" src="images/material_thickness.png"></a><div class="imagecaption"><a class="target" name="figure_varyingthickness">&#xA0;</a><b style="font-style:normal;">Figure&#xA0;27:</b> <code>thickness</code> varying from 0.0 at the top of the prism to 3.0 at the
bottom of the prism</div></div></center>
<p></p>
@@ -1014,19 +1073,19 @@ forward/backward scattering. Some fabrics also exhibit two-tone specular colors
</p><p>
<a href="#figure_materialcloth">Figure&#xA0;26</a> shows how the standard material model fails to capture the appearance of a
<a href="#figure_materialcloth">Figure&#xA0;28</a> shows how the standard material model fails to capture the appearance of a
sample of denim fabric. The surface appears rigid (almost plastic-like), more similar to a tarp
than a piece of clothing. This figure also shows how important the softer specular lobe caused by
absorption and scattering is to the faithful recreation of the fabric.
</p><p>
</p><center><div class="image" style><a href="images/screenshot_cloth.png" target="_blank"><img class="markdeep" src="images/screenshot_cloth.png"></a><div class="imagecaption"><a class="target" name="figure_materialcloth">&#xA0;</a><b style="font-style:normal;">Figure&#xA0;26:</b> Comparison of denim fabric rendered using the standard model
</p><center><div class="image" style><a href="images/screenshot_cloth.png" target="_blank"><img class="markdeep" src="images/screenshot_cloth.png"></a><div class="imagecaption"><a class="target" name="figure_materialcloth">&#xA0;</a><b style="font-style:normal;">Figure&#xA0;28:</b> Comparison of denim fabric rendered using the standard model
(left) and the cloth model (right)</div></div></center>
<p></p><p>
Velvet is an interesting use case for a cloth material model. As shown in <a href="#figure_materialvelvet">figure&#xA0;27</a>
Velvet is an interesting use case for a cloth material model. As shown in <a href="#figure_materialvelvet">figure&#xA0;29</a>
this type of fabric exhibits strong rim lighting due to forward and backward scattering. These
scattering events are caused by fibers standing straight at the surface of the fabric. When the
incident light comes from the direction opposite to the view direction, the fibers will forward
@@ -1035,7 +1094,7 @@ direction, the fibers will scatter the light backward.
</p><p>
</p><center><div class="image" style><a href="images/screenshot_cloth_velvet.png" target="_blank"><img class="markdeep" src="images/screenshot_cloth_velvet.png"></a><div class="imagecaption"><a class="target" name="figure_materialvelvet">&#xA0;</a><b style="font-style:normal;">Figure&#xA0;27:</b> Velvet fabric showcasing forward and
</p><center><div class="image" style><a href="images/screenshot_cloth_velvet.png" target="_blank"><img class="markdeep" src="images/screenshot_cloth_velvet.png"></a><div class="imagecaption"><a class="target" name="figure_materialvelvet">&#xA0;</a><b style="font-style:normal;">Figure&#xA0;29:</b> Velvet fabric showcasing forward and
backward scattering</div></div></center>
<p></p><p>
@@ -1097,12 +1156,12 @@ two-tone specular materials.
</p><p>
The effect of <code>sheenColor</code> is shown in <a href="#figure_materialclothsheen">figure&#xA0;28</a>
The effect of <code>sheenColor</code> is shown in <a href="#figure_materialclothsheen">figure&#xA0;30</a>
(click on the image to see a larger version).
</p><p>
</p><center><div class="image" style><a href="images/screenshot_cloth_sheen.png" target="_blank"><img class="markdeep" src="images/screenshot_cloth_sheen.png"></a><div class="imagecaption"><a class="target" name="figure_materialclothsheen">&#xA0;</a><b style="font-style:normal;">Figure&#xA0;28:</b> Blue fabric without (left) and with (right) sheen</div></div></center>
</p><center><div class="image" style><a href="images/screenshot_cloth_sheen.png" target="_blank"><img class="markdeep" src="images/screenshot_cloth_sheen.png"></a><div class="imagecaption"><a class="target" name="figure_materialclothsheen">&#xA0;</a><b style="font-style:normal;">Figure&#xA0;30:</b> Blue fabric without (left) and with (right) sheen</div></div></center>
<p></p>
<a class="target" name="subsurfacecolor">&#xA0;</a><a class="target" name="materialmodels/clothmodel/subsurfacecolor">&#xA0;</a><a class="target" name="toc3.3.2">&#xA0;</a><h3>Subsurface color</h3>
@@ -1119,12 +1178,12 @@ useful to create softer fabrics.
<p></p><p>
The effect of <code>subsurfaceColor</code> is shown in <a href="#figure_materialclothsubsurface">figure&#xA0;29</a>
The effect of <code>subsurfaceColor</code> is shown in <a href="#figure_materialclothsubsurface">figure&#xA0;31</a>
(click on the image to see a larger version).
</p><p>
</p><center><div class="image" style><a href="images/screenshot_cloth_subsurface.png" target="_blank"><img class="markdeep" src="images/screenshot_cloth_subsurface.png"></a><div class="imagecaption"><a class="target" name="figure_materialclothsubsurface">&#xA0;</a><b style="font-style:normal;">Figure&#xA0;29:</b> White cloth (left column) vs white cloth with
</p><center><div class="image" style><a href="images/screenshot_cloth_subsurface.png" target="_blank"><img class="markdeep" src="images/screenshot_cloth_subsurface.png"></a><div class="imagecaption"><a class="target" name="figure_materialclothsubsurface">&#xA0;</a><b style="font-style:normal;">Figure&#xA0;31:</b> White cloth (left column) vs white cloth with
brown subsurface scatting (right)</div></div></center>
<p></p>
@@ -1160,12 +1219,12 @@ the blending mode specified by the <code>postLightingBlending</code> material op
</p><p>
<a href="#figure_materialunlit">Figure&#xA0;30</a> shows an example of the unlit material model
<a href="#figure_materialunlit">Figure&#xA0;32</a> shows an example of the unlit material model
(click on the image to see a larger version).
</p><p>
</p><center><div class="image" style><a href="images/screenshot_unlit.jpg" target="_blank"><img class="markdeep" src="images/screenshot_unlit.jpg"></a><div class="imagecaption"><a class="target" name="figure_materialunlit">&#xA0;</a><b style="font-style:normal;">Figure&#xA0;30:</b> The unlit model is used to render debug information</div></div></center>
</p><center><div class="image" style><a href="images/screenshot_unlit.jpg" target="_blank"><img class="markdeep" src="images/screenshot_unlit.jpg"></a><div class="imagecaption"><a class="target" name="figure_materialunlit">&#xA0;</a><b style="font-style:normal;">Figure&#xA0;32:</b> The unlit model is used to render debug information</div></div></center>
<p></p>
<a class="target" name="specularglossiness">&#xA0;</a><a class="target" name="materialmodels/specularglossiness">&#xA0;</a><a class="target" name="toc3.5">&#xA0;</a><h2>Specular glossiness</h2>
@@ -1241,7 +1300,7 @@ the JSON object notation:
<span class="line"> // fragment shader</span>
<span class="line">}</span></code></pre><p>
A minimum viable material definition must contain a <code>material</code> section and a <code>fragment</code> block. The
A minimum viable material definition must contain a <code>material</code> preamble and a <code>fragment</code> block. The
<code>vertex</code> block is optional.
</p>
@@ -1713,33 +1772,33 @@ non-shader data.
<p></p><p>
</p><ul>
<li class="minus"><code>default</code>: the transparent object is rendered normally (as seen in <a href="#figure_transparencydefault">figure&#xA0;31</a>),
<li class="minus"><code>default</code>: the transparent object is rendered normally (as seen in <a href="#figure_transparencydefault">figure&#xA0;33</a>),
honoring the <code>culling</code> mode, etc.
</li>
<li class="minus"><code>twoPassesOneSide</code>: the transparent object is first rendered in the depth buffer, then again in
the color buffer, honoring the <code>culling</code> mode. This effectively renders only half of the
transparent object as shown in <a href="#figure_transparencytwopassesoneside">figure&#xA0;32</a>.
transparent object as shown in <a href="#figure_transparencytwopassesoneside">figure&#xA0;34</a>.
</li>
<li class="minus"><code>twoPassesTwoSides</code>: the transparent object is rendered twice in the color buffer: first with its
back faces, then with its front faces. This mode lets you render both set of faces while reducing
or eliminating sorting issues, as shown in <a href="#figure_transparencytwopassestwosides">figure&#xA0;33</a>.
or eliminating sorting issues, as shown in <a href="#figure_transparencytwopassestwosides">figure&#xA0;35</a>.
<code>twoPassesTwoSides</code> can be combined with <code>doubleSided</code> for better effect.</li></ul>
<p></p><pre class="listing tilde"><code><span class="line">material {</span>
<span class="line"> transparency : twoPassesOneSide</span>
<span class="line">}</span></code></pre><p>
</p><center><div class="image" style><a href="images/screenshot_transparency_default.png" target="_blank"><img class="markdeep" src="images/screenshot_transparency_default.png"></a><div class="imagecaption"><a class="target" name="figure_transparencydefault">&#xA0;</a><b style="font-style:normal;">Figure&#xA0;31:</b> This double sided model shows the type of sorting issues transparent
</p><center><div class="image" style><a href="images/screenshot_transparency_default.png" target="_blank"><img class="markdeep" src="images/screenshot_transparency_default.png"></a><div class="imagecaption"><a class="target" name="figure_transparencydefault">&#xA0;</a><b style="font-style:normal;">Figure&#xA0;33:</b> This double sided model shows the type of sorting issues transparent
objects can be subject to in <code>default</code> mode</div></div></center>
<p></p><p>
</p><center><div class="image" style><a href="images/screenshot_twopasses_oneside.png" target="_blank"><img class="markdeep" src="images/screenshot_twopasses_oneside.png"></a><div class="imagecaption"><a class="target" name="figure_transparencytwopassesoneside">&#xA0;</a><b style="font-style:normal;">Figure&#xA0;32:</b> In <code>twoPassesOneSide</code> mode, only one set of faces is visible
</p><center><div class="image" style><a href="images/screenshot_twopasses_oneside.png" target="_blank"><img class="markdeep" src="images/screenshot_twopasses_oneside.png"></a><div class="imagecaption"><a class="target" name="figure_transparencytwopassesoneside">&#xA0;</a><b style="font-style:normal;">Figure&#xA0;34:</b> In <code>twoPassesOneSide</code> mode, only one set of faces is visible
and correctly sorted</div></div></center>
<p></p><p>
</p><center><div class="image" style><a href="images/screenshot_twopasses_twosides.png" target="_blank"><img class="markdeep" src="images/screenshot_twopasses_twosides.png"></a><div class="imagecaption"><a class="target" name="figure_transparencytwopassestwosides">&#xA0;</a><b style="font-style:normal;">Figure&#xA0;33:</b> In <code>twoPassesTwoSides</code> mode, both set of faces are visible
</p><center><div class="image" style><a href="images/screenshot_twopasses_twosides.png" target="_blank"><img class="markdeep" src="images/screenshot_twopasses_twosides.png"></a><div class="imagecaption"><a class="target" name="figure_transparencytwopassestwosides">&#xA0;</a><b style="font-style:normal;">Figure&#xA0;35:</b> In <code>twoPassesTwoSides</code> mode, both set of faces are visible
and sorting issues are minimized or eliminated</div></div></center>
<p></p>
@@ -1905,14 +1964,14 @@ and sorting issues are minimized or eliminated</div></div></center>
</p></dd><dt>Description</dt><dd><p> When adding a clear coat layer, the change in index of refraction (IoR) is taken into account
to modify the specular color of the base layer. This appears to darken <code>baseColor</code>. When this
effect is disabled, <code>baseColor</code> is left unmodified. See <a href="#figure_clearcoatiorchange">figure&#xA0;34</a> for an
effect is disabled, <code>baseColor</code> is left unmodified. See <a href="#figure_clearcoatiorchange">figure&#xA0;36</a> for an
example of how this property can affect a red metallic base layer.
</p></dd></dl><p></p><pre class="listing tilde"><code><span class="line">material {</span>
<span class="line"> clearCoatIorChange : false</span>
<span class="line">}</span></code></pre><p>
</p><center><div class="image" style><a href="images/screenshot_clear_coat_ior_change.jpg" target="_blank"><img class="markdeep" src="images/screenshot_clear_coat_ior_change.jpg"></a><div class="imagecaption"><a class="target" name="figure_clearcoatiorchange">&#xA0;</a><b style="font-style:normal;">Figure&#xA0;34:</b> The same rough metallic ball with a clear coat layer rendered
</p><center><div class="image" style><a href="images/screenshot_clear_coat_ior_change.jpg" target="_blank"><img class="markdeep" src="images/screenshot_clear_coat_ior_change.jpg"></a><div class="imagecaption"><a class="target" name="figure_clearcoatiorchange">&#xA0;</a><b style="font-style:normal;">Figure&#xA0;36:</b> The same rough metallic ball with a clear coat layer rendered
with <code>clearCoatIorChange</code> enabled (left) and disabled
(right).</div></div></center>
@@ -1928,21 +1987,21 @@ with <code>clearCoatIorChange</code> enabled (left) and disabled
</p></dd><dt>Description</dt><dd><p> Multi-bounce ambient occlusion takes into account interreflections when applying ambient
occlusion to image-based lighting. Turning this feature on avoids over-darkening occluded
areas. It also takes the surface color into account to generate colored ambient occlusion.
<a href="#figure_multibounceao">Figure&#xA0;35</a> compares the ambient occlusion term of a surface with and without
<a href="#figure_multibounceao">Figure&#xA0;37</a> compares the ambient occlusion term of a surface with and without
multi-bounce ambient occlusion. Notice how multi-bounce ambient occlusion introduces color
in the occluded areas. <a href="#figure_multibounceaoanimated">Figure&#xA0;36</a> toggles between multi-bounce ambient
in the occluded areas. <a href="#figure_multibounceaoanimated">Figure&#xA0;38</a> toggles between multi-bounce ambient
occlusion on and off on a lit brick material to highlight the effects of this property.
</p></dd></dl><p></p><pre class="listing tilde"><code><span class="line">material {</span>
<span class="line"> multiBounceAmbientOcclusion : true</span>
<span class="line">}</span></code></pre><p>
</p><center><div class="image" style><a href="images/screenshot_multi_bounce_ao.jpg" target="_blank"><img class="markdeep" src="images/screenshot_multi_bounce_ao.jpg"></a><div class="imagecaption"><a class="target" name="figure_multibounceao">&#xA0;</a><b style="font-style:normal;">Figure&#xA0;35:</b> Brick texture amient occlusion map rendered with multi-bounce ambient
</p><center><div class="image" style><a href="images/screenshot_multi_bounce_ao.jpg" target="_blank"><img class="markdeep" src="images/screenshot_multi_bounce_ao.jpg"></a><div class="imagecaption"><a class="target" name="figure_multibounceao">&#xA0;</a><b style="font-style:normal;">Figure&#xA0;37:</b> Brick texture amient occlusion map rendered with multi-bounce ambient
occclusion enabled (left) and disabled (right).</div></div></center>
<p></p><p>
</p><center><div class="image" style><a href="images/screenshot_multi_bounce_ao.gif" target="_blank"><img class="markdeep" src="images/screenshot_multi_bounce_ao.gif"></a><div class="imagecaption"><a class="target" name="figure_multibounceaoanimated">&#xA0;</a><b style="font-style:normal;">Figure&#xA0;36:</b> Brick texture rendered with multi-bounce ambient
</p><center><div class="image" style><a href="images/screenshot_multi_bounce_ao.gif" target="_blank"><img class="markdeep" src="images/screenshot_multi_bounce_ao.gif"></a><div class="imagecaption"><a class="target" name="figure_multibounceaoanimated">&#xA0;</a><b style="font-style:normal;">Figure&#xA0;38:</b> Brick texture rendered with multi-bounce ambient
occclusion enabled and disabled.</div></div></center>
<p></p>
@@ -1959,7 +2018,7 @@ occclusion enabled and disabled.</div></div></center>
</p></dd><dt>Description</dt><dd><p> Static ambient occlusion maps and dynamic ambient occlusion (SSAO, etc.) apply to diffuse
indirect lighting. When setting this property to other than <code>none</code>, a new ambient occlusion
term is derived from the surface roughness and applied to specular indirect lighting.
This effect helps remove unwanted specular reflections as shown in <a href="#figure_specularao">figure&#xA0;37</a>.
This effect helps remove unwanted specular reflections as shown in <a href="#figure_specularao">figure&#xA0;39</a>.
When this value is set to <code>simple</code>, Filament uses a cheap but approximate method of computing
the specular ambient occlusion term. If this value is set to <code>bentNormals</code>, Filament will use
a much more accurate but much more expensive method. <code>bentNormals</code> only works if the material
@@ -1970,7 +2029,7 @@ occclusion enabled and disabled.</div></div></center>
<span class="line"> specularAmbientOcclusion : simple</span>
<span class="line">}</span></code></pre><p>
</p><center><div class="image" style><a href="images/screenshot_specular_ao.gif" target="_blank"><img class="markdeep" src="images/screenshot_specular_ao.gif"></a><div class="imagecaption"><a class="target" name="figure_specularao">&#xA0;</a><b style="font-style:normal;">Figure&#xA0;37:</b> Comparison of specular ambient occlusion on and off. The effect is
</p><center><div class="image" style><a href="images/screenshot_specular_ao.gif" target="_blank"><img class="markdeep" src="images/screenshot_specular_ao.gif"></a><div class="imagecaption"><a class="target" name="figure_specularao">&#xA0;</a><b style="font-style:normal;">Figure&#xA0;39:</b> Comparison of specular ambient occlusion on and off. The effect is
particularly visible under the hose.</div></div></center>
<p></p>
@@ -2179,6 +2238,8 @@ plastic with bump mapping:
<span class="line"> <span class="hljs-type">float</span> ambientOcclusion; <span class="hljs-comment">// default: 0.0</span></span>
<span class="line"></span>
<span class="line"> <span class="hljs-comment">// not available when the shading model is subsurface or cloth</span></span>
<span class="line"> float3 sheenColor; <span class="hljs-comment">// default: float3(0.0)</span></span>
<span class="line"> <span class="hljs-type">float</span> sheenRoughness; <span class="hljs-comment">// default: 0.0</span></span>
<span class="line"> <span class="hljs-type">float</span> clearCoat; <span class="hljs-comment">// default: 1.0</span></span>
<span class="line"> <span class="hljs-type">float</span> clearCoatRoughness; <span class="hljs-comment">// default: 0.0</span></span>
<span class="line"> float3 clearCoatNormal; <span class="hljs-comment">// default: float3(0.0, 0.0, 1.0)</span></span>
@@ -2313,7 +2374,7 @@ The following APIs are only available from the fragment block:
<tr><td style="text-align:left"> <strong class="asterisk">getWorldNormalVector()</strong> </td><td style="text-align:center"> float3 </td><td style="text-align:left"> Normalized normal in world space, after bump mapping (must be used after <code>prepareMaterial()</code>) </td></tr>
<tr><td style="text-align:left"> <strong class="asterisk">getWorldGeometricNormalVector()</strong> </td><td style="text-align:center"> float3 </td><td style="text-align:left"> Normalized normal in world space, before bump mapping (can be used before <code>prepareMaterial()</code>) </td></tr>
<tr><td style="text-align:left"> <strong class="asterisk">getWorldReflectedVector()</strong> </td><td style="text-align:center"> float3 </td><td style="text-align:left"> Reflection of the view vector about the normal (must be used after <code>prepareMaterial()</code>) </td></tr>
<tr><td style="text-align:left"> <strong class="asterisk">getNormalizedViewportCoord(float2)</strong> </td><td style="text-align:center"> float2 </td><td style="text-align:left"> Normalized viewport position (i.e. clip-space position normalized to [0, 1], can be used before <code>prepareMaterial()</code>) </td></tr>
<tr><td style="text-align:left"> <strong class="asterisk">getNormalizedViewportCoord()</strong> </td><td style="text-align:center"> float2 </td><td style="text-align:left"> Normalized viewport position (i.e. clip-space position normalized to [0, 1], can be used before <code>prepareMaterial()</code>) </td></tr>
<tr><td style="text-align:left"> <strong class="asterisk">getNdotV()</strong> </td><td style="text-align:center"> float </td><td style="text-align:left"> The result of <code>dot(normal, view)</code>, always strictly greater than 0 (must be used after <code>prepareMaterial()</code>) </td></tr>
<tr><td style="text-align:left"> <strong class="asterisk">getColor()</strong> </td><td style="text-align:center"> float4 </td><td style="text-align:left"> Interpolated color of the fragment, if the color attribute is required </td></tr>
<tr><td style="text-align:left"> <strong class="asterisk">getUV0()</strong> </td><td style="text-align:center"> float2 </td><td style="text-align:left"> First interpolated set of UV coordinates, only available if the uv0 attribute is required </td></tr>

View File

@@ -13,7 +13,7 @@ This document is part of the [Filament project](https://github.com/google/filame
## Authors
- [Romain Guy](https://github.com/romainguy), [@romainguy](https://twitter.com/romainguy)
- [Mathias Agopian](https://github.com/pixelflinger), [@romainguy](https://twitter.com/darthmoosious)
- [Mathias Agopian](https://github.com/pixelflinger), [@darthmoosious](https://twitter.com/darthmoosious)
# Overview
@@ -81,6 +81,8 @@ in table [standardProperties].
**metallic** | Whether a surface appears to be dielectric (0.0) or conductor (1.0). Often used as a binary value (0 or 1)
**roughness** | Perceived smoothness (1.0) or roughness (0.0) of a surface. Smooth surfaces exhibit sharp reflections
**reflectance** | Fresnel reflectance at normal incidence for dielectric surfaces. This directly controls the strength of the reflections
**sheenColor** | Strength of the sheen layer
**sheenRoughness** | Perceived smoothness or roughness of the sheen layer
**clearCoat** | Strength of the clear coat layer
**clearCoatRoughness** | Perceived smoothness or roughness of the clear coat layer
**anisotropy** | Amount of anisotropy in either the tangent or bitangent direction
@@ -106,6 +108,8 @@ The type and range of each property is described in table [standardPropertiesTyp
**metallic** | float | [0..1] | Should be 0 or 1
**roughness** | float | [0..1] |
**reflectance** | float | [0..1] | Prefer values > 0.35
**sheenColor** | float3 | [0..1] | Linear RGB
**sheenRoughness** | float | [0..1] |
**clearCoat** | float | [0..1] | Should be 0 or 1
**clearCoatRoughness** | float | [0..1] |
**anisotropy** | float | [-1..1] | Anisotropy is in the tangent direction when this value is positive
@@ -293,9 +297,40 @@ impossible materials, however, this might be desirable for artistic reasons.
The `reflectance` property is designed as a normalized property in the range 0..1 which makes
it easy to define from a texture.
See the Index of refraction section for more information about the `ior` property and refractive
See section [Index of refraction] for more information about the `ior` property and refractive
indices.
### Sheen color
The sheen color controls the color appearance and strength of an optional sheen layer on top of the
base layer described by the properties above. The sheen layer always sits below the clear coat layer
if such a layer is present.
The sheen layer can be used to represent cloth and fabric materials. Please refer to
section [Cloth model] for more information about cloth and fabric materials.
The effect of `sheenColor` is shown in figure [materialSheenColor]
(click on the image to see a larger version).
![Figure [materialSheenColor]: Different sheen colors](images/screenshot_sheen_color.png)
!!! Note
If you do not need the other properties offered by the standard lit material model but want to
create a cloth-like or fabric-like appearance, it is more efficient to use the dedicated cloth
model described in section [Cloth model].
### Sheen roughness
The `sheenRoughness` property is similar to the `roughness` property but applies only to the
sheen layer.
The effect of `sheenRoughness` on a rough metal is shown in figure [sheenRoughnessProperty]
(click on the image to see a larger version). In this picture, the base layer is a dark blue, with
`metallic` set to `0.0` and `roughness` set to `1.0`.
![Figure [sheenRoughnessProperty]: `sheenRoughness` varying from 0.0
(left) to 1.0 (right)](images/materials/sheen_roughness.png)
### Clear coat
Multi-layer materials are fairly common, particularly materials with a thin translucent
@@ -322,6 +357,9 @@ The effect of `clearCoat` on a rough metal is shown in figure [clearCoatProperty
The clear coat layer effectively doubles the cost of specular computations. Do not assign a
value, even 0.0, to the clear coat property if you don't need this second layer.
!!! Note
The clear coat layer is added on top of the sheen layer if present.
### Clear coat roughness
The `clearCoatRoughness` property is similar to the `roughness` property but applies only to the
@@ -490,8 +528,9 @@ Other dielectric materials | 1.33 to 1.58
[Table [commonMatIOR]: Index of refraction of common materials]
The appearance of a refractive material will greatly depend on the `refractionType` and
`refractionMode` settings of the material. Refer to the Blending and transparency: refractionType
section and the Blending and transparency: refractionMode section for more information.
`refractionMode` settings of the material. Refer to section
[Blending and transparency: refractionType] and section [Blending and transparency: refractionMode]
for more information.
The effect of `ior` when `refractionMode` is set to `cubemap` and `refractionType` is set to `solid`
can be seen in figure [iorProperty2] (click on the image to see a larger version).
@@ -795,7 +834,7 @@ fragment {
}
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
A minimum viable material definition must contain a `material` section and a `fragment` block. The
A minimum viable material definition must contain a `material` preamble and a `fragment` block. The
`vertex` block is optional.
### Differences with JSON
@@ -1771,6 +1810,8 @@ struct MaterialInputs {
float ambientOcclusion; // default: 0.0
// not available when the shading model is subsurface or cloth
float3 sheenColor; // default: float3(0.0)
float sheenRoughness; // default: 0.0
float clearCoat; // default: 1.0
float clearCoatRoughness; // default: 0.0
float3 clearCoatNormal; // default: float3(0.0, 0.0, 1.0)

Binary file not shown.

After

Width:  |  Height:  |  Size: 557 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 24 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.6 MiB

View File

@@ -170,6 +170,7 @@ set(MATERIAL_SRCS
src/materials/separableGaussianBlur.mat
src/materials/antiAliasing/fxaa.mat
src/materials/antiAliasing/taa.mat
src/materials/vsmMipmap.mat
)
# Embed the binary resource blob for materials.
@@ -290,6 +291,18 @@ add_custom_command(
APPEND
)
add_custom_command(
OUTPUT "${MATERIAL_DIR}/sao.filamat"
DEPENDS src/materials/ssao/ssaoUtils.fs
APPEND
)
add_custom_command(
OUTPUT "${MATERIAL_DIR}/sao.filamat"
DEPENDS src/materials/ssao/ssct.fs
APPEND
)
add_custom_command(
OUTPUT ${RESGEN_OUTPUTS}
COMMAND resgen ${RESGEN_FLAGS} ${MATERIAL_BINS}
@@ -337,7 +350,7 @@ target_link_libraries(${TARGET} PUBLIC utils)
target_link_libraries(${TARGET} PUBLIC geometry) # TODO: remove this dependency after deprecating VertexBuffer::populateTangentQuaternions
target_link_libraries(${TARGET} PUBLIC filaflat)
target_link_libraries(${TARGET} PUBLIC filabridge)
target_link_libraries(${TARGET} PUBLIC ibl)
target_link_libraries(${TARGET} PUBLIC ibl-lite)
if (FILAMENT_ENABLE_MATDBG)
target_link_libraries(${TARGET} PUBLIC matdbg)
@@ -377,7 +390,6 @@ set(LINUX_LINKER_OPTIMIZATION_FLAGS
)
set(LINUX_COMPILER_FLAGS
-fPIC
)
if (MSVC)

View File

@@ -297,10 +297,12 @@ if (APPLE)
test/ShaderGenerator.cpp
test/TrianglePrimitive.cpp
test/Arguments.cpp
test/test_FeedbackLoops.cpp
test/test_MissingRequiredAttributes.cpp
test/test_ReadPixels.cpp
test/test_BufferUpdates.cpp
test/test_MRT.cpp)
test/test_MRT.cpp
)
target_link_libraries(backend_test PRIVATE
backend
@@ -326,6 +328,11 @@ if (APPLE)
spirv-cross-msl
)
if (NOT IOS)
target_link_libraries(backend_test PRIVATE image imageio)
list(APPEND BACKEND_TEST_DEPS image imageio)
endif()
set(BACKEND_TEST_COMBINED_OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/libbackendtest_combined.a")
combine_static_libs(backend_test "${BACKEND_TEST_COMBINED_OUTPUT}" "${BACKEND_TEST_DEPS}")
@@ -337,7 +344,7 @@ if (APPLE)
endif()
endif()
if (APPLE AND NOT IOS AND NOT FILAMENT_USE_SWIFTSHADER)
if (APPLE AND NOT IOS)
add_executable(backend_test_mac test/mac_runner.mm)
target_link_libraries(backend_test_mac PRIVATE "-framework Metal -framework AppKit -framework QuartzCore")
# Because each test case is a separate file, the -force_load flag is necessary to prevent the

View File

@@ -22,6 +22,8 @@
#include <utils/BitmaskEnum.h>
#include <utils/unwindows.h> // Because we define ERROR in the FenceStatus enum.
#include <backend/PresentCallable.h>
#include <math/vec4.h>
#include <array> // FIXME: STL headers are not allowed in public headers
@@ -41,6 +43,8 @@ namespace backend {
static constexpr uint64_t SWAP_CHAIN_CONFIG_TRANSPARENT = 0x1;
static constexpr uint64_t SWAP_CHAIN_CONFIG_READABLE = 0x2;
static constexpr uint64_t SWAP_CHAIN_CONFIG_ENABLE_XCB = 0x4;
static constexpr uint64_t SWAP_CHAIN_CONFIG_APPLE_CVPIXELBUFFER = 0x8;
static constexpr size_t MAX_VERTEX_ATTRIBUTE_COUNT = 16; // This is guaranteed by OpenGL ES.
static constexpr size_t MAX_SAMPLER_COUNT = 16; // Matches the Adreno Vulkan driver.
@@ -215,6 +219,11 @@ enum class SamplerType : uint8_t {
SAMPLER_3D, //!< 3D texture
};
//! Subpass type
enum class SubpassType : uint8_t {
SUBPASS_INPUT
};
//! Texture sampler format
enum class SamplerFormat : uint8_t {
INT = 0, //!< signed integer sampler
@@ -878,6 +887,11 @@ struct PolygonOffset {
};
using FrameScheduledCallback = void(*)(backend::PresentCallable callable, void* user);
using FrameCompletedCallback = void(*)(void* user);
} // namespace backend
} // namespace filament

View File

@@ -36,7 +36,7 @@ namespace backend {
* within a CATransation:
*
* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
* void myFrameFinishedCallback(PresentCallable presentCallable, void* user) {
* void myFrameScheduledCallback(PresentCallable presentCallable, void* user) {
* [CATransaction begin];
* // Update other UI elements...
* presentCallable();
@@ -44,11 +44,13 @@ namespace backend {
* }
* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
*
* To obtain a PresentCallable, pass a backend::FrameFinishedCallback to the beginFrame() function.
* The callback is called with a PresentCallable object and optional user data:
* To obtain a PresentCallable, set a SwapChain::FrameScheduledCallback on a SwapChain with the
* SwapChain::setFrameScheduledCallback method. The callback is called with a PresentCallable object
* and optional user data:
*
* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
* if (renderer->beginFrame(swapChain, myFrameFinishedCallback, nullptr)) {
* swapChain->setFrameScheduledCallback(myFrameScheduledCallback, nullptr);
* if (renderer->beginFrame(swapChain)) {
* renderer->render(view);
* renderer->endFrame();
* }
@@ -57,14 +59,14 @@ namespace backend {
* @remark Only Filament's Metal backend supports PresentCallables and frame callbacks. Other
* backends ignore the callback (which will never be called) and proceed normally.
*
* @remark The backend::FrameFinishedCallback is called on an arbitrary thread.
* @remark The SwapChain::FrameScheduledCallback is called on an arbitrary thread.
*
* Applications *must* call each PresentCallable they receive. Each PresentCallable represents a
* frame that is waiting to be presented. If an application fails to call a PresentCallable, a
* memory leak could occur. To "cancel" the presentation of a frame, pass false to the
* PresentCallable, which will cancel the presentation of the frame and release associated memory.
*
* @see Renderer, SwapChain, Renderer.beginFrame
* @see Renderer, SwapChain::setFrameScheduledCallback
*/
class UTILS_PUBLIC PresentCallable {
public:
@@ -92,18 +94,9 @@ private:
};
/**
* FrameFinishedCallback is a callback function that notifies an application when Filament has
* finished processing a frame and that frame is ready to be scheduled for presentation.
*
* beginFrame() takes an optional FrameFinishedCallback. If the callback is provided, then that
* frame will *not* automatically be scheduled for presentation. Instead, the application must call
* the given PresentCallable.
*
* @remark The backend::FrameFinishedCallback is called on an arbitrary thread.
*
* @see PresentCallable, beginFrame()
* @deprecated, FrameFinishedCallback has been renamed to SwapChain::FrameScheduledCallback.
*/
using FrameFinishedCallback = void(*)(PresentCallable callable, void* user);
using FrameFinishedCallback UTILS_DEPRECATED = void(*)(PresentCallable callable, void* user);
} // namespace backend
} // namespace filament

View File

@@ -133,8 +133,16 @@ DECL_DRIVER_API_0(tick)
DECL_DRIVER_API_N(beginFrame,
int64_t, monotonic_clock_ns,
uint32_t, frameId,
backend::FrameFinishedCallback, callback,
uint32_t, frameId)
DECL_DRIVER_API_N(setFrameScheduledCallback,
backend::SwapChainHandle, sch,
backend::FrameScheduledCallback, callback,
void*, user)
DECL_DRIVER_API_N(setFrameCompletedCallback,
backend::SwapChainHandle, sch,
backend::FrameCompletedCallback, callback,
void*, user)
DECL_DRIVER_API_N(setPresentationTime,
@@ -283,6 +291,7 @@ DECL_DRIVER_API_SYNCHRONOUS_N(bool, isTextureFormatMipmappable, backend::Texture
DECL_DRIVER_API_SYNCHRONOUS_N(bool, isRenderTargetFormatSupported, backend::TextureFormat, format)
DECL_DRIVER_API_SYNCHRONOUS_0(bool, isFrameBufferFetchSupported)
DECL_DRIVER_API_SYNCHRONOUS_0(bool, isFrameTimeSupported)
DECL_DRIVER_API_SYNCHRONOUS_0(bool, areFeedbackLoopsSupported)
DECL_DRIVER_API_SYNCHRONOUS_0(math::float2, getClipSpaceParams)
DECL_DRIVER_API_SYNCHRONOUS_0(bool, canGenerateMipmaps)
DECL_DRIVER_API_SYNCHRONOUS_N(void, setupExternalImage, void*, image)

View File

@@ -43,7 +43,8 @@ public:
struct Sampler {
utils::CString name = {}; // name of the sampler in the shader
size_t binding = 0; // binding point of the sampler in the shader
uint16_t binding = 0; // binding point of the sampler in the shader
bool strict = false; // if true, this sampler must always have a bound texture
};
using SamplerGroupInfo = std::array<std::vector<Sampler>, SAMPLER_BINDING_COUNT>;

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