
three.js 指数平方雾 FogExp2场景距离感与大气深度的完整指南【免费下载链接】three.jsJavaScript 3D Library.项目地址: https://gitcode.com/GitHub_Trending/th/three.js导读FogExp2Exponential Squared Fog指数平方雾是 three.js 内置的两类雾Fog之一它让场景在相机近处保持清晰、远处随距离呈指数平方级加速变浓常用于地形、点云、粒子与开放世界场景来烘托大气深度并隐藏远处网格裁剪带来的生硬边缘。本文以 docs/pages/FogExp2.html.md 为核心深入 FogExp2 源码 与 WebGL/WebGPU 渲染管线实现讲解它的数学原理、构造参数、属性方法、着色器实现以及 JSON 序列化链路帮助你掌握这套可控性极强、几乎零配置的远景淡化方案。概览什么是指数平方雾three.js 在场景中通过 Scene.fog 属性挂载两类雾Fog线性雾用near/far两个距离定义一段线性渐变的雾带见 src/scenes/Fog.jsFogExp2指数平方雾不设远近边界只用密度系数density控制雾随距离增长的速度视线越远雾越浓从相机处起就开始生效因此能营造出比线性雾更自然弥漫的空气透视效果。FogExp2 的官方描述是gives a clear view near the camera and a faster than exponentially densening fog farther from the camera——相机近处视野通透远离相机的区域雾的浓度增长比指数还快指数平方能非常高效地把远景融入背景色。快速上手代码示例把 FogExp2 赋给scene.fog即可无需在材质或渲染器上做任何额外配置const scene new THREE.Scene(); scene.fog new THREE.FogExp2( 0xcccccc, 0.002 );第一参是雾的颜色十六进制数或 Color 实例第二参是雾的密度。0xcccccc 是常见的浅灰色背景能营造阴天或尘雾弥漫的氛围。更多实战用法可以对照仓库中已启用的示例例如点云场景 webgl_points_dynamic.html、webgl_points_sprites.html、粒子类 webgpu_particles_soft.html、地形 webgl_geometry_terrain.html 以及自定义雾散射场景 webgpu_custom_fog_scattering.html都会借助 FogExp2 做远场淡化。与线性雾 Fog 的选择对比维度Fog线性雾FogExp2指数平方雾构造参数(color, near, far)(color, density)雾带起止由near/far明确界定近处完全无雾从相机处即开始无明确边界浓度增长随距离线性增长随距离按density² × depth²指数平方增长适用场景有明确雾带边界、需要精确控制起止距离远景弥漫、天际线淡化、隐藏 far plane 裁剪两者的判型标志与选择逻辑在渲染器中被明确区分见下文的源码展开实际编码时根据是否需要明确雾带边界决定即可。构造函数与参数语义new FogExp2( color : number | Color, density : number )对照 FogExp2 源码第 21-54 行color雾的颜色源码内部通过new Color( color )转换为一个 Color 实例存储因此既支持十六进制数0xcccccc、整数/百分比 RGB也支持直接传入现成的Color对象。density定义雾变得浓密的速度默认值为0.00025。这是一个需要在场景尺寸量级上校准的参数对于世界坐标单位尺度较大的场景如地形0.000250.002通常合理密度越大同等距离下雾越浓、能见距离越短。需要注意密度并非越小雾越稀的线性直觉——因为着色器中浓度因子对密度是平方关系见下文公式调整密度值对视觉影响十分显著建议小幅试错。构造函数可以不传参直接new FogExp2()雾色默认白色new Color(undefined)解析为白色密度落到0.00025这一点也由单元测试 FogExp2.tests.js 验证no params、仅传 color、传 colordensity 三种实例化路径。属性详解FogExp2 的属性全部在构造函数内初始化见 src/scenes/FogExp2.js运行期可安全读写。.color : Color雾的颜色类型为 Color构造时从 number/Color 归一化而来。由于渲染时最终以该 Color 为基准取色并写入 uniform下文源码可证运行期动态修改会实时影响雾色。.density : number雾的浓度系数控制雾随距离变浓的快慢默认0.00025。它是整个 FogExp2 唯一需要调参的量值增大时能见距离快速缩短由于雾因子对 density 呈平方依赖即使把 density 缩小到原值的一半同距离处的雾量也会骤降到约四分之一。.isFogExp2 : boolean只读类型测试标志恒为true。渲染管线正是靠它把 FogExp2 与线性 Fog、或未来可能的其他雾类型区分开判型逻辑见下文渲染管线如何消费 FogExp2。与Fog.isFog、Sprite.isSprite等约定一致适用于做鸭子类型判断。.name : string雾的可选名称默认为空字符串。与 Object3D 的 name 用途类似主要服务于序列化/编辑器场景——导出到 JSON 后该名称会一并写入供加载与调试识别。方法详解.clone() : FogExp2返回一份全新实例并把颜色与密度拷贝过去clone() { return new FogExp2( this.color, this.density ); }实现即 源码第 61-65 行。注意这里直接把this.colorColor 实例作为构造入参新实例内部会再次new Color()深拷贝一份因此修改原实例的 color 不会影响克隆体。.toJSON( meta : Object | string ) : Object将雾序列化为 JSON 对象meta 参数在 当前实现 中未被使用形参注释为/* meta */。序列化结果结构固定{ type: FogExp2, name: this.name, color: this.color.getHex(), // 颜色以十六进制整数输出 density: this.density }这套结构对 ObjectLoader 是可逆的加载器遇到type: FogExp2的 JSON 数据时会重建对应实例因此toJSON 是场景导出如编辑器保存、.json场景文件与加载闭环的关键一环。从源码结构看color用getHex()而非 RGB 数组是为了让 JSON 更紧凑且无精度损失。渲染管线如何消费 FogExp2源码级原理雾不是材质属性而是由渲染器根据场景当前激活的 fog 统一注入的。以片元最终颜色混合为终点全链路如下。1. ShaderChunk 中的数学公式WebGL 渲染器的雾计算集中在雾相关 shader 代码块 fog_vertex.glsl.js 与 fog_fragment.glsl.jsWebGPU 有对应的节点式实现。片元侧关键代码#ifdef FOG_EXP2 float fogFactor 1.0 - exp( - fogDensity * fogDensity * vFogDepth * vFogDepth ); #endif gl_FragColor.rgb mix( gl_FragColor.rgb, fogColor, fogFactor );即FogExp2 的雾因子公式为factor 1 − exp( −density² · depth² )其中depthvFogDepth是片元到相机的距离。正是depth²让远处浓度比指数还快地逼近 1而density²解释了为何调小 density 效果衰减剧烈。factor为 0 时保持原色趋近 1 时片元完全融为fogColor。线性雾则走smoothstep( fogNear, fogFar, vFogDepth )分支——两种雾共享同一 mix 输出逻辑只是因子来源不同。2. Uniform 刷新雾属性如何进入 GPU雾参数要进入 shader需在每次渲染前刷新到对应 uniform。WebGL 管线中WebGLMaterials.refreshFog 会按类型分发线性 Fog 写入fogNear/fogFar命中fog.isFogExp2时写入fogDensity.value fog.density两类雾都通过fog.color.getRGB(...)把 Color 写入fogColor注意按当前渲染器色彩空间做了一次适配见 refreshFog 中对getUnlitUniformColorSpace的调用。配合 fog_pars_fragment.glsl.js 中的#ifdef FOG_EXP2宏同一套 fog chunk 即可服务两种雾。3. WebGPU / Node 渲染器的节点式实现在 WebGPU 与 TSL 节点渲染路径中雾被抽象为雾节点。核心逻辑位于 NodeManager.updateFogif ( sceneFog.isFogExp2 ) { const color reference( color, color, sceneFog ).setGroup( renderGroup ); const density reference( density, float, sceneFog ).setGroup( renderGroup ); return fog( color, densityFogFactor( density ) ); } else if ( sceneFog.isFog ) { ... return fog( color, rangeFogFactor( near, far ) ); }可以看到两种雾以isFogExp2标志严格分流指数平方雾由 TSL 的densityFogFactor生成浓度因子线性雾由rangeFogFactor生成两者最终都汇聚到统一的fog()节点。这也说明只要在scene.fog上挂一个 FogExp2WebGL 与 WebGPU 两大渲染后端都会自动、无需额外代码地生效。4. 从判型到序列化一个完整的类设计闭环纵观全链路即可得到 FogExp2 的一生构造时打上isFogExp2 true并初始化 color/density/name渲染器据scene.fog.isFogExp2分支注入正确的 uniform/雾节点与 shader 宏.clone()提供实例复制.toJSON()输出带type: FogExp2的 JSON可被 ObjectLoader 原样重建判型标志同时服务于渲染分发与JSON 反序列化两条路径这正是 three.js 类体系标志 统一接口风格的典型样板。单元测试 FogExp2.tests.js 覆盖了实例化与isFogExp2判型两条基础约束可作为理解该类契约的快速参考。调参实践建议以相机单位尺度为准场景如果以米为世界单位视野数百米density 取0.00020.002如果单位尺度巨大地形、星系类场景需要同步缩小 density否则视口内会一片全白。先定色再调密度雾色取与场景主背景、renderer.setClearColor接近的色调可让远景无缝隐入天空/背景密度从小值起逐步增大直到 far plane 裁切处恰好被完全遮盖factor≈1。运行期可控color 与 density 都是普通属性可直接在动画循环中动态渐变如随海拔或时间变化无需重建对象或重建材质。性能友好指数平方雾不需要 near/far 距离判断片元只多一次exp计算配合几何体简化与视锥剔除使用即可无需额外预处理。小结FogExp2 是 three.js 中最省心的远景雾化工具只需new THREE.FogExp2(color, density)赋给scene.fog两个参数即可获得从相机近处透明到远处完全被雾色覆盖的平滑大气效果。其数学内核1 − exp(−density²·depth²)、以isFogExp2驱动的双渲染后端分发、以及toJSON/ObjectLoader构成的序列化闭环共同保证了它在任何规模场景中都可预测、可持久化且几乎零样板代码地使用。【免费下载链接】three.jsJavaScript 3D Library.项目地址: https://gitcode.com/GitHub_Trending/th/three.js创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考