片段着色器上的插值从 0 + 半像素开始



我在片段着色器上的插值时遇到问题。我只是在画一个全屏四边形。视区设置为 (0, 0, 128, 128)。

每个顶点都有一个纹理坐标。

var textureCoordinates = [
    0.0, 1.0,
    1.0, 1.0,
    0.0, 0.0,
    1.0, 0.0
];

我通过可变变量将纹理坐标从顶点着色器传递到片段着色器,效果很好。

vTextureCoord = aTextureCoord;

问题是插值从 0+半像素开始,到 1 半像素结束。半像素为 (1/128) * 0.5。

我希望插值从 0 开始并以 1 结束。这是因为 vTextureCoord 将用作我在片段着色器上的噪点函数的输入。

MAG 和 MIN 筛选器均设置为"最近"。

WRAP_S和WRAP_T设置为CLAMP_TO_EDGE。

请注意,纹理坐标属性不是强制性的,这只是我将数字从 0 插值到 1 的方式。如果有更简单的方法可以使用属性以外的其他东西在片段着色器上插入从 0 到 1 的数字,那么我很想知道怎么做!

试图将纹理坐标偏移半个像素,但它似乎没有像我预期的那样工作。

我还尝试在片段着色器上减去半像素,但插值并没有以 1 结束。

newTextureCoord = vTextureCoord - (1.0 / 128.0) * 0.5;

任何提示,评论或反馈都非常感谢!

如果没有多重采样技术,片段将始终在像素中心采样。您看到的行为是预期行为。

您提到的纹理示例参数根本不影响插值。仅当使用 texture() 系列 GLSL 函数从纹理中采样时,它们才具有效果。

您的评论是对的,将 texcoords 移动半个像素是不够的,您还需要一个比例。你想要的是 f(0.5/128)=0 和 f(127.5/128)=1 的映射。这当然是一个简单的线性变换 f(x)=(128/127)*x - 1/(2*127),您可以将其应用于顶点坐标,这样您就不会有任何运行时开销,至少在视口大小恒定的情况下。

应用纹理坐标的方式,0 对应于第一个纹素的左边缘,1 对应于最后一个纹素的右边缘。第一个纹素的大小为 128,其纹理坐标范围从 0 到 1/128,中心为 0.5/128。最后一个纹素的范围是 127/128 到 1,中心位于 127.5/128。

如果要将第一个/最后一个纹素的中心放在边缘,则需要相应地调整纹理坐标,方法是在左边缘添加半个纹素的宽度,并在右边缘减去相同的量:

var textureCoordinates = [
    0.5 / 128.0, 127.5 / 128.0,
    127.5 / 128.0, 127.5 / 128.0,
    0.5 / 128.0, 0.5 / 128.0,
    127.5 / 128.0, 0.5 / 128.0
];

最新更新