2D Lighting system (canvas2D)

For developers using the Construct 2 Javascript SDK

Post » Sun Oct 13, 2013 1:44 am

Hey there!

I am currently developing a 2D lighting system in javascript for canvas2D.
The goal is to create an identical thing for webgl as soon as it properly works.

I've gotten as far as to have a light working perfectly, except when adding more than 1 light gives a problem.

The system works by drawing a sprite (yes I copied the Sprite plugin, it was the fastest way) and clipping away where shadow should be.

but when using more than 1 light, the cliping path subtracts when overlapping

Works Fine:


Subtracting paths:

B
18
S
6
G
3
Posts: 30
Reputation: 4,218

Post » Sun Oct 13, 2013 4:59 am

Do you have a code snippet to show? Hard to offer suggestions without it. Except that you need to restrict clipping to the current light sprite obviously.
B
40
S
16
G
6
Posts: 543
Reputation: 7,649

Post » Sun Oct 13, 2013 12:20 pm

You cannot implement a lighting system by clipping for this exact reason. You need to render each light separately with additive blending.
Scirra Founder
B
402
S
238
G
89
Posts: 24,644
Reputation: 196,095

Post » Sun Oct 13, 2013 1:46 pm

[QUOTE=ErekT] Do you have a code snippet to show? Hard to offer suggestions without it. Except that you need to restrict clipping to the current light sprite obviously.[/QUOTE]

This is exactly what I want to do.
Right now I draw a path in with the canvas context element, then simply clip();

//for each object type
for (i = 0, leni = this.type.obstacleTypes.length; i < leni; i++)
{
    //for each instance
    instances = this.type.obstacleTypes.instances;
    for (j = 0, lenj = instances.length; j < lenj; j++)
    {
     rinst = instances[j];
     //if overlapping
     if (runtime.testOverlap(this, rinst)){
//have to draw the path around the object first (set it to the viewsize, because if they overlap, it basicly cuts every light according to 1)
            ctx.beginPath();
            ctx.lineTo(0, 0);
            ctx.lineTo(0, myy + runtime.height + this.height);
            ctx.lineTo(myx + runtime.width + this.width, myy + runtime.height + this.height);
            ctx.lineTo(myx + runtime.width + this.width, 0);
            ctx.lineTo(0,0);
//Draw a path that needs to be cut out of the image
//this part has a lot of conditional lineTo(); which is omitted

            ctx.moveTo(endpoint.x, endpoint.y);
            ctx.lineTo(imgp1X, imgp1Y);
            ctx.lineTo(imgp0X, imgp0Y);
            ctx.lineTo(endpoint.x, endpoint.y);
                                                    
            ctx.closePath();
            ctx.clip();
// after this it draws the image
                                        }
                    }
              }              


[QUOTE=Ashley] You cannot implement a lighting system by clipping for this exact reason. You need to render each light separately with additive blending.[/QUOTE]

How would I go about doing this? is there a way to manipulate the cur_image, or even in webgl?

I would like to be able to specify a region that will not be rendered.armed102013-10-13 14:00:11
B
18
S
6
G
3
Posts: 30
Reputation: 4,218

Post » Sun Oct 13, 2013 4:40 pm

[QUOTE=armed10]I am currently developing a 2D lighting system in javascript for canvas2D.
The goal is to create an identical thing for webgl as soon as it properly works.
[/QUOTE] have you checked the paster plugin thread?
B
12
S
3
G
1
Posts: 347
Reputation: 2,866

Post » Sun Oct 13, 2013 5:03 pm

No I haven't, I'll do that right now.

EDIT: I don't see how this helps, but I should be able to replicate my code in webgl which may allow me to do this per image instead of canvas wide.armed102013-10-13 17:07:56
B
18
S
6
G
3
Posts: 30
Reputation: 4,218

Post » Mon Oct 14, 2013 12:19 am

You could use the ctx.save() before clipping and ctx.restore() after clipping to reset the clipping region. I may be a problem when making the webgl version as webgl doesn't appear to have an equivalent to clip().

Another way to go about it is drawing to a canvas and using a blend to combine the images in various ways.

Look here:http://www.w3schools.com/tags/canvas_globalcompositeoperation.asp

The idea can easily be used with webgl as well.
B
94
S
33
G
118
Posts: 5,394
Reputation: 75,849

Post » Mon Oct 14, 2013 9:31 am

Thanks for the reply!

although using restore seems to cut performance to an unworkable level, even when using only 2 sprites, the blending options might be just what i need.
B
18
S
6
G
3
Posts: 30
Reputation: 4,218

Post » Mon Oct 14, 2013 11:37 pm

2D lighting in webgl would be awesome! I'll follow your progress closely :)
B
12
S
2
Posts: 85
Reputation: 899

Post » Fri Oct 18, 2013 1:17 pm

[QUOTE=DoudouSupreme] 2D lighting in webgl would be awesome! I'll follow your progress closely :)[/QUOTE]

Thank you, I will keep this thread updated. I also have a rather elaborate prototype due in the next 2 weeks, so I won't be updating this soon.

The current system works IF you use separate layers for the lights (because of the source-out drawing). The performance of canvas2D rendering this way instead of clip() makes for less performance, though I tested about 6 lights and it worked fine. There is some drop in frame-rate.

Node-webkit export does have major performance issues with this method.

My best option is to implement a WebGL version, since this would increase performance and will probably have more efficient image manipulation tools available.

If interested I will post the Canvas2D version with a tutorial on how to use it, for testing purposes.
B
18
S
6
G
3
Posts: 30
Reputation: 4,218

Next

Return to Javascript SDK

Who is online

Users browsing this forum: No registered users and 0 guests