mirror of
https://github.com/niri-wm/niri.git
synced 2026-06-22 02:01:55 +07:00
Implement custom shader for window-close anim
This commit is contained in:
@@ -169,6 +169,47 @@ animations {
|
||||
}
|
||||
```
|
||||
|
||||
##### `custom-shader`
|
||||
|
||||
<sup>Since: 0.1.6, experimental</sup>
|
||||
|
||||
You can write a custom shader for drawing the window during a close animation.
|
||||
|
||||
See [this example shader](./examples/close-custom-shader.frag) for a full documentation with several animations to experiment with.
|
||||
|
||||
If a custom shader fails to compile, niri will print a warning and fall back to the default, or previous successfully compiled shader.
|
||||
|
||||
> [!WARNING]
|
||||
>
|
||||
> Custom shaders do not have a backwards compatibility guarantee.
|
||||
> I may need to change their interface as I'm developing new features.
|
||||
|
||||
Example: close will fill the current geometry with a solid gradient that gradually fades away.
|
||||
|
||||
```
|
||||
animations {
|
||||
window-resize {
|
||||
spring damping-ratio=1.0 stiffness=800 epsilon=0.0001
|
||||
|
||||
custom-shader r"
|
||||
vec4 close_color(vec3 coords_geo, vec3 size_geo) {
|
||||
vec4 color = vec4(0.0);
|
||||
|
||||
if (0.0 <= coords_geo.x && coords_geo.x <= 1.0
|
||||
&& 0.0 <= coords_geo.y && coords_geo.y <= 1.0)
|
||||
{
|
||||
vec4 from = vec4(1.0, 0.0, 0.0, 1.0);
|
||||
vec4 to = vec4(0.0, 1.0, 0.0, 1.0);
|
||||
color = mix(from, to, coords_geo.y);
|
||||
}
|
||||
|
||||
return color * (1.0 - niri_clamped_progress);
|
||||
}
|
||||
"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
#### `horizontal-view-movement`
|
||||
|
||||
All horizontal camera view movement animations, such as:
|
||||
|
||||
@@ -0,0 +1,113 @@
|
||||
// Your shader must contain one function (see the bottom of this file).
|
||||
//
|
||||
// It should not contain any uniform definitions or anything else, as niri
|
||||
// provides them for you.
|
||||
//
|
||||
// All symbols defined by niri will have a niri_ prefix, so don't use it for
|
||||
// your own variables and functions.
|
||||
|
||||
// The function that you must define looks like this:
|
||||
vec4 close_color(vec3 coords_geo, vec3 size_geo) {
|
||||
vec4 color = /* ...compute the color... */;
|
||||
return color;
|
||||
}
|
||||
|
||||
// It takes as input:
|
||||
//
|
||||
// * coords_geo: coordinates of the current pixel relative to the window
|
||||
// geometry.
|
||||
//
|
||||
// These are homogeneous (the Z component is equal to 1) and scaled in such a
|
||||
// way that the 0 to 1 coordinates lie within the window geometry. Pixels
|
||||
// outside the window geometry will have coordinates below 0 or above 1.
|
||||
//
|
||||
// The window geometry is its "visible bounds" from the user's perspective.
|
||||
//
|
||||
// The shader runs over the full screen area, so you must expect and handle
|
||||
// coordinates outside the [0, 1] range. If the window is scrolled off-screen,
|
||||
// all of the coordinates to the shader can fall outside the [0, 1] range.
|
||||
//
|
||||
// * size_geo: size of the window geometry in logical pixels.
|
||||
//
|
||||
// It is homogeneous (the Z component is equal to 1).
|
||||
//
|
||||
// The function must return the color of the pixel (with premultiplied alpha).
|
||||
// The pixel color will be further processed by niri (for example, to apply the
|
||||
// final opacity from window rules).
|
||||
|
||||
// Now let's go over the uniforms that niri defines.
|
||||
//
|
||||
// You should only rely on the uniforms documented here. Any other uniforms can
|
||||
// change or be removed without notice.
|
||||
|
||||
// The window texture.
|
||||
uniform sampler2D niri_tex;
|
||||
|
||||
// Matrix that converts geometry coordinates into the window texture
|
||||
// coordinates.
|
||||
//
|
||||
// The window texture can and will go outside the geometry (for client-side
|
||||
// decoration shadows for example), which is why this matrix is necessary.
|
||||
uniform mat3 niri_geo_to_tex;
|
||||
|
||||
|
||||
// Unclamped progress of the animation.
|
||||
//
|
||||
// Goes from 0 to 1 but may overshoot and oscillate.
|
||||
uniform float niri_progress;
|
||||
|
||||
// Clamped progress of the animation.
|
||||
//
|
||||
// Goes from 0 to 1, but will stop at 1 as soon as it first reaches 1. Will not
|
||||
// overshoot or oscillate.
|
||||
uniform float niri_clamped_progress;
|
||||
|
||||
// Random float in [0; 1), consistent for the duration of the animation.
|
||||
uniform float niri_random_seed;
|
||||
|
||||
// Now let's look at some examples. You can copy everything below this line
|
||||
// into your custom-shader to experiment.
|
||||
|
||||
// Example: fill the current geometry with a solid vertical gradient and
|
||||
// gradually make transparent.
|
||||
vec4 solid_gradient(vec3 coords_geo, vec3 size_geo) {
|
||||
vec4 color = vec4(0.0);
|
||||
|
||||
// Paint only the area inside the current geometry.
|
||||
if (0.0 <= coords_geo.x && coords_geo.x <= 1.0
|
||||
&& 0.0 <= coords_geo.y && coords_geo.y <= 1.0)
|
||||
{
|
||||
vec4 from = vec4(1.0, 0.0, 0.0, 1.0);
|
||||
vec4 to = vec4(0.0, 1.0, 0.0, 1.0);
|
||||
color = mix(from, to, coords_geo.y);
|
||||
}
|
||||
|
||||
// Make it transparent.
|
||||
color *= (1.0 - niri_clamped_progress);
|
||||
|
||||
return color;
|
||||
}
|
||||
|
||||
// Example: gradually scale down and make transparent, equivalent to the
|
||||
// default closing animation.
|
||||
vec4 default_close(vec3 coords_geo, vec3 size_geo) {
|
||||
// Scale down the window.
|
||||
float scale = max(0.0, ((1.0 - niri_clamped_progress) / 5.0 + 0.8));
|
||||
coords_geo = vec3((coords_geo.xy - vec2(0.5)) / scale + vec2(0.5), 1.0);
|
||||
|
||||
// Get color from the window texture.
|
||||
vec3 coords_tex = niri_geo_to_tex * coords_geo;
|
||||
vec4 color = texture2D(niri_tex, coords_tex.st);
|
||||
|
||||
// Make the window transparent.
|
||||
color *= (1.0 - niri_clamped_progress);
|
||||
|
||||
return color;
|
||||
}
|
||||
|
||||
// This is the function that you must define.
|
||||
vec4 close_color(vec3 coords_geo, vec3 size_geo) {
|
||||
// You can pick one of the example functions or write your own.
|
||||
return solid_gradient(coords_geo, size_geo);
|
||||
}
|
||||
|
||||
@@ -37,6 +37,9 @@ vec4 resize_color(vec3 coords_curr_geo, vec3 size_curr_geo) {
|
||||
// final opacity from window rules).
|
||||
|
||||
// Now let's go over the uniforms that niri defines.
|
||||
//
|
||||
// You should only rely on the uniforms documented here. Any other uniforms can
|
||||
// change or be removed without notice.
|
||||
|
||||
// Previous (before resize) window texture.
|
||||
uniform sampler2D niri_tex_prev;
|
||||
@@ -65,12 +68,12 @@ uniform mat3 niri_curr_geo_to_prev_geo;
|
||||
uniform mat3 niri_curr_geo_to_next_geo;
|
||||
|
||||
|
||||
// Unclamped progress of the resize.
|
||||
// Unclamped progress of the animation.
|
||||
//
|
||||
// Goes from 0 to 1 but may overshoot and oscillate.
|
||||
uniform float niri_progress;
|
||||
|
||||
// Clamped progress of the resize.
|
||||
// Clamped progress of the animation.
|
||||
//
|
||||
// Goes from 0 to 1, but will stop at 1 as soon as it first reaches 1. Will not
|
||||
// overshoot or oscillate.
|
||||
|
||||
Reference in New Issue
Block a user