GAMES101-09- Shading3(Texture Mapping cont.)
Shading3(Texture Mapping cont.)
Barycentric coordinates重心坐标
重心坐标解决的是在三角形中进行插值。
为什么要在三角形内部进行插值呢?
答:因为我们很多操作是在三角形三顶点处理的,然后希望三角形内部能是个平滑的过渡,所以需要进行插值。
可以插值什么呢?
答:纹理的过渡,颜色的过渡等。
定义
三角形所在平面任意点都能用三个顶点,,的任意坐标线性表示,只需要满足线性坐标系数之和为1,这样就得到任意点在重心坐标下的线性表示。
而当三角形的点在三角形内部,则线性表示的系数还应该满足非负数的条件,即。
那么在重心坐标下,点可以表示为:
而任意点的坐标可以用面积比表示如下:
在给出三角形顶点坐标的情况下,则表达式可写为:
特别的,我们可以知道三角形的重心在重心坐标系下是特殊表示,可以表示为:
怎么做插值?
插值的实现,简单理解就是将三角形内要插值的点对应的属性用三顶点对应属性,,的值线性表示出来。属性可以是纹理,颜色,深度等等。
这样一理解,重心坐标实现插值是比较容易的,但是有一个问题,就是在投影的情况下重心坐标有可能会改变,也就是说不能在投影后的重心坐标里做插值,而是应该在三维空间中做插值
Texture queries
Applying Texture
Texture Magnification纹理放大
首先理解什么是像素覆盖纹理的情况。
如下图中,近处一个像素所覆盖的纹理就比较小,远处一个像素所覆盖的纹理就比较大。
一个像素覆盖纹理小的情况
假如一个纹理太小了,将这个纹理放到一个高分辨率的物体上就会导致多个像素点分布在一个纹理元素上(texel,一个纹理元素就是纹理上的一个像素),得到很多非整数像素坐标。这会造成第一个图的效果。
第二个图是使用了双线性(Bilinear)插值处理后的结果,效果还不错。
第三个图是双三次(Bicubic)插值处理后的结果。可以看到效果双三次插值效果最好。
Bilinear interpolation双线性插值
黑色点表示纹理的采样位置,现在我想知道纹理红色点处点的坐标。那么我们可以先找到邻近的四个纹理采样点。算出红色点距离左下角采样点的偏移量。如同所示。在这里我们认为两个采样点之间的距离为1。(,就在0到1之间)
下一步进行线性插值,返回到中间的某个值,表示这个值在到中间的比例,取值为0到1。(Unity里面的lerp用的就是线性插值算法)
根据线性插值的思路,我们可以先在水平 方向上得到两个插值的点和,然后在垂直方向上得到插值,这个过程可以称为双线性插值。
Bicubic interpolation双三次插值
相比于Bilinear,Bicubic会取周围16个纹理元素做插值,每次用4个做一个三次插值,效果自然更好。但没有再细讲。
一个像素覆盖纹理大的情况
但在下图中的例子里,如果采用上述同样的操作,就会得到下图右侧的结果,显然是有问题的,近处会出现锯齿,远处会出现摩尔纹。
为什么会这样呢?
答:从下图可以看出,当纹理分辨率越来越高时,屏幕像素覆盖的纹理区域大的时候。可以看到,当纹理分辨率过高时,一个屏幕像素要表示多个纹理像素,这显然会出问题。
纹理放大的处理方法
Supersampling
可以看到,超采样能够解决问题,但是性能开销巨大。
Mipmap
Mipmap能让我们实现快速的,近似的,方形的范围查询,能够迅速得到纹理元素内部的平均值。
简单来说,mipmap将level0的原图,以分辨率缩小一半的方式一层一层的缩小,每一层都在上一层的基础上缩小。
level0原图加上在运用mipmap之后的所有层的图像,存储大小只增加了三分之一。
Mip层级,在计算机视觉界,这叫做图像金字塔(Image Pyramid)。
现在我们需要用Mipmap迅速实现范围的查询,那么首先要考虑的就是要查询的区域究竟有多大。
比如我们要确定红色左下角那个像素点所占的纹理区域,我们可以先确定其上、右两个像素点在纹理上的区域,然后再做一个近似求,最后可以近似将视为所求像素点占据的纹理区域边长。
在确定像素对应纹理区域的边长后,如何确定纹理内部的平均值呢?
答:这就是Mipmap的巧妙之处。我们根据这个正方形区域的大小(边长为)来选择使用第层的mipmap,比如是,我们可以知道第二层的mipmap使用4X4个像素平均成一个像素,那么使用第二层的mipmap就正好可以一个纹理元素对应一个像素。
上图展示了场景中的Mipmap Level可视化以后的效果。可以看出,离得远的地方的贴图要对应的像素很少,就要使用高层的mipmap。相反,离得近的就使用底层的。
注意,可以看到上图渐变效果不连续,原因是因为mipmap level本身就是离散的(没有0.5层这样的层数)。
那么想要连续的效果应该怎么办呢?
答:插值。进行三线性插值。
比如遇到类似1.8层这样的情况时,我们选择插值处理。先找到第一层,再找到第二层,接下来找到这个点在1,2层的双线性插值。再将得到的两个插值再进行插值。这叫做三线性插值。这样一来,任何区域的值都可以得到了。
上图是当运用三线性插值之后得到的连续的层效果。
Mipmap局限性
上图中远处的部分完全糊掉了,我们管这种情况叫Overblur。出现这种情况,一是因为我们本身就采用了近似正方形。二是因为使用了三线性插值,也是近似的,所以得到的结果肯定不精确。
Mipmap局限性的处理方法——各向异性过滤(Anisotropic Filtering)
各向异性的意思是在各个方向上的表现不相同。通过各向异性可以考虑不同的方向性。
如上图,就是按两个方向压扁,压扁后的图的某个像素的正方形区域就可以对应到原图的(应该是经过拉扯变化的)区域,而不必限制在一个正方形区域上,范围变大自然可以得到更准确的结果。
为什么要这样做?
答:因为很多时候,屏幕空间里的正方形区域对应的可不一定是正方形区域,而是各种奇奇怪怪的长条形状。使用刚刚的各向异性过滤以后就可以很好的得到这些长条形状的快速范围查询。得到的结果就能比单mipmap好得多。
各向异性过滤也不能完全解决问题,因为我们用正方形也只能对应到长条形的矩形,对于斜着的区域(看看图中最大的那个),拿矩形去框也不能很好的对应。
总结,各向异性过滤对于矩形能得到更准确的结果,但是仍然不能很好地处理斜着的形状。这个时候,就可以考虑EWA过滤掉方法。
Mipmap局限性的处理方法——EWA Filtering
EWA过滤就是把斜着的图形拆成很多个圆形去覆盖不规则形状,每一次就查询一个圆形,然后多次查询,自然就可以覆盖这个不规则的形状,得到好的结果。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 单元测试从入门到精通
· 上周热点回顾(3.3-3.9)
· winform 绘制太阳,地球,月球 运作规律