11
\$\begingroup\$

I want to have 2D lighting that can be blocked by in-game objects. My game has a top-down view and all game objects are described by rectangles.

Let's say I have a 10x10 world and I place a light at 1x1 and walls all around that light. I want to be able to see the light source at 1x1, but not anywhere else, because it's blocked by the walls.

I've heard of casting light rays works, but how does that really work?

\$\endgroup\$
5
  • 1
    \$\begingroup\$ Would like to see some language-agnostic answers to this question. \$\endgroup\$
    – Dashto
    Commented Jun 10, 2013 at 6:10
  • 2
    \$\begingroup\$ @Dashto: You need a working piece of code in language you use? That is a wrong place to ask for.. \$\endgroup\$
    – Kromster
    Commented Jun 10, 2013 at 8:39
  • \$\begingroup\$ What have you tried? When you say "anywhere else to have no light source", what do you mean? Just lit up you 1,1 block and that's it. Maybe I don't get your question, could you post an illustration? \$\endgroup\$ Commented Jun 10, 2013 at 14:44
  • 1
    \$\begingroup\$ @Krom Stern: I'm asking for the exact opposite, actually - a conceptual answer that doesn't depend on language. The two threads linked as duplicates don't talk about the concepts very much. In fact most of the similar questions on this site simply have answers saying "Use this library!" which is less helpful for someone who wants to understand how it works. \$\endgroup\$
    – Dashto
    Commented Jun 10, 2013 at 18:16
  • \$\begingroup\$ @Dashto: That is important piece of info, you should add that to the question ;) \$\endgroup\$
    – Kromster
    Commented Jun 10, 2013 at 18:35

3 Answers 3

13
\$\begingroup\$

Amit Patel has written a very nice article on 2D ray casting.

This involves casting rays to each of the vertices inside the range of the light source to build a light mesh.

enter image description here

All of the visual examples are interactive in the post and very easy to understand.

You don't have to limit yourself to a box either, the perimeter you trace can be any shape you like.

\$\endgroup\$
1
\$\begingroup\$

You should use raycasting algorithm, which means, you should be able to compute the intersection of ray (half-line) with any object in your scene (lines, squares, circles, triangles ....) and choose the closest intersection. You cast the ray in all directions and then "draw the light" only to the closest object.

Here is how it may look like.

\$\endgroup\$
1
  • \$\begingroup\$ I just asked how I would use ray casting. I know about it. \$\endgroup\$ Commented Jun 14, 2013 at 2:44
0
\$\begingroup\$

If you know what ray casting is, then all you need to do really is hard-code it. It's not overly complex as long as you have coordinates for each vertex.

First, create a light-emanating object. Place your light at x,y coordinates.

#include <math.h>
int i = 0;
if ( sqrt( abs( light.x - vertex.x )^2 + abs( light.y - vertex.y )^2 ) <= light.radius)
{
    lightOccludingVertices[i] = vertex;
    i++;
}

//If two or more vertices are both a member of an individual wall,
//illuminate the triangular area between the light, the furthest 
//vertex on the x-axis, and the furthest vertex on the y-axis

This is not guaranteed to work for a concave polygon, but it should work just fine for any convex polygons.

This will work if your occluding objects (walls, character, flying purple people eater) are painted to the screen after applying lighting. Otherwise, half of a wall will appear significantly brighter than the other half. If your point light is equidistant from two pairs of vertices of the same wall (exactly half as high as your wall's height), apply the triangle to the two nearest vertices, rather than the two further away.

I should also mention that this method requires a dynamically-created vertex point where the edge of the light's radius meets the surface of the occluding object. This creates a minimum of 3 vertices for any occluding object and will allow for walls that extend past the radius of the light (or off the screen) to also block any light.

More information on concave and convex polygons

\$\endgroup\$

You must log in to answer this question.

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