You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Android OpenGL ES 2.0场景下如何快速翻转FBO解决纹理倒置问题

你遇到的翻转问题本质是OpenGL纹理坐标默认左下角为(0,0),每次FBO离屏渲染会默认沿Y轴翻转一次内容,所以每多一级滤镜输出,纹理朝向就会反转一次,和固定方向的蒙版纹理自然就出现偶数级错位的问题。

方案1:着色器动态调整采样坐标(推荐,零额外开销)

这是成本最低的修改方式,不需要额外的渲染流程,仅需调整采样逻辑即可:

  • 新增uniform变量控制是否翻转Y轴,根据当前滤镜是奇数/偶数级传入对应值
  • 仅对来自上一级FBO的uTexture做坐标翻转,固定蒙版uMaskTexture保持原始坐标采样

修改后的着色器代码:

#version 100
precision mediump float;
uniform sampler2D uTexture;
uniform sampler2D uMaskTexture;
// 新增控制变量,需要翻转时传1.0,不需要时传0.0
uniform float uFlipY;
varying vec2 vTexCoord;
void main(){
    // 调整uTexture的采样坐标
    vec2 texCoord = vTexCoord;
    texCoord.y = mix(texCoord.y, 1.0 - texCoord.y, uFlipY);
    // 修复原代码逻辑错误:不能对采样器直接做乘法,需先采样再计算
    vec4 srcColor = texture2D(uTexture, texCoord);
    float mask = texture2D(uMaskTexture, vTexCoord).r;
    gl_FragColor = srcColor * mask;
}

使用逻辑:第N个滤镜(从0开始计数)渲染时,uFlipY传入N % 2的值即可,刚好抵消每一级FBO带来的自动翻转,无需额外处理FBO本身。

方案2:CPU侧修改顶点纹理坐标

如果不想修改着色器代码,可以在绑定顶点缓冲前动态修改纹理坐标的Y值:

  • 不需要翻转时,纹理坐标保持原(0,0), (1,0), (0,1), (1,1)
  • 需要翻转时,将纹理坐标Y值替换为1-Y,即变为(0,1), (1,1), (0,0), (1,0)
    该方案同样无额外渲染开销,适合着色器统一封装不便修改的场景。

方案3:单独翻转FBO纹理(不推荐,仅作补充)

如果必须得到正向的FBO纹理供其他逻辑使用,可以增加一个极简的翻转渲染Pass:

  • 准备一个全屏Quad和专用翻转着色器,仅做gl_FragColor = texture2D(inputTex, vec2(vTexCoord.x, 1.0 - vTexCoord.y))逻辑
  • 每级滤镜渲染完成后,将FBO输出过一遍翻转Pass再传入下一级
    该方案会增加额外的draw call和显存读写开销,非必要不建议使用。

内容的提问来源于stack exchange,提问作者oHuflying

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.27 06:54:01