这里回顾GAMES101 Lecture 10,这一讲完成了着色,并介绍了几何(基本表示方法)。

课程主页:

课程作业:

课程视频:

本讲内容

这一讲介绍的内容:

  • 纹理的应用;
  • 几何导论(本课程的第二部分!)
    • 几何示例;
    • 几何的各种表示;

纹理的应用

纹理有很多用途,在现代GPU中,纹理 = 内存 + 范围查询(过滤)

  • 将数据带入fragment计算的通用方法

许多应用

  • 环境照明
  • 存储微几何
  • 程序纹理
  • 实体造型
  • 体绘制

环境光照(Environment Map)

一个房间内,来自四面八方都有光,如果可以把任意一个方向的光都记录下来,这就是环境光照。纹理可以用来描述环境光照,环境光可以渲染其他物体,效果如下:

Spherical Environment Map

Spherical Environment Map是指把环境光照记录在球面上,然后像展开地球仪一样展开,最后进行贴图:

展开后的例子如下:

这里的一个问题是图片上部和下部扭曲了,即靠近极点的位置发生了扭曲,那么是否能够解决该问题,一个方法是利用Cube Map。

Cube Map

Cube Map的思路很简单,对一个球面外接一个立方体,然后把球面投影到立体方上:

效果:

这样就会缓解扭曲的问题。

纹理会影响着色

纹理不一定只代表颜色:

  • 如果存储相对高度/法线会怎样?
    • 之前替换的是系数$k_d$;
  • 这就是凹凸/法线贴图;
  • 伪造详细的几何图形;

整体原理是:

  • 相对高度发生变化导致法线发生变化;
  • 最后着色结果会发生变化;

图示:

凹凸贴图

凹凸贴图的思路是添加表面细节而不添加更多三角形:

  • 由纹理定义的每个纹素的“高度偏移”;
  • 高度偏移会扰动每个像素的表面法线(仅用于着色计算)
  • 那么问题是如何计算扰动后的法向量?

计算扰动后的法向量

  • 假设原始表面的法向量为$n(p)=(0,0,1)$
  • 在$p$的梯度为
    • ${dp} / {du}={c}_1 [{h}({u}+1)-{h}({u})]$
    • ${dp} / {dv}={c}_2 [{h}({v}+1)-{h}({v})]$
  • 扰动后的法向量为$n=(-dp/du,-dp/dv, 1).normalized()$
    • 计算思路为两个切线向量分别为$(1, 0, dp/du)$和$(1, 0, dp/dv)$;
  • 注意到这是局部坐标,最后的结果需要进行坐标变换;

图示:

说明:

  • $dp$为切线;
  • 函数坐标为$(u, v, h(u,v))$;
  • $h$为纹理函数;
  • $c_1, c_2$为预设的系数;

位移贴图

凹凸贴图由于没有移动顶点,所以在边界处会产生问题,即物体的边界依然是规则的,一个解决方法是唯一贴图,即移动顶点,其思路是:

  • 使用与凹凸贴图相同的纹理;
  • 实际上移动顶点;

效果如下:

3D噪声 + 实体建模

三维纹理的思路是定义空间中任意一个点的值,下图中利用三维中的噪声函数计算每个点的值,得到了大理石的效果:

提供预先计算的着色

之前课程并没有介绍过如何处理阴影,一个方法是预先计算好环境光遮蔽的纹理,在着色时把环境光遮蔽和着色结果相乘,得到最终结果:

3D纹理和体渲染

在核磁共振中,扫描得到的信息是3D的,可以将该信息视为纹理,然后进行渲染作图:

几何

几何的例子见课件,这部分中点介绍表示集合的方式。

很多表示几何的方式

  • 隐式
    • 代数曲面;
    • 水平集;
    • 距离函数;
  • 显式
    • 点云;
    • 多边形网格
    • 细分,
    • NURBS

最佳表示视任务而定。

隐式表示

隐式表示基于对点分类:

  • 即点满足某些特定关系就在表面上;

例如:

  • 球体:三维空间中满足$x^2+y^2+z^2 = 1$的点;
  • 更一般地,$f(x,y,z) = 0$;

隐式表达的特点为:

  • 采样很困难;
    • 很难求解$f(x,y,z) = 0$;
    • 例如$f(x, y, z)=\left(2-\sqrt{x^2+y^2}\right)^2+z^2-1$;
  • 内外测试很容易;
    • 只需判断$f(x,y,z) < 0$还是$f(x,y,z) > 0$;
    • 例如点$(3 / 4,1 / 2,1 / 4)$和$f(x, y, z)=x^2+y^2+z^2-1$位置关系;

显式表达

显式表达中,所有点都直接给出或通过参数映射给出:

图示:

隐式表达的特点为:

  • 采样很容易;
    • 直接利用参数方程$f$即可;
    • 例如$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)$

更多隐式表达

还有其他隐式表达方式,分别为:

  • 代数曲面
  • 构造立体几何
  • 水平集方法
  • 分形

代数曲面

代数曲面是关于$x,y,z$多项式的零集:

缺点是不直观。

Constructive Solid Geometry

Constructive Solid Geometry利用基本几何的基本运算定义新的几何,在下图中的基本运算为布尔运算,通过这些基本运算可以构造出各种复杂图形:

距离函数

对于任何一个几何,不描述其表面,而是描述空间中的点到该表面的最近距离(距离函数),考虑如下例子:

两个球随着距离的变化变成了不同的形状,具体方式为:

  • 对每个点计算关于球的距离函数;
  • 对两个距离函数进行融合;
  • 逆变换得到图形;
    • 计算距离函数的零点;

来看一个更复杂的例子:

$A,B$描述被物体挡住的两个时刻(图中阴影/黑色部分是指被物体挡住,白色部分是指原物体),现在的问题是求出中间时刻的状态。

方案1:直接对图片融合(线性融合),即得到$\mathrm{blend}(A,B)$,该图的区域分别为黑色,灰色和白色。

显然这不是我们要的效果,理想的效果应该是黑色区域大小变化。

方案2:

更好的方式先计算有向距离函数$SDF(A), SDF(B)$,然后计算$\mathrm{blend}(SDF(A), SDF(B))$,最后得到原始图。

再来看一个例子,也是通过距离函数得到:

最后是一个牛逼的例子:

水平集

距离函数的零点通常很难求得,一个方法是存储特定点的值:

表面是插值为零的点,等高线即应用了该方法。

医学数据中的水平集

水平集也可以定义在3维,假设有一个三维数据集,每个点对应一个密度函数$f(x,y,z)$,那么可以利用$f(x,y ,z)=c$得到物体表面,这也是CT,MRI的原理。

物理模拟中的水平集

描述水滴落下来的水花,也可以利用距离函数的水平集描述:

分形

  • 分形表现出自相似性,可以表述所有尺度的细节;
  • 描述自然现象的“语言”;
  • 但很难控制形状!

示例:

隐式表达小结

  • 优点:
    • 简洁的描述(例如,一个函数)
    • 某些查询很容易(物体内部、到表面的距离)
    • 适合光线到表面的交集(稍后会详细介绍)
    • 对于简单的形状、准确的描述/无采样误差
    • 易于处理拓扑变化(例如,流体)
  • 缺点:
    • 难以为复杂形状建模