2011
09.09

## Lights in full color roguelikes

So long I’ve always used a very basic light model in my prototypes. For a point light at position lx,ly, the light reaching position x,y is :
```int squaredDist = (lx-x)*(lx-x)+(ly-y)*(ly-y); double intensityCoef = 1.0-squaredDist/(radius*radius); ```
The formula makes the intensity value 1.0 at light position and 0.0 at distance radius from the light.

It’s very fast (especially since 1.0/(radius*radius) can be precomputed) but doesn’t produce very good looking lights : The intensity decreases linearly and seems to end abruptly at the light range.

A more realistic approach is to use the inverse square law. The light intensity decreases proportionnally to the inverse of square distance :

```int squaredDist = (lx-x)*(lx-x)+(ly-y)*(ly-y); double intensityCoef = 1.0/(1.0+squaredDist); ``` There are several issues with this naive approach :

• The intensity decreases very rapidely. This forces us to have huge light radius, which impacts performances
• The intensity doesn’t reach 0. At the light radius, it’s still 1.0/(1.0+radius*radius) and it drop abruptly to 0 after.

We can easily fix both issues. First we scale down the distance to keep the intensity from dropping too fast :
```double intensityCoef1 = 1.0/(1.0+squaredDist/20); ```
Then we subtract the remaining intensity at radius range so that it reaches 0 :
```double intensityCoef2 = intensityCoef1 - 1.0/(1.0+radius*radius); ```
The issue is that intensity at light position is no more 1.0 but 1.0 – 1.0/(1.0+radius*radius), which results is less bright lights.
To fix that, we scale the final intensity :
```double intensityCoef3 = intensityCoef2 / (1.0 - 1.0/(1.0+radius*radius)); ``` 