学习进度
0/9 已勾只保存在这台浏览器;勾满 9 项即视为本题完成。
先把题目说成人话
电梯向右移动时,站在里面的人会换位置,贴在墙上的“朝上”箭头却不该被向右拖歪。三维计算若只用三行数字,旋转和缩放容易写成统一乘法,额外的平移却像一项另加的搬运;投影又需要一种办法,让同一物体离相机越远时落到幕布上越小。现实要解决的是把这些动作放进一条可连续组合的矩阵链,同时保留“位置”和“方向”并非同类对象的区别。
给三维数据补上第四个比例分量的表示法叫齐次坐标(Homogeneous Coordinates),第四个分量常写作(w)。在进入投影前,有限位置通常带一,普通方向通常带零;旋转、缩放和平移组成的统一变换叫仿射变换(Affine Transform)。投影以后,第四分量会变成比例尺,不能继续把它当成简单开关。
这是虚构教学故事,不是个人项目经历。
场景:先让问题变得看得见
想象电梯把一个标记点和一支“朝上”的箭头一起搬到右边:标记点应跟着车厢换位置,箭头表达的朝向却不应因为这次平移而改变。先让两者经过完全相同的搬运动作,观察最后一列产生的位移究竟应该交给谁,再把同样思路接到相机投影。
(右脑)画面:电梯里有一个地面标记和一支朝上的箭头。车厢向右移动,标记必须跟着换位置,箭头却只说明“朝上”,不应被横向搬运变成斜箭。可以想象两者各带一张行李标签:标记允许领取车厢的平移,方向不领取。电梯随后来到一台投影机前,这张标签不再只负责分类,而会变成与前后距离有关的缩放票据。票据必须跟着位置走过裁剪闸门,最后才能按比例把位置落到标准幕布;若提前撕掉,远近关系和边界判断都会失真。
(左脑)对表:本题对象是齐次点、齐次方向、4×4 仿射矩阵、clip-space 坐标和透视除法。点受平移、方向不受平移的手算结果是事实;“所有向量都用 w=1”是假设。xyz 位置继承场景长度单位,NDC 在除法后无长度单位;仿射方向 d=(x,y,z,0) 是合法方向对象,本来就不做位置的透视除法,而由有限位置投影得到、正等待转成 NDC 的 clip 位置若 w=0 才是退化情况。点/方向的 1/0 约定不能继续当作投影后 w 的布尔解释。行李标签类比帮助区分对象类别,但不等于射影等价和透视公式的证明。
小明:先形成一个完整猜测
小明把角色的“朝上方向”也当成位置,给它领取平移的标签。乘完平移矩阵后,这支方向箭在横向凭空多出一截,角色只是换了位置,朝向却跟着改变。这个反例把第一层问题说清了:普通方向没有“所在位置”,所以不应接收平移。法线虽然也不接收平移,但它在非均匀缩放下还有额外规则,不能由这个标签例子直接推出完整变换。
小红:把猜测放回现实检查
小红保持矩阵不变,让同一组 xyz 分别以 w=1 和 w=0 进入矩阵,直接比较平移到底影响谁:
[1 0 0 10] [1] [11] [1 0 0 10] [0] [0]
[0 1 0 0] [2] = [ 2] [0 1 0 0] [1] = [1]
[0 0 1 0] [3] [ 3] [0 0 1 0] [0] [0]
[0 0 0 1] [1] [ 1] [0 0 0 1] [0] [0]
这不仅区分点与方向,也把缩放、旋转、平移统一进 4×4 矩阵,多个变换可以连续相乘。
我:用检查结果修正模型
我再补上投影这半条链。齐次坐标表示的是比例类:当 w≠0 且 λ≠0 时,(x,y,z,w) 与 (λx,λy,λz,λw) 表示同一个三维点,恢复笛卡尔坐标要除以 w。这里的“方向不收平移”只适用于普通方向的仿射分类;法线在非均匀缩放或斜切下要用线性部分的逆转置,w=0 不能替代这一步。投影矩阵故意让 clip-space w 与深度有关,然后执行
p_ndc = p_clip.xyz / p_clip.w。
这次除法发生在完整投影之后。若在顶点 Shader 中过早除掉 w,后续裁剪和透视正确性都会被破坏。w=0 不能还原为有限笛卡尔点;在标准透视投影中,它对应相机平面附近的退化位置,应交给齐次裁剪规则处理,不应随手 clamp。最终还要在 Unity 所用 API 的 clip/NDC 范围、Y 翻转和矩阵乘法约定下核对,因为概念一致,具体约定未必相同。
(右脑)画面修正:小明让方向箭领取平移后,箭头被横向拖歪,直接否定了“第四个分量统一补一”;小红让同一组空间数字分别作为位置与普通方向通过同一矩阵,清楚看到只有位置被搬走。模型先修正为“第四分量区分仿射位置与普通方向”,走到投影还要再更新:裁剪空间里的第四分量承载齐次比例,不能继续当布尔标签,也不能在裁剪前提前相除。法线则另有保持垂直关系的逆转置规则,不能从普通方向的标签故事偷换出来。
(左脑)严格对表:仿射输入将有限位置写为 p=(x,y,z,1),普通方向写为 d=(x,y,z,0),用同一 4×4 矩阵相乘,只有 p 获得最后一列的平移;d 的 w=0 合法,因为它表达方向而非待还原的有限位置。法线同样不收平移,但对非均匀缩放或斜切必须使用线性部分的 inverse-transpose,不能只把 w 设为 0。一般齐次等价为 (x,y,z,w)∼(λx,λy,λz,λw),λ≠0;对待还原的位置,w≠0 时笛卡尔坐标为 (x/w,y/w,z/w)。投影链先求 p_clip=P·V·M·p,再按管线约定裁剪,随后仅对合法的 clip 位置求 p_ndc=p_clip.xyz/p_clip.w;此处 w=0 才是退化,不能过早相除或用 clamp 掩盖。验收以点/普通方向平移、法线非均匀缩放、矩阵组合、已知透视点和 Unity 目标 API 的 NDC/Y/乘法约定为准。
老师解惑
- 点与方向:仿射约定中点用
w=1、方向用w=0,所以只有点接收平移。 - 齐次等价:
(x,y,z,w) ~ (λx,λy,λz,λw)要求λ≠0;w≠0时除以 w 得笛卡尔坐标。 - 平移矩阵:额外一维把常量平移放进矩阵最后一列,使仿射变换可以统一组合。
- 透视除法:只在投影得到裁剪坐标后进行;clip-space w 有明确的投影意义。
w=0:在射影几何中可表示无穷远方向;在普通 Shader 管线中仍必须结合当前空间理解。
工具分工
- transform-math Lab:把点、方向和平移矩阵放在同一画面里观察。
- 矩阵单元测试:用可手算输入验证 w=0/1、组合顺序与逆变换。
- Shader 调试输出:分别显示 clip-space w 与 NDC,定位过早透视除法。
- Unity Frame Debugger:确认相关 Pass 与投影资源;数学数值仍需调试输出或抓帧核对。
记忆钩子
仿射阶段,点的 w=1 会被搬家,方向的 w=0 不会;投影阶段,w 留到最后一次透视除法。
这是教学场景,不是目标项目的真实捕获或个人经历。
下一步:验证这条因果
w=1 的点会平移,w=0 的方向不会。
教学边界:它不替代完整投影矩阵与 API 约定。