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

Three.js程序化星球开发报WebGL: INVALID_VALUE: texImage2D: no canvas错求解

问题原因

这个报错是新版Three.js的API校验逻辑和旧版不一致导致的,核心问题有4个:

  1. 你在generate_maps函数中往textures数组存入的是THREE.WebGLRenderTarget实例,但是ShaderMaterial的uniform接收的纹理需要是RenderTarget实例的.texture属性,旧版Three.js会隐式转换,新版已经移除了这个兼容逻辑,所以纹理读取失败触发no canvas报错。
  2. 你创建RenderTarget时指定了format: THREE.RGBFormat,但后续调用gl.readPixels时读取的是gl.RGBA格式,通道数不匹配导致bump纹理数据异常。
  3. 你手动构造的bump数据对象不符合Three.js纹理要求,Three.js的bumpMap参数要求传入THREE.Texture类的实例(比如DataTexture/CanvasTexture),不能直接传入自定义的带buffer的对象。
  4. 纹理参数配置错误导致无法生成mipmap:默认情况下Three.js纹理会开启mipmap生成,但若纹理没有正确初始化,就会触发Can not generate mips的报错。

解决步骤

  • 第一步:修改generate_maps中往textures数组存值的逻辑,改为存入RenderTarget的texture属性:
// 原代码
textures.push( texture );
// 替换为
textures.push( texture.texture );
  • 第二步:统一RenderTarget和readPixels的通道格式,建议把RenderTarget的配置改为RGBA格式:
var texture = new THREE.WebGLRenderTarget( resolution, resolution, { 
    minFilter : THREE.LinearFilter, 
    magFilter : THREE.LinearFilter, 
    format : THREE.RGBAFormat // 从RGBFormat改为RGBAFormat
} );
  • 第三步:把bump的buffer转为Three.js的DataTexture实例:
// 原代码
bumps.push( {
    image :
    {
        data   : buffer,
        height : resolution,
        width  : resolution
    }
} );
// 替换为
const bumpTexture = new THREE.DataTexture(buffer, resolution, resolution, THREE.RGBAFormat, THREE.UnsignedByteType);
bumpTexture.needsUpdate = true;
bumps.push(bumpTexture);
  • 第四步:关闭不需要的mipmap生成(可选,如果你不需要mipmap可以加上,避免警告):
    给RenderTarget的纹理设置minFilter为LinearFilter,不需要mipmap:
texture.texture.minFilter = THREE.LinearFilter;
texture.texture.generateMipmaps = false;

另外你还要检查textures.water、textures.ground、textures.ice这三个渐变纹理是否正确初始化,没有正确赋值也会触发纹理不可渲染的警告。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.27 01:54:04