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

顶点着色器输出后,三角形为什么是四个分量 (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)

相关推荐
旖旎夜光38 分钟前
【C++ 基础入门】C++多态(下):单/多继承虚表、多态补充与 21 道高频题
开发语言·c++·笔记·学习
叼烟扛炮6 小时前
[LangChain] 学习笔记(07):大模型长出手脚——工具(Tools)定义与调用闭环
笔记·学习·langchain
叼烟扛炮10 小时前
[LangChain] 学习笔记(06):突破大模型限制——结构化输出(Structured Output)
windows·笔记·学习·langchain
且从容.11 小时前
VUE3学习笔记(根据黑马教程总结)
笔记·学习
蒸蒸yyyyzwd13 小时前
关于 AI 开发相关的一些面经。
笔记·学习
坤坤子吖19 小时前
Linux网络编程:TCP服务器的多进程与多线程实现
linux·服务器·开发语言·网络·c++·笔记·学习
蒸蒸yyyyzwd21 小时前
后端相关学习笔记。
笔记·学习
旖旎夜光21 小时前
【C++ 基础入门】C++ 多态(上):虚函数、重写、override/final 与抽象类
开发语言·c++·笔记·学习
橙橙笔记1 天前
QT的学习第四部分
linux·qt·学习·音视频
叼烟扛炮1 天前
Linux 学习笔记(五十四):内网穿透实战——用 frp 让外网访问你的私人电脑
linux·服务器·网络·笔记·学习