-
Notifications
You must be signed in to change notification settings - Fork 2.7k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Canvas2D Filters #5621
Comments
Conceptually, adding filters to Canvas2D seems reasonable. Adding full SVG-filter support seems like a large amount of new API for limited benefit. In practice, most content uses only a fairly small set of filter types. If we're going to add filter support, we should start with a small set of popular filters, and only expand the set if compelling needs arise. Also, we should start with the "linked-list" model of filters that the css |
I agree with @litherum. I felt a little odd writing up all the SVG filters into the doc. I have a hard time imagining the practical usage for the lighting filters, for example. Do we have any idea what a "small set of popular filters" would be? |
I'm not sure what would be the real benefit of this... This should theoretically not even require access to the DOM (thinking of OffscreenCanvas), since we can generate such a filter from data:// URI or a blob:// URI (though Chrome has a bug where they don't allow blob URIs yet, IIRC per specs they should and FF does support it). So the example in the explainer can already be achieved: https://jsfiddle.net/hogyqxw1/ and it seems everything in this proposal becomes neat API wrapping that could be done by a library. What would be great though is that we finally have a load event for these filters, and that implementers support it in Worker thread too (they don't currently). |
I think the idea is precisely to provide a more user-friendly API for a feature that's already implemented but relatively hidden and difficult to use. |
There is somewhat perverse value in hard-to-optimize paths being hard to use, so as to keep devs pointed at the APIs we want them to use, and can optimize well. |
@jdashg Why are filters hard-to-optimize? Aren't they just shaders? |
Use an API with shaders, like WebGL. Not all canvas2d implementations are implemented with shaders, since not all canvas2d implementations are hardware accelerated. |
OffscreenCanvas can't support URL filters properly. Even if we could somehow address this, it's not clear at this point that any web engine can build a SVG on a WebWorker (and not sure if we ever want to do that), which would still leaves us with a weird situation of "we have this capability but no way for users to describe what they want". I'd also argue that the URL filter to SVG is mostly a hack to allow filters to be described, as opposed to a properly well designed spec that describes Canvas filter capabilities. Having a clear and friendlier interface would be an overall win. I'm not sure that "because some filters can be slow performing right now, let's make it hard for people to use it" is a good argument. If there was a fundamental performance problem with a feature, sure, make more expensive things harder. But if filters are useful and people start using it more, then eventually it will be worth it for us to optimize for it. Making it convoluted to use just to prevent people from using it at all sounds bad. |
We basically can't afford to optimize all fast-paths for all use-cases, so design-wise, we try to shepherd devs towards the always-fast APIs and have them write the fast-paths for their multitude of fast-paths that they care about. If we want to keep shipping things that have the most impact for the most users, we don't want to design a system that encourages us to clean up after devs that string together friendly interfaces that are hard to optimize. Put another way, I want to focus on providing the web with features that aren't possible today, rather than signing us up for perpetual maintenance for keeping these other APIs fast through sheer force of engineering. This is not about making it convoluted, but cutting our losses and not making it easier to fall into the performance pits that we already have coming from svg. |
It seems indeed none can do it yet, but OffscreenCanvas support is limited to Blink based browsers currently.
There are already at least two places where the specs currently expect this feature:
Also one advantage of the current CanvasFilter is its direct parallel with CSS. If you really want to go the Primitives interface way, I guess it might be good to consider how this could fit there too. |
I have few thoughts about the two proposals in https://github.com/fserb/canvas2D/blob/master/spec/filters.md: For the main proposal:
For the alternative proposal:
Regarding both proposals
Finally I have these two questions, I think the filter will be applied to every individual drawing. In this example:
the rect and the circle will be blurred separately. What should a web developer do to blur the rect and the circle as a group? Will it be a better solution to use a stack of nested filters:
In this example the rect and the circle will be blurred as a group. The path will be blurred and will have a drop shadow. |
It's notable that the canvas API doesn't allow for graphical grouping for opacity or compositing either, so any solution for filters should also be generalizable to allow for group opacity and group composing. |
This point derives from the desire expressed in #5621 (comment) to start with only a very limited API, and particularly to "start with the "linked-list" model of filters that the css filter() function accepts, rather than arbitrary graphs that are allowed by SVG". This is addressed in the current PR which you may want to review: https://whatpr.org/html/6763/canvas.html. So currently the only inputs are indeed
Once again, some work has been made in the PR to clear this up. Basically the current status is that all properties are accepted but only the ones that match with a valid attribute for said filter element would apply, minus core, presentation, filter primitives and "class", "style", "in", and "filter" attributes (which is a pain-point for me).
That's a point I agree on.
This is a good point, I think currently the conversion model only expects numbers, which would thus forbid the use of relative units, but given the small subset of supported filters and that currently filter primitives and presentation attributes are ignored, I doubt this is really a problem for now, is it?
As Simon said, this is not a problem that's unique to filters, the whole canvas API could benefit from such a thing, which we can currently workaround by using a second canvas. |
Tests: WPT html/canvas/element/manual/filters, html/canvas/element/filters, and html/canvas/offscreen/filters. Closes whatwg#5621.
I'm surprised this was merged without more discussion, particularly about how to achieve group effects. I think the API as it stands is a footgun, encouraging authors to write inefficient code (where every drawing effect gets filtered), and getting incorrect results (expectations of grouped effects where none occurs). Not all implementations can simply map filters to GPU shaders, so filter operations can have significant cost. Filtering on every draw call has potentially high performance cost on those platforms. |
Could you clarify what in this API makes the users expect "grouped effects" more than the simple CSS filters syntax we have for years? It seems that you want a layer API, which was discussed in #7329 though it's currently postponed. |
@smfr I'm sorry, it wasn't clear to me your feedback was blocking / not addressed. Could you please open a new issue to track this? Hopefully @mysteryDate can address it. |
Did the filters feature actually meet the “support of at least two implementers” requirement for adding features? I think maybe it didn’t. The PR lists WebKit and Chromium as the supporting implementers but it seems WebKit did not actually support; the three WebKit folks who spoke up in this issue all had objections that I don’t think were addressed in what was merged (despite an earlier email statement that this feature generally sounds ok). |
That is a good point. Mozilla was not too enthusiastic about this, though we did not block. I created #7874 to revert, though it seems that is not as straightforward as I would have hoped. Hopefully @mysteryDate or @domenic can help out. |
Reading back the first comment by @litherum it seems the Webkit team is arguing against The proposal here was to extend this feature with a |
Yeah, if WebKit is against I notice that PR cites https://lists.webkit.org/pipermail/webkit-dev/2021-May/031840.html which contains the exchange
Perhaps it wasn't clear to @smfr that "better support for SVG filters" was referring specifically to the proposal in #6763. We will try to do better as editors about getting explicit support instead of relying on this sort of more-vague statement. |
It's important to try to tease apart "integration of filters into canvas2D" and "a specific formulation of the API that makes it way harder to create group effects than it is to apply individually to each drawing command independently." We haven't argued against the integration of filters into canvas2D. We do believe, though, that a single individual drawing command is almost never sufficient to display anything interesting; drawing commands naturally need to be grouped together in collections to create images/graphics. An API that applies filters independently to each individual drawing command is bad for everyone:
We understand that it is possible to use this API in conjunction with drawing canvases-to-other-canvases to create group effects. Our concerns are about how it's easier to use such an API poorly than it would be to use it correctly. We're referring to the "pit of success" idea here. There are many potential ways of alleviating these concerns, each with pros and cons:
I think this is a ripe area for constructive design and collaboration; let's try to move forward together to make 2D canvas as great as it can be!! |
So you want two different APIs to apply filters? Also, I once again recommend you to have a look at the Canvas Layers proposal since all your concerns are exactly the goal it tried to reach, with the added benefit that it would also work for globalAlpha, compositing, etc. |
I agree with @Kaiido, it seems that the problems people are having with this API are orthogonal to the API itself, and were addressed on the Canvas Layer proposal. Is the argument here that there should be a |
I've added the agenda+, and it would be nice if people could come to the meeting so we can discuss this. From my understanding so far, it seems people are opposed to the I'm happy to discuss alternative ways of setting filters (with layers, for example). Or any other issue people may have. |
The |
A javascript interface for using SVG filters within canvas.
The SVG filter exposes deep, flexible drawing modifiers for 2d graphics. Integrating these into canvas 2d should be technically feasible once an interface is defined.
Working proposal: https://github.com/fserb/canvas2D/blob/master/spec/filters.md
(cc @whatwg/canvas )
The text was updated successfully, but these errors were encountered: