diff --git a/RELEASE_NOTES.md b/RELEASE_NOTES.md
index ef6965157d..c87f1c8cd0 100644
--- a/RELEASE_NOTES.md
+++ b/RELEASE_NOTES.md
@@ -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
diff --git a/android/filamat-android/src/main/cpp/MaterialBuilder.cpp b/android/filamat-android/src/main/cpp/MaterialBuilder.cpp
index 48b83ecfdf..ecd9e43ff0 100644
--- a/android/filamat-android/src/main/cpp/MaterialBuilder.cpp
+++ b/android/filamat-android/src/main/cpp/MaterialBuilder.cpp
@@ -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
diff --git a/android/filamat-android/src/main/java/com/google/android/filament/filamat/MaterialBuilder.java b/android/filamat-android/src/main/java/com/google/android/filament/filamat/MaterialBuilder.java
index 4e0710baba..d044b9e0d2 100644
--- a/android/filamat-android/src/main/java/com/google/android/filament/filamat/MaterialBuilder.java
+++ b/android/filamat-android/src/main/java/com/google/android/filament/filamat/MaterialBuilder.java
@@ -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);
diff --git a/docs/Materials.html b/docs/Materials.html
index 599447fd8d..068585a0ef 100644
--- a/docs/Materials.html
+++ b/docs/Materials.html
@@ -696,7 +696,7 @@ and with (right)
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 4.2.24 about
specularAmbientOcclusion).
@@ -711,11 +711,6 @@ instance.
- -
specularAmbientOcclusion is turned on.@@ -1952,17 +1947,24 @@ occclusion enabled and disabled.
-
boolean
+
string
-
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.
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 37.
+ 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 37.
+ 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.
material {
- specularAmbientOcclusion : true
+ specularAmbientOcclusion : simple
}
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.
diff --git a/docs/Materials.md.html b/docs/Materials.md.html
index 36f40622db..7c4a4f736b 100644
--- a/docs/Materials.md.html
+++ b/docs/Materials.md.html
@@ -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`.
diff --git a/filament/include/filament/Scene.h b/filament/include/filament/Scene.h
index 6a15463dd8..6dca2229fc 100644
--- a/filament/include/filament/Scene.h
+++ b/filament/include/filament/Scene.h
@@ -84,7 +84,6 @@ public:
*/
void setIndirectLight(IndirectLight const* ibl) noexcept;
-
/**
* Adds an Entity to the Scene.
*
diff --git a/filament/src/Renderer.cpp b/filament/src/Renderer.cpp
index 60d8e58379..232b5faeea 100644
--- a/filament/src/Renderer.cpp
+++ b/filament/src/Renderer.cpp
@@ -766,7 +766,7 @@ bool FRenderer::beginFrame(FSwapChain* swapChain, uint64_t vsyncSteadyClockTimeN
#endif
// latch the frame time
- std::chrono::duration