2d Lighting

Started by
17 comments, last by nex7 16 years, 9 months ago
Anyone know of any tutorials on 2d isometric lighting. I am using the DX9 sprite class to render all of my tiles and sprites so id like to find a pure 2d lighting solution. thanks.
Advertisement
when using D3DXSprite to render I'm pretty sure you're limited to a tile-based lighting model, which doesn't look all that great.

The idea is that each tile drawn can have some amount of light affecting it at the granularity of a tile (not a pixel).

To do this, you would create objects in your world that represent lights, these objects would have a color representing the color of the light, a radius representing how far each light reached at it's maximum.

when rendering a tile you would check the distance between all of the lights in the scene if any light was close enough so that the tile was within the light's radius, then the light would contribute to the lighting of that tile.

you would keep a color accumulation variable around, which is set initially to your 'ambient light' color (how bright the scene is without any lights affecting it).

when you discover that a light would affect the lighting of a tile, you interpolate the lights color between black (0,0,0) and the light color (r,g,b) depending how far the tile is from the light (>= light radius is black, <= light center is r,g,b).

Then you add this calculated light contribution to the color accumulation variable, being sure that you don't exceed the maximum color range (255,255,255).

after all lights are tested and applied, that resulting color is the color you want to Modulate (multiply) with your texture color, in order to 'tint' the tile to make it look like there is light affecting the tiles.

There are a bunch of optimizations for this, mainly determining the number of lights tested for a given tile, but this is the basic idea.

An example of tile based lighting from my game Morning's Wrath:

On a side note, this is just about the same way lighting would work on a per-pixel scale, however you would need to use pixel shaders to do this, and you would probably need to draw the tiles yourself using a vertex buffer and drawprimitive calls; if you got that far however and didn't wish to use shaders it could be acomplished to a lesser extent using per-vertex lighting which interpolates vertex point colors across polygons to give a smoother lighting apperence.

Raymond Jacobs, Owner - Ethereal Darkness Interactive
www.EDIGames.com - EDIGamesCompany - @EDIGames

Maybe you'll find this helpful.
Thanks guys...both very good info...

I will prolly just use EDI's approach...it seems the easiest and looks pretty good...i am already interpolating day and night cycles per tile so adding a little pointlight + range into the mix wont be hard at all.

Thanks!
EDI...how do you split up your animations?

Right now im using animation sheets for just about everything and for characters that tends to be...well HUGE..

I was thinking about loading the sheets on demand for the less used ones...sooo

sheets would be split by type..and the less used sheets would be loaded on demand...

Idle sheet -- kept in memory
walk sheet -- kept in memory
attack sheet --loaded on demand
per tile lighting is working great! might try to soften those edges a bit but its fine for now :)

thanks EDI
Sheets are very handy, because you get the natural col/row addressing scheme.

The one issue I'll warn you about is texture size limitation issues, e.g. you can't count on your 3D hardware being able to load 2048x2048 sized textures.

In morning's wrath I used a sheet method with weird sheet sizes, each row was a direction and it's columns were frames; since I started with a 2D API (DirectDraw), later when I had to switch to D3D it was a nightmare, and required me to split large images into texture sized bits and reconstruct them during a draw (NIGHT-MARE) :)

For the 2D version of Malathedra I decided to use individual frames, which had the advantage of being well within texture-size requirements; and I used a 'sheet' xml data structure to arrange these frame images into a row/col type table which I could then use for row/col addressing.

unless you're dealing with very fixed sized art assets (e.g. all multiples of 32x32 type sprites) I would recommend going with individual images with an association table. but if you feel you can keep your sprite sheet sizes in check then go with single-image sheets.

as for loading, Direct3D does a wonderful job of automatically managing textures, load your textures with the POOL_MANAGED flag as you need them (on first use (lazy init)) and if you exceed your texture memory d3d will swap them out for you; plus you get the added benefit of having your textures restored on device reset conditions.

Raymond Jacobs, Owner - Ethereal Darkness Interactive
www.EDIGames.com - EDIGamesCompany - @EDIGames

yeah ive split all animations up so that the largest sheet size is 1024x1024

the editor that i wrote has an animation editor which takes those and allows you to specify an image per animation.

it allows you to specify frame width/height..indexing position into the texture and the interval between frames. This all saves out to a file and is used by the object creator which just points to an animation file.

I think ill just keep the images small.

I chose the same row column method you did. The editor will allow me to go all the way down to 1 row per texture but the entire animation..say "north walk" has to be in the same image so im looking at a long strip instead of a large sheet.
Here is a shot of the lighting in action....the fall off needs some work but for tile resolution lighting it's not half bad. and i obviously need an artist :)

Light Falloff
Hi, I happen to be finishing up a isometric tile engine in opengl and was wondering how the above mentioned lighting model could be implemented in opengl?

Thanks.

This topic is closed to new replies.

Advertisement