Along the same vein of Android's shimmer ripple, h...
# compose-desktop
k
Along the same vein of Android's shimmer ripple, here's a more realistic example of a "decorator" shader-based runtime effect applied on a button. The button on the left is a regular Aurora button, and the one on the right is configured with a render effect that uses a shader to draw an outside glow when the mouse moves over that button. No need to increase the layout bounds of the button. No need for the button composable itself to be "aware" of this glow drawn around it. The render effect layer handles all of that, and all you need to do is pass all the relevant info (in this case corner radius, glow amount, max glow distance and glow color) into the shader. And of course, write the shader itself 😅
🤩 7
K 2
👍🏻 1
🔥 1
👍 9
❤️ 1
j
A challenge for you, mimic the Windows mouse effect where the glow is based on the mouse position when it is over a clickable element 🙂
message has been deleted
k
Or make every button look like the Eye of Sauron, borrowing some code from https://www.shadertoy.com/view/4dSfDK (press the mouse anywhere in the preview and slide it around)
j
love it
k
On a more serious note though, one should be careful about where the shader is applied. Depending on how strong the overall visual effect is, you might want to confine in only to outside the control (like the glow here), on top of the whole thing (like Android's ripple, which is rather subtle), or only on top of that control's background. In the later case - which is, I think, what you would want for that Windows 10 effect, so that it doesn't interfere with the foreground content like the icon and the text, the shader would need to be applied inside that composable (only on the background).
Also reminds me of the Disco app that would emulate smoke coming out of its window during the whole process of burning a CD. See

https://www.youtube.com/watch?v=zklSrGUELjA

r
I miss Disco
Did you implement the glow as an SDF?
k
The shader is not super-optimized. Or even optimized at all.
And simplified now with a round-rect SDF. Thanks for the pointer.
r
return vec4(glowRed * glowAmount, glowGreen * glowAmount, glowBlue * glowAmount, glowAmount)
you could pass a
vec3
glowColor
instead of 3 separate floats and write
return vec4(glowColor * glowAmount, glowAmount)
instead or
vec4(glowColor, 1.0) * glowAmount
k
Yes, this is something that I plan on wiring in Skiko once the currently pending PR goes in. Right now I've only added two
uniform
variants that accept one
float
and one
int
.
👍🏻 1
r
Ah right ok
BTW avoid int if you can
k
how so
r
GPUs are designed to do floats
Int computations are less efficient and going int<>float can cause stalls, etc.
So unless you have a very good reason to use an int (i.e. to index an array), use floats instead
😃 1
👍 2
👍🏻 1
k
This is me in general trying to write any kind of shader
😄 7
r
sounds about right 🙂
at least it’s 2D so you don’t have to worry about some of the more annoying crap when it comes to shaders (quad shading, derivatives, etc.)
k
Hey guys, here's a 5-part YouTube series about how this 2-line shader actually works
😄 2
r
Shaders themselves, esp in the contex of AGSL, are not very complicated
It’s writing optimized shaders that’s hard
k
Well yeah, I had that 8-part if-else-else block that got replaced by a one-liner
Not that a one-liner is necessarily more optimized, but it was in this case
r
Yeah it’s a bit complex
but roughly:
• Branches are fine if they are not divergent (i.e. many surrounding pixels will take the same branch)
• Modern GPUs are scalar, so write the code to optimize for that. For instance don’t do: float * myVec3 * float, but (float * float) * myVec3 (potentially saves 2 multiplications here)
• Trig functions (cos/sin/etc.) can often be removed in favor of other computations that will be faster. For instance dot(a, b) where a and b are unit vectors will return the cos(angle) between the two vectors
• A number of things are free: abs(), negation (-a), * 2, * 4, * 0.5, clamp(x, 0, 1). For instance clamp(-a, 0.0, 1.0) * 2.0 can become a single instruction on most (all?) modern GPUs
• Precompute what you can as uniforms
k
👍
j
this is really cool, nice work Kirill!
r
Hi @Kirill Grouchnikov how can we achieve custom blur effect in android? https://www.pushing-pixels.org/2022/04/09/shader-based-render-effects-in-compose-desktop-with-skia.html In the sample code you shared you have passed a blur shader. But I can’t pass it as it is available only in desktop version. Is there a glsl method for blurring content pixels?
I found this but couldn’t transform it to agls https://www.shadertoy.com/view/Xltfzj
r
I’ve done it