☰
学习:顶点着色器输出后,三角形为什么是四个分量
2026/9/30 9:35:07 网站建设 项目流程

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

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询