You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Fragment Shader中使用[[point_coord]]获取UV坐标不符合预期的问题求助

问题分析与解决方案

核心问题:误用[[point_coord]]语义

你用[[point_coord]]来获取UV坐标是完全错误的——这个语义仅适用于点图元(MTLPrimitiveTypePoint)的渲染,用来获取单个点精灵内部的相对坐标。而你当前渲染的是三角形图元(两个三角形组成矩形),在这种场景下[[point_coord]]的返回值是未定义的,会随着顶点顺序、光栅化方式的变化而随机波动,这就是你看到效果异常且随顶点顺序改变的原因。

正确实现步骤

1. 给顶点数据添加UV属性

修改你的Vertex结构体,加入UV坐标字段,同时更新顶点数组,为每个顶点分配对应的UV值(左下角(0,0)、右上角(1,1)的标准UV映射):

struct Vertex {
    var position: vector_float3
    var uv: vector_float2 // 新增UV字段
}

let vertices = [
    Vertex(position: vector_float3(1, 1, 0), uv: vector_float2(1, 1)),
    Vertex(position: vector_float3(1,-1, 0), uv: vector_float2(1, 0)),
    Vertex(position: vector_float3(-1,-1, 0), uv: vector_float2(0, 0)), 
   
    Vertex(position: vector_float3(1, 1, 0), uv: vector_float2(1, 1)),
    Vertex(position: vector_float3(-1, 1, 0), uv: vector_float2(0, 1)),
    Vertex(position: vector_float3(-1,-1, 0), uv: vector_float2(0, 0))
]

2. 在顶点着色器中传递UV坐标

更新你的顶点着色器输出结构体(RasterizerData),添加UV字段,并在顶点着色器中把顶点的UV值传递给输出:

struct RasterizerData {
    float4 position [[position]];
    float2 uv [[user(locn)]]; // 新增UV输出字段,locn对应你的顶点缓冲区布局索引
};

vertex RasterizerData vertexShader(Vertex input [[stage_in]]) {
    RasterizerData output;
    output.position = float4(input.position, 1.0);
    output.uv = input.uv; // 传递UV坐标
    return output;
}

3. 修改片段着色器使用正确的UV坐标

移除[[point_coord]]参数,改用从RasterizerData传入的UV坐标,同时确保返回完整的float4颜色值:

fragment float4 fragmentShader(RasterizerData input [[stage_in]]) {
    float2 coord = (input.uv - float2(0.5)) * 2;
    // 返回RGB颜色(这里用红色通道展示正弦波,你可以调整其他通道)
    return float4((sin(coord.x * 10) / 2) + 0.5, 0.0, 0.0, 1.0);
}

效果说明

这样修改后,你就能得到稳定的、沿X轴方向的正弦波渐变效果——UV坐标是你手动定义的标准映射,不会随顶点顺序变化而波动,sin(coord.x*10)会在X轴方向生成均匀的正弦波形,通过/2 + 0.5把正弦值从[-1,1]映射到颜色需要的[0,1]区间。

内容的提问来源于stack exchange,提问作者Łukasz

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.07 20:38:18