如何在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
相关产品推荐
相关产品推荐

