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

如何在OpenGL片段着色器中旋转sampler2D纹理?

解决方案:在片段着色器中反向修正纹理坐标

当然可以解决这个问题——你不需要直接旋转sampler2D对象,而是在片段着色器中先对传入的纹理坐标执行反向旋转,抵消顶点着色器的旋转影响,之后再应用你原有的复杂处理逻辑即可。

问题根源

你当前的顶点着色器对顶点执行了逆时针90度旋转(w=1.57即π/2弧度),这会让纹理采样的坐标映射关系发生旋转,但你的片段着色器逻辑是基于原纹理的坐标方向设计的,导致水平方向的处理逻辑被错误应用到了垂直方向。通过对纹理坐标做反向旋转,就能让坐标方向回到原逻辑预期的状态。

具体实现

保持你的顶点着色器不变,在片段着色器中添加纹理坐标的反向旋转步骤:

#version 120

uniform sampler2D u_texture;
varying vec2 v_texCoord;

void main() {
    // 顶点着色器用了逆时针90度旋转,这里执行顺时针90度反向旋转
    const float rotAngle = -1.57;
    // 2D旋转矩阵,比mat3更高效
    mat2 rotMatrix = mat2(cos(rotAngle), -sin(rotAngle),
                          sin(rotAngle), cos(rotAngle));

    // 修正:先将纹理坐标转到中心旋转,避免偏移
    vec2 centeredCoord = v_texCoord - vec2(0.5);
    vec2 rotatedCentered = rotMatrix * centeredCoord;
    vec2 correctedTexCoord = rotatedCentered + vec2(0.5);

    // 可选:如果纹理出现上下翻转,添加这行修正(适配OpenGL纹理原点在左下角的特性)
    // correctedTexCoord.y = 1.0 - correctedTexCoord.y;

    // 用修正后的坐标采样纹理,再执行你原有的复杂处理逻辑
    vec4 baseColor = texture2D(u_texture, correctedTexCoord);

    // ---------- 这里放你原有的片段着色器复杂处理代码 ----------
    // ...

    gl_FragColor = baseColor; // 替换为你处理后的最终颜色
}

优化与注意事项

  • 性能优化:如果旋转角度固定,建议将旋转矩阵作为uniform变量从CPU传入,避免在每个像素中重复计算三角函数。
  • 坐标原点适配:OpenGL默认纹理原点在左下角,若你的原逻辑是基于屏幕左上角原点设计的,可能需要对Y坐标做翻转(如代码中注释的行)。
  • 灵活调整:如果不需要旋转顶点,仅需处理纹理,也可以直接移除顶点着色器中的顶点旋转逻辑,直接在片段着色器中对原纹理坐标执行所需旋转后再处理。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.12 02:20:55