By default ancillary buffers are discarded on commit (eg. depth buffer),
but in certain situations the platform may want to preserve them. this
new virtual allows a concrete implementation to specify which buffers
need to be preserved.
Note that in ES2 mode, the depth value returned by the picking API
only has 8-bits precision and incurs a bigger performance penalty,
because glReadPixels is synchronous.
This is only the first step where we:
- clean-up some code to prepare for 2nd step
- add support for the linear->srgb in the shaders
The linear->srgb conversion is protected by a
specification constant and will be enabled only
if the corresponding EGL extension in not present.
Then, if enabled, the actual conversion is
controlled by a uniform so that it can be
selectively enabled on swapchains that have it
turned on.
In this change, the emulation logic that sets
these gates is not implemented (that's step 2).
This CL contains two parts:
- changes to matc/filamat
- changes to filament itself
Filamat can now generate ES2 compatible shaders. Only the unlit variant
is supported. Fog and picking are supported as well.
post-processing, skinning, instancing, all lighting and shadowing are not supported.
Filament is updated to not issue commands that are not supported in ES2.
Addtionnally, the hello-triangle sample is updated to work on an ES2 device.
From the backend's point of view, UBOs are emulated with uniforms.
The backend will maintain a data structure that maps an offset into
the UBO to a uniform and will do the appropriate glUniform* calls
at the right time and if needed (e.g. only if the UBO content has
changed).
The mapping from an UBO content to uniforms is passed to Program
upon creation.
This first round is mostly about making the backend compile with the
ES2 header only and use the ES2 code path when running on an ES2
context. We also add feature level 0, which corresponds to ES2
devices.
We introduce the macro FILAMENT_SILENCE_NOT_SUPPORTED_BY_ES2, which is
exclusively used to compile-out code that cannot compile with ES2
headers. This macro is active when ES2 headers are used.
There is also a new `OpenGLContext::isES2()` method that is returns
whether we're running an ES2 context, either statically (desktop, ios)
or dynamically (mobile).
This PR should add or remove any functionality.
A material global is a variable seen by all materials. There are 4 such
variable which are all vec4 and they can be set on a per-view basis.
All materials used during Renderer::render() will see the same value.
These variable can be accessed in the materials by using
getMaterialGloabal{0|1|2|3}.
* vulkan: Fix Adreno issue with optimized material
Turning off the simplification pass seems to remove all of the
artifacts associated with Adreno GPUs.
- `-g` option was missing from `build.sh`
- `-Pcom.google.android.filament.matnopt` should be passed to
the sample apps as well.
- Add logic to respect `-Pcom.google.android.filament.matnopt`
in `FilamentPlugin.groovy`
They're not hardcoded in a database inside MaterialBuilder and are
generated. This will be needed later for ES2 support.
We could actually imagine something more dynamic in the future too.
- Moved most of the layout transition logic into VulkanImageUtil
so that we'd have a single place to consider if failure arises
- Add an abstraction on top of vk's layouts so that reasoning
about our use cases (and corresponding layout is easier).
- Removed the redundant VulkanDepthLayout
- Refactor VulkanTexture::transitionLayout so that most of the
transition paths can be done through this entry point. It also
enables us to handle tracking the current layout.
- Add a special case to transition the depth attachment/texture
if it is both a sampler and an attachment.
- Add a few debug printing markers across the classe - guarded
under the existing FILAMENT_VULKAN_VERBOSE define.
- refactor the code so that all defines are generated in the same place
- generate common_type after all defines are generated
- protect (with defines) structures and UBOs that are not needed, based
on the variant
* Support the external image on macOS
Implement CocoaExternalImage.
* Fix to take an onwership of the external image
* Correct incorrect comments
* Rename a function explicitly
Make a function name to know copying RECTANGLE to TEXTURE2D.
* Do lazy initialization
Create CocoaExternalImage::SharedGl when it's needed.
* Fix a crash when engine is terminated
Destroy the external image shared gl before gl context is destroyed.
* Remove an useless variable
* Improve size optimizations when compiling material
This changes the behavior of the size optimizer in matc (-S), but
only for GLSL and MSL. With this change we gain a ~65% size reduction
on a lit material compiled for OpenGL. To get those gains we generate
extra SPIRV debug information to preserve variable names and better
utilize the line dictionary. Unfortunately this break the SPIRV
optimizer so we skip it and instead rely on a simple DCE pass provided
by glslang. We also enhance the whitespace removal pass of the GLSL
minifier to move lone { and } to the previous line, which avoids
generating an extra index in each shader variant. Each index being
at least as big as the character itself, this is quite wasteful.
When generating SPIRV for Vulkan, we rely on spirv-opt for size
optimizations as before.
Some shaders can be shared across all materials (e.g. the depth
shaders). We use the filament default material as the "source" of
the cache, but until now we relied on an a priori knowledge of which
variants were present in the default material.
With this change, we now query once the list of variants (of interest)
in the default material and reuse that list for caching these variants
later.
This is better because the cached variants are now entirely driven by
the default material (which they depend on anyways). This is also faster
because we don't need to query which variant we need each time we create
a material.
- Depth attachment layout has generated a lot of error due to
it being read-only. But the store-ops for the attachment during
the renderpass are all write ops. We set the depth attachment
layout as VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL
- Enable extra blitting step for SSAO because of the above layout
conundrum.
- Index buffers did not have a pipeline barriers after loading
them.
- Remove `assert_invariant(utils::popcount(sampleCount) == 1);`
from `reduceSampleCount`. This assert fails when enabling the
duplicate pass for SSAO.
The VSM variant is never needed for unlit materials, it was filtered
out correctly for color shaders but not for the depth shaders.
This removes 4 variants from all unlit materials.
Also improve matinfo variants output.
* Suppress numerous libz warnings
zlib will fix this issue later (see https://github.com/madler/zlib/issues/633).
For now we will just turn off the warning.
* Fix Windows build
The feature-level option sets the maximum feature level allowed for
the material. matc will fail if the specified material has a higher
feature level than the value set with the feature-level option. The
default is 3 (max).
This can be used to ensure that materials don't use features above
a specified level.
... which is needed to avoid compilation error with recent LLVM libc++ (after https://reviews.llvm.org/D146097). Previously, symbols like std::terminate() were available through other headers (e.g. <functional>, <vector>, etc.).
- FogOption::color is now correctly multiplied by the exposure and
environment intensity.
- New option to exclude the skybox from the fog
- better documentation and naming
In device vertex domain it is easy to specify infinite world-space
coordinated (e.g. with the skybox), this results in complications
everywhere. We were mitigating this by essentially moving these
coordinates to around 16000 (give or take depending on the near plane),
but that was way too small.
Now we move them around 1e19, which seems to work. It's important with
applications rendering very large scenes to not use too small of a value.
This happened because the code iterated over the keys of a hashmap,
which obviously were not guaranteed to be in the same order as those
entries where added to the hashmap.
We fix this by adding a "visitor" to the materialchunk, so we can
iterate through it in order and retried the info we need.
When we call TextureProvider::cancelDecoding, we should make sure
that textures that have been decoded, but not yet used (popped)
should be released (i.e. memory freed and the meta data marked
appropriately.)
The PixelBufferDescriptor was not being deallocated properly, which
resulted in the leak. This patch explicitly deletes the
PixelBufferDescriptor at the end of the callback to prevent the leak
.This is necessary as the move constructor does not automatically
deallocate the existing PixelBufferDescriptor.
An attachment would be wrongly discarded if used as read-only: because
it didn't have a dependency to it, the discard flag was set.
This is fixed by setting the discard flag only if a resource is written
and has dependencies to it.
Should fix: #5005
- Add a TaskHandler class for process events on the backend
thread
- Check fence status when handler runs and copy bits to the client
when the fence is reached.
* Add way to retrieve the user world-space in materials
added `getUserWorldFromWorldMatrix()` and `getUserWorldPosition()` to
retrieve the API-level (user) world position in materials.
Deprecated `getWorldOffset()`
`getWorldOffset` didn't work when an IBL rotation was applied.
* fix large scenes with an ibl rotation
Rotate the IBL around the camera instead of the world so that the camera
is always at the origin regardless of the rotation.
* Add new alphaToCoverage material property
The alphaToCoverage property lets you enable or disable alpha to coverage
in a material. More importantly it lets you overrides the behavior of
blending: masked which automatically enables alphaToCoverage.
* Update release notes
The fog calculation could fail when the falloff was strong and the
camera z position was far from the fog height. The problem was
that the computation was spread between the cpu and gpu by splitting
an exp(), but with certain parameters the two exp() would independently
blow-up. We fix this by doing the exp() only on the gpu side.
try to be more explicit about which configurations are supported,
and use the same pattern everywhere for checking the gl version at
either compile and runtime.
This didn't happen in practice, but we would call (null) if the
clip_control extension was available and we were not on GL 4.1.
We "fix" this by not supporting the clip_control extension on desktop.
It doesn't matter because clip_control is core as of 4.5 and is
present in only 8% of non 4.5 GL implementation, and this doesn't
include any macOS versions.
This small abstraction is (will be) needed because GLES 2.0 doesn't
have sync object, however synchronization is sometimes available
externally, in particular with EGL.
This PR doesn't provide other implementations.
- make sure to initialize all extension booleans, we treat them
as feature flags.
- be more explicit about #define'ing gl tokens, so we can more easily
catch errors later.
- don't blindly use extension tokens that might not be available
(e.g.: GL_TEXTURE_EXTERNAL_OES or GL_TEXTURE_CUBE_MAP_ARRAY). It
would probably cause a spurious gl error.
- iOS is treated the same way than Android now. The only difference
is that iOS only provides prototypes and no typedef, whereas
Android only provides typedefs and no prototypes.
- Timer queries is core in GL and an extension on all versions of
GLES. On iOS it's not available at the header level. An additional
subtlety is that glGetObjectuiv is core in GLES 3.0, so it conflicts
with the extension.
So, now we do things correctly:
- on desktop we use the core methods
- on ios we ifdef out everything related to timer queries
- on gles 2.0 and up we use only the extension entry-points
We were not testing for that case properly. This case is taken when
either:
- depth & stencil textures are the same and not null
- or, only depth is specified but both attachments are requested
Also cleanup the dimension checks in debug builds.
- some of the convenience are not available in ES2
- it's less efficient
- we can save some PBO space when reading back
a partial framebuffer.
We also avoid using GL_PACK_ROW_LENGTH which technically is not
a convenience, but in our case we are doing an extra copy anyways, so
we can account for the row-length at that point.
- We now call visitScene only once for the directional shadowmap instead of
1 + cascade_count times.
- Don't use visitScene for spot shadows
it was only used to compute the near/far planes, but instead we can
use the radius of the light. This could degrade the quality of the
spot shadows, but this can be corrected by setting a correct radius.
caveat: currently the near is hardcoded to 0.01 units. this should be
user-settable.
- Improve performance of visitScene calls
instead of transforming 8 points of an AABB and finding the min/max,
we transform the AABB and use its minz and maxz. This works for affine
transforms.
This change also cleans-up AABB and Box transform APIs, which also
are now inline.
- StructureOfArray: don't initialize trivial ctors
We mimic the behavior of std::vector<> here, where a resize() won't
initialize the array if the type is trivially_default_constructible.
This can reveal existing bugs, where we depended on the initialization
to 0.
- StructureOfArray: add push_back(std::tuple<>)
This basically allows us to push_back() a struct of the SoA.
- Make PerRenderableData trivially constructible
this improves performance when we have tons of objects in the scene
because PerRenderableData is used in arrays.
We use isnan() to detect that the estimation of directional light
parameters from the IBL has failed, however isnan() always returns
false with -ffast-math, which we're using in release builds.
This works around that. The affected code is non essential, performance
is not a concern here.
When loading a glTF file on platforms without a filesystem, a client
calls `addResourceData` to populate `ResourceLoader`'s cache with data.
For example, a web client might make HTTP fetch requests to fill in
buffer data. This internal cache of data is stored in
`ResourceLoader::Impl::mUriDataCache`.
This works well, except the cache must persist until after it has been
uploaded to the GPU.
There was already a mechanism (see `uploadUserdata`) in place to ensure
that glTF data persisted until after it had been uploaded to the GPU.
However, this mechanism did not extend to client-provided data. Thus, a
race occured between Filament's driver consuming the buffer and it
getting freed.
Instead of storing the arrays into an array of void*, we use a
tuple<> instead. This improves debugging because now the tuple<>
has pointer with the correct types.
It also improves most of the code except `push_back` which now
relies on a hack -- this is the only place where I'm not able to
resolve the array strictly at compile time, even if in practice it is.
UbershaderProvider.getNativeObject() is accessed from AssetLoader.cpp,
so it must be annotated with @UsedByNative("AssetLoader.cpp") to
avoid runtime crashes when minification is applied.
Fixes#5944
`-d` now enables matdbg and adds debugging data, but doesn't affect
material optimization
`-g` disables material optimizations
A similar change is done with gradle options. The new proprety
`com.google.android.filament.matnopt` is used to disable material
optimizations.
These options mimic `matc` options.
- -m option now works with "directory_*.png" or just "*.png"
- "color" replaced by "albedo" to mach other places in the source tree
- fixed warnings
- clear the background when IBL is not used
* Calculate view vector without using camera eye position
* Fix compilation error (during parsing the material when a height map is passed in)
* Add SUN light to the scene
This change adds a 'SRGB' config flag when creating a SwapChain that
enables linear to sRGB conversion on write.
When using this flag, the linear->srgb conversion in the color grading
post processing should be disabled (or, the whole post-processing
stage should be disabled).
There is also a new query to determine if this flag is supported by
the underlaying platform.
On Metal, this happens automatically when the underlaying layer is sRGB.
This reverts commit 3799e219fc.
This change adds a 'SRGB' config flag when creating a SwapChain that
enables linear to sRGB conversion on write.
When using this flag, the linear->srgb conversion in the color grading
post processing should be disabled (or, the whole post-processing
stage should be disabled).
There is also a new query to determine if this flag is supported by
the underlaying platform.
On Metal, this happens automatically when the underlaying layer is sRGB.
We now structure the code to assume we have EGL_KHR_no_config_context,
which is the common case. This allows use to decouple context creation
from swapchain creation.
We still handle the case where the extension is not present by always
selecting a transparent config.
There can be up to 4 channels drawing commands can be associated to.
Channels work like "priorities" except it's the strongest command ordering
key, in particular it takes precedence over the object's blending mode.
We were using a specialization constant to size an array inside an
UBO interface block, which caused the crash in the Vulkan driver.
However, this specialization constant was only used to workaround a
Chrome bug on WebGL. Additionally, specialized array size inside blocks
are not fully supported in spirv.
This workaround simply replaces the specialization constant by a
constant on Vulkan.
Fix#6444
- Remove DefaultPlatform from public headers
DefaultPlatform is now PlatormFactory and is just an implementation
detail.
- VulkanPlatform is now public
- Improvements to the OpenGLPlatform interface
- Cleanup PlatformEGL and PlatformEGLAndroid
Also:
- reworked how external image worked so that all the implementation
is contained in the Platform and no dependency to the backend is
needed.
- MetalPlatform is now entirely private and final
This is because MetalPlatform wasn't an interface. We probably need one
so it could be customized in the future. But as it stands now it's
better to be private.
* Refactor VulkanContext/Driver initialization
Move the initialization of VulkanContext fields to the class
itself. This will clean up how the various extension support
flags are deteremined.
Also disable debugUtils extension for Mesa driver (#6192).
* Re-land #1 "[vulkan] Refactor vkEnumerate methods (#6423)"
This reverts commit 6f7d203adb.
The above commit (6f7d20) is the revert of #6423. Commit
6f7d20 is PR #6425.
"[vulkan] Refactor vkEnumerate methods (#6423)" failed [here] due to
a missing function attribute (VKAPI_ATTR in bluevk) for ARM64
compilers.
[here]: https://github.com/google/filament/actions/runs/3841550984
Since cmake 3.25 LINUX is automatically set based on CMAKE_SYSTEM_NAME,
which the android cmake files are setting to "Linux". This created an
inconsistant state in our build system.
At least some adreno compilers don't like returning an element of a
UBO array that is a structure in the vertex shader.
To work this around we have to copy the each of the structure fields.
Fixes#6355
Vulkan and Metal should be handled exactly the same within filament,
when it comes to texture-space and clip-space because filament
always transforms vulkan's clip-space to gl's/metal's).
Our shadow code took different paths, both equivalent though, but it's
confusing.
Since cmake 3.25 LINUX is automatically set based on CMAKE_SYSTEM_NAME,
which the android cmake files are setting to "Linux". This created an
inconsistant state in our build system.
The race coud lead to user after free and crashes.
We now keep a list of acquired streams with pending images on the
main thread, and use that to update the streams synchronously in
beginFrame. We can then enqueue a command for the driver thread that
will look for that stream in the active list of textures with stream
attached. Race avoided.
The previous code used the later list from both threads.
When more than one view was used, only the first view was cleared with
the ClearOption. This was actually intended when the views are rendering
into the swapchain (e.g. post process disabled), but that's incorrect
when the views render into intermediate buffers.
The clear flags are now associated with the actual rendertarget.
* Add new outputColorSpace() API to ColorGrading
This allows the application to select the desired output color space.
The default is set to Rec709-sRGB-D65 ("sRGB") but can be changed to
Rec709-Linear-D65.
Currently only the transfer function is taken into account and must
be either sRGB or Linear. Future updates will add support for
different gamuts and white points.
* Update release notes
WebGL complained about:
Precisions of uniform block 'ShadowUniforms' member
'ShadowUniforms.shadows.texelSizeAtOneMeter' differ between VERTEX and
FRAGMENT shaders.
this field didn't have a precision qualifier, this might be specific to
WebGL or a Chrome bug, unsure. Either we fix it by specifying all
qualifiers.
WebGL complained about:
Precisions of uniform block 'ShadowUniforms' member
'ShadowUniforms.shadows.texelSizeAtOneMeter' differ between VERTEX and
FRAGMENT shaders.
this field didn't have a precision qualifier, this might be specific to
WebGL or a Chrome bug, unsure. Either we fix it by specifying all
qualifiers.
WebGL complained about:
Precisions of uniform block 'ShadowUniforms' member
'ShadowUniforms.shadows.texelSizeAtOneMeter' differ between VERTEX and
FRAGMENT shaders.
this field didn't have a precision qualifier, this might be specific to
WebGL or a Chrome bug, unsure. Either we fix it by specifying all
qualifiers.
Since cmake 3.25 LINUX is automatically set based on CMAKE_SYSTEM_NAME,
which the android cmake files are setting to "Linux". This created an
inconsistant state in our build system.
Use a much more precise way to calculate the directional shadow frustum.
With very large scenes, we were losing the precision on the direction
of the light, and in some case even producing NaN in the matrix.
This partially addresses #6293
All shadow maps need a 1-px border for different reasons.
The directional shadow needs a "not in shadow" border because it uses
the intersection of receivers and casters in light-space.
Other shadow types need a border because of bilinear access at the
edges. Until now, the spot/point shadow border was handled with the
sampler's CLAMP.
Instead, now, we always generate a border and in one case we fill it
with "not in shadow" (by not rendering into it), in the other cases we
render the 2px larger shadowmap so we get completely correct bilinear
filter.
Additionally, for PCF, DPCF and PCSS we use a large filter kernel which
accesses data outside the texture, until now this was handled with CLAMP,
but that failed (2 of the edges were not handled in the same way) when
the shadowmap was smaller than the texture.
We fix this by clamping manually the texture coordinates.
The real motivation for these changes is to allow the use of a
shadow Atlas later.
When width/height is converted to GLSizei, which is signed, it can
become negative, which happened with a "full" viewport.
On some GL implementation, this resulted in a failure.
The viewport is now entirely handled by ShadowMap, that is, we're no
longer setting a viewport in the renderpass, instead the ShadowMap
uses a post projection transform to achieve the same effect.
This will become useful when store shadow maps in an Atlas.
point light shadows are not sampled just like spotlight shadows, the
only difference is that we're calculating the face first to access the
corresponding shadowmap data (including the light transform).
- the layer is now stored in the shadow ubo
- we now have one shadow ubo per face
- ShadowMap holds UBO index even for cascades
- move some shadow "view" uniforms into the shadow UBO
breakage was due to an uninitialized variable at the beginning of the
frame, caused by a recent change.
shadows would disappear when cascades were used with 'stable' shadows.
ShadowMap had recently inflated due to its internal use of
PerViewUniforms, which keeps a shadow copy of the uniform data. This
copy is not needed for ShadowMaps.
In addition to the new getters, this change fixes the duplication of
a MaterialInstance, which didn't carry along the following states:
- alpha mask threshold
- specular AA threshold
- specular AA variance
- double sidedness
TODO: stencil state, polygon offset and scissor are stil not queryable
* Recompute bounding boxes with morph targets
* Reduce the number of heap allocation while recomputing bounding boxes
Co-authored-by: Romain Guy <romainguy@curious-creature.com>
Instead of constantly reusing the View's UBO, each shadowmap now
manages it own. All UBOs for all shadow maps are updated together,
then later during rendering, we're simply binding the correct UBO.
This change will be needed later so that we can update several
shadow maps in a single texture.
There are two main changes to achieve this:
1. ShadowMap now has PerViewUniforms object
2. For point lights, each face now has a ShadowMap object
One consequence is that ShadowMap is now very large (over 2KB). This
will be addressed later.
This 2D allocator only supports power-of-two, square allocations. It
uses a quadtree to store the allocated regions.
The quadtree implementation currently has a fixed depth (templated).
The allocator does a best-fit match, but currently doesn't implement a
free method.
- RenderPass::Executor now only executes the commands, it doesn't
create a backend render pass anymore. This is still done in the
RenderPass::execute() helper.
- scissor and poloyon offset overrides are now set on Executor because
they are not needed to generate the commands.
glDispatchCompute requires Android API level 21, however bumping our
required minimum from 19 to 21 caused some clients' builds to fail.
Commenting-out that line for now to proceed with the 1.28.0 upgrade.
glDispatchCompute requires Android API level 21, however bumping our
required minimum from 19 to 21 caused some clients' builds to fail.
Commenting-out that line for now to proceed with the 1.28.0 upgrade.
The VulkanProgram constructor was bailing out early and emitting a
warning because it saw that one of the stages wasn't fulfilled.
However it's okay for a pipeline to be missing a compute program.
Fixes regression that started with fabba73b1.
- remove mEngine from ShadowMap
- remove storage of ShadowMapInfo in ShadowMap
- ShadowMap::render should be on ShadowMapManager
- remove more attributes from ShadowMap
ShadowMap is now reduced to 32 bytes.
Spotlight shadow maps are now limited only by h/w limits (UBO size and
2d array maximum layers), which works out to about 146 shadows.
In practice we hardcode the limite to 64, but this can be changed at
compile time. A higher maximum increases memory usage.
There used to be a bitfield per renderable with a bit for each shadow
map indicating if the renderable was "visible" from this light. The
limit to 14 came from that bitfield. All shadow maps used to be culled
first, setting the bitfield appropriately.
Instead, we are now processing spotlight shadows one at a time,
performing culling as we go. For this reason we don't need a bit per
shadow map.
No need to generate a sentinel command in the main loop when a
command is canceled, this is now done automatically at a higher level.
The main benefit is that we can reject renderables that are not visible
a bit faster.
The VulkanProgram constructor was bailing out early and emitting a
warning because it saw that one of the stages wasn't fulfilled.
However it's okay for a pipeline to be missing a compute program.
Fixes regression that started with fabba73b1.
this case was causing uninitialized variables to be used creating a
false positive "shadows on" in the first cascade.
The main change here is to bail out as soon as we know there is no shadowing.
we attempted to select a shader which processed the required number of
component, but were always selecting the 4-components version.
this should improve blur performance for VSM.
This basically adds two settings:
- highPrecision at the View level, which controls the bit depth
of the vsm shadow texture used. This affects all shadowmaps.
- elvsm per shadowmap, which enables Exponential Layered VSM.
the main change in the shaders is that we now always output the
"negative" EVSM, even when it's not enabled. If no shadowmap uses
ELVSM, then the texture is stil an RG texture and the calculation is
lost (with some luck culled by the shader compiler), either way it's
not a lot of math and it's done only once per shadow texel.
During the color pass, on the other hand, we compute the "negative"
EVSM only if enabled.
We were always adjusting the near/far of the view volume based on the
scene content for shadowing, which defeated the "stable" shadows.
Also changed the default cascade splits from a linear split to a
log2 split, because due to the perspective projection, the log2 split
actually looks linear. Also intuitively, it makes more sense to give
more resolution to the shadows close to the camera.
* Fix a crash by setting not exist material parameters on ubershader
* gltfio: add getFeatureMap, remove logic for dummy textures
Co-authored-by: Philip Rideout <philiprideout@gmail.com>
to emulate the bindless API in the gl backend we always used the highest
texture unit available. However at feature level 3, we support up to 62
textures, so the that max was bumped to 62 -- however, where we're not
on a feature level 2 device, that texture unit doesn't exist.
Instead we now always use binding 31, which is guaranteed to exist by
EGL's minspec.
to emulate the bindless API in the gl backend we always used the highest
texture unit available. However at feature level 3, we support up to 62
textures, so the that max was bumped to 62 -- however, where we're not
on a feature level 2 device, that texture unit doesn't exist.
Instead we now always use binding 31, which is guaranteed to exist by
EGL's minspec.
* minimal backend support for compute
- added api to dispatch a compute shader
- added api to create and bind a ssbo
- added api to read back a buffer
Only implemented in the gl backend
* Add a backend compute test suite
* basic support for compute shaders in matc
this is still very much work-in-progress.
We're not supporting images nor ssbo for now.
* rename UniformInterfaceBlock to BufferInterfaceBlock
* augment BufferInterfaceBlock to support ssbo features
- add support for std430
- add support for ssbo
- add support for variable-size array
- add support for memory qualifiers
* reformat MaterialBuilder
* material format: move subpasses outside of parameters
subpasses now are their own json property instead of being a
"parameter".
* refactor parameter() methods to match Buffer/SamplerInterfaceBlock
We're just shuffling the arguments.
* add support for buffers in .mat files
* filamat now generates buffer blocks (ssbo)
* take feature level into consideration when optimizing shaders
* don't store the 'uniform binding' chunk for level 2 materials
this includes some refactoring/cleanups of MaterialParser
* matinfo: fixes for compute
- separate subpasses from parameters
- don't attempt to print material properties
it is not true that the whole box is inside the frustum if we have
8 vertices and some frustum vertices are in the box -- that's even
non-sensical.
We now test for this case by checking that we have all (8) vertices of
the box inside the frustum.
This caused some shadows to be missing.
This is because most android devices only support 16 texture in the
shaders (94.4%), so we can't realistically have feature level 2 demand
that.
Instead feature level 2 enables compute/ES3.1 features.
This is a feature request from Google. It allows users to "preload" an
asset, ie you can now create all VertexBuffer objects, Texture objects,
etc, without actually creating any entities or renderable components.
In the past we used TransformManager to help out with computing the big
asset-level bounding box, but now we use `gltf_node_transform_world()`
because entities might not yet exist.
One minor side effect is that `FilamentAsset::getBoundingBox()` now
returns the AABB that was determined at load time, and does not account
for instances. As a result, our `gltf_instances` sample app looks
slightly different but this is expected.
In VulkanPipelineCache, `getShaderStageFlags()` and `getUsageFlags()`
are used to track which samplers are used in the VERTEX stage and which
are used in the FRAGMENT stage. The recent change I made was incorrect
because it did not account for samplers that are used in BOTH stages.
This fixes the recent regression where we see validation errors when
running `gltf_viewer` in ubershader mode.
Some (poorly authored) glTF assets have several `image` elements
that all refer to the same URL or buffer view. When this occurs,
we create only 1 Filament Texture.
These assets regressed after PR 6051, which consolidated the texture
related fields in `FilamentAsset`, but did not include an ownership flag
in the new `TextureInfo` struct.
- fix View::setVisibleLayers to match code. By default only layer 0
is active, despite the documentation stating otherwise.
- add a helper to enable/disable layers more easily
- don't use layer 0,1,2 for the overdraw function as they were used by
FilamentApp in "multi view" mode.
- improve scissor documentation, specify coordinate system and
clipping behavior
- scissor now takes the guard bands into account
- on the backend side the scissor is no longer clipped to the viewport
- clipping to the viewport is now done on the filament side
- don't set scissor when material instance doesn't specify one
(common case)
AssetLoader now loads assets in two passes:
- Pass 1 creates VertexBuffer objects, MorphTargetBuffer objects, etc.
- Pass 2 creates entities, renderables, etc (only if numInstances > 0)
This feature will help us integrate gltfio with an internal library at
Google.
The asset previously had three confusing fields related to textures:
mTextures, mTextureSlots, and mTextureBindings.
These are now consolidated into a single field, which simply has one top
level array item per `cgltf_texture`.
The memory footprint is smaller because we no longer bother to store
`TextureSampler` objects, instead we simply defer their construction
until calling setParameter.
Last but not least, we now assert in debug builds if the usages of a
particular texture have inconsistent sRGB flags. In the past,
inconsistent sRGB would be silently ignored.
In other words, we will now assert if you try to use the same texture
for `baseColor` and `normalMap`, whereas in the past we would simply
exhibit non-deterministic behavior in this situation (with respect to
sRGB semantics).
gltfio can now ask the material provider plugin which `Material` would
be used for a given set of requirements. Prior to this change, gltfio
could only create a new `MaterialInstance`.
This method is necessary to support an upcoming gltfio feature.
This broke asyncGetLoadProgress() and caused WebGL to crash reliably
because ResourceLoader got destroyed too soon.
Bug was introduced with de7dfc2ea6.
I intend to cherry pick this to rc/1.27.0, which is where it was
introduced, so there's no need to update the release notes.
This broke asyncGetLoadProgress() and caused WebGL to crash reliably
because ResourceLoader got destroyed too soon.
Bug was introduced with de7dfc2ea6.
I intend to cherry pick this to rc/1.27.0, which is where it was
introduced, so there's no need to update the release notes.
* check that user materials don't exceed their allowed features
* backend sampler limits now take feature level into account
- in the backend, the constants are now in an array indexed by the
feature level
- samplerBindingMap now asserts only what it can.
- matc (filamat) now logs the user samplers when an error is detected.
* Add JNI for TransformManager.getChildCount(), TransformManager.getChildren() and scene.hasEntity()
* Update RELEASE_NOTES.md
* Fixes
* Change getChildren to take a nullable array
* Remove no params TransformManager.getChildren()
* Update RELEASE_NOTES.md
Co-authored-by: Ben Doherty <benjdoherty15@gmail.com>
Co-authored-by: Ben Doherty <bendoherty@google.com>
One of the bloom texture ended-up dangling in the material's
SamplerGroup. That sampler group was never used to draw with, but was
made active which caused problem with the backends.
Also make sure the public API can unset a texture in a MaterialInstance
by passing nullptr for the texture.
For each "cgltf_material", we now create one "MaterialInstance", even
if a given asset has multiple instances. In the future, we might make
this behavior configurable to make better use of Filament's
auto-instancing feature.
This change is a feature request from Google, but also this behavior is
more consistent with the code comments.
Also some related cleanup:
(1) Use FixedCapacityVector instead of robin_map.
(2) Move the cache to move out of the asset and into the loader,
because it is only used at load time.
in a few places filamat loses the value of targetApi and targetLanguage
and attempt to guess it from other values, this lead to inconsistencies.
we now keep both targetApi and targetLanguage and use them appropriately.
in particular we don't use the optimization level to "guess" what
targetLangage we're on.
In the end this resolve a prior unit test failure and allows us to not
have to use "spirv" rules when generating only GLSL.
We use TargetLanguage::SPIRV instead of GLSL which affects how the
source GLSL is generated, in particular which version is used.
This change is not a problem for these unit tests, but is probably
exposing another problem -- we will address that separately.
We were keeping the list if uniform names in Material and passing
pointers to the backend. Unfortunately, HwProgram can outlive
Material because it is legal to destroy a Material once it's not
needed on the client side. e.g. just after rendering something.
This was happening with the IBLPrefilter code, but probably elsewhere
too.
We now just store CStrings in HwProgram.
The immutable inverse bind matrices can be shared among instances, so
they are now stored in Asset, not in Instance.
Also, there are now two "load" phases for skinning data:
(1) storing the inverse bind matrices
(2) building the Entity mappings (for animation efficiency)
Phase 1 is done in `ResourceLoader` because inverse bind matrices can
live in an external bin file.
Phase 2 is done during Instance creation, because that's when entities
are created.
Prior to this change, `recomputeBoundingBoxes` was an opt-in config
parameter in ResourceLoader. It is now a method on FilamentInstance.
The old API did not work for dynamically created instances. Since this
is a relatively obscure feature, we considered removing it completely,
especially since the computation requires the presence of CPU-side
vertex data combined with the transform hierarchy.
Instead of removing the feature, we decided to move it to a better
place. This paves the way for some upcoming improvements, which include
reducing the memory footprint for assets. It also improves overall code
organization and separation of concerns.
* Fix warning C4146: unary minus operator applied to unsigned type, result still unsigned
* Fix warning C4068: unknown pragma 'nounroll'
* Fix warning C4068: unknown pragma 'unroll'
* Fix warning C4068: unknown pragma 'clang'
* Fix warning C4305: 'initializing': truncation from 'double' to 'float'
* Fix warning C4267: 'argument': conversion from 'size_t' to 'utils::FixedCapacityVector<filament::uberz::WritableArchive::Material,std::allocator<T>,true>::size_type', possible loss of data
* Fix warning C4267: 'argument': conversion from 'size_t' to 'uint32_t', possible loss of data
* Fix warning C4244: 'initializing': conversion from 'A' to 'T', possible loss of data
* Fix warning C4334: '<<': result of 32-bit shift implicitly converted to 64 bits (was 64-bit shift intended?)
* Fix warning C4293: '>>': shift count negative or too big, undefined behavior
* Fix diagnostic warning C4189: 'channels': local variable is initialized but not referenced
* Use [[maybe_unused]] where possible and revert aa79bd6fa8.
* Revert unary minus for non-MSVC compilers
* Add macro for enabling warnings temporarily
* Get rid of UTILS_HAS_CXX17
* Revisit warning related macros
Co-authored-by: Levente Koncz <levente.koncz@shapr3d.com>
this case could cause an assert in debug builds. There was a few bugs:
- when computing the intersection between a box and a frustum, a special
case test had a typo which would cause extra work in some case. Also,
we were not detecting correctly when there was no intersection at all.
This could result in some intersection point being found.
- Finally, we reject the intersection volume when it has only 3 vertices
because that's not a volume.
Fixes#5933
The main goal of this change is to have "ugly" code only in filamat.
In particular, the sampler binding information is now recorded
into the material file and used on the filament side to inform the
backend.
This means that on the filament side we only have generic code with
all the "uglyness" in filamat. In particular SamplerBindingMap and
SibGenerator now only exist in filamat.
Files of greater interest:
Material.cpp, MaterialBuilder.cpp
This is a workaround for the following Chrome issues:
https://crbug.com/1348017 Compiling GLSL is very slow with struct arrays
https://crbug.com/1348363 Lighting looks wrong with D3D11 but not OpenGL
This requires a rebuild of materials for WebGL users.
Fixes#5859.
partially revert a recent change where Program needs a DriverApi in its
ctor. This was a misguided change. Backend API never take a DriverApi
as parameter.
Checking the feature level, for instance, should happen as a
precondition, or in the backend as postcondition.
GLES3.0 (and GL4.1) need informations about the uniform block bindings
because they don't allow to do that setup in the shaders. So we store
that information in the material blob and retrieve it on the filament
side in Material. This information is passed to Program so it can
create the bindings.
Prior to this change, this information was set by Material itself, but
this ment we had two places where these bindings were hardcoded.
The bulk of the change is to add a new material chunk which stores an
array of {name, binding}, retrieve it on the Material side and pass it
to Program.
- remove unused SamplerBindingMap parameter
In fact, the SamplerBindingMap is used, but it is passed inside the
MaterialInfo structure, so it doesn't need to be passed as parameter.
- Don't create unneeded SamplerBindingMap temporaries
This change was motivated by some internal work at Google and has the
benefit of simplifying the gltfio API and implementation. There are 2
major API changes:
(1) Consolidate separate loader entry points for GLB and GLTF.
The distinction between GLB and GLTF can be made from the file content
alone, because GLB has a 4-byte magic string in its header. There is no
need for separate entry points. Clients do not (and should not) need
to check the file name extension.
(2) Remove the distinction between "instanced" and "non-instanced"
glTF assets.
In the new scheme, all assets have at least 1 instance.
Broadly speaking, in gltfio an "asset" is a collection of Filament
objects like textures and vertex buffers, while an "instance" is a
collection of entities and components (e.g. the transform hierarchy).
This API change makes life easier for clients because they no longer
need to decide a priori if they will ever need to add instances.
This change also moves some public-facing methods from FilamentAsset to
FilamentInstance:
- getSkinCount, getSkinNameAt
- getJointCountAt, getJointsAt
- attachSkin, detachSkin
* Begin Sorting SubProjects into Folders
* Add more subprojects to folders
* Add even more subprojects to folders
* Add further subprojects to folders
* Move the last two projects
* Move Resources to a Resources subfolder
* Remove spaces to be stylistically coherent
* Revert Improper CMake Modifications
* Revert erroneous line removals
* Only specify sdl2's folder on WIN32
* Add the shader subprojects to a Generated folder
* Move shaders to Filament/Shaders
* new feature level API for backends
backend can now return a "feature level", each level corresponds to a
"bundle" of features.
Level1: ES3.0 capabilities
Level2: ES3.1 capabilities + 31 textures + cubemap arrays
Currently metal always returns level 1, GL and Vulkan return level 2
if 31 textures or more are supported.
* Add public APIs for feature levels
* Add infrastructure to check feature levels in materials
* validate material feature level on use
The validation is done when creating a renderable. If the engine doesn't
support the material's feature level, an exception is thrown (or assert
if exceptions are not enabled).
* material documentation
* activate ESSL 3.10 for feature level 2
also generate #defines to identify available feature levels
* support for cubemap arrays in the public API
if feature level 2 is supported, cubemap arrays can be used from the
public API.
* add release notes
With VERTEX_DOMAIN_DEVICE the vertex shader doesn't apply the
projection (since the vertices are already in clip space), however,
both TAA and guard bands need to jitter/offset the clip space, and
it is done at the projection level.
We now store the clip space offset separately so that it can be applied
to VERTEX_DOMAIN_DEVICE vertices.
We also introduce a new material parameter, vertexDomainDeviceJittered,
a boolean that controls whether clip space offset (above) is applied.
This is because a VERTEX_DOMAIN_DEVICE material that uses the built-in
projection matrices generally ends-up with the jitter already applied,
this is the case with the Skybox for instance.
Fixes#5917
Fixed a comment that said "We store 64 bytes per bone.". The actual
number is 32.
Developers who know their users have powerful devices may wish to exceed
ES3.0 minspec constraints to allow more bones and / or morph targets.
Fixes#5785.
The custom release callback that I provided was in the wrong place; it
was only being used for a path string, not the actual buffer content.
The cgltf API is a bit awkward in this area.
No need to update RELEASE_NOTES because this will be cherry picked to
the RC branch, which is where the bug introduced.
Fixes#5918.
Filament does not yet fully support threads with WASM, but this is a
baby step in that direction.
To enable experimental pthreads support, enable the WEBGL_PTHREADS CMake
option. This will enable pthreads support in `gltfio` and `utils`, which
is known to work, but not when served with GitHub Pages.
The web server must emit COOP, COEP and CORP headers, so our build
instructions now recommend the use of `emrun` for local testing.
This also changes our demos so that they do not use unpkg, which
does not work when using `emrun`, due to cross-origin restrictions.
Filament does not yet fully support threads with WASM, but this is a
baby step in that direction.
To enable experimental pthreads support, enable the WEBGL_PTHREADS CMake
option. This will enable pthreads support in `gltfio` and `utils`, which
is known to work, but not when served with GitHub Pages.
The web server must emit COOP, COEP and CORP headers, so our build
instructions now recommend the use of `emrun` for local testing.
This also changes our demos so that they do not use unpkg, which
does not work when using `emrun`, due to cross-origin restrictions.
This feature can improve load time when textures are downloaded from the
web on non-filesystem platforms like Android.
More specifically, this allows downloaded texture assets to arrive after
the user calls asyncBeginLoad(), which means that decoding and
downloading can occur concurrently.
Prior to this PR, we already used JobSystem for decoding, but we did not
kick off any jobs until after all assets were downloaded.
Still TBD: add this feature for external vertex data.
Partial fix for #5909.
Earlier versions of cgltf did not support file reader customization.
This was fixed back in Dec 2019 but at the time I did not notice, so
we never bothered cleaning up our usage.
In the future we would like WebGL + Android builds to permit texture
downloads to occur concurrently with the texture decoder jobs. This PR
is basically a preparatory refactoring, but with the nice side effect of
removing a memcpy.
it was a duplicate state from the true gl state which could easily cause
problems. It only existed to optimize state updates when nothing changed
but we already have fine-grained tests for this.
It was culled by the frame-graph because it didn't have "read" from
any of its resource, only writes. However, it does set uniforms, so need
to be called.
fix#5874
StructureOfArray always aligned each array to the same alignment as
malloc (usually 8 bytes), but that was not enough if one of its type
has stricter alignment requirements.
StructureOfArray now always honors at least the alignment requirement
of each array.
Also removed dependency on EntityInstance.h
Fixes#5727
We used to have a mix of fatal and non-fatal assertions for precondtions
errors. From now on, we always throw if exceptions are enabled or
crash with a log otherwise.
In most places this is simply replaced by `std::string_view`.
We also change a few internal/private headers so they accept
`std::string_view` instead of `utils::CString`.
Internally we use std::string_view and the public API is augmented
with APIs that take a length for strings, which makes them useable
with string_view parameters.
Also fix exception specification for all setParameter methods, which
can throw if exceptions are enabled (or exit the program otherwise).
When FTransformManager computes accurate world transforms, it adds downcasted leftover to translation part to restore precision.
However, both transltation and leftover are given as float3 - simply adding them resut float3, so addling leftover become meaningless.
one or both should be upcasted first.
I have disabled building SDL with headless EGL, because
SDL_config_minimal.h doesn't work with EGL, and I don't know how to
implement a an SDL config that would work with EGL.
I have verified that this works in a separate project, and that it
compiles in this project.
```
$ ./build.sh -e release
$ find ./out/ -name "*EGL*"
./out/cmake-release/filament/backend/CMakeFiles/backend.dir/src/opengl/platforms/PlatformEGL.cpp.o
./out/cmake-release/filament/backend/CMakeFiles/backend.dir/src/opengl/platforms/PlatformEGLHeadless.cpp.o
./out/cmake-release/libs/bluegl/CMakeFiles/bluegl.dir/src/BlueGLLinuxEGL.cpp.o
```
I have disabled building SDL with headless EGL, because
SDL_config_minimal.h doesn't work with EGL, and I don't know how to
implement a an SDL config that would work with EGL.
I have verified that this works in a separate project, and that it
compiles in this project.
```
$ ./build.sh -e release
$ find ./out/ -name "*EGL*"
./out/cmake-release/filament/backend/CMakeFiles/backend.dir/src/opengl/platforms/PlatformEGL.cpp.o
./out/cmake-release/filament/backend/CMakeFiles/backend.dir/src/opengl/platforms/PlatformEGLHeadless.cpp.o
./out/cmake-release/libs/bluegl/CMakeFiles/bluegl.dir/src/BlueGLLinuxEGL.cpp.o
```
GL_ES_30 becomes MOBILE
GL_CORE_41 becomes DESKTOP
ShaderModel controls which flavor of GLSL (GL or ES) is used both when
reading and outputting materials.
It's also used to set default quality settings and the default precision
of all fragment shaders.
Technically, Vulkan and Metal don't need this distinction, but the GL
backend does.
this is more in line with other APIs of the backend. This change is
complete for the GL backend, but for the metal/vulkan backend we still
use a SamplerGroup as the internal data structure, which is just
temporary.
Eventually, SamplerGroup should becomes a "filament" only API (not
a backend API).
SamplerGroup itself is now a more "traditional" class where copy and
move ctor do what you'd expect. This actually removes a few copy of
the internal data in some cases and uses less memory, at the cost of
doing some heap allocations, but they should be rare and outside of
the main loop.
we mow do most of the work of validating the sampler parameters and
resolving to an actual GL sampler, when updating a SamplerGroup,
instead of doing this each time a program is made active.
A lot of cpu work is saved when the same samplergroup is reused with
multiple programs.
this is the start at making HwSamplerGroup more "real". It shouldn't
keep a reference to the filament::SamplerGroup, which is just an object
to pass the data.
for now, we move the SamplerGroup reference into the concrete classes to
keep the same implementation. But now it becomes an "implementation
detail" of the respective backends.
- remove the 2 argument version of setSampler
- use a bool instead of bitfield for the dirty state
- try to avoid setting dirty bit if setting same sampler
Starting with 3.1.14, embind started to support for `noexcept`
which caused multiple definition errors since we have a workaround
in place that alreadys supplies template instantiations for `noexcept`.
This change should not affect G3 since our JS bindings are not used
in G3.
The upstream fix is here:
https://github.com/emscripten-core/emscripten/pull/17140Fixes#5789.
This is not intended to be used yet because we're not currently
checking that cubemap array are actually supported, however, if they
are, they should work.
the depth of the texture wasn't taken into account. In practice this
would restrict the number of mip levels of a 3d texture that would have
a larger dimension in depth.
The main goal is to allow more flexibility, allow cubemap arrays in
the future and better match vk and metal apis.
Main changes:
- remove updateCubeImage
- remove update2DImage
- update3DImage is now the only texture upload backend API
cubemaps are now treated just like a 2D array of 6 layers.
For this reason, Texture::setImage(..., FaceOFfsets) is deprecated.
Additionally, the 2D versions of Texture::setImage() become inline
helpers.
A side effect of this change is that it is now possible to update only
a single face of a cubemap, but also a region of a face (or faces).
This PR changes how Metal handles buffer updates. Previously, Metal allocated a full new buffer each time an `updateBufferObject` command was issued; however, it did not copy the previous contents of the buffer over to the new buffer, so partial updates did not work correctly.
Now, Metal allocates a single, private GPU buffer and employs temporary staging buffers whose contents get blitted to the private buffer at each update.
There's still some room for optimizations, and I need to give more thought to how I want to implement `updateBufferObjectUnsynchronized`.
- move all froxel configuration constants out of Engine.h, unlike
the previous todo/comment, these shouldn't be part of Engine::Config.
- same for irradiance map
For some android gpu drivers, some uniform arrays should be initialized to be used in the shader, even if not used.
Co-authored-by: Mathias Agopian <mathias@google.com>
This code adds a config object, "ConfigParams," to Engine creation parameters for setting memory buffer sizes for command buffers and driver handle arena sizes. It will use #define values (FILAMENT_PER_FRAME_COMMANDS_SIZE_IN_MB, etc.) as defaults (and as minimum acceptable values) if the user does not provide values. It attempts to validate the values given to prevent the user from creating a unusable state.
BlobDictionary and LineDictionary were storing blobs as map keys to
achieve simple compression, but they also stored duplicates of
in a vector for index-based lookup.
Now, the vector is storage and the map has keys that are string_view.
- getNear() and getCullingFar() now return doubles
- updated documentation
- all setProjection() calls can now throw (when enabled) and will
do so if preconditions are not met (instead of setting a default
projection).
- Frustum can now be logged on debug builds
This patch enables user scissor in Metal backend; There was no implementation for it.
While the absence of the feature in Metal does not incur serious problem, many rendering glitches were found in apps using ImGui due to it.
Co-authored-by: Benjamin Doherty <bendoherty@google.com>
auto-instancing can have some overhead, so when it is known that the
scene doesn't have identical primitives, it is better to disable it.
(disabled by default).
Also add some missing bindings for `enableAccurateTranslations`.
Reflects a change from Betty and should be cherry picked to v1.23.3
Users could customize the ImGuiHelper camera, but they had no control
over the scissor coordinates. This allows them to use vertically flipped
coordinates, which, unfortunately, is required for MediaPipe
integration.
Reflects a change from Betty and should be cherry picked to v1.23.3
Users could customize the ImGuiHelper camera, but they had no control
over the scissor coordinates. This allows them to use vertically flipped
coordinates, which, unfortunately, is required for MediaPipe
integration.
This was too tricky, it highlights that we definitely need refactor this
to share code with the flattener / unflattener pipeline. I'll look at
that next.
a 64 bytes pool seems to work with both clang and msvc, unfortunately,
c++ doesn't let us know the allocator object size at compile time
for map containers, so we have to guess.
* BlueVKDarwin: Simplify the build and loading process.
Some of our CMake logic was not necessary because we do not staticly
link against anything for Vulkan. All entry points are dynamically
loaded.
Some of the load-time code was also needlessly complicated. In fact the
ICD environment variable that we were setting is now deprecated.
I tested this PR with:
- macOS + June LunarG SDK
- Android on a Pixel 6
* Fix up, further simplification.
This lets us avoid the following validation error.
Attempting to create a VkDevice from a VkPhysicalDevice which is
from a portability driver without the
VK_INSTANCE_CREATE_ENUMERATE_PORTABILITY_BIT_KHR bit in the
VkInstanceCreateInfo flags being set...
This will allow us to fix the validation error related to
VK_KHR_portability_enumeration.
Also, macOS comes with Python 3 nowadays so we're upgrading the script
from Python 2.
Unsynchronized update just means that the buffer is updated regardless
if what the gpu is doing, the synchronization is the responsibility of
the caller.
Also added resetBufferObject(), which essentially destroys and reallocate
a buffer for the same handle.
- rename PerRenderableUibBones to PerRenderableBonesUib to be more
consistant with other interface block naming.
- make sure the C++ struct and the UBO definition match.
PerRenderableBonesUib is a UBO with one bones[256] field, but the
C++ struct has a single bone and treated the UBO as an array.
This makes things less confusing.
We can now use sizeof(PerRenderableBonesUib) in many places which
better expresse what we are doing.
- Fix an off-by-one assert when setting a skinning buffer to a renderable
- Asserts that no more than 256 bones are associated to a renderable
- improve documentation and fix some typos
We no longer use the hardcoded objectUniform UBO name, instead, we
access the object uniforms through the new getObjectUniforms().
Because it's not possible to return a "Uniform Block" from a function
in GLSL, a large part of this change, is to replace the interface block
by a structure.
Note: getObjectUniforms() is not public, but it is used by gltfio to
access the userData field, which is also not public at the moment.
DEPTH commands are now sorted just like COLOR commands, that is,
they use a 10 bits z-bucket and the material id in the sorting key.
This allows instance-able primitives to be sorted next to each other.
We still use resgen for convience, but the archive is now passed in
from the client application.
This will allow us to shrink the gltfio Android library (stay tuned).
This boolean parameter is used with materials that need to access
`getInstanceIndex()` (filament's equivalent to `gl_InstanceIndex`).
It is false by default, and getInstanceIndex() is not accessible.
This is intended to be used in concert with
`RenderableManager::Builder::instances()`.
a 64 bytes pool seems to work with both clang and msvc, unfortunately,
c++ doesn't let us know the allocator object size at compile time
for map containers, so we have to guess.
An ubershader archive is a bundle of filamat packages with some metadata
that conveys which glTF features each material supports.
This PR does three things:
1. Adds a new command line tool called `uberz` that consumes a list
of filamat files and metadata text files and produces a single
ubershader archive.
2. Adds a new library (also called `uberz`) that is used by `gltfio`
to read ubershader archives, and used by the above command line
tool to write ubershader archives.
3. Enhances `UbershaderLoader` so that it no longers uses a hardcoded
set of materials, and instead takes an ubershader archive.
Ubershader archives have a simple binary layout that can be memcpy'd
directly into a C struct. The metadata is specified using a text file
with key-value pairs. These two file formats have formal desriptions in
the README in `libs/uberz`.
In a subsequent PR, we will remove the `gltfio_resources` target and
change the signature of `createUbershaderLoader` so that it takes
an archive.
We were re-building various C++ files in three different targets
(basis_encoder, basis_transcoder, basisu executable), it's probably
better just to set up proper dependencies between the libraries. Note
that I'm not sure if this actually improves build times.
More importantly, this creates a CMake target for the zstd library
because we want to use zstd in other places.
blendOrder was used to control the draw order of blended render
primitive within a Renderable. We now have an option to make the
blend order global, in this case those primitives with a global blend
order are always sorted solely using the blend order value (i.e. the
distance from the camera is not take into account).
This change includes a fix for an issue we filed against spirv-tools:
https://github.com/KhronosGroup/SPIRV-Tools/issues/4371
So, it should reduce the number of extraneous matrix copies in finalized
GLSL code.
I did quick size total of all filamat files (*) before and after this
update, it went from 11.3 MB to 11.1 MB.
(*) All backends are enabled, includes built-in Filament shaders and
gltfio ubershaders.
* Add JS bindings for Texture class methods
This change introduces bindings for the following methods:
- getWidth
- getHeight
- getDepth
- getLevels
Closes 4492
* Mark level arguments as optional
* Revert docs defs
* Revert docs/webgl/filament.js
if we have more than 16K of UBO data, we now use a "out of band" buffer
on the heap instead of the command stream, which has limited space.
to minimize the heap allocation we use a simple pool allocator that
recycles a few heap buffers (per Scene).
This optimizes and cleans up some code from a 3P contributor.
When computing a bounding box, there was no need for an inner loop
through the entire skins array.
Tested using the torus model in #4973 and the `-r` flag in gltf_viewer.
I think the most important thing here is that we now let users know that
"offset" is not a byte count. This also fixes some small typos, e.g.
"weights" was used in the docstring instead of "positions".
To avoid making API changes, this does not fix a few weird things I
noticed in the Java API. For example, there is a redundant "count"
argument in methods that take an array. Also some methods do not
provide an "offset" argument, which is not consistent with C++.
Our `morphNormal` GLSL function treats each normal target as a
displacement from the base normal (similar to the glTF spec) but the
normal that is extracted from the tangent frame is actually an absolute
normal.
In other words, if b is the base normal, we were doing:
b = b + w0 * n0 + w1 * n1 + ...
This is obviously wrong, since the base normal has an overpowering
influence.
The fixed math looks like this:
b = b + w0 * (n0 - b) + w1 * (n1 - b) + ...
Fixes#5584.
By design we shouldn't access the scene SOA when executing the
high level commands.
This change increases the size of a command to 64 bytes and
PrimitiveInfo to 48 bytes (both with some small padding left).
This removes usage of regexps from the parsing phase and splits the
program into three sub-packages: parser, database, and emitters.
The parser now generates an AST according to the formal grammar
described in the README:
https://github.com/google/filament/blob/pr/beamsplitter_rewrite2/tools/beamsplitter/README.md#grammar
This allows for nice readable error messages. More importantly, it
permits the C++ syntax to be less restrictive and paves the way for
possible expansion of the tool beyond `Options.h`.
I looked at the C++ AST generated by clang but it is huge and unwieldy.
For our purposes this simplified AST is much easier to work with.
The new lexer is inspired by the following Rob Pike talk.
- https://www.youtube.com/watch?v=HxaD_trXwRE
Beamsplitter does not use the state machine described in the above
prezo, but it does use a Go channel for separating the parser from the
lexer. In our case, the lexer is actually a recursive descent parser
with simple lookahead functionality. This made it easy for the "real"
parser to create an ergonomic coarse-grained AST.
This is a big change but it is a no-op in terms of the generated code.
* gltfio: Clear texture caches before loading resources
* iOS gltf-viewer: add double-tap to reload model for debugging
* iOS samples: add instructions on ASan / UBSan debugging
- Ensure C++17 is used to compile sample projects
- Upgrade to the latest Xcodegen and re-generate projects
- Add a bundle ID disambiguator so users don't need create unique bundle Ids when opening sample projects
- Add a simple generate-samples.sh script
The API is the same but there are some minor differences, which include:
- Ordering of fields in AmbientOcclusionOptions
- More @NonNull annotations that we forgot
- Javadoc formatting is different
This is a temporary workaround for a memory corruption issue observed on
some devices from a specific vendor. We will try to make this workaround
more targeted in a subequent change.
Partial revert for b2cdf9f2b4.
There were two places where we were doing unaligned reads: one when
computing the hash for the material identifier, and one when parsing
the chunk in ShaderReplacer.
We also had a potential overflow since civetweb does not add a trailing
null to incoming WebSockets messages.
This moves parser into a subpackage to shield it from the various
emitters (this folder structure is similar to what Rob Pike used for his
text templating library). This also adds a WIP Java code generator,
currently disabled.
We now have 3 public APIS:
- opaqueBlit() which is used for basic blitting and scaling and
supports sub-resources.
- blit() which is used for blitting + composition
- can optionally perform basic scaling
- doesn't support sub-resources
- upscale() which is used for high quality upscaling
- can do composition (blending)
- doesn't support sub-resources
This is a temporary workaround for a memory corruption issue observed on
some devices from a specific vendor. We will try to make this workaround
more targeted in a subequent change.
Partial revert for b2cdf9f2b4.
The most important change here is that we no longer apply the
backend (e.g. Metal/Vulkan) UV transformation before calling the
user's vertex shader. This is an API change for post-process materials
(but they're not public).
Now the user is responsible for using uvToRenderTargetUV() in their
shaders (either in the fragment or vertex as appropriate).
This makes it easier to handle offsets/transforms with all APIs.
Conceptually, the only thing that is needed is to call
uvToRenderTargetUV() just before making a texture call.
This fixes a couple of issues:
- some image shifting in metal/vk
- flare in metal/vk was upside down
We also simplify the DoF code quite a bit now that we can rely on the
rendertargets begin multiple of 16.
We also "fix" SSAO that was working by accident on metal/vk. The UV
correction was applied 3 times 2 of which were canceling each other.
This adds a code generator, implemented in Go.
This PR also prepares `Options.h` (the ground truth) by simplifying its
syntax just a bit. The ground truth file must have very simple C++
syntax, which is described in the README:
https://github.com/google/filament/blob/pr/codegen2/tools/codegen-options/README.md
This process revealed a small bug: `Filter.MEDIAN` was bound to the
incorrect value in Java.
The generated code is not yet used, stay tuned.
* Add multi-scene support to gltf_viewer.
To test this, I generated a multi-scene asset as follows.
```
gltf-transform merge Avocado/glTF/Avocado.gltf \
BarramundiFish/glTF/BarramundiFish.gltf \
~/Desktop/Merged.gltf
```
* Specify c++17 in pbxproj files.
When the guard band is enabled, the effective rendering area is
increased by a certain amount (currently 16 pixels on each side) so
that screen-space effects (e.g. SSAO, SSR, DoF) behave better around
the edges of the screen. Of course, this comes at a performance and
memory cost.
Currently the guard band is not configurable other than being optional.
Added c++, java and js bindings.
This also removes clipping of the blit rectangle that occurred in the VK
backend that is no longer necessary. There's also no need to assert
since validation will catch out-of-bounds blitting.
Reverts the clipping in acdb8addfd.
Also deprecate some fields of DisplayInfo this shouldn't be a problem
because they were not actually used.
This change should allow an external-to-filament code to manage
frame pacing (e.g. something like swappy).
- For completion, FilamentAsset now has getRenderableEntities(). This is
similar to sister methods getLightEntities() and getCameraEntities()
except there is no need to store a separate array.
- The web helmet demo does not need to enable shadows, they are already
enabled.
- The ViewerGui populateAsset() method was doing two things that are
now decoupled for clarity: setAsset() and populateAsset().
- The updateRootTransform() method is now called only when the autoscale
checkbox is toggled, instead of every frame.
- The getFooEntities() methods in Java now skip doing work for empty
lists. Actually these should not return arrays at all, but let's fix
that later, since it will break backwards compatibility.
We can't call prepareProgram() from any thread, since it is calling
into the backend. When we had more than a certain number of commands,
we would use the jobsystem to generate them and so prepareProgram()
could end up being called from a jobsystem thread.
This is fixed by looping through all the commands once they're generated
and calling prepareProgram() then.
The main changes are:
- ColorPass() and RefractionPass() are now static and moved into a
new RendererUtils file. These methods don't need FRenderer and are
more like a big "script".
- Cleaned-up includes
- Reformatted/reordered methods
The SimpleViewer C++ class was not viewer component like `ModelViewer`
and `<filament-viewer>`. It was actually just the UI builder used
in the `gltf_viewer` desktop app and the remote Android interface.
This adds a new implementation of the TextureProvider interface called
Ktx2Provider.
Tested using the KTX2 variant of the StainedGlassLamp model in the
Khronos samples repo.
Tested on WebGL 2.0 (Chrome v100), Android (Pixel 6 Pro), and Desktop
(Metal, OpenGL, and Vulkan via MoltenVK).
A "safe" mip-level is one that has exactly half the dimensions of
the current level. In other words, we guarantee that we can halve the
dimensions 4 times without loss (i.e. odd dimension).
This is achieved by effectively padding the viewport (i.e. making the
viewport's dimensions multiple of 16). The post-processing passes
eventually take care of cropping the extra padding so the final
image is unchanged.
This is a more generic solution to dynamic resolution padding, helps
with memory allocations and helps all the algorithms that depend on
mipmaping (e.g. DoF, SSAO, Bloom).
One important improvement brought by this change is that all "final"
post-processing effects are now able to handle a sub-region of the
source, including: color-gradding, fxaa and upscaling.
It was assumed that ETC2 is supported on all ES3 devices, but WebGL on
desktop machines does not support ETC2.
Note that WebGL has its own special extension strings for compressed
textures.
Some uniforms are needed during shadow map generation, other
during shadow sampling (color pass). We didn't have a clear separation
between them and ended up setting the UBOs that were needed only for
sampling multiple times during generation.
- rename common_math and common_shadowing from .fs to .glsl
because they were both included in both vertex and fragment
shaders
- add getFragCoord() which always returns coordinates in the
glsl convention. This is useful when used with RNGs to get
consistant results accross backends.
this is because this uniform is not well defined -- it's unclear if
it is set to the viewport or the buffer size.
also, it's not needed, and removes a couple multiplies from the shader.
- add getUserViewMatrix() on CameraInfo, the "user" view matrix is the
view matrix before we apply the world origin transform, it is needed in
a few places, so we make it a method so that in the future we could
precompute it if we wanted to.
- remove worldOffset which is just the last column of worldOrigin
it made it actually more confusing to have two version of the uv
(normalized and not). Also the unnormalized version was computed from
frameUniforms which is not great in the case of post-processing
(it just happened to work).
This allows clients to provide their own asynchronous texture decoders
for various mime-typed images. This is a plug-in component for gltfio,
in some ways similar to MaterialProvider.
There are two motivations for this: to decouple gltfio from STB and
to make it easier to integrate support for BasisU textures.
This also has the side effect of simplifying ResourceLoader, since the
texture decoding jobs have been moved out.
As part of this work, I made the "stb" CMake target into a traditional
static library. Previously we had several files called `Image.cpp`
whose sole purpose was to enable STB_IMAGE_IMPLEMENTATION.
If there is an error during the driver initialization, Engine::create()
returns nullptr, but the FEngine was allocated and would then never
be destroyed.
mTerminated was useless because by construction it would always have
the expected value.
This version is used only on qualcomm devices. It's now forbidden to
create a program inside a renderpass. Unfortunately there was still
one codepath doing so.
this state only exists during Renderer::render(), having it outside
of view is more flexible as it give us an opportunity to adjust
camera parameter globally before drawing.
Also greatly reduced the size of RenderPass (which is a Value object).
mipgen can now emit basis-encoded KTX2 files. Both the desktop and
web "suzanne" samples use this as a test for compressed textures.
This PR does not add KTX2 support to glTF, but it's on the way.
`BasisEncoder` has a builder style API that calls the basis encoder to
create KTX2 files. This hides some low-level BasisU features that we are
not using, like file I/O and mipmap generation.
`Ktx2Reader` is an easy-to-use API for creating Filament textures from
KTX2 files. Its API primarily consists of these two methods:
bool requestFormat(Texture::InternalFormat format);
Filament::Texture* load(const uint8_t* data, size_t size);
The first method is used to build an ordered list of formats that are
supported by your hardware. The second method consumes the contents of a
basis-encoded KTX2 file and attempts to produce a Filament texture with
a preferred format.
IMPORTANT: Our tools still let you use KTX1 for non-compressed images
because it is useful for HDR, but you can no longer use KTX1 for
block-compressed data.
Partial fix for #4771.
This is only a good place for a flush *if* we're going to draw another
view (so the GPU can start working). Otherwise, it can be costly
on some drivers and unnecessary since swapbuffers will do the same.
The original article we used for our bloom (siggraph'14) called for
a radius parameter for the upsample stage. We're always using 1.0 right
now, but it is useful to keep this possibility for experimentations.
a bug was introduced in 8/2020 where the downsampling filter was wrong,
due to a mistake using textureLodOffset, which obviously uses offsets
in source texel -- we were assuming destination.
Path resolution was broken with #5285, which only worked when the glTF
happened to be at root level. This new fix has been tested against:
- My Sponza zip file that hass all files in a "sponza" folder.
- My Bistro zip file, which has resources in a child folder relative to
the gltf file
- A self-created flat zip using IridescentDishWithOlives, with
everything at root level.
Side note: Bistro still fails on a Pixel 6 Pro Mali but for an unrelated
reason: (null deref in backend::TimerQueryNative::queryResultAvailable)
- don't use __PRETTY_FUNCTION__ and try to parse it, __func__ is
standardized and in most case returns what we want (the function name).
- add native support for string_view in our ostream.
- uninline string support from ostream
When creating a KTX file (e.g. with mipgen), you can of course choose
whether or not you want to use an sRGB format.
At load time, your app has an expectation about whether a particular
texture has an sRGB format. e.g. the glTF convention is that albedo
textures should be sRGB, while roughness textures are linear.
Before this commit, our KTX loader would look at the app's expectation,
then silently re-interpret the bits in the glTF texture in order to
match this expectation. This seems very wrong.
Instead, if the expectated format does not match the format in the KTX
file, we now print a warning.
Fixes#2422, which will also be obsoleted by our upcoming KTX2 support.
The `g_linearized` variable was being used for two purposes: to denote
the linearity of the source format AND the linearity of the destination
format. This was confusing and is now split is `sourceIsLinear` and
`destIsLinear`.
This change has no effect on the the look of the suzanne demo.
We do not support these formats and they add bloat to the basis tables.
In a release x86 build, this reduces the transcoder size from 774 KiB to
475 KiB.
Allocation and destruction of handles generates a fair amount of code
because they are synchronized and the spinlock is inlined.
So we fix this by generating the 3 (de)allocation methods we really
need, we only need 3 because we're using 3 pools. These are now
out-of-line, which reduces size and reduces pressure on the i-cache.
Performance is not affected much because in the end it's just a
static branch (and in most case the return is elided).
The main change here is that instead of allocating a Dispatcher on the
heap and storing a pointer to it in the CommandStream, we now have
a Dispatcher directly inside the CommandStream.
This avoids a heap allocation and a dereference when executing a command.
Changes:
- Remove the strange header-only variant of libs/image
- Rename KtxBundle => Ktx1Bundle
- Move image/KtxUtility => ktxreader/Ktx1Reader
- Add unit test for Ktx1Reader and test stub for KTX2.
Notes:
- Ktx1Bundle does not depend on Filament and is used by cmgen
and mipgen to generate KTX files.
- Ktx1Reader has a dependency on Filament and should therefore live in
a separate library, which it now does.
The `demo_*` web samples were using unpkg to refer to the Filament build
rather than using the local copy, which was inconsistent with the other
web samples.
We now use the local copy of Filament for everything except the
drag-and-drop viewer, which always uses the latest version of Filament.
With this change we are now generating refraction and reflections
buffer into their own layer of a 2D array -- so they can coexist.
This change doesn't actually enable both at the same time yet.
There are downsides to this approach:
- a 2d array of 2 layers is created even if only one of reflection or
refraction is active. This could be fixed at the cost of more
complexity.
- if reflections are active then refraction must use a RGBA16F texture
instead of RGB_11_11_10, because they share the texture
unlike for refraction, the reflection buffer is distinct from "the"
color buffer, this allows an optimization (compared to ssr) when we
generate the mipmap chain -- we can allocate the mipmaped texture
and render the SSR pass directly into its level 0. This achieved
use the framegraph's forward resource feature.
With this change, shaders are compiled at program creation, programs
are linked at the start of the next render pass and queries are
deferred until first use.
This should improve overall performance on some drivers.
This reduces the size of OpenGLProgram from 64 to 32 bytes and
improves the code that sets new samplers.
The main simplification is that we're not trying to "pack" the
texture units used in the program. For e.g. we could be using
units 0,3,4, where before it would be 0,1,2.
This allows us to do less tracking.
Another optimization is that we're discarding entirely a SamplerGroup
if the program doesn't use any of its samplers. This helps remove
a test in updateSampler which in turn remove somem tracking data.
Instead of recomputing the Frustum from its 8 vertices, we compute it
from the projection matrix directly. This ensures this works with any
projection matrix. Building a Frustum object from 8 vertices required
these vertices to be given in a certain order which wasn't correct if
the projection was flipped for instance.
Removed the API to construct a Frustum from vertices.
fixes b/225975881
move its content to DriverEnums.h, we do this because it is used
in libfilabridge, which has an unspoken rule that it only includes
DriverEnums.h.
filabridge also only has a header dependency, so it can't call any
method, not even operator<<.
Also cleanups and simplifications.
The main simplification is that we don't need an actual map to retrieve
the global offset of a sampler, it can be easily calculated as:
global_offset = offset_of_the_block + local_offset
Instead of passing the level and layer explicitly to gaussianBlurPass,
we rely on the information already contained in the handle. i.e. we
honor the "subresource" part of the handle (if it has one).
In other words, it's now possible to pass a subresource (e.g. a layer)
to generateGaussianMipmap or gaussianBlurPass and things should work as
expected.
The problem here would happen when forwarding a subresource (i.e.
replacing an existing resource by a subresource) and the existing
resource had been written to. In this situation, the subresource's
parent needs to depend on the subresource (i.e. as if it was written to
by it). This would normally happen during write() but in this situation,
the write had already happened.
the dependency graph would be incorrectly severed in the situation where
a subresource was written to and later its parent was read from.
In this situation, the parent node is in fact a new version of the
original parent node, so we need a "read" dependency of the orginal to
the copy (otherwise the orginal node is not a dependent of anyone
and gets culled).
Some clients need to link against both Filament and OpenGL. This can lead to symbol clashes under certain circumstances. As a fix, prefix all of our `bluegl` symbols with `bluegl_`. Previously we made this naming change for Windows, but now we'll do it on all platforms for simplicity.
The existing behavior was surprising for users who draw opaque objects
into a semitransparent views, and this was especially evident with
the labels in `TextureLinearInterpolationTest`.
We now disable blending for MASKED, which is what our existing materials
documentation already says. We also now set the fragment alpha to 1 when
the fragment is not discarded, which prevents the "punch through"
effect. This is consistent with ThreeJS.
Fixes#4576.
We were decrementing activeJobCount after removing the job from the
queue, which could cause other threads in the pool to preempt us before
the decrement, causing them to spin forever trying to get a non-existant
job, until the decrement actually happened.
Now we always decrement first and fix-up the count if we couldn't get
a job from the queues. The race is inverted, and doesn't cause threads
to spin a long time.
fixes b/201100123
This removes some special handling of the default render target lifetime
that is no longer needed, and renames "surface" to "swapChain" where it
is appropriate to do so.
This is a gltfio API change (!)
Jave clients now need to call destroy on MaterialProvider.
Previously, the Java AssetLoader took over ownership of a native
material provider upon construction, but this was neither documented
nor consistent with the C++ layer. (This is historical; in the past we
did not expose MaterialProvider to Java.)
One motivation for this (aside from API consistency) is that users may
wish to preserve the material cache from one run to another.
Fixes#5132.
We now have a single varyings.glsl containing our varyings for both
the vertex and fragment shader. This file is included with the right
definition of VARYING as `in` or `out`.
inputs.vs is now renamed attributes.vs
This changes the WebGL and desktop glTF viewers so that they always
call `updateBoneMatrices`, even when there are 0 animations. Note
that our Android sample was already doing this correctly.
When combined with #5301, this fixes#5299, although users would need to
use the `recomputeBoundingBoxes` feature in gltfio (`-r` in the desktop
viewer) for this model to be scaled to fill the viewport, since its
embedded bounds are quite large.
In the past there was an API gotcha because users had to "get" the
animator before releasing the glTF source data. This could have been
surprising because it was a getter method, not a factory method.
This was due to overeager optimization on my part, I wanted to avoid
animator overhead for non-animated models, when in fact it has very
little overhead.
Moreover, the animator is conceivably useful even when there are no
pre-supplied animations (e.g. for applying skins), so let's just create
it unconditionally.
Motivated by #5299.
Two changes:
1) Khronos has moved from "master" to "main".
2) BlueVK was attempting to generate reasonable "operator<<" support for
bit flags but this was buggy due to type aliases. Since we weren't using
it anyway, I simply removed this functionality from BlueVK.
Instead of having 2 fields we're following the vulkan convention of
having only the layer field.
The layer/face convention is still maintained in the public APIs.
fixes#5273
Dragging a zip file into the Remote Viewer page would fail if it
contained a glTF with `./` prefixes in the `images` section. The best
fix is to use Java's proper URI object rather than trying to parse the
string.
The JSON response to /api/active became malformed after #4465 because
raw hex strings need to be enclosed by quotes.
This commit changes the variant format in the /api/materials response
to be consistent with one used for /api/active. By using integers
instead of strings, we're avoiding the need to parse integers at run
time.
The JSON error did not appear in the Chrome console because it was being
silenced as a hack to appease "matinfo --web-server". I fix this by
removing the hack and simply emitting a valid response when there's
no live backend.
Also fixed the display of materials, which were always being marked
as active even when they had no active variants.
We held a reference to a cache item after potentially clearing it due to
pool growth. I was able to trigger an error only after enabling ASAN and
loading a large model. Many thanks to @jeanlemotan for catching this.
When we added per-layout arenas for each of the 3 descriptor types, we
did not account for them when determining how much of the Vk Pool is in
use. Therefore the "growth" (really a re-creation) of the Vk Pool wasn't
always occurring when necessary, causing descriptor set allocation to
fail with large models.
In the current version of the library, it looks like the DYNAMIC config
macro has been replaced with a STATIC config macro.
Also disabled the "unused-private-field" warning since this is a 3rd
party library and its not our fault.
The main change here is from ResourceList which ended-up generating
a lot of code due to inlining. This class is only used for tracking
user resources and is not in the performance path.
This saves another ~5K or so of code.
This caused a unit test failure because a StaticString constructed
from "make" had a different hash than one constructed from a literal,
even though the two strings were lexigraphically equivalent.
Having MorphTargetBuffer in FRenderPrimitive is a concept of glTF. Filament doesn't have to follow this concept. Actually the responsibility of FRenderPrimitive is to define vertex input stream because FRenderPrimitive maps to HwRenderPrimitive in Filament. If we store MorphTargetBuffer into FRenderPrimitive then it exceeds the responsibility of FRenderPrimitive. Because MorphTargetBuffer doesn't have any information on how to set up vertex input stream. So handling morphing like skinning will be better.
We were not unrolling the == loop because the generated code with
unrolling was very branchy; but that's not a good call either because
the loop has the same number of unpredicted branches.
Theoretically the compiler should be able to emit a branchless == but
it doesn't. At least we give it a chance.
When we introduced texture-based morphing, our custom depth resolver
needed to be updated to set up samplers correctly. This fixes a
validation error about shader stage access.
Every sidecar texture should have the same dimensions as its parent
texture.
Prior to this change, the sidecar texture would have the dimensions of
the RenderTarget wrapper rather than the parent texture. This was wrong
because the RenderTarget might be slightly smaller than the texture.
This caused an issue when the same texture was attached to two render
targets with different sizes, because there's only 1 cached sidecar per
texture.
We were passing the wrong texture object to VulkanDisposer::acquire().
MSAA depth sidecar textures are not managed by VulkanDisposer, but their
parent textures are.
Fixes#5217.
When we overhauled image layout transitions, we moved as many
transitions as possible into the render pass. However the transition
that we perform for "depth read only" layout needs to be applied to
multiple miplevels, so we cannot use the render pass for that.
We now handle "too many bone weights" in the same way that we handle
"too many UV sets". i.e. emit an error message and do not panic.
This change allows us to render the model in #5234 quite reasonably.
Fixes#5234.
This fixes the emscripten binding errors that we've been seeing
with the <filament-viewer> test page, which prevented us from
including web in the last few Filament releases.
The binding errors were caused by double-initializing the emscripten
module.
I fixed this by allowing clients (e.g. FilamentViewer) to call
Filament.init() more than once. We now accumulate a list of "on ready"
callbacks that get triggered after the emscripten module becomes ready.
As far as I can tell, multiple canvases were actually always broken, and
the viewer test page worked in the past only because we got lucky.
This fixes the emscripten binding errors that we've been seeing
with the <filament-viewer> test page, which prevented us from
including web in the last few Filament releases.
The binding errors were caused by double-initializing the emscripten
module.
I fixed this by allowing clients (e.g. FilamentViewer) to call
Filament.init() more than once. We now accumulate a list of "on ready"
callbacks that get triggered after the emscripten module becomes ready.
As far as I can tell, multiple canvases were actually always broken, and
the viewer test page worked in the past only because we got lucky.
Previously, the Vulkan backend made an educated guess about the depth
write state during the start of the render pass. The logic for this
did not make any sense, so now we're replacing it with an explicit
hint that PostProcessManager sets up. In a sense this gives backends
a sneak peek into the raster state.
The existing unit test had an incorrect expectation in what happens
after splicing an existing range. Fixing the unit test revealed an
actual bug in the RangeMap implementation. It should never modify the
lower bound of an existing interval, because that invalidates the
iterator. It should also never retain a pointer or reference to a range
when the range is potentially removed by subsequent codelines.
We can now specify an "instance count" per renderable during creation.
This instance count applies to all render primitives in the
Renderable.
This will simply draw the renderable "instance count" times. A new
method available to vertex shaders, getInstanceIndex(), allows the
material to discriminate the instances and adjust the position/transform
accordingly.
Typically this is used for particle systems.
Two big changes to simplify and fix layout transitions:
(1) The RenderPassKey struct has been reduced from 88 bytes to 56 bytes
by using custom enum types and bitmasks. It also now has separate fields
for "final" and "initial" image layouts.
(2) VulkanSwapChain now leverages VulkanTexture, which enables it to
share tracking functionality, avoid duplicated state, and have less code
overall.
In a future PR we will clean up the ReadPixels and Blit paths, and also
remove some hacks that appease Vulkan when SSAO is enabled.
The main change here is that for screen-space reflections, the lod
calculation takes the camera distance into account.
We also now correctly take into account that we blur each lod
successively which increases the standard deviation by 10%. This applies
to both refraction and reflection.
This works by first generating a reflection buffer which gets blurred,
then the color pass samples from this buffer according to the roughness
of the surface being rendered.
A lot of the changes here involve utilizing "reserved" variants for
the new "SSR" pass and all the fallout from that.
Variants are no longer just a bit mask, but rather a combination of
some bits, depending on the variant. Because of that the variant filer
must be updated.
Basically we now make a distinction between the "variants" as a public
material API and the actual `Variant` data type.
This change does the impedance match between the two.
The previous code would convert each element of the source data
into 8 bit-per-element, but we wnat to preserve the original format
that the user provides.
The new solution is to use `slice()` which is a robust way to clone
all the data in a typed array.
This fixes the new regression with Triangle that Ben caught.
The previous code would convert each element of the source data
into 8 bit-per-element, but we wnat to preserve the original format
that the user provides.
The new solution is to use `slice()` which is a robust way to clone
all the data in a typed array.
This fixes the new regression with Triangle that Ben caught.
If emscripten grows the heap inside one of our BufferDescriptor binding
functions, then the old heap becomes "detached" and an error can
occur.
This fixes the issue seen with the Parquet demo that Ben caught.
If emscripten grows the heap inside one of our BufferDescriptor binding
functions, then the old heap becomes "detached" and an error can
occur.
This fixes the issue seen with the Parquet demo that Ben caught.
filament/src/Renderer.cpp
- make code mode readable, hopefully
- SSR mipmap generation is now more or less standalone
- when possible, resolve color buffer directly into
mimpmapped texture's base level.
All three types of caches (descriptor sets, pipelines, and pipeline
layouts) are now managed in exactly the same way. They all use an LRU
eviction scheme that is based on a count of command buffer flush
events.
Vulkan objects can only be destroyed if there are no in-flight command
buffers that reference them, so an easy way to know when it is safe to
evict a given entry is to wait for "N" flushes after its last use, where
"N" is the number of command buffers in the command buffer ring.
Another big simplification is that there are no more dirty flags,
instead we store two sets of state vectors for each type of cache: the
"currently bound" state, and the "current requirements" state.
All three types of caches (descriptor sets, pipelines, and pipeline
layouts) are now managed in exactly the same way. They all use an LRU
eviction scheme that is based on a count of command buffer flush
events.
Vulkan objects can only be destroyed if there are no in-flight command
buffers that reference them, so an easy way to know when it is safe to
evict a given entry is to wait for "N" flushes after its last use, where
"N" is the number of command buffers in the command buffer ring.
Another big simplification is that there are no more dirty flags,
instead we store two sets of state vectors for each type of cache: the
"currently bound" state, and the "current requirements" state.
- Rename projectToPixelMatrix to uvFromViewMatrix, this match our
existing style better.
- slightly more efficient direction transform
- limit roughness to 0.1 instead of 0.01, because in a lot of cases,
the roughness increases with the LOD, for instance if it comes from
a texture (to combat aliasing).
The current Variant is need to calculate BindingIndexMap correctly.
But we can't use the current Variant when calculate BindingIndexMap
because SamplerBindingMap uses only the dummy Variant. Both are
should be same.
The morphing sampler group can be added if skinning or morphing is
enabled. However SamplerBindingMap can't know skinning or morphing
is enabled because only dummy Variant is used. It causes generating
the different sampler bindings between SamplerBindingMap and
program's sampler groups.
Fixes#5139
- Make sure to disabled SSR when it's... disabled.
- Fade the reflection when the ray direction is towards de camera,
where it will likely hit a back face
- Simplify the fading code, for near identical results.
Fixes#5142 by replacing unsafe pointers with map keys.
One of the differences between robin_map and unordered_map is the
following:
pointers to keys or values in the map are invalidated in the same
way as iterators to these keys-values
Therefore it is unsafe to track the pointer to a value that is stored
in a robin_map.
This is mostly just code cleanup. One actual bug was the fact that the
dummy sampler was re-created every time a new pipeline layout was
created.
It also felt strange to use `auto&` to refer to a C-style array. I
changed this into a `std::array` which is more consistent with other
fixed size arrays in this class.
Fixes#5142 by replacing unsafe pointers with map keys.
One of the differences between robin_map and unordered_map is the
following:
pointers to keys or values in the map are invalidated in the same
way as iterators to these keys-values
Therefore it is unsafe to track the pointer to a value that is stored
in a robin_map.
This is mostly just code cleanup. One actual bug was the fact that the
dummy sampler was re-created every time a new pipeline layout was
created.
It also felt strange to use `auto&` to refer to a C-style array. I
changed this into a `std::array` which is more consistent with other
fixed size arrays in this class.
This fixes the gltf_viewer automated testing mode, invoked via
`--batch=default --headless`.
ReadPixels was being issued with an out-of-bounds size on high DPI
platforms, which caused weird backend errors.
Since we create an invisible SDL window while in headless mode, the
presence of the SDL window does *not* indicate headless vs non-headless.
Partial fix for #5111
Because the morphing buffer is actually a texture, it's possible that
the last line is not a full width when updating the buffer.
Because texture are updated via a rectangle, it was possible to read
past the malloc'ed buffer during the update.
Moreover, because the count can be specified, we can't just blindly send
more "dummy" data.
Finally, added an offset to match the skinning API, and in that case,
the first line can also be incomplete.
We fix this by issuing up to 3 texture update calls if needed.
The java/js API update will come later.
Support legacy morphing (morphing with targets supplied via VertexAttributes) for older clients. This gives clients more time to transition over to the new MorphTargetBuffer API.
Support legacy morphing (morphing with targets supplied via VertexAttributes) for older clients. This gives clients more time to transition over to the new MorphTargetBuffer API.
Instead of building the Variant based on flags in RenderPass, we just
pass the Variant itself to RenderPass. The caller has more knowledge
of what it wants to do.
This allows `MorphStressTest` to work on Vulkan.
However, `Horse` is still broken because it provides positions but not
tangents. Separate fix for that is coming.
Partial fix for #5109.
This fixes validation errors and makes a first pass at simplification.
VulkanTexture now tracks image layout using RangeMap, which paves the
way for further simplification.
This will allow the Vulkan backend to efficiently track the subresource
image layouts for each texture.
This is a sparse container for a series of ordered non-overlapping
integer intervals, where each interval maps to a concrete value.
This is because we're using the same program variant for skinning
and morphing, in the skinning-only case, the buffer won't be accessed
in the shader, but it must be present.
fixes#5085
This allows the `Horse.glb` model to work with Vulkan without any
validation errors. As a reminder, the glTF spec says:
```
When normals are not specified, client implementations MUST calculate
flat normals
```
Fixes#5115.
* Get the morph target count from the renderable
* Set the morph target count by Builder
* Update morph target weights partially
* Remove noexcept at functions could throw exceptions
* Update Java bindings at RenderableManager
* Add missing comments
* Update morph target weights from offset
Co-authored-by: Mathias Agopian <mathias@google.com>
This allows `MorphStressTest` to work on Vulkan.
However, `Horse` is still broken because it provides positions but not
tangents. Separate fix for that is coming.
Partial fix for #5109.
This fixes validation errors and makes a first pass at simplification.
VulkanTexture now tracks image layout using RangeMap, which paves the
way for further simplification.
There is no need to go through all primitive and call updateSamplerGroup,
because the SamplerGroup never changes -- it just hold the texture that
holds the data.
This is because we're using the same program variant for skinning
and morphing, in the skinning-only case, the buffer won't be accessed
in the shader, but it must be present.
fixes#5085
This will allow the Vulkan backend to efficiently track the subresource
image layouts for each texture.
This is a sparse container for a series of ordered non-overlapping
integer intervals, where each interval maps to a concrete value.
This fixes a double-initialization problem for one of the function
pointers, and also updates the BlueVK generator to fix issues with the
latest Khronos XML file.
The corollary C++ changes will be made in a subsequent PR since they
will be difficult to review.
See #5026.
2D array textures are initialized with .depth = 1 and layerCount = depth (see line 58 in VulkanTexture.cpp). By setting layerCount = 1 only the first layer was copied over, leaving the other layers uninitialized.
This functionality (in the Automation section) was violating a
constraint that was landed in November.
1) Call postRender inside beginFrame / endFrame.
2) Use RGBA when issuing ReadPixels (required by some backends) and
convert to RGB when dumping out the PPM file.
screen-space reflections are integrated in the indirect light computation
(similarly to screen-space refraction), this is because it can be seen as
the specular term of screen-space GI.
However, because this effect is screen-space, the data it accesses has
the ibl luminance (and exposure) applied.
Besides some minor refactoring, this change just applies the
screen-space reflections *after* the ibl's specular term is exposed.
We can now do screen-space refraction and reflections at the same time.
This change mostly removes the checks that were preventing it from
working.
The real change in the PR is to adjust the reprojection matrix based
on whether the SSR buffer (both for refractions and reflections) comes
from this or the previous frame.
what's not allowed at this point is an object which has both screen
space refraction and reflection.
this is accomplished by just always disabling screen-space reflections
for the translucent step of the refraction pass.
The `uint8_t` here needs to be cast to an integer to be printed
correctly. Also these warnings seem to be quite common so we should
hide them in Release builds.
These warnings probably indicate an actual problem that I do not fully
understand yet.
2022-01-18 16:04:16 -08:00
7070 changed files with 717711 additions and 799834 deletions
@@ -41,9 +41,7 @@ Here are all the libraries available in the group `com.google.android.filament`:
| ------------- | ------------- |
| [](https://maven-badges.herokuapp.com/maven-central/com.google.android.filament/filament-android) | The Filament rendering engine itself. |
| [](https://maven-badges.herokuapp.com/maven-central/com.google.android.filament/gltfio-android) | A glTF 2.0 loader for Filament, depends on `filament-android`. |
| [](https://maven-badges.herokuapp.com/maven-central/com.google.android.filament/gltfio-android-lite) | Trimmed version of `gltfio` that does not support some glTF extensions. |
| [](https://maven-badges.herokuapp.com/maven-central/com.google.android.filament/filament-utils-android) | KTX loading, Kotlin math, and camera utilities, depends on `gltfio-android`. |
| [](https://maven-badges.herokuapp.com/maven-central/com.google.android.filament/filament-utils-android-lite) | Trimmed version of `filament-utils` that does not support some glTF features. |
| [](https://maven-badges.herokuapp.com/maven-central/com.google.android.filament/filamat-android) | A runtime material builder/compiler. This library is large but contains a full shader compiler/validator/optimizer and supports both OpenGL and Vulkan. |
| [](https://maven-badges.herokuapp.com/maven-central/com.google.android.filament/filamat-android-lite) | A much smaller alternative to `filamat-android` that can only generate OpenGL shaders. It does not provide validation or optimizations. |
@@ -52,7 +50,7 @@ Here are all the libraries available in the group `com.google.android.filament`:
iOS projects can use CocoaPods to install the latest release:
```
pod 'Filament', '~> 1.17.0'
pod 'Filament', '~> 1.36.0'
```
### Snapshots
@@ -63,7 +61,7 @@ steps:
1. Find the [commit](https://github.com/google/filament/commits/main) you're interested in.
2. Click the green check mark under the commit message.
3. Click on the _Details_ link for the platform you're interested in.
4. On the top right, click on the _Artifacts_ dropdown and choose an artifact.
4. On the top left click _Summary_, then in the _Artifacts_ section choose the desired artifact.
## Documentation
@@ -118,14 +116,15 @@ steps:
- Image-based lighting
- Physically-based camera (shutter speed, sensitivity and aperture)
- Physical light units
- Point lights, spot lights and directional light
- Point lights, spot lights, and directional light
- Specular anti-aliasing
-Spot and directional light shadows
-Point, spot, and directional light shadows
- Cascaded shadows
- EVSM, PCSS, DPCF, or PCF shadows
- Transparent shadows
- Contact shadows
- Screen-space ambient occlusion
- Screen-space reflections
- Screen-space refraction
- Global fog
- Dynamic resolution (with support for AMD FidelityFX FSR)
Some files were not shown because too many files have changed in this diff
Show More
Reference in New Issue
Block a user
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.