Compare commits

..
Author SHA1 Message Date
Mathias Agopian a8a37a537a simplify a lot libibl's Image class 2019-03-13 13:45:43 -07:00
Mathias Agopian 13d3ade5bb libibl doesn't need to depend on libimage 2019-03-13 13:45:43 -07:00
Mathias Agopian 54d292bc8a move all libibl APIs in namespace filament::ibl 2019-03-12 22:36:54 -07:00
Mathias Agopian 43ac656a38 Cleanup libibl a bit. Add some basic documentation. 2019-03-12 22:36:54 -07:00
Mathias Agopian f8fc2dd808 split cmgen into an exe + libibl.a 2019-03-12 22:36:54 -07:00
Mathias Agopian 529c44e548 cleanup cmgen in praparation of lib split
we mostly remove dependencies on includes.
2019-03-12 22:36:54 -07:00
Mathias Agopian 637390ea85 Update MaterialParser.cpp 2019-03-12 15:37:05 -07:00
Mathias Agopian 69db5134a6 simplify MaterialParser
no need to hide the implementation anymore, since the whole thing
is internal and doesn't appear in public headers.

this saves a dynamic allocation when unflattening materials.
2019-03-12 15:37:05 -07:00
Philip Rideout 0102489748 gltfio: add UbershaderLoader, an implemention of MaterialProvider. 2019-03-12 15:29:17 -07:00
Philip Rideout 3b827da834 geometry: add JS bindings for SurfaceOrientation
These bindings are not user friendly because clients need to
manually allocate / deallocate memory. However it gets the job done.

Fixes #959.
2019-03-12 14:31:09 -07:00
Philip Rideout ce50ea17c0 Avoid NaN when normal is colinear with fake axis.
I reproduced the issue by hacking our redball demo and visually
verified the fix.

