Graphics Tech

Image quality for real-world simulations depends on the techniques used to render images. Here are some of the methods used.

This article is a subsection of
How to Optimise MSFS for VR

Note: This article is currently being edited. When the article is fully realised this notice will be removed.

Variable Rate Shaders (VRS & VRCS)

This is a rendering technique that prioritises areas of interest with the highest resolution. There are three ways to consider using it:

  • In combination with eye tracking, where the eye focus has the highest resolution
  • As defined by the game developer whereby the developer defines the resolution priority using an encoded texture.
  • By detecting and rendering motion at a lower resolution

The graphics engine splits the screen display into a grid of tiles (arbitrarily 16×16 pixels) and applies a scaled pixel resolution depending on the priority seen within each tile, as defined by the developer or by eye tracking.

Here is an example using a 4×4 pixel tile, showing the savings relative to the highest quality:

  • 16 individual 1×1 pixels (100%)
  • 8 each 2×1 or 1×2 scaled pixels (50%)
  • 4 each of 2×2 scaled pixels (25%)
  • 2 each of 4×2 or 2×4 scaled pixels (12.5%)
  • 1 single 4×4 scaled pixel (6.25%)

Note 1: any quality range from supersampling to course mapping to be rendered.
Note 2: the size of the tiles and the extent of scaled pixel sizes is ultimately arbitrary

Variable Rate Compute Shaders (VRCS)

A compute shader allows for a flexible mapping between compute threads and output pixels, which is a more implementation dependent explanation of the VRS technique.

Vulcan

Vulkan is a graphics and compute API that supports multiple platforms. It facilitates pre-emptive loading of assets on multiple threads in order to keep rendering frame rate consistent. Shaders can be compiled and cached when a program is initialised for the first time. Programming for Vulcan requires more effort and planning than OpenGL for which it is the successor.

Mesh Shaders

A mesh shader is preceded by a task shader and is followed by a rasteriser. The task shader divides a mesh into work groups. The work groups are passed to the mesh shader for parallel processing. The mesh shaders simplify the work groups into reusable arrays of vertices and attributes called meshlets suitable for efficient drawing by the hardware rasteriser.

Sampler Feedback

Sampler feedback is provided in Direct X 12. At runtime, sampler feedback provides information about what mip level is being used to render a scene and what part of a texture is being sampled. This knowledge can be significantly helpful to minimise memory use and thereby increase efficiency.

Ray Tracing

LOD

Upscaling

Spatial

AMD FSR

NVIDIA NIS

Temporal

DLSS

graphics tech dlss show improved temporal handling
a DLSS upscaler uses previous frames to improve the result

FSR 2.0

Foveated Rendering

Game Stack Rescale

VR Headsets

Graphics Pipelines

Nanite & Lumen

Nanite is the name of the virtual geometry engine in Unreal Engine created for Unreal by Epic Games, led by Brian Karis.

SIGGRAPH- A Deep Dive into Nanite Virtualized Geometry

Nanite Geometry

  • Nanite is a complex graphics engine whose frame rate depends upon the display size rather than scene complexity. The basic unit is the triangle mesh. Nanite is a triangle rendering pipeline.
  • Source geometry meshes from industry standard modelling tools are parsed into a new format when they are loaded.
  • All of the reformatted data is stored in video memory across frames and is sparsely updated with changes.
  • All Nanite mesh data is stored in single large resources that is accessible at any time.
  • Triangles are grouped into clusters, clusters are rebuilt internally to simplify. the edges remain unchanged to prevent visible gaps between clusters.
  • Clusters are culled using a hierarchical depth buffer, remaining clusters are matched with the lowest MIP level.
  • Good occlusion culling is achieved by isolating the differences between the depth buffers of the current and previous frames. Anything new will be added to the frame.
  • The visibility pass uses shaders to combine the depth buffer with (interpolated) textures and the result is stored into a GBuffer. The CPU cost is independent of the scene or the objects in view.
UE5’s Nanite engine’s view of an image on a screen display

How Mesh LOD is Managed Over Time

  • Clusters are arranged into trees of LOD levels dynamically, with unused nodes removed from the tree as necessary over time. The parent LOD has the least amount of detail.
  • To prevent visible cracks forming in a mesh due to varying LOD levels across an object, groups of clusters are created and all members of the same group are given the same LOD level.
  • As the LOD levels change:
    • New groups of clusters are selected with the least number of (locked) boundary edges. This maximises the opportunity for internal simplification.
    • For each group, individual triangles are merged and simplified by 50% using a Quadratic Error Metric to optimise the position of a new vertex in space with minimal error. This is not perfect but does work well. The level of error is stored in the group.
    • The simplified list is reassembled into new clusters within the group.
    • The boundaries do not change and cracks are eliminated.
    • Additional information is added for close but unconnected clusters to control which groups the cluster end up in.
  • The net result are two list of groups with the least number of locked edges, one with a LOD level one half of the other. When the level of error between the two is less than 1 pixel, the change between the LOD representations is imperceptible (via TAA antialiasing).
  • A thread pool is used for culling LOD, supported by shader programming to ensure the mechanism completes correctly in all hardware environments.
  • Occlusion culling is performed on the new frame and combined with the differences from the previous frame in order to isolate changes that need to be updated and given materials.

Rasterisation

  • A software rasteriser is faster when working with small triangles (less than 32 pixels long).
  • A hardware rasteriser is faster for large areas.
  • The most appropriate rasteriser is used throughout the image.

Inefficiencies

  • Currently Nanite does not work well with large numbers of gaps and holes, for example in subjects such as grass and tree leaves.
  • Tiny instances cannot be culled easily.
  • Visibility Buffer Imposters are objects that carry enough information to be rendered instead of small instances, but the lower resolution can be noticeable in specific circumstances.
  • Materials are applied in tiles using information stored as a depth buffer. This code is being reworked.

Glossary

BVH – Bounding Volume Hierarchy. Any mesh object can be simply represented with a cube that completely encloses its extremities. Smaller mesh component objects a complex object can be represented in cubes of their own, grouped and enclosed by larger cubes nested inside each other.

Compute Unit – is (approximately) a group of GPU cores that share their own rendering units and cache. A GPU will have multiple compute units.

DAG – Directed Acyclic Graph. A hierarchical list of nodes where the relationship is flowing in one direction (eg: from parent to child or parent to grandchild, never from child to parent etc.). A child may have more than one parent.

HZB – Hierarchical depth buffer

Interpolation – Creating new values between two known values in even steps.

LOD – Level of Detail – related to the amount of detail stored in a version of a 3D model. Distant objects do no require as much detail as nearby objects. Related to Mipmap.

LZ – Lempel-Ziv compression replaces repeating blocks of byte aligned data with a short reference code. It is a straight-forward, simple, lossless compression technique used to reduce stored data sizes.

Mesh – a three dimensional net composed of a collection of evenly distributed points that are interpreted as vertices, edges, and faces according to context. A mesh can be moulded into any shape and is normally made visible by painting the surfaces with images or colours.

MIP – An acronym for a Latin phrase: Multum in Parvo, meaning “much in little”. Usually used as Mipmap or MIP level.

Mipmaps – a size-ordered list of progressively lower resolution images. Each rectangular image is half the size of the one before. Related to LOD.

ROP – Raster Operations

SRV – Shader Resource View

Shader – A small program used to render pixels, usually as a fragment of a larger image. There are specific shaders to produce specific outputs, for example ray-traced or vertex shading. Each type of shader will require its own specific type of source data to work with.

UAV – Unordered Access View

References

Related Articles