aboutsummaryrefslogtreecommitdiff
path: root/wiki
diff options
context:
space:
mode:
authorIvan Molodetskikh <yalterz@gmail.com>2024-05-12 09:56:11 +0400
committerIvan Molodetskikh <yalterz@gmail.com>2024-05-12 09:56:11 +0400
commit36a54615caf82d5509eeea2e096a16e6d6588aff (patch)
tree70d72d944b867a95e9273060128a1ff68e8be31a /wiki
parent9004c8395438038d69f7b479a8a9035663cb4be0 (diff)
downloadniri-36a54615caf82d5509eeea2e096a16e6d6588aff.tar.gz
niri-36a54615caf82d5509eeea2e096a16e6d6588aff.tar.bz2
niri-36a54615caf82d5509eeea2e096a16e6d6588aff.zip
Add crossfade_or_crop_next resize shader example
Diffstat (limited to 'wiki')
-rw-r--r--wiki/examples/resize_custom_shader.frag44
1 files changed, 44 insertions, 0 deletions
diff --git a/wiki/examples/resize_custom_shader.frag b/wiki/examples/resize_custom_shader.frag
index a95e678f..3c2ad0b5 100644
--- a/wiki/examples/resize_custom_shader.frag
+++ b/wiki/examples/resize_custom_shader.frag
@@ -159,6 +159,50 @@ vec4 stretch_or_crop_next(vec3 coords_curr_geo, vec3 size_curr_geo) {
return color;
}
+// Example: cropped next texture if it's bigger than the current geometry, and
+// crossfade between previous and next texture otherwise.
+vec4 crossfade_or_crop_next(vec3 coords_curr_geo, vec3 size_curr_geo) {
+ vec3 coords_next_geo = niri_curr_geo_to_next_geo * coords_curr_geo;
+ vec3 coords_prev_geo = niri_curr_geo_to_prev_geo * coords_curr_geo;
+
+ vec3 coords_crop = niri_geo_to_tex_next * coords_next_geo;
+ vec3 coords_stretch = niri_geo_to_tex_next * coords_curr_geo;
+ vec3 coords_stretch_prev = niri_geo_to_tex_prev * coords_curr_geo;
+
+ // We can crop if the current window size is smaller than the next window
+ // size. One way to tell is by comparing to 1.0 the X and Y scaling
+ // coefficients in the current-to-next transformation matrix.
+ bool can_crop_by_x = niri_curr_geo_to_next_geo[0][0] <= 1.0;
+ bool can_crop_by_y = niri_curr_geo_to_next_geo[1][1] <= 1.0;
+ bool crop = can_crop_by_x && can_crop_by_y;
+
+ vec4 color;
+
+ if (crop) {
+ // However, when we crop, we also want to crop out anything outside the
+ // current geometry. This is because the area of the shader is unspecified
+ // and usually bigger than the current geometry, so if we don't fill pixels
+ // outside with transparency, the texture will leak out.
+ //
+ // When crossfading, this is not an issue because the area outside will
+ // correspond to client-side decoration shadows, which are already supposed
+ // to be outside.
+ if (coords_curr_geo.x < 0.0 || 1.0 < coords_curr_geo.x ||
+ coords_curr_geo.y < 0.0 || 1.0 < coords_curr_geo.y) {
+ color = vec4(0.0);
+ } else {
+ color = texture2D(niri_tex_next, coords_crop.st);
+ }
+ } else {
+ // If we can't crop, then crossfade.
+ color = texture2D(niri_tex_next, coords_stretch.st);
+ vec4 color_prev = texture2D(niri_tex_prev, coords_stretch_prev.st);
+ color = mix(color_prev, color, niri_clamped_progress);
+ }
+
+ return color;
+}
+
// This is the function that you must define.
vec4 resize_color(vec3 coords_curr_geo, vec3 size_curr_geo) {
// You can pick one of the example functions or write your own.