1. Texture Mapping
下图中,不同位置的反射模型是一样的,但是颜色不同,这是因为漫反射系数不同。同样的,一个点应该还存在着很多属性,那么应当如何定义属性。
三维图形的表面可以展开为二维平面,这一个二维平面(包含着对应的三维中三角形的属性)便是Texture。如何实行一个好的纹理映射,是一个复杂的问题(Parameterization)。
使用u与v来表示纹理,纹理范围(u,v)为\({[0,1]}^2\)。
纹理可以使用多次,令其无缝衔接是一个好的方向,即Tiled Texture
2. Interpolation Across Triangles: Barycentric Coordinates 重心坐标
利用三角形顶点属性做插值获得内部属性,比如纹理、颜色、法线。
2.1 重心坐标定义
利用重心坐标表示任意点在三角形平面内的相对位置\((\alpha,\beta,\gamma)\):
相应的,顶点的重心坐标是1,如下:
对于任意一点的重心坐标,可以通过面积比来定义:
可知,重心的重心坐标就是\((1/3,1/3,1/3)\)。
此外,一般表达式为
2.2 插值
使用重心坐标做属性插值:
但是,重心坐标在投影后不能保证不变化。因此,对于三维空间的属性,应当使用三维空间中的重心坐标做插值,再投影。比如,三角形内部的点的深度应当在三维空间中做插值。
3. Applying Texture
对纹理的映射坐标已经定义到三角形顶点上,对于其他点,利用重心坐标找到纹理中的位置(u,v),映射到纹理中查询属性,然后将该属性应用到点(像素或者亚像素)上,比如phong shading的漫反射系数。
4. Texture Magnification
4.1 小纹理
- 如果纹理较小,而分辨率较高,那么一个像素会映射到纹理中的一个非整数位置,那么一个纹理元素 Texel会被映射到很多像素上,效果如图一,不连续。
- 当一个像素映射到纹理中的非整数位置时,可以使用周围的四个texel做双线性插值 Bilinear interpolation,获得像素属性的平滑过渡。
- 然而,双线性插值并不是一种高质量的方法,比如Bicubic,使用周围16个值计算。虽然计算量大,但是效果更好。
4.2 大纹理
- Point Query
如果纹理较大,会造成走样,如下图远处为摩尔纹,近处为锯齿。
这是一个像素对于近处覆盖区域很小,对于远处覆盖位置很大,那么一个像素为了能够代表很大的一个区域,就不能简单的映射到远处位置纹理的一个点上了。这是因为一个像素内部代表的区域很大,意味着像素内部的高频成分很高,那么就会造成采样问题,即aliasing。
- Range Query
类似于antialiasing中的模糊方法,如果不去做一个点的采样,而是获取该像素对应区域的属性均值,那么就会抗走样,即范围查询。
使用Mipmap可进行范围查询,速度快,但是是近似值,且只适合方形。如下可知,不断倍化方块对应的空间尺寸,极限是\(1\times1\)。则复杂度为O(logn)。此外,因为图的尺寸越来越小,则占用空间不断变成1/4,相应的最后所有图(包含原图)的空间只是\(\frac{4}{3}\)倍。
Mipmap的level D求取方法是:取该像素与2个邻居的中心在纹理中的映射位置,利用这两个纹理中的距离的最大值作为该像素在纹理中的方块的映射范围,相应的取对log得到level D,即在第D层中会变成一个像素大小,那么查询纹理的第D层就可以直接找到像素对应的值。
然而,将层D设置为整数又是一个采样,为了避免走样,在层之间再做一次双线性插值,则为三线性插值。
来源
[1]Games101. 闫令琪