Reader small image

You're reading from  Mastering Graphics Programming with Vulkan

Product typeBook
Published inFeb 2023
PublisherPackt
ISBN-139781803244792
Edition1st Edition
Right arrow
Authors (2):
Marco Castorina
Marco Castorina
author image
Marco Castorina

Marco Castorina first got familiar with Vulkan while working as a driver developer at Samsung. Later he developed a 2D and 3D renderer in Vulkan from scratch for a leading media-server company. He recently joined the games graphics performance team at AMD. In his spare time, he keeps up to date with the latest techniques in real-time graphics.
Read more about Marco Castorina

Gabriel Sassone
Gabriel Sassone
author image
Gabriel Sassone

Gabriel Sassone is a rendering enthusiast currently working as a Principal Rendering Engineer at Multiplayer Group. Previously working for Avalanche Studios, where his first contact with Vulkan happened, where they developed the Vulkan layer for the proprietary Apex Engine and its Google Stadia Port. He previously worked at ReadyAtDawn, Codemasters, FrameStudios, and some non-gaming tech companies. His spare time is filled with music and rendering, gaming, and outdoor activities.
Read more about Gabriel Sassone

View More author details
Right arrow

GPU-Driven Rendering

In this chapter, we will upgrade the geometry pipeline to use the latest available technology: mesh shaders and meshlets. The idea behind this technique is to move the flow of mesh rendering from the CPU to the GPU, moving culling and draw command generation into different shaders.

We will first work on the mesh structure on the CPU, by separating it into different meshlets that are groups of up to 64 triangles, each with an individual bounding sphere. We will then use compute shaders to perform culling and write a list of commands to draw the meshlets in the different passes. Finally, we will use the mesh shaders to render the meshlets. There will also be a compute version provided, as mesh shaders are still available only on Nvidia GPUs for now.

Traditionally, geometry culling has been performed on the CPU. Each mesh on the scene is usually represented by an axis aligned bounding box (AABB). An AABB can easily be culled against the camera frustum, but...

Technical requirements

Breaking down large meshes into meshlets

In this chapter, we are going to focus primarily on the geometry stage of the pipeline, the one before the shading stage. Adding some complexity to the geometry stage of the pipeline will pay dividends in later stages as we’ll reduce the number of pixels that need to be shaded.

Note

When we refer to the geometry stage of the graphics pipeline, we don’t mean geometry shaders. The geometry stage of the pipeline refers to input assembly (IA), vertex processing, and primitive assembly (PA). Vertex processing can, in turn, run one or more of the following shaders: vertex, geometry, tessellation, task, and mesh shaders.

Content geometry comes in many shapes, sizes, and complexity. A rendering engine must be able to deal with meshes from small, detailed objects to large terrains. Large meshes (think terrain or buildings) are usually broken down by artists so that the rendering engine can pick out the different levels of details...

Understanding task and mesh shaders

Before we begin, we should mention that mesh shaders can be used without task shaders. If, for instance, you wanted to perform culling or some other pre-processing step on the meshlets on the CPU, you are free to do so.

Also, note that task and mesh shaders replace vertex shaders in the graphics pipeline. The output of mesh shaders is going to be consumed by the fragment shader directly.

The following diagram illustrates the differences between the traditional geometry pipeline and the mesh shader pipeline:

Figure 6.4 – The difference between traditional and mesh pipeline

Figure 6.4 – The difference between traditional and mesh pipeline

In this section, we are going to provide an overview of how task and mesh shaders work and then use this information to implement back-face and frustum culling using task shaders.

Both task and mesh shaders use the same execution model of compute shaders, with some minor changes. The output of task shaders is consumed directly by a mesh...

GPU culling using compute

In the previous section, we demonstrated how to perform back-face and frustum culling on meshlets. In this section, we are going to implement frustum and occlusion culling using compute shaders.

Depending on the rendering pipeline, occlusion culling is usually done through a depth pre-pass, where we write only the depth buffer. The depth buffer can then be used during the G-Buffer pass to avoid shading fragments that we already know are occluded.

The downside of this approach is that we have to draw the scene twice and, unless there is other work that can overlap with the depth pre-pass, have to wait for the depth pre-pass to complete before proceeding to the next step.

The algorithm described in this section was first presented at https://advances.realtimerendering.com/s2015/aaltonenhaar_siggraph2015_combined_final_footer_220dpi.pdf.

Here’s how it works:

  1. Using the depth buffer from the previous frame, we render the visible objects...

Summary

In this chapter, we have introduced the concept of meshlets, a construct that helps us break down large meshes into more manageable chunks and that can be used to perform occlusion computations on the GPU. We have demonstrated how to use the library of our choice (MeshOptimizer) to generate meshlets, and we also illustrated the extra data structures (cones and bounding spheres) that are useful for occlusion operations.

We introduced mesh and task shaders. Conceptually similar to compute shaders, they allow us to quickly process meshlets on the GPU. We demonstrated how to use task shaders to perform back-face and frustum culling, and how mesh shaders replace vertex shaders by processing and generating multiple primitives in parallel.

Finally, we went through the implementation of occlusion culling. We first listed the steps that compose this technique. Next, we demonstrated how to compute a depth pyramid from our existing depth buffer. Lastly, we analyzed the occlusion...

Further reading

As we mentioned in a previous section, task and mesh shaders are only available on Nvidia GPUs. This blog post has more details about their inner workings: https://developer.nvidia.com/blog/introduction-turing-mesh-shaders/.

Our implementation has been heavily inspired by the algorithms and techniques described in these resources:

Our go-to reference implementation for a task and mesh shader has been this project: https://github.com/zeux/niagara, which is also accompanied by a series of videos showing its development: https://www.youtube.com/playlist?list=PL0JVLUVCkk-l7CWCn3-cdftR0oajugYvd.

These libraries can be used to generate meshlets:

A more recent development in occlusion culling...

lock icon
The rest of the chapter is locked
You have been reading a chapter from
Mastering Graphics Programming with Vulkan
Published in: Feb 2023Publisher: PacktISBN-13: 9781803244792
Register for a free Packt account to unlock a world of extra content!
A free Packt account unlocks extra newsletters, articles, discounted offers, and much more. Start advancing your knowledge today.
undefined
Unlock this book and the full library FREE for 7 days
Get unlimited access to 7000+ expert-authored eBooks and videos courses covering every tech area you can think of
Renews at $15.99/month. Cancel anytime

Authors (2)

author image
Marco Castorina

Marco Castorina first got familiar with Vulkan while working as a driver developer at Samsung. Later he developed a 2D and 3D renderer in Vulkan from scratch for a leading media-server company. He recently joined the games graphics performance team at AMD. In his spare time, he keeps up to date with the latest techniques in real-time graphics.
Read more about Marco Castorina

author image
Gabriel Sassone

Gabriel Sassone is a rendering enthusiast currently working as a Principal Rendering Engineer at Multiplayer Group. Previously working for Avalanche Studios, where his first contact with Vulkan happened, where they developed the Vulkan layer for the proprietary Apex Engine and its Google Stadia Port. He previously worked at ReadyAtDawn, Codemasters, FrameStudios, and some non-gaming tech companies. His spare time is filled with music and rendering, gaming, and outdoor activities.
Read more about Gabriel Sassone