Tips on improving a 3D game's lighting?

Phew. Well, first off; apologies this took so long. Life and broken laptops did get in the way for a bit in my defense.

Anyways, without further ado, here’s the final result (that I am quite satisfied with!):

To anyone in future who may find themselves in my position, these tutorials were great in helping me get an understanding of what was going on and how the whole process worked:

1. Reimer’s Shadow Map
2. Reimer’s Render to Texture
3. Reimer’s Real Shadow

I had to tweak the shader quite a bit to get the result I liked, and here’s my resulting Shader code: Pastebin

There were a few issues to its implementation that I’ll cover below just in case anyone has a use for it too:

Before I start the list however, I’d like to say the biggest help for solving some of my Shader issues was to have the direction of the light rotate with the game time. It made it much easier to see which parts of meshes weren’t being affected by the light properly, as they stood out much more with the changing light.

  • Incorrect backface lighting. I have an abundance of planes in my game with no culling (such as the leaves in the trees pictured above). I found that the back of the plane would have inverted lighting on it (which makes sense, as I was asking for the shader to light both sides of the mesh at once). While I’m not sure if it was 100% the right thing to do, I re-added culling, and just did two planes facing outwards instead to solve the issue.

  • Weird diffuse lighting. This one took me the longest to solve, and the issue looked like this:

In the end, it had turned out that I had accidentally applied my diffuse calculations twice. Once when the shader detected that a specific pixel wasn’t covered by the shade, and once universally afterwards (rookie mistake, but for my second shader, not too bad).

  • Awkward looking shadows for complex meshes. Due to my shadow map being downscaled, complex meshes ended up having a lot of awkward pixels in the shadows they cast. This was solved by using a technique I learned from Smash Bros. I added much lower resolution meshes for those cases, which would be used to cast the shadow instead (while the main technique still rendered the high resolution model).

  • Z-fighting shadows. These occurred when perfectly vertical planes (like the grass edge in the picture above) would cast and receive shadows from themselves. I’ve simply disabled shadow casting (but not receiving) on those cases to solve this. I imagine it would also be possible to automatically detect and disable shadows with the shader itself (detecting vertical planes based on normals), but the method I’m using at the moment works fine for me.

There we are! I’m sure most of what I’ve said you already know (I hope at the very least what I wrote wasn’t misguided O_O). I hope maybe someone else will have a use for it someday though!

Thanks for the help everyone!

2 Likes