有没有一种方法可以在Metal中同时实现混合和深度



我有一个显示一些纹理四边形的金属视图。纹理是从PNG加载的,因此是预乘的。某些纹理具有透明像素。

当我启用混合并按正确的顺序绘制时,透明度会起作用,您可以通过纹理的透明部分看到其他四边形下面的四边形。然而,我必须通过排序来计算正确的绘制顺序,这很昂贵,而且会大大降低渲染速度。

当我尝试使用深度模板并以任何顺序绘制时,我可以使用z位置使顺序正确工作,但随后混合停止工作。纹理的透明部分显示金属场景的背景色,而不是下面的四边形。

我做错了什么?有没有办法做到这一点?有人能提供一些示例代码吗?

我看到的另一个选择是尝试在GPU上进行排序,这很好,因为GPU帧时间明显小于CPU帧时间。然而,我也不知道该怎么做。

如有任何帮助,我们将不胜感激

Alpha混合是一种依赖于顺序的透明技术。这意味着(半透明)对象不能以任何任意顺序渲染,就像(更昂贵的)与顺序无关的透明技术一样。
  • 确保透明2D对象(例如,圆形、矩形等)具有不同的深度值。(通过这种方式,您可以自己定义绘制顺序。否则,绘制顺序取决于排序算法的实现和排序前的初始顺序。)
  • 根据这些二维对象的深度值从后到前对其进行排序
  • 使用alpha混合从后向前绘制2D对象(画家的算法)。(当然,2D对象需要alpha值<1才能真正看到一些混合。)

您需要正确设置pipelineStateDescriptor:

// To have depth buffer.
pipelineStateDescriptor.depthAttachmentPixelFormat = .depth32Float
// To use transparency.
pipelineStateDescriptor.colorAttachments[0].isBlendingEnabled = true
pipelineStateDescriptor.colorAttachments[0].rgbBlendOperation = .add
pipelineStateDescriptor.colorAttachments[0].alphaBlendOperation = .add
pipelineStateDescriptor.colorAttachments[0].sourceRGBBlendFactor = .sourceAlpha
pipelineStateDescriptor.colorAttachments[0].sourceAlphaBlendFactor = .sourceAlpha
pipelineStateDescriptor.colorAttachments[0].destinationRGBBlendFactor = .oneMinusSourceAlpha
pipelineStateDescriptor.colorAttachments[0].destinationAlphaBlendFactor = .oneMinusSourceAlpha

希望这能有所帮助。从这里

最新更新