Three.js 场景雾化教程
场景雾化 ·Scene Fog· ▶ 在线运行案例案例合集三维可视化功能案例threehub.cn开源仓库github地址https://github.com/z2586300277/three-cesium-examples400个案例代码:网盘链接你将学到什么Fog线性雾与FogExp2指数雾的区别scene.fog与renderer.setClearColor颜色一致的重要性远距离物体如何被雾自然隐没效果说明场景中有一只Fox 模型z -500很远和一块放大的地面较近。开启雾后远处狐狸逐渐融入雾色看不见近处地面清晰。GUI 可切换雾类型linear / exp2启用/关闭雾雾颜色、near/far线性或 density指数核心概念雾如何工作雾在片元着色阶段根据像素到相机的距离将物体颜色向雾色混合最终颜色 mix(物体颜色, 雾色, fogFactor)| 类型 | 构造函数 | fogFactor 依据 | |------|---------|----------------| |Fog线性雾 |new THREE.Fog(color, near, far)| near 内无雾far 外全雾之间线性 | |FogExp2指数雾 |new THREE.FogExp2(color, density)| 距离越远指数增长更自然 |// 线性雾10~800 单位之间渐变scene.fog new THREE.Fog(0xffffff, 10, 800);// 指数雾density 越大雾越浓 scene.fog new THREE.FogExp2(0xffffff, 0.005);背景色必须匹配renderer.setClearColor(fogColor);scene.fog new THREE.Fog(fogColor, near, far);若setClearColor与fog.color不一致地平线会出现明显色差接缝。本案例场景布局// 狐狸在很远的 -Zgltf.scene.position.set(0, 0, -500);// 地面放大 10 倍偏移到相机前方 model.scale.set(10, 10, 10); model.position.z 60; model.position.x - 200;far 800时狐狸距相机约 500已在雾区边缘适合演示「远物消失」。logarithmicDepthBuffer本案例 Renderer 开了logarithmicDepthBuffer: true大near/far 跨度0.1 ~ 100000时减轻 Z-fighting与雾效配合展示大场景。实现步骤Scene 相机远裁剪far: 100000 灯光加载远距 Fox 近距地面 glbgetFog(type, color)工厂函数创建两种雾GUI 切换 type / enable动态setFogFolder重建参数面板改雾色时同步renderer.setClearColor代码要点import * as THREE from threeimport { OrbitControls } from three/examples/jsm/controls/OrbitControls.js import { GLTFLoader } from three/examples/jsm/loaders/GLTFLoader.js import { GUI } from three/addons/libs/lil-gui.module.min.jsconst box document.getElementById(box)const scene new THREE.Scene()const camera new THREE.PerspectiveCamera(50, box.clientWidth / box.clientHeight, 0.1, 100000)camera.position.set(0, 20, 60)const renderer new THREE.WebGLRenderer({ antialias: true, alpha: true, logarithmicDepthBuffer: true })renderer.setSize(box.clientWidth, box.clientHeight)box.appendChild(renderer.domElement)const controls new OrbitControls(camera, renderer.domElement)controls.enableDamping trueanimate()function animate() {requestAnimationFrame(animate)controls.update()renderer.render(scene, camera)}scene.add(new THREE.AmbientLight(0xffffff, 1))const directionalLight new THREE.DirectionalLight(0xffffff, 1)directionalLight.position.set(0, 100, 0)scene.add(directionalLight)window.onresize () {renderer.setSize(box.clientWidth, box.clientHeight)camera.aspect box.clientWidth / box.clientHeightcamera.updateProjectionMatrix()}new GLTFLoader().load(GLOBAL_CONFIG.getFileUrl(files/model/Fox.glb), (gltf) {gltf.scene.position.set(0, 0, -500)scene.add(gltf.scene)})new GLTFLoader().load(GLOBAL_CONFIG.getFileUrl(models/glb/foorGround.glb), (gltf) {const model gltf.scenemodel.position.z 60model.position.x - 200model.scale.set(10, 10, 10)scene.add(model)})function getFog(type, color) {renderer.setClearColor(color || 0xffffff)if (type linear) return new THREE.Fog(color || 0xffffff, 10, 800)else return new THREE.FogExp2(color || 0xffffff, 0.005)}const folder new GUI()let fogFolder nullconst fogOption { type: scene.fog instanceof THREE.FogExp2 ? exp2 : linear, enable: !!scene.fog }folder.add(fogOption, type, [linear, exp2]).name(雾类型).onChange((v) {scene.fog getFog(v, scene.fog?.color)setFogFolder(v)})folder.add(fogOption, enable).name(启用雾).onChange((v) {if (v) scene.fog getFog(fogOption.type)else scene.fog nullsetFogFolder(fogOption.type)})fogOption.enable setFogFolder(fogOption.type)function setFogFolder(type) {if (fogFolder) {fogFolder.destroy?.()fogFolder null}if (!scene.fog) returnfogFolder folder.addFolder(type 雾)fogFolder.addColor(scene.fog, color).name(颜色).onChange((v) renderer.setClearColor(v))if (type linear) {fogFolder.add(scene.fog, near).name(近点)fogFolder.add(scene.fog, far).name(远点)}else fogFolder.add(scene.fog, density).name(密度).min(0).max(0.1).step(0.00001)}完整源码GitHub小结本文提供场景雾化完整 Three.js 源码与在线 Demo建议先运行案例再改 uniform/参数做二次实验更多 Three.js 实战案例见 three-cesium-examples 合集 与 GitHub 开源仓库