在项目中,总会遇到一些 需要 逐渐变大的区域的实现效果,而变大到一定程度消失,需要保证页面不卡顿,如果采用 callbackProperty 或有卡顿现象,跳针现象,无法保证区域可操纵性,常使用方式:
window.viewer.entities.add({
position: Cesium.Cartesian3.fromDegrees(100, 21),
name: 'xxx',
ellipse: {
semiMinorAxis: new Cesium.CallbackProperty(changeR, false),
semiMajorAxis: new Cesium.CallbackProperty(changeR, false),
Material: Cesium.Color.RED,
}
})
function changeR () {
// increateR 增加量
// 增加量 为 增加速度 * 时间
return r + increateR (increateR = (newDate - oldDate) * speed)
}
为保证,需求,我们直接使材质发生变化,也就是直接作用到GPU 上,cesium 采用 material方式,常见的方法
// 创建一个圆形几何体
var circleGeometry = new Cesium.EllipseGeometry({
center: Cesium.Cartesian3.fromDegrees(100, 21), // 圆心位置
semiMinorAxis: explode.DamageRange,
semiMajorAxis: explode.DamageRange,
vertexFormat: Cesium.PerInstanceColorAppearance.VERTEX_FORMAT // 使用PerInstanceColorAppearance格式
});
// 创建一个实体实例
var instance = new Cesium.GeometryInstance({
geometry: circleGeometry,
attributes: {
color: new Cesium.ColorGeometryInstanceAttribute(0.0, 1.0, 1.0, 1.0) // 设置实体的颜色
},
id: 'circle' // 设置实例的id
});
window.viewer.scene.primitives.add({
geometryInstances: [instance],
appearance: new Cesium.EllipsoidSurfaceAppearance({
//
material: new Cesium.Material({
fabric: {
uniforms: {
u_color: new Cesium.Color(1.0, 0.0, 0.0, 0.3),
u_duration: explode.TimeToLast,
czm_frameNumberFraction: 1000,
},
source: `
czm_material czm_getMaterial(czm_materialInput materialInput) {
czm_material material = czm_getDefaultMaterial(materialInput);
vec2 st = materialInput.st;
float radius = length(st - vec2(0.5));
float t = fract(czm_frameNumber / (czm_frameNumberFraction * u_duration));
float timePercent = min(1.0, t);
if (timePercent >= 1.0) {
return material;
} else {
material.alpha = alpha;
material.diffuse = u_color.rgb;
return material.diffuse = u_color.rgb;
}
}
`
}
})
})
});
这种方法,实时计算alpha 值,可以做到区域随着变化而变化,但是并不能保证区域从零开始,于是
// 创建一个圆形几何体
var circleGeometry = new Cesium.EllipseGeometry({
center: Cesium.Cartesian3.fromDegrees(100, 21), // 圆心位置
semiMinorAxis: explode.DamageRange,
semiMajorAxis: explode.DamageRange,
vertexFormat: Cesium.PerInstanceColorAppearance.VERTEX_FORMAT // 使用PerInstanceColorAppearance格式
});
// 创建一个实体实例
var instance = new Cesium.GeometryInstance({
geometry: circleGeometry,
attributes: {
color: new Cesium.ColorGeometryInstanceAttribute(0.0, 1.0, 1.0, 1.0) // 设置实体的颜色
},
id: 'circle' // 设置实例的id
});
window.viewer.scene.primitives.add({
geometryInstances: [instance],
appearance: new Cesium.EllipsoidSurfaceAppearance({
//
material: new Cesium.Material({
fabric: {
uniforms: {
u_color: new Cesium.Color(1.0, 0.0, 0.0, 0.3),
u_duration: explode.TimeToLast,
u_frameNumber: 0.0,
czm_frameNumberFraction: 1000,
},
source: `
czm_material czm_getMaterial(czm_materialInput materialInput) {
czm_material material = czm_getDefaultMaterial(materialInput);
vec2 st = materialInput.st;
float radius = length(st - vec2(0.5));
float t = fract(u_frameNumber / (czm_frameNumberFraction * u_duration));
float timePercent = min(1.0, t);
if (timePercent >= 1.0) {
return material;
} else {
material.alpha = alpha;
material.diffuse = u_color.rgb;
return material.diffuse = u_color.rgb;
}
}
`
}
})
})
});
// 实时监控 u_frameNumber 变化
function timeExp () {
let _requestId = 0;
let _now = Date.now();
let that = this;
let _primitive = null;
function animationFrame () {
if (Math.floor(Date.now() - _now) > explode.TimeToLast * 1000) {
explodesCollection.remove(_primitive)
Cesium.cancelAnimationFrame(_requestId)
} else {
if (_primitive) {
_primitive.appearance.material.uniforms.u_frameNumber = Date.now() - _now;
} else {
_primitive = that.getById(explode.Handle)
}
_requestId = Cesium.requestAnimationFrame(animationFrame)
}
}
}
采用 此方法,可是实时计算区域变化,随着时间的推移从而采用 js控制 GPU 变化
如此,可实现,区域随时间的推演而材质发生变化的需求,如果量比较大,不会影响渲染效果