Tile by tile lighting how would i do this

Here is my code

private Color getLightBrightness(List<MasterTile> lights,Color current, MasterTile tile){
		Color brightNess = current;
		int n = 1 - 0 + 1;
		
		Vector2 tileCoords = new Vector2(tile.getX()/MasterTile.TILE_WIDTH,tile.getY()/MasterTile.TILE_HEIGHT);
		for(int i = 0;i < lights.size();i++){
			MasterTile t = lights.get(i);
			float distance =  tileCoords.dst(t.getX()/MasterTile.TILE_WIDTH, t.getY()/MasterTile.TILE_HEIGHT);
			distance %= n;
			System.out.println(distance);
			//Utils.mixColours(current, LIGHT, distance);
		}
		
		
		return brightNess;
	}

Here is what i am trying to do

How would i do this with a shader? examples?

I am going for this effect

I’d make light brightness (1f to 0f) be the value (in the HSV color model) of the tile’s texture (if you want to have brighter lights than 1f, I’d use Math.max(light.brightness, 1f)). Normal light source with brightness 1f would have a reach of, for example, 5 tiles. You’d then divide the brightness of the light by the distance from the light source.

PS: I’m too lazy to write it in a shader or a program, but if you wish, I can write it in pseudo-code.
PPS: Please, only one post. If you want to expand your post, edit the original one, don’t reply to it. Thank you.

I am not completely sure what you mean?
:confused:

MrPizzaCake means use the light brightness as the brightness value in the HSB (not HSV!) colour model. HSB stands for hue, saturation, and brightness. Then in order to get the brightness of a tile, you would take its position from a light source (perhaps the nearest source since it’ll have the most effect) and take the light source’s brightness and divide it by the distance away and that’s the tile’s brightness.

Personally how I do it is by overlaying a shadow on top of the tile which is the “darkness” of each block. I have to use a shader to mask the lightmap onto the terrain so it doesn’t cover the background.

You can see how I do it more in depth here. Note that it seems a bit more complex but can make really good looking effects.

Sorry, I often get 'em confused :stuck_out_tongue:

As i can see, it’s my lighting effect youre looking for :smiley:

well its pretty simple, albeit limited. no shaders or raycasting involved, it is just a floodfill algorithm tweaked to fit my tile system.

http://www.java-gaming.org/index.php?topic=26363.0 is the article (last post) that got me somewhere after months of headaches, though you will have to find a way to make it work with your system. I used to algorithm from before he rounded off so it keeps the retro look.

My code looks something like this just so you can see what an example of a system implemented version would be(more complex things since i also have color lighting and a separate array for light tiles)

public void applyLightRec(int x, int y, int lastLight, int xt, int yt, int r, int g, int b, int alph) {
			int x1 = (int) (xt + ( TritonForge.pixel.width / TileArt.tileSize) + 2);
			int y1 = (int) (yt + ( TritonForge.pixel.height / TileArt.tileSize) + 2);
			if (x < xt-10 || x > x1+10)return;
			if (y < yt-10 || y > y1+10)return;
			int newLight = lastLight+getLightBlockingAmmountAt(x, y);
			if (newLight >= getLight(x, y)) return;
			
			Light u = light[x][y-1];
			Light d = light[x][y+1];
			Light ri = light[x+1][y];
			Light l = light[x-1][y];
			
			light[x][y].r = r;
			light[x][y].gr = g;
			light[x][y].b = b;
			light[x][y].alph = alph;
			light[x][y].lighting = newLight;
			Color col = new Color(r,g,b,alph);
			Color col1 = new Color(u.r,u.gr,u.b,u.alph);
			Color col2 = new Color(ri.r,ri.gr,ri.b,ri.alph);
			Color col3 = new Color(d.r,d.gr,d.b,d.alph);
			Color col4 = new Color(l.r,l.gr,l.b,l.alph);
			Color new1 = blend(col,col1);
			Color new2 = blend(col,col2);
			Color new3 = blend(col,col3);
			Color new4 = blend(col,col4);
			applyLightRec(x+1, y, newLight, xt, yt,new1.getRed(),new1.getGreen(),new1.getBlue(), new1.getAlpha());
			applyLightRec(x, y+1, newLight, xt, yt,new3.getRed(),new3.getGreen(),new3.getBlue(), new3.getAlpha());
			applyLightRec(x-1, y, newLight, xt, yt,new4.getRed(),new4.getGreen(),new4.getBlue(), new4.getAlpha());
			applyLightRec(x, y-1, newLight, xt, yt,new2.getRed(),new2.getGreen(),new2.getBlue(), new2.getAlpha());
		}

Best of luck

Actually, that’s pretty much identical to mine. It’s recursive and has a diamond shape. The shape OP is looking for is rounded.

Yours does look a lot simpler than mine programmatically :stuck_out_tongue:

Well there is a rounded version in the thread i linked him to

Ah, I overlooked that as I skimmed the post. Sorry!

