Revert "engine: move setFrontFaceWindingInverted from View to MaterialInstance (#7331)" (#7360)

This reverts commit 038f07cb34.
This commit is contained in:
Powei Feng
2023-11-13 22:26:03 -08:00
parent 2250664e58
commit 8eade6be1f
17 changed files with 136 additions and 140 deletions

View File

@@ -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

View File

@@ -433,13 +433,6 @@ Java_com_google_android_filament_MaterialInstance_nSetStencilWriteMask(JNIEnv*,
instance->setStencilWriteMask(writeMask, static_cast<MaterialInstance::StencilFace>(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<jboolean>(instance->isFrontFaceWindingInverted());
}

View File

@@ -202,6 +202,20 @@ Java_com_google_android_filament_View_nIsPostProcessingEnabled(JNIEnv*,
return static_cast<jboolean>(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<jboolean>(view->isFrontFaceWindingInverted());
}
extern "C" JNIEXPORT void JNICALL
Java_com_google_android_filament_View_nSetAmbientOcclusion(JNIEnv*, jclass, jlong nativeView, jint ordinal) {
View* view = (View*) nativeView;

View File

@@ -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);

View File

@@ -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);

View File

@@ -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;

View File

@@ -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.
*

View File

@@ -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

View File

@@ -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<FScene::INSTANCES>();
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<uint32_t&>(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<FRenderPrimitive>& 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;

View File

@@ -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<uint32_t> vr) noexcept;
static void updateSummedPrimitiveCounts(
FScene::RenderableSoa& renderableData, utils::Range<uint32_t> vr) noexcept;
// a reference to the Engine, mostly to get to things like JobSystem

View File

@@ -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);
}

View File

@@ -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();

View File

@@ -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<int32_t>::max()
};
bool mFrontFaceWindingInverted : 1;
utils::CString mName;
};

View File

@@ -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);

View File

@@ -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;

View File

@@ -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<ACCURATE>(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;
}

View File

@@ -1411,10 +1411,7 @@ class_<MaterialInstance>("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>("TextureSampler")
.constructor<backend::SamplerMinFilter, backend::SamplerMagFilter, backend::SamplerWrapMode>()