简体   繁体   English

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

[英]Is there a way to enable blending and depth at the same time in Metal

I have a metal view that displays some textured quads.我有一个显示一些纹理四边形的金属视图。 The textures are loaded from PNGs so are premultiplied.纹理是从 PNG 加载的,因此是预乘的。 Some of the textures have transparent pixels.一些纹理具有透明像素。

When I enable blending and draw in the right order, the transparency works and you can see quads beneath other quads through the transparent parts of the textures.当我启用混合并以正确的顺序绘制时,透明度会起作用,您可以通过纹理的透明部分看到其他四边形下方的四边形。 However, I'm having to calculate the right draw order by sorting which is expensive and slowing down my rendering a lot.但是,我必须通过排序来计算正确的绘制顺序,这很昂贵并且会大大减慢我的渲染速度。

When I've tried to use depth stencils and draw in any order, I can get the order working correctly using z position, but then the blending stops working.当我尝试使用深度模板并以任何顺序绘制时,我可以使用 z 位置使顺序正确工作,但随后混合停止工作。 The transparent parts of the texture reveal the background color of the metal scene rather than the quad below.纹理的透明部分显示金属场景的背景颜色,而不是下面的四边形。

What am I doing wrong?我究竟做错了什么? Is there a way to get this working and could someone provide some example code?有没有办法让它工作,有人可以提供一些示例代码吗?

The other option I see is to try and do the sorting on the GPU, which would be fine as the GPU frame time is significantly smaller than the CPU frame time.我看到的另一个选择是尝试在 GPU 上进行排序,这很好,因为 GPU 帧时间明显小于 CPU 帧时间。 However, I'm also not sure how to do this.但是,我也不确定该怎么做。

Any help would be greatly appreciated.任何帮助将不胜感激。 :) :)

Alpha blending is an order-dependent transparency technique. Alpha 混合是一种依赖顺序的透明技术。 This means that the (semi-)transparent objects cannot be rendered in any arbitrary order as is the case for (more expensive) order-independent transparency techniques.这意味着(半)透明对象不能像(更昂贵的)与顺序无关的透明技术那样以任意顺序呈现。

  • Make sure your transparent 2D objects (eg, circle, rectangle, etc.) have different depth values.确保您的透明 2D 对象(例如,圆形、矩形等)具有不同的深度值。 (This way you can define the draw ordering yourself. Otherwise the draw ordering depends on the implementation of the sorting algorithm and the initial ordering before sorting.) (这样你可以自己定义绘制顺序。否则绘制顺序取决于排序算法的实现和排序前的初始排序。)
  • Sort these 2D objects based on their depth value from back to front.根据深度值从后到前对这些 2D 对象进行排序。
  • Draw the 2D objects from back to front (painter's algorithm) using alpha blending.使用 alpha 混合从后向前绘制 2D 对象(画家算法)。 (Of course, your 2D objects need an alpha value < 1 to actually see some blending.) (当然,您的 2D 对象需要一个 < 1 的 alpha 值才能真正看到一些混合。)

And you need to setup pipelineStateDescriptor correctly:你需要正确设置 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

Hope this helps.希望这可以帮助。 From here这里

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM