Three.js 官方选择辉光简化版教程 官方选择辉光简化版 ·Three Bloom· ▶ 在线运行案例案例合集三维可视化功能案例threehub.cn开源仓库github地址https://github.com/z2586300277/three-cesium-examples400个案例代码:网盘链接你将学到什么ShaderMaterial 自定义着色器实现核心视觉效果EffectComposer 多 Pass 后期处理管线UnrealBloomPass 辉光 Bloom 效果OrbitControls 相机轨道交互glTF/Draco 模型加载与优化Raycaster 鼠标拾取与交互requestAnimationFrame渲染循环与resize自适应效果说明本案例演示官方选择辉光简化版效果原场景渲染后经 EffectComposer 叠加 Bloom/模糊等全屏后期支持鼠标拾取、绘制或拖拽交互核心用到 ShaderMaterial、EffectComposer、UnrealBloomPass。建议先打开文首在线案例查看动态画面再对照下方源码逐步理解。核心概念Scene / Camera / WebGLRenderer构成最小渲染闭环大场景可开logarithmicDepthBuffer缓解 Z-fighting。ShaderMaterial通过uniforms 自定义 GLSL 控制逐像素/逐点效果透明粒子常配合depthTest: false。EffectComposer以多 Pass 链式渲染RenderPass → 特效 Pass → 输出屏幕替代直接renderer.render。OrbitControls提供轨道旋转/缩放开启enableDamping后需在 animate 中controls.update()。实现步骤搭建 Scene、PerspectiveCamera、WebGLRenderer挂载 canvas 并处理resize异步加载模型 / 3D Tiles / GeoJSON 等资源并加入 scene 或 entities定义 uniforms / onBeforeCompile 或 ShaderMaterial编写 GLSL 与材质参数组装 EffectComposer Pass 链在 animate 中调用composer.render()创建 OrbitControls及 Raycaster 等交互控件若源码包含在requestAnimationFrame循环中更新状态并 renderCesium 为viewer.render或自动渲染代码要点import * as THREE from threeimport { GLTFLoader } from three/addons/loaders/GLTFLoader.js import { OrbitControls } from three/addons/controls/OrbitControls.js import { EffectComposer } from three/addons/postprocessing/EffectComposer.js import { RenderPass } from three/addons/postprocessing/RenderPass.js import { ShaderPass } from three/addons/postprocessing/ShaderPass.js import { UnrealBloomPass } from three/addons/postprocessing/UnrealBloomPass.jsconst renderer new THREE.WebGLRenderer({ antialias: true, logarithmicDepthBuffer: true, }) renderer.setSize(window.innerWidth, window.innerHeight) document.body.appendChild(renderer.domElement)const scene new THREE.Scene() const camera new THREE.PerspectiveCamera(40, window.innerWidth / window.innerHeight, 1, 100000) camera.position.set(200, 200, 200) new OrbitControls(camera, renderer.domElement)const light new THREE.DirectionalLight(0xffffff, 3) light.position.set(100, 100, 100) scene.add(light)// 物体 new GLTFLoader().load(FILE_HOST files/model/Fox.glb, (gltf) scene.add(gltf.scene)) const mesh new THREE.Mesh(new THREE.BoxGeometry(20, 20, 20), new THREE.MeshStandardMaterial({ color: 0x00ff00 })) mesh.position.set(50, 0, 0) scene.add(mesh)// 后期处理 const renderScene new RenderPass(scene, camera) const bloomPass new UnrealBloomPass(new THREE.Vector2(window.innerWidth, window.innerHeight), 0.8, 0.4, 0.0) const bloomComposer new EffectComposer(renderer) bloomComposer.renderToScreen false bloomComposer.addPass(renderScene) bloomComposer.addPass(bloomPass)const finalPass new ShaderPass( new THREE.ShaderMaterial({ uniforms: { baseTexture: { value: null }, bloomTexture: { value: bloomComposer.renderTarget2.texture }, }, vertexShader:varying vec2 vUv; void main() { vUv uv; gl_Position projectionMatrixmodelViewMatrixvec4( position, 1.0 ); }, fragmentShader:uniform sampler2D baseTexture; uniform sampler2D bloomTexture; varying vec2 vUv; void main() { gl_FragColor ( texture2D( baseTexture, vUv ) vec4( 1.0 ) * texture2D( bloomTexture, vUv ) ); }, defines: {}, }), baseTexture ) finalPass.needsSwap true const finalComposer new EffectComposer(renderer) finalComposer.addPass(renderScene) finalComposer.addPass(finalPass)// 点击切换辉光 window.addEventListener(click, onClick) function onClick(event) { const raycaster new THREE.Raycaster() const mouse new THREE.Vector2( (event.offsetX / event.target.clientWidth) * 2 - 1, -(event.offsetY / event.target.clientHeight) * 2 1 ) raycaster.setFromCamera(mouse, camera) const intersects raycaster.intersectObjects(scene.children) if (intersects.length 0) intersects[0].object.layers.toggle(1) // 切换图层 }// 窗口大小变化 window.onresize function () { camera.aspect window.innerWidth / window.innerHeight camera.updateProjectionMatrix() renderer.setSize(window.innerWidth, window.innerHeight) bloomComposer.setSize(window.innerWidth, window.innerHeight) finalComposer.setSize(window.innerWidth, window.innerHeight) }// 辉光图层 const bloomLayer new THREE.Layers() bloomLayer.set(1)const darkMaterial new THREE.MeshBasicMaterial({ color: black }) const materials {}render() function render() { requestAnimationFrame(render) scene.traverse(obj { if (obj.isMesh bloomLayer.test(obj.layers) false) { materials[obj.uuid] obj.material // 保存原材质 obj.material darkMaterial // 替换材质 } }) bloomComposer.render() // 渲染到bloomComposer scene.traverse(obj { if (materials[obj.uuid]) { obj.material materials[obj.uuid] // 恢复原材质 delete materials[obj.uuid] // 删除原材质 } }) finalComposer.render() }完整源码GitHub小结本文提供官方选择辉光简化版完整 Three.js 源码与在线 Demo建议先运行案例再改 uniform/参数做二次实验更多 Three.js 实战案例见 three-cesium-examples 合集 与 GitHub 开源仓库