# How GLSL Post‑FX Effects Power Sensor Simulations in God’s Eye View

> Learn how GLSL post-fx effects create realistic sensor simulations in God's Eye View. Explore NVG, FLIR, and CRT effects powered by Cesium PostProcessStage objects.

- Repository: [Bilawal Sidhu/gods-eye-view](https://github.com/bilawalsidhu/gods-eye-view)
- Tags: internals
- Published: 2026-09-12

---

**God’s Eye View implements sensor simulations by attaching GLSL fragment shaders as Cesium `PostProcessStage` objects to the scene graph, manipulating the rendered color texture through uniforms to generate NVG, FLIR, CRT, and other visual effects in real time.**

God’s Eye View is an open-source geospatial visualization project that renders immersive sensor simulations—including night vision, thermal imaging, and retro CRT modes—using Cesium JS. The system achieves these cinematic looks by injecting custom GLSL post‑fx effects into the rendering pipeline, processing the final framebuffer after the 3D world draws but before it reaches the screen.

## Shader Module Architecture

Each visual style ships as a self‑contained GLSL module exposing uniforms and a fragment shader entry point. The codebase defines distinct shaders such as `retroShader`, `nightVisionShader`, `thermalShader`, `animeShader`, `noirShader`, and `snowShader` in dedicated style files.

For example, the CRT retro simulation in [`src/styles/retro.js`](https://github.com/bilawalsidhu/gods-eye-view/blob/main/src/styles/retro.js) implements pixelation, scan‑lines, and distortion effects. Every module follows a consistent pattern: they sample the rendered color texture, apply algorithmic transformations based on uniform values, and write the result to `out_FragColor`. Key uniforms include **intensity**, **pixelation**, and **distortion**, which the UI controls update at runtime.

## Cesium Post‑Process Integration

The central orchestration happens in [`src/ui.js`](https://github.com/bilawalsidhu/gods-eye-view/blob/main/src/ui.js) (lines 3052–3276), where the application constructs `Cesium.PostProcessStage` instances and registers them with the scene pipeline.

```javascript
// ui.js – adding a stage to the Cesium pipeline
this.viewer.scene.postProcessStages.add(stage);
// bloom & sharpen stages are cached for later intensity tweaks
this._bloomStage = this.viewer.scene.postProcessStages.bloom;
this.viewer.scene.postProcessStages.add(this._sharpenStage);

```

The controller caches references to expensive effects like bloom and sharpen, enabling real‑time intensity adjustments without reconstructing the stage objects.

## Activating Sensor Modes

Mode switching is handled by `CockpitViewController.setVisionMode` in [`src/ui.js`](https://github.com/bilawalsidhu/gods-eye-view/blob/main/src/ui.js). When a user selects a sensor—such as “NVG” for night vision or “FLIR” for thermal—the controller normalizes the input, swaps the active style, and triggers a cross‑fade transition lasting `TRANSITION_DURATION_MS = 500` milliseconds.

```javascript
setVisionMode(mode, { revealParameters = false } = {}) {
  const next = normalizeCockpitVisionMode(mode);
  this.visionMode = next;
  // … UI updates …
  this.onVisionChange?.(next, this.active, { revealParameters });
}

```

The `normalizeCockpitVisionMode` helper and mode definitions reside in [`src/cockpitVisionPolicy.js`](https://github.com/bilawalsidhu/gods-eye-view/blob/main/src/cockpitVisionPolicy.js), which enumerates supported `COCKPIT_VISION_MODES` and their associated shader mappings.

## Uniform Management and Intensity Mapping

Effect intensity travels from UI controls to GPU uniforms through a mapping layer in [`src/bloom.js`](https://github.com/bilawalsidhu/gods-eye-view/blob/main/src/bloom.js). Helper functions like `bloomStrengthFromIntensity` convert percentage values (0–200) into Cesium‑native bloom parameters.

The shader modules read the `intensity` uniform to drive visual impact—modulating pixelation severity, scan‑line opacity, color channel separation, or thermal gradient contrast. This decoupling allows the rendering engine to remain agnostic of UI implementation while the post‑process stages react to uniform updates every frame.

## Detection Overlay Rendering

Sensor simulations must preserve detection call‑outs and targeting markers. The detection system in [`src/data/detection.js`](https://github.com/bilawalsidhu/gods-eye-view/blob/main/src/data/detection.js) draws overlays on a separate “sensor lane” that blends with the post‑processed output. This ensures that threat markers and sensor call‑outs appear correctly warped and color‑graded alongside the simulated imagery, maintaining situational awareness even under heavy visual distortion.

## Practical Implementation Examples

### Switching to Night‑Vision (NVG)

```javascript
// Assume `viewer` is a Cesium Viewer instance
const cockpit = new CockpitViewController(viewer, {
  onVisionChange: (mode) => console.log('Vision mode →', mode),
});

// User presses the “NVG” button – change the vision mode
cockpit.setVisionMode('surveillance'); // “surveillance” = NVG style

```

### Adding a Custom GLSL Post‑Process Stage

```javascript
import { Cesium } from 'cesium';

// Simple grayscale shader
const grayStage = new Cesium.PostProcessStage({
  name: 'gray',
  fragmentShader: `
    uniform sampler2D colorTexture;
    in vec2 v_textureCoordinates;
    void main() {
      vec4 col = texture(colorTexture, v_textureCoordinates);
      float gray = dot(col.rgb, vec3(0.299, 0.587, 0.114));
      out_FragColor = vec4(gray, gray, gray, col.a);
    }
  `,
  uniforms: {}
});

// Insert into the pipeline (after existing stages)
viewer.scene.postProcessStages.add(grayStage);

```

### Adjusting Bloom Intensity via UI Control

```javascript
// UI slider returns a value 0‑200 (percent)
function onBloomSlider(percent) {
  const intensity = bloomStrengthFromIntensity(percent);
  cockpit._bloomStage.enabled = intensity > 0;
  cockpit._bloomStage.strength = intensity;
}

```

## Summary

- **GLSL post‑fx effects** are packaged as modular shader files (e.g., [`src/styles/retro.js`](https://github.com/bilawalsidhu/gods-eye-view/blob/main/src/styles/retro.js)) that expose uniforms for real‑time parameter adjustment.
- **Cesium.PostProcessStage** objects wrap these shaders and attach to `viewer.scene.postProcessStages`, executing after the main 3D render.
- **CockpitViewController.setVisionMode** manages sensor switching with a 500 ms cross‑fade transition defined by `TRANSITION_DURATION_MS`.
- **Uniform mapping** in [`src/bloom.js`](https://github.com/bilawalsidhu/gods-eye-view/blob/main/src/bloom.js) bridges UI percentages to GPU‑compatible intensity values.
- **Detection overlays** in [`src/data/detection.js`](https://github.com/bilawalsidhu/gods-eye-view/blob/main/src/data/detection.js) render on a separate compositing lane to ensure markers remain visible under distortion effects.

## Frequently Asked Questions

### How do I add a custom sensor simulation shader to God’s Eye View?

Create a new GLSL fragment shader module that samples `colorTexture` and writes to `out_FragColor`, then instantiate a `Cesium.PostProcessStage` with your shader source and add it via `viewer.scene.postProcessStages.add()`. Register the mode in [`src/cockpitVisionPolicy.js`](https://github.com/bilawalsidhu/gods-eye-view/blob/main/src/cockpitVisionPolicy.js) and wire the activation through `CockpitViewController.setVisionMode`.

### What is the transition duration between vision modes?

The default cross‑fade duration is **500 milliseconds**, defined by the constant `TRANSITION_DURATION_MS` in [`src/ui.js`](https://github.com/bilawalsidhu/gods-eye-view/blob/main/src/ui.js). This value controls the smooth interpolation when switching between NVG, FLIR, CRT, or other sensor simulations.

### How does bloom intensity translate to Cesium rendering parameters?

The [`src/bloom.js`](https://github.com/bilawalsidhu/gods-eye-view/blob/main/src/bloom.js) module provides `bloomStrengthFromIntensity()`, which maps UI percentage values (typically 0–200) to Cesium’s internal bloom strength scalar. The cached `this._bloomStage` receives these values through its `strength` property, while the `enabled` boolean toggles the effect entirely.

### Where are the GLSL shader uniforms defined for sensor effects?

Uniforms are declared within each style module (such as [`src/styles/retro.js`](https://github.com/bilawalsidhu/gods-eye-view/blob/main/src/styles/retro.js)) and bound to the `Cesium.PostProcessStage` constructor’s `uniforms` object. The `CockpitViewController` updates these uniforms—particularly `intensity`—at runtime to reflect cockpit control inputs.