有没有办法在 Metal 中同时启用混合和深度

Dom*_*man 5 textures alphablending depth-buffer ios metal

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

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

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

我究竟做错了什么?有没有办法让它工作并且有人可以提供一些示例代码?

我看到的另一个选择是尝试在 GPU 上进行排序,这很好,因为 GPU 帧时间明显小于 CPU 帧时间。但是,我也不确定如何做到这一点。

任何帮助将不胜感激。:)

Bor*_*rzh 1

Alpha 混合是一种依赖于顺序的透明度技术。这意味着(半)透明对象不能像(更昂贵的)顺序无关透明技术那样以任意顺序渲染。

  • 确保透明的 2D 对象(例如圆形、矩形等)具有不同的深度值。(这样你就可以自己定义绘制顺序。否则绘制顺序取决于排序算法的实现和排序前的初始顺序。)
  • 根据这些 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
Run Code Online (Sandbox Code Playgroud)

希望这可以帮助。从这里