我使用了这种fragent着色器(灵感来自一段时间前在NVIDIA网站上找到的一些教程)。它基本上计算2D纹理的双线性插值。

uniform sampler2D myTexture;
uniform vec2 textureDimension;

#define texel_size_x 1.0 / textureDimension[0]
#define texel_size_y 1.0 / textureDimension[1]

vec4 texture2D_bilinear( sampler2D texture, vec2 uv)
{
    vec2 f;
    uv = uv + vec2( - texel_size_x / 2.0, - texel_size_y / 2.0);

    f.x = fract( uv.x * textureDimension[0]);
    f.y = fract( uv.y * textureDimension[1]);

    vec4 t00 = texture2D( texture, vec2(uv));
    vec4 t10 = texture2D( texture, vec2(uv) + vec2( texel_size_x, 0));
    vec4 tA = mix( t00, t10, f.x);

    vec4 t01 = texture2D( texture, vec2(uv) + vec2( 0, texel_size_y));
    vec4 t11 = texture2D( texture, vec2(uv) + vec2( texel_size_x, texel_size_y));
    vec4 tB = mix( t01, t11, f.x);

    vec4 result = mix( tA, tB, f.y);
    return result;
}

它看起来非常简单而且前卫。我最近在几张ATI卡(最新驱动程序...)上对其进行了测试,并得到以下结果:



(左:最近的邻居)(右:使用中的分片)

如您所见,出现了一些水平线和垂直线,必须指出的是,这些线在视口(viewport)坐标中也没有固定,在纹理坐标中也没有固定。

我必须移植多个着色器以使其在ATI卡上正常工作,对于我写了一段时间的错误代码,似乎NVIDIA实现似乎更宽松。但是在这种情况下,我看不到应该改变什么!

关于NVIDIA和ATI GLSL实现之间的差异,我应该了解什么才能克服这一问题?

最佳答案

据我所知,在对纹理进行采样之前,没有对纹理坐标进行量化。这很可能是这些线条出现的原因,因为您的输入纹理坐标正好位于那里的纹理像素之间的边界上。因此,您需要首先将uv量化为texel中心。请记住,纹理坐标0和1不在texel中心,而是定义网格的边界,其中网格单元是texel,而texel中心在(texel_n + 0.5) / texture_dim,或者使用GLSL函数texelFetch可用GLSL 1.30及更高版本。

07-24 09:24