[HN Gopher] Show HN: Box2D fluid simulation in WebGL and WASM
___________________________________________________________________
Show HN: Box2D fluid simulation in WebGL and WASM
Author : Birch-san
Score : 33 points
Date : 2021-04-02 18:32 UTC (4 hours ago)
(HTM) web link (birchlabs.co.uk)
(TXT) w3m dump (birchlabs.co.uk)
| boogies wrote:
| Does this work for most people? I'd assume it was just my
| slightly out of date version of the weird browser Palemoon that
| makes it throw "SyntaxError: missing declaration after 'import'
| keyword" and stay blank white (https://ibb.co/Bj2HHxH) for me,
| but a dead comment just claimed it's broken on both macOS and iOS
| Safari, and Chrome.
| stevenpetryk wrote:
| Works only in Chromium for me, not Safari or Firefox. But it's
| just a technical demo so, meh.
| Birch-san wrote:
| Ah, if it's blank, then it blew up really early.
|
| It sounds like it's complaining about the use of ES modules.
| This script is loaded with `<script type="module">` and uses ES
| imports (`import App from './App.svelte'`).
|
| Yes, Safari is expected to go bang (doesn't support module
| Workers).
|
| I target Chromium's featureset -- I developed on macOS Edge.
| macOS Chrome and Android's Chrome WebView work for me too.
|
| It needs a few modern features in order to work:
| - Web workers - WebAssembly - top-level await (on
| Web, and in Worker) - ES modules + imports (on Web, and
| in Worker) - requestAnimationFrame in Worker -
| WebGL2 - OffscreenCanvas
|
| Most of these were chosen for "ease of development". With
| bundling, it'd be possible to eliminate the ES modules / await
| usage. WebGL2 isn't strictly necessary either. WASM + workers
| are widely supported.
|
| So the primary blocker to Firefox support is support for
| OffscreenCanvas, and requestAnimationFrame in Worker. There's
| other options there: render on the main thread instead. Harder
| to develop (syncing timing + state between threads). Can
| probably be done performantly with SharedArrayBuffer.
|
| In truth, I did include error-handling to provide a
| compatibility explanation if the worker explodes. This displays
| in Firefox. But I hadn't expected the main thread to explode
| too.
|
| Here's a GIF of what it's supposed to look like!
|
| https://birchlabs.co.uk/box2d-wasm-liquidfun/liquidfun.gif
| [deleted]
| LinguaBrowse wrote:
| Nice work!
|
| What's the benefit of using WebGL compared to Canvas?
|
| Does the WASM bring a performance improvement in practice,
| relative to the equivalent JS library?
|
| Keep it up!
| stevenpetryk wrote:
| You can write vertex shaders in WebGL to massively parallelize
| calculating the movement of each particle. This isn't possible
| in canvas.
|
| And that just optimizes the physics--there's even more
| parallelization with the actual drawing! Drawing a bunch of
| points like this can be achieved using a single fragment shader
| that takes a big array of positions. Drawing new positions
| involves just copying the array of positions from the CPU to
| the GPU.
|
| But if you're using both vertex and fragment shaders, the GPU
| might entirely handle updating and drawing points over time
| (and thus can be parallelized across hundreds of cores), only
| needing the CPU to set up the initial point positions and get
| things started.
|
| With canvas, all the work (including rendering each frame)
| takes the JS main thread, running on the CPU.
|
| Here's a cool demo of how much better WebGL is at rendering a
| ton of 2D sprites! Be careful turning up the number of sprites
| with canvas--it might lock up your main thread and be difficult
| to undo.
|
| https://bl.ocks.org/DevAndyLee/raw/a901617de28912b1e3cbdc6e8...
| moron4hire wrote:
| They aren't doing the particle sim in WebGL. That's the WASM
| part.
|
| As an aside: there are new standards in the works for getting
| even the CanvasContext2D rendering off of the main thread. On
| an HTMLCanvasElement, you can call
| transferControlToOffscreen(), which will retrun an
| OffscreenCanvas object. That object can then be transfered to
| a Worker. From there, you can create the 2D rendering context
| (make sure you don't create any 2D contexts on that canvas in
| the main thread) and draw to the canvas in the worker (you
| can do this for WebGL contexts, as well).
|
| All the drawing ops performed on the OffscreenCanvas will
| appear in the HTMLCanvasElement immediately, without having
| to perform a callback message from the Worker back to the
| main thread.
|
| https://developer.mozilla.org/en-
| US/docs/Web/API/OffscreenCa...
|
| Unfortunately, OffscreenCanvas is still in development in
| Firefox, only accessible behind a flag. In my testing with
| the feature enabled, it also seems that Mozilla hasn't
| implemented 2D contexts in Workers, only having the WebGL
| context available, which is quite annoying.
|
| I don't know the status in Safari, but Apple has historically
| been very slow about implementing new features.
| stevenpetryk wrote:
| Yeah, I didn't know the specifics of this sim, I just
| wanted to clarify the advantages of WebGL for even 2D
| stuff.
|
| The OffscreenCanvas thing sounds awesome! I still think it
| might be slower because you can't utilize shaders... but
| I'm sure we'll get there.
| moron4hire wrote:
| Yes, that is definitely true.
|
| I use it for text rendering, myself. Getting text
| rendering working in shader code is pretty difficult and
| gives pretty low quality results. You have to create a
| glyph map for all the characters you plan to render--
| which also means you have to plan ahead of time what text
| you're going to render--and you are stuck with only one
| color for all of the text (there are some multicolor SDF-
| based systems, but they aren't very common).
|
| So I render the text in a 2D rendering context, with all
| the fancy bells and whistles and support for changing
| fonts on the fly and colors and transformations and a
| sane API, in a Worker, save off an ImageBitmap object
| from it, transfer that ImageBitmap back to the main
| thread, and use it as a texture on 3D geometry.
|
| I also use 3D contexts in Workers to do some pre-
| processing on textures, like converting equirectangular
| skymaps into rectalinear cubemaps. The worker is setup to
| be able to preload these images while the user is doing
| other things, then transfer the results when they are
| needed during a scene transition, so the scene transition
| is nearly instanteous.
| singularity2001 wrote:
| Doesn't work on Firefox
|
| SyntaxError: import declarations may only appear at top level of
| a module
| Y_Y wrote:
| How come only Chrome has whatever feature this needs?
| paulgb wrote:
| GPU on the web is unfortunately kind of fragmented at the
| moment. WebGL 1 has pretty broad support but has some technical
| limitations; WebGL 2 (which this uses) is supported in most
| things but not (stable) Safari or iOS-based browsers[1]. WebGPU
| is apparently around the corner but it will likely be years
| before it has broad support.
|
| (I see reports here of it also not working on Firefox, which
| must be another reason, as FF does support WebGL2 and
| WebAssembly.)
|
| [1] https://caniuse.com/webgl2
| hwillis wrote:
| God damn I can't wait for webGPU. I would really, _really_
| like to have geometry stages, compute shaders, RTX, and
| actual vulkan-style commands, but that 's a little too much
| to ask of browsers. Too many kinds of hardware, even if you
| pass device checks onto the developer (which they still
| should).
|
| 60 second explanation of the three APIs:
|
| WebGL 1: vertices and triangles are stored on the global GL
| context object and need to be rebuilt every frame. Shader
| language is a very goofy, somewhat obnoxious GLSL lookalike.
| You can write vertex and fragment shaders, which are the
| necessary ones to render, but also the least interesting.
| Post-processing is a _serious_ pain. FPS is limited by
| bandwidth to submit to the GPU and CPU usage can be _stupid_
| high.
|
| WebGL 2: improved shader language (much more similar to GLSL,
| better compilation, better branching), still only two
| pipeline stages. Render buffers, depth buffers, multidraw,
| allowing for modern techniques like deferred rendering and
| efficient shadowmaps. Vertex attribute buffers are their own
| thing amd dont have to be freshened for every draw call. At
| this point webGL is similar-ish to native opengl with a bunch
| of missing features. In webGL 1 you had to do things very
| differently from a native api, which was very slow, messy,
| and annoying.
|
| WebGPU:Vulkan came out! And everyone learned that oh,
| actually having everything on a single thread really sucks,
| huh. OpenGL has a global context that prevents great
| threading- have to make draws from a single thread, even if
| you can construct buffers etc in job threads (minor
| improvement) you have to sync back. Vulkan and webGPU let you
| submit to command buffers with their own contexts. In WebGL 1
| you had to rebuild and rebind all of an object's vertices
| every time it had a drawcall. In WebGL 2 you built them once
| and just have to rebind each one in series for every frame.
| In WebGPU, you can bind in parallel from webworkers. Not
| ideal parallelism, but shockingly good for javascript. For
| some things like shaders, you don't even need to recompile,
| which is a hard-to-avoid main thread blocker in WebGL 1/2.
|
| WebGPU can also do compute, which _rules_ - many complex AAA
| techniques really require this and don't work on WebGL
| because it wants to send all its render buffers back to the
| CPU.
| nitrogen wrote:
| Current Firefox shows this error in the page: _SyntaxError:
| import declarations may only appear at top level of a module_
| FriendlyNormie wrote:
| Your dogshit experiment doesn't work, asshole. Doesn't load on
| Safari on neither a Mac nor an iPhone, and on Chrome it just
| shows a blank white box and some javascript errors. The browser
| it's "supposed" to work on. Jesus. Fuck you and your worthless
| dogshit. If I wanted to relive the experience of wrestling with
| experimental garbage websites that don't work then I'd go back to
| 1999 and try to use sites with embedded Java applets. FUCK YOU.
___________________________________________________________________
(page generated 2021-04-02 23:00 UTC)