Also this is more related to your code TritonDreyja, but I don’t really think you should be creating a new Color object for every recursion of the lighting update. Maybe store a bunch of shared Color objects that you can re-use over and over (I had to use around 7 of them :point:).

I have been trying for hours now and I don’t seem to be getting anywhere
I would like to mention I am using Libgdx

Vertex Shader

#version 100
attribute vec4 a_position;
attribute vec4 a_color;

uniform mat4 u_projModelView;


uniform vec3 lightPos;
uniform vec4 lightColour;
uniform vec4 lightSunColour;



varying vec4 v_col;
void main()
{
	v_col = lightSunColour;

	float distance = length(lightPos.xy - a_position.xy);
	
	float a = distance;
	vec4 light = vec4(a,a,a,1.0) * lightColour;
	v_col += light;




 	v_col = a_color;
	gl_Position =  u_projModelView * a_position;
}

I am getting no results from this
and I am sending the base colour as transparent so i can see all of the other tiles under it and the sun colour as white and the light colour as yellow

… Sorry

Well first problem i am having is that libgdx is not accepting my uniforms… WTF

		UNIFORM_LIGHT_POS = shader.getUniformLocation("lightPos");
		System.out.println(UNIFORM_LIGHT_POS);
		UNIFORM_LIGHT_COLOUR = shader.getUniformLocation("lightColour");
		System.out.println(UNIFORM_LIGHT_COLOUR);
		UNIFORM_SUNLIGHT_COLOUR = shader.getUniformLocation("lightSunColour");
		System.out.println(UNIFORM_SUNLIGHT_COLOUR);

result

-1
0
-1

vertex

#version 100
attribute vec4 a_position;
attribute vec4 a_color;

uniform mat4 u_projModelView;

uniform vec3 lightPos;
uniform vec4 lightColour;
uniform vec4 lightSunColour;


varying vec4 v_col;
void main()
{

 	v_col = lightColour;
	gl_Position =  u_projModelView * a_position;
}

fragment

#version 100
#ifdef GL_ES
precision mediump float;
#endif

varying vec4 v_col;

void main()
{
gl_FragColor = v_col;
}

I think my problem is something to do with the ShapeRenderer

This is correct behaviour of OpenGL, since these uniforms are not active (i.e. used in a way that influences any output).
In the documentation of mentioned glGetUniformLocation it says: [quote]This function returns -1 if name does not correspond to an active uniform variable in program […]
[/quote]

but my output was never yellow which what “lightColour” equals to

How would i do this?? been at this for over 2 days now… kinda getting annoyed as i am not getting anywhere

Okay here is what i have so far, the ShapeRenderer cannot do lighting with shaders unless the lights are static throughout the whole game(which they aren’t)
the SpriteBatch is possible but I cannot draw a shadow mask like ShapeRenderer so I would need to create a image to get that working (Which I don’t want to) and then when trying to change the SpriteBatch shader I realized that I had to have a texture and there was no way getting round this… I HAVE NO IDEA WHAT TO DO

This is how my tiles are working

I have one layer which is the ground then i have the top layer and then i will render players and creatures etc (weather) and then i have another layer which is the light layer and all of the things i have tried are not getting me anywhere :?

Managed to get something working using the ShapeRenderer but the FPS has gone down to 12 instead of 120

Can somebody help me via skype
Skype: tommohawkaction

Are you batching all the shadows or starting/ending the shape renderer batch for each tile? If so stop doing that. Also make sure you’re culling off the tiles that aren’t visible and not rendering them.

Here is my renderer

shapeRenderer.setProjectionMatrix(camera.combined);

		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);

		Gdx.gl.glEnable(GL20.GL_BLEND);
		Gdx.gl.glBlendFunc(GL20.GL_SRC_ALPHA, GL20.GL_ONE_MINUS_SRC_ALPHA);

		// Lights
		shapeRenderer.begin(ShapeType.Filled);
		{

			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;
					Color tileColor = sunlight;

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

							LightTile lightTile = lights[x1][y1];
							if (lightTile == null)
								continue;


							float distance = Vector2.dst(x1,y1, x, y);
							distance = (float) (Math.floor(distance));
							if (distance > 3) {
								distance -= 3.1f;

							}else if (distance > 2) {
								distance -= 2.3f;

							}else if (distance > 1) {
								distance -= 1.5f;

							} else {
								distance -= 0.8f;
							}
							
							if(distance < 0){
								distance = 0;
							}

							tileColor = Utils.mixColours(tileColor, Color.WHITE, distance);

							System.out.println(distance);

						}
					}

					shapeRenderer.setColor(tileColor);
					shapeRenderer.rect(x * MasterTile.TILE_WIDTH, y * MasterTile.TILE_HEIGHT, MasterTile.TILE_WIDTH, MasterTile.TILE_HEIGHT);

				}
			}
		}

		shapeRenderer.end();

		Gdx.gl.glDisable(GL20.GL_BLEND);

Print statements are expensive, remove that and you might see a boost in FPS. Also, I’m pretty sure the ShapeRenderer class is slow, but I don’t know why. I would just use textures,

So how would i do this using a texture?? a transparent texture?