{"id":3731,"date":"2026-01-30T20:06:06","date_gmt":"2026-01-31T04:06:06","guid":{"rendered":"https:\/\/rose.dev\/blog\/?p=3731"},"modified":"2026-01-30T20:06:07","modified_gmt":"2026-01-31T04:06:07","slug":"transparent-lightweight-glsl-shaders-for-wayland-hypr-focused-c","status":"publish","type":"post","link":"https:\/\/rose.dev\/blog\/2026\/01\/30\/transparent-lightweight-glsl-shaders-for-wayland-hypr-focused-c\/","title":{"rendered":"Transparent Lightweight GLSL Shaders for Wayland (Hypr Focused) C++"},"content":{"rendered":"\n<p>While customizing my desktop with fun little overlays using <a href=\"https:\/\/github.com\/hyprwm\/hyprland-plugins\/blob\/main\/hyprwinwrap\/README.md\" target=\"_blank\" rel=\"noreferrer noopener\">Hyprwinwrap<\/a>, I thought it would be really cool to display shaders on top of my wallpaper. After trying and failing to find an existing program that would suit my needs, a new project idea was born.<\/p>\n\n\n\n<p class=\"has-light-pink-color has-text-color has-link-color wp-elements-223fabc7b230c8dbc22093eb1ebe26ca\"><a href=\"https:\/\/github.com\/gen3vra\/wayland-glsl-transparent-shaders\" target=\"_blank\" rel=\"noreferrer noopener\"><strong>wayshaders <\/strong>(https:\/\/github.com\/gen3vra\/wayland-glsl-transparent-shaders)<\/a><\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Lightweight &#8211; nothing except the shader rendering engine and bare necessities<\/li>\n\n\n\n<li>Customizable &#8211; load custom shaders and settings from disk without recompiling<\/li>\n\n\n\n<li>Wayland compatible transparency &#8211; I should be able to see through the rendered window if the shader outputs an alpha below 1.0<\/li>\n\n\n\n<li>Modern GLSL compatible<\/li>\n\n\n\n<li>Ability to externally set window class for use with Hyprwinwrap so we can layer it on top of our desktop<\/li>\n<\/ul>\n\n\n\n<p>My current live wallpaper setup <strong>without <\/strong>wayshaders:<\/p>\n\n\n\n<figure class=\"wp-block-video\"><video controls loop src=\"https:\/\/rose.dev\/blog\/wp-content\/uploads\/2026\/01\/default.mp4\" playsinline><\/video><figcaption class=\"wp-element-caption\"><a href=\"https:\/\/motionbgs.com\/solitary-reflection\" target=\"_blank\" rel=\"noreferrer noopener\">https:\/\/motionbgs.com\/solitary-reflection<\/a><\/figcaption><\/figure>\n\n\n\n<p>And with a nice star shader:<\/p>\n\n\n\n<figure class=\"wp-block-video\"><video controls loop src=\"https:\/\/rose.dev\/blog\/wp-content\/uploads\/2026\/01\/stars.mp4\" playsinline><\/video><\/figure>\n\n\n\n<p>Awesome, but maybe you want something more &#8220;interesting&#8221;.<br>Here&#8217;s a ShaderToy converted shader called Eon:<\/p>\n\n\n\n<figure class=\"wp-block-video\"><video controls loop src=\"https:\/\/rose.dev\/blog\/wp-content\/uploads\/2026\/01\/eon.mp4\" playsinline><\/video><\/figure>\n\n\n\n<p>I realized early in the project most of the fun ShaderToy projects use layering with iChannels and more than one shader. This program uses a similar structure so it&#8217;s possible to achieve advanced effects.<\/p>\n\n\n\n<figure class=\"wp-block-video\"><video controls loop src=\"https:\/\/rose.dev\/blog\/wp-content\/uploads\/2026\/01\/cells.mp4\" playsinline><\/video><figcaption class=\"wp-element-caption\">Cellular automata simulation<\/figcaption><\/figure>\n\n\n\n<p>For instance, put a file named &#8220;shader0.frag\/shader0.vert&#8221; next to wayshader for a basic one shader setup. If you need multipass rendering on that one shader, simply insert <code>uniform sampler2D u_sampler0 <\/code>as a variable. <code>u_sampler0 <\/code>will then contain a reference to last frame&#8217;s buffer so you can make trails, transformations, etc.<\/p>\n\n\n\n<p>Want another layer? Easy. Add &#8220;shader1.frag\/shader1.vert&#8221; next to the program. This shader will be rendered as its own pass on top of the previous shader. <\/p>\n\n\n\n<p>The <code>u_sampler <\/code>variables are mapped to each shader&#8217;s index; <code>u_sampler0 <\/code>is always a reference to <code>shader0<\/code>&#8216;s buffer. <code>shader1<\/code> has access to <code>u_sampler1<\/code>, which is a reference to its own buffer. <code>shader2<\/code> will have access to <code>u_sampler0<\/code>, <code>u_sampler1<\/code>, and <code>u_sampler2 <\/code>(its own buffer). Supports up to 32 &#8220;channels&#8221; with the same pattern.<\/p>\n\n\n\n<p>It also provides basic inputs in the form of <code>u_resolution<\/code>, <code>u_time<\/code>, and <code>u_frame<\/code>.<\/p>\n\n\n\n<p class=\"has-light-pink-color has-text-color has-link-color wp-elements-223fabc7b230c8dbc22093eb1ebe26ca\"><a href=\"https:\/\/github.com\/gen3vra\/wayland-glsl-transparent-shaders\" target=\"_blank\" rel=\"noreferrer noopener\"><strong>wayshaders <\/strong>(https:\/\/github.com\/gen3vra\/wayland-glsl-transparent-shaders)<\/a><\/p>\n\n\n\n<p>Pull requests and feedback are always welcomed.<\/p>\n<hr>\r\nIt helps me if you share this post\r\n<br\/>\r\n<br\/>\r\nPublished 2026-01-30 20:06:06 ","protected":false},"excerpt":{"rendered":"<p>While customizing my desktop with fun little overlays using Hyprwinwrap, I thought it would be really cool to display shaders on top of my wallpaper. After trying and failing to find an existing program that would suit my needs, a new project idea was born. wayshaders (https:\/\/github.com\/gen3vra\/wayland-glsl-transparent-shaders) My current live wallpaper setup without wayshaders: And &hellip; <a href=\"https:\/\/rose.dev\/blog\/2026\/01\/30\/transparent-lightweight-glsl-shaders-for-wayland-hypr-focused-c\/\" class=\"more-link\">Continue reading <span class=\"screen-reader-text\">Transparent Lightweight GLSL Shaders for Wayland (Hypr Focused) C++<\/span><\/a><\/p>\n","protected":false},"author":1,"featured_media":3797,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"jetpack_post_was_ever_published":false,"footnotes":""},"categories":[922,832,833],"tags":[1104,1294,1293,1280,1249,1204,1212,1284,1295],"class_list":["post-3731","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-release","category-software","category-technology","tag-c-2","tag-glsl","tag-hypr","tag-hyprland","tag-linux","tag-shaders","tag-transparent","tag-wayland","tag-wayshader"],"jetpack_featured_media_url":"https:\/\/rose.dev\/blog\/wp-content\/uploads\/2026\/01\/solitary-header.avif","_links":{"self":[{"href":"https:\/\/rose.dev\/blog\/wp-json\/wp\/v2\/posts\/3731","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/rose.dev\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/rose.dev\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/rose.dev\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/rose.dev\/blog\/wp-json\/wp\/v2\/comments?post=3731"}],"version-history":[{"count":58,"href":"https:\/\/rose.dev\/blog\/wp-json\/wp\/v2\/posts\/3731\/revisions"}],"predecessor-version":[{"id":3799,"href":"https:\/\/rose.dev\/blog\/wp-json\/wp\/v2\/posts\/3731\/revisions\/3799"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/rose.dev\/blog\/wp-json\/wp\/v2\/media\/3797"}],"wp:attachment":[{"href":"https:\/\/rose.dev\/blog\/wp-json\/wp\/v2\/media?parent=3731"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/rose.dev\/blog\/wp-json\/wp\/v2\/categories?post=3731"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/rose.dev\/blog\/wp-json\/wp\/v2\/tags?post=3731"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}