使用前请先到three.JS官网下载所需文件,如在使用引用的文件时,控制台报以下错误:Uncaught TypeError: Failed to resolve module specifier "three.js". Relative references must start with either "/", "./", or "../".
需要到引用的文件中第一句 import...from three 这里,将three修改为../../../build/three.module.js(找到自己文件路径下的three.module.js)
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Three.js引用obj文件与mtl材质,并为模型添加点击事件的呼吸灯效果</title>
</head>
<body>
</body>
<script type="module">
draw();
import * as THREE from './file/three.js-master/build/three.module.js'
import { OrbitControls } from './file/three.js-master/examples/jsm/controls/OrbitControls.js'
import { OBJLoader } from './file/three.js-master/examples/jsm/loaders/OBJLoader.js'
import { MTLLoader } from './file/three.js-master/examples/jsm/loaders/MTLLoader.js'
import { EffectComposer } from './file/three.js-master/examples/jsm/postprocessing/EffectComposer.js'
import { RenderPass } from './file/three.js-master/examples/jsm/postprocessing/RenderPass.js'
import { OutlinePass } from './file/three.js-master/examples/jsm/postprocessing/OutlinePass.js'
import { ShaderPass } from './file/three.js-master/examples/jsm/postprocessing/ShaderPass.js'
import { FXAAShader } from './file/three.js-master/examples/jsm/shaders/FXAAShader.js'
import { GammaCorrectionShader } from './file/three.js-master/examples/jsm/shaders/GammaCorrectionShader.js';
var renderer;
var container, stats;
var camera, scene, renderer, controls, light;
var composer, effectFXAA, outlinePass;
let selectedObjects = [];
const raycaster = new THREE.Raycaster();
const mouse = new THREE.Vector2();
const obj3d = new THREE.Object3D();
const group = new THREE.Group();
function init() {
container = document.createElement('div');
document.body.appendChild(container);
const width = window.innerWidth;
const height = window.innerHeight;
scene = new THREE.Scene();
renderer = new THREE.WebGLRenderer();
renderer.shadowMap.enabled = true;
renderer.setClearColor(0x000000);
renderer.setSize(width, height);
document.body.appendChild(renderer.domElement);
scene = new THREE.Scene();
scene.add(new THREE.AmbientLight(0xffffff));
light = new THREE.PointLight
(0xffffff);
light.position.set(0, 10, 0);
//告诉平行光需要开启阴影投射
light.castShadow = false;
scene.add(light);
camera = new THREE.PerspectiveCamera(90, window.innerWidth / window.innerHeight, 0.1, 100, 1);
camera.position.set(-20, 20, 20); //设置相机位置
camera.lookAt(scene.position); //设置相机方向(一般都是指向的场景对象(中心))
//辅助工具
var helper = new THREE.AxesHelper(0);
scene.add(helper);
var mtlLoader = new MTLLoader();
//加载mtl文件
mtlLoader.load('./obj/ces.mtl', function (material) {
var objLoader = new OBJLoader();
//设置当前加载的纹理
objLoader.setMaterials(material);
// objLoader.setPath('/lib/assets/models/');
objLoader.load('./obj/ces.obj', function (object) {
//将模型缩放并添加到场景当中
object.scale.set(5, 5, 5);
scene.add(object);
})
});
// 可加可不加
// scene.add(group);
// group.add(obj3d);
composer = new EffectComposer(renderer);
const renderPass = new RenderPass(scene, camera);
composer.addPass(renderPass);
outlinePass = new OutlinePass(new THREE.Vector2(window.innerWidth, window.innerHeight), scene, camera);
composer.addPass(outlinePass);
outlinePass.visibleEdgeColor.set(0x0000ff);
//高亮发光描边厚度
outlinePass.edgeThickness = 1;
//高亮描边发光强度
outlinePass.edgeStrength = 10;
//模型闪烁频率控制,默认0不闪烁
outlinePass.pulsePeriod = 1;
effectFXAA = new ShaderPass(FXAAShader);
effectFXAA.uniforms['resolution'].value.set(1 / window.innerWidth, 1 / window.innerHeight);
// 解决使用outlinePass产生色差问题
const effectColorSpaceConversion = new ShaderPass(GammaCorrectionShader);
composer.addPass(effectColorSpaceConversion);
composer.addPass(effectFXAA);
renderer.domElement.style.touchAction = 'none';
// renderer.domElement.addEventListener('pointermove', onPointerMove); 鼠标悬浮
renderer.domElement.addEventListener('click', onPointerMove); //鼠标点击
function onPointerMove(event) {
// if (event.isPrimary === false) return; 如果是点击事件 注释这句话
mouse.x = (event.clientX / window.innerWidth) * 2 - 1;
mouse.y = - (event.clientY / window.innerHeight) * 2 + 1;
checkIntersection();
}
function addSelectedObject(object) {
selectedObjects = [];
selectedObjects.push(object);
}
function checkIntersection() {
raycaster.setFromCamera(mouse, camera);
const intersects = raycaster.intersectObject(scene, true);
if (intersects.length > 0) {
const selectedObject = intersects[0].object;
addSelectedObject(selectedObject);
outlinePass.selectedObjects = selectedObjects;
} else {
outlinePass.selectedObjects = [];
}
}
}
//用户交互插件 鼠标左键按住旋转,右键按住平移,滚轮缩放
var controls;
function initControls() {
controls = new OrbitControls(camera, renderer.domElement);
// 如果使用animate方法时,将此函数删除
//controls.addEventListener( 'change', render );
// 使动画循环使用时阻尼或自转 意思是否有惯性
controls.enableDamping = true;
//动态阻尼系数 就是鼠标拖拽旋转灵敏度
//controls.dampingFactor = 0.25;
//是否可以缩放
controls.enableZoom = true;
//是否自动旋转
controls.autoRotate = false;
//设置相机距离原点的最远距离
controls.minDistance = 1;
//设置相机距离原点的最远距离
controls.maxDistance = 200;
//是否开启右键拖拽
controls.enablePan = true;
}
function render() {
renderer.render(scene, camera);
}
//窗口变动触发的函数
function onWindowResize() {
camera.aspect = window.innerWidth / window.innerHeight;
camera.updateProjectionMatrix();
render();
renderer.setSize(window.innerWidth, window.innerHeight);
}
function animate() {
requestAnimationFrame(animate);
const timer = performance.now();
composer.render();
}
function draw() {
init()
animate();
initControls();
window.onresize = onWindowResize;
}
</script>
</html>