Skip to content

WaterMaterialProperty 水面材质

动态水域波浪材质,基于 Cesium 原生 'Water' 材质类型封装。在河流、湖泊等水域多边形上叠加波浪折射效果,法线纹理默认内嵌程序生成的涟漪扰动图,无需宿主提供图片资源。


能力定位

WaterMaterialProperty 适合:

  • 河流 / 湖泊动态水面:水域多边形波浪渲染;
  • 海岸、水库水域:态势可视化中的水域范围;
  • 水域高亮:与 perPositionHeight 配合贴合真实高程。

WaterColumnEffect(粒子喷泉/水柱)不同,本材质用于面状水面表面, 基于 Cesium 原生 'Water' fabric 类型,无需注册自定义 GLSL。

构造函数

ts
constructor(options: WaterMaterialPropertyOptions)
ts
interface WaterMaterialPropertyOptions {
  baseWaterColor?: Color | Property; // 水面基础颜色,默认 Color.AQUA.withAlpha(0.6)
  normalMap?: string;                // 法线纹理(涟漪扰动图),默认内嵌程序生成的法线图
  frequency?: number | Property;     // 波纹频率,默认 1000.0
  animationSpeed?: number | Property; // 动画速度,默认 0.01
  amplitude?: number | Property;     // 波幅,默认 10
  specularIntensity?: number | Property; // 镜面反射强度,默认 10
}
参数类型默认值描述
baseWaterColorColor | PropertyColor.AQUA.withAlpha(0.6)水面基础颜色,与源案例一致
normalMapstring程序生成涟漪法线图法线纹理地址(URL / data-URI),可覆盖为任意法线图
frequencynumber | Property1000.0波纹频率
animationSpeednumber | Property0.01波纹动画速度
amplitudenumber | Property10波幅
specularIntensitynumber | Property10镜面反射强度

数值型参数均支持 CallbackProperty 动态驱动(如随时间改变频率)。

材质属性接口

WaterMaterialProperty 实现 Cesium MaterialProperty 契约,可直接赋给实体材质:

ts
getType(time): string          // 返回 'Water'(Cesium 原生类型,无需注册)
getValue(time, result?): object // 返回 baseWaterColor/normalMap/frequency/animationSpeed/amplitude/specularIntensity uniforms
isConstant: boolean            // 全部属性为常量时为 true
definitionChanged: Event       // 属性赋值时触发
equals(other): boolean         // 属性相等判断

基础示例

ts
import { WaterMaterialProperty } from '@nexa/gis-cesium'
import { Cartesian3, Color } from 'cesium'

const material = new WaterMaterialProperty({
  baseWaterColor: Color.AQUA.withAlpha(0.6),
})

// 河流水域多边形(perPositionHeight 沿高程面贴合)
const entity = viewer.entities.add({
  polygon: {
    hierarchy: [
      Cartesian3.fromDegrees(121.44, 29.79, 0),
      Cartesian3.fromDegrees(121.50, 29.79, 0),
      Cartesian3.fromDegrees(121.50, 29.80, 0),
      Cartesian3.fromDegrees(121.44, 29.80, 0),
    ],
    perPositionHeight: true,
    material,
  },
})

进阶示例

从 GeoJSON 河网数据生成水域,并动态切换水面颜色:

ts
import { WaterMaterialProperty } from '@nexa/gis-cesium'
import { Cartesian3, Color } from 'cesium'

const material = new WaterMaterialProperty({
  baseWaterColor: Color.AQUA.withAlpha(0.6),
  normalMap: '/static/images/effects/waterNormalsSmall.jpg', // 覆盖为源案例法线图
})

async function loadRiver (url: string) {
  const geo = await (await fetch(url)).json()
  geo.features.forEach((feature: any) => {
    const ring = feature.geometry.coordinates[0]
    viewer.entities.add({
      polygon: {
        hierarchy: ring.map(([lng, lat]: number[]) => Cartesian3.fromDegrees(lng, lat, 0)),
        perPositionHeight: true,
        material,
      },
    })
  })
}

await loadRiver('/static/data/hedao-nei.json')
await loadRiver('/static/data/hedao-wai.json')

// 颜色切换(对应源案例 updateColor)
material.baseWaterColor = Color.fromCssColorString('#00bfff').withAlpha(0.6)

实现与性能说明

  • 原生材质类型getType() 返回 'Water',直接消费 Cesium 内置 'Water' fabric, 无需 registerAll 注册 GLSL;blendColor / specularMap / fadeFactor 由 Cesium 缓存默认补齐;
  • 法线纹理内嵌:默认值为程序生成的涟漪法线图(data-URI),非浏览器环境返回占位图, 避免宿主页面引入外部图片资源;normalMap 可覆盖为任意法线图 URL;
  • 属性驱动:数值属性支持 CallbackProperty,可随时间或业务状态动态变化;
  • 资源所有权:材质属性本身无生命周期;引用它的多边形实体由创建方负责移除。

Cesium 版本限制

  • 需要 Cesium 内置 'Water' 材质类型(Material.WaterType);
  • 已验证目标版本:Cesium 1.133.1。

清理责任

  • WaterMaterialPropertyon/off,本身不持有 DOM 或监听资源;
  • 引用该材质的实体由创建方负责移除:
ts
viewer.entities.remove(entity)
// 或批量清理
viewer.entities.removeAll()

与原生 Cesium API 的组合方式

  • 可直接赋给 entity.polygon.material / entity.ellipsoid.material 等实体材质;
  • 也可与原生 new Cesium.Material({ fabric: { type: 'Water' } }) 等价使用, getValue(time) 的返回值即该材质所需的 uniforms;
  • perPositionHeight 结合可贴合真实地形高程的水面。