Cesium之水流模型

本文介绍了使用Cesium创建水流模型的方法,通过Primitive图元实现仿真的水效果,重点讲解了定义材质、创建primitive以及解决元素变形错位的策略,结合官方示例详细阐述了制作过程。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

关于Primitive。

Primitive和Entity,一般翻译成图元和实体,图元更接近底层,实体是封装后的高级对象,使用更加简便。一般来说,Primitive的使用相对繁琐,相比Entity需要使用者自己初始化更多对象,包括外观、地理信息等,但正因为如此,为Primitive添加材质要方便很多,因为可以直接操作几何体的外观部分。

如何做出比较仿真的水

那么既然我们要仿真出比较偏向于真实流水的效果,当然是使用primitive对象会更加方便一些。

这里有官方的示例可以参照:传送门

从示例中我们可以看出,模仿水流效果的重点是材质文件和我们对于材质的基本属性设置。

以下图片材料即官方示例给出的材质材料,可以直接保存使用。
请添加图片描述

水流模型的制作

①定义材质

const material = new Cesium.Material({
      fabric: {
        type: "Water",
        uniforms: {
          // baseWaterColor: new Cesium.Color(64 / 255.0, 157 / 255.0, 253 / 255.0, 0.5),
          normalMap: '/static/waterNormals.jpg',
          frequency: 8000.0, // 控制波数的数字。
          animationSpeed: 0.02, // 控制水的动画速度的数字。
          amplitude: 5.0, // 控制水波振幅的数字。
          specularIntensity: 0.8, // 控制镜面反射强度的数字。
        }
      }
    })

②定义primitive

注意areaArr为[经度,纬度,高度,经度……]的一维数组,primitive的形状将会根据不同数据绘画出不同的水流形状。

let primitives = new Cesium.Primitive({
      geometryInstances: new Cesium.GeometryInstance({
        geometry: new Cesium.PolygonGeometry({
          polygonHierarchy: new Cesium.PolygonHierarchy(
            Cesium.Cartesian3.fromDegreesArray(areaArr)
          ),
          vertexFormat: Cesium.EllipsoidSurfaceAppearance.VERTEX_FORMAT,
          extrudedHeight: parseFloat(10),
          height: parseFloat(10)
        }),
      }),
      appearance: new Cesium.EllipsoidSurfaceAppearance({
        material: material
      }),
    })

③把primitive加入到viewer当中

this.viewer.scene.primitives.add(
      primitives
    );

在这里插入图片描述

元素变形错位的解决方案

加载后出现变形错位,很有可能是渲染方式错了,或者数据比较复杂,上面的解决方案适合比较简单的数据。

而下面这种则利用了cesium自带的渲染矢量方式,首先ceisumAPI会帮我们生成entity对象。然后我们拿出entity对象的坐标点位(通过entity.polygon.hierarchy.getValue()),把这些点位再构建一个polygon对象,赋给primitive,同时给primitive加载材质便可以解决错位变形问题。

Cesium.GeoJsonDataSource.load('资源文件地址').then(function (dataSource) {
      let entity = dataSource.entities.values[0];
      var geometry = new Cesium.PolygonGeometry({
        polygonHierarchy: entity.polygon.hierarchy.getValue(),
        height: -20,
        extrudedHeight: 10
      });
      let primitives = new Cesium.Primitive({
        geometryInstances: new Cesium.GeometryInstance({
          geometry: geometry,
        }),
        appearance: new Cesium.EllipsoidSurfaceAppearance({
          material: waterMaterial,
        }),
        asynchronous: false,
      })
      that.viewer.scene.primitives.add(
        primitives
      );

    })
### 使用 Cesium 实现水流流速效果 为了在 Cesium 中实现水流流速的效果,可以采用多种方法来增强视觉表现力。一种常见的方式是通过使用纹理动画和粒子系统相结合的方法。 #### 利用纹理动画创建流动感 可以通过设置材质属性中的 `image` 属性为带有方向性的水纹图片,并让其随着时间推移而移动,从而营造出流水的感觉。下面是一个简单的例子: ```javascript var viewer = new Cesium.Viewer('cesiumContainer'); // 定义一个矩形区域作为水面范围 var rectangle = Cesium.Rectangle.fromDegrees( 114.41804582947493, 30.605153408233175, 114.41793674042736, 30.605157286745346); viewer.entities.add({ name : 'Water Surface', availability : new Cesium.TimeIntervalCollection([new Cesium.TimeInterval({ start : Cesium.JulianDate.now(), stop : Cesium.JulianDate.addSeconds(Cesium.JulianDate.now(), 10, new Cesium.JulianDate()) })]), position: Cesium.Cartesian3.fromDegrees((114.41804582947493 + 114.41793674042736)/2, (30.605153408233175 + 30.605157286745346)/2), ellipse : { semiMinorAxis : 100.0, semiMajorAxis : 100.0, height : 0, material : new Cesium.Material({ fabric : { type : 'Image', uniforms : { image : './path/to/water_texture.png', // 替换为实际路径 repeat : new Cesium.Cartographic(2.0, 2.0) } }, translucent : true }), outline : false } }); ``` 这段代码定义了一个椭圆形实体表示水面,并为其指定了一个图像材料。这里的 `./path/to/water_texture.png` 应该替换为你自己的具有流动特性的水体纹理文件的位置[^1]。 #### 添加时间依赖性以模拟速度变化 为了让这种流动看起来更自然,还可以引入时间因素使纹理坐标随时间改变位置,进而表现出不同的流速。这通常涉及到修改顶点着色器或利用 Cesium 的内置功能调整模型矩阵。 对于更加复杂的场景,比如展示不同地点的不同流速,则可能需要用到地理信息系统(GIS)数据源提供的具体流量信息来进行精确建模。 #### 结合粒子系统增加真实度 除了上述方法外,也可以考虑加入一些小型的透明粒子沿着预设轨迹运动,以此进一步强化水流的真实性和动感。这些粒子可以在特定条件下(如下雨天)被激活显示出来。 以上就是在 Cesium 中实现基本水流流速效果的主要思路和技术要点。
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值