7
$\begingroup$

Since long ago I wanted to implement a 2D lightning algorithm based on an idea I saw on YouTube. The video is realtime, but it runs on the CPU and the resolution is pretty low. I'm curious if anyone has an idea how to do this on the GPU.

The algorithm works the following way:

  • We have light data maps, these hold the color of the material (e.g. a red glass has 0xFF0000) and how transparent that pixel is.
  • Work out the light values of each pixel in growing circles from a light source. In other words, first calculate values right next to the light (8 pixels), then the neighbours of these pixels and so on. The color of a pixel is its value from the lightning data map, its alpha equals: (alpha of the pixel next to it closest to the light source - own alpha). So it is some kind of ray casting algorithm that calculates value for each pixel and can handle colored glass and fog/smoke.

So the CPU implementation is pretty trivial. My problem is that I want to use this in a mobile game, but I don't know how this would work as a shader. How can this be implemented on the GPU (that would run on mobile, so with OpenGL ES 2.0/3.0, maybe with Metal - if this is not possible then with OpenCL/CUDA)?

Note: I am not looking for full implementations, just ideas/shader pseudocode how this would be possible.

$\endgroup$
7
$\begingroup$

If your wall geometry is vector graphics you can simply extrude the segment away from the light position. This means 2 triangles per draw call, all the extrusion offsets can can be handled in the vertex shader.

enter image description here

Image 1: For each wall generate a shadow volume extrusion.

Quick and extremely dirty sample implementation of shadow volumes here:

Now since your shader can color the triangles as they see fit you can apply a shader on the triangles that is colored. Just like you would render transparent surfaces. To do this proper you may need a offscreen buffer for getting a proper color accumulation mode.

enter image description here

Image 2: Coloring the volumes based on distance to light.

Certainly the coloring algorithm may be whatever you like. for example the color could become darker the nearer you are to the extrude edge etc.

And here is very quickly done extremely dirty live example of colored shadow volumes:

This is just one way hopefully others will elborate. You can also use the exact same methods as you would in 3d. As for nonuniform fog, you could just use a raymarcher.

$\endgroup$
  • $\begingroup$ Thanks for the answer! But I am not looking for a simple 2D shadows algorithm (there are lots on the web), I am looking for a shadow/light algorithm that can handle volumetric fog and colored transparent surfaces (as seen in the Youtube video). $\endgroup$ – sydd Jan 10 '16 at 17:57
  • $\begingroup$ @sydd that is just a shader on the shadow volume. Easy to extend. $\endgroup$ – joojaa Jan 10 '16 at 18:17
  • $\begingroup$ @sydd added colored example $\endgroup$ – joojaa Jan 11 '16 at 17:43
  • $\begingroup$ thanks, it looks nice! But as I wrote my post is about porting the algorithm I described to the GPU. Actually someone gave an answer on SO at stackoverflow.com/questions/34708021/… . This answer is what im looking for, but its slow, thus I dont think that this algorithm is feasible for a real game. $\endgroup$ – sydd Jan 12 '16 at 17:23
  • $\begingroup$ @sydd raycasting can be accelerated by precomputing the data into a better datastructure. $\endgroup$ – joojaa Jan 12 '16 at 18:19

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.