纹理映射
1.纹理映射
纹理映射:用于增强渲染的真实感和细节,允许在三维模型表面上贴附二维图像,以模拟材质、颜色、光照等细节。
纹理坐标的伪代码表示:
即通过对每个光栅化的屏幕坐标算出它的纹理坐标(u,v)(利用三角形顶点重心坐标插值),再利用这个u,v坐标去查询texture上的颜色,把这个颜色信息当作漫反射系数Kd。
1.1 纹理过小的问题
问题:例如,有一张大小为100x100像素的纹理贴图,然后将这个贴图应用到一个500x500像素的屏幕上,这样多个像素点可能会映射到纹理贴图的相同区域,这使得纹理像素的信息被多个屏幕像素所共享。
如果只是简单地使用最近的纹理坐标点,即离目标点最近的(u, v)坐标,取样不足以准确反映屏幕上多个像素的信息,会导致渲染结果出现严重的走样问题。
解决方法:使用更复杂的纹理过滤技术,如双线性插值,考虑周围像素的颜色信息,从而在渲染过程中更加平滑地处理纹理映射,减少走样的影响。
注:Bicubic:双三次插值是利用三次方程来进行两次插值,但是计算开销过大
1.2 纹理过大的问题
现象:
近处出现锯齿,远处出现摩尔纹
原因:根据近大远小,远处的一张完整的贴图可能在屏幕空间中仅仅是几个像素的大小,屏幕空间的一个像素对应了纹理贴图上的一片范围的点,而用一个点采样的结果代替纹理空间一片范围的颜色信息,必然会导致严重失真
如上图,一个屏幕空间的蓝色像素点离相机越远,对应在texture空间的范围也就越大
解决方法:超采样(计算开销过大,不好)、MipMap
纹理足迹(Texture Footprint): 当纹理贴图映射到几何体表面时,每个像素在纹理空间中的足迹描述了纹理在几何体上的分布。
1.3 MipMap
level 0代表的是原始texture,也是精度最高的纹理,随着level的提升,每提升一级将4个相邻像素点求均值合为一个像素点,因此越高的level也就代表了更大的footprint的区域查询。接下来要做的就是根据屏幕像素的footprint大小选定不同level的texture,再进行点查询即可,而这其实就相当于在原始texture上进行了区域查询。
注:通过MipMap将区域查询的问题,再次转换为点查询。使用MipMap仅将纹理map的大小扩大了1/3
确定level:利用屏幕像素的相邻像素点估算footprint大小再确定level
在屏幕空间中取当前像素点的右方和上方的两个相邻像素点(4个全取也可以),分别查询得到这3个点对应在Texture space的坐标,计算出当前像素点与右方像素点和上方像素点在Texture space的距离,二者取最大值得到L,再通过L得到D。
D算出的是一个连续值而不是整数的解决办法:
(1)四舍五入取得最近的那个level D(纹理之间可能存在突变,不连续,故不好)
(2)利用D值在向下和向上取整的两个不同level进行三线性插值(即将level连续化),如下图。
三线性插值的MipMap的效果:远处出现了过曝的现象
出现该问题的原因是屏幕空间中的正方形的像素,在纹理空间中的形状可能是不规则的矩形
1.4 各向异性过滤Mipmap
各向异性的过滤:
将纹理分为水平方向上的level和竖直方向的level
2.凹凸贴图
凹凸贴图的原理: 利用凹凸贴图来改变原本光滑的平面的法线, 使原本光滑的平面产生凹凸感。
pass