着色Shading(3)(纹理映射的继续)(笔记)



前言


十一、三角形内部插值(Interpolation Across Triangles)

为什么要在三角形内部进行插值

在这里插入图片描述
我们需要插值来对三角形内部的点均匀赋值,赋值的内容可能是纹理坐标,颜色,法线向量等等。

重心坐标(Barycentric Coordinates)

在这里插入图片描述
运用重心坐标(Barycentric Coordinates)可以实现在三角形内部进行插值,重心坐标是一种用于三角形的坐标系统。三角形中任何一点(x, y)都可以表示成顶点坐标ABC的线性组合。α,β,γ都必须是非负的,且相加必须等于1(简单来说,这是为了限制点在三角形的平面内)。
在这里插入图片描述
就比如说,A点的重心坐标为(α, β, γ) = (1, 0, 0)
在这里插入图片描述
从几何视角上看,重心坐标其实就是面积比(proportional areas)。可以看到在上图中的三角形中,将某点和顶点ABC相连,可以得到三个三角形,三个三角形分别由ABC点对应,α, β, γ就分别是对应的三角形的面积除以总面积。
在这里插入图片描述
三角形重心的重心坐标如上,既然是重心,一定是能平分出三个三角形的点。
在这里插入图片描述
重心坐标的公式,懒得自己推导了。

使用重心坐标

在这里插入图片描述
算出V的重心坐标,和能够表示位置,纹理坐标,颜色,法向量,深度的顶点Va,Vb,Vc组合就可以得到V点的属性,上图表示了V的颜色。但是重心坐标有一个问题,也就是三角形在投影变换后,点的重心坐标是可能改变的。所以三维空间中的属性最好在三维空间中做插值,别投影到平面坐标以后再做。

十二、纹理反走样

纹理放大(Texture Magnification)

在这里插入图片描述
假如一个纹理太小了,将这个纹理放到一个高分辨率的物体上就会导致多个像素点分布在一个纹理元素上(texel,一个纹理元素就是纹理上的一个像素),得到很多非整数像素坐标。这会造成第一个图的效果。第二个图是使用了双线性(Bilinear)插值处理后的结果,效果还不错。第三个图是双三次(Bicubic)插值处理后的结果。可以看到效果双三次插值效果最好。

双线性插值(Bilinear Interpolation)

在这里插入图片描述
黑色点表示纹理的采样位置,现在我想知道红色点f(x, y)点的坐标。
在这里插入图片描述
我们可以拿到邻近的四个纹理采样点,
在这里插入图片描述
算出红色点距离左下角采样点u00的偏移量(t, s)。如同所示。在这里我们认为两个采样点之间的距离为1。t,s就在0到1之间。
q
Unity里面的lerp用的就是线性插值算法,返回v0到v1中间的某个值,x表示这个值在v0到v1中间的比例,x取值为0到1。
在这里插入图片描述
接下来,运用刚刚学到的线性插值,计算u1,u2,再通过u1,u2计算出f(x, y)的值。
也就是说,经过以上过程,红色点的属性值会拥有周围4个点的属性特点。
以上流程就称为双线性插值,因为做了两次插值操作。

双三次插值(Bicubic Interpolation)

相比于Bilinear,Bicubic会取周围16个纹理元素做插值,每次用4个做一个三次插值,效果自然更好。具体算法没怎么讲。

要是纹理太大了怎么办

在这里插入图片描述
纹理太大了,问题会更严重。如果按照简单纹理映射,近处会出现锯齿,远处会出现摩尔纹。
在这里插入图片描述
上图是纹理分辨率越来越高时,屏幕像素覆盖的纹理区域。可以看到,当纹理分辨率过高时,一个屏幕像素要表示多个纹理像素,这显然会出问题。
在这里插入图片描述
可以看到,超采样能够解决问题,但是性能开销巨大。

Mipmap

Mipmap能让我们实现快速的,近似的,方形的范围查询
在这里插入图片描述
简单来说,mipmap将level0的原图,以分辨率缩小一半的方式一层一层的缩小,每一层都在上一层的基础上缩小。
level0原图加上在运用mipmap之后的所有层的图像,存储大小只增加了三分之一。
在这里插入图片描述
Mip层级,在计算机视觉界,这叫做图像金字塔(Image Pyramid)。

