第 6 讲:纹理映射、Mipmap 与凹凸效果

若把橙子表面的每个凹坑都做成真实几何,模型会非常重。纹理映射的思路是:几何只负责大形状,把颜色和部分细节存到另一张二维图里。

1. 建立表面到纹理的对应

每个网格顶点除了三维位置,还带纹理坐标 (u,v)(u,v)。光栅化时先在三角形内插值得到 (u,v)(u,v),再去纹理图中反查颜色。这个方向是从屏幕样本回到纹理,因此也叫 backward mapping;若从纹理像素向屏幕正向撒点,容易留下空洞。

参数坐标和纹理坐标经世界坐标映射到屏幕坐标

UV 参数化没有统一答案:

  • 圆柱可用环绕角和高度。
  • 球面可用经纬角,但极点和接缝会扭曲。
  • 复杂模型通常切开后铺成 atlas。

同一块纹理可以平铺复用。切缝、重叠、面积畸变和角度畸变之间往往需要权衡。

2. 重心插值与透视修正

屏幕三角形内,重心坐标给出仿射插值:

a=αa0+βa1+γa2.a=\alpha a_0+\beta a_1+\gamma a_2.

它适合已经在同一仿射空间里的值。纹理坐标却来自透视投影前的三维表面,直接插值会让棋盘纹理在远处“游动”。透视正确插值应为

a=αa0/w0+βa1/w1+γa2/w2α/w0+β/w1+γ/w2.a= \frac{ \alpha a_0/w_0+ \beta a_1/w_1+ \gamma a_2/w_2 }{ \alpha/w_0+\beta/w_1+\gamma/w_2 }.

人话解释:先把属性和齐次深度一起带过投影,再除回来。

3. 放大:附近纹素怎样混

最近邻采样取最近的一个纹素,快但会出现方块。双线性插值先在两个方向各做一次线性插值,相当于按距离混合周围四个纹素:

c(u,v)=(1−s)(1−t)c00+s(1−t)c10+(1−s)tc01+stc11.c(u,v)= (1-s)(1-t)c_{00} +s(1-t)c_{10} +(1-s)tc_{01} +stc_{11}.

它能平滑放大结果,但并不能解决严重缩小时的走样。

4. 缩小:一个像素覆盖很多纹素

远处一个屏幕像素可能覆盖纹理中的大片区域。只取一个点会漏掉区域内大部分高频信息,导致闪烁和摩尔纹。单纯提高屏幕采样数也可能代价过高。

Mipmap 预先生成尺寸逐级减半的低通图像。渲染时估计相邻屏幕样本在纹理空间的跨度,选择合适层级:

Mipmap 为同一纹理预存逐级缩小的分辨率层次

L≈log⁡2ρ,L\approx\log_2\rho,

其中 ρ\rho 是像素足迹的尺度。层内用双线性插值、相邻层之间再线性插值,就是 trilinear filtering。

Mipmap 假设足迹近似正方形。斜视平面时足迹会变成长条,选一个方形层级容易过度模糊;各向异性过滤会沿长轴取更多样本,Ripmap 和 summed-area table 也是课件提到的扩展。

5. 环境贴图

环境贴图把视线反射方向映到一张“周围世界”的纹理。球面贴图会在部分方向产生集中畸变;Cube Map 用六张正方形纹理覆盖立方体六面,给定方向后选择绝对分量最大的轴并计算面内坐标。

它能廉价模拟镜面环境反射,但默认环境离物体足够远,没有真实近场视差。

6. 纹理不只存颜色

Bump Mapping 用高度图的有限差分估计局部坡度,在切线空间扰动法线,再变换到世界空间参与光照。几何位置没有移动,因此:

  • 表面明暗会像有凹凸。
  • 物体轮廓和真实遮挡仍是原来的。

Displacement Mapping 则沿法线真正移动顶点或细分后的表面,能改变轮廓和阴影,但要求几何分辨率足够高。

纹理还可存法线、粗糙度、遮罩和任意参数。三维程序噪声可直接按空间位置生成纹理,体纹理与体渲染则把数据定义在整个三维体积中,而不只贴在表面。

7. 选择过滤方法的判断

先判断屏幕像素在纹理里覆盖多大区域:

  • 小于一个纹素:纹理被放大,用双线性可改善块状感。
  • 约等于一个纹素:普通采样即可。
  • 覆盖很多纹素:纹理被缩小,应用 Mipmap 或更强的预过滤。
  • 足迹细长:考虑各向异性过滤。

“纹理糊不糊”不是只调一个线性过滤开关,而是像素足迹与采样率共同决定的。

评论