Skip to main content

Get Started With Compute Shaders

Getting Started With Compute Shaders

The shader that's a 'Jack of all trades'. Of course, it's the Compute Shader.
These beauties allow your general purpose parallelized code to run on the GPU.
These can be used to do some pretty cool stuff that would be pretty difficult to do otherwise even with multi-threaded CPU code.
When bringing up Compute shaders in the context of video games, It's mostly used in physics simulations and freaky looking particle effects and to a lower extent as a core part of some post-processing effects and render pipeline optimizations such as various culling operations like occlusion culling.

The most important thing about compute shaders is that it allows for more efficient communication from CPU to GPU side and vice-versa. That basically means you can send arbitrary data to the GPU, let it do some work and then read it's output and then do whatever you want with it.
You can now see that how different compute shaders are when compared to other shaders, such as the fragment shader; which will only give output from the GPU in the form of a pixel buffer.
This will be the start of a series of tutorials related to creating various effects & simulations with the help of Compute Shaders in Unity.

You should somewhat familiar with writing shaders as well as have basic C# and Unity knowledge.
Before we start on the good stuff we need to be able to run a basic compute shader and see it's output in Unity.
Keep in mind that you need a graphics card released after the year 2011 ( or Intel HD 4000 or later ) be able to run compute shaders.

Unity setup

  • Create a new scene
  • Create a new compute shader & name it 'Test.compute'
    // Each #kernel tells which function to compile; you can have many kernels
    #pragma kernel CSMain
    // Create a RenderTexture with enableRandomWrite flag and set it
    // with cs.SetTexture
    RWTexture2D Result;
    [numthreads(8,8,1)]
    void CSMain (uint3 id : SV_DispatchThreadID)
    {
    // TODO: insert actual code here!
       Result[id.xy] = float4(id.x & id.y, (id.x & 15)/15.0, (id.y & 15)/15.0, 0.0);
    }
    This is default Compute Shader template, We won't be changing this.
  • Create a C# script called 'ComputeTester.cs'
    using UnityEngine;
    
    public class ComputeTester : MonoBehaviour
    {
        public ComputeShader computeShader;
        public int textureRes = 256; // Size of render texture we will be making
    
        private Renderer rend;
        private RenderTexture renderTexture;
    
        private void Start()
        {
            renderTexture = new RenderTexture(textureRes, textureRes, 24) // We have 24 as parameter for depth so that we will have depth buffer & stencil buffer support
            {
                enableRandomWrite = true
            };
            renderTexture.Create();//Need to call this to actually make it available in graphics memory
    
            rend = GetComponent();
            rend.enabled = true;
    
            int kernelHandle = computeShader.FindKernel("CSMain"); //Find entry point to our Compute Shader
            computeShader.SetTexture(kernelHandle, "Result", renderTexture); //Assigning our render texture in our Compute Shader which is called 'Result'
            computeShader.Dispatch(kernelHandle, textureRes / 8, textureRes / 8, 1); // Executes code on GPU with the input we have provided.
            rend.material.SetTexture("_MainTex", renderTexture); //Telling out render's material to use the render texture as it's texture
        }
    
        private void OnDestroy()
        {
            renderTexture.Release(); // Remove the render texture from graphics memory
        }
    } 
    Attach this script to any gameObject with a renderer component. Don't forget to assign our compute shader in the editor.
  • We should end up with this.

    We didn't go into any depth here, Just go this up and running.
    In future tutorials we will explore this in greater detail.
That's it! Hope you learnt something. Support Bitshift Programmer by leaving a like on Bitshift Programmer Facebook Page and be updated as soon as there is a new blog post.
If you have any questions that you might have about shaders or unity development in general don't be shy and leave a message on my facebook page or down in the comments.
For more Shader development tutorials, go : HERE
For Unity development tutorials, go : HERE

POPULAR POSTS

Fortnite Procedural Construction Animation Shader

Fortnite Construction Shader This shader is loosely based on the one that was presented by the Fortnite developers in their GDC talk: Inner Working Of Fortnite's Shader-Based Procedural Animations.

 Here is what we will end up with:
This technique requires you to author the 3D model in a certain way, More or less how those Fortnite developers did.
So we need the authored 3D model and the shader that uses data we get from the model to achieve the desired effect.

There are some nuances here and there so make sure you don't miss out on the details.😗
The first step will be preparing the 3D model and putting in the required data. I used Blender 2.79 but any 3D modeling software would do.
3D Model PreparationModel It
Apply Vertex Colors: For the direction of flight
Each color is a component of a vector (x, y, z). This will be considered as local space.
Values range from -1.0 to +1.0 for each component.
Negative values are achieved by using values of less than 0.5 and positive values wi…

Advanced Billboard Shader + World-Space UI Support

Advanced Billboard Shader + World-Space UI SupportAs you know billboarding is basically a plane with a texture on it that always facing the camera.These are some examples of what we are going for. This tutorial is going to be pretty straight-forward and easy to follow along you will learn how to make a billboard shader that not only keeps looking at the camera but also keeps its relative scaling intact.We will also provide an option to keep it rendered on top of all the other objects in the scene. This will be most useful for world-space UI that needs to be rendered on top of other geometry.We will be making 2 shaders here,Modified Default Unlit shader :- This one is a general shader ( easy to modify furthur ).Modified Default UI shader :- This one supports whatever a UI shader supports along with our billboarding capabilities. So let's get started with making the first one. As usual create a new Unlit shader and dive into the properties we need.Properties { _MainTex ("Texture…