如何在WebGL中旋转纹理 修正摄像头纹理-90度偏移恢复正常朝向
WebGL摄像头纹理-90度旋转偏移修复方案
摄像头采集的视频帧自带方向元数据,原生video标签会自动读取元数据做方向校正,但WebGL调用texImage2D直接上传video元素时不会自动处理这部分元数据,就会出现纹理旋转偏移。
以下是三种常用修复方案,按推荐优先级排序:
方案1:调整着色器纹理UV坐标(性能最优,首选)
不需要修改现有纹理上传逻辑,直接在片元着色器采样纹理时,对UV坐标做90度旋转变换即可,无额外性能开销。
常规四边形的纹理坐标默认以左下角为(0,0)、右上角为(1,1),针对-90度的偏移,将采样用的UV做如下替换:
// 原采样逻辑 // gl_FragColor = texture2D(u_sampler, v_uv); // 旋转+90度校正后的采样逻辑 vec2 rotatedUV = vec2(v_uv.y, 1.0 - v_uv.x); gl_FragColor = texture2D(u_sampler, rotatedUV);
如果是前置摄像头存在镜像需求,可以对应调整UV分量:
- 仅水平镜像适配:
vec2(1.0 - v_uv.y, 1.0 - v_uv.x) - 仅垂直翻转适配:
vec2(v_uv.y, v_uv.x)
方案2:配合纹理解包参数调整
WebGL提供了纹理上传时的Y轴翻转全局参数,可以配合UV调整简化逻辑,注意该参数是全局状态,设置后会影响后续所有texImage2D的上传行为。
在原有updateTexture函数中添加参数设置:
function updateTexture(gl, texture, video) { const level = 0; const internalFormat = gl.RGBA; const srcFormat = gl.RGBA; const srcType = gl.UNSIGNED_BYTE; gl.bindTexture(gl.TEXTURE_2D, texture); // 上传纹理时自动翻转Y轴 gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, true); gl.texImage2D(gl.TEXTURE_2D, level, internalFormat, srcFormat, srcType, video); }
注意:该参数仅能实现Y轴翻转,无法独立完成90度旋转,必须配合方案1的UV坐标调整使用,单独设置无法解决旋转偏移问题。
方案3:离屏Canvas预旋转校正(兼容性最好)
如果需要适配不同设备的任意角度摄像头偏移,可以先将视频帧绘制到离屏Canvas,在绘制阶段完成旋转校正,再将Canvas作为纹理源上传到WebGL。该方案不需要修改着色器逻辑,但每帧会多一次Canvas绘制开销,高分辨率场景下有一定性能损耗。
实现代码如下:
// 初始化离屏Canvas const offscreenCanvas = document.createElement('canvas'); const offCtx = offscreenCanvas.getContext('2d'); function updateTexture(gl, texture, video) { const level = 0; const internalFormat = gl.RGBA; const srcFormat = gl.RGBA; const srcType = gl.UNSIGNED_BYTE; // 旋转90度后宽高需要互换 offscreenCanvas.width = video.videoHeight; offscreenCanvas.height = video.videoWidth; // 绘制旋转后的视频帧到离屏Canvas offCtx.save(); offCtx.translate(offscreenCanvas.width / 2, offscreenCanvas.height / 2); offCtx.rotate(Math.PI / 2); // 旋转90度校正 offCtx.drawImage(video, -video.videoWidth / 2, -video.videoHeight / 2); offCtx.restore(); // 上传校正后的Canvas作为纹理 gl.bindTexture(gl.TEXTURE_2D, texture); gl.texImage2D(gl.TEXTURE_2D, level, internalFormat, srcFormat, srcType, offscreenCanvas); }
内容的提问来源于stack exchange,提问作者Dev
相关产品推荐
相关产品推荐

