Compare commits
39
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
8ed10d77de | ||
|
|
e8e99a0de6 | ||
|
|
6630aa5f36 | ||
|
|
bc83ffdcd1 | ||
|
|
c21f211a13 | ||
|
|
58d4671c24 | ||
|
|
93caca7245 | ||
|
|
bf77c023b9 | ||
|
|
95128d5f55 | ||
|
|
6d17d858de | ||
|
|
05003ea358 | ||
|
|
98847d6509 | ||
|
|
d3828cdd1c | ||
|
|
4beda6feee | ||
|
|
7cacef9509 | ||
|
|
5cd7de7318 | ||
|
|
9c87e72a81 | ||
|
|
652d973ad8 | ||
|
|
84661777e7 | ||
|
|
c8ab2f335e | ||
|
|
db14efc151 | ||
|
|
d1ca059dad | ||
|
|
c71a22914f | ||
|
|
71d0723026 | ||
|
|
5c371089f2 | ||
|
|
2c7064e93d | ||
|
|
3961989aca | ||
|
|
b92af357f7 | ||
|
|
f2a1051df9 | ||
|
|
594ab3e9e3 | ||
|
|
7f18c7fd43 | ||
|
|
9c1a252ba5 | ||
|
|
bf8e798b60 | ||
|
|
b94e90416a | ||
|
|
e9fde8346e | ||
|
|
3ae747b544 | ||
|
|
5924633085 | ||
|
|
a07c19e5b7 | ||
|
|
59f4d1ba20 |
@@ -818,6 +818,7 @@ add_subdirectory(${EXTERNAL}/jsmn/tnt)
|
||||
add_subdirectory(${EXTERNAL}/stb/tnt)
|
||||
add_subdirectory(${EXTERNAL}/getopt)
|
||||
add_subdirectory(${EXTERNAL}/perfetto/tnt)
|
||||
add_subdirectory(${EXTERNAL}/zstd/tnt)
|
||||
|
||||
# Note that this has to be placed after mikktspace in order for combine_static_libs to work.
|
||||
add_subdirectory(${LIBRARIES}/geometry)
|
||||
|
||||
@@ -7,3 +7,10 @@ We are chaning the way Vulkan buffers are handled. We need to switch over to a m
|
||||
appropriate header in [RELEASE_NOTES.md](./RELEASE_NOTES.md).
|
||||
|
||||
## Release notes for next branch cut
|
||||
|
||||
- engine: add a `linearFog` material parameter. [⚠️ **New Material Version**]
|
||||
- opengl: When `Material::compile()` is called on a platform which doesn't support parallel compilation, shaders are automatically compiled over a number of frames
|
||||
- engine: Added `useDefaultDepthVariant` material parameter to force Filament to use its default variant for
|
||||
depth-only passes. [**Requires recompiling materials**]
|
||||
- material: fix specularFactor in `LOW_QUALITY` mode. [**Requires recompiling materials**] to take effect.
|
||||
- material: Add CRC32 validation for material packages [⚠️ **New Material Version**]
|
||||
|
||||
@@ -31,7 +31,7 @@ repositories {
|
||||
}
|
||||
|
||||
dependencies {
|
||||
implementation 'com.google.android.filament:filament-android:1.63.1'
|
||||
implementation 'com.google.android.filament:filament-android:1.63.0'
|
||||
}
|
||||
```
|
||||
|
||||
@@ -51,7 +51,7 @@ Here are all the libraries available in the group `com.google.android.filament`:
|
||||
iOS projects can use CocoaPods to install the latest release:
|
||||
|
||||
```shell
|
||||
pod 'Filament', '~> 1.63.1'
|
||||
pod 'Filament', '~> 1.63.0'
|
||||
```
|
||||
|
||||
## Documentation
|
||||
|
||||
@@ -67,6 +67,10 @@ add_library(abseil STATIC IMPORTED)
|
||||
set_target_properties(abseil PROPERTIES IMPORTED_LOCATION
|
||||
${FILAMENT_DIR}/lib/${ANDROID_ABI}/libabseil.a)
|
||||
|
||||
add_library(zstd STATIC IMPORTED)
|
||||
set_target_properties(zstd PROPERTIES IMPORTED_LOCATION
|
||||
${FILAMENT_DIR}/lib/${ANDROID_ABI}/libzstd.a)
|
||||
|
||||
if (FILAMENT_ENABLE_FGVIEWER)
|
||||
add_library(fgviewer STATIC IMPORTED)
|
||||
set_target_properties(fgviewer PROPERTIES IMPORTED_LOCATION
|
||||
@@ -74,6 +78,10 @@ if (FILAMENT_ENABLE_FGVIEWER)
|
||||
endif()
|
||||
|
||||
if (FILAMENT_ENABLE_MATDBG)
|
||||
add_library(filamat STATIC IMPORTED)
|
||||
set_target_properties(filamat PROPERTIES IMPORTED_LOCATION
|
||||
${FILAMENT_DIR}/lib/${ANDROID_ABI}/libfilamat.a)
|
||||
|
||||
add_library(matdbg STATIC IMPORTED)
|
||||
set_target_properties(matdbg PROPERTIES IMPORTED_LOCATION
|
||||
${FILAMENT_DIR}/lib/${ANDROID_ABI}/libmatdbg.a)
|
||||
@@ -138,6 +146,7 @@ target_link_libraries(filament-jni
|
||||
PRIVATE utils
|
||||
PRIVATE perfetto
|
||||
PRIVATE abseil
|
||||
PRIVATE zstd
|
||||
|
||||
# libgeometry is PUBLIC because gltfio uses it.
|
||||
PUBLIC geometry
|
||||
|
||||
@@ -239,8 +239,25 @@ public class Material {
|
||||
FRONT_AND_BACK
|
||||
}
|
||||
|
||||
/**
|
||||
* Shader compiler priority queue
|
||||
*
|
||||
* On platforms which support parallel shader compilation, compilation requests will be
|
||||
* processed in order of priority, then insertion order.
|
||||
*
|
||||
* See {@link #compile(CompilerPriorityQueue, int, Object, Runnable)}.
|
||||
*/
|
||||
public enum CompilerPriorityQueue {
|
||||
/** We need this program NOW.
|
||||
*
|
||||
* When passed as an argument to {@link #compile(CompilerPriorityQueue, int, Object,
|
||||
* Runnable)}, if the platform doesn't support parallel compilation, but does support
|
||||
* amortized shader compilation, the given shader program will be synchronously compiled.
|
||||
*/
|
||||
CRITICAL,
|
||||
/** We will need this program soon. */
|
||||
HIGH,
|
||||
/** We will need this program eventually. */
|
||||
LOW
|
||||
}
|
||||
|
||||
|
||||
@@ -911,6 +911,10 @@ public class Texture {
|
||||
public static final int BLIT_SRC = 0x40;
|
||||
/** Texture can be used the destination of a blit() */
|
||||
public static final int BLIT_DST = 0x80;
|
||||
/** Texture can be used for protected content */
|
||||
public static final int PROTECTED = 0x0100;
|
||||
/** Texture can be used with generateMipmaps() */
|
||||
public static final int GEN_MIPMAPPABLE = 0x0200;
|
||||
/** by default textures are <code>UPLOADABLE</code> and <code>SAMPLEABLE</code>*/
|
||||
public static final int DEFAULT = UPLOADABLE | SAMPLEABLE;
|
||||
}
|
||||
|
||||
@@ -1561,7 +1561,9 @@ public class View {
|
||||
}
|
||||
|
||||
/**
|
||||
* Options to control large-scale fog in the scene
|
||||
* Options to control large-scale fog in the scene. Materials can enable the `linearFog` property,
|
||||
* which uses a simplified, linear equation for fog calculation; in this mode, the heightFalloff
|
||||
* is ignored as well as the mipmap selection in IBL or skyColor mode.
|
||||
*/
|
||||
public static class FogOptions {
|
||||
/**
|
||||
@@ -1578,7 +1580,7 @@ public class View {
|
||||
*/
|
||||
public float cutOffDistance = Float.POSITIVE_INFINITY;
|
||||
/**
|
||||
* fog's maximum opacity between 0 and 1
|
||||
* fog's maximum opacity between 0 and 1. Ignored in `linearFog` mode.
|
||||
*/
|
||||
public float maximumOpacity = 1.0f;
|
||||
/**
|
||||
@@ -1586,12 +1588,15 @@ public class View {
|
||||
*/
|
||||
public float height = 0.0f;
|
||||
/**
|
||||
* How fast the fog dissipates with altitude. heightFalloff has a unit of [1/m].
|
||||
* How fast the fog dissipates with the altitude. heightFalloff has a unit of [1/m].
|
||||
* It can be expressed as 1/H, where H is the altitude change in world units [m] that causes a
|
||||
* factor 2.78 (e) change in fog density.
|
||||
*
|
||||
* A falloff of 0 means the fog density is constant everywhere and may result is slightly
|
||||
* faster computations.
|
||||
*
|
||||
* In `linearFog` mode, only use to compute the slope of the linear equation. Completely
|
||||
* ignored if set to 0.
|
||||
*/
|
||||
public float heightFalloff = 1.0f;
|
||||
/**
|
||||
@@ -1612,7 +1617,7 @@ public class View {
|
||||
@NonNull @Size(min = 3)
|
||||
public float[] color = {1.0f, 1.0f, 1.0f};
|
||||
/**
|
||||
* Extinction factor in [1/m] at altitude 'height'. The extinction factor controls how much
|
||||
* Extinction factor in [1/m] at an altitude 'height'. The extinction factor controls how much
|
||||
* light is absorbed and out-scattered per unit of distance. Each unit of extinction reduces
|
||||
* the incoming light to 37% of its original value.
|
||||
*
|
||||
@@ -1621,10 +1626,15 @@ public class View {
|
||||
* the composition of the fog/atmosphere.
|
||||
*
|
||||
* For historical reason this parameter is called `density`.
|
||||
*
|
||||
* In `linearFog` mode this is the slope of the linear equation if heightFalloff is set to 0.
|
||||
* Otherwise, heightFalloff affects the slope calculation such that it matches the slope of
|
||||
* the standard equation at the camera height.
|
||||
*/
|
||||
public float density = 0.1f;
|
||||
/**
|
||||
* Distance in world units [m] from the camera where the Sun in-scattering starts.
|
||||
* Ignored in `linearFog` mode.
|
||||
*/
|
||||
public float inScatteringStart = 0.0f;
|
||||
/**
|
||||
@@ -1632,6 +1642,7 @@ public class View {
|
||||
* is scattered (by the fog) towards the camera.
|
||||
* Size of the Sun in-scattering (>0 to activate). Good values are >> 1 (e.g. ~10 - 100).
|
||||
* Smaller values result is a larger scattering size.
|
||||
* Ignored in `linearFog` mode.
|
||||
*/
|
||||
public float inScatteringSize = -1.0f;
|
||||
/**
|
||||
@@ -1657,6 +1668,8 @@ public class View {
|
||||
*
|
||||
* `fogColorFromIbl` is ignored when skyTexture is specified.
|
||||
*
|
||||
* In `linearFog` mode mipmap level 0 is always used.
|
||||
*
|
||||
* @see Texture
|
||||
* @see fogColorFromIbl
|
||||
*/
|
||||
@@ -1671,7 +1684,7 @@ public class View {
|
||||
/**
|
||||
* Options to control Depth of Field (DoF) effect in the scene.
|
||||
*
|
||||
* cocScale can be used to set the depth of field blur independently from the camera
|
||||
* cocScale can be used to set the depth of field blur independently of the camera
|
||||
* aperture, e.g. for artistic reasons. This can be achieved by setting:
|
||||
* cocScale = cameraAperture / desiredDoFAperture
|
||||
*
|
||||
|
||||
@@ -60,6 +60,7 @@ jlong nCreateHDRTexture(JNIEnv* env, jclass,
|
||||
.height(image->getHeight())
|
||||
.levels(0xff)
|
||||
.sampler(Texture::Sampler::SAMPLER_2D)
|
||||
.usage(Texture::Usage::DEFAULT | Texture::Usage::GEN_MIPMAPPABLE)
|
||||
.format(textureFormat)
|
||||
.build(*engine);
|
||||
|
||||
|
||||
+2
-2
@@ -46,8 +46,8 @@ fun loadTexture(engine: Engine, resources: Resources, resourceId: Int, type: Tex
|
||||
.height(bitmap.height)
|
||||
.sampler(Texture.Sampler.SAMPLER_2D)
|
||||
.format(internalFormat(type))
|
||||
// This tells Filament to figure out the number of mip levels
|
||||
.levels(0xff)
|
||||
.levels(0xff) // This tells Filament to figure out the number of mip levels
|
||||
.usage(Texture.Usage.DEFAULT or Texture.Usage.GEN_MIPMAPPABLE)
|
||||
.build(engine)
|
||||
|
||||
// TextureHelper offers a method that skips the copy of the bitmap into a ByteBuffer
|
||||
|
||||
@@ -120,7 +120,7 @@ set(GLTFIO_INCLUDE_DIRS
|
||||
${FILAMENT_DIR}/include
|
||||
../../filament/backend/include
|
||||
../../libs/gltfio/include
|
||||
../../third_party/basisu/zstd
|
||||
../../third_party/zstd/lib
|
||||
../../third_party/cgltf
|
||||
../../third_party/meshoptimizer/src
|
||||
../../third_party/robin-map
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
GROUP=com.google.android.filament
|
||||
VERSION_NAME=1.63.1
|
||||
VERSION_NAME=1.63.0
|
||||
|
||||
POM_DESCRIPTION=Real-time physically based rendering engine for Android.
|
||||
|
||||
|
||||
+1
@@ -276,6 +276,7 @@ public class MainActivity extends Activity
|
||||
.width(bitmap.getWidth())
|
||||
.height(bitmap.getHeight())
|
||||
.sampler(Texture.Sampler.SAMPLER_2D)
|
||||
.usage(Texture.Usage.DEFAULT | Texture.Usage.GEN_MIPMAPPABLE)
|
||||
.format(Texture.InternalFormat.SRGB8_A8) // It is crucial to use an SRGB format.
|
||||
.levels(0xff) // tells Filament to figure out the number of mip levels
|
||||
.build(engine);
|
||||
|
||||
@@ -1199,6 +1199,24 @@ material {
|
||||
}
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
### General: linearFog
|
||||
|
||||
Type
|
||||
: `boolean`
|
||||
|
||||
Value
|
||||
: `true` or `false`. Defaults to `false`.
|
||||
|
||||
Description
|
||||
: When set to `true`, a simplified fog equation is used for large-scale fog calculations. In this mode,
|
||||
in-scattering is ignored as well as height falloff.
|
||||
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ JSON
|
||||
material {
|
||||
linearFog : true
|
||||
}
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
### General: quality
|
||||
|
||||
Type
|
||||
@@ -1263,6 +1281,45 @@ material {
|
||||
}
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
### General: useDefaultDepthVariant
|
||||
|
||||
Type
|
||||
: `boolean`
|
||||
|
||||
Value
|
||||
: `true` or `false`. Defaults to `false`.
|
||||
|
||||
Description
|
||||
: This parameter forces Filament to use its default variant for depth passes, such as those used
|
||||
in shadow rendering. This provides an optimization for materials with expensive custom vertex
|
||||
shaders. For example, custom vertex shader computations intended to be consumed by the fragment
|
||||
stage can be skipped during the depth-only pass. This parameter is only meaningful if the
|
||||
material has a vertex block.
|
||||
This parameter should not be set to `true` for vertex blocks that modify geometry (i.e.,
|
||||
modifying `worldPosition`), otherwise shadows may render incorrectly.
|
||||
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ JSON
|
||||
material {
|
||||
variables : [
|
||||
customColor
|
||||
],
|
||||
useDefaultDepthVariant : true
|
||||
}
|
||||
|
||||
vertex {
|
||||
void materialVertex(inout MaterialVertexInputs material) {
|
||||
material.customColor = /* expensive computation that can be skipped for depth-only passes */
|
||||
}
|
||||
}
|
||||
|
||||
fragment {
|
||||
void material(inout MaterialInputs material) {
|
||||
prepareMaterial(material);
|
||||
material.baseColor = variable_customColor;
|
||||
}
|
||||
}
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
### Vertex and attributes: requires
|
||||
|
||||
Type
|
||||
|
||||
+3
-2
@@ -181,7 +181,7 @@ important for <code>matc</code> (material compiler).</p>
|
||||
}
|
||||
|
||||
dependencies {
|
||||
implementation 'com.google.android.filament:filament-android:1.62.2'
|
||||
implementation 'com.google.android.filament:filament-android:1.63.0'
|
||||
}
|
||||
</code></pre>
|
||||
<p>Here are all the libraries available in the group <code>com.google.android.filament</code>:</p>
|
||||
@@ -196,7 +196,7 @@ dependencies {
|
||||
</div>
|
||||
<h3 id="ios"><a class="header" href="#ios">iOS</a></h3>
|
||||
<p>iOS projects can use CocoaPods to install the latest release:</p>
|
||||
<pre><code class="language-shell">pod 'Filament', '~> 1.62.2'
|
||||
<pre><code class="language-shell">pod 'Filament', '~> 1.63.0'
|
||||
</code></pre>
|
||||
<h2 id="documentation"><a class="header" href="#documentation">Documentation</a></h2>
|
||||
<ul>
|
||||
@@ -501,6 +501,7 @@ and tools.</p>
|
||||
<li><code>filamesh</code>: Mesh converter</li>
|
||||
<li><code>glslminifier</code>: Minifies GLSL source code</li>
|
||||
<li><code>matc</code>: Material compiler</li>
|
||||
<li><code>filament-matp</code>: Material parser</li>
|
||||
<li><code>matinfo</code> Displays information about materials compiled with <code>matc</code></li>
|
||||
<li><code>mipgen</code> Generates a series of miplevels from a source image</li>
|
||||
<li><code>normal-blending</code>: Tool to blend normal maps</li>
|
||||
|
||||
+3
-2
@@ -181,7 +181,7 @@ important for <code>matc</code> (material compiler).</p>
|
||||
}
|
||||
|
||||
dependencies {
|
||||
implementation 'com.google.android.filament:filament-android:1.62.2'
|
||||
implementation 'com.google.android.filament:filament-android:1.63.0'
|
||||
}
|
||||
</code></pre>
|
||||
<p>Here are all the libraries available in the group <code>com.google.android.filament</code>:</p>
|
||||
@@ -196,7 +196,7 @@ dependencies {
|
||||
</div>
|
||||
<h3 id="ios"><a class="header" href="#ios">iOS</a></h3>
|
||||
<p>iOS projects can use CocoaPods to install the latest release:</p>
|
||||
<pre><code class="language-shell">pod 'Filament', '~> 1.62.2'
|
||||
<pre><code class="language-shell">pod 'Filament', '~> 1.63.0'
|
||||
</code></pre>
|
||||
<h2 id="documentation"><a class="header" href="#documentation">Documentation</a></h2>
|
||||
<ul>
|
||||
@@ -501,6 +501,7 @@ and tools.</p>
|
||||
<li><code>filamesh</code>: Mesh converter</li>
|
||||
<li><code>glslminifier</code>: Minifies GLSL source code</li>
|
||||
<li><code>matc</code>: Material compiler</li>
|
||||
<li><code>filament-matp</code>: Material parser</li>
|
||||
<li><code>matinfo</code> Displays information about materials compiled with <code>matc</code></li>
|
||||
<li><code>mipgen</code> Generates a series of miplevels from a source image</li>
|
||||
<li><code>normal-blending</code>: Tool to blend normal maps</li>
|
||||
|
||||
+103
-62
@@ -235,36 +235,38 @@ counter-increment: h6;margin-right:10px}
|
||||
<a href="#materialdefinitions/materialblock/general:constants" target="_self" class="level3"><span class="tocNumber">4.2.5 </span>General: constants</a><br/>
|
||||
<a href="#materialdefinitions/materialblock/general:variantfilter" target="_self" class="level3"><span class="tocNumber">4.2.6 </span>General: variantFilter</a><br/>
|
||||
<a href="#materialdefinitions/materialblock/general:flipuv" target="_self" class="level3"><span class="tocNumber">4.2.7 </span>General: flipUV</a><br/>
|
||||
<a href="#materialdefinitions/materialblock/general:quality" target="_self" class="level3"><span class="tocNumber">4.2.8 </span>General: quality</a><br/>
|
||||
<a href="#materialdefinitions/materialblock/general:instanced" target="_self" class="level3"><span class="tocNumber">4.2.9 </span>General: instanced</a><br/>
|
||||
<a href="#materialdefinitions/materialblock/general:vertexdomaindevicejittered" target="_self" class="level3"><span class="tocNumber">4.2.10 </span>General: vertexDomainDeviceJittered</a><br/>
|
||||
<a href="#materialdefinitions/materialblock/vertexandattributes:requires" target="_self" class="level3"><span class="tocNumber">4.2.11 </span>Vertex and attributes: requires</a><br/>
|
||||
<a href="#materialdefinitions/materialblock/vertexandattributes:variables" target="_self" class="level3"><span class="tocNumber">4.2.12 </span>Vertex and attributes: variables</a><br/>
|
||||
<a href="#materialdefinitions/materialblock/vertexandattributes:vertexdomain" target="_self" class="level3"><span class="tocNumber">4.2.13 </span>Vertex and attributes: vertexDomain</a><br/>
|
||||
<a href="#materialdefinitions/materialblock/vertexandattributes:interpolation" target="_self" class="level3"><span class="tocNumber">4.2.14 </span>Vertex and attributes: interpolation</a><br/>
|
||||
<a href="#materialdefinitions/materialblock/blendingandtransparency:blending" target="_self" class="level3"><span class="tocNumber">4.2.15 </span>Blending and transparency: blending</a><br/>
|
||||
<a href="#materialdefinitions/materialblock/blendingandtransparency:blendfunction" target="_self" class="level3"><span class="tocNumber">4.2.16 </span>Blending and transparency: blendFunction</a><br/>
|
||||
<a href="#materialdefinitions/materialblock/blendingandtransparency:postlightingblending" target="_self" class="level3"><span class="tocNumber">4.2.17 </span>Blending and transparency: postLightingBlending</a><br/>
|
||||
<a href="#materialdefinitions/materialblock/blendingandtransparency:transparency" target="_self" class="level3"><span class="tocNumber">4.2.18 </span>Blending and transparency: transparency</a><br/>
|
||||
<a href="#materialdefinitions/materialblock/blendingandtransparency:maskthreshold" target="_self" class="level3"><span class="tocNumber">4.2.19 </span>Blending and transparency: maskThreshold</a><br/>
|
||||
<a href="#materialdefinitions/materialblock/blendingandtransparency:refractionmode" target="_self" class="level3"><span class="tocNumber">4.2.20 </span>Blending and transparency: refractionMode</a><br/>
|
||||
<a href="#materialdefinitions/materialblock/blendingandtransparency:refractiontype" target="_self" class="level3"><span class="tocNumber">4.2.21 </span>Blending and transparency: refractionType</a><br/>
|
||||
<a href="#materialdefinitions/materialblock/rasterization:culling" target="_self" class="level3"><span class="tocNumber">4.2.22 </span>Rasterization: culling</a><br/>
|
||||
<a href="#materialdefinitions/materialblock/rasterization:colorwrite" target="_self" class="level3"><span class="tocNumber">4.2.23 </span>Rasterization: colorWrite</a><br/>
|
||||
<a href="#materialdefinitions/materialblock/rasterization:depthwrite" target="_self" class="level3"><span class="tocNumber">4.2.24 </span>Rasterization: depthWrite</a><br/>
|
||||
<a href="#materialdefinitions/materialblock/rasterization:depthculling" target="_self" class="level3"><span class="tocNumber">4.2.25 </span>Rasterization: depthCulling</a><br/>
|
||||
<a href="#materialdefinitions/materialblock/rasterization:doublesided" target="_self" class="level3"><span class="tocNumber">4.2.26 </span>Rasterization: doubleSided</a><br/>
|
||||
<a href="#materialdefinitions/materialblock/rasterization:alphatocoverage" target="_self" class="level3"><span class="tocNumber">4.2.27 </span>Rasterization: alphaToCoverage</a><br/>
|
||||
<a href="#materialdefinitions/materialblock/lighting:reflections" target="_self" class="level3"><span class="tocNumber">4.2.28 </span>Lighting: reflections</a><br/>
|
||||
<a href="#materialdefinitions/materialblock/lighting:shadowmultiplier" target="_self" class="level3"><span class="tocNumber">4.2.29 </span>Lighting: shadowMultiplier</a><br/>
|
||||
<a href="#materialdefinitions/materialblock/lighting:transparentshadow" target="_self" class="level3"><span class="tocNumber">4.2.30 </span>Lighting: transparentShadow</a><br/>
|
||||
<a href="#materialdefinitions/materialblock/lighting:clearcoatiorchange" target="_self" class="level3"><span class="tocNumber">4.2.31 </span>Lighting: clearCoatIorChange</a><br/>
|
||||
<a href="#materialdefinitions/materialblock/lighting:multibounceambientocclusion" target="_self" class="level3"><span class="tocNumber">4.2.32 </span>Lighting: multiBounceAmbientOcclusion</a><br/>
|
||||
<a href="#materialdefinitions/materialblock/lighting:specularambientocclusion" target="_self" class="level3"><span class="tocNumber">4.2.33 </span>Lighting: specularAmbientOcclusion</a><br/>
|
||||
<a href="#materialdefinitions/materialblock/anti-aliasing:specularantialiasing" target="_self" class="level3"><span class="tocNumber">4.2.34 </span>Anti-aliasing: specularAntiAliasing</a><br/>
|
||||
<a href="#materialdefinitions/materialblock/anti-aliasing:specularantialiasingvariance" target="_self" class="level3"><span class="tocNumber">4.2.35 </span>Anti-aliasing: specularAntiAliasingVariance</a><br/>
|
||||
<a href="#materialdefinitions/materialblock/anti-aliasing:specularantialiasingthreshold" target="_self" class="level3"><span class="tocNumber">4.2.36 </span>Anti-aliasing: specularAntiAliasingThreshold</a><br/>
|
||||
<a href="#materialdefinitions/materialblock/shading:customsurfaceshading" target="_self" class="level3"><span class="tocNumber">4.2.37 </span>Shading: customSurfaceShading</a><br/>
|
||||
<a href="#materialdefinitions/materialblock/general:linearfog" target="_self" class="level3"><span class="tocNumber">4.2.8 </span>General: linearFog</a><br/>
|
||||
<a href="#materialdefinitions/materialblock/general:quality" target="_self" class="level3"><span class="tocNumber">4.2.9 </span>General: quality</a><br/>
|
||||
<a href="#materialdefinitions/materialblock/general:instanced" target="_self" class="level3"><span class="tocNumber">4.2.10 </span>General: instanced</a><br/>
|
||||
<a href="#materialdefinitions/materialblock/general:vertexdomaindevicejittered" target="_self" class="level3"><span class="tocNumber">4.2.11 </span>General: vertexDomainDeviceJittered</a><br/>
|
||||
<a href="#materialdefinitions/materialblock/general:usedefaultdepthvariant" target="_self" class="level3"><span class="tocNumber">4.2.12 </span>General: useDefaultDepthVariant</a><br/>
|
||||
<a href="#materialdefinitions/materialblock/vertexandattributes:requires" target="_self" class="level3"><span class="tocNumber">4.2.13 </span>Vertex and attributes: requires</a><br/>
|
||||
<a href="#materialdefinitions/materialblock/vertexandattributes:variables" target="_self" class="level3"><span class="tocNumber">4.2.14 </span>Vertex and attributes: variables</a><br/>
|
||||
<a href="#materialdefinitions/materialblock/vertexandattributes:vertexdomain" target="_self" class="level3"><span class="tocNumber">4.2.15 </span>Vertex and attributes: vertexDomain</a><br/>
|
||||
<a href="#materialdefinitions/materialblock/vertexandattributes:interpolation" target="_self" class="level3"><span class="tocNumber">4.2.16 </span>Vertex and attributes: interpolation</a><br/>
|
||||
<a href="#materialdefinitions/materialblock/blendingandtransparency:blending" target="_self" class="level3"><span class="tocNumber">4.2.17 </span>Blending and transparency: blending</a><br/>
|
||||
<a href="#materialdefinitions/materialblock/blendingandtransparency:blendfunction" target="_self" class="level3"><span class="tocNumber">4.2.18 </span>Blending and transparency: blendFunction</a><br/>
|
||||
<a href="#materialdefinitions/materialblock/blendingandtransparency:postlightingblending" target="_self" class="level3"><span class="tocNumber">4.2.19 </span>Blending and transparency: postLightingBlending</a><br/>
|
||||
<a href="#materialdefinitions/materialblock/blendingandtransparency:transparency" target="_self" class="level3"><span class="tocNumber">4.2.20 </span>Blending and transparency: transparency</a><br/>
|
||||
<a href="#materialdefinitions/materialblock/blendingandtransparency:maskthreshold" target="_self" class="level3"><span class="tocNumber">4.2.21 </span>Blending and transparency: maskThreshold</a><br/>
|
||||
<a href="#materialdefinitions/materialblock/blendingandtransparency:refractionmode" target="_self" class="level3"><span class="tocNumber">4.2.22 </span>Blending and transparency: refractionMode</a><br/>
|
||||
<a href="#materialdefinitions/materialblock/blendingandtransparency:refractiontype" target="_self" class="level3"><span class="tocNumber">4.2.23 </span>Blending and transparency: refractionType</a><br/>
|
||||
<a href="#materialdefinitions/materialblock/rasterization:culling" target="_self" class="level3"><span class="tocNumber">4.2.24 </span>Rasterization: culling</a><br/>
|
||||
<a href="#materialdefinitions/materialblock/rasterization:colorwrite" target="_self" class="level3"><span class="tocNumber">4.2.25 </span>Rasterization: colorWrite</a><br/>
|
||||
<a href="#materialdefinitions/materialblock/rasterization:depthwrite" target="_self" class="level3"><span class="tocNumber">4.2.26 </span>Rasterization: depthWrite</a><br/>
|
||||
<a href="#materialdefinitions/materialblock/rasterization:depthculling" target="_self" class="level3"><span class="tocNumber">4.2.27 </span>Rasterization: depthCulling</a><br/>
|
||||
<a href="#materialdefinitions/materialblock/rasterization:doublesided" target="_self" class="level3"><span class="tocNumber">4.2.28 </span>Rasterization: doubleSided</a><br/>
|
||||
<a href="#materialdefinitions/materialblock/rasterization:alphatocoverage" target="_self" class="level3"><span class="tocNumber">4.2.29 </span>Rasterization: alphaToCoverage</a><br/>
|
||||
<a href="#materialdefinitions/materialblock/lighting:reflections" target="_self" class="level3"><span class="tocNumber">4.2.30 </span>Lighting: reflections</a><br/>
|
||||
<a href="#materialdefinitions/materialblock/lighting:shadowmultiplier" target="_self" class="level3"><span class="tocNumber">4.2.31 </span>Lighting: shadowMultiplier</a><br/>
|
||||
<a href="#materialdefinitions/materialblock/lighting:transparentshadow" target="_self" class="level3"><span class="tocNumber">4.2.32 </span>Lighting: transparentShadow</a><br/>
|
||||
<a href="#materialdefinitions/materialblock/lighting:clearcoatiorchange" target="_self" class="level3"><span class="tocNumber">4.2.33 </span>Lighting: clearCoatIorChange</a><br/>
|
||||
<a href="#materialdefinitions/materialblock/lighting:multibounceambientocclusion" target="_self" class="level3"><span class="tocNumber">4.2.34 </span>Lighting: multiBounceAmbientOcclusion</a><br/>
|
||||
<a href="#materialdefinitions/materialblock/lighting:specularambientocclusion" target="_self" class="level3"><span class="tocNumber">4.2.35 </span>Lighting: specularAmbientOcclusion</a><br/>
|
||||
<a href="#materialdefinitions/materialblock/anti-aliasing:specularantialiasing" target="_self" class="level3"><span class="tocNumber">4.2.36 </span>Anti-aliasing: specularAntiAliasing</a><br/>
|
||||
<a href="#materialdefinitions/materialblock/anti-aliasing:specularantialiasingvariance" target="_self" class="level3"><span class="tocNumber">4.2.37 </span>Anti-aliasing: specularAntiAliasingVariance</a><br/>
|
||||
<a href="#materialdefinitions/materialblock/anti-aliasing:specularantialiasingthreshold" target="_self" class="level3"><span class="tocNumber">4.2.38 </span>Anti-aliasing: specularAntiAliasingThreshold</a><br/>
|
||||
<a href="#materialdefinitions/materialblock/shading:customsurfaceshading" target="_self" class="level3"><span class="tocNumber">4.2.39 </span>Shading: customSurfaceShading</a><br/>
|
||||
<a href="#materialdefinitions/vertexblock" target="_self" class="level2"><span class="tocNumber">4.3 </span>Vertex block</a><br/>
|
||||
<a href="#materialdefinitions/vertexblock/materialvertexinputs" target="_self" class="level3"><span class="tocNumber">4.3.1 </span>Material vertex inputs</a><br/>
|
||||
<a href="#materialdefinitions/vertexblock/customvertexattributes" target="_self" class="level3"><span class="tocNumber">4.3.2 </span>Custom vertex attributes</a><br/>
|
||||
@@ -731,7 +733,7 @@ Note that the <code>normal</code> property affects the <em class="underscore">ba
|
||||
<p>
|
||||
<p>The <code>bentNormal</code> property defines the average unoccluded direction at a point on the surface. It is
|
||||
used to improve the accuracy of indirect lighting. Bent normals can also improve the quality of
|
||||
specular ambient occlusion (see section <a href="#toc4.2.33" target="_self">4.2.33</a> about
|
||||
specular ambient occlusion (see section <a href="#toc4.2.35" target="_self">4.2.35</a> about
|
||||
<code>specularAmbientOcclusion</code>).</p>
|
||||
</p><p>
|
||||
Bent normals can greatly increase the visual fidelity of an asset with various cavities and concave
|
||||
@@ -810,7 +812,7 @@ light to bend further away from the initial path.
|
||||
</table><center><div class="tablecaption"><b style="font-style:normal;">Table 6:</b> Index of refraction of common materials</div></center></div>
|
||||
</p><p>
|
||||
The appearance of a refractive material will greatly depend on the <code>refractionType</code> and
|
||||
<code>refractionMode</code> settings of the material. Refer to section <a href="#toc4.2.21" target="_self">4.2.21</a> and section <a href="#toc4.2.20" target="_self">4.2.20</a>
|
||||
<code>refractionMode</code> settings of the material. Refer to section <a href="#toc4.2.23" target="_self">4.2.23</a> and section <a href="#toc4.2.22" target="_self">4.2.22</a>
|
||||
for more information.
|
||||
</p><p>
|
||||
The effect of <code>ior</code> when <code>refractionMode</code> is set to <code>cubemap</code> and <code>refractionType</code> is set to <code>solid</code>
|
||||
@@ -1400,7 +1402,16 @@ non-shader data.</p>
|
||||
</p></dd></dl></p><pre class="listing tilde"><code><span class="line"></span>material <span class="hljs-punctuation">{</span>
|
||||
<span class="line"></span> flipUV <span class="hljs-punctuation">:</span> <span class="hljs-literal"><span class="hljs-keyword">false</span></span>
|
||||
<span class="line"></span><span class="hljs-punctuation">}</span></code></pre>
|
||||
<a class="target" name="general:quality"> </a><a class="target" name="materialdefinitions/materialblock/general:quality"> </a><a class="target" name="toc4.2.8"> </a><h3 id="general-quality"><a class="header" href="#general-quality">General: quality</a></h3>
|
||||
<a class="target" name="general:linearfog"> </a><a class="target" name="materialdefinitions/materialblock/general:linearfog"> </a><a class="target" name="toc4.2.8"> </a><h3 id="general-linearfog"><a class="header" href="#general-linearfog">General: linearFog</a></h3>
|
||||
<p>
|
||||
<dl><dt>Type</dt><dd><p> <code>boolean</code>
|
||||
</p></dd><dt>Value</dt><dd><p> <code>true</code> or <code>false</code>. Defaults to <code>false</code>.
|
||||
</p></dd><dt>Description</dt><dd><p> When set to <code>true</code>, a simplified fog equation is used for large-scale fog calculations. In this mode,
|
||||
in-scattering is ignored as well as height falloff.
|
||||
</p></dd></dl></p><pre class="listing tilde"><code><span class="line"></span>material <span class="hljs-punctuation">{</span>
|
||||
<span class="line"></span> linearFog <span class="hljs-punctuation">:</span> <span class="hljs-literal"><span class="hljs-keyword">true</span></span>
|
||||
<span class="line"></span><span class="hljs-punctuation">}</span></code></pre>
|
||||
<a class="target" name="general:quality"> </a><a class="target" name="materialdefinitions/materialblock/general:quality"> </a><a class="target" name="toc4.2.9"> </a><h3 id="general-quality"><a class="header" href="#general-quality">General: quality</a></h3>
|
||||
<p>
|
||||
<dl><dt>Type</dt><dd><p> <code>string</code>
|
||||
</p></dd><dt>Value</dt><dd><p> Any of <code>low</code>, <code>normal</code>, <code>high</code>, <code>default</code>. Defaults to <code>default</code>.
|
||||
@@ -1411,7 +1422,7 @@ non-shader data.</p>
|
||||
</p></dd></dl></p><pre class="listing tilde"><code><span class="line"></span>material <span class="hljs-punctuation">{</span>
|
||||
<span class="line"></span> quality <span class="hljs-punctuation">:</span> default
|
||||
<span class="line"></span><span class="hljs-punctuation">}</span></code></pre>
|
||||
<a class="target" name="general:instanced"> </a><a class="target" name="materialdefinitions/materialblock/general:instanced"> </a><a class="target" name="toc4.2.9"> </a><h3 id="general-instanced"><a class="header" href="#general-instanced">General: instanced</a></h3>
|
||||
<a class="target" name="general:instanced"> </a><a class="target" name="materialdefinitions/materialblock/general:instanced"> </a><a class="target" name="toc4.2.10"> </a><h3 id="general-instanced"><a class="header" href="#general-instanced">General: instanced</a></h3>
|
||||
<p>
|
||||
<dl><dt>Type</dt><dd><p> <code>boolean</code>
|
||||
</p></dd><dt>Value</dt><dd><p> <code>true</code> or <code>false</code>. Defaults to <code>false</code>.
|
||||
@@ -1423,7 +1434,7 @@ non-shader data.</p>
|
||||
</p></dd></dl></p><pre class="listing tilde"><code><span class="line"></span>material <span class="hljs-punctuation">{</span>
|
||||
<span class="line"></span> instanced <span class="hljs-punctuation">:</span> <span class="hljs-literal"><span class="hljs-keyword">true</span></span>
|
||||
<span class="line"></span><span class="hljs-punctuation">}</span></code></pre>
|
||||
<a class="target" name="general:vertexdomaindevicejittered"> </a><a class="target" name="materialdefinitions/materialblock/general:vertexdomaindevicejittered"> </a><a class="target" name="toc4.2.10"> </a><h3 id="general-vertexdomaindevicejittered"><a class="header" href="#general-vertexdomaindevicejittered">General: vertexDomainDeviceJittered</a></h3>
|
||||
<a class="target" name="general:vertexdomaindevicejittered"> </a><a class="target" name="materialdefinitions/materialblock/general:vertexdomaindevicejittered"> </a><a class="target" name="toc4.2.11"> </a><h3 id="general-vertexdomaindevicejittered"><a class="header" href="#general-vertexdomaindevicejittered">General: vertexDomainDeviceJittered</a></h3>
|
||||
<p>
|
||||
<dl><dt>Type</dt><dd><p> <code>boolean</code>
|
||||
</p></dd><dt>Value</dt><dd><p> <code>true</code> or <code>false</code>. Defaults to <code>false</code>.
|
||||
@@ -1437,7 +1448,37 @@ non-shader data.</p>
|
||||
</p></dd></dl></p><pre class="listing tilde"><code><span class="line"></span>material <span class="hljs-punctuation">{</span>
|
||||
<span class="line"></span> vertexDomainDeviceJittered <span class="hljs-punctuation">:</span> <span class="hljs-literal"><span class="hljs-keyword">true</span></span>
|
||||
<span class="line"></span><span class="hljs-punctuation">}</span></code></pre>
|
||||
<a class="target" name="vertexandattributes:requires"> </a><a class="target" name="materialdefinitions/materialblock/vertexandattributes:requires"> </a><a class="target" name="toc4.2.11"> </a><h3 id="vertex-and-attributes-requires"><a class="header" href="#vertex-and-attributes-requires">Vertex and attributes: requires</a></h3>
|
||||
<a class="target" name="general:usedefaultdepthvariant"> </a><a class="target" name="materialdefinitions/materialblock/general:usedefaultdepthvariant"> </a><a class="target" name="toc4.2.12"> </a><h3 id="general-usedefaultdepthvariant"><a class="header" href="#general-usedefaultdepthvariant">General: useDefaultDepthVariant</a></h3>
|
||||
<p>
|
||||
<dl><dt>Type</dt><dd><p> <code>boolean</code>
|
||||
</p></dd><dt>Value</dt><dd><p> <code>true</code> or <code>false</code>. Defaults to <code>false</code>.
|
||||
</p></dd><dt>Description</dt><dd><p> This parameter forces Filament to use its default variant for depth passes, such as those used
|
||||
in shadow rendering. This provides an optimization for materials with expensive custom vertex
|
||||
shaders. For example, custom vertex shader computations intended to be consumed by the fragment
|
||||
stage can be skipped during the depth-only pass. This parameter is only meaningful if the
|
||||
material has a vertex block.
|
||||
This parameter should not be set to <code>true</code> for vertex blocks that modify geometry (i.e.,
|
||||
modifying <code>worldPosition</code>), otherwise shadows may render incorrectly.
|
||||
</p></dd></dl></p><pre class="listing tilde"><code><span class="line"></span>material <span class="hljs-punctuation">{</span>
|
||||
<span class="line"></span> variables <span class="hljs-punctuation">:</span> <span class="hljs-punctuation">[</span>
|
||||
<span class="line"></span> customColor
|
||||
<span class="line"></span> <span class="hljs-punctuation">]</span><span class="hljs-punctuation">,</span>
|
||||
<span class="line"></span> useDefaultDepthVariant <span class="hljs-punctuation">:</span> <span class="hljs-literal"><span class="hljs-keyword">true</span></span>
|
||||
<span class="line"></span><span class="hljs-punctuation">}</span>
|
||||
<span class="line"></span>
|
||||
<span class="line"></span>vertex <span class="hljs-punctuation">{</span>
|
||||
<span class="line"></span> void materialVertex(inout MaterialVertexInputs material) <span class="hljs-punctuation">{</span>
|
||||
<span class="line"></span> material.customColor = <span class="hljs-comment">/* expensive computation that can be skipped for depth-only passes */</span>
|
||||
<span class="line"></span> <span class="hljs-punctuation">}</span>
|
||||
<span class="line"></span><span class="hljs-punctuation">}</span>
|
||||
<span class="line"></span>
|
||||
<span class="line"></span>fragment <span class="hljs-punctuation">{</span>
|
||||
<span class="line"></span> void material(inout MaterialInputs material) <span class="hljs-punctuation">{</span>
|
||||
<span class="line"></span> prepareMaterial(material);
|
||||
<span class="line"></span> material.baseColor = variable_customColor;
|
||||
<span class="line"></span> <span class="hljs-punctuation">}</span>
|
||||
<span class="line"></span><span class="hljs-punctuation">}</span></code></pre>
|
||||
<a class="target" name="vertexandattributes:requires"> </a><a class="target" name="materialdefinitions/materialblock/vertexandattributes:requires"> </a><a class="target" name="toc4.2.13"> </a><h3 id="vertex-and-attributes-requires"><a class="header" href="#vertex-and-attributes-requires">Vertex and attributes: requires</a></h3>
|
||||
<p>
|
||||
<dl><dt>Type</dt><dd><p> array of <code>string</code>
|
||||
</p></dd><dt>Value</dt><dd><p> Each entry must be any of <code>uv0</code>, <code>uv1</code>, <code>color</code>, <code>position</code>, <code>tangents</code>, <code>custom0</code>
|
||||
@@ -1470,7 +1511,7 @@ non-shader data.</p>
|
||||
<span class="line"></span> material.baseColor.rgb *= getCustom0().rgb;
|
||||
<span class="line"></span> <span class="hljs-punctuation">}</span>
|
||||
<span class="line"></span><span class="hljs-punctuation">}</span></code></pre>
|
||||
<a class="target" name="vertexandattributes:variables"> </a><a class="target" name="materialdefinitions/materialblock/vertexandattributes:variables"> </a><a class="target" name="toc4.2.12"> </a><h3 id="vertex-and-attributes-variables"><a class="header" href="#vertex-and-attributes-variables">Vertex and attributes: variables</a></h3>
|
||||
<a class="target" name="vertexandattributes:variables"> </a><a class="target" name="materialdefinitions/materialblock/vertexandattributes:variables"> </a><a class="target" name="toc4.2.14"> </a><h3 id="vertex-and-attributes-variables"><a class="header" href="#vertex-and-attributes-variables">Vertex and attributes: variables</a></h3>
|
||||
<p>
|
||||
<dl><dt>Type</dt><dd><p> array of <code>string</code>
|
||||
</p></dd><dt>Value</dt><dd><p> Up to 5 strings, each must be a valid GLSL identifier.
|
||||
@@ -1525,7 +1566,7 @@ non-shader data.</p>
|
||||
<span class="line"></span> material.eyeDirection.xyz = mulMat3x3Float3(getWorldFromViewMatrix()<span class="hljs-punctuation">,</span> u);
|
||||
<span class="line"></span> <span class="hljs-punctuation">}</span>
|
||||
<span class="line"></span><span class="hljs-punctuation">}</span></code></pre>
|
||||
<a class="target" name="vertexandattributes:vertexdomain"> </a><a class="target" name="materialdefinitions/materialblock/vertexandattributes:vertexdomain"> </a><a class="target" name="toc4.2.13"> </a><h3 id="vertex-and-attributes-vertexdomain"><a class="header" href="#vertex-and-attributes-vertexdomain">Vertex and attributes: vertexDomain</a></h3>
|
||||
<a class="target" name="vertexandattributes:vertexdomain"> </a><a class="target" name="materialdefinitions/materialblock/vertexandattributes:vertexdomain"> </a><a class="target" name="toc4.2.15"> </a><h3 id="vertex-and-attributes-vertexdomain"><a class="header" href="#vertex-and-attributes-vertexdomain">Vertex and attributes: vertexDomain</a></h3>
|
||||
<p>
|
||||
<dl><dt>Type</dt><dd><p> <code>string</code>
|
||||
</p></dd><dt>Value</dt><dd><p> Any of <code>object</code>, <code>world</code>, <code>view</code>, <code>device</code>. Defaults to <code>object</code>.
|
||||
@@ -1547,7 +1588,7 @@ non-shader data.</p>
|
||||
</p></dd></dl></p><pre class="listing tilde"><code><span class="line"></span>material <span class="hljs-punctuation">{</span>
|
||||
<span class="line"></span> vertexDomain <span class="hljs-punctuation">:</span> device
|
||||
<span class="line"></span><span class="hljs-punctuation">}</span></code></pre>
|
||||
<a class="target" name="vertexandattributes:interpolation"> </a><a class="target" name="materialdefinitions/materialblock/vertexandattributes:interpolation"> </a><a class="target" name="toc4.2.14"> </a><h3 id="vertex-and-attributes-interpolation"><a class="header" href="#vertex-and-attributes-interpolation">Vertex and attributes: interpolation</a></h3>
|
||||
<a class="target" name="vertexandattributes:interpolation"> </a><a class="target" name="materialdefinitions/materialblock/vertexandattributes:interpolation"> </a><a class="target" name="toc4.2.16"> </a><h3 id="vertex-and-attributes-interpolation"><a class="header" href="#vertex-and-attributes-interpolation">Vertex and attributes: interpolation</a></h3>
|
||||
<p>
|
||||
<dl><dt>Type</dt><dd><p> <code>string</code>
|
||||
</p></dd><dt>Value</dt><dd><p> Any of <code>smooth</code>, <code>flat</code>. Defaults to <code>smooth</code>.
|
||||
@@ -1558,7 +1599,7 @@ non-shader data.</p>
|
||||
</p></dd></dl></p><pre class="listing tilde"><code><span class="line"></span>material <span class="hljs-punctuation">{</span>
|
||||
<span class="line"></span> interpolation <span class="hljs-punctuation">:</span> flat
|
||||
<span class="line"></span><span class="hljs-punctuation">}</span></code></pre>
|
||||
<a class="target" name="blendingandtransparency:blending"> </a><a class="target" name="materialdefinitions/materialblock/blendingandtransparency:blending"> </a><a class="target" name="toc4.2.15"> </a><h3 id="blending-and-transparency-blending"><a class="header" href="#blending-and-transparency-blending">Blending and transparency: blending</a></h3>
|
||||
<a class="target" name="blendingandtransparency:blending"> </a><a class="target" name="materialdefinitions/materialblock/blendingandtransparency:blending"> </a><a class="target" name="toc4.2.17"> </a><h3 id="blending-and-transparency-blending"><a class="header" href="#blending-and-transparency-blending">Blending and transparency: blending</a></h3>
|
||||
<p>
|
||||
<dl><dt>Type</dt><dd><p> <code>string</code>
|
||||
</p></dd><dt>Value</dt><dd><p> Any of <code>opaque</code>, <code>transparent</code>, <code>fade</code>, <code>add</code>, <code>masked</code>, <code>multiply</code>, <code>screen</code>, <code>custom</code>. Defaults to <code>opaque</code>.
|
||||
@@ -1597,7 +1638,7 @@ non-shader data.</p>
|
||||
</p><pre class="listing tilde"><code><span class="line"></span>material <span class="hljs-punctuation">{</span>
|
||||
<span class="line"></span> blending <span class="hljs-punctuation">:</span> transparent
|
||||
<span class="line"></span><span class="hljs-punctuation">}</span></code></pre>
|
||||
<a class="target" name="blendingandtransparency:blendfunction"> </a><a class="target" name="materialdefinitions/materialblock/blendingandtransparency:blendfunction"> </a><a class="target" name="toc4.2.16"> </a><h3 id="blending-and-transparency-blendfunction"><a class="header" href="#blending-and-transparency-blendfunction">Blending and transparency: blendFunction</a></h3>
|
||||
<a class="target" name="blendingandtransparency:blendfunction"> </a><a class="target" name="materialdefinitions/materialblock/blendingandtransparency:blendfunction"> </a><a class="target" name="toc4.2.18"> </a><h3 id="blending-and-transparency-blendfunction"><a class="header" href="#blending-and-transparency-blendfunction">Blending and transparency: blendFunction</a></h3>
|
||||
<p>
|
||||
<dl><dt>Type</dt><dd><p> <code>object</code>
|
||||
</p></dd><dt>Fields</dt><dd><p> <code>srcRGB</code>, <code>srcA</code>, <code>dstRGB</code>, <code>dstA</code>
|
||||
@@ -1618,7 +1659,7 @@ non-shader data.</p>
|
||||
<span class="line"></span> dstA<span class="hljs-punctuation">:</span> oneMinusSrcAlpha
|
||||
<span class="line"></span> <span class="hljs-punctuation">}</span>
|
||||
<span class="line"></span> <span class="hljs-punctuation">}</span></code></pre>
|
||||
<a class="target" name="blendingandtransparency:postlightingblending"> </a><a class="target" name="materialdefinitions/materialblock/blendingandtransparency:postlightingblending"> </a><a class="target" name="toc4.2.17"> </a><h3 id="blending-and-transparency-postlightingblending"><a class="header" href="#blending-and-transparency-postlightingblending">Blending and transparency: postLightingBlending</a></h3>
|
||||
<a class="target" name="blendingandtransparency:postlightingblending"> </a><a class="target" name="materialdefinitions/materialblock/blendingandtransparency:postlightingblending"> </a><a class="target" name="toc4.2.19"> </a><h3 id="blending-and-transparency-postlightingblending"><a class="header" href="#blending-and-transparency-postlightingblending">Blending and transparency: postLightingBlending</a></h3>
|
||||
<p>
|
||||
<dl><dt>Type</dt><dd><p> <code>string</code>
|
||||
</p></dd><dt>Value</dt><dd><p> Any of <code>opaque</code>, <code>transparent</code>, <code>add</code>. Defaults to <code>transparent</code>.
|
||||
@@ -1641,7 +1682,7 @@ non-shader data.</p>
|
||||
</p></dd></dl></p><pre class="listing tilde"><code><span class="line"></span>material <span class="hljs-punctuation">{</span>
|
||||
<span class="line"></span> postLightingBlending <span class="hljs-punctuation">:</span> add
|
||||
<span class="line"></span><span class="hljs-punctuation">}</span></code></pre>
|
||||
<a class="target" name="blendingandtransparency:transparency"> </a><a class="target" name="materialdefinitions/materialblock/blendingandtransparency:transparency"> </a><a class="target" name="toc4.2.18"> </a><h3 id="blending-and-transparency-transparency"><a class="header" href="#blending-and-transparency-transparency">Blending and transparency: transparency</a></h3>
|
||||
<a class="target" name="blendingandtransparency:transparency"> </a><a class="target" name="materialdefinitions/materialblock/blendingandtransparency:transparency"> </a><a class="target" name="toc4.2.20"> </a><h3 id="blending-and-transparency-transparency"><a class="header" href="#blending-and-transparency-transparency">Blending and transparency: transparency</a></h3>
|
||||
<p>
|
||||
<dl><dt>Type</dt><dd><p> <code>string</code>
|
||||
</p></dd><dt>Value</dt><dd><p> Any of <code>default</code>, <code>twoPassesOneSide</code> or <code>twoPassesTwoSides</code>. Defaults to <code>default</code>.
|
||||
@@ -1674,7 +1715,7 @@ non-shader data.</p>
|
||||
<center><div class="image" style=""><a class="target" name="figure_transparencytwopassestwosides"> </a><a href="../images/screenshot_twopasses_twosides.png" target="_blank"><img class="markdeep" src="../images/screenshot_twopasses_twosides.png" /></a><center><span class="imagecaption"><b style="font-style:normal;">Figure 35:</b> In <code>twoPassesTwoSides</code> mode, both set of faces are visible
|
||||
</span></center></div></center>
|
||||
</p>
|
||||
<a class="target" name="blendingandtransparency:maskthreshold"> </a><a class="target" name="materialdefinitions/materialblock/blendingandtransparency:maskthreshold"> </a><a class="target" name="toc4.2.19"> </a><h3 id="blending-and-transparency-maskthreshold"><a class="header" href="#blending-and-transparency-maskthreshold">Blending and transparency: maskThreshold</a></h3>
|
||||
<a class="target" name="blendingandtransparency:maskthreshold"> </a><a class="target" name="materialdefinitions/materialblock/blendingandtransparency:maskthreshold"> </a><a class="target" name="toc4.2.21"> </a><h3 id="blending-and-transparency-maskthreshold"><a class="header" href="#blending-and-transparency-maskthreshold">Blending and transparency: maskThreshold</a></h3>
|
||||
<p>
|
||||
<dl><dt>Type</dt><dd><p> <code>number</code>
|
||||
</p></dd><dt>Value</dt><dd><p> A value between <code>0.0</code> and <code>1.0</code>. Defaults to <code>0.4</code>.
|
||||
@@ -1686,7 +1727,7 @@ non-shader data.</p>
|
||||
<span class="line"></span> blending <span class="hljs-punctuation">:</span> masked<span class="hljs-punctuation">,</span>
|
||||
<span class="line"></span> maskThreshold <span class="hljs-punctuation">:</span> <span class="hljs-number">0.5</span>
|
||||
<span class="line"></span><span class="hljs-punctuation">}</span></code></pre>
|
||||
<a class="target" name="blendingandtransparency:refractionmode"> </a><a class="target" name="materialdefinitions/materialblock/blendingandtransparency:refractionmode"> </a><a class="target" name="toc4.2.20"> </a><h3 id="blending-and-transparency-refractionmode"><a class="header" href="#blending-and-transparency-refractionmode">Blending and transparency: refractionMode</a></h3>
|
||||
<a class="target" name="blendingandtransparency:refractionmode"> </a><a class="target" name="materialdefinitions/materialblock/blendingandtransparency:refractionmode"> </a><a class="target" name="toc4.2.22"> </a><h3 id="blending-and-transparency-refractionmode"><a class="header" href="#blending-and-transparency-refractionmode">Blending and transparency: refractionMode</a></h3>
|
||||
<p>
|
||||
<dl><dt>Type</dt><dd><p> <code>string</code>
|
||||
</p></dd><dt>Value</dt><dd><p> Any of <code>none</code>, <code>cubemap</code>, <code>screenspace</code>. Defaults to <code>none</code>.
|
||||
@@ -1702,7 +1743,7 @@ non-shader data.</p>
|
||||
</p></dd></dl></p><pre class="listing tilde"><code><span class="line"></span>material <span class="hljs-punctuation">{</span>
|
||||
<span class="line"></span> refractionMode <span class="hljs-punctuation">:</span> cubemap<span class="hljs-punctuation">,</span>
|
||||
<span class="line"></span><span class="hljs-punctuation">}</span></code></pre>
|
||||
<a class="target" name="blendingandtransparency:refractiontype"> </a><a class="target" name="materialdefinitions/materialblock/blendingandtransparency:refractiontype"> </a><a class="target" name="toc4.2.21"> </a><h3 id="blending-and-transparency-refractiontype"><a class="header" href="#blending-and-transparency-refractiontype">Blending and transparency: refractionType</a></h3>
|
||||
<a class="target" name="blendingandtransparency:refractiontype"> </a><a class="target" name="materialdefinitions/materialblock/blendingandtransparency:refractiontype"> </a><a class="target" name="toc4.2.23"> </a><h3 id="blending-and-transparency-refractiontype"><a class="header" href="#blending-and-transparency-refractiontype">Blending and transparency: refractionType</a></h3>
|
||||
<p>
|
||||
<dl><dt>Type</dt><dd><p> <code>string</code>
|
||||
</p></dd><dt>Value</dt><dd><p> Any of <code>solid</code>, <code>thin</code>. Defaults to <code>solid</code>.
|
||||
@@ -1716,7 +1757,7 @@ non-shader data.</p>
|
||||
<span class="line"></span> refractionMode <span class="hljs-punctuation">:</span> cubemap<span class="hljs-punctuation">,</span>
|
||||
<span class="line"></span> refractionType <span class="hljs-punctuation">:</span> thin<span class="hljs-punctuation">,</span>
|
||||
<span class="line"></span><span class="hljs-punctuation">}</span></code></pre>
|
||||
<a class="target" name="rasterization:culling"> </a><a class="target" name="materialdefinitions/materialblock/rasterization:culling"> </a><a class="target" name="toc4.2.22"> </a><h3 id="rasterization-culling"><a class="header" href="#rasterization-culling">Rasterization: culling</a></h3>
|
||||
<a class="target" name="rasterization:culling"> </a><a class="target" name="materialdefinitions/materialblock/rasterization:culling"> </a><a class="target" name="toc4.2.24"> </a><h3 id="rasterization-culling"><a class="header" href="#rasterization-culling">Rasterization: culling</a></h3>
|
||||
<p>
|
||||
<dl><table><tr valign=top><td><dt>Type</dt></td><td><dd><p> <code>string</code>
|
||||
</p></dd></td></tr><tr valign=top><td><dt>Value</dt></td><td><dd><p> Any of <code>none</code>, <code>front</code>, <code>back</code>, <code>frontAndBack</code>. Defaults to <code>back</code>.
|
||||
@@ -1725,7 +1766,7 @@ non-shader data.</p>
|
||||
</p></dd></td></tr></table></dl></p><pre class="listing tilde"><code><span class="line"></span>material <span class="hljs-punctuation">{</span>
|
||||
<span class="line"></span> culling <span class="hljs-punctuation">:</span> none
|
||||
<span class="line"></span><span class="hljs-punctuation">}</span></code></pre>
|
||||
<a class="target" name="rasterization:colorwrite"> </a><a class="target" name="materialdefinitions/materialblock/rasterization:colorwrite"> </a><a class="target" name="toc4.2.23"> </a><h3 id="rasterization-colorwrite"><a class="header" href="#rasterization-colorwrite">Rasterization: colorWrite</a></h3>
|
||||
<a class="target" name="rasterization:colorwrite"> </a><a class="target" name="materialdefinitions/materialblock/rasterization:colorwrite"> </a><a class="target" name="toc4.2.25"> </a><h3 id="rasterization-colorwrite"><a class="header" href="#rasterization-colorwrite">Rasterization: colorWrite</a></h3>
|
||||
<p>
|
||||
<dl><table><tr valign=top><td><dt>Type</dt></td><td><dd><p> <code>boolean</code>
|
||||
</p></dd></td></tr><tr valign=top><td><dt>Value</dt></td><td><dd><p> <code>true</code> or <code>false</code>. Defaults to <code>true</code>.
|
||||
@@ -1733,7 +1774,7 @@ non-shader data.</p>
|
||||
</p></dd></td></tr></table></dl></p><pre class="listing tilde"><code><span class="line"></span>material <span class="hljs-punctuation">{</span>
|
||||
<span class="line"></span> colorWrite <span class="hljs-punctuation">:</span> <span class="hljs-literal"><span class="hljs-keyword">false</span></span>
|
||||
<span class="line"></span><span class="hljs-punctuation">}</span></code></pre>
|
||||
<a class="target" name="rasterization:depthwrite"> </a><a class="target" name="materialdefinitions/materialblock/rasterization:depthwrite"> </a><a class="target" name="toc4.2.24"> </a><h3 id="rasterization-depthwrite"><a class="header" href="#rasterization-depthwrite">Rasterization: depthWrite</a></h3>
|
||||
<a class="target" name="rasterization:depthwrite"> </a><a class="target" name="materialdefinitions/materialblock/rasterization:depthwrite"> </a><a class="target" name="toc4.2.26"> </a><h3 id="rasterization-depthwrite"><a class="header" href="#rasterization-depthwrite">Rasterization: depthWrite</a></h3>
|
||||
<p>
|
||||
<dl><table><tr valign=top><td><dt>Type</dt></td><td><dd><p> <code>boolean</code>
|
||||
</p></dd></td></tr><tr valign=top><td><dt>Value</dt></td><td><dd><p> <code>true</code> or <code>false</code>. Defaults to <code>true</code> for opaque materials, <code>false</code> for transparent materials.
|
||||
@@ -1741,7 +1782,7 @@ non-shader data.</p>
|
||||
</p></dd></td></tr></table></dl></p><pre class="listing tilde"><code><span class="line"></span>material <span class="hljs-punctuation">{</span>
|
||||
<span class="line"></span> depthWrite <span class="hljs-punctuation">:</span> <span class="hljs-literal"><span class="hljs-keyword">false</span></span>
|
||||
<span class="line"></span><span class="hljs-punctuation">}</span></code></pre>
|
||||
<a class="target" name="rasterization:depthculling"> </a><a class="target" name="materialdefinitions/materialblock/rasterization:depthculling"> </a><a class="target" name="toc4.2.25"> </a><h3 id="rasterization-depthculling"><a class="header" href="#rasterization-depthculling">Rasterization: depthCulling</a></h3>
|
||||
<a class="target" name="rasterization:depthculling"> </a><a class="target" name="materialdefinitions/materialblock/rasterization:depthculling"> </a><a class="target" name="toc4.2.27"> </a><h3 id="rasterization-depthculling"><a class="header" href="#rasterization-depthculling">Rasterization: depthCulling</a></h3>
|
||||
<p>
|
||||
<dl><dt>Type</dt><dd><p> <code>boolean</code>
|
||||
</p></dd><dt>Value</dt><dd><p> <code>true</code> or <code>false</code>. Defaults to <code>true</code>.
|
||||
@@ -1750,7 +1791,7 @@ non-shader data.</p>
|
||||
</p></dd></dl></p><pre class="listing tilde"><code><span class="line"></span>material <span class="hljs-punctuation">{</span>
|
||||
<span class="line"></span> depthCulling <span class="hljs-punctuation">:</span> <span class="hljs-literal"><span class="hljs-keyword">false</span></span>
|
||||
<span class="line"></span><span class="hljs-punctuation">}</span></code></pre>
|
||||
<a class="target" name="rasterization:doublesided"> </a><a class="target" name="materialdefinitions/materialblock/rasterization:doublesided"> </a><a class="target" name="toc4.2.26"> </a><h3 id="rasterization-doublesided"><a class="header" href="#rasterization-doublesided">Rasterization: doubleSided</a></h3>
|
||||
<a class="target" name="rasterization:doublesided"> </a><a class="target" name="materialdefinitions/materialblock/rasterization:doublesided"> </a><a class="target" name="toc4.2.28"> </a><h3 id="rasterization-doublesided"><a class="header" href="#rasterization-doublesided">Rasterization: doubleSided</a></h3>
|
||||
<p>
|
||||
<dl><dt>Type</dt><dd><p> <code>boolean</code>
|
||||
</p></dd><dt>Value</dt><dd><p> <code>true</code> or <code>false</code>. Defaults to <code>false</code>.
|
||||
@@ -1770,7 +1811,7 @@ non-shader data.</p>
|
||||
<span class="line"></span> material.baseColor = materialParams.albedo;
|
||||
<span class="line"></span> <span class="hljs-punctuation">}</span>
|
||||
<span class="line"></span><span class="hljs-punctuation">}</span></code></pre>
|
||||
<a class="target" name="rasterization:alphatocoverage"> </a><a class="target" name="materialdefinitions/materialblock/rasterization:alphatocoverage"> </a><a class="target" name="toc4.2.27"> </a><h3 id="rasterization-alphatocoverage"><a class="header" href="#rasterization-alphatocoverage">Rasterization: alphaToCoverage</a></h3>
|
||||
<a class="target" name="rasterization:alphatocoverage"> </a><a class="target" name="materialdefinitions/materialblock/rasterization:alphatocoverage"> </a><a class="target" name="toc4.2.29"> </a><h3 id="rasterization-alphatocoverage"><a class="header" href="#rasterization-alphatocoverage">Rasterization: alphaToCoverage</a></h3>
|
||||
<p>
|
||||
<dl><dt>Type</dt><dd><p> <code>boolean</code>
|
||||
</p></dd><dt>Value</dt><dd><p> <code>true</code> or <code>false</code>. Defaults to <code>false</code>.
|
||||
@@ -1792,7 +1833,7 @@ non-shader data.</p>
|
||||
<span class="line"></span> material.baseColor = materialParams.albedo;
|
||||
<span class="line"></span> <span class="hljs-punctuation">}</span>
|
||||
<span class="line"></span><span class="hljs-punctuation">}</span></code></pre>
|
||||
<a class="target" name="lighting:reflections"> </a><a class="target" name="materialdefinitions/materialblock/lighting:reflections"> </a><a class="target" name="toc4.2.28"> </a><h3 id="lighting-reflections"><a class="header" href="#lighting-reflections">Lighting: reflections</a></h3>
|
||||
<a class="target" name="lighting:reflections"> </a><a class="target" name="materialdefinitions/materialblock/lighting:reflections"> </a><a class="target" name="toc4.2.30"> </a><h3 id="lighting-reflections"><a class="header" href="#lighting-reflections">Lighting: reflections</a></h3>
|
||||
<p>
|
||||
<dl><dt>Type</dt><dd><p> <code>string</code>
|
||||
</p></dd><dt>Value</dt><dd><p> <code>default</code> or <code>screenspace</code>. Defaults to <code>default</code>.
|
||||
@@ -1804,7 +1845,7 @@ non-shader data.</p>
|
||||
<span class="line"></span> name <span class="hljs-punctuation">:</span> <span class="hljs-string">"Glossy metal"</span><span class="hljs-punctuation">,</span>
|
||||
<span class="line"></span> reflections <span class="hljs-punctuation">:</span> screenspace
|
||||
<span class="line"></span><span class="hljs-punctuation">}</span></code></pre>
|
||||
<a class="target" name="lighting:shadowmultiplier"> </a><a class="target" name="materialdefinitions/materialblock/lighting:shadowmultiplier"> </a><a class="target" name="toc4.2.29"> </a><h3 id="lighting-shadowmultiplier"><a class="header" href="#lighting-shadowmultiplier">Lighting: shadowMultiplier</a></h3>
|
||||
<a class="target" name="lighting:shadowmultiplier"> </a><a class="target" name="materialdefinitions/materialblock/lighting:shadowmultiplier"> </a><a class="target" name="toc4.2.31"> </a><h3 id="lighting-shadowmultiplier"><a class="header" href="#lighting-shadowmultiplier">Lighting: shadowMultiplier</a></h3>
|
||||
<p>
|
||||
<dl><dt>Type</dt><dd><p> <code>boolean</code>
|
||||
</p></dd><dt>Value</dt><dd><p> <code>true</code> or <code>false</code>. Defaults to <code>false</code>.
|
||||
@@ -1826,7 +1867,7 @@ non-shader data.</p>
|
||||
<span class="line"></span> material.baseColor = vec4(<span class="hljs-number">0.0</span><span class="hljs-punctuation">,</span> <span class="hljs-number">0.0</span><span class="hljs-punctuation">,</span> <span class="hljs-number">0.0</span><span class="hljs-punctuation">,</span> <span class="hljs-number">0.7</span>);
|
||||
<span class="line"></span> <span class="hljs-punctuation">}</span>
|
||||
<span class="line"></span><span class="hljs-punctuation">}</span></code></pre>
|
||||
<a class="target" name="lighting:transparentshadow"> </a><a class="target" name="materialdefinitions/materialblock/lighting:transparentshadow"> </a><a class="target" name="toc4.2.30"> </a><h3 id="lighting-transparentshadow"><a class="header" href="#lighting-transparentshadow">Lighting: transparentShadow</a></h3>
|
||||
<a class="target" name="lighting:transparentshadow"> </a><a class="target" name="materialdefinitions/materialblock/lighting:transparentshadow"> </a><a class="target" name="toc4.2.32"> </a><h3 id="lighting-transparentshadow"><a class="header" href="#lighting-transparentshadow">Lighting: transparentShadow</a></h3>
|
||||
<p>
|
||||
<dl><dt>Type</dt><dd><p> <code>boolean</code>
|
||||
</p></dd><dt>Value</dt><dd><p> <code>true</code> or <code>false</code>. Defaults to <code>false</code>.
|
||||
@@ -1852,7 +1893,7 @@ non-shader data.</p>
|
||||
<center><div class="image" style=""><a class="target" name="figure_transparentshadow"> </a><a href="../images/screenshot_transparent_shadows.jpg" target="_blank"><img class="markdeep" src="../images/screenshot_transparent_shadows.jpg" /></a><center><span class="imagecaption"><b style="font-style:normal;">Figure 36:</b> Objects rendered with transparent shadows and blurry VSM with a
|
||||
</span></center></div></center>
|
||||
</p>
|
||||
<a class="target" name="lighting:clearcoatiorchange"> </a><a class="target" name="materialdefinitions/materialblock/lighting:clearcoatiorchange"> </a><a class="target" name="toc4.2.31"> </a><h3 id="lighting-clearcoatiorchange"><a class="header" href="#lighting-clearcoatiorchange">Lighting: clearCoatIorChange</a></h3>
|
||||
<a class="target" name="lighting:clearcoatiorchange"> </a><a class="target" name="materialdefinitions/materialblock/lighting:clearcoatiorchange"> </a><a class="target" name="toc4.2.33"> </a><h3 id="lighting-clearcoatiorchange"><a class="header" href="#lighting-clearcoatiorchange">Lighting: clearCoatIorChange</a></h3>
|
||||
<p>
|
||||
<dl><dt>Type</dt><dd><p> <code>boolean</code>
|
||||
</p></dd><dt>Value</dt><dd><p> <code>true</code> or <code>false</code>. Defaults to <code>true</code>.
|
||||
@@ -1866,7 +1907,7 @@ non-shader data.</p>
|
||||
<center><div class="image" style=""><a class="target" name="figure_clearcoatiorchange"> </a><a href="../images/screenshot_clear_coat_ior_change.jpg" target="_blank"><img class="markdeep" src="../images/screenshot_clear_coat_ior_change.jpg" /></a><center><span class="imagecaption"><b style="font-style:normal;">Figure 37:</b> The same rough metallic ball with a clear coat layer rendered
|
||||
</span></center></div></center>
|
||||
</p>
|
||||
<a class="target" name="lighting:multibounceambientocclusion"> </a><a class="target" name="materialdefinitions/materialblock/lighting:multibounceambientocclusion"> </a><a class="target" name="toc4.2.32"> </a><h3 id="lighting-multibounceambientocclusion"><a class="header" href="#lighting-multibounceambientocclusion">Lighting: multiBounceAmbientOcclusion</a></h3>
|
||||
<a class="target" name="lighting:multibounceambientocclusion"> </a><a class="target" name="materialdefinitions/materialblock/lighting:multibounceambientocclusion"> </a><a class="target" name="toc4.2.34"> </a><h3 id="lighting-multibounceambientocclusion"><a class="header" href="#lighting-multibounceambientocclusion">Lighting: multiBounceAmbientOcclusion</a></h3>
|
||||
<p>
|
||||
<dl><dt>Type</dt><dd><p> <code>boolean</code>
|
||||
</p></dd><dt>Value</dt><dd><p> <code>true</code> or <code>false</code>. Defaults to <code>false</code> on mobile, <code>true</code> on desktop.
|
||||
@@ -1886,7 +1927,7 @@ non-shader data.</p>
|
||||
<center><div class="image" style=""><a class="target" name="figure_multibounceaoanimated"> </a><a href="../images/screenshot_multi_bounce_ao.gif" target="_blank"><img class="markdeep" src="../images/screenshot_multi_bounce_ao.gif" /></a><center><span class="imagecaption"><b style="font-style:normal;">Figure 39:</b> Brick texture rendered with multi-bounce ambient
|
||||
</span></center></div></center>
|
||||
</p>
|
||||
<a class="target" name="lighting:specularambientocclusion"> </a><a class="target" name="materialdefinitions/materialblock/lighting:specularambientocclusion"> </a><a class="target" name="toc4.2.33"> </a><h3 id="lighting-specularambientocclusion"><a class="header" href="#lighting-specularambientocclusion">Lighting: specularAmbientOcclusion</a></h3>
|
||||
<a class="target" name="lighting:specularambientocclusion"> </a><a class="target" name="materialdefinitions/materialblock/lighting:specularambientocclusion"> </a><a class="target" name="toc4.2.35"> </a><h3 id="lighting-specularambientocclusion"><a class="header" href="#lighting-specularambientocclusion">Lighting: specularAmbientOcclusion</a></h3>
|
||||
<p>
|
||||
<dl><dt>Type</dt><dd><p> <code>string</code>
|
||||
</p></dd><dt>Value</dt><dd><p> <code>none</code>, <code>simple</code> or <code>bentNormals</code>. Defaults to <code>none</code> on mobile, <code>simple</code> on desktop. For
|
||||
@@ -1905,7 +1946,7 @@ non-shader data.</p>
|
||||
<center><div class="image" style=""><a class="target" name="figure_specularao"> </a><a href="../images/screenshot_specular_ao.gif" target="_blank"><img class="markdeep" src="../images/screenshot_specular_ao.gif" /></a><center><span class="imagecaption"><b style="font-style:normal;">Figure 40:</b> Comparison of specular ambient occlusion on and off. The effect is
|
||||
</span></center></div></center>
|
||||
</p>
|
||||
<a class="target" name="anti-aliasing:specularantialiasing"> </a><a class="target" name="materialdefinitions/materialblock/anti-aliasing:specularantialiasing"> </a><a class="target" name="toc4.2.34"> </a><h3 id="anti-aliasing-specularantialiasing"><a class="header" href="#anti-aliasing-specularantialiasing">Anti-aliasing: specularAntiAliasing</a></h3>
|
||||
<a class="target" name="anti-aliasing:specularantialiasing"> </a><a class="target" name="materialdefinitions/materialblock/anti-aliasing:specularantialiasing"> </a><a class="target" name="toc4.2.36"> </a><h3 id="anti-aliasing-specularantialiasing"><a class="header" href="#anti-aliasing-specularantialiasing">Anti-aliasing: specularAntiAliasing</a></h3>
|
||||
<p>
|
||||
<dl><dt>Type</dt><dd><p> <code>boolean</code>
|
||||
</p></dd><dt>Value</dt><dd><p> <code>true</code> or <code>false</code>. Defaults to <code>false</code>.
|
||||
@@ -1917,7 +1958,7 @@ non-shader data.</p>
|
||||
</p></dd></dl></p><pre class="listing tilde"><code><span class="line"></span>material <span class="hljs-punctuation">{</span>
|
||||
<span class="line"></span> specularAntiAliasing <span class="hljs-punctuation">:</span> <span class="hljs-literal"><span class="hljs-keyword">true</span></span>
|
||||
<span class="line"></span><span class="hljs-punctuation">}</span></code></pre>
|
||||
<a class="target" name="anti-aliasing:specularantialiasingvariance"> </a><a class="target" name="materialdefinitions/materialblock/anti-aliasing:specularantialiasingvariance"> </a><a class="target" name="toc4.2.35"> </a><h3 id="anti-aliasing-specularantialiasingvariance"><a class="header" href="#anti-aliasing-specularantialiasingvariance">Anti-aliasing: specularAntiAliasingVariance</a></h3>
|
||||
<a class="target" name="anti-aliasing:specularantialiasingvariance"> </a><a class="target" name="materialdefinitions/materialblock/anti-aliasing:specularantialiasingvariance"> </a><a class="target" name="toc4.2.37"> </a><h3 id="anti-aliasing-specularantialiasingvariance"><a class="header" href="#anti-aliasing-specularantialiasingvariance">Anti-aliasing: specularAntiAliasingVariance</a></h3>
|
||||
<p>
|
||||
<dl><dt>Type</dt><dd><p> <code>float</code>
|
||||
</p></dd><dt>Value</dt><dd><p> A value between 0 and 1, set to 0.15 by default.
|
||||
@@ -1927,7 +1968,7 @@ non-shader data.</p>
|
||||
</p></dd></dl></p><pre class="listing tilde"><code><span class="line"></span>material <span class="hljs-punctuation">{</span>
|
||||
<span class="line"></span> specularAntiAliasingVariance <span class="hljs-punctuation">:</span> <span class="hljs-number">0.2</span>
|
||||
<span class="line"></span><span class="hljs-punctuation">}</span></code></pre>
|
||||
<a class="target" name="anti-aliasing:specularantialiasingthreshold"> </a><a class="target" name="materialdefinitions/materialblock/anti-aliasing:specularantialiasingthreshold"> </a><a class="target" name="toc4.2.36"> </a><h3 id="anti-aliasing-specularantialiasingthreshold"><a class="header" href="#anti-aliasing-specularantialiasingthreshold">Anti-aliasing: specularAntiAliasingThreshold</a></h3>
|
||||
<a class="target" name="anti-aliasing:specularantialiasingthreshold"> </a><a class="target" name="materialdefinitions/materialblock/anti-aliasing:specularantialiasingthreshold"> </a><a class="target" name="toc4.2.38"> </a><h3 id="anti-aliasing-specularantialiasingthreshold"><a class="header" href="#anti-aliasing-specularantialiasingthreshold">Anti-aliasing: specularAntiAliasingThreshold</a></h3>
|
||||
<p>
|
||||
<dl><dt>Type</dt><dd><p> <code>float</code>
|
||||
</p></dd><dt>Value</dt><dd><p> A value between 0 and 1, set to 0.2 by default.
|
||||
@@ -1936,7 +1977,7 @@ non-shader data.</p>
|
||||
</p></dd></dl></p><pre class="listing tilde"><code><span class="line"></span>material <span class="hljs-punctuation">{</span>
|
||||
<span class="line"></span> specularAntiAliasingThreshold <span class="hljs-punctuation">:</span> <span class="hljs-number">0.1</span>
|
||||
<span class="line"></span><span class="hljs-punctuation">}</span></code></pre>
|
||||
<a class="target" name="shading:customsurfaceshading"> </a><a class="target" name="materialdefinitions/materialblock/shading:customsurfaceshading"> </a><a class="target" name="toc4.2.37"> </a><h3 id="shading-customsurfaceshading"><a class="header" href="#shading-customsurfaceshading">Shading: customSurfaceShading</a></h3>
|
||||
<a class="target" name="shading:customsurfaceshading"> </a><a class="target" name="materialdefinitions/materialblock/shading:customsurfaceshading"> </a><a class="target" name="toc4.2.39"> </a><h3 id="shading-customsurfaceshading"><a class="header" href="#shading-customsurfaceshading">Shading: customSurfaceShading</a></h3>
|
||||
<p>
|
||||
<dl><dt>Type</dt><dd><p> <code>bool</code>
|
||||
</p></dd><dt>Value</dt><dd><p> <code>true</code> or <code>false</code>. Defaults to <code>false</code>.
|
||||
|
||||
+1
-1
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -1199,6 +1199,24 @@ material {
|
||||
}
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
### General: linearFog
|
||||
|
||||
Type
|
||||
: `boolean`
|
||||
|
||||
Value
|
||||
: `true` or `false`. Defaults to `false`.
|
||||
|
||||
Description
|
||||
: When set to `true`, a simplified fog equation is used for large-scale fog calculations. In this mode,
|
||||
in-scattering is ignored as well as height falloff.
|
||||
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ JSON
|
||||
material {
|
||||
linearFog : true
|
||||
}
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
### General: quality
|
||||
|
||||
Type
|
||||
@@ -1263,6 +1281,45 @@ material {
|
||||
}
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
### General: useDefaultDepthVariant
|
||||
|
||||
Type
|
||||
: `boolean`
|
||||
|
||||
Value
|
||||
: `true` or `false`. Defaults to `false`.
|
||||
|
||||
Description
|
||||
: This parameter forces Filament to use its default variant for depth passes, such as those used
|
||||
in shadow rendering. This provides an optimization for materials with expensive custom vertex
|
||||
shaders. For example, custom vertex shader computations intended to be consumed by the fragment
|
||||
stage can be skipped during the depth-only pass. This parameter is only meaningful if the
|
||||
material has a vertex block.
|
||||
This parameter should not be set to `true` for vertex blocks that modify geometry (i.e.,
|
||||
modifying `worldPosition`), otherwise shadows may render incorrectly.
|
||||
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ JSON
|
||||
material {
|
||||
variables : [
|
||||
customColor
|
||||
],
|
||||
useDefaultDepthVariant : true
|
||||
}
|
||||
|
||||
vertex {
|
||||
void materialVertex(inout MaterialVertexInputs material) {
|
||||
material.customColor = /* expensive computation that can be skipped for depth-only passes */
|
||||
}
|
||||
}
|
||||
|
||||
fragment {
|
||||
void material(inout MaterialInputs material) {
|
||||
prepareMaterial(material);
|
||||
material.baseColor = variable_customColor;
|
||||
}
|
||||
}
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
### Vertex and attributes: requires
|
||||
|
||||
Type
|
||||
|
||||
+26
-11
@@ -152,6 +152,7 @@ set(SRCS
|
||||
src/fg/PassNode.cpp
|
||||
src/fg/ResourceNode.cpp
|
||||
src/fsr.cpp
|
||||
src/ZstdHelper.cpp
|
||||
)
|
||||
|
||||
set(PRIVATE_HDRS
|
||||
@@ -235,6 +236,7 @@ set(PRIVATE_HDRS
|
||||
src/materials/fsr/ffx_a.h
|
||||
src/materials/fsr/ffx_fsr1.h
|
||||
src/materials/fsr/ffx_fsr1_mobile.fs
|
||||
src/ZstdHelper.h
|
||||
)
|
||||
|
||||
set(MATERIAL_SRCS
|
||||
@@ -605,6 +607,28 @@ add_custom_command(
|
||||
APPEND
|
||||
)
|
||||
|
||||
file(MAKE_DIRECTORY "${GENERATION_ROOT}/generated/data/")
|
||||
|
||||
set(output_path_dfg_bin "${GENERATION_ROOT}/generated/data/dfg.bin")
|
||||
add_custom_command(
|
||||
OUTPUT ${output_path_dfg_bin}
|
||||
COMMAND cmgen --quiet --size=${DFG_LUT_SIZE} --ibl-dfg-multiscatter --ibl-dfg-cloth --ibl-dfg=${output_path_dfg_bin}
|
||||
DEPENDS cmgen
|
||||
COMMENT "Generating DFG LUT to ${output_path_dfg_bin}"
|
||||
)
|
||||
|
||||
set(dfg_package_name "dfg")
|
||||
get_resgen_vars(${RESOURCE_DIR} ${dfg_package_name})
|
||||
add_custom_command(
|
||||
OUTPUT ${RESGEN_OUTPUTS}
|
||||
COMMAND resgen ${RESGEN_FLAGS} -Z ${output_path_dfg_bin}
|
||||
DEPENDS resgen
|
||||
DEPENDS ${output_path_dfg_bin}
|
||||
COMMENT "Generating DFG resource package for ${dfg_package_name}"
|
||||
)
|
||||
list(APPEND GENERATED_RESOURCE_HDRS ${RESGEN_HEADER})
|
||||
list(APPEND GENERATED_RESOURCE_SRCS ${RESGEN_SOURCE})
|
||||
|
||||
# Add the generated resource files to the source and header lists.
|
||||
list(APPEND PRIVATE_HDRS ${GENERATED_RESOURCE_HDRS})
|
||||
list(APPEND SRCS ${GENERATED_RESOURCE_SRCS})
|
||||
@@ -613,16 +637,6 @@ if (DEFINED RESGEN_SOURCE_FLAGS)
|
||||
set_source_files_properties(${GENERATED_RESOURCE_SRCS} PROPERTIES COMPILE_FLAGS ${RESGEN_SOURCE_FLAGS})
|
||||
endif()
|
||||
|
||||
file(MAKE_DIRECTORY "${GENERATION_ROOT}/generated/data/")
|
||||
|
||||
set(output_path "${GENERATION_ROOT}/generated/data/dfg.inc")
|
||||
add_custom_command(
|
||||
OUTPUT ${output_path}
|
||||
COMMAND cmgen --quiet --size=${DFG_LUT_SIZE} --ibl-dfg-multiscatter --ibl-dfg-cloth --ibl-dfg=${output_path}
|
||||
DEPENDS cmgen
|
||||
COMMENT "Generating DFG LUT ${output_path}"
|
||||
)
|
||||
list(APPEND DATA_BINS ${output_path})
|
||||
|
||||
# ==================================================================================================
|
||||
# Includes & target definition
|
||||
@@ -633,7 +647,7 @@ include_directories(${GENERATION_ROOT})
|
||||
include_directories(src)
|
||||
|
||||
# we're building a library
|
||||
add_library(${TARGET} STATIC ${PRIVATE_HDRS} ${PUBLIC_HDRS} ${SRCS} ${DATA_BINS})
|
||||
add_library(${TARGET} STATIC ${PRIVATE_HDRS} ${PUBLIC_HDRS} ${SRCS})
|
||||
|
||||
# specify where the public headers of this library are
|
||||
target_include_directories(${TARGET} PUBLIC ${PUBLIC_HDR_DIR})
|
||||
@@ -650,6 +664,7 @@ target_link_libraries(${TARGET} PUBLIC math)
|
||||
target_link_libraries(${TARGET} PUBLIC utils)
|
||||
target_link_libraries(${TARGET} PUBLIC filaflat)
|
||||
target_link_libraries(${TARGET} PUBLIC filabridge)
|
||||
target_link_libraries(${TARGET} PRIVATE zstd)
|
||||
|
||||
if (FILAMENT_USE_ABSEIL_LOGGING)
|
||||
target_link_libraries(${TARGET} PUBLIC absl::log)
|
||||
|
||||
@@ -672,9 +672,21 @@ enum class Precision : uint8_t {
|
||||
|
||||
/**
|
||||
* Shader compiler priority queue
|
||||
*
|
||||
* On platforms which support parallel shader compilation, compilation requests will be processed in
|
||||
* order of priority, then insertion order. See Material::compile().
|
||||
*/
|
||||
enum class CompilerPriorityQueue : uint8_t {
|
||||
/** We need this program NOW.
|
||||
*
|
||||
* When passed as an argument to Material::compile(), if the platform doesn't support parallel
|
||||
* compilation, but does support amortized shader compilation, the given shader program will be
|
||||
* synchronously compiled.
|
||||
*/
|
||||
CRITICAL,
|
||||
/** We will need this program soon. */
|
||||
HIGH,
|
||||
/** We will need this program eventually. */
|
||||
LOW
|
||||
};
|
||||
|
||||
@@ -1056,6 +1068,7 @@ enum class TextureUsage : uint16_t {
|
||||
BLIT_SRC = 0x0040, //!< Texture can be used the source of a blit()
|
||||
BLIT_DST = 0x0080, //!< Texture can be used the destination of a blit()
|
||||
PROTECTED = 0x0100, //!< Texture can be used for protected content
|
||||
GEN_MIPMAPPABLE = 0x0200, //!< Texture can be used with generateMipmaps()
|
||||
DEFAULT = UPLOADABLE | SAMPLEABLE, //!< Default texture usage
|
||||
ALL_ATTACHMENTS = COLOR_ATTACHMENT | DEPTH_ATTACHMENT | STENCIL_ATTACHMENT | SUBPASS_INPUT, //!< Mask of all attachments
|
||||
};
|
||||
|
||||
@@ -152,6 +152,12 @@ public:
|
||||
*/
|
||||
bool disableParallelShaderCompile = false;
|
||||
|
||||
/**
|
||||
* Set to `true` to forcibly disable amortized shader compilation in the backend.
|
||||
* Currently only honored by the GL backend.
|
||||
*/
|
||||
bool disableAmortizedShaderCompile = false;
|
||||
|
||||
/**
|
||||
* Disable backend handles use-after-free checks.
|
||||
*/
|
||||
@@ -220,7 +226,7 @@ public:
|
||||
* @param sharedContext an optional shared context. This is not meaningful with all graphic
|
||||
* APIs and platforms.
|
||||
* For EGL platforms, this is an EGLContext.
|
||||
*
|
||||
*
|
||||
* @param driverConfig specifies driver initialization parameters
|
||||
*
|
||||
* @return nullptr on failure, or a pointer to the newly created driver.
|
||||
|
||||
@@ -80,7 +80,7 @@ public:
|
||||
Program& operator=(const Program& rhs) = delete;
|
||||
|
||||
Program(Program&& rhs) noexcept;
|
||||
Program& operator=(Program&& rhs) noexcept = delete;
|
||||
Program& operator=(Program&& rhs) noexcept;
|
||||
|
||||
~Program() noexcept;
|
||||
|
||||
|
||||
@@ -32,6 +32,7 @@ CompilerThreadPool::~CompilerThreadPool() noexcept {
|
||||
assert_invariant(mCompilerThreads.empty());
|
||||
assert_invariant(mQueues[0].empty());
|
||||
assert_invariant(mQueues[1].empty());
|
||||
assert_invariant(mQueues[2].empty());
|
||||
}
|
||||
|
||||
void CompilerThreadPool::init(uint32_t threadCount,
|
||||
@@ -55,7 +56,7 @@ void CompilerThreadPool::init(uint32_t threadCount,
|
||||
});
|
||||
|
||||
FILAMENT_TRACING_VALUE(FILAMENT_TRACING_CATEGORY_FILAMENT, "CompilerThreadPool Jobs",
|
||||
mQueues[0].size() + mQueues[1].size());
|
||||
mQueues[0].size() + mQueues[1].size() + mQueues[2].size());
|
||||
|
||||
if (UTILS_LIKELY(!mExitRequested)) {
|
||||
Job job;
|
||||
|
||||
@@ -59,7 +59,7 @@ private:
|
||||
bool mExitRequested{ false };
|
||||
utils::Mutex mQueueLock;
|
||||
utils::Condition mQueueCondition;
|
||||
std::array<Queue, 2> mQueues;
|
||||
std::array<Queue, 3> mQueues;
|
||||
// lock must be held for methods below
|
||||
std::pair<Queue&, Queue::iterator> find(program_token_t const& token);
|
||||
};
|
||||
@@ -67,4 +67,3 @@ private:
|
||||
} // namespace filament::backend
|
||||
|
||||
#endif // TNT_FILAMENT_BACKEND_COMPILERTHREADPOOL_H
|
||||
|
||||
|
||||
@@ -37,6 +37,8 @@ Program::Program() noexcept { // NOLINT(modernize-use-equals-default)
|
||||
|
||||
Program::Program(Program&& rhs) noexcept = default;
|
||||
|
||||
Program& Program::operator=(Program&& rhs) noexcept = default;
|
||||
|
||||
Program::~Program() noexcept = default;
|
||||
|
||||
Program& Program::priorityQueue(CompilerPriorityQueue priorityQueue) noexcept {
|
||||
|
||||
@@ -102,6 +102,9 @@ static inline MTLTextureUsage getMetalTextureUsage(TextureUsage usage) {
|
||||
if (any(usage & TextureUsage::BLIT_SRC)) {
|
||||
u |= MTLTextureUsageShaderRead;
|
||||
}
|
||||
if (any(usage & TextureUsage::GEN_MIPMAPPABLE)) {
|
||||
u |= (MTLTextureUsageRenderTarget | MTLTextureUsageShaderRead);
|
||||
}
|
||||
|
||||
return MTLTextureUsage(u);
|
||||
}
|
||||
|
||||
@@ -2421,7 +2421,17 @@ bool OpenGLDriver::isStereoSupported() {
|
||||
}
|
||||
|
||||
bool OpenGLDriver::isParallelShaderCompileSupported() {
|
||||
return mShaderCompilerService.isParallelShaderCompileSupported();
|
||||
// We emulate parallel compilation even on platforms that don't support it by amortizing the
|
||||
// cost of shader compilation over N frames. It would be nice to move this behavior out of the
|
||||
// OpenGL into a generic system usable by all backends. However, the behavior of async shader
|
||||
// compilation is closely coupled to the internals of ShaderCompilerService, which is
|
||||
// GL-specific. It would also be nice to inform the engine that they're working with this fake
|
||||
// amortized system, but this fact will become implicit when we generalize this feature for all
|
||||
// backends.
|
||||
if (mDriverConfig.disableAmortizedShaderCompile) {
|
||||
return mShaderCompilerService.isParallelShaderCompileSupported();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool OpenGLDriver::isDepthStencilResolveSupported() {
|
||||
|
||||
@@ -60,6 +60,11 @@ namespace filament::backend {
|
||||
|
||||
using namespace utils;
|
||||
|
||||
// How many ticks do we wait in between compiling non-IMMEDIATE programs synchronously?
|
||||
constexpr uint32_t NUM_TICKS_BETWEEN_PROGRAMS = 16;
|
||||
// How many non-IMMEDIATE synchronous programs are we allowed to compile on the same tick?
|
||||
constexpr uint32_t MAX_NUM_SYNCHRONOUS_PROGRAMS_PER_FRAME = 1;
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
|
||||
static std::string to_string(bool const b) { return b ? "true" : "false"; }
|
||||
@@ -265,6 +270,7 @@ void ShaderCompilerService::terminate() noexcept {
|
||||
mCompilerThreadPool.terminate();
|
||||
|
||||
mRunAtNextTickOps.clear();
|
||||
mPendingSynchronousPrograms.clear();
|
||||
|
||||
// We could have some pending callbacks here, we need to execute them.
|
||||
// This is equivalent to calling cancelTickOp() on all active tokens.
|
||||
@@ -274,6 +280,7 @@ void ShaderCompilerService::terminate() noexcept {
|
||||
ShaderCompilerService::program_token_t ShaderCompilerService::createProgram(
|
||||
CString const& name, Program&& program) {
|
||||
auto& gl = mDriver.getContext();
|
||||
CompilerPriorityQueue const priorityQueue = program.getPriorityQueue();
|
||||
|
||||
// Create a token. A callback condition (handle) is internally created upon token creation.
|
||||
auto token = std::make_shared<OpenGLProgramToken>(*this, name);
|
||||
@@ -281,7 +288,33 @@ ShaderCompilerService::program_token_t ShaderCompilerService::createProgram(
|
||||
token->attributes = std::move(program.getAttributes());
|
||||
}
|
||||
|
||||
// Initiate program compilation.
|
||||
if (mMode == Mode::SYNCHRONOUS) {
|
||||
if (priorityQueue == CompilerPriorityQueue::CRITICAL ||
|
||||
shouldCompileSynchronousProgramThisTick()) {
|
||||
// We should immediately compile this program this frame.
|
||||
compileProgram(token, std::move(program));
|
||||
} else {
|
||||
// We already exceeded the number of non-IMMEDIATE synchronous programs we're allowed to
|
||||
// create this frame. Queue it for a future frame, sorted by priority.
|
||||
auto const pos = std::lower_bound(mPendingSynchronousPrograms.begin(),
|
||||
mPendingSynchronousPrograms.end(), priorityQueue,
|
||||
[](PendingSynchronousProgram const& lhs,
|
||||
CompilerPriorityQueue const priorityQueue) {
|
||||
return std::get<1>(lhs).getPriorityQueue() < priorityQueue;
|
||||
});
|
||||
mPendingSynchronousPrograms.emplace(pos, token, std::move(program));
|
||||
}
|
||||
} else {
|
||||
// Truly asynchronous platforms can always begin compiling immediately.
|
||||
compileProgram(token, std::move(program));
|
||||
}
|
||||
|
||||
return token;
|
||||
}
|
||||
|
||||
void ShaderCompilerService::compileProgram(
|
||||
program_token_t const& token, Program&& program) noexcept {
|
||||
auto& gl = mDriver.getContext();
|
||||
CompilerPriorityQueue const priorityQueue = program.getPriorityQueue();
|
||||
switch (mMode) {
|
||||
case Mode::THREAD_POOL: {
|
||||
@@ -330,6 +363,8 @@ ShaderCompilerService::program_token_t ShaderCompilerService::createProgram(
|
||||
}
|
||||
|
||||
case Mode::SYNCHRONOUS:
|
||||
mNumProgramsCreatedSynchronouslyThisTick++;
|
||||
UTILS_FALLTHROUGH;
|
||||
case Mode::ASYNCHRONOUS: {
|
||||
// Try retrieving the program from the cache first. If no program found,
|
||||
// a normal compilation/linking process is performed.
|
||||
@@ -365,8 +400,6 @@ ShaderCompilerService::program_token_t ShaderCompilerService::createProgram(
|
||||
assert_invariant(false);
|
||||
}
|
||||
}
|
||||
|
||||
return token;
|
||||
}
|
||||
|
||||
GLuint ShaderCompilerService::getProgram(program_token_t& token) {
|
||||
@@ -400,6 +433,7 @@ GLuint ShaderCompilerService::getProgram(program_token_t& token) {
|
||||
}
|
||||
} else {
|
||||
token->compiler.cancelTickOp(token);
|
||||
token->compiler.cancelPendingSynchronousProgram(token);
|
||||
}
|
||||
|
||||
token = nullptr; // This will try submitting a callback handle to the callback manager.
|
||||
@@ -411,6 +445,9 @@ void ShaderCompilerService::tick() {
|
||||
} else {
|
||||
executeTickOps();
|
||||
}
|
||||
if (UTILS_UNLIKELY(mMode == Mode::SYNCHRONOUS)) {
|
||||
compilePendingSynchronousPrograms();
|
||||
}
|
||||
}
|
||||
|
||||
CallbackManager::Handle ShaderCompilerService::issueCallbackHandle() const noexcept {
|
||||
@@ -487,9 +524,9 @@ void ShaderCompilerService::ensureTokenIsReady(program_token_t const& token) {
|
||||
// just log warnings here instead of repeatedly checking compile status. If this turns
|
||||
// out to be a real issue later, we would need to consider doing the canonical way.
|
||||
if (!isCompileCompleted(token)) {
|
||||
LOG(WARNING)
|
||||
LOG(INFO)
|
||||
<< "Shader compilation for OpenGL program " << token->name.c_str_safe()
|
||||
<< " is not completed yet. The following program link may not succeed.";
|
||||
<< " is not completed yet. The following program link may be slow.";
|
||||
}
|
||||
|
||||
linkProgram(mDriver.getContext(), token);
|
||||
@@ -497,9 +534,12 @@ void ShaderCompilerService::ensureTokenIsReady(program_token_t const& token) {
|
||||
}
|
||||
|
||||
case Mode::SYNCHRONOUS: {
|
||||
// We must not have called the TickOp yet until now. Call now to have
|
||||
// `token->gl.program` ready to use.
|
||||
tick();
|
||||
// This program might still be in the queue, so try to compile it now.
|
||||
compilePendingSynchronousProgramNow(token);
|
||||
// If the program was just compiled on the above line, or the program was compiled but
|
||||
// the tick ops weren't yet executed, we must execute them to populate
|
||||
// `token->gl.program`.
|
||||
executeTickOps();
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -591,6 +631,65 @@ void ShaderCompilerService::executeTickOps() noexcept {
|
||||
FILAMENT_TRACING_VALUE(FILAMENT_TRACING_CATEGORY_FILAMENT, "ShaderCompilerService Jobs", ops.size());
|
||||
}
|
||||
|
||||
bool ShaderCompilerService::shouldCompileSynchronousProgramThisTick() const noexcept {
|
||||
return mDriver.getDriverConfig().disableAmortizedShaderCompile ||
|
||||
(mNumProgramsCreatedSynchronouslyThisTick < MAX_NUM_SYNCHRONOUS_PROGRAMS_PER_FRAME &&
|
||||
mNumTicksUntilNextSynchronousProgram == 0);
|
||||
}
|
||||
|
||||
void ShaderCompilerService::compilePendingSynchronousPrograms() noexcept {
|
||||
if (mDriver.getDriverConfig().disableAmortizedShaderCompile) {
|
||||
return;
|
||||
}
|
||||
|
||||
auto it = mPendingSynchronousPrograms.begin();
|
||||
while (it != mPendingSynchronousPrograms.end() && shouldCompileSynchronousProgramThisTick()) {
|
||||
compileProgram(std::get<0>(*it), std::move(std::get<1>(*it)));
|
||||
it = mPendingSynchronousPrograms.erase(it);
|
||||
}
|
||||
if (mNumProgramsCreatedSynchronouslyThisTick) {
|
||||
mNumTicksUntilNextSynchronousProgram = NUM_TICKS_BETWEEN_PROGRAMS;
|
||||
mNumProgramsCreatedSynchronouslyThisTick = 0u;
|
||||
} else if (mNumTicksUntilNextSynchronousProgram) {
|
||||
mNumTicksUntilNextSynchronousProgram--;
|
||||
}
|
||||
}
|
||||
|
||||
void ShaderCompilerService::compilePendingSynchronousProgramNow(
|
||||
program_token_t const& token) noexcept {
|
||||
if (mDriver.getDriverConfig().disableAmortizedShaderCompile) {
|
||||
return;
|
||||
}
|
||||
|
||||
auto pos = std::find_if(mPendingSynchronousPrograms.begin(),
|
||||
mPendingSynchronousPrograms.end(), [&](PendingSynchronousProgram const& item) {
|
||||
return std::get<0>(item) == token;
|
||||
});
|
||||
if (pos != mPendingSynchronousPrograms.end()) {
|
||||
compileProgram(std::get<0>(*pos), std::move(std::get<1>(*pos)));
|
||||
mPendingSynchronousPrograms.erase(pos);
|
||||
}
|
||||
}
|
||||
|
||||
void ShaderCompilerService::cancelPendingSynchronousProgram(program_token_t const& token) noexcept {
|
||||
if (mDriver.getDriverConfig().disableAmortizedShaderCompile) {
|
||||
return;
|
||||
}
|
||||
|
||||
// We do a linear search here, but this is rare, and we know the list is pretty small.
|
||||
auto const pos = std::find_if(mPendingSynchronousPrograms.begin(),
|
||||
mPendingSynchronousPrograms.end(), [&](const auto& item) {
|
||||
return std::get<0>(item) == token;
|
||||
});
|
||||
if (pos != mPendingSynchronousPrograms.end()) {
|
||||
mPendingSynchronousPrograms.erase(pos);
|
||||
return;
|
||||
}
|
||||
FILAMENT_TRACING_CONTEXT(FILAMENT_TRACING_CATEGORY_FILAMENT);
|
||||
FILAMENT_TRACING_VALUE(FILAMENT_TRACING_CATEGORY_FILAMENT,
|
||||
"ShaderCompilerService Pending Programs", mPendingSynchronousPrograms.size());
|
||||
}
|
||||
|
||||
/* static */ void ShaderCompilerService::compileShaders(OpenGLContext& context,
|
||||
Program::ShaderSource shadersSource,
|
||||
FixedCapacityVector<Program::SpecializationConstant> const& specializationConstants,
|
||||
|
||||
@@ -17,8 +17,6 @@
|
||||
#ifndef TNT_FILAMENT_BACKEND_OPENGL_SHADERCOMPILERSERVICE_H
|
||||
#define TNT_FILAMENT_BACKEND_OPENGL_SHADERCOMPILERSERVICE_H
|
||||
|
||||
#include "gl_headers.h"
|
||||
|
||||
#include "CallbackManager.h"
|
||||
#include "CompilerThreadPool.h"
|
||||
#include "OpenGLBlobCache.h"
|
||||
@@ -35,7 +33,6 @@
|
||||
#include <functional>
|
||||
#include <list>
|
||||
#include <memory>
|
||||
#include <mutex>
|
||||
#include <tuple>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
@@ -136,6 +133,12 @@ private:
|
||||
std::vector<ContainerType> mRunAtNextTickOps;
|
||||
|
||||
std::list<program_token_t> mCanceledTokens;
|
||||
// These members are only ever accessed on the main thread and are completely unused when mMode
|
||||
// is not SYNCHRONOUS.
|
||||
uint32_t mNumProgramsCreatedSynchronouslyThisTick = 0u;
|
||||
uint32_t mNumTicksUntilNextSynchronousProgram = 0u;
|
||||
using PendingSynchronousProgram = std::tuple<program_token_t, Program>;
|
||||
std::vector<PendingSynchronousProgram> mPendingSynchronousPrograms;
|
||||
|
||||
GLuint initialize(program_token_t& token);
|
||||
void ensureTokenIsReady(program_token_t const& token);
|
||||
@@ -149,6 +152,13 @@ private:
|
||||
void executeTickOps() noexcept;
|
||||
bool cancelTickOp(program_token_t const& token) noexcept;
|
||||
|
||||
bool shouldCompileSynchronousProgramThisTick() const noexcept;
|
||||
void compilePendingSynchronousPrograms() noexcept;
|
||||
void compilePendingSynchronousProgramNow(program_token_t const& token) noexcept;
|
||||
void cancelPendingSynchronousProgram(program_token_t const& token) noexcept;
|
||||
|
||||
void compileProgram(program_token_t const& token, Program&& program) noexcept;
|
||||
|
||||
// Compile shaders with the given `shaderSource`. `gl.shaders` is always populated with valid
|
||||
// shader IDs after this method. But this doesn't necessarily mean the shaders are successfully
|
||||
// compiled. Errors can be checked by calling `checkCompileStatus` later.
|
||||
|
||||
@@ -499,6 +499,7 @@ io::ostream& operator<<(io::ostream& out, ShaderStage shaderStage) {
|
||||
|
||||
io::ostream& operator<<(io::ostream& out, CompilerPriorityQueue compilerPriorityQueue) {
|
||||
switch (compilerPriorityQueue) {
|
||||
CASE(CompilerPriorityQueue, CRITICAL)
|
||||
CASE(CompilerPriorityQueue, HIGH)
|
||||
CASE(CompilerPriorityQueue, LOW)
|
||||
}
|
||||
|
||||
@@ -37,10 +37,16 @@ inline void blitFast(VulkanCommandBuffer* commands, VkImageAspectFlags aspect, V
|
||||
const VkOffset3D srcRect[2], const VkOffset3D dstRect[2]) {
|
||||
VkCommandBuffer const cmdbuf = commands->buffer();
|
||||
if constexpr (FVK_ENABLED(FVK_DEBUG_BLITTER)) {
|
||||
FVK_LOGD << "Fast blit from=" << src.texture->getVkImage() << ",level=" << (int) src.level
|
||||
<< " layout=" << src.getLayout()
|
||||
<< " to=" << dst.texture->getVkImage() << ",level=" << (int) dst.level
|
||||
<< " layout=" << dst.getLayout();
|
||||
FVK_LOGE << "Fast blit from=" << src.texture->getVkImage() << ", level=" << (int) src.level
|
||||
<< ", layer=" << (int) src.layer
|
||||
<< ", layout=" << src.getLayout()
|
||||
<< ", src-rect=(" << srcRect[0].x << "," << srcRect[0].y << "," << srcRect[0].z << ")"
|
||||
<< "->(" << srcRect[1].x << "," << srcRect[1].y << "," << srcRect[1].z << ")"
|
||||
<< " to=" << dst.texture->getVkImage() << ", level=" << (int) dst.level
|
||||
<< ", layer=" << (int) dst.layer
|
||||
<< ", layout=" << dst.getLayout()
|
||||
<< ", dst-rect=(" << dstRect[0].x << "," << dstRect[0].y << "," << dstRect[0].z << ")"
|
||||
<< "->(" << dstRect[1].x << "," << dstRect[1].y << "," << dstRect[1].z << ")";
|
||||
}
|
||||
|
||||
VkImageSubresourceRange const srcRange = src.getSubresourceRange();
|
||||
@@ -69,6 +75,7 @@ inline void blitFast(VulkanCommandBuffer* commands, VkImageAspectFlags aspect, V
|
||||
if (oldDstLayout == VulkanLayout::UNDEFINED) {
|
||||
oldDstLayout = dst.texture->getDefaultLayout();
|
||||
}
|
||||
|
||||
src.texture->transitionLayout(commands, srcRange, oldSrcLayout);
|
||||
dst.texture->transitionLayout(commands, dstRange, oldDstLayout);
|
||||
}
|
||||
|
||||
@@ -206,6 +206,11 @@ VulkanDriver::VulkanDriver(VulkanPlatform* platform, VulkanContext& context,
|
||||
: mPlatform(platform),
|
||||
mResourceManager(driverConfig.handleArenaSize, driverConfig.disableHandleUseAfterFreeCheck,
|
||||
driverConfig.disableHeapHandleTags),
|
||||
// Note that we always create the default rendertarget before createDefaultRenderTarget(). We
|
||||
// swap the content later when createDefaultRenderTarget() is called. This frees
|
||||
// createDefaultRenderTarget() from being ordered with makeCurrent().
|
||||
mDefaultRenderTarget(
|
||||
fvkmemory::resource_ptr<VulkanRenderTarget>::construct(&mResourceManager)),
|
||||
mAllocator(createAllocator(mPlatform->getInstance(), mPlatform->getPhysicalDevice(),
|
||||
mPlatform->getDevice())),
|
||||
mContext(context),
|
||||
@@ -698,8 +703,11 @@ void VulkanDriver::destroyProgram(Handle<HwProgram> ph) {
|
||||
}
|
||||
|
||||
void VulkanDriver::createDefaultRenderTargetR(Handle<HwRenderTarget> rth, int) {
|
||||
assert_invariant(!mDefaultRenderTarget);
|
||||
auto renderTarget = resource_ptr<VulkanRenderTarget>::make(&mResourceManager, rth);
|
||||
assert_invariant(mDefaultRenderTarget); // Default render target should already exist.
|
||||
|
||||
auto renderTarget = resource_ptr<VulkanRenderTarget>::make(&mResourceManager, rth,
|
||||
std::move(std::move(*mDefaultRenderTarget.get())));
|
||||
|
||||
mDefaultRenderTarget = renderTarget;
|
||||
}
|
||||
|
||||
@@ -775,6 +783,7 @@ void VulkanDriver::destroyRenderTarget(Handle<HwRenderTarget> rth) {
|
||||
|
||||
auto rt = resource_ptr<VulkanRenderTarget>::cast(&mResourceManager, rth);
|
||||
if (UTILS_UNLIKELY(rt == mDefaultRenderTarget)) {
|
||||
// Note that this should only happen on driver shutdown.
|
||||
mDefaultRenderTarget = {};
|
||||
} else {
|
||||
rt.dec();
|
||||
@@ -1366,6 +1375,10 @@ void VulkanDriver::generateMipmaps(Handle<HwTexture> th) {
|
||||
srcw = dstw;
|
||||
srch = dsth;
|
||||
} while ((srcw > 1 || srch > 1) && ++level < t->levels - 1);
|
||||
|
||||
VulkanCommandBuffer* commandBuffer = &mCommands.get();
|
||||
// Here we transition to the whole image to the most likely next layout.
|
||||
t->transitionLayout(commandBuffer, t->getPrimaryViewRange(), t->getDefaultLayout());
|
||||
}
|
||||
|
||||
void VulkanDriver::compilePrograms(CompilerPriorityQueue priority,
|
||||
|
||||
@@ -308,6 +308,15 @@ struct VulkanRenderTarget : private HwRenderTarget, fvkmemory::Resource {
|
||||
// Creates a special "default" render target (i.e. associated with the swap chain)
|
||||
explicit VulkanRenderTarget();
|
||||
|
||||
VulkanRenderTarget(VulkanRenderTarget&& target) {
|
||||
swap(std::move(target));
|
||||
}
|
||||
|
||||
VulkanRenderTarget& operator=(VulkanRenderTarget&& target) {
|
||||
swap(std::move(target));
|
||||
return *this;
|
||||
}
|
||||
|
||||
void transformClientRectToPlatform(VkRect2D* bounds) const;
|
||||
|
||||
void transformViewportToPlatform(VkViewport* bounds) const;
|
||||
@@ -355,6 +364,12 @@ struct VulkanRenderTarget : private HwRenderTarget, fvkmemory::Resource {
|
||||
void emitBarriersEndRenderPass(VulkanCommandBuffer& commands);
|
||||
|
||||
private:
|
||||
void swap(VulkanRenderTarget&& target) {
|
||||
std::swap(mOffscreen, target.mOffscreen);
|
||||
std::swap(mProtected, target.mProtected);
|
||||
std::swap(mInfo, target.mInfo);
|
||||
}
|
||||
|
||||
struct Auxiliary {
|
||||
static constexpr int8_t UNDEFINED_INDEX = -1;
|
||||
|
||||
@@ -368,7 +383,7 @@ private:
|
||||
int8_t msaaDepthIndex = UNDEFINED_INDEX;
|
||||
int8_t msaaIndex = UNDEFINED_INDEX;
|
||||
};
|
||||
bool const mOffscreen;
|
||||
bool mOffscreen;
|
||||
bool mProtected;
|
||||
|
||||
std::unique_ptr<Auxiliary> mInfo;
|
||||
|
||||
@@ -207,16 +207,11 @@ fvkmemory::resource_ptr<VulkanStageImage::Resource> VulkanStagePool::acquireImag
|
||||
VulkanStageImage* stageImage = new VulkanStageImage(
|
||||
vkformat, width, height, memory, image, mCurrentFrame);
|
||||
|
||||
// We use VK_IMAGE_LAYOUT_GENERAL here because the spec says:
|
||||
// "Host access to image memory is only well-defined for linear images and for image
|
||||
// subresources of those images which are currently in either the
|
||||
// VK_IMAGE_LAYOUT_PREINITIALIZED or VK_IMAGE_LAYOUT_GENERAL layout. Calling
|
||||
// vkGetImageSubresourceLayout for a linear image returns a subresource layout mapping that is
|
||||
// valid for either of those image layouts."
|
||||
fvkutils::transitionLayout(cmdbuffer, {
|
||||
.image = stageImage->image(),
|
||||
.oldLayout = VulkanLayout::UNDEFINED,
|
||||
.newLayout = VulkanLayout::STAGING, // (= VK_IMAGE_LAYOUT_GENERAL)
|
||||
// TRANSFER_SRC because we're about to blit this to the actual texture.
|
||||
.newLayout = VulkanLayout::TRANSFER_SRC,
|
||||
.subresources = { aspectFlags, 0, 1, 0, 1 },
|
||||
});
|
||||
|
||||
|
||||
@@ -117,12 +117,14 @@ inline VulkanLayout getDefaultLayoutImpl(TextureUsage usage) {
|
||||
if (any(usage & TextureUsage::DEPTH_ATTACHMENT)) {
|
||||
if (any(usage & TextureUsage::SAMPLEABLE)) {
|
||||
return VulkanLayout::DEPTH_SAMPLER;
|
||||
} else {
|
||||
return VulkanLayout::DEPTH_ATTACHMENT;
|
||||
}
|
||||
return VulkanLayout::DEPTH_ATTACHMENT;
|
||||
}
|
||||
|
||||
if (any(usage & TextureUsage::COLOR_ATTACHMENT)) {
|
||||
if (any(usage & TextureUsage::SAMPLEABLE)) {
|
||||
return VulkanLayout::FRAG_READ;
|
||||
}
|
||||
return VulkanLayout::COLOR_ATTACHMENT;
|
||||
}
|
||||
// Finally, the layout for an immutable texture is optimal read-only.
|
||||
@@ -162,6 +164,10 @@ VkImageUsageFlags getUsage(VulkanContext const& context, uint8_t samples,
|
||||
usage |= VK_IMAGE_USAGE_TRANSFER_DST_BIT;
|
||||
}
|
||||
|
||||
if (any(tusage & TextureUsage::GEN_MIPMAPPABLE)) {
|
||||
usage |= VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT;
|
||||
}
|
||||
|
||||
// Determine if we can use the transient usage flag combined with lazily allocated memory.
|
||||
const bool useTransientAttachment =
|
||||
// Lazily allocated memory is available.
|
||||
|
||||
@@ -64,7 +64,7 @@ WebGPUDescriptorSetLayout::WebGPUDescriptorSetLayout(DescriptorSetLayout const&
|
||||
std::string baseLabel;
|
||||
if (std::holds_alternative<utils::StaticString>(layout.label)) {
|
||||
const auto& temp = std::get_if<utils::StaticString>(&layout.label);
|
||||
baseLabel = temp->c_str();
|
||||
baseLabel = temp->c_str() == nullptr ? "" : temp->c_str();
|
||||
} else if (std::holds_alternative<utils::CString>(layout.label)) {
|
||||
const auto& temp = std::get_if<utils::CString>(&layout.label);
|
||||
baseLabel = temp->c_str();
|
||||
|
||||
@@ -64,6 +64,28 @@ using namespace std::chrono_literals;
|
||||
|
||||
namespace filament::backend {
|
||||
|
||||
namespace {
|
||||
|
||||
void setDefaultTargetFlags(WebGPURenderTarget& defaultRenderTarget,
|
||||
WebGPUSwapChain const& swapChain) {
|
||||
const wgpu::TextureFormat depthFormat{ swapChain.getDepthFormat() };
|
||||
TargetBufferFlags newTargetFlags{ filament::backend::TargetBufferFlags::NONE };
|
||||
|
||||
// Assuming Color always present in default render target.
|
||||
newTargetFlags |= filament::backend::TargetBufferFlags::COLOR;
|
||||
if (depthFormat != wgpu::TextureFormat::Undefined) {
|
||||
if (hasDepth(depthFormat)) {
|
||||
newTargetFlags |= filament::backend::TargetBufferFlags::DEPTH;
|
||||
}
|
||||
if (hasStencil(depthFormat)) {
|
||||
newTargetFlags |= filament::backend::TargetBufferFlags::STENCIL;
|
||||
}
|
||||
}
|
||||
defaultRenderTarget.setTargetFlags(newTargetFlags);
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
Driver* WebGPUDriver::create(WebGPUPlatform& platform, const Platform::DriverConfig& driverConfig) noexcept {
|
||||
constexpr size_t defaultSize = FILAMENT_WEBGPU_HANDLE_ARENA_SIZE_IN_MB * 1024U * 1024U;
|
||||
Platform::DriverConfig validConfig {driverConfig};
|
||||
@@ -384,6 +406,9 @@ void WebGPUDriver::createSwapChainR(Handle<HwSwapChain> sch, void* nativeWindow,
|
||||
"rebuilding Filament with that flag, e.g. ./build.sh -x "
|
||||
<< FWGPU_PRINT_SYSTEM << " ...";
|
||||
#endif
|
||||
if (mDefaultRenderTarget) {
|
||||
setDefaultTargetFlags(*mDefaultRenderTarget, *mSwapChain);
|
||||
}
|
||||
}
|
||||
|
||||
void WebGPUDriver::createSwapChainHeadlessR(Handle<HwSwapChain> sch, uint32_t width,
|
||||
@@ -392,6 +417,9 @@ void WebGPUDriver::createSwapChainHeadlessR(Handle<HwSwapChain> sch, uint32_t wi
|
||||
mSwapChain = constructHandle<WebGPUSwapChain>(sch, extent, mAdapter,
|
||||
mDevice, flags);
|
||||
assert_invariant(mSwapChain);
|
||||
if (mDefaultRenderTarget) {
|
||||
setDefaultTargetFlags(*mDefaultRenderTarget, *mSwapChain);
|
||||
}
|
||||
}
|
||||
|
||||
void WebGPUDriver::createVertexBufferInfoR(Handle<HwVertexBufferInfo> vertexBufferInfoHandle,
|
||||
@@ -488,6 +516,9 @@ void WebGPUDriver::createDefaultRenderTargetR(Handle<HwRenderTarget> renderTarge
|
||||
assert_invariant(!mDefaultRenderTarget);
|
||||
mDefaultRenderTarget = constructHandle<WebGPURenderTarget>(renderTargetHandle);
|
||||
assert_invariant(mDefaultRenderTarget);
|
||||
if (mSwapChain) {
|
||||
setDefaultTargetFlags(*mDefaultRenderTarget, *mSwapChain);
|
||||
}
|
||||
}
|
||||
|
||||
void WebGPUDriver::createRenderTargetR(Handle<HwRenderTarget> renderTargetHandle,
|
||||
@@ -1187,23 +1218,6 @@ void WebGPUDriver::makeCurrent(Handle<HwSwapChain> drawSch, Handle<HwSwapChain>
|
||||
|
||||
assert_invariant(mTextureView);
|
||||
|
||||
assert_invariant(mDefaultRenderTarget);
|
||||
|
||||
wgpu::TextureFormat depthFormat = mSwapChain->getDepthFormat();
|
||||
TargetBufferFlags newTargetFlags = filament::backend::TargetBufferFlags::NONE;
|
||||
|
||||
//Assuming Color always present in default render target.
|
||||
newTargetFlags |= filament::backend::TargetBufferFlags::COLOR;
|
||||
if (depthFormat != wgpu::TextureFormat::Undefined) {
|
||||
if (hasDepth(depthFormat)) {
|
||||
newTargetFlags |= filament::backend::TargetBufferFlags::DEPTH;
|
||||
}
|
||||
if (hasStencil(depthFormat)) {
|
||||
newTargetFlags |= filament::backend::TargetBufferFlags::STENCIL;
|
||||
}
|
||||
}
|
||||
mDefaultRenderTarget->setTargetFlags(newTargetFlags);
|
||||
|
||||
if (!mCommandEncoder) {
|
||||
wgpu::CommandEncoderDescriptor commandEncoderDescriptor = { .label = "frame_command_encoder" };
|
||||
mCommandEncoder = mDevice.CreateCommandEncoder(&commandEncoderDescriptor);
|
||||
|
||||
@@ -125,7 +125,7 @@ WebGPURenderTarget::WebGPURenderTarget(const uint32_t width, const uint32_t heig
|
||||
mDefaultRenderTarget{ false },
|
||||
mTargetFlags{ targetFlags },
|
||||
mSamples{ samples },
|
||||
mLayerCount{ layerCount },
|
||||
mLayerCount{ layerCount <= 0 ? static_cast<uint8_t>(1) : layerCount },
|
||||
mColorAttachments{ colorAttachmentsMRT },
|
||||
mDepthAttachment{ depthAttachmentInfo },
|
||||
mStencilAttachment{ stencilAttachmentInfo },
|
||||
@@ -140,7 +140,9 @@ WebGPURenderTarget::WebGPURenderTarget(const uint32_t width, const uint32_t heig
|
||||
WebGPURenderTarget::WebGPURenderTarget()
|
||||
: HwRenderTarget{ 0, 0 },
|
||||
mDefaultRenderTarget{ true },
|
||||
mTargetFlags{ TargetBufferFlags::NONE },
|
||||
// starting with the initial assumption that the default render target has a single color
|
||||
// attachment and a depth attachment, not necessarily a depth attachment
|
||||
mTargetFlags{ TargetBufferFlags::COLOR0 | TargetBufferFlags::DEPTH },
|
||||
mSamples{ 1 },
|
||||
mLayerCount{ 1 },
|
||||
mSampleCountPerAttachment{ 1 } {}
|
||||
|
||||
@@ -256,7 +256,7 @@ template<typename WebGPUPrintable>
|
||||
|| FWGPU_ENABLED(FWGPU_DEBUG_UPDATE_IMAGE) \
|
||||
|| FWGPU_ENABLED(FWGPU_DEBUG_BLIT) \
|
||||
|| FWGPU_ENABLED(FWGPU_DEBUG_BIND_GROUPS)
|
||||
[[nodiscard]] std::string webGPUTextureToString(wgpu::Texture const& texture) {
|
||||
[[nodiscard]] inline std::string webGPUTextureToString(wgpu::Texture const& texture) {
|
||||
if (texture == nullptr) {
|
||||
return "nullptr (no wgpu::Texture)";
|
||||
}
|
||||
@@ -411,7 +411,7 @@ template<typename WebGPUPrintable>
|
||||
}
|
||||
}
|
||||
|
||||
[[nodiscard]] std::string filamentTextureUsageFlagsToString(const TextureUsage flags) {
|
||||
[[nodiscard]] inline std::string filamentTextureUsageFlagsToString(const TextureUsage flags) {
|
||||
if (flags == TextureUsage::NONE) {
|
||||
return "NONE";
|
||||
}
|
||||
|
||||
@@ -143,11 +143,13 @@ namespace {
|
||||
retUsage |= wgpu::TextureUsage::RenderAttachment;
|
||||
}
|
||||
if (any(TextureUsage::BLIT_SRC & fUsage)) {
|
||||
retUsage |= wgpu::TextureUsage::RenderAttachment;
|
||||
retUsage |= wgpu::TextureUsage::TextureBinding;
|
||||
}
|
||||
if (any(TextureUsage::BLIT_DST & fUsage)) {
|
||||
retUsage |= wgpu::TextureUsage::RenderAttachment;
|
||||
retUsage |= wgpu::TextureUsage::TextureBinding;
|
||||
}
|
||||
if (any(TextureUsage::GEN_MIPMAPPABLE & fUsage)) {
|
||||
retUsage |= (wgpu::TextureUsage::RenderAttachment | wgpu::TextureUsage::TextureBinding);
|
||||
}
|
||||
// WGPU Render attachment covers either color or stencil situation dependant
|
||||
// NOTE: Depth attachment isn't used this way in Vulkan but logically maps to WGPU docs. If
|
||||
|
||||
@@ -36,14 +36,16 @@
|
||||
namespace test {
|
||||
|
||||
ScreenshotParams::ScreenshotParams(int width, int height, std::string fileName,
|
||||
uint32_t expectedHash, bool isSrgb, int numAllowedDeviations, int pixelMatchThreshold)
|
||||
uint32_t expectedHash, bool isSrgb, int numAllowedDeviations, int pixelMatchThreshold,
|
||||
std::optional<float> forceAlphaValue)
|
||||
: mWidth(width),
|
||||
mHeight(height),
|
||||
mIsSrgb(isSrgb),
|
||||
mExpectedPixelHash(expectedHash),
|
||||
mFileName(std::move(fileName)),
|
||||
mAllowedPixelDeviations(numAllowedDeviations),
|
||||
mPixelMatchThreshold(pixelMatchThreshold) {}
|
||||
mPixelMatchThreshold(pixelMatchThreshold),
|
||||
mForceAlphaValue(forceAlphaValue) {}
|
||||
|
||||
int ScreenshotParams::width() const {
|
||||
return mWidth;
|
||||
@@ -61,6 +63,10 @@ uint32_t ScreenshotParams::expectedHash() const {
|
||||
return mExpectedPixelHash;
|
||||
}
|
||||
|
||||
std::optional<float> ScreenshotParams::forceAlphaValue() const {
|
||||
return mForceAlphaValue;
|
||||
}
|
||||
|
||||
std::filesystem::path ScreenshotParams::actualDirectoryPath() {
|
||||
return BackendTest::binaryDirectory().append("images/actual_images");
|
||||
}
|
||||
@@ -177,9 +183,29 @@ RenderTargetDump::RenderTargetDump(filament::backend::DriverApi& api,
|
||||
const size_t size = mInternal->params.width() * mInternal->params.height() * 4;
|
||||
mInternal->bytes.resize(size);
|
||||
|
||||
using filament::backend::PixelDataFormat;
|
||||
using filament::backend::PixelDataType;
|
||||
constexpr PixelDataFormat readPixelFormat = PixelDataFormat::RGBA;
|
||||
constexpr PixelDataType readPixelType = PixelDataType::UBYTE;
|
||||
|
||||
auto cb = [](void* buffer, size_t size, void* user) {
|
||||
auto* internal = static_cast<RenderTargetDump::Internal*>(user);
|
||||
internal->bytesFilled = true;
|
||||
|
||||
// If requested, we overwrite the alpha value.
|
||||
// If the read pixel format or type changes, this logic must be updated.
|
||||
static_assert(readPixelFormat == PixelDataFormat::RGBA);
|
||||
static_assert(readPixelType == PixelDataType::UBYTE);
|
||||
if (auto alphaValue = internal->params.forceAlphaValue(); alphaValue) {
|
||||
const int pixelCount = internal->params.width() * internal->params.height();
|
||||
const int channels = 4;
|
||||
constexpr int kAlphaChannel = 3;
|
||||
uint8_t* pixelBuffer = static_cast<uint8_t*>(buffer);
|
||||
for (int p = 0; p < pixelCount; p++) {
|
||||
pixelBuffer[p * channels + kAlphaChannel] = *alphaValue * 255.0f;
|
||||
}
|
||||
}
|
||||
|
||||
#ifndef FILAMENT_IOS
|
||||
image::LinearImage image;
|
||||
if (internal->params.isSrgb()) {
|
||||
@@ -203,9 +229,8 @@ RenderTargetDump::RenderTargetDump(filament::backend::DriverApi& api,
|
||||
filePath);
|
||||
#endif
|
||||
};
|
||||
filament::backend::PixelBufferDescriptor pb(mInternal->bytes.data(), size,
|
||||
filament::backend::PixelDataFormat::RGBA, filament::backend::PixelDataType::UBYTE, cb,
|
||||
(void*)mInternal.get());
|
||||
filament::backend::PixelBufferDescriptor pb(mInternal->bytes.data(), size, readPixelFormat,
|
||||
readPixelType, cb, (void*) mInternal.get());
|
||||
api.readPixels(renderTarget, 0, 0, mInternal->params.width(), mInternal->params.height(),
|
||||
std::move(pb));
|
||||
}
|
||||
|
||||
@@ -19,6 +19,7 @@
|
||||
|
||||
#include <filesystem>
|
||||
#include <vector>
|
||||
#include <optional>
|
||||
|
||||
#include "gtest/gtest.h"
|
||||
|
||||
@@ -27,9 +28,9 @@
|
||||
|
||||
// Arguments are (RenderTargetHandle renderTarget, ImageExpectations& expectations,
|
||||
// ScreenshotParams screenshotParams)
|
||||
#define EXPECT_IMAGE(renderTarget, expectations, screenshotParams) \
|
||||
#define EXPECT_IMAGE(renderTarget, screenshotParams) \
|
||||
do { \
|
||||
expectations.addExpectation( \
|
||||
getExpectations().addExpectation( \
|
||||
__FILE__, \
|
||||
__LINE__, \
|
||||
renderTarget, \
|
||||
@@ -45,12 +46,72 @@ class ScreenshotParams {
|
||||
public:
|
||||
// TODO(b/422804941): Add a set of environments where this test should use a different golden.
|
||||
ScreenshotParams(int width, int height, std::string fileName, uint32_t expectedPixelHash,
|
||||
bool isSrgb = false, int numAllowedDeviations = 0, int pixelMatchThreshold = 0);
|
||||
bool isSrgb = false, int numAllowedDeviations = 0, int pixelMatchThreshold = 0,
|
||||
std::optional<float> forceAlphaValue = std::nullopt);
|
||||
|
||||
class Builder {
|
||||
public:
|
||||
Builder& width(int width) {
|
||||
mWidth = width;
|
||||
return *this;
|
||||
}
|
||||
|
||||
Builder& height(int height) {
|
||||
mHeight = height;
|
||||
return *this;
|
||||
}
|
||||
|
||||
Builder& fileName(std::string fileName) {
|
||||
mFileName = fileName;
|
||||
return *this;
|
||||
}
|
||||
|
||||
Builder& expectedPixelHash(uint32_t pixelHash) {
|
||||
mExpectedPixelHash = pixelHash;
|
||||
return *this;
|
||||
}
|
||||
|
||||
Builder& isSrgb(bool isSrgb) {
|
||||
mIsSrgb = isSrgb;
|
||||
return *this;
|
||||
}
|
||||
|
||||
Builder& numAllowedDeviations(int numAllowedDeviations) {
|
||||
mNumAllowedDeviations = numAllowedDeviations;
|
||||
return *this;
|
||||
}
|
||||
|
||||
Builder& pixelMatchTheshold(int pixelMatchTheshold) {
|
||||
mPixelMatchThreshold = pixelMatchTheshold;
|
||||
return *this;
|
||||
}
|
||||
|
||||
Builder& forceAlphaValue(float alphaValue) {
|
||||
mForceAlphaValue = alphaValue;
|
||||
return *this;
|
||||
}
|
||||
|
||||
ScreenshotParams build() {
|
||||
return ScreenshotParams(mWidth, mHeight, mFileName, mExpectedPixelHash, mIsSrgb,
|
||||
mNumAllowedDeviations, mPixelMatchThreshold, mForceAlphaValue);
|
||||
}
|
||||
|
||||
private:
|
||||
int mWidth;
|
||||
int mHeight;
|
||||
std::string mFileName;
|
||||
uint32_t mExpectedPixelHash;
|
||||
bool mIsSrgb;
|
||||
int mNumAllowedDeviations;
|
||||
int mPixelMatchThreshold;
|
||||
std::optional<float> mForceAlphaValue;
|
||||
};
|
||||
|
||||
int width() const;
|
||||
int height() const;
|
||||
bool isSrgb() const;
|
||||
uint32_t expectedHash() const;
|
||||
std::optional<float> forceAlphaValue() const;
|
||||
|
||||
static std::filesystem::path actualDirectoryPath();
|
||||
std::string actualFileName() const;
|
||||
@@ -70,6 +131,7 @@ private:
|
||||
std::string mFileName;
|
||||
int mAllowedPixelDeviations;
|
||||
int mPixelMatchThreshold;
|
||||
std::optional<float> mForceAlphaValue;
|
||||
};
|
||||
|
||||
/**
|
||||
|
||||
@@ -173,6 +173,7 @@ ShaderGenerator::Blob ShaderGenerator::transpileShader(ShaderStage stage, std::s
|
||||
return { (uint8_t*)spirv.data(), (uint8_t*)(spirv.data() + spirv.size()) };
|
||||
} else if (backend == Backend::WEBGPU){
|
||||
filamat::GLSLPostProcessor::spirvToWgsl(&spirv, &result);
|
||||
return { result.c_str(), result.c_str() + result.length() + 1 };
|
||||
}
|
||||
|
||||
return {};
|
||||
|
||||
@@ -47,7 +47,7 @@ layout(location = 0) in vec4 mesh_position;
|
||||
void main() {
|
||||
gl_Position = vec4(mesh_position.xy, 0.0, 1.0);
|
||||
#if defined(TARGET_VULKAN_ENVIRONMENT)
|
||||
// In Vulkan, clip space is Y-down. In OpenGL and Metal, clip space is Y-up.
|
||||
// In Vulkan, clip space is Y-down. In OpenGL, Metal and WebGPU, clip space is Y-up.
|
||||
gl_Position.y = -gl_Position.y;
|
||||
#endif
|
||||
})" };
|
||||
@@ -64,7 +64,7 @@ void main() {
|
||||
params.scaleMinusOne.z + 1.0,
|
||||
1.0);
|
||||
#if defined(TARGET_VULKAN_ENVIRONMENT)
|
||||
// In Vulkan, clip space is Y-down. In OpenGL and Metal, clip space is Y-up.
|
||||
// In Vulkan, clip space is Y-down. In OpenGL, Metal and WebGPU, clip space is Y-up.
|
||||
gl_Position.y = -gl_Position.y;
|
||||
#endif
|
||||
})" };
|
||||
@@ -80,7 +80,7 @@ void main() {
|
||||
gl_Position = vec4(mesh_position.xy, 0.0, 1.0);
|
||||
uv = (mesh_position.xy * 0.5 + 0.5);
|
||||
#if defined(TARGET_VULKAN_ENVIRONMENT)
|
||||
// In Vulkan, clip space is Y-down. In OpenGL and Metal, clip space is Y-up.
|
||||
// In Vulkan, clip space is Y-down. In OpenGL, Metal and WebGPU, clip space is Y-up.
|
||||
gl_Position.y = -gl_Position.y;
|
||||
#endif
|
||||
})" };
|
||||
@@ -158,9 +158,19 @@ layout(binding = 0, set = 0) uniform Params {
|
||||
} params;
|
||||
)";
|
||||
}
|
||||
case ShaderUniformType::Sampler: {
|
||||
case ShaderUniformType::Sampler2D: {
|
||||
return R"(
|
||||
layout(location = 0, set = 0) uniform sampler2D test_tex;
|
||||
)";
|
||||
}
|
||||
case ShaderUniformType::ISampler2D: {
|
||||
return R"(
|
||||
layout(location = 0, set = 0) uniform isampler2D test_tex;
|
||||
)";
|
||||
}
|
||||
case ShaderUniformType::USampler2D: {
|
||||
return R"(
|
||||
layout(location = 0, set = 0) uniform usampler2D test_tex;
|
||||
)";
|
||||
}
|
||||
default:
|
||||
@@ -179,7 +189,7 @@ std::vector<UniformConfig> GetUniformConfig(ShaderUniformType type) {
|
||||
case ShaderUniformType::SimpleWithPadding: {
|
||||
return {{ "Params" }};
|
||||
}
|
||||
case ShaderUniformType::Sampler: {
|
||||
case ShaderUniformType::Sampler2D: {
|
||||
filament::SamplerInterfaceBlock::SamplerInfo samplerInfo{
|
||||
"backend_test", "test_tex", 0,
|
||||
SamplerType::SAMPLER_2D, SamplerFormat::FLOAT, Precision::HIGH, false };
|
||||
@@ -187,6 +197,22 @@ std::vector<UniformConfig> GetUniformConfig(ShaderUniformType type) {
|
||||
"test_tex", DescriptorType::SAMPLER_2D_FLOAT, samplerInfo
|
||||
}};
|
||||
}
|
||||
case ShaderUniformType::ISampler2D: {
|
||||
filament::SamplerInterfaceBlock::SamplerInfo samplerInfo{
|
||||
"backend_test", "test_tex", 0,
|
||||
SamplerType::SAMPLER_2D, SamplerFormat::INT, Precision::HIGH, false };
|
||||
return {{
|
||||
"test_tex", DescriptorType::SAMPLER_2D_INT, samplerInfo
|
||||
}};
|
||||
}
|
||||
case ShaderUniformType::USampler2D: {
|
||||
filament::SamplerInterfaceBlock::SamplerInfo samplerInfo{
|
||||
"backend_test", "test_tex", 0,
|
||||
SamplerType::SAMPLER_2D, SamplerFormat::UINT, Precision::HIGH, false };
|
||||
return {{
|
||||
"test_tex", DescriptorType::SAMPLER_2D_INT, samplerInfo
|
||||
}};
|
||||
}
|
||||
default:
|
||||
abort();
|
||||
}
|
||||
@@ -252,4 +278,4 @@ std::string SharedShaders::getFragmentShaderText(FragmentShaderType fragment,
|
||||
return fragmentText->withUniform(*uniformText);
|
||||
}
|
||||
|
||||
} // namespace test
|
||||
} // namespace test
|
||||
|
||||
@@ -23,7 +23,9 @@ enum class ShaderUniformType : uint8_t {
|
||||
None,
|
||||
Simple,
|
||||
SimpleWithPadding,
|
||||
Sampler,
|
||||
Sampler2D,
|
||||
ISampler2D,
|
||||
USampler2D,
|
||||
};
|
||||
|
||||
struct SimpleMaterialParams {
|
||||
|
||||
@@ -199,7 +199,7 @@ TEST_F(BlitTest, ColorMagnify) {
|
||||
|
||||
{
|
||||
RenderFrame frame(api);
|
||||
EXPECT_IMAGE(dstRenderTargets[0], getExpectations(),
|
||||
EXPECT_IMAGE(dstRenderTargets[0],
|
||||
ScreenshotParams(kDstTexWidth, kDstTexHeight, "ColorMagnify", 0x410bdd31));
|
||||
api.commit(swapChain);
|
||||
}
|
||||
@@ -255,7 +255,7 @@ TEST_F(BlitTest, ColorMinify) {
|
||||
{ 0, 0, kSrcTexWidth >> srcLevel, kSrcTexHeight >> srcLevel },
|
||||
SamplerMagFilter::LINEAR);
|
||||
|
||||
EXPECT_IMAGE(dstRenderTargets[0], getExpectations(),
|
||||
EXPECT_IMAGE(dstRenderTargets[0],
|
||||
ScreenshotParams(kDstTexWidth, kDstTexHeight, "ColorMinify", 0xf3d9c53f));
|
||||
}
|
||||
|
||||
@@ -336,7 +336,7 @@ TEST_F(BlitTest, ColorResolve) {
|
||||
srcRenderTarget, { 0, 0, kSrcTexWidth, kSrcTexHeight },
|
||||
SamplerMagFilter::NEAREST);
|
||||
|
||||
EXPECT_IMAGE(dstRenderTarget, getExpectations(),
|
||||
EXPECT_IMAGE(dstRenderTarget,
|
||||
ScreenshotParams(kDstTexWidth, kDstTexHeight, "ColorResolve", 531759687));
|
||||
}
|
||||
|
||||
@@ -403,7 +403,7 @@ TEST_F(BlitTest, Blit2DTextureArray) {
|
||||
|
||||
{
|
||||
RenderFrame frame(api);
|
||||
EXPECT_IMAGE(dstRenderTarget, getExpectations(),
|
||||
EXPECT_IMAGE(dstRenderTarget,
|
||||
ScreenshotParams(kDstTexWidth, kDstTexHeight, "Blit2DTextureArray",
|
||||
0x8de7d55b));
|
||||
api.commit(swapChain);
|
||||
@@ -479,7 +479,7 @@ TEST_F(BlitTest, BlitRegion) {
|
||||
RenderFrame frame(api);
|
||||
// TODO: for some reason, this test has very, very slight (as in one pixel) differences
|
||||
// between OpenGL and Metal. So disable golden checking for now.
|
||||
// EXPECT_IMAGE(dstRenderTarget, expectations, ScreenshotParams(kDstTexWidth,
|
||||
// EXPECT_IMAGE(dstRenderTarget, ScreenshotParams(kDstTexWidth,
|
||||
// kDstTexHeight, "BlitRegion", 0x74fa34ed));
|
||||
api.commit(swapChain);
|
||||
}
|
||||
@@ -546,7 +546,7 @@ TEST_F(BlitTest, BlitRegionToSwapChain) {
|
||||
|
||||
// TODO: for some reason, this test has been disabled. It needs to be tested on all
|
||||
// machines.
|
||||
// EXPECT_IMAGE(dstRenderTarget, expectations,
|
||||
// EXPECT_IMAGE(dstRenderTarget,
|
||||
// ScreenshotParams(kDstTexWidth, kDstTexHeight, "BlitRegionToSwapChain", 0x0));
|
||||
}
|
||||
|
||||
|
||||
@@ -237,9 +237,8 @@ TEST_F(BufferUpdatesTest, BufferObjectUpdateWithOffset) {
|
||||
}
|
||||
|
||||
|
||||
EXPECT_IMAGE(renderTarget, getExpectations(),
|
||||
ScreenshotParams(screenWidth(), screenHeight(), "BufferObjectUpdateWithOffset",
|
||||
2320747245));
|
||||
EXPECT_IMAGE(renderTarget, ScreenshotParams(screenWidth(), screenHeight(),
|
||||
"BufferObjectUpdateWithOffset", 2320747245));
|
||||
|
||||
api.flush();
|
||||
api.commit(swapChain);
|
||||
|
||||
@@ -247,7 +247,7 @@ TEST_F(BackendTest, FeedbackLoops) {
|
||||
// NOTE: Calling glReadPixels on any miplevel other than the base level
|
||||
// seems to be un-reliable on some GPU's.
|
||||
if (frame == kNumFrames - 1) {
|
||||
EXPECT_IMAGE(renderTargets[0], getExpectations(),
|
||||
EXPECT_IMAGE(renderTargets[0],
|
||||
ScreenshotParams(kTexWidth, kTexHeight, "FeedbackLoops", 4192780705));
|
||||
}
|
||||
|
||||
|
||||
@@ -287,9 +287,9 @@ TEST_F(LoadImageTest, UpdateImage2D) {
|
||||
// Test integer format uploads.
|
||||
// TODO: These cases fail on OpenGL and Vulkan.
|
||||
// TODO: These cases now also fail on Metal, but at some point previously worked.
|
||||
testCases.emplace_back("RGB_INTEGER UBYTE to RGB8UI", PixelDataFormat::RGB_INTEGER, PixelDataType::UBYTE, TextureFormat::RGB8UI);
|
||||
testCases.emplace_back("RGB_INTEGER USHORT to RGB16UI", PixelDataFormat::RGB_INTEGER, PixelDataType::USHORT, TextureFormat::RGB16UI);
|
||||
testCases.emplace_back("RGB_INTEGER INT to RGB32I", PixelDataFormat::RGB_INTEGER, PixelDataType::INT, TextureFormat::RGB32I);
|
||||
testCases.emplace_back("RGB_INTEGER UBYTE to RGB8UI", PixelDataFormat::RGB_INTEGER, PixelDataType::UBYTE, TextureFormat::RGB8UI);
|
||||
testCases.emplace_back("RGB_INTEGER USHORT to RGB16UI", PixelDataFormat::RGB_INTEGER, PixelDataType::USHORT, TextureFormat::RGB16UI);
|
||||
testCases.emplace_back("RGB_INTEGER INT to RGB32I", PixelDataFormat::RGB_INTEGER, PixelDataType::INT, TextureFormat::RGB32I);
|
||||
|
||||
// Test uploads with buffer padding.
|
||||
// TODO: Vulkan crashes with "Assertion failed: (offset + size <= allocationSize)"
|
||||
@@ -319,14 +319,23 @@ TEST_F(LoadImageTest, UpdateImage2D) {
|
||||
auto defaultRenderTarget = cleanup.add(api.createDefaultRenderTarget(0));
|
||||
|
||||
// Create a program.
|
||||
filament::SamplerInterfaceBlock::SamplerInfo samplerInfo { "test", "tex", 0,
|
||||
SamplerType::SAMPLER_2D, getSamplerFormat(t.textureFormat), Precision::HIGH, false };
|
||||
|
||||
std::string const fragment = getFormattedFragment(fragmentTemplate, t.textureFormat);
|
||||
Shader shader(api, cleanup, ShaderConfig{
|
||||
.vertexShader = mVertexShader,
|
||||
.fragmentShader= fragment,
|
||||
.uniforms = {{"test_tex", DescriptorType::SAMPLER_2D_FLOAT, samplerInfo}}
|
||||
ShaderUniformType uniformType;
|
||||
switch (getSamplerFormat(t.textureFormat)) {
|
||||
case SamplerFormat::FLOAT:
|
||||
case SamplerFormat::SHADOW: // not used for tests, but must cover all cases
|
||||
uniformType = ShaderUniformType::Sampler2D;
|
||||
break;
|
||||
case SamplerFormat::INT:
|
||||
uniformType = ShaderUniformType::ISampler2D;
|
||||
break;
|
||||
case SamplerFormat::UINT:
|
||||
uniformType = ShaderUniformType::USampler2D;
|
||||
break;
|
||||
}
|
||||
Shader shader = SharedShaders::makeShader(api, cleanup, {
|
||||
.mVertexType = VertexShaderType::Textured,
|
||||
.mFragmentType = FragmentShaderType::Textured,
|
||||
.mUniformType = uniformType,
|
||||
});
|
||||
|
||||
// Create a Texture.
|
||||
@@ -374,8 +383,13 @@ TEST_F(LoadImageTest, UpdateImage2D) {
|
||||
api.draw2(0, 3, 1);
|
||||
api.endRenderPass();
|
||||
|
||||
EXPECT_IMAGE(defaultRenderTarget, getExpectations(),
|
||||
ScreenshotParams(kTexSize, kTexSize, t.name, expectedHash));
|
||||
EXPECT_IMAGE(defaultRenderTarget, ScreenshotParams::Builder()
|
||||
.width(kTexSize)
|
||||
.height(kTexSize)
|
||||
.fileName(t.name)
|
||||
.expectedPixelHash(expectedHash)
|
||||
.forceAlphaValue(1.0f)
|
||||
.build());
|
||||
|
||||
api.commit(swapChain);
|
||||
api.endFrame(0);
|
||||
@@ -463,7 +477,7 @@ TEST_F(LoadImageTest, UpdateImageSRGB) {
|
||||
api.draw2(0, 3, 1);
|
||||
api.endRenderPass();
|
||||
|
||||
EXPECT_IMAGE(defaultRenderTarget, getExpectations(),
|
||||
EXPECT_IMAGE(defaultRenderTarget,
|
||||
ScreenshotParams(kTexSize, kTexSize, "UpdateImageSRGB", 3300305265));
|
||||
|
||||
api.commit(swapChain);
|
||||
@@ -539,7 +553,7 @@ TEST_F(LoadImageTest, UpdateImageMipLevel) {
|
||||
api.endRenderPass();
|
||||
}
|
||||
|
||||
EXPECT_IMAGE(defaultRenderTarget, getExpectations(),
|
||||
EXPECT_IMAGE(defaultRenderTarget,
|
||||
ScreenshotParams(kTexSize, kTexSize, "UpdateImageMipLevel", 1875922935));
|
||||
|
||||
api.commit(swapChain);
|
||||
@@ -625,7 +639,7 @@ TEST_F(LoadImageTest, UpdateImage3D) {
|
||||
api.draw2(0, 3, 1);
|
||||
api.endRenderPass();
|
||||
|
||||
EXPECT_IMAGE(defaultRenderTarget, getExpectations(),
|
||||
EXPECT_IMAGE(defaultRenderTarget,
|
||||
ScreenshotParams(kTexSize, kTexSize, "UpdateImage3D", 1875922935));
|
||||
}
|
||||
|
||||
|
||||
@@ -40,7 +40,7 @@ std::string fragmentTexturedLod (R"(#version 450 core
|
||||
layout(location = 0) out vec4 fragColor;
|
||||
layout(location = 0) in vec2 uv;
|
||||
|
||||
layout(location = 0, set = 0) uniform sampler2D backend_test_sib_tex;
|
||||
layout(binding = 0, set = 0) uniform sampler2D backend_test_sib_tex;
|
||||
|
||||
void main() {
|
||||
fragColor = textureLod(backend_test_sib_tex, uv, 1);
|
||||
@@ -69,12 +69,12 @@ TEST_F(BackendTest, TextureViewLod) {
|
||||
Shader whiteShader = SharedShaders::makeShader(api, cleanup, ShaderRequest {
|
||||
.mVertexType = VertexShaderType::Textured,
|
||||
.mFragmentType = FragmentShaderType::White,
|
||||
.mUniformType = ShaderUniformType::Sampler
|
||||
.mUniformType = ShaderUniformType::Sampler2D
|
||||
});
|
||||
|
||||
// Create a program that samples a texture.
|
||||
std::string vertexShader = SharedShaders::getVertexShaderText(
|
||||
VertexShaderType::Textured, ShaderUniformType::Sampler);
|
||||
VertexShaderType::Textured, ShaderUniformType::Sampler2D);
|
||||
filament::SamplerInterfaceBlock::SamplerInfo samplerInfo {
|
||||
"backend_test", "sib_tex", 0,
|
||||
SamplerType::SAMPLER_2D, SamplerFormat::FLOAT, Precision::HIGH, false };
|
||||
|
||||
@@ -105,6 +105,7 @@ void initPushConstants() {
|
||||
|
||||
TEST_F(BackendTest, PushConstants) {
|
||||
SKIP_IF(Backend::OPENGL, "Push constants not supported on OpenGL");
|
||||
SKIP_IF(Backend::WEBGPU, "Push constants not supported on WebGPU");
|
||||
|
||||
initPushConstants();
|
||||
|
||||
@@ -178,9 +179,8 @@ TEST_F(BackendTest, PushConstants) {
|
||||
|
||||
api.endRenderPass();
|
||||
|
||||
EXPECT_IMAGE(renderTarget, getExpectations(),
|
||||
ScreenshotParams(params.viewport.width, params.viewport.height, "pushConstants",
|
||||
3575588741));
|
||||
EXPECT_IMAGE(renderTarget, ScreenshotParams(params.viewport.width, params.viewport.height,
|
||||
"pushConstants", 3575588741));
|
||||
|
||||
api.commit(swapChain);
|
||||
api.endFrame(0);
|
||||
|
||||
@@ -40,7 +40,7 @@ Shader createShader(DriverApi& api, Cleanup& cleanup, Backend backend) {
|
||||
return SharedShaders::makeShader(api, cleanup, ShaderRequest{
|
||||
.mVertexType = VertexShaderType::Textured,
|
||||
.mFragmentType = FragmentShaderType::Textured,
|
||||
.mUniformType = ShaderUniformType::Sampler
|
||||
.mUniformType = ShaderUniformType::Sampler2D
|
||||
});
|
||||
}
|
||||
|
||||
@@ -199,7 +199,7 @@ TEST_F(BackendTest, RenderExternalImage) {
|
||||
api.flush();
|
||||
api.commit(swapChain);
|
||||
api.endFrame(0);
|
||||
EXPECT_IMAGE(defaultRenderTarget, getExpectations(),
|
||||
EXPECT_IMAGE(defaultRenderTarget,
|
||||
ScreenshotParams(screenWidth(), screenHeight(), "RenderExternalImage", 1206264951));
|
||||
|
||||
api.stopCapture(0);
|
||||
|
||||
@@ -132,7 +132,7 @@ TEST_F(BackendTest, ScissorViewportRegion) {
|
||||
api.draw2(0, 3, 1);
|
||||
api.endRenderPass();
|
||||
|
||||
EXPECT_IMAGE(fullRenderTarget, getExpectations(),
|
||||
EXPECT_IMAGE(fullRenderTarget,
|
||||
ScreenshotParams(kSrcTexWidth >> 1, kSrcTexHeight >> 1, "scissor", 15842520));
|
||||
|
||||
api.commit(swapChain);
|
||||
@@ -224,7 +224,7 @@ TEST_F(BackendTest, ScissorViewportEdgeCases) {
|
||||
api.draw2(0, 3, 1);
|
||||
api.endRenderPass();
|
||||
|
||||
EXPECT_IMAGE(renderTarget, getExpectations(),
|
||||
EXPECT_IMAGE(renderTarget,
|
||||
ScreenshotParams(512, 512, "ScissorViewportEdgeCases", 2199186852));
|
||||
|
||||
api.commit(swapChain);
|
||||
|
||||
@@ -144,7 +144,7 @@ TEST_F(BasicStencilBufferTest, StencilBuffer) {
|
||||
|
||||
RunTest(renderTarget);
|
||||
|
||||
EXPECT_IMAGE(renderTarget, getExpectations(),
|
||||
EXPECT_IMAGE(renderTarget,
|
||||
ScreenshotParams(screenWidth(), screenHeight(), "StencilBuffer", 0x3B1AEF0F));
|
||||
|
||||
flushAndWait();
|
||||
@@ -170,7 +170,7 @@ TEST_F(BasicStencilBufferTest, DepthAndStencilBuffer) {
|
||||
|
||||
RunTest(renderTarget);
|
||||
|
||||
EXPECT_IMAGE(renderTarget, getExpectations(),
|
||||
EXPECT_IMAGE(renderTarget,
|
||||
ScreenshotParams(screenWidth(), screenHeight(), "DepthAndStencilBuffer", 0x3B1AEF0F));
|
||||
|
||||
flushAndWait();
|
||||
@@ -266,9 +266,8 @@ TEST_F(BasicStencilBufferTest, StencilBufferMSAA) {
|
||||
api.stopCapture(0);
|
||||
api.endFrame(0);
|
||||
|
||||
EXPECT_IMAGE(renderTarget1, getExpectations(),
|
||||
ScreenshotParams(screenWidth(), screenHeight(), "StencilBufferAutoResolve",
|
||||
3353562179));
|
||||
EXPECT_IMAGE(renderTarget1, ScreenshotParams(screenWidth(), screenHeight(),
|
||||
"StencilBufferAutoResolve", 3353562179));
|
||||
|
||||
flushAndWait();
|
||||
getDriver().purge();
|
||||
|
||||
@@ -164,7 +164,9 @@ struct BloomOptions {
|
||||
};
|
||||
|
||||
/**
|
||||
* Options to control large-scale fog in the scene
|
||||
* Options to control large-scale fog in the scene. Materials can enable the `linearFog` property,
|
||||
* which uses a simplified, linear equation for fog calculation; in this mode, the heightFalloff
|
||||
* is ignored as well as the mipmap selection in IBL or skyColor mode.
|
||||
*/
|
||||
struct FogOptions {
|
||||
/**
|
||||
@@ -183,7 +185,7 @@ struct FogOptions {
|
||||
float cutOffDistance = INFINITY;
|
||||
|
||||
/**
|
||||
* fog's maximum opacity between 0 and 1
|
||||
* fog's maximum opacity between 0 and 1. Ignored in `linearFog` mode.
|
||||
*/
|
||||
float maximumOpacity = 1.0f;
|
||||
|
||||
@@ -193,12 +195,15 @@ struct FogOptions {
|
||||
float height = 0.0f;
|
||||
|
||||
/**
|
||||
* How fast the fog dissipates with altitude. heightFalloff has a unit of [1/m].
|
||||
* How fast the fog dissipates with the altitude. heightFalloff has a unit of [1/m].
|
||||
* It can be expressed as 1/H, where H is the altitude change in world units [m] that causes a
|
||||
* factor 2.78 (e) change in fog density.
|
||||
*
|
||||
* A falloff of 0 means the fog density is constant everywhere and may result is slightly
|
||||
* faster computations.
|
||||
*
|
||||
* In `linearFog` mode, only use to compute the slope of the linear equation. Completely
|
||||
* ignored if set to 0.
|
||||
*/
|
||||
float heightFalloff = 1.0f;
|
||||
|
||||
@@ -220,7 +225,7 @@ struct FogOptions {
|
||||
LinearColor color = { 1.0f, 1.0f, 1.0f };
|
||||
|
||||
/**
|
||||
* Extinction factor in [1/m] at altitude 'height'. The extinction factor controls how much
|
||||
* Extinction factor in [1/m] at an altitude 'height'. The extinction factor controls how much
|
||||
* light is absorbed and out-scattered per unit of distance. Each unit of extinction reduces
|
||||
* the incoming light to 37% of its original value.
|
||||
*
|
||||
@@ -229,11 +234,16 @@ struct FogOptions {
|
||||
* the composition of the fog/atmosphere.
|
||||
*
|
||||
* For historical reason this parameter is called `density`.
|
||||
*
|
||||
* In `linearFog` mode this is the slope of the linear equation if heightFalloff is set to 0.
|
||||
* Otherwise, heightFalloff affects the slope calculation such that it matches the slope of
|
||||
* the standard equation at the camera height.
|
||||
*/
|
||||
float density = 0.1f;
|
||||
|
||||
/**
|
||||
* Distance in world units [m] from the camera where the Sun in-scattering starts.
|
||||
* Ignored in `linearFog` mode.
|
||||
*/
|
||||
float inScatteringStart = 0.0f;
|
||||
|
||||
@@ -242,6 +252,7 @@ struct FogOptions {
|
||||
* is scattered (by the fog) towards the camera.
|
||||
* Size of the Sun in-scattering (>0 to activate). Good values are >> 1 (e.g. ~10 - 100).
|
||||
* Smaller values result is a larger scattering size.
|
||||
* Ignored in `linearFog` mode.
|
||||
*/
|
||||
float inScatteringSize = -1.0f;
|
||||
|
||||
@@ -269,6 +280,8 @@ struct FogOptions {
|
||||
*
|
||||
* `fogColorFromIbl` is ignored when skyTexture is specified.
|
||||
*
|
||||
* In `linearFog` mode mipmap level 0 is always used.
|
||||
*
|
||||
* @see Texture
|
||||
* @see fogColorFromIbl
|
||||
*/
|
||||
@@ -283,7 +296,7 @@ struct FogOptions {
|
||||
/**
|
||||
* Options to control Depth of Field (DoF) effect in the scene.
|
||||
*
|
||||
* cocScale can be used to set the depth of field blur independently from the camera
|
||||
* cocScale can be used to set the depth of field blur independently of the camera
|
||||
* aperture, e.g. for artistic reasons. This can be achieved by setting:
|
||||
* cocScale = cameraAperture / desiredDoFAperture
|
||||
*
|
||||
|
||||
+47
-13
@@ -16,32 +16,66 @@
|
||||
|
||||
#include "DFG.h"
|
||||
|
||||
#include "ZstdHelper.h"
|
||||
|
||||
#include "details/Engine.h"
|
||||
#include "details/Texture.h"
|
||||
|
||||
#include <filament/Texture.h>
|
||||
|
||||
#include <backend/DriverEnums.h>
|
||||
|
||||
#include <utils/debug.h>
|
||||
#include <utils/compiler.h>
|
||||
#include <utils/Panic.h>
|
||||
|
||||
#include <cstdlib>
|
||||
#include <cstdint>
|
||||
#include <cstddef>
|
||||
#include <utility>
|
||||
|
||||
#include "generated/resources/dfg.h"
|
||||
|
||||
namespace filament {
|
||||
|
||||
const uint16_t DFG::DFG_LUT[] = {
|
||||
#include "generated/data/dfg.inc"
|
||||
};
|
||||
|
||||
void DFG::init(FEngine& engine) noexcept {
|
||||
void DFG::init(FEngine& engine) {
|
||||
constexpr size_t fp16Count = DFG_LUT_SIZE * DFG_LUT_SIZE * 3;
|
||||
constexpr size_t byteCount = fp16Count * sizeof(uint16_t);
|
||||
|
||||
static_assert(sizeof(DFG_LUT) == byteCount, "DFG_LUT_SIZE doesn't match size of the DFG LUT");
|
||||
|
||||
Texture* lut = Texture::Builder()
|
||||
Texture::Builder builder = Texture::Builder()
|
||||
.width(DFG_LUT_SIZE)
|
||||
.height(DFG_LUT_SIZE)
|
||||
.format(backend::TextureFormat::RGB16F)
|
||||
.build(engine);
|
||||
.format(backend::TextureFormat::RGB16F);
|
||||
|
||||
Texture::PixelBufferDescriptor buffer(DFG_LUT, byteCount,
|
||||
Texture::Format::RGB, Texture::Type::HALF);
|
||||
if (ZstdHelper::isCompressed(DFG_PACKAGE, DFG_DFG_SIZE)) {
|
||||
const size_t decodedSize = ZstdHelper::getDecodedSize(DFG_PACKAGE, byteCount);
|
||||
assert_invariant(decodedSize == byteCount);
|
||||
|
||||
lut->setImage(engine, 0, std::move(buffer));
|
||||
// If the LUT is Zstd compressed, decompress it.
|
||||
void* decodedData = malloc(decodedSize);
|
||||
|
||||
FILAMENT_CHECK_POSTCONDITION(decodedData)
|
||||
<< "Couldn't allocate " << decodedSize << " bytes for DFG LUT decompression.";
|
||||
|
||||
if (UTILS_LIKELY(decodedData)) {
|
||||
bool const success = ZstdHelper::decompress(
|
||||
decodedData, decodedSize, DFG_PACKAGE, byteCount);
|
||||
|
||||
FILAMENT_CHECK_POSTCONDITION(success) << "Couldn't decompress DFG LUT.";
|
||||
|
||||
// Use decodedData for the texture
|
||||
Texture* lut = builder.build(engine);
|
||||
lut->setImage(engine, 0, { decodedData, decodedSize,
|
||||
Texture::Format::RGB, Texture::Type::HALF,
|
||||
+[](void* buffer, size_t, void*) { free(buffer); } });
|
||||
mLUT = downcast(lut);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
assert_invariant(DFG_DFG_SIZE == byteCount);
|
||||
Texture* lut = builder.build(engine);
|
||||
lut->setImage(engine, 0, { DFG_PACKAGE, byteCount, Texture::Format::RGB, Texture::Type::HALF });
|
||||
mLUT = downcast(lut);
|
||||
}
|
||||
|
||||
|
||||
+4
-4
@@ -23,6 +23,9 @@
|
||||
|
||||
#include <utils/compiler.h>
|
||||
|
||||
#include <cstdint>
|
||||
#include <cstddef>
|
||||
|
||||
namespace filament {
|
||||
|
||||
class FEngine;
|
||||
@@ -40,7 +43,7 @@ public:
|
||||
DFG& operator=(DFG const& rhs) = delete;
|
||||
DFG& operator=(DFG&& rhs) = delete;
|
||||
|
||||
void init(FEngine& engine) noexcept;
|
||||
void init(FEngine& engine);
|
||||
|
||||
size_t getLutSize() const noexcept {
|
||||
return DFG_LUT_SIZE;
|
||||
@@ -61,9 +64,6 @@ private:
|
||||
|
||||
// make sure to use the right size here
|
||||
static constexpr size_t DFG_LUT_SIZE = FILAMENT_DFG_LUT_SIZE;
|
||||
|
||||
// this lookup table is generated with cmgen
|
||||
static const uint16_t DFG_LUT[];
|
||||
};
|
||||
|
||||
#undef FILAMENT_DFG_LUT_SIZE
|
||||
|
||||
@@ -363,6 +363,10 @@ bool MaterialParser::getStereoscopicType(StereoscopicType* value) const noexcept
|
||||
return mImpl.getFromSimpleChunk(MaterialStereoscopicType, reinterpret_cast<uint8_t*>(value));
|
||||
}
|
||||
|
||||
bool MaterialParser::getMaterialCrc32(uint32_t* value) const noexcept {
|
||||
return mImpl.getFromSimpleChunk(MaterialCrc32, value);
|
||||
}
|
||||
|
||||
bool MaterialParser::getRequiredAttributes(AttributeBitset* value) const noexcept {
|
||||
uint32_t rawAttributes = 0;
|
||||
if (!mImpl.getFromSimpleChunk(MaterialRequiredAttributes, &rawAttributes)) {
|
||||
|
||||
@@ -126,6 +126,7 @@ public:
|
||||
bool getSpecularAntiAliasingVariance(float* value) const noexcept;
|
||||
bool getSpecularAntiAliasingThreshold(float* value) const noexcept;
|
||||
bool getStereoscopicType(backend::StereoscopicType*) const noexcept;
|
||||
bool getMaterialCrc32(uint32_t* value) const noexcept;
|
||||
|
||||
bool getShader(filaflat::ShaderContent& shader, backend::ShaderModel shaderModel,
|
||||
Variant variant, backend::ShaderStage stage) noexcept;
|
||||
|
||||
@@ -198,7 +198,8 @@ FMaterial* PostProcessManager::PostProcessMaterial::getMaterial(FEngine& engine,
|
||||
if (UTILS_UNLIKELY(mSize)) {
|
||||
loadMaterial(engine);
|
||||
}
|
||||
mMaterial->prepareProgram(Variant{ Variant::type_t(variant) });
|
||||
mMaterial->prepareProgram(Variant{ Variant::type_t(variant) },
|
||||
CompilerPriorityQueue::CRITICAL);
|
||||
return mMaterial;
|
||||
}
|
||||
|
||||
|
||||
@@ -243,7 +243,7 @@ void RenderPass::appendCommands(FEngine const& engine,
|
||||
for (Command const* first = curr, *last = curr + commandCount ; first != last ; ++first) {
|
||||
if (UTILS_LIKELY((first->key & CUSTOM_MASK) == uint64_t(CustomCommand::PASS))) {
|
||||
auto ma = first->info.mi->getMaterial();
|
||||
ma->prepareProgram(first->info.materialVariant);
|
||||
ma->prepareProgram(first->info.materialVariant, CompilerPriorityQueue::CRITICAL);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -112,6 +112,8 @@ RendererUtils::ColorPassOutput RendererUtils::colorPass(
|
||||
|
||||
const bool canAutoResolveDepth = engine.getDriverApi().isAutoDepthResolveSupported();
|
||||
|
||||
FrameGraphTexture::Usage depthStencilUsage = FrameGraphTexture::Usage::DEPTH_ATTACHMENT;
|
||||
|
||||
if (!data.depth) {
|
||||
// clear newly allocated depth/stencil buffers, regardless of given clear flags
|
||||
clearDepthFlags = TargetBufferFlags::DEPTH;
|
||||
@@ -151,6 +153,7 @@ RendererUtils::ColorPassOutput RendererUtils::colorPass(
|
||||
.format = format,
|
||||
});
|
||||
if (config.enabledStencilBuffer) {
|
||||
depthStencilUsage |= FrameGraphTexture::Usage::STENCIL_ATTACHMENT;
|
||||
data.stencil = data.depth;
|
||||
}
|
||||
}
|
||||
@@ -172,10 +175,10 @@ RendererUtils::ColorPassOutput RendererUtils::colorPass(
|
||||
// We set a "read" constraint on these attachments here because we need to preserve them
|
||||
// when the color pass happens in several passes (e.g. with SSR)
|
||||
data.color = builder.read(data.color, FrameGraphTexture::Usage::COLOR_ATTACHMENT);
|
||||
data.depth = builder.read(data.depth, FrameGraphTexture::Usage::DEPTH_ATTACHMENT);
|
||||
data.depth = builder.read(data.depth, depthStencilUsage);
|
||||
|
||||
data.color = builder.write(data.color, FrameGraphTexture::Usage::COLOR_ATTACHMENT);
|
||||
data.depth = builder.write(data.depth, FrameGraphTexture::Usage::DEPTH_ATTACHMENT);
|
||||
data.depth = builder.write(data.depth, depthStencilUsage);
|
||||
|
||||
/*
|
||||
* There is a bit of magic happening here regarding the viewport used.
|
||||
|
||||
@@ -0,0 +1,42 @@
|
||||
/*
|
||||
* Copyright (C) 2025 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include "ZstdHelper.h"
|
||||
|
||||
#include <zstd.h>
|
||||
|
||||
#include <cstddef>
|
||||
#include <cstdint>
|
||||
|
||||
namespace filament {
|
||||
|
||||
bool ZstdHelper::isCompressed(const void* src, size_t src_size) noexcept {
|
||||
if (src_size < 4) {
|
||||
return false;
|
||||
}
|
||||
const uint32_t magic = *static_cast<const uint32_t*>(src);
|
||||
return magic == ZSTD_MAGICNUMBER;
|
||||
}
|
||||
|
||||
size_t ZstdHelper::getDecodedSize(const void* src, size_t src_size) noexcept {
|
||||
return ZSTD_getFrameContentSize(src, src_size);
|
||||
}
|
||||
|
||||
size_t ZstdHelper::decompress(void* dst, size_t dst_size, const void* src, size_t src_size) noexcept {
|
||||
return ZSTD_decompress(dst, dst_size, src, src_size);
|
||||
}
|
||||
|
||||
} // namespace filament
|
||||
@@ -0,0 +1,55 @@
|
||||
/*
|
||||
* Copyright (C) 2025 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef TNT_FILAMENT_ZSTD_HELPER_H
|
||||
#define TNT_FILAMENT_ZSTD_HELPER_H
|
||||
|
||||
#include <stddef.h>
|
||||
|
||||
namespace filament {
|
||||
|
||||
class ZstdHelper {
|
||||
public:
|
||||
/**
|
||||
* Checks if the given binary blob is Zstd compressed.
|
||||
* @param src Pointer to the source data.
|
||||
* @param src_size Size of the source data.
|
||||
* @return True if the data is Zstd compressed, false otherwise.
|
||||
*/
|
||||
static bool isCompressed(const void* src, size_t src_size) noexcept;
|
||||
|
||||
/**
|
||||
* Returns the decompressed size of a Zstd compressed blob.
|
||||
* @param src Pointer to the source data.
|
||||
* @param src_size Size of the source data.
|
||||
* @return The decompressed size, or 0 if an error occurs.
|
||||
*/
|
||||
static size_t getDecodedSize(const void* src, size_t src_size) noexcept;
|
||||
|
||||
/**
|
||||
* Decompresses a Zstd compressed blob into a pre-allocated buffer.
|
||||
* @param dst Pointer to the destination buffer.
|
||||
* @param dst_size Size of the destination buffer.
|
||||
* @param src Pointer to the source data.
|
||||
* @param src_size Size of the source data.
|
||||
* @return The number of bytes decompressed, or 0 if an error occurs.
|
||||
*/
|
||||
static size_t decompress(void* dst, size_t dst_size, const void* src, size_t src_size) noexcept;
|
||||
};
|
||||
|
||||
} // namespace filament
|
||||
|
||||
#endif // TNT_FILAMENT_ZSTD_HELPER_H
|
||||
@@ -101,6 +101,8 @@ backend::Platform::DriverConfig getDriverConfig(FEngine* instance) {
|
||||
.handleArenaSize = instance->getRequestedDriverHandleArenaSize(),
|
||||
.metalUploadBufferSizeBytes = instance->getConfig().metalUploadBufferSizeBytes,
|
||||
.disableParallelShaderCompile = instance->features.backend.disable_parallel_shader_compile,
|
||||
.disableAmortizedShaderCompile =
|
||||
instance->features.backend.disable_amortized_shader_compile,
|
||||
.disableHandleUseAfterFreeCheck =
|
||||
instance->features.backend.disable_handle_use_after_free_check,
|
||||
.disableHeapHandleTags = instance->features.backend.disable_heap_handle_tags,
|
||||
|
||||
@@ -733,6 +733,8 @@ public:
|
||||
CORRECTNESS_ASSERTION_DEFAULT;
|
||||
bool assert_material_instance_texture_descriptor_set_compatible =
|
||||
CORRECTNESS_ASSERTION_DEFAULT;
|
||||
bool assert_texture_format_mipmappable = CORRECTNESS_ASSERTION_DEFAULT;
|
||||
bool assert_texture_can_generate_mipmap = CORRECTNESS_ASSERTION_DEFAULT;
|
||||
} debug;
|
||||
} engine;
|
||||
struct {
|
||||
@@ -746,15 +748,22 @@ public:
|
||||
bool enable_staging_buffer_bypass = false;
|
||||
} vulkan;
|
||||
bool disable_parallel_shader_compile = false;
|
||||
bool disable_amortized_shader_compile = false;
|
||||
bool disable_handle_use_after_free_check = false;
|
||||
bool disable_heap_handle_tags = true; // FIXME: this should be false
|
||||
} backend;
|
||||
struct {
|
||||
bool check_crc32_after_loading = false;
|
||||
} material;
|
||||
} features;
|
||||
|
||||
std::array<FeatureFlag, sizeof(features)> const mFeatures{{
|
||||
{ "backend.disable_parallel_shader_compile",
|
||||
"Disable parallel shader compilation in GL and Metal backends.",
|
||||
&features.backend.disable_parallel_shader_compile, true },
|
||||
{ "backend.disable_amortized_shader_compile",
|
||||
"Disable amortized shader compilation in GL backend.",
|
||||
&features.backend.disable_amortized_shader_compile, true },
|
||||
{ "backend.disable_handle_use_after_free_check",
|
||||
"Disable Handle<> use-after-free checks.",
|
||||
&features.backend.disable_handle_use_after_free_check, true },
|
||||
@@ -783,11 +792,20 @@ public:
|
||||
"Assert that the attribute stride of a vertex buffer is a multiple of 4.",
|
||||
&features.engine.debug.assert_vertex_buffer_attribute_stride_mult_of_4, false },
|
||||
{ "backend.vulkan.enable_staging_buffer_bypass",
|
||||
"vulkan: enable a staging bypass logic for unified memory architecture",
|
||||
"vulkan: enable a staging bypass logic for unified memory architecture.",
|
||||
&features.backend.vulkan.enable_staging_buffer_bypass, false },
|
||||
{ "engine.debug.assert_material_instance_texture_descriptor_set_compatible",
|
||||
"Assert that the textures in a material instance are compatible with descriptor set.",
|
||||
&features.engine.debug.assert_material_instance_texture_descriptor_set_compatible, false },
|
||||
{ "engine.debug.assert_texture_format_mipmappable",
|
||||
"Assert if a texture (with levels > 1) that the format is mipmappable.",
|
||||
&features.engine.debug.assert_texture_format_mipmappable, false },
|
||||
{ "engine.debug.assert_texture_can_generate_mipmap",
|
||||
"Assert if a texture has the correct usage set for generating mipmaps.",
|
||||
&features.engine.debug.assert_texture_can_generate_mipmap, false },
|
||||
{ "material.check_crc32_after_loading",
|
||||
"Verify the checksum of package data when a material is loaded.",
|
||||
&features.material.check_crc32_after_loading, false },
|
||||
}};
|
||||
|
||||
utils::Slice<const FeatureFlag> getFeatureFlags() const noexcept {
|
||||
|
||||
@@ -188,6 +188,28 @@ Material* Material::Builder::build(Engine& engine) const {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
// Try checking CRC32 value for the package and skip if it's unavailable.
|
||||
if (downcast(engine).features.material.check_crc32_after_loading) {
|
||||
uint32_t parsedCrc32 = 0;
|
||||
materialParser->getMaterialCrc32(&parsedCrc32);
|
||||
|
||||
constexpr size_t crc32ChunkSize = sizeof(uint64_t) + sizeof(uint32_t) + sizeof(uint32_t);
|
||||
const size_t originalSize = mImpl->mSize - crc32ChunkSize;
|
||||
assert_invariant(mImpl->mSize > crc32ChunkSize);
|
||||
|
||||
std::vector<uint32_t> crc32Table;
|
||||
hash::crc32GenerateTable(crc32Table);
|
||||
uint32_t expectedCrc32 = hash::crc32Update(0, mImpl->mPayload, originalSize, crc32Table);
|
||||
if (parsedCrc32 != expectedCrc32) {
|
||||
CString name;
|
||||
materialParser->getName(&name);
|
||||
LOG(ERROR) << "The material '" << name.c_str_safe()
|
||||
<< "' is corrupted: crc32_expected=" << expectedCrc32
|
||||
<< ", crc32_parsed=" << parsedCrc32;
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
uint32_t v = 0;
|
||||
materialParser->getShaderModels(&v);
|
||||
bitset32 shaderModels;
|
||||
@@ -223,7 +245,7 @@ Material* Material::Builder::build(Engine& engine) const {
|
||||
materialParser->getName(&name);
|
||||
LOG(WARNING) << "The stereoscopic type in the compiled material '"
|
||||
<< name.c_str_safe() << "' is " << (int) materialStereoscopicType
|
||||
<< ", which is not compatiable with the engine's setting "
|
||||
<< ", which is not compatible with the engine's setting "
|
||||
<< (int) engineStereoscopicType << ".";
|
||||
}
|
||||
}
|
||||
@@ -1164,7 +1186,7 @@ void FMaterial::precacheDepthVariants(FEngine& engine) {
|
||||
}
|
||||
assert_invariant(Variant::isValidDepthVariant(variant));
|
||||
if (hasVariant(variant)) {
|
||||
prepareProgram(variant);
|
||||
prepareProgram(variant, CompilerPriorityQueue::HIGH);
|
||||
}
|
||||
}
|
||||
return;
|
||||
|
||||
@@ -142,7 +142,7 @@ public:
|
||||
// Must be called outside of backend render pass.
|
||||
// Must be called before getProgram() below.
|
||||
void prepareProgram(Variant const variant,
|
||||
backend::CompilerPriorityQueue const priorityQueue = CompilerPriorityQueue::HIGH) const noexcept {
|
||||
backend::CompilerPriorityQueue const priorityQueue) const noexcept {
|
||||
// prepareProgram() is called for each RenderPrimitive in the scene, so it must be efficient.
|
||||
if (UTILS_UNLIKELY(!isCached(variant))) {
|
||||
prepareProgramSlow(variant, priorityQueue);
|
||||
|
||||
@@ -242,16 +242,29 @@ Texture* Texture::Builder::build(Engine& engine) {
|
||||
|
||||
if (mImpl->mUsage == TextureUsage::NONE) {
|
||||
mImpl->mUsage = TextureUsage::DEFAULT;
|
||||
if (mImpl->mLevels > 1 &&
|
||||
(mImpl->mWidth > 1 || mImpl->mHeight > 1) &&
|
||||
!mImpl->mExternal) {
|
||||
const bool formatMipmappable =
|
||||
downcast(engine).getDriverApi().isTextureFormatMipmappable(mImpl->mFormat);
|
||||
if (formatMipmappable) {
|
||||
// by default mipmappable textures have the BLIT usage bits set
|
||||
mImpl->mUsage |= TextureUsage::BLIT_SRC | TextureUsage::BLIT_DST;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
auto const& featureFlags = downcast(engine).features.engine.debug;
|
||||
|
||||
bool const formatMipmappable =
|
||||
downcast(engine).getDriverApi().isTextureFormatMipmappable(mImpl->mFormat);
|
||||
|
||||
FILAMENT_FLAG_GUARDED_CHECK_PRECONDITION(mImpl->mLevels == 1 || formatMipmappable,
|
||||
featureFlags.assert_texture_format_mipmappable)
|
||||
<< "Texture levels is > 1 (levels=" << +mImpl->mLevels
|
||||
<< " dim=" << mImpl->mWidth << "x" << mImpl->mHeight
|
||||
<< ", but the format ("
|
||||
<< int(mImpl->mFormat) << ") "
|
||||
<< " is not mipmppable";
|
||||
|
||||
// TODO: This exists for backwards compatibility, but should remove when safe.
|
||||
if (!featureFlags.assert_texture_can_generate_mipmap &&
|
||||
// Guess whether GEN_MIPMAPPABLE should be added or not based the following criteria.
|
||||
(formatMipmappable &&
|
||||
mImpl->mLevels > 1 &&
|
||||
(mImpl->mWidth > 1 || mImpl->mHeight > 1) &&
|
||||
!mImpl->mExternal)) {
|
||||
mImpl->mUsage |= TextureUsage::GEN_MIPMAPPABLE;
|
||||
}
|
||||
|
||||
// TODO: remove in a future filament release.
|
||||
@@ -640,6 +653,9 @@ void FTexture::generateMipmaps(FEngine& engine) const noexcept {
|
||||
FILAMENT_CHECK_PRECONDITION(formatMipmappable)
|
||||
<< "Texture format " << (unsigned)mFormat << " is not mipmappable.";
|
||||
|
||||
FILAMENT_CHECK_PRECONDITION(any(mUsage & TextureUsage::GEN_MIPMAPPABLE))
|
||||
<< "Texture usage does not have GEN_MIPMAPPABLE set";
|
||||
|
||||
if (mLevelCount < 2 || (mWidth == 1 && mHeight == 1)) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -19,8 +19,6 @@
|
||||
|
||||
#include "Froxelizer.h"
|
||||
#include "PerViewDescriptorSetUtils.h"
|
||||
#include "HwDescriptorSetLayoutFactory.h"
|
||||
#include "ShadowMapManager.h"
|
||||
#include "TypedUniformBuffer.h"
|
||||
|
||||
#include "components/LightManager.h"
|
||||
@@ -30,10 +28,8 @@
|
||||
#include "details/IndirectLight.h"
|
||||
#include "details/Texture.h"
|
||||
|
||||
#include <filament/Engine.h>
|
||||
#include <filament/Exposure.h>
|
||||
#include <filament/Options.h>
|
||||
#include <filament/TextureSampler.h>
|
||||
#include <filament/MaterialEnums.h>
|
||||
#include <filament/Viewport.h>
|
||||
|
||||
@@ -56,9 +52,11 @@
|
||||
#include <algorithm>
|
||||
#include <array>
|
||||
#include <cmath>
|
||||
#include <cstring>
|
||||
#include <cstddef>
|
||||
#include <limits>
|
||||
#include <random>
|
||||
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
|
||||
namespace filament {
|
||||
@@ -243,6 +241,22 @@ void ColorPassDescriptorSet::prepareFog(FEngine& engine, const CameraInfo& camer
|
||||
.filterMin = SamplerMinFilter::LINEAR_MIPMAP_LINEAR
|
||||
});
|
||||
|
||||
// Fog calculation details:
|
||||
// Optical path: (
|
||||
// f = heightFalloff
|
||||
// Te(y, z) = z * density * (exp(-f * eye_y) - exp(-f * eye_y - f * y)) / (f * y)
|
||||
// Transmittance:
|
||||
// t(y , z) = exp(-Te(y, z))
|
||||
|
||||
// In Linear Mode, formally the slope of the linear equation is: dt(y,z)/dz(0, eye_y)
|
||||
// (the derivative of the transmittance at distance 0 and camera height). When the height
|
||||
// falloff is disabled, the density parameter exactly represents this value.
|
||||
constexpr double EPSILON = std::numeric_limits<float>::epsilon();
|
||||
double const f = heightFalloff;
|
||||
double const eye = userCameraPosition.y - options.height;
|
||||
double const dt = options.density * (f <= EPSILON ? 1.0 : (std::exp(-f * eye) - std::exp(-2.0 * f * eye)) / (f * eye));
|
||||
float const fogEndLinear = float(1.0 / dt);
|
||||
|
||||
s.fogStart = options.distance;
|
||||
s.fogMaxOpacity = options.maximumOpacity;
|
||||
s.fogHeightFalloff = heightFalloff;
|
||||
@@ -253,6 +267,8 @@ void ColorPassDescriptorSet::prepareFog(FEngine& engine, const CameraInfo& camer
|
||||
s.fogInscatteringSize = options.inScatteringSize;
|
||||
s.fogColorFromIbl = fogColorTextureHandle ? 1.0f : 0.0f;
|
||||
s.fogFromWorldMatrix = mat3f{ cof(fogFromWorld) };
|
||||
s.fogLinearParams = { 1.0f / (fogEndLinear - options.distance),
|
||||
-options.distance / (fogEndLinear - options.distance) };
|
||||
}
|
||||
|
||||
void ColorPassDescriptorSet::prepareSSAO(Handle<HwTexture> ssao,
|
||||
@@ -332,7 +348,7 @@ void ColorPassDescriptorSet::prepareDirectionalLight(FEngine& engine,
|
||||
}
|
||||
}
|
||||
|
||||
void ColorPassDescriptorSet::prepareAmbientLight(FEngine& engine, FIndirectLight const& ibl,
|
||||
void ColorPassDescriptorSet::prepareAmbientLight(FEngine const& engine, FIndirectLight const& ibl,
|
||||
float const intensity, float const exposure) noexcept {
|
||||
auto& s = mUniforms.edit();
|
||||
|
||||
|
||||
@@ -115,7 +115,7 @@ public:
|
||||
void prepareDirectionalLight(FEngine& engine, float exposure,
|
||||
math::float3 const& sceneSpaceDirection, LightManagerInstance instance) noexcept;
|
||||
|
||||
void prepareAmbientLight(FEngine& engine,
|
||||
void prepareAmbientLight(FEngine const& engine,
|
||||
FIndirectLight const& ibl, float intensity, float exposure) noexcept;
|
||||
|
||||
void prepareDynamicLights(Froxelizer& froxelizer) noexcept;
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
Pod::Spec.new do |spec|
|
||||
spec.name = "Filament"
|
||||
spec.version = "1.63.1"
|
||||
spec.version = "1.63.0"
|
||||
spec.license = { :type => "Apache 2.0", :file => "LICENSE" }
|
||||
spec.homepage = "https://google.github.io/filament"
|
||||
spec.authors = "Google LLC."
|
||||
spec.summary = "Filament is a real-time physically based rendering engine for Android, iOS, Windows, Linux, macOS, and WASM/WebGL."
|
||||
spec.platform = :ios, "11.0"
|
||||
spec.source = { :http => "https://github.com/google/filament/releases/download/v1.63.1/filament-v1.63.1-ios.tgz" }
|
||||
spec.source = { :http => "https://github.com/google/filament/releases/download/v1.63.0/filament-v1.63.0-ios.tgz" }
|
||||
|
||||
# Fix linking error with Xcode 12; we do not yet support the simulator on Apple silicon.
|
||||
spec.pod_target_xcconfig = {
|
||||
|
||||
@@ -21,7 +21,7 @@ targetTemplates:
|
||||
base:
|
||||
OTHER_LDFLAGS: ["-lfilament", "-lbackend", "-lfilaflat", "-lktxreader",
|
||||
"-lfilabridge", "-lutils", "-lsmol-v", "-lgeometry", "-libl",
|
||||
"-labseil"]
|
||||
"-labseil", "-lzstd"]
|
||||
ENABLE_BITCODE: NO
|
||||
CLANG_CXX_LANGUAGE_STANDARD: gnu++17
|
||||
# This allows users to not have to specify a unique bundle ID when building the sample apps.
|
||||
|
||||
@@ -255,6 +255,7 @@
|
||||
"-lgeometry",
|
||||
"-libl",
|
||||
"-labseil",
|
||||
"-lzstd",
|
||||
"-lfilamat",
|
||||
"-force_load ../../../out/ios-debug/filament/lib/arm64/libbackend_test.a",
|
||||
);
|
||||
@@ -363,6 +364,7 @@
|
||||
"-lgeometry",
|
||||
"-libl",
|
||||
"-labseil",
|
||||
"-lzstd",
|
||||
"-lfilamat",
|
||||
"-force_load ../../../out/ios-debug/filament/lib/arm64/libbackend_test.a",
|
||||
);
|
||||
@@ -464,6 +466,7 @@
|
||||
"-lgeometry",
|
||||
"-libl",
|
||||
"-labseil",
|
||||
"-lzstd",
|
||||
"-lfilamat",
|
||||
"-force_load ../../../out/ios-debug/filament/lib/arm64/libbackend_test.a",
|
||||
);
|
||||
@@ -510,6 +513,7 @@
|
||||
"-lgeometry",
|
||||
"-libl",
|
||||
"-labseil",
|
||||
"-lzstd",
|
||||
"-lfilamat",
|
||||
"-force_load ../../../out/ios-debug/filament/lib/arm64/libbackend_test.a",
|
||||
);
|
||||
|
||||
@@ -426,6 +426,7 @@
|
||||
"-lgeometry",
|
||||
"-libl",
|
||||
"-labseil",
|
||||
"-lzstd",
|
||||
"-lgltfio_core",
|
||||
"-luberarchive",
|
||||
"-limage",
|
||||
@@ -482,6 +483,7 @@
|
||||
"-lgeometry",
|
||||
"-libl",
|
||||
"-labseil",
|
||||
"-lzstd",
|
||||
"-lgltfio_core",
|
||||
"-luberarchive",
|
||||
"-limage",
|
||||
@@ -600,6 +602,7 @@
|
||||
"-lgeometry",
|
||||
"-libl",
|
||||
"-labseil",
|
||||
"-lzstd",
|
||||
"-lgltfio_core",
|
||||
"-luberarchive",
|
||||
"-limage",
|
||||
@@ -656,6 +659,7 @@
|
||||
"-lgeometry",
|
||||
"-libl",
|
||||
"-labseil",
|
||||
"-lzstd",
|
||||
"-lgltfio_core",
|
||||
"-luberarchive",
|
||||
"-limage",
|
||||
|
||||
@@ -293,6 +293,7 @@
|
||||
"-lgeometry",
|
||||
"-libl",
|
||||
"-labseil",
|
||||
"-lzstd",
|
||||
"-lfilameshio",
|
||||
"-lmeshoptimizer",
|
||||
"-limage",
|
||||
@@ -340,6 +341,7 @@
|
||||
"-lgeometry",
|
||||
"-libl",
|
||||
"-labseil",
|
||||
"-lzstd",
|
||||
"-lfilameshio",
|
||||
"-lmeshoptimizer",
|
||||
"-limage",
|
||||
@@ -449,6 +451,7 @@
|
||||
"-lgeometry",
|
||||
"-libl",
|
||||
"-labseil",
|
||||
"-lzstd",
|
||||
"-lfilameshio",
|
||||
"-lmeshoptimizer",
|
||||
"-limage",
|
||||
@@ -613,6 +616,7 @@
|
||||
"-lgeometry",
|
||||
"-libl",
|
||||
"-labseil",
|
||||
"-lzstd",
|
||||
"-lfilameshio",
|
||||
"-lmeshoptimizer",
|
||||
"-limage",
|
||||
|
||||
@@ -329,6 +329,7 @@
|
||||
"-lgeometry",
|
||||
"-libl",
|
||||
"-labseil",
|
||||
"-lzstd",
|
||||
"-lgltfio_core",
|
||||
"-luberarchive",
|
||||
"-limage",
|
||||
@@ -382,6 +383,7 @@
|
||||
"-lgeometry",
|
||||
"-libl",
|
||||
"-labseil",
|
||||
"-lzstd",
|
||||
"-lgltfio_core",
|
||||
"-luberarchive",
|
||||
"-limage",
|
||||
@@ -607,6 +609,7 @@
|
||||
"-lgeometry",
|
||||
"-libl",
|
||||
"-labseil",
|
||||
"-lzstd",
|
||||
"-lgltfio_core",
|
||||
"-luberarchive",
|
||||
"-limage",
|
||||
@@ -660,6 +663,7 @@
|
||||
"-lgeometry",
|
||||
"-libl",
|
||||
"-labseil",
|
||||
"-lzstd",
|
||||
"-lgltfio_core",
|
||||
"-luberarchive",
|
||||
"-limage",
|
||||
|
||||
@@ -310,6 +310,7 @@
|
||||
"-lgeometry",
|
||||
"-libl",
|
||||
"-labseil",
|
||||
"-lzstd",
|
||||
"-lfilameshio",
|
||||
"-lmeshoptimizer",
|
||||
"-limage",
|
||||
@@ -357,6 +358,7 @@
|
||||
"-lgeometry",
|
||||
"-libl",
|
||||
"-labseil",
|
||||
"-lzstd",
|
||||
"-lfilameshio",
|
||||
"-lmeshoptimizer",
|
||||
"-limage",
|
||||
@@ -404,6 +406,7 @@
|
||||
"-lgeometry",
|
||||
"-libl",
|
||||
"-labseil",
|
||||
"-lzstd",
|
||||
"-lfilameshio",
|
||||
"-lmeshoptimizer",
|
||||
"-limage",
|
||||
@@ -561,6 +564,7 @@
|
||||
"-lgeometry",
|
||||
"-libl",
|
||||
"-labseil",
|
||||
"-lzstd",
|
||||
"-lfilameshio",
|
||||
"-lmeshoptimizer",
|
||||
"-limage",
|
||||
|
||||
@@ -232,6 +232,7 @@
|
||||
"-lgeometry",
|
||||
"-libl",
|
||||
"-labseil",
|
||||
"-lzstd",
|
||||
);
|
||||
PRODUCT_BUNDLE_IDENTIFIER = "${SAMPLE_CODE_DISAMBIGUATOR}.google.filament.hello-triangle";
|
||||
SAMPLE_CODE_DISAMBIGUATOR = "${DEVELOPMENT_TEAM}";
|
||||
@@ -338,6 +339,7 @@
|
||||
"-lgeometry",
|
||||
"-libl",
|
||||
"-labseil",
|
||||
"-lzstd",
|
||||
);
|
||||
PRODUCT_BUNDLE_IDENTIFIER = "${SAMPLE_CODE_DISAMBIGUATOR}.google.filament.hello-triangle";
|
||||
SAMPLE_CODE_DISAMBIGUATOR = "${DEVELOPMENT_TEAM}";
|
||||
@@ -382,6 +384,7 @@
|
||||
"-lgeometry",
|
||||
"-libl",
|
||||
"-labseil",
|
||||
"-lzstd",
|
||||
);
|
||||
PRODUCT_BUNDLE_IDENTIFIER = "${SAMPLE_CODE_DISAMBIGUATOR}.google.filament.hello-triangle";
|
||||
SAMPLE_CODE_DISAMBIGUATOR = "${DEVELOPMENT_TEAM}";
|
||||
@@ -536,6 +539,7 @@
|
||||
"-lgeometry",
|
||||
"-libl",
|
||||
"-labseil",
|
||||
"-lzstd",
|
||||
);
|
||||
PRODUCT_BUNDLE_IDENTIFIER = "${SAMPLE_CODE_DISAMBIGUATOR}.google.filament.hello-triangle";
|
||||
SAMPLE_CODE_DISAMBIGUATOR = "${DEVELOPMENT_TEAM}";
|
||||
|
||||
@@ -394,6 +394,7 @@
|
||||
"-lgeometry",
|
||||
"-libl",
|
||||
"-labseil",
|
||||
"-lzstd",
|
||||
);
|
||||
PRODUCT_BUNDLE_IDENTIFIER = "${SAMPLE_CODE_DISAMBIGUATOR}.google.filament.transparent-rendering";
|
||||
SAMPLE_CODE_DISAMBIGUATOR = "${DEVELOPMENT_TEAM}";
|
||||
@@ -438,6 +439,7 @@
|
||||
"-lgeometry",
|
||||
"-libl",
|
||||
"-labseil",
|
||||
"-lzstd",
|
||||
);
|
||||
PRODUCT_BUNDLE_IDENTIFIER = "${SAMPLE_CODE_DISAMBIGUATOR}.google.filament.transparent-rendering";
|
||||
SAMPLE_CODE_DISAMBIGUATOR = "${DEVELOPMENT_TEAM}";
|
||||
@@ -482,6 +484,7 @@
|
||||
"-lgeometry",
|
||||
"-libl",
|
||||
"-labseil",
|
||||
"-lzstd",
|
||||
);
|
||||
PRODUCT_BUNDLE_IDENTIFIER = "${SAMPLE_CODE_DISAMBIGUATOR}.google.filament.transparent-rendering";
|
||||
SAMPLE_CODE_DISAMBIGUATOR = "${DEVELOPMENT_TEAM}";
|
||||
@@ -526,6 +529,7 @@
|
||||
"-lgeometry",
|
||||
"-libl",
|
||||
"-labseil",
|
||||
"-lzstd",
|
||||
);
|
||||
PRODUCT_BUNDLE_IDENTIFIER = "${SAMPLE_CODE_DISAMBIGUATOR}.google.filament.transparent-rendering";
|
||||
SAMPLE_CODE_DISAMBIGUATOR = "${DEVELOPMENT_TEAM}";
|
||||
|
||||
@@ -98,6 +98,8 @@ enum UTILS_PUBLIC ChunkType : uint64_t {
|
||||
DictionaryText = charTo64bitNum("DIC_TEXT"),
|
||||
DictionarySpirv = charTo64bitNum("DIC_SPIR"),
|
||||
DictionaryMetalLibrary = charTo64bitNum("DIC_MLIB"),
|
||||
|
||||
MaterialCrc32 = charTo64bitNum("MAT_CRC "),
|
||||
};
|
||||
|
||||
} // namespace filamat
|
||||
|
||||
@@ -177,6 +177,8 @@ struct PerViewUib { // NOLINT(cppcoreguidelines-pro-type-member-init)
|
||||
float fogOneOverFarMinusNear;
|
||||
float fogNearOverFarMinusNear;
|
||||
std140::mat33 fogFromWorldMatrix;
|
||||
math::float2 fogLinearParams; // { 1/(end-start), -start/(end-start) }
|
||||
math::float2 fogReserved0;
|
||||
|
||||
// --------------------------------------------------------------------------------------------
|
||||
// Screen-space reflections [variant: SSR (i.e.: VSM | SRE)]
|
||||
@@ -202,7 +204,7 @@ struct PerViewUib { // NOLINT(cppcoreguidelines-pro-type-member-init)
|
||||
float es2Reserved2;
|
||||
|
||||
// bring PerViewUib to 2 KiB
|
||||
math::float4 reserved[40];
|
||||
math::float4 reserved[39];
|
||||
};
|
||||
|
||||
// 2 KiB == 128 float4s
|
||||
|
||||
@@ -54,6 +54,10 @@ bool MaterialChunk::initialize(filamat::ChunkType materialTag) {
|
||||
}
|
||||
|
||||
auto [start, end] = mContainer.getChunkRange(materialTag);
|
||||
if (start == end) {
|
||||
return false;
|
||||
}
|
||||
|
||||
Unflattener unflattener(start, end);
|
||||
|
||||
mUnflattener = unflattener;
|
||||
|
||||
@@ -148,7 +148,7 @@ install(DIRECTORY ${PUBLIC_HDR_DIR}/filamat DESTINATION include)
|
||||
|
||||
# Need to install libtint for filamat on Android.
|
||||
# See libs/filamat/CMakeLists.txt and android/filamat-android/CMakeLists.txt.
|
||||
if (ANDROID)
|
||||
if (ANDROID AND FILAMENT_SUPPORTS_WEBGPU)
|
||||
target_link_libraries(${TARGET} libtint_combined)
|
||||
endif()
|
||||
|
||||
|
||||
@@ -532,6 +532,9 @@ public:
|
||||
//! Enable / disable flipping of the Y coordinate of UV attributes, enabled by default.
|
||||
MaterialBuilder& flipUV(bool flipUV) noexcept;
|
||||
|
||||
//! Enable / disable the cheapest linear fog, disabled by default.
|
||||
MaterialBuilder& linearFog(bool enabled) noexcept;
|
||||
|
||||
//! Enable / disable multi-bounce ambient occlusion, disabled by default on mobile.
|
||||
MaterialBuilder& multiBounceAmbientOcclusion(bool multiBounceAO) noexcept;
|
||||
|
||||
@@ -635,6 +638,12 @@ public:
|
||||
//! specify compute kernel group size
|
||||
MaterialBuilder& groupSize(filament::math::uint3 groupSize) noexcept;
|
||||
|
||||
/**
|
||||
* Force Filament to use its default variant for depth passes. Useful if a material provides a
|
||||
* custom vertex shader which can be skipped during depth-only passes.
|
||||
*/
|
||||
MaterialBuilder& useDefaultDepthVariant() noexcept;
|
||||
|
||||
/**
|
||||
* Build the material. If you are using the Filament engine with this library, you should use
|
||||
* the job system provided by Engine.
|
||||
@@ -948,6 +957,7 @@ private:
|
||||
bool mClearCoatIorChange = true;
|
||||
|
||||
bool mFlipUV = true;
|
||||
bool mLinearFog = false;
|
||||
|
||||
bool mMultiBounceAO = false;
|
||||
bool mMultiBounceAOSet = false;
|
||||
@@ -968,6 +978,8 @@ private:
|
||||
filament::UserVariantFilterMask mVariantFilter = {};
|
||||
|
||||
bool mNoSamplerValidation = false;
|
||||
|
||||
bool mUseDefaultDepthVariant = false;
|
||||
};
|
||||
|
||||
} // namespace filamat
|
||||
|
||||
@@ -1090,6 +1090,7 @@ void GLSLPostProcessor::registerPerformancePasses(Optimizer& optimizer, Config c
|
||||
RegisterPass(CreateDeadBranchElimPass());
|
||||
RegisterPass(CreateBlockMergePass());
|
||||
RegisterPass(CreateSimplificationPass(), MaterialBuilder::TargetApi::METAL);
|
||||
RegisterPass(CreateCanonicalizeIdsPass());
|
||||
}
|
||||
|
||||
void GLSLPostProcessor::registerSizePasses(Optimizer& optimizer, Config const& config) {
|
||||
@@ -1132,6 +1133,7 @@ void GLSLPostProcessor::registerSizePasses(Optimizer& optimizer, Config const& c
|
||||
RegisterPass(CreateRedundancyEliminationPass());
|
||||
RegisterPass(CreateAggressiveDCEPass());
|
||||
RegisterPass(CreateCFGCleanupPass());
|
||||
RegisterPass(CreateCanonicalizeIdsPass());
|
||||
}
|
||||
|
||||
} // namespace filamat
|
||||
|
||||
@@ -404,6 +404,11 @@ MaterialBuilder& MaterialBuilder::groupSize(math::uint3 const groupSize) noexcep
|
||||
return *this;
|
||||
}
|
||||
|
||||
MaterialBuilder& MaterialBuilder::useDefaultDepthVariant() noexcept {
|
||||
mUseDefaultDepthVariant = true;
|
||||
return *this;
|
||||
}
|
||||
|
||||
MaterialBuilder& MaterialBuilder::materialDomain(
|
||||
MaterialDomain const materialDomain) noexcept {
|
||||
mMaterialDomain = materialDomain;
|
||||
@@ -539,6 +544,11 @@ MaterialBuilder& MaterialBuilder::flipUV(bool const flipUV) noexcept {
|
||||
return *this;
|
||||
}
|
||||
|
||||
MaterialBuilder& MaterialBuilder::linearFog(bool const enabled) noexcept {
|
||||
mLinearFog = enabled;
|
||||
return *this;
|
||||
}
|
||||
|
||||
MaterialBuilder& MaterialBuilder::customSurfaceShading(bool const customSurfaceShading) noexcept {
|
||||
mCustomSurfaceShading = customSurfaceShading;
|
||||
return *this;
|
||||
@@ -708,6 +718,7 @@ void MaterialBuilder::prepareToBuild(MaterialInfo& info) noexcept {
|
||||
info.specularAntiAliasing = mSpecularAntiAliasing;
|
||||
info.clearCoatIorChange = mClearCoatIorChange;
|
||||
info.flipUV = mFlipUV;
|
||||
info.linearFog = mLinearFog;
|
||||
info.requiredAttributes = mRequiredAttributes;
|
||||
info.blendingMode = mBlendingMode;
|
||||
info.postLightingBlendingMode = mPostLightingBlendingMode;
|
||||
@@ -925,7 +936,8 @@ bool MaterialBuilder::generateShaders(JobSystem& jobSystem, const std::vector<Va
|
||||
mMaterialVertexCode.getResolved(), mMaterialVertexCode.getLineOffset(),
|
||||
mMaterialDomain);
|
||||
|
||||
container.emplace<bool>(MaterialHasCustomDepthShader, needsStandardDepthProgram());
|
||||
container.emplace<bool>(MaterialHasCustomDepthShader,
|
||||
needsStandardDepthProgram() && !mUseDefaultDepthVariant);
|
||||
|
||||
std::atomic_bool cancelJobs(false);
|
||||
bool firstJob = true;
|
||||
@@ -1374,10 +1386,25 @@ error:
|
||||
goto error;
|
||||
}
|
||||
|
||||
// Flatten all chunks in the container into a Package.
|
||||
Package package(container.getSize());
|
||||
// Flatten all container chunks into a single package and compute its CRC32 value, storing it as
|
||||
// a separate chunk.
|
||||
constexpr size_t crc32ChunkSize = sizeof(uint64_t) + sizeof(uint32_t) + sizeof(uint32_t);
|
||||
const size_t originalContainerSize = container.getSize();
|
||||
const size_t signedContainerSize = originalContainerSize + crc32ChunkSize;
|
||||
|
||||
Package package(signedContainerSize);
|
||||
Flattener f{ package.getData() };
|
||||
container.flatten(f);
|
||||
size_t flattenSize = container.flatten(f);
|
||||
|
||||
std::vector<uint32_t> crc32Table;
|
||||
hash::crc32GenerateTable(crc32Table);
|
||||
uint32_t crc = hash::crc32Update(0, f.getStartPtr(), flattenSize, crc32Table);
|
||||
f.writeUint64(static_cast<uint64_t>(MaterialCrc32));
|
||||
f.writeUint32(static_cast<uint32_t>(sizeof(crc)));
|
||||
f.writeUint32(static_cast<uint32_t>(crc));
|
||||
|
||||
assert_invariant(flattenSize == originalContainerSize);
|
||||
assert_invariant(signedContainerSize == f.getBytesWritten());
|
||||
|
||||
return package;
|
||||
}
|
||||
|
||||
@@ -62,6 +62,9 @@ public:
|
||||
return mStart == (uint8_t*) FAKE_DRY_RUNNER_START_ADDR;
|
||||
}
|
||||
|
||||
uint8_t* getStartPtr() {
|
||||
return mStart;
|
||||
}
|
||||
size_t getBytesWritten() {
|
||||
return mCursor - mStart;
|
||||
}
|
||||
@@ -183,7 +186,7 @@ public:
|
||||
return size;
|
||||
}
|
||||
|
||||
void writeOffsetplaceholder(size_t index) {
|
||||
void writeOffsetPlaceholder(size_t index) {
|
||||
mOffsetPlaceholders.insert(std::pair<size_t, uint8_t*>(index, mCursor));
|
||||
if (!isDryRunner()) {
|
||||
mCursor[0] = 0x0;
|
||||
@@ -228,7 +231,7 @@ public:
|
||||
mCursor += 4;
|
||||
}
|
||||
|
||||
void writePlaceHoldValue(size_t v) {
|
||||
void writeValue(size_t v) {
|
||||
assert(!mValuePlaceholders.empty());
|
||||
|
||||
if (v > UINT32_MAX) {
|
||||
|
||||
@@ -57,7 +57,7 @@ void compressShader(std::string_view src, Flattener &f, const LineDictionary& di
|
||||
|
||||
cur++;
|
||||
}
|
||||
f.writePlaceHoldValue(numLines);
|
||||
f.writeValue(numLines);
|
||||
}
|
||||
|
||||
void MaterialTextChunk::flatten(Flattener& f) {
|
||||
@@ -90,7 +90,7 @@ void MaterialTextChunk::flatten(Flattener& f) {
|
||||
for (size_t i = 0; i < mEntries.size(); i++) {
|
||||
writeEntryAttributes(i, f);
|
||||
const ShaderMapping& mapping = mDuplicateMap[i];
|
||||
f.writeOffsetplaceholder(mapping.isDup ? mapping.dupOfIndex : i);
|
||||
f.writeOffsetPlaceholder(mapping.isDup ? mapping.dupOfIndex : i);
|
||||
}
|
||||
|
||||
// Write all strings
|
||||
|
||||
@@ -250,6 +250,8 @@ utils::io::sstream& CodeGenerator::generateCommonProlog(utils::io::sstream& out,
|
||||
CodeGenerator::generateDefine(out, "LEGACY_MORPHING", material.useLegacyMorphing);
|
||||
}
|
||||
if (stage == ShaderStage::FRAGMENT) {
|
||||
CodeGenerator::generateDefine(out, "FILAMENT_LINEAR_FOG",
|
||||
material.linearFog);
|
||||
CodeGenerator::generateDefine(out, "MATERIAL_HAS_CUSTOM_DEPTH",
|
||||
material.userMaterialHasCustomDepth);
|
||||
}
|
||||
|
||||
@@ -44,6 +44,7 @@ struct UTILS_PUBLIC MaterialInfo {
|
||||
bool specularAntiAliasing;
|
||||
bool clearCoatIorChange;
|
||||
bool flipUV;
|
||||
bool linearFog;
|
||||
bool multiBounceAO;
|
||||
bool multiBounceAOSet;
|
||||
bool specularAOSet;
|
||||
|
||||
@@ -189,6 +189,8 @@ BufferInterfaceBlock const& UibGenerator::getPerViewUib() noexcept {
|
||||
{ "fogOneOverFarMinusNear", 0, Type::FLOAT, Precision::HIGH },
|
||||
{ "fogNearOverFarMinusNear", 0, Type::FLOAT, Precision::HIGH },
|
||||
{ "fogFromWorldMatrix", 0, Type::MAT3, Precision::HIGH, FeatureLevel::FEATURE_LEVEL_0 },
|
||||
{ "fogLinearParams", 0, Type::FLOAT2, Precision::HIGH, FeatureLevel::FEATURE_LEVEL_0 },
|
||||
{ "fogReserved0", 0, Type::FLOAT2, Precision::HIGH },
|
||||
|
||||
// ------------------------------------------------------------------------------------
|
||||
// Screen-space reflections [variant: SSR (i.e.: VSM | SRE)]
|
||||
|
||||
@@ -65,4 +65,6 @@ add_executable(${TARGET} ${SRCS})
|
||||
|
||||
target_link_libraries(${TARGET} matp gtest)
|
||||
|
||||
target_include_directories(${TARGET} PRIVATE ${matp_SOURCE_DIR}/src)
|
||||
|
||||
set_target_properties(test_matp PROPERTIES FOLDER Tests)
|
||||
@@ -18,7 +18,6 @@
|
||||
#ifndef TNT_MATERIALPARSER_H
|
||||
#define TNT_MATERIALPARSER_H
|
||||
|
||||
#include <string>
|
||||
#include <unordered_map>
|
||||
|
||||
#include "Config.h"
|
||||
@@ -82,12 +81,14 @@ private:
|
||||
using MaterialConfigProcessor = bool (MaterialParser::*)
|
||||
(const MaterialLexeme&, filamat::MaterialBuilder& builder) const;
|
||||
// Map used to store Command pattern function pointers.
|
||||
std::unordered_map<std::string, MaterialConfigProcessor> mConfigProcessor;
|
||||
// Using string_view is generally not recommended in a map, but the string keys are program constants,
|
||||
// which guarantees that the strings will outlive lifetime of the map. See MaterialParser.cpp
|
||||
std::unordered_map<std::string_view, MaterialConfigProcessor> mConfigProcessor;
|
||||
|
||||
// The same, but for pure JSON syntax
|
||||
using MaterialConfigProcessorJSON = bool (MaterialParser::*)
|
||||
(const JsonishValue*, filamat::MaterialBuilder& builder) const;
|
||||
std::unordered_map<std::string, MaterialConfigProcessorJSON> mConfigProcessorJSON;
|
||||
std::unordered_map<std::string_view, MaterialConfigProcessorJSON> mConfigProcessorJSON;
|
||||
};
|
||||
|
||||
} // namespace matp
|
||||
|
||||
@@ -16,8 +16,6 @@
|
||||
|
||||
#include "JsonishParser.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
#include <iostream>
|
||||
|
||||
#include <string.h>
|
||||
|
||||
@@ -368,7 +368,7 @@ bool MaterialParser::parseMaterial(const char* buffer, size_t size,
|
||||
identifier = lexeme.getStringValue();
|
||||
if (mConfigProcessor.find(identifier) == mConfigProcessor.end()) {
|
||||
std::cerr << "Unknown identifier '"
|
||||
<< lexeme.getStringValue()
|
||||
<< identifier
|
||||
<< "' at line:" << lexeme.getLine()
|
||||
<< " position:" << lexeme.getLinePosition() << std::endl;
|
||||
return false;
|
||||
|
||||
@@ -1185,6 +1185,11 @@ static bool processFlipUV(MaterialBuilder& builder, const JsonishValue& value) {
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool processLinearFog(MaterialBuilder& builder, const JsonishValue& value) {
|
||||
builder.linearFog(value.toJsonBool()->getBool());
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool processMultiBounceAO(MaterialBuilder& builder, const JsonishValue& value) {
|
||||
builder.multiBounceAmbientOcclusion(value.toJsonBool()->getBool());
|
||||
return true;
|
||||
@@ -1350,6 +1355,13 @@ static bool processVariantFilter(MaterialBuilder& builder, const JsonishValue& v
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool processUseDefaultDepthVariant(MaterialBuilder& builder, const JsonishValue& value) {
|
||||
if (value.toJsonBool()->getBool()) {
|
||||
builder.useDefaultDepthVariant();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
ParametersProcessor::ParametersProcessor() {
|
||||
using Type = JsonishValue::Type;
|
||||
mParameters["name"] = { &processName, Type::STRING };
|
||||
@@ -1397,6 +1409,8 @@ ParametersProcessor::ParametersProcessor() {
|
||||
mParameters["featureLevel"] = { &processFeatureLevel, Type::NUMBER };
|
||||
mParameters["groupSize"] = { &processGroupSizes, Type::ARRAY };
|
||||
mParameters["stereoscopicType"] = { &processStereoscopicType, Type::STRING };
|
||||
mParameters["useDefaultDepthVariant"] = { &processUseDefaultDepthVariant, Type::BOOL };
|
||||
mParameters["linearFog"] = { &processLinearFog, Type::BOOL };
|
||||
}
|
||||
|
||||
bool ParametersProcessor::process(MaterialBuilder& builder, const JsonishObject& jsonObject) {
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
|
||||
#include <gtest/gtest.h>
|
||||
|
||||
#include "../src/DirIncluder.h"
|
||||
#include "DirIncluder.h"
|
||||
|
||||
using namespace utils;
|
||||
using namespace filamat;
|
||||
|
||||
@@ -18,10 +18,12 @@
|
||||
|
||||
#include "TestMaterialParser.h"
|
||||
|
||||
#include <filamat/MaterialBuilder.h>
|
||||
|
||||
#include <filament-matp/MaterialParser.h>
|
||||
#include "../src/JsonishLexer.h"
|
||||
#include "../src/JsonishParser.h"
|
||||
#include "../src/MaterialLexer.h"
|
||||
#include "JsonishLexer.h"
|
||||
#include "JsonishParser.h"
|
||||
#include "MaterialLexer.h"
|
||||
|
||||
class MaterialLexer: public ::testing::Test {
|
||||
protected:
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user