【发布时间】:2017-09-19 16:06:57
【问题描述】:
这是我第一次尝试使用 Stencil 测试,但我看到了一些使用 OpenGL 的示例和一些关于 Metal 的示例,但重点是深度测试。我了解 Stencil 测试背后的理论,但我不知道如何在 Metal 上进行设置。
我想画不规则的形状。为简单起见,让我们考虑以下 2D 多边形:
我希望模板通过重叠三角形的数量为奇数的地方,这样我就可以达到这样的效果,白色区域是要忽略的区域:
我正在按照确切的顺序执行以下步骤:
设置depthStencilPixelFormat:
mtkView.depthStencilPixelFormat = .stencil8
mtkView.clearStencil = .allZeros
模板附件:
let textureDescriptor = MTLTextureDescriptor.texture2DDescriptor(pixelFormat: .stencil8, width: drawable.texture.width, height: drawable.texture.height, mipmapped: true)
textureDescriptor.textureType = .type2D
textureDescriptor.storageMode = .private
textureDescriptor.usage = [.renderTarget, .shaderRead, .shaderWrite]
mainPassStencilTexture = device.makeTexture(descriptor: textureDescriptor)
let stencilAttachment = MTLRenderPassStencilAttachmentDescriptor()
stencilAttachment.texture = mainPassStencilTexture
stencilAttachment.clearStencil = 0
stencilAttachment.loadAction = .clear
stencilAttachment.storeAction = .store
renderPassDescriptor.stencilAttachment = stencilAttachment
模板描述符:
stencilDescriptor.depthCompareFunction = MTLCompareFunction.always
stencilDescriptor.isDepthWriteEnabled = true
stencilDescriptor.frontFaceStencil.stencilCompareFunction = MTLCompareFunction.equal
stencilDescriptor.frontFaceStencil.stencilFailureOperation = MTLStencilOperation.keep
stencilDescriptor.frontFaceStencil.depthFailureOperation = MTLStencilOperation.keep
stencilDescriptor.frontFaceStencil.depthStencilPassOperation = MTLStencilOperation.invert
stencilDescriptor.frontFaceStencil.readMask = 0x1
stencilDescriptor.frontFaceStencil.writeMask = 0x1
stencilDescriptor.backFaceStencil = nil
depthStencilState = device.makeDepthStencilState(descriptor: stencilDescriptor)
最后,我在主通道中设置参考值和模板状态:
renderEncoder.setStencilReferenceValue(0x1)
renderEncoder.setDepthStencilState(self.depthStencilState)
我是否遗漏了什么,因为我得到的结果就像根本没有模板一样。更改深度测试的设置时我可以看到一些差异,但更改模板设置时没有任何反应...
有什么线索吗?
提前谢谢你
【问题讨论】:
标签: swift metal stencil-buffer