Jump to content
  • Advertisement


  • Content Count

  • Joined

  • Last visited

Community Reputation

123 Neutral

About dgmdavid

  • Rank
  1. dgmdavid

    2D game Terraria-like lighting

    This is a rather good idea, renman29. I'm going to test this right now. As for dynamic objects, there will be. And the light from the torches do a little flickering, so I'll have to update de lighting in a fixed timestep, I think. Right now I update it every frame.
  2. dgmdavid

    2D game Terraria-like lighting

    I think I should have posted this to "general programming".   Any ideas on how to handle colored lights using a similar technique like the code I posted?
  3. dgmdavid

    2D game Terraria-like lighting

      What do you mean by that?
  4. dgmdavid

    2D game Terraria-like lighting

    It's not slow on my computer. But when you zoom out and many more tiles are on screen, like (480x270 tiles (259200 triangles per frame)), plus the lighting calculations, plus the same amount of trigs for the shadow it drops to ~30 fps in my i3 with hd6850, which is pretty bad. But today I revisited the method where I paint a texture with the lightmap and draw a single quad all over the tiles and it's now much faster. I was definitely doing something wrong. It's now getting ~52 fps, compared to ~30 that was before (480x270 tiles, zoom 0.4x). This is much better. The intented zoom for you to play is around 2x and it's now running at ~610 fps. It will do for now, but I want it to run as intended (ie 60 fps) on a weaker hardware. I think the best thing to do now is to try to improve the lighting calculation. Here's how I do it: //GenerateLighting void BitWorld::GenerateLighting( int x1, int y1, int x2, int y2 ) {     //validate the range of the input values     if( y1<0 ) y1 = 0;     if( y2>=world_height ) y2 = world_height-1;     //propagate the light to the other blocks left-top to right-bottom     for( int ey=y1; ey<=y2; ++ey )         for( int ex=x1; ex<=x2; ++ex )             CalcLighting( ex, ey );     //propagate the light to the other blocks right-bottom to left-top     for( int ey=y2; ey>=y1; --ey )         for( int ex=x2; ex>=x1; --ex )             CalcLighting( ex, ey ); } inline void BitWorld::CalcLighting( int x, int y ) {     SWorldBlock *block;     SWorldLighting *lptr;     int l1=0, l2=0, lt, absorb;     SBlockInfo *fg, *bg;     block = GetWorldBlockPtr( x, y );     lptr = GetLightPtr( x, y );     fg = BlockInfo->GetBlockInfo( block->foreground_id );     bg = BlockInfo->GetBlockInfo( block->background_id );          //calculate the max lighting from the neighbour blocks and light absorption     lt = 0;     int z[8];     z[0] = (GetLightLevel( x-1, y-1 )*15)>>4;     z[1] = GetLightLevel( x,   y-1 );     z[2] = (GetLightLevel( x+1, y-1 )*15)>>4;     z[3] = GetLightLevel( x-1, y   );     z[4] = GetLightLevel( x+1, y   );     z[5] = (GetLightLevel( x-1, y+1 )*15)>>4;     z[6] = GetLightLevel( x,   y+1 );     z[7] = (GetLightLevel( x+1, y+1 )*15)>>4;          //find the maximum: slight faster than the "for" method, much faster than cascading "max" functions     if( z[1]>z[0] ) z[0] = z[1];     if( z[2]>z[0] ) z[0] = z[2];     if( z[3]>z[0] ) z[0] = z[3];     if( z[4]>z[0] ) z[0] = z[4];     if( z[5]>z[0] ) z[0] = z[5];     if( z[6]>z[0] ) z[0] = z[6];     if( z[7]>z[0] ) z[0] = z[7];     if( z[0]>lt ) lt = z[0];     if( lt>0 )     {         if( block->foreground_id>0 || block->background_id>0 )         {             if( block->foreground_id==0 )                 l1 = 8; //16             else {                 l1 = fg->light_absorption;                 //open doors block less light                 if( fg->type==BLOCK_TYPE_DOOR ) if( block->foreground_offset>fg->frame_tile_count ) l1 = 4;             }             //TODO: background blocks absorb a fixed amount of light? ie equal to all? make it a "constant"?             if( block->background_id==0 ) l2 = 8/*16*/; else l2 = 24;  //bg->light_absorption/3;             if( block->liquid_level>16 ) { l1+=12; l2+=12; }             if( l1>l2 ) absorb = l1; else absorb = l2;         } else {             absorb = 16;             if( block->liquid_level>16 ) { l1+=12; l2+=12; }         }         lt -= absorb;     }     //blocks that emit light itself     if( fg->light_emit>lt ) lt = fg->light_emit+(int)(flicker_cos*(float)fg->light_flicker);     if( bg->light_emit>lt ) lt = bg->light_emit+(int)(flicker_cos*(float)bg->light_flicker); //TODO: is this really the way to do it?                  //the block is empty? emit sunlight! xD     if( ( block->foreground_id==0 || fg->is_translucent ) && ( block->background_id==0 || bg->is_translucent ) )     {         //int l = 300; //GetWorldLight( ey ); //TODO: precompute?         if( lt<300 ) lt = 300;         if( block->liquid_level>16 ) lt-=32;     }     if( lt<0 ) lt = 0;     //set the current light level to the block     lptr->light_level = lt; } Pretty bad, I know. Any suggestions?
  5. Hello guys. This is my first post, so if I posted in the wrong section please let me know.   Ok, so I'm making a game similar to Terraria/Starbound (but much more modest, of course). I made an algorithm to calculate the lighting that, despite the lack of optimization right now, works pretty well (at least for my taste). But this algorithm is not important and it's not what I want to talk about here. How to render this is what I came here to discuss.   To render the tiles, I was coloring them accordingly to the "light map" and it worked "ok". This is how it looked like using this method:   Then I changed the way I was doing, so now I render the tiles "full bright" and then I render "black/colored" tiles in front of them, adjusting the alpha channel to "match" the light level (each corner using an average of the surrounding lighting). But the performance of this, of course, is not that great because I doubled the number of triangles being rendered and the "smoothing calculations". Here's how it looks like using this method:   Then I made a quick test and "rendered" (by hand?) every "tile in the light map" as a single pixel on a texture to represent the "light level", then render a single quad in front of the screen with the texture (with filters) stretched. The visual results are exactly the same as the previous method. But, to my surprise, the performance was even worse.   So I was thinking if there's a better way to do it using pixel shaders or other techiniques? I'm using DirectX9 and C++.   Any hints will be appreciated. Thank you in advance. (sorry about my english, I can't even grammar)
  • Advertisement

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

GameDev.net is your game development community. Create an account for your GameDev Portfolio and participate in the largest developer community in the games industry.

Sign me up!