简体   繁体   中英

How to turn-off/disable Metal depth testing

I know how to enable the depth test in Metal using swift.

Just call the MTLRenderCommandEncoder.setDepthStencilState() with appropriate MTLDepthStencilState object like this and it works fine.

renderCommandEncoder.setDepthStencilState( state )

to turn it off, I thought this could work but it gives me an error at runtime.

renderCommandEncoder.setDepthStencilState( nil )

the error:

-[MTLDebugRenderCommandEncoder setDepthStencilState:]:3843: failed assertion `Set Depth Stencil State Validation
depthStencilState must not be nil.

it is weird because Apple's documentation says that the default value is nil and the function setDepthStencilState() takes optional value.

any idea how to turn depth-testing off or am I doing something wrong?

environment:

  • Xcode 13.2
  • Swift 5
  • deployment target: MacOS 11.1

You can disable depth test by creating an MTLDepthStencilState from MTLDepthStencilDescriptor with depthCompareFunction set to always .

let descriptor = MTLDepthStencilDescriptor()
descriptor.depthCompareFunction = .always
let depthStencilState = device.makeDepthStencilState(descriptor: descriptor)
renderCommandEncoder.setDepthStencilState(depthStencilState)

Update: just setting the depthCompareFunction to always will make the depth test always pass, but it will also still write out the depth for all the fragments. If you want to keep the depth buffer in the same state, you can set isDepthWriteEnabled to false .

I don't use swift , but you will understand my logic.

In Metal, you configure depth testing independently from the render pipeline, so you can mix and match combinations of render pipelines and depth tests. The depth test is represented by a MTLDepthStencilState object, and like you do with a render pipeline, you can create multiple variation of this object.

Create a new MTLDepthStencilState object and configure it with the following settings:

DepthStencilDescriptor* depthStencilDescriptor = DepthStencilDescriptor::alloc()->init();
depthStencilDescriptor->setDepthWriteEnabled(false); /* disable depth write */
_depthStencilStateNoWrite = _device->newDepthStencilState(depthStencilDescriptor);
depthStencilDescriptor->release();

Use it whenever you want your object to be ignored by the depth test like so:

renderEncoder->setDepthStencilState(_depthStencilStateNoWrite);

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM