How to Render Detection Bounding Boxes in CesiumJS Using the gods-eye-view Toolkit

The gods-eye-view repository renders detection bounding boxes in CesiumJS through a canvas 2D overlay that batches CRT-style corner-bracket geometry into a single Path2D operation, eliminating per-box draw calls while supporting tier-based coloring and fade-in animations.

Rendering detection bounding boxes in CesiumJS typically requires complex Entity or Primitive API setup, but the open-source gods-eye-view repository provides a lightweight, renderer-agnostic alternative. This implementation computes bounding box geometry in pure JavaScript and paints corner-bracket overlays via a canvas 2D host that sits atop the Cesium WebGL canvas. By leveraging the detection overlay system defined in src/data/detection.js, you can visualize aircraft, ships, satellites, and other trackable objects without modifying Cesium's internal rendering pipeline.

Core Detection Rendering Architecture

The detection overlay operates independently of Cesium's Entity API, using a world-overlay host pattern that registers a paint lane on a canvas positioned above the 3D scene.

The Canvas 2D Pipeline

According to the source code in src/data/detection.js, the overlay executes a five-step rendering process each frame:

  1. Collection: Gathers objects from any layer implementing getDetectableObjects({mode, maxCount, seed})
  2. Projection: Transforms each object's 3D geospatial position into screen coordinates using Cesium's camera matrix
  3. Sizing: Calculates appropriate half-width and half-height (aircraft reticles scale with distance while ground objects use fixed pixel sizes)
  4. Batching: Accumulates all corner-bracket geometry into a single Path2D instance via appendCornerBracket()
  5. Painting: Strokes the batched path once per color/alpha group on the overlay canvas

This approach minimizes GPU state changes by reducing thousands of potential individual draw calls into a single canvas stroke operation.

Key Functions in src/data/detectionDraw.js

Function Purpose
appendCornerBracket(sink, sx, sy, halfW, halfH) Generates four L-shaped corner segments for a box centered at screen coordinates (sx, sy) using the provided Path2D sink
resolveTier(obj) Returns the color tier string (civil, military, sea, space, vehicle) for stroke color selection
acquireAlpha(firstSeenMs, nowMs, fadeMs) Computes fade-in alpha values for newly detected objects to create the "acquire" animation effect

The sink parameter accepts any object exposing moveTo(x, y) and lineTo(x, y) methods, making the function compatible with standard Path2D instances or custom rendering contexts.

Implementing the Detection Overlay

You can initialize the complete detection system with minimal boilerplate or manually draw brackets for custom HUD implementations.

Initializing the Automatic Overlay

The simplest method registers the detection lane with the world-overlay host and begins automatic rendering:

import * as Cesium from 'cesium';
import { initDetection, setMode, setDetectionStyle } from './data/detection.js';

const viewer = new Cesium.Viewer('cesiumContainer');

// Data layers must expose getDetectableObjects()
const layers = [
  /* your detectable object layers */
];

// Optional callback for mode changes
function onModeChange(label) {
  console.info('[Detection] mode →', label);
}

// Initialize and activate the overlay
initDetection(viewer, layers, onModeChange);
setMode('BALANCED');        // Options: OFF, SPARSE, BALANCED, DENSE
setDetectionStyle('retro'); // Theme keys defined in worldOverlayTokens.js

Once initialized, src/data/detection.js handles all projection, culling, and batching automatically. The overlay retrieves object positions, computes screen-space bounds, and invokes appendCornerBracket() for each visible detection.

Manual Bracket Drawing for Custom UIs

For custom HUD elements outside the standard overlay, import the geometry helper directly from src/data/detectionDraw.js:

import { appendCornerBracket } from './data/detectionDraw.js';

const path = new Path2D();
const sx = 300;    // Screen X center
const sy = 200;    // Screen Y center
const halfW = 30;  // Half-width in pixels
const halfH = 30;  // Half-height in pixels

// Append corner-bracket geometry to the path
appendCornerBracket(path, sx, sy, halfW, halfH);

// Render in your canvas loop
ctx.strokeStyle = '#00ff00';
ctx.lineWidth = 2;
ctx.stroke(path);

This method guarantees visual consistency with the built-in overlay while allowing integration into custom canvas rendering pipelines.

Configuring Visual Behavior

The detection system supports runtime configuration of density modes and visual themes without requiring reinitialization.

Controlling Detection Density

The four density modes implemented in src/data/detection.js control object population and screen real estate:

  • OFF: Disables rendering entirely
  • SPARSE: Displays only objects within a central focus ring with reduced box sizes
  • BALANCED: Medium-density visualization suitable for standard operational interfaces
  • DENSE: Renders bounding boxes for every detectable object within view frustum (debug mode)

Switch modes dynamically:

import { setMode, setDetectionTuning } from './data/detection.js';

setMode('SPARSE');                      // Toggle to sparse mode
setDetectionTuning({ densityPct: 75 }); // Fine-tune to 75% of maximum density

Customizing Visual Themes

Themes are defined in src/overlays/worldOverlayTokens.js within the DETECTION_THEME_MAP object. Each theme controls bracket colors, label typography, glow radius, blend modes, and scan-line overlays.

import { setDetectionStyle } from './data/detection.js';

setDetectionStyle('surveillance');  // Options include: retro, surveillance, thermal

To create custom themes, extend DETECTION_THEME_MAP in src/overlays/worldOverlayTokens.js with your color palette and rebuild the project.

Summary

  • The gods-eye-view detection system renders bounding boxes via a canvas 2D overlay rather than Cesium primitives, ensuring renderer agnosticism and high performance through geometry batching.
  • Core geometry generation occurs in src/data/detectionDraw.js through the appendCornerBracket() function, which constructs L-shaped corner segments compatible with standard Path2D objects.
  • Automatic initialization via initDetection() in src/data/detection.js registers a world-overlay paint lane that projects 3D positions, resolves color tiers, and manages fade-in animations through acquireAlpha().
  • Density modes (OFF, SPARSE, BALANCED, DENSE) and visual themes (retro, surveillance, thermal) provide runtime customization without code modification.
  • Manual drawing support allows reuse of appendCornerBracket() for custom HUD implementations while maintaining visual consistency with the automatic overlay.

Frequently Asked Questions

Does this detection system use CesiumJS Entity or Primitive APIs?

No. The implementation avoids both the Entity and Primitive APIs, instead using a canvas 2D overlay positioned above the Cesium WebGL canvas. This approach batches all bounding box geometry into a single Path2D stroke operation in src/data/detection.js, reducing overhead compared to creating individual Cesium entities for each detection box.

How do I change the color of individual bounding boxes?

Colors are determined by the resolveTier() function in src/data/detectionDraw.js, which maps object types to tier categories (civil, military, sea, space, vehicle). To customize colors, modify the DETECTION_THEME_MAP in src/overlays/worldOverlayTokens.js or manually set ctx.strokeStyle when using the appendCornerBracket() helper for custom drawing contexts.

Can I use this overlay with any version of CesiumJS?

Yes. Because the detection overlay is renderer-agnostic, it works with any CesiumJS version that provides camera projection matrices. The system relies on standard JavaScript canvas 2D APIs and Cesium's built-in position-to-screen-space conversion, making it immune to changes in Cesium's internal WebGL rendering architecture.

What controls the fade-in animation for newly detected objects?

The fade-in effect is governed by the acquireAlpha() function in src/data/detectionDraw.js, which calculates opacity based on the time elapsed since firstSeenMs relative to the current nowMs and the configured fadeMs duration. This alpha value is combined with radial keyhole fading in src/data/detectionRenderDemand.js to produce the final opacity for each bracket.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →