We would love you to play this but your browser doesn't support HTML5 canvas.
Just use a different browser and you can happily play this game.

How to do HTML5/WebGL Lighting in GameMaker

The above demo can be used with the mouse and shows casting shadows in GameMaker that works in HTML5 and any other module.

Objective :

I needed a simple way of doing lighting in GameMaker that would work in HTML5, was efficient, and had very few limitations. Some other examples I saw online required me to make other objects all over the place and that just seemed messy.

So I came up with this really elegant way of casting lights by just drawing triangles. This could easily be adapted to have multiple light sources or cast coloured light with the use of surfaces.

If you are looking for something more advanced with more options I have written an Advanced Lighting Guide however it builds on this one so it is worth reading them both.

If you are looking to do drop shadows in GameMaker you might find this guide better.

When I run the exe version of this game on my computer it runs at a steady 600fps so you can see you could add in a huge number of walls and light sources before it would impact performance.

Code :
// In Create Event:

shadowsize = 1100

// In Draw Event:

with(obj_wall)
    // draw_shadows
    draw_set_colour(c_black)

    draw_primitive_begin(pr_trianglestrip)
        draw_vertex(bbox_left, bbox_top);
        var dir = point_direction(other.x,other.y,bbox_left,bbox_top)
        draw_vertex(x+lengthdir_x(other.shadowsize,dir), y+lengthdir_y(other.shadowsize,dir));

        draw_vertex(bbox_left, bbox_bottom);
        var dir = point_direction(other.x,other.y,bbox_left,bbox_bottom)
        draw_vertex(x+lengthdir_x(other.shadowsize,dir), y+lengthdir_y(other.shadowsize,dir));

        draw_vertex(bbox_right, bbox_top);
        var dir = point_direction(other.x,other.y,bbox_right,bbox_top)
        draw_vertex(x+lengthdir_x(other.shadowsize,dir), y+lengthdir_y(other.shadowsize,dir));
 
        draw_vertex(bbox_right, bbox_bottom);
        var dir = point_direction(other.x,other.y,bbox_right,bbox_bottom)
        draw_vertex(x+lengthdir_x(other.shadowsize,dir), y+lengthdir_y(other.shadowsize,dir));
   
    draw_primitive_end()
    
};
How it Works :

I think this might be called Ray Tracing, however I’m not sure of the technical in’s and out’s of ray tracing.

I think it will take me longer to explain the code than the whole of the code, basically I take the 4 corners of each wall and draw a line from the player through this point and extend it further out by 1100px (this number can be changed). I then draw a triangle from here to the next corner.

I have included an image below that I think will help show what is happening. In this image I am only drawing the lines that are being extended. And I then basically fill inside all of those lines. Easy Peasy!

Notes :

This is a HTML5 compatible version of drawing shadows, however it does require WebGL to be enabled. To be this isn’t a problem because I am all in favour of users keeping their browsers up to date. It would be possible to make this work in WebGL by drawing triangles rather than the draw_primitive_begin(pr_trianglestrip) I am using, however this would make the code a little more messy so I’m happy with it the way it is.

This is actually a slimmed down version of what I use, I think its more efficient to collect all the walls in the step event and remove the ones that are off the screen or behind other walls and only cast the minimum amount of shadows you need to. However because this already performs so well it’s unlikely other people will need to do this.

If you want to do field of view this example might be better.

If you want to test if WebGL is working on your browser you can use this page.