计算Mipmap Level

在这里插入图片描述
要计算mipmap level,首先要计算一个像素对应到纹理上要处理的面积有多大。如图,将像素采样点和纹理采样点对应起来,找到这个采样点的相邻采样点,再将各个相邻采样点对应的的纹理采样点找到。单个采样点要处理的面积就可以通过相邻点的位置推算出来。
在这里插入图片描述
可以根据最大距离取一个近似的正方形区域。
接下来,根据这个正方形区域的大小(对应到第0层纹理上覆盖的纹理元素的多少)来选择使用第几层的mipmap,比如是4X4,我们可以知道第二层的mipmap使用4X4个像素平均成一个像素,那么使用第二层的mipmap就正好可以一个纹理元素对应一个像素。
在这里插入图片描述
上图展示了场景中的Mipmap Level可视化以后的效果。可以看出,离得远的地方的贴图要对应的像素很少,就要使用高层的mipmap。相反,离得近的就使用底层的。
注意,可以看到渐变效果不连续,原因是因为mipmap level本身就是离散的(没有0.5层这样的层数)。
在这里插入图片描述
当遇到类似1.8层这样的情况时,我们会选择插值处理。先找到第一层,再找到第二层,接下来找到这个点在1,2层的双线性插值。再将得到的两个插值再进行插值。这叫做三线性插值。这样一来,任何区域的值都可以得到了。
在这里插入图片描述
上图是当运用三线性插值之后得到的连续的层效果。

Mipmap的局限性

在这里插入图片描述
上图中远处的部分完全糊掉了,我们管这种情况叫Overblur。出现这种情况,一是因为我们本身就采用了近似正方形。二是因为使用了三线性插值。得到的结果肯定不精确。

各向异性过滤(Anisotropic Filtering)

在这里插入图片描述
各项异性的意思是在各个方向上的表现不相同。通过各向异性可以考虑不同的方向性。
将图按两个方向压扁(也就是Ripmap?),压扁后的图的某个正方形区域就可以对应到原图的长方形(或者应该是各种拉扯过的反正已经不是正方形的)区域。
在这里插入图片描述
为什么要这样做,因为很多时候,屏幕空间里的正方形区域对应的可不一定是正方形区域,而是各种奇奇怪怪的长条形状。使用刚刚的各向异性过滤以后就可以很好的得到这些长条形状的快速范围查询。得到的结果就能比单mipmap好得多。
各向异性过滤也不能完全解决问题,因为我们用正方形也只能对应到长条形的矩形,对于斜着的区域(看看图中最大的那个),拿矩形去框也不能很好的对应。
总结,各向异性过滤对于矩形能得到更准确的结果,但是任然不能很好的处理斜着的形状。
在这里插入图片描述
最后,为了得到最好的质量,人们只能使用将形状拆成很多的圆形来多次查找(也就是上图的办法,具体不懂了),最后还是只能用性能换取质量(大概3倍计算量,而各向异性过滤带来的只是三分之一)。

十三、应用纹理

到底什么是纹理

在这里插入图片描述
在现代GPU中,纹理 = 内存中的数据 + 范围查询(滤波)。从这个角度出发。纹理可以表示的东西就很多了。

简单的纹理映射:漫反射颜色(Diffuse Color)

在这里插入图片描述
对于每个光栅屏幕采样点(x, y),将纹理在(x, y)的坐标(u, v)通过重心坐标计算出来,将纹理在(u, v)点的颜色提取出来,赋值到屏幕采样点。这个颜色通常就是漫反射的Kd。

环境光映射(Environment Map)

在这里插入图片描述
环境光映射,也叫环境贴图。可以理解成将物体环境中会出现的反射光做成一张贴图,贴到物体上。我们认为环境光源没有深度信息,处在无限远。
在这里插入图片描述
环境光映射可以用来渲染真实的光照。

球面映射(Spherical Map)

