Show HN: WebGPU Tech Demo

georginikolov | 138 points

It's nice that you can do this. But 3D rendering in the browser is rare. It's been working for years, with WebGL. Here are some examples.[1] Once in a while you see 3D models you can rotate and zoom. There are 3D games in the browser.[2] Unity will target WebGL if desired. Despite fairly good technology for 3D in the browser, it hasn't really caught on.

WebGPU is more powerful. It's basically Vulkan Lite. Limited threading. Bindless Vulkan is at least two years away. Only one queue to the GPU. This limits performance to roughly OpenGL levels. Not clear there's a big market for slightly better 3D in the browser. You can't do an AAA title in the browser yet, because the browser environment is too weak. But in a few years, maybe.

Unclear where this is going. The near future might be a world in which the only way you can run unapproved programs is via a browser. Phones mostly only run apps from approved app stores, and Windows in S mode only runs approved apps from Microsoft's store. Each year, the restrictions seem to get tighter. In which case the only way to do 3D anything without paying off the platform operator will be to use WebGPU or WebGL.

[1] https://webglsamples.org/

[2] https://www.crazygames.com/t/3d

Animats | 8 hours ago

This is really cool. I'm using an M1 Pro at the moment, and with all of the settings turned on I maintain around 50FPS. This seems pretty reasonable to me. Reflections, ambient occlusion, bloom, etc.

It looks like changing the shadow map resolution breaks things:

    None of the supported sample types (UnfilterableFloat|Depth) of [Texture "Directional Shadow Depth Texture"] match the expected sample types (Float).
     - While validating entries[3] as a Sampled Texture.
    Expected entry layout: {sampleType: TextureSampleType::Float, viewDimension: 2, multisampled: 0}
     - While validating [BindGroupDescriptor ""G-Buffer Textures Input Bind Group""] against [BindGroupLayout "GBuffer Textures Bind Group"]
     - While calling [Device].CreateBindGroup([BindGroupDescriptor ""G-Buffer Textures Input Bind Group""]).

    // redacted...

    webgpu-sponza-demo/:1 WebGPU: too many warnings, no more warnings will be reported to the console for this GPUDevice.
steve_adams_86 | 2 days ago

Nice demo - small tip/bug report, when I enable performance stats I get “FPS: 30.2ms”, which doesn’t make dimensional sense - one side of this statement has the wrong units.

If “30.2ms” is how long it took to render 1 frame, then label it “frame time”, not FPS (frames per second, or frame rate). Or if you want to show FPS, compute an actual FPS value, ie 1000/frame_time_ms.

(Frame time is a better metric for performance optimization work than the more popularly known frame rate, because frame time is linear, and frame rate isn’t.)

moosedev | 2 days ago

Only works in Chrome, probably.

Firefox: 'Uncaught (in promise) ReferenceError: GPUShaderStage is not defined <anonymous> https://gnikoloff.github.io/webgpu-sponza-demo/assets/index-... <anonymous> https://gnikoloff.github.io/webgpu-sponza-demo/assets/index-... index-BeB41sTJ.js:422:31 "

Animats | 2 days ago

Firefox 133.0.3 fails with:

Uncaught (in promise) ReferenceError: GPUShaderStage is not defined

    <anonymous> https://gnikoloff.github.io/webgpu-sponza-demo/assets/index-BeB41sTJ.js:422

    <anonymous> https://gnikoloff.github.io/webgpu-sponza-demo/assets/index-BeB41sTJ.js:2288
sounds | 2 days ago

It's exciting to see WebGPU move from requiring "this nightly version of a specific browser" but I still had to go over to my desktop for that instead of Safari on iOS. There had been some rumbling that might be changing in 18.2 https://news.ycombinator.com/item?id=42110252 but I just tried resetting the feature flags to defaults and it was still off by default for me :/.

In this part of the code:

  private onKeyDown = (e: KeyboardEvent) => {
    // @ts-expect-error Deprecated but still available
    this.presedKeys[e.keyCode] = true
  }
