Dynamic tile map lighting.

So, I’ve been toying around with dynamic tilemap lighting, and it’s going okay-ish, but I can’t wrap my head around combining lights. As of now, each tilemap holds values of the lighting of each individual tile, from 0 - 255. 255 being completely black. So anyway, here’s a screenshot of the problem:

http://img690.imageshack.us/img690/5263/dynamiclightingrev1.png

Essentially the bottom-right image shows when a light below it collides with a light above it…the bottoms lights fade overrides the above lights brightness.

Here’s the code, it’s simple so I’ll put it all up:

public void checkLighting(int x, int y){
		if (mapTiles[3][x][y] < 255){ //Checks if the tile is lit up.
				for (int c = 1; c < 10; c++){ //Diagnally ascending variable, breaking it into levels.
						for (int a = 0; a < (c*2)+1; a++){ // Takes each "level" and goes right and down
							try{
//Sets lighting that of the original tile and makes it darker by 20*c. Same with the rest.	
								mapTiles[3][x-c+a][y-c] = (mapTiles[3][x][y] + (20*c)); 	
								mapTiles[3][x+c-a][y+c] = (mapTiles[3][x][y] + (20*c));
							}catch(Exception e){} //To prevent error from leaving bounds of tilemap.
						}
						
						for (int b = 0; b < (c*2)+1; b++){ //Takes each "level" and goes left and up
							try{
								mapTiles[3][x-c][y-c+b] = (mapTiles[3][x][y] + (20*c));			
								mapTiles[3][x+c][y+c-b] = (mapTiles[3][x][y] + (20*c));
							}catch(Exception e){}
						}
				}
			}
		}

Any tips on fusing the lights? Help is greatly appreciated :slight_smile:

When you add a new light source, you do something like: Math.max(oldValue, newValue) for each tile affected. Or if you want over laps to be a little brighter, do something like add them some how?

Light “stacks” additively. Put two lights on the same spot and it will be twice as bright (though that does not mean that the human eye sees it as twice as bright, but to handle that you need tone mapping and preferable HDR rendering).

It makes a lot more sense to set 100% darkness to 0 and 100% brightness to 255. That way, each tile contains how bright it is, instead of how dark it is which makes a lot of things easier. For exampe, you can just add together the light contribution from each light to determine the brightness of each tile. I don´t know how you render the tiles in the end, but if you use OpenGL you can just call glColor3f(brightness, brightness, brightness); (need to cast brightness to byte though) and the tile texture color will be multiplied by the brightness. If you use Java2D, I don´t know exactly how to do it, but to multiply a color by the intensity you convert the 0-255 brightness value to a 0.0-1.0 float value and multiply it with the color of each pixel.

I’m doing in this in the simplest way possible, seeing as it’s not a major feature of the game. So, essentially, it’s just aesthetic; the 0-255 thing is the transparency of the black blocks that overlap the tiles ;p lol.

Again, everything becomes simpler if you store the brightness instead of the transparency.

With brightness:
intensity = sum(light_contribution[i]);
pixel color = color X (intensity / 255.0f);

With transparency:
transparency = 255 - sum(255 - light_contribution[i]);
pixel color = color X ((255 - transparency) / 255.0f);

Which one makes more sense?

I did the exact same thing when I did 2D lighting. I imagined a “shroud” that had a transparency value that worked as an overlay over the game world, and I bumped into the same problem when lights started overlapping.

So if I use the brightness thing, I could just change the color and leave the transparency alone, right?

I really want to make this as simple as possible, if possible.

The calculations just get simpler. What graphics library are you using?

Slick2d, sorry it took so long to get back to you…been a bit busy.


That article changed my life. xD

It’s helpful for isometrics, but I’m not sure on how I’m going to use this for what I need to do here lol

Argh!!! Copy paste on an iPhone is going to kill me…

http://archive.gamedev.net/archive/reference/programming/features/2dsoftshadow/index.html

This is the article I meant… >_>

That article changed my life! lol

Can you fill me on how you achieved that isometric effect in the other article though? I originally planned to make my game’s dungeons isometric, but couldn’t draw the tiles, seeing as the whole game is essentially hand-drawn. Converting orthogonal tile-sets to look isometric would make my life awesome. lol

Heh, that was a copy paste fail, but anyway…

Drawing isometric tiles is no different from drawing normal tiles. The best looking way is to have an isometric tileset since it produces the sharpest textures. Using a normal tileset makes the tiles look blurry, which you can see in the screenshot in that thread. The only thing I did was rotate the whole screen by 45 degrees and then flatten it a bit by scaling. It´s all there in the source code, so take a look there.

That one was meant for drawing extremely large maps. The map there was 2048x2048 tiles = 4 million quads = 16 million vertices, which to be fair can actually be handled by a decent GPU at over 60 FPS. If you have that large maps you obviously needs some form of culling to get rid of the tiles that are outside the screen, as simply drawing all those quads is going to eat more vertex power. It´s inefficient for both the CPU and the GPU. Instead my program just draws a single 2048x2048 sized quad and then a shader figures out which tile to read for each pixel on the screen. Since parts that are outside of the screen is automatically clipped by OpenGL, no culling is needed, an the only limiting factor is the texture size the GPU can handle, but simply streaming parts of the texture to the GPU as the player moves across the world allows you to have maps of any size. Again, the source is there, so take a look if you want to.

This is obviously overkill for most games and has pretty much no connection to isometric tiles. I just put that there since everyone was talking about isometric tiles when I created that thread. xD The rotate and scale trick works for drawing tiles in any way, so you can just “convert” normal tilesets to isometric that way even if you just use normal quads.

Ooooh, new idea: combine this with tesselation and I have a brand new 3D tile terrain renderer! =D

By the way, I kinda can’t get soft shading to work in my engine lol. Problem is, being the noob I am, I don’t really know where to start.

I was going to use OpenGL, but the thing is my engine wasn’t built to use it, so I don’t have access to an OpenGL drawable canvas, I’d imagine.

I’m using Slick2d, and using a GameContainer and the Graphics object to draw things, not sure if there’s some magical connection I could use for access to OpenGL. Slick tends to have magical connections like these that I don’t know about until I make an idiot of myself on here asking about them, because they generally aren’t in plain sight on the tutorial pages ;p

Would you know? Assuming I can’t use OpenGL, how should I approach simplistic lighting?

The OpenGL classes are static. GL11. GL12, GL20, e.t.c.

So, in that case, I should be able to pull all the functions I need from where? I’m sorry if these are real obvious, but I haven’t used OpenGL directly at all…ever. lol

EDIT:
I’m also a bit of a visual learner, so you know, keep that in mind ^-^ Haha

theagentd is referring to LWJGL, implements the OpenGL API as static methods. JOGL uses a GL graphics context object that gets passed in, similar to awt/swing, while GDX uses a global object. Since Slick2D uses LWJGL under the covers, that’s what you’d be using. Anyway, the LWJGL wiki will get you started on that static method API.

o_O Then this is a great opportunity to start! That article is what got me going with OpenGL. If you have no experience at all you should start out with doing some basic stuff; glBegin-glEnd, colors, texturing, e.t.c. The thing is that the lighting in that article is very easy to implement (at least only with hard shadows). The only things you need are FBOs, textures, very basic glBegin/glEnd geometry and blending pretty much. Even better, you´ll gain most of the basic knowledge needed to make games from just this.

;D

Always nice seeing that reposted.

I based my lighting system on this article as well for Daedalus … in fact it is this article that motivated me to start to program my own game, and I saw a lot of other articles based on yours all over the internet ! It seems that you’ve inspired a lot of people with this ! :slight_smile: Thanks !!