1、entity自定义材质
entity材质类型为Cesium.MaterialProperty。自定义材质实例如下,例子为实现飞线材质
import * as Cesium from 'cesium'
import gsap from 'gsap'
export default class polylineTrailMaterialProperty {
params: {
uTime: number
}
name: string
deFinitionChanged = new Cesium.Event()
isConstant = false
constructor(name: string) {
this.name = name
this.params = {
uTime: 0
}
;(Cesium.Material as any)._materialCache.addMaterial(
'polylineTrailMaterial',
{
fabric: {
type: 'polylineTrailMaterial',
uniforms: {
uTime:this.params.uTime
},
source: `
czm_material czm_getMaterial(czm_materialInput materialInput)
{
// 生成默认的基础材质
czm_material material = czm_getDefaultMaterial(materialInput);
vec2 st = materialInput.st;
// 定义动画持续时间,从0到1
float durationTime = 10.0;
// 获取当前帧数,fract(x) 返回x的小数部分
float time = fract(czm_frameNumber / (60.0 * durationTime));
time = time * (1.0 + 0.1);
// 平滑过度函数
// smoothstep(edge0,edge1,val)
float alpha = smoothstep(time - 0.1,time,st.s) * step(-time,-st.s);
material.alpha = alpha;
material.diffuse = vec3(1.0,1.0,1.0);
return material;
}
`
}
}
)
this.animate()
}
getType(time?: Cesium.JulianDate) {
return 'polylineTrailMaterial'
}
getValue(time: Cesium.JulianDate, result: { [key: string]: number }) {
result.uTime = this.params.uTime
return result
}
equals(other: Cesium.Property): boolean {
// 判断两个材质是否相等
return (
other instanceof polylineTrailMaterialProperty && this.name === other.name
)
}
animate() {
gsap.to(this.params, {
uTime: 1,
duration: 1,
repeat: -1,
yoyo: true
})
}
}
2、primitive的创建需要分为geometry、instance、appearance、material、primitive五步,material在appearance的option中,为Cesium.Material类型,他的自定义方式与上述类似
let material = new Cesium.Material({
fabric:{
uniforms:{
},
source:{`
czm_material czm_getMaterial(czm_materialInput materialInput){
czm_material material = czm_getDefaultMaterial(materialInput);
material.diffuse=vec3(1.0,0.0,0.0);
return material;
}
`}
}
})
上述源码存在于material.shaderSource中,在片元着色器中调用。
appearance._fragmentShaderSource : 片元着色器
appearance._vertexShaderSource : 顶点着色器
3、一些注意点
czm_frameNumber : 当前帧数
czm_materialInput:作为每个材质的czm_getMaterial函数的输入。
materialInput.st:二位纹理坐标,s从下至上,t从左至右,左下角(0,0),右上角(1,1)
glsl中一些常用函数:
smoothstep(t1,t2,val) : 生成0到1的平滑过渡值,它也叫平滑阶梯函数 ,x在 t1 到 t2 值的范围内变化曲线由缓到快再到缓的过程。
step(x,a) : 如果a小于x就是0 否则 返回1。
fract(x) : 返回x的小数部分
clamp(x,min,max) : 将随机变化的数值限制在一个给定的区间[min, max]内,也就是第一个和第二个比 选出大的temp,然后temp和第三个比,选出小的。
4、用纹理图实现轨迹飞线材质
import * as Cesium from 'cesium'
export default class SpritelineMaterialProperty {
name: string
img: string
deFinitionChanged = new Cesium.Event()
isConstant = false
constructor(name: string = 'spriteline1') {
this.name = name
this.img = '/api/textures/spriteline1.png'
;(Cesium.Material as any)._materialCache.addMaterial(
'SpritelineMaterialProperty',
{
fabric: {
type: 'SpritelineMaterialProperty',
uniforms: {
img: this.img
},
source: `
czm_material czm_getMaterial(czm_materialInput materialInput)
{
// 生成默认的基础材质
czm_material material = czm_getDefaultMaterial(materialInput);
vec2 st = materialInput.st;
// 定义动画持续时间,从0到1
float durationTime = 2.0;
// 获取当前帧数,fract(x) 返回x的小数部分
float time = fract(czm_frameNumber / (60.0 * durationTime));
// 根据uv采样颜色
vec4 color = texture2D(img,vec2(fract(st.s - time),st.t));
material.alpha = color.a;
material.diffuse = color.rgb;
return material;
}
`
}
}
)
}
getType(time?: Cesium.JulianDate) {
return 'SpritelineMaterialProperty'
}
getValue(time: Cesium.JulianDate, result: { [key: string]: number }) {
return result
}
equals(other: Cesium.Property): boolean {
// 判断两个材质是否相等
return (
other instanceof SpritelineMaterialProperty && this.name === other.name
)
}
}
vec4 texture2D(sampler2D sampler, vec2 coord) :第一个参数代表图片纹理,第二个参数代表纹理坐标点,通过GLSL的内建函数texture2D来获取对应位置纹理的颜色RGBA值