在这里插入图片描述
我们可以将环境光记录在一个球上,再将球的表面展开。
在这里插入图片描述
当然展开之后图片的底部和顶部出现了扭曲现象。

立方体映射(Cube Map)

在这里插入图片描述
拿一个包围盒,将球包住,接下来就可以将球的表面信息记录到立方体的表面上。
在这里插入图片描述
这样得到的扭曲就少多了。

凹凸贴图/法线贴图(Bump Mapping/Normal Mapping)

在这里插入图片描述
用纹理来定义某一个点在物体上的相对高度(相对自定义的基础高度,当然这只是假的高度),不同的高度会引起物体的表面法线发生改变,然后在着色时运用这个纹理的信息,在物体表面的着色就会产生明暗对比,就可以得到凹凸的视觉效果,这样就可以在不改变几何形体的情况下用纹理来表现物体表面的凹凸状况。
简单来说,在一个球上通过纹理整一些假的高度/法线,来在一个正常光滑的几何球上实现视觉上的凹凸不平的效果。
凹凸贴图,法线贴图,干的都是一件事,但是凹凸贴图上记录的是高度,而法线贴图直接记录凹凸贴图计算后的法线。
在这里插入图片描述
上图说明了凹凸贴图的具体效果,凹凸贴图通过运用记录在上的(假的)高度信息,在没有添加三角形的情况下增加了表面的细节。

凹凸贴图的法线计算(在平面上)

在这里插入图片描述
假设现在有一个平面,他不考虑凹凸贴图的情况下的法线在p点竖直向上np(0, 1)。
在这里插入图片描述
接下来,算出在考虑凹凸贴图时的p点的切线,用导数思想,移动一个像素高度变化了多少来得到。
在这里插入图片描述
通过切线相邻得到法向向量。

凹凸贴图的法线计算(在三维空间)

在这里插入图片描述
假设现在有一个三维空间物体,他不考虑凹凸贴图的情况下的法线在p点竖直向上np(0, 0, 1)。
在这里插入图片描述
接下来,参考贴图u, v两个方向的变化,通过导数得到p的切线方向向量。
在这里插入图片描述
最后根据切线方向得到法线方向。
在这里插入图片描述
注意,我们认为以上计算发生在局部坐标系,所以原法线向量才始终是(0, 0, 1)。接下来还得将法向向量变换到世界坐标系。

置换贴图(Displacement Mapping)

在这里插入图片描述
置换贴图或者叫位移贴图,置换贴图是实现凹凸贴图效果更高级的办法。置换贴图使用和凹凸贴图一样的纹理,但是置换贴图真的会通过纹理信息移动三角形顶点的位置。
置换贴图当然能实现比法线贴图更真实的效果,但是置换贴图要求模型的三角形面数足够多,多到顶点之间的间隔要比纹理定义的频率更高。DX在遇到置换贴图时会根据需要将模型中的三角形拆分成更多小三角形。

3D Procedural Noise + Solid Modeling

在这里插入图片描述
这种纹理用来定义三维空间中的噪声函数,这些噪声可以经过数学上的处理来变成需要的样子。
第二张图中的花瓶就是通过三维空间噪声来定义的。

纹理还可以用于记录一些先前已经算好的信息

在这里插入图片描述
上图展示了将环境光遮蔽算法生成的贴图运用到模型上的效果,可以看到相对于简单的着色方法,用了这个预先算好的贴图以后光影效果显得更真实了,由于只是贴了张图,也比每帧都实时计算来的快得多。
说句题外话,坦克世界和战争雷霆里面战车不同部位的装甲值信息应该就是通过贴图来记录的。

三维纹理和体积渲染(3D Textures and Volume Rendering)

在这里插入图片描述
三维纹理记录三维空间中的信息,可以再使用这个三维空间中的信息来进行体积渲染,比如医院里的核磁共振图啥的。

课程的最后

游戏画质选项中,各向异性通常要你选择多少X(4X,8X),多少X就是Ripmap计算多少层。各项异性过滤开多少X和显卡算力基本没有关系,只要显存足够就行。

猜你喜欢

转载自blog.csdn.net/qq_37856544/article/details/113349066
今日推荐