Skip to content

Commit

Permalink
Add dynamic raster states to MaterialInstance.
Browse files Browse the repository at this point in the history
Fulfills a request from tirichards@.

This is similar in some ways to dynamic backface culling but simpler
because there is no interaction with double-sided lighting.

For reference, dynamic backface culling was implemented with google#1936, google#1877, google#1641.
  • Loading branch information
prideout committed Feb 10, 2020
1 parent 891e85b commit 4665f60
Show file tree
Hide file tree
Showing 12 changed files with 146 additions and 16 deletions.
1 change: 1 addition & 0 deletions RELEASE_NOTES.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ A new header is inserted each time a *tag* is created.
- Removed depth-prepass related APIs.
- gltfio: add asynchronous API to ResourceLoader.
- gltfio: generate normals for flat-shaded models that do not have normals.
- Material instances now allow dynamic depth testing and other rasterization state.

## v1.4.5

Expand Down
24 changes: 24 additions & 0 deletions android/filament-android/src/main/cpp/MaterialInstance.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -324,3 +324,27 @@ Java_com_google_android_filament_MaterialInstance_nSetCullingMode(JNIEnv*,
MaterialInstance* instance = (MaterialInstance*) nativeMaterialInstance;
instance->setCullingMode((MaterialInstance::CullingMode) cullingMode);
}

extern "C"
JNIEXPORT void JNICALL
Java_com_google_android_filament_MaterialInstance_nSetColorWrite(JNIEnv*,
jclass, jlong nativeMaterialInstance, jboolean enable) {
MaterialInstance* instance = (MaterialInstance*) nativeMaterialInstance;
instance->setColorWrite(enable);
}

extern "C"
JNIEXPORT void JNICALL
Java_com_google_android_filament_MaterialInstance_nSetDepthWrite(JNIEnv*,
jclass, jlong nativeMaterialInstance, jboolean enable) {
MaterialInstance* instance = (MaterialInstance*) nativeMaterialInstance;
instance->setDepthWrite(enable);
}

extern "C"
JNIEXPORT void JNICALL
Java_com_google_android_filament_MaterialInstance_nSetDepthCulling(JNIEnv*,
jclass, jlong nativeMaterialInstance, jboolean enable) {
MaterialInstance* instance = (MaterialInstance*) nativeMaterialInstance;
instance->setDepthCulling(enable);
}
Original file line number Diff line number Diff line change
Expand Up @@ -422,7 +422,7 @@ public CullingMode getCullingMode() {
}

/**
* Indicates whether this material will write to the color buffer.
* Indicates whether instances of this material will, by default, write to the color buffer.
*
* @see
* <a href="https://google.github.io/filament/Materials.html#materialdefinitions/materialblock/rasterization:colorwrite">
Expand All @@ -433,7 +433,7 @@ public boolean isColorWriteEnabled() {
}

/**
* Indicates whether this material will write to the depth buffer.
* Indicates whether instances of this material will, by default, write to the depth buffer.
*
* @see
* <a href="https://google.github.io/filament/Materials.html#materialdefinitions/materialblock/rasterization:depthwrite">
Expand All @@ -444,7 +444,7 @@ public boolean isDepthWriteEnabled() {
}

/**
* Indicates whether this material will use depth testing.
* Indicates whether instances of this material will, by default, use depth testing.
*
* @see
* <a href="https://google.github.io/filament/Materials.html#materialdefinitions/materialblock/rasterization:depthculling">
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -430,6 +430,39 @@ public void setCullingMode(Material.CullingMode mode) {
nSetCullingMode(getNativeObject(), mode.ordinal());
}

/**
* Overrides the default color-buffer write state that was set on the material.
*
* @see
* <a href="https://google.github.io/filament/Materials.html#materialdefinitions/materialblock/rasterization:colorWrite">
* Rasterization: colorWrite</a>
*/
void setColorWrite(boolean enable) {
nSetColorWrite(getNativeObject(), enable);
}

