本文主要是介绍研究纹理采样器在像素级别的采样位置,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
问题
【纹理采样器】是一个基础的概念。假设有一个正方形面片,顶点的UV范围是0.0~1.0,那么在这个正方形面片上采样一张纹理时,会呈现出完整的纹理。
但我现在关注的问题是,在像素级别上,采样的位置是怎样的。具体来讲:对于UV值是(0.0,0.0)的点,它对应的采样位置是纹理最左上角像素的中心?还是纹理最左上角像素的左上角?即,下面左右哪个是正确的情况?

在宏观上,尤其是像素较多的时候,二者看起来应该差异很小。但,存在一些对像素级别的差异较为敏感的场合,因此需要对这个问题进行明确。
问题的答案是:右者。
下面我想通过实验来验证这个答案。不过,就算不做实验,其实也能推理出来左边的情况是有问题的。
实验
我选择在UE4里做实验
测试用方形面片
方形面片直接将Plane拖入场景,可以认为它的UV是范围是0.0~1.0

测试用纹理
一个4×4像素尺寸的棋盘格状贴图:

将其拖入UE4中。

测试用材质

结果

这验证了最初的问题里确实右者是答案。因为:假设是左者,那么(0.0,0.0)位置对应了纹理左上角像素的中心,那么它一定是最黑的位置,但显然结果上(0.0,0.0)位置不是最黑的,(0.125,0.125)才是最黑的。
另一个更有说服力的结果
改变贴图的采样方式为Nearest(临近采样)

然后查看渲染结果:

假设一开始的问题是左者,那么第一个黑与白的分界线的位置应该是1/6处,但这里是1/4,显然一开始问题答案是右者。
不需要实验的推理
首先,从上一部分的【另一个更有说服力的结果】也可以看到,假设采样的方式是按照左者进行,那么最终采样出的结果,势必和原图有较大差异,会是这样:

这将会一般性的认识相矛盾:在一般性的认识里,我用一个UV范围是0.0~1.0的面片进行采样,得到的结果一定是完整的纹理,而不是看起来“少了一圈”。
不过在我看来,最重要的是:如果使用左者进行采样,那么会使Tilling(重复平铺)出问题。
设想在左者采样方式下:
一个U方向上0.001(趋近于0.0稍微比0.0大)的位置,采样时的值将趋近于最左边像素的值;而一个0.999(趋近于1.0稍微比1.0小)的位置,采样时的值将趋近于最右边像素的值。然而0.001和0.999在空间上是趋近的,因此在最左边像素不等于最右边像素时,势必会有颜色的跳变出现。而如果强制最左边像素等于最右边像素,那也意味着资源上的浪费。
而在右者采样方式下:
0.001采样时的值将趋近于最左边像素和最右边像素的均值,而0.999也一样。
需要关注此问题的情况
正如开头提到,这个问题在大多数情况下不需要关注。
目前我意识到的需要关注这个问题的情况是:需要将顶点与实际纹理中像素对应起来的时候。
例如,对于n个依次排列的顶点,希望其对应纹理上依次排列的n个像素。那么对于X方向(或者说贴图上的U方向),第0个顶点不是0.0,最后一个顶点也不是1.0。而是比0.0~1.0的这个范围“缩小”一圈。即,第x(0到1-n)个顶点的U值是:
U = x + 0.5 n U=\frac{x+0.5}{n} U=nx+0.5
这篇关于研究纹理采样器在像素级别的采样位置的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!