Effect example
Description of elements:
the code
/*
* @Date: 2023-07-19 11:15:22
* @LastEditors: ReBeX [email protected]
* @LastEditTime: 2023-07-28 12:08:58
* @FilePath: \cesium-tyro-blog\src\utils\Material\FlowPictureMaterialProperty.js
* @Description: 流动纹理/图片材质
*/
import * as Cesium from 'cesium'
export default class FlowPictureMaterialProperty {
constructor(options) {
this._definitionChanged = new Cesium.Event();
this._color = undefined;
this._colorSubscription = undefined;
this.image = options.image;
this.color = options.color;
this.duration = options.duration;
this._time = (new Date()).getTime();
};
get isConstant() {
return false;
}
get definitionChanged() {
return this._definitionChanged;
}
getType(time) {
return Cesium.Material.FlowPictureMaterialType;
}
getValue(time, result) {
if (!Cesium.defined(result)) {
result = {
};
}
result.time = (((new Date()).getTime() - this._time) % this.duration) / this.duration;
result.color = Cesium.Property.getValueOrDefault(this._color, time, Cesium.Color.RED, result.color);
// result.color = Cesium.Property.getValueOrClonedDefault(this._color, time, Cesium.Color.WHITE, result.color);
result.image = this.image;
return result
}
equals(other) {
return (this === other ||
(other instanceof FlowPictureMaterialProperty &&
Property.equals(this._color, other._color))
)
}
}
Object.defineProperties(FlowPictureMaterialProperty.prototype, {
color: Cesium.createPropertyDescriptor('color'),
})
// Cesium.FlowPictureMaterialProperty = FlowPictureMaterialProperty;
Cesium.Material.FlowPictureMaterialProperty = 'FlowPictureMaterialProperty';
Cesium.Material.FlowPictureMaterialType = 'FlowPictureMaterialType';
Cesium.Material.FlowPictureMaterialSource =
`
czm_material czm_getMaterial(czm_materialInput materialInput)
{
czm_material material = czm_getDefaultMaterial(materialInput);
vec2 st = materialInput.st;
vec4 colorImage = texture(image, vec2(fract(st.s - time), st.t));
material.alpha = colorImage.a * color.a;
material.diffuse = (colorImage.rgb+color.rgb)/2.0;
return material;
}
`
Cesium.Material._materialCache.addMaterial(Cesium.Material.FlowPictureMaterialType, {
fabric: {
type: Cesium.Material.FlowPictureMaterialType,
uniforms: {
color: new Cesium.Color(1.0, 0.0, 0.0, 1.0),
time: 0,
image: ''
},
source: Cesium.Material.FlowPictureMaterialSource
},
translucent: function (material) {
return true;
}
})
console.log('成功加载流动纹理/图片材质');
// ? 如何使用
// import FlowPictureMaterialProperty from '@/utils/Material/FlowPictureMaterialProperty.js'
// material: new FlowPictureMaterialProperty({
// color: new Cesium.Color(1.0, 0.0, 0.0, 1.0),
// image: '/src/assets/images/cat.png',
// duration: 3000,
// })
Example
import FlowPictureMaterialProperty from '@/utils/Material/FlowPictureMaterialProperty.js'
import {
viewer } from '@/utils/createCesium.js' // 引入地图对象
import * as Cesium from 'cesium'
const ellipse = viewer.entities.add({
position: Cesium.Cartesian3.fromDegrees(50, 50),
ellipse: {
semiMajorAxis: 150000.0, // 长半轴距离
semiMinorAxis: 150000.0, // 短半轴距离
material: new FlowPictureMaterialProperty({
color: Cesium.Color.WHITE, // new Cesium.Color(1.0, 1.0, 1.0, 1.0),
image: '/src/assets/images/redBar.png',
duration: 1500,
})
}
});
viewer.zoomTo(ellipse);
shader
The core of implementing a custom material is the source attribute of the fabric object. The following is the shader code of this material based on GLSL syntax:
czm_material czm_getMaterial(czm_materialInput materialInput)
{
czm_material material = czm_getDefaultMaterial(materialInput);
vec2 st = materialInput.st;
vec4 colorImage = texture(image, vec2(fract(st.s - time), st.t));
material.alpha = colorImage.a * color.a;
material.diffuse = (colorImage.rgb+color.rgb)/2.0;
return material;
}
materialInput
The main function of the code is to create a material object based on the input material
, then modify the material by manipulating the texture image and color, and finally return the modified material. Here is an explanation of the code:
czm_getDefaultMaterial(materialInput)
Create a default material: Create a default material object by calling a function and assign it to a variablematerial
.- Get texture coordinates and colors:
materialInput.st
Get texture coordinates by and assign them to variablesst
. Then, use the global variabletime
tost.s
calculate to get a new texture coordinatevec2(fract(st.s - time), st.t)
. Next, use that texture coordinateimage
to read the color value from the texture and assign it to a variablecolorImage
. - Modify transparency and diffuse color: set
material.alpha
tocolorImage.a
multiplied bycolor.a
, indicating that the transparency of the material is the product of the original color and the transparency of the texture image. Then,material.diffuse
set to addcolorImage.rgb
andcolor.rgb
divide by 2.0, indicating that the diffuse color of the material is the average of the original color and the color of the texture image. - ReturnModifiedMaterial: Returns the modifiedMaterial
material
as the result of the function.
other