javascript - Three.js“THREE.EffectComposer 依赖于 THREE.ShaderPass”问题
问题描述
嗨,我是 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>
解决方案
问题是EffectComposer.js
脚本无法访问它需要的正确元素(即THREE.ShaderPass
)。
要解决此问题,您只需在 JavaScript/HTML 文件中导入 EffectComposer 脚本所需的文件,以便可以读取所需的缺失元素。以这种方式导入的某些文件可能需要它们自己的导入元素(即ShaderPass.js
需要来自 的元素Pass.js
),因此请确保以正确的顺序导入它们,以便可以最后读取需要附加元素的 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>
推荐阅读
- c# - 无法在 ORACLE 存储过程中提取 XML 节点值
- python - 使用发布请求python获取购物车项目
- firebase - 非用户数据的firebase实时数据库安全规则
- html - AngularJS在第一次初始点击后重复自动点击按钮
- javascript - 如何根据最高 z-index 获取元素属性
- python - 在返回差异天数的 Dataframe 中减去两个日期
- python - Python pandas 在输出 csv 文件中保留十进制逗号
- android - 直接回复按钮不发送广播意图
- python - Python有时无法将字符串转换为浮点数
- git - 如何处理功能分支差异创建