← Back

ofxDawn

github.com/ofWorks/ofxDawn · @ofWorks
OF 0.12 Utilities macOS Windows

Dawn / WebGPU for ofWorks

1 0 Last commit 3mo ago Created 4mo ago

README

ofxDawn



WebGPU for openFrameworks on macOS, powered by Dawn (the same WebGPU implementation used in Chromium).

The addon brings up a headless WebGPU device on Dawn's Metal backend and provides a GPU particle system simulated with a WGSL compute shader and rendered through openFrameworks.

Platform: macOS only (Apple Silicon + Intel — the bundled lib is a
universal binary). The Dawn backend here is Metal.

What's included



createShaderModule() helper. Async WebGPU requests are driven synchronously by pumping ProcessEvents(). WebGPU storage buffer (advanced by a compute shader) and is **rendered on the GPU** as points straight into a shared texture — the data never leaves the GPU. WebGPU render target and an OpenGL texture, exposed as an ofTexture.

The bundled library



libs/dawn/lib/macos/libwebgpu_dawn.a is Dawn's monolithic static build. It exports the standard wgpu* C symbols directly, so there's no proc-table wiring — #include <webgpu/webgpu_cpp.h> and call wgpu::CreateInstance().

The Metal backend pulls in these frameworks (declared in addon_config.mk): Metal, IOSurface, Foundation (plus QuartzCore, IOKit, Cocoa, which the ofWorks core already links).

Building (ofWorks / ofGen)



cd example
ofGen          # generates chalet/zed/xcode projects from of.yml
chalet build   # build
chalet run     # run


ofGen reads addon_config.mk and auto-detects the static lib under libs/dawn/lib/macos/, the headers under libs/dawn/include/, and the frameworks from the macos: section — so a project's of.yml only needs to list ofxDawn under addons:.

Usage



#include "ofxDawn.h"

include "ofxDawnParticles.h"

include "ofxDawnSharedTexture.h"

ofxDawn dawn; ofxDawnParticles particles; ofxDawnSharedTexture sharedTex; void ofApp::setup() { dawn.setup(); sharedTex.setup(dawn, ofGetWidth(), ofGetHeight()); particles.setup(dawn, 200000, glm::vec2(ofGetWidth(), ofGetHeight())); } void ofApp::update() { // simulate + render on the GPU, into the shared texture particles.update(ofGetLastFrameTime(), glm::vec2(ofGetMouseX(), ofGetMouseY()), sharedTex); } void ofApp::draw() { sharedTex.getTexture().draw(0, 0); // zero-copy, no readback }


How rendering works (zero-copy interop)



Particles are simulated by a compute shader and rendered on the GPU as a point list, straight into a WebGPU texture that is backed by an IOSurface (imported via SharedTextureMemoryIOSurfaceDescriptor). That same IOSurface is bound to a GL_TEXTURE_RECTANGLE with CGLTexImageIOSurface2D and wrapped as an ofTexture, so OF draws it directly — **no CPU round-trip and no vertex upload**. ofxDawnSharedTexture owns this bridge; the surface is rendered between beginAccess() / endAccess().

Synchronization: OpenGL can't wait on Metal's MTLSharedEvent fences, so after submitting the WebGPU work the addon does a CPU waitForGPU() (queue OnSubmittedWorkDone) before OF samples the texture. This is the one remaining GPU sync per frame; eliminating it (e.g. by pipelining across frames) is a possible future optimization.

Roadmap



replacing the CPU readback / ofVboMesh path the GPU isn't stalled each draw) RGBA16Float / RGBA32Float for HDR and high-precision targets) trail → tonemap → IOSurface, glm camera, instanced well/probe geometry, ofxMicroUI controls). Shaders port nearly verbatim; main work is the extra render passes, uniform-layout matching, and UI wiring. particles, slice by hardness (HU window), color-map via a transfer function, view in 3D. Shares the glm-camera / 3D-point milestone with the Fulcrum port. Plan + conversion workflow in docs/CT_VOLUME.md; pre-convert DICOM with tools/dicom_to_nrrd.py.

License



Dawn is BSD-licensed (see libs/dawn/LICENSE).

Get this addon

HTTPS
SSH