使用OpenGL ES 2.0在Android上进行双线性过滤

时间:2014-12-03 02:43:08

标签: 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 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上运行该程序时,图像充满了尖叫声。我不知道为什么。

1 个答案:

答案 0 :(得分:0)

明显的问题:你为什么要在着色器中进行双线性过滤,而不仅仅是使用内置的硬件双线性过滤?我确定这是一个很好的理由,但告诉我们这可能会帮助您避免许多类似问题的问题;您是否适当地设置了过滤模式?"

话虽如此,它可能是一个精确问题。您可能希望将v_texCoord舍入到确切的采样网站,因为我猜您有GL_NEAREST过滤设置,以禁用硬件双线性过滤,但由于精度问题,例如v_texCoord + vec2(texelSizeX, 0)然后在v_texCoord接近0时对同一个纹素而不是下一个纹素进行采样,或者v_texCoord处采样的样本可能是下一个纹素。接近1,或沿着这些线的东西。

OpenGL将texel的中心视为其位置。因此,如果你在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

......两者都是相关的读取,所以性能会受到很大的影响。

相关问题