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.
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}.
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.
- 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
- 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.
* 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.
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.
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
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.
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.
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
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.
* 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