/**
* Overrides the default depth-buffer write state that was set on the material.
*
* @see
* <a href="https://google.github.io/filament/Materials.html#materialdefinitions/materialblock/rasterization:depthWrite">
* Rasterization: depthWrite</a>
*/
void setDepthWrite(boolean enable) {
nSetDepthWrite(getNativeObject(), enable);
}

/**
* Overrides the default depth testing state that was set on the material.
*
* @see
* <a href="https://google.github.io/filament/Materials.html#materialdefinitions/materialblock/rasterization:depthCulling">
* Rasterization: depthCulling</a>
*/
void setDepthCulling(boolean enable) {
nSetDepthCulling(getNativeObject(), enable);
}

public long getNativeObject() {
if (mNativeObject == 0) {
throw new IllegalStateException("Calling method on destroyed MaterialInstance");
Expand Down Expand Up @@ -499,6 +532,8 @@ private static native void nSetSpecularAntiAliasingThreshold(long nativeMaterial
float threshold);

private static native void nSetDoubleSided(long nativeMaterialInstance, boolean doubleSided);

private static native void nSetCullingMode(long nativeMaterialInstance, long mode);
private static native void nSetColorWrite(long nativeMaterialInstance, boolean enable);
private static native void nSetDepthWrite(long nativeMaterialInstance, boolean enable);
private static native void nSetDepthCulling(long nativeMaterialInstance, boolean enable);
}
6 changes: 3 additions & 3 deletions filament/include/filament/Material.h
Original file line number Diff line number Diff line change
Expand Up @@ -153,13 +153,13 @@ class UTILS_PUBLIC Material : public FilamentAPI {
//! This value only makes sense when the blending mode is transparent or fade.
TransparencyMode getTransparencyMode() const noexcept;

//! Indicates whether this material will write to the color buffer.
//! Indicates whether instances of this material will, by default, write to the color buffer.
bool isColorWriteEnabled() const noexcept;

//! Indicates whether this material will write to the depth buffer.
//! Indicates whether instances of this material will, by default, write to the depth buffer.
bool isDepthWriteEnabled() const noexcept;

//! Indicates whether this material will use depth testing.
//! Indicates whether instances of this material will, by default, use depth testing.
bool isDepthCullingEnabled() const noexcept;

//! Indicates whether this material is double-sided.
Expand Down
17 changes: 16 additions & 1 deletion filament/include/filament/MaterialInstance.h
Original file line number Diff line number Diff line change
Expand Up @@ -125,7 +125,7 @@ class UTILS_PUBLIC MaterialInstance : public FilamentAPI {

/**
* Set up a custom scissor rectangle; by default this encompasses the View.
*
*
* @param left left coordinate of the scissor box
* @param bottom bottom coordinate of the scissor box
* @param width width of the scissor box
Expand Down Expand Up @@ -188,6 +188,21 @@ class UTILS_PUBLIC MaterialInstance : public FilamentAPI {
* Overrides the default triangle culling state that was set on the material.
*/
void setCullingMode(CullingMode culling) noexcept;

/**
* Overrides the default color-buffer write state that was set on the material.
*/
void setColorWrite(bool enable) noexcept;

/**
* Overrides the default depth-buffer write state that was set on the material.
*/
void setDepthWrite(bool enable) noexcept;

/**
* Overrides the default depth testing state that was set on the material.
*/
void setDepthCulling(bool enable) noexcept;
};

} // namespace filament
Expand Down
33 changes: 32 additions & 1 deletion filament/src/MaterialInstance.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -44,9 +44,15 @@ FMaterialInstance::FMaterialInstance() noexcept = default;
FMaterialInstance::FMaterialInstance(FEngine& engine, FMaterial const* material) {
mMaterial = material;

const RasterState& rasterState = mMaterial->getRasterState();

// We inherit the resolved culling mode rather than the builder-set culling mode.
// This preserves the property whereby double-sidedness automatically disables culling.
mCulling = mMaterial->getRasterState().culling;
mCulling = rasterState.culling;

mColorWrite = rasterState.colorWrite;
mDepthWrite = rasterState.depthWrite;
mDepthFunc = rasterState.depthFunc;

mMaterialSortingKey = RenderPass::makeMaterialSortingKey(
material->getId(), material->generateMaterialInstanceId());
Expand Down Expand Up @@ -172,6 +178,18 @@ void FMaterialInstance::setCullingMode(CullingMode culling) noexcept {
mCulling = culling;
}

void FMaterialInstance::setColorWrite(bool enable) noexcept {
mColorWrite = enable;
}

void FMaterialInstance::setDepthWrite(bool enable) noexcept {
mDepthWrite = enable;
}

void FMaterialInstance::setDepthCulling(bool enable) noexcept {
mDepthFunc = enable ? RasterState::DepthFunc::LE : RasterState::DepthFunc::A;
}

// explicit template instantiation of our supported types
template UTILS_NOINLINE void FMaterialInstance::setParameter<bool> (const char* name, bool v) noexcept;
template UTILS_NOINLINE void FMaterialInstance::setParameter<float> (const char* name, float v) noexcept;
Expand Down Expand Up @@ -312,4 +330,17 @@ void MaterialInstance::setCullingMode(CullingMode culling) noexcept {
upcast(this)->setCullingMode(culling);
}

void MaterialInstance::setColorWrite(bool enable) noexcept {
upcast(this)->setColorWrite(enable);
}

void MaterialInstance::setDepthWrite(bool enable) noexcept {
upcast(this)->setDepthWrite(enable);
}

void MaterialInstance::setDepthCulling(bool enable) noexcept {
upcast(this)->setDepthCulling(enable);
}


} // namespace filament
9 changes: 6 additions & 3 deletions filament/src/RenderPass.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -210,7 +210,7 @@ void RenderPass::recordDriverCommands(FEngine::DriverApi& driver, const Command*
FMaterial const* UTILS_RESTRICT ma = nullptr;
auto const& customCommands = mCustomCommands;

auto updateMaterial = [&](FMaterialInstance const* materialInstance) {
auto useMaterialInstance = [&](FMaterialInstance const* materialInstance) {
mi = materialInstance;
ma = mi->getMaterial();
pipeline.scissor = mi->getScissor();
Expand All @@ -220,7 +220,7 @@ void RenderPass::recordDriverCommands(FEngine::DriverApi& driver, const Command*

FMaterialInstance const * const materialInstanceOverride = mMaterialInstanceOverride;
if (UTILS_UNLIKELY(materialInstanceOverride)) {
updateMaterial(materialInstanceOverride);
useMaterialInstance(materialInstanceOverride);
}

first--;
Expand All @@ -240,7 +240,7 @@ void RenderPass::recordDriverCommands(FEngine::DriverApi& driver, const Command*
pipeline.rasterState = info.rasterState;
if (UTILS_UNLIKELY(!materialInstanceOverride && mi != info.mi)) {
// this is always taken the first time
updateMaterial(info.mi);
useMaterialInstance(info.mi);
}

pipeline.program = ma->getProgram(info.materialVariant.key);
Expand Down Expand Up @@ -289,6 +289,9 @@ void RenderPass::setupColorCommand(Command& cmdDraw, bool hasDepthPass,
cmdDraw.primitive.rasterState = ma->getRasterState();
cmdDraw.primitive.rasterState.inverseFrontFaces = inverseFrontFaces;
cmdDraw.primitive.rasterState.culling = mi->getCullingMode();
cmdDraw.primitive.rasterState.colorWrite = mi->getColorWrite();
cmdDraw.primitive.rasterState.depthWrite = mi->getDepthWrite();
cmdDraw.primitive.rasterState.depthFunc = mi->getDepthFunc();
cmdDraw.primitive.mi = mi;
cmdDraw.primitive.materialVariant.key = variant;

Expand Down
15 changes: 15 additions & 0 deletions filament/src/details/MaterialInstance.h
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,12 @@ class FMaterialInstance : public MaterialInstance {

backend::CullingMode getCullingMode() const noexcept { return mCulling; }

bool getColorWrite() const noexcept { return mColorWrite; }

bool getDepthWrite() const noexcept { return mDepthWrite; }

backend::RasterState::DepthFunc getDepthFunc() const noexcept { return mDepthFunc; }

void setPolygonOffset(float scale, float constant) noexcept {
mPolygonOffset = { scale, constant };
}
Expand All @@ -120,6 +126,12 @@ class FMaterialInstance : public MaterialInstance {

void setCullingMode(CullingMode culling) noexcept;

void setColorWrite(bool enable) noexcept;

void setDepthWrite(bool enable) noexcept;

void setDepthCulling(bool enable) noexcept;

private:
friend class FMaterial;
friend class MaterialInstance;
Expand All @@ -139,6 +151,9 @@ class FMaterialInstance : public MaterialInstance {
backend::SamplerGroup mSamplers;
backend::PolygonOffset mPolygonOffset;
backend::CullingMode mCulling;
bool mColorWrite;
bool mDepthWrite;
backend::RasterState::DepthFunc mDepthFunc;

uint64_t mMaterialSortingKey = 0;

Expand Down
6 changes: 3 additions & 3 deletions libs/filamat/include/filamat/MaterialBuilder.h
Original file line number Diff line number Diff line change
Expand Up @@ -318,13 +318,13 @@ class UTILS_PUBLIC MaterialBuilder : public MaterialBuilderBase {
*/
MaterialBuilder& culling(CullingMode culling) noexcept;

//! Enable / disable color-buffer write (enabled by default).
//! Enable / disable color-buffer write (enabled by default, material instances can override).
MaterialBuilder& colorWrite(bool enable) noexcept;

//! Enable / disable depth-buffer write (enabled by default for opaque, disabled for others).
//! Enable / disable depth-buffer write (enabled by default for opaque, disabled for others, material instances can override).
MaterialBuilder& depthWrite(bool enable) noexcept;

//! Enable / disable depth based culling (enabled by default).
//! Enable / disable depth based culling (enabled by default, material instances can override).
MaterialBuilder& depthCulling(bool enable) noexcept;

/**
Expand Down
3 changes: 3 additions & 0 deletions web/filament-js/filament.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,9 @@ export class MaterialInstance {
public setMaskThreshold(threshold: number): void;
public setDoubleSided(doubleSided: boolean): void;
public setCullingMode(mode: CullingMode): void;
public setColorWrite(enable: boolean): void;
public setDepthWrite(enable: boolean): void;
public setDepthCulling(enable: boolean): void;
}

export class EntityManager {
Expand Down
5 changes: 4 additions & 1 deletion web/filament-js/jsbindings.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -958,7 +958,10 @@ class_<MaterialInstance>("MaterialInstance")
.function("setPolygonOffset", &MaterialInstance::setPolygonOffset)
.function("setMaskThreshold", &MaterialInstance::setMaskThreshold)
.function("setDoubleSided", &MaterialInstance::setDoubleSided)
.function("setCullingMode", &MaterialInstance::setCullingMode);
.function("setCullingMode", &MaterialInstance::setCullingMode)
.function("setColorWrite", &MaterialInstance::setColorWrite)
.function("setDepthWrite", &MaterialInstance::setDepthWrite)
.function("setDepthCulling", &MaterialInstance::setDepthCulling);

class_<TextureSampler>("TextureSampler")
.constructor<backend::SamplerMinFilter, backend::SamplerMagFilter, backend::SamplerWrapMode>();
Expand Down

0 comments on commit 4665f60

Please sign in to comment.