From 549c58228734deeb5f5ac5a9171eaafb93304c63 Mon Sep 17 00:00:00 2001 From: mackong Date: Tue, 1 Aug 2023 06:49:48 +0800 Subject: [PATCH] engine: support setDepthFunc for MaterialInstance (#7004) Co-authored-by: Mathias Agopian --- NEW_RELEASE_NOTES.md | 5 ++++- .../src/main/cpp/MaterialInstance.cpp | 16 ++++++++++++++++ .../android/filament/MaterialInstance.java | 18 ++++++++++++++++++ filament/include/filament/MaterialInstance.h | 11 +++++++++++ filament/src/MaterialInstance.cpp | 8 ++++++++ filament/src/details/MaterialInstance.h | 4 ++++ samples/depthtesting.cpp | 19 ++++++++++++++++++- web/filament-js/filament.d.ts | 1 + web/filament-js/jsbindings.cpp | 2 ++ 9 files changed, 82 insertions(+), 2 deletions(-) diff --git a/NEW_RELEASE_NOTES.md b/NEW_RELEASE_NOTES.md index 828fc26716..9dda512353 100644 --- a/NEW_RELEASE_NOTES.md +++ b/NEW_RELEASE_NOTES.md @@ -12,4 +12,7 @@ appropriate header in [RELEASE_NOTES.md](./RELEASE_NOTES.md). - opengl: fix b/290388359 : possible crash when shutting down the engine - engine: Improve precision of frame time measurement when using emulated TimerQueries - backend: Improve frame pacing on Android and Vulkan. -- backend: workaround b/291140208 (gltf_viewer crashes on Nexus 6P) \ No newline at end of file +- backend: workaround b/291140208 (gltf_viewer crashes on Nexus 6P) +- engine: support `setDepthFunc` for `MaterialInstance` +- web: Added setDepthFunc()/getDepthFunc() to MaterialInstance +- android: Added setDepthFunc()/getDepthFunc() to MaterialInstance diff --git a/android/filament-android/src/main/cpp/MaterialInstance.cpp b/android/filament-android/src/main/cpp/MaterialInstance.cpp index 5273dc2c80..d692689e94 100644 --- a/android/filament-android/src/main/cpp/MaterialInstance.cpp +++ b/android/filament-android/src/main/cpp/MaterialInstance.cpp @@ -357,6 +357,14 @@ Java_com_google_android_filament_MaterialInstance_nSetDepthCulling(JNIEnv*, instance->setDepthCulling(enable); } +extern "C" +JNIEXPORT void JNICALL +Java_com_google_android_filament_MaterialInstance_nSetDepthFunc(JNIEnv*, + jclass, jlong nativeMaterialInstance, jlong function) { + MaterialInstance* instance = (MaterialInstance*) nativeMaterialInstance; + instance->setDepthFunc(static_cast(function)); +} + extern "C" JNIEXPORT void JNICALL Java_com_google_android_filament_MaterialInstance_nSetStencilCompareFunction(JNIEnv*, jclass, @@ -524,3 +532,11 @@ Java_com_google_android_filament_MaterialInstance_nIsDepthCullingEnabled(JNIEnv* MaterialInstance* instance = (MaterialInstance*)nativeMaterialInstance; return instance->isDepthCullingEnabled(); } + +extern "C" +JNIEXPORT jint JNICALL +Java_com_google_android_filament_MaterialInstance_nGetDepthFunc(JNIEnv* env, jclass clazz, + jlong nativeMaterialInstance) { + MaterialInstance* instance = (MaterialInstance*)nativeMaterialInstance; + return (jint)instance->getDepthFunc(); +} diff --git a/android/filament-android/src/main/java/com/google/android/filament/MaterialInstance.java b/android/filament-android/src/main/java/com/google/android/filament/MaterialInstance.java index bde26df5ac..9f30568f52 100644 --- a/android/filament-android/src/main/java/com/google/android/filament/MaterialInstance.java +++ b/android/filament-android/src/main/java/com/google/android/filament/MaterialInstance.java @@ -625,6 +625,15 @@ public class MaterialInstance { nSetDepthCulling(getNativeObject(), enable); } + /** + * Sets the depth comparison function (default is {@link TextureSampler.CompareFunction#GE}). + * + * @param func the depth comparison function + */ + public void setDepthFunc(TextureSampler.CompareFunction func) { + nSetDepthFunc(getNativeObject(), func.ordinal()); + } + /** * Returns whether depth culling is enabled. */ @@ -632,6 +641,13 @@ public class MaterialInstance { return nIsDepthCullingEnabled(getNativeObject()); } + /** + * Returns the depth comparison function. + */ + public TextureSampler.CompareFunction getDepthFunc() { + return TextureSampler.EnumCache.sCompareFunctionValues[nGetDepthFunc(getNativeObject())]; + } + /** * Sets the stencil comparison function (default is {@link TextureSampler.CompareFunction#ALWAYS}). * @@ -908,6 +924,7 @@ public class MaterialInstance { private static native void nSetDepthWrite(long nativeMaterialInstance, boolean enable); private static native void nSetStencilWrite(long nativeMaterialInstance, boolean enable); private static native void nSetDepthCulling(long nativeMaterialInstance, boolean enable); + private static native void nSetDepthFunc(long nativeMaterialInstance, long function); private static native void nSetStencilCompareFunction(long nativeMaterialInstance, long function, long face); @@ -939,4 +956,5 @@ public class MaterialInstance { private static native boolean nIsDepthWriteEnabled(long nativeMaterialInstance); private static native boolean nIsStencilWriteEnabled(long nativeMaterialInstance); private static native boolean nIsDepthCullingEnabled(long nativeMaterialInstance); + private static native int nGetDepthFunc(long nativeMaterialInstance); } diff --git a/filament/include/filament/MaterialInstance.h b/filament/include/filament/MaterialInstance.h index c2095e1c47..ee7a8e252f 100644 --- a/filament/include/filament/MaterialInstance.h +++ b/filament/include/filament/MaterialInstance.h @@ -52,6 +52,7 @@ class UTILS_PUBLIC MaterialInstance : public FilamentAPI { public: using CullingMode = filament::backend::CullingMode; using TransparencyMode = filament::TransparencyMode; + using DepthFunc = filament::backend::SamplerCompareFunc; using StencilCompareFunc = filament::backend::SamplerCompareFunc; using StencilOperation = filament::backend::StencilOperation; using StencilFace = filament::backend::StencilFace; @@ -367,6 +368,16 @@ public: */ void setDepthCulling(bool enable) noexcept; + /** + * Overrides the default depth function state that was set on the material. + */ + void setDepthFunc(DepthFunc depthFunc) noexcept; + + /** + * Returns the depth function state. + */ + DepthFunc getDepthFunc() const noexcept; + /** * Returns whether depth culling is enabled. */ diff --git a/filament/src/MaterialInstance.cpp b/filament/src/MaterialInstance.cpp index ec3e3ea931..33f3ab764b 100644 --- a/filament/src/MaterialInstance.cpp +++ b/filament/src/MaterialInstance.cpp @@ -255,6 +255,14 @@ void MaterialInstance::setDepthCulling(bool enable) noexcept { downcast(this)->setDepthCulling(enable); } +void MaterialInstance::setDepthFunc(DepthFunc depthFunc) noexcept { + downcast(this)->setDepthFunc(depthFunc); +} + +MaterialInstance::DepthFunc MaterialInstance::getDepthFunc() const noexcept { + return downcast(this)->getDepthFunc(); +} + void MaterialInstance::setStencilWrite(bool enable) noexcept { downcast(this)->setStencilWrite(enable); } diff --git a/filament/src/details/MaterialInstance.h b/filament/src/details/MaterialInstance.h index c98c8f3115..6be23b7e06 100644 --- a/filament/src/details/MaterialInstance.h +++ b/filament/src/details/MaterialInstance.h @@ -101,6 +101,10 @@ public: backend::RasterState::DepthFunc getDepthFunc() const noexcept { return mDepthFunc; } + void setDepthFunc(backend::RasterState::DepthFunc depthFunc) noexcept { + mDepthFunc = depthFunc; + } + void setPolygonOffset(float scale, float constant) noexcept { // handle reversed Z mPolygonOffset = { -scale, -constant }; diff --git a/samples/depthtesting.cpp b/samples/depthtesting.cpp index 8b67846676..77fae2233f 100644 --- a/samples/depthtesting.cpp +++ b/samples/depthtesting.cpp @@ -26,6 +26,8 @@ #include #include +#include + #include #include @@ -48,6 +50,7 @@ struct App { Skybox* skybox; Entity whiteTriangle; Entity colorTriangle; + MaterialInstance::DepthFunc depthFunc; }; struct Vertex { @@ -115,8 +118,11 @@ int main(int argc, char** argv) { .culling(false) .receiveShadows(false) .castShadows(false) + .priority(5) // draw after whiteTriangle. .build(*engine, app.colorTriangle); scene->addEntity(app.colorTriangle); + + app.depthFunc = MaterialInstance::DepthFunc::GE; }; auto cleanup = [&app](Engine* engine, View*, Scene*) { @@ -131,6 +137,17 @@ int main(int argc, char** argv) { utils::EntityManager::get().destroy(app.camera); }; + auto gui = [&app](Engine* engine, View* view) { + int depthFuncSelection = (int) app.depthFunc; + ImGui::Combo("Depth Function", &depthFuncSelection, + "Less or equal\0Greater or equal\0Strictly less than\0" + "Strictly greater than\0Equal\0Not equal\0Always\0Never\0\0"); + if (depthFuncSelection != (int) app.depthFunc) { + app.depthFunc = (MaterialInstance::DepthFunc) depthFuncSelection; + app.mat->getDefaultInstance()->setDepthFunc(app.depthFunc); + } + }; + FilamentApp::get().animate([&app](Engine* engine, View* view, double now) { constexpr float ZOOM = 1.5f; const uint32_t w = view->getViewport().width; @@ -144,7 +161,7 @@ int main(int argc, char** argv) { filament::math::mat4f::rotation(now, filament::math::float3{ 0, 1, 0 })); }); - FilamentApp::get().run(config, setup, cleanup); + FilamentApp::get().run(config, setup, cleanup, gui); return 0; } diff --git a/web/filament-js/filament.d.ts b/web/filament-js/filament.d.ts index d0bfaa0372..16d6e2f383 100644 --- a/web/filament-js/filament.d.ts +++ b/web/filament-js/filament.d.ts @@ -183,6 +183,7 @@ export class MaterialInstance { public setDepthWrite(enable: boolean): void; public setStencilWrite(enable: boolean): void; public setDepthCulling(enable: boolean): void; + public setDepthFunc(func: CompareFunc): void; public setStencilCompareFunction(func: CompareFunc, face?: StencilFace): void; public setStencilOpStencilFail(op: StencilOperation, face?: StencilFace): void; public setStencilOpDepthFail(op: StencilOperation, face?: StencilFace): void; diff --git a/web/filament-js/jsbindings.cpp b/web/filament-js/jsbindings.cpp index ce4401e976..201ca0c4f2 100644 --- a/web/filament-js/jsbindings.cpp +++ b/web/filament-js/jsbindings.cpp @@ -1371,6 +1371,8 @@ class_("MaterialInstance") .function("setStencilWrite", &MaterialInstance::setStencilWrite) .function("setDepthCulling", &MaterialInstance::setDepthCulling) .function("isDepthCullingEnabled", &MaterialInstance::isDepthCullingEnabled) + .function("setDepthFunc", &MaterialInstance::setDepthFunc) + .function("getDepthFunc", &MaterialInstance::getDepthFunc) .function("setStencilCompareFunction", &MaterialInstance::setStencilCompareFunction) .function("setStencilCompareFunction", EMBIND_LAMBDA(void, (MaterialInstance* self, MaterialInstance::StencilCompareFunc func), {