<link href="path/to/cesium/Widgets/widgets.css" rel="stylesheet">
<script src="path/to/cesium/Cesium.js"></script>
<div id="cesiumContainer"></div>
<script>
const viewer = new Cesium.Viewer('cesiumContainer', {
terrainProvider: Cesium.createWorldTerrain(),
baseLayer: Cesium.ImageryLayer.fromProviderAsync(Cesium.createTileMapServiceImageryProvider({
url: Cesium.buildModuleUrl('Assets/Textures/NaturalEarthII')
}))
});
</script>
const flowMapMaterial = new Cesium.Material({
fabric: {
type: 'FlowMapWater',
uniforms: {
flowMap: 'path/to/flowmap.png', // FlowMap 纹理(RG通道编码流向)
normalMap: 'path/to/waterNormals.jpg',// 基础法线贴图
speed: 0.3, // 流速控制
amplitude: 1.5, // 波纹振幅
time: 0 // 时间变量
},
source: `
uniform sampler2D flowMap;
uniform sampler2D normalMap;
uniform float speed;
uniform float amplitude;
uniform float time;
varying vec2 v_st;
varying vec3 v_positionEC;
void main() {
// 获取 FlowMap 向量场(范围映射到 -1 到 1)
vec2 flowDir = texture2D(flowMap, v_st).rg * 2.0 - 1.0;
flowDir *= speed;
// 双相位插值(防止周期断层)
float phase0 = fract(time * 0.1);
float phase1 = fract(time * 0.1 + 0.5);
vec2 uvOffset0 = flowDir * phase0;
vec2 uvOffset1 = flowDir * phase1;
// 混合法线贴图
vec3 normal0 = texture2D(normalMap, v_st * 10.0 + uvOffset0).rgb;
vec3 normal1 = texture2D(normalMap, v_st * 10.0 + uvOffset1).rgb;
float lerpFactor = abs(0.5 - phase0) * 2.0;
vec3 finalNormal = mix(normal0, normal1, lerpFactor);
// 计算光照与颜色
vec3 viewDir = normalize(-v_positionEC);
vec3 reflected = reflect(viewDir, finalNormal);
vec4 baseColor = vec4(0.1, 0.3, 0.8, 0.8);
gl_FragColor = vec4(baseColor.rgb * (0.5 + dot(finalNormal, viewDir)), baseColor.a);
}
`
}
});
// 创建水面几何体(河道形状)
const waterPolygon = viewer.scene.primitives.add(
new Cesium.Primitive({
geometryInstances: new Cesium.GeometryInstance({
geometry: new Cesium.PolygonGeometry({
polygonHierarchy: new Cesium.PolygonHierarchy(
Cesium.Cartesian3.fromDegreesArray([
-75.0, 40.0, -74.5, 40.2, -74.0, 40.0
])
),
vertexFormat: Cesium.EllipsoidSurfaceAppearance.VERTEX_FORMAT,
extrudedHeight: 0,
height: 0
})
}),
appearance: new Cesium.EllipsoidSurfaceAppearance({
material: flowMapMaterial,
aboveGround: false
})
})
);
// 更新时间变量
viewer.scene.preUpdate.addEventListener(() => {
flowMapMaterial.uniforms.time = Cesium.JulianDate.now().secondsOfDay;
});
flowMapMaterial.uniforms.speed = 0.5; // 流速(0.1-2.0)
flowMapMaterial.uniforms.amplitude = 2.0;// 波纹高度
flowMapMaterial.uniforms.normalMap = new Cesium.TextureUniform({
url: 'path/to/new_normalmap.jpg' // 替换法线贴图
});