News for hackers. Stuff that matters.
Re:Illuminated.js – 2D lights and shadows rendering engine f... by gren on Friday May 11, 2012 @05:21AM (#3958370)
Performance has been my focus on this work, I use a lot a cache canvas to not redraws gradient and path things but just copy caches. But i'm stuck on Canvas and requestAnimationFrame performances. Let's hope it will continue to improve, otherwise I could try to use WebGL but it will not be supported by every browsers for today.

Do you use a lot of sampling in the lights? I reach good fps on my macbook pro, especially on Chrome (but also on my home computer under Linux).

I hope we can use it with less sampling and less compute() calls for our games :)

Re:Illuminated.js – 2D lights and shadows rendering engine f... by Jimmie on Friday May 11, 2012 @05:30AM (#3958393)
Default scene, Chrome 18.0.1025.168, Os X 1.6.8, Year old Macbook Pro

Runs so slow I can barely drag the objects around. It looks great though, I mean the output is fantastic just not performant.

Re:Illuminated.js – 2D lights and shadows rendering engine f... by gren on Friday May 11, 2012 @05:39AM (#3958415)
eah I think the default scene use too much samples, like 51 for the right light.

Now my technique of combining shadow samples together is probably not the most efficient, I draw them with source-over and an alpha which is also a wrong hacky current implementation... but maybe using the CanvasData would be less efficient (technically I need to make the average of shadow samples' grayscales) - well we never know, I haven't tried yet ;)

I would be happy to have any contribution in the library :)

Re:Illuminated.js – 2D lights and shadows rendering engine f... by timb on Friday May 11, 2012 @09:17AM (#3959014)
the editor could turn down samples for lights while dragging, and turn samples back up when dragging is finished.
Re:Illuminated.js – 2D lights and shadows rendering engine f... by ajuc on Friday May 11, 2012 @06:59AM (#3958599)
I feel you. I'm doing 2d game in html5 (I have 2 rendering engines - pure canvas, and webgl). Webgl works great, but works on small percentage of browsers, canvas version runs with ~ 45 FPS in 1280x960 on my 2 core celeron 2Ghz. And the main problem is just fill rate - I have background, and scrolling terrain, so I need to clear whole window every frame, and less than 50 (64x64 pixel) sprites at one time on screen. That's already too much for canvas to redraw at 60 FPS.
Re:Illuminated.js – 2D lights and shadows rendering engine f... by de90 on Friday May 11, 2012 @08:21AM (#3958831)
Are you currently prerendering to a separate canvas? Drawing it to a different (hidden) canvas, grabbing the image data, and just pushing that to the actual canvas might be a bit performance boost.
Re:Illuminated.js – 2D lights and shadows rendering engine f... by ajuc on Friday May 11, 2012 @03:54PM (#3961024)
I've just tested. The fastest I get (37% time in drawing according to chrome profile, and ~45 fps) is when I draw everything moving to one, visible canvas, that I clear at the start of each frame, and everything static (background) is on another canvas, that isn't changed when it's not needed.

When I draw everything moving to off screen canvas, and then drawImage this off screen canvas into visible canvas, I get 48% of time in draw function, and ~35 fps.

It is indeed faster to draw everything to off screen canvas, than to on screen one (when I commented out copying off screen canvas to on screen canvas, and left only drawing sprites and tiles to off screen canvas - I got steady 60 fps, but obviously nothing is visible then :)). And copying whole canvas to the visible one is still slower, than drawing the sprites and tiles on the visible canvas in the first place.

But thanks for ideas.

Re:Illuminated.js – 2D lights and shadows rendering engine f... by de90 on Friday May 11, 2012 @08:51PM (#3962216)
Are you redrawing every time to the invisible canvas, or are you saving the data, and just pushing that to the screen? I'm not entirely sure if this is plausible for you situation, but take the event of a game like mario. The ground on the bottom can be drawn one time grabbing each tile from a tile sheet, and then you can save that bitmap data, so you cut out having to 'pick out' each tile, and just push that data to the screen. Any chance you have an example of what you're doing for your sprite\tile layer? I believe it can be a bit fast this way, but we may just not be on the same page.
Re:Illuminated.js – 2D lights and shadows rendering engine f... by ajuc on Saturday May 12, 2012 @06:46AM (#3963463)
I have 4096x4096 tiles 64x64 pixels each. I can't draw that to off screen canvas at once. I only draw tiles that are visible, and terain is mostly empty (some platform in the air), than I don't draw anything obviously.

My fastest code:

    for (var y=y1; y>=y0; --y) {
        var resultY = (0.5+
            (level.topLeft.y - camera.position.y + camera.screen.height / 2 +
            level.cellHeight + y * level.cellHeight-level.cellHeight)
        )|0; // fast clip to int
        for (var x=x1; x>=x0; --x) {
            var tileImageNo = level.layers[z].cells.valueAt([x, y])-1;
            if (tileImageNo==null || tileImageNo<=0) {
                //nothing to do
            } else {
                ctxOnScreenCanvas.drawImage(
                    tiles[tileImageNo],
                    (0.5+
                        (level.topLeft.x - camera.position.x + camera.screen.width / 2 +
                        level.cellWidth + x * level.cellWidth- level.cellWidth)
                    )|0, // fast clip to int
                    resultY
                );
            }
        }
    }
I've also tried drawing to OffScreenCanvas in the loop, and then drawing that canvas to screen, but it was slower.

I could try drawing to off screen canvas only when player moves out off current off screen canvas, but that will trade small delay each turn into big delay every N turns, and that's even worse. But I'll try that.

EDIT: cuting out not important code.

Re:Illuminated.js – 2D lights and shadows rendering engine f... by de90 on Saturday May 12, 2012 @11:34AM (#3964141)
Gotcha, my suggestion, might require too much change to be worthwhile, but won't hurt to say it. Here is the assumptions I am working off of:

- You have a background layer, lets just say it's a blue background - A middle layer, lets say clouds that move as you move to the right - And a tile layer, which draws the sprites, and the tiles of the maps

For the tile layer, we can break it down into two separate groups, animated sprites, and static sprites.

The static sprites, can be drawn to the offscreen canvas, and you get the imageData from that one time, and then push that data to the screen there after. Then the animated sprites will just be drawn to the on screen canvas every time. http://imgur.com/n6RFF The stuff that should be drawn to the offscreen canvas, then grab the image data has gray around it, and the animated sprites are in the green.

So for drawing the tiles of the map we only have to loop through the tile data, one time, and after that if the imgData remains valid (a separate flag) we can just push that imgData to the screen.

This would also allow drawing section of the screens on the offscreen canvas in chunks, and storing that draw to just be pushed to the screen at appropriate times.

I don't know if I explained it very well, I could probably through together a crappy little demo if you'd like.

Re:Illuminated.js – 2D lights and shadows rendering engine f... by gren on Friday May 11, 2012 @08:44AM (#3958884)
This is what I do except I use drawImage.

You think using getImageData and putImageData is more performant that drawImage(canvas, 0, 0) ?

BTW i'm not sure it will works for combining images together with special composite operation.

Re:Illuminated.js – 2D lights and shadows rendering engine f... by leeoniya on Friday May 11, 2012 @10:49AM (#3959454)
drawImage is usually faster. i think it's also more useful if you need alpha composition (overlays).

http://jsperf.com/canvas-drawimage-vs-putimagedata/11

also read this about imageData caching and explanations of the different opts. loop unrolling helps a bit, forget the typed array stuff for now, it wont work anywhere for some time.

http://hacks.mozilla.org/2011/12/faster-canvas-pixel-manipul...

Re:Illuminated.js – 2D lights and shadows rendering engine f... by gren on Friday May 11, 2012 @11:20AM (#3959650)
Thanks!
Re:Illuminated.js – 2D lights and shadows rendering engine f... by ajuc on Friday May 11, 2012 @09:35AM (#3959090)
I have 3 canvas elements, bottom with static backgroud, middle with scrolling terrain, and upper with sprites. I clear the whole middle canvas each frame, and only redraw parts of the other canvas elements.

But I don't use hidden canvases, just .drawImage each visible tile of terrain into the middle canvas each frame. I'll try to draw to hidden canvas, and see the difference, thanks for suggestion.

Re:Illuminated.js – 2D lights and shadows rendering engine f... by JackC on Friday May 11, 2012 @10:20AM (#3959284)
Huh. I've never worked with canvas, but is it possible that moving the middle canvas itself would be faster than clearing and redrawing it every frame? Like you have two canvases side by side in a div with overflow hidden, move both canvases each frame, and when one of them is totally off screen, move it to the other side and draw new terrain. Or are you hoping to avoid animating the canvases themselves?
Re:Illuminated.js – 2D lights and shadows rendering engine f... by ajuc on Friday May 11, 2012 @03:56PM (#3961035)
I'll need not 2, but 4 canvas elements, each at least [width/2+1, height/2+1]. I'll try this, and let you know. Thanks for ideas, even if it seems a little strange.
Re:Illuminated.js – 2D lights and shadows rendering engine f... by ajuc on Friday May 11, 2012 @06:09PM (#3961698)
Eh, wrong again. 9 canvases of size [width/2+1, height/2+1], or 4 of size [width, height].
Re:Illuminated.js – 2D lights and shadows rendering engine f... by leeoniya on Friday May 11, 2012 @10:42AM (#3959415)
try http://www.kineticjs.com/

they use multiple canvas layers. from working a lot with canvas lately, the fastest was to draw to canvas is not to draw to it :). if you have a scrolling bg that is static, you can just use a bg image sprite and scroll it via CSS/js. anything that can be done with a sprite should probably be done with one.

even for collisions etc, you're best off doing all the logic for your shapes and manipulating a DOM element (or even a mini-canvas) than re-rendering an entire huge canvas.