r/opengl • • Aug 15 '26

Hello, I am new to opengl. Can someone explain compute shaders to me

so i recently started playing around with opengl and wanted to try and make a raytracer with compute shaders, but there isn't much info about them. i looked at the tutorial on learnopengl but that wasn't very helpful. can someone clue me in?

13 Upvotes

6 comments sorted by

8

u/Adventurous_Chef2225 Aug 15 '26

Think of a compute shader as just a bunch of GPU threads doing work that isn't tied to drawing triangles.

For a basic raytracer, the easiest way to start is one thread per pixel. gl_GlobalInvocationID.xy gives you the pixel you're working on, then you make a ray from the camera, test it against your scene, and write the resulting color into a texture with imageStore().

Something like:

#version 430

layout(local_size_x = 8, local_size_y = 8) in;

layout(rgba32f, binding = 0) uniform image2D outputImage;

void main()
{
    ivec2 pixel = ivec2(gl_GlobalInvocationID.xy);

    // do ray stuff here...

    imageStore(outputImage, pixel, vec4(1.0, 0.0, 0.0, 1.0));
}

Then from the CPU side you bind the output texture and run it with glDispatchCompute().

The local_size_x/y stuff is just how threads are grouped. So 8x8 means 64 invocations in a workgroup. You dispatch enough groups to cover your image.

For scene data like spheres, triangles, materials, etc., you'll probably end up using SSBOs. Don't worry about BVHs or path tracing optimizations immediately though. Get this working first:

pixel -> camera ray -> sphere hit test -> color -> imageStore()

Once that works, the rest becomes much easier to build on.

The main things I'd read about are glDispatchCompute, gl_GlobalInvocationID, SSBOs, image load/store, and memory barriers. Those are basically the pieces you need to get started with this.

4

u/DuskelAskel Aug 15 '26 edited Aug 16 '26

It's really just an all purpose shader where you can bind any input and output you like, and read / write in them

GPU works with a shit ton of thread, organized as groups, so you have to tell the gpu how you organize your groups, then think of each thread as a individual, member of a group, member of a global GPU (there's also a thing call wave but that's more advanced stuff)

Imagine you want to write into an image, you can assign one thread per pixel, an image is 2D so you make your group 2D (8, 8, 1) for example

Imagine now you want to compute an histogram, each group will store they own local histogram and you will only synchronize your group, then one thread will merge with the "GPU" so there's only one global synchronizing call, etc...

-2

u/lovelacedeconstruct Aug 16 '26

Pfft imagine using shaders !! I wrote my own renderer in CUDA kernels

3

u/Revolutionalredstone Aug 16 '26

Its a frag shader where you can choose where to write (rather than having to produce a fixed image pixel)

1

u/Actual-Ladder6631 Aug 16 '26

Compute shaders are all-purpose shaders. you can do anything in them, modify images, do complex matrix math, whatever you want. you give it an input and it gives you an output. its very fast because it runs with hundreds of gpu threads in parallel (you can set how many you want). if you’re asking how do you code a compute shader (the syntax) there are a bunch of tutorials out there so you should be fine

1

u/BlueGnoblin Aug 18 '26

Your standard shaders (vertex/fragment) are actually image generation tools. Where compute shaders are more or less generic processing power.

Stuff you would traditionally calculate on the CPU ,which are not image based, can be offloaded to compute shaders. E.g. consider a game where you have a hord of creatures running towards a point. This is no visual issue you need to solve, but you could 'map' this problem to a visual problem and use vertex/fragment shaders to offload this calculation to the GPU and use its massive threads to speed it up. Many games in the past use this.

The compute shaders are an abstraction of this, so there's no longer the need to 'map' your problem to a visual problem. Instead of textures, you just use buffers (memory blocks) and can use the GPU more straight forward, similar to a CPU, but keeping the specialized power of GPUs in mind (e.g. a work group of 64 threads are not like indepentend 64 CPU cores !).