我使用这个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卡上测试了它(最新的驱动程序......),我得到了以下结果:
(左:最近邻居)(右:使用中更清晰)
正如您所看到的那样,出现了一些水平和垂直线条,重要的是要提及这些线条在纹理坐标中的视口设置中都没有固定。
我必须移植几个着色器才能使它们在ATI卡上正常工作,看起来NVIDIA的实现对错误有点许可代码我写了一些时间。但在这种情况下,我看不出我应该改变什么!
我应该知道NVIDIA和ATI GLSL实施之间的差异以克服这个问题吗?
答案 0 :(得分:4)
nVidia更宽容,例如nVidia允许你错误地(即float4浮动)只是使它成为警告,ATI不会(错误)。 如果你使用OpenGL比使用DirectX有更大的区别,例如我有一个非常复杂的顶点着色器(矩阵调色板蒙皮),即使没有最轻微的警告,它也不适用于ATI(但在nVidia上有效)。 / p>
所以,如果你不想让着色器“无处不在”工作,请购买ATI卡:-)(或者更好的是集成芯片组^^)。
答案 1 :(得分:2)
据我所知,在采样纹理之前,你没有量化纹理坐标。这很可能是出现这些线条的原因,因为输入纹理坐标恰好位于那里的纹素之间的边界上。因此,您需要先将uv
量化为纹素中心。请记住,纹理坐标0和1不在纹素中心,而是定义网格的边框,其中网格单元格是纹素和纹素中心位于(texel_n + 0.5) / texture_dim
,或者您使用GLSL函数{{1}可用GLSL 1.30及更高版本。