Black Hole Shader Tutorial

1.png

*Smooth youtube edutainment narrator voice*

Quite a few people have asked us "How did you do the black hole effect in Godot?". Well, here it is.

The black hole shader is actually quite simple at its very core, but there are a lot of details to pay attention to. We'll cover some of the things we did for our game.

To make ours, we followed this tutorial for Unity. Here's the link if you want to read through it.

Basically, the shader only does the following: - Take the camera view from behind the the mesh and flip it upside down. - Draw a black hole in the middle.

That's it.

So lets get started.

Setting up the Environment

Start with an empty scene and add a world environment. Without this, you won't be able to see the distortion. 2.png We'll just load ours. 3.png Once you're done with that, throw a sphere in the middle. This will be our black hole. 4.png For this tutorial, we'll make a visual shader, but you should be able to easily replicate this in code. Visual shaders are just a bit more accessible to everyone. So create a new shader material, create a visual shader for it, and set it to VisualShader. 5.png Once that's all done, set shader flag Unshaded to true 8.png We'll now proceed in the visual editor.

Flip Effect

Let's do the flip effect. Hooking these two nodes together will make the sphere invisible by redrawing what's behind it on top of it. 9.png This sequence of nodes will apply the flip with heavy distortion along the edges. 10.png We now need to smooth out the edges to make it less jarring.

Godot now has a Fresnel node, which makes this extremely easy compared to previous versions.

These nodes essentially shade the edges of our sphere. 11.png You can see this by hooking it straight to the albedo output. 12.png Changing the power values in the fresnel and the floatop will change the look of the fade, experiment later to see what works best for you. For our game, we hooked the fresnel output to a shader parameter. 13.png Adding a multiply before adding to the screen UV lets us gently ease into the flipped look.

And with that, the flip effect is done. 14.png

The Black Hole

The black hole is incredibly simple. All we want to do is to black out the middle of the sphere. And for that, we already have a fresnel effect. 15.png if we multiply the fresnel, we can adjust the size of the black hole. and by rounding, we'll send it to either 0 or 1. Again, we can preview by hooking it up to the albedo. Increasing the multiplication factor (which we've hooked up to a FloatParameter) will decrease the proportional size of the black hole. 16.png Finally, if we multiply the end results of our two branches together, we'll have a black hole! 17.png

Caveats

Once that's all done, you can throw on an accretion disk mesh and you have a cool looking black hole! 18.png But watch out! Due to how the shader works, there are some limitations.

Do not enter the black hole

Entering the black hole will make everything disappear. 19.png For our game, we added a script which would detect if the camera was inside the black hole or not, and swap out the shaders. (Due to how Godot works, it will recompile the shaders on run time, you'll notice the first time you get close to the black hole in our game, it will lag briefly)

Transparency

Due to how transparent objects are shaded (after everything else), the distortion effect will not render them. 20.png The solution is to change the draw order of things to have the black hole last, but the fastest way we found was just to apply alpha scissor to our transparent objects and deal with the sad looking edges. 21.png

Things in front of the black hole

Things in front of the black hole also render funny, since it just does a screen space warp. 22.png It's possible to fix this by being clever with the draw order, but in our game, we just made sure the camera was never in an angle that would let you see any of these glitches.

Summary

There are many ways that you could customise the behaviour of this shader, many of which we would've loved to have put into our game, but alas, we ran out of time.

So, happy programming, it would be nice to see this out in the wild, perhaps in future game jams? :smiley:

We hope this was useful, and sorry for taking up so much space with this looooong blog post.

Play "Out of Spacetime" in Browser on itch.io!

23.png