Laserbrain Studios

Games Forum Blog Contact

Author Topic: Improved lighting technique  (Read 1480 times)

Christian Knudsen

  • Administrator
  • Ace
  • *****
  • Posts: 3014
    • View Profile
Improved lighting technique
« on: June 09, 2014, 01:31:56 PM »

There have been a bunch of improvements to Hostile Takeover‘s visuals in the past year. I’ve upped the graphics from 24-bit to 32-bit, since it seemed more and more silly to sacrifice visuals for better performance on low-end computers. And I also abandoned the older, more retro UI in favor of a somewhat more modern and less obtrusive design.


But one of the changes that took the longest to implement was the new and improved lighting system. Not because it’s all that complex, but because it took some tinkering and experimentation to figure out how to do it right. So that’s what I want to talk about in this blog post.


In the below image, you can see the 3 levels of lighting quality that you can set in the game’s options menu. These 3 levels represent the lighting system as it has progressed since I first started working on the game. Instead of just using the highest quality in the game and scrapping the older versions of the system, I decided to allow players to set the lighting quality in the game, since on older computers, lowering the quality can improve frame rate slightly.


The 3 levels of lighting quality


The quality 1 lighting just considers the lighting level of a single tile. The floor sprites have the level of lighting of the tile they’re on, and the wall sprites the tile they’re facing.


With quality 2 (which is what was available in the old releases of the game), the lighting is smoothed between adjacent floor and wall sprites. To achieve this smoothed effect, I use vertex coloring. In OpenGL, vertices are basically the corners of the texture you’re drawing to screen. So when drawing a floor or wall sprite to screen, they’re drawn as rectangles (‘quads’ in OpenGL) and therefor each have 4 vertices:


A floor sprite A wall sprite


When drawing one of these sprites to screen, I can tell OpenGL how light or dark each corner of the sprite should be, and OpenGL then smoothes out the light level across the entire sprite and between the corners. To make adjacent floor and wall sprites blend more into each other, I set the light levels of the corners to be an average of the sprites that share that corner.


This works fairly well and certainly gives smoother lighting than for lighting quality 1. It’s not perfect, however, and as you can see in the comparison image, there are still some hard edges between the individual floor and wall sprites. The reason for this is that the corners of the actual floor and wall images don’t line up with the corners of the sprite. The floor is diamond shaped, while the texture is a rectangle. And because of the isometric perspective, the corners of the actual walls don’t line up with the corners of the sprites either. To fix this, I split the sprites into sub-sprites when drawing them to screen:


A floor sprite divided into sub-sprites A wall sprite divided into sub-sprites


This gives me sprite corners that line up with (some) of the floor and wall corners. And since the floor and wall corners now line up with the sprite’s corners, the vertex coloring makes the smooth lighting match up better between adjacent floors and walls. As a result, the transition between adjacent floors and walls is practically seamless. Here’s how the corners of a wall’s sub-sprites matches up perfectly with the corners of an adjacent wall’s sub-sprites:


Sub-sprite corners lining up perfectly


I’m really pleased with this system — not least because I’m now getting almost perfectly smooth lighting without any use of shaders or other more demanding methods.



Benedikt S. Vogler

  • Guest
Re: Improved lighting technique
« Reply #1 on: June 09, 2014, 06:25:49 PM »
Thanks for sharing some tech details :-)

Christian Knudsen

  • Administrator
  • Ace
  • *****
  • Posts: 3014
    • View Profile
Re: Improved lighting technique
« Reply #2 on: June 10, 2014, 10:24:10 AM »
No sweat. Hope it's helpful!

GLI

  • Hidden Asset Alpha Tester
  • Ace
  • *****
  • Posts: 1138
    • View Profile
Re: Improved lighting technique
« Reply #3 on: June 11, 2014, 10:58:57 AM »
I’m really pleased with this system — not least because I’m now getting almost perfectly smooth lighting without any use of shaders or other more demanding methods.

Well... How about shadows that depends on direction of light source and distance from it?

This guy isn't standing directly under street lamp but his shadow suggests such situation. I mean that "long shadows" can warn e.g. guards that somebody is hiding after some obstacle:
Laying down - short shadow
Crouching - medium shadow
Standing - long shadow
Genuine Lifelike Individual

Christian Knudsen

  • Administrator
  • Ace
  • *****
  • Posts: 3014
    • View Profile
Re: Improved lighting technique
« Reply #4 on: June 11, 2014, 12:15:44 PM »
Implementing shadows that vary in length with distance to light sources would be a lot of work to implement in 2D. It could probably be done by having a set of long directional shadows for each character animation frame. I could then squash these shadow sprites to make them smaller when getting closer to the light source.

The big problem is that I'd run into issues with cast shadows clipping under objects and walls instead of being cast on the walls/objects themselves. With the shadows as they are now -- always right beneath the character -- there's no risk of this happening. To get accurate shadows, I'd have to switch to full 3D.

Besides, I don't think it'd be worth the effort. It would probably be quite annoying to not only have to worry about yourself being behind cover, but your shadow as well.