学习:顶点着色器输出后,三角形为什么是四个分量

顶点着色器输出后,三角形为什么是四个分量 (x, y, z, w)?


一、先给结论(最重要)

顶点着色器输出的不是"屏幕坐标",

而是 裁剪空间齐次坐标(Clip Space, Homogeneous Coordinates):

复制代码
(x, y, z, w)

其中:

分量 含义
x 裁剪空间 X
y 裁剪空间 Y
z 裁剪空间 Z(深度)
w 齐次坐标的"除数"

👉 真正的屏幕坐标 = (x/w, y/w, z/w)


二、为什么不是 (x, y, z) 就够了?

1️⃣ 透视投影无法用 3D 坐标正确表达

在透视投影下:

  • 远处的物体更小
  • 平行线会交汇(透视收敛)

如果用普通 3D 坐标:

复制代码
(x, y, z)

你无法在后续步骤中做正确的透视除法


2️⃣ 齐次坐标的本质作用

w 的作用是:

把"透视除法"延迟到最后一步

这样:

  • 裁剪
  • 插值
  • 深度计算

都可以在 线性空间​ 中正确进行


三、这四个值是怎么来的?

1️⃣ 顶点着色器中你通常写的代码

复制代码
gl_Position = projection * view * model * vec4(aPos, 1.0);

最终得到的:

复制代码
gl_Position = (x, y, z, w)

2️⃣ 投影矩阵做了什么?

以透视投影为例:

复制代码
x_clip = x_eye * fov_scale / aspect
y_clip = y_eye * fov_scale
z_clip = 混合(near, far)
w_clip = -z_eye

✅ 注意:w 通常等于 -z_eye


四、为什么 z 也要保留?

1️⃣ z 不是"深度值本身"

在裁剪空间中:

复制代码
z ∈ [-w, w]

它用于:

  • 深度缓冲(Z-Buffer)
  • 裁剪判断
  • 透视正确插值

2️⃣ 屏幕深度是"非线性"的

经过透视除法后:

复制代码
depth = z/w

结果:

  • 近处精度高
  • 远处精度低

✅ 这是故意设计的(符合人眼)


五、w 到底为什么这么重要?

1️⃣ 透视除法(Perspective Division)

GPU 在光栅化前自动做:

复制代码
x_ndc = x / w
y_ndc = y / w
z_ndc = z / w

得到 NDC(标准化设备坐标):

复制代码
x ∈ [-1, 1]
y ∈ [-1, 1]
z ∈ [-1, 1]

2️⃣ 再映射到屏幕

复制代码
screen_x = (x_ndc + 1) * width  / 2
screen_y = (1 - y_ndc) * height / 2

👉 这才是你最终看到的像素位置


六、为什么插值也必须用 (x, y, z, w)?

❌ 错误做法

直接在屏幕空间插值 (x, y)

→ 近大远小会变形


✅ 正确做法(GPU 实际行为)

  1. 在 裁剪空间 插值 (x, y, z, w)

  2. 对每个像素做:

    x/w, y/w, z/w

✅ 保证:

  • 纹理不变形
  • 深度正确
  • 透视正确

七、w 还能干什么?(高级但重要)

1️⃣ 投影纹理(Projective Texture)

复制代码
uv = (x/w, y/w)

2️⃣ 阴影贴图

复制代码
light_space = x/w

3️⃣ 顶点属性插值

颜色、法线、UV 都"除以 w"


八、一句话总结

**顶点着色器输出的 (x, y, z, w)**​

不是屏幕坐标,而是"透视正确的中间表达"

  • w 是透视投影的灵魂
  • 没有 w,光栅化会全错
  • 屏幕坐标 = (x/w, y/w)

相关推荐
lengxuenong1 小时前
枚举及其优化学习手册
c++·学习·算法·青少年编程
M78佐菲2 小时前
ARM学习笔记(12)
linux·arm开发·笔记·嵌入式硬件·学习
奇思妙想聪明勤奋的小羊3 小时前
ai-agent-book第五章:Coding Agent 与通用 Agent 学习笔记
人工智能·笔记·学习
优化Henry3 小时前
BBU与RRU光链路详解:从双纤一收一发到单纤双向
网络·笔记·学习·5g·tdd
辣知4 小时前
辣知·化智68 半仙隐士渭水钓的不是鱼
学习
传奇开心果编程4 小时前
【用案例学Material 3 Expressive】第1课:从一封邮件开始,感受安卓设计新语言的表现力
android·学习·ui·kotlin·android jetpack
sunoo-2294 小时前
【嵌入式 ARM 学习第十二天】SPI 裸机驱动 + I2C 触摸屏驱动 + 三大串行协议深度对比
arm开发·笔记·vscode·学习·imx6ull
墨心@5 小时前
第 4 章《工具》学习总结
学习·自然语言处理·prompt·agent·harness
AOI小白新手上路5 小时前
4-1_地址空间_RISC与CISC_学习笔记
笔记·学习