What Is the Scope Mask in God's Eye View? Circular Viewport Feature Explained
The Scope Mask is a canvas-based circular viewport that creates a feathered "tunnel-vision" effect, with altitude-adaptive opacity and zero performance cost when disabled.
The Scope Mask is the signature visual feature that gives the open-source geospatial visualization tool God's Eye View its distinctive circular focus. Unlike traditional post-processing approaches that rely on shader chains, this feature uses a lightweight 2D canvas layer to deliver GPU-friendly masking with adjustable softness and dynamic transparency. The implementation prioritizes render performance through quantized updates and adaptive repainting.
How the Scope Mask Works in God's Eye View
The Scope Mask operates as a dedicated <canvas> element (#scope-mask) positioned beneath detection layers with a z-index of 2. This architectural choice—direct canvas drawing rather than WebGL shaders—eliminates the complexity and overhead of the six post-process shaders that were previously attempted and removed from the codebase.
Canvas-Based Architecture
The core implementation lives in src/scopeMask.js and creates a single persistent canvas attached to the Cesium viewer container. Drawing occurs only when necessary: on initialization, resize, device-pixel-ratio changes, or terminus opacity updates. No per-frame canvas work runs during normal render loops.
Key structural decisions include:
- Static geometry — the radial gradient uses pre-computed inner and outer radii from
scopeMaskGeometry(width, height, featherRatio) - Layer separation — canvas sits at z-index 2, detection layers at z-index 5, ensuring mask appears beneath overlays
- Clean disable state — when turned off, the canvas clears once and enters zero-cost idle mode
Feathered Edge Control
The mask edge uses a radial gradient with configurable feathering. The default ratio (SCOPE_FEATHER_RATIO_DEFAULT = 0.11) means the soft edge extends 11% of the keyhole radius inward. Users adjust this via the #scope-feather-slider control in the UI.
// Adjust edge softness from hard crop (0.0) to very soft (0.2)
import { setScopeMaskFeather } from './scopeMask.js';
setScopeMaskFeather(0.15); // 15% feather radius
The setScopeMaskFeather(ratio) function triggers a single canvas repaint with the new gradient geometry computed by scopeMaskGeometry().
Altitude-Adaptive Terminus Opacity
A distinguishing feature of the Scope Mask is its dynamic opacity response to camera altitude. The area outside the circular keyhole—called the terminus— adjusts transparency based on the viewer's distance from Earth's surface.
Opacity Thresholds
| Altitude Range | Terminus Behavior | Constant |
|---|---|---|
| Above 10,000 km | Fixed translucent at 94% | SCOPE_OUTSIDE_ALPHA |
| Below 7,000 km | Fully opaque at 100% | SCOPE_TERMINUS_ALPHA_NEAR |
| 7,000–10,000 km | Smooth-step interpolation | scopeTerminusAlpha function |
The smooth-step ramp prevents jarring transitions as users zoom. However, raw continuous updates would waste canvas calls.
Quantized Repaints for Performance
To minimize canvas operations, terminus opacity changes are quantized to 0.005 steps (SCOPE_TERMINUS_QUANTUM). A repaint occurs only when the quantized value crosses a grid boundary:
// From scopeMask.js - quantized update logic
// Maximum ~12 repaints across full altitude band
const quantized = Math.round(rawAlpha / SCOPE_TERMINUS_QUANTUM) * SCOPE_TERMINUS_QUANTUM;
if (quantized !== lastQuantizedAlpha) {
requestScopePaint();
}
This guarantees bounded canvas work regardless of animation frame rate or zoom velocity.
Device Pixel Ratio Handling
The implementation correctly handles high-DPI displays through a ResizeObserver monitoring window.devicePixelRatio. When DPR changes:
- Canvas backing store rescales to new DPR
- Simultaneous terminus opacity changes coalesce into single paint
- Gradient regenerated at full native resolution
Only two paint paths exist: DPR-change path (lines 84–94) and quantized-opacity path (lines 92–99), ensuring no redundant operations.
Public API for the Scope Mask
The src/scopeMask.js module exports a clean interface used by src/ui.js and other components:
| Function | Purpose | Called From |
|---|---|---|
installScopeMask(viewer) |
Initialize canvas in Cesium container | Application bootstrap |
setScopeMaskEnabled(enabled) |
Toggle visibility (true/false) | #scope-toggle button |
setScopeMaskFeather(ratio) |
Update edge softness (0.0–0.2) | #scope-feather-slider |
setScopeTerminusOverride(alpha) |
Pin opacity, bypass altitude logic | Share-link generation |
getScopeTerminusOverride() |
Read current override state | UI state sync |
scopeMaskGeometry(w, h, feather) |
Compute gradient radii and center | Internal + external layout |
Integration with Detection Layers
The mask state propagates to src/worldFocus.js, which uses the enabled flag to determine whether detection layers should apply clipping. This coordination ensures visual consistency across the rendering pipeline.
Complete Usage Examples
Basic Installation and Control
// src/main.js or equivalent entry point
import { installScopeMask, setScopeMaskEnabled } from './scopeMask.js';
// After Cesium viewer initialization
installScopeMask(viewer);
// Toggle from UI button handler
document.querySelector('#scope-toggle').addEventListener('click', () => {
const isEnabled = /* read current state */;
setScopeMaskEnabled(!isEnabled);
});
Creating Shareable Views with Fixed Opacity
import { setScopeTerminusOverride } from './scopeMask.js';
// Lock terminus to 80% opacity for consistent screenshots
setScopeTerminusOverride(0.8);
// Restore altitude-adaptive behavior
setScopeTerminusOverride(null);
Programmatic Feather Adjustment
import { setScopeMaskFeather } from './scopeMask.js';
// Animate feather for intro effect
function animateFeather(targetRatio, durationMs) {
const start = performance.now();
const initial = 0.05; // Start slightly softer than default
function frame(now) {
const elapsed = now - start;
const t = Math.min(elapsed / durationMs, 1);
const current = initial + (targetRatio - initial) * t;
setScopeMaskFeather(current);
if (t < 1) requestAnimationFrame(frame);
}
requestAnimationFrame(frame);
}
// Soft edge that tightens to default 0.11
animateFeather(0.11, 800);
Source File Structure
The Scope Mask feature spans four primary files in the bilawalsidhu/gods-eye-view repository:
src/scopeMask.js— Core implementation with canvas management, gradient drawing, quantized updates, and public APIsrc/ui.js— Button and slider wiring that forwards user input to mask functionssrc/celestialRing.js— Provides keyhole geometry for mask centeringsrc/worldFocus.js— Consumes mask state for detection layer clipping decisions
Summary
- The Scope Mask in God's Eye View renders a circular viewport using a dedicated 2D canvas, not shader chains, for reliable performance across devices
- Feathered edges adjust via
setScopeMaskFeather()with ratio-based control (default 0.11) - Altitude-adaptive terminus opacity transitions automatically between 94% (high orbit) and 100% (near surface) with smooth-step interpolation
- Quantized repaints at 0.005 granularity limit canvas operations to ~12 maximum across all altitudes
- Zero-cost disable state clears canvas once, then performs no work until re-enabled
- The public API in
src/scopeMask.jsprovides clean integration points for UI controls and programmatic manipulation
Frequently Asked Questions
How does the Scope Mask differ from post-processing shader approaches?
The original implementation attempted six chained post-process shaders to create the circular mask, but this produced no actual mask effect and incurred significant GPU overhead. The current canvas-based approach in src/scopeMask.js draws a radial gradient directly to a 2D canvas, achieving the visual result with simpler code, better browser compatibility, and explicit control over update frequency.
What causes the Scope Mask to repaint?
Three events trigger canvas repaints: (1) initialization or resize/device-pixel-ratio changes via ResizeObserver, (2) quantized terminus opacity crossing a 0.005 boundary during altitude changes, and (3) explicit calls to setScopeMaskFeather() or setScopeTerminusOverride(). Normal camera rotation and animation do not trigger repaints.
Can I use the Scope Mask without the altitude-adaptive opacity?
Yes. Call setScopeTerminusOverride(alpha) with any value 0–1 to pin the outer terminus at fixed opacity, bypassing the altitude logic entirely. Pass null to restore adaptive behavior. This is useful for creating consistent screenshots, share links, or presentation modes where automatic opacity changes would be distracting.
Does the Scope Mask impact performance when disabled?
No. When setScopeMaskEnabled(false) is called, the canvas clears once to transparent and enters a zero-work state. No canvas operations, no gradient calculations, and no resize observations occur until the mask is re-enabled. The "scope off" configuration is explicitly designed as the cheapest possible rendering path.
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:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →