我正在尝试使用Metal来显示一些具有复杂alpha的3D对象。
我得到白色边缘在相同的对象到对象alpha混合。但在不同的对象工作良好。
我已经通过在一个对象中禁用depthMask解决了Android中的这个问题。
谁能帮我怎么做在金属iOS?
我的renderEncoder如下:
let pipelineStateDescriptor = MTLRenderPipelineDescriptor()
pipelineStateDescriptor.vertexFunction = vertexProgram
pipelineStateDescriptor.fragmentFunction = fragmentProgram
pipelineStateDescriptor.colorAttachments[0].pixelFormat = .BGRA8Unorm
pipelineStateDescriptor.colorAttachments[0].blendingEnabled = true
pipelineStateDescriptor.colorAttachments[0].rgbBlendOperation = MTLBlendOperation.Add;
pipelineStateDescriptor.colorAttachments[0].alphaBlendOperation = MTLBlendOperation.Add;
pipelineStateDescriptor.colorAttachments[0].sourceRGBBlendFactor = MTLBlendFactor.SourceAlpha;
pipelineStateDescriptor.colorAttachments[0].sourceAlphaBlendFactor = MTLBlendFactor.SourceAlpha;
pipelineStateDescriptor.colorAttachments[0].destinationRGBBlendFactor = MTLBlendFactor.OneMinusSourceAlpha;
pipelineStateDescriptor.colorAttachments[0].destinationAlphaBlendFactor = MTLBlendFactor.OneMinusSourceAlpha;
pipelineStateDescriptor.depthAttachmentPixelFormat = .Depth32Float
pipelineState = try! device.newRenderPipelineStateWithDescriptor(pipelineStateDescriptor)
let depthStencilDescriptor = MTLDepthStencilDescriptor()
depthStencilDescriptor.depthCompareFunction = .Less
depthStencilDescriptor.depthWriteEnabled = true
depthStencilState = device.newDepthStencilStateWithDescriptor(depthStencilDescriptor)
let renderPassDescriptor = MTLRenderPassDescriptor()
renderPassDescriptor.colorAttachments[0].texture = drawable.texture
renderPassDescriptor.colorAttachments[0].loadAction = .Clear
renderPassDescriptor.colorAttachments[0].clearColor = MTLClearColor(red: 1.0, green: 1.0, blue: 1.0, alpha: 1.0)
renderPassDescriptor.colorAttachments[0].storeAction = .Store
renderPassDescriptor.depthAttachment.loadAction = .Clear
renderPassDescriptor.depthAttachment.clearDepth = 1.0
renderPassDescriptor.depthAttachment.storeAction = .MultisampleResolve
let commandBuffer = commandQueue.commandBuffer()
commandBuffer.addCompletedHandler { (commandBuffer) -> Void in
dispatch_semaphore_signal(self.bufferProvider.avaliableResourcesSemaphore)
}
renderEncoder = commandBuffer.renderCommandEncoderWithDescriptor(renderPassDescriptor)
//For now cull mode is used instead of depth buffer
renderEncoder.setCullMode(MTLCullMode.Front)
renderEncoder.setDepthClipMode(.Clip)
renderEncoder.setRenderPipelineState(pipelineState)
renderEncoder.setDepthStencilState(depthStencilState)
我最终通过以下函数解决了这个问题:
class func defaultSampler(device: MTLDevice) -> MTLSamplerState
{
let pSamplerDescriptor:MTLSamplerDescriptor? = MTLSamplerDescriptor();
if let sampler = pSamplerDescriptor
{
sampler.minFilter = MTLSamplerMinMagFilter.Linear
sampler.magFilter = MTLSamplerMinMagFilter.Linear
sampler.mipFilter = MTLSamplerMipFilter.Linear
sampler.maxAnisotropy = 1
sampler.sAddressMode = MTLSamplerAddressMode.ClampToZero
sampler.tAddressMode = MTLSamplerAddressMode.ClampToZero
sampler.rAddressMode = MTLSamplerAddressMode.ClampToZero
sampler.normalizedCoordinates = true
sampler.lodMinClamp = 0
sampler.lodMaxClamp = FLT_MAX
}
else
{
print(">> ERROR: Failed creating a sampler descriptor!")
}
return device.newSamplerStateWithDescriptor(pSamplerDescriptor!)
}