smoot movement of light

Started by
14 comments, last by JTippetts 18 years, 10 months ago
Hello In my game I do a custom tile based lighting. But a problem is when a player moves to a new tile, light that surrounds him moves +-1 tile by x or y axis. I don't know how can I do some smooth light transitions. Here is an example Click here. How can I get that light smootly follow the player, not in steps (tile by tile)? [Edited by - streamer on June 5, 2005 4:04:17 PM]
Advertisement
In Golem, I placed lights in the world on a world-coordinate basis, then used simple distance algorithms to light each corner of the tile. Each tile represented a block of 64x64 units in world coordinates. Since a light could occupy any of these world coordinates, the lighting remained smooth as the light moved. The biggest mistake you can make is to try to keep everything in 'tile coordinates', which results in the blocky lighting. Refine your coordinate system finer than the 'tile coordinate' level for best results. Makes it easier to do smooth scrolling, too, since the player object (and thus the following camera) can move on finer increments than whole tiles.
Hmmm I don't think I understand you. Do you mean that every tile is segmented in 64x64 grid? If I do that I'll have a performace drawback...
My game scrolls just fine - smootly, one by one pixel. Player and NPC-s have two type of coordinates. First coordinate is tile based, and second is offset coordinate of player inside of tile. If player "steps" out of tile he will "step" into a neighbour tile. I think that this is good solution because when I draw map, every tile draws everything that have inside them.

Quote:The biggest mistake you can make is to try to keep everything in 'tile coordinates', which results in the blocky lighting.

So I need to update tiles to be of more triangles? Because I made every tile of two triangle...Max I can do (because I am bounded to 4 vertex) is 'blocky' lighting which follow player tile by tile.
Arey you using 3d or 2d?

Do you want 2D lighting so that anything within a radius of the player the same brightness even if it is tall or deep?

Do you plan to use the same technique for lights in the game?
Quote:Original post by streamer
Hmmm I don't think I understand you. Do you mean that every tile is segmented in 64x64 grid? If I do that I'll have a performace drawback...
My game scrolls just fine - smootly, one by one pixel. Player and NPC-s have two type of coordinates. First coordinate is tile based, and second is offset coordinate of player inside of tile. If player "steps" out of tile he will "step" into a neighbour tile. I think that this is good solution because when I draw map, every tile draws everything that have inside them.

Quote:The biggest mistake you can make is to try to keep everything in 'tile coordinates', which results in the blocky lighting.

So I need to update tiles to be of more triangles? Because I made every tile of two triangle...Max I can do (because I am bounded to 4 vertex) is 'blocky' lighting which follow player tile by tile.


Sounds like you've got the right idea, with your scrolling pixel by pixel. Now, just allow your lights to move pixel by pixel. Then use the distance (in pixels) from the light to each corner of a tile, assign light values based on this distance, then interpolate those light values across the tile. 3D APIs make this simple to do.
Quote:Original post by SimmerD
Arey you using 3d or 2d?

Do you want 2D lighting so that anything within a radius of the player the same brightness even if it is tall or deep?

Do you plan to use the same technique for lights in the game?



Yes and no :) Distanced objects are more shaded, closer more brightened, but for now I have not any graphics that are so tall to have reduce they amount of light. Tallest graphic for now are cc. max 10x tallest as player. So I don't need to shade graphic's height when rendering.
This light effect looks prety cool when combined with mass amount of light effects, specialy when light moves.

And I'm combining a 2D and 3D.
Quote:Original post by VertexNormal
Sounds like you've got the right idea, with your scrolling pixel by pixel. Now, just allow your lights to move pixel by pixel. Then use the distance (in pixels) from the light to each corner of a tile, assign light values based on this distance, then interpolate those light values across the tile. 3D APIs make this simple to do.


Yeah that sounds right. But then instead 2 triangles I'll need to draw 64 triangles per tile. That'll slow down a game a lot because I use 4 layers for graphic for now, then I'll implement a few more layers, and that's too much.
Anyway, I'll give it a try.
By the way, is there any possible solution to use a texture with circular shades of gray, and mask a scene somehow to have an effect where brighter area of texture will show mush beneath it and darker less?

The lighting in Golem was done with 32 triangles per tile. Even older hardware should have no problem with it, if you design things correctly. I was getting framerates in the mid 100s even on old GeForce 2 cards.
Example
Hmmm then I'm definitly missing something :) Are you rendering a whole screen in one step (in other words f.e: a whole screen is in one vertwx buffer) or are you d rendering on tile by tile basis (every tile one render call)?
I have about 1000 separate render calls per frame (every call, some things are rendered).

And what do you mean design things correctly?
In the New and Improved, Supertronic Whirly-Gig Golem engine (I just made that name up, just now [grin]) I store the map in a large vertex buffer object for the triangle verts, but I render tiles on a tile-by-tile basis in 8 passes, one pass for each terrain type layer. Each tile renders 4 triangle strips of 8 triangles apiece, covering a span of 5x5 vertices in the VBO. These vertices are spaced so that the tile, when drawn, covers the desired number of pixels on-screen. During a pre-processing pass, I calculate the triangle strip indices for each tile and store them in the tile structure. These strips index into the large full-map VBO, so drawing a tile is as simple as 4 draw indexed primitive calls. (Note that this improved version of the engine also achieves even better framerates than the initial Golem engine featured in the above screenshot; in that earlier one, I wasn't using VBOs, and some things were being done in a clunky manner.)

For lighting, in the earlier version (I'm working on shader based lighting right now) I maintained a separate color buffer with a color entry for each vertex in the map. I would combine ambient, directional, and dynamic light values for each vertex into the buffer, upload the color data for the currently visible tiles to the VBO, and draw the triangles using this color data. The light values were a composite of ambient color, directional light (for the 3D heightmapped version of the engine) and dynamic lights. Dynamic lights were calculated for each vertex. To avoid sqrt, I would usually just work with Distance^2, and store light ranges as Range^2. This gives a quadratic rather than a linear falloff to the light pool that, imho, looks better than the linear falloff.

For the first Golem engine, I also maintained a second static light map, for lights that would never move. These lights were placed and precalculated when the map was randomly generated, and values from this static lightmap were simply summed into the final vertex light calculation. This avoided the necessity of having to use dynamic lights for things such as torches, enabling me to place as many static lights as my little heart desired with no additional performance impact. If you have lots of torches and such, this is the way to go; you trade a little extra memory usage for a lot of extra performance savings.

Lighting for walls and objects was obtained directly from the final light map. Walls would obtain the 5 light values for the edge of the tile they occupy, objects would query the map for the nearest vertex and use the light value for that for the entire object. (This looked a little strange with huge objects, though. [grin])

How are you drawing your terrain? Are you using custom-created transition tiles to blend between terrain types, or are you using alpha values to do the blending? This can make a difference. In the initial Golem engine (pictured above) I was using a single 'layer' (ie, no alpha blending, the whole map view was drawn in one pass) with custom tile transitions. Thus, almost every tile was a different texture, requiring a texture switch (which ate up a lot of time) for each tile. With a layered and blended approach such as my new engine uses, I only do 8 texture switches to draw the entire terrain, rather than one per tile, which makes a huge difference even if I do have to draw 8 passes instead of 1. It's those stage switches that eat you alive; modern cards have more than enough fill rate to draw any 'standard' isometric style view at insane speeds.

This topic is closed to new replies.

Advertisement