7
\$\begingroup\$

I've been working on a tile-based game in which some areas may be lit (currently seen), some may be black (never seen) and some may be dark (previously seen, but not currently seen).

Looking at the absolutely wonderful Pixel Dungeon that has a similar scheme, it has an effect where the dark/black tiles sort of "bleed" into lighter tiles (image from the game's Tumblr):

example

Look at 1 above - the area beyond the wall is dark, the wall itself it lit, but the darkness "glows" and creates a nice transition to light. There's also a slightly different "glow" from black tiles to light tiles, as seen at 2 - it's darker (you can't even see the edge of the wall).

I'd be delighted to implement something similar, and if I just want the effect as seen at 1 and 2 I can just create appropriate overlays, something like: shade from dark for shade-from-dark and shade from black for shade-from-black.

It's not that simple, however:

  • For locations such as 3 I need black-to-dark shading.
  • For locations such as 4 I need shading from 2 dark sides and two lit sides.
  • For locations such as 5 I need shading from 2 black sides, 1 dark side and one lit side.
  • For locations such as 6 I need shading from 1 black corner, 1 dark... hold on a minute, this gets insane!

So I'm looking for some saner solution to achieve this lovely effect.

So far I've had these ideas:

  1. Generating textures at run-time given the "light status" of the 9 surrounding tile of the tile (and cache these textures).
  2. Applying a shader when drawing these tiles to interpolate the shading required at each pixel from the surrounding tiles, using either bilinear or bicubic interpolation.
  3. Changing the "dark" and "black" textures to actually be larger than a tile - containing the texture + bleed into adjacent tiles, something like:

    enter image description here

    And then let these textures overlay each other (but that's a lot of blending).

  4. Byte56 suggests suggests setting the color per vertex for the underlying tile and it will blend with the texture, but that does not seem accurate enough - for example a dark tile surrounded by black tiles will be completely black, which isn't good. And what if in all the corners are black tiles and on all the sides are lit sides? I guess I could model this accurately by having 9 vertices for each tile instead of 4.

I'd be happy for some input about these proposals as well as any other ideas for achieving this.

I'm using Libgdx and Java, but I have a feeling an answer will not really depend on the framework being used.

\$\endgroup\$
4
  • 2
    \$\begingroup\$ Usually this is just setting the color for the quad used for rendering the tile on. Black makes the texture black, white makes it show the original texture. You can set these colors per vertex, allowing for smoother transitions. No textures needed for lighting. \$\endgroup\$
    – House
    Commented Jun 1, 2013 at 13:13
  • \$\begingroup\$ @Byte56 that's a good suggestion though a bit problematic (I'll actually need 9 vertices to model this accurately, I believe) - updated the question to add it as another alternative. If you think that's nevertheless the best option, or that 4 vertices are enough, please do add an answer below. \$\endgroup\$
    – Oak
    Commented Jun 2, 2013 at 10:21
  • \$\begingroup\$ @Oak what did you end up going for? I more or less am currently asking myself the same question as you. \$\endgroup\$
    – payne
    Commented Aug 27, 2019 at 10:03
  • \$\begingroup\$ @payne I ended up with idea #1 above, generating a texture on-the-fly. My reference has since gone open-source so it's possible to see it was using that technique as well: github.com/watabou/pixel-dungeon/blob/… \$\endgroup\$
    – Oak
    Commented Aug 29, 2019 at 17:17

1 Answer 1

1
\$\begingroup\$

One method you could try:

Create a texture that has one pixel for every tile (visible on-screen). Then for each tile, set the corresponding pixel to black, 50% grey, or white, and finally, use that texture on a quad that covers the entire scene using a multiply blend. No need to worry about which corner has how many lit/dark neighbours, and OpenGL texture interpolation (make sure filtering is set to GL_LINEAR, not GL_NEAREST) will make the smooth transition for you.

The best part is that it also enables any kind of lighting you want, just in case you want a 75% grey area, or a bright green light somewhere.

If you have smooth scrolling, you will need to fiddle with either the texture coordinates of the quad, or move the quad itself, to account for the current sub-tile scrolling position.

\$\endgroup\$

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .