什么是 Apple 的 Metal(金属着色器语言)纹理坐标?

What are Apple's Metal (Metal Shader Language) texture coordinates?

在iOS或OS/X中Metal Shader Language内核函数使用了哪些纹理坐标?例如,给定一个 MTLTexture and uint2 gid[[thread_position_in_grid]] Is gid.x and gid.ybetween 0..1 (x and y are floats) or 0..inTexture.get_width() ( x 和 y 是整数)。

提前致谢

thread_position_in_grid 总是由无符号整数组成,并提供这些选项,但其中 none 与纹理坐标有关。问另一个相关问题可能会有所帮助,因为您似乎将纹理和内核函数的概念混为一谈。

  • 16 或 -32 位
  • 1D、2D 或 3D

thread_position_in_grid 是网格中的索引(整数),它采用您在 dispatchThreadgroups:threadsPerThreadgroup: 中指定的范围内的值。由您决定您想要多少个线程组,以及每个组有多少个线程。

在下面的sample code中你可以看到threadsPerGroup.width * numThreadgroups.width == inputImage.widththreadsPerGroup.height * numThreadgroups.height == inputImage.height。在这种情况下,网格中的位置将因此是 non-normalized(整数)像素坐标。

Metal 中计算着色器的每次启动都伴随着线程 ID 的密集矩形 3D 网格。调用 [MTLComputeCommandEncoder dispatchThreadGroups:threadsPerThreadgroup:] 时会设置网格的尺寸。例如,您可以将线程组大小设置为 {16,16,1}(一个线程组中有 256 个线程,一个 16x16x1 正方形),线程组计数设置为 {1,2,1},这将导致启动两个线程组,总面积为 512 {16,32,1} 形状的线程。这些是在内核顶部显示为 [[thread_position_in_grid]] 的整数。线程位置是你告诉你是哪个线程的方式,就像通过 dispatch_apply().

传递给块的 threadID 参数一样

Metal 指定没有从 [[thread_position_in_grid]] 映射到纹理中的坐标。这是由您在计算着色器中的软件中完成的。如果你想在图像中的某个偏移处读取纹理区域中的每隔一个像素,那么你需要将 threadID 乘以 2 并在将新坐标传递给 texture2d.sample 之前在你的内核中添加一个偏移量。由于 Metal 无法启动部分线程组,因此您需要确保不执行不需要的线程组。例如,当应用于较小的纹理时,32x64 启动的全尺寸可能会导致您注销纹理的末端。在这种情况下,您必须检查线程 ID 以查看线程是否会注销结尾,然后 return 退出着色器或跳过该线程的纹理写入调用以避免问题。