前言: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)
    // 新建一个场景通道  覆盖到原来的场景上
    renderPass = new RenderPass(scene, camera)
    composer.addPass(renderPass);
    // 物体边缘发光通道 --应用的宽高-应用的场景-应用的相机-应用的模型==计算位置
    outlinePass = new OutlinePass(new THREE.Vector2(window.innerWidth, window.innerHeight), scene, camera,
        selectedObjects)
    outlinePass.selectedObjects = selectedObjects
    outlinePass.edgeStrength = 10.0 // 边框的亮度
    outlinePass.edgeGlow = 1 // 光晕[0,1]
    outlinePass.usePatternTexture = false // 是否使用父级的材质
    outlinePass.edgeThickness = 1.0 // 边框宽度
    outlinePass.downSampleRatio = 1 // 边框弯曲度
    outlinePass.pulsePeriod = 2 // 呼吸闪烁的速度
    outlinePass.visibleEdgeColor.set(parseInt(0x00CCFF)) // 呼吸显示的颜色 0x00CCFF 0x00ff00
    outlinePass.hiddenEdgeColor = new THREE.Color(0, 0, 0) // 呼吸消失的颜色
    outlinePass.clear = true
    composer.addPass(outlinePass)
    // 自定义的着色器通道 作为参数
    let effectFXAA = new ShaderPass(FXAAShader)
    effectFXAA.uniforms.resolution.value.set(1 / window.innerWidth, 1 / window.innerHeight)
    effectFXAA.renderToScreen = true
    composer.addPass(effectFXAA)
    // 抗锯齿
    smaaPass = new SMAAPass();
    composer.addPass(smaaPass);
    // 创建伽马校正通道
    const gammaPass = new ShaderPass(GammaCorrectionShader);
    composer.addPass(gammaPass);
}
最后修改:2024 年 06 月 11 日
如果觉得我的文章对你有用,请随意赞赏