法向量方向的“自由意志“:为什么“约定“重于“绝对“

法向量方向的“自由意志“:为什么“约定“重于“绝对“
引子一个看似荒谬的问题有一天一位学习图形学的新手向我提出了一个特别有意思的问题“视锥体的6个平面的法向量都指向内部——这不是一个确定的、必然的事实吗为什么你说这是一个’约定’为什么可以’自己选择’”我愣了一下。这个问题看似天真——但它直击一个极其深刻的本质。表面上视锥体的形状是确定的边界是确定的一切好像都是客观存在的。但真的是这样吗让我先反问一个问题一堵墙它的法向量到底指向哪里朝内朝外你会发现——这个问题没有客观答案。墙就是墙它没有天然朝向。朝向是我们赋予它的。今天我们就来彻底搞懂为什么法向量指向内部是一个约定而不是绝对真理这个看似哲学的问题背后藏着什么样的工程智慧一、几何客体 vs 数学描述让我们从最根本的地方开始——几何客体和它的数学描述是两件事。几何客体客观存在视锥体作为一个几何形状它是客观存在的它有确定的形状梯形柱它有确定的位置相机能看到的空间它有确定的边界6个平面这些是事实——不管你怎么描述它视锥体就在那里。就像一块砖头就是一块砖头——不管你叫它brick还是砖它的形状和位置都不会变。数学描述人为选择但当我们用数学去描述这个几何客体时——描述的方式是我们选择的。同一块砖头可以有很多种描述方式用长×宽×高描述用8个顶点的坐标描述用6个面的方程描述用体积和重心描述这些描述都能唯一确定这块砖头——但描述本身是人造的。同样地视锥体作为几何客体是客观的——但用什么数学方式描述它是人为的。“法向量的方向”就在这个人为选择的层面。二、平面的双向性一个哲学问题让我们聚焦到平面这个概念。问题一个平面有几个法向量方向答案两个。想象一块玻璃↑ 方向A │ │ │ ══════════╪══════════ 玻璃 │ │ │ ↓ 方向B这块玻璃有两个法向方向——A和B。它们相反但都垂直于玻璃。问题哪一个是法向量答案都是——或者说任选一个作为法向量都可以。这就是问题的核心一个平面本身没有内在的法向量方向。“哪个方向是法向量”是一个人为的选择。这不是随便说的——这是数学上的严格事实。平面方程AxByCzD0Ax By Cz D 0AxByCzD0和−Ax−By−Cz−D0-Ax - By - Cz - D 0−Ax−By−Cz−D0描述的是同一个平面。但它们的法向量(A,B,C)(A, B, C)(A,B,C)和(−A,−B,−C)(-A, -B, -C)(−A,−B,−C)——方向完全相反。同一个平面两种描述两种法向量方向——两种都是正确的。三、约定从何而来既然平面本身没有天然法向量方向那我们为什么要约定一个因为——不约定就没法做判断。回忆一下我们上一篇讲的用ddd值判断点在平面的哪一面dAxByCzDd Ax By Cz DdAxByCzDd0d 0d0正面法向量指向的一侧d0d 0d0背面“正面和背面这两个词——它们的含义完全取决于法向量指向哪里”。如果法向量指向A方向——A方向就是正面如果法向量指向B方向——B方向就是正面“正面不是绝对的是相对的——相对于我们选择的法向量方向”。所以约定不是可有可无的——它是判断能进行的前提。没有约定你无法说点在平面的哪一面——因为哪一面本身没有意义。四、视锥体的约定两种可能回到视锥体的6个平面——理论上每个平面的法向量都有两个可选方向。这意味着——理论上视锥体的法向量约定有26642^6 642664种可能但实际上我们只会考虑两种自洽的约定约定A全部指向内部↓ ═══════════ ║ ║ → ║ ║ ← ║ ║ ═══════════ ↑ [相机]6个法向量全部指向视锥体内部。判断点在视锥体内的逻辑点在所有6个平面的正面d0d 0d0约定B全部指向外部↑ ═══════════ ║ ║ ← ║ ║ → ║ ║ ═══════════ ↓ [相机]6个法向量全部指向视锥体外部。判断点在视锥体内的逻辑点在所有6个平面的背面d0d 0d0两种约定都能用关键的洞察这两种约定都能正确完成剔除。它们只是语言的选择——就像英语说 “inside”法语说 “à l’intérieur”中文说里面——描述的是同一件事。Unity选择约定A法向量朝内d0d 0d0表示在内。Unreal选择的具体约定可能不同但本质上都是从两种可能中选一种。这就是为什么我说这是约定——因为它是从多种自洽方案中选择了一种作为标准。五、为什么Unity选法向量朝内既然两种约定都能用为什么大多数引擎选择法向量朝内这背后有三个选择的理由——都是工程和直觉上的理由1与d0d 0d0 在内对齐人类的直觉“正的” “好的” “在里面”。“在视锥体内 d0d 0d0”比“在视锥体内 d0d 0d0”更符合直觉。如果剔除失败在外我们更愿意说ddd是负的——“负的 不好的 被拒绝”。这是一种心理上的和谐。理由2与其他凸体判断保持一致Unity不止有视锥体——还有AABB、OBB、Sphere等凸体。对于所有这些凸体Unity都采用法向量朝内的约定——这样所有的点在内判断逻辑完全一致。统一的约定减少了程序员的认知负担。理由3与包含关系的语义一致“法向量朝内”天然地表达了面向物体内部的语义。“在视锥体内”就是在所有面的’内侧’——语言上非常自然。这种语义一致性让代码读起来像自然语言if(IsInsideAllPlanes(point,frustum))// ...读者一看就懂——因为约定和语义完美吻合。六、举反例如果Unity选法向量朝外为了更深刻地理解约定的价值我们来想象一下如果Unity选了另一种约定假设Unity选择法向量朝外// 假设的Unity API法向量朝外boolIsPointInFrustum(Point p,Frustum f){for(inti0;i6;i){floatdf.planes[i].DistanceTo(p);if(d0)returnfalse;// 在法向量方向 在外}returntrue;}这段代码✅完全正确❌反直觉“d0d 0d0表示在外”这不奇怪吗如果Unity选了这个约定——每一个新手都会疑惑“为什么正的是外负的是内”这就是约定选择的价值——好的约定降低认知负担。七、约定的哲学工程学的自由意志从更高的层面看“法向量方向的约定”反映了工程学的一个深刻哲学在数学上等价的方案中选择最符合人类直觉、最便于工程实现的那一个。类似的约定无处不在图形学里充满了这样的约定约定1坐标系的手性Unity 用左手坐标系OpenGL 用右手坐标系数学上都能工作——只是约定不同约定2矩阵的存储OpenGL 用列主序DirectX 用行主序本质是同一个矩阵——只是约定不同约定3三角形的正面顺时针Clockwise绕序 正面逆时针Counter-Clockwise绕序 正面不同引擎有不同约定约定4深度值的方向近处 0远处 1近处 1远处 0“反向深度”不同API、不同优化目的采用不同约定约定5纹理坐标的Y轴OpenGLY轴向上DirectXY轴向下同一张图坐标约定相反这些约定都不是客观真理——都是人为选择。但一旦选定整个引擎都要围绕它设计。约定的锚定效应约定一旦确立就产生锚定效应——所有相关的代码、API、文档都要围绕这个约定展开。比如Unity 选了法向量朝内 →所有API返回的Frustum平面都是法向量朝内的Unity 选了左手坐标系 →所有旋转、变换的方向都要匹配左手规则约定不能随便改——因为改一个约定会撬动整个引擎。这就是“约定的力量”——它看似自由实则约束一切。八、几何客体不变数学描述随人让我们最后总结一下这个深刻的哲学┌─────────────────────────────────────┐ │ │ │ 几何客体视锥体 │ │ ↑ │ │ │ 是客观的、唯一的 │ │ │ │ ├────────┼────────────────────────────┤ │ │ │ │ │ 是人为的、有选择的 │ │ ↓ │ │ 数学描述平面方程 法向量方向 │ │ ↑ │ │ │ │ │ │ 影响 │ │ ↓ │ │ 判断逻辑d 0 or d 0 │ │ │ └─────────────────────────────────────┘视锥体本身客观、唯一。用什么方程描述人为选择。法向量朝哪里人为约定。正面和背面的定义由约定决定。判断代码的写法跟随约定。这就是约定的层次——它介于客体和代码之间起着桥梁的作用。九、一个绝妙的比喻地图上的北为了让这个抽象的哲学更具体让我用一个比喻——地图上的北。地球是一个球——它是客观存在的。它有一个自转轴——两端就是北极和南极。但——“哪个极点叫’北极’”这是人类的约定在地球的物理层面——两个极点是完全对称的——没有一个天然的北和南。是我们人类选择让北指向某一个特定方向让地图上上方是北让指南针的红针指向北这些都是约定——但一旦约定确立全世界的地图、导航、天文都围绕它建立。如果外星人来到地球——他们可能会把我们的北叫南。这不是错误——只是约定不同。视锥体的法向量方向也是一样的几何客体视锥体是客观的——就像地球是客观的。法向量朝哪里是人为的——就像北在哪里是人为的。一旦约定确立整个引擎都要围绕它建立——就像地图和导航系统一样。十、回答最初的疑问回到本文开头的问题“视锥体的6个平面的法向量都指向内部——这不是一个确定的、必然的事实吗”答案是确定和必然的层次要分清“视锥体的形状是确定的”→对几何客体的性质“法向量指向内部”→不是确定的这是数学描述的选择“Unity选择了’法向量朝内’的约定”→这是确定的Unity的具体选择“约定一旦确立判断逻辑就随之确定”→对约定的锚定效应所以“法向量指向内部不是几何真理”而是Unity的工程选择——它是从多种可能中选择了一种最符合直觉、最便于实现的方案。这就是约定和事实的边界。结语约定的智慧从平面的两面性到数学描述的自由度到法向量方向的选择到约定的锚定效应——我们看到看似绝对的技术细节背后往往藏着约定的自由意志。约定不是真理——它是工程学的智慧它承认数学的多样性它选择最便于人类使用的那一种它通过统一带来简洁它通过锚定带来稳定Unity选择了法向量朝内——这是它的自由。Unreal可能有别的选择——这也是它的自由。两者都能做出精彩的画面——只是约定不同。下次当你在图形学里看到某个看似必然的技术细节请多问一句“这真的是必然的吗还是它只是一个’约定’”很多时候你会发现——它其实是约定。而理解约定就是理解图形学乃至整个工程学的重要一步。因为工程学的美不在于唯一的真理——而在于多种可能中选出最好的那一个并让所有人围绕它协作。这就是约定的智慧。 ✨