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

时间:2014-12-28 10:49:47

标签: opengl glsl webgl interpolation fragment-shader

我在片段着色器上有插值问题。我只是画一个全屏四边形。视口设置为(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过滤器都设置为NEAREST。

WRAP_S和WRAP_T设置为CLAMP_TO_EDGE。

请注意,纹理坐标属性不是强制性的,它只是我从0到1插入数字的方法。如果有更简单的方法来插入0到1之间的数字片段着色器使用别的东西而不是属性然后我很想知道如何!

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

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

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

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

2 个答案:

答案 0 :(得分:3)

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

您提到的纹理样本参数根本不会影响插值。只有在使用texture() GLSL函数族的纹理进行采样时,它们才有效。

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

答案 1 :(得分:1)

应用纹理坐标的方式,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
];