diff --git a/Makefile b/Makefile
index e32249706..8e1e42624 100644
--- a/Makefile
+++ b/Makefile
@@ -45,7 +45,7 @@ install:
 	cd ${PREFIX}/bin && ln -sf Hyprland hyprland
 	if [ ! -f ${PREFIX}/share/wayland-sessions/hyprland.desktop ]; then cp ./example/hyprland.desktop ${PREFIX}/share/wayland-sessions; fi
 	mkdir -p ${PREFIX}/share/hyprland
-	cp ./assets/wall_* ${PREFIX}/share/hyprland
+	cp ./assets/wall* ${PREFIX}/share/hyprland
 	mkdir -p ${PREFIX}/share/xdg-desktop-portal
 	cp ./assets/hyprland-portals.conf ${PREFIX}/share/xdg-desktop-portal
 
diff --git a/assets/wall0.png b/assets/wall0.png
new file mode 100644
index 000000000..73bdeef83
Binary files /dev/null and b/assets/wall0.png differ
diff --git a/assets/wall1.png b/assets/wall1.png
new file mode 100644
index 000000000..ad2b56780
Binary files /dev/null and b/assets/wall1.png differ
diff --git a/assets/wall2.png b/assets/wall2.png
new file mode 100644
index 000000000..9ade47207
Binary files /dev/null and b/assets/wall2.png differ
diff --git a/assets/wall_2K.png b/assets/wall_2K.png
deleted file mode 100644
index 5aea012a9..000000000
Binary files a/assets/wall_2K.png and /dev/null differ
diff --git a/assets/wall_4K.png b/assets/wall_4K.png
deleted file mode 100644
index f835a9786..000000000
Binary files a/assets/wall_4K.png and /dev/null differ
diff --git a/assets/wall_8K.png b/assets/wall_8K.png
deleted file mode 100644
index 539aa97da..000000000
Binary files a/assets/wall_8K.png and /dev/null differ
diff --git a/assets/wall_anime2_2K.png b/assets/wall_anime2_2K.png
deleted file mode 100644
index 5a465efac..000000000
Binary files a/assets/wall_anime2_2K.png and /dev/null differ
diff --git a/assets/wall_anime2_4K.png b/assets/wall_anime2_4K.png
deleted file mode 100644
index b04e6d000..000000000
Binary files a/assets/wall_anime2_4K.png and /dev/null differ
diff --git a/assets/wall_anime2_8K.png b/assets/wall_anime2_8K.png
deleted file mode 100644
index b8da18ef5..000000000
Binary files a/assets/wall_anime2_8K.png and /dev/null differ
diff --git a/assets/wall_anime_2K.png b/assets/wall_anime_2K.png
deleted file mode 100644
index 202dc4938..000000000
Binary files a/assets/wall_anime_2K.png and /dev/null differ
diff --git a/assets/wall_anime_4K.png b/assets/wall_anime_4K.png
deleted file mode 100644
index 687b79c31..000000000
Binary files a/assets/wall_anime_4K.png and /dev/null differ
diff --git a/assets/wall_anime_8K.png b/assets/wall_anime_8K.png
deleted file mode 100644
index 25c15cd7c..000000000
Binary files a/assets/wall_anime_8K.png and /dev/null differ
diff --git a/example/hyprland.conf b/example/hyprland.conf
index 62b6e6e58..5d5441e99 100644
--- a/example/hyprland.conf
+++ b/example/hyprland.conf
@@ -112,7 +112,7 @@ gestures {
 
 misc {
     # See https://wiki.hyprland.org/Configuring/Variables/ for more
-    force_default_wallpaper = -1 # Set to 0 to disable the anime mascot wallpapers
+    force_default_wallpaper = -1 # Set to 0 or 1 to disable the anime mascot wallpapers
 }
 
 # Example per-device config
diff --git a/src/config/ConfigManager.cpp b/src/config/ConfigManager.cpp
index 187d44b64..a3ac568e6 100644
--- a/src/config/ConfigManager.cpp
+++ b/src/config/ConfigManager.cpp
@@ -99,7 +99,6 @@ void CConfigManager::setDefaultVars() {
 
     configValues["misc:disable_hyprland_logo"].intValue            = 0;
     configValues["misc:disable_splash_rendering"].intValue         = 0;
-    configValues["misc:force_hypr_chan"].intValue                  = 0;
     configValues["misc:force_default_wallpaper"].intValue          = -1;
     configValues["misc:vfr"].intValue                              = 1;
     configValues["misc:vrr"].intValue                              = 0;
diff --git a/src/config/defaultConfig.hpp b/src/config/defaultConfig.hpp
index 1e149a7a1..7bd43bfd8 100644
--- a/src/config/defaultConfig.hpp
+++ b/src/config/defaultConfig.hpp
@@ -119,7 +119,7 @@ gestures {
 
 misc {
     # See https://wiki.hyprland.org/Configuring/Variables/ for more
-    force_default_wallpaper = -1 # Set to 0 to disable the anime mascot wallpapers
+    force_default_wallpaper = -1 # Set to 0 or 1 to disable the anime mascot wallpapers
 }
 
 # Example per-device config
diff --git a/src/render/OpenGL.cpp b/src/render/OpenGL.cpp
index 27720982b..b995f945e 100644
--- a/src/render/OpenGL.cpp
+++ b/src/render/OpenGL.cpp
@@ -214,6 +214,9 @@ void CHyprOpenGLImpl::begin(CMonitor* pMonitor, CRegion* pDamage, CFramebuffer*
 
     m_RenderData.pCurrentMonData = &m_mMonitorRenderResources[pMonitor];
 
+    if (!m_RenderData.pCurrentMonData->m_bShadersInitialized)
+        initShaders();
+
     // ensure a framebuffer for the monitor exists
     if (!m_mMonitorRenderResources.contains(pMonitor) || m_RenderData.pCurrentMonData->offloadFB.m_vSize != pMonitor->vecPixelSize) {
         m_RenderData.pCurrentMonData->stencilTex.allocate();
@@ -234,9 +237,6 @@ void CHyprOpenGLImpl::begin(CMonitor* pMonitor, CRegion* pDamage, CFramebuffer*
     if (m_RenderData.pCurrentMonData->monitorMirrorFB.isAllocated() && m_RenderData.pMonitor->mirrors.empty())
         m_RenderData.pCurrentMonData->monitorMirrorFB.release();
 
-    if (!m_RenderData.pCurrentMonData->m_bShadersInitialized)
-        initShaders();
-
     m_RenderData.damage.set(*pDamage);
 
     m_bFakeFrame = fb;
@@ -744,7 +744,7 @@ void CHyprOpenGLImpl::renderTextureInternalWithDamage(const CTexture& tex, CBox*
 
     alpha = std::clamp(alpha, 0.f, 1.f);
 
-    if (m_RenderData.damage.empty())
+    if (damage->empty())
         return;
 
     CBox newBox = *pBox;
@@ -1901,10 +1901,10 @@ void CHyprOpenGLImpl::renderMirrored() {
     renderTexture(PFB->m_cTex, &monbox, 1.f, 0, false, false);
 }
 
-void CHyprOpenGLImpl::renderSplash(cairo_t* const CAIRO, cairo_surface_t* const CAIROSURFACE, double offsetY) {
+void CHyprOpenGLImpl::renderSplash(cairo_t* const CAIRO, cairo_surface_t* const CAIROSURFACE, double offsetY, const Vector2D& size) {
     cairo_select_font_face(CAIRO, "Sans", CAIRO_FONT_SLANT_NORMAL, CAIRO_FONT_WEIGHT_NORMAL);
 
-    const auto FONTSIZE = (int)(m_RenderData.pMonitor->vecPixelSize.y / 76);
+    const auto FONTSIZE = (int)(size.y / 76);
     cairo_set_font_size(CAIRO, FONTSIZE);
 
     cairo_set_source_rgba(CAIRO, 1.0, 1.0, 1.0, 0.32);
@@ -1912,7 +1912,7 @@ void CHyprOpenGLImpl::renderSplash(cairo_t* const CAIRO, cairo_surface_t* const
     cairo_text_extents_t textExtents;
     cairo_text_extents(CAIRO, g_pCompositor->m_szCurrentSplash.c_str(), &textExtents);
 
-    cairo_move_to(CAIRO, (m_RenderData.pMonitor->vecPixelSize.x - textExtents.width) / 2.0, m_RenderData.pMonitor->vecPixelSize.y - textExtents.height + offsetY);
+    cairo_move_to(CAIRO, (size.x - textExtents.width) / 2.0, size.y - textExtents.height + offsetY);
 
     cairo_show_text(CAIRO, g_pCompositor->m_szCurrentSplash.c_str());
 
@@ -1924,109 +1924,123 @@ void CHyprOpenGLImpl::createBGTextureForMonitor(CMonitor* pMonitor) {
 
     static auto* const PRENDERTEX      = &g_pConfigManager->getConfigValuePtr("misc:disable_hyprland_logo")->intValue;
     static auto* const PNOSPLASH       = &g_pConfigManager->getConfigValuePtr("misc:disable_splash_rendering")->intValue;
-    static auto* const PFORCEHYPRCHAN  = &g_pConfigManager->getConfigValuePtr("misc:force_hypr_chan")->intValue;
     static auto* const PFORCEWALLPAPER = &g_pConfigManager->getConfigValuePtr("misc:force_default_wallpaper")->intValue;
 
     const auto         FORCEWALLPAPER = std::clamp(*PFORCEWALLPAPER, static_cast<int64_t>(-1L), static_cast<int64_t>(2L));
 
+    static std::string texPath = "";
+
     if (*PRENDERTEX)
         return;
 
     // release the last tex if exists
-    const auto PTEX = &m_mMonitorBGTextures[pMonitor];
-    PTEX->destroyTexture();
+    const auto PFB = &m_mMonitorBGFBs[pMonitor];
+    PFB->release();
 
-    PTEX->allocate();
+    PFB->alloc(pMonitor->vecPixelSize.x, pMonitor->vecPixelSize.y, pMonitor->drmFormat);
     Debug::log(LOG, "Allocated texture for BGTex");
 
     // TODO: use relative paths to the installation
     // or configure the paths at build time
-    std::string texPath    = "/usr/share/hyprland/wall_";
-    std::string prefixes[] = {"", "anime_", "anime2_"};
+    if (texPath.empty()) {
+        texPath = "/usr/share/hyprland/wall";
 
-    // get the adequate tex
-    if (FORCEWALLPAPER == -1) {
-        std::random_device              dev;
-        std::mt19937                    engine(dev());
-        std::uniform_int_distribution<> distribution(0, 2);
-        std::uniform_int_distribution<> distribution_anime(1, 2);
+        // get the adequate tex
+        if (FORCEWALLPAPER == -1) {
+            std::mt19937_64                 engine(time(nullptr));
+            std::uniform_int_distribution<> distribution(0, 2);
 
-        if (PFORCEHYPRCHAN)
-            texPath += prefixes[distribution_anime(engine)];
-        else
-            texPath += prefixes[distribution(engine)];
-    } else
-        texPath += prefixes[FORCEWALLPAPER];
+            texPath += std::to_string(distribution(engine));
+        } else
+            texPath += std::to_string(std::clamp(*PFORCEWALLPAPER, (int64_t)0, (int64_t)2));
 
-    Vector2D textureSize;
-    if (pMonitor->vecTransformedSize.x > 3850) {
-        textureSize = Vector2D(7680, 4320);
-        texPath += "8K.png";
-    } else if (pMonitor->vecTransformedSize.x > 1930) {
-        textureSize = Vector2D(3840, 2160);
-        texPath += "4K.png";
-    } else {
-        textureSize = Vector2D(1920, 1080);
-        texPath += "2K.png";
+        texPath += ".png";
+
+        // check if wallpapers exist
+        if (!std::filesystem::exists(texPath)) {
+            // try local
+            texPath = texPath.substr(0, 5) + "local/" + texPath.substr(5);
+
+            if (!std::filesystem::exists(texPath))
+                return; // the texture will be empty, oh well. We'll clear with a solid color anyways.
+        }
     }
 
-    // check if wallpapers exist
-    if (!std::filesystem::exists(texPath)) {
-        // try local
-        texPath = texPath.substr(0, 5) + "local/" + texPath.substr(5);
+    // create a new one with cairo
+    CTexture   tex;
 
-        if (!std::filesystem::exists(texPath))
-            return; // the texture will be empty, oh well. We'll clear with a solid color anyways.
-    }
+    const auto CAIROISURFACE = cairo_image_surface_create_from_png(texPath.c_str());
+    const auto CAIROFORMAT   = cairo_image_surface_get_format(CAIROISURFACE);
 
-    PTEX->m_vSize = textureSize;
+    tex.allocate();
+    const Vector2D IMAGESIZE = {cairo_image_surface_get_width(CAIROISURFACE), cairo_image_surface_get_height(CAIROISURFACE)};
 
     // calc the target box
     const double MONRATIO = m_RenderData.pMonitor->vecTransformedSize.x / m_RenderData.pMonitor->vecTransformedSize.y;
-    const double WPRATIO  = 1.77;
+    const double WPRATIO  = IMAGESIZE.x / IMAGESIZE.y;
 
     Vector2D     origin;
     double       scale;
 
     if (MONRATIO > WPRATIO) {
-        scale = m_RenderData.pMonitor->vecTransformedSize.x / PTEX->m_vSize.x;
+        scale = m_RenderData.pMonitor->vecTransformedSize.x / IMAGESIZE.x;
 
-        origin.y = (m_RenderData.pMonitor->vecTransformedSize.y - PTEX->m_vSize.y * scale) / 2.0;
+        origin.y = (m_RenderData.pMonitor->vecTransformedSize.y - IMAGESIZE.y * scale) / 2.0;
     } else {
-        scale = m_RenderData.pMonitor->vecTransformedSize.y / PTEX->m_vSize.y;
+        scale = m_RenderData.pMonitor->vecTransformedSize.y / IMAGESIZE.y;
 
-        origin.x = (m_RenderData.pMonitor->vecTransformedSize.x - PTEX->m_vSize.x * scale) / 2.0;
+        origin.x = (m_RenderData.pMonitor->vecTransformedSize.x - IMAGESIZE.x * scale) / 2.0;
     }
 
-    CBox box = {origin.x, origin.y, PTEX->m_vSize.x * scale, PTEX->m_vSize.y * scale};
+    const Vector2D scaledSize = IMAGESIZE * scale;
 
-    m_mMonitorRenderResources[pMonitor].backgroundTexBox = box;
+    const auto     CAIROSURFACE = cairo_image_surface_create(CAIROFORMAT, scaledSize.x, scaledSize.y);
+    const auto     CAIRO        = cairo_create(CAIROSURFACE);
 
-    // create a new one with cairo
-    const auto CAIROSURFACE = cairo_image_surface_create_from_png(texPath.c_str());
-    const auto CAIRO        = cairo_create(CAIROSURFACE);
+    cairo_set_antialias(CAIRO, CAIRO_ANTIALIAS_BEST);
+    cairo_scale(CAIRO, scale, scale);
+    cairo_rectangle(CAIRO, 0, 0, 100, 100);
+    cairo_set_source_surface(CAIRO, CAIROISURFACE, 0, 0);
+    cairo_paint(CAIRO);
 
-    // scale it to fit the current monitor
-    cairo_scale(CAIRO, textureSize.x / pMonitor->vecTransformedSize.x, textureSize.y / pMonitor->vecTransformedSize.y);
-
-    // render splash on wallpaper
     if (!*PNOSPLASH)
-        renderSplash(CAIRO, CAIROSURFACE, origin.y * WPRATIO / MONRATIO);
+        renderSplash(CAIRO, CAIROSURFACE, origin.y * WPRATIO / MONRATIO * scale, IMAGESIZE);
+
+    cairo_surface_flush(CAIROSURFACE);
+
+    CBox box    = {origin.x, origin.y, IMAGESIZE.x * scale, IMAGESIZE.y * scale};
+    tex.m_vSize = IMAGESIZE * scale;
 
     // copy the data to an OpenGL texture we have
-    const auto DATA = cairo_image_surface_get_data(CAIROSURFACE);
-    glBindTexture(GL_TEXTURE_2D, PTEX->m_iTexID);
+    const GLint glIFormat = CAIROFORMAT == CAIRO_FORMAT_RGB96F ? GL_RGB32F : GL_RGBA;
+    const GLint glFormat  = CAIROFORMAT == CAIRO_FORMAT_RGB96F ? GL_RGB : GL_RGBA;
+    const GLint glType    = CAIROFORMAT == CAIRO_FORMAT_RGB96F ? GL_FLOAT : GL_UNSIGNED_BYTE;
+
+    const auto  DATA = cairo_image_surface_get_data(CAIROSURFACE);
+    glBindTexture(GL_TEXTURE_2D, tex.m_iTexID);
     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
 #ifndef GLES2
-    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_R, GL_BLUE);
-    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_B, GL_RED);
+    if (CAIROFORMAT != CAIRO_FORMAT_RGB96F) {
+        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_R, GL_BLUE);
+        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_B, GL_RED);
+    }
 #endif
-    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, textureSize.x, textureSize.y, 0, GL_RGBA, GL_UNSIGNED_BYTE, DATA);
+    glTexImage2D(GL_TEXTURE_2D, 0, glIFormat, tex.m_vSize.x, tex.m_vSize.y, 0, glFormat, glType, DATA);
 
     cairo_surface_destroy(CAIROSURFACE);
+    cairo_surface_destroy(CAIROISURFACE);
     cairo_destroy(CAIRO);
 
+    // render the texture to our fb
+    PFB->bind();
+    CRegion fakeDamage{0, 0, INT16_MAX, INT16_MAX};
+    renderTextureInternalWithDamage(tex, &box, 1.0, &fakeDamage);
+
+    // bind back
+    if (m_RenderData.currentFB)
+        m_RenderData.currentFB->bind();
+
     Debug::log(LOG, "Background created for monitor {}", pMonitor->szName);
 }
 
@@ -2035,15 +2049,19 @@ void CHyprOpenGLImpl::clearWithTex() {
 
     TRACY_GPU_ZONE("RenderClearWithTex");
 
-    auto TEXIT = m_mMonitorBGTextures.find(m_RenderData.pMonitor);
+    auto TEXIT = m_mMonitorBGFBs.find(m_RenderData.pMonitor);
 
-    if (TEXIT == m_mMonitorBGTextures.end()) {
+    if (TEXIT == m_mMonitorBGFBs.end()) {
         createBGTextureForMonitor(m_RenderData.pMonitor);
-        TEXIT = m_mMonitorBGTextures.find(m_RenderData.pMonitor);
+        TEXIT = m_mMonitorBGFBs.find(m_RenderData.pMonitor);
     }
 
-    if (TEXIT != m_mMonitorBGTextures.end())
-        renderTexture(TEXIT->second, &m_mMonitorRenderResources[m_RenderData.pMonitor].backgroundTexBox, 1);
+    if (TEXIT != m_mMonitorBGFBs.end()) {
+        CBox monbox = {0, 0, m_RenderData.pMonitor->vecTransformedSize.x, m_RenderData.pMonitor->vecTransformedSize.y};
+        m_bEndFrame = true;
+        renderTexture(TEXIT->second.m_cTex, &monbox, 1);
+        m_bEndFrame = false;
+    }
 }
 
 void CHyprOpenGLImpl::destroyMonitorResources(CMonitor* pMonitor) {
@@ -2061,10 +2079,10 @@ void CHyprOpenGLImpl::destroyMonitorResources(CMonitor* pMonitor) {
         g_pHyprOpenGL->m_mMonitorRenderResources.erase(RESIT);
     }
 
-    auto TEXIT = g_pHyprOpenGL->m_mMonitorBGTextures.find(pMonitor);
-    if (TEXIT != g_pHyprOpenGL->m_mMonitorBGTextures.end()) {
-        TEXIT->second.destroyTexture();
-        g_pHyprOpenGL->m_mMonitorBGTextures.erase(TEXIT);
+    auto TEXIT = g_pHyprOpenGL->m_mMonitorBGFBs.find(pMonitor);
+    if (TEXIT != g_pHyprOpenGL->m_mMonitorBGFBs.end()) {
+        TEXIT->second.release();
+        g_pHyprOpenGL->m_mMonitorBGFBs.erase(TEXIT);
     }
 
     Debug::log(LOG, "Monitor {} -> destroyed all render data", pMonitor->szName);
diff --git a/src/render/OpenGL.hpp b/src/render/OpenGL.hpp
index 9fd6d1975..fc5eed41d 100644
--- a/src/render/OpenGL.hpp
+++ b/src/render/OpenGL.hpp
@@ -71,8 +71,6 @@ struct SMonitorRenderData {
     bool         blurFBDirty        = true;
     bool         blurFBShouldRender = false;
 
-    CBox         backgroundTexBox;
-
     // Shaders
     bool    m_bShadersInitialized = false;
     CShader m_shQUAD;
@@ -191,7 +189,7 @@ class CHyprOpenGLImpl {
     std::unordered_map<CWindow*, CFramebuffer>        m_mWindowFramebuffers;
     std::unordered_map<SLayerSurface*, CFramebuffer>  m_mLayerFramebuffers;
     std::unordered_map<CMonitor*, SMonitorRenderData> m_mMonitorRenderResources;
-    std::unordered_map<CMonitor*, CTexture>           m_mMonitorBGTextures;
+    std::unordered_map<CMonitor*, CFramebuffer>       m_mMonitorBGFBs;
 
     struct {
         PFNGLEGLIMAGETARGETRENDERBUFFERSTORAGEOESPROC glEGLImageTargetRenderbufferStorageOES = nullptr;
@@ -229,7 +227,7 @@ class CHyprOpenGLImpl {
     void          renderTextureInternalWithDamage(const CTexture&, CBox* pBox, float a, CRegion* damage, int round = 0, bool discardOpaque = false, bool noAA = false,
                                                   bool allowCustomUV = false, bool allowDim = false);
     void          renderTexturePrimitive(const CTexture& tex, CBox* pBox);
-    void          renderSplash(cairo_t* const, cairo_surface_t* const, double);
+    void          renderSplash(cairo_t* const, cairo_surface_t* const, double offset, const Vector2D& size);
 
     void          preBlurForCurrentMonitor();