How we visualized signal waves in Echo
Hi everyone! I decided to write a small post about the things I learned while implementing a shadow and signal occlusion for our bat-themed puzzle game.
Before this jam I've never dealt with 2D lighting systems so the task was new to me - I needed to make a circular wave and a point light that can be occluded by the environment around the player, specifically tiles and props (like columns). Luckily after a bit of digging I found this great post about a dynamic 2D lighting system in GameMaker.
The idea of using diagonal quads and moving their marked vertices away from the light source in the vertex shader was exactly what I needed. However since I needed shadows for multiple purposes I didn't use the depth test, instead rendering them into the first channel of the RG8 shadow mask texture. The second channel is then used for color information to make the colored glass mechanic possible.
I then wrote a simple shader that multiplied the shadow mask, the preset color based on the information from the second channel and the texture output together. This same shader is used to render both the player light and any of the signal waves.
Of course, the next challenge was that I couldn't just fill the entire scene into one vertex buffer for shadow and color calculations at the start of the scene and reuse it, because of doors that can be opened or closed dynamically. So those are writted to a dedicated vertex buffer that is updated every time any door changes it's state. The rest of the scene is static and is recorded into vertex buffers at the start of a new level.
Wave objects get initialized with a shadow mask texture upon creation, which is copied from the player's own shadow map (or rendered from the point of view of the reverb statue). These maps are then redrawn in response to any change in the dynamic geometry.
On the gif the opacity of the objects is lowered so you can see what's happening behind them. You'll notice especially in debug color view that colored glass doesn't exibit the same "triangle artifacts" that the shadow casters have. This was necessary to fix since the glass is a bit transparent in the game itself and was achieved simply by adding another quad to the vertex buffer that matched the glass sprite shape and has no vertices marked for move in the vertex shader.
And that's pretty much it, not a perfect system, but it works well enough for the levels we designed. I wanted to do some filtering on the mask so that aliasing would be less noticeable but unfortunately any blurring makes the tips of the shadow quads peak out from under the tiles in a distracting way and the quads can't be offset further into the tile because this introduces holes in the coverage. I'll have to think of some alternative approach that hopefully will still let us use the tiles for walls.
Hopefully some of you found this useful!
We'll be very grateful if you check the game out here https://ldjam.com/events/ludum-dare/59/echo-2
