WebGL2中3D纹理图像显示倒置,无法用UNPACK_FLIP_Y_WEBGL如何修复?
解决WebGL2中3D纹理Y轴倒置的问题
问题背景
用WebGL处理2D纹理时,设置gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, true)就能解决图像倒置问题,但在WebGL2里用3D纹理时,这个参数会被标记为非法,同时加载出的3D纹理还是呈Y轴倒置状态。
解决方案
方案1:加载前手动翻转每个纹理切片的Y轴
把数据传给texImage3D之前,手动处理Uint8Array里的像素数据,对每个深度切片的Y轴做翻转。
示例代码(假设纹理是RGB格式,size为切片的宽高):
function flip3DTextureY(data, size) { const bytesPerPixel = 3; // 对应RGB格式 const sliceSize = size * size * bytesPerPixel; // 遍历每个深度切片 for (let z = 0; z < size; z++) { const sliceStart = z * sliceSize; // 翻转当前切片的Y轴 for (let y = 0; y < Math.floor(size / 2); y++) { const rowTop = sliceStart + y * size * bytesPerPixel; const rowBottom = sliceStart + (size - 1 - y) * size * bytesPerPixel; // 交换上下两行的像素数据 const temp = new Uint8Array(data.buffer, rowTop, size * bytesPerPixel); data.set(new Uint8Array(data.buffer, rowBottom, size * bytesPerPixel), rowTop); data.set(temp, rowBottom); } } return data; } // 使用方式:先翻转数据再传入texImage3D const flippedData = flip3DTextureY(data, size); // 后续调用texImage3D时传入flippedData即可
方案2:在着色器采样时翻转Y坐标
要是不想修改原始纹理数据,直接在片元着色器里把3D纹理的采样Y坐标翻转,用1.0 - vTexCoord.y替换原本的Y分量就行。
示例片元着色器代码:
#version 300 es precision highp float; uniform sampler3D uTexture; in vec3 vTexCoord; out vec4 fragColor; void main() { // 翻转Y轴坐标:原范围[0,1]转为[1,0] vec3 flippedTexCoord = vec3(vTexCoord.x, 1.0 - vTexCoord.y, vTexCoord.z); fragColor = texture(uTexture, flippedTexCoord); }
补充说明
WebGL2里UNPACK_FLIP_Y_WEBGL只对2D纹理(包括2D纹理数组)有效,3D纹理不支持这个参数是因为它的设计逻辑只适配2D图像翻转,没法直接套用在多切片的3D纹理上。上面两个方案都能解决Y轴倒置问题,按需选择就行:想要纹理数据本身是正确状态选方案1,不想改动原始数据选方案2更省事。
内容的提问来源于stack exchange,提问作者adarian
相关产品推荐
相关产品推荐

