【问题标题】:iOS Metal Shader - Texture read and write access?iOS Metal Shader - 纹理读写访问?
【发布时间】:2016-07-08 00:22:48
【问题描述】:

我正在使用金属着色器将许多粒子绘制到屏幕上。每个粒子都有自己的位置(可以更改),并且通常两个粒子具有相同的位置。如何检查我写入的texture2d 是否在某个位置没有像素? (如果还没有绘制粒子,我想确保只在某个位置绘制粒子,因为如果在同一位置绘制许多粒子,我会得到难看的闪烁)

我试过outTexture.read(particlePosition),但这显然不起作用,因为纹理访问限定符是access::write

有没有办法同时对texture2d 进行读写访问? (如果没有,我怎么还能解决我的问题?)

【问题讨论】:

    标签: ios shader metal


    【解决方案1】:

    有几种方法可以在这里工作。在并发系统编程中,您所说的被称为first-write wins

    1) 如果粒子只需要阻止其他粒子被绘制(并且在同一渲染过程中不会被场景中的其他元素潜在地遮挡),您可以将特殊值写入深度缓冲区以表示片段已写入特定坐标。例如,您将打开深度测试(使用深度比较函数 Equal),将深度缓冲区清除为某个距离较远的值(如 1.0),然后将值 0.0 写入片段函数中的深度缓冲区。对给定像素的任何后续写入都将无法通过深度测试并且不会被绘制。

    2) 使用帧缓冲回读。在 iOS 上,Metal 允许您通过使用 [[color(0)]] 将参数分配给片段函数来从当前绑定的主渲染缓冲区中读取。此参数将包含渲染缓冲区中的当前颜色值,您可以对其进行测试以确定它是否已被写入。这确实需要您将纹理清除为您的片段函数永远不会生成的预定颜色,因此它比上述方法更受限制,并且性能可能更低。

    无论您是渲染到可绘制对象的纹理以直接呈现到屏幕上,还是渲染到某些屏幕外纹理,上述所有内容都适用。

    【讨论】:

      【解决方案2】:

      回答读写部分:您可以为输出纹理指定读/写访问权限:

      texture2d<float, access::read_write> outTexture [[texture(1)]],

      此外,您的纹理描述符必须指定用法:

      textureDescriptor?.usage = [.shaderRead, .shaderWrite]

      【讨论】:

        猜你喜欢
        • 2016-10-30
        • 2016-04-24
        • 2022-01-22
        • 1970-01-01
        • 2018-01-05
        • 1970-01-01
        • 1970-01-01
        • 2018-06-09
        • 2017-09-27
        相关资源
        最近更新 更多