diff options
| author | Ivan Molodetskikh <yalterz@gmail.com> | 2024-05-12 09:52:21 +0400 |
|---|---|---|
| committer | Ivan Molodetskikh <yalterz@gmail.com> | 2024-05-12 09:52:36 +0400 |
| commit | 9004c8395438038d69f7b479a8a9035663cb4be0 (patch) | |
| tree | 349acfc1e9ac7df31bb52db66f7f9e8a59d19e79 /wiki/examples | |
| parent | 29c7552852874a08f9e70ed52ddfb6be8f55bc69 (diff) | |
| download | niri-9004c8395438038d69f7b479a8a9035663cb4be0.tar.gz niri-9004c8395438038d69f7b479a8a9035663cb4be0.tar.bz2 niri-9004c8395438038d69f7b479a8a9035663cb4be0.zip | |
Implement custom shader for window-close anim
Diffstat (limited to 'wiki/examples')
| -rw-r--r-- | wiki/examples/close_custom_shader.frag | 113 | ||||
| -rw-r--r-- | wiki/examples/resize_custom_shader.frag | 7 |
2 files changed, 118 insertions, 2 deletions
diff --git a/wiki/examples/close_custom_shader.frag b/wiki/examples/close_custom_shader.frag new file mode 100644 index 00000000..8a777b99 --- /dev/null +++ b/wiki/examples/close_custom_shader.frag @@ -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); +} + diff --git a/wiki/examples/resize_custom_shader.frag b/wiki/examples/resize_custom_shader.frag index 71710a9f..a95e678f 100644 --- a/wiki/examples/resize_custom_shader.frag +++ b/wiki/examples/resize_custom_shader.frag @@ -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. |
