Skip to content

模型高度辉光

ModelHeightGlowEffect 使用 CesiumJS 公开 CustomShader,为已有 Model 或 3D Tileset 添加高度渐变和动态扫描光环。

能力定位

该效果适用于城市白模、建筑群、工业设施等需要按模型高度着色的场景。它替代旧版 Cesium 中修改内部 Shader 源码的做法,不访问 _model_rendererResources 等私有字段。

Effect 只临时接管目标的 customShader:调用方仍然负责加载、加入场景、移除和销毁 Model 或 Cesium3DTileset。

基础用法

typescript
import { ModelHeightGlowEffect } from '@nexa/gis-cesium'
import { Cesium3DTileset, Color } from 'cesium'

const tileset = await Cesium3DTileset.fromUrl('/tiles/buildings/tileset.json')
viewer.scene.primitives.add(tileset)

const effect = new ModelHeightGlowEffect({
  target: tileset,
  color: new Color(0.2, 0.5, 1.0, 1.0),
  heightRange: 100,
  glowWidth: 0.025,
  speed: 1 / 6,
})

effect.on(viewer)

// 退出场景时恢复 tileset 原有 CustomShader
effect.destroy(viewer)
// tileset 仍由调用方管理
viewer.scene.primitives.remove(tileset)

配置项

参数类型默认值说明
targetModel | Cesium3DTileset必填已由调用方加载的渲染目标
colorColor(0.2, 0.5, 1.0, 1.0)高度渐变和扫描光环颜色
heightRangenumber100模型坐标中的渐变高度范围,必须为有限正数
glowWidthnumber0.025光环宽度占高度范围的比例,范围 (0, 1]
speednumber1 / 6每秒扫描周期数,必须为有限非负数;0 表示静止

动画通过 scene.preRender 按真实经过时间更新 u_time uniform,不依赖渲染帧数,因此不同帧率下速度保持一致。

应用于普通 glTF Model

typescript
import { ModelHeightGlowEffect } from '@nexa/gis-cesium'
import { Cartesian3, Model, Transforms } from 'cesium'

const model = await Model.fromGltfAsync({
  url: '/models/buildings.gltf',
  modelMatrix: Transforms.eastNorthUpToFixedFrame(
    Cartesian3.fromDegrees(121.47, 31.23)
  ),
})
viewer.scene.primitives.add(model)

const effect = new ModelHeightGlowEffect({ target: model })
effect.on(viewer)

// Effect 不拥有 model,分别清理
effect.destroy(viewer)
viewer.scene.primitives.remove(model)

生命周期与所有权

  • on(viewer) 保存目标原有 customShader,赋予 Effect 自己创建的 Shader,并注册一个 preRender 监听器。
  • off(viewer) 移除监听器;只有目标仍使用 Effect 的 Shader 时才恢复原值,不会覆盖业务侧运行期换上的新 Shader。
  • destroy(viewer) 同时释放 Effect 自己创建的 CustomShader GPU 资源;不会移除或销毁目标。
  • onoffdestroy 均可重复调用,且支持 on → off → on 复用。

限制与兼容性

  • 高度来自 fsInput.attributes.positionMC.z,因此 heightRange 应按模型局部坐标尺度配置。
  • Cesium3DTileset.customShader 只影响由 Cesium Model 管线渲染的瓦片内容。
  • 不要在同一个 3D Tileset 上同时使用 Cesium3DTileStyleCustomShader;Cesium 官方不保证组合结果。
  • Shader 使用 fragmentMain(FragmentInput, czm_modelMaterial) 公共接口,不使用旧版 gl_FragColor 或私有 Renderer 资源。
  • GLSL 编译和最终视觉属于 WebGL 行为,升级 Cesium 后应在真实浏览器中回归。

示例资产

内置案例使用 /static/custom-shader-buildings.gltf。该文件由 nexa 程序化生成,使用内嵌 Buffer、无纹理和外部请求,并在 glTF asset.extras 中记录 CC0-1.0 来源信息。