研究纹理采样器在像素级别的采样位置

问题

【纹理采样器】是一个基础的概念。假设有一个正方形面片,顶点的UV范围是0.0~1.0,那么在这个正方形面片上采样一张纹理时,会呈现出完整的纹理。

但我现在关注的问题是,在像素级别上,采样的位置是怎样的。具体来讲:对于UV值是(0.0,0.0)的点,它对应的采样位置是纹理最左上角像素的中心?还是纹理最左上角像素的左上角?即,下面左右哪个是正确的情况?
研究纹理采样器在像素级别的采样位置_第1张图片
在宏观上,尤其是像素较多的时候,二者看起来应该差异很小。但,存在一些对像素级别的差异较为敏感的场合,因此需要对这个问题进行明确。

问题的答案是:右者

下面我想通过实验来验证这个答案。不过,就算不做实验,其实也能推理出来左边的情况是有问题的。

实验

我选择在UE4里做实验

测试用方形面片

方形面片直接将Plane拖入场景,可以认为它的UV是范围是0.0~1.0
在这里插入图片描述

测试用纹理

一个4×4像素尺寸的棋盘格状贴图:
研究纹理采样器在像素级别的采样位置_第2张图片
将其拖入UE4中。
在这里插入图片描述

测试用材质

研究纹理采样器在像素级别的采样位置_第3张图片

结果

研究纹理采样器在像素级别的采样位置_第4张图片
这验证了最初的问题里确实右者是答案。因为:假设是左者,那么(0.0,0.0)位置对应了纹理左上角像素的中心,那么它一定是最黑的位置,但显然结果上(0.0,0.0)位置不是最黑的,(0.125,0.125)才是最黑的。

另一个更有说服力的结果

改变贴图的采样方式为Nearest(临近采样)
研究纹理采样器在像素级别的采样位置_第5张图片
然后查看渲染结果:
研究纹理采样器在像素级别的采样位置_第6张图片
假设一开始的问题是左者,那么第一个黑与白的分界线的位置应该是1/6处,但这里是1/4,显然一开始问题答案是右者

不需要实验的推理

首先,从上一部分的【另一个更有说服力的结果】也可以看到,假设采样的方式是按照左者进行,那么最终采样出的结果,势必和原图有较大差异,会是这样:
在这里插入图片描述
这将会一般性的认识相矛盾:在一般性的认识里,我用一个UV范围是0.0~1.0的面片进行采样,得到的结果一定是完整的纹理,而不是看起来“少了一圈”。


不过在我看来,最重要的是:如果使用左者进行采样,那么会使Tilling(重复平铺)出问题。

设想在左者采样方式下:
一个U方向上0.001(趋近于0.0稍微比0.0大)的位置,采样时的值将趋近于最左边像素的值;而一个0.999(趋近于1.0稍微比1.0小)的位置,采样时的值将趋近于最右边像素的值。然而0.0010.999在空间上是趋近的,因此在最左边像素不等于最右边像素时,势必会有颜色的跳变出现。而如果强制最左边像素等于最右边像素,那也意味着资源上的浪费。

而在右者采样方式下:
0.001采样时的值将趋近于最左边像素最右边像素的均值,而0.999也一样。

需要关注此问题的情况

正如开头提到,这个问题在大多数情况下不需要关注。

目前我意识到的需要关注这个问题的情况是:需要将顶点与实际纹理中像素对应起来的时候。
例如,对于n个依次排列的顶点,希望其对应纹理上依次排列的n个像素。那么对于X方向(或者说贴图上的U方向),第0个顶点不是0.0,最后一个顶点也不是1.0。而是比0.0~1.0的这个范围“缩小”一圈。即,第x01-n)个顶点的U值是:
U = x + 0.5 n U=\frac{x+0.5}{n} U=nx+0.5

你可能感兴趣的:(cg)