首先看看实际效果如何:视线300米内正常,2000米外看不见,中间渐变模糊。
直接看代码吧:
//雾天
//需要加上out vec4 out_FragColor;
const fragmentShaderSource = `
float getDistance(sampler2D depthTexture, vec2 texCoords)
{
float depth = czm_unpackDepth(texture(depthTexture, texCoords));
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)
{
float startDistance = nearFarScalar.x;
float startValue = nearFarScalar.y;
float endDistance = nearFarScalar.z;
float endValue = nearFarScalar.w;
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;
out vec4 out_FragColor;
void main(void)
{
float distance = getDistance(depthTexture, v_textureCoordinates);
vec4 sceneColor = texture(colorTexture, v_textureCoordinates);
float blendAmount = interpolateByDistance(fogByDistance, distance);
vec4 finalFogColor = vec4(fogColor.rgb, fogColor.a * blendAmount);
out_FragColor = alphaBlend(finalFogColor, sceneColor);
}
`;
let fogday = new Cesium.PostProcessStage({
fragmentShader: fragmentShaderSource,
uniforms: {
fogByDistance: new Cesium.Cartesian4(300, 0.0, 2000, 1.0),
fogColor: Cesium.Color.WHITE,
},
})
const SetFogDay = (status) => {
if (status) {
if (viewer.scene.postProcessStages.contains(fogday)) {
console.log("包含fogday");
} else {
console.log("不包含fogday");
fogday = new Cesium.PostProcessStage({
fragmentShader: fragmentShaderSource,
uniforms: {
fogByDistance: new Cesium.Cartesian4(300, 0.0, 2000, 1.0),
fogColor: Cesium.Color.WHITE,
},
})
}
console.log("雾天效果开启");
viewer.scene.postProcessStages.add(fogday);
} else {
console.log("雾天效果关闭");
viewer.scene.postProcessStages.remove(fogday);
}
}
直接执行SetFogDay方法,传入天气状态参数,类型布尔,SetFogDay(true)开启雾天效果,SetFogDay(false)关闭雾天效果。