Deferred Shading Progress

Hey Folks! Hope everyone had a good weekend, and Turkey Day if you celebrate that. We were fortunate enough to have friends invite us to their parents' house for dinner, which recharged our social/family stats, so to speak.

The time away also seems to have helped refresh the old brain. I think I'm starting to get somewhere with Unity's rendering pipeline, and a better understanding of it.

In today's image, we see a field of random walls (light brown blocks) on floor (dark brown), and the gray area represents line of sight from a "corridor" in the middle. One of the big improvements since last week is the texture coordinates: they now line-up with the rest of the scene, so the gray area appears to move around "lighting up" the floor tiles. It turns out Unity has a few helper functions exactly for this sort of thing: UnityObjectToClipPos() and ComputeScreenPos().

I also pored over the docs a bit and now have a better understanding of how vertex info is passed to fragment shaders, and how fragment shaders get used in the final render. Not 100% yet, mind you, but I'm starting to be able to wield this thing.

And the results are still promising. As you can see in the top right, we're rendering this view at a solid 66fps, even with the line of sight mesh running off-screen and intersecting with 100s of more blocks there. Granted, this is only 640x360 (360p), but I'm sort of thinking that'll be the target res for the game, with a higher res UI rendered over it for text, menus, etc. 360 nicely fits into 720p (2x), 1080p (3x), and 4K screens (6x). Even 1440 vertical can be easy to fit (4x360), and it's why a lot of pixel art games are using that as a standard. (Either with or without custom UI resolution atop it.)

For reference, here's a 360p mockup I created using Emily's tile art and native (360p) UI:


It's scaled-up for the website, but there are only 360 pixels from top to bottom in the original image. I could probably squeeze most of the UI into that, judging by the mockup. But I know from NEO Scavenger that's a risk.

Anyway, the next step would be to render light "fans" in the scene. Each light would be a mesh a lot like what I'm doing here for line of sight. Except instead of gray normal maps in the mesh, it'll render the lit sprite. Then, the final scene render will render each light like that, add up the brightnesses from each, and create a final lit scene. And I'll likely use this same line of sight trick to mask out parts of the scene the player can't see.

I think this will look pretty nice if I can get it to work. And if performance holds up...celebration time?

Tags: Ostranauts