100% Orange Juice Devlog – Panel Rendering Update

We bring you another in-depth devlog from Rapha on the mostly invisible panel rendering update that just went live in version 3.29.2! We hope you’ll enjoy this technical explanation.

When 100% Orange Juice was originally built, drawing field panels was a bit like painting a house one brick at a time! Every single panel required 2 separate square draw operations from your GPU (one for the gray base, the other for the top)¹, slowing things down on big maps. Last year, we upgraded our engine to group similar pieces together, which cut down the workload significantly (all bases ~belong to us~ were drawn together, and the tops were grouped by texture used and drawn later)².

In this update, we made a massive leap forward by moving the heavy lifting entirely onto the GPU using a clever technique. Now, no matter how many panels are on a map, the game processes them in just two quick draw steps (all tops and all bases), letting your hardware handle it all effortlessly without breaking a sweat³. Similar tech is what allows the background of our new field Ambition to work, despite having almost a thousand of objects rendering, they are all instanced by the GPU, so its instantaneous.

This also allowed us to optimize the drawing order: we render the detailed colorful tops first so the GPU knows those pixels are hidden. This prevents the graphics card from wasting energy drawing parts of the bases you can’t even see, resulting in smoother performance. As a result, panels are true 3D objects now! They might be a bit more prone to aliasing, but they are smoothed out nicely by MSAA.

This opens the door for cool things in the future because panels are no longer optical illusions, they actually exist in 3D space. ||ヽ( ̄▽ ̄)ノミ|Ю

Technical Notes

¹: Why didn’t it matter in the beginning? DirectX9. DirectX9 was built at a time when GPU standards were really lax, so the driver had to fix the messy draw calls for you using whatever wizardry the manufacturer could do, that’s why it somehow worked without slowing down to a mess. This is a reminder of why some things were “fast”, became “slow” and are getting “fast” again, because they initially were carried by the driver, sadly. Some people like to describe this phenomenon as “old code suddenly aging like milk because modern hardware architectures stopped holding its hand with driver-side magic”. Just search “every game ships broken” to read stories about how driver manufacturers sometimes had to patch out entire sections of some games to make them work. That’s one reason why gaming on Linux was such a huge challenge that took years, while you can emulate the API just fine, you don’t know about the specific fixes vendors shipped to fix the game’s broken bits.

²: Initially they were batched by geometry, gathering the points and drawing them all at once, then at some point we updated the engine to support instancing, where you give your GPU an object, groups of information like position and rotation, and it draws them all from a single bunch of vertices.

³: This new one boosts instancing to the next level by using 3D textures (a graphics rendering construct where textures are stacked in memory and sent to the GPU). We can now send the layer of the texture needed in this stack, allowing for every single piece of information needed to draw all panels to be ready at your GPU’s hand all at the same time.

Leave a comment