Tile by tile lighting light wont change from white?

Am i doing this a complicated way? if so how do improve this?

What color is ‘sunlight’ in the above example?

public LightEngine(OrthographicCamera camera, SpriteBatch spriteBatch) {
		Pixmap tilePixel = new Pixmap(1, 1, Format.RGB888);
		tilePixel.setColor(new Color(0, 0, 0, 0));
		tilePixel.fill();
		pixelTexture = new Texture(tilePixel);

		sunlight = new Color(0f, 0f, 0f, 0f);
		this.camera = camera;
		this.spriteBatch = spriteBatch;
	}

If ‘sunlight’ is [ 0 0 0 0 ], then won’t the final color always be [ 0 0 0 0 ]? Is that what you want?

Even if i change it to [1,1,1,1] there is no change?

http://giant.gfycat.com/LavishSpanishIrishsetter.gif

to mix colors in my program I add the color values of all neighboring tiles and then divide by a constant.

Looks really cool dude

Could you show me your mix colour code and example on how you do your lighting

I remain uncertain about the method you’re using, but as for the immediate problem, here are two suggestions. First, in this line:

spriteBatch.setColor(tileColor);

Try temporarily changing the color to a known, fixed value of your choosing (e.g. purple), just to make sure the color is actually having an effect and that the problem isn’t later in the rendering process.

If that doesn’t tell you anything, then in this code (or whatever it looks like now):

Color tileColor = Color.WHITE;
tileColor = Utils.mixColours(tileColor, Color.WHITE, tileBrightness);
tileColor = Utils.mixColours(tileColor, Color.BLACK, sunlight.a);

Use either the debugger or debug output to see if, at the end of this code, ‘tileColor’ has the value you expect it to have.

(The optimal solution may just be to take a different approach, as others are suggesting, but it might still be useful to understand why your current code isn’t working as you expect.)


	      r = 0;
			g = 0;
			b = 0;
			intensity = 1f;
			if (north != null) {
				r += north.r * north.intensity / (damp + elevation);
				g += north.g * north.intensity / (damp + elevation);
				b += north.b * north.intensity / (damp + elevation);

			}

			if (south != null) {
				r += south.r * south.intensity / (damp + elevation);
				g += south.g * south.intensity / (damp + elevation);
				b += south.b * south.intensity / (damp + elevation);
			}

			if (west != null) {
				r += west.r * west.intensity / (damp + elevation);
				g += west.g * west.intensity / (damp + elevation);
				b += west.b * west.intensity / (damp + elevation);
			}

			if (east != null) {
				r += east.r * east.intensity / (damp + elevation);
				g += east.g * east.intensity / (damp + elevation);
				b += east.b * east.intensity / (damp + elevation);
			}


Damp is the constant I mentioned earlier (Which has to be at least 4) and elevation is something else that isn’t really important.

Notice I reset my color values before this all happens that’s because each tiles does this individually. I don’t have a mixing color class.

edit: And then I limit each value to 1 and 0

The setColor is fine and works as expected but what i am not sure about is my mix colour method and whether i am meant to use transparency and what colour i sould have the pixmap?

my method will not work for you because Im not actually calculating distance from my lights. All of my lighting is created from editing the r,g and b values and editing the intensity of lights. It give me less control over my lights but I get pretty lights plus I can make shadows from the absence of light without any raycasting

Thanks anyway dude i just wish i can work this out…
I tried using color.lerp method but that just makes everything black… ??? ??? ??? ???

package com.hawk.linear.engine.renderer;

import com.badlogic.gdx.graphics.Color;
import com.badlogic.gdx.graphics.OrthographicCamera;
import com.badlogic.gdx.graphics.Pixmap;
import com.badlogic.gdx.graphics.Pixmap.Format;
import com.badlogic.gdx.graphics.Texture;
import com.badlogic.gdx.graphics.g2d.SpriteBatch;
import com.badlogic.gdx.math.Vector2;
import com.badlogic.gdx.utils.Array;
import com.hawk.linear.engine.tile.MasterTile;
import com.hawk.linear.utils.Utils;

public class LightEngine {

	public static final int MAX_LIGHTS = 20;
	private static final float MAX_DISTANCE = 5f;
	public static boolean ENABLED = true;

