mirror of
				https://github.com/jiawanlong/Cesium-Examples.git
				synced 2025-11-04 09:14:17 +00:00 
			
		
		
		
	
		
			
				
	
	
		
			121 lines
		
	
	
		
			5.1 KiB
		
	
	
	
		
			HTML
		
	
	
	
	
	
			
		
		
	
	
			121 lines
		
	
	
		
			5.1 KiB
		
	
	
	
		
			HTML
		
	
	
	
	
	
<!--********************************************************************
 | 
						||
* by jiawanlong
 | 
						||
*********************************************************************-->
 | 
						||
<!DOCTYPE html>
 | 
						||
<html>
 | 
						||
 | 
						||
<head>
 | 
						||
    <meta charset="UTF-8" />
 | 
						||
    <link rel="stylesheet" href="./../../libs/cesium/Cesium1.98/Widgets/widgets.css">
 | 
						||
    <script type="text/javascript" src="./../../libs/cesium/Cesium1.98/Cesium.js"></script>
 | 
						||
</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> |