CesiumJS【Basic】- #066 绘制水波填充多边形(Entity方式)-使用shader

绘制水波填充多边形(Entity方式)-使用shader

1 目标

使用Entity方式绘制绘制水波填充多边形 - 使用shader

2 代码

2.1 main.ts

import * as Cesium from 'cesium';

// 创建 Cesium Viewer 实例
const viewer = new Cesium.Viewer('cesiumContainer', {});

// 定义凸多边形的顶点坐标(使用经纬度数组)
const positions = Cesium.Cartesian3.fromDegreesArray([
  -120.0, 40.0,
  -110.0, 45.0,
  -100.0, 45.0,
  -90.0, 40.0,
  -95.0, 35.0,
  -105.0, 30.0,
  -115.0, 35.0
]);

// 创建自定义材质属性类,实现 Cesium.MaterialProperty 接口
class CustomWaterMaterialProperty implements Cesium.MaterialProperty {
  private _definitionChanged = new Cesium.Event();
  private params: {
    baseWaterColor: Cesium.Color; // 基础水色
    blendColor: Cesium.Color; // 混合颜色
    specularMap: string; // 高光贴图
    normalMap: string; // 法线贴图
    frequency: number; // 波浪频率
    animationSpeed: number; // 动画速度
    amplitude: number; // 波浪振幅
    specularIntensity: number; // 高光强度
    fadeFactor: number; // 消退因子
  };

  constructor(
    baseWaterColor: Cesium.Color,
    blendColor: Cesium.Color,
    specularMap: string,
    normalMap: string,
    frequency: number,
    animationSpeed: number,
    amplitude: number,
    specularIntensity: number,
    fadeFactor: number
  ) {
    this.params = {
      baseWaterColor: baseWaterColor,
      blendColor: blendColor,
      specularMap: specularMap,
      normalMap: normalMap,
      frequency: frequency,
      animationSpeed: animationSpeed,
      amplitude: amplitude,
      specularIntensity: specularIntensity,
      fadeFactor: fadeFactor,
    };

    // 片段着色器代码,用于创建水波效果
    const fs = `
      uniform sampler2D specularMap; // 高光贴图
      uniform sampler2D normalMap; // 法线贴图
      uniform vec4 baseWaterColor; // 基础水色
      uniform vec4 blendColor; // 混合颜色
      uniform float frequency; // 波浪频率
      uniform float animationSpeed; // 动画速度
      uniform float amplitude; // 波浪振幅
      uniform float specularIntensity; // 高光强度
      uniform float fadeFactor; // 消退因子

      czm_material czm_getMaterial(czm_materialInput materialInput)
      {
        czm_material material = czm_getDefaultMaterial(materialInput); // 获取默认材质
        float time = czm_frameNumber * animationSpeed; // 计算时间,控制动画效果

        // 计算波浪消退效果
        float fade = max(1.0, (length(materialInput.positionToEyeEC) / 10000000000.0) * frequency * fadeFactor);

        // 获取高光贴图的值
        float specularMapValue = texture(specularMap, materialInput.st).r;

        // 获取法线贴图中的噪声,用于模拟水波效果
        vec4 noise = czm_getWaterNoise(normalMap, materialInput.st * frequency, time, 0.0);
        vec3 normalTangentSpace = noise.xyz * vec3(1.0, 1.0, (1.0 / amplitude));

        // 根据距离远近调整法线扰动
        normalTangentSpace.xy /= fade;

        // 混合高光贴图的值
        normalTangentSpace = mix(vec3(0.0, 0.0, 50.0), normalTangentSpace, specularMapValue);

        normalTangentSpace = normalize(normalTangentSpace);

        // 计算法线的切线空间的扰动比率
        float tsPerturbationRatio = clamp(dot(normalTangentSpace, vec3(0.0, 0.0, 1.0)), 0.0, 1.0);

        // 混合材质的透明度
        material.alpha = mix(blendColor.a, baseWaterColor.a, specularMapValue) * specularMapValue;

        // 根据高光贴图的值计算基础颜色
        material.diffuse = mix(blendColor.rgb, baseWaterColor.rgb, specularMapValue);

        // 根据法线扰动调整扩散高光
        material.diffuse += (0.1 * tsPerturbationRatio);

        // 设置材质的法线方向
        material.normal = normalize(materialInput.tangentToEyeMatrix * normalTangentSpace);

        // 设置材质的高光强度和光泽度
        material.specular = specularIntensity;
        material.shininess = 10.0;

        return material; // 返回材质
      }
    `;

    // 添加材质到 Cesium 的材质缓存中
    (Cesium.Material as any)._materialCache.addMaterial("CustomWaterMaterial", {
      fabric: {
        type: "CustomWaterMaterial",
        uniforms: {
          baseWaterColor: this.params.baseWaterColor,
          blendColor: this.params.blendColor,
          specularMap: this.params.specularMap,
          normalMap: this.params.normalMap,
          frequency: this.params.frequency,
          animationSpeed: this.params.animationSpeed,
          amplitude: this.params.amplitude,
          specularIntensity: this.params.specularIntensity,
          fadeFactor: this.params.fadeFactor,
        },
        source: fs, // 片段着色器代码
      },
      translucent: function (material) {
        // 判断材质是否是透明的
        return material.uniforms.baseWaterColor.alpha < 1 || material.uniforms.blendColor.alpha < 1;
      }
    });
  }

