金属片段着色器 uv 坐标在读取顶点颜色时发生变化

Metal fragment shader uv coordinates change when reading in vertex color

我正在尝试将抖动应用于简单的彩色四边形,发现了一个奇怪的问题。我有一个片段着色器,它应该计算一些 uv 和 return 抖动颜色的抖动。这在带纹理的四边形上工作正常,但奇怪的是,当我从我的 inVertex 访问颜色数据时,uv 坐标更改为一些奇怪的值,并且 y 值似乎映射到x 轴。我将尝试说明当我更改片段着色器代码周围的内容时会发生什么。

fragment float4 fragment_colored_dithered(ColoredVertex inVertex [[stage_in]],
                                              float2 uv[[point_coord]]) {
        float4 color = inVertex.color;
        uv = (uv/2) + 0.5;
        if (uv.y < 0.67) {
            return float4(uv.y, 0, 0, 1);
        }
        else {
            return color;
        }
    }

产生以下结果:

在图像左侧显示我的渐变四边形的位置,请注意 if (uv.y < 0.67) 映射到图像中的 x 值。

如果我更改此片段着色器而不更改代码中的任何其他内容,例如我 return float4(0, 0, 1, 0) 而不是 inVertex.color,则 uv 坐标会正确映射。

fragment float4 fragment_colored_dithered(ColoredVertex inVertex [[stage_in]],
                                          float2 uv[[point_coord]]) {
    float4 color = inVertex.color;
    uv = (uv/2) + 0.5;
    if (uv.y < 0.67) {
        return float4(uv.y, 0, 0, 1);
    }
    else {
        return float4(0, 0, 1, 0); //return color;
    }
} 

产生这个(正确的)结果:

我想我可以通过将 1x1 纹理应用于渐变并使用纹理坐标来解决这个问题,但我真的很想知道这里发生了什么,这是一个错误还是我不知道的功能'不懂?

为什么要使用 [[point_coord]]?你认为它代表什么?

除非您正在绘制点图元,否则您不应该使用它。由于您正在绘制 "quad",并根据屏幕截图,我假设您没有绘制点图元。

我怀疑 [[point_coord]] 只是未定义,并且在您绘制三角形时会出现随机行为。随机性显然受到片段着色器的细节(例如堆栈布局)的影响。

您应该使用 [[position]] 并按 window 大小缩放,或者在 ColoredVertex 结构中使用插值字段来承载 "texture" 坐标。