[whatwg] CSS Filter Effects for Canvas 2D Context
cabanier at gmail.com
Mon Jul 16 21:34:13 PDT 2012
On Mon, Jul 16, 2012 at 1:02 PM, Ashley Gullen <ashley at scirra.com> wrote:
> 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,
> 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
> 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.
I agree that it would be great to have filter effects in Canvas. It should
be fairly efficient if you have a GPU backend since the effects can all be
done with shaders so it should take up too much memory.
This workflow could even support our CSS shaders proposal. Also since CORS
is no longer an issue with Canvas, we could remove all the limitations we
had to build in to ensure security.
I would be worried about performance in CPU implementations though...
> On 25 January 2012 16:26, Tab Atkins Jr. <jackalmage at gmail.com> wrote:
> > On Wed, Jan 25, 2012 at 6:41 AM, David Geary <david.mark.geary at gmail.com
> > wrote:
> > > On Tue, Jan 24, 2012 at 5:22 PM, Chris Marrin <cmarrin at apple.com>
> > >> 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
> > > 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
More information about the whatwg