Rendering Questions

Hey Folks! Hope everyone had a good weekend. A lot of nice weather, family time, and Battletech on mine. Plus, I finally saw Blade Runner 2049. (Yes, I consume media with considerable lag.)

As mentioned last week, I'm currently chewing on some graphics/rendering quandaries raised by Amandine's tech assessment. Emily is ready to start making more art assets, and ship pieces seems like the next logical step. But the current rendering setup isn't going to cut it in the wild, particularly as ships (and stations) get bigger and/or players with aging PCs try to sling those pixels around. So I don't want to send her down the wrong path making art in one style only to discover it needed different rules.

That's where today's image comes in. What we see today is a collage showing a few investigations I have going in parallel.

On the top is a mockup I'm trying out at 360p. You heard that right. One of the tricks pixel art games are using lately is to design the art around a 640x360 resolution, and then scale that up when it comes time to display on different monitors. The magic behind that number is that you get pixel-perfect zoom at many standard screen sizes:

2x zoom = 720p
3x zoom = 1080p
4x zoom = 2560x1440
6x zoom = 3840x2160 (a.k.a. "4k")

In other words, this basically can work on any modern display with either perfect scaling and negligible black bars, or scaling so nearly perfect that the user barely sees the anti-aliasing.

Of course, that's a pretty tight screen. And if the game has a lot of text, it can get crowded fast. And part of that mockup at the top is to see whether it's too tight to be legible. Currently, it just barely fits. Might work, might not.

Alternatively, Amandine points out that most games (even AAA ones) tend to get around this by rendering the game like described above, then rendering a separate UI on top of it at a higher res. Going too far can make things look inconsistent. But there are definitely games doing this. Into the Breach being one of the more recent examples.

Anyway, part of my homework is to figure out a resolution and upscaling strategy.

My other homework is to look into alternative lighting systems. Currently, I use Unity's vanilla point lights and standard shaders to do normal mapped sprites with real-time shadow maps. This is good because it's pretty, it's easy, and it's well-supported.

However, this is bad because it gets expensive fast. Like, systems will start bogging-down above 3-6 light sources. And if you look at Emily's beautiful ship mockup above, there are probably 10 just in that section of the screen. And if the UI weren't there, we'd be approaching 20. For a ship with a hallway and 4 rooms, let alone a large ship or station.

One option is to just avoid shadows. You wouldn't be able to get Emily's pretty mood lighting (it would spill over to other rooms), but it'd probably work in most cases. I might be able to improve upon this by using so-called "cookie cutter lights," which are just masks that define which areas around the light get lit. I could, for example, make a cookie-cutter that fans out in a semi-circle, or even a 90-degree arc for a corner light. But the player would be expected to choose appropriate lights for each space.

Another option is to limit the number of active lights to only the nearest few. E.g. walls and people don't get lit by every light around them, just the strongest 3-4. A lot of older games did this, and again, it might be passable.

However, Amandine pointed out that this might be doable using a custom renderer/shader that does what 3D does, just in 2D. It's faster, and uniquely suited to a top-down scene like mine. The bottom two images show some examples of this at work. The lower left using an off-the-shelf system from Unity (Light2D), and the lower right using a 1D Shadow Map technique cribbed from gamasutra.

Both make significant use of the GPU to allow for many lights and many shadow casters with little performance cost. The question is, can I use it in my game? Will it work as advertised? Can I customize it to match my game's style?

Those questions are still ongoing :)