First, this commit introduces some very simple bugfixes regarding ES2
compatibility related to postprocessing.
Second, this commit adds support for creating textures specified as R8, SRGB8,
and SRGB8_A8 in ES2. R8 is trivial: just use GL_LUMINANCE instead. The sRGB
formats, however, are maybe a bit more controversial. As implemented, they
instead just use the equivalent non-sRGB formats. This is of course technically
incorrect. There are a few approaches to how to add sRGB compatibility for ES2
that I can think of.
1. Do a bunch of complex shader nonsense in matc. Maybe even traversing the AST
and ensuring any texture lookup of a texture flagged as sRGB uses some
compatibility function. This would require static analysis to track if samplers
are reassigned to another variable, for example. This of course also breaks down
if you don't know at compile time if the shader will receive an RGB or an sRGB
sampler, or if the shader should be able to support both RGB or sRGB samplers.
Really only worth mentioning here for the sake of completion.
2. You could also generate simple compatibility functions to look up each
sampler, which would only apply to FL0 materials.
First, we would have to extend the material format to be able to explicitly
"color" a sampler as sRGB or not, like:
```
parameters : [
{
type : sampler2d,
name : albedo,
precision : medium,
colorSpace : srgb,
},
{
type : sampler2d,
name : normal,
precision : medium,
colorSpace : linear,
}
],
```
Then, the following GLSL code would be generated.
```glsl
\#if __VERSION__ == 100
vec4 texture_albedo(vec2 position) {
return sRGBtoLinear(texture2D(materialParams_albedo, position));
}
vec4 texture_normal(vec2 position) {
return texture2D(materialParams_albedo, position);
}
\#else
vec4 texture_albedo(vec2 position) {
return texture(materialParams_albedo, position);
}
vec4 texture_normal(vec2 normal) {
return texture(materialParams_normal, position);
}
\#endif
```
Finally, at runtime, if a sampler is "colored" one way or the other, we would
verify that only the appropriate kinds of samplers are bound.
I'm actually very partial to this solution. Since sRGB compatibility is only a
concern on ES2, we can generate this code only for FL0 shaders, which already
require GLSL shader authors to care about ESSL 1.0 compatibility by calling the
appropriate `textureXX` functions. Additionally, it provides a layer of
high-level validation that texture lookups are correct, even if a real ES2
context is not available on the device being tested.
3. Leave it entirely up to the client. (What this commit does.) This leaves
client code ripe for making mistakes, but luckily, we can go back and do
solution 2 whenever. If specifying a color space for a sampler remains optional,
then if this feature is retrofitted in the future, client code will continue to
compile.
Enable a limited subset of materials in PostProcessManager for FL0.
Create new function Material::getFeatureLevel() in C++ and Java.
Create missing Material::getReflectionMode() method in Java.
This change hard-codes writing the post process output at index 0 (i.e. color)
to gl_FragColor when generating ESSL 1.0 shaders. Any other outputs (besides
depth) are discarded with a warning, but as far as I can tell, no such cases yet
exist in Filament.
Fix edge case where an empty struct could be generated in an ESSL 1.0 shader.
Include _maskThreshold and _doubleSided in ESSL 1.0 shaders.
Add GL_OES_standard_derivatives extension to ESSL 1.0 shaders. According to
gpuinfo.org, this has 96% device coverage and supports both Mali-400 and Adreno
(TM) 304.
Remove 3D sampler support from ESSL 1.0 shaders. This extension is only
supported by 62% of devices.
Change filagui material to a FL0 material.
don't use FixedCapacityVector to store pointers to active shadowmaps,
that's just not needed. They're all stored un a static array already
and directional and spot shadows are partitioned.
This saves a couple heap allocations as well a an pointer dereference.
compile_commands.json was being generated, but hidden away inside of the cmake
build directories. This change makes build.sh link it to the main project dir
and adds some associated .gitignore entries. Now compile_commands.json is
properly read when starting clangd from Emacs, for example, and probably many
other editors.
When we enable SSR the first time, the SSR buffer is not initialized,
this can result in the color pass fragment shader aborting, which in
turn prevents the SSR history buffer from being initialized (since
it's made from the result of the color pass), repeating the cycle.
In some other case, the system somehow recovers but we still see a
flicker when enabling SSR.
The solution here is to disable SSR in the shader until the history
buffer is ready (i.e. a frame later).
The reason is that some implementations of WGL require all contexts to
be created on the same thread, which we're not necessarily doing here.
fixes#7078
- only check/log in debug builds
- use epsilon = 2e-7 * double(tempPairCount)
- compute boneWeightsSum in double
- don't modify the weights if they're within the threshold
FIXES=[306565054]
We've seen hangs/ANR that are not well understood on that spinlock, so
for now we're going back to mutexes, which, on android, are very
efficient under low contention (no syscall).
FIXES=[308029108]
This change does three main things. First, it adds an option to the Engine
Builder to pick the feature level at which to instantiate Filament. The only
real practical purpose of allowing this is to be able to instantiate at feature
level 0. Secondly, it allows feature level 0 to properly work on non-ES2
devices. Thirdly, it changes both Android and desktop hellotriangle samples to
explicitly opt-in to feature level 0.
Unfortunately, feature levels are used in two different, somewhat contradictory
ways presently in Filament, which can make reasoning about this change a bit
confusing. From a client perspective, feature levels refer to buckets of
capabilities which are guaranteed to be supported. Internally, there is a
separate "feature level" stored internally at the Driver subclass level which
generally corresponds to the maximum supported feature level, but is also
referenced when activating workarounds for limited devices. For example, Uniform
Buffer Objects are not supported in ES2, however, Filament supports emulating
them such that the client does not need to care at all; a supported feature is a
supported feature. But internally, Filament uses this "Driver" feature level to
determine whether or not a given workaround is needed. There were several cases
where the "active feature level" was being examined in order to activate these
workarounds rather than the "driver feature level", which was incorrect.
Why should non-ES2-only devices want to activate feature level 0? Allowing this
behavior 1. makes feature level 0 more consistent with the behavior of other
feature levels and 2. allows clients a layer of validation that their software
will work on all devices supported by Filament if they explicitly opt into it.
Consistency: Filament guarantees that any given device which supports a given
feature level will also support running on every feature level below, except for
feature level 0. This change removes that exception.
Validation: It's not perfect, and there will likely be bugs and unexpected
differences in behavior between ES2 and non-ES2 devices that crop up in the
future between two devices running on the same feature level. However, it's at
least a basic high level layer of validation that enables more rapid testing
workflows directly via desktop versions of Filament rather than having to fiddle
with something like ANGLE to get perfect GLES 2.0 compliance. Additionally, it
expands options for automated testing (with the same caveats).
This change has been tested on both the desktop and Android versions of
hellotriangle.
* prevent public classes from being created on the stack
- we used to to this by deleting operator delete, but this prevented
the internal "F" classes from being virtual; which can be useful
when using EntityManger::Listener.
now we just make the destructor protected in each class.
- EntityManger::Listener now has a virtual destructor so that
objects could be correctly destroyed from Listener*
* improve EntityManger and Component managers
- all component managers now have the same "base" API
- getComponentCount()
- empty()
- getEntity()
- getEntities()
- Scene now has getEntityCount()
- EntityManager now has getEntityCount()
- all component manager implement gc() the same way, by calling destroy()
- SingleInstanceComponentManager::gc() that calls removeComponent() has
been removed because it's dangerous. removeComponent() is often
not enough, some additional cleanup might be needed.
CameraManager creates a Transform component for each Camera component
is not already present. However, it didn't destroy the transform
component when it's itself destroyed. the leaked transform component
would eventually be garbage collected, but caused significant
slow down and memory pressure. This is because camera components are
created every frame for the shadow maps.
FIXES=[303914944]
- the insert and retrieve handlers can now be set/unset independently.
this could be useful for debugging.
- program caching is disabled if the GL implementation doesn't support it.
- removed unused code
FIXES=[307549547]
- Ensure that waiting on lock times out so that we don't lock
up a thread when the client is gone.
- Add an experimental folder to matdbg/web/ for the new
UI work.
The transient property `mRootNotes` in FAssetLoader is built when a new
root asset is created and referenced whenever a new instance is created.
So it incurs an undefined behavior when a previously created asset tries
creating a new instance after a newly created asset has already created
via the same asset loader.
Move this transient property to each asset so that they can reference it
when a new instance is created.
This partially fixes#7269
There's no functional change in this commit.
Make some parameter names more legible by renaming them and put output
parameters to the right of their function.
The temporary variable has been used to store the current instance of
FFilamentAsset being loaded for easy access from internal methods. This
causes a crash as to a complex scenario as follows.
val asset1 = assetLoader.createAsset(assetBuffer1)
val instance1 = assetLoader.createInstance(asset1)
val asset2 = assetLoader.createAsset(assetBuffer2)
val instance2 = assetLoader.createInstance(asset1)
As the first step of fixing this issue, remove the transient property
`mAsset` from FAssetLoader. This commit alone doesn't resolve the issue,
and more commits are following.
Consolidate the low level version of createInstance, which takes a
pointer to cgltf_data type, into the high level version as the latter
one uses a parameter for FFilamentAsset instead of referencing mAsset.
Update all other relevant methods to take a FFilamentAsset pointer
instead of cgltf_data.
This partially fixes#7269
* debugging PCF mode
This mode always uses a hard PCF and takes a
slightly slower code path.
* dynamic shadowmap visualization
The directional shadowmap visualizer is implemented behind a
specialization constant. Add the DebugRegistry infrastructure to be
able to update the spec-constant at runtime and have a subset of
all materials invalidated.
This allows to toggle the visualization at runtime using a debug
property.
This is also a proof of concept that we can update spec-constants
at runtime; we could probably leverage this work for engine-wide
shader configurations.
* Update main.fs
* Update filament/src/details/Material.cpp
Co-authored-by: Powei Feng <powei@google.com>
---------
Co-authored-by: Powei Feng <powei@google.com>
- Remove queue submit call when using headless swapchain. It was meant
to emulate a real swapchain, but queue submits are expensive.
- Add option to remove flush and wait when window resizes. If a
headless platform uses this signal to refresh the swapchain, we
don't necessarily need it to also flush and wait before the refresh.
- Refactor VulkanPlatform customizations