- From: Ashley Gullen <ashley@scirra.com>
- Date: Mon, 16 Jul 2012 21:02:48 +0100
- To: "Tab Atkins Jr." <jackalmage@gmail.com>
- Cc: "whatwg@whatwg.org" <whatwg@whatwg.org>, David Geary <david.mark.geary@gmail.com>, Ronald Jett <rjett@level-studios.com>, Chris Marrin <cmarrin@apple.com>
I'd like to bring up this subject again especially now that first implementations are starting to appear. IMO the big use case here is games - the CSS filters are great for interesting visual effects. However there doesn't seem to be a way to use them in canvas rendering, other than applying the effect to an entire canvas. Games typically want to apply effects to individual objects (meaning individual drawImage() calls), and there is no good way to do this. Stacking separate canvas elements is out of the question, because it makes Z ordering with effects impossible. Consider trying to overlay an image with no effect on top of an image with an effect. Also consider the fact canvas has compositing modes like "lighter" and "destination-out", but CSS filters do not provide these. This makes it impossible to combine CSS filters and composite modes. An example is displaying an additive blended explosion (typical in games) on top of an image with a blur CSS filter, which seems to be impossible to achieve at all. One way to define this is to specify that drawImage(), when passed another canvas as a parameter, must take in to account the canvas' 'filter' CSS property. So to draw an image with a blur you'd render using an intermediate canvas, e.g. tempcanvascontext.drawImage(myimage, 0, 0); tempcanvas.style.filter = "blur(10px)"; gamecanvascontext.drawImage(tempcanvas, 0, 0); // draws with blur Another way would be just to add a 'filter' property to the 2D context, e.g.: gamecanvascontext.filter = "blur(10px)"; gamecanvascontext.drawImage(myimage, 0, 0); This would also be extremely powerful if custom CSS shaders are also supported, allowing for user-written effects in the canvas 2D context. Effects should should apply to all drawing operations for consistency, including lines, paths, rectangles and patterns. I have no idea if this is easy for implementers (would appreciate comments on that), but hopefully the CSS filter rendering can be recycled with drawImage(). Another argument is that you should just use WebGL and write shaders for advanced effects. This is an option, but given that a filter effect can be applied to an entire canvas, it seems a waste not to enable it for individual draw calls, especially given the 2D context is considerably easier and quicker to code for. Ashley Gullen Scirra.com On 25 January 2012 16:26, Tab Atkins Jr. <jackalmage@gmail.com> wrote: > On Wed, Jan 25, 2012 at 6:41 AM, David Geary <david.mark.geary@gmail.com> > wrote: > > On Tue, Jan 24, 2012 at 5:22 PM, Chris Marrin <cmarrin@apple.com> wrote: > >> Adding filter functions to canvas would require you to re-render the > items > >> for every filter change and you'd have to animate it all yourself. > > > > Sure, but you must create a superfluous canvas for each set of images > that > > you animate, and invoke an entirely different technology to apply the > > filter. You must make sure that those superfluous canvases have > > transparent backgrounds, no borders, and have the correct Z order so they > > appear over, and not under, the primary canvas for the application. And > I'm > > sure there are other gotchas to this hybrid approach that don't > immediately > > come to mind. > > > > I'd much rather use the filtering underlying API and control the > rendering > > and animation myself. > > Yes, it's effectively creating an ad-hoc retained-mode API out of > multiple <canvas> elements solely so it can apply filtering. > > (Using multiple backing canvases to sprite things is a reasonable > performance hack, but I don't think it should be required for basic > functionality.) > > ~TJ >
Received on Monday, 16 July 2012 20:03:30 UTC