Three.js程序化星球开发报WebGL: INVALID_VALUE: texImage2D: no canvas错求解
问题原因
这个报错是新版Three.js的API校验逻辑和旧版不一致导致的,核心问题有4个:
- 你在
generate_maps函数中往textures数组存入的是THREE.WebGLRenderTarget实例,但是ShaderMaterial的uniform接收的纹理需要是RenderTarget实例的.texture属性,旧版Three.js会隐式转换,新版已经移除了这个兼容逻辑,所以纹理读取失败触发no canvas报错。 - 你创建RenderTarget时指定了
format: THREE.RGBFormat,但后续调用gl.readPixels时读取的是gl.RGBA格式,通道数不匹配导致bump纹理数据异常。 - 你手动构造的bump数据对象不符合Three.js纹理要求,Three.js的bumpMap参数要求传入
THREE.Texture类的实例(比如DataTexture/CanvasTexture),不能直接传入自定义的带buffer的对象。 - 纹理参数配置错误导致无法生成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
相关产品推荐
相关产品推荐