  getType(): string {
    return "CustomWaterMaterial"; // 返回材质类型
  }

  getValue(time: Cesium.JulianDate, result: any): any {
    if (!result) {
      result = {};
    }
    result.baseWaterColor = this.params.baseWaterColor; // 获取基础水颜色
    result.blendColor = this.params.blendColor; // 获取混合颜色
    result.specularMap = this.params.specularMap; // 获取高光贴图
    result.normalMap = this.params.normalMap; // 获取法线贴图
    result.frequency = this.params.frequency; // 获取波浪频率
    result.animationSpeed = this.params.animationSpeed; // 获取动画速度
    result.amplitude = this.params.amplitude; // 获取波浪振幅
    result.specularIntensity = this.params.specularIntensity; // 获取高光强度
    result.fadeFactor = this.params.fadeFactor; // 获取消退因子
    return result;
  }

  equals(other: Cesium.MaterialProperty): boolean {
    return (
      other instanceof CustomWaterMaterialProperty &&
      Cesium.Color.equals(this.params.baseWaterColor, other.params.baseWaterColor) &&
      Cesium.Color.equals(this.params.blendColor, other.params.blendColor) &&
      this.params.specularMap === other.params.specularMap &&
      this.params.normalMap === other.params.normalMap &&
      this.params.frequency === other.params.frequency &&
      this.params.animationSpeed === other.params.animationSpeed &&
      this.params.amplitude === other.params.amplitude &&
      this.params.specularIntensity === other.params.specularIntensity &&
      this.params.fadeFactor === other.params.fadeFactor
    );
  }

  get isConstant(): boolean {
    return false; // 材质的参数可以变化
  }

  get definitionChanged(): Cesium.Event {
    return this._definitionChanged; // 返回材质定义改变事件
  }

  set definitionChanged(value: Cesium.Event) {
    this._definitionChanged = value;
  }
}

// 创建自定义材质实例
const material = new CustomWaterMaterialProperty(
  new Cesium.Color(0.2, 0.3, 0.6, 1.0), // 基础水色
  new Cesium.Color(0.0, 1.0, 0.699, 1.0), // 混合颜色
  '', // 高光贴图路径
  'water.png', // 法线贴图路径
  100.0, // 波浪频率
  0.005, // 动画速度
  10.0, // 波浪振幅
  0.5, // 高光强度
  1.0  // 消退因子
);

// 添加多边形实体到场景中,并应用自定义材质
const polygonEntity = viewer.entities.add({
  polygon: {
    hierarchy: new Cesium.PolygonHierarchy(positions), // 使用顶点坐标数组定义多边形层次结构
    material: material // 应用自定义材质
  }
});


3 资源

在这里插入图片描述

评论 5
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

满天飞飞

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值