09 Shading(Texture Mapping)
关键点
- Texture Mapping
- Barycentric Coordinates
- Bilinear interpolation/Bicubic
- Range Query - Mipmap - alisaing
- Anisotropic Filtering - Ripmap - overblur
- Environment Map
- Bump/Normal Map
- Displacement Mapping
- 3D Procedural noise
- Shading
- 3D textures and Volume Rendering
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 插值
使用重心坐标做属性插值:
但是,重心坐标在投影后不能保证不变化。因此,对于三维空间的属性,应当使用三维空间中的重心坐标做插值,再投影。比如,三角形内部的点的深度应当在三维空间中做插值。
2.3 Applying Texture
对纹理的映射坐标已经定义到三角形顶点上,对于其他点,利用重心坐标找到纹理中的位置(u,v),映射到纹理中查询属性,然后将该属性应用到点(像素或者亚像素)上,比如phong shading的漫反射系数。
3. Texture Magnification
3.1 小纹理
- 如果纹理较小,而分辨率较高,那么一个像素会映射到纹理中的一个非整数位置,那么一个纹理元素 Texel会被映射到很多像素上,效果如图一,不连续。
- 当一个像素映射到纹理中的非整数位置时,可以使用周围的四个texel做双线性插值 Bilinear interpolation,获得像素属性的平滑过渡。
- 然而,双线性插值并不是一种高质量的方法,比如Bicubic,使用周围16个值计算。虽然计算量大,但是效果更好。
3.2 大纹理
3.2.1 Aliasing
- Point Query
如果纹理较大,会造成走样,如下图远处为摩尔纹,近处为锯齿。
这是一个像素对于近处覆盖区域很小,对于远处覆盖位置很大,那么一个像素为了能够代表很大的一个区域,就不能简单的映射到远处位置纹理的一个点上了。这是因为一个像素内部代表的区域很大,意味着像素内部的高频成分很高,那么就会造成采样问题,即aliasing。
- Range Query
类似于antialiasing中的模糊方法,如果不去做一个点的采样,而是获取该像素对应区域的属性均值,那么就会抗走样,即范围查询。
3.2.2 Mipmap Trilinear Sampling
- Mipmap
使用Mipmap可进行范围查询,速度快,但是是近似值,且只适合方形。如下可知,不断倍化方块对应的空间尺寸,极限是\(1\times1\)。则复杂度为O(logn)。此外,因为图的尺寸越来越小,则占用空间不断变成1/4,相应的最后所有图(包含原图)的空间只是\(\frac{4}{3}\)倍。
取该像素与2个邻居的中心在纹理中的映射位置,利用这两个纹理中的距离的最大值作为该像素在纹理中的方块的映射范围,相应的取对log得到level D,即在第D层中会变成一个像素大小,那么查询纹理的第D层就可以直接找到像素对应的值。
然而,将层D设置为整数又是一个采样,为了避免走样,在层之间再做一次双线性插值,则为三线性插值。
3.2.3 Anisotropic Filtering 各向异性过滤
- OverBlur
使用mipmap三线性插值会造成远处模糊。
这是因为屏幕上的一个像素映射到纹理上不一定是正方形,更多的可能是长条形,此外这个长条可能是倾斜的,即各向异性。
- Ripmap
将纹理不仅是按照方形压缩,而且会沿着一个方向压缩。可见存储空间为原来的4倍,因此只要显存足够就可以使用。
4. Environment Map
- Spherical Map
假设环境光只与方向有关,但是与深度无关,那么可以将环境光记录在一个球上,并进行展开。但是将球面展开后会变形。
- Cube Map
同样用球来记录环境光,但是不再展开,而是将环境光沿径向投在立方体的六个面,就会减少扭曲。
5. Bump/Normal Map 凹凸贴图/法线贴图
使用纹理记录相对于基本平面的高度,那么就可以求出各处的假法线,利用假法线求解出光的反射强度,就会产生明暗效果。
- 假设原本法线(0,0,1)
- 对u和v两个方向变化一个单位,利用差分得到导数,得到切线方向
- 利用切线方向导数,得到法线方向,并做归一化。
- 以上是在局部坐标系中的,在局部坐标系中发现永远是(0,0,1),得到结果之后在转换到世界坐标系
6. Displacement Mapping 位移贴图
凹凸贴图在边缘没有凹凸效果,并且不能实现自我的光照映射。位移贴图可以解决问题,但是要求三角形足够小,其频率要高于纹理频率。
DirectX提供了dynamic tessellation,不需要一开始就提供很细致的模型,而是根据需要做处理。
7. Others
7.1 3D Procedural noise 三维噪声算法
- Perlin noise
7.2 Shading 阴影
- 用纹理来记录已经计算好的阴影信息。
7.3 3D textures and Volume Rendering 体渲染
来源
[1]Games101. 闫令琪
本文来自博客园,作者:ETHERovo,转载请注明原文链接:https://www.cnblogs.com/etherovo/p/17319910.html