Three.js使用EffectComposer实现UnrealBloomPass bloom效果报THREE.ShaderPass错求助
问题修复方案
- 版本不匹配&重复引入核心库
你的HTML里同时引入了CDN的r128版本Three.js和本地build目录下的Three.js,重复加载会导致全局THREE对象冲突,且本地的OrbitControls、EffectComposer等插件如果和核心库版本不一致,就会触发ShaderPass相关的报错。删除任意一个Three.js引入,确保所有插件版本和核心库版本完全一致。 - 缺失Clock实例声明
渲染函数中调用了clock.getDelta(),但代码中没有初始化Clock实例,在渲染逻辑前添加const clock = new THREE.Clock()即可。 - 异步加载资源访问报错
root1、root2仅在GLTF模型加载完成的回调中赋值,animate函数执行时如果模型还未加载完成,访问undefined的rotation属性会触发报错。可以给root1、root2加初始空值判断,或者在模型全部加载完成后再执行animate函数。 - HTML结构错误
你将Three.js的CDN引入放在了<!DOCTYPE html>之前,会导致浏览器解析异常,将所有外部资源引入都放在body标签末尾、自定义js之前即可。 - 缺失EffectComposer依赖文件
r128版本的EffectComposer运行依赖ShaderPass.js和CopyShader.js两个文件,你没有在HTML中引入这两个依赖,需要先于EffectComposer引入。
修正后代码参考
JS 部分
// Canvas Setup const clock = new THREE.Clock() // 新增Clock声明 const canvas = document.querySelector("#canv") const width = window.innerWidth; const height = window.innerHeight; const renderer = new THREE.WebGLRenderer({canvas}); renderer.setSize( width, height ); renderer.setClearColor( 0x111, 1); const fov = 100; const aspect = width/height; const near = 0.1; const far = 5; const camera = new THREE.PerspectiveCamera(fov, aspect, near, far); camera.position.z = 2; const scene = new THREE.Scene(); // 初始化root变量避免未定义 let root1 = null, root2 = null let modelLoadedCount = 0 const checkAllLoaded = () => { modelLoadedCount++ if(modelLoadedCount === 2) animate() // 模型全部加载完成才启动渲染 } // Geometry Settings const loader = new THREE.GLTFLoader().setPath("./"); loader.load("assets/model.glb", (gltf) =>{ root1 = gltf.scene; scene.add(root1); checkAllLoaded() }); loader.load("assets/model2.glb", (gltf) =>{ root2 = gltf.scene; scene.add(root2); checkAllLoaded() }); // Lighting const light1 = new THREE.DirectionalLight(0x404040); const light2 = new THREE.AmbientLight(0x404040); light1.position.y = 2; light1.position.z = 2; light1.intensity = 2; light1.shadowDarkness = .1 light2.position.y = -2; light2.position.z = -2; light2.intensity = 2; light2.shadowDarkness = .1 scene.add(light1); scene.add(light2); // Controls const controls = new THREE.OrbitControls(camera, renderer.domElement); // 补全变量声明 controls.enableZoom = true; controls.enablePan = false; controls.maxDistance = 2; controls.minDistance = 1.3; controls.maxPolarAngle = 2.5; controls.minPolarAngle = .5; controls.enableDamping = true; controls.update(); // Effect Composer const composer = new THREE.EffectComposer(renderer); composer.addPass(new THREE.RenderPass(scene, camera)); const bloomPass = new THREE.UnrealBloomPass( new THREE.Vector2( window.innerWidth, window.innerHeight ), 1.5, 0.4, 0.85 ); bloomPass.threshold = 0; bloomPass.strength = 3; bloomPass.radius = 1; composer.addPass(bloomPass); // Render function animate() { var delta = clock.getDelta(); requestAnimationFrame( animate ); if(root1) root1.rotation.y += 0.002; if(root2) root2.rotation.y += 0.0035; controls.update() composer.render(delta); }
HTML 部分
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> </head> <body> <canvas id="canv"></canvas> <!-- 统一使用同一版本的依赖,删除重复引入 --> <script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/r128/three.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/r128/examples/js/controls/OrbitControls.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/r128/examples/js/loaders/GLTFLoader.js"></script> <!-- 新增缺失的EffectComposer依赖 --> <script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/r128/examples/js/postprocessing/ShaderPass.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/r128/examples/js/shaders/CopyShader.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/r128/examples/js/postprocessing/EffectComposer.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/r128/examples/js/postprocessing/RenderPass.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/r128/examples/js/postprocessing/UnrealBloomPass.js"></script> <script src="exp.js"></script> </body> </html>
内容的提问来源于stack exchange,提问作者L4Chl4N
相关产品推荐
相关产品推荐

