跪拜 Guibai
← All articles
Cesium · WebGL · Vue.js

Dynamic Cloud and Rain Shaders for CesiumJS Using Post-Processing

By Tony费 ·
Read original on juejin.cn ↗ Google Translate ↗ Alt translation

Adding weather to a geospatial visualization usually means swapping tile sets or injecting particle systems, both of which are expensive and complex. Screen-space post-processing shaders sidestep that entirely: the effect costs a single full-screen quad per frame, works on any Cesium scene without modifying the globe, and can be toggled or tuned at runtime with a uniform.

Summary

CesiumJS ships without built-in weather effects, so dynamic atmosphere must be painted onto the final frame through its PostProcessStage pipeline. This implementation provides two shaders: one that layers four octaves of FBM noise to generate slow-moving dark clouds, and another that uses a hash function to scatter animated rain streaks across the screen. Both effects run as post-processing passes on the color texture, meaning they operate purely in screen space without touching the 3D scene geometry.

A sky mask derived from the screen-space Y coordinate confines the cloud overlay to the upper portion of the view, leaving terrain and buildings untouched. The rain shader applies a slight darkening and a blue-grey tint, with intensity blended via a uniform so the effect scales from a drizzle to a downpour. Each shader is driven by a requestAnimationFrame loop that increments a time uniform, producing continuous animation.

The Vue 3 integration wraps everything in a single component with Element Plus sliders and toggle buttons. Cleanup on unmount removes the post-process stages and destroys the Cesium viewer to prevent memory leaks, and the code targets GLSL 300-ES for compatibility with Cesium 1.141.0.

Takeaways
Both cloud and rain effects are implemented as Cesium PostProcessStage fragment shaders that operate on the already-rendered color texture.
Clouds use four octaves of FBM noise with independent UV offsets and speeds, then composite the layers with decreasing weight to produce a natural overcast look.
A skyMask derived from v_textureCoordinates.y restricts cloud rendering to the sky region, preventing the ground from being tinted gray.
Rain streaks are generated by hashing the screen X coordinate, then animating a high-frequency sine function vertically to create the illusion of falling drops.
Rain intensity is a single uniform that blends between the original scene color and a darkened, blue-tinted version, giving a continuous drizzle-to-storm range.
Both shaders use requestAnimationFrame to increment a time uniform, avoiding reliance on Cesium's own clock and keeping the animation independent of simulation time.
The Vue 3 component cleans up all post-process stages and destroys the viewer instance in onUnmounted to prevent GPU and memory leaks.
Conclusions

Screen-space weather effects are surprisingly cheap because they skip geometry entirely; the entire cloud system is just a few noise lookups per pixel.

Using a sky mask based on screen Y is a pragmatic shortcut that works for most ground-level views but would fail if the camera pitched upward, exposing the hard cutoff.

The rain shader's hash-based placement means streaks are stateless and deterministic per frame, which avoids any need for particle buffers or persistent state across draws.

Tying animation to requestAnimationFrame rather than Cesium's clock decouples the weather from simulation speed, so pausing the scene doesn't freeze the rain.

Concepts & terms
PostProcessStage
A CesiumJS API that runs a custom fragment shader over the final rendered frame. It receives the scene's color texture as input and outputs a modified image, enabling effects like bloom, color grading, or weather overlays without altering the 3D scene.
FBM (Fractal Brownian Motion) noise
A technique that sums multiple layers (octaves) of noise at increasing frequencies and decreasing amplitudes. Each octave adds finer detail, producing natural-looking textures like clouds, terrain, or smoke.
GLSL 300-ES
The OpenGL ES Shading Language version 3.00, used for WebGL 2.0. It replaces older GLSL syntax (varying/attribute) with in/out qualifiers and requires explicit precision declarations, which newer Cesium versions expect.
Source: juejin.cn ↗ Google Translate ↗ Backup ↗