This is a quick post thrown together to report on my experience with the new Safari 14 regarding support for WebGL 2. The news of improved WebGL support was floated last month in the Shadertoy Community Group:Fast forward to today and the Safari 14 update has now come to my laptop (which still runs macOS Mojave). So the first thing I did check out all my shaders on Shadertoy and then some to see if the promises were true. My verdict (TL/DR):
- Yes, all WebGL 2 shaders that I tried out compile out of the box (although the WebGL 2 support is still disabled by default and has to be enabled in the experimental features menu).
- No, Safari is not the perfect browser for Shadertoy, at least not for authoring. More on that later.
Performance and compile times
The developer tools in Safari come with a profiler that feels similar to DTrace or’Instruments’ in XCode, where you can inspect the stack trace of a timeline. Thus is should be possible to track the exact compile times for a shader. Unfortunately, the WebGL APIs of
linkProgram seem to return early and the bulk of the work happens later in the driver, resulting in Shadertoy happily reporting that compilation only took 2 seconds, where in reality it was blocking the last animation frame for 11 seconds.
For the comparison I was mostly interested in running Space Glider, my procedural planet/atmospheric scattering/flight sim testbed implemented all in shader code with notoriously long compile times, triggering all sorts of driver bugs and compatibility issues especially on Windows. Below are the results on compile times and runtime performance on Safari 14 and Firefox 80 (15-inch Macbook Pro 2017; 2.8 GHz Intel 7700HQ; Radeon Pro 555):
|Browser||Compile time||Runtime FPS @ 640×360|
|Safari 14||11 s||around 30|
|Firefox 80||13 s||around 30|
As can be seen, the run time performance of the compiled shaders are essentially the same, however Safari seems to compile a little bit faster.
As far as I could see at a quick glance there are no obvious output differences between Safari’s and Firefox’s WebGL implementations. Since the simulation runs at the edge of floating point precision, deterministic output cannot be expected. For example: I made an own version of a sincospi function so that conversion from lat-long coordinates is more consistent across platforms (not necessarily ‘better’ or more precise, just so as to not to have a dependency on builtin sin/cos). But still the compiler has a lot of latitude in the evaluation of the custom function and how it is inlined.
For the comparison I choose start location ‘L’, then waited for t = 30s to make the screenshot. The top one is from Safari and bottom one is from Firefox:
What looks reassuring is that the patterns on the ground texture are in agreement. There is a slight 0.4 m difference in altitude and 0.02° difference in heading.
The planet is so large that the observed altitude difference amounts to only 4 ulp in a 32-bit floating point position vector. Since there is a clear parallax between the images (in the Safari version the camera is closer to the ground), it seems that the cause it is not the terrain height itself, but the player position against the terrain. The player is positioned by a ray intersection routine and 4 ulp are actually pretty decent for that.
While the shaders themselves now run fine, the experience of writing and editing shaders using the Shadertoy UI is still not as smooth as in Chrome or Firefox.
Issue 1: Viewport size
The mapping from window size to viewport size is inconsistent and broken. One has to use the screen zoom via Cmd + and – to get to the intended viewport resolution for a given window size. And even at the default zoom level, the viewport contents is never pixel perfect but always scaled (at least gamma correct).
Issue 2: Fullscreen size
The size of the fullscreen viewport equals the window viewport. Going fullscreen in 640×360 invokes this VGA flight sim nostalgia, with the slight aspect ratio distortion (since the MacBook has a 16:10 screen) giving that extra authenticity.
Issue 3: No Shadertoy-plugin
There is a cool plugin that extends the Shadertoy UI with new tools, some of which are really super useful. An equivalent Safari-extension is missing so no points.
Curiously, the initial development of Space Glider started out in Safari when it was WebGL 1 only. Most of the code was written early in 2018 when I had one and a half hours time to kill on a daily commute. Later that year, Shadertoy was updated to support WebGL 2, and then I switched to Firefox.
While it would have been possible to live without
uint types, or arrays, the addition of 3‑D textures for volume noise with proper mipmapping and support for the
textureLod() function were basically essential for the procedural terrain and the volumetric clouds.
Safari has had for a long time ‘experimental WebGL 2’ support, but it lacked support for exactly the things that I needed. Buffer mipmaps and 3‑D texture lookup was broken. And it would not accept the backslash-line continuation so that macros were constrained onto a single line, which is too impractical.
It is nice to see that Safari is now back in the club, so to speak!