所有的类型都引入 cesium 1.102.0 版本
glsl 自定义着色器+代码注释
interface DirectionWallShaderProps {
count: number;
direction: '+' | '-';
freely: 'vertical' | 'cross';
}
const getDirectionWallShader = (options: DirectionWallShaderProps) => {
return `czm_material czm_getMaterial(czm_materialInput materialInput) {
// 获取默认的材质
czm_material material = czm_getDefaultMaterial(materialInput);
// 获取纹理坐标
vec2 st = materialInput.st;
// 基于帧数计算动画值
float animation = czm_frameNumber/60.0;
// 计算纹理坐标和动画值的组合
vec4 colorImage = texture(image, vec2(fract(float(${options.count}) * ${options.freely === 'vertical' ? 'st.s' : 'st.t'} ${
options.direction
} animation), fract(st.t)));
// 定义输出的片段颜色
vec4 fragColor;
// 计算片段颜色的 RGB 值
fragColor.rgb = (colorImage.rgb+color.rgb) / 1.0;
// 应用 gamma 矫正
fragColor = czm_gammaCorrect(fragColor);
// 设置材质的漫反射、透明度和自发光属性
material.diffuse = colorImage.rgb;
material.alpha = colorImage.a;
material.emission = fragColor.rgb;
// 返回最终的材质
return material;
}`;
};
自定义材质
class WallShader {
private color: Color;
isConstant!: boolean;
definitionChanged = new Event();
image: string;
freely: DirectionWallShaderProps['freely'];
direction: DirectionWallShaderProps['direction'];
count: DirectionWallShaderProps['count'];
constructor({ color, image, freely, direction, count }: WallShaderProps) {
this.definitionChanged = new Event();
this.isConstant = false;
this.color = color;
this.image = image;
this.freely = freely;
this.direction = direction;
this.count = count;
this.addMaterial();
}
getType() {
return 'WallShader';
}
equals(other: WallShader) {
return this === other || other instanceof WallShader;
}
getValue(
_time: JulianDate,
result: {
color: Color;
image: string;
}
) {
return result;
}
addMaterial() {
(Material as any)._materialCache.addMaterial('WallShader', {
fabric: {
type: 'WallShader',
uniforms: {
color: this.color,
image: this.image
},
source: getDirectionWallShader({
freely: this.freely,
direction: this.direction,
count: this.count
})
},
translucent: () => {
return true;
}
});
}
}
代码使用
viewer.entities.add({
id: 'wall',
wall: {
positions: positions,
maximumHeights: positions.map(() => height),
minimumHeights: positions.map(() => 0),
material: new WallShader({
color: Color.fromCssColorString(wallColor),
image,
freely,
count,
direction
}) as unknown as MaterialProperty
}
});