2025-03-11 08:25:45 +00:00
|
|
|
|
<!--********************************************************************
|
|
|
|
|
* by jiawanlong
|
|
|
|
|
*********************************************************************-->
|
|
|
|
|
<!DOCTYPE html>
|
|
|
|
|
<html>
|
|
|
|
|
|
|
|
|
|
<head>
|
|
|
|
|
<meta charset="UTF-8" />
|
2025-03-19 03:00:22 +00:00
|
|
|
|
<link rel="stylesheet" href="./../../libs/cesium/Cesium1.98/Widgets/widgets.css">
|
|
|
|
|
<script type="text/javascript" src="./../../libs/cesium/Cesium1.98/Cesium.js"></script>
|
2025-03-11 08:25:45 +00:00
|
|
|
|
</head>
|
|
|
|
|
|
|
|
|
|
<body style="margin: 0; overflow: hidden; background: #fff; width: 100%; height: 100%; position: absolute; top: 0">
|
|
|
|
|
<div id="map" style="margin: 0 auto; width: 100%; height: 100%"></div>
|
|
|
|
|
<script type="text/javascript">
|
|
|
|
|
|
|
|
|
|
Cesium.Ion.defaultAccessToken = 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJqdGkiOiI3ZjQ5ZGUzNC1jNWYwLTQ1ZTMtYmNjYS05YTY4ZTVmN2I2MDkiLCJpZCI6MTE3MTM4LCJpYXQiOjE2NzY0NDUyODB9.ZaNSBIfc1sGLhQd_xqhiSsc0yr8oS0wt1hAo9gbke6M'
|
|
|
|
|
const viewer = new Cesium.Viewer('map', {});
|
|
|
|
|
|
|
|
|
|
// 开启帧率
|
|
|
|
|
viewer.scene.debugShowFramesPerSecond = true;
|
|
|
|
|
// 深度监测
|
|
|
|
|
viewer.scene.globe.depthTestAgainstTerrain = true;
|
|
|
|
|
// 清除默认地形
|
|
|
|
|
viewer.scene.terrainProvider = new Cesium.EllipsoidTerrainProvider({});
|
|
|
|
|
|
|
|
|
|
// 加载火星地形
|
|
|
|
|
viewer.terrainProvider = new Cesium.CesiumTerrainProvider({
|
|
|
|
|
url: 'http://data.mars3d.cn/terrain'
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
const fs = `
|
|
|
|
|
uniform sampler2D colorTexture; // 颜色纹理
|
|
|
|
|
uniform sampler2D depthTexture; // 深度纹理
|
|
|
|
|
in vec2 v_textureCoordinates; // 纹理坐标
|
|
|
|
|
uniform float u_earthRadiusOnCamera;
|
|
|
|
|
uniform float u_cameraHeight;
|
|
|
|
|
uniform float u_fogHeight;
|
|
|
|
|
uniform vec3 u_fogColor;
|
|
|
|
|
uniform float u_globalDensity;
|
|
|
|
|
// 通过深度纹理与纹理坐标得到世界坐标
|
|
|
|
|
vec4 getWorldCoordinate(sampler2D depthTexture, vec2 texCoords) {
|
|
|
|
|
float depthOrLogDepth = czm_unpackDepth(texture(depthTexture, texCoords));
|
|
|
|
|
vec4 eyeCoordinate = czm_windowToEyeCoordinates(gl_FragCoord.xy, depthOrLogDepth);
|
|
|
|
|
eyeCoordinate = eyeCoordinate / eyeCoordinate.w;
|
|
|
|
|
vec4 worldCoordinate = czm_inverseView * eyeCoordinate;
|
|
|
|
|
worldCoordinate = worldCoordinate / worldCoordinate.w;
|
|
|
|
|
return worldCoordinate;
|
|
|
|
|
}
|
|
|
|
|
// 计算粗略的高程,依赖js传递的相机位置处的地球高程u_earthRadiusOnCamera。好处是计算量非常低
|
|
|
|
|
float getRoughHeight(vec4 worldCoordinate) {
|
|
|
|
|
float disToCenter = length(vec3(worldCoordinate));
|
|
|
|
|
return disToCenter - u_earthRadiusOnCamera;
|
|
|
|
|
}
|
|
|
|
|
// 得到a向量在b向量的投影长度,如果同向结果为正,异向结果为复
|
|
|
|
|
float projectVector(vec3 a, vec3 b) {
|
|
|
|
|
float scale = dot(a, b) / dot(b, b);
|
|
|
|
|
float k = scale / abs(scale);
|
|
|
|
|
return k * length(scale * b);
|
|
|
|
|
}
|
|
|
|
|
// 线性浓度积分高度雾
|
|
|
|
|
float linearHeightFog(vec3 positionToCamera, float cameraHeight, float pixelHeight, float fogMaxHeight) {
|
|
|
|
|
float globalDensity = u_globalDensity / 10.0;
|
|
|
|
|
vec3 up = -1.0 * normalize(czm_viewerPositionWC);
|
|
|
|
|
float vh = projectVector(normalize(positionToCamera), up);
|
|
|
|
|
|
|
|
|
|
// 让相机沿着视线方向移动 雾气产生距离 的距离
|
|
|
|
|
float s = step(100.0, length(positionToCamera));
|
|
|
|
|
vec3 sub = mix(positionToCamera, normalize(positionToCamera) * 100.0, s);
|
|
|
|
|
positionToCamera -= sub;
|
|
|
|
|
cameraHeight = mix(pixelHeight, cameraHeight - 100.0 * vh, s);
|
|
|
|
|
|
|
|
|
|
float b = mix(cameraHeight, fogMaxHeight, step(fogMaxHeight, cameraHeight));
|
|
|
|
|
float a = mix(pixelHeight, fogMaxHeight, step(fogMaxHeight, pixelHeight));
|
|
|
|
|
|
|
|
|
|
float fog = (b - a) - 0.5 * (pow(b, 2.0) - pow(a, 2.0)) / fogMaxHeight;
|
|
|
|
|
fog = globalDensity * fog / vh;
|
|
|
|
|
|
|
|
|
|
if(abs(vh) <= 0.01 && cameraHeight < fogMaxHeight) {
|
|
|
|
|
float disToCamera = length(positionToCamera);
|
|
|
|
|
fog = globalDensity * (1.0 - cameraHeight / fogMaxHeight) * disToCamera;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
fog = mix(0.0, 1.0, fog / (fog + 1.0));
|
|
|
|
|
|
|
|
|
|
return fog;
|
|
|
|
|
}
|
|
|
|
|
void main(void) {
|
|
|
|
|
vec4 color = texture(colorTexture, v_textureCoordinates);
|
|
|
|
|
vec4 positionWC = getWorldCoordinate(depthTexture, v_textureCoordinates);
|
|
|
|
|
float pixelHeight = getRoughHeight(positionWC);
|
|
|
|
|
vec3 positionToCamera = vec3(vec3(positionWC) - czm_viewerPositionWC);
|
|
|
|
|
float fog = linearHeightFog(positionToCamera, u_cameraHeight, pixelHeight, u_fogHeight);
|
|
|
|
|
out_FragColor = mix(color, vec4(u_fogColor, 1.0), fog);
|
|
|
|
|
}`
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
const customPostProcessStage = new Cesium.PostProcessStage({
|
|
|
|
|
fragmentShader: fs,
|
|
|
|
|
uniforms: {
|
|
|
|
|
u_earthRadiusOnCamera: () => Cesium.Cartesian3.magnitude(viewer.camera.positionWC) - viewer.camera.positionCartographic.height,
|
|
|
|
|
u_cameraHeight: () => viewer.camera.positionCartographic.height,
|
|
|
|
|
u_fogColor: () => new Cesium.Color(0.8, 0.82, 0.84),
|
|
|
|
|
u_fogHeight: () => 1000,
|
|
|
|
|
u_globalDensity: () => 0.6,
|
|
|
|
|
}
|
|
|
|
|
})
|
|
|
|
|
viewer.scene.postProcessStages.add(customPostProcessStage)
|
|
|
|
|
|
|
|
|
|
viewer.camera.setView({
|
|
|
|
|
destination:new Cesium.Cartesian3(-1386705.7605894802,5226754.975571179,3375582.2076837276),
|
|
|
|
|
orientation: {
|
|
|
|
|
heading:3.968066845543675, // east, default value is 0.0 (north)
|
|
|
|
|
pitch: -0.300780994602595, // default value (looking down)
|
|
|
|
|
roll: 0.00007913394522685024 // default value
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
</script>
|
|
|
|
|
</body>
|
|
|
|
|
|
|
|
|
|
</html>
|