林安随笔 - Threejs
type: channel
link: https://www.yuaq.cn/index.php/category/Threejs/
items: threejs 学习（模型点击高亮）
items: threejs 学习（基础配置）

threejs 学习（模型点击高亮）
type: item
date: 2024-06-11T13:04:00+08:00
description: 前言：threejs实现导入模型，点击模型，被点击模型出现呼吸灯描边效果，主要使用threejs后处理模块实现使用技术：vue3+threejs@0.165.0效果图：引入使用库import * as THREE from 'three'; // threejs import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls'; // 控制器 import { GLTFLoader } from 'three/examples/jsm/loaders/GLTFLoader'; // gltf/glb模型加载器 import { RGBELoader } from 'three/examples/jsm/loaders/RGBELoader'; // hdr环境贴图加载器 import { EffectComposer } from "three/examples/jsm/postprocessing/EffectComposer"; // 后期效果合成器 import { RenderPass } from "three/examples/jsm/postprocessing/RenderPass"; // 后期通道效果 import { OutlinePass } from "three/examples/jsm/postprocessing/OutlinePass"; // 发光描边 import { ShaderPass } from "three/examples/jsm/postprocessing/ShaderPass"; // 着色器 import { FXAAShader } from "three/examples/jsm/shaders/FXAAShader"; // 抗锯齿后处理 import { SMAAPass } from "three/examples/jsm/postprocessing/SMAAPass"; // 抗锯齿后处理 import { GammaCorrectionShader } from "three/examples/jsm/shaders/GammaCorrectionShader"; // 后处理颜色 伽马校正定义全局变量let camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000), scene = new THREE.Scene(), renderer = new THREE.WebGLRenderer({ antialias: true }), controls, smaaPass, raycaster = new THREE.Raycaster(), mouse, composer, renderPass, outlinePass;点击事件// 点击事件 const onDocumentMouseDown = (event) => { // 将鼠标位置转换成归一化设备坐标(-1 到 +1) mouse = new THREE.Vector2(); mouse.x = (event.clientX / window.innerWidth) * 2 - 1; mouse.y = - (event.clientY / window.innerHeight) * 2 + 1; // 使用鼠标的位置和当前相机的矩阵来更新射线 raycaster.setFromCamera(mouse, camera); // 计算物体和射线的交点 let intersects = raycaster.intersectObjects(scene.children); if (intersects.length != 0 && intersects[0].object instanceof THREE.Mesh) { outlineObj([intersects[0].object]) // 判断点击到模型，触发高亮效果 animate() } } // 双击事件 const onDocumentDoubleClick = () => { // 取消高亮显示 composer = null }高亮效果实现// 高亮显示模型（呼吸灯） const outlineObj = (selectedObjects) => { // 创建一个EffectComposer（效果组合器）对象，然后在该对象上添加后期处理通道。 composer = new EffectComposer(renderer)…

threejs 学习（基础配置）
type: item
date: 2024-06-11T13:00:00+08:00
description: 前言：threejs入门，场景贴图、模型引入技术：vue3+three@0.165.0依赖引入import * as THREE from 'three'; import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls'; import { GLTFLoader } from 'three/examples/jsm/loaders/GLTFLoader'; import { RGBELoader } from 'three/examples/jsm/loaders/RGBELoader';代码let camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000), scene = new THREE.Scene(), renderer = new THREE.WebGLRenderer({ antialias: true }), controls； // 初始化场景 const initScene = () => { setEnvMap(); loadGltf('three/01.glb', [0, -20, 0], [0, 0, 0], [0.1, 0.1, 0.1], 'three/01.jpg') loadGltf('three/02.glb', [-20, -19, 0], [0, 0, 0], [10, 10, 10], 'three/02.png') } // 场景设置 const setEnvMap = () => { new RGBELoader().load(`three/001.hdr`, (texture) => { texture.mapping = THREE.EquirectangularRefractionMapping; scene.background = texture; scene.environment = texture; }, // 加载失败的回调 (xhr) => { console.error(xhr); } ); } // 加载gltf/glb模型 const loadGltf = (url, position, rotation, scale, textureUrl) => { const gltfLoader = new GLTFLoader(); gltfLoader.load(url, (gltf) => { let model = gltf.scene; if (textureUrl) { const textureLoader = new THREE.TextureLoader(); const texture = textureLoader.load(textureUrl); model.traverse((child) => { if (child instanceof THREE.Mesh) { child.material.map = texture; } }); } model.position.set(position[0], position[1], position[2]); model.rotation.set(rotation[0], rotation[1], rotation[2]); model.scale.set(scale[0], scale[1], scale[2]); scene.add(model); }); } // 相机 const initCamera = () => { camera.position.set(0, 28, 10); camera.lookAt(0, 0, 1); } // 渲染器 const initRenderer = () => { renderer.setSize(window.innerWidth, window.innerHeight); document.body.appendChild(renderer.domElement); } // 控制器 const initControls = () => { controls = new OrbitControls(camera, renderer.domElement); controls.dampingFactor = 0.25; controls.minDistance = 10; controls.maxDistance = 50; controls.maxPolarAngle = Math.PI / 2; controls.minPola…