Tile by tile lighting light wont change from white?

Avoid setting your reused colour to a static one… You should just make your own and set it to red, rather than manipulating the static (final) colour instance.

If you want the tiles to be tinted, you’ll either have to tint the image via sprite batch’s setColor method, and draw the sprite, rather than drawing something on top of the sprite.

The coloured outer bits are intentional in my pseudocode as you can see in this image:

I’m glad to see you got the lerp with the light colour and shadow working though!

So how does the math work?

The math for…?

Okay, let’s give it a try. :slight_smile:

For this whole lighting computation thingy to work, you must have at least a very basic understanding of linear functions, because in the simplest of cases, your light’s intensity/brightness at any tile is a linear function of the tile’s distance to a light source. (In reality however it is not a linear function, but we will leave that aside for a moment.)

It first helps if you think about your lights and tiles this way:

  • your tiles are initially completely dark (when there is no light source in the scene)
  • your tiles have color attenuation factors for RGB channels (their RGB color, given via their texture)
  • this attenuation factor is also called the “albedo” of your tile surfaces (i.e. the factor for each of the RGB channels that gives how much of the incoming light gets reflected back off that tile)
  • this albedo factor is between 0.0 and 1.0 for each of the RGB channels
  • now think that each light source emits some light on a tile, based on the distance between the tile and that light source
  • the light’s strength is not bound by any constant (i.e. it is not necessarily between 0.0 and 1.0, though it helps to avoid having to do tone mapping)
  • also think that once light reaches a tile, it gets weakened by the mentioned albedo factor of the tile
  • weakening the incoming light then only means multiplying the incoming light by the tile’s albedo factor (i.e. sampling your texture and multiplying that with the light’s contribution)
  • multiple lights in the scene “add up!” (i.e. their contributions linearly sum together) and the albedo attenuation can happen afterwards (this is because multiplication is distributive over addition!)

What’s left now is to compute the light’s contribution with respect to a given tile:

Using a linear function, the intensity/contribution ‘I’ of light ‘l’ on tile ‘t’ can be expressed as:
I(l, t) = a * d(l, t) + b
where

  • a is some negative constant factor less than zero
  • b is some positive constant greater than zero
  • d() is a measure, like the euclidean distance function (you know, that sqrt(x² + y²))

a then gives you the “slope” of that linear function (i.e. how fast the brightness decreases the greater the distance between tile and light becomes).
b gives you the brightness at the light’s center.

If you now want your tiles to be completely dark when they are at least 5 units away from a particular light source, and you want the light to have brightness 1 at its center, you would need the constants a = -0.2 and b = 1.0.
This will give you a linear attenuation of the light’s contribution to a tile over your scene.

I hope that made it a little bit clearer. :slight_smile:

That was a really good explanation KaiHH!

[quote](In reality however it is not a linear function, but we will leave that aside for a moment.)
[/quote]
Correct. In OP’s images, he’s obviously using a linear function but in my image I’m not (the “middle” part of a light source is much clearer than the edges). The formula for mine is (WARNING doesn’t make sense):


float threshold = 0.7f;
alpha >= threshold ? return ((alpha - threshold) * (1f / (1 - threshold)) + (1f - threshold) : return ((alpha - (1 - threshold)) * (1 / 1 - (alpha - (1 - threshold))) * (1f - threshold))

I should probably redo my formula…

EDIT: formula re-done! Help from my friend was used.


// this is the threshold where it becomes more dark faster
float threshold = 0.7f;
float thresholdInverse = 1f - threshold;
		
// simple linear formula
float linear = alpha * threshold;
		
// square alpha
float square = ((float) Math.pow(alpha, 2));
// essentially the same as adding itself multiplied by thresholdInverse
square *= (1 + thresholdInverse);
// subtract a bit so it doesn't become totally pitch black too early on
square -= (thresholdInverse / 2);
		
if (alpha >= threshold) {
	return square;
} else {
	return linear;
}