Metal MTLTexture replaces semi-transparent areas with black when alpha values that aren't 1 or 0

前提是你 提交于 2019-11-29 09:34:55

Thanks to Jessy I decided to look through how I was blending my alphas and I've figured it out. My texture still looks darkened in the GPU debugger, but in the actual app everything looks correct. I made my changes to my pipeline state descriptor, which you can see below.

pipelineStateDescriptor.colorAttachments[0].blendingEnabled = true
pipelineStateDescriptor.colorAttachments[0].rgbBlendOperation = .Add
pipelineStateDescriptor.colorAttachments[0].alphaBlendOperation = .Add
pipelineStateDescriptor.colorAttachments[0].sourceRGBBlendFactor = .DestinationAlpha
pipelineStateDescriptor.colorAttachments[0].sourceAlphaBlendFactor = .DestinationAlpha
pipelineStateDescriptor.colorAttachments[0].destinationRGBBlendFactor = .OneMinusSourceAlpha
pipelineStateDescriptor.colorAttachments[0].destinationAlphaBlendFactor = .OneMinusBlendAlpha

Since you are using a CGContext that is configured to use colors premultiplied with the alpha channel, using the standard RGB = src.rgb * src.a + dst.rgb * (1-src.a) will cause darkened areas because the src.rgb values are premultiplied with src.a already. This means that what you want is src.rgb + dst.rgb * (1-src.a) which is configured like this:

pipeline.colorAttachments[0].isBlendingEnabled = true
pipeline.colorAttachments[0].rgbBlendOperation = .add
pipeline.colorAttachments[0].alphaBlendOperation = .add
pipeline.colorAttachments[0].sourceRGBBlendFactor = .one
pipeline.colorAttachments[0].sourceAlphaBlendFactor = .sourceAlpha
pipeline.colorAttachments[0].destinationRGBBlendFactor = .oneMinusSourceAlpha
pipeline.colorAttachments[0].destinationAlphaBlendFactor = .oneMinusSourceAlpha

The .one means to leave RGB as-is. The reason for premultiplied colors is that you only need to multiply the colors once on creation as opposed to every time you blend. Your configuration achieves this too, but indirectly.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!