diff --git a/android/filament-android/src/main/cpp/View.cpp b/android/filament-android/src/main/cpp/View.cpp index 58b2a643c6..65e86a6b55 100644 --- a/android/filament-android/src/main/cpp/View.cpp +++ b/android/filament-android/src/main/cpp/View.cpp @@ -241,8 +241,14 @@ Java_com_google_android_filament_View_nGetAmbientOcclusion(JNIEnv*, jclass, jlon extern "C" JNIEXPORT void JNICALL Java_com_google_android_filament_View_nSetAmbientOcclusionOptions(JNIEnv*, jclass, - jlong nativeView, jfloat radius, jfloat bias, jfloat power, jfloat resolution) { + jlong nativeView, jfloat radius, jfloat bias, jfloat power, jfloat resolution, jfloat intensity) { View* view = (View*) nativeView; - View::AmbientOcclusionOptions options = { .radius = radius, .bias = bias, .power = power, .resolution = resolution}; + View::AmbientOcclusionOptions options = { + .radius = radius, + .bias = bias, + .power = power, + .resolution = resolution, + .intensity = intensity + }; view->setAmbientOcclusionOptions(options); } diff --git a/android/filament-android/src/main/java/com/google/android/filament/View.java b/android/filament-android/src/main/java/com/google/android/filament/View.java index 047591a2be..2ff681543a 100644 --- a/android/filament-android/src/main/java/com/google/android/filament/View.java +++ b/android/filament-android/src/main/java/com/google/android/filament/View.java @@ -149,6 +149,11 @@ public class View { * How each dimension of the AO buffer is scaled. Must be positive and <= 1. */ public float resolution = 0.5f; + + /** + * Strength of the Ambient Occlusion effect. Must be positive. + */ + public float intensity = 1.0f; } /** @@ -761,7 +766,8 @@ public class View { */ public void setAmbientOcclusionOptions(@NonNull AmbientOcclusionOptions options) { mAmbientOcclusionOptions = options; - nSetAmbientOcclusionOptions(getNativeObject(), options.radius, options.bias, options.power, options.resolution); + nSetAmbientOcclusionOptions(getNativeObject(), options.radius, options.bias, options.power, + options.resolution, options.intensity); } /** @@ -819,5 +825,5 @@ public class View { private static native boolean nIsFrontFaceWindingInverted(long nativeView); private static native void nSetAmbientOcclusion(long nativeView, int ordinal); private static native int nGetAmbientOcclusion(long nativeView); - private static native void nSetAmbientOcclusionOptions(long nativeView, float radius, float bias, float power, float resolution); + private static native void nSetAmbientOcclusionOptions(long nativeView, float radius, float bias, float power, float resolution, float intensity); } diff --git a/filament/include/filament/View.h b/filament/include/filament/View.h index 895c10091d..dc2869ac20 100644 --- a/filament/include/filament/View.h +++ b/filament/include/filament/View.h @@ -147,9 +147,10 @@ public: */ struct AmbientOcclusionOptions { float radius = 0.3f; //!< Ambient Occlusion radius in meters, between 0 and ~10. - float bias = 0.005f; //!< Self-occlusion bias in meters. Use to avoid self-occlusion. Between 0 and a few mm. + float bias = 0.0001f; //!< Self-occlusion bias in meters. Use to avoid self-occlusion. Between 0 and a few mm. float power = 0.0f; //!< Controls ambient occlusion's contrast. Between 0 (linear) and 1 (squared) float resolution = 0.5; //!< How each dimension of the AO buffer is scaled. Must be positive and <= 1. + float intensity = 1.0; //!< Strength of the Ambient Occlusion effect. }; /** diff --git a/filament/src/PostProcessManager.cpp b/filament/src/PostProcessManager.cpp index 0b779b5494..544b045123 100644 --- a/filament/src/PostProcessManager.cpp +++ b/filament/src/PostProcessManager.cpp @@ -377,6 +377,7 @@ FrameGraphId PostProcessManager::ssao(FrameGraph& fg, RenderP pInstance->setParameter("projectionScaleRadius", projectionScale * data.options.radius); pInstance->setParameter("bias", data.options.bias); pInstance->setParameter("power", data.options.power); + pInstance->setParameter("intensity", std::max(0.0f, data.options.intensity)); pInstance->setParameter("maxLevel", uint32_t(levelCount - 1)); pInstance->commit(driver); diff --git a/filament/src/materials/sao.mat b/filament/src/materials/sao.mat index 82d0838b54..42fde0720b 100644 --- a/filament/src/materials/sao.mat +++ b/filament/src/materials/sao.mat @@ -30,6 +30,10 @@ material { type : float, name : power }, + { + type : float, + name : intensity + }, { type : int, name : maxLevel @@ -234,7 +238,7 @@ fragment { float vn = dot(v, normal); // distance * cos(v, normal) const float uu = 0.015; float falloff = saturate(1.0 - vv * materialParams.invRadiusSquared); - float occlusion = falloff * max(0.0, vn - materialParams.bias) / (vv + uu); + float occlusion = falloff * max(0.0, vn + origin.z * materialParams.bias) / (vv + uu); return occlusion; } @@ -258,7 +262,7 @@ fragment { occlusion += computeAmbientOcclusionSAO(i, ssDiskRadius, ssOrigin, origin, normal, noise); } - float ao = 1.0 - occlusion / float(kSpiralSampleCount); + float ao = max(0.0, 1.0 - (2.0 / float(kSpiralSampleCount)) * materialParams.intensity * occlusion); // simulate user-controled ao^n with n[1, 2] ao = mix(ao, ao * ao, materialParams.power); diff --git a/samples/material_sandbox.cpp b/samples/material_sandbox.cpp index d776d4d8ba..c26789a4ba 100644 --- a/samples/material_sandbox.cpp +++ b/samples/material_sandbox.cpp @@ -347,7 +347,8 @@ static void gui(filament::Engine* engine, filament::View*) { DebugRegistry& debug = engine->getDebugRegistry(); ImGui::Checkbox("enabled###ssao", ¶ms.ssao); ImGui::SliderFloat("radius", ¶ms.ssaoOptions.radius, 0.05f, 5.0f); - ImGui::SliderFloat("bias", ¶ms.ssaoOptions.bias, 0.0f, 0.1f); + ImGui::SliderFloat("bias", ¶ms.ssaoOptions.bias, 0.0f, 0.01f, "%.6f"); + ImGui::SliderFloat("intensity", ¶ms.ssaoOptions.intensity, 0.0f, 10.0f); ImGui::SliderFloat("power", ¶ms.ssaoOptions.power, 0.0f, 1.0f); } ImGui::Unindent();