Commit Graph

246 Commits

Author SHA1 Message Date
Mathias Agopian
968c2c40fa Cleanup shader generation
- 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
2023-04-12 10:12:19 -07:00
Mathias Agopian
6b3dfbc635 reduce our reliance on unsigned types
This is to facilitate ES2 support, in all places where unsigned types
were not strictly needed, we now use the corresponding signed type.
2023-04-12 10:12:19 -07:00
Ben Doherty
6cab8d2cd4 Expose specialization constants to materials as constant parameters (#6652) 2023-04-11 11:09:53 -07:00
Mathias Agopian
c264d26edd filter out VSM variant for unlit materials DEPTH shaders
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.
2023-04-04 16:52:04 -07:00
Mathias Agopian
7cba0da0a2 implement cascades visualization as a post-process
this allows us to remove code from the main shaders that is basically
never used, reducing shader size and runtime costs.
2023-03-23 12:11:56 -07:00
Mathias Agopian
d8eb48c9de Improvements to fog
- 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
2023-03-23 09:31:01 -07:00
Benjamin Doherty
74eb8a77e5 Bump MATERIAL_VERSION to 32 2023-03-13 14:04:40 -07:00
Mathias Agopian
e2e5f7cee9 Add way to retrieve the user world-space in materials (#6607)
* 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.
2023-03-03 21:34:17 -08:00
Romain Guy
5a75fb9b53 Add new alphaToCoverage material property (#6606)
* 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
2023-03-02 12:40:55 -08:00
Mathias Agopian
7933b08e85 fix fog instability with strong falloff
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.
2023-03-01 16:48:16 -08:00
Mathias Agopian
2e7fc6229b Improve StructureOfArray
- 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.
2023-02-22 16:28:40 -08:00
Mathias Agopian
0d72a0904b getNormalizedViewportCoord() now returns the logical viewport coords
This is a better user-facing API because materials don't need to know
about the physical viewport.
2022-12-13 16:37:49 -08:00
Mathias Agopian
f619b62877 Handle shadow borders better
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.
2022-11-21 15:38:25 -08:00
Mathias Agopian
77fcf4d260 don't store the light direction in the shadowmap structure
We already have it in the Light structure.
2022-11-17 11:07:47 -08:00
Mathias Agopian
9768f49714 unify point and spotlight shadows
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).
2022-11-08 16:35:54 -08:00
Mathias Agopian
6c54cfe88a Shadowmaping code improvements
- 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
2022-11-08 15:25:33 -08:00
Mathias Agopian
2dc8d6bcc0 minor cleanups, comment fixes
- update comments
- remove unused or unneeded methods
2022-11-08 15:25:33 -08:00
Ben Doherty
c5cc7fe26a Metal: generate argument buffer structures ourselves (#6242) 2022-11-01 12:44:42 -04:00
Mathias Agopian
acd5823953 Add support for point light shadows
[experimental]
2022-10-10 13:03:36 -07:00
Mathias Agopian
a02ef1a6c7 Remove the limit to 14 spot shadow maps, now 64.
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.
2022-10-07 14:07:51 -07:00
Mathias Agopian
5aa414dd24 support for ELVSM and 32 bits xVSM
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.
2022-09-30 12:04:27 -07:00
Ben Doherty
f151f56a2e Metal: use argument buffers for SamplerGroups (#6093) 2022-09-28 16:50:11 -07:00
Mathias Agopian
fabba73b1e Initial support for compute
* 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
2022-09-27 15:52:40 -07:00
Mathias Agopian
c84834d666 bump max sampler count to 62
This is needed for feature level 2.
2022-09-13 10:49:21 -07:00
Mathias Agopian
2073a9f3e5 cleanup Froxelizer comments
also fix typos, formatting.
2022-08-30 20:31:47 -07:00
Mathias Agopian
a7a55c7617 Specification constants support (#6001)
* Add support for specialization constants

* remove WebGL instancing count hack

use a specification constant instead

* update release notes
2022-08-29 09:38:23 -07:00
Mathias Agopian
87cece8379 use separate enums for uniform and sampler binding points (#5984)
Co-authored-by: Benjamin Doherty <bendoherty@google.com>
2022-08-24 16:36:13 -07:00
Philip Rideout
fe3790cb9c WASM: Set CONFIG_MAX_INSTANCES to a small value + hack the GLSL.
Temporary fix until spec constants arrive.

Second attempt, fixes #5859.
2022-08-24 16:24:25 -07:00
Mathias Agopian
8257fbdbf3 Fix a merge that went bad 2022-08-23 17:16:56 -07:00
Mathias Agopian
f57224952a record sampler informations in the material file
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
2022-08-23 17:03:30 -07:00
Philip Rideout
3c982cae64 Revert "WASM: Set CONFIG_MAX_INSTANCES to a small value."
This reverts commit 7aa5d4a375.
2022-08-23 16:42:16 -07:00
Philip Rideout
7aa5d4a375 WASM: Set CONFIG_MAX_INSTANCES to a small value.
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.
2022-08-23 11:57:26 -07:00
Philip Rideout
1d06dd630a Add CONFIG for MaxInstanceCount. 2022-08-23 09:32:01 -07:00
Mathias Agopian
357000a0e7 Make ShaderStageFlags an enum class 2022-08-19 22:08:59 -07:00
Mathias Agopian
80e26ba4af Make BindingPoints an enum class 2022-08-19 22:08:59 -07:00
Mathias Agopian
5909215967 keep only 1 entry point for UniformInterfaceBlock::add
add() now take a list of Uniforms, and is the only entry point.
At least clang generates much less code this way.
2022-08-19 16:23:39 -07:00
Mathias Agopian
f0eb1c59b1 don't hardcode uniform block bindings on filament side
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.
2022-08-19 16:23:39 -07:00
Mathias Agopian
b2ec57776d new feature level API for backends (#5784)
* 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
2022-08-17 10:14:26 -07:00
Mathias Agopian
c6502054e9 Fix guard bands and TAA with VERTEX_DOMAIN_DEVICE
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
2022-08-16 15:32:33 -07:00
Philip Rideout
e0c11cfeed Add CONFIG_MINSPEC_UBO_SIZE and fix comment.
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.
2022-08-16 10:38:33 -07:00
Mathias Agopian
5b71274fa5 get rid of utils::StaticString
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`.
2022-08-02 09:51:13 -07:00
Mathias Agopian
841ea86cea MaterialInstance public API friendly to std::string_view
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).
2022-08-01 14:17:29 -07:00
Mathias Agopian
e0eaaf4fb9 skip SSAO texture read if SSAO is disabled 2022-08-01 09:49:47 -07:00
Mathias Agopian
6bc0e032fc Access the object uniforms relative to gl_InstanceIndex 2022-07-06 15:51:41 -07:00
Philip Rideout
1ac57038d9 smolv blobs are now 8-byte aligned in filamat. (breaks materials) (#5705) 2022-06-16 11:23:52 -07:00
Mathias Agopian
6ebaad28b3 cleanup and fixes regarding skinning UBO (#5676)
- 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
2022-06-10 15:03:41 -07:00
Mathias Agopian
803ce07701 Always access object uniforms via getObjectUniforms()
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.
2022-06-10 09:13:18 -07:00
Mathias Agopian
95d3b19ced Allow UniformInterfaceBlock to have arrays of size 1 2022-06-10 09:13:18 -07:00
Mathias Agopian
61e117beaa Added a new instanced material parameter
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()`.
2022-06-08 17:10:38 -07:00
Mathias Agopian
1af76638cf rework per renderable ubo update
We now store the per renderable ubo data in the scene SoA before sending
to the gpu. This is needed to prepare future work on instancing.
2022-05-25 12:07:59 -07:00