Cesium-Examples/examples/cesiumEx/5.1.1、雾Webgl2.html

125 lines
4.9 KiB
HTML
Raw Normal View History

2025-03-11 08:25:45 +00:00
<!--********************************************************************
* by jiawanlong
*********************************************************************-->
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<link
rel="stylesheet"
2025-03-19 03:00:22 +00:00
href="./../../libs/cesium/Cesium1.98/Widgets/widgets.css"
2025-03-11 08:25:45 +00:00
/>
<script
type="text/javascript"
2025-03-19 03:00:22 +00:00
src="./../../libs/cesium/Cesium1.98/Cesium.js"
2025-03-11 08:25:45 +00:00
></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;
const tileset = new Cesium.Cesium3DTileset({
url: "./data/tileset.json",
});
tileset.readyPromise
.then(function (tileset) {
viewer.scene.primitives.add(tileset);
viewer.zoomTo(tileset);
})
.catch(function (error) {
console.log(error);
});
// 模型删除
// viewer.scene.primitives.remove(tileset)
// viewer.scene.primitives.removeAll()
function setFogEffect1(viewer) {
const fs = `
float getDistance(sampler2D depthTexture, vec2 texCoords)
{
//它用于将从深度纹理中读取到的深度值进行解压缩,以便在着色器中进行深度测试和深度值比较等操作。
//深度纹理通常用于实现阴影效果、深度检测等功能。
//在Cesium中深度值通常被存储在一个16位的纹理单元中这个值被压缩成0到1之间的浮点数以便节省显存空间。
float depth = czm_unpackDepth(texture(depthTexture, texCoords));
//若深度值为0则返回无穷远
if (depth == 0.0) {
return czm_infinity;
}
//将窗口坐标系(即屏幕坐标系)下的像素坐标转换为相机坐标系下的坐标
vec4 eyeCoordinate = czm_windowToEyeCoordinates(gl_FragCoord.xy, depth);
//返回物体离相机的距离
return -eyeCoordinate.z / eyeCoordinate.w;
}
//根据距离,在中间进行插值
float interpolateByDistance(vec4 nearFarScalar, float distance)
{
//根据常识,雾应该是距离远,越看不清,近距离内的物体可以看清
//因此近距离alpha=0远距离的alpha=1.0
//本例中设置可见度为200米
//雾特效的起始距离
float startDistance = nearFarScalar.x;
//雾特效的起始alpha值
float startValue = nearFarScalar.y;
//雾特效的结束距离
float endDistance = nearFarScalar.z;
//雾特效的结束alpha值
float endValue = nearFarScalar.w;
//根据每段距离占总长度的占比插值alpha距离越远alpha值越大。插值范围0,1。
float t = clamp((distance - startDistance) / (endDistance - startDistance), 0.0, 1.0);
return mix(startValue, endValue, t);
}
vec4 alphaBlend(vec4 sourceColor, vec4 destinationColor)
{
return sourceColor * vec4(sourceColor.aaa, 1.0) + destinationColor * (1.0 - sourceColor.a);
}
uniform sampler2D colorTexture;
uniform sampler2D depthTexture;
uniform vec4 fogByDistance;
uniform vec4 fogColor;
in vec2 v_textureCoordinates;
void main(void)
{
//获取地物距相机的距离
float distance = getDistance(depthTexture, v_textureCoordinates);
//获取场景原本的纹理颜色
vec4 sceneColor = texture(colorTexture, v_textureCoordinates);
//根据距离对alpha进行插值
float blendAmount = interpolateByDistance(fogByDistance, distance);
//将alpha变化值代入雾的原始颜色中并将雾与场景原始纹理进行融合
vec4 finalFogColor = vec4(fogColor.rgb, fogColor.a * blendAmount);
out_FragColor = alphaBlend(finalFogColor, sceneColor);
}`;
viewer.scene.postProcessStages.add(
new Cesium.PostProcessStage({
name: "test",
fragmentShader: fs,
uniforms: {
fogByDistance: new Cesium.Cartesian4(10, 0.0, 200, 0.7),
fogColor: Cesium.Color.WHITE,
},
})
);
}
setFogEffect1(viewer);
</script>
</body>
</html>