From 8eade6be1fd3ca8159f8955ecee4d86b95e8e92d Mon Sep 17 00:00:00 2001 From: Powei Feng Date: Mon, 13 Nov 2023 22:26:03 -0800 Subject: [PATCH] Revert "engine: move setFrontFaceWindingInverted from View to MaterialInstance (#7331)" (#7360) This reverts commit 038f07cb345702af9bda7bea21f6870c7e53c42f. --- RELEASE_NOTES.md | 1 - .../src/main/cpp/MaterialInstance.cpp | 34 ++++------- .../filament-android/src/main/cpp/View.cpp | 14 +++++ .../android/filament/MaterialInstance.java | 29 --------- .../com/google/android/filament/View.java | 28 +++++++++ filament/include/filament/MaterialInstance.h | 21 ------- filament/include/filament/View.h | 21 +++++++ filament/src/MaterialInstance.cpp | 8 --- filament/src/RenderPass.cpp | 17 +++--- filament/src/RenderPass.h | 11 ++-- filament/src/View.cpp | 8 +++ filament/src/details/MaterialInstance.cpp | 4 +- filament/src/details/MaterialInstance.h | 10 ---- filament/src/details/Renderer.cpp | 1 + filament/src/details/View.h | 5 ++ samples/rendertarget.cpp | 59 ++++++++++--------- web/filament-js/jsbindings.cpp | 5 +- 17 files changed, 136 insertions(+), 140 deletions(-) diff --git a/RELEASE_NOTES.md b/RELEASE_NOTES.md index c6a410af3b..20a3c0fab4 100644 --- a/RELEASE_NOTES.md +++ b/RELEASE_NOTES.md @@ -17,7 +17,6 @@ Instead, if you are authoring a PR for the main branch, add your release note to - engine: Add `Material::getFeatureLevel()` - engine: Add missing `Material::getReflectionMode()` method in Java - engine: Support basic usage of post-processing materials on feature level 0 -- engine: move `setFrontFaceWindingInverted` from `View` to `MaterialInstance` [**API CHANGE**] ## v1.45.1 diff --git a/android/filament-android/src/main/cpp/MaterialInstance.cpp b/android/filament-android/src/main/cpp/MaterialInstance.cpp index 1046c75a5a..c0b0bcb716 100644 --- a/android/filament-android/src/main/cpp/MaterialInstance.cpp +++ b/android/filament-android/src/main/cpp/MaterialInstance.cpp @@ -433,13 +433,6 @@ Java_com_google_android_filament_MaterialInstance_nSetStencilWriteMask(JNIEnv*, instance->setStencilWriteMask(writeMask, static_cast(face)); } -extern "C" JNIEXPORT void JNICALL -Java_com_google_android_filament_MaterialInstance_nSetFrontFaceWindingInverted(JNIEnv*, - jclass, jlong nativeMaterialInstance, jboolean inverted) { - MaterialInstance* instance = (MaterialInstance*) nativeMaterialInstance; - instance->setFrontFaceWindingInverted(inverted); -} - extern "C" JNIEXPORT jstring JNICALL Java_com_google_android_filament_MaterialInstance_nGetName(JNIEnv* env, jclass, @@ -476,7 +469,7 @@ extern "C" JNIEXPORT jfloat JNICALL Java_com_google_android_filament_MaterialInstance_nGetMaskThreshold(JNIEnv* env, jclass clazz, jlong nativeMaterialInstance) { - MaterialInstance* instance = (MaterialInstance*) nativeMaterialInstance; + MaterialInstance* instance = (MaterialInstance*)nativeMaterialInstance; return instance->getMaskThreshold(); } @@ -484,7 +477,7 @@ extern "C" JNIEXPORT jfloat JNICALL Java_com_google_android_filament_MaterialInstance_nGetSpecularAntiAliasingVariance(JNIEnv* env, jclass clazz, jlong nativeMaterialInstance) { - MaterialInstance* instance = (MaterialInstance*) nativeMaterialInstance; + MaterialInstance* instance = (MaterialInstance*)nativeMaterialInstance; return instance->getSpecularAntiAliasingVariance(); } @@ -492,7 +485,7 @@ extern "C" JNIEXPORT jfloat JNICALL Java_com_google_android_filament_MaterialInstance_nGetSpecularAntiAliasingThreshold(JNIEnv* env, jclass clazz, jlong nativeMaterialInstance) { - MaterialInstance* instance = (MaterialInstance*) nativeMaterialInstance; + MaterialInstance* instance = (MaterialInstance*)nativeMaterialInstance; return instance->getSpecularAntiAliasingThreshold(); } @@ -500,7 +493,7 @@ extern "C" JNIEXPORT jboolean JNICALL Java_com_google_android_filament_MaterialInstance_nIsDoubleSided(JNIEnv* env, jclass clazz, jlong nativeMaterialInstance) { - MaterialInstance* instance = (MaterialInstance*) nativeMaterialInstance; + MaterialInstance* instance = (MaterialInstance*)nativeMaterialInstance; return instance->isDoubleSided(); } @@ -508,7 +501,7 @@ extern "C" JNIEXPORT jint JNICALL Java_com_google_android_filament_MaterialInstance_nGetCullingMode(JNIEnv* env, jclass clazz, jlong nativeMaterialInstance) { - MaterialInstance* instance = (MaterialInstance*) nativeMaterialInstance; + MaterialInstance* instance = (MaterialInstance*)nativeMaterialInstance; return (jint)instance->getCullingMode(); } @@ -516,7 +509,7 @@ extern "C" JNIEXPORT jboolean JNICALL Java_com_google_android_filament_MaterialInstance_nIsColorWriteEnabled(JNIEnv* env, jclass clazz, jlong nativeMaterialInstance) { - MaterialInstance* instance = (MaterialInstance*) nativeMaterialInstance; + MaterialInstance* instance = (MaterialInstance*)nativeMaterialInstance; return instance->isColorWriteEnabled(); } @@ -524,7 +517,7 @@ extern "C" JNIEXPORT jboolean JNICALL Java_com_google_android_filament_MaterialInstance_nIsDepthWriteEnabled(JNIEnv* env, jclass clazz, jlong nativeMaterialInstance) { - MaterialInstance* instance = (MaterialInstance*) nativeMaterialInstance; + MaterialInstance* instance = (MaterialInstance*)nativeMaterialInstance; return instance->isDepthWriteEnabled(); } @@ -532,7 +525,7 @@ extern "C" JNIEXPORT jboolean JNICALL Java_com_google_android_filament_MaterialInstance_nIsStencilWriteEnabled(JNIEnv* env, jclass clazz, jlong nativeMaterialInstance) { - MaterialInstance* instance = (MaterialInstance*) nativeMaterialInstance; + MaterialInstance* instance = (MaterialInstance*)nativeMaterialInstance; return instance->isStencilWriteEnabled(); } @@ -540,7 +533,7 @@ extern "C" JNIEXPORT jboolean JNICALL Java_com_google_android_filament_MaterialInstance_nIsDepthCullingEnabled(JNIEnv* env, jclass clazz, jlong nativeMaterialInstance) { - MaterialInstance* instance = (MaterialInstance*) nativeMaterialInstance; + MaterialInstance* instance = (MaterialInstance*)nativeMaterialInstance; return instance->isDepthCullingEnabled(); } @@ -548,13 +541,6 @@ extern "C" JNIEXPORT jint JNICALL Java_com_google_android_filament_MaterialInstance_nGetDepthFunc(JNIEnv* env, jclass clazz, jlong nativeMaterialInstance) { - MaterialInstance* instance = (MaterialInstance*) nativeMaterialInstance; + MaterialInstance* instance = (MaterialInstance*)nativeMaterialInstance; return (jint)instance->getDepthFunc(); } - -extern "C" JNIEXPORT jboolean JNICALL -Java_com_google_android_filament_MaterialInstance_nIsFrontFaceWindingInverted(JNIEnv*, - jclass, jlong nativeMaterialInstance) { - MaterialInstance* instance = (MaterialInstance*) nativeMaterialInstance; - return static_cast(instance->isFrontFaceWindingInverted()); -} diff --git a/android/filament-android/src/main/cpp/View.cpp b/android/filament-android/src/main/cpp/View.cpp index 047b71105f..fc4de145e9 100644 --- a/android/filament-android/src/main/cpp/View.cpp +++ b/android/filament-android/src/main/cpp/View.cpp @@ -202,6 +202,20 @@ Java_com_google_android_filament_View_nIsPostProcessingEnabled(JNIEnv*, return static_cast(view->isPostProcessingEnabled()); } +extern "C" JNIEXPORT void JNICALL +Java_com_google_android_filament_View_nSetFrontFaceWindingInverted(JNIEnv*, + jclass, jlong nativeView, jboolean inverted) { + View* view = (View*) nativeView; + view->setFrontFaceWindingInverted(inverted); +} + +extern "C" JNIEXPORT jboolean JNICALL +Java_com_google_android_filament_View_nIsFrontFaceWindingInverted(JNIEnv*, + jclass, jlong nativeView) { + View* view = (View*) nativeView; + return static_cast(view->isFrontFaceWindingInverted()); +} + extern "C" JNIEXPORT void JNICALL Java_com_google_android_filament_View_nSetAmbientOcclusion(JNIEnv*, jclass, jlong nativeView, jint ordinal) { View* view = (View*) nativeView; 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 44152f9bd7..389999b7d8 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 @@ -850,32 +850,6 @@ public class MaterialInstance { setStencilWriteMask(writeMask, StencilFace.FRONT_AND_BACK); } - /** - * Returns true if front face winding order is inverted. - * - * @see #setFrontFaceWindingInverted - */ - public boolean isFrontFaceWindingInverted() { - return nIsFrontFaceWindingInverted(getNativeObject()); - } - - /** - * Inverts the winding order of front faces. By default front faces use a counter-clockwise - * winding order. When the winding order is inverted, front faces are faces with a clockwise - * winding order. - * - * Changing the winding order will directly affect the culling mode in materials - * (see Material#getCullingMode). - * - * Inverting the winding order of front faces is useful when rendering mirrored reflections - * (water, mirror surfaces, front camera in AR, etc.). - * - * @param inverted True to invert front faces, false otherwise. - */ - public void setFrontFaceWindingInverted(boolean inverted) { - nSetFrontFaceWindingInverted(getNativeObject(), inverted); - } - public long getNativeObject() { if (mNativeObject == 0) { throw new IllegalStateException("Calling method on destroyed MaterialInstance"); @@ -967,9 +941,6 @@ public class MaterialInstance { private static native void nSetStencilWriteMask(long nativeMaterialInstance, int writeMask, long face); - private static native void nSetFrontFaceWindingInverted(long nativeView, boolean inverted); - private static native boolean nIsFrontFaceWindingInverted(long nativeView); - private static native String nGetName(long nativeMaterialInstance); private static native long nGetMaterial(long nativeMaterialInstance); 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 b5f958369f..91622d26c4 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 @@ -709,6 +709,32 @@ public class View { nSetPostProcessingEnabled(getNativeObject(), enabled); } + /** + * Returns true if post-processing is enabled. + * + * @see #setPostProcessingEnabled + */ + public boolean isFrontFaceWindingInverted() { + return nIsFrontFaceWindingInverted(getNativeObject()); + } + + /** + * Inverts the winding order of front faces. By default front faces use a counter-clockwise + * winding order. When the winding order is inverted, front faces are faces with a clockwise + * winding order. + * + * Changing the winding order will directly affect the culling mode in materials + * (see Material#getCullingMode). + * + * Inverting the winding order of front faces is useful when rendering mirrored reflections + * (water, mirror surfaces, front camera in AR, etc.). + * + * @param inverted True to invert front faces, false otherwise. + */ + public void setFrontFaceWindingInverted(boolean inverted) { + nSetFrontFaceWindingInverted(getNativeObject(), inverted); + } + /** * Sets options relative to dynamic lighting for this view. * @@ -1185,6 +1211,8 @@ public class View { private static native void nSetColorGrading(long nativeView, long nativeColorGrading); private static native void nSetPostProcessingEnabled(long nativeView, boolean enabled); private static native boolean nIsPostProcessingEnabled(long nativeView); + private static native void nSetFrontFaceWindingInverted(long nativeView, boolean inverted); + 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, float intensity, float bilateralThreshold, int quality, int lowPassFilter, int upsampling, boolean enabled, boolean bentNormals, float minHorizonAngleRad); diff --git a/filament/include/filament/MaterialInstance.h b/filament/include/filament/MaterialInstance.h index cbfe230e6b..0c6ef20573 100644 --- a/filament/include/filament/MaterialInstance.h +++ b/filament/include/filament/MaterialInstance.h @@ -480,27 +480,6 @@ public: void setStencilWriteMask(uint8_t writeMask, StencilFace face = StencilFace::FRONT_AND_BACK) noexcept; - /** - * Inverts the winding order of front faces. By default front faces use a counter-clockwise - * winding order. When the winding order is inverted, front faces are faces with a clockwise - * winding order. - * - * Changing the winding order will directly affect the culling mode in materials - * (see Material::getCullingMode()). - * - * Inverting the winding order of front faces is useful when rendering mirrored reflections - * (water, mirror surfaces, front camera in AR, etc.). - * - * @param inverted True to invert front faces, false otherwise. - */ - void setFrontFaceWindingInverted(bool inverted) noexcept; - - /** - * Returns true if the winding order of front faces is inverted. - * See setFrontFaceWindingInverted() for more information. - */ - bool isFrontFaceWindingInverted() const noexcept; - protected: // prevent heap allocation ~MaterialInstance() = default; diff --git a/filament/include/filament/View.h b/filament/include/filament/View.h index e15fa8724e..5eddb99143 100644 --- a/filament/include/filament/View.h +++ b/filament/include/filament/View.h @@ -629,6 +629,27 @@ public: //! Returns true if post-processing is enabled. See setPostProcessingEnabled() for more info. bool isPostProcessingEnabled() const noexcept; + /** + * Inverts the winding order of front faces. By default front faces use a counter-clockwise + * winding order. When the winding order is inverted, front faces are faces with a clockwise + * winding order. + * + * Changing the winding order will directly affect the culling mode in materials + * (see Material::getCullingMode()). + * + * Inverting the winding order of front faces is useful when rendering mirrored reflections + * (water, mirror surfaces, front camera in AR, etc.). + * + * @param inverted True to invert front faces, false otherwise. + */ + void setFrontFaceWindingInverted(bool inverted) noexcept; + + /** + * Returns true if the winding order of front faces is inverted. + * See setFrontFaceWindingInverted() for more information. + */ + bool isFrontFaceWindingInverted() const noexcept; + /** * Enables use of the stencil buffer. * diff --git a/filament/src/MaterialInstance.cpp b/filament/src/MaterialInstance.cpp index e11e6e8b60..33f3ab764b 100644 --- a/filament/src/MaterialInstance.cpp +++ b/filament/src/MaterialInstance.cpp @@ -340,12 +340,4 @@ bool MaterialInstance::isDepthCullingEnabled() const noexcept { return downcast(this)->isDepthCullingEnabled(); } -void MaterialInstance::setFrontFaceWindingInverted(bool inverted) noexcept { - downcast(this)->setFrontFaceWindingInverted(inverted); -} - -bool MaterialInstance::isFrontFaceWindingInverted() const noexcept { - return downcast(this)->isFrontFaceWindingInverted(); -} - } // namespace filament diff --git a/filament/src/RenderPass.cpp b/filament/src/RenderPass.cpp index b602e52786..55a66a75d3 100644 --- a/filament/src/RenderPass.cpp +++ b/filament/src/RenderPass.cpp @@ -323,7 +323,7 @@ void RenderPass::instanceify(FEngine& engine) noexcept { UTILS_ALWAYS_INLINE // this function exists only to make the code more readable. we want it inlined. inline // and we don't need it in the compilation unit void RenderPass::setupColorCommand(Command& cmdDraw, Variant variant, - FMaterialInstance const* const UTILS_RESTRICT mi, bool invertedFrontFaces) noexcept { + FMaterialInstance const* const UTILS_RESTRICT mi, bool inverseFrontFaces) noexcept { FMaterial const * const UTILS_RESTRICT ma = mi->getMaterial(); variant = Variant::filterVariant(variant, ma->isVariantLit()); @@ -359,7 +359,7 @@ void RenderPass::setupColorCommand(Command& cmdDraw, Variant variant, cmdDraw.primitive.rasterState.blendFunctionDstAlpha = blendingMustBeOff ? BlendFunction::ZERO : cmdDraw.primitive.rasterState.blendFunctionDstAlpha; - cmdDraw.primitive.rasterState.inverseFrontFaces = invertedFrontFaces; + cmdDraw.primitive.rasterState.inverseFrontFaces = inverseFrontFaces; cmdDraw.primitive.rasterState.culling = mi->getCullingMode(); cmdDraw.primitive.rasterState.colorWrite = mi->isColorWriteEnabled(); cmdDraw.primitive.rasterState.depthWrite = mi->isDepthWriteEnabled(); @@ -458,6 +458,7 @@ RenderPass::Command* RenderPass::generateCommandsImpl(uint32_t extraFlags, auto const* const UTILS_RESTRICT soaInstanceInfo = soa.data(); const bool hasShadowing = renderFlags & HAS_SHADOWING; + const bool viewInverseFrontFaces = renderFlags & HAS_INVERSE_FRONT_FACES; const bool hasInstancedStereo = renderFlags & IS_STEREOSCOPIC; Command cmdColor; @@ -512,6 +513,7 @@ RenderPass::Command* RenderPass::generateCommandsImpl(uint32_t extraFlags, const uint32_t distanceBits = reinterpret_cast(distance); // calculate the per-primitive face winding order inversion + const bool inverseFrontFaces = viewInverseFrontFaces ^ soaVisibility[i].reversedWindingOrder; const bool hasMorphing = soaVisibility[i].morphing; const bool hasSkinningOrMorphing = soaVisibility[i].skinning || hasMorphing; @@ -549,6 +551,7 @@ RenderPass::Command* RenderPass::generateCommandsImpl(uint32_t extraFlags, soaInstanceInfo[i].count | PrimitiveInfo::USER_INSTANCE_MASK; cmdDepth.primitive.instanceBufferHandle = soaInstanceInfo[i].handle; cmdDepth.primitive.materialVariant.setSkinning(hasSkinningOrMorphing); + cmdDepth.primitive.rasterState.inverseFrontFaces = inverseFrontFaces; if (UTILS_UNLIKELY(hasInstancedStereo)) { cmdColor.primitive.instanceCount = @@ -560,9 +563,8 @@ RenderPass::Command* RenderPass::generateCommandsImpl(uint32_t extraFlags, renderableVariant.setFog(soaVisibility[i].fog && Variant::isFogVariant(variant)); } - bool const shadowCaster = soaVisibility[i].castShadows & hasShadowing; - bool const writeDepthForShadowCasters = depthContainsShadowCasters & shadowCaster; - bool const reverseWindingOrder = soaVisibility[i].reversedWindingOrder; + const bool shadowCaster = soaVisibility[i].castShadows & hasShadowing; + const bool writeDepthForShadowCasters = depthContainsShadowCasters & shadowCaster; const Slice& primitives = soaPrimitives[i]; const FRenderableManager::SkinningBindingInfo& skinning = soaSkinning[i]; @@ -577,11 +579,10 @@ RenderPass::Command* RenderPass::generateCommandsImpl(uint32_t extraFlags, auto const& morphTargets = morphing.targets[pi]; FMaterialInstance const* const mi = primitive.getMaterialInstance(); FMaterial const* const ma = mi->getMaterial(); - bool const invertedFrontFaces = mi->isFrontFaceWindingInverted() ^ reverseWindingOrder; if constexpr (isColorPass) { cmdColor.primitive.primitiveHandle = primitive.getHwHandle(); - RenderPass::setupColorCommand(cmdColor, renderableVariant, mi, invertedFrontFaces); + RenderPass::setupColorCommand(cmdColor, renderableVariant, mi, inverseFrontFaces); cmdColor.primitive.skinningHandle = skinning.handle; cmdColor.primitive.skinningOffset = skinning.offset; @@ -610,6 +611,7 @@ RenderPass::Command* RenderPass::generateCommandsImpl(uint32_t extraFlags, cmdColor.key |= makeField(primitive.getBlendOrder(), BLEND_ORDER_MASK, BLEND_ORDER_SHIFT); + const TransparencyMode mode = mi->getTransparencyMode(); // handle transparent objects, two techniques: @@ -687,7 +689,6 @@ RenderPass::Command* RenderPass::generateCommandsImpl(uint32_t extraFlags, cmdDepth.primitive.primitiveHandle = primitive.getHwHandle(); cmdDepth.primitive.mi = mi; cmdDepth.primitive.rasterState.culling = mi->getCullingMode(); - cmdDepth.primitive.rasterState.inverseFrontFaces = invertedFrontFaces; cmdDepth.primitive.skinningHandle = skinning.handle; cmdDepth.primitive.skinningOffset = skinning.offset; diff --git a/filament/src/RenderPass.h b/filament/src/RenderPass.h index fcbfba9d57..4b671a648f 100644 --- a/filament/src/RenderPass.h +++ b/filament/src/RenderPass.h @@ -264,7 +264,8 @@ public: using RenderFlags = uint8_t; static constexpr RenderFlags HAS_SHADOWING = 0x01; - static constexpr RenderFlags IS_STEREOSCOPIC = 0x02; + static constexpr RenderFlags HAS_INVERSE_FRONT_FACES = 0x02; + static constexpr RenderFlags IS_STEREOSCOPIC = 0x04; // Arena used for commands using Arena = utils::Arena< @@ -415,11 +416,11 @@ private: Variant variant, RenderFlags renderFlags, FScene::VisibleMaskType visibilityMask, math::float3 cameraPosition, math::float3 cameraForward) noexcept; - static void setupColorCommand(Command& cmdDraw, Variant variant, FMaterialInstance const* mi, - bool invertedFrontFaces) noexcept; + static void setupColorCommand(Command& cmdDraw, Variant variant, + FMaterialInstance const* mi, bool inverseFrontFaces) noexcept; - static void updateSummedPrimitiveCounts(FScene::RenderableSoa& renderableData, - utils::Range vr) noexcept; + static void updateSummedPrimitiveCounts( + FScene::RenderableSoa& renderableData, utils::Range vr) noexcept; // a reference to the Engine, mostly to get to things like JobSystem diff --git a/filament/src/View.cpp b/filament/src/View.cpp index fd915fbc23..dd8e9380a7 100644 --- a/filament/src/View.cpp +++ b/filament/src/View.cpp @@ -171,6 +171,14 @@ bool View::isPostProcessingEnabled() const noexcept { return downcast(this)->hasPostProcessPass(); } +void View::setFrontFaceWindingInverted(bool inverted) noexcept { + downcast(this)->setFrontFaceWindingInverted(inverted); +} + +bool View::isFrontFaceWindingInverted() const noexcept { + return downcast(this)->isFrontFaceWindingInverted(); +} + void View::setDynamicLightingOptions(float zLightNear, float zLightFar) noexcept { downcast(this)->setDynamicLightingOptions(zLightNear, zLightFar); } diff --git a/filament/src/details/MaterialInstance.cpp b/filament/src/details/MaterialInstance.cpp index fafd6c71af..ad3ea314ce 100644 --- a/filament/src/details/MaterialInstance.cpp +++ b/filament/src/details/MaterialInstance.cpp @@ -42,8 +42,7 @@ FMaterialInstance::FMaterialInstance() noexcept mDepthWrite(false), mHasScissor(false), mIsDoubleSided(false), - mTransparencyMode(TransparencyMode::DEFAULT), - mFrontFaceWindingInverted(false) { + mTransparencyMode(TransparencyMode::DEFAULT) { } FMaterialInstance::FMaterialInstance(FEngine& engine, @@ -61,7 +60,6 @@ FMaterialInstance::FMaterialInstance(FEngine& engine, mHasScissor(false), mIsDoubleSided(other->mIsDoubleSided), mScissorRect(other->mScissorRect), - mFrontFaceWindingInverted(other->mFrontFaceWindingInverted), mName(name ? CString(name) : other->mName) { FEngine::DriverApi& driver = engine.getDriverApi(); diff --git a/filament/src/details/MaterialInstance.h b/filament/src/details/MaterialInstance.h index aa01d1b779..6be23b7e06 100644 --- a/filament/src/details/MaterialInstance.h +++ b/filament/src/details/MaterialInstance.h @@ -205,14 +205,6 @@ public: } } - void setFrontFaceWindingInverted(bool inverted) noexcept { - mFrontFaceWindingInverted = inverted; - } - - bool isFrontFaceWindingInverted() const noexcept { - return mFrontFaceWindingInverted; - } - const char* getName() const noexcept; void setParameter(std::string_view name, @@ -275,8 +267,6 @@ private: (uint32_t)std::numeric_limits::max() }; - bool mFrontFaceWindingInverted : 1; - utils::CString mName; }; diff --git a/filament/src/details/Renderer.cpp b/filament/src/details/Renderer.cpp index ea30a0a4ea..1304ccb340 100644 --- a/filament/src/details/Renderer.cpp +++ b/filament/src/details/Renderer.cpp @@ -626,6 +626,7 @@ void FRenderer::renderJob(ArenaScope& arena, FView& view) { RenderPass::RenderFlags renderFlags = 0; if (view.hasShadowing()) renderFlags |= RenderPass::HAS_SHADOWING; + if (view.isFrontFaceWindingInverted()) renderFlags |= RenderPass::HAS_INVERSE_FRONT_FACES; if (view.hasInstancedStereo()) renderFlags |= RenderPass::IS_STEREOSCOPIC; RenderPass pass(engine, commandArena); diff --git a/filament/src/details/View.h b/filament/src/details/View.h index 504beabdf8..c2152a52f5 100644 --- a/filament/src/details/View.h +++ b/filament/src/details/View.h @@ -115,6 +115,10 @@ public: void setFrustumCullingEnabled(bool culling) noexcept { mCulling = culling; } bool isFrustumCullingEnabled() const noexcept { return mCulling; } + void setFrontFaceWindingInverted(bool inverted) noexcept { mFrontFaceWindingInverted = inverted; } + bool isFrontFaceWindingInverted() const noexcept { return mFrontFaceWindingInverted; } + + void setVisibleLayers(uint8_t select, uint8_t values) noexcept; uint8_t getVisibleLayers() const noexcept { return mVisibleLayers; @@ -491,6 +495,7 @@ private: Viewport mViewport; bool mCulling = true; + bool mFrontFaceWindingInverted = false; FRenderTarget* mRenderTarget = nullptr; diff --git a/samples/rendertarget.cpp b/samples/rendertarget.cpp index 3002501344..9ff53ccc37 100644 --- a/samples/rendertarget.cpp +++ b/samples/rendertarget.cpp @@ -65,14 +65,13 @@ struct App { View* offscreenView = nullptr; Scene* offscreenScene = nullptr; Camera* offscreenCamera = nullptr; - MaterialInstance* invertedMeshMatInstance = nullptr; enum class ReflectionMode { - NEGATIVE_SCALE_TRANSFORM, - MATERIAL, + RENDERABLES, + CAMERA, }; - ReflectionMode mode = ReflectionMode::MATERIAL; + ReflectionMode mode = ReflectionMode::CAMERA; Config config; utils::Entity quadEntity; @@ -106,6 +105,22 @@ static mat4f reflectionMatrix(float4 plane) { return transpose(m); } +static void setReflectionMode(App& app, App::ReflectionMode mode) { + switch (mode) { + case App::ReflectionMode::RENDERABLES: + app.offscreenScene->addEntity(app.reflectedMonkey); + app.offscreenScene->remove(app.monkeyMesh.renderable); + app.offscreenView->setFrontFaceWindingInverted(false); + break; + case App::ReflectionMode::CAMERA: + app.offscreenScene->addEntity(app.monkeyMesh.renderable); + app.offscreenScene->remove(app.reflectedMonkey); + app.offscreenView->setFrontFaceWindingInverted(true); + break; + } + app.mode = mode; +} + static void printUsage(char* name) { std::string exec_name(utils::Path(name).getName()); std::string usage( @@ -118,7 +133,7 @@ static void printUsage(char* name) { " --api, -a\n" " Specify the backend API: opengl (default), vulkan, or metal\n" " --mode, -m\n" - " Specify the reflection mode: material (default), or ntransform\n\n" + " Specify the reflection mode: camera (default), or renderables\n\n" ); const std::string from("SHOWCASE"); for (size_t pos = usage.find(from); pos != std::string::npos; pos = usage.find(from, pos)) { @@ -157,12 +172,12 @@ static int handleCommandLineArguments(int argc, char* argv[], App* app) { } break; case 'm': - if (arg == "material") { - app->mode = App::ReflectionMode::MATERIAL; - } else if (arg == "ntransform") { - app->mode = App::ReflectionMode::NEGATIVE_SCALE_TRANSFORM; + if (arg == "camera") { + app->mode = App::ReflectionMode::CAMERA; + } else if (arg == "renderables") { + app->mode = App::ReflectionMode::RENDERABLES; } else { - std::cerr << "Unrecognized mode. Must be 'materail'|'ntransform'.\n"; + std::cerr << "Unrecognized mode. Must be 'camera'|'renderables'.\n"; exit(1); } break; @@ -182,11 +197,6 @@ int main(int argc, char** argv) { auto& em = utils::EntityManager::get(); auto vp = view->getViewport(); - // For Vulkan, DEPTH32F is more readily available. - auto const depthFormat = app.config.backend == Engine::Backend::VULKAN - ? Texture::InternalFormat::DEPTH32F - : Texture::InternalFormat::DEPTH24; - // Instantiate offscreen render target. app.offscreenView = engine->createView(); app.offscreenScene = engine->createScene(); @@ -199,7 +209,7 @@ int main(int argc, char** argv) { app.offscreenDepthTexture = Texture::Builder() .width(vp.width).height(vp.height).levels(1) .usage(Texture::Usage::DEPTH_ATTACHMENT) - .format(depthFormat).build(*engine); + .format(Texture::InternalFormat::DEPTH24).build(*engine); app.offscreenRenderTarget = RenderTarget::Builder() .texture(RenderTarget::AttachmentPoint::COLOR, app.offscreenColorTexture) .texture(RenderTarget::AttachmentPoint::DEPTH, app.offscreenDepthTexture) @@ -276,22 +286,19 @@ int main(int argc, char** argv) { rcm.setCastShadows(rcm.getInstance(app.monkeyMesh.renderable), false); scene->addEntity(app.monkeyMesh.renderable); - auto invertedMi = app.invertedMeshMatInstance = MaterialInstance::duplicate(mi); - invertedMi->setFrontFaceWindingInverted(true); - - // Create a reflected monkey. + // Create a reflected monkey, which is used only for App::ReflectionMode::RENDERABLES. app.reflectedMonkey = em.create(); RenderableManager::Builder(1) .boundingBox({{ -2, -2, -2 }, { 2, 2, 2 }}) - .material(0, app.mode == App::ReflectionMode::MATERIAL ? invertedMi : mi) + .material(0, mi) .geometry(0, RenderableManager::PrimitiveType::TRIANGLES, app.monkeyMesh.vertexBuffer, app.monkeyMesh.indexBuffer) .receiveShadows(true) .castShadows(false) .build(*engine, app.reflectedMonkey); - app.offscreenScene->addEntity(app.reflectedMonkey); + setReflectionMode(app, app.mode); // Add light source to both scenes. - // NOTE: this is slightly wrong when the reflection mode is NEGATIVE_SCALE_TRANSFORM. + // NOTE: this is slightly wrong when the reflection mode is RENDERABLES. app.lightEntity = em.create(); LightManager::Builder(LightManager::Type::SUN) .color(Color::toLinear(sRGBColor(0.98f, 0.92f, 0.89f))) @@ -314,7 +321,6 @@ int main(int argc, char** argv) { engine->destroy(app.reflectedMonkey); engine->destroy(app.lightEntity); engine->destroy(app.quadEntity); - engine->destroy(app.invertedMeshMatInstance); engine->destroy(app.meshMatInstance); engine->destroy(app.meshMaterial); engine->destroy(app.monkeyMesh.renderable); @@ -357,12 +363,11 @@ int main(int argc, char** argv) { app.offscreenCamera->setCustomProjection(renderingProjection, cullingProjection, camera.getNear(), camera.getCullingFar()); switch (app.mode) { - case App::ReflectionMode::NEGATIVE_SCALE_TRANSFORM: + case App::ReflectionMode::RENDERABLES: tcm.setTransform(tcm.getInstance(app.reflectedMonkey), reflection * xform); app.offscreenCamera->setModelMatrix(model); break; - case App::ReflectionMode::MATERIAL: - tcm.setTransform(tcm.getInstance(app.reflectedMonkey), xform); + case App::ReflectionMode::CAMERA: app.offscreenCamera->setModelMatrix(reflection * model); break; } diff --git a/web/filament-js/jsbindings.cpp b/web/filament-js/jsbindings.cpp index b1e3609603..90e4171b7a 100644 --- a/web/filament-js/jsbindings.cpp +++ b/web/filament-js/jsbindings.cpp @@ -1411,10 +1411,7 @@ class_("MaterialInstance") .function("setStencilWriteMask", EMBIND_LAMBDA(void, (MaterialInstance* self, uint8_t writeMask), { self->setStencilWriteMask(writeMask, backend::StencilFace::FRONT_AND_BACK); - }), allow_raw_pointers()) - .function("setFrontFaceWindingInverted", &MaterialInstance::setFrontFaceWindingInverted) - .function("isFrontFaceWindingInverted", &MaterialInstance::isFrontFaceWindingInverted); - + }), allow_raw_pointers()); class_("TextureSampler") .constructor()