Sebastian Aaltonen

Sebastian Aaltonen

@sebaaltonen.bsky.social

Building a new renderer at HypeHype. Former principal engineer at Unity and Ubisoft. Opinions are my own.

1.9K followers94 following70 posts

Pinned

I ended up writing an API in the end of the blog post titled "No Graphics API". At least my API has only 150 lines of code. In comparison WebGPU is 2700 lines and Vulkan is over 20,000. But "5% API" isn't as catchy title as "No API" :)

"Parkour City" was one of the first bigger games in HypeHype. It looked pretty bad two years ago. With our new renderer, this game today looks pretty good. I did a minor remix: Changed the visual style preset and tweaked the sun and fog settings.

This game doesn't have any textures. This is true for most of the games on the platform currently. Texture support is a recent addition, and we are going to add lots of new texturing features in January / February.

For most people, virtual texturing is a streaming tech. For me, it's always been a way for the GPU to access all texture data simultaneously -> max batching + no binding cost. VT is a surface cache for the visible pixel data set. Caches your material blending and decals -> big perf win.

This is why we have virtual texturing in HypeHype. Our games are tiny (10MB), so we don't need to stream anything. However, we still implemented virtual texturing to improve our CPU and GPU performance. It also solves material variety and tiling issues (fast material blending and decaling).

Sebastian Aaltonen reposted

My hot take is that promotion of ECS and "kernelization" were one of the most harmful ideas in game programming. They apply only selectively, and were preached like a religion by angry individuals "if you don't do it, you are incompetent, silly or lazy, and your performance will suck!"

This demo doesn't yet have a virtual texture decaling system. It will make it possible to add lots of texture variety with minimal storage cost. But it's possible to make pretty good-looking results even with just a couple of traditional tiling textures.

Sebastian Aaltonen reposted

In our next Tiny Glade update we'll bump the light limit from 32 to 32k while keeping the cost more or less the same. The small limit has been a cop out, as we didn't quite know how to render huge numbers of (screen-space) shadow-casting lights without severe performance degradation.

3->4 shadow cascades performance (M3 Max): 3 cascades: Vertex = 0.20ms Pixel = 0.07ms 4 cascades: Vertex = 0.39ms (195%) Pixel = 0.11ms (157%) On M3 Max, a total cost of 0.5ms for good-looking shadows is a no-brainer. However, a 185% cost is too much for low- and mid-tier phones.

Today, I added storage buffer support to HypeHype RHI and all the backends: WebGPU, Metal, and Vulkan. I tested changing some shaders to SSBO instead of UBO. Works on all platforms! Metal was the easiest. Buffers are just GPU pointers in Metal. There's no UBO or SSBO. Zero changes...

View full thread

DX12 has a complete buffer zoo: constant buffers, structured buffers, raw buffers, append buffers, typed buffers, SRV, and UAV of each. Of course, there are also vertex buffers and index buffers. Sane APIs like Metal and CUDA just use a GPU pointer.

My "No Graphics API" blog post will include chapters discussing the "buffer zoo" and its history. Why did we end up with this mess instead of the clean future we can already start to see with Metal 2.0, CUDA, and similar modern APIs?

Today, I added storage buffer support to HypeHype RHI and all the backends: WebGPU, Metal, and Vulkan. I tested changing some shaders to SSBO instead of UBO. Works on all platforms! Metal was the easiest. Buffers are just GPU pointers in Metal. There's no UBO or SSBO. Zero changes...

View full thread

Vulkan required the SSBO type to be in the descriptor set layout. And I added SSBO descriptors into descriptor pools. We have one persistent pool and two temp pools, one per active frame (2). The active temp descriptor pool is reset every frame, and now it also has SSBO descriptors.

This is yet another example where it's clear that Metal API and MSL are more modern compared to HLSL/GLSL and Vulkan/DX12. In Metal every buffer is just a 64-bit GPU pointer. There's no buffer zoo. Every buffer is just a buffer and bound the same way, including argument buffers.

Today, I added storage buffer support to HypeHype RHI and all the backends: WebGPU, Metal, and Vulkan. I tested changing some shaders to SSBO instead of UBO. Works on all platforms! Metal was the easiest. Buffers are just GPU pointers in Metal. There's no UBO or SSBO. Zero changes...

WebGPU required an RHI change. WebGPU only allows read-only SSBO binding in vertex shaders (due to mobile GPUs splitting vertex shader to position+attribute shader, side-effects would break it). WebGPU requires a bind group layout to declare read-only binding, and it's validated against the shader.

View full thread

Sebastian Aaltonen reposted

Trying the tiny MLP in more locations (left) vs the spherical 10m visibility it is "learning" from (right). The one node hidden layer can only coarsely approximate the visibility signal and only in one broad direction. Also not all probes manage to converge in a reasonable time.

Kostas Anagnostou@kostasanagnostou.bsky.social

Comparing a small (1 node hidden layer) MLP (top) with an L2 Spherical Harmonics (bottom) encoding of raytraced visibility (left). The 6 floats MLP appears to capture occlusion better that the 9 floats SH.

Today we managed to switch our Flutter web build to use WASM. It's at least 3x faster. Our game engine was already using WASM. When combined with my recent WebGPU gfx backend and Jolt physics with WASM SIMD, our new web build feels almost like the native build now :)

“The first draft of anything is shit.” - Ernest Hemingway He was absolutely right. Every time I write a presentation I get that feeling. Takes a full rewrite + several polish passes to make anything feel good. Same is happening with my "No Graphics API" blog post...

Now that we shipped WebGPU and Android will be 100% Vulkan soon, we started designing compute shader pipeline. GPU-driven rendering, virtual shadow maps, compute stochastic lighting, etc. But this is not without issues on mobile. I worry about vertex work overlap...

This is how vertex work overlaps with pixel work currently. We setup barriers in Vulkan and Metal to only block pixel work. This is approx 20% perf gain on G57 when heavy vertex work overlaps previous frame. On Apple (left) 10%, but more if heavily GPU bound.

For Metal/Vulkan/GL users. I am talking about texel buffers. If you are using texel buffer, what's the reason for that? Are you aware that modern GPUs can load 8 bit and 16 bit values from SSBO directly (doesn't apply to older Android phones)?

Just pushed my WebGPU gfx backend to production. Took 21 days to develop in total: native Dawn Mac + Windows first, then Emscripten for web. Runs really smoothly on the browser and the page load is super fast. Zero issues on Mac, Windows or Chrome. Safari Tech Preview has some flickering tris.

The web version of HypeHype doesn't yet have threading. We will investigate that soon. Native versions (Mac, Windows, Android, iOS) are fully threaded of course. This is why there's a stall between game loading in web. Native feed is 100% smooth (preload next game in thread).

Have been tuning HypeHype's custom GTAO implementation for two days: Morton sampling pattern, bilateral blur uses slope-based weight (instead of constant Z), 2x2 depth downsample passes use median (instead of max). Still work to do, but starts to look pretty good. Game: "Block City" by Blue Mint

Have been tuning HypeHype's custom GTAO implementation for two days: Morton sampling pattern, bilateral blur uses slope-based weight (instead of constant Z), 2x2 depth downsample passes use median (instead of max). Still work to do, but starts to look pretty good. Game: "Block City" by Blue Mint

We are leaning on GTAO a lot, as there's no baked lighting. Games have to be <10MB each. There's simply no room to store any baked lighting data. And you can press a button to start remixing any game. Everything can be modified. Baked lighting doesn't really work for us.

You are up to date.