Copied verbatim from BENCHMARK-METHODOLOGY.md (gv-lab-web).
OverRock™ Benchmark: Testing Methodology (ORB-1.2)
This page explains what the OverRock™ Benchmark does, how it measures, and how the score is calculated. It describes benchmark version ORB-1.2, first shipped in OverRock™ Test (Lab) 0.1.28. The code is earth/bench.js (client) and the leaderboard Worker (server).
1. What runs
The benchmark is a watchable run of about 95 seconds on the app's own 3D globe. The camera orbits the Earth continuously (yaw about 0.11 rad/s). Seven stages run back to back:
| # | Stage | Length | What is on screen | What it stresses |
|---|---|---|---|---|
| 1 | Orbit | 10 s | Globe at full quality, zoom 1× | Base scene: imagery, clouds, atmosphere, shading |
| 2 | Weather | 14 s | Zoom 1.5×, seeded synthetic radar rain field + 300 lightning strikes | Weather overlays, blending, lightning |
| 3 | Wildfire | 12 s | Zoom 2.1×, 8,000 seeded fire points + smoke plumes | Point sprites, transparent overdraw |
| 4 | Close-up | 14 s | Zoom sweeps from 2.5× to 60× with camera tilt | High-detail imagery tiles, texture bandwidth |
| 5 | Particle storm | 14 s | Particle field (1,000,000 on PC, 300,000 on phones) | GPU compute (WebGPU) or vertex throughput (WebGL2) |
| 6 | Everything | 11 s | Rain, lightning, fires, smoke and particles together, zoom 1.35× | Combined load |
| 7 | Planet dive | 18 s | A cinematic camera rotates to a sunlit landmark, dives on an eased spline down to the Sentinel-2 10 m limit (1 image texel per screen pixel), holds, then swoops back up. Haze and imagery relief shading are on. | Large-texture streaming, sampling and atlas uploads at full native resolution |
All visual quality categories are forced to their maximum for the run. Weather, fires and lightning come from fixed random seeds, not live data, so every machine renders the same workload.
2. Run modes, resolution and settings
Before each run, a settings pop-up shows the detected rig and graphics API and offers two modes:
- Official run (scored), the default. This is a locked preset: full native resolution, every quality category at Max (imagery, clouds, 3D rain, smoke, lightning, effects), 1,000,000 particles (300,000 on phones), uncapped frame timing and all six stages. Only official runs can be submitted to the leaderboard.
- Custom run. You set each quality category yourself. The run is scored with the same formula and the card lists the settings used. Custom runs are never submitted, and the server rejects any submission that is not marked official.
Both modes go fullscreen: native fullscreen in the PC app, and immersive mode in the Android benchmark screen. They exit fullscreen afterwards. Esc (PC) or Back (Android) stops a run at any time.
- Native resolution only. The device pixel ratio is set to the display's real
devicePixelRatio, so the scene renders at the window's full native pixel count. There is no upscaling, no frame generation, no dynamic resolution and no reduced-resolution preset. - Native anti-aliasing from the renderer is allowed. No vendor-specific upscalers or AI features are used.
- The rendered pixel count is recorded and shown on the HUD and results card.
3. Graphics API
- The particle stage first asks for a WebGPU adapter with
powerPreference: 'high-performance', which requests the dedicated GPU on systems that have one. If WebGPU is missing or fails at any point, the run continues on WebGL2; it never aborts. - The results report the API that actually ran:
WebGPU · Direct3D 12on Windows,WebGPU · Vulkanon Android/Linux,WebGPU · Metalon Apple. WebGPU's backend per platform is fixed by the browser engine, so the label comes from the platform.WebGL2 · Direct3D 11 / Vulkan / OpenGL ES / OpenGL, read from the ANGLE renderer string.
- The globe scene itself renders on WebGL2 in ORB-1.2; WebGPU drives the particle stages.
4. How frames are measured
- Frames are timed uncapped: for each displayed frame the scene is rendered K times back to back, then the benchmark waits for the GPU to finish (
gl.finish()and, on WebGPU,queue.onSubmittedWorkDone()). Frame time = elapsed time ÷ K. K adapts between 1 and 8 so each measured batch takes about 12 ms. This means the monitor refresh rate and V-Sync do not cap the result. - Warm-up: the first 0.6 s of every stage is discarded.
- Per stage:
- Average FPS = 1000 ÷ mean frame time (ms).
- 1% low FPS = 1000 ÷ the 99th-percentile frame time.
- Max FPS = 1000 ÷ the fastest frame time.
- The HUD shows live FPS, frame time in ms, the API, resolution and progress. The results card includes a frame-time graph of the whole run.
5. CPU test
After the GPU stages, a CPU test runs in Web Workers. It is shaped like a game simulation tick:
- 4,096 aircraft and 2,048 ships advanced on great-circle paths (trigonometry),
- 24,576 weather particles advected 4 steps through a 16 MB wind grid with scattered reads (cache-heavy; a large L3 cache helps),
- 512 Kepler orbit solves.
Procedure: a 0.8 s warm-up on 1 worker, then ST = ticks per second on 1 worker for 4 s, then MT = total ticks per second on min(8, logical cores) workers for 4 s. Each worker has its own data, so working-set size grows with thread count.
Thread scaling is capped at 8 and has diminishing returns (exponent 0.65), so extra cores beyond what games typically use cannot run up the score.
Planet dive details
If every HD tile hasn't arrived within 150 s, the run still finishes but is marked HD tiles incomplete (slow network) and is treated as a custom run: it can't be submitted, so network speed can never shape a ranked score. The dive picks the most sunlit landmark that a single clear Sentinel-2 pass (one acquisition day) fully covers, and builds the close-up only from that pass's granules. They share date, sun angle and processing, so the mosaic has no tone seams or gaps. The 30 m layer above 20 m/px is Landsat (WELD), so there's a slight shift in colour where the dive switches to Sentinel-2.
- Landmark: the most sunlit of ten fixed landmarks at run time (Grand Canyon, Uluru, Mount Fuji, Matterhorn, Table Mountain, Giza, Torres del Paine, Mount Everest, Monument Valley, Lake Tekapo), so the close-up is always in daylight.
- Preload: before the stage starts (untimed), every tile the dive will show, for the whole visible footprint at every zoom level from orbit to 10 m, is downloaded and decoded. Network speed never affects the timed frames. If a tile can't be fetched within 150 s, the stage still runs and the gap shows the next coarser imagery.
- Sharpness: the deepest point is the zoom where one Sentinel-2 10 m texel maps to one screen pixel, never beyond. Textures use mipmaps and maximum anisotropic filtering.
- Run-to-run the landmark can differ, and its image content is similar in cost. Compare scores within ORB-1.2 only.
6. Score formula (ORB-1.2, exact)
Stage score S_i = 0.7 × avgFPS_i + 0.3 × onePercentLowFPS_i
GPU score = round(10 × geomean(S_1..S_7) × sqrt(nativePixels / 2,073,600))
scale = min(8, max(1, MT / ST))
CPU score = round(2 × (0.55 × ST + 0.45 × ST × scale^0.65))
OverRock™ Score = round(0.75 × GPU score + 0.25 × CPU score)
The GPU and CPU sub-scores are always shown separately next to the total. The leaderboard recomputes all scores on the server from the submitted per-stage stats; the score the client calculated is ignored.
7. Vendor neutrality
- No GPU or CPU brand, model or driver is used anywhere in the score. The hardware names are only displayed on the rig card and stored on the leaderboard for filtering.
- The same code and workload run on every device. There are no vendor-specific code paths.
- No vendor logos or marketing are used. GPU and CPU names appear as plain text only, read from the device you actually own.
8. Getting repeatable results
- Plug in laptops and phones, close other heavy apps, and let the device cool down between runs.
- Run twice and use the second run. The first run may include shader compilation and tile downloads.
- Phones and thin laptops can throttle when hot. Run-to-run variation of a few percent is normal.
- Window size changes the native pixel count. The GPU score's pixel factor partly normalises this, but compare runs at the same resolution.
9. Leaderboard and anti-cheat
Leaderboard submission is opt-in and tied to a signed-in Discord account. You choose to submit, either with your Discord name or anonymously. A submission sends the benchmark version, API, resolution, pixel count, per-stage stats, CPU results and detected hardware names. Nothing else is sent. The server (free Cloudflare Worker + D1):
- issues a one-time token at the start of each run. The token must be at least 55 s and at most 30 min old, is single-use, and the payload must carry a matching HMAC signature;
- rejects anything that is not an Official run, a wrong benchmark version, the wrong stage list, implausible stage numbers (for example a 1% low above the average, or too few frames), a non-native resolution, an unknown API string, or CPU numbers that are impossible for the thread count;
- holds for review runs on software renderers, GPU names that don't match the renderer, and GPU scores more than 1.6× the median for the same GPU/API/resolution;
- rate-limits per IP and applies a daily cap, so it stays inside the free tier.
10. Versioning
Scores are only comparable within the same benchmark version (ORB-1.2 here). Any change to the scenes, measurement or formula gets a new version, and the leaderboard only shows and accepts the current version.