GAMES101: Geometry

本文系统解析几何表示与处理技术,涵盖隐式/显式几何、构造实体几何及距离函数等基础概念,深入探讨贝塞尔曲线算法、曲面建模及网格操作(细分、简化、正则化),并结合阴影映射原理分析硬阴影与软阴影生成。内容贯穿几何建模核心方法,适用于计算机图形学、3D渲染及游戏开发领域,助力理解几何数据处理与高效渲染技术。(Generated by DeepSeek r1)

几何

什么是几何

对于一些物体,无论放大多少倍都能保持光滑曲线,而不是变为三角形的集合。

包括布料的效果计算、模拟的水滴运动、一些物体的轮廓等,都涉及几何描述。

几何表示方式

几何的表示方式有以下几种。

隐式几何

不使用直接的数值表示,而是通过约束关系(隐函数)表示点集。

例如 $f(x, y, z) = x^2 + y^2 + z^2 - 1$ 表示一个单位球,$f(x, y, z) = (2 - \sqrt{x^2 + y^2})^2 + z^2 - 1$ 表示一个圆环。

缺点在于不够直观,在观察到实际图像前很难判定物体的形状。

image-20250217192323960

显式几何

有两种方式显式地表示几何

  1. 向我们所学的一样,直接用三角形的集合表示
  2. 参数映射的方式表示:定义 $f: \R^2 \rightarrow \R^3; (u, v) \rightarrow (x, y, z)$

例如,$f(u, v) = ((2 + \cos u) \cos v, (2 + \cos u) \sin v, \sin u)$ 仍然表示一个圆环,$f(u, v) = (\cos u \sin v, \sin u \sin v, \cos v)$ 表示一个单位球。

构造实体几何

构造实体几何 Constructive Solid Geometry 是指通过基本几何的布尔运算生成新的几何。

image-20250217192555306

距离函数

不直接描述物体的表面,而描述空间任何一点到物体表面的最短距离(可以为),这样的函数称为距离函数。而通过所有点的距离函数可以刻画出物体的轮廓。

举例:给定 A B 两张图,A 图左侧 $\frac{1}{3}$ 黑,B 图左侧 $\frac{2}{3}$ 黑,希望生成中间图(左侧 $\frac{1}{2}$ 黑)。

这时如果简单地应用插值,那么会出现黑-灰-白的三色图像,和我们希望的结果不同。

这时候先求出对 A 图的距离函数(黑线表示距离为 $0$,就是轮廓),再求出对 B 图的距离函数,两黑线的中点就是新图像的轮廓处。利用取中点后的新图像生成图,就能得到正确的结果。

image-20250217232530508

水平集

在难以用函数表示图形的时候,我们可以存储一个二维矩阵。利用双线性插值就可以计算出函数值为 $0$ 的位置。

在等高线绘制中有经典应用。

image-20250217232856315

显式几何的表示方法

点云

用一系列点 $(x, y, z)$ 来表示物体,理论上可以表示任何物体。

扫描成像时往往就会得到点云,缺点在于数据量非常大(单个像素远多于 1 个点)

常常将点云转化为多边形面(polygon mesh)

多边形面

最广泛应用的表示方法,将物体表面分割为多边形(通常为三角形、四边形)

在处理、模拟过程中更加简单

Wavefront Object File Format

用来表示物体的文件格式,后缀名.obj,本质是文本文件。

内部文本描述了顶点、法线、纹理坐标及其连接情况

  • v xxx xxx xxx 表示一个顶点

  • vt xxx xxx 表示一个纹理坐标

  • vn xxx xxx xxx 表示一条法线

  • f x1/y1/z1 x2/y2/z2 x3/y3/z3 表示一个面,使用 x1 x2 x3 三个顶点,使用纹理坐标 y1 y2 y3,使用法线 z1 z2 z3

贝塞尔曲线 Bézier Curves

定义

用四个控制点定义一条三次贝塞尔曲线:需要曲线在起点 $p_0$ 时切线为 $\vec t_0 = 3(p_1 - p_0)$,在终点 $p_3$ 时切线为 $\vec t_1 = 3(p_3 - p_2)$。

de Casteljau Algorithm

给定一系列点,要生成连续的贝塞尔曲线可以使用 de Casteljau Algorithm。

考虑三个点的情况(该算法生成的曲线称为二次贝塞尔曲线 quadratic Bezier):

假设一个点沿着要生成的曲线从 $b_0$ 运动到 $b_1$,花费一个单位时间,那么时间 $t$ 会确定曲线的一个点 $b_t$。

问题转化为给定时间 $t \in [0, 1]$,求出对应的曲线上的点。

算法在 $b_0b_1$、$b_1b_2$ 上各找一个点 $b_0^1$、$b_1^1$,使得 $\overrightarrow {b_0 b_0^1} = t \overrightarrow{b_0b_1}$,$\overrightarrow{b_1b_1^1} = t \overrightarrow{b_1b_2}$。

连接 $b_0^1b_1^1$,找一个点 $b_0^2$ 使得 $\overrightarrow{b_0^1b_0^2} = t \overrightarrow{b_0^1b_1^1}$,点 $b_0^2$ 就是 $b_t$。

对于 $n > 3$ 个点的情况,对于每条边 $b{i}b{i + 1}$,找到 $b{i}^\prime$ 使得 $\overrightarrow {b{i} b{i}^{\prime}} = t \overrightarrow{b{i}b_{i + 1}}$,然后递归地对 $b_i^\prime$ 使用 de Casteljau Algorithm,最后回到三个点的情况,得到的一个点就是 $b_t$。

代数表示

由上文可知,$b_t$ 的值是 $b_1, b_2, b_3 \cdots$ 线性插值的结果,现在我们需要得到与 $t$ 相关的插值系数。

先观察三个点的情况:
$$
b_0^1 &= &(1 - t) b_0 + t b_1 \
b_1^1 &= &(1 - t) b_1 + t b_2 \
b_0^2 &= &(1 - t) b_0^1 + t b_1^1 \
&= &(1-t)^2 b_0 + 2t(1-t)b_1 + t^2 b_2
$$
发现是二项式系数,那么可以推广:
$$
bx^y = \sum{i = 0}^{y} \binom{y}{i} t^i (1-t)^{(y - i)} b_{x + i}\
b^n(t) = b0^n = \sum{i = 0}^{n} \binom{n}{i} t^i (1-t)^{(n - i)} b_{i}
$$
$B_i^n(t) = \binom{n}{i} t^i (1-t)^{(n - i)}$ 也称为伯恩斯坦多项式

性质

  • 起点 $b_0$,终点 $b_n$。
  • 三次贝塞尔曲线的特性:$\vec t_0 = 3(p_1 - p_0), \vec t_1 = 3(p_3 - p_2)$。
  • 仿射变换不变性:先做仿射变换再求曲线,和先求曲线再做仿射变换,得到的结果相同。(投影变换不行)
  • 凸包性:曲线一定在控制点围成的凸包内

逐段贝塞尔曲线 Piecewise Bézier Curves

将一长段曲线拆开,每一段由简单的贝塞尔曲线刻画(通常是三次贝塞尔曲线),各段曲线在端点处连接。

广泛应用于字体、设计(PS 的钢笔工具)等。

在两条贝塞尔曲线 ${a_i} {b_i}$ 的交界处,需要讨论连续性问题:

  • $C^0$ 连续:$a_n = b_1$,就是端点相同,两条曲线连在一起。
  • $C^1$ 连续:$a_n = b1 = \frac{1}{2}(a{n - 1} + b_1)$,满足两条曲线在端点处切线相同,实现平滑过渡。

基函数样条 B-Spline

样条:穿过给定的一组点的一条连续曲线,同时在每个点都有一定量的连续导数。

基函数样条是指用一个基函数和一组控制点生成的曲线,但需要比贝塞尔曲线更多的信息。

B 样条有空间局部性(改变一个控制点时,只有该点前后的有限个点附近的曲线发生变化),而贝塞尔曲线需要分段来做到。

本课程不涵盖 B 样条和 NURBS(非均匀有理 B 样条)的内容,也不涵盖曲线的操作(合并、分割等)。

有关内容可以在 清华大学-计算机图形学基础(国家级精品课)bilibili 中学习。

曲面

贝塞尔曲面

从曲线的概念延伸,简单的贝塞尔曲面由 4x4 点阵控制。

先沿 X 方向生成 4 个贝塞尔曲线;对于 $x = x_0$ 上的 4 个点,将它们当作控制点生成 Y 方向的贝塞尔曲线。这样做就形成了一个曲面,称为双三次贝塞尔曲面 Bicubic Bezier Surface。

网格操作

  • 表面细分 subdivision / upsampling:细化物体表面的划分,使用更多的三角形。
  • 表面简化 simplification / downsampling:用更少的三角形描述物体表面,同时尽量保持形状。
  • 表面正则化 regularization:调整三角形使得所有的三角形都更接近正三角形,减少形状对渲染结果的影响。

Loop Subdivision

表面细分其实是两步操作:1. 拆分更多的三角形 2. 调整三角形的位置,使得物体表面更光滑、更接近真实

Loop subdivision 的规则是:

  1. 对于每个三角形,取三边中点相互连接,一个三角形被划分为四个三角形;
  2. 设定原来的三角形顶点为旧点,所取的中点为新点,分别调整位置:
    • 对于新点 $v$,设它在边 $AB$ 上且共边的两个三角形为 $\triangle ABC, \triangle ABD$,那么新点的坐标为 $v = \dfrac{3}{8}(A + B) + \dfrac{1}{8}(C + D)$。
    • 对于旧点 $v$,设它的度为 $n$ 且相邻的点为 ${ pi }{i = 1} ^ n$,那么旧点的新坐标为 $v^\prime = (1 - nu)v + u \sum_{i = 1}^{n}p_i$,其中 $u = \dfrac{3}{8n}$(特例,$n = 3$ 时为 $\dfrac{3}{16}$)。
temp

temp

$1 - nu$ 的道理在于,当一个点的度很小时,它应该是形状上的关键节点,更新的时候应趋向于保持不动;

当一个点的度很大时,它在图形中更多起到平滑过渡和连接的作用,更新时应更多参考其他点的坐标。

Catmull-Clark Subdivision

对于一般(即三角形、四边形混杂)的情况,该算法可以较好地细分网格。

概念

四边形 quad face,其他的称为非四边形 non-quad face。

度不为 4 的点称为奇异点 extraordinary vertex。

操作

对每条边取中点,对每个面也取一个中点,将每个边中点连向面的中点。

image-20250309153311414

image-20250309153202661

image-20250309153710623

可以发现第一次细分之后,所有的非四边形面都消失了;取而代之的是它中心会生成的奇异点。

调整位置时,将点分为三类:

  1. 面的中心 $f = \dfrac{v_1 + v_2 + v_3 + v_4}{4}$
  2. 边的中心 $e = \dfrac{v_1 + v_2 + f_1 + f_2}{4}$
  3. 旧的顶点 $v^\prime = \dfrac{f_1 + f_2 + f_3 + f_4 + 2(e_1 + e_2 + e_3 + e_4) + 4 v}{16}$

网格简化

有时候一些物体在渲染时不需要很高的精细程度(低于存储),这时候为了降低运算负担、同时尽量不影响渲染效果,我们就需要对物体表面进行简化操作。

边坍缩:将一条边坍缩为一个点,同时将相邻的边改为连向这个点。问题在于确定新点的位置。

二次误差度量:希望将点放在一个位置,使得该点和原本几个面的距离的平方和最小(该和称为二次误差);每一条边都计算二次误差度量,贪心地选择值最小的边坍缩。

注意边坍缩之后,相邻的边的二次误差也会变化,需要更新;所以可以使用堆来维护。

阴影生成

在先前的渲染中,我们尚未考虑遮挡情况,也就是阴影的情况。

解决阴影的方法,称为阴影映射 shadow mapping;2018 年的古墓丽影:暗影是最早支持阴影的一批游戏。

最重要的思想:点不在阴影里的条件为同时能被摄像机看见能被光源看见。我们暂时只介绍点光源的情况。

先从光源处渲染,找到光源能看到的点。这一步我们不做着色,只记录深度图(也叫 shadow map)。

再从实际观察角度渲染,对于看到的每个点,投影到光源视角下的位置,查找“深度图中该位置的深度”和“点投影后的深度”是否一致,不一致说明在阴影里。

在浮点数计算中,判断相等是很困难的事情,所以在精度限制下会出现一些细节上的丢失(图中球的条形阴影);深度图的分辨率也会影响阴影的效果。

image-20250309164509334

硬阴影和软阴影

硬阴影:点要么可见要么不可见,阴影有锐利的边缘。

软阴影:阴影与不在阴影的点之间有过渡,适用于光源有一定的大小。

软阴影是实际存在的现象,物理、天文上称为半影 Penumbra。

暂无评论

发送评论 编辑评论


				
|´・ω・)ノ
ヾ(≧∇≦*)ゝ
(☆ω☆)
(╯‵□′)╯︵┴─┴
 ̄﹃ ̄
(/ω\)
∠( ᐛ 」∠)_
(๑•̀ㅁ•́ฅ)
→_→
୧(๑•̀⌄•́๑)૭
٩(ˊᗜˋ*)و
(ノ°ο°)ノ
(´இ皿இ`)
⌇●﹏●⌇
(ฅ´ω`ฅ)
(╯°A°)╯︵○○○
φ( ̄∇ ̄o)
ヾ(´・ ・`。)ノ"
( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃
(ó﹏ò。)
Σ(っ °Д °;)っ
( ,,´・ω・)ノ"(´っω・`。)
╮(╯▽╰)╭
o(*////▽////*)q
>﹏<
( ๑´•ω•) "(ㆆᴗㆆ)
😂
😀
😅
😊
🙂
🙃
😌
😍
😘
😜
😝
😏
😒
🙄
😳
😡
😔
😫
😱
😭
💩
👻
🙌
🖕
👍
👫
👬
👭
🌚
🌝
🙈
💊
😶
🙏
🍦
🍉
😣
Source: github.com/k4yt3x/flowerhd
颜文字
Emoji
小恐龙
花!
上一篇