The suppressed error was trying to highlight ".keyCode" causes a broken experience when the user has a non-QWERTY keyboard. Switching to using ".code" will behave based on consistent position ("KeyW" is always where W is on QWERTY, even when the user is e.g. AZERTY) for less work than suppressing the error. For user controlled instructions things get a bit more complicated/dicey if you want to 100% polish https://developer.mozilla.org/en-US/docs/Web/API/Keyboard/ge... but if there is a step to skip it's properly labling WASD in the user's layout rather than having movement be randomly positioned keys.
zamadatix | 2 days ago

One of the big unlocks of WebGPU - shown here - is many lights in the scene, which is not possible with WebGL.

You might notice this still looks pretty dated, and that's primarily because the scene doesn't include ambient occlusion, which is usually the most important lighting feature to fake for realistic looking lighting.

stevebmark | 2 days ago

This is insane. I am noob in webgpu but how close we are to shipping a full fledged games that users can play on a browser?

Nithur | 11 hours ago

Demo or not, it must have decent error handling and inform user about critical errors, without diving into devtools.

butz | a day ago

Fails on latest chromium and firefox on linux. (Arch btw)

ActionHank | 2 days ago

For anyone interested, my team and I have been working on a WebGPU backend for Unreal Engine 5. Supports versions 5.1 all the way up to 5.5

UE5 WebGPU demo: https://play.spacelancers.com/

Company website: https://simplystream.com/

astlouis44 | 2 days ago

Works for me even on intel integrated. Nice work.

edit: I see you also wrote a webgpu ray tracer, very impressive! I am slowly working on a browser based 3d game in my spare time, your projects are right on my interests. I see you used MIT license on your ray tracer, do you have a license for the sponza demo?

hnuser123456 | 2 days ago

There are some bonus nifties under the "Open controls" dropdown on the top-right.

I suppose they are unchecked by default so that the demo runs out of the box on worse hardware.

hombre_fatal | 2 days ago

Cool but WebGPU is taking a long time to get to several platforms.

colordrops | 2 days ago

> Use QWASDE keys to navigate the scene

Interesting key ordering in the instructions.

stronglikedan | 2 days ago

On M1 Macbook Air with Chrome, I get 27 FPS (default settings).

ghoshbishakh | 2 days ago

Unresponsive white screen. Chrome on Android, Pixel 7.

solardev | 2 days ago

This is pretty cool, thanks for building it!

ridruejo | 2 days ago

Neat demo, but it runs pretty poorly on my 1650 Ti. It looks like the framerate is being displayed in the wrong unit, so I'm not sure exactly how fast it's rendering. Also glad to see a TAA toggle, when it's on, the ghosting artifacts are pretty atrocious.

mightyham | 2 days ago

Fails on Samsung A53, manages only as far as the controls.

pjmlp | 2 days ago

Nice work!

Out of curiosity, are there any of these features that couldn't be done with WebGL 2?

Jyaif | 2 days ago

This is very good stuff.

Did you do the whole reversing of the z trick?

I despise implementing cascaded shadow maps, and have a lot of respect for anyone that makes them work.

fidotron | 2 days ago

Is it just me, or is performance kinda... bad? Don't get me wrong, it's stable 144FPS, but it feels like it got my GPU's fans spinning faster than some modern games did (and indeed, power draw was fairly high). Similarly, when I launched it on my iPhone, even after it automatically disabled reflections, the phone got noticeably warm in my hand in under a minute.

Unless this was meant to be more of a stress test?

adrian17 | 2 days ago

WebGPU tech demo running in modern browsers showcasing various rendering techniques like deferred rendering with 400+ dynamic lights, Hi-Z screen space reflections and cascaded shadow mapping.

WebGPT has entered the chat.

reaperducer | 2 days ago

Progress indicator spins forever. Console:

  webgpu-sponza-demo/:1 No available adapters.
  index-BeB41sTJ.js:2288 Uncaught (in promise) TypeError: 
  Cannot read properties of null (reading 'requestDevice')
    at yn.initialize (index-BeB41sTJ.js:2288:13559)
    at async index-BeB41sTJ.js:2288:13792
Newest Chrome on Win11.
johnyzee | 2 days ago
[deleted]
| 2 days ago

[flagged]

sktrdie | 2 days ago