【问题标题】:How to pass a variable number of MTLTextures to a fragment shader?如何将可变数量的 MTLTextures 传递给片段着色器?
【发布时间】:2018-11-16 19:28:30
【问题描述】:

将可变数量的 MTLTexture 作为数组传递给片段着色器的正确语法是什么?

这个 StackOverflow 问题:"How to use texture2d_array array in metal?" 提到使用:

array<texture2d<half>, 5>

但是,这需要指定数组的大小。在Metal Shading Language Specification.pdf(第 2.11 节)中,他们也演示了这种类型。然而,他们也提到了array_ref,但我不清楚如何使用它,或者它是否被允许作为给定此语句共享的片段的参数类型:

"array_ref 类型不能作为参数传递给图形 和核函数。”

我目前正在做的只是将参数声明为:

fragment float4 fragmentShader(RasterizerData in [[ stage_in ]],
                               sampler s [[ sampler(0) ]],
                               const array<texture2d<half>, 128> textures [[ texture(0) ]]) {

  const half4 c = textures[in.textureIndex].sample(s, in.coords);
}

因为限制是 128 个片段纹理。在任何渲染过程中,我可能会使用 1..n 个纹理,其中我确保 n 不超过 128。这似乎对我有用,但我做错了吗?


我的用例是绘制一个被细分为一堆瓷砖的 2D 平面。根据预先计算的纹理索引,从阵列中的指定纹理中采样每个图块的内容。纹理在渲染通道开始时使用setFragmentTexture:atIndex 以正确的顺序设置。纹理索引从顶点着色器传递到片段着色器。

【问题讨论】:

    标签: macos metal fragment-shader


    【解决方案1】:

    您应该考虑使用数组纹理而不是纹理数组。即类型为MTLTextureType2DArray 的纹理。您可以使用纹理描述符的arrayLength 属性来指定数组纹理包含多少二维切片。

    要填充纹理,请使用 -replaceRegion:...-copyFrom{Buffer,Texture}:...toTexture:... 等方法指定要写入的切片。

    在着色器中,您可以使用array 参数指定要采样或读取的元素。

    【讨论】:

    • 我曾考虑过,但是所有源纹理都需要具有相同的大小,而我的情况并非如此。例如,我可能有一个 21,000 x 5,000 像素的图像,我用四个大小为 5,000 x 1,000 的纹理和一个大小为 1,000 x 1,000 的纹理表示。使用单个纹理是不可能的,因为最大尺寸是 16384。较小的纹理给了我更多的粒度来确定哪些纹理是“脏的”以及谁的 mipmap 需要重新生成。这些纹理是通过 XPC 服务填充的,可渲染任意图块。
    • 跟进:通过重新设计我的平铺引擎并允许平铺中的“溢出”,以便我可以获得统一大小的平铺,如果使用 2D 数组可以显着提高性能并清理代码一点点。 Metal 文档、WWDC 视频和 Xcode 调试工具非常好,但如果您还没有使用低级图形的经验,那么还有很多东西需要学习。
    • @kennyc 我正在做类似的事情,尝试将一个非常大的图像渲染为瓷砖。您能否为我指出一些资源?
    • @akshay 很难提供很多指导,因为这是一个非常广泛的主题,有许多不同的方法来实现它。如果您不是绝对需要 Metal,那么我将首先使用 AppKit/UIKit 和 ImageIO 让事情正常工作。滚动视图可以是任意大的尺寸。当用户滚动时,根据滚动视图的边界绘制图像的适当部分。您还可以在滚动视图中使用 CALayer,并将您的图像平铺成您设置为图层内容的较小图像。我在管道中使用 Metal 并将图像图块映射到纹理。
    • @kennyc 我还使用金属将图像映射到纹理。但我担心无论何时用户放大和缩小,所有可见纹理都会以不同的比例重新生成。
    猜你喜欢
    • 1970-01-01
    • 2014-06-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-12-18
    • 1970-01-01
    • 2015-11-20
    • 1970-01-01
    相关资源
    最近更新 更多