Re: [whatwg] CSS Filter Effects for Canvas 2D Context

On Thu, Jul 26, 2012 at 11:42 AM, David Geary <david.mark.geary@gmail.com>wrote:

> On Mon, Jul 16, 2012 at 2:02 PM, Ashley Gullen <ashley@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.
> >
>
> Forcing developers to use CSS with Canvas to get high-level *graphics*
> functionality is just plain wrong. If anything, it's completely backwards.
> Why do we arbitrarily restrict high-level graphics functionality such as
> filters and composite modes to individual technologies like CSS and Canvas?
> I'm completely unaware of the advantages of such an approach. The term "CSS
> filters" is absurd.
>

I think Ashley's point was to make CSS shaders-like functionality available
in Canvas.


>
> Filters are an important high-level graphics capability that should be
> available to any HTML5 technology that chooses to incorporate them. I agree
> with Ashley, let's get them into Canvas.
>
> 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 like the filter attribute on the context, provided that it's part of the
> state saved by save():
>
>     gamecanvascontext.drawImage(...); // image drawn normally
>
>     gamecanvascontext.save();
>
>     gamecanvascontext.filter = '...';
>     gamecanvascontext.drawImage(...); // image drawn w/filter
>
>     gamecanvascontext.restore();
>
>     gamecanvascontext.drawImage(...); // image drawn normally
>
> The default filter could be a no-op, which would be similar in behavior to
> the default clipping region (they would both do nothing).
>

This looks very reasonable.

On another note, wouldn't it be nice if you could add a grouping operator
such as this:

gamecanvascontext.filter = '...';
gamecanvascontext.beginGroup();
... // lots of drawing operators
gamecanvascontext.endGroup();

 and have everything in that group at endGroup time?


>
> > 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.
> >
>
> It's a poor argument, IMO. We should leave 3D for WebGL, but make advanced
> effects available to all interested technologies.
>
>
> >  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.
> >
>
> Agreed.
>
>
> David
>
>
> >
> > 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 Saturday, 28 July 2012 04:50:08 UTC