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

WebGL2中如何将源纹理指定Mipmap层级复制到目标纹理对应层级?

WebGL2中复制2D纹理指定Mip层级到Texture2DArray的可行方案

WebGL2基于OpenGL ES 3.0规范,并不支持glCopyImageSubData——这个API是OpenGL ES 3.2才引入的,目前主流浏览器都没有在WebGL2中实现它。不过你可以通过帧缓冲(Framebuffer)作为中间载体来实现需求,具体思路是:将2D纹理的指定Mip层级绑定到帧缓冲,再从帧缓冲复制到Texture2DArray的对应Mip层级。

具体实现步骤

  1. 提前创建一个帧缓冲对象(仅需初始化一次)
  2. 对每个需要复制的Mip层级:
    • 将2D纹理的目标Mip层级绑定到帧缓冲的颜色附件
    • 从帧缓冲复制像素数据到Texture2DArray的指定Mip层级和Z索引

代码示例

// 初始化帧缓冲(全局只需创建一次)
const fbo = gl.createFramebuffer();

/**
 * 复制2D纹理的指定Mip层级到Texture2DArray的对应层级
 * @param {WebGLTexture} srcTex2D - 源2D纹理
 * @param {number} srcMipLevel - 源Mip层级
 * @param {WebGLTexture} dstArrayTex - 目标Texture2DArray
 * @param {number} dstMipLevel - 目标Mip层级
 * @param {number} dstZIndex - 目标Array纹理的Z索引
 */
function copy2DMipToArrayMip(srcTex2D, srcMipLevel, dstArrayTex, dstMipLevel, dstZIndex) {
  // 获取源Mip层级的实际尺寸
  gl.bindTexture(gl.TEXTURE_2D, srcTex2D);
  const baseWidth = gl.getTexParameter(gl.TEXTURE_2D, gl.TEXTURE_WIDTH);
  const baseHeight = gl.getTexParameter(gl.TEXTURE_2D, gl.TEXTURE_HEIGHT);
  const mipWidth = baseWidth >> srcMipLevel;
  const mipHeight = baseHeight >> srcMipLevel;

  // 将源纹理的指定Mip层级绑定到帧缓冲
  gl.bindFramebuffer(gl.FRAMEBUFFER, fbo);
  gl.framebufferTexture2D(
    gl.FRAMEBUFFER,
    gl.COLOR_ATTACHMENT0,
    gl.TEXTURE_2D,
    srcTex2D,
    srcMipLevel
  );

  // 调试用:检查帧缓冲完整性(发布环境可移除)
  if (gl.checkFramebufferStatus(gl.FRAMEBUFFER) !== gl.FRAMEBUFFER_COMPLETE) {
    console.error("Framebuffer incomplete when copying mip level");
    return;
  }

  // 执行复制操作
  gl.bindTexture(gl.TEXTURE_2D_ARRAY, dstArrayTex);
  gl.copyTexSubImage3D(
    gl.TEXTURE_2D_ARRAY,
    dstMipLevel,
    0, 0, dstZIndex, // 目标纹理的偏移(x,y,z)
    0, 0, // 帧缓冲的源偏移(因尺寸匹配,设为0)
    mipWidth, mipHeight // 复制的像素尺寸
  );

  // 解绑资源,避免干扰后续操作
  gl.bindFramebuffer(gl.FRAMEBUFFER, null);
  gl.bindTexture(gl.TEXTURE_2D_ARRAY, null);
  gl.bindTexture(gl.TEXTURE_2D, null);
}

注意事项

  • 确保源2D纹理已生成完整Mip链:在更新2D纹理后,调用gl.generateMipmap(gl.TEXTURE_2D)生成所有Mip层级
  • 频繁更新场景下,尽量复用帧缓冲对象,避免重复创建销毁带来的性能开销
  • 在Three.js中,可通过texture.__webglTexture获取底层WebGL纹理对象,但操作时需注意避开Three.js的内部纹理更新逻辑,防止冲突

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.16 23:52:08