8、计算机图形学——纹理的相关问题及解决办法

一、纹理映射的相关问题

1.1、小纹理大像素

大纹理小像素简单说就是纹理很小,但是被平铺在了一块像素超过纹理贴图大小的区域上,这样就会导致一个纹理像素要对应多个屏幕像素,导致纹理失真走样

如下图所示

造成这种情况的原因就是因为采用了最近邻纹理采样的方式,最近邻纹理采样的原理如下

其中,图中的十字表示纹理坐标(纹理坐标是0-1的小数,所以可以取非整数),因为左上角的纹理像素的中心点与纹理坐标的位置最接近,所以,直接将该纹理像素返回,所以最终结果就是一个深蓝色。而再对其他纹理坐标进行采样时,得到的纹理像素也是一个没有过渡的纯色。正式因为没有过渡色,所以这些有差异的纯色组合在一起时,整体的贴图区域就会产生颗粒感。

解决办法:双线性插值

使用双线性插值的结果返回的纹理像素的结果如下

双线性插值的示意图如下:

首先选中离纹理坐标最近的四个纹理像素,然后,做两次横向插值,得到u0和u1,插值公式如下

得到了u0和u1之后,再做一次纵向插值,最终得到红点的像素,插值公式如下

最终得到纹理坐标对应的颜色就是一个周围四个像素混合的结果,能起到一个过渡的作用,所以,经过双线性插值知乎的纹理的颗粒感就没有了,因为插值出了很多的过渡色

双线性插值和最近邻采样的对比效果如下

双向性插值纹理采样因为引入了过渡色,没有了颗粒感,但是因为贴到了较大的区域,会使得整体的贴图区域变得模糊。

1.2、大纹理小像素

纹理过小并使用最近邻纹理过滤的话,会使得纹理渲染结果变得有颗粒感。但是如果纹理过大的话,也会有问题,如下图所示

上图中,近处纹理产生了锯齿,而远处纹理产生了摩尔纹。

原因可以用下图表示

产生锯齿的原因:纹理过大,但是每个像素的实际大小并不能覆盖到所有的近处纹理,从而导致采样率较低,于是形成锯齿效果。

产生摩尔纹的原因:由于透视投影会产生近大远小的效果,远处纹理会包含更多的纹理细节,但是,这些丰富的细节却只能用一个像素来呈现(最右边蓝色点),采样率更低,显然会使得远处纹理细节会撕裂的更厉害,所以就会产生摩尔纹。

既然是因为采样频率不够,那么最直观的解决办法就是超采样,提高采样频率,超采样虽然能解决锯齿和摩尔纹问题,但计算成本是太高

那么既然一个采样点不能代表纹理细节,那么就可以将纹理区域内的所有像素进行求和求平均来代替当前像素的纹理。但是,远处和近处的纹理区域不一致,该如何求平均呢?

就像下面这幅图,近处白圈和远处白圈在图片中的像素面积都已差不多的,但是明显远处白圈包含更多的纹理。

为了解决快速查询纹理平均像素值的问题,mipmap算法出现了

mipmap算法过程如下图所示:

level 0代表原始texture,随着level提高,每升一级将4个相邻像素点求均值合为一个像素,默认最高级的level是一个像素,也就是原始所有像素求平均值。

因此,level越大,也就表示了越大纹理区域的平均值,那么,接下来要做的就是根据屏幕像素所代表的纹理区域大小来选选择不同level来计算纹理区域的平均值。

那么,接下来的问题就是如何将屏幕像素区域所代表的纹理区域与level进行一一对应或者说如何计算一个屏幕像素所覆盖的纹理区域?

方法如上图所示,首先,找到像素点及其上方与右方的两个像素点,将其映射到纹理坐标上,然后计算两个纹理坐标的距离,将该距离作为覆盖纹理区域的边长。因为从屏幕坐标映射到纹理坐标,所以,在屏幕坐标上相邻的两个点会发生偏移,所以需要计算当屏幕坐标变化一个单位时,纹理坐标u和v变化了多少,所以就要分别计算uv在x和y方向上的偏导,为了简化计算,直接取两个方向偏导的最大值来作文纹理区域的边长。

比如最后计算出的L的值是4,那么也就意味着屏幕坐标相差1时,纹理坐标相差4。也就是说,需要将一个4*4的纹理坐标求和求平均化成1个像素,而这个像素就需要去level 2中去查询,因为level2中就表示每16个像素融合成一个像素。因此,最终的层级就可以表示为L以2为底的对数,也就是上图中坐标的公式

找到了层级D之后,就可以在相应的纹理上进行纹理坐标的查找

然而这里还有一个问题,因为最终算出的层数有可能是小数,而mipmap只准备了整数层级进行范围查找,如何计算小数层级的纹理像素呢?

方法1:直接近似,四舍五入

近似的效果如下

可见过渡非常不自然,如何让过渡变得自然呢?还得是线性插值。

方法2:三线性插值

比如计算出来的D=1.8,那么就需先分别到D=1和D=2的纹理坐标,并分别进行一次双线性插值得到纹理像素的值,然后再使用这两个纹理像素的值再进行一次插值

总计需要两次双线性插值和一次线性插值,所以被叫做双线性插值

最终得到的结果如下

使用mipmap算法处理大纹理后,将纹理贴在像素区域的结果如下

可见,图片整体模糊过度,尤其是远处,原因就是在计算覆盖区域的时候直接使用最大值进行近似计算,导致近似计算出来的区域比实际的区域大,从而模糊的区域变大,最终导致整体效果模糊过度

解决这个问题就需要使用各向异性滤波

二、各向异性滤波

2.1、为啥要引入各项异性滤波

如下图所示,屏幕空间的像素所对应的纹理区域并不一定是正方形,很多都是长条形,所以需要增加额外的查找空间来匹配纹理区域,所以,各向异性滤波就会多出一些长方形的纹理图片

各项异性滤波的查找空间如下图

对比mipmap,mipmap的查找空间只包含对角线所表示的纹理图片,各向异性滤波所产生的的纹理区域更多,所以结果就更加准确

各向异性滤波并不能完全解决过模糊的问题,因为将纹理区域近似为长方形有时候也是不准确的,但是效果也不错

 

参考:

GAMES101-现代计算机图形学入门-闫令琪_哔哩哔哩_bilibili

欢迎大家评论交流,作者水平有限,如有错误,欢迎指出

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值