通过GLSL/WebGL实现图片无畸变旋转 现有代码出现倾斜翻转问题
你的代码存在3个核心问题:
- 未校正纹理宽高比、旋转中心错误:你直接对[0,1]区间的原始纹理坐标做旋转,默认旋转锚点是纹理左上角而非中心,且非正方形纹理的x/y轴单位长度不对等,旋转后必然出现拉伸倾斜。
- 坐标系适配错误:WebGL默认纹理坐标Y轴原点在左下角,和常规图片的左上角原点坐标系不匹配,这是你旋转180度仅出现X轴翻转的核心原因。
- 逻辑冗余与语法问题:
mod操作会导致旋转后超出范围的纹理重复显示,同时你给出的代码末尾缺少函数闭合大括号。
修复后的完整片元着色器代码
uniform sampler2D texture; uniform vec2 texSize; varying vec2 texCoord; uniform float degrees; const float PI = 3.1415926535897932384626433832795; float deg2rad(float deg){ return deg * PI / 180.0; } void main() { // 1. 坐标平移到纹理中心,校正宽高比避免拉伸 vec2 coord = texCoord - vec2(0.5); float aspect = texSize.x / texSize.y; coord.x *= aspect; // 2. 构造旋转矩阵执行旋转,调整符号适配Y轴方向 float rad = deg2rad(degrees); float sin_factor = sin(rad); float cos_factor = cos(rad); coord = mat2(cos_factor, -sin_factor, sin_factor, cos_factor) * coord; // 3. 还原宽高比,平移回原坐标区间 coord.x /= aspect; coord += vec2(0.5); // 4. 超出纹理范围的区域返回透明,可根据需求改为黑色 if(coord.x < 0.0 || coord.x > 1.0 || coord.y < 0.0 || coord.y > 1.0) { gl_FragColor = vec4(0.0); } else { gl_FragColor = texture2D(texture, coord); } }
核心调整说明
- 新增了宽高比校正逻辑,保证旋转时x/y轴单位长度一致,不会出现拉伸倾斜
- 调整了旋转矩阵的参数顺序与乘法方向,适配WebGL纹理Y轴方向,解决180度翻转异常的问题
- 移除了
mod操作,新增范围判断,避免旋转后出现重复的纹理内容 - 清理了冗余的灰度计算代码,补全了语法缺失的闭合大括号
内容的提问来源于stack exchange,提问作者simone
相关产品推荐
相关产品推荐

