前言
今天主要和大家介绍一下cesium中怎么实现一个扩散圆的效果!
基本原理
如果有一个红色的圆形,我们希望在shader里面把这个圆形变成一个从四周向中心透明渐变的圆应该怎么做呢?我们只需要通过"UV"去计算导中心(0.5,0.5)的距离就可以得到。
//伪代码
float dis = distance(uv, vec2(0.5, 0.5));
color.a = fract(dis);
如果我希望圆形呈现一个慢慢变大的效果应该怎么做呢?我们只需要判断当dis大于某个阈值的时候透明度为零,否则不变,这个阈值随时间不断从0-1就行。
//伪代码
//fract函数去time的小数,范围0-1
float per1 = fract(time);
float dis = distance(uv, vec2(0.5, 0.5));
//step函数当dis大于per1的时候返回1,小于就返回0,
float pass1 = step(per1, dis) == 0.0? color.a * dis / per1: 0.0;
color.a = pass1;
cesium实现
基本的原理就是这样,那接下来就让我们自cesium实现这个效果。
1.先用 primetive 创建一个圆形
const instance = new Cesium.GeometryInstance({
geometry: new Cesium.EllipseGeometry({
center: Cesium.Cartesian3.fromDegrees(118, 23, 0),
semiMinorAxis: 500,
semiMajorAxis: 500,
}),
});
2.创建一个 MaterialAppearance,更具上面的原理修改 material 的 source,注意下面的代码我优化了一下效果,增加了两道波纹,并且实现了一个渐变消失的过程。
const appearance = new Cesium.MaterialAppearance({
material: new Cesium.Material({
fabric: {
uniforms: {
color: Cesium.Color.fromCssColorString(color),
speed: 1,
},
source: `
czm_material czm_getMaterial(czm_materialInput materialInput) {
czm_material material = czm_getDefaultMaterial(materialInput);
material.diffuse = 1.5 * color.rgb;
vec2 st = materialInput.st;
float dis = distance(st, vec2(0.5, 0.5));
//重复三次,每次的时间偏移一点,实现三道扩散
float per1 = fract(czm_frameNumber * 0.032 * speed);
float per2 = fract((czm_frameNumber * 0.032 * speed) - 0.3);
float per3 = fract((czm_frameNumber * 0.032 * speed) - 0.6);
float pass1 = step(per1 * 0.3, dis) == 0.0? color.a * dis / per1: 0.0;
float pass2 = step(per2 * 0.3, dis) == 0.0? color.a * dis / per2: 0.0;
float pass3 = step(per3 * 0.3, dis) == 0.0? color.a * dis / per3: 0.0;
//实现每道扩散渐变消失的效果
pass1 = pass1* (1.0 - per1) * 2.0;
pass2 = pass2* (1.0 - per2) * 2.0;
pass3 = pass3* (1.0 - per3) * 2.0;
material.alpha = pass1;
return material;
}
`,
}
}),
})
3.最终添加场景就行了
let primitive = viewer.scene.primitives.add(
new Cesium.Primitive({
geometryInstances: instance,
appearance: appearance
})
);
扩散圆的效果到这里就介绍完毕啦,希望能对大家有所帮助!有问题可以在评论区留言~小编会定时回复大家的问题