Change specularAmbientOcclusion from boolean to enum (#2352)
The user can now choose amongst 3 specular AO methods: - None, specAO is off - Simple, specAO is inferred from roughness and diffuse AO - Bent normals, specAO is computed accurately from cone intersections The last method is more expensive but produces the best results. This change also fixes a few issues: - Rename materialRefraction() and materialRefractionType() for consistency - Fixes user time in shaders
This commit is contained in:
+11
-1
@@ -5,7 +5,17 @@ A new header is inserted each time a *tag* is created.
|
||||
|
||||
## Next release
|
||||
|
||||
- gltfio: fixed incorrect cone angles with lights
|
||||
- gltfio: fixed incorrect cone angles with lights.
|
||||
- Specular ambient occlusion now offers 3 modes: off, simple (default on desktop) and bent normals.
|
||||
The latter is more accurate but more expensive and requires a bent normal to be specified in the
|
||||
material. If selected and not bent normal is specified, Filament falls back to the simple mode.
|
||||
- Specular ambient occlusion from bent normals now smoothly disappears as roughness goes from 0.3
|
||||
to 0.1. Specular ambient occlusion can completely remove specular light which looks bad on glossy
|
||||
metals. Use the simple specular occlusion mode for glossy metals instead.
|
||||
- Refraction can now be set on `MaterialBuilder` from Java.
|
||||
- Refraction mode and type can now be set by calling `MaterialBuilder::refractionMode()`.
|
||||
and `MaterialBuilder::refractionType()` instad of `materialRefraction()` and
|
||||
`materialRefractionType()` (️⚠ API change).
|
||||
|
||||
## v1.5.2
|
||||
|
||||
|
||||
@@ -83,6 +83,13 @@ Java_com_google_android_filament_filamat_MaterialBuilder_nMaterialBuilderName(JN
|
||||
builder->name(name);
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT void JNICALL
|
||||
Java_com_google_android_filament_filamat_MaterialBuilder_nMaterialBuilderMaterialDomain(JNIEnv* env,
|
||||
jclass, jlong nativeBuilder, jint domain) {
|
||||
auto builder = (MaterialBuilder*) nativeBuilder;
|
||||
builder->materialDomain((MaterialBuilder::MaterialDomain) domain);
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT void JNICALL
|
||||
Java_com_google_android_filament_filamat_MaterialBuilder_nMaterialBuilderShading(JNIEnv*,
|
||||
jclass, jlong nativeBuilder, jint shading) {
|
||||
@@ -246,6 +253,7 @@ Java_com_google_android_filament_filamat_MaterialBuilder_nMaterialBuilderSpecula
|
||||
builder->specularAntiAliasingThreshold(threshold);
|
||||
}
|
||||
|
||||
|
||||
extern "C" JNIEXPORT void JNICALL
|
||||
Java_com_google_android_filament_filamat_MaterialBuilder_nMaterialBuilderClearCoatIorChange(
|
||||
JNIEnv*, jclass, jlong nativeBuilder, jboolean clearCoatIorChange) {
|
||||
@@ -269,9 +277,23 @@ Java_com_google_android_filament_filamat_MaterialBuilder_nMaterialBuilderMultiBo
|
||||
|
||||
extern "C" JNIEXPORT void JNICALL
|
||||
Java_com_google_android_filament_filamat_MaterialBuilder_nMaterialBuilderSpecularAmbientOcclusion(
|
||||
JNIEnv*, jclass, jlong nativeBuilder, jboolean specularAO) {
|
||||
JNIEnv*, jclass, jlong nativeBuilder, jint specularAO) {
|
||||
auto builder = (MaterialBuilder*) nativeBuilder;
|
||||
builder->specularAmbientOcclusion(specularAO);
|
||||
builder->specularAmbientOcclusion((MaterialBuilder::SpecularAmbientOcclusion) specularAO);
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT void JNICALL
|
||||
Java_com_google_android_filament_filamat_MaterialBuilder_nMaterialBuilderRefractionMode(JNIEnv* env,
|
||||
jclass, jlong nativeBuilder, jint mode) {
|
||||
auto builder = (MaterialBuilder*) nativeBuilder;
|
||||
builder->refractionMode((MaterialBuilder::RefractionMode) mode);
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT void JNICALL
|
||||
Java_com_google_android_filament_filamat_MaterialBuilder_nMaterialBuilderRefractionType(JNIEnv* env,
|
||||
jclass, jlong nativeBuilder, jint type) {
|
||||
auto builder = (MaterialBuilder*) nativeBuilder;
|
||||
builder->refractionType((MaterialBuilder::RefractionType) type);
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT void JNICALL
|
||||
|
||||
+46
-3
@@ -146,6 +146,28 @@ public class MaterialBuilder {
|
||||
// mode is ignored. Can be combined with two-sided lighting
|
||||
}
|
||||
|
||||
public enum MaterialDomain {
|
||||
SURFACE,
|
||||
POST_PROCESS
|
||||
}
|
||||
|
||||
public enum SpecularAmbientOcclusion {
|
||||
NONE,
|
||||
SIMPLE,
|
||||
BENT_NORMALS
|
||||
}
|
||||
|
||||
public enum RefractionMode {
|
||||
NONE,
|
||||
CUBEMAP,
|
||||
SCREEN_SPACE
|
||||
}
|
||||
|
||||
public enum RefractionType {
|
||||
SOLID,
|
||||
THIN
|
||||
}
|
||||
|
||||
public enum Platform {
|
||||
DESKTOP,
|
||||
MOBILE,
|
||||
@@ -191,6 +213,12 @@ public class MaterialBuilder {
|
||||
return this;
|
||||
}
|
||||
|
||||
@NonNull
|
||||
public MaterialBuilder materialDomain(MaterialDomain domain) {
|
||||
nMaterialBuilderMaterialDomain(mNativeObject, domain.ordinal());
|
||||
return this;
|
||||
}
|
||||
|
||||
@NonNull
|
||||
public MaterialBuilder shading(@NonNull Shading shading) {
|
||||
nMaterialBuilderShading(mNativeObject, shading.ordinal());
|
||||
@@ -325,6 +353,18 @@ public class MaterialBuilder {
|
||||
return this;
|
||||
}
|
||||
|
||||
@NonNull
|
||||
public MaterialBuilder refractionMode(RefractionMode mode) {
|
||||
nMaterialBuilderRefractionMode(mNativeObject, mode.ordinal());
|
||||
return this;
|
||||
}
|
||||
|
||||
@NonNull
|
||||
public MaterialBuilder refractionType(RefractionType type) {
|
||||
nMaterialBuilderRefractionType(mNativeObject, type.ordinal());
|
||||
return this;
|
||||
}
|
||||
|
||||
@NonNull
|
||||
public MaterialBuilder clearCoatIorChange(boolean clearCoatIorChange) {
|
||||
nMaterialBuilderClearCoatIorChange(mNativeObject, clearCoatIorChange);
|
||||
@@ -344,8 +384,8 @@ public class MaterialBuilder {
|
||||
}
|
||||
|
||||
@NonNull
|
||||
public MaterialBuilder specularAmbientOcclusion(boolean specularAO) {
|
||||
nMaterialBuilderSpecularAmbientOcclusion(mNativeObject, specularAO);
|
||||
public MaterialBuilder specularAmbientOcclusion(SpecularAmbientOcclusion specularAO) {
|
||||
nMaterialBuilderSpecularAmbientOcclusion(mNativeObject, specularAO.ordinal());
|
||||
return this;
|
||||
}
|
||||
|
||||
@@ -419,6 +459,7 @@ public class MaterialBuilder {
|
||||
private static native void nDestroyPackage(long nativePackage);
|
||||
|
||||
private static native void nMaterialBuilderName(long nativeBuilder, String name);
|
||||
private static native void nMaterialBuilderMaterialDomain(long nativeBuilder, int domain);
|
||||
private static native void nMaterialBuilderShading(long nativeBuilder, int shading);
|
||||
private static native void nMaterialBuilderInterpolation(long nativeBuilder, int interpolation);
|
||||
private static native void nMaterialBuilderUniformParameter(long nativeBuilder, int type,
|
||||
@@ -450,13 +491,15 @@ public class MaterialBuilder {
|
||||
float variance);
|
||||
private static native void nMaterialBuilderSpecularAntiAliasingThreshold(long mNativeObject,
|
||||
float threshold);
|
||||
private static native void nMaterialBuilderRefractionMode(long nativeBuilder, int mode);
|
||||
private static native void nMaterialBuilderRefractionType(long nativeBuilder, int type);
|
||||
private static native void nMaterialBuilderClearCoatIorChange(long mNativeObject,
|
||||
boolean clearCoatIorChange);
|
||||
private static native void nMaterialBuilderFlipUV(long nativeBuilder, boolean flipUV);
|
||||
private static native void nMaterialBuilderMultiBounceAmbientOcclusion(long nativeBuilder,
|
||||
boolean multiBounceAO);
|
||||
private static native void nMaterialBuilderSpecularAmbientOcclusion(long nativeBuilder,
|
||||
boolean specularAO);
|
||||
int specularAO);
|
||||
private static native void nMaterialBuilderTransparencyMode(long nativeBuilder, int mode);
|
||||
private static native void nMaterialBuilderPlatform(long nativeBuilder, int platform);
|
||||
private static native void nMaterialBuilderTargetApi(long nativeBuilder, int api);
|
||||
|
||||
+15
-13
@@ -696,7 +696,7 @@ and with (right)</div></div></center>
|
||||
|
||||
|
||||
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 also improve the quality of
|
||||
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.24">4.2.24</a> about
|
||||
<code>specularAmbientOcclusion</code>).
|
||||
|
||||
@@ -711,11 +711,6 @@ instance.
|
||||
</p><center><div class="image" style><a href="images/material_bent_normal.gif" target="_blank"><img class="markdeep" src="images/material_bent_normal.gif"></a><div class="imagecaption"><a class="target" name="figure_bentnormalmapped"> </a><b style="font-style:normal;">Figure 17:</b> Example of a model rendered with and without a bent normal map. Both
|
||||
versions use the same ambient occlusion map.</div></div></center>
|
||||
|
||||
<p></p><p>
|
||||
|
||||
</p><div class="admonition warning">Using a bent normal map increases the runtime cost of the material, particularly when
|
||||
<code>specularAmbientOcclusion</code> is turned on.</div>
|
||||
|
||||
<p></p>
|
||||
<a class="target" name="clearcoatnormal"> </a><a class="target" name="materialmodels/litmodel/clearcoatnormal"> </a><a class="target" name="toc3.1.15"> </a><h3>Clear coat normal</h3>
|
||||
<p>
|
||||
@@ -1952,17 +1947,24 @@ occclusion enabled and disabled.</div></div></center>
|
||||
<p>
|
||||
|
||||
|
||||
</p><dl><dt>Type</dt><dd><p> <code>boolean</code>
|
||||
</p><dl><dt>Type</dt><dd><p> <code>string</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.
|
||||
</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
|
||||
compatibility reasons, <code>true</code> and <code>false</code> are also accepted and map respectively to <code>simple</code>
|
||||
and <code>none</code>.
|
||||
|
||||
</p></dd><dt>Description</dt><dd><p> Static ambient occlusion maps and dynamic ambient occlusion (SSAO, etc.) apply to diffuse
|
||||
indirect lighting. When setting this property to true, a new ambient occlusion term is
|
||||
derived from the surface roughness and applied to specular indirec lighting. This effect
|
||||
helps remove unwanted specular reflections as shown in <a href="#figure_specularao">figure 37</a>.
|
||||
indirect lighting. When setting this property to other than <code>none</code>, a new ambient occlusion
|
||||
term is derived from the surface roughness and applied to specular indirect lighting.
|
||||
This effect helps remove unwanted specular reflections as shown in <a href="#figure_specularao">figure 37</a>.
|
||||
When this value is set to <code>simple</code>, Filament uses a cheap but approximate method of computing
|
||||
the specular ambient occlusion term. If this value is set to <code>bentNormals</code>, Filament will use
|
||||
a much more accurate but much more expensive method. <code>bentNormals</code> only works if the material
|
||||
sets the <code>bentNormal</code> property inside the fragment shader. If that property isn't set,
|
||||
<code>bentNormals</code> will behave like <code>simple</code>.
|
||||
|
||||
</p></dd></dl><p></p><pre class="listing tilde"><code><span class="line">material {</span>
|
||||
<span class="line"> specularAmbientOcclusion : true</span>
|
||||
<span class="line"> specularAmbientOcclusion : simple</span>
|
||||
<span class="line">}</span></code></pre><p>
|
||||
|
||||
</p><center><div class="image" style><a href="images/screenshot_specular_ao.gif" target="_blank"><img class="markdeep" src="images/screenshot_specular_ao.gif"></a><div class="imagecaption"><a class="target" name="figure_specularao"> </a><b style="font-style:normal;">Figure 37:</b> Comparison of specular ambient occlusion on and off. The effect is
|
||||
@@ -1979,7 +1981,7 @@ particularly visible under the hose.</div></div></center>
|
||||
|
||||
</p></dd><dt>Description</dt><dd><p> Reduces specular aliasing and preserves the shape of specular highlights as an object moves
|
||||
away from the camera. This anti-aliasing solution is particularly effective on glossy materials
|
||||
(low roughness) but increases the cost of the material. The strengthf of the anti-aliasing
|
||||
(low roughness) but increases the cost of the material. The strength of the anti-aliasing
|
||||
effect can be controlled using two other properties: <code>specularAntiAliasingVariance</code> and
|
||||
<code>specularAntiAliasingThreshold</code>.
|
||||
|
||||
|
||||
+15
-12
@@ -408,7 +408,7 @@ and with (right)](images/screenshot_normal_mapping.jpg)
|
||||
### Bent normal
|
||||
|
||||
The `bentNormal` property defines the average unoccluded direction at a point on the surface. It is
|
||||
used to improve the accuracy of indirect lighting. Bent normals also improve the quality of
|
||||
used to improve the accuracy of indirect lighting. Bent normals can also improve the quality of
|
||||
specular ambient occlusion (see section [Lighting: specularAmbientOcclusion] about
|
||||
`specularAmbientOcclusion`).
|
||||
|
||||
@@ -419,10 +419,6 @@ instance.
|
||||
![Figure [bentNormalMapped]: Example of a model rendered with and without a bent normal map. Both
|
||||
versions use the same ambient occlusion map.](images/material_bent_normal.gif)
|
||||
|
||||
!!! Warning
|
||||
Using a bent normal map increases the runtime cost of the material, particularly when
|
||||
`specularAmbientOcclusion` is turned on.
|
||||
|
||||
### Clear coat normal
|
||||
|
||||
The `clearCoatNormal` property defines the normal of the clear coat layer at a given point. It
|
||||
@@ -1537,20 +1533,27 @@ occclusion enabled and disabled.](images/screenshot_multi_bounce_ao.gif)
|
||||
### Lighting: specularAmbientOcclusion
|
||||
|
||||
Type
|
||||
: `boolean`
|
||||
: `string`
|
||||
|
||||
Value
|
||||
: `true` or `false`. Defaults to `false` on mobile, `true` on desktop.
|
||||
: `none`, `simple` or `bentNormals`. Defaults to `none` on mobile, `simple` on desktop. For
|
||||
compatibility reasons, `true` and `false` are also accepted and map respectively to `simple`
|
||||
and `none`.
|
||||
|
||||
Description
|
||||
: Static ambient occlusion maps and dynamic ambient occlusion (SSAO, etc.) apply to diffuse
|
||||
indirect lighting. When setting this property to true, a new ambient occlusion term is
|
||||
derived from the surface roughness and applied to specular indirec lighting. This effect
|
||||
helps remove unwanted specular reflections as shown in figure [specularAO].
|
||||
indirect lighting. When setting this property to other than `none`, a new ambient occlusion
|
||||
term is derived from the surface roughness and applied to specular indirect lighting.
|
||||
This effect helps remove unwanted specular reflections as shown in figure [specularAO].
|
||||
When this value is set to `simple`, Filament uses a cheap but approximate method of computing
|
||||
the specular ambient occlusion term. If this value is set to `bentNormals`, Filament will use
|
||||
a much more accurate but much more expensive method. `bentNormals` only works if the material
|
||||
sets the `bentNormal` property inside the fragment shader. If that property isn't set,
|
||||
`bentNormals` will behave like `simple`.
|
||||
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ JSON
|
||||
material {
|
||||
specularAmbientOcclusion : true
|
||||
specularAmbientOcclusion : simple
|
||||
}
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
@@ -1568,7 +1571,7 @@ Value
|
||||
Description
|
||||
: Reduces specular aliasing and preserves the shape of specular highlights as an object moves
|
||||
away from the camera. This anti-aliasing solution is particularly effective on glossy materials
|
||||
(low roughness) but increases the cost of the material. The strengthf of the anti-aliasing
|
||||
(low roughness) but increases the cost of the material. The strength of the anti-aliasing
|
||||
effect can be controlled using two other properties: `specularAntiAliasingVariance` and
|
||||
`specularAntiAliasingThreshold`.
|
||||
|
||||
|
||||
@@ -84,7 +84,6 @@ public:
|
||||
*/
|
||||
void setIndirectLight(IndirectLight const* ibl) noexcept;
|
||||
|
||||
|
||||
/**
|
||||
* Adds an Entity to the Scene.
|
||||
*
|
||||
|
||||
@@ -766,7 +766,7 @@ bool FRenderer::beginFrame(FSwapChain* swapChain, uint64_t vsyncSteadyClockTimeN
|
||||
#endif
|
||||
|
||||
// latch the frame time
|
||||
std::chrono::duration<double> time(userVsync - mUserEpoch);
|
||||
std::chrono::duration<double> time(appVsync - mUserEpoch);
|
||||
float h = float(time.count());
|
||||
float l = float(time.count() - h);
|
||||
mShaderUserTime = { h, l, 0, 0 };
|
||||
|
||||
@@ -145,15 +145,24 @@ static constexpr size_t MAX_CUSTOM_ATTRIBUTES = 8;
|
||||
/**
|
||||
* Material domains
|
||||
*/
|
||||
enum MaterialDomain : uint8_t {
|
||||
enum class MaterialDomain : uint8_t {
|
||||
SURFACE = 0, //!< shaders applied to renderables
|
||||
POST_PROCESS = 1, //!< shaders applied to rendered buffers
|
||||
};
|
||||
|
||||
/**
|
||||
* Specular occlusion
|
||||
*/
|
||||
enum class SpecularAmbientOcclusion : uint8_t {
|
||||
NONE = 0, //!< no specular occlusion
|
||||
SIMPLE = 1, //!< simple specular occlusion
|
||||
BENT_NORMALS = 2, //!< more accurate specular occlusion, requires bent normals
|
||||
};
|
||||
|
||||
/**
|
||||
* Refraction
|
||||
*/
|
||||
enum RefractionMode : uint8_t {
|
||||
enum class RefractionMode : uint8_t {
|
||||
NONE = 0, //!< no refraction
|
||||
CUBEMAP = 1, //!< refracted rays go to the ibl cubemap
|
||||
SCREEN_SPACE = 2, //!< refracted rays go to screen space
|
||||
@@ -162,7 +171,7 @@ enum RefractionMode : uint8_t {
|
||||
/**
|
||||
* Refraction type
|
||||
*/
|
||||
enum RefractionType : uint8_t {
|
||||
enum class RefractionType : uint8_t {
|
||||
SOLID = 0, //!< refraction through solid objects (e.g. a sphere)
|
||||
THIN = 1, //!< refraction through thin objects (e.g. window)
|
||||
};
|
||||
|
||||
@@ -184,6 +184,7 @@ public:
|
||||
using Interpolation = filament::Interpolation;
|
||||
using VertexDomain = filament::VertexDomain;
|
||||
using TransparencyMode = filament::TransparencyMode;
|
||||
using SpecularAmbientOcclusion = filament::SpecularAmbientOcclusion;
|
||||
|
||||
using UniformType = filament::backend::UniformType;
|
||||
using SamplerType = filament::backend::SamplerType;
|
||||
@@ -235,12 +236,6 @@ public:
|
||||
//! Specify the domain that this material will operate in.
|
||||
MaterialBuilder& materialDomain(MaterialDomain materialDomain) noexcept;
|
||||
|
||||
//! Specify the refraction
|
||||
MaterialBuilder& materialRefraction(RefractionMode refraction) noexcept;
|
||||
|
||||
//! Specify the refraction type
|
||||
MaterialBuilder& materialRefractionType(RefractionType refractionType) noexcept;
|
||||
|
||||
/**
|
||||
* Set the code content of this material.
|
||||
*
|
||||
@@ -388,8 +383,14 @@ public:
|
||||
//! Enable / disable multi-bounce ambient occlusion, disabled by default on mobile.
|
||||
MaterialBuilder& multiBounceAmbientOcclusion(bool multiBounceAO) noexcept;
|
||||
|
||||
//! Enable / disable specular ambient occlusion, disabled by default on mobile.
|
||||
MaterialBuilder& specularAmbientOcclusion(bool specularAO) noexcept;
|
||||
//! Set the specular ambient occlusion technique. Disabled by default on mobile.
|
||||
MaterialBuilder& specularAmbientOcclusion(SpecularAmbientOcclusion specularAO) noexcept;
|
||||
|
||||
//! Specify the refraction
|
||||
MaterialBuilder& refractionMode(RefractionMode refraction) noexcept;
|
||||
|
||||
//! Specify the refraction type
|
||||
MaterialBuilder& refractionType(RefractionType refractionType) noexcept;
|
||||
|
||||
//! Specifies how transparent objects should be rendered (default is DEFAULT).
|
||||
MaterialBuilder& transparencyMode(TransparencyMode mode) noexcept;
|
||||
@@ -573,7 +574,8 @@ private:
|
||||
|
||||
bool mMultiBounceAO = false;
|
||||
bool mMultiBounceAOSet = false;
|
||||
bool mSpecularAO = false;
|
||||
|
||||
SpecularAmbientOcclusion mSpecularAO = SpecularAmbientOcclusion::NONE;
|
||||
bool mSpecularAOSet = false;
|
||||
};
|
||||
|
||||
|
||||
@@ -210,12 +210,12 @@ MaterialBuilder& MaterialBuilder::materialDomain(MaterialDomain materialDomain)
|
||||
return *this;
|
||||
}
|
||||
|
||||
MaterialBuilder& MaterialBuilder::materialRefraction(RefractionMode refraction) noexcept {
|
||||
MaterialBuilder& MaterialBuilder::refractionMode(RefractionMode refraction) noexcept {
|
||||
mRefractionMode = refraction;
|
||||
return *this;
|
||||
}
|
||||
|
||||
MaterialBuilder& MaterialBuilder::materialRefractionType(RefractionType refractionType) noexcept {
|
||||
MaterialBuilder& MaterialBuilder::refractionType(RefractionType refractionType) noexcept {
|
||||
mRefractionType = refractionType;
|
||||
return *this;
|
||||
}
|
||||
@@ -303,7 +303,7 @@ MaterialBuilder& MaterialBuilder::multiBounceAmbientOcclusion(bool multiBounceAO
|
||||
return *this;
|
||||
}
|
||||
|
||||
MaterialBuilder& MaterialBuilder::specularAmbientOcclusion(bool specularAO) noexcept {
|
||||
MaterialBuilder& MaterialBuilder::specularAmbientOcclusion(SpecularAmbientOcclusion specularAO) noexcept {
|
||||
mSpecularAO = specularAO;
|
||||
mSpecularAOSet = true;
|
||||
return *this;
|
||||
|
||||
@@ -41,8 +41,8 @@ struct UTILS_PUBLIC MaterialInfo {
|
||||
bool flipUV;
|
||||
bool multiBounceAO;
|
||||
bool multiBounceAOSet;
|
||||
bool specularAO;
|
||||
bool specularAOSet;
|
||||
filament::SpecularAmbientOcclusion specularAO;
|
||||
filament::RefractionMode refractionMode;
|
||||
filament::RefractionType refractionType;
|
||||
filament::AttributeBitset requiredAttributes;
|
||||
|
||||
@@ -296,32 +296,33 @@ std::string ShaderGenerator::createFragmentProgram(filament::backend::ShaderMode
|
||||
|
||||
cg.generateDefine(fs, "MAX_SHADOW_CASTING_SPOTS", uint32_t(CONFIG_MAX_SHADOW_CASTING_SPOTS));
|
||||
|
||||
bool specularAO = material.specularAOSet ?
|
||||
material.specularAO : !isMobileTarget(shaderModel);
|
||||
cg.generateDefine(fs, "SPECULAR_AMBIENT_OCCLUSION", specularAO ? 1u : 0u);
|
||||
auto defaultSpecularAO = isMobileTarget(shaderModel) ?
|
||||
SpecularAmbientOcclusion::NONE : SpecularAmbientOcclusion::SIMPLE;
|
||||
auto specularAO = material.specularAOSet ? material.specularAO : defaultSpecularAO;
|
||||
cg.generateDefine(fs, "SPECULAR_AMBIENT_OCCLUSION", uint32_t(specularAO));
|
||||
|
||||
cg.generateDefine(fs, "HAS_REFRACTION", material.refractionMode != RefractionMode::NONE);
|
||||
if (material.refractionMode != RefractionMode::NONE) {
|
||||
cg.generateDefine(fs, "REFRACTION_MODE_CUBEMAP", uint32_t(RefractionMode::CUBEMAP));
|
||||
cg.generateDefine(fs, "REFRACTION_MODE_SCREEN_SPACE", uint32_t(RefractionMode::SCREEN_SPACE));
|
||||
switch (material.refractionMode) {
|
||||
case NONE:
|
||||
case RefractionMode::NONE:
|
||||
// can't be here
|
||||
break;
|
||||
case CUBEMAP:
|
||||
case RefractionMode::CUBEMAP:
|
||||
cg.generateDefine(fs, "REFRACTION_MODE", "REFRACTION_MODE_CUBEMAP");
|
||||
break;
|
||||
case SCREEN_SPACE:
|
||||
case RefractionMode::SCREEN_SPACE:
|
||||
cg.generateDefine(fs, "REFRACTION_MODE", "REFRACTION_MODE_SCREEN_SPACE");
|
||||
break;
|
||||
}
|
||||
cg.generateDefine(fs, "REFRACTION_TYPE_SOLID", uint32_t(RefractionType::SOLID));
|
||||
cg.generateDefine(fs, "REFRACTION_TYPE_THIN", uint32_t(RefractionType::THIN));
|
||||
switch (material.refractionType) {
|
||||
case SOLID:
|
||||
case RefractionType::SOLID:
|
||||
cg.generateDefine(fs, "REFRACTION_TYPE", "REFRACTION_TYPE_SOLID");
|
||||
break;
|
||||
case THIN:
|
||||
case RefractionType::THIN:
|
||||
cg.generateDefine(fs, "REFRACTION_TYPE", "REFRACTION_TYPE_THIN");
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -54,7 +54,7 @@ std::string shaderWithAllProperties(ShaderType type,
|
||||
builder.optimization(filamat::MaterialBuilder::Optimization::NONE);
|
||||
builder.shading(shadingModel);
|
||||
builder.includeCallback(includer);
|
||||
builder.materialRefraction(refractionMode);
|
||||
builder.refractionMode(refractionMode);
|
||||
|
||||
MaterialBuilder::PropertyList allProperties;
|
||||
std::fill_n(allProperties, MaterialBuilder::MATERIAL_PROPERTIES_COUNT, true);
|
||||
|
||||
@@ -6,7 +6,7 @@ material {
|
||||
depthWrite : true,
|
||||
doubleSided : ${DOUBLESIDED},
|
||||
flipUV : false,
|
||||
specularAmbientOcclusion: true,
|
||||
specularAmbientOcclusion: simple,
|
||||
parameters : [
|
||||
|
||||
{ type : float3, name : specularFactor },
|
||||
|
||||
@@ -242,7 +242,7 @@ Material* createMaterial(Engine* engine, const MaterialKey& config, const UvMap&
|
||||
MaterialBuilder builder = MaterialBuilder()
|
||||
.name(name)
|
||||
.flipUV(false)
|
||||
.specularAmbientOcclusion(true)
|
||||
.specularAmbientOcclusion(MaterialBuilder::SpecularAmbientOcclusion::SIMPLE)
|
||||
.material(shader.c_str())
|
||||
.doubleSided(config.doubleSided)
|
||||
.targetApi(filamat::targetApiFromBackend(engine->getBackend()));
|
||||
|
||||
@@ -362,7 +362,7 @@ static void setup(Engine* engine, View* view, Scene* scene) {
|
||||
.name("DefaultMaterial")
|
||||
.material(shader.c_str())
|
||||
.multiBounceAmbientOcclusion(true)
|
||||
.specularAmbientOcclusion(true)
|
||||
.specularAmbientOcclusion(MaterialBuilder::SpecularAmbientOcclusion::BENT_NORMALS)
|
||||
.shading(Shading::LIT);
|
||||
|
||||
if (hasUV) {
|
||||
|
||||
@@ -1,3 +1,12 @@
|
||||
//------------------------------------------------------------------------------
|
||||
// Ambient occlusion configuration
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
// Diffuse BRDFs
|
||||
#define SPECULAR_AO_OFF 0
|
||||
#define SPECULAR_AO_SIMPLE 1
|
||||
#define SPECULAR_AO_BENT_NORMALS 2
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Ambient occlusion helpers
|
||||
//------------------------------------------------------------------------------
|
||||
@@ -8,7 +17,6 @@ float evaluateSSAO() {
|
||||
return textureLod(light_ssao, uv, 0.0).r;
|
||||
}
|
||||
|
||||
#if SPECULAR_AMBIENT_OCCLUSION == 1
|
||||
float SpecularAO_Lagarde(float NoV, float visibility, float roughness) {
|
||||
// Lagarde and de Rousiers 2014, "Moving Frostbite to PBR"
|
||||
return saturate(pow(NoV + visibility, exp2(-16.0 * roughness - 1.0)) - 1.0 + visibility);
|
||||
@@ -39,9 +47,11 @@ float sphericalCapsIntersection(float cosCap1, float cosCap2, float cosDistance)
|
||||
float area = sq(x) * (-2.0 * x + 3.0);
|
||||
return area * (1.0 - max(cosCap1, cosCap2));
|
||||
}
|
||||
#endif
|
||||
|
||||
// This function could (should?) be implemented as a 3D LUT instead, but we need to save samplers
|
||||
float SpecularAO_Cones(float visibility, float roughness) {
|
||||
float SpecularAO_Cones(float NoV, float visibility, float roughness) {
|
||||
#if defined(MATERIAL_HAS_BENT_NORMAL)
|
||||
// Jimenez et al. 2016, "Practical Realtime Strategies for Accurate Indirect Occlusion"
|
||||
|
||||
// aperture from ambient occlusion
|
||||
@@ -56,22 +66,23 @@ float SpecularAO_Cones(float visibility, float roughness) {
|
||||
float ao = sphericalCapsIntersection(cosAv, cosAs, 0.5 * cosB + 0.5) / (1.0 - cosAs);
|
||||
// Smoothly kill specular AO when entering the perceptual roughness range [0.1..0.3]
|
||||
// Without this, specular AO can remove all reflections, which looks bad on metals
|
||||
if (fract(getUserTime().x) < 0.5)
|
||||
return SpecularAO_Lagarde(NoV, visibility, roughness);
|
||||
else
|
||||
return mix(1.0, ao, smoothstep(0.01, 0.09, roughness));
|
||||
#else
|
||||
return SpecularAO_Lagarde(NoV, visibility, roughness);
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Computes a specular occlusion term from the ambient occlusion term.
|
||||
*/
|
||||
float computeSpecularAO(float NoV, float visibility, float roughness) {
|
||||
#if SPECULAR_AMBIENT_OCCLUSION == 1
|
||||
#if defined(MATERIAL_HAS_BENT_NORMAL)
|
||||
return SpecularAO_Cones(visibility, roughness);
|
||||
#else
|
||||
#if SPECULAR_AMBIENT_OCCLUSION == SPECULAR_AO_SIMPLE
|
||||
return SpecularAO_Lagarde(NoV, visibility, roughness);
|
||||
#endif
|
||||
#elif SPECULAR_AMBIENT_OCCLUSION == SPECULAR_AO_BENT_NORMALS
|
||||
return SpecularAO_Cones(NoV, visibility, roughness);
|
||||
#else
|
||||
return 1.0;
|
||||
#endif
|
||||
@@ -100,7 +111,7 @@ void multiBounceAO(float visibility, const vec3 albedo, inout vec3 color) {
|
||||
}
|
||||
|
||||
void multiBounceSpecularAO(float visibility, const vec3 albedo, inout vec3 color) {
|
||||
#if MULTI_BOUNCE_AMBIENT_OCCLUSION == 1 && SPECULAR_AMBIENT_OCCLUSION == 1
|
||||
#if MULTI_BOUNCE_AMBIENT_OCCLUSION == 1 && SPECULAR_AMBIENT_OCCLUSION != SPECULAR_AO_OFF
|
||||
color *= gtaoMultiBounce(visibility, albedo);
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -429,7 +429,20 @@ static bool processMultiBounceAO(MaterialBuilder& builder, const JsonishValue& v
|
||||
}
|
||||
|
||||
static bool processSpecularAmbientOcclusion(MaterialBuilder& builder, const JsonishValue& value) {
|
||||
builder.specularAmbientOcclusion(value.toJsonBool()->getBool());
|
||||
static const std::unordered_map<std::string, MaterialBuilder::SpecularAmbientOcclusion> strToEnum {
|
||||
{ "none", MaterialBuilder::SpecularAmbientOcclusion::NONE },
|
||||
{ "simple", MaterialBuilder::SpecularAmbientOcclusion::SIMPLE },
|
||||
{ "bentNormals", MaterialBuilder::SpecularAmbientOcclusion::BENT_NORMALS },
|
||||
// Backward compatibility
|
||||
{ "false", MaterialBuilder::SpecularAmbientOcclusion::NONE },
|
||||
{ "true", MaterialBuilder::SpecularAmbientOcclusion::SIMPLE },
|
||||
};
|
||||
auto jsonString = value.toJsonString();
|
||||
if (!isStringValidEnum(strToEnum, jsonString->getString())) {
|
||||
return logEnumIssue("specularAO", *jsonString, strToEnum);
|
||||
}
|
||||
|
||||
builder.specularAmbientOcclusion(stringToEnum(strToEnum, jsonString->getString()));
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -475,7 +488,7 @@ static bool processRefractionMode(MaterialBuilder& builder, const JsonishValue&
|
||||
return logEnumIssue("refraction", *jsonString, strToEnum);
|
||||
}
|
||||
|
||||
builder.materialRefraction(stringToEnum(strToEnum, jsonString->getString()));
|
||||
builder.refractionMode(stringToEnum(strToEnum, jsonString->getString()));
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -489,7 +502,7 @@ static bool processRefractionType(MaterialBuilder& builder, const JsonishValue&
|
||||
return logEnumIssue("refractionType", *jsonString, strToEnum);
|
||||
}
|
||||
|
||||
builder.materialRefractionType(stringToEnum(strToEnum, jsonString->getString()));
|
||||
builder.refractionType(stringToEnum(strToEnum, jsonString->getString()));
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -556,7 +569,7 @@ ParametersProcessor::ParametersProcessor() {
|
||||
mParameters["clearCoatIorChange"] = { &processClearCoatIorChange, Type::BOOL };
|
||||
mParameters["flipUV"] = { &processFlipUV, Type::BOOL };
|
||||
mParameters["multiBounceAmbientOcclusion"] = { &processMultiBounceAO, Type::BOOL };
|
||||
mParameters["specularAmbientOcclusion"] = { &processSpecularAmbientOcclusion, Type::BOOL };
|
||||
mParameters["specularAmbientOcclusion"] = { &processSpecularAmbientOcclusion, Type::STRING };
|
||||
mParameters["domain"] = { &processDomain, Type::STRING };
|
||||
mParameters["refractionMode"] = { &processRefractionMode, Type::STRING };
|
||||
mParameters["refractionType"] = { &processRefractionType, Type::STRING };
|
||||
|
||||
Reference in New Issue
Block a user