ShipVFX · Benchmarks · measured on real hardware

We don't quote performance.
We measure it.

Every number here comes from an automated 17-scenario benchmark - ships flying at full throttle, effects filling the screen - run on real devices and re-run every release. No estimates, no "up to". When a frame is pinned at a display's refresh ceiling, we say so instead of inventing headroom.

60fps 8-ship fleet, 2017 phone OnePlus 5T · Mobile tier, panel-capped
460fps 8-ship fleet, desktop RTX 3090 · Mobile tier
0errors across every scenario both platforms · 30 s soak clean
80× faster trails after the port CPU loop → vertex shader

The breakthrough: trails cost almost nothing now

2026-07-11 A/B

The plasma trail - half the look of a thruster - used to churn every vertex on the CPU each frame. It moved to the vertex shader with the visuals byte-for-byte identical. Cost per ship, measured on the RTX 3090:

Before · CPU churn
4.85 ms
After · vertex shader
0.06 ms

An 8-ship fleet went from stuttering to hundreds of fps on desktop from this one change - and the same trails now cost nothing measurable on a 2017 phone.

Eight full ships - the stress case

2026-07-18 pass

Frames per second with a fleet of eight on screen, every effect running.

RTX 3090 · Mobile tier
460fps
RTX 3090 · Powerhouse
314fps
OnePlus 5T · Mobile tier
60fps
OnePlus 5T · Powerhouse
55fps
0125250375500 fps

A 2017 phone holds its panel's locked 60 with eight fully-dressed ships; the desktop runs the same scene at triple-digit headroom. Single ships are never the question.

One ship on a 2017 phone

2026-07-18 pass

The OnePlus 5T panel refreshes at 60 Hz - the dashed line is its ceiling, not ours.

Ship model alone
60fps *
Mobile tier, full FX
60fps *
Powerhouse tier, full FX
60fps *
60 Hz

* pinned at the panel refresh - real headroom is higher than shown. On the cold 2026-07-18 pass all three sit on the cap: the Mobile tier never drops a frame, and the desktop-grade Powerhouse tier holds 60 too. The only run where a single Powerhouse ship measured below the panel (56 fps) was the thermally-degraded 2026-07-11 handset - so treat 56 as the hot-device floor, not the number this phone gives you cold.

What each effect costs on mobile

2026-07-11 pass

Milliseconds added per frame over the Mobile-tier baseline, on the OnePlus 5T. These come from the 2026-07-11 run, on a handset that had been benchmarked all evening and was thermally throttled. That is deliberate: when we re-ran it cold on 2026-07-18 the phone pinned at its 60 Hz panel in every single-ship scenario, so each feature subtracted to +0.00 ms - which measures the panel, not the effect. The hot figures are the honest upper bound, and the cold result is shown beside each row.

Exotic distortion the one real mobile cost - desktop-gated
+1.13ms +0.00 cold
Flight-path contrail
+0.87ms +0.02 cold
Powerhouse reactor trail
+0.65ms +0.19 cold
Smoke · sparks · shock diamonds · lights the dearest of the four; sparks +0.14, shock diamonds +0.16
+0.19ms +0.00 cold
Rotating beacon, beam + cast light measured 2026-07-18 by A/B; per ship in an 8-ship fleet, free on one ship
+0.10ms pass B
Plasma trail animation runs in the vertex shader
~0ms
00.651.3 ms

Distortion is the only feature with a real mobile price tag - which is exactly why it ships desktop-gated. Everything else, trails included, is effectively free.

The framework is free. Your triangles are not.

2026-07-12 pass

A separate mobile run on 2026-07-12 swapped in a 1.85-million-triangle hull with no LODs, to find the mesh ceiling. It has not been re-run since, and it does not need to be: the wall it finds is raw geometry, which no ShipVFX release moves. The eight-hull row is the Mobile tier with all the effects running - stripping them back to mesh-only buys 1.3 fps. The lesson is clean:

One 1.85M-tri hull
60fps *
Eight of them (14.8M tris)
16fps

Eight of those hulls cost +40.9 ms/frame in raw geometry; all the VFX combined add just +4.4 ms. On a mobile fleet the triangle count is the budget - ShipVFX is not the bottleneck. Ship LODs for your hulls; the framework overhead stays negligible either way.

The rig & the rules

Desktop

RTX 3090

Windows 11 · D3D12 · 1920×1080 · vSync off, uncapped · quality tier "PC"

Mobile

OnePlus 5T (2017)

Snapdragon 835 · Adreno 540 · GLES3 · 2160×1080 @ 60 Hz · quality tier "Mobile"

Next

iOS

iPhone + Metal joins the tables when the device lands. Same scenarios, same rules.

  • 17 scenarios, ~6 minutes. Empty floor, hull-only isolation, one ship and an 8-ship fleet at both tiers, one run per premium effect, subtractive isolation of the always-on systems, and a 30-second soak with live state cycling and FX rebuilds.
  • Real flight, real pixels. Ships fly nose-first at full throttle so trails bend and particles emit like in a game; the camera keeps hulls and effects filling the frame so mobile fill-rate is genuinely stressed.
  • Recorded: average fps, p50/p95/p99/worst frame times, decay slope, GC, managed and native memory slopes, peak particles, and every logged error. Zero errors, both devices.
  • Three passes, median reported, first pass discarded. The opening pass is always low while shaders warm up, so a single run understates the machine. Passes two and three agree within about 1%.
  • Every panel names its pass. Two benchmark runs feed this page: 2026-07-18 on a cold handset, which is where the headline fleet and single-ship figures come from, and 2026-07-11/12, which by its own report ran hot. We do not silently blend them. Where the older pass is the only one that could measure something - the per-feature costs, because a cold phone hides them all under its 60 Hz panel - the panel says so and shows both results.
  • A throttled device is a feature here, not a flaw. Reporting the hot handset's per-feature costs rather than the cold run's zeroes overstates what the effects cost you. That is the direction we would rather be wrong in.
  • Measured on a working desktop, not a clean-room bench. The dev machine runs its normal load while benchmarking. These are a floor, not a ceiling: a quiet machine measures higher. We would rather publish the number you would actually hit on a busy workstation.
  • Honesty rules. Uncapped everywhere; refresh-capped rows flagged, never extrapolated; the test hull is our own asset (not part of the pack). Older Adreno drivers run OpenGL ES 3 - Unity 6's Vulkan path is unstable on that generation; modern devices run Vulkan.

The demo on the home page is this same build, live in your browser.