Three.js 光柱教程
光柱 ·Light Bar· ▶ 在线运行案例
- 案例合集:三维可视化功能案例(threehub.cn)
- 开源仓库github地址:https://github.com/z2586300277/three-cesium-examples
- 400个案例代码:网盘链接
你将学到什么
- OrbitControls 相机轨道交互
requestAnimationFrame渲染循环与resize自适应
效果说明
本案例演示光柱效果:基于 WebGL 实现「光柱」可视化效果,附完整可运行源码;核心用到 OrbitControls。建议先打开文首在线案例查看动态画面,再对照下方源码逐步理解。
核心概念
- OrbitControls轨道旋转缩放;开
enableDamping时每帧需controls.update()。
实现步骤
- 搭建 Scene / Camera / Renderer 与 OrbitControls
- rAF 循环中 update 并 render
代码要点
import * as THREE from 'three'import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls.js'
const box = document.getElementById('box')
const scene = new THREE.Scene()
const camera = new THREE.PerspectiveCamera(75, box.clientWidth / box.clientHeight, 0.1, 1000)
camera.position.set(0, 10, 10)
const renderer = new THREE.WebGLRenderer({ antialias: true, alpha: true, preserveDrawingBuffer: true })
renderer.setSize(box.clientWidth, box.clientHeight)
box.appendChild(renderer.domElement)
new OrbitControls(camera, renderer.domElement)
scene.add(new THREE.AmbientLight(0xffffff, 0.5), new THREE.AxesHelper(100))
// 随机创建光柱 for (let i = 0; i < 10; i++) {
const lightBar = createLightBar(0xffffff * Math.random())
lightBar.position.set(Math.random()10 - 5, 0, Math.random()10 - 5)
scene.add(lightBar)
}
animate()
function animate() {
requestAnimationFrame(animate)
renderer.render(scene, camera)
}
window.onresize = () => {
renderer.setSize(box.clientWidth, box.clientHeight)
camera.aspect = box.clientWidth / box.clientHeight
camera.updateProjectionMatrix()
}
function createLightBar(color = 0xfcde8c) { // 创建mesh const geometry = new THREE.CylinderGeometry(0.3, 0.3, 10, 6)
const material = new THREE.MeshBasicMaterial({ color, transparent: true, opacity: 0.3, side: THREE.DoubleSide })
const mesh = new THREE.Mesh(geometry, material)
material.blending = THREE.AdditiveBlending
// 创建纹理 const texture = new THREE.TextureLoader().load(FILE_HOST + 'images/channels/lightMap.png')
texture.wrapS = THREE.RepeatWrapping
texture.wrapT = THREE.RepeatWrapping
// 创建平面 const plane = new THREE.PlaneGeometry(1.5, 10)
const planeMaterial = new THREE.MeshBasicMaterial({ transparent: true, opacity: 0.3, side: THREE.DoubleSide, map: texture })
planeMaterial.blending = THREE.AdditiveBlending
planeMaterial.depthTest = false
const planeMesh = new THREE.Mesh(plane, planeMaterial)
const planeMesh2 = planeMesh.clone()
planeMesh2.rotation.y = Math.PI / 3
const planeMesh3 = planeMesh.clone()
planeMesh3.rotation.y = -Math.PI / 3
mesh.add(planeMesh3)
mesh.add(planeMesh)
mesh.add(planeMesh2)
// 创建group const group = new THREE.Group()
group.RootMaterials = [material, planeMaterial]
group.add(mesh)
return group
}完整源码:GitHub
小结
- 本文提供光柱完整 Three.js 源码与在线 Demo,建议先运行案例再改 uniform/参数做二次实验
- 更多 Three.js 实战案例见 three-cesium-examples 合集 与 GitHub 开源仓库