WebGL创建天空盒报错texture referenced by sampler cube isnot renderable求助
错误触发原因与修复方案
报错核心是你创建的立方体贴图不符合WebGL的可渲染要求,具体问题和修复方法如下:
问题1:事件回调名称大小写错误
JS中图片加载完成的回调属性名是全小写的onload,你代码中写的onLoad不会被触发,导致没有任何一张纹理被写入到立方体贴图中,空纹理自然不可渲染。
问题2:复用同一个Image对象导致加载异常
你在循环外只创建了一个Image实例,循环中反复给src赋值会中断上一张还没完成的图片请求,最终最多只能加载到最后一张纹理,无法凑齐立方体贴图必须的6个面。同时异步回调里的i变量会出现闭包问题,即使加载完成也会把纹理写到错误的立方体贴图层上。
问题3:纹理参数设置时机错误
你在循环结束后立刻设置纹理参数、执行渲染,此时所有图片都是异步加载中,6个立方体贴图面还没有被填充,WebGL会判定纹理不完整无法渲染。
问题4:纹理尺寸不匹配(潜在问题)
立方体贴图要求6个面的宽高必须完全相等,否则也会触发不可渲染错误。
修复后的代码示例
const cubeImageSources = [ "grimmnight_bk.jpg", "grimmnight_dn.jpg", "grimmnight_ft.jpg", "grimmnight_lf.jpg", "grimmnight_rt.jpg", "grimmnight_up.jpg", ]; let cubeMapTexture = gl.createTexture(); gl.activeTexture(gl.TEXTURE1); gl.bindTexture(gl.TEXTURE_CUBE_MAP, cubeMapTexture); // 统计加载完成的图片数量 let loadedCount = 0; for (let i = 0; i < cubeImageSources.length; i++) { // 每个面单独创建Image实例 const indexedImage = new Image(); indexedImage.crossOrigin = ""; indexedImage.onload = function() { gl.texImage2D( gl.TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, indexedImage ); loadedCount++; // 6张图全部加载完成后再设置纹理参数,触发渲染 if (loadedCount === 6) { gl.texParameteri(gl.TEXTURE_CUBE_MAP, gl.TEXTURE_MAG_FILTER, gl.LINEAR); gl.texParameteri(gl.TEXTURE_CUBE_MAP, gl.TEXTURE_MIN_FILTER, gl.LINEAR); gl.texParameteri(gl.TEXTURE_CUBE_MAP, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE); gl.texParameteri(gl.TEXTURE_CUBE_MAP, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE); // 在这里调用你的渲染函数,确保纹理就绪后再渲染 render(); } } indexedImage.src = `${window.location.origin}/game/images/texture/${cubeImageSources[i]}`; }
你原有着色器和uniform赋值逻辑无需改动,只需保证所有渲染逻辑都在6张纹理加载完成后执行即可。
内容的提问来源于stack exchange,提问作者Pravin Poudel
相关产品推荐
相关产品推荐

