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

Three.js使用CubeCamera渲染反射报错Framebuffer与active Texture形成反馈循环

报错原因

你触发的GL_INVALID_OPERATION: Feedback loop formed between Framebuffer and active Texture是WebGL的原生限制:不允许对同一个纹理同时执行读写操作。
你在调用cubeCamera1.update(renderer, scene)时,CubeCamera会往cubeRenderTarget1里写入6个面的反射内容,但此时你的场景里的meshGLB的材质正好用了cubeRenderTarget1.texture作为envMap,就形成了「读写同一个纹理」的反馈循环,触发报错。

解决方案

最简单的处理方式是更新CubeCamera前临时隐藏使用反射材质的物体,更新完成后再恢复显示,调整后的代码如下:

// 先把meshGLB的作用域提上去,确保animate函数里能访问到
let meshGLB = null

const reflection=()=> {
  renderer.outputEncoding = THREE.sRGBEncoding; 
  cubeRenderTarget1 = new THREE.WebGLCubeRenderTarget( 256, {
    format: THREE.RGBFormat,
    generateMipmaps: true,
    minFilter: THREE.LinearMipmapLinearFilter,
    encoding: THREE.sRGBEncoding 
  });
  cubeCamera1 = new THREE.CubeCamera( .01, 10, cubeRenderTarget1 );
  cubeCamera1.position.z = 3
  cubeCamera1.position.y = -4
  reflectionMaterial = new THREE.MeshBasicMaterial( {
    envMap: cubeRenderTarget1.texture,
    color: 0x011111,
  });
}
reflection()

gltfLoader.load(
  '/exportPackages/sceneMaya.glb', 
  (gltf) => {   
    meshGLB= gltf.scene.children.find(child => child.name === 'mesh_0')
    meshGLB.material = reflectionMaterial 
    scene.add(gltf.scene)           
  })

const animate =()=> {
  requestAnimationFrame(animate)
  // 更新反射贴图前隐藏用了反射材质的模型
  if (meshGLB) meshGLB.visible = false
  cubeCamera1.update( renderer, scene )
  // 更新完恢复显示
  if (meshGLB) meshGLB.visible = true
  // 补全主场景渲染逻辑,原代码缺少这一步会导致场景无内容输出
  renderer.render(scene, camera)
}; 
animate()

如果场景内有多个需要使用反射材质的物体,可以把它们统一放到一个THREE.Group里,更新CubeCamera前统一隐藏整个组即可。如果需要更精细的渲染控制,也可以用Layers做分层渲染:给CubeCamera设置只渲染不需要反射的层,反射材质物体单独放一个层仅给主相机渲染,效果和临时隐藏一致。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.28 14:45:04