关于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
);
})