Disclaimer

For Non-Engineers: The goal of this blog is to be layman-friendly so any feedback about anything confusing or unclear is valuable and appreciated. I am currently working on a way to allow those without a Github account to provide feedback at the end of the article.

For Engineers: This is still a subject I am actively learning about so feel free to leave a comment with corrections or suggestions if you have any.

Last time we talked about what god rays are and some ways that video games try to emulate them. Today I’ll be documenting my progress as I attempt to implement a version of the approach detailed here. Giant shout out to Cyanilux’s blog and t3ssel8r’s video on the topic for the inspiration.

For Developers

I will be creating this effect in my game The Far Reaches using 4.3 Beta 1 build of the Godot open source engine. This may leverage some of the features strictly available to that version so if you’re following along as a developer please bear that in mind.

Implementation

To kick things off, I quickly threw together a basic scene to work with and add our god rays to.

Caption

Basic Scene

Adding Quads

Let’s jump back to what I said last time. To quickly reiterate:

The first step is to place our quads in our scene where we would like the rays to be and set them to act as billboards. This means the quad will always face the camera regardless of how the camera moves.

Sound like we need some squares. Let’s place a few quads throughout our scene and uhhh…

Caption

Some Quads

Those quads certainly don’t look like they’re facing the camera. Let’s try to remedy that with a shader that transforms our quads such that they remain facing the camera.

Applying the shader seems to have given us the billboard effect that we were looking for!

Caption

Billboarding Effect

Stretching Towards the Light

Now we have a bunch of squares but they’re not really looking like heavenly rays yet. Let’s jump into this next little bit that I mentioned last time:

Then we use a vertex shader to stretch the upper parts of the quad towards our light source. This creates the effect of a quadrilateral shape stretching from its base towards the sun.

The trick here is that we need to only have the upper parts of the quad stretching. This way the base of the quads can remain firmly planted where we placed them in our scene. We need two things to do this: the direction towards our sun or light source and an amount to stretch by.

Then we can simply move the vertices along that direction by that amount.

With just a couple lines of code, our little quads are starting to look a bit more beam-like!

Caption

Stretched Quads

Modulating the Alpha

“Modulating the Alpha” sounds like a bit of Magic: The Gathering card text but the reality is much more mundane. What we mean here is that we want to change (modulate) the transparency (the alpha component of our color) of our rays based on several factors. Those factors include:

Scene Depth

The closer a ray is to an object, the less we want the ray to obscure that object. This can be accomplished using what’s called a depth buffer. Depth buffers are just images that store how far away each pixel is from the camera.

We can take a look at how far away our ray is from the screen and then compare it against how far away the rest of the scene is. The closer they are together, the smaller the alpha value we want so long as the ray is in front of the scene.

A lot of words here but basically: the closer our ray is to something, the less visible it should be.

I took this as an opportunity to widen the quads slightly and the results are a huge step in the right direction:

Caption

Alpha Modulation - Scene Depth

Camera Position

We want rays to dissipate as our camera nears them as to avoid blocking our view of the scene. Similar to how we achieved Scene Depth modulation, we can choose a distance at which we would like the the rays to start dissipating and compare the ray’s depth against it.

The rays should then become more transparent the closer they get to the camera.

Caption

Alpha Modulation - Camera Distance

Shadow Map

I mentioned shadow maps in my last post but to reiterate, shadow maps allow us to check if a position in the world is in shadow or not. I won’t delve too far into how shadow maps are generated but suffice to say that they are incredibly useful for anything involving shadows as the name suggests.

If a ray is in shadow, we want it to be invisible; we can use the shadow map of our sun to identify what parts of our ray are in shadows and change the transparency accordingly to achieve this.

And there we go! Now we have these very satisfying sections of the ray that get blocked by objects in our game. I can’t wait to try this out later in a scene with lots of trees and foliage.

Caption

Alpha Modulation - Shadow Mapping

Finishing Touches

Now comes the exciting part! Theoretically we just multiply all of the alpha values we created in the previous sections together and…

Caption

All Together

It’s looking pretty good for what was at one point just a bunch of white squares. I still think we can do just a little better.

Adding Noise

Let’s give the rays a more stripe-like quality. We can do this by once again by modulating the alpha. We’re going to use something called a noise texture which is basically just a way of getting random values.

A useful type of noise for this is a type called gradient noise where the various points along the noise make a smooth gradient. A common choice for gradient noise is a type of noise called perlin noise. It looks like:

Caption

Perlin Noise

By sampling values along single direction we can get a stripe-like pattern that we can use to modulate the rays’ alphas along their cross-axis.

Caption

Stripes

Better yet, we can also move our sample up and down the noise texture to get the impression of the stripes moving.

Caption

Moving Stripes

Let’s just quickly change the color of our quads to make our rays take on a more golden hue as well and that’s looking pretty good!

Caption

The Result

Conclusion

I think that marks a good stopping point for now although there’s plenty of room for improvement. For one, I would like it if the rays moved as though clouds int atmosphere were affecting them.

Additionally, I might do a post about implementing a dynamic weather system that utilizes these rays. For now we’ve covered the core components that go into achieving this stylistic form of god rays and I hope you learned something with me. And, hey, at the very least it was cool to go from this…

Caption

…to this!

Caption

As always please leave a comment below if anything was confusing or if I got some information wrong so I can clarify / correct any mistakes. Also feel free to let me know what you think, offer advice or tell me what topics you’d like me to try to tackle!

Take care and see you soon!

— Carson


Resources