-
Notifications
You must be signed in to change notification settings - Fork 137
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
Add support for blurred rounded rectangle. #665
Conversation
Implements the blurred rounded rectangle approximation outlined in https://raphlinus.github.io/graphics/2020/04/21/blurred-rounded-rects.html
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is looking really good, and works well!
The main blocking concern is copying the logic into the CPU shaders
transform: Affine, | ||
brush: Color, | ||
size: impl Into<Size>, | ||
radius: f64, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not because I expect you to do this, but because it's important that it's raised, but is it at all plausible for the corner radii to be different? I.e. make this function accept a RoundedRect
- which despite the docs, can have different radii on each corner since linebender/kurbo#166
I don't have a good understanding of the underlying maths to make this work
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I thought about this as well but seems tricky at least.
If it would be dependent on the (continuous) distance alone it would be fine in my opinion but the parameters (e.g squircle shape) derived from the corner radius would introduce dicontinuities at the quadrant boundaries, probably visible at larger filter lengths. We could derive shared parameters for the whole shape with some tradeoff in quality but without larger adjustments to the approach.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah - that's fine. I've not thought about it deeply, and I don't think that it is a necessary feature.
Thought it would be important to at least ensure that it is discussed, as much for when Raph comes through to gut-check this.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't think that it is a necessary feature.
FWIW, this definitely is a necessary feature for full CSS box-shadow support. Not sure how common they are in the wild, but the spec certainly allows authors to specify such shadows.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You should be able to emulate it with multiple rounded rectangles, each in their own clip layer. That means that you would be responsible for the behaviour in the degerenate cases. I don't think these clip layers would need to be nested.
I think it's possible you would get conflation artifacts, though...
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
https://github.com/DioxusLabs/blitz/blob/main/packages/blitz/src/renderer/multicolor_rounded_rect.rs
we implemented the maths here for rounded-rect, you might be able to find some of it helpful
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just rounded rect can be done without too much difficulty in a distance field context by, basically, setting the radius by quadrant. But in the blurred case you will definitely see discontinuities depending on the exact parameters. I think it is possible to fix, but will require some doing.
Of course another possibility is to render the rounded rect as a vector shape (as in the code Jon linked) and blur it, but (a) that's going to be slower than doing it in a shader, even with heavier math, and (b) we don't have the infrastructure in place. It would be nice to have though, as you do need that for text shadows.
I don't recommend using clips for this, it adds complexity and possible performance issues, as well as potential conflation artifacts.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for the review! I added the snapshot tests along with support in the cpu pipeline (besides fine rasterization) |
One last thought: I'd like to see this used in stats displays for background. I've put my implementations on Zulip, because I'm running into issues. Otherwise, we're just waiting on Raph for licensing confirmation on the code used from him, I think |
thanks for testing, should be fixed. A fill style was missing resulting in the rect path being interpreted as stroke. |
I've been testing this in my vello test branch for floem. Works great! It would be nice to have some docs for the std dev arg. I can see that it affects blur but that's as much as I can see. I imagine most people will be approaching this API from a web-dev background and looking for blur and won't have an understanding of the terminology in terms of gaussian blur. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This looks great, thanks! I'm not sure exactly what needs to be done to fix the snapshot issue. Also, there's been a bit more discussion about multiple radii, that would be a good followup issue (or, better, PR).
transform: Affine, | ||
brush: Color, | ||
size: impl Into<Size>, | ||
radius: f64, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just rounded rect can be done without too much difficulty in a distance field context by, basically, setting the radius by quadrant. But in the blurred case you will definitely see discontinuities depending on the exact parameters. I think it is possible to fix, but will require some doing.
Of course another possibility is to render the rounded rect as a vector shape (as in the code Jon linked) and blur it, but (a) that's going to be slower than doing it in a shader, even with heavier math, and (b) we don't have the infrastructure in place. It would be nice to have though, as you do need that for text shadows.
I don't recommend using clips for this, it adds complexity and possible performance issues, as well as potential conflation artifacts.
@msiglreith a reminder that the policy is author-merged, and I believe you have permission to press the button.
I don't follow what this is referring to though |
Implements the blurred rounded rectangle approximation outlined in https://raphlinus.github.io/graphics/2020/04/21/blurred-rounded-rects.html. Closes #640
The convolution is mostly taken verbatim from https://git.sr.ht/~raph/blurrr translated to wgsl. Added input bounds for the
erf
function due to artifacts atstd_dev < 0.1
.Possible optimizations would include moving parts of the precomputation to the CPU side, right now each tile recalculates the same values.
Scene output: