绘制水波填充多边形(Entity方式)-使用shader
1 目标
使用Entity方式绘制绘制水波填充多边形 - 使用shader
2 代码
2.1 main.ts
import * as Cesium from 'cesium';
// 创建 Cesium Viewer 实例
const viewer = new Cesium.Viewer('cesiumContainer', {});
// 定义凸多边形的顶点坐标(使用经纬度数组)
const positions = Cesium.Cartesian3.fromDegreesArray([
-120.0, 40.0,
-110.0, 45.0,
-100.0, 45.0,
-90.0, 40.0,
-95.0, 35.0,
-105.0, 30.0,
-115.0, 35.0
]);
// 创建自定义材质属性类,实现 Cesium.MaterialProperty 接口
class CustomWaterMaterialProperty implements Cesium.MaterialProperty {
private _definitionChanged = new Cesium.Event();
private params: {
baseWaterColor: Cesium.Color; // 基础水色
blendColor: Cesium.Color; // 混合颜色
specularMap: string; // 高光贴图
normalMap: string; // 法线贴图
frequency: number; // 波浪频率
animationSpeed: number; // 动画速度
amplitude: number; // 波浪振幅
specularIntensity: number; // 高光强度
fadeFactor: number; // 消退因子
};
constructor(
baseWaterColor: Cesium.Color,
blendColor: Cesium.Color,
specularMap: string,
normalMap: string,
frequency: number,
animationSpeed: number,
amplitude: number,
specularIntensity: number,
fadeFactor: number
) {
this.params = {
baseWaterColor: baseWaterColor,
blendColor: blendColor,
specularMap: specularMap,
normalMap: normalMap,
frequency: frequency,
animationSpeed: animationSpeed,
amplitude: amplitude,
specularIntensity: specularIntensity,
fadeFactor: fadeFactor,
};
// 片段着色器代码,用于创建水波效果
const fs = `
uniform sampler2D specularMap; // 高光贴图
uniform sampler2D normalMap; // 法线贴图
uniform vec4 baseWaterColor; // 基础水色
uniform vec4 blendColor; // 混合颜色
uniform float frequency; // 波浪频率
uniform float animationSpeed; // 动画速度
uniform float amplitude; // 波浪振幅
uniform float specularIntensity; // 高光强度
uniform float fadeFactor; // 消退因子
czm_material czm_getMaterial(czm_materialInput materialInput)
{
czm_material material = czm_getDefaultMaterial(materialInput); // 获取默认材质
float time = czm_frameNumber * animationSpeed; // 计算时间,控制动画效果
// 计算波浪消退效果
float fade = max(1.0, (length(materialInput.positionToEyeEC) / 10000000000.0) * frequency * fadeFactor);
// 获取高光贴图的值
float specularMapValue = texture(specularMap, materialInput.st).r;
// 获取法线贴图中的噪声,用于模拟水波效果
vec4 noise = czm_getWaterNoise(normalMap, materialInput.st * frequency, time, 0.0);
vec3 normalTangentSpace = noise.xyz * vec3(1.0, 1.0, (1.0 / amplitude));
// 根据距离远近调整法线扰动
normalTangentSpace.xy /= fade;
// 混合高光贴图的值
normalTangentSpace = mix(vec3(0.0, 0.0, 50.0), normalTangentSpace, specularMapValue);
normalTangentSpace = normalize(normalTangentSpace);
// 计算法线的切线空间的扰动比率
float tsPerturbationRatio = clamp(dot(normalTangentSpace, vec3(0.0, 0.0, 1.0)), 0.0, 1.0);
// 混合材质的透明度
material.alpha = mix(blendColor.a, baseWaterColor.a, specularMapValue) * specularMapValue;
// 根据高光贴图的值计算基础颜色
material.diffuse = mix(blendColor.rgb, baseWaterColor.rgb, specularMapValue);
// 根据法线扰动调整扩散高光
material.diffuse += (0.1 * tsPerturbationRatio);
// 设置材质的法线方向
material.normal = normalize(materialInput.tangentToEyeMatrix * normalTangentSpace);
// 设置材质的高光强度和光泽度
material.specular = specularIntensity;
material.shininess = 10.0;
return material; // 返回材质
}
`;
// 添加材质到 Cesium 的材质缓存中
(Cesium.Material as any)._materialCache.addMaterial("CustomWaterMaterial", {
fabric: {
type: "CustomWaterMaterial",
uniforms: {
baseWaterColor: this.params.baseWaterColor,
blendColor: this.params.blendColor,
specularMap: this.params.specularMap,
normalMap: this.params.normalMap,
frequency: this.params.frequency,
animationSpeed: this.params.animationSpeed,
amplitude: this.params.amplitude,
specularIntensity: this.params.specularIntensity,
fadeFactor: this.params.fadeFactor,
},
source: fs, // 片段着色器代码
},
translucent: function (material) {
// 判断材质是否是透明的
return material.uniforms.baseWaterColor.alpha < 1 || material.uniforms.blendColor.alpha < 1;
}
});
}
getType(): string {
return "CustomWaterMaterial"; // 返回材质类型
}
getValue(time: Cesium.JulianDate, result: any): any {
if (!result) {
result = {};
}
result.baseWaterColor = this.params.baseWaterColor; // 获取基础水颜色
result.blendColor = this.params.blendColor; // 获取混合颜色
result.specularMap = this.params.specularMap; // 获取高光贴图
result.normalMap = this.params.normalMap; // 获取法线贴图
result.frequency = this.params.frequency; // 获取波浪频率
result.animationSpeed = this.params.animationSpeed; // 获取动画速度
result.amplitude = this.params.amplitude; // 获取波浪振幅
result.specularIntensity = this.params.specularIntensity; // 获取高光强度
result.fadeFactor = this.params.fadeFactor; // 获取消退因子
return result;
}
equals(other: Cesium.MaterialProperty): boolean {
return (
other instanceof CustomWaterMaterialProperty &&
Cesium.Color.equals(this.params.baseWaterColor, other.params.baseWaterColor) &&
Cesium.Color.equals(this.params.blendColor, other.params.blendColor) &&
this.params.specularMap === other.params.specularMap &&
this.params.normalMap === other.params.normalMap &&
this.params.frequency === other.params.frequency &&
this.params.animationSpeed === other.params.animationSpeed &&
this.params.amplitude === other.params.amplitude &&
this.params.specularIntensity === other.params.specularIntensity &&
this.params.fadeFactor === other.params.fadeFactor
);
}
get isConstant(): boolean {
return false; // 材质的参数可以变化
}
get definitionChanged(): Cesium.Event {
return this._definitionChanged; // 返回材质定义改变事件
}
set definitionChanged(value: Cesium.Event) {
this._definitionChanged = value;
}
}
// 创建自定义材质实例
const material = new CustomWaterMaterialProperty(
new Cesium.Color(0.2, 0.3, 0.6, 1.0), // 基础水色
new Cesium.Color(0.0, 1.0, 0.699, 1.0), // 混合颜色
'', // 高光贴图路径
'water.png', // 法线贴图路径
100.0, // 波浪频率
0.005, // 动画速度
10.0, // 波浪振幅
0.5, // 高光强度
1.0 // 消退因子
);
// 添加多边形实体到场景中,并应用自定义材质
const polygonEntity = viewer.entities.add({
polygon: {
hierarchy: new Cesium.PolygonHierarchy(positions), // 使用顶点坐标数组定义多边形层次结构
material: material // 应用自定义材质
}
});
3 资源

2385

被折叠的 条评论
为什么被折叠?



