Devblog

Visual quality & performance in Astral Shipwright

Getting a game to look good is hard, but getting a good-looking game to perform well is even harder. And here is why Astral Shipwright was moved to Unreal Engine 5 six months ago, using a development branch of the engine's sources: new features of the engine bring both great quality and new ways to get the game running well. The previous devblog entry focused on planets, and we'll move on today with the rendering of the stations featured in the game.

Close-up shot of station walls

Real-time reflections

If you've played Helium Rain before, you might have noticed that reflective surfaces are somewhat absent. Windows or mirrors aren't to be seen, solar panels are fairly rough, metals are painted. This is because reflections are a very difficult topic in game development: realistic reflections normally require a prohibitive amount of computation, essentially simulating thousands of light bounces per pixel. This is what raytracing does in movies and raytracing-enabled games, although to vastly different degrees.

In Helium Rain, reflections where completely screen-space - reflecting pixels already rendered in the scene. This looks great, but has really visible limitations for a space game - planets and moons will never reflect on hulls unless they're visible in the same shot! In Astral Shipwright, I experimented with ray-traced reflections at first, but the performance and quality were not acceptable, on top of requiring dedicated GPU hardware. The final solution is UE5's Lumen technology, which is available as an option in the game to get full dynamic reflections at a fraction of raytracing's cost.

Mirror reflections on a large window

Lumen is based both on screen-space and raytraced elements that do not require hardware GPU support, but owners of such hardware will find an option in the game's settings to further enhance visual quality by using DXR (also known as RTX).

Nanite

The other highlight UE5 feature is Nanite, and Nanite is even more interesting. The technology has mostly been described as a way to render incredibly detailed 3D assets, but in my opinion this is not the most exciting part. Instead, I would describe Nanite as a feature that automatically reduces the level of detail of game assets depending on the need. It is an incredible optimization tool - you could argue that a Nanite-powered scene would in fact push less triangles to the screen compared to a traditional scene with the same visual quality, with a lot less effort in development.

That's a lot of triangles

Nanite essentially ensures that every triangle on the screen is no smaller than a pixel, as you can see in the above image. This sounds insanely dense until you realize a 2560x1440 scene would need about three million triangles, a number consistent with previous-gen console games. While Nanite itself has a cost, the technology yields incredible benefits:

  • every game asset can be seen from far away without inducing aliasing, or requiring manual level-of-detail work;
  • game assets can receive more detail;
  • a low-quality version of every asset is automatically generated for use in Lumen, raytracing, etc.

This low-quality variant is also what will be displayed on machines that do not support Nanite. Look at the image below for an example - you can probably see that light sources feature visible edges, and small artifacts are visible if you look very closely. Every asset in this scene is a degraded variant of the original, but the overall quality is satisfying and the polycount in the scene is less than a million triangles.

Here's our station with the Nanite proxy mesh

As of today, it looks like Nanite will require both DX12 support and Shader Model 6.6 support. The latter is too recent to accurately map to existing GPU models - stay tuned for compatibility updates!

Resolution scaling

Resolution scaling, also known as upscaling or upsampling, is the concept of rendering a video game at a given internal resolution and presenting it at a higher resolution. It's not a novel concept - the time it takes to render a game frame is almost always higher when resolution increases, and lowering a game's resolution to get it to run on an older rig is a staple of PC gaming. The loss of quality associated with upscaling is less popular and console games today are scrutinized as part of reviews to determine their internal resolution.

Resolution scaling has recently been enjoying a revival of sorts, with technologies such as Nvidia's DLSS or AMD's FSR, the advent of AI upscaling, and more complex game engines that can provided temporal upscaling. For the first time, people are actually asking for upscaling features because they look closer and closer to native resolution with a significant framerate boost. Astral Shipwright supports three upscaling technologies, to ensure everyone has an option; and features an internal resolution slider to allow customization from 50% to 150% of the display resolution.

  • Temporal Super Resolution (TSR): The default resolution scaling in Astral Shipwright is a new feature of Unreal Engine 5. It is a temporally based upscaler - meaning each frame reuses some pixels from the previous frame, enabling large performance gains. It works on every platform and is quite high quality.
  • Temporal Anti-Aliasing (TAA): Unreal Engine 4 relied on its anti-aliasing technology to upscale images. This is provided in Astral Shipwright as a fallback if TSR does not yield enough gains.
  • DLSS: For players using an Nvidia RTX 2000 series GPU or above, DLSS is available as a high-end AI upscale. Please note that the internal resolution slider will be disabled in this case.

Thank you for reading!

Devblog

Devblog history

  • Visual quality & performance in Astral Shipwright
  • Creating high-quality game planets
  • Welcome to the Astral Shipwright devblog
  • Follow the project