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

创建WebGL纹理时从颜色缓冲区更新失败问题排查

WebGL纹理创建时调用texSubImage2D失败,更新时却成功的原因分析

问题背景

我有一个WebGL纹理,最初用图像像素填充。现在想用颜色数组清空它,编写了createGLTexture函数创建2D纹理,但传入颜色数据时触发错误:

Uncaught TypeError: Failed to execute 'texSubImage2D' on 'WebGL2RenderingContext': Overload resolution failed.at createGLTexture

但使用updateGLTexture函数在纹理创建后更新颜色却能成功实现蓝色清空,疑惑为何创建时调用texSubImage2D失败,两者调用逻辑是否存在差异?

创建纹理函数代码

function createGLTexture(gl, format,intFormat, w, h,wrapType, flip, genMipmaps, data)
{
  var texture = gl.createTexture();
  gl.bindTexture(gl.TEXTURE_2D, texture);
  gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, flip);
  gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR);
  gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S,wrapType);
  gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T,wrapType);
  if (genMipmaps === true)
  {
    gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR_MIPMAP_LINEAR);
    gl.texStorage2D(gl.TEXTURE_2D, 1, intFormat, w, h);
  } else
  {
    gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR);
    gl.texStorage2D(gl.TEXTURE_2D, 1, intFormat, w, h);
  }

  if (data != null) {
    gl.texSubImage2D(gl.TEXTURE_2D, 0, 0, 0, format, gl.UNSIGNED_BYTE, data);
  }

  if (genMipmaps === true) {
    gl.generateMipmap(gl.TEXTURE_2D);
  }

   return texture;
}

初始化颜色代码

//img - 已预加载的图像
var colorData = new Uint8Array(img.width * img.height * 3);
for(var i = 0; i < colorData.length;i+=3)
{
colorData[i] = 0;
colorData[i + 1] = 0;
colorData[i + 2] = 255;
} 
var tex = createGLTexture(gl,gl.RGB,gl.RGB8,img.width,img.height,gl.CLAMP_TO_EDGE,false,false,colorData);

更新纹理函数代码

function updateGLTexture(gl,texture, format,w,h, genMipmaps, data)
{
   gl.bindTexture(gl.TEXTURE_2D, texture);
   gl.texSubImage2D(gl.TEXTURE_2D, 0, 0, 0,w,h, format, gl.UNSIGNED_BYTE, data);
   if (genMipmaps === true)
   {
     gl.generateMipmap(gl.TEXTURE_2D);
   }
   gl.bindTexture(gl.TEXTURE_2D, null);
}

核心原因:参数缺失导致重载不匹配

你在createGLTexture中调用texSubImage2D时,缺少了宽度和高度参数,而updateGLTexture中的调用参数是完整的。

WebGL2中,当使用TypedArray作为像素数据时,texSubImage2D的正确参数顺序必须包含更新区域的宽高:

gl.texSubImage2D(target, level, xoffset, yoffset, width, height, format, type, pixels);

createGLTexture里的调用跳过了width和height,导致WebGL无法匹配到正确的API重载,触发类型错误;而updateGLTexture中传入了w和h,参数完全匹配,因此执行成功。

解决方案

修改createGLTexture中texSubImage2D的调用,补充宽高参数:

if (data != null) {
  gl.texSubImage2D(gl.TEXTURE_2D, 0, 0, 0, w, h, format, gl.UNSIGNED_BYTE, data);
}

额外说明

即便已经通过texStorage2D为纹理分配了存储空间,使用TypedArray更新纹理时,texSubImage2D仍需明确指定宽高参数——这是WebGL2 API的强制要求,与纹理是否已初始化存储空间无关。

内容的提问来源于stack exchange,提问作者Michael IV

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.03 07:32:06