	private Array<MasterTile> lights;
	private SpriteBatch spriteBatch;
	private Texture pixelTexture;
	private OrthographicCamera camera;

	private Color sunlight;

	public LightEngine(OrthographicCamera camera, SpriteBatch spriteBatch) {
		Pixmap tilePixel = new Pixmap(1, 1, Format.RGB888);
		tilePixel.setColor(new Color(0, 0, 0, 0));
		tilePixel.fill();
		pixelTexture = new Texture(tilePixel);

		sunlight = new Color(1f, 1f, 1f, 1f);
		this.camera = camera;
		this.spriteBatch = spriteBatch;
	}

	public static void setEnabled(boolean e) {
		ENABLED = e;
	}

	public void setSunBrightness(float b) {
		sunlight.a = b;
	}
	public float getSunBrightness() {
		return sunlight.a;
	}
	public void addSunBrightness(float a) {
		sunlight.a += a;
	}
	

	public void setLights(Array<MasterTile> lights) {
		this.lights = lights;
	}

	public Array<MasterTile> getLights() {
		return lights;
	}

	public void render(float delta) {

		if (ENABLED) {
			int camX = (int) (camera.position.x + (MasterTile.TILE_WIDTH / 2) - camera.viewportWidth / 2) / MasterTile.TILE_WIDTH;
			int camY = (int) (camera.position.y + (MasterTile.TILE_HEIGHT / 2) - camera.viewportHeight / 2) / MasterTile.TILE_HEIGHT;
			int camZoomFixX = (int) (((camera.zoom - 1) * 100) / (MasterTile.TILE_WIDTH / 10));
			int camZoomFixY = (int) (((camera.zoom - 1) * 100) / (MasterTile.TILE_WIDTH / 10));
			int offset = 1;

			if (camZoomFixX < 0)
				camZoomFixX = 0;
			if (camZoomFixY < 0)
				camZoomFixY = 0;

			int startX = camX - (camZoomFixX + offset);
			int toX = (camX + TileRenderer.AMOUNT_WIDTH) + (camZoomFixX + offset);
			int startY = camY - (camZoomFixY + offset);
			int toY = (camY + TileRenderer.AMOUNT_HEIGHT) + (camZoomFixY + offset);

			// Lights
			{

				for (int x = startX; x < toX; x++) {
					for (int y = startY; y < toY; y++) {
						if (x < 0 || x > TileRenderer.map.getWidth() - 1 || y < 0 || y > TileRenderer.map.getHeight() - 1)
							continue;

						float tileBrightness = sunlight.a;

						for (int i = 0; i < lights.size; i++) {

							MasterTile tile = lights.get(i);
							if (tile == null)
								continue;
							float distance = Vector2.dst(tile.getX() / MasterTile.TILE_WIDTH, tile.getY() / MasterTile.TILE_HEIGHT, x, y);
							tileBrightness -= Math.max(0, 1 - distance / MAX_DISTANCE);
							

						}
						
						Color tileColor = Color.WHITE;
						tileColor = tileColor.lerp(Color.RED, tileBrightness);
		                tileColor = tileColor.lerp(sunlight, sunlight.a);
		                	                
						spriteBatch.setColor(tileColor);
						spriteBatch.draw(pixelTexture, x * MasterTile.TILE_WIDTH, y * MasterTile.TILE_HEIGHT, MasterTile.TILE_WIDTH, MasterTile.TILE_HEIGHT);
						spriteBatch.setColor(Color.WHITE);

					}
				}
			}
		}
	}

}

I’d suggest you do something like the following:

  1. On paper (literally or figuratively), work out the math for the effect you want. That is, given the input parameters and the output you want, what math will yield that?
  2. Implement the math in your code (this would presumably go where you’re lerp-ing currently).
  3. If the result isn’t what you expect, use the debugger and/or debug output to determine where things are going wrong.
  4. If that doesn’t lead to a solution, post the relevant code, the input values, the expected output values, and the actual output values for us to take a look at.

Maybe you’ll be able to fix it without going through these steps, but if you continue to find yourself stuck, a systematic approach as described above might be a good idea.

