前言
纹理贴图的时候,很重要的一步就是纹理采样
采样就是如上图中所示,根据片元的纹理坐标,到纹理图中提取对应位置颜色的过程
但被渲染的片元数量与对应纹理区域中的像素数量并不总能一一对应
例如图中红圈,一个片元可能会覆盖多个纹理像素也可能覆盖不到一个纹理像素,如何采样?,那就需要设置采样方式了,在three中就是设置纹理的magFilter
,minFilter
属性,来改变采样方法。
大佬视频的参考链接www.bilibili.com/video/BV1X7…
magFilter属性
使用场景
- 一张小纹理贴到一个大空间(例如16X16的纹理映射到32X32的像素空间),相当于纹理拉大
- 透视关系下近处的片元
上述情况下一个片元会覆盖不到一个纹理像素(图中红圈)
可设置的属性值
THREE.NearestFilter
最近点采样THREE.LinearFilter
线性采样 默认值
属性介绍
NearestFilter 最近点采样方法
返回与指定纹理坐标(在曼哈顿距离之内)最接近的纹理像素的值。
原理
如图纹理的S,T坐标范围是0-1,纹理本身是由一个个离散的像素组成的,将每个纹理像素看成一个小方块,则每个像素都占一定的纹理坐标。
根据片元的纹理坐标,计算出落在哪个像素中(小方块),最近点采样就直接取此像素的颜色值为采样值
特点
计算量小,但很容易产生明显锯齿
LinearFilter 线性采样方法
返回距离指定的纹理坐标最近的四个纹理元素的加权平均值
原理
线性采样会考虑纹理坐标点附近的4个纹理像素值,一般根据面积比例加权计算出最终采样结果
特点
因为对像素做了加权平均,所以过度比较平滑
minFilter 缩小滤镜
使用场景
- 一张大纹理贴到一个小空间(例如32X32的纹理映射到16X16的像素空间),相当于纹理缩小
- 透视关系下远处的片元
上述情况下一个片元会覆盖多个纹理像素
可设置的属性值
THREE.NearestFilter
THREE.NearestMipmapNearestFilter
THREE.NearestMipmapLinearFilter
THREE.LinearFilter
THREE.LinearMipmapNearestFilter
THREE.LinearMipmapLinearFilter
默认值
NearestFilter
、LinearFilter
上面已经介绍过了, 其他四种属性就是增加了mipmap相关操作,后面会介绍mipmap \
NearestMipmapNearestFilter
选择与被纹理化像素的尺寸最匹配的mipmap, 并以NearestFilter
为标准来生成纹理值。
NearestMipmapLinearFilter
选择与被纹理化像素的尺寸最接近的两个mipmap, 并以NearestFilter
为标准来从每个mipmap中生成纹理值。最终的纹理值是这两个值的加权平均值。
LinearMipmapNearestFilter
选择与被纹理化像素的尺寸最匹配的mipmap, 并以LinearFilter
(最靠近像素中心的四个纹理元素的加权平均值)为标准来生成纹理值。
LinearMipmapLinearFilter
是默认值,它选择与被纹理化像素的尺寸最接近的两个mipmap, LinearFilter
为标准来从每个mipmap中生成纹理值。最终的纹理值是这两个值的加权平均值。
Mipmap介绍
原理
当minFilter设置为LinearFilter时发现,远处应该模糊,但远处的画面反而比近处的更清楚.
因为都是用的同一张分辨率的纹理,远处的对应关系相当于纹理被缩小,自然比近处放大的纹理清楚,但如果缩小太多,远处也会因为采样率不足产生锯齿 .
一种解决方法就是远处用分辨率较低的纹理,近处用分辨率较大的纹理,这就是Mipmap
的核心思想
如上图所示,使用mipmap,提供一张原始纹理图,系统就会在加载纹理时自动生成一系列由大到小的纹理图,每幅纹理图是前一幅尺寸的1/2(面积1/4),直至纹理的尺寸缩小到1x1
当程序运行时,渲染管线会先计算出级别,决定使用哪些纹理图,然后根据我们选择的处理方式来处理,比如LinearMipmapLinearFilter就是选择跟级别最相近的两个级别的纹理图进行处理
如下图左侧(LinearMipmapLinearFilter)明显远处变模糊,右侧(LinearFilter)
总结
three中纹理的magFilter、minFilter属性都是有默认值的,默认值一般情况下是合理的,不需要修改,了解原理是为了可以更好地用于特殊情况的处理