这是我的代码。它在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上运行该程序时,图像充满了尖叫声。我不知道为什么。
答案 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
......两者都是相关的读取,所以性能会受到很大的影响。