Parity

We render every effect on the iPhone simulator and in Chromium at the same moments, then diff the frames. This is the diff.

Ember in the browser at 3.4 sBrowser
Chromium, SwiftShader3.4 s
Ember on the iPhone simulator at 3.4 sSimulator
iPhone 17 Pro simulator3.4 s
Difference, 16x
Black is identicalMasked: status bar
0 s1 s3.4 s7 s
Wrong knob
Sets horizon 0.55

How a check runs

  1. Freeze time. Time is a plain number, so both sides draw the exact same instants. No clock runs.
  2. Render both. Chromium with a software GPU, and the showcase app on an iPhone simulator, at 402 by 874 points, 3x.
  3. Mask the chrome. The status bar and the home indicator are not the effect, so they are left out.
  4. Score it. Pixels that differ, the largest gap on any channel, and the colour shift a person would see, folded into one number. 95 passes, which means no channel more than 2 out of 255 apart.

Things we learned

Metalfract(sin(x) * 43758.5)

The same hash, two GPUs

The usual shader noise is fract(sin(x) * 43758.5). One GPU rounds a multiply and add once, the other twice, so the last bit differs. A hash exists to blow up tiny differences, so it did: Aurora, our first test effect, scored 81. Integer hashes only now, and the build rejects the float kind.

MetalANGLE

Never land on a tie

If a test can come out exactly equal, the two GPUs round it differently and the edge flips. Pick the branch with whole numbers, or leave a margin.

The default forgave 37 out of 255

Those two oranges differ by 37 in blue. The diff tool called them the same at its default setting, so the checker runs it far stricter and adds two measures it cannot fool.

A check that cannot fail proves nothing

Every effect is checked again with one knob deliberately wrong. The real scores sit at the top of the line; the wrong ones fall off it. 358 of 358 caught.

Every effect

EmberShallowsKomorebiGlasscastOxideRain PaneLocal SkyStrataTidelineAuroraSilkFrostGrainientDotgridStorm GlassSmokeFirefliesSnowfallContourLight LeakThunderheadDunesNightwaterPrismBeamsRipplesHalftoneGuillocheWax SealBearingEuler CoinNewtonOrbVelvetCrackleLeatherObsidianWashiCarbonOrigamiGlitterMarbleFoilTerrazzoBreathLacquerLanternLatheFilamentCompassOrbitRubberTickTaffyBeaconPaperfallRulerLensShimmerMatchstrikeInkdropMercuryEmbersGiltLetterpressWet InkLevelChalkSwingTypewriterEmbroideryWatercolourEngraveStencilParallaxSand ScriptVapourBulbs

What it does not prove

  • It is the simulator, not a phone. Apple does not promise the simulator matches a real GPU, so devices are checked by hand.
  • It checks fixed moments. A spring interrupted by a real finger at some other moment is not checked.
  • The content around each demo on this site (a booking card, a journal) is decoration. Only the effect is compared.