【问题标题】:Three.js "THREE.EffectComposer relies on THREE.ShaderPass" issueThree.js“THREE.EffectComposer 依赖于 THREE.ShaderPass”问题
【发布时间】:2021-05-27 20:03:49
【问题描述】:

您好,我是 three.js 的大新手,我正在尝试使用效果合成器功能,以便使用 UnrealBloomPass.js 在我的对象上实现绽放效果。不幸的是,我遇到了几个与效果器中的 THREE.ShaderPass 相关的错误,由于缺乏经验,我不知道如何解决它们。有人可以帮帮我吗?

这是我的代码:

// Canvas Setup
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();

// Geometry Settings
const loader = new THREE.GLTFLoader().setPath("./");
loader.load("assets/model.glb", (gltf) =>{
    root1 = gltf.scene;
    scene.add(root1);
});

loader.load("assets/model2.glb", (gltf) =>{
    root2 = gltf.scene;
    scene.add(root2);
});

// 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
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 );
    
    root1.rotation.y += 0.002;
    root2.rotation.y += 0.0035;
    controls.update()
    // renderer.render( scene, camera );
    composer.render(delta);
}
animate();
<script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/r128/three.min.js"></script>
<!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="build/three.min.js"></script>
    <script src="build/OrbitControls.js"></script>
    <script src="build/GLTFLoader.js"></script>
    <script src="build/EffectComposer.js"></script>
    <script src="build/RenderPass.js"></script>
    <script src="build/UnrealBloomPass.js"></script>
    <script src="exp.js"></script>

</body>
</html>

【问题讨论】:

  • build/EffectComposer.js 文件说明了什么?我敢打赌它会尝试使用你没有包含的元素,比如 CopyShaderShaderPass
  • @Marquizzo 是的,我认为你是对的,在 chrome 中查看问题部分似乎是这样的:if ( THREE.CopyShader === undefined ) {console.error( 'THREE.EffectComposer relies on THREE.CopyShader' );}if ( THREE.ShaderPass === undefined ) {if ( THREE.ShaderPass === undefined ) {console.error( 'THREE.EffectComposer relies on THREE.ShaderPass' );}this.copyPass = new THREE.ShaderPass( THREE.CopyShader );@987654334 @ 也为糟糕的格式感到抱歉,我对堆栈溢出是全新的。你可以在原来的 EffectComposer.js 文件中找到这个 sn-p
  • 是的,你必须在你的脚本标签中包含这些。
  • 啊,好的,非常感谢@Marquizzo,我确实添加了Pass.jsLuminosityHighPassShader.js,但总的来说它工作得很好,再次非常感谢你

标签: javascript three.js webgl


【解决方案1】:

问题是EffectComposer.js 脚本无法访问它需要的正确元素(即THREE.ShaderPass)。

要解决此问题,您只需在 JavaScript/HTML 文件中导入 EffectComposer 脚本所需的文件,以便读取所需的缺失元素。以这种方式导入的某些文件可能需要它们自己的导入元素(即ShaderPass.js 需要来自Pass.js 的元素),因此请确保以正确的顺序导入它们,以便可以最后读取需要附加元素的 js 文件和那些需要导入其他脚本可以先读取。

请参阅下面的更改代码(主要是 HTML 文件):

// Canvas Setup
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( 0x0c023d, 1);
    const fov = 12;
    const aspect = width/height;
    const near = 0.1;
    const far = 20;
const camera = new THREE.PerspectiveCamera(fov, aspect, near, far);
camera.position.z = 10;  
const scene = new THREE.Scene();

// Geometry Settings
const loader = new THREE.GLTFLoader().setPath("./");
loader.load("assets/model.glb", (gltf) =>{
    root1 = gltf.scene;
    root1.name = 'world';
    scene.add(root1);
});

loader.load("assets/model2.glb", (gltf) =>{
    root2 = gltf.scene;
    root2.name = 'clouds';
    scene.add(root2);
});
loader.load("assets/house.glb", (gltf) =>{
    root3 = gltf.scene;
    root3.name = 'house';
    scene.add(root3);
});
loader.load("assets/city.glb", (gltf) =>{
    root4 = gltf.scene;
    root4.name = 'city';
    scene.add(root4);
});

// const geometry = new THREE.BoxGeometry();
// const material = new THREE.MeshBasicMaterial( { color: 0x00ff00 } );
// const cube = new THREE.Mesh( geometry, material );
// cube.scale.y = 3;
// scene.add( cube );

// 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);


// Orbit Controls
controls = new THREE.OrbitControls(camera, renderer.domElement);
controls.enableZoom = true;
controls.enablePan = false;
controls.maxDistance = 12;
controls.minDistance = 1.3;
controls.maxPolarAngle = 2.5;
controls.minPolarAngle = .5;
controls.enableDamping = true;
controls.update();

// Hover Controls
const raycaster = new THREE.Raycaster();
const pointer = new THREE.Vector2();
let INTERSECTED;

document.addEventListener( 'mousemove', onPointerMove );

function onPointerMove( event ) {
    pointer.x = ( event.clientX / window.innerWidth ) * 2 - 1;
    pointer.y = - ( event.clientY / window.innerHeight ) * 2 + 1;
}

function hoverObj() {
    raycaster.setFromCamera( pointer, camera );
    const intersects = raycaster.intersectObjects( scene.children );
    if ( intersects.length > 0 ) {
        if ( INTERSECTED != intersects[ 0 ].object ) {
            if ( INTERSECTED ) INTERSECTED.material.emissive.setHex( INTERSECTED.currentHex );
            console.log("yo")
            var INTERSECTED = intersects[ 0 ].object;
            
        }else{
            
        }
    }
}
// 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 = .5;
    bloomPass.strength = 3;
    bloomPass.radius = 1;
composer.addPass(bloomPass);

// Resize Window Function
window.addEventListener('resize', onWindowResize, false);
function onWindowResize() {
    camera.aspect = window.innerWidth / window.innerHeight;
    renderer.setSize(window.innerWidth, window.innerHeight);
    camera.updateProjectionMatrix();
};

// Animation
function animate() {
    // var delta = clock.getDelta();
    requestAnimationFrame( animate );
    scene.getObjectByName(root1.name).rotation.y += 0.002;
    scene.getObjectByName(root3.name).rotation.y += 0.002;
    scene.getObjectByName(root4.name).rotation.y += 0.002;
    scene.getObjectByName(root2.name).rotation.y += 0.0035;
    controls.update();
    hoverObj();
    objrender();
}
// Render
function objrender(){
    // renderer.render( scene, camera );
    composer.render();
}
animate();
<!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="build/three.min.js"></script>
    <!-- required for ShaderPass -->
    <script src="build/Pass.js"></script>
    <!-- both scripts required for EffectComposer  -->
    <script src="build/ShaderPass.js"></script>
    <script src="build/CopyShader.js"></script>
    <!-- required for UnrealBloomPass -->
    <script src="build/LuminosityHighPassShader.js"></script>
    <!-- the main functions i want to use -->
    <script src="build/OrbitControls.js"></script>
    <script src="build/GLTFLoader.js"></script>
    <script src="build/EffectComposer.js"></script>
    <script src="build/RenderPass.js"></script>
    <script src="build/UnrealBloomPass.js"></script>
    <!-- main three.js script -->
    <script src="exp.js"></script>

</body>
</html>

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2012-05-23
    • 2011-08-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-07-12
    • 2020-08-13
    • 2012-12-29
    相关资源
    最近更新 更多