Been working on it all morning and have had no luck and i have redone the whole thing…
It doesn’t help when i am not completely sure how the lerp is working but when using my mix method it works perfect other than the fact that i cannot chnage the colour of the lighting

						Color tileColor = sun_light;
						tileColor = tileColor.lerp(new Color(1,1,1,sun_light.a), tileBrightness);
						
		                	                
						spriteBatch.setColor(tileColor);
						spriteBatch.draw(pixelTexture, x * MasterTile.TILE_WIDTH, y * MasterTile.TILE_HEIGHT, MasterTile.TILE_WIDTH, MasterTile.TILE_HEIGHT);
						spriteBatch.setColor(Color.WHITE);
	private Color sun_light = Color.BLACK;

	public LightEngine(OrthographicCamera camera, SpriteBatch spriteBatch) {
		Pixmap tilePixel = new Pixmap(1, 1, Format.RGB888);
		tilePixel.setColor(new Color(1,1,1,0));
		tilePixel.fill();
		pixelTexture = new Texture(tilePixel);
		this.camera = camera;
		this.spriteBatch = spriteBatch;
	}

Result

Well i got the same thing i had working before working using the lerp method but i cannot change the colour of the light still???

:frowning: >:( >:( >:( >:( >:( >:( >:( >:( >:( >:( >:(

				for (int x = startX; x < toX; x++) {
					for (int y = startY; y < toY; y++) {
						if (x < 0 || x > TileRenderer.map.getWidth() - 1 || y < 0 || y > TileRenderer.map.getHeight() - 1)
							continue;

						float tileBrightness = ambient;

						for (int i = 0; i < lights.size; i++) {

							MasterTile tile = lights.get(i);
							if (tile == null)
								continue;
							float distance = Vector2.dst(tile.getX() / MasterTile.TILE_WIDTH, tile.getY() / MasterTile.TILE_HEIGHT, x, y);
							tileBrightness -= Math.max(0, 1 - distance / MAX_DISTANCE);
							

						}
						
						Color tileColor = new Color(0,0,0,0);
						tileColor.lerp(Color.BLACK, tileBrightness);
						
						
		                	                
						spriteBatch.setColor(tileColor);
						spriteBatch.draw(pixelTexture, x * MasterTile.TILE_WIDTH, y * MasterTile.TILE_HEIGHT, MasterTile.TILE_WIDTH, MasterTile.TILE_HEIGHT);
						spriteBatch.setColor(Color.WHITE);

Previously you said that if you change this:

spriteBatch.setColor(tileColor);

To something like this:

spriteBatch.setColor(Color.RED); // Or maybe something with alpha < 1...

It works, and the light is tinted correctly. Is that correct?

If so, that suggests the problem is occurring earlier. In that case, try this. First, temporarily change your loop:

for (int x = startX; x < toX; x++) {
    for (int y = startY; y < toY; y++) {

So it just renders the light for one tile for the time being. That way you can just focus on one tile and its values for the moment, which will simplify debugging.

Then, here’s what you want to find out:

Color tileColor = new Color(0,0,0,0);
tileColor.lerp(Color.BLACK, tileBrightness);
                  
// What is the value of 'tileColor' right here?

spriteBatch.setColor(tileColor);

You can examine the value in the debugger, or print it to the console (here is where having only one tile to deal with will make things easier).

If it’s still not working, post the updated code (making sure we can see what the inputs are), and also post the value you got for ‘tileColor’ from the debugger or debug output.

Maybe the problem is obvious from what you’ve posted so far and someone will point it out. If not though, taking the above steps should help in diagnosing the problem.

One thing I noticed was that your pixmap for the tilePixel was filled transparently. It should be filled with an opaque colour (white). Another thing I noticed was that you’re treating “brightness” and the colour alpha as the exact same thing, but in reality brightness is the inversion of alpha (1.0f - alpha = brightness).

Either you have a new brightness array that keeps track of brightness independently from the colour alpha, or invert alpha when you’re about to render.

In your latest post you make a Color object (you should really just have some reused object that’s not created so often) that is black and then attempt to lerp it… with black?

I’ll try to go step by step what the order should be.


set a brightness variable to the ambient (if it's day, set it to 1) brightness
using a stored colour variable that's not re-created constantly, set it to the ambient colour. ignore alpha for now
loop through the lights
   get the distance away from a light, calculate what the brightness WOULD be
   if the calculated brightness is more than the current brightness, replace it
   lerp your stored colour variable with the light's colour, with a factor of the distance
set the stored colour variable's alpha to the inverse of the brightness (1.0f - brightness)
render the square over the tile

That should work, at least I hope it does. It might be best for you to redo the inner for loop rather than try to fix it. It will be less confusing that way.

set a brightness variable to the ambient (if it’s day, set it to 1) brightness


	private float ambient;

public void setSunBrightness(float b) {
		ambient = b;
	}
	public float getSunBrightness() {
		return ambient;
	}
	public void addSunBrightness(float value) {
		ambient += value;
	}

using a stored colour variable that’s not re-created constantly, set it to the ambient colour. ignore alpha for now

	private Color ambientColour;
	public LightEngine(OrthographicCamera camera, SpriteBatch spriteBatch) {
		Pixmap tilePixel = new Pixmap(1, 1, Format.RGB888);
		tilePixel.setColor(new Color(1,1,1,0));
		tilePixel.fill();
		pixelTexture = new Texture(tilePixel);
		this.camera = camera;
		this.spriteBatch = spriteBatch;
		
		ambientColour = Color.RED; // Here!!!
	}

loop through the lights

						for (int i = 0; i < lights.size; i++) {
}


get the distance away from a light, calculate what the brightness WOULD be



float tileBrightness = 0;
						for (int i = 0; i < lights.size; i++) {

							MasterTile tile = lights.get(i);
							if (tile == null)
								continue;
							float distance = Vector2.dst(tile.getX() / MasterTile.TILE_WIDTH, tile.getY() / MasterTile.TILE_HEIGHT, x, y);
							tileBrightness -= Math.max(0, 1 - distance / MAX_DISTANCE);
							

						}

if the calculated brightness is more than the current brightness, replace it

						float tileBrightness = 0;

						for (int i = 0; i < lights.size; i++) {

							MasterTile tile = lights.get(i);
							if (tile == null)
								continue;
							float distance = Vector2.dst(tile.getX() / MasterTile.TILE_WIDTH, tile.getY() / MasterTile.TILE_HEIGHT, x, y);
							float calBrightness = Math.max(0, 1 - distance / MAX_DISTANCE);
							if(calBrightness > tileBrightness){
								tileBrightness = calBrightness;
							}
							

						}

lerp your stored colour variable with the light’s colour, with a factor of the distance

						float tileBrightness = 0;

						for (int i = 0; i < lights.size; i++) {

							MasterTile tile = lights.get(i);
							if (tile == null)
								continue;
							float distance = Vector2.dst(tile.getX() / MasterTile.TILE_WIDTH, tile.getY() / MasterTile.TILE_HEIGHT, x, y);
							float calBrightness = Math.max(0, 1 - distance / MAX_DISTANCE);
							if(calBrightness > tileBrightness){
								tileBrightness = calBrightness;
							}
							

						}
						
						Color tileColor = new Color(0,0,0,0); // here
						tileColor.lerp(ambientColour, tileBrightness); // here

set the stored colour variable’s alpha to the inverse of the brightness (1.0f - brightness)

						Color tileColor = new Color(0,0,0,0);
						tileColor.lerp(ambientColour, tileBrightness);
						
						ambientColour.a = 1.0f - tileBrightness; // here

render the square over the tile

						spriteBatch.setColor(tileColor);
						spriteBatch.draw(pixelTexture, x * MasterTile.TILE_WIDTH, y * MasterTile.TILE_HEIGHT, MasterTile.TILE_WIDTH, MasterTile.TILE_HEIGHT);
						spriteBatch.setColor(Color.WHITE);

Well it didn’t quite work however i wasn’t expecting this
What could be the problem??
Also can you explain how this works (for future projects)

The problem was the colours didn’t mix

I was expecting a different result where all tiles should be that colour instead of the outer lines

Changed

						float tileBrightness = 0;

						for (int i = 0; i < lights.size; i++) {

							MasterTile tile = lights.get(i);
							if (tile == null)
								continue;
							float distance = Vector2.dst(tile.getX() / MasterTile.TILE_WIDTH, tile.getY() / MasterTile.TILE_HEIGHT, x, y);
							tileBrightness += Math.max(0, 1 - distance / MAX_DISTANCE);
							

						}