C++ ATI卡上的碎片着色器与NVIDIA卡上的碎片着色器 我使用这个FrAgent着色器(灵感来自于英伟达网站上的一些教程)。它基本上计算二维纹理的双线性插值 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; }

C++ ATI卡上的碎片着色器与NVIDIA卡上的碎片着色器 我使用这个FrAgent着色器(灵感来自于英伟达网站上的一些教程)。它基本上计算二维纹理的双线性插值 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; },c++,opengl,nvidia,shader,ati,C++,Opengl,Nvidia,Shader,Ati,它看起来很简单,很有前瞻性。我最近在几个ATI卡(最新的驱动程序…)上测试了它,结果如下: (左:最近的邻居)(右:正在使用切碎器) 正如您所看到的,出现了一些水平线和垂直线,需要注意的是,这些线在视口坐标和纹理坐标中都不是固定的 我必须移植几个着色器才能使它们在ATI卡上正确工作,似乎NVIDIA实现对我编写的错误代码更宽容一些。但在这种情况下,我看不出我应该改变什么 要克服这一点,我需要了解NVIDIA和ATI GLSL实现之间的区别吗 nVidia更为宽容,例如,nVidia允许您错误地

它看起来很简单,很有前瞻性。我最近在几个ATI卡(最新的驱动程序…)上测试了它,结果如下:

(左:最近的邻居)(右:正在使用切碎器)

正如您所看到的,出现了一些水平线和垂直线,需要注意的是,这些线在视口坐标和纹理坐标中都不是固定的

我必须移植几个着色器才能使它们在ATI卡上正确工作,似乎NVIDIA实现对我编写的错误代码更宽容一些。但在这种情况下,我看不出我应该改变什么


要克服这一点,我需要了解NVIDIA和ATI GLSL实现之间的区别吗

nVidia更为宽容,例如,nVidia允许您错误地施放(即float4到float),仅将其作为警告,ATI不会(错误)。 如果使用OpenGL,与使用DirectX相比,会有更大的区别,例如,我有一个非常复杂的顶点着色器(矩阵调色板蒙皮),即使没有任何警告,它在ATI上也不起作用(但在nVidia上起作用)


因此,如果您不想让着色器“无处不在”工作,请使用ATI卡:-)(或者更好,使用集成芯片组^^)。

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

您能重现Mesa的问题吗?@genpfault我忘了提到目标操作系统是windows 7/Vista/XP。。。mesa驱动程序适用于这些吗?是的。只是软件,但这就是想法。区别?是的,nVidia的OpenGL驱动程序可以工作,ATI的Do't.ps。您遇到的错误可能是在纹理查找时如何处理纹理的问题(即使用钳制或镜像),或者再次出现溢出,将所有查找添加到float2(vec2)中,并用0.25(即div乘以4)而不是mix()函数。@Valmond如果我一直除以4,我想我会失去这个双线性插值着色器的双线性部分:)。。。但是我明白你的意思了,我会尝试手工做混合部分。我可能解释得不好,只是把4个纹理查找加在一起,然后除以4(当你做4个查找时,如果你把它们加在一起,你需要除以4)。这将执行双线性插值(并且没有椭圆流)。如果这样做不起作用,您可能希望删除“fract()”调用(只需立即使用该值(即X而不是fract(X)),与钳形结合。@Valmond:将四个texel相加并除以四将在该纹理区域产生一个常量值。这不是任何类型的插值。感谢我移动了
uv
,偏移量
-f*texel\u size
…这没关系。我天真地希望
glTexParameterf(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_NEAREST);
正在完整单元格中应用textel颜色…我知道在网格边界(0和1)上有一些选择,但它应该是确定的,对吗?