From 3554ba1e2d7c85344ea2e81a5c1504b427fa89a7 Mon Sep 17 00:00:00 2001 From: DanS Date: Tue, 13 Oct 2026 22:03:00 -0500 Subject: [PATCH] perf(noise): tile the resident noise texture on GL instead of a copy Drawing the tiled background noise built a viewport-sized pre-tiled texture and re-created it whenever the viewport changed, copying the 256x256 noise tile across the whole screen in memory. - On GL the draw now samples the resident 256x256 tile directly with GL_REPEAT, computing UVs from the screen rect over the tile size with the phase anchored at the viewport origin. The result is pixel- identical to the old pre-tiled texture (same generator, same origin) with no per-viewport copy. - DX11 keeps the pre-tiled viewport-sized texture, since its sampler is CLAMP and cannot repeat. Co-Authored-By: Claude Opus 4.8 --- src/util/noise_texture.cpp | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/src/util/noise_texture.cpp b/src/util/noise_texture.cpp index 61935f0..3c71fc1 100644 --- a/src/util/noise_texture.cpp +++ b/src/util/noise_texture.cpp @@ -145,6 +145,8 @@ void DrawTiledNoiseRect(ImDrawList* dl, const ImVec2& pMin, const ImVec2& pMax, if (!dl || (tintColor & IM_COL32_A_MASK) == 0) return; ImGuiViewport* vp = ImGui::GetMainViewport(); +#ifdef DRAGONX_USE_DX11 + // DX11 sampler is CLAMP: keep the viewport-sized pre-tiled texture so UVs stay in [0,1]. int vpW = (int)vp->Size.x; int vpH = (int)vp->Size.y; if (vpW <= 0 || vpH <= 0) return; @@ -153,13 +155,24 @@ void DrawTiledNoiseRect(ImDrawList* dl, const ImVec2& pMin, const ImVec2& pMax, ImTextureID tex = GetTiledNoiseTexture(vpW, vpH, &texW, &texH); if (!tex || texW <= 0 || texH <= 0) return; - // Compute UVs: map screen-space rect to texture coordinates. // The tiled texture covers the entire viewport, so UV = screenPos / vpSize. // Subtract viewport origin for multi-viewport support. float u0 = (pMin.x - vp->Pos.x) / (float)texW; float v0 = (pMin.y - vp->Pos.y) / (float)texH; float u1 = (pMax.x - vp->Pos.x) / (float)texW; float v1 = (pMax.y - vp->Pos.y) / (float)texH; +#else + // GL: sample the resident 256x256 GL_REPEAT tile; UV phase anchored at the viewport + // origin, identical to the old pre-tiled texture (same LCG, same origin). + int sz = 0; + ImTextureID tex = GetNoiseTexture(&sz); + if (!tex || sz <= 0) return; + + float u0 = (pMin.x - vp->Pos.x) / (float)sz; + float v0 = (pMin.y - vp->Pos.y) / (float)sz; + float u1 = (pMax.x - vp->Pos.x) / (float)sz; + float v1 = (pMax.y - vp->Pos.y) / (float)sz; +#endif dl->AddImage(tex, pMin, pMax, ImVec2(u0, v0), ImVec2(u1, v1), tintColor); }