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

使用相同数据修改WGSL片段着色器后渲染结果异常问题

问题:为何使用看似相同的数据却得到不同渲染结果?

我是WGSL新手,正在跟随wgpu教程编写第一个三角形渲染程序。

正确的着色器代码如下:

// Vertex shader

struct VertexOutput {
    @builtin(position) clip_position: vec4<f32>,
    @location(0) position: vec2<f32>,
};

@vertex
fn vs_main(
    @builtin(vertex_index) in_vertex_index: u32,
) -> VertexOutput {
    var out: VertexOutput;
    let x = f32(1 - i32(in_vertex_index)) * 0.5;
    let y = f32(i32(in_vertex_index & 1u) * 2 - 1) * 0.5;
    out.position = vec2<f32>(x, y);
    out.clip_position = vec4<f32>(x, y, 0.0, 1.0);
    return out;
}

// Fragment shader

@fragment
fn fs_main(in: VertexOutput) -> @location(0) vec4<f32> {
    return vec4<f32>(in.position, 0.5, 1.0);
}

正确渲染结果:
正确渲染结果

由于out.position与out.clip_position的前两个元素值相同,我尝试将片段着色器修改为:

- return vec4<f32>(in.position, 0.5, 1.0);
+ return vec4<f32>(in.clip_position.xy, 0.5, 1.0);

但修改后得到错误的渲染结果:
错误渲染结果

骨架代码基于tutorial3-pipeline示例,请问为何使用相同数据却得到不同渲染结果?


解答

核心原因是**@builtin(position)在顶点着色器输出和片段着色器输入时的语义完全不同**:

  1. 顶点着色器中的@builtin(position):这是你手动计算的裁剪空间位置,值为(x, y, 0.0, 1.0),作用是告知GPU如何对三角形进行光栅化。
  2. 片段着色器中的@builtin(position):它不再是顶点输出的原始裁剪空间值,而是当前片段在**窗口空间(屏幕像素坐标)**中的位置——比如窗口分辨率为800x600时,坐标范围大概是0800、0600,完全不是你原本定义的[-0.5, 0.5]范围。

当你在片段着色器中读取in.clip_position.xy时,拿到的是超大的像素坐标值,GPU会将超出颜色有效范围(0~1)的部分 clamp 到1,所以最终整个三角形呈现纯白色,也就是你看到的错误结果。

而自定义的@location(0) position是作为普通顶点属性传递的,GPU会对其进行线性插值,片段着色器拿到的是和顶点输出同范围的[-0.5, 0.5]的值,用它作为颜色输出时,能正确呈现渐变效果。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.13 01:23:28