Compute Shaders
GPU-generated texture using a compute shader in DX12
During the research phase of our project, every team member set out to explore different technologies that we could incorporate into our engine. Our goal is to collect lots of interesting data about current developments and practices. Most recently, we researched compute shaders and how game engines could utilize them to gain performance. These are our findings.
GPUs are great at performing operations on texture data. This is what they are built to do – perform parallel calculations on large sets of data. However, reaching the programmable point in a graphics pipeline, which we could utilize to perform those (perhaps unorthodox) calculations introduces a lot of overhead; in particular, having to go through a rasterizing stage. This is where compute shaders become useful. Introduced with DirectX11 (Direct Compute) and OpenGL version 4.3, compute shaders allow programmers to utilize the parallel processing power of a GPU without needing external libraries (like CUDA or OpenCL). The compute shader shares the shader language of other common shaders (vertex, pixel), but is not part of the main rendering pipeline. The compute shader is also not limited to working in the space of geometry, rather allowing the user to define their own compute space, providing more flexibility when executing GPGPU (General-purpose Computing on GPU).
So, what can we use compute shaders for in our engine? Let’s give a few examples:
- Generating texture data (noise textures, mip maps, any other procedural texture generation).
- Performing post-processing effects without a pixel shader (and therefore not being bound to only accessing a single pixel at a time). Blur effects are a good example where compute shaders introduce a performance increase over pixel shaders.
- Physics calculations – PhysX and Bullet utilize compute shaders to speed up their simulations.
- Particle systems – Can compute the entire particle system on the GPU.
- AI pathfinding
- Global illumination
- Fluid simulations, cloth/hair simulations
- Basically, anything that could be calculated in batches
Drawbacks? Sure there are!
- Introduces issues with memory coherency – need to take care to properly sync data.
- Added complexity.
- GPU load might already be high – need to use with caution, especially when it comes to GPGPU.
- Older hardware might not actually support compute shaders.
In conclusion, compute shaders could be useful if handled properly and cautiously. The pros and cons are even more apparent when using compute in combination with a multithreaded application – performance increases drastically, but so does the amount of management and complexity. Our team will definitely consider utilizing compute shaders, especially if we decide to multithread our engine.