介绍
Cesium 1.123的更新引入了一种全新的“程序化”光照系统,基于 CesiumJS 的图像基照明(Image-Based Lighting,IBL)方法,旨在显著提升默认光照环境的真实感和视觉质量。通过动态生成环境贴图和相关光照值,该系统能够实时响应场景中的位置和光源变化,为模型和 3D 瓦片(3D Tilesets)提供更加真实的渲染效果。
DynamicEnvironmentMapManager
DynamicEnvironmentMapManager
是本次更新的核心组件,用于动态生成与当前场景光照条件匹配的环境贴图,并计算多种反射和漫反射参数。以下是对其主要功能和参数的详细描述:
功能
- 环境贴图生成
- 使用场景中的当前位置和太阳位置动态生成一组环境贴图。
- 基于环境贴图,生成多个高光贴图(Specular Maps),涵盖不同表面粗糙度的反射。
- 光照值计算
- 球面谐波漫反射光照:通过计算球面谐波(Spherical Harmonics)系数,提升光扩散的真实感。
- 辐射贴图(Radiance Map)和辐照贴图(Irradiance Map):分别表示高分辨率的镜面反射效果和环境光的整体分布。
- 动态更新
- 根据场景中位置变化或时间变化(如太阳运动)自动更新环境贴图。
- 内置多个更新触发条件,包括位置阈值(
maximumPositionEpsilon
)和时间阈值(maximumSecondsDifference
)。
- 性能优化
- 使用延迟更新机制,仅在需要时重新生成贴图和计算参数。
- 支持多层级的高光贴图生成(
mipmapLevels
),以适配不同渲染需求。
主要参数
以下是 DynamicEnvironmentMapManager
的重要构造参数及其作用:
enabled
: 是否启用动态环境贴图更新,默认为true
。mipmapLevels
: 高光贴图生成的层级数,默认为10
,层级越多,反射效果越精细。maximumSecondsDifference
: 更新环境贴图的最大时间间隔,默认为3600
秒。maximumPositionEpsilon
: 更新环境贴图的最大位置变化阈值,单位为米,默认为1000
。atmosphereScatteringIntensity
: 大气散射光的强度,默认为2.0
,可以根据场景光源亮度调整。gamma
: 环境光的伽马校正值,默认为1.0
。brightness
: 环境光的亮度校正值,默认为1.0
。saturation
: 环境光的饱和度校正值,默认为1.0
。groundColor
: 地面的固有颜色,默认值为地球的平均地面色(#717145
)。groundAlbedo
: 地面的反射率,默认为0.31
,反映地球的平均反照率。
实现细节
-
贴图更新逻辑
- 通过
ComputeCommand
创建计算命令,将辐射贴图结果更新到CubeMap
的每个面。 - 支持多层级卷积计算,用于生成不同粗糙度的高光贴图。
- 通过
-
光照计算
- 在 GPU 上使用片段着色器(如
ComputeRadianceMapFS
和ComputeIrradianceFS
)高效完成辐射和辐照的卷积计算。 - 利用球面谐波计算漫反射系数,结合大气散射提升光照真实性。
- 在 GPU 上使用片段着色器(如
-
重置与销毁
-
提供
reset
方法以便在条件改变时清理未完成的计算命令并标记更新状态。/** * 取消所有正在进行的命令,并将环境贴图标记为“脏”状态。 * 这意味着当前的计算命令会被中断,并且环境贴图需要重新计算。 * * @private * @function */ DynamicEnvironmentMapManager.prototype.reset = function () { // 获取当前辐射贴图计算命令的数量 let length = this._radianceMapComputeCommands.length; // 遍历并清除辐射贴图计算命令 for (let i = 0; i < length; ++i) { this._radianceMapComputeCommands[i] = undefined; } // 获取当前卷积计算命令的数量 length = this._convolutionComputeCommands.length; // 遍历并清除卷积计算命令 for (let i = 0; i < length; ++i) { this._convolutionComputeCommands[i] = undefined; } // 如果辐射照射计算命令已定义,则清除它 if (defined(this._irradianceComputeCommand)) { this._irradianceComputeCommand = undefined; } // 将辐射贴图状态标记为“脏”以指示需要重新计算 this._radianceMapDirty = true; // 将辐射命令状态标记为“脏” this._radianceCommandsDirty = true; };
-
提供
destroy
方法以销毁所有 WebGL 资源,确保资源管理的高效性。/** * 销毁该对象所持有的WebGL资源。销毁对象允许我们有确定性的方式释放WebGL资源, * 而不是依赖垃圾回收器来销毁该对象。 * <br /><br /> * 一旦对象被销毁,就不应再使用它;调用任何除了 <code>isDestroyed</code> 之外的函数将会 * 导致抛出 {@link DeveloperError} 异常。因此,应将返回值(<code>undefined</code>)重新赋值给对象, * 如示例所示。 * * @throws {DeveloperError} 当对象已被销毁(即调用了 destroy())时抛出。 * @example * mapManager = mapManager && mapManager.destroy(); * @see DynamicEnvironmentMapManager#isDestroyed */ DynamicEnvironmentMapManager.prototype.destroy = function () { // 取消所有正在进行的辐射贴图计算命令 let length = this._radianceMapComputeCommands.length; for (let i = 0; i < length; ++i) { this._radianceMapComputeCommands[i] = undefined; } // 取消所有正在进行的卷积计算命令 length = this._convolutionComputeCommands.length; for (let i = 0; i < length; ++i) { this._convolutionComputeCommands[i] = undefined; } // 清除辐射照射贴图计算命令 this._irradianceMapComputeCommand = undefined; // 销毁所有辐射贴图纹理 length = this._radianceMapTextures.length; for (let i = 0; i < length; ++i) { this._radianceMapTextures[i] = this._radianceMapTextures[i] && this._radianceMapTextures[i].destroy(); } // 销毁所有高光贴图纹理 length = this._specularMapTextures.length; for (let i = 0; i < length; ++i) { this._specularMapTextures[i] = this._specularMapTextures[i] && this._specularMapTextures[i].destroy(); } // 销毁辐射立方体贴图 this._radianceCubeMap = this._radianceCubeMap && this._radianceCubeMap.destroy(); // 销毁辐射照射贴图 this._irradianceMapTexture = this._irradianceMapTexture && this._irradianceMapTexture.destroy(); // 销毁当前对象,并释放其所有资源 return destroyObject(this); };
-
使用示例
以下是 DynamicEnvironmentMapManager
的典型使用场景:
// 在场景中启用动态环境贴图
scene.atmosphere.dynamicLighting = Cesium.DynamicAtmosphereLightingType.SUNLIGHT;
// 调整光源和环境贴图的光照强度
scene.light.intensity = 0.5;
const environmentMapManager = tileset.environmentMapManager;
environmentMapManager.atmosphereScatteringIntensity = 3.0;
// 设置环境贴图的地面颜色为森林绿
environmentMapManager.groundColor = Cesium.Color.fromCssColorString("#203b34");
更详细的解析后面再更新
TilesBuilder: TilesBuilder提供一个高效、兼容、优化的数据转换工具,一站式完成数据转换、数据发布、数据预览操作。