cc @AdrianAtGoogle
2019-03-12 14:30:25 -07:00
Mathias Agopian ca79e9d420 More doxygen documentation 2019-03-12 13:35:58 -07:00
Mathias Agopian fb4e498bc1 fix documentation typos 2019-03-12 13:35:58 -07:00
Mathias Agopian b44717ae54 Add doxygen documentation 2019-03-12 13:35:58 -07:00
Mathias Agopian 6e4491c852 Make dithering an enum. 2019-03-12 13:32:28 -07:00
Mathias Agopian 07bb62490b Add an option to turn dithering on/off 2019-03-12 13:32:28 -07:00
Romain Guy b8f72590bb Fix Android builds on Windows (#968)
* Fix Android builds on Windows

This PR fixes #927

* Add missing endline

* Fix armv7a Android builds
2019-03-12 10:49:26 -07:00
Philip Rideout 39c63146e0 gltfio: add ubershader template.
We will need 6 pre-compiled materials (lit vs nonlit and the 3 blend
modes). This uses CMake's "configure_file" functionality to generate 6
mat files, then invokes matc on each one. They are then combined using
resgen.
2019-03-12 08:16:55 -07:00
Philip Rideout 960d1321e6 Repair web builds. 2019-03-11 18:36:29 -07:00
Mathias Agopian 8ffba072b2 remove the "byteSize" parameter from update[Vertex|Index]Buffer
It was redundant with BufferDescriptor::size.
2019-03-11 18:27:06 -07:00
Philip Rideout 031ff260f7 Repair web builds. 2019-03-11 17:44:12 -07:00
Mathias Agopian c78db48b81 Better Camera component management
- getCameraComponent(Entity) retrieves a Camera component from an entity
- destroyCameraComponent(Entity) destroys just the camera component
  attached to an entity.

destroyCamera() are now deprecated because the API is confusing, it's
not immediately clear that it's destroying all component + the entity
itself.

Node: We don't add the corresponding Java APIs yet because there is no 
easy way to guarantee they're safe without making sure that 
getCameraComponent() will always return the same instance (which it
wouldn't currently).
2019-03-11 15:51:38 -07:00
Romain Guy 11eaad7992 Fix CI builds 2019-03-11 14:37:29 -07:00
Romain Guy eda6ea64c8 Require CMake 3.10 2019-03-11 14:32:50 -07:00
Romain Guy 79dec2f8b5 Give our own CMake a higher priority 2019-03-11 14:28:26 -07:00
Romain Guy 41397e1b82 Move 3p models to models/ directory 2019-03-11 14:21:51 -07:00
Romain Guy 31a70d2352 Print CMake version number 2019-03-11 14:14:09 -07:00
Romain Guy 98ce5e2f5a Require CMake 3.12 because of CI 2019-03-11 14:07:13 -07:00
Romain Guy 9d8c000bcc Make CMake 3.13 the minimum version 2019-03-11 14:05:45 -07:00
Romain Guy d238d7f6f2 Add CMake version check 2019-03-11 14:03:05 -07:00
Romain Guy 73af2620f9 Cleanup build.sh 2019-03-11 14:02:56 -07:00
yoshi (Yoshihisa Kaino) 160297db9c Fix Activate link #957 (#958) 2019-03-11 07:45:46 -07:00
Philip Rideout 8628c43fbf gltfio: material generator cleanup. 2019-03-10 15:11:58 -07:00
Philip Rideout af9b3a99e0 gltfio: introduce MaterialProvider interface.
This prepares for an alternate "sans filamat" implementation of
MaterialProvider, which will be especially useful for web.
2019-03-10 11:59:47 -07:00
Philip Rideout 7a2924738c gltfio: transparency fixups
- rename gltfio::AlphaMode to use glTF nomenclature
- keep depth writes enabled for transparent renderables
2019-03-09 18:58:04 -08:00
Philip Rideout 06964a787a Repair parquet and helmet web demos. 2019-03-09 06:39:31 -08:00
Romain Guy 2e8c01d8aa Update README.md per #946 2019-03-08 23:11:29 -08:00
Mathias Agopian b2738a2c8c Don't expose private structure in public header 2019-03-08 19:16:46 -08:00
Philip Rideout 0e4ca0bc7b Fix falling streetcar / quaternion slerp. 2019-03-08 17:50:15 -08:00
Philip Rideout 64f2a580da Update public site with latest JavaScript demos.
It has been a while, we've made a fix to our KTX writer, added a helmet
demo, etc.
2019-03-08 17:49:28 -08:00
Philip Rideout f1f9fde3a4 Various JavaScript updates.
Add shadows to the FlightHelmet demo, add a link to it on the site,
and add recently-introduced entry points to the JS bindings.
2019-03-08 12:56:48 -08:00
Philip Rideout c98ac44827 gltfio: fix UV set issue seen in littlest_tokyo 2019-03-08 11:31:22 -08:00
Philip Rideout 3c2a6d5f8c Link to rasterized markdown on website. 2019-03-08 09:59:01 -08:00
Mathias Agopian d5178f862a minor cleanup: remove unneeded complexity 2019-03-07 17:21:58 -08:00
Mathias Agopian 4de71f7239 Remove dependency of UniformBuffer on UniformInterfaceBlock 2019-03-07 16:42:02 -08:00
Mathias Agopian 302d296949 Remove driver's UniformInterfaceBlock dependency 2019-03-07 16:42:02 -08:00
Mathias Agopian 1836377753 don't have two version of SamplerFormat
Instead, alias one on the other.
Also sort aliases in the header.
2019-03-07 16:42:02 -08:00
Mathias Agopian 462251bde6 Remove unused code and data
This is no longer used. Get rid of it.
2019-03-07 16:42:02 -08:00
Mathias Agopian a1eedb95a0 'driver' shouldn't include filament/*.h headers
only filament/driver/* are allowed. These were not even needed.
2019-03-07 16:41:43 -08:00
Philip Rideout b14759a0a4 gltfio: add wireframe functionality.
This makes it easy to draw a transformed box around each renderable for
diagnostic purposes. The API is similar to Animator in that it is
exposed through FilamentAsset but is created lazily and is implementated
outside of FilamentAsset.
2019-03-07 15:03:43 -08:00
Romain Guy f02fe33070 Reformat comments 2019-03-07 14:53:33 -08:00
Philip Rideout 1ccf2d6a08 gltfio: fix up and enhance AABB functionality.
gltfio computes two types of bounding boxes: one for renderables (used
for frustum culling) and one for the overall asset (used for
positioning the camera or asset).

Both of these are based on the min+max attributes in the glTF file, but
the asset-level box was incorrect because only two corners of the
transformed AABB were considered.

This CL also adds optional computation of bounding boxes that crawls
through the vertex positions. This is useful when diagnosing potential
issues with the asset's min+max info.

These enhancements are motivated by a culling issue seen with the voxel
Cathedral on sketchfab.
2019-03-07 14:11:21 -08:00
Mathias Agopian d2afc27703 Address review comments 2019-03-07 13:43:27 -08:00
Mathias Agopian 801d24b6e7 Remove some unused code and includes 2019-03-07 13:43:27 -08:00
Mathias Agopian 91738d0513 Remove the 'group' parameter from SamplerBindingMap 2019-03-07 13:43:27 -08:00
Mathias Agopian 2a72e8aee8 break dependency of Program on SamplerInterfaceBlock and SamplerBindingMap
Instead of passing SamplerInterfaceBlocks and a SamplerBindingMap to
Program, we now set a 'sampler group' per binding point:

Program::addSamplerGroup(...)

A sampler group here consists of a list of N 'Sampler' and a 'Sampler'
is just a unique name (unifrom name in the shader) and binding point in
the shader.

That's all the driver layer needs.

With this change we get rid of the code that re-created the uniform
names in the driver -- this should never have been done there. And we
also remove the hash-map lookups in vulkan and metal drivers.
2019-03-07 13:43:27 -08:00
Mathias Agopian b0d640832a cleaup of Program.h 2019-03-07 13:43:27 -08:00
Mathias Agopian 50d8a8a2d8 fix SamplerBindingMap for non postprocess materials
This fixes #935

SamplerBindingMap was always adding the post-process samplers to the
map -- but matc doesn't generate those. This led the vulkan backend
to believe there was a post-process sampler bound, when there wasn't.

This is also technically a bug in the Vulkan backend because it should
have used the SamplerInterfaceBlock to determine which shaders are
actually used instead of blindly going through the whole list and 
trusting SamplerBindingMap.

The fix is kind of a hack, but the whole SamplerBindingMap is kind of a
hack anyways.
2019-03-06 18:26:08 -08:00
Romain Guy 23fe2cba98 Update MoltenVK to 1.1.101.0 (#937) 2019-03-06 16:52:24 -08:00
sebavan 906097625e Add Charlie importance sampling to cmgen.exe (#936) 2019-03-06 15:43:07 -08:00
Philip Rideout 8d979a7cb8 Resurrect quat slerp NaN protection.
In my previous NaN-related commit, I added a conditional similar to the
one seen in glMatrix, but this was insufficient for the interpolation
seen in a glTF skinning test because a divide-by-zero was occuring later
in the function. This commit simply adds back the previous protection.
2019-03-06 12:36:20 -08:00
Romain Guy 5ef0247569 Fix normal map sample 2019-03-06 12:03:34 -08:00
Pixelflinger 46e3326b81 move getSamplerBindingsStart() to SibGenerator
This is a bit more logical to have it there because SibGenerator
is about about what filament needs, whereas SamplerInterfaceBlock.h
is generic.
2019-03-06 11:47:26 -08:00
Pixelflinger 413f6a97b1 Engine.h doesn't need to store the per-view/post-process Sib
It's only used to get the size of the SamplerGroup.
Actually, Engine also uses the post-process Sib to create the
post-process material, but this should go away when we have
material domains -- so pretend it's not there.
2019-03-06 11:47:26 -08:00
Pixelflinger 1597b6f572 rename SamplerBuffer to SamplerGroup
This is the first part of a larger rework:
- Rename SamplerBuffer to SamplerGroup
- remove dependency on SamplerInterfaceGroup
2019-03-06 11:47:26 -08:00
Mathias Agopian dc57eb4b7b fix filameshio test
when testing we're often using the NoopDriver, which
is has neither spirv or text shaders, so we default
to text to make this case work.
2019-03-05 18:38:01 -08:00
Mathias Agopian 7d81d9bb51 cleanup filamat namespace 2019-03-05 17:54:37 -08:00
Mathias Agopian 4abe017bc5 cleanup MaterialChunkType.h 2019-03-05 17:54:37 -08:00
Mathias Agopian 0f6f53d501 MaterialChunk doesn't expose the Unflattener in its API
this makes the API more robust, because now it's not possible
to mess up the call to getShader(), by construction.
2019-03-05 17:54:37 -08:00
Mathias Agopian 084fd95489 Factorize all the various getShader() methods
This removes a lot of code and complexity. MaterialParser now has 
a single, generic getShader() method.
2019-03-05 17:54:37 -08:00
Mathias Agopian ff53515295 Merge [Spirv|Text]DictionaryReadder into DictionaryReader 2019-03-05 17:54:37 -08:00
prideout bba42ea81f Repair Vulkan sychronization, fixes #929. 2019-03-05 16:57:09 -08:00
Philip Rideout 66f6031e2c Vulkan: support R16G16B16 textures via DataReshaper.
This change happens to "fix" issue #875, although we may wish to rethink
our DFG representation in the future.
2019-03-05 09:20:26 -08:00
Mathias Agopian f2ba48f4a7 Program::shader() now only takes a void* + size
Program::shader() was taking a string before which didn't make sense
for spirv.  Now it's just a blob, in the case of GL/Metal, the blob
must be a null terminated c-string, and the size must include the
terminating null character.

This fixes an out-of-bound access in ShaderBuilder::getShader() (which
doesn't exist anymore), because it was creating a CString passing
a size that included the null terminating char, which is not was CString
expects. CString can now assert() in that case.


driver::Program now uses a std::vector<> for storage, which we should
fix at some point (b/c it's a public header). CString was not suited to
store binary blobs.
2019-03-04 19:00:26 -08:00
Mathias Agopian 955ab2d2f3 Cleanup in MaterialParser 2019-03-04 19:00:26 -08:00
Mathias Agopian 561726b938 remove unneeded dependency on SamplerBindingMap.h 2019-03-04 15:52:46 -08:00
Mathias Agopian 7b3475f1da API change: rename matrix factory functions
scale() -> scaling()
translate() -> translation()
rotate() -> rotation()

These static functions create a matrix, they don't modify it.
Fixes #826
2019-03-04 14:34:02 -08:00
Romain Guy 923db48614 Add build command for Markdeep files (#919)
* Add build command for Markdeep files

build.sh -w can now be used to "rasterize" Markdeep .md.html files
to regular, static .html files. These files load faster and do not
suffer from an initial flash of uninitialized content.

This new command requires node, npm and nx to run puppeteer to
"rasterize" the Markdeep documents. This should eventually be
integrated in the actual build system to automatically re-generate
the HTML files when the Markdeep documents are edited.

* Remove unnecessary .gitignore file

* Change constant names for JS docs
2019-03-04 14:23:05 -08:00
Romain Guy 9558f0d6ca Use uniform sampling for cloth DFG (#921) 2019-03-02 14:10:38 -08:00
Mathias Agopian 3297c9bc78 More headers clean-up
- EngineEnums.h is not a private headers as it contained mostly private
stuff

- MaterialEnums.h is still public, but now only contains public stuff.
Private parts were moved to MaterialEnums.h or MaterialBuilder.h

- And finally SamplerBinderMap is moved under private/ as well, since
it's certainly not a public API.

With this change, the public headers of filabridge become more reasonable
and limited.
2019-03-02 00:21:09 -08:00
Philip Rideout 6c75c6436e Add support for glb files.
Tested with DamagedHelmet.glb
2019-03-02 00:02:40 -08:00
Mathias Agopian 28ebc64fd9 cleanup. use createResourceNode() everywhere appropriate
now that we have a createResourceNode() method, use it.
2019-03-01 18:26:43 -08:00
Mathias Agopian 3c027b9ea0 When moving a resource we invalidate the 'from' handle
This is because 'from' is now written to, so we should invalidate it
just like for a regular write.

moveResource() now asserts when using an invalid handle. The caller can
use isValid() to check the handle if desired.
2019-03-01 18:26:43 -08:00
Mathias Agopian 8861b55d3d Get rid of RenderTargetPool
This might come back in some form in the future, for now we rely on
the driver not being too slow allocating memory.
2019-03-01 16:46:52 -08:00
Mathias Agopian bb72e796bf Switch to FrameGraph
Filament's main rendering loop now uses the new FrameGraph API.
2019-03-01 16:46:52 -08:00
Mathias Agopian c5fc7a01e8 remove an incorrect assert() in shadow mapping
when we compute the depth range of the shadow map, if znear is behind
zfar, it just means we don't have any shadow caster in front of
a receiver, and we can just bail out without shadowing -- as opposed
to asserting.
2019-03-01 16:43:45 -08:00
Mathias Agopian ee1377fcad Always centers the camera to the world origin
This is effectively moving all shader computations to view space,
improving floating-point precision in the shaders, by staying
around zero where fp precision is highest. This also ensures that
when the camera is very far from the origin, objects are still
rendered and lit properly.
2019-03-01 16:43:27 -08:00
Ben Doherty 1aa4eff190 Fix post processing issue for Metal (#906) 2019-03-01 12:46:53 -08:00
Philip Rideout 16d878186c Finalize Animator implementation.
- Add support for CUBICSPLINE and STEP interpolation methods.
- Use cgltf_accessor_read_float() instead of manually unpacking values.
- Fix potential NaN in decomposeMatrix.
- Reduce malloc churn by stashing the vector of bone matrices.
2019-03-01 12:35:55 -08:00
Mathias Agopian bf93468c3f Minor MaterialEnum.h cleanup -- first step. 2019-03-01 08:43:01 -08:00
Mathias Agopian 71762cf55e remove dependency on [Sampler|Uniform]InterfaceBlock.h
it just wasn't needed.
2019-03-01 08:43:01 -08:00
Mathias Agopian a6a4055a0a don't fully qualify filament namespaces 2019-03-01 08:43:01 -08:00
Mathias Agopian 8d484dd762 break dependency of filaflat on filabridge
filaflat only had on header dependency on filabridge (DriverEnums.h)
and only needed two small enum types.
In fact, I don't think it was right for filaflat to assume any 
particular value for these fields -- this is the responsibility of the
callers.
2019-03-01 08:43:01 -08:00
Philip Rideout 6e7c705c92 AssetLoader fixups after code review. 2019-03-01 08:36:27 -08:00
Philip Rideout 38facc9038 AssetLoader cleanup per code review. 2019-03-01 07:27:03 -08:00
Philip Rideout c7848efd86 Introduce the gltfio library.
This is our new mobile-friendly and web-friendly library for loading
glTF assets. It is still a work in progress, but already capable of
loading many conformance models, including those with animation,
skinning, and a couple of extensions (nonlit and texture transforms).

Next week we will add a sample app demonstrating its usage.
2019-03-01 07:27:03 -08:00
Philip Rideout 13cd77bc9a SurfaceOrientation now supports uint32 indices. 2019-03-01 07:27:03 -08:00
Romain Guy fa9ba2c592 Update README.md
Mention Metal support
2019-02-28 15:00:00 -08:00
Ben Doherty 4f22eb44e6 Add transparent-rendering iOS demo (#905) 2019-02-28 14:42:14 -08:00
Mathias Agopian 4b587a1f6d silence a few warnings 2019-02-28 12:29:56 -08:00
Mathias Agopian 583645a943 Move MaterialParser from filaflat to filament
With this change, filaflat looses almost all its dependencies on
filabridge (only needs DriverEnums.h) and becomes only a parsing
library that doesn't know anything about materials.
It still knows about "shaders" as blobs of text or data (spirv).

Filaflat itself is used by matinfo and filament.
2019-02-28 12:29:56 -08:00
Mathias Agopian 42875b7809 break dependency of matinfo on MaterialParser 2019-02-28 12:29:56 -08:00
Mathias Agopian 54283291d1 Expose more APIs of filaflat publicly
We now expose things like 

BlobDictionary: dictionary content
MaterialChunk: construct a material from the BlobDictionary
SpirvDictionaryReader: reads a spirv dictionary
TextDictionaryReader: reads an ascii dictionary

All these classes are generic enough and don't have any outside
dependencies.

The only remaining class which has outside dependencies is 
MaterialParser, which will be eliminated soon.
2019-02-28 12:29:56 -08:00
Mathias Agopian 9263eda90e Remove dependency on Variant.h in MaterialChunk.cpp
this dependency was only used to restrict the variant to filament's
usage of it. but really this shouldn't be done here.
2019-02-28 12:29:56 -08:00
Mathias Agopian 16cef02441 break Unflattener dependency on ChunkCountainer.h 2019-02-28 12:29:56 -08:00
Mathias Agopian d07222fc3c cleanup: break dependency filamat->filaflat dependency 2019-02-28 12:29:56 -08:00
Mathias Agopian 0dd8414844 minor cleanup, try to remove some uneeded dependencies
this is in praparation for much larger changes
2019-02-28 12:29:56 -08:00
Philip Rideout 7a5ca724fc Add cgltf to third_party (MIT License).
This is used by our upcoming gltfio library and is the lightest-weight
glTF reader that we know of. In fact it does not do much other than
parse the JSON and provide C structures for the data.
2019-02-28 12:29:44 -08:00
Ben Doherty c8a6a4dd62 Implement MSAA for Metal (#897) 2019-02-28 12:27:20 -08:00
Ben Doherty 4d90b9d0f0 Link iOS sample apps with the geometry library (#899) 2019-02-28 12:26:05 -08:00
Ondrej Stava ebe7b2e182 Fixed uninitialized properties in the Viewport class. (#903)
The default constructor of the Viewport class left the view properties in an uninitialized state that could lead to an undeterministic behavior in the later stages during rendering.
In our case, the issue manifested in the Froxelizer class in the setViewport() method that was flaky because sometimes the old viewport in the Froxelizer class (mViewport) was equal to the newly set viewport which caused the mDirtyFlags to not be updated. This then resulted in a crash because mPlanesX and mPlanesY were not allocated in the update() function even though they were used.
2019-02-28 10:25:55 -08:00
Philip Rideout 08af0f06bc Add new queries to TransformManager and Scene. 2019-02-28 02:17:18 -08:00
Mathias Agopian cdbfbcc1e4 docs: fix a few warnings when invoking doxygen 2019-02-27 19:01:05 -08:00
Benjamin Doherty ced19bde17 Fix a few documentation issues 2019-02-27 18:47:12 -08:00
Ben Doherty 523e1b957f Metal context cleanup (#895)
* Rename MetalImpl to MetalContext and move to separate header

* Remove m prefix from MetalContext variables

* Refactor out acquireDrawable method

* mCommandQueue -> commandQueue
2019-02-27 13:42:17 -08:00
Mathias Agopian 2ec6916f63 Fix a default material instance sampler initialization
This fixes #887. this bug existed since forever, when setting the
samplers on a new material instance from the default material
instance, we were losing the dirty bits (i.e. they were copied),
and so the newly initialized buffer would never be comited.


This adds a setSamplers() methods which does exactly that, and for
symmetry (and more efficiently) we also add setUniforms() to 
UniformBuffer.
2019-02-27 11:47:57 -08:00
Mathias Agopian 9d78f1a54e cleanup regarding SamplerBuffer and UniformBuffer
- UniformBuffer::toBufferDescriptor() now cleans the dirty flags
- SamplerBuffer move ctor and operator now clean the dirty flags of the
  moved (source) buffer.
- SamplerBuffer::toCommandStream() can be used to more efficiently copy
  a SamplerBuffer into the command stream -- this saves a copy.
- simplified SamplerBuffer's copy and move ctor/operator
- added a few constexpr here and there
2019-02-27 11:47:57 -08:00
Mathias Agopian 1ec8fc16a4 more support for 2D texture arrays in the driver
Very much untested, but it should work!
2019-02-27 11:47:38 -08:00
Romain Guy 705c1969b2 Add clearCoatIorChange property to materials (#890)
This property can be used to control the darkening of the base layer
due to a change in index of refraction when going through the clear
coat layer.
2019-02-27 10:30:46 -08:00
Philip Rideout ace38eff24 SurfaceOrientation cleanup per code review. 2019-02-27 08:47:24 -08:00
Philip Rideout 6d1e0ed6f4 Introduce SurfaceOrientation helper class.
This moves our existing VertexBuffer utility into a new "geometry"
library and adds new functionality for computing tangents based on UV's.
The UV-based method comes from Eric Lengyel.

We considered mikktspace (which thankfully has a zlib-style license) but
it would require re-indexing via meshoptimizer and is therefore a bit
heavyweight.

The new library has no dependencies and will add only 7 KB to Filament's
Android aar file.

Fixes #858 and preps for #528.
2019-02-27 08:47:24 -08:00
Philip Rideout c65e561c59 Fix nans in math::slerp, second attempt.
My earlier fix (3b373e5) was insufficient in some cases, this new
approach is cribbed from glMatrix.
2019-02-26 21:03:49 -08:00
Romain Guy 552b1c551f The cloth material model is not more expensive 2019-02-26 14:50:25 -08:00
Philip Rideout b1ba798312 Disable macOS deprecation warnings. 2019-02-26 14:14:59 -08:00
Mathias Agopian e40935dae8 Fix #871 -- double free if RenderableManager::Builder (#886)
The move ctor wasn't implemented properly. We actually fix this by
using a std::vector<> instead of a raw allocation for storing entries.
This std::vector<> is never reallocated.
2019-02-25 15:32:31 -08:00
Adrian Perez 38a6d047c9 Add a public method for creating atlas textures (#844) 2019-02-25 15:32:14 -08:00
Romain Guy b3284edb36 Android standalone toolchains are not longer necessary (#874)
* Android standalone toolchains are not longer necessary

The latest NDK (19) contains ABI/API level specific command line
tools making standalone toolchains unnecessary. This change adapts
to the new model which greatly simplifies the build script and
ensures the latest version of the tools is being used.

Note that this requires a fairly recent version of CMake which fixes
a bug related to ranlib. This change was tested with CMake 3.13
(CMake 3.7 does not work).

* Modify CI build script to fetch recent CMake

* Remove dependency on standalone toolchains in Windows README

* Use correct CMake path

* Update NDK to latest

* Only download CMake and NDK for Android builds

* Add version constant for ninja

* Make output more quiet
2019-02-25 15:14:31 -08:00
Ben Doherty 2378e64153 Add material-builder Android sample (#884) 2019-02-25 14:46:05 -08:00
Philip Rideout 186920e8d0 Fix up emissive energy compensation for glTF. 2019-02-25 14:32:58 -08:00
Ben Doherty d8ca867691 Small changes to iOS readme
Add `-i` flag to ensure installs and "apps" is now plural.
2019-02-25 13:57:43 -08:00
Ben Doherty 5e27fdea68 Add glRenderbufferStorageMultisampleEXT declaration to iOS (#866) 2019-02-25 13:22:38 -08:00
Mathias Agopian c0e63b24c1 rework multisample driver api
It's now possible to create a multisample FBO with a non-multisample
texture attachment. In this case, the drive is responsible for
automatically resolving the multisample buffer into the texture on
endRenderPass().

This allows us to avoid doing a "resolve blit" on the client side, but 
more importantly, it allows the driver to do this efficiently,
especially on tilers.

The semantic of this operation is the same than with
EXT_multisampled_render_to_texture. i.e. the multisample buffer is
lost after resolve. For GL/GLES drivers if 
EXT_multisampled_render_to_texture is not available this behavior
is emulated with a renderbuffer + blit.


This CL also fixes the creation of attachments to a face of a cubemap.
2019-02-25 13:22:38 -08:00
Pixelflinger 8a6de4cff1 Fix fxaa offset (#868)
vertex shader interpolants are interpolated at pixel centers by the GPU,
but we were doing our own "pixel-center" adjustment, so we ended-up with
"vertex_uv" at a pixel corner instead of center.

with this change, the vertex shader always compute vertex_uv in
fractional texels and the conversion to texture coordinates is done
in the fxaa code.

The half-pixel adjustment is removed.

This leads to sharper looking images because in addition to shifting
everything by 0.5 pixels, this was essentially applying a box-filter
to the whole picture -- kind of like taking 1 mip level down.
2019-02-25 13:22:14 -08:00
Philip Rideout e56ff75e1b Fix WebGL continuous builds. 2019-02-25 12:31:36 -08:00
Philip Rideout 147dafb4c1 Fix webgl on kokoro. 2019-02-25 12:02:47 -08:00
Ben Doherty 5f6f026648 Correct typo in Windows readme for Android
Fixes #882
2019-02-25 11:19:11 -08:00
Romain Guy fdee8e2e5c Add missing call to surfaceChanged()
Fixes #842
2019-02-23 22:34:43 -08:00
Philip Rideout e9430dd07f Do not use CMAKE_SOURCE_DIR.
This is one of those CMake gotchas, we should always use
CMAKE_CURRENT_SOURCE_DIR instead of CMAKE_SOURCE_DIR to allow
Filament to exist as a subproject.

In particular, this was causing the following build error when trying to
build Filament as a nested project.

    combine-static-libs.sh: No such file or directory

Fixes #861.
2019-02-22 15:38:52 -08:00
Ben Doherty 538243295c Add TextureReshaper (#862) 2019-02-22 12:34:29 -08:00
Ben Doherty fa3f34ea4b Update iOS samples README (#857) 2019-02-22 09:14:22 -08:00
Ben Doherty 3faef1f9cb Complete the MaterialBuilder JNI (#845) 2019-02-21 14:53:32 -08:00
Ben Doherty d0bab0fa8a Add hello-pbr iOS demo (#851) 2019-02-21 12:57:29 -08:00
Romain Guy 4738e93b83 Replace Cloth DFG approximation with DFG LUT
By removing the Fresnel term (often ommitted from fabric/cloth BRDFs)
we can store the DG term for the cloth BRDF in the 3rd channel of the
existing DFG LUT.
2019-02-21 11:44:52 -08:00
Ben Doherty 803c922ac1 Fix, can't set material parameters on default material instance (#854) 2019-02-21 10:30:01 -08:00
Ben Doherty cc637870b6 Fix Vulkan swapchain size on Windows (#852) 2019-02-20 17:25:29 -08:00
Ben Doherty 5c57a18b35 Initialize MaterialBuilder in samples (#850) 2019-02-20 14:47:29 -08:00
Philip Rideout d538e71959 Repair gltf_viewer by calling Material::init. 2019-02-20 14:39:30 -08:00
Mathias Agopian c1c84f6400 minor code and comments cleanups in dfg computations
also added uniform hemisphere sampling function for reference.
2019-02-20 13:52:57 -08:00
Philip Rideout 84eb9547f5 Tangent-related fixups in MeshAssimp.
Assimp's CalcTangentSpace deviates from de facto glTF 2.0 so we were
compensating for this with an unconditional fixup in MeshAssimp. However
the fixup should apply only when CalcTangentSpace is active, i.e. when
the model is missing tangents.

This makes it so that NormalTangentMirrorTest (has tangents) and
NormalTangentTest (needs tangents) both look reasonable.

I also noticed that MeshAssimp was inexplicably applying
aiProcess_CalcTangentSpace twice: once as a flag, and once as a
post-process. I removed the latter.

This will be fixed in the upcoming cgltf-based loader, which will
use our officially-sanctioned utility method in VertexBuffer.

See #528
2019-02-20 13:29:44 -08:00
Mathias Agopian 9b5060bb1d improve bindBufferRange() state tracking
we never rely (or should rely) on the fact that glBinderBufferRange()
also sets the generic binding, so we don't need to check for that when
calling glBindBufferRange().

This helps a little bit reducing the numbers of GL calls, especially
when several consecutive draw calls use the same material instance.
2019-02-20 12:34:45 -08:00
Ben Doherty d22e2f2834 Fix wrong init method being called (#846) 2019-02-20 11:05:55 -08:00
Ben Doherty 52ebfb1665 Add Init and Shutdown methods to MaterialBuilder (#840) 2019-02-20 10:44:12 -08:00
Adrian Perez 07eda48196 Missing include 2019-02-20 09:41:18 -08:00
Romain Guy b2f19a1879 Remove incorrect approximations 2019-02-19 18:41:31 -08:00
Mathias Agopian 39b9d30d1a Minor RenderStream cleanups 2019-02-19 18:31:43 -08:00
Mathias Agopian 45beccc68b Fix build when DEBUG_RENDER_STREAM is enabled 2019-02-19 18:31:43 -08:00
Mathias Agopian 45e7580dc6 rename synchronous driver calls
synchronous driver calls are split in 2 calls, respectively:
fooS() and fooR() instead of fooSynchronous() and foo().

This is a tiny step towards decoupling drivers from the
renderstream, which is a pipedream of mine.
2019-02-19 18:31:43 -08:00
Romain Guy 6f9df5bfab Update incorrect equations of importance sampling 2019-02-19 17:59:39 -08:00
Philip Rideout 91ce2f412b Bump MATERIAL_VERSION. 2019-02-19 15:54:58 -08:00
Philip Rideout e60744a6e4 Introduce MATERIAL_VERSION and panic.
Material archives already contain two version chunks (post process and
normal) but the renderer was ignoring these. The change makes it so that
matc writes a new MaterialEnums value into these chunks, and the engine
panics when receiving a material version that it does not expect.

This also adds a --version option to matc. No changes were necessary
to matinfo because it already prints out these values.

Fixes #796.
2019-02-19 15:54:58 -08:00
Ben Doherty de4abe3295 Replace MoltenVK with Metal for iOS sample (#825) 2019-02-19 12:25:24 -08:00
Philip Rideout b6ccdc0529 Update stb and add tnt/README.
Fixes #832.
2019-02-19 12:18:29 -08:00
526 changed files with 43498 additions and 39664 deletions
+13 -7
View File
@@ -16,7 +16,7 @@ option(ENABLE_JAVA "Compile Java projects, requires a JDK and the JAVA_HOME env
option(USE_EXTERNAL_GLES3 "Experimental: Compile Filament against OpenGL ES 3" OFF)
option(GENERATE_WEB_DOCS "Build WebGL documentation and tutorials" OFF)
option(GENERATE_JS_DOCS "Build WebGL documentation and tutorials" OFF)
# ==================================================================================================
# OS specific
@@ -218,8 +218,7 @@ endif()
# By default, build with Vulkan support on desktop platforms, although clients must request to use
# it at run time. On Android, the build does not include Vulkan support unless CMake is invoked
# with -DFILAMENT_SUPPORTS_VULKAN=ON.
# Vulkan is not supported on Windows.
if (ANDROID OR WIN32 OR WEBGL)
if (ANDROID OR WIN32 OR WEBGL OR IOS)
option(FILAMENT_SUPPORTS_VULKAN "Include the Vulkan backend" OFF)
else()
option(FILAMENT_SUPPORTS_VULKAN "Include the Vulkan backend" ON)
@@ -229,7 +228,8 @@ if (FILAMENT_SUPPORTS_VULKAN)
endif()
# Build with Metal support on non-WebGL Apple platforms.
if (APPLE AND NOT WEBGL)
# Apple's simulator does not support Metal.
if (APPLE AND (NOT IOS OR IOS_ARCH STREQUAL "arm64") AND NOT WEBGL)
option(FILAMENT_SUPPORTS_METAL "Include the Metal backend" ON)
else()
option(FILAMENT_SUPPORTS_METAL "Include the Metal backend" OFF)
@@ -303,7 +303,9 @@ endif()
# ==================================================================================================
# Sets the following variables: RESGEN_HEADER, RESGEN_SOURCE, RESGEN_FLAGS, RESGEN_SOURCE_FLAGS,
# and RESGEN_OUTPUTS
# and RESGEN_OUTPUTS. Please pass in an ARCHIVE_NAME that is unique to your project, otherwise the
# incbin directive will happily consume a blob from the wrong project without warnings or errors.
# Also be sure to include the ASM language in the CMake "project" directive for your project.
function(get_resgen_vars ARCHIVE_DIR ARCHIVE_NAME)
set(OUTPUTS
${ARCHIVE_DIR}/${ARCHIVE_NAME}.bin
@@ -318,7 +320,7 @@ function(get_resgen_vars ARCHIVE_DIR ARCHIVE_NAME)
set(RESGEN_HEADER "${ARCHIVE_DIR}/${ARCHIVE_NAME}.h" PARENT_SCOPE)
# Visual Studio makes it difficult to use assembly without using MASM. MASM doesn't support
# the equivalent of .incbin, so on Windows we'll just tell resgen to output a C file.
if (WEBGL OR WIN32)
if (WEBGL OR WIN32 OR ANDROID_ON_WINDOWS)
set(RESGEN_OUTPUTS "${OUTPUTS};${ARCHIVE_DIR}/${ARCHIVE_NAME}.c" PARENT_SCOPE)
set(RESGEN_FLAGS -cx ${ARCHIVE_DIR} -p ${ARCHIVE_NAME} PARENT_SCOPE)
set(RESGEN_SOURCE "${ARCHIVE_DIR}/${ARCHIVE_NAME}.c" PARENT_SCOPE)
@@ -339,6 +341,8 @@ add_subdirectory(${EXTERNAL}/libgtest/tnt)
add_subdirectory(${LIBRARIES}/filabridge)
add_subdirectory(${LIBRARIES}/filaflat)
add_subdirectory(${LIBRARIES}/filameshio)
add_subdirectory(${LIBRARIES}/geometry)
add_subdirectory(${LIBRARIES}/ibl)
add_subdirectory(${LIBRARIES}/image)
add_subdirectory(${LIBRARIES}/math)
add_subdirectory(${LIBRARIES}/utils)
@@ -373,7 +377,7 @@ if (WEBGL)
add_subdirectory(web/filament-js)
add_subdirectory(web/samples)
if (GENERATE_WEB_DOCS)
if (GENERATE_JS_DOCS)
add_subdirectory(web/docs)
endif()
@@ -384,6 +388,7 @@ endif()
if (NOT ANDROID AND NOT WEBGL AND NOT IOS)
add_subdirectory(${LIBRARIES}/bluegl)
add_subdirectory(${LIBRARIES}/filagui)
add_subdirectory(${LIBRARIES}/gltfio)
add_subdirectory(${LIBRARIES}/imageio)
add_subdirectory(${FILAMENT}/java/filamat)
@@ -391,6 +396,7 @@ if (NOT ANDROID AND NOT WEBGL AND NOT IOS)
add_subdirectory(${FILAMENT}/samples)
add_subdirectory(${EXTERNAL}/astcenc/tnt)
add_subdirectory(${EXTERNAL}/cgltf/tnt)
add_subdirectory(${EXTERNAL}/etc2comp)
add_subdirectory(${EXTERNAL}/getopt)
add_subdirectory(${EXTERNAL}/imgui/tnt)
+1 -1
View File
@@ -20,7 +20,7 @@ again.
Contributor License Agreement (see details above).
1. Fork the desired repo, develop and test your code changes.
1. Ensure that your code adheres to the existing style in the sample to which
you are contributing. Refer to [CodeStyle.md](/CodeStyle.md) for the recommended coding
you are contributing. Refer to [CodeStyle.md](/CODE_STYLE.md) for the recommended coding
standards for this project.
1. Ensure that your code has an appropriate set of unit tests which all pass.
1. Submit a pull request.
+19 -87
View File
@@ -26,11 +26,11 @@ badges above.
## Documentation
- [Filament](https://google.github.io/filament/Filament.md.html), an in-depth explanation of
- [Filament](https://google.github.io/filament/Filament.html), an in-depth explanation of
real-time physically based rendering, the graphics capabilities and implementation of Filament.
This document explains the math and reasoning behind most of our decisions. This document is a
good introduction to PBR for graphics programmers.
- [Materials](https://google.github.io/filament/Materials.md.html), the full reference
- [Materials](https://google.github.io/filament/Materials.html), the full reference
documentation for our material system. This document explains our different material models, how
to use the material compiler `matc` and how to write custom materials.
- [Material Properties](https://google.github.io/filament/Material%20Properties.pdf), a reference
@@ -62,6 +62,7 @@ Here are a few sample materials rendered with Filament:
- OpenGL 4.1+ for Linux, macOS and Windows
- OpenGL ES 3.0+ for Android and iOS
- Metal for macOS and iOS
- Vulkan 1.0 for Android, Linux, macOS and iOS (with MoltenVk), and Windows
- WebGL 2.0 for all platforms
@@ -90,7 +91,7 @@ Here are a few sample materials rendered with Filament:
Many other features have been either prototyped or planned:
- IES light profiles
- IES light profiles/cookies
- Area lights
- Fog
- Color grading
@@ -124,7 +125,9 @@ and tools.
- `filaflat`: Serialization/deserialization library used for materials
- `filagui`: Helper library for [Dear ImGui](https://github.com/ocornut/imgui)
- `filamat`: Material generation library
- `filameshio`: Tiny mesh parsing library (see also `tools/filamesh`)
- `filameshio`: Tiny filamesh parsing library (see also `tools/filamesh`)
- `geometry`: Mesh-related utilities
- `gltfio`: Loader for glTF 2.0
- `image`: Image filtering and simple transforms
- `imageio`: Image file reading / writing, only intended for internal use
- `math`: Math library
@@ -133,6 +136,7 @@ and tools.
- `shaders`: Shaders used by `filamat` and `matc`
- `third_party`: External libraries and assets
- `environments`: Environment maps under CC0 license that can be used with `cmgen`
- `models`: Models under permissive licenses
- `textures`: Textures under CC0 license
- `tools`: Host tools
- `cmgen`: Image-based lighting asset generator
@@ -154,7 +158,7 @@ and tools.
To build Filament, you must first install the following tools:
- CMake 3.4 (or more recent)
- CMake 3.10 (or more recent)
- clang 7.0 (or more recent)
- [ninja 1.8](https://github.com/ninja-build/ninja/wiki/Pre-built-Ninja-packages) (or more recent)
@@ -169,7 +173,7 @@ To build Filament for Android you must also install the following:
- Android Studio 3.3
- Android SDK
- Android NDK
- Android NDK 19 or higher
### Environment variables
@@ -232,8 +236,8 @@ Make sure you've installed the following dependencies:
- `clang-7`
- `libglu1-mesa-dev`
- `libc++-7-dev` (`libcxx-devel` on Fedora)
- `libc++abi-7-dev`
- `libc++-7-dev` (`libcxx-devel` and `libcxx-static` on Fedora)
- `libc++abi-7-dev` (`libcxxabi-static` on Fedora)
- `ninja-build`
- `libxi-dev`
@@ -334,10 +338,9 @@ Install the following components:
- [Windows 10 SDK](https://developer.microsoft.com/en-us/windows/downloads/windows-10-sdk)
- [Visual Studio 2015 or 2017](https://www.visualstudio.com/downloads)
- [Clang 6](http://releases.llvm.org/download.html)
- [Clang 7](http://releases.llvm.org/download.html)
- [Python 3.7](https://www.python.org/ftp/python/3.7.0/python-3.7.0.exe)
- [Git 2.16.1 or later](https://github.com/git-for-windows/git/releases/download/v2.16.1.windows.4/PortableGit-2.16.1.4-64-bit.7z.exe)
- [Cmake 3.11 or later](https://cmake.org/files/v3.11/cmake-3.11.0-rc1-win64-x64.msi)
- [Cmake 3.13 or later](https://github.com/Kitware/CMake/releases/download/v3.13.4/cmake-3.13.4-win64-x64.msi)
If you're using Visual Studio 2017, you'll also need to install the [LLVM Compiler
Toolchain](https://marketplace.visualstudio.com/items?itemName=LLVMExtensions.llvm-toolchain)
@@ -463,24 +466,6 @@ Run `build.sh -h` for more information.
#### ARM 64-bit target (arm64-v8a)
##### Linux toolchain
```
$ $SDK/ndk-bundle/build/tools/make_standalone_toolchain.py --arch arm64 --api 21 \
--stl libc++ --force \
--install-dir toolchains/Linux/aarch64-linux-android-4.9
```
##### Darwin toolchain
```
$ $SDK/ndk-bundle/build/tools/make_standalone_toolchain.py --arch arm64 --api 21 \
--stl libc++ --force \
--install-dir toolchains/Darwin/aarch64-linux-android-4.9
```
##### Compiling
Then invoke CMake in a build directory of your choice, inside of filament's directory:
```
@@ -508,24 +493,6 @@ binaries should be found in `out/android-release/filament/lib/arm64-v8a`.
#### ARM 32-bit target (armeabi-v7a)
##### Linux toolchain
```
$ $SDK/ndk-bundle/build/tools/make_standalone_toolchain.py --arch arm --api 21 \
--stl libc++ --force \
--install-dir toolchains/Linux/arm-linux-androideabi-4.9
```
##### Darwin toolchain
```
$ $SDK/ndk-bundle/build/tools/make_standalone_toolchain.py --arch arm --api 21 \
--stl libc++ --force \
--install-dir toolchains/Darwin/arm-linux-androideabi-4.9
```
##### Compiling
Then invoke CMake in a build directory of your choice, inside of filament's directory:
```
@@ -553,24 +520,6 @@ binaries should be found in `out/android-release/filament/lib/armeabi-v7a`.
#### Intel 64-bit target (x86_64)
##### Linux toolchain
```
$ $SDK/ndk-bundle/build/tools/make_standalone_toolchain.py --arch x86_64 --api 21 \
--stl libc++ --force \
--install-dir toolchains/Linux/x86_64-linux-android-4.9
```
##### Darwin toolchain
```
$ $SDK/ndk-bundle/build/tools/make_standalone_toolchain.py --arch x86_64 --api 21 \
--stl libc++ --force \
--install-dir toolchains/Darwin/x86_64-linux-android-4.9
```
##### Compiling
Then invoke CMake in a build directory of your choice, sibling of filament's directory:
```
@@ -598,24 +547,6 @@ binaries should be found in `out/android-release/filament/lib/x86_64`.
#### Intel 32-bit target (x86)
##### Linux toolchain
```
$ $SDK/ndk-bundle/build/tools/make_standalone_toolchain.py --arch x86 --api 21 \
--stl libc++ --force \
--install-dir toolchains/Linux/i686-linux-android-4.9
```
##### Darwin toolchain
```
$ $SDK/ndk-bundle/build/tools/make_standalone_toolchain.py --arch x86 --api 21 \
--stl libc++ --force \
--install-dir toolchains/Darwin/i686-linux-android-4.9
```
##### Compiling
Then invoke CMake in a build directory of your choice, sibling of filament's directory:
```
@@ -725,13 +656,13 @@ same version that our continuous builds use.
```
cd <your chosen parent folder for the emscripten SDK>
curl -L https://github.com/juj/emsdk/archive/0d8576c.zip > emsdk.zip
curl -L https://github.com/emscripten-core/emsdk/archive/a77638d.zip > emsdk.zip
unzip emsdk.zip
mv emsdk-* emsdk
cd emsdk
./emsdk update
./emsdk install sdk-1.38.11-64bit
./emsdk activate sdk-1.38.11-64bit
./emsdk install sdk-1.38.28-64bit
./emsdk activate sdk-1.38.28-64bit
```
After this you can invoke the [easy build](#easy-build) script as follows:
@@ -898,7 +829,8 @@ MoltenVK.
## Generating C++ documentation
To generate the documentation you must first install `doxygen`, then run the following commands:
To generate the documentation you must first install `doxygen` and `graphviz`, then run the
following commands:
```
$ cd filament/filament
-37
View File
@@ -39,43 +39,6 @@ ninja matc resgen cmgen
The build should succeed and a `ImportExecutables-Release.cmake` file should automatically be
created at Filament's root directory.
## Toolchains
Generate a toolchain for each Android architecture you're interested in building for.
From Filament's root directory, run the NDK `make_standalone_toolchain.py` script for each
architecture.
```
python %ANDROID_HOME%\ndk-bundle\build\tools\make_standalone_toolchain.py ^
--arch arm64 ^
--api 21 ^
--stl libc++ ^
--force ^
--install-dir "toolchains/Windows/aarch64-linux-android-4.9"
python %ANDROID_HOME%\ndk-bundle\build\tools\make_standalone_toolchain.py ^
--arch arm ^
--api 21 ^
--stl libc++ ^
--force ^
--install-dir "toolchains/Windows/arm-linux-android-4.9"
python %ANDROID_HOME%\ndk-bundle\build\tools\make_standalone_toolchain.py ^
--arch x86_64 ^
--api 21 ^
--stl libc++ ^
--force ^
--install-dir "toolchains/Windows/x86_64-linux-android-4.9"
python %ANDROID_HOME%\ndk-bundle\build\tools\make_standalone_toolchain.py ^
--arch x86 ^
--api 21 ^
--stl libc++ ^
--force ^
--install-dir "toolchains/Windows/x86-linux-android-4.9"
````
## Build
1. Create the build directories.
@@ -18,11 +18,23 @@
#include <filamat/MaterialBuilder.h>
#include <filament/EngineEnums.h>
#include <private/filament/EngineEnums.h>
using namespace filament;
using namespace filamat;
extern "C" JNIEXPORT void JNICALL
Java_com_google_android_filament_filamat_MaterialBuilder_nMaterialBuilderInit(JNIEnv *env,
jclass type) {
MaterialBuilder::init();
}
extern "C" JNIEXPORT void JNICALL
Java_com_google_android_filament_filamat_MaterialBuilder_nMaterialBuilderShutdown(JNIEnv *env,
jclass type) {
MaterialBuilder::shutdown();
}
extern "C" JNIEXPORT jlong JNICALL
Java_com_google_android_filament_filamat_MaterialBuilder_nCreateMaterialBuilder(JNIEnv *env,
jclass type) {
@@ -80,7 +92,49 @@ extern "C" JNIEXPORT void JNICALL
Java_com_google_android_filament_filamat_MaterialBuilder_nMaterialBuilderShading(JNIEnv* env,
jclass type, jlong nativeBuilder, jint shading) {
auto builder = (MaterialBuilder*) nativeBuilder;
builder->shading((Shading) shading);
builder->shading((MaterialBuilder::Shading) shading);
}
extern "C" JNIEXPORT void JNICALL
Java_com_google_android_filament_filamat_MaterialBuilder_nMaterialBuilderInterpolation(JNIEnv* env,
jclass type, jlong nativeBuilder, jint interpolation) {
auto builder = (MaterialBuilder*) nativeBuilder;
builder->interpolation((MaterialBuilder::Interpolation) interpolation);
}
extern "C" JNIEXPORT void JNICALL
Java_com_google_android_filament_filamat_MaterialBuilder_nMaterialBuilderUniformParameter(
JNIEnv* env, jclass type, jlong nativeBuilder, jint uniformType, jstring name_) {
auto builder = (MaterialBuilder*) nativeBuilder;
const char* name = env->GetStringUTFChars(name_, nullptr);
builder->parameter((MaterialBuilder::UniformType) uniformType, name);
}
extern "C" JNIEXPORT void JNICALL
Java_com_google_android_filament_filamat_MaterialBuilder_nMaterialBuilderUniformParameterArray(
JNIEnv* env, jclass type, jlong nativeBuilder, jint uniformType, jint size, jstring name_) {
auto builder = (MaterialBuilder*) nativeBuilder;
const char* name = env->GetStringUTFChars(name_, nullptr);
builder->parameter((MaterialBuilder::UniformType) uniformType, (size_t) size, name);
}
extern "C" JNIEXPORT void JNICALL
Java_com_google_android_filament_filamat_MaterialBuilder_nMaterialBuilderSamplerParameter(
JNIEnv* env, jclass type, jlong nativeBuilder, jint samplerType, jint format,
jint precision, jstring name_) {
auto builder = (MaterialBuilder*) nativeBuilder;
const char* name = env->GetStringUTFChars(name_, nullptr);
builder->parameter((MaterialBuilder::SamplerType) samplerType,
(MaterialBuilder::SamplerFormat) format, (MaterialBuilder::SamplerPrecision) precision,
name);
}
extern "C" JNIEXPORT void JNICALL
Java_com_google_android_filament_filamat_MaterialBuilder_nMaterialBuilderVariable(
JNIEnv* env, jclass type, jlong nativeBuilder, jint variable, jstring name_) {
const char* name = env->GetStringUTFChars(name_, nullptr);
auto builder = (MaterialBuilder*) nativeBuilder;
builder->variable((MaterialBuilder::Variable) variable, name);
}
extern "C" JNIEXPORT void JNICALL
@@ -106,6 +160,27 @@ Java_com_google_android_filament_filamat_MaterialBuilder_nMaterialBuilderMateria
builder->materialVertex(code);
}
extern "C" JNIEXPORT void JNICALL
Java_com_google_android_filament_filamat_MaterialBuilder_nMaterialBuilderBlending(JNIEnv* env,
jclass type, jlong nativeBuilder, jint mode) {
auto builder = (MaterialBuilder*) nativeBuilder;
builder->blending((MaterialBuilder::BlendingMode) mode);
}
extern "C" JNIEXPORT void JNICALL
Java_com_google_android_filament_filamat_MaterialBuilder_nMaterialBuilderVertexDomain(JNIEnv* env,
jclass type, jlong nativeBuilder, jint vertexDomain) {
auto builder = (MaterialBuilder*) nativeBuilder;
builder->vertexDomain((MaterialBuilder::VertexDomain) vertexDomain);
}
extern "C" JNIEXPORT void JNICALL
Java_com_google_android_filament_filamat_MaterialBuilder_nMaterialBuilderCulling(JNIEnv* env,
jclass type, jlong nativeBuilder, jint mode) {
auto builder = (MaterialBuilder*) nativeBuilder;
builder->culling((MaterialBuilder::CullingMode) mode);
}
extern "C" JNIEXPORT void JNICALL
Java_com_google_android_filament_filamat_MaterialBuilder_nMaterialBuilderColorWrite(JNIEnv* env,
jclass type, jlong nativeBuilder, jboolean enable) {
@@ -113,9 +188,100 @@ Java_com_google_android_filament_filamat_MaterialBuilder_nMaterialBuilderColorWr
builder->colorWrite(enable);
}
extern "C" JNIEXPORT void JNICALL
Java_com_google_android_filament_filamat_MaterialBuilder_nMaterialBuilderDepthWrite(JNIEnv* env,
jclass type, jlong nativeBuilder, jboolean depthWrite) {
auto builder = (MaterialBuilder*) nativeBuilder;
builder->depthWrite(depthWrite);
}
extern "C" JNIEXPORT void JNICALL
Java_com_google_android_filament_filamat_MaterialBuilder_nMaterialBuilderDepthCulling(JNIEnv* env,
jclass type, jlong nativeBuilder, jboolean depthCulling) {
auto builder = (MaterialBuilder*) nativeBuilder;
builder->depthCulling(depthCulling);
}
extern "C" JNIEXPORT void JNICALL
Java_com_google_android_filament_filamat_MaterialBuilder_nMaterialBuilderDoubleSided(JNIEnv* env,
jclass type, jlong nativeBuilder, jboolean doubleSided) {
auto builder = (MaterialBuilder*) nativeBuilder;
builder->doubleSided(doubleSided);
}
extern "C" JNIEXPORT void JNICALL
Java_com_google_android_filament_filamat_MaterialBuilder_nMaterialBuilderMaskThreshold(JNIEnv* env,
jclass type, jlong nativeBuilder, jfloat maskThreshold) {
auto builder = (MaterialBuilder*) nativeBuilder;
builder->maskThreshold(maskThreshold);
}
extern "C" JNIEXPORT void JNICALL
Java_com_google_android_filament_filamat_MaterialBuilder_nMaterialBuilderShadowMultiplier(
JNIEnv* env, jclass type, jlong nativeBuilder, jboolean shadowMultiplier) {
auto builder = (MaterialBuilder*) nativeBuilder;
builder->shadowMultiplier(shadowMultiplier);
}
extern "C" JNIEXPORT void JNICALL
Java_com_google_android_filament_filamat_MaterialBuilder_nMaterialBuilderCurvatureToRoughness(
JNIEnv* env, jclass type, jlong nativeBuilder, jboolean curvatureToRoughness) {
auto builder = (MaterialBuilder*) nativeBuilder;
builder->curvatureToRoughness(curvatureToRoughness);
}
extern "C" JNIEXPORT void JNICALL
Java_com_google_android_filament_filamat_MaterialBuilder_nMaterialBuilderLimitOverInterpolation(
JNIEnv* env, jclass type, jlong nativeBuilder, jboolean limitOverInterpolation) {
auto builder = (MaterialBuilder*) nativeBuilder;
builder->limitOverInterpolation(limitOverInterpolation);
}
extern "C" JNIEXPORT void JNICALL
Java_com_google_android_filament_filamat_MaterialBuilder_nMaterialBuilderClearCoatIorChange(
JNIEnv* env, jclass type, jlong nativeBuilder, jboolean clearCoatIorChange) {
auto builder = (MaterialBuilder*) nativeBuilder;
builder->clearCoatIorChange(clearCoatIorChange);
}
extern "C" JNIEXPORT void JNICALL
Java_com_google_android_filament_filamat_MaterialBuilder_nMaterialBuilderFlipUV(JNIEnv* env,
jclass type, jlong nativeBuilder, jboolean flipUV) {
auto builder = (MaterialBuilder*) nativeBuilder;
builder->flipUV(flipUV);
}
extern "C" JNIEXPORT void JNICALL
Java_com_google_android_filament_filamat_MaterialBuilder_nMaterialBuilderTransparencyMode(
JNIEnv* env, jclass type, jlong nativeBuilder, jint mode) {
auto builder = (MaterialBuilder*) nativeBuilder;
builder->transparencyMode((MaterialBuilder::TransparencyMode) mode);
}
extern "C" JNIEXPORT void JNICALL
Java_com_google_android_filament_filamat_MaterialBuilder_nMaterialBuilderPlatform(JNIEnv* env,
jclass type, jlong nativeBuilder, jint platform) {
auto builder = (MaterialBuilder*) nativeBuilder;
builder->platform((MaterialBuilder::Platform) platform);
}
extern "C" JNIEXPORT void JNICALL
Java_com_google_android_filament_filamat_MaterialBuilder_nMaterialBuilderTargetApi(JNIEnv* env,
jclass type, jlong nativeBuilder, jint targetApi) {
auto builder = (MaterialBuilder*) nativeBuilder;
builder->targetApi((MaterialBuilder::TargetApi) targetApi);
}
extern "C" JNIEXPORT void JNICALL
Java_com_google_android_filament_filamat_MaterialBuilder_nMaterialBuilderOptimization(JNIEnv* env,
jclass type, jlong nativeBuilder, jint optimization) {
auto builder = (MaterialBuilder*) nativeBuilder;
builder->optimization((MaterialBuilder::Optimization) optimization);
}
extern "C" JNIEXPORT void JNICALL
Java_com_google_android_filament_filamat_MaterialBuilder_nMaterialBuilderVariantFilter(JNIEnv* env,
jclass type, jlong nativeBuilder, jbyte variantFilter) {
auto builder = (MaterialBuilder*) nativeBuilder;
builder->variantFilter((uint8_t) variantFilter);
}
@@ -26,6 +26,70 @@ public class MaterialBuilder {
private final BuilderFinalizer mFinalizer;
private final long mNativeObject;
static {
System.loadLibrary("filamat-jni");
}
public enum Shading {
UNLIT, // no lighting applied, emissive possible
LIT, // default, standard lighting
SUBSURFACE, // subsurface lighting model
CLOTH // cloth lighting model
}
public enum Interpolation {
SMOOTH, // default, smooth interpolation
FLAT // flat interpolation
}
public enum UniformType {
BOOL,
BOOL2,
BOOL3,
BOOL4,
FLOAT,
FLOAT2,
FLOAT3,
FLOAT4,
INT,
INT2,
INT3,
INT4,
UINT,
UINT2,
UINT3,
UINT4,
MAT3,
MAT4
}
public enum SamplerType {
SAMPLER_2D, // 2D texture
SAMPLER_CUBEMAP, // Cube map texture
SAMPLER_EXTERNAL, // External texture
}
public enum SamplerFormat {
INT,
UINT,
FLOAT,
SHADOW
}
public enum SamplerPrecision {
LOW,
MEDIUM,
HIGH,
DEFAULT
}
public enum Variable {
CUSTOM0,
CUSTOM1,
CUSTOM2,
CUSTOM3
}
public enum VertexAttribute {
POSITION, // XYZ position (float3)
TANGENTS, // tangent, bitangent and normal, encoded as a quaternion (4 floats or half floats)
@@ -36,11 +100,38 @@ public class MaterialBuilder {
BONE_WEIGHTS // weights of the 4 bones (normalized float4)
}
public enum Shading {
UNLIT, // no lighting applied, emissive possible
LIT, // default, standard lighting
SUBSURFACE, // subsurface lighting model
CLOTH // cloth lighting model
public enum BlendingMode {
OPAQUE, // material is opaque
TRANSPARENT, // material is transparent and color is alpha-pre-multiplied,
// affects diffuse lighting only
ADD, // material is additive (e.g.: hologram)
MASKED, // material is masked (i.e. alpha tested)
FADE // material is transparent and color is alpha-pre-multiplied,
// affects specular lighting
}
public enum VertexDomain {
OBJECT, // vertices are in object space, default
WORLD, // vertices are in world space
VIEW, // vertices are in view space
DEVICE // vertices are in normalized device space
}
public enum CullingMode {
NONE,
FRONT,
BACK,
FRONT_AND_BACK
}
public enum TransparencyMode {
DEFAULT, // the transparent object is drawn honoring the raster state
TWO_PASSES_ONE_SIDE, // the transparent object is first drawn in the depth buffer,
// then in the color buffer, honoring the culling mode, but
// ignoring the depth test function
TWO_PASSES_TWO_SIDES // the transparent object is drawn twice in the color buffer,
// first with back faces only, then with front faces; the culling
// mode is ignored. Can be combined with two-sided lighting
}
public enum Platform {
@@ -49,6 +140,27 @@ public class MaterialBuilder {
ALL
}
public enum TargetApi {
ALL,
OPENGL,
VULKAN,
}
public enum Optimization {
NONE,
PREPROCESSOR,
SIZE,
PERFORMANCE
}
public static void init() {
nMaterialBuilderInit();
}
public static void shutdown() {
nMaterialBuilderShutdown();
}
public MaterialBuilder() {
mNativeObject = nCreateMaterialBuilder();
mFinalizer = new BuilderFinalizer(mNativeObject);
@@ -66,6 +178,38 @@ public class MaterialBuilder {
return this;
}
@NonNull
public MaterialBuilder interpolation(@NonNull Interpolation interpolation) {
nMaterialBuilderInterpolation(mNativeObject, interpolation.ordinal());
return this;
}
@NonNull
public MaterialBuilder uniformParameter(@NonNull UniformType type, String name) {
nMaterialBuilderUniformParameter(mNativeObject, type.ordinal(), name);
return this;
}
@NonNull
public MaterialBuilder uniformParameterArray(@NonNull UniformType type, int size, String name) {
nMaterialBuilderUniformParameterArray(mNativeObject, type.ordinal(), size, name);
return this;
}
@NonNull
public MaterialBuilder samplerParameter(@NonNull SamplerType type, SamplerFormat format,
SamplerPrecision precision, String name) {
nMaterialBuilderSamplerParameter(
mNativeObject, type.ordinal(), format.ordinal(), precision.ordinal(), name);
return this;
}
@NonNull
public MaterialBuilder variable(@NonNull Variable variable, String name) {
nMaterialBuilderVariable(mNativeObject, variable.ordinal(), name);
return this;
}
@NonNull
public MaterialBuilder require(@NonNull VertexAttribute attribute) {
nMaterialBuilderRequire(mNativeObject, attribute.ordinal());
@@ -84,18 +228,114 @@ public class MaterialBuilder {
return this;
}
@NonNull
public MaterialBuilder blending(@NonNull BlendingMode mode) {
nMaterialBuilderBlending(mNativeObject, mode.ordinal());
return this;
}
@NonNull
public MaterialBuilder vertexDomain(@NonNull VertexDomain vertexDomain) {
nMaterialBuilderVertexDomain(mNativeObject, vertexDomain.ordinal());
return this;
}
@NonNull
public MaterialBuilder culling(@NonNull CullingMode mode) {
nMaterialBuilderCulling(mNativeObject, mode.ordinal());
return this;
}
@NonNull
public MaterialBuilder colorWrite(boolean enable) {
nMaterialBuilderColorWrite(mNativeObject, enable);
return this;
}
@NonNull
public MaterialBuilder depthWrite(boolean enable) {
nMaterialBuilderDepthWrite(mNativeObject, enable);
return this;
}
@NonNull
public MaterialBuilder depthCulling(boolean enable) {
nMaterialBuilderDepthCulling(mNativeObject, enable);
return this;
}
@NonNull
public MaterialBuilder doubleSided(boolean doubleSided) {
nMaterialBuilderDoubleSided(mNativeObject, doubleSided);
return this;
}
@NonNull
public MaterialBuilder maskThreshold(float threshold) {
nMaterialBuilderMaskThreshold(mNativeObject, threshold);
return this;
}
@NonNull
public MaterialBuilder shadowMultiplier(boolean shadowMultiplier) {
nMaterialBuilderShadowMultiplier(mNativeObject, shadowMultiplier);
return this;
}
@NonNull
public MaterialBuilder curvatureToRoughness(boolean curvatureToRoughness) {
nMaterialBuilderCurvatureToRoughness(mNativeObject, curvatureToRoughness);
return this;
}
@NonNull
public MaterialBuilder limitOverInterpolation(boolean limitOverInterpolation) {
nMaterialBuilderLimitOverInterpolation(mNativeObject, limitOverInterpolation);
return this;
}
@NonNull
public MaterialBuilder clearCoatIorChange(boolean clearCoatIorChange) {
nMaterialBuilderClearCoatIorChange(mNativeObject, clearCoatIorChange);
return this;
}
@NonNull
public MaterialBuilder flipUV(boolean flipUV) {
nMaterialBuilderFlipUV(mNativeObject, flipUV);
return this;
}
@NonNull
public MaterialBuilder transparencyMode(@NonNull TransparencyMode mode) {
nMaterialBuilderTransparencyMode(mNativeObject, mode.ordinal());
return this;
}
@NonNull
public MaterialBuilder platform(@NonNull Platform platform) {
nMaterialBuilderPlatform(mNativeObject, platform.ordinal());
return this;
}
@NonNull
public MaterialBuilder targetApi(@NonNull TargetApi api) {
nMaterialBuilderTargetApi(mNativeObject, api.ordinal());
return this;
}
@NonNull
public MaterialBuilder optimization(@NonNull Optimization optimization) {
nMaterialBuilderOptimization(mNativeObject, optimization.ordinal());
return this;
}
@NonNull
public MaterialBuilder variantFilter(byte variantFilter) {
nMaterialBuilderVariantFilter(mNativeObject, variantFilter);
return this;
}
@NonNull
public MaterialPackage build() {
long nativePackage = nBuilderBuild(mNativeObject);
@@ -124,6 +364,9 @@ public class MaterialBuilder {
}
}
private static native void nMaterialBuilderInit();
private static native void nMaterialBuilderShutdown();
private static native long nCreateMaterialBuilder();
private static native void nDestroyMaterialBuilder(long nativeBuilder);
@@ -134,9 +377,40 @@ public class MaterialBuilder {
private static native void nMaterialBuilderName(long nativeBuilder, String name);
private static native void nMaterialBuilderShading(long nativeBuilder, int shading);
private static native void nMaterialBuilderInterpolation(long nativeBuilder, int interpolation);
private static native void nMaterialBuilderUniformParameter(long nativeBuilder, int type,
String name);
private static native void nMaterialBuilderUniformParameterArray(long nativeBuilder, int type,
int size, String name);
private static native void nMaterialBuilderSamplerParameter(long nativeBuilder, int type,
int format, int precision, String name);
private static native void nMaterialBuilderVariable(long nativeBuilder, int variable,
String name);
private static native void nMaterialBuilderRequire(long nativeBuilder, int attribute);
private static native void nMaterialBuilderMaterial(long nativeBuilder, String code);
private static native void nMaterialBuilderMaterialVertex(long nativeBuilder, String code);
private static native void nMaterialBuilderBlending(long nativeBuilder, int mode);
private static native void nMaterialBuilderVertexDomain(long nativeBuilder, int vertexDomain);
private static native void nMaterialBuilderCulling(long nativeBuilder, int mode);
private static native void nMaterialBuilderColorWrite(long nativeBuilder, boolean enable);
private static native void nMaterialBuilderDepthWrite(long nativeBuilder, boolean enable);
private static native void nMaterialBuilderDepthCulling(long nativeBuilder, boolean enable);
private static native void nMaterialBuilderDoubleSided(long nativeBuilder, boolean doubleSided);
private static native void nMaterialBuilderMaskThreshold(long nativeBuilder, float mode);
private static native void nMaterialBuilderShadowMultiplier(long mNativeObject,
boolean shadowMultiplier);
private static native void nMaterialBuilderCurvatureToRoughness(long mNativeObject,
boolean curvatureToRoughness);
private static native void nMaterialBuilderLimitOverInterpolation(long mNativeObject,
boolean limitOverInterpolation);
private static native void nMaterialBuilderClearCoatIorChange(long mNativeObject,
boolean clearCoatIorChange);
private static native void nMaterialBuilderFlipUV(long nativeBuilder, boolean flipUV);
private static native void nMaterialBuilderTransparencyMode(long nativeBuilder, int mode);
private static native void nMaterialBuilderPlatform(long nativeBuilder, int platform);
private static native void nMaterialBuilderTargetApi(long nativeBuilder, int api);
private static native void nMaterialBuilderOptimization(long nativeBuilder, int optimization);
private static native void nMaterialBuilderVariantFilter(long nativeBuilder,
byte variantFilter);
}
+5
View File
@@ -14,6 +14,10 @@ add_library(filaflat STATIC IMPORTED)
set_target_properties(filaflat PROPERTIES IMPORTED_LOCATION
${FILAMENT_DIR}/lib/${ANDROID_ABI}/libfilaflat.a)
add_library(geometry STATIC IMPORTED)
set_target_properties(geometry PROPERTIES IMPORTED_LOCATION
${FILAMENT_DIR}/lib/${ANDROID_ABI}/libgeometry.a)
add_library(filabridge STATIC IMPORTED)
set_target_properties(filabridge PROPERTIES IMPORTED_LOCATION
${FILAMENT_DIR}/lib/${ANDROID_ABI}/libfilabridge.a)
@@ -74,6 +78,7 @@ target_link_libraries(filament-jni
filament
filaflat
filabridge
geometry
utils
log
GLESv3
@@ -91,8 +91,7 @@ Java_com_google_android_filament_IndexBuffer_nSetBuffer(JNIEnv *env, jclass type
BufferDescriptor desc(data, sizeInBytes, &JniBufferCallback::invoke, callback);
indexBuffer->setBuffer(*engine, std::move(desc),
(uint32_t) destOffsetInBytes, (uint32_t) sizeInBytes);
indexBuffer->setBuffer(*engine, std::move(desc), (uint32_t) destOffsetInBytes);
return 0;
}
@@ -110,7 +110,7 @@ Java_com_google_android_filament_VertexBuffer_nSetBufferAt(JNIEnv *env, jclass t
BufferDescriptor desc(data, sizeInBytes, &JniBufferCallback::invoke, callback);
vertexBuffer->setBufferAt(*engine, (uint8_t) bufferIndex, std::move(desc),
(uint32_t) destOffsetInBytes, (uint32_t) sizeInBytes);
(uint32_t) destOffsetInBytes);
return 0;
}
@@ -122,6 +122,20 @@ Java_com_google_android_filament_View_nGetAntiAliasing(JNIEnv*, jclass,
return (jint) view->getAntiAliasing();
}
extern "C" JNIEXPORT void JNICALL
Java_com_google_android_filament_View_nSetDithering(JNIEnv*, jclass,
jlong nativeView, jint dithering) {
View* view = (View*) nativeView;
view->setDithering((View::Dithering) dithering);
}
extern "C" JNIEXPORT jint JNICALL
Java_com_google_android_filament_View_nGetDithering(JNIEnv*, jclass,
jlong nativeView) {
View* view = (View*) nativeView;
return (jint)view->getDithering();
}
extern "C" JNIEXPORT void JNICALL
Java_com_google_android_filament_View_nSetDynamicResolutionOptions(JNIEnv*,
jclass, jlong nativeView, jboolean enabled, jboolean homogeneousScaling,
@@ -60,6 +60,11 @@ public class View {
FXAA
}
public enum Dithering {
NONE,
TEMPORAL
}
public enum DepthPrepass {
DEFAULT(-1),
DISABLED(0),
@@ -160,6 +165,15 @@ public class View {
return AntiAliasing.values()[nGetAntiAliasing(getNativeObject())];
}
public void setDithering(@NonNull Dithering dithering) {
nSetDithering(getNativeObject(), dithering.ordinal());
}
@NonNull
public Dithering getDithering() {
return Dithering.values()[nGetDithering(getNativeObject())];
}
public void setDynamicResolutionOptions(@NonNull DynamicResolutionOptions options) {
mDynamicResolution = options;
nSetDynamicResolutionOptions(getNativeObject(),
@@ -257,6 +271,8 @@ public class View {
private static native int nGetSampleCount(long nativeView);
private static native void nSetAntiAliasing(long nativeView, int type);
private static native int nGetAntiAliasing(long nativeView);
private static native void nSetDithering(long nativeView, int dithering);
private static native int nGetDithering(long nativeView);
private static native void nSetDynamicResolutionOptions(long nativeView,
boolean enabled, boolean homogeneousScaling,
float targetFrameTimeMilli, float headRoomRatio, float scaleRate,
@@ -381,6 +381,9 @@ public class UiHelper {
final Surface surface = holder.getSurface();
if (surface != null && surface.isValid()) {
callback.surfaceCreated(holder);
int format = isOpaque() ? PixelFormat.OPAQUE : PixelFormat.TRANSLUCENT;
callback.surfaceChanged(holder, format,
holder.getSurfaceFrame().width(), holder.getSurfaceFrame().height());
}
}
}
+10
View File
@@ -39,6 +39,16 @@ Demonstrates how to render into a `TextureView` instead of a `SurfaceView`:
![Texture View](../../docs/images/samples/sample_texture_view.jpg)
### `material-builder`
Demonstrates how to programatically generate Filament materials, as opposed to compiling them on the
host machine:
![Material Builder](../../docs/images/samples/sample_image_based_lighting.jpg)
The `material-builder` sample requires the `filamat` static library which can be compiled by adding
the `-l` flag to the `./build.sh` command.
## Prerequisites
Before you start, make sure to read [Filament's README](../../README.md). You need to be able to
@@ -0,0 +1,12 @@
*.iml
.gradle
/local.properties
/.idea/workspace.xml
/.idea/libraries
/.idea/caches
/.idea/gradle.xml
.DS_Store
/build
/captures
/app/src/main/assets/envs
.externalNativeBuild
@@ -0,0 +1 @@
/build
@@ -0,0 +1,92 @@
apply plugin: 'com.android.application'
apply plugin: 'kotlin-android'
apply plugin: 'kotlin-android-extensions'
apply from: '../../../build/filament-tasks.gradle'
compileMesh {
group 'Filament'
description 'Compile mesh'
inputFile = file("../../../../third_party/shader_ball/shader_ball.obj")
outputDir = file("src/main/assets/models")
}
generateIbl {
group 'Filament'
description 'Generate IBL'
inputFile = file("../../../../third_party/environments/flower_road_2k.hdr")
outputDir = file("src/main/assets/envs")
}
preBuild.dependsOn compileMesh
preBuild.dependsOn generateIbl
android {
compileSdkVersion 28
defaultConfig {
applicationId "com.google.android.filament.ibl"
minSdkVersion 21
targetSdkVersion 28
versionCode 1
versionName "1.0"
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
// Filament comes with native code, the following declarations
// can be used to generate architecture specific APKs
flavorDimensions 'cpuArch'
productFlavors {
arm8 {
dimension 'cpuArch'
ndk {
abiFilters 'arm64-v8a'
}
}
arm7 {
dimension 'cpuArch'
ndk {
abiFilters 'armeabi-v7a'
}
}
x86_64 {
dimension 'cpuArch'
ndk {
abiFilters 'x86_64'
}
}
x86 {
dimension 'cpuArch'
ndk {
abiFilters 'x86'
}
}
universal {
dimension 'cpuArch'
}
}
// We use the .filamat extension for materials compiled with matc
// Telling aapt to not compress them allows to load them efficiently
aaptOptions {
noCompress 'filamat'
}
}
dependencies {
implementation fileTree(dir: 'libs', include: ['*.jar'])
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
// Depend on Filament
implementation 'com.google.android.filament:filament-android'
// Depend on Filamat
implementation 'com.google.android.filament:filamat-android'
}
+21
View File
@@ -0,0 +1,21 @@
# Add project specific ProGuard rules here.
# You can control the set of applied configuration files using the
# proguardFiles setting in build.gradle.
#
# For more details, see
# http://developer.android.com/guide/developing/tools/proguard.html
# If your project uses WebView with JS, uncomment the following
# and specify the fully qualified class name to the JavaScript interface
# class:
#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
# public *;
#}
# Uncomment this to preserve the line number information for
# debugging stack traces.
#-keepattributes SourceFile,LineNumberTable
# If you keep the line number information, uncomment this to
# hide the original source file name.
#-renamesourcefileattribute SourceFile
@@ -0,0 +1,21 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.google.android.filament.ibl">
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/AppTheme">
<activity android:name=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN"/>
<category android:name="android.intent.category.LAUNCHER"/>
</intent-filter>
</activity>
</application>
</manifest>
@@ -0,0 +1,149 @@
/*
* Copyright (C) 2018 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.google.android.filament.ibl
import android.content.res.AssetManager
import android.graphics.BitmapFactory
import com.google.android.filament.Engine
import com.google.android.filament.IndirectLight
import com.google.android.filament.Skybox
import com.google.android.filament.Texture
import java.io.BufferedReader
import java.io.InputStreamReader
import java.nio.ByteBuffer
import kotlin.math.log2
data class Ibl(val indirectLight: IndirectLight,
val indirectLightTexture: Texture,
val skybox: Skybox,
val skyboxTexture: Texture)
fun loadIbl(assets: AssetManager, name: String, engine: Engine): Ibl {
val (ibl, iblTexture) = loadIndirectLight(assets, name, engine)
val (skybox, skyboxTexture) = loadSkybox(assets, name, engine)
return Ibl(ibl, iblTexture, skybox, skyboxTexture)
}
fun destroyIbl(engine: Engine, ibl: Ibl) {
engine.destroySkybox(ibl.skybox)
engine.destroyTexture(ibl.skyboxTexture)
engine.destroyIndirectLight(ibl.indirectLight)
engine.destroyTexture(ibl.indirectLightTexture)
}
private fun peekSize(assets: AssetManager, name: String): Pair<Int, Int> {
assets.open(name).use { input ->
val opts = BitmapFactory.Options().apply { inJustDecodeBounds = true }
BitmapFactory.decodeStream(input, null, opts)
return opts.outWidth to opts.outHeight
}
}
private fun loadIndirectLight(
assets: AssetManager,
name: String,
engine: Engine): Pair<IndirectLight, Texture> {
val (w, h) = peekSize(assets, "$name/m0_nx.rgbm")
val texture = Texture.Builder()
.width(w)
.height(h)
.levels(log2(w.toFloat()).toInt() + 1)
.format(Texture.InternalFormat.RGBA8)
.rgbm(true)
.sampler(Texture.Sampler.SAMPLER_CUBEMAP)
.build(engine)
repeat(texture.levels) {
loadCubemap(texture, assets, name, engine, "m${it}_", it)
}
val sphericalHarmonics = loadSphericalHarmonics(assets, name)
return IndirectLight.Builder()
.reflections(texture)
.irradiance(3, sphericalHarmonics)
.intensity(30_000.0f)
.build(engine) to texture
}
private fun loadSphericalHarmonics(assets: AssetManager, name: String): FloatArray {
val re = Regex("""\(\s*([+-]?\d+\.\d+),\s*([+-]?\d+\.\d+),\s*([+-]?\d+\.\d+)\);""")
// 3 bands = 9 RGB coefficients, so 9 * 3 floats
val sphericalHarmonics = FloatArray(9 * 3)
BufferedReader(InputStreamReader(assets.open("$name/sh.txt"))).use { input ->
repeat(9) { i ->
val line = input.readLine()
re.find(line)?.let {
sphericalHarmonics[i * 3] = it.groups[1]?.value?.toFloat() ?: 0.0f
sphericalHarmonics[i * 3 + 1] = it.groups[2]?.value?.toFloat() ?: 0.0f
sphericalHarmonics[i * 3 + 2] = it.groups[3]?.value?.toFloat() ?: 0.0f
}
}
}
return sphericalHarmonics
}
private fun loadSkybox(assets: AssetManager, name: String, engine: Engine): Pair<Skybox, Texture> {
val (w, h) = peekSize(assets, "$name/nx.rgbm")
val texture = Texture.Builder()
.width(w)
.height(h)
.levels(1)
.format(Texture.InternalFormat.RGBA8)
.rgbm(true)
.sampler(Texture.Sampler.SAMPLER_CUBEMAP)
.build(engine)
loadCubemap(texture, assets, name, engine)
return Skybox.Builder().environment(texture).build(engine) to texture
}
private fun loadCubemap(texture: Texture,
assets: AssetManager,
name: String,
engine: Engine,
prefix: String = "",
level: Int = 0) {
// This is important, in the RGBM format the alpha channel does not encode
// opacity but a scale factor (to represent HDR data). We must tell Android
// to not premultiply the RGB channels by the alpha channel
val opts = BitmapFactory.Options().apply { inPremultiplied = false }
// RGBM is always 4 bytes per pixel
val faceSize = texture.getWidth(level) * texture.getHeight(level) * 4
val offsets = IntArray(6) { it * faceSize }
// Allocate enough memory for all the cubemap faces
val storage = ByteBuffer.allocateDirect(faceSize * 6)
arrayOf("px", "nx", "py", "ny", "pz", "nz").forEach { suffix ->
assets.open("$name/$prefix$suffix.rgbm").use {
val bitmap = BitmapFactory.decodeStream(it, null, opts)
bitmap?.copyPixelsToBuffer(storage)
}
}
// Rewind the texture buffer
storage.flip()
android.util.Log.d("Texture", "Cubemap level: $level $faceSize ${texture.getWidth(level)}")
val buffer = Texture.PixelBufferDescriptor(storage, Texture.Format.RGBM, Texture.Type.UBYTE)
texture.setImage(engine, level, buffer, offsets)
}
@@ -0,0 +1,38 @@
/*
* Copyright (C) 2018 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.google.android.filament.ibl
import java.io.InputStream
import java.nio.ByteBuffer
import java.nio.ByteOrder
fun readIntLE(input: InputStream): Int {
return input.read() and 0xff or (
input.read() and 0xff shl 8) or (
input.read() and 0xff shl 16) or (
input.read() and 0xff shl 24)
}
fun readFloat32LE(input: InputStream): Float {
val bytes = ByteArray(4)
input.read(bytes, 0, 4)
return ByteBuffer.wrap(bytes).order(ByteOrder.LITTLE_ENDIAN).float
}
fun readUIntLE(input: InputStream): Long {
return readIntLE(input).toLong() and 0xFFFFFFFFL
}
@@ -0,0 +1,338 @@
/*
* Copyright (C) 2018 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.google.android.filament.ibl
import android.animation.ValueAnimator
import android.app.Activity
import android.os.Bundle
import android.view.Choreographer
import android.view.Surface
import android.view.SurfaceView
import android.view.animation.LinearInterpolator
import com.google.android.filament.*
import com.google.android.filament.android.UiHelper
import com.google.android.filament.filamat.MaterialBuilder
import kotlin.math.PI
import kotlin.math.cos
import kotlin.math.sin
class MainActivity : Activity() {
// Make sure to initialize Filament first
// This loads the JNI library needed by most API calls
companion object {
init {
Filament.init()
}
}
// The View we want to render into
private lateinit var surfaceView: SurfaceView
// UiHelper is provided by Filament to manage SurfaceView and SurfaceTexture
private lateinit var uiHelper: UiHelper
// Choreographer is used to schedule new frames
private lateinit var choreographer: Choreographer
// Engine creates and destroys Filament resources
// Each engine must be accessed from a single thread of your choosing
// Resources cannot be shared across engines
private lateinit var engine: Engine
// A renderer instance is tied to a single surface (SurfaceView, TextureView, etc.)
private lateinit var renderer: Renderer
// A scene holds all the renderable, lights, etc. to be drawn
private lateinit var scene: Scene
// A view defines a viewport, a scene and a camera for rendering
private lateinit var view: View
// Should be pretty obvious :)
private lateinit var camera: Camera
private lateinit var material: Material
private lateinit var materialInstance: MaterialInstance
private lateinit var mesh: Mesh
private lateinit var ibl: Ibl
// Filament entity representing a renderable object
@Entity private var light = 0
// 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()
private val animator = ValueAnimator.ofFloat(0.0f, (2.0 * PI).toFloat())
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
surfaceView = SurfaceView(this)
setContentView(surfaceView)
choreographer = Choreographer.getInstance()
setupSurfaceView()
setupFilament()
setupView()
setupScene()
}
private fun setupSurfaceView() {
uiHelper = UiHelper(UiHelper.ContextErrorPolicy.DONT_CHECK)
uiHelper.renderCallback = SurfaceCallback()
// NOTE: To choose a specific rendering resolution, add the following line:
// uiHelper.setDesiredSize(1280, 720)
uiHelper.attachTo(surfaceView)
}
private fun setupFilament() {
engine = Engine.create()
renderer = engine.createRenderer()
scene = engine.createScene()
view = engine.createView()
camera = engine.createCamera()
}
private fun setupView() {
// Clear the background to middle-grey
// Setting up a clear color is useful for debugging but usually
// unnecessary when using a skybox
view.setClearColor(0.035f, 0.035f, 0.035f, 1.0f)
// 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() {
buildMaterial()
setupMaterial()
loadImageBasedLight()
scene.skybox = ibl.skybox
scene.indirectLight = ibl.indirectLight
// This map can contain named materials that will map to the material names
// loaded from the filamesh file. The material called "DefaultMaterial" is
// applied when no named material can be found
val materials = mapOf("DefaultMaterial" to materialInstance)
// Load the mesh in the filamesh format (see filamesh tool)
mesh = loadMesh(assets, "models/shader_ball.filamesh", materials, engine)
// Move the mesh down
// Filament uses column-major matrices
engine.transformManager.setTransform(engine.transformManager.getInstance(mesh.renderable),
floatArrayOf(
1.0f, 0.0f, 0.0f, 0.0f,
0.0f, 1.0f, 0.0f, 0.0f,
0.0f, 0.0f, 1.0f, 0.0f,
0.0f, -1.2f, 0.0f, 1.0f
))
// Add the entity to the scene to render it
scene.addEntity(mesh.renderable)
// We now need a light, let's create a directional light
light = EntityManager.get().create()
// Create a color from a temperature (D65)
val (r, g, b) = Colors.cct(6_500.0f)
LightManager.Builder(LightManager.Type.DIRECTIONAL)
.color(r, g, b)
// Intensity of the sun in lux on a clear day
.intensity(110_000.0f)
// The direction is normalized on our behalf
.direction(-0.753f, -1.0f, 0.890f)
.castShadows(true)
.build(engine, light)
// Add the entity to the scene to light it
scene.addEntity(light)
// Set the exposure on the camera, this exposure follows the sunny f/16 rule
// Since we've defined a light that has the same intensity as the sun, it
// guarantees a proper exposure
camera.setExposure(16.0f, 1.0f / 125.0f, 100.0f)
startAnimation()
}
private fun buildMaterial() {
// MaterialBuilder.init() must be called before any MaterialBuilder methods can be used.
// It only needs to be called once per process.
// When your app is done building materials, call MaterialBuilder.shutdown() to free
// internal MaterialBuilder resources.
MaterialBuilder.init()
val matPackage = MaterialBuilder()
// By default, materials are generated only for DESKTOP. Since we're an Android
// app, we set the platform to MOBILE.
.platform(MaterialBuilder.Platform.MOBILE)
// Set the name of the Material for debugging purposes.
.name("Clear coat")
// Defaults to LIT. We could change the shading model here if we desired.
.shading(MaterialBuilder.Shading.LIT)
// Add a parameter to the material that can be set via the setParameter method once
// we have a material instance.
.uniformParameter(MaterialBuilder.UniformType.FLOAT3, "baseColor")
// Fragment block- see the material readme (docs/Materials.md.html) for the full
// specification.
.material("void material(inout MaterialInputs material) {\n" +
" prepareMaterial(material);\n" +
" material.baseColor.rgb = materialParams.baseColor;\n" +
" material.roughness = 0.65;\n" +
" material.metallic = 1.0;\n" +
" material.clearCoat = 1.0;\n" +
"}\n")
.build()
if (matPackage.isValid) {
val buffer = matPackage.buffer
material = Material.Builder().payload(buffer, buffer.remaining()).build(engine)
}
// We're done building materials, so we call shutdown here to free resources. If we wanted
// to build more materials, we could call MaterialBuilder.init() again (with a slight
// performance hit).
MaterialBuilder.shutdown()
}
private fun setupMaterial() {
// Create an instance of the material to set different parameters on it
materialInstance = material.createInstance()
// Specify that our color is in sRGB so the conversion to linear
// is done automatically for us. If you already have a linear color
// you can pass it directly, or use Colors.RgbType.LINEAR
materialInstance.setParameter("baseColor", Colors.RgbType.SRGB, 0.71f, 0.0f, 0.0f)
}
private fun loadImageBasedLight() {
ibl = loadIbl(assets, "envs/flower_road_2k", engine)
ibl.indirectLight.intensity = 40_000.0f
}
private fun startAnimation() {
// Animate the triangle
animator.interpolator = LinearInterpolator()
animator.duration = 18_000
animator.repeatMode = ValueAnimator.RESTART
animator.repeatCount = ValueAnimator.INFINITE
animator.addUpdateListener { a ->
val v = (a.animatedValue as Float)
camera.lookAt(cos(v) * 4.5, 1.5, sin(v) * 4.5, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0)
}
animator.start()
}
override fun onResume() {
super.onResume()
choreographer.postFrameCallback(frameScheduler)
animator.start()
}
override fun onPause() {
super.onPause()
choreographer.removeFrameCallback(frameScheduler)
animator.cancel()
}
override fun onDestroy() {
super.onDestroy()
// Always detach the surface before destroying the engine
uiHelper.detach()
// This ensures that all the commands we've sent to Filament have
// been processed before we attempt to destroy anything
Fence.waitAndDestroy(engine.createFence(Fence.Type.SOFT), Fence.Mode.FLUSH)
// Cleanup all resources
destroyMesh(engine, mesh)
destroyIbl(engine, ibl)
engine.destroyEntity(light)
engine.destroyRenderer(renderer)
engine.destroyMaterialInstance(materialInstance)
engine.destroyMaterial(material)
engine.destroyView(view)
engine.destroyScene(scene)
engine.destroyCamera(camera)
// Engine.destroyEntity() destroys Filament related resources only
// (components), not the entity itself
val entityManager = EntityManager.get()
entityManager.destroy(light)
// 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!!)) {
renderer.render(view)
renderer.endFrame()
}
}
}
}
inner class SurfaceCallback : UiHelper.RendererCallback {
override fun onNativeWindowChanged(surface: Surface) {
swapChain?.let { engine.destroySwapChain(it) }
swapChain = engine.createSwapChain(surface)
}
override fun onDetachedFromSurface() {
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)
}
}
}
@@ -0,0 +1,266 @@
/*
* Copyright (C) 2018 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.google.android.filament.ibl
import android.content.res.AssetManager
import android.util.Log
import com.google.android.filament.*
import com.google.android.filament.VertexBuffer.AttributeType.*
import com.google.android.filament.VertexBuffer.VertexAttribute.*
import java.io.InputStream
import java.nio.charset.Charset
import java.nio.ByteBuffer
import java.nio.ByteOrder
import java.nio.channels.Channels
import java.nio.channels.ReadableByteChannel
data class Mesh(
@Entity val renderable: Int,
val indexBuffer: IndexBuffer,
val vertexBuffer: VertexBuffer,
val aabb: Box)
fun destroyMesh(engine: Engine, mesh: Mesh) {
engine.destroyEntity(mesh.renderable)
engine.destroyIndexBuffer(mesh.indexBuffer)
engine.destroyVertexBuffer(mesh.vertexBuffer)
EntityManager.get().destroy(mesh.renderable)
}
fun loadMesh(assets: AssetManager, name: String,
materials: Map<String, MaterialInstance>, engine: Engine): Mesh {
// See tools/filamesh/README.md for a description of the filamesh file format
assets.open(name).use { input ->
val header = readHeader(input)
val channel = Channels.newChannel(input)
val vertexBufferData = readSizedData(channel, header.verticesSizeInBytes)
val indexBufferData = readSizedData(channel, header.indicesSizeInBytes)
val parts = readParts(header, input)
val definedMaterials = readMaterials(input)
val indexBuffer = createIndexBuffer(engine, header, indexBufferData)
val vertexBuffer = createVertexBuffer(engine, header, vertexBufferData)
val renderable = createRenderable(
engine, header, indexBuffer, vertexBuffer, parts, definedMaterials, materials)
return Mesh(renderable, indexBuffer, vertexBuffer, header.aabb)
}
}
private const val FILAMESH_FILE_IDENTIFIER = "FILAMESH"
private const val MAX_UINT32 = 4294967295
@Suppress("unused")
private const val HEADER_FLAG_INTERLEAVED = 0x1L
private const val HEADER_FLAG_SNORM16_UV = 0x2L
@Suppress("unused")
private const val HEADER_FLAG_COMPRESSED = 0x4L
private class Header {
var valid = false
var versionNumber = 0L
var parts = 0L
var aabb = Box()
var flags = 0L
var posOffset = 0L
var positionStride = 0L
var tangentOffset = 0L
var tangentStride = 0L
var colorOffset = 0L
var colorStride = 0L
var uv0Offset = 0L
var uv0Stride = 0L
var uv1Offset = 0L
var uv1Stride = 0L
var totalVertices = 0L
var verticesSizeInBytes = 0L
var indices16Bit = 0L
var totalIndices = 0L
var indicesSizeInBytes = 0L
}
private class Part {
var offset = 0L
var indexCount = 0L
var minIndex = 0L
var maxIndex = 0L
var materialID = 0L
var aabb = Box()
}
private fun readMagicNumber(input: InputStream): Boolean {
val temp = ByteArray(FILAMESH_FILE_IDENTIFIER.length)
input.read(temp)
val tempS = String(temp, Charset.forName("UTF-8"))
return tempS == FILAMESH_FILE_IDENTIFIER
}
private fun readHeader(input: InputStream): Header {
val header = Header()
if (!readMagicNumber(input)) {
Log.e("Filament", "Invalid filamesh file.")
return header
}
header.versionNumber = readUIntLE(input)
header.parts = readUIntLE(input)
header.aabb = Box(
readFloat32LE(input), readFloat32LE(input), readFloat32LE(input),
readFloat32LE(input), readFloat32LE(input), readFloat32LE(input))
header.flags = readUIntLE(input)
header.posOffset = readUIntLE(input)
header.positionStride = readUIntLE(input)
header.tangentOffset = readUIntLE(input)
header.tangentStride = readUIntLE(input)
header.colorOffset = readUIntLE(input)
header.colorStride = readUIntLE(input)
header.uv0Offset = readUIntLE(input)
header.uv0Stride = readUIntLE(input)
header.uv1Offset = readUIntLE(input)
header.uv1Stride = readUIntLE(input)
header.totalVertices = readUIntLE(input)
header.verticesSizeInBytes = readUIntLE(input)
header.indices16Bit = readUIntLE(input)
header.totalIndices = readUIntLE(input)
header.indicesSizeInBytes = readUIntLE(input)
header.valid = true
return header
}
private fun readSizedData(channel: ReadableByteChannel, sizeInBytes: Long): ByteBuffer {
val buffer = ByteBuffer.allocateDirect(sizeInBytes.toInt())
buffer.order(ByteOrder.LITTLE_ENDIAN)
channel.read(buffer)
buffer.flip()
return buffer
}
private fun readParts(header: Header, input: InputStream): List<Part> {
return List(header.parts.toInt()) {
val p = Part()
p.offset = readUIntLE(input)
p.indexCount = readUIntLE(input)
p.minIndex = readUIntLE(input)
p.maxIndex = readUIntLE(input)
p.materialID = readUIntLE(input)
p.aabb = Box(
readFloat32LE(input), readFloat32LE(input), readFloat32LE(input),
readFloat32LE(input), readFloat32LE(input), readFloat32LE(input))
p
}
}
private fun readMaterials(input: InputStream): List<String> {
return List(readUIntLE(input).toInt()) {
val data = ByteArray(readUIntLE(input).toInt())
input.read(data)
// Skip null terminator
input.skip(1)
data.toString(Charset.forName("UTF-8"))
}
}
private fun createIndexBuffer(engine: Engine, header: Header, data: ByteBuffer): IndexBuffer {
val indexType = if (header.indices16Bit != 0L) {
IndexBuffer.Builder.IndexType.USHORT
} else {
IndexBuffer.Builder.IndexType.UINT
}
return IndexBuffer.Builder()
.bufferType(indexType)
.indexCount(header.totalIndices.toInt())
.build(engine)
.apply { setBuffer(engine, data) }
}
private fun uvNormalized(header: Header) = header.flags and HEADER_FLAG_SNORM16_UV != 0L
private fun createVertexBuffer(engine: Engine, header: Header, data: ByteBuffer): VertexBuffer {
val uvType = if (!uvNormalized(header)) {
HALF2
} else {
SHORT2
}
val vertexBufferBuilder = VertexBuffer.Builder()
.bufferCount(1)
.vertexCount(header.totalVertices.toInt())
// We store colors as unsigned bytes (0..255) but the shader wants values in the 0..1
// range so we must mark this attribute normalized
.normalized(COLOR)
// The same goes for the tangent frame: we store it as a signed short, but we want
// values in 0..1 in the shader
.normalized(TANGENTS)
.attribute(POSITION, 0, HALF4, header.posOffset.toInt(), header.positionStride.toInt())
.attribute(TANGENTS, 0, SHORT4, header.tangentOffset.toInt(), header.tangentStride.toInt())
.attribute(COLOR, 0, UBYTE4, header.colorOffset.toInt(), header.colorStride.toInt())
// UV coordinates are stored as normalized 16-bit integers or half-floats depending on
// the range they span. When stored as half-float, there is only enough precision for
// sub-pixel addressing in textures that are <= 1024x1024
.attribute(UV0, 0, uvType, header.uv0Offset.toInt(), header.uv0Stride.toInt())
// When UV coordinates are stored as 16-bit integers we must normalize them (we want
// values in the range -1..1)
.normalized(UV0, uvNormalized(header))
if (header.uv1Offset != MAX_UINT32 && header.uv1Stride != MAX_UINT32) {
vertexBufferBuilder
.attribute(UV1, 0, uvType, header.uv1Offset.toInt(), header.uv1Stride.toInt())
.normalized(UV1, uvNormalized(header))
}
return vertexBufferBuilder.build(engine).apply { setBufferAt(engine, 0, data) }
}
private fun createRenderable(
engine: Engine,
header: Header,
indexBuffer: IndexBuffer,
vertexBuffer: VertexBuffer,
parts: List<Part>,
definedMaterials: List<String>,
materials: Map<String, MaterialInstance>): Int {
val builder = RenderableManager.Builder(header.parts.toInt()).boundingBox(header.aabb)
repeat(header.parts.toInt()) { i ->
builder.geometry(i,
RenderableManager.PrimitiveType.TRIANGLES,
vertexBuffer,
indexBuffer,
parts[i].offset.toInt(),
parts[i].minIndex.toInt(),
parts[i].maxIndex.toInt(),
parts[i].indexCount.toInt())
// Find a material in the supplied material map, otherwise we fall back to
// the default material named "DefaultMaterial"
val material = materials[definedMaterials[parts[i].materialID.toInt()]]
material?.let {
builder.material(i, material)
} ?: builder.material(i, materials["DefaultMaterial"]!!)
}
return EntityManager.get().create().apply { builder.build(engine, this) }
}
@@ -0,0 +1,27 @@
// Clear coat material with a single parameter:
// - baseColor
material {
name : clear_coat,
shadingModel : lit,
parameters : [
{
type : float3,
name : baseColor
}
],
}
fragment {
void material(inout MaterialInputs material) {
prepareMaterial(material);
material.baseColor.rgb = materialParams.baseColor;
// To create a metallic paint-like material we want
// a rough base metallic layer and a glossy clear coat
material.roughness = 0.65;
material.metallic = 1.0;
material.clearCoat = 1.0;
}
}
@@ -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>
@@ -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>
@@ -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>
@@ -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

@@ -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>
@@ -0,0 +1,3 @@
<resources>
<string name="app_name">Image-Based Lighting</string>
</resources>
@@ -0,0 +1,8 @@
<resources>
<!-- Base application theme. -->
<style name="AppTheme" parent="android:Theme.Material.Light.DarkActionBar">
<!-- Customize your theme here. -->
</style>
</resources>
@@ -0,0 +1,27 @@
// Top-level build file where you can add configuration options common to all sub-projects/modules.
buildscript {
ext.kotlin_version = '1.3.11'
repositories {
google()
jcenter()
}
dependencies {
classpath 'com.android.tools.build:gradle:3.3.0'
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
// NOTE: Do not place your application dependencies here; they belong
// in the individual module build.gradle files
}
}
allprojects {
repositories {
google()
jcenter()
}
}
task clean(type: Delete) {
delete rootProject.buildDir
}
@@ -0,0 +1,13 @@
# Project-wide Gradle settings.
# IDE (e.g. Android Studio) users:
# Gradle settings configured through the IDE *will override*
# any settings specified in this file.
# For more details on how to configure your build environment visit
# http://www.gradle.org/docs/current/userguide/build_environment.html
# Specifies the JVM arguments used for the daemon process.
# The setting is particularly useful for tweaking memory settings.
org.gradle.jvmargs=-Xmx1536m
# When configured, Gradle will run in incubating parallel mode.
# This option should only be used with decoupled projects. More details, visit
# http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
# org.gradle.parallel=true
@@ -0,0 +1,6 @@
#Mon Jan 14 11:08:47 PST 2019
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-4.10.1-all.zip
+172
View File
@@ -0,0 +1,172 @@
#!/usr/bin/env sh
##############################################################################
##
## Gradle start up script for UN*X
##
##############################################################################
# Attempt to set APP_HOME
# Resolve links: $0 may be a link
PRG="$0"
# Need this for relative symlinks.
while [ -h "$PRG" ] ; do
ls=`ls -ld "$PRG"`
link=`expr "$ls" : '.*-> \(.*\)$'`
if expr "$link" : '/.*' > /dev/null; then
PRG="$link"
else
PRG=`dirname "$PRG"`"/$link"
fi
done
SAVED="`pwd`"
cd "`dirname \"$PRG\"`/" >/dev/null
APP_HOME="`pwd -P`"
cd "$SAVED" >/dev/null
APP_NAME="Gradle"
APP_BASE_NAME=`basename "$0"`
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
DEFAULT_JVM_OPTS=""
# Use the maximum available, or set MAX_FD != -1 to use that value.
MAX_FD="maximum"
warn () {
echo "$*"
}
die () {
echo
echo "$*"
echo
exit 1
}
# OS specific support (must be 'true' or 'false').
cygwin=false
msys=false
darwin=false
nonstop=false
case "`uname`" in
CYGWIN* )
cygwin=true
;;
Darwin* )
darwin=true
;;
MINGW* )
msys=true
;;
NONSTOP* )
nonstop=true
;;
esac
CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
# Determine the Java command to use to start the JVM.
if [ -n "$JAVA_HOME" ] ; then
if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
# IBM's JDK on AIX uses strange locations for the executables
JAVACMD="$JAVA_HOME/jre/sh/java"
else
JAVACMD="$JAVA_HOME/bin/java"
fi
if [ ! -x "$JAVACMD" ] ; then
die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
Please set the JAVA_HOME variable in your environment to match the
location of your Java installation."
fi
else
JAVACMD="java"
which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
Please set the JAVA_HOME variable in your environment to match the
location of your Java installation."
fi
# Increase the maximum file descriptors if we can.
if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then
MAX_FD_LIMIT=`ulimit -H -n`
if [ $? -eq 0 ] ; then
if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
MAX_FD="$MAX_FD_LIMIT"
fi
ulimit -n $MAX_FD
if [ $? -ne 0 ] ; then
warn "Could not set maximum file descriptor limit: $MAX_FD"
fi
else
warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
fi
fi
# For Darwin, add options to specify how the application appears in the dock
if $darwin; then
GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
fi
# For Cygwin, switch paths to Windows format before running java
if $cygwin ; then
APP_HOME=`cygpath --path --mixed "$APP_HOME"`
CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
JAVACMD=`cygpath --unix "$JAVACMD"`
# We build the pattern for arguments to be converted via cygpath
ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
SEP=""
for dir in $ROOTDIRSRAW ; do
ROOTDIRS="$ROOTDIRS$SEP$dir"
SEP="|"
done
OURCYGPATTERN="(^($ROOTDIRS))"
# Add a user-defined pattern to the cygpath arguments
if [ "$GRADLE_CYGPATTERN" != "" ] ; then
OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
fi
# Now convert the arguments - kludge to limit ourselves to /bin/sh
i=0
for arg in "$@" ; do
CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
else
eval `echo args$i`="\"$arg\""
fi
i=$((i+1))
done
case $i in
(0) set -- ;;
(1) set -- "$args0" ;;
(2) set -- "$args0" "$args1" ;;
(3) set -- "$args0" "$args1" "$args2" ;;
(4) set -- "$args0" "$args1" "$args2" "$args3" ;;
(5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
(6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
(7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
(8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
(9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
esac
fi
# Escape application args
save () {
for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done
echo " "
}
APP_ARGS=$(save "$@")
# Collect all arguments for the java command, following the shell quoting and substitution rules
eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS"
# by default we should be in the correct project dir, but when run from Finder on Mac, the cwd is wrong
if [ "$(uname)" = "Darwin" ] && [ "$HOME" = "$PWD" ]; then
cd "$(dirname "$0")"
fi
exec "$JAVACMD" "$@"
+84
View File
@@ -0,0 +1,84 @@
@if "%DEBUG%" == "" @echo off
@rem ##########################################################################
@rem
@rem Gradle startup script for Windows
@rem
@rem ##########################################################################
@rem Set local scope for the variables with windows NT shell
if "%OS%"=="Windows_NT" setlocal
set DIRNAME=%~dp0
if "%DIRNAME%" == "" set DIRNAME=.
set APP_BASE_NAME=%~n0
set APP_HOME=%DIRNAME%
@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
set DEFAULT_JVM_OPTS=
@rem Find java.exe
if defined JAVA_HOME goto findJavaFromJavaHome
set JAVA_EXE=java.exe
%JAVA_EXE% -version >NUL 2>&1
if "%ERRORLEVEL%" == "0" goto init
echo.
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
echo.
echo Please set the JAVA_HOME variable in your environment to match the
echo location of your Java installation.
goto fail
:findJavaFromJavaHome
set JAVA_HOME=%JAVA_HOME:"=%
set JAVA_EXE=%JAVA_HOME%/bin/java.exe
if exist "%JAVA_EXE%" goto init
echo.
echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
echo.
echo Please set the JAVA_HOME variable in your environment to match the
echo location of your Java installation.
goto fail
:init
@rem Get command-line arguments, handling Windows variants
if not "%OS%" == "Windows_NT" goto win9xME_args
:win9xME_args
@rem Slurp the command line arguments.
set CMD_LINE_ARGS=
set _SKIP=2
:win9xME_args_slurp
if "x%~1" == "x" goto execute
set CMD_LINE_ARGS=%*
:execute
@rem Setup the command line
set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
@rem Execute Gradle
"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
:end
@rem End local scope for the variables with windows NT shell
if "%ERRORLEVEL%"=="0" goto mainEnd
:fail
rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
rem the _cmd.exe /c_ return code!
if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
exit /b 1
:mainEnd
if "%OS%"=="Windows_NT" endlocal
:omega
@@ -0,0 +1,4 @@
includeBuild '../../filament-android'
includeBuild '../../filamat-android'
include ':app'
+129 -132
View File
@@ -1,8 +1,6 @@
#!/bin/bash
set -e
# NDK API level
API_LEVEL=21
# Host tools required by Android, WebGL, and iOS builds
MOBILE_HOST_TOOLS="matc resgen cmgen"
WEB_HOST_TOOLS="${MOBILE_HOST_TOOLS} mipgen filamesh"
@@ -31,10 +29,8 @@ function print_help {
echo " -p platform1,platform2,..."
echo " Where platformN is [desktop|android|ios|webgl|all]."
echo " Platform(s) to build, defaults to desktop."
echo " Building for Android or iOS will automatically generate / download"
echo " Building for iOS will automatically generate / download"
echo " the toolchains if needed and perform a partial desktop build."
echo " -t"
echo " Generate the Android toolchain, requires \$ANDROID_HOME to be set."
echo " -u"
echo " Run all unit tests, will trigger a debug build if needed."
echo " -v"
@@ -43,6 +39,8 @@ function print_help {
echo " Add iOS simulator support to the iOS build."
echo " -l"
echo " Add filamat support to the Android build."
echo " -w"
echo " Build Web documents (compiles .md.html files to .html)."
echo ""
echo "Build types:"
echo " release"
@@ -74,6 +72,10 @@ function print_help {
echo ""
}
# Requirements
CMAKE_MAJOR=3
CMAKE_MINOR=10
# Internal variables
TARGET=release
@@ -92,16 +94,16 @@ ISSUE_ARCHIVES=false
ISSUE_CMAKE_ALWAYS=false
ISSUE_WEB_DOCS=false
RUN_TESTS=false
WEB_DOCS_OPTION="-DGENERATE_WEB_DOCS=OFF"
JS_DOCS_OPTION="-DGENERATE_JS_DOCS=OFF"
ENABLE_JAVA=ON
INSTALL_COMMAND=
GENERATE_TOOLCHAINS=false
VULKAN_ANDROID_OPTION="-DFILAMENT_SUPPORTS_VULKAN=OFF"
BUILD_FILAMAT_ANDROID=false
@@ -116,8 +118,6 @@ BUILD_CUSTOM_TARGETS=
UNAME=`echo $(uname)`
LC_UNAME=`echo ${UNAME} | tr '[:upper:]' '[:lower:]'`
TOOLCHAIN_SCRIPT=${ANDROID_HOME}/ndk-bundle/build/tools/make_standalone_toolchain.py
# Functions
function build_clean {
@@ -127,48 +127,11 @@ function build_clean {
rm -Rf android/filament-android/.externalNativeBuild
}
function generate_toolchain {
local ARCH=$1
local ARCH_NAME=$2
local TOOLCHAIN_NAME=toolchains/${UNAME}/${ARCH_NAME}-4.9
if [ -z "$ANDROID_HOME" ]; then
echo "The environment variable \$ANDROID_HOME is not set." >&2
exit 1
fi
if [ ! -f "$TOOLCHAIN_SCRIPT" ]; then
echo "The NDK is not properly installed in $ANDROID_HOME." >&2
exit 1
fi
if [ -d "$TOOLCHAIN_NAME" ]; then
echo "Removing existing $ARCH toolchain..."
rm -Rf ${TOOLCHAIN_NAME}
fi
echo "Generating $ARCH toolchain..."
${TOOLCHAIN_SCRIPT} \
--arch ${ARCH} \
--api ${API_LEVEL} \
--stl libc++ \
--force \
--install-dir ${TOOLCHAIN_NAME}
}
function generate_toolchains {
generate_toolchain "arm64" "aarch64-linux-android"
generate_toolchain "arm" "arm-linux-androideabi"
generate_toolchain "x86_64" "x86_64-linux-android"
generate_toolchain "x86" "i686-linux-android"
}
function build_desktop_target {
local LC_TARGET=`echo $1 | tr '[:upper:]' '[:lower:]'`
local BUILD_TARGETS=$2
if [ ! "$BUILD_TARGETS" ]; then
if [[ ! "$BUILD_TARGETS" ]]; then
BUILD_TARGETS=${BUILD_CUSTOM_TARGETS}
fi
@@ -177,7 +140,7 @@ function build_desktop_target {
cd out/cmake-${LC_TARGET}
if [ ! -d "CMakeFiles" ] || [ "$ISSUE_CMAKE_ALWAYS" == "true" ]; then
if [[ ! -d "CMakeFiles" ]] || [[ "$ISSUE_CMAKE_ALWAYS" == "true" ]]; then
cmake \
-G "$BUILD_GENERATOR" \
-DCMAKE_BUILD_TYPE=$1 \
@@ -188,13 +151,13 @@ function build_desktop_target {
fi
${BUILD_COMMAND} ${BUILD_TARGETS}
if [ "$INSTALL_COMMAND" ]; then
if [[ "$INSTALL_COMMAND" ]]; then
echo "Installing ${LC_TARGET} in out/${LC_TARGET}/filament..."
${BUILD_COMMAND} ${INSTALL_COMMAND}
fi
if [ -d "../${LC_TARGET}/filament" ]; then
if [ "$ISSUE_ARCHIVES" == "true" ]; then
if [[ -d "../${LC_TARGET}/filament" ]]; then
if [[ "$ISSUE_ARCHIVES" == "true" ]]; then
echo "Generating out/filament-${LC_TARGET}-${LC_UNAME}.tgz..."
cd ../${LC_TARGET}
tar -czvf ../filament-${LC_TARGET}-${LC_UNAME}.tgz filament
@@ -205,11 +168,11 @@ function build_desktop_target {
}
function build_desktop {
if [ "$ISSUE_DEBUG_BUILD" == "true" ]; then
if [[ "$ISSUE_DEBUG_BUILD" == "true" ]]; then
build_desktop_target "Debug" "$1"
fi
if [ "$ISSUE_RELEASE_BUILD" == "true" ]; then
if [[ "$ISSUE_RELEASE_BUILD" == "true" ]]; then
build_desktop_target "Release" "$1"
fi
}
@@ -219,11 +182,11 @@ function build_webgl_with_target {
echo "Building WebGL $LC_TARGET..."
mkdir -p out/cmake-webgl-${LC_TARGET}
cd out/cmake-webgl-${LC_TARGET}
if [ ! "$BUILD_TARGETS" ]; then
if [[ ! "$BUILD_TARGETS" ]]; then
BUILD_TARGETS=${BUILD_CUSTOM_TARGETS}
ISSUE_CMAKE_ALWAYS=true
fi
if [ ! -d "CMakeFiles" ] || [ "$ISSUE_CMAKE_ALWAYS" == "true" ]; then
if [[ ! -d "CMakeFiles" ]] || [[ "$ISSUE_CMAKE_ALWAYS" == "true" ]]; then
# Apply the emscripten environment within a subshell.
(
source ${EMSDK}/emsdk_env.sh
@@ -233,17 +196,17 @@ function build_webgl_with_target {
-DCMAKE_BUILD_TYPE=$1 \
-DCMAKE_INSTALL_PREFIX=../webgl-${LC_TARGET}/filament \
-DWEBGL=1 \
$WEB_DOCS_OPTION \
${JS_DOCS_OPTION} \
../..
${BUILD_COMMAND} ${BUILD_TARGETS}
)
fi
if [ -d "web/filament-js" ]; then
if [ "$ISSUE_ARCHIVES" == "true" ]; then
if [[ -d "web/filament-js" ]]; then
if [[ "$ISSUE_ARCHIVES" == "true" ]]; then
which -s python3
if [ $? == 0 ]; then
if [[ $? == 0 ]]; then
echo "Generating JavaScript documentation..."
local DOCS_FOLDER="web/docs"
local DOCS_SCRIPT="../../web/docs/build.py"
@@ -281,11 +244,11 @@ function build_webgl {
ISSUE_DEBUG_BUILD=${OLD_ISSUE_DEBUG_BUILD}
ISSUE_RELEASE_BUILD=${OLD_ISSUE_RELEASE_BUILD}
if [ "$ISSUE_DEBUG_BUILD" == "true" ]; then
if [[ "$ISSUE_DEBUG_BUILD" == "true" ]]; then
build_webgl_with_target "Debug"
fi
if [ "$ISSUE_RELEASE_BUILD" == "true" ]; then
if [[ "$ISSUE_RELEASE_BUILD" == "true" ]]; then
build_webgl_with_target "Release"
fi
}
@@ -299,14 +262,14 @@ function build_android_target {
cd out/cmake-android-${LC_TARGET}-${ARCH}
if [ ! -d "CMakeFiles" ] || [ "$ISSUE_CMAKE_ALWAYS" == "true" ]; then
if [[ ! -d "CMakeFiles" ]] || [[ "$ISSUE_CMAKE_ALWAYS" == "true" ]]; then
cmake \
-G "$BUILD_GENERATOR" \
-DCMAKE_BUILD_TYPE=$1 \
-DCMAKE_INSTALL_PREFIX=../android-${LC_TARGET}/filament \
-DCMAKE_TOOLCHAIN_FILE=../../build/toolchain-${ARCH}-linux-android.cmake \
$VULKAN_ANDROID_OPTION \
$FILAMAT_ANDROID_OPTION \
${VULKAN_ANDROID_OPTION} \
${FILAMAT_ANDROID_OPTION} \
../..
fi
@@ -319,18 +282,12 @@ function build_android_target {
function build_android_arch {
local ARCH=$1
local ARCH_NAME=$2
local TOOLCHAIN_ARCH=$3
local TOOLCHAIN_NAME=toolchains/${UNAME}/${ARCH_NAME}-4.9
if [ ! -d "$TOOLCHAIN_NAME" ]; then
generate_toolchain ${TOOLCHAIN_ARCH} ${ARCH_NAME}
fi
if [ "$ISSUE_DEBUG_BUILD" == "true" ]; then
if [[ "$ISSUE_DEBUG_BUILD" == "true" ]]; then
build_android_target "Debug" "$ARCH"
fi
if [ "$ISSUE_RELEASE_BUILD" == "true" ]; then
if [[ "$ISSUE_RELEASE_BUILD" == "true" ]]; then
build_android_target "Release" "$ARCH"
fi
}
@@ -338,8 +295,8 @@ function build_android_arch {
function archive_android {
local LC_TARGET=`echo $1 | tr '[:upper:]' '[:lower:]'`
if [ -d "out/android-${LC_TARGET}/filament" ]; then
if [ "$ISSUE_ARCHIVES" == "true" ]; then
if [[ -d "out/android-${LC_TARGET}/filament" ]]; then
if [[ "$ISSUE_ARCHIVES" == "true" ]]; then
echo "Generating out/filament-android-${LC_TARGET}-${LC_UNAME}.tgz..."
cd out/android-${LC_TARGET}
tar -czvf ../filament-android-${LC_TARGET}-${LC_UNAME}.tgz filament
@@ -355,36 +312,36 @@ function build_android {
build_desktop "${MOBILE_HOST_TOOLS}"
INSTALL_COMMAND=${OLD_INSTALL_COMMAND}
build_android_arch "aarch64" "aarch64-linux-android" "arm64"
build_android_arch "arm7" "arm-linux-androideabi" "arm"
build_android_arch "x86_64" "x86_64-linux-android" "x86_64"
build_android_arch "x86" "i686-linux-android" "x86"
build_android_arch "aarch64" "aarch64-linux-android"
build_android_arch "arm7" "arm-linux-androideabi"
build_android_arch "x86_64" "x86_64-linux-android"
build_android_arch "x86" "i686-linux-android"
if [ "$ISSUE_DEBUG_BUILD" == "true" ]; then
if [[ "$ISSUE_DEBUG_BUILD" == "true" ]]; then
archive_android "Debug"
fi
if [ "$ISSUE_RELEASE_BUILD" == "true" ]; then
if [[ "$ISSUE_RELEASE_BUILD" == "true" ]]; then
archive_android "Release"
fi
cd android/filament-android
if [ "$ISSUE_DEBUG_BUILD" == "true" ]; then
if [[ "$ISSUE_DEBUG_BUILD" == "true" ]]; then
./gradlew -Pfilament_dist_dir=../../out/android-debug/filament assembleDebug \
-Pextra_cmake_args=${VULKAN_ANDROID_OPTION}
if [ "$INSTALL_COMMAND" ]; then
if [[ "$INSTALL_COMMAND" ]]; then
echo "Installing out/filament-android-debug.aar..."
cp build/outputs/aar/filament-android-debug.aar ../../out/
fi
fi
if [ "$ISSUE_RELEASE_BUILD" == "true" ]; then
if [[ "$ISSUE_RELEASE_BUILD" == "true" ]]; then
./gradlew -Pfilament_dist_dir=../../out/android-release/filament assembleRelease \
-Pextra_cmake_args=${VULKAN_ANDROID_OPTION}
if [ "$INSTALL_COMMAND" ]; then
if [[ "$INSTALL_COMMAND" ]]; then
echo "Installing out/filament-android-release.aar..."
cp build/outputs/aar/filament-android-release.aar ../../out/
fi
@@ -393,23 +350,23 @@ function build_android {
cd ../..
if [ "$BUILD_FILAMAT_ANDROID" == "true" ]; then
if [[ "$BUILD_FILAMAT_ANDROID" == "true" ]]; then
cd android/filamat-android
if [ "$ISSUE_DEBUG_BUILD" == "true" ]; then
if [[ "$ISSUE_DEBUG_BUILD" == "true" ]]; then
./gradlew -Pfilament_dist_dir=../../out/android-debug/filament assembleDebug
if [ "$INSTALL_COMMAND" ]; then
if [[ "$INSTALL_COMMAND" ]]; then
echo "Installing out/filamat-android-debug.aar..."
cp build/outputs/aar/filamat-android-debug.aar ../../out/
fi
fi
if [ "$ISSUE_RELEASE_BUILD" == "true" ]; then
if [[ "$ISSUE_RELEASE_BUILD" == "true" ]]; then
./gradlew -Pfilament_dist_dir=../../out/android-release/filament assembleRelease
if [ "$INSTALL_COMMAND" ]; then
if [[ "$INSTALL_COMMAND" ]]; then
echo "Installing out/filamat-android-release.aar..."
cp build/outputs/aar/filamat-android-release.aar ../../out/
fi
@@ -422,7 +379,7 @@ function build_android {
function ensure_ios_toolchain {
local TOOLCHAIN_PATH="build/toolchain-mac-ios.cmake"
if [ -e ${TOOLCHAIN_PATH} ]; then
if [[ -e ${TOOLCHAIN_PATH} ]]; then
echo "iOS toolchain file exists."
return 0
fi
@@ -462,7 +419,7 @@ function build_ios_target {
cd out/cmake-ios-${LC_TARGET}-${ARCH}
if [ ! -d "CMakeFiles" ] || [ "$ISSUE_CMAKE_ALWAYS" == "true" ]; then
if [[ ! -d "CMakeFiles" ]] || [[ "$ISSUE_CMAKE_ALWAYS" == "true" ]]; then
cmake \
-G "$BUILD_GENERATOR" \
-DCMAKE_BUILD_TYPE=$1 \
@@ -476,8 +433,8 @@ function build_ios_target {
${BUILD_COMMAND} install
if [ -d "../ios-${LC_TARGET}/filament" ]; then
if [ "$ISSUE_ARCHIVES" == "true" ]; then
if [[ -d "../ios-${LC_TARGET}/filament" ]]; then
if [[ "$ISSUE_ARCHIVES" == "true" ]]; then
echo "Generating out/filament-${LC_TARGET}-ios.tgz..."
cd ../ios-${LC_TARGET}
tar -czvf ../filament-${LC_TARGET}-ios.tgz filament
@@ -499,58 +456,97 @@ function build_ios {
# In theory, we could support iPhone architectures older than arm64, but
# only arm64 devices support OpenGL 3.0 / Metal
if [ "$ISSUE_DEBUG_BUILD" == "true" ]; then
if [[ "$ISSUE_DEBUG_BUILD" == "true" ]]; then
build_ios_target "Debug" "arm64" "iphoneos"
if [ "$IOS_BUILD_SIMULATOR" == "true" ]; then
if [[ "$IOS_BUILD_SIMULATOR" == "true" ]]; then
build_ios_target "Debug" "x86_64" "iphonesimulator"
fi
fi
if [ "$ISSUE_RELEASE_BUILD" == "true" ]; then
if [[ "$ISSUE_RELEASE_BUILD" == "true" ]]; then
build_ios_target "Release" "arm64" "iphoneos"
if [ "$IOS_BUILD_SIMULATOR" == "true" ]; then
if [[ "$IOS_BUILD_SIMULATOR" == "true" ]]; then
build_ios_target "Release" "x86_64" "iphonesimulator"
fi
fi
}
function build_web_docs {
echo "Building Web documents..."
mkdir -p out/web-docs
cd out/web-docs
# Create an empty npm package to link markdeep-rasterizer into
npm list | grep web-docs@1.0.0 > /dev/null || npm init --yes > /dev/null
npm list | grep markdeep-rasterizer > /dev/null || npm install ../../build/web/markdeep-rasterizer > /dev/null
# Generate documents
npx markdeep-rasterizer ../../docs/Filament.md.html ../../docs/Materials.md.html ../../docs/
cd ../..
}
function validate_build_command {
set +e
# Make sure CMake is installed
cmake_binary=`which cmake`
if [ ! "$cmake_binary" ]; then
if [[ ! "$cmake_binary" ]]; then
echo "Error: could not find cmake, exiting"
exit 1
fi
# Only check CMake's version number when building Android binaries
if [[ "$ISSUE_ANDROID_BUILD" == "true" ]]; then
cmake_version=`cmake --version`
if [[ "$cmake_version" =~ ([0-9]+)\.([0-9]+)\.[0-9]+ ]]; then
if [[ "${BASH_REMATCH[1]}" -lt "${CMAKE_MAJOR}" ]] || \
[[ "${BASH_REMATCH[2]}" -lt "${CMAKE_MINOR}" ]]; then
echo "Error: cmake version ${CMAKE_MAJOR}.${CMAKE_MINOR}+ is required," \
"${BASH_REMATCH[1]}.${BASH_REMATCH[2]} installed, exiting"
exit 1
fi
fi
fi
# Make sure Ninja is installed
if [ "$BUILD_COMMAND" == "ninja" ]; then
if [[ "$BUILD_COMMAND" == "ninja" ]]; then
ninja_binary=`which ninja`
if [ ! "$ninja_binary" ]; then
if [[ ! "$ninja_binary" ]]; then
echo "Warning: could not find ninja, using make instead"
BUILD_GENERATOR="Unix Makefiles"
BUILD_COMMAND="make"
fi
fi
# Make sure Make is installed
if [ "$BUILD_COMMAND" == "make" ]; then
if [[ "$BUILD_COMMAND" == "make" ]]; then
make_binary=`which make`
if [ ! "$make_binary" ]; then
if [[ ! "$make_binary" ]]; then
echo "Error: could not find make, exiting"
exit 1
fi
fi
# Make sure we have Java
javac_binary=`which javac`
if [ "$JAVA_HOME" == "" ] || [ ! "$javac_binary" ]; then
if [[ "$JAVA_HOME" == "" ]] || [[ ! "$javac_binary" ]]; then
echo "Warning: JAVA_HOME is not set, skipping Java projects"
ENABLE_JAVA=OFF
fi
# If building a WebAssembly module, ensure we know where Emscripten lives.
if [ "$EMSDK" == "" ] && [ "$ISSUE_WEBGL_BUILD" == "true" ]; then
if [[ "$EMSDK" == "" ]] && [[ "$ISSUE_WEBGL_BUILD" == "true" ]]; then
echo "Error: EMSDK is not set, exiting"
exit 1
fi
# Web documents require node and npm for processing
if [[ "$ISSUE_WEB_DOCS" == "true" ]]; then
node_binary=`which node`
npm_binary=`which npm`
npx_binary=`which npx`
if [[ ! "$node_binary" ]] || [[ ! "$npm_binary" ]] || [[ ! "$npx_binary" ]]; then
echo "Error: Web documents require node, npm and npx to be installed"
exit 1
fi
fi
set -e
}
@@ -558,18 +554,19 @@ function run_test {
test=$1
# The input string might contain arguments, so we use "set -- $test" to replace $1 with the
# first whitespace-separated token in the string.
set -- $test
set -- ${test}
test_name=`basename $1`
./out/cmake-debug/${test} --gtest_output="xml:out/test-results/$test_name/sponge_log.xml"
}
function run_tests {
if [ "$ISSUE_WEBGL_BUILD" == "true" ]; then
echo "TypeScript `tsc --version`"
tsc --noEmit \
third_party/gl-matrix/gl-matrix.d.ts \
web/filament-js/filament.d.ts \
web/filament-js/test.ts
if [[ "$ISSUE_WEBGL_BUILD" == "true" ]]; then
if ! echo "TypeScript `tsc --version`" ; then
tsc --noEmit \
third_party/gl-matrix/gl-matrix.d.ts \
web/filament-js/filament.d.ts \
web/filament-js/test.ts
fi
else
while read test; do
run_test "$test"
@@ -581,7 +578,7 @@ function run_tests {
pushd `dirname $0` > /dev/null
while getopts ":hacfijmp:tuvsl" opt; do
while getopts ":hacfijmp:tuvslw" opt; do
case ${opt} in
h)
print_help
@@ -590,7 +587,7 @@ while getopts ":hacfijmp:tuvsl" opt; do
a)
ISSUE_ARCHIVES=true
INSTALL_COMMAND=install
WEB_DOCS_OPTION="-DGENERATE_WEB_DOCS=ON"
JS_DOCS_OPTION="-DGENERATE_JS_DOCS=ON"
;;
c)
ISSUE_CLEAN=true
@@ -611,9 +608,9 @@ while getopts ":hacfijmp:tuvsl" opt; do
p)
ISSUE_DESKTOP_BUILD=false
platforms=$(echo "$OPTARG" | tr ',' '\n')
for platform in $platforms
for platform in ${platforms}
do
case $platform in
case ${platform} in
desktop)
ISSUE_DESKTOP_BUILD=true
;;
@@ -635,9 +632,6 @@ while getopts ":hacfijmp:tuvsl" opt; do
esac
done
;;
t)
GENERATE_TOOLCHAINS=true
;;
u)
ISSUE_DEBUG_BUILD=true
RUN_TESTS=true
@@ -662,6 +656,9 @@ while getopts ":hacfijmp:tuvsl" opt; do
IOS_BUILD_SIMULATOR=true
echo "iOS simulator support enabled."
;;
w)
ISSUE_WEB_DOCS=true
;;
\?)
echo "Invalid option: -$OPTARG" >&2
echo ""
@@ -677,7 +674,7 @@ while getopts ":hacfijmp:tuvsl" opt; do
esac
done
if [ "$#" == "0" ]; then
if [[ "$#" == "0" ]]; then
print_help
exit 1
fi
@@ -685,9 +682,9 @@ fi
shift $(($OPTIND - 1))
for arg; do
if [ "$arg" == "release" ]; then
if [[ "$arg" == "release" ]]; then
ISSUE_RELEASE_BUILD=true
elif [ "$arg" == "debug" ]; then
elif [[ "$arg" == "debug" ]]; then
ISSUE_DEBUG_BUILD=true
else
BUILD_CUSTOM_TARGETS="$BUILD_CUSTOM_TARGETS $arg"
@@ -696,30 +693,30 @@ done
validate_build_command
if [ "$ISSUE_CLEAN" == "true" ]; then
if [[ "$ISSUE_CLEAN" == "true" ]]; then
build_clean
fi
if [ "$GENERATE_TOOLCHAINS" == "true" ]; then
generate_toolchains
fi
if [ "$ISSUE_DESKTOP_BUILD" == "true" ]; then
if [[ "$ISSUE_DESKTOP_BUILD" == "true" ]]; then
build_desktop
fi
if [ "$ISSUE_ANDROID_BUILD" == "true" ]; then
if [[ "$ISSUE_ANDROID_BUILD" == "true" ]]; then
build_android
fi
if [ "$ISSUE_IOS_BUILD" == "true" ]; then
if [[ "$ISSUE_IOS_BUILD" == "true" ]]; then
build_ios
fi
if [ "$ISSUE_WEBGL_BUILD" == "true" ]; then
if [[ "$ISSUE_WEBGL_BUILD" == "true" ]]; then
build_webgl
fi
if [ "$RUN_TESTS" == "true" ]; then
if [[ "$ISSUE_WEB_DOCS" == "true" ]]; then
build_web_docs
fi
if [[ "$RUN_TESTS" == "true" ]]; then
run_tests
fi
+2
View File
@@ -14,6 +14,8 @@ set -x
UNAME=`echo $(uname)`
LC_UNAME=`echo $UNAME | tr '[:upper:]' '[:lower:]'`
FILAMENT_ANDROID_CI_BUILD=true
# build-common.sh will generate the following variables:
# $GENERATE_ARCHIVES
# $BUILD_DEBUG
+23 -2
View File
@@ -4,13 +4,34 @@
CLANG_VERSION=7
# version of libcxx and libcxxabi we want to use
CXX_VERSION=7.0.0
# version of CMake to use instead of the default one
CMAKE_VERSION=3.13.4
# version of ninja to use
NINJA_VERSION=1.8.2
# Steps specific to our CI environment
# CI runs on Ubuntu 14.04, we need to install clang-6.0 and the
# CI runs on Ubuntu 14.04, we need to install clang-7.0 and the
# appropriate libc++ ourselves
if [ "$KOKORO_BUILD_ID" ]; then
sudo ln -s /usr/include/x86_64-linux-gnu/asm /usr/include/asm
if [ "$FILAMENT_ANDROID_CI_BUILD" ]; then
# Update NDK
yes | $ANDROID_HOME/tools/bin/sdkmanager "ndk-bundle" > /dev/null
# Install CMake
mkdir -p cmake
cd cmake
sudo wget https://github.com/Kitware/CMake/releases/download/v$CMAKE_VERSION/cmake-$CMAKE_VERSION-Linux-x86_64.sh
sudo chmod +x ./cmake-$CMAKE_VERSION-Linux-x86_64.sh
sudo ./cmake-$CMAKE_VERSION-Linux-x86_64.sh --skip-license > /dev/null
sudo update-alternatives --install /usr/bin/cmake cmake `pwd`/bin/cmake 1000 --force
cd ..
fi
# Install clang
# This may or may not be needed...
# sudo apt-key adv --keyserver apt.llvm.org --recv-keys 15CF4D18AF4F7421
sudo apt-add-repository "deb http://apt.llvm.org/trusty/ llvm-toolchain-trusty-$CLANG_VERSION main"
@@ -68,6 +89,6 @@ if [ "$KOKORO_BUILD_ID" ]; then
export FILAMENT_REQUIRES_CXXABI=false
fi
wget -q https://github.com/ninja-build/ninja/releases/download/v1.8.2/ninja-linux.zip
wget -q https://github.com/ninja-build/ninja/releases/download/v$NINJA_VERSION/ninja-linux.zip
unzip -q ninja-linux.zip
export PATH="$PWD:$PATH"
+18 -4
View File
@@ -20,21 +20,29 @@ set(CMAKE_SYSTEM_NAME Linux)
# this one not so much
set(CMAKE_SYSTEM_VERSION 1)
# android
set(API_LEVEL 21)
# architecture
set(ARCH aarch64-linux-android)
set(DIST_ARCH arm64-v8a)
# toolchain
set(TOOLCHAIN ${CMAKE_SOURCE_DIR}/toolchains/${CMAKE_HOST_SYSTEM_NAME}/${ARCH}-4.9)
string(TOLOWER ${CMAKE_HOST_SYSTEM_NAME} HOST_NAME_L)
set(TOOLCHAIN $ENV{ANDROID_HOME}/ndk-bundle/toolchains/llvm/prebuilt/${HOST_NAME_L}-x86_64/)
# specify the cross compiler
set(COMPILER_SUFFIX)
set(TOOL_SUFFIX)
if(WIN32)
set(COMPILER_SUFFIX ".cmd")
set(CMAKE_AR ${TOOLCHAIN}/bin/${ARCH}-ar.exe CACHE FILEPATH "Archiver")
set(TOOL_SUFFIX ".exe")
endif()
set(CMAKE_C_COMPILER ${TOOLCHAIN}/bin/${ARCH}-clang${COMPILER_SUFFIX})
set(CMAKE_CXX_COMPILER ${TOOLCHAIN}/bin/${ARCH}-clang++${COMPILER_SUFFIX})
set(CMAKE_C_COMPILER ${TOOLCHAIN}/bin/${ARCH}${API_LEVEL}-clang${COMPILER_SUFFIX})
set(CMAKE_CXX_COMPILER ${TOOLCHAIN}/bin/${ARCH}${API_LEVEL}-clang++${COMPILER_SUFFIX})
set(CMAKE_AR ${TOOLCHAIN}/bin/${ARCH}-ar${TOOL_SUFFIX} CACHE FILEPATH "Archiver")
set(CMAKE_RANLIB ${TOOLCHAIN}/bin/${ARCH}-ranlib${TOOL_SUFFIX})
set(CMAKE_STRIP ${TOOLCHAIN}/bin/${ARCH}-strip${TOOL_SUFFIX})
# where is the target environment
set(CMAKE_FIND_ROOT_PATH ${TOOLCHAIN}/sysroot)
@@ -57,3 +65,9 @@ set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -fPIE -pie -static-libstdc
set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -static-libstdc++" CACHE STRING "Toolchain LDFLAGS")
set(ANDROID TRUE)
# we are compiling Android on Windows
set(ANDROID_ON_WINDOWS FALSE)
if(WIN32)
set(ANDROID_ON_WINDOWS TRUE)
endif()
+20 -5
View File
@@ -20,21 +20,30 @@ set(CMAKE_SYSTEM_NAME Linux)
# this one not so much
set(CMAKE_SYSTEM_VERSION 1)
# android
set(API_LEVEL 21)
# architecture
set(ARCH arm-linux-androideabi)
set(ARCH armv7a-linux-androideabi)
set(AR_ARCH arm-linux-androideabi)
set(DIST_ARCH armeabi-v7a)
# toolchain
set(TOOLCHAIN ${CMAKE_SOURCE_DIR}/toolchains/${CMAKE_HOST_SYSTEM_NAME}/${ARCH}-4.9)
string(TOLOWER ${CMAKE_HOST_SYSTEM_NAME} HOST_NAME_L)
set(TOOLCHAIN $ENV{ANDROID_HOME}/ndk-bundle/toolchains/llvm/prebuilt/${HOST_NAME_L}-x86_64/)
# specify the cross compiler
set(COMPILER_SUFFIX)
set(TOOL_SUFFIX)
if(WIN32)
set(COMPILER_SUFFIX ".cmd")
set(CMAKE_AR ${TOOLCHAIN}/bin/${ARCH}-ar.exe CACHE FILEPATH "Archiver")
set(TOOL_SUFFIX ".exe")
endif()
set(CMAKE_C_COMPILER ${TOOLCHAIN}/bin/${ARCH}-clang${COMPILER_SUFFIX})
set(CMAKE_CXX_COMPILER ${TOOLCHAIN}/bin/${ARCH}-clang++${COMPILER_SUFFIX})
set(CMAKE_C_COMPILER ${TOOLCHAIN}/bin/${ARCH}${API_LEVEL}-clang${COMPILER_SUFFIX})
set(CMAKE_CXX_COMPILER ${TOOLCHAIN}/bin/${ARCH}${API_LEVEL}-clang++${COMPILER_SUFFIX})
set(CMAKE_AR ${TOOLCHAIN}/bin/${AR_ARCH}-ar${TOOL_SUFFIX} CACHE FILEPATH "Archiver")
set(CMAKE_RANLIB ${TOOLCHAIN}/bin/${AR_ARCH}-ranlib${TOOL_SUFFIX})
set(CMAKE_STRIP ${TOOLCHAIN}/bin/${AR_ARCH}-strip${TOOL_SUFFIX})
# where is the target environment
set(CMAKE_FIND_ROOT_PATH ${TOOLCHAIN}/sysroot)
@@ -69,3 +78,9 @@ set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -march=armv7-a -Wl,-
set(CMAKE_POSITION_INDEPENDENT_CODE ON)
set(ANDROID TRUE)
# we are compiling Android on Windows
set(ANDROID_ON_WINDOWS FALSE)
if(WIN32)
set(ANDROID_ON_WINDOWS TRUE)
endif()
+18 -4
View File
@@ -20,21 +20,29 @@ set(CMAKE_SYSTEM_NAME Linux)
# this one not so much
set(CMAKE_SYSTEM_VERSION 1)
# android
set(API_LEVEL 21)
# architecture
set(ARCH i686-linux-android)
set(DIST_ARCH x86)
# toolchain
set(TOOLCHAIN ${CMAKE_SOURCE_DIR}/toolchains/${CMAKE_HOST_SYSTEM_NAME}/${ARCH}-4.9)
string(TOLOWER ${CMAKE_HOST_SYSTEM_NAME} HOST_NAME_L)
set(TOOLCHAIN $ENV{ANDROID_HOME}/ndk-bundle/toolchains/llvm/prebuilt/${HOST_NAME_L}-x86_64/)
# specify the cross compiler
set(COMPILER_SUFFIX)
set(TOOL_SUFFIX)
if(WIN32)
set(COMPILER_SUFFIX ".cmd")
set(CMAKE_AR ${TOOLCHAIN}/bin/${ARCH}-ar.exe CACHE FILEPATH "Archiver")
set(TOOL_SUFFIX ".exe")
endif()
set(CMAKE_C_COMPILER ${TOOLCHAIN}/bin/${ARCH}-clang${COMPILER_SUFFIX})
set(CMAKE_CXX_COMPILER ${TOOLCHAIN}/bin/${ARCH}-clang++${COMPILER_SUFFIX})
set(CMAKE_C_COMPILER ${TOOLCHAIN}/bin/${ARCH}${API_LEVEL}-clang${COMPILER_SUFFIX})
set(CMAKE_CXX_COMPILER ${TOOLCHAIN}/bin/${ARCH}${API_LEVEL}-clang++${COMPILER_SUFFIX})
set(CMAKE_AR ${TOOLCHAIN}/bin/${ARCH}-ar${TOOL_SUFFIX} CACHE FILEPATH "Archiver")
set(CMAKE_RANLIB ${TOOLCHAIN}/bin/${ARCH}-ranlib${TOOL_SUFFIX})
set(CMAKE_STRIP ${TOOLCHAIN}/bin/${ARCH}-strip${TOOL_SUFFIX})
# where is the target environment
set(CMAKE_FIND_ROOT_PATH ${TOOLCHAIN}/sysroot)
@@ -54,3 +62,9 @@ set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -Wl,--no-warn-mismat
set(CMAKE_POSITION_INDEPENDENT_CODE ON)
set(ANDROID TRUE)
# we are compiling Android on Windows
set(ANDROID_ON_WINDOWS FALSE)
if(WIN32)
set(ANDROID_ON_WINDOWS TRUE)
endif()
+18 -4
View File
@@ -20,21 +20,29 @@ set(CMAKE_SYSTEM_NAME Linux)
# this one not so much
set(CMAKE_SYSTEM_VERSION 1)
# android
set(API_LEVEL 21)
# architecture
set(ARCH x86_64-linux-android)
set(DIST_ARCH x86_64)
# toolchain
set(TOOLCHAIN ${CMAKE_SOURCE_DIR}/toolchains/${CMAKE_HOST_SYSTEM_NAME}/${ARCH}-4.9)
string(TOLOWER ${CMAKE_HOST_SYSTEM_NAME} HOST_NAME_L)
set(TOOLCHAIN $ENV{ANDROID_HOME}/ndk-bundle/toolchains/llvm/prebuilt/${HOST_NAME_L}-x86_64/)
# specify the cross compiler
set(COMPILER_SUFFIX)
set(TOOL_SUFFIX)
if(WIN32)
set(COMPILER_SUFFIX ".cmd")
set(CMAKE_AR ${TOOLCHAIN}/bin/${ARCH}-ar.exe CACHE FILEPATH "Archiver")
set(TOOL_SUFFIX ".exe")
endif()
set(CMAKE_C_COMPILER ${TOOLCHAIN}/bin/${ARCH}-clang${COMPILER_SUFFIX})
set(CMAKE_CXX_COMPILER ${TOOLCHAIN}/bin/${ARCH}-clang++${COMPILER_SUFFIX})
set(CMAKE_C_COMPILER ${TOOLCHAIN}/bin/${ARCH}${API_LEVEL}-clang${COMPILER_SUFFIX})
set(CMAKE_CXX_COMPILER ${TOOLCHAIN}/bin/${ARCH}${API_LEVEL}-clang++${COMPILER_SUFFIX})
set(CMAKE_AR ${TOOLCHAIN}/bin/${ARCH}-ar${TOOL_SUFFIX} CACHE FILEPATH "Archiver")
set(CMAKE_RANLIB ${TOOLCHAIN}/bin/${ARCH}-ranlib${TOOL_SUFFIX})
set(CMAKE_STRIP ${TOOLCHAIN}/bin/${ARCH}-strip${TOOL_SUFFIX})
# where is the target environment
set(CMAKE_FIND_ROOT_PATH ${TOOLCHAIN}/sysroot)
@@ -54,3 +62,9 @@ set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -Wl,--no-warn-mismat
set(CMAKE_POSITION_INDEPENDENT_CODE ON)
set(ANDROID TRUE)
# we are compiling Android on Windows
set(ANDROID_ON_WINDOWS FALSE)
if(WIN32)
set(ANDROID_ON_WINDOWS TRUE)
endif()
+14 -10
View File
@@ -7,17 +7,21 @@ export PATH="$PWD:$PATH"
# The Kokoro machines have Python 3.6.3 installed. Let's verify that here, and install the
# distributions required for web/docs.
python --version
python3 --version
pip3 install mistletoe pygments jsbeautifier future_fstrings
# Install a typescript compiler to allow testing.
npm install -g typescript
sudo pip install certifi
sudo /Applications/Python\ 2.7/Install\ Certificates.command
# Install a specific version of emscripen to avoid surprises.
curl -L https://github.com/juj/emsdk/archive/0d8576c.zip > emsdk.zip
unzip emsdk.zip
mv emsdk-* emsdk
emsdk/emsdk update
emsdk/emsdk install sdk-1.38.11-64bit
emsdk/emsdk activate sdk-1.38.11-64bit
export EMSDK="$PWD/emsdk"
# FIXME: kokoro machines have node and npm but currently they are symlinked to non-existent files
# npm install -g typescript
# Install emscripten.
curl -L https://github.com/emscripten-core/emsdk/archive/a77638d.zip > emsdk.zip
unzip emsdk.zip ; mv emsdk-* emsdk ; cd emsdk
python emsdk install latest
python emsdk activate latest
export EMSDK="$PWD"
cd ..
+2
View File
@@ -0,0 +1,2 @@
node_modules
package-lock.json
+56
View File
@@ -0,0 +1,56 @@
#!/usr/bin/env node
const puppeteer = require('puppeteer');
const fs = require('fs');
const path = require('path');
const cheerio = require("cheerio");
const markdeepScript = '<script src="https://casual-effects.com/markdeep/latest/markdeep.min.js"></script>';
async function domDump(url) {
const browser = await puppeteer.launch({headless: true});
const page = await browser.newPage();
await page.goto(url, {waitUntil: 'networkidle0'});
const html = await page.content();
await browser.close();
return html;
}
var files = process.argv.slice(2);
if (files.length < 2) {
console.log("npx markdeep-rasterizer <file1> ... <output_dir>");
console.log("Each file must be a .md.html file.");
console.log("The output directory is mandatory.");
process.exit(1);
}
var outputDir = path.join(process.cwd(), files[files.length - 1]);
files = files.slice(0, files.length - 1);
files.forEach(function(file) {
if (file.substring(file.length - '.md.html'.length, file.length) === '.md.html') {
file = file.substring(0, file.length - '.md.html'.length);
}
var markdeepFile = path.join(process.cwd(), file + '.md.html');
var outputFile = path.basename(file + '.html');
domDump('file://' + markdeepFile + '?export').then(function(dom) {
console.log('Processing ' + markdeepFile + '...');
// Parse the DOM
var $ = cheerio.load(dom);
// Because of ?export Markdeep generated the output in a <pre> tag
dom = $('pre').text();
// We must remove the remaining invocation of Markdeep
dom = dom.replace(markdeepScript, '');
// Now replace <pre> with its own content so we can preserve headers
$('pre').replaceWith(dom);
fs.writeFile(path.join(outputDir, outputFile), $.html(), function(err) {
if (err) console.log(err);
});
}).catch(function(e) {
console.log('Could no process ' + markdeepFile + '!');
});
});
@@ -0,0 +1,18 @@
{
"name": "markdeep-rasterizer",
"version": "1.0.0",
"description": "Rasterizes Markdeep files to HTML using puppeteer",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"author": "Romain Guy <romainguy@curious-creature.com>",
"license": "Apache-2.0",
"bin": {
"markdeep-rasterizer": "./cli.js"
},
"dependencies": {
"cheerio": "^1.0.0-rc.2",
"puppeteer": "^1.12.2"
}
}
+6294
View File
File diff suppressed because one or more lines are too long
+13 -55
View File
@@ -1083,10 +1083,10 @@ D_{velvet}(v,h,\alpha) = \frac{1}{\pi(1 + 4\alpha^2)} (1 + 4 \frac{exp\left(\fra
For the full specular BRDF, we also follow [#Neubelt13] and replace the traditional denominator with a smoother variant:
$$\begin{equation}\label{clothSpecularBRDF}
f_{r}(v,h,\alpha) = \frac{F(v,h) D_{velvet}(v,h,\alpha)}{4(\NoL + \NoV - (\NoL)(\NoV))}
f_{r}(v,h,\alpha) = \frac{D_{velvet}(v,h,\alpha)}{4(\NoL + \NoV - (\NoL)(\NoV))}
\end{equation}$$
The implementation of the velvet NDF is presented in listing [clothBRDF], optimized to properly fit in half float formats and to avoid computing a costly cotangent, relying instead on trigonometric identities.
The implementation of the velvet NDF is presented in listing [clothBRDF], optimized to properly fit in half float formats and to avoid computing a costly cotangent, relying instead on trigonometric identities. Note that we removed the Fresnel component from this BRDF.
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
float D_Ashikhmin(float linearRoughness, float NoH) {
@@ -1156,7 +1156,7 @@ The complete implementation of our cloth BRDF, including sheen color and optiona
// specular BRDF
float D = distributionCloth(linearRoughness, NoH);
float V = visibilityCloth(NoV, NoL);
vec3 F = fresnel(sheenColor, LoH);
vec3 F = sheenColor;
vec3 Fr = (D * V) * F;
// diffuse BRDF
@@ -2014,7 +2014,7 @@ $$\begin{equation}
I(f(n, v, \alpha)) \equiv \frac{1}{N}\sum_{\forall \, i \in image} f(l_i, n, v, \alpha) \left<\NoL\right>
\end{equation}$$
However, in practice we're using _importance sampling_ which needs to take de $pdf$ of the distribution
However, in practice we're using _importance sampling_ which needs to take the $pdf$ of the distribution
into account and adds a term $\frac{\left<\VoH\right>}{D(h_i, \alpha)\left<\NoH\right>}$.
See Importance Sampling For The IBL section:
@@ -2417,57 +2417,11 @@ Figure [anisotropicDirection] demonstrates this modified implementation in pract
### Cloth ###
The IBL implementation for the cloth material model is more complicated than for the other material models. The main difference stems from the use of a different NDF (Ashikhmin vs height-correlated Smith GGX). As described in this section, we use the split-sum approximation to compute the DFG term of the BRDF when computing an IBL. Since this DFG term is based on the wrong NDF, we must find a new approximation.
The IBL implementation for the cloth material model is more complicated than for the other material models. The main difference stems from the use of a different NDF ("Charlie" vs height-correlated Smith GGX). As described in this section, we use the split-sum approximation to compute the DFG term of the BRDF when computing an IBL. This DFG term is designed for a different BRDF and cannot be used for the cloth BRDF. Since we designed our cloth BRDF to not need a Fresnel term, we can generate a single DG term in the 3rd channel of the DFG LUT. The result is shown in figure [dfgClothLUT].
The approximation we use is purely analytical and was manually fitted against a Monte-Carlo reference shown in figure [clothDFGReference] (using $2^{22}$ samples per data point instead of importance sampling). This visual comparison shows the significant impact the cloth NDF has on the BRDF. Using the standard DFG term would result in widely incorrect results.
The DG term is generated using uniform sampling as recommended in [#Estevez17]. With uniform sampling the $pdf$ is simply $\frac{1}{2\pi}$ and we must still use the Jacobian $\frac{1}{\eft< 4 \VoH \right>}$.
![Figure [clothDFGReference]: DFG LUT (left) vs Ashikhmin DFG LUT (middle) vs "Charlie" DFG LUT (right)](images/ibl/dfg_cloth.png)
Manual fitting was performed in Mathematica (as shown in figure [clothManualFitting]) and while not perfect, the analytical approximation strikes a decent balance between correctness and runtime cost.
![Figure [clothManualFitting]: Manual fitting of the DFG term for the cloth NDF](images/ibl/cloth_dfg_approximation.png)
Listing [clothApprox] shows the implementation of the DFG approximation for the Ashikhmin NDF. We also provide the [Mathematica notebook](math/Cloth%20DFG%20Approximation.nb) containing the formulas of our approximation as well as comparisons to the reference LUT.
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
vec2 PrefilteredDFG_Cloth_Ashikhmin(float roughness, float NoV) {
const vec4 c0 = vec4(0.24, 0.93, 0.01, 0.20);
const vec4 c1 = vec4(2.00, -1.30, 0.40, 0.03);
float s = 1.0 - NoV;
float e = s - c0.y;
float g = c0.x * exp2(-(e * e) / (2.0 * c0.z)) + s * c0.w;
float n = roughness * c1.x + c1.y;
float r = max(1.0 - n * n, c1.z) * g;
return vec2(r, r * c1.w);
}
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
[Listing [clothApprox]: GLSL implementation of the DFG approximation for the Ashikhmin cloth NDF]
Listing [clothCharlieApprox] shows the implementation of the DFG approximation for the "Charlie" NDF.
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
vec2 PrefilteredDFG_Cloth_Charlie(float roughness, float NoV) {
const vec3 c0 = vec3(0.95, 1250.0, 0.0095);
const vec4 c1 = vec4(0.04, 0.2, 0.3, 0.2);
float a = 1.0 - NoV;
float b = 1.0 - roughness;
float n = pow(c1.x + a, 64.0);
float e = b - c0.x;
float g = exp2(-(e * e) * c0.y);
float f = b + c1.y;
float a2 = a * a;
float a3 = a2 * a;
float c = n * g + c1.z * (a + c1.w) * roughness + f * f * a3 * a3 * a2;
float r = min(c, 18.0);
return vec2(r, r * c0.z);
}
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
[Listing [clothCharlieApprox]: GLSL implementation of the DFG approximation for the "Charlie" cloth NDF]
![Figure [dfgClothLUT]: DFG LUT with a 3rd channel encoding the DG term of the cloth BRDF](images/ibl/dfg_cloth.png)
The remainder of the image-based lighting implementation follows the same steps as the implementation of regular lights, including the optional subsurface scattering term and its wrap diffuse component. Just as with the clear coat IBL implementation, we cannot integrate over the hemisphere and use the view direction as the dominant light direction to compute the wrap diffuse component.
@@ -3621,13 +3575,13 @@ $$\begin{equation}
The PDF of the BRDF can therefore be expressed as in equation $\ref{importantPDF}$:
$$\begin{equation}\label{importantPDF}
p(\theta,\phi) = \frac{\alpha^2}{\pi(cos^2\theta (\alpha^2-1) + 1) cos\theta sin\theta}
p(\theta,\phi) = \frac{\alpha^2}{\pi(cos^2\theta (\alpha^2-1) + 1)^2} cos\theta sin\theta
\end{equation}$$
The term $sin\theta$ comes from the differential solid angle $sin\theta d\phi d\theta$ since we integrate over a sphere. We sample $\theta$ and $\phi$ independently:
$$\begin{align*}
p(\theta) &= \int_0^{2\pi} p(\theta,\phi) d\phi = \frac{2\alpha^2}{cos^2\theta (\alpha^2-1) + 1} cos\theta sin\theta \\
p(\theta) &= \int_0^{2\pi} p(\theta,\phi) d\phi = \frac{2\alpha^2}{(cos^2\theta (\alpha^2-1) + 1)^2} cos\theta sin\theta \\
p(\phi) &= \frac{p(\theta,\phi)}{p(\phi)} = \frac{1}{2\pi}
\end{align*}$$
@@ -4285,6 +4239,10 @@ void main() {
# Revisions
February 20, 2019: Cloth shading
- Removed Fresnel term from the cloth BRDF
- Removed cloth DFG approximations, replaced with a new channel in the DFG LUT
August 21, 2018: Multiscattering
- Added section [Energy loss in specular reflectance] on how to compensate for energy loss in single scattering BRDFs
+1928
View File
File diff suppressed because one or more lines are too long
+27 -5
View File
@@ -436,9 +436,6 @@ Chromaticity information should instead be set on the sheen color. To create mor
such as denim, cotton, etc. use the base color for chromaticity and use the default sheen color
or set the sheen color to the luminance of the base color.
!!! Warning
The cloth material model is more expensive than the standard material model.
!!! Tip
To see the effect of the `roughness` parameter make sure the `sheenColor` is brighter than
`baseColor`. This can be used to create a fuzz effect. Taking the luminance of `baseColor`
@@ -1096,7 +1093,7 @@ Value
Description
: Reduces specular aliasing by increasing roughness based on the local geometric curvature.
This property is particularly effective if you only use MSAA.
This property is particularly effective if you only use MSAA as your anti-aliasing method.
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ JSON
material {
@@ -1105,7 +1102,7 @@ material {
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
![Figure [curvatureToRoughness]: Close up of a glossy metallic surface rendered normally (left) and
with `curvatureToRoughness` (right).](images/screenshot_curvature_to_roughness.png)
with `curvatureToRoughness` (right).](images/screenshot_curvature_to_roughness.jpg)
### limitOverInterpolation
@@ -1128,6 +1125,31 @@ material {
}
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
### clearCoatIorChange
Type
: `boolean`
Value
: `true` or `false`. Defaults to `true`.
Description
: 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 `baseColor`. When this
effect is disabled, `baseColor` is left unmodified. See figure [clearCoatIorChange] for an
example of how this property can affect a red metallic base layer.
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ JSON
material {
clearCoatIorChange : false
}
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
![Figure [clearCoatIorChange]: The same rough metallic ball with a clear coat layer rendered
with `clearCoatIorChange` enabled (left) and disabled
(right).](images/screenshot_clear_coat_ior_change.jpg)
### variantFilter
Type
+2 -2
View File
@@ -66,8 +66,8 @@
<h1>Core Documentation</h1>
<ul>
<li><a href="https://github.com/google/filament/blob/master/README.md">Build Instructions</a></li>
<li><a href="https://google.github.io/filament/Filament.md.html">Filament Design</a></li>
<li><a href="https://google.github.io/filament/Materials.md.html">Materials Overview</a></li>
<li><a href="https://google.github.io/filament/Filament.html">Filament Design</a></li>
<li><a href="https://google.github.io/filament/Materials.html">Materials Overview</a></li>
<li><a href="https://google.github.io/filament/Material%20Properties.pdf">Materials Ref Sheet</a></li>
</ul>
Binary file not shown.

Before

Width:  |  Height:  |  Size: 319 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 76 KiB

After

Width:  |  Height:  |  Size: 22 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 66 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 152 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 346 KiB

+1 -1
View File
@@ -26,7 +26,7 @@
<pubDate>Tue, 30 Oct 2018 13:13:14 -0700</pubDate>
<guid>https://google.github.io/filament/webgl/</guid>
<description> tutorials Triangle Tutorial Redball Tutorial Suzanne Tutorial demos parquet suzanne knotess other documentation JavaScript API reference WebGL Meetup Slides (2018) </description>
<description> tutorials Triangle Tutorial Redball Tutorial Suzanne Tutorial demos parquet suzanne helmet knotess other documentation JavaScript API reference WebGL Meetup Slides (2018) </description>
</item>
</channel>
File diff suppressed because it is too large Load Diff

Before

Width:  |  Height:  |  Size: 2.6 MiB

After

Width:  |  Height:  |  Size: 2.6 MiB

Before

Width:  |  Height:  |  Size: 5.1 MiB

After

Width:  |  Height:  |  Size: 5.1 MiB

Before

Width:  |  Height:  |  Size: 806 KiB

After

Width:  |  Height:  |  Size: 806 KiB

Before

Width:  |  Height:  |  Size: 2.9 MiB

After

Width:  |  Height:  |  Size: 2.9 MiB

Before

Width:  |  Height:  |  Size: 3.8 MiB

After

Width:  |  Height:  |  Size: 3.8 MiB

Before

Width:  |  Height:  |  Size: 3.0 MiB

After

Width:  |  Height:  |  Size: 3.0 MiB

Before

Width:  |  Height:  |  Size: 5.4 MiB

After

Width:  |  Height:  |  Size: 5.4 MiB

Before

Width:  |  Height:  |  Size: 17 KiB

After

Width:  |  Height:  |  Size: 17 KiB

Before

Width:  |  Height:  |  Size: 3.5 MiB

After

Width:  |  Height:  |  Size: 3.5 MiB

Before

Width:  |  Height:  |  Size: 3.5 MiB

After

Width:  |  Height:  |  Size: 3.5 MiB

Before

Width:  |  Height:  |  Size: 4.4 MiB

After

Width:  |  Height:  |  Size: 4.4 MiB

Before

Width:  |  Height:  |  Size: 5.1 MiB

After

Width:  |  Height:  |  Size: 5.1 MiB

Before

Width:  |  Height:  |  Size: 737 KiB

After

Width:  |  Height:  |  Size: 737 KiB

Before

Width:  |  Height:  |  Size: 3.6 MiB

After

Width:  |  Height:  |  Size: 3.6 MiB

Before

Width:  |  Height:  |  Size: 4.3 MiB

After

Width:  |  Height:  |  Size: 4.3 MiB

Binary file not shown.
Binary file not shown.
Binary file not shown.
BIN
View File
Binary file not shown.
Binary file not shown.
+9 -12
View File
File diff suppressed because one or more lines are too long
Binary file not shown.
Binary file not shown.
Binary file not shown.
+154
View File
@@ -0,0 +1,154 @@
<!DOCTYPE html>
<html lang="en">
<head>
<title>FlightHelmet</title>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width,user-scalable=no,initial-scale=1">
<link href="https://google.github.io/filament/favicon.png" rel="icon" type="image/x-icon" />
<style>
body { margin: 0; overflow: hidden; }
canvas { touch-action: none; width: 100%; height: 100%; }
</style>
</head>
<body>
<canvas></canvas>
<script src="filament.js"></script>
<script src="gl-matrix-min.js"></script>
<script src="https://unpkg.com/gltumble"></script>
<script>
const ibl_suffix = Filament.getSupportedFormatSuffix('etc s3tc');
const env = 'syferfontein_18d_clear_2k';
const ibl_url = `${env}/${env}_ibl${ibl_suffix}.ktx`;
const sky_url = `${env}/${env}_skybox.ktx`;
const helmet_filamat_url = 'helmet.filamat';
const filamesh_url = 'helmet.filamesh';
Filament.init([
'FlightHelmet_baseColor.png',
'FlightHelmet_occlusionRoughnessMetallic.png',
'FlightHelmet_normal.png',
'FlightHelmet_baseColor1.png',
'FlightHelmet_occlusionRoughnessMetallic1.png',
'FlightHelmet_normal1.png',
'FlightHelmet_baseColor2.png',
'FlightHelmet_occlusionRoughnessMetallic2.png',
'FlightHelmet_normal2.png',
'FlightHelmet_baseColor3.png',
'FlightHelmet_occlusionRoughnessMetallic3.png',
'FlightHelmet_normal3.png',
'FlightHelmet_baseColor4.png',
'FlightHelmet_occlusionRoughnessMetallic4.png',
'FlightHelmet_normal4.png',
helmet_filamat_url, filamesh_url, ibl_url, sky_url
], () => {
window.Fov = Filament.Camera$Fov;
window.LightType = Filament.LightManager$Type;
window.app = new App(document.getElementsByTagName('canvas')[0]);
});
class App {
constructor(canvas) {
this.canvas = canvas;
const engine = this.engine = Filament.Engine.create(this.canvas);
this.scene = engine.createScene();
this.trackball = new Trackball(canvas, {startSpin: 0.035});
const sunlight = Filament.EntityManager.get().create();
Filament.LightManager.Builder(LightType.SUN)
.color([0.98, 0.92, 0.89])
.intensity(100000.0)
.direction([0.6, -1.0, -0.8])
.castShadows(true)
.sunAngularRadius(1.9)
.sunHaloSize(10.0)
.sunHaloFalloff(80.0)
.build(engine, sunlight);
this.scene.addEntity(sunlight);
const indirectLight = this.ibl = engine.createIblFromKtx(ibl_url);
this.scene.setIndirectLight(indirectLight);
indirectLight.setIntensity(100000);
const skybox = engine.createSkyFromKtx(sky_url);
this.scene.setSkybox(skybox);
const sampler = new Filament.TextureSampler(
Filament.MinFilter.LINEAR_MIPMAP_LINEAR,
Filament.MagFilter.LINEAR,
Filament.WrapMode.CLAMP_TO_EDGE);
const helmetMaterial = engine.createMaterial(helmet_filamat_url);
const setTextures = function(minstance, suffix) {
const setParam = minstance.setTextureParameter.bind(minstance);
const createTex = engine.createTextureFromPng.bind(engine);
const baseColor = `FlightHelmet_baseColor${suffix}.png`;
const orm = `FlightHelmet_occlusionRoughnessMetallic${suffix}.png`;
const normal = `FlightHelmet_normal${suffix}.png`;
setParam('baseColor', createTex(baseColor, {srgb: true}), sampler);
setParam('occlusionRoughnessMetallic', createTex(orm), sampler);
setParam('normalMap', createTex(normal), sampler);
};
const GlassPlasticMat = helmetMaterial.createInstance();
const LeatherPartsMat = helmetMaterial.createInstance();
const LensesMat = helmetMaterial.createInstance();
const MetalPartsMat = helmetMaterial.createInstance();
const RubberWoodMat = helmetMaterial.createInstance();
setTextures(GlassPlasticMat, '');
setTextures(LeatherPartsMat, '1');
setTextures(LensesMat, '2');
setTextures(MetalPartsMat, '3');
setTextures(RubberWoodMat, '4');
const mats = { GlassPlasticMat, LeatherPartsMat, LensesMat, MetalPartsMat, RubberWoodMat };
const mesh = engine.loadFilamesh(filamesh_url, null, mats);
let rm = engine.getRenderableManager();
let renderable = rm.getInstance(mesh.renderable);
rm.setCastShadows(renderable, true);
rm.setReceiveShadows(renderable, true);
this.helmet = mesh.renderable;
this.scene.addEntity(mesh.renderable);
this.swapChain = engine.createSwapChain();
this.renderer = engine.createRenderer();
this.camera = engine.createCamera();
this.view = engine.createView();
this.view.setCamera(this.camera);
this.view.setScene(this.scene);
this.resize();
this.render = this.render.bind(this);
this.resize = this.resize.bind(this);
window.addEventListener('resize', this.resize);
window.requestAnimationFrame(this.render);
}
render() {
const tcm = this.engine.getTransformManager();
const inst = tcm.getInstance(this.helmet);
tcm.setTransform(inst, this.trackball.getMatrix());
inst.delete();
this.renderer.render(this.swapChain, this.view);
window.requestAnimationFrame(this.render);
}
resize() {
const dpr = window.devicePixelRatio;
const width = this.canvas.width = window.innerWidth * dpr;
const height = this.canvas.height = window.innerHeight * dpr;
this.view.setViewport([0, 0, width, height]);
const y = -0.125, eye = [0, y, 2], center = [0, y, 0], up = [0, 1, 0];
this.camera.lookAt(eye, center, up);
const aspect = width / height;
const fov = aspect < 1 ? Fov.HORIZONTAL : Fov.VERTICAL;
this.camera.setProjectionFov(30, aspect, 1.0, 10.0, fov);
}
}
</script>
</body>
</html>
+1
View File
@@ -79,6 +79,7 @@
<ul>
<li><a href="https://google.github.io/filament/webgl/parquet.html">parquet</a></li>
<li><a href="https://google.github.io/filament/webgl/suzanne.html">suzanne</a></li>
<li><a href="https://google.github.io/filament/webgl/helmet.html">helmet</a></li>
<li><a href="https://prideout.net/knotess/">knotess</a></li>
</ul>
Binary file not shown.
Binary file not shown.

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