Android上使用OpenGL ES 2.0的双线性过滤器

Android上使用OpenGL ES 2.0的双线性过滤器,android,opengl-es,Android,Opengl Es,这是我的代码。它在PC/Windows上运行良好,但在Android 4.42上放大图像时会出现锯齿 #ifdef GL_ES precision highp float; #endif varying vec4 v_fragmentColor; varying vec2 v_texCoord; uniform float u_width; //width of image uniform float u_height; //height of image void mai

这是我的代码。它在PC/Windows上运行良好,但在Android 4.42上放大图像时会出现锯齿

#ifdef GL_ES
precision highp float;
#endif


varying vec4 v_fragmentColor;
varying vec2 v_texCoord;

uniform float u_width;    //width  of image
uniform float u_height;   //height of image


void main()
{
    float texelSizeX = 1.0/u_width;
    float texelSizeY = 1.0/u_height;

    //four pixels' color
    vec4 p0q0 = texture2D(CC_Texture0, v_texCoord);    
    vec4 p1q0 = texture2D(CC_Texture0, v_texCoord + vec2(texelSizeX, 0));  
    vec4 p0q1 = texture2D(CC_Texture0, v_texCoord + vec2(0, texelSizeY));  
    vec4 p1q1 = texture2D(CC_Texture0, v_texCoord + vec2(texelSizeX , texelSizeY));


    //bilinear interpolation
    float a = fract(v_texCoord.s * u_width);
    float b = fract(v_texCoord.t * u_height);
    vec4 color_q0 = mix( p0q0, p1q0, a );
    vec4 color_q1 = mix( p0q1, p1q1, a );   

    vec4 color = mix( color_q0, color_q1, b); 
    gl_FragColor = v_fragmentColor * color;
}
很抱歉,我不能发布图片。我用VS2012很好地调试了代码,图像看起来很平滑。
但当我在Android上运行这个程序时,图像中充满了jag。我不知道为什么。

显而易见的问题:为什么要在着色器中进行双线性过滤,而不仅仅是使用内置的硬件双线性过滤?我相信有一个很好的理由,但是告诉我们这可能会帮助你避免很多问题,比如你是否正确设置了过滤模式

尽管如此,这可能是一个精度问题。您可能希望将v_texCoord四舍五入到准确的采样点,因为我猜您已经设置了GL_最近的过滤,以禁用硬件双线性过滤,但由于精度问题,例如v_texCoord+Vec2texlsizex,当v_texCoord接近0时,0将对同一个texel而不是下一个texel进行采样,或者在v_texCoord采集的样本可能是接近1时的下一个texel,或者沿着这些线的某个东西

OpenGL将纹理的中心视为其位置。所以,如果你在1d中,你可以做如下事情:

r_texCoord.x = v_texCoord.x - mod(v_texCoord.x, 1.0/u_width) + 0.5/u_width;
或者,如果您乐于使用整体纹理坐标而不是普通的OpenGL[0.0,1.0]范围,那么您可以稍微简化,因为floor和ceil已经知道如何将您移动到整体边界:

(floor(v_texCoord.x) + 0.5) / u_width

…这两个都是独立的读取,因此性能会受到很大影响。

是的,我将过滤器GL_设置得最近。事实上,我使用了PNG图像压缩,它有一个调色板并在数据区域存储索引值。也就是说,纹理实际上是存储索引。我想通过texcoord和调色板读取着色器中的RGBA值,这样我就可以不要使用内置的硬件双线性过滤。我会试试你的方法。酷。用于截断到texel中心的代码是临时编写的,很难相信没有更好的解决方案,但它应该有助于表明精度是否是问题。我希望。