你可以直接这样回答
两向量夹角先归一化,再用 acos(clamp(dot(a,b),-1,1));若只是阈值,直接比较 dot 更便宜。Shader 精度问题先查空间、长度、范围和非法输入,再做 clamp/重排/精度选择,并用目标设备复测。
这道题真正想听什么?
先确认比较对象和回答边界,再决定要不要展开公式、工程实现或性能取舍。
考 dot(a,b)=|a||b|cosθ 的因果,以及归一化、clamp、零向量、精度和空间。Shader 中很多“角度错了”其实是输入未归一化、矩阵空间不一致或 acos 输入略超 [-1,1];不要一上来换成更高精度。
把答案讲到 2 分钟面试必答 · 约 2 分钟 · 补足因果、输入和取舍
我会区分方向、位置和法线,确保在同一空间;对零向量和 acos 边界做保护,避免把 clamp 当根因。移动端先做误差预算,减少范围和采样,必要时 f32/f16 A/B,保留可视化与 capture。
面试官可能继续追问什么?补充自测 · 约 3 分钟 · 检查自己是不是真的懂了
- 问:只用 dot 就能得到角度吗? 答:dot 给 cosθ;如果只做阈值判断,通常不用昂贵
acos,比较 cos 值即可。 - 问:f16 一定不行吗? 答:看范围、误差预算和设备;先降低数值范围、归一化和避免灾难性相减,再决定精度。
- 因果链: 向量来源/空间 → normalize/dot → clamp/角度 → 光照/遮挡证据。
如果概念还是悬空,就去做实验关键证据 · 约 5–15 分钟 · 预测 → 单变量 → 观察
实验不是第二份答案,它只负责证明答案
如果上面的解释已经听懂,可以直接跳过。卡住时,再沿着这三步把抽象词变成画面证据。
- 先猜 先把变量画成箭头、角度或范围:它变大时,画面应该怎样变化?
- 去取证 固定其他条件,只改一个参数。先写下变化,不用“更真实”“更高级”这种空词代替证据。
- 再追问为什么 是哪一步造成这个结果?如果结果相反,先检查输入、空间、算法,还是显示输出?
我完全没头绪,给我一个起点
先截下默认状态,只动页面当前开放的那个参数。你只需要说清楚“原来怎样 → 改了什么 → 现在怎样”。
1. 先预测
在 Transform Math Lab 观察 basis;在 Screen Space Lab 切 debugMode=normal/position/depth;在 Graphics Debugger 阅读 spaces 与 precision。注意:这些页面不会直接吐出 dot、N·L 或 acos 数值;它们给的是方向箭头、法线/位置/深度通道和精度边界。输入 → 变化 → 输出: 两方向/空间 → 纸面或 DevTools 计算 normalize·dot·clamp → 角度推理,再用 Lab 的深度/空间证据检查假设。
公式的口语翻译:
cosθ = clamp(dot(normalize(a), normalize(b)), -1, 1)
θ = acos(cosθ)
先把两根箭头变成单位长度,再取投影关系;clamp 是防止浮点小误差把 acos 送进非法区间,不是修复空间错误。
老师追问
先别急着查答案: 先把每个符号翻译成方向、长度、夹角或范围:变量变大时,哪个边界会先被碰到?
为什么: 你刚才的预测依赖哪个前提?如果把“向量夹角与精度”里最关键的变量或约束关掉,画面/输出会先坏在哪里?
如果结果相反: 先排除哪一层,再谈结论?这个规则的边界是什么?
2. 再动手
3. 最后对证据
归一化后方向夹角稳定;near/far 比例过大时深度精度风险变明显。Lab 的 debug 是教学模型,不能直接代表某个 shader 的 f16/移动 GPU 行为;真实验证需使用目标设备、frame capture 和误差阈值。
答案在代码哪里发生?实现定位 · 约 3 分钟 · 变量、函数和关键行
完整 5 分钟版本面试扩展 · 约 5 分钟 · 项目边界、验证与降级
工程上会对法线长度、N·L、深度重建和关键分母做有限监控,记录设备、相机范围和输入数据。高精度只放在敏感阶段,低档通过阈值/质量 tier 降低成本。Lab 帮我练因果,不替代生产 shader 的硬件验证。
哪些说法最容易答歪?必看陷阱 · 约 1 分钟 · 面试前最后检查
- 直接对未归一化向量取
acos。 - 忽略零向量和 clamp 边界。
- 把 view/world/tangent 混为一谈。
- 只换精度,不测范围、误差和性能。