🔥Three.js轮廓线高亮神器来啦!自定义高亮选中效果只需一个类搞定!
在开发 Three.js 项目的过程中,很多人都会遇到这样一个需求------如何高亮选中某个物体?
我们希望用户点击一个模型,它能"亮起来",视觉上突出显示,这样不仅提升交互体验,也让整体项目看起来更"高级"。
🎯 本文将手把手带你封装一个支持多物体、可配置、易管理 的轮廓线系统,使用 Three.js 中的 OutlinePass
实现,只需一句话即可启用高亮选中效果!
✅ 轮廓线效果到底是啥?
轮廓线(Outline)是一种通过为选中的物体描边来增强视觉效果的技术。在 Three.js 中,我们可以借助 EffectComposer
与 OutlinePass
来实现。
如下图所示(官方示例) 👇,添加了轮廓线的物体会被边缘描边勾勒出来,非常醒目:
✨ 功能亮点
我们将封装成一个 CustomOutline
类,具有以下特点:
- ✅ 多物体高亮支持,可批量添加或删除选中对象
- ✅ 动态启用/禁用轮廓线效果(比如切换编辑/预览模式)
- ✅ 支持可配置参数(颜色、粗细、透明度等)
- ✅ 释放资源、自动清理引用,适配复杂项目
📦 核心依赖
你需要先安装/引入以下 Three.js 扩展:
js
import { EffectComposer } from 'three/examples/jsm/postprocessing/EffectComposer.js'
import { RenderPass } from 'three/examples/jsm/postprocessing/RenderPass.js'
import { OutlinePass } from 'three/examples/jsm/postprocessing/OutlinePass.js'
import { OutputPass } from 'three/examples/jsm/postprocessing/OutputPass.js'
🧠 类的核心结构一览
我们将封装一个 CustomOutline
类,支持以下方法:
方法名 | 功能说明 |
---|---|
addSelectedObjects(obj) |
添加高亮对象 |
removeSelectedObjects(obj) |
移除高亮对象 |
clearSelectedObjects() |
清除所有高亮 |
setOutlineParameters(options) |
设置描边参数 |
enable() / disable() |
启用/关闭描边 |
render() |
每帧渲染时调用 |
dispose() |
释放资源 |
setSize(width, height) |
自适应画布大小 |
📄 使用示例
js
// 初始化
const outline = new CustomOutline(scene, camera, renderer)
// 设置轮廓线参数
outline.setOutlineParameters({
edgeStrength: 5,
edgeThickness: 2,
visibleEdgeColor: '#00ffff',
})
// 添加选中高亮的物体
outline.addSelectedObjects(mesh)
// 渲染循环中调用
function animate() {
requestAnimationFrame(animate)
outline.render()
}
✅ 小提示 :你还可以动态设置 visibleEdgeColor
或 hiddenEdgeColor
来实现不同状态下的风格变化!
💡 适用场景
- 模型编辑器中的物体选中反馈
- 三维配置器中高亮显示部件
- 智慧矿山、数字孪生等系统中的对象标识
- 教学可视化、模型拆解引导
📁 完整源码
js
/**
* CustomOutline 类 - Three.js 的轮廓线效果管理器
* 提供了一个完整的轮廓线效果系统,支持:
* - 可配置的轮廓线参数(颜色、宽度、透明度等)
* - 多个物体的轮廓线效果
* - 独立控制物体的轮廓线效果
* - 动态启用/禁用轮廓线系统
*/
import * as THREE from 'three'
import { EffectComposer } from 'three/examples/jsm/postprocessing/EffectComposer.js'
import { RenderPass } from 'three/examples/jsm/postprocessing/RenderPass.js'
import { OutlinePass } from 'three/examples/jsm/postprocessing/OutlinePass.js'
import { OutputPass } from 'three/examples/jsm/postprocessing/OutputPass.js'
/**
* 默认的轮廓线效果参数配置
*/
const DEFAULT_OUTLINE_OPTIONS = {
edgeStrength: 3.0, // 轮廓线强度
edgeGlow: 0.0, // 轮廓线发光强度
edgeThickness: 1.0, // 轮廓线粗细
pulsePeriod: 0, // 轮廓线闪烁周期(0为不闪烁)
usePatternTexture: false, // 是否使用纹理
visibleEdgeColor: new THREE.Color(0xffffff), // 可见部分轮廓线颜色
hiddenEdgeColor: new THREE.Color(0x190a05), // 被遮挡部分轮廓线颜色
opacity: 1.0, // 轮廓线透明度
}
export default class CustomOutline {
/**
* 创建一个新的轮廓线效果实例
* @param {THREE.Scene} scene - Three.js 场景实例
* @param {THREE.Camera} camera - Three.js 相机实例
* @param {THREE.WebGLRenderer} renderer - Three.js 渲染器实例
*/
constructor(scene, camera, renderer) {
this._scene = scene
this._camera = camera
this._renderer = renderer
this._selectedObjects = []
this._enabled = true
this._initOutlineEffect()
}
/**
* 初始化轮廓线效果的各个组件
* @private
*/
_initOutlineEffect() {
// 创建效果合成器
this._composer = new EffectComposer(this._renderer)
// 添加场景渲染通道
const renderPass = new RenderPass(this._scene, this._camera)
this._composer.addPass(renderPass)
// 创建轮廓线通道
this._outlinePass = new OutlinePass(
new THREE.Vector2(window.innerWidth, window.innerHeight),
this._scene,
this._camera,
)
// 设置默认参数
this.setOutlineParameters()
// 添加轮廓线通道
this._composer.addPass(this._outlinePass)
// 添加输出通道
const outputPass = new OutputPass()
this._composer.addPass(outputPass)
}
/**
* 更新轮廓线效果的参数配置
* @param {Object} options - 轮廓线参数配置对象
*/
setOutlineParameters(options = {}) {
const params = { ...DEFAULT_OUTLINE_OPTIONS, ...options }
Object.entries(params).forEach(([key, value]) => {
if (key in this._outlinePass) {
this._outlinePass[key] = value
}
})
}
/**
* 添加要显示轮廓线的物体
* @param {THREE.Object3D|Array<THREE.Object3D>} objects - 要添加轮廓线的物体或物体数组
*/
addSelectedObjects(objects) {
const objectsArray = Array.isArray(objects) ? objects : [objects]
objectsArray.forEach((object) => {
if (!this._selectedObjects.includes(object)) {
this._selectedObjects.push(object)
}
})
this._outlinePass.selectedObjects = this._selectedObjects
}
/**
* 移除物体的轮廓线效果
* @param {THREE.Object3D|Array<THREE.Object3D>} objects - 要移除轮廓线的物体或物体数组
*/
removeSelectedObjects(objects) {
const objectsArray = Array.isArray(objects) ? objects : [objects]
this._selectedObjects = this._selectedObjects.filter(
(selected) => !objectsArray.includes(selected),
)
this._outlinePass.selectedObjects = this._selectedObjects
}
/**
* 清除所有轮廓线效果
*/
clearSelectedObjects() {
this._selectedObjects = []
this._outlinePass.selectedObjects = []
}
/**
* 获取当前所有具有轮廓线效果的物体
* @returns {Array<THREE.Object3D>} 具有轮廓线效果的物体数组
*/
getSelectedObjects() {
return [...this._selectedObjects]
}
/**
* 更新轮廓线效果的渲染尺寸
* @param {number} width - 新的渲染宽度
* @param {number} height - 新的渲染高度
*/
setSize(width, height) {
this._composer.setSize(width, height)
}
/**
* 设置轮廓线的可见边缘颜色
* @param {THREE.Color|string|number} color - 新的颜色值
*/
setVisibleEdgeColor(color) {
this._outlinePass.visibleEdgeColor = new THREE.Color(color)
}
/**
* 设置轮廓线的隐藏边缘颜色
* @param {THREE.Color|string|number} color - 新的颜色值
*/
setHiddenEdgeColor(color) {
this._outlinePass.hiddenEdgeColor = new THREE.Color(color)
}
/**
* 销毁轮廓线效果,释放资源
*/
dispose() {
this.clearSelectedObjects()
this._outlinePass.dispose()
this._composer.dispose()
// 清理引用
this._outlinePass = null
this._composer = null
this._selectedObjects = null
}
/**
* 临时禁用轮廓线效果,但保留配置
*/
disable() {
this._enabled = false
}
/**
* 重新启用之前禁用的轮廓线效果
*/
enable() {
this._enabled = true
}
/**
* 执行轮廓线效果的渲染
*/
render() {
if (!this._enabled) {
// 如果禁用了轮廓线效果,直接使用普通渲染
this._renderer.render(this._scene, this._camera)
return
}
this._composer.render()
}
}
🔚 结语
Three.js 是一个强大的 3D 渲染引擎,而 OutlinePass
的轮廓线效果则能为你的项目增添视觉亮点与交互体验。
希望这个封装类能帮你节省时间、提升项目质量。
📌 喜欢就点个赞 👍,关注我!