Android下OpenGL ES自定义点生成错误导致绘制线条偏移问题
问题根因
- 片元着色器嵌套循环次数过高:你当前的片元着色器每像素要执行超过9000次循环,多数移动GPU对片元着色器的循环次数有严格限制,超过上限后驱动会强制截断未执行的循环,导致边界后的像素判断逻辑未执行,出现塌陷、偏移问题。
- 未考虑
gl_FragCoord的坐标特性:gl_FragCoord返回的是像素中心的浮点坐标(比如左下角第一个像素坐标为(0.5, 0.5)),直接和整数i比较会出现半像素偏移。 - 纹理过滤方式不匹配:你用了
GL_LINEAR线性过滤,采样时会混合相邻像素,导致绘制的边缘出现偏移模糊。
修复步骤
- 优化片元着色器逻辑,删除内层循环:你要实现的斜率为1的平行线上的40x40红色块,可以直接通过直线方程判断,不需要逐点遍历。
- 修正坐标偏移:对
gl_FragCoord做取整处理,匹配整数像素坐标。 - 修改纹理过滤方式为
GL_NEAREST:保证像素级精确绘制。
1. 纹理创建代码修改(仅修改过滤参数部分)
glGenFramebuffers(1, &fbo); glGenTextures(1, &targetTexture); glBindFramebuffer(GL_FRAMEBUFFER, fbo); glBindTexture(GL_TEXTURE_2D, targetTexture); glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA16F, screenWidth, screenHeight, 0, GL_RGBA, GL_FLOAT, nullptr); // 把线性过滤改成最近邻过滤,避免像素混合 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); glBindTexture(GL_TEXTURE_2D, 0); glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, targetTexture, 0); glBindFramebuffer(GL_FRAMEBUFFER, 0);
2. 优化后的片元着色器代码
#version 310 es precision highp float; out vec4 outColor; void main(){ // 取整获得整数像素坐标,消除半像素偏移 int x = int(floor(gl_FragCoord.x)); int y = int(floor(gl_FragCoord.y)); bool isColoured = false; // 仅循环遍历每条线的偏移,不需要遍历每个点,循环次数从9000+降到9次 for(int j=100; j<=1700; j=j+200){ int c = j - 100; // 判断x-y是否落在对应线条的范围内,且x在你设定的有效区间内 if(abs((x - y) - c) <= 20 && x >= j -20 && x <= j + 1000 + 20){ isColoured = true; break; } } outColor = isColoured ? vec4(1.0, 0.0, 0.0, 1.0) : vec4(1.0, 1.0, 1.0, 1.0); }
内容的提问来源于stack exchange,提问作者Chamith Thisaranga
相关产品推荐
相关产品推荐

