aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorVaxry <[email protected]>2023-08-03 15:11:10 +0200
committerGitHub <[email protected]>2023-08-03 15:11:10 +0200
commitd96f8ff0fe44f874700c8c132086a206132635c5 (patch)
tree59ac4147a9fcc14bbb9897618268a56ae0ca57f0
parent5c50fac907df3463492a019f01f84d547ab93650 (diff)
downloadHyprland-d96f8ff0fe44f874700c8c132086a206132635c5.tar.gz
Hyprland-d96f8ff0fe44f874700c8c132086a206132635c5.zip
renderer: Various Blur Improvements (#2877)
* move blur to its own category * blur improvements, contrast, brightness, noise
-rw-r--r--src/config/ConfigManager.cpp15
-rw-r--r--src/render/OpenGL.cpp97
-rw-r--r--src/render/OpenGL.hpp1
-rw-r--r--src/render/Renderer.cpp6
-rw-r--r--src/render/Shader.hpp4
-rw-r--r--src/render/shaders/Textures.hpp30
6 files changed, 127 insertions, 26 deletions
diff --git a/src/config/ConfigManager.cpp b/src/config/ConfigManager.cpp
index 820e81af..50132d13 100644
--- a/src/config/ConfigManager.cpp
+++ b/src/config/ConfigManager.cpp
@@ -126,12 +126,15 @@ void CConfigManager::setDefaultVars() {
configValues["debug:manual_crash"].intValue = 0;
configValues["decoration:rounding"].intValue = 0;
- configValues["decoration:blur"].intValue = 1;
- configValues["decoration:blur_size"].intValue = 8;
- configValues["decoration:blur_passes"].intValue = 1;
- configValues["decoration:blur_ignore_opacity"].intValue = 0;
- configValues["decoration:blur_new_optimizations"].intValue = 1;
- configValues["decoration:blur_xray"].intValue = 0;
+ configValues["decoration:blur:enabled"].intValue = 1;
+ configValues["decoration:blur:size"].intValue = 8;
+ configValues["decoration:blur:passes"].intValue = 1;
+ configValues["decoration:blur:ignore_opacity"].intValue = 0;
+ configValues["decoration:blur:new_optimizations"].intValue = 1;
+ configValues["decoration:blur:xray"].intValue = 0;
+ configValues["decoration:blur:noise"].floatValue = 0.0117;
+ configValues["decoration:blur:contrast"].floatValue = 0.8916;
+ configValues["decoration:blur:brightness"].floatValue = 0.8172;
configValues["decoration:active_opacity"].floatValue = 1;
configValues["decoration:inactive_opacity"].floatValue = 1;
configValues["decoration:fullscreen_opacity"].floatValue = 1;
diff --git a/src/render/OpenGL.cpp b/src/render/OpenGL.cpp
index 81401727..1040aa86 100644
--- a/src/render/OpenGL.cpp
+++ b/src/render/OpenGL.cpp
@@ -321,6 +321,16 @@ void CHyprOpenGLImpl::initShaders() {
m_RenderData.pCurrentMonData->m_shBLUR2.radius = glGetUniformLocation(prog, "radius");
m_RenderData.pCurrentMonData->m_shBLUR2.halfpixel = glGetUniformLocation(prog, "halfpixel");
+ prog = createProgram(TEXVERTSRC, FRAGBLURFINISH);
+ m_RenderData.pCurrentMonData->m_shBLURFINISH.program = prog;
+ m_RenderData.pCurrentMonData->m_shBLURFINISH.tex = glGetUniformLocation(prog, "tex");
+ m_RenderData.pCurrentMonData->m_shBLURFINISH.proj = glGetUniformLocation(prog, "proj");
+ m_RenderData.pCurrentMonData->m_shBLURFINISH.posAttrib = glGetAttribLocation(prog, "pos");
+ m_RenderData.pCurrentMonData->m_shBLURFINISH.texAttrib = glGetAttribLocation(prog, "texcoord");
+ m_RenderData.pCurrentMonData->m_shBLURFINISH.noise = glGetUniformLocation(prog, "noise");
+ m_RenderData.pCurrentMonData->m_shBLURFINISH.contrast = glGetUniformLocation(prog, "contrast");
+ m_RenderData.pCurrentMonData->m_shBLURFINISH.brightness = glGetUniformLocation(prog, "brightness");
+
prog = createProgram(QUADVERTSRC, FRAGSHADOW);
m_RenderData.pCurrentMonData->m_shSHADOW.program = prog;
m_RenderData.pCurrentMonData->m_shSHADOW.proj = glGetUniformLocation(prog, "proj");
@@ -801,8 +811,8 @@ CFramebuffer* CHyprOpenGLImpl::blurMainFramebufferWithDamage(float a, wlr_box* p
wlr_matrix_multiply(glMatrix, m_RenderData.projection, matrix);
// get the config settings
- static auto* const PBLURSIZE = &g_pConfigManager->getConfigValuePtr("decoration:blur_size")->intValue;
- static auto* const PBLURPASSES = &g_pConfigManager->getConfigValuePtr("decoration:blur_passes")->intValue;
+ static auto* const PBLURSIZE = &g_pConfigManager->getConfigValuePtr("decoration:blur:size")->intValue;
+ static auto* const PBLURPASSES = &g_pConfigManager->getConfigValuePtr("decoration:blur:passes")->intValue;
// prep damage
CRegion damage{*originalDamage};
@@ -891,6 +901,59 @@ CFramebuffer* CHyprOpenGLImpl::blurMainFramebufferWithDamage(float a, wlr_box* p
drawPass(&m_RenderData.pCurrentMonData->m_shBLUR2, &tempDamage); // up
}
+ // finalize with effects
+ {
+ static auto* const PBLURCONTRAST = &g_pConfigManager->getConfigValuePtr("decoration:blur:contrast")->floatValue;
+ static auto* const PBLURNOISE = &g_pConfigManager->getConfigValuePtr("decoration:blur:noise")->floatValue;
+ static auto* const PBLURBRIGHTNESS = &g_pConfigManager->getConfigValuePtr("decoration:blur:brightness")->floatValue;
+
+ if (currentRenderToFB == PMIRRORFB)
+ PMIRRORSWAPFB->bind();
+ else
+ PMIRRORFB->bind();
+
+ glActiveTexture(GL_TEXTURE0);
+
+ glBindTexture(currentRenderToFB->m_cTex.m_iTarget, currentRenderToFB->m_cTex.m_iTexID);
+
+ glTexParameteri(currentRenderToFB->m_cTex.m_iTarget, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
+
+ glUseProgram(m_RenderData.pCurrentMonData->m_shBLURFINISH.program);
+
+#ifndef GLES2
+ glUniformMatrix3fv(m_RenderData.pCurrentMonData->m_shBLURFINISH.proj, 1, GL_TRUE, glMatrix);
+#else
+ wlr_matrix_transpose(glMatrix, glMatrix);
+ glUniformMatrix3fv(m_RenderData.pCurrentMonData->m_shBLURFINISH.proj, 1, GL_FALSE, glMatrix);
+#endif
+ glUniform1f(m_RenderData.pCurrentMonData->m_shBLURFINISH.contrast, *PBLURCONTRAST);
+ glUniform1f(m_RenderData.pCurrentMonData->m_shBLURFINISH.noise, *PBLURNOISE);
+ glUniform1f(m_RenderData.pCurrentMonData->m_shBLURFINISH.brightness, *PBLURBRIGHTNESS);
+
+ glUniform1i(m_RenderData.pCurrentMonData->m_shBLURFINISH.tex, 0);
+
+ glVertexAttribPointer(m_RenderData.pCurrentMonData->m_shBLURFINISH.posAttrib, 2, GL_FLOAT, GL_FALSE, 0, fullVerts);
+ glVertexAttribPointer(m_RenderData.pCurrentMonData->m_shBLURFINISH.texAttrib, 2, GL_FLOAT, GL_FALSE, 0, fullVerts);
+
+ glEnableVertexAttribArray(m_RenderData.pCurrentMonData->m_shBLURFINISH.posAttrib);
+ glEnableVertexAttribArray(m_RenderData.pCurrentMonData->m_shBLURFINISH.texAttrib);
+
+ if (!damage.empty()) {
+ for (auto& RECT : damage.getRects()) {
+ scissor(&RECT, false /* this region is already transformed */);
+ glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
+ }
+ }
+
+ glDisableVertexAttribArray(m_RenderData.pCurrentMonData->m_shBLURFINISH.posAttrib);
+ glDisableVertexAttribArray(m_RenderData.pCurrentMonData->m_shBLURFINISH.texAttrib);
+
+ if (currentRenderToFB != PMIRRORFB)
+ currentRenderToFB = PMIRRORFB;
+ else
+ currentRenderToFB = PMIRRORSWAPFB;
+ }
+
// finish
glEnable(GL_BLEND);
glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
@@ -914,9 +977,9 @@ void CHyprOpenGLImpl::markBlurDirtyForMonitor(CMonitor* pMonitor) {
}
void CHyprOpenGLImpl::preRender(CMonitor* pMonitor) {
- static auto* const PBLURNEWOPTIMIZE = &g_pConfigManager->getConfigValuePtr("decoration:blur_new_optimizations")->intValue;
- static auto* const PBLURXRAY = &g_pConfigManager->getConfigValuePtr("decoration:blur_xray")->intValue;
- static auto* const PBLUR = &g_pConfigManager->getConfigValuePtr("decoration:blur")->intValue;
+ static auto* const PBLURNEWOPTIMIZE = &g_pConfigManager->getConfigValuePtr("decoration:blur:new_optimizations")->intValue;
+ static auto* const PBLURXRAY = &g_pConfigManager->getConfigValuePtr("decoration:blur:xray")->intValue;
+ static auto* const PBLUR = &g_pConfigManager->getConfigValuePtr("decoration:blur:enabled")->intValue;
if (!*PBLURNEWOPTIMIZE || !m_mMonitorRenderResources[pMonitor].blurFBDirty || !*PBLUR)
return;
@@ -1012,8 +1075,8 @@ void CHyprOpenGLImpl::preWindowPass() {
}
bool CHyprOpenGLImpl::preBlurQueued() {
- static auto* const PBLURNEWOPTIMIZE = &g_pConfigManager->getConfigValuePtr("decoration:blur_new_optimizations")->intValue;
- static auto* const PBLUR = &g_pConfigManager->getConfigValuePtr("decoration:blur")->intValue;
+ static auto* const PBLURNEWOPTIMIZE = &g_pConfigManager->getConfigValuePtr("decoration:blur:new_optimizations")->intValue;
+ static auto* const PBLUR = &g_pConfigManager->getConfigValuePtr("decoration:blur:enabled")->intValue;
return !(!m_RenderData.pCurrentMonData->blurFBDirty || !*PBLURNEWOPTIMIZE || !*PBLUR || !m_RenderData.pCurrentMonData->blurFBShouldRender);
}
@@ -1021,10 +1084,10 @@ bool CHyprOpenGLImpl::preBlurQueued() {
void CHyprOpenGLImpl::renderTextureWithBlur(const CTexture& tex, wlr_box* pBox, float a, wlr_surface* pSurface, int round, bool blockBlurOptimization) {
RASSERT(m_RenderData.pMonitor, "Tried to render texture with blur without begin()!");
- static auto* const PBLURENABLED = &g_pConfigManager->getConfigValuePtr("decoration:blur")->intValue;
+ static auto* const PBLURENABLED = &g_pConfigManager->getConfigValuePtr("decoration:blur:enabled")->intValue;
static auto* const PNOBLUROVERSIZED = &g_pConfigManager->getConfigValuePtr("decoration:no_blur_on_oversized")->intValue;
- static auto* const PBLURNEWOPTIMIZE = &g_pConfigManager->getConfigValuePtr("decoration:blur_new_optimizations")->intValue;
- static auto* const PBLURXRAY = &g_pConfigManager->getConfigValuePtr("decoration:blur_xray")->intValue;
+ static auto* const PBLURNEWOPTIMIZE = &g_pConfigManager->getConfigValuePtr("decoration:blur:new_optimizations")->intValue;
+ static auto* const PBLURXRAY = &g_pConfigManager->getConfigValuePtr("decoration:blur:xray")->intValue;
TRACY_GPU_ZONE("RenderTextureWithBlur");
@@ -1098,7 +1161,7 @@ void CHyprOpenGLImpl::renderTextureWithBlur(const CTexture& tex, wlr_box* pBox,
// stencil done. Render everything.
wlr_box MONITORBOX = {0, 0, m_RenderData.pMonitor->vecTransformedSize.x, m_RenderData.pMonitor->vecTransformedSize.y};
// render our great blurred FB
- static auto* const PBLURIGNOREOPACITY = &g_pConfigManager->getConfigValuePtr("decoration:blur_ignore_opacity")->intValue;
+ static auto* const PBLURIGNOREOPACITY = &g_pConfigManager->getConfigValuePtr("decoration:blur:ignore_opacity")->intValue;
m_bEndFrame = true; // fix transformed
const auto SAVEDRENDERMODIF = m_RenderData.renderModif;
m_RenderData.renderModif = {}; // fix shit
@@ -1252,8 +1315,8 @@ void CHyprOpenGLImpl::makeRawWindowSnapshot(CWindow* pWindow, CFramebuffer* pFra
// will try to copy the bg to apply blur.
// this isn't entirely correct, but like, oh well.
// small todo: maybe make this correct? :P
- const auto BLURVAL = g_pConfigManager->getInt("decoration:blur");
- g_pConfigManager->setInt("decoration:blur", 0);
+ const auto BLURVAL = g_pConfigManager->getInt("decoration:blur:enabled");
+ g_pConfigManager->setInt("decoration:blur:enabled", 0);
// TODO: how can we make this the size of the window? setting it to window's size makes the entire screen render with the wrong res forever more. odd.
glViewport(0, 0, PMONITOR->vecPixelSize.x, PMONITOR->vecPixelSize.y);
@@ -1268,7 +1331,7 @@ void CHyprOpenGLImpl::makeRawWindowSnapshot(CWindow* pWindow, CFramebuffer* pFra
g_pHyprRenderer->renderWindow(pWindow, PMONITOR, &now, false, RENDER_PASS_ALL, true);
- g_pConfigManager->setInt("decoration:blur", BLURVAL);
+ g_pConfigManager->setInt("decoration:blur:enabled", BLURVAL);
// restore original fb
#ifndef GLES2
@@ -1309,8 +1372,8 @@ void CHyprOpenGLImpl::makeWindowSnapshot(CWindow* pWindow) {
// will try to copy the bg to apply blur.
// this isn't entirely correct, but like, oh well.
// small todo: maybe make this correct? :P
- const auto BLURVAL = g_pConfigManager->getInt("decoration:blur");
- g_pConfigManager->setInt("decoration:blur", 0);
+ const auto BLURVAL = g_pConfigManager->getInt("decoration:blur:enabled");
+ g_pConfigManager->setInt("decoration:blur:enabled", 0);
glViewport(0, 0, m_RenderData.pMonitor->vecPixelSize.x, m_RenderData.pMonitor->vecPixelSize.y);
@@ -1326,7 +1389,7 @@ void CHyprOpenGLImpl::makeWindowSnapshot(CWindow* pWindow) {
g_pHyprRenderer->renderWindow(pWindow, PMONITOR, &now, !pWindow->m_bX11DoesntWantBorders, RENDER_PASS_ALL);
- g_pConfigManager->setInt("decoration:blur", BLURVAL);
+ g_pConfigManager->setInt("decoration:blur:enabled", BLURVAL);
// restore original fb
#ifndef GLES2
diff --git a/src/render/OpenGL.hpp b/src/render/OpenGL.hpp
index 9080c90b..d38f54ae 100644
--- a/src/render/OpenGL.hpp
+++ b/src/render/OpenGL.hpp
@@ -61,6 +61,7 @@ struct SMonitorRenderData {
CShader m_shEXT;
CShader m_shBLUR1;
CShader m_shBLUR2;
+ CShader m_shBLURFINISH;
CShader m_shSHADOW;
CShader m_shBORDER1;
CShader m_shGLITCH;
diff --git a/src/render/Renderer.cpp b/src/render/Renderer.cpp
index bb1ab511..cf6877f3 100644
--- a/src/render/Renderer.cpp
+++ b/src/render/Renderer.cpp
@@ -969,13 +969,13 @@ void CHyprRenderer::renderMonitor(CMonitor* pMonitor) {
damage = {0, 0, (int)pMonitor->vecTransformedSize.x * 10, (int)pMonitor->vecTransformedSize.y * 10};
pMonitor->lastFrameDamage = damage;
} else {
- static auto* const PBLURENABLED = &g_pConfigManager->getConfigValuePtr("decoration:blur")->intValue;
+ static auto* const PBLURENABLED = &g_pConfigManager->getConfigValuePtr("decoration:blur:enabled")->intValue;
// if we use blur we need to expand the damage for proper blurring
if (*PBLURENABLED == 1) {
// TODO: can this be optimized?
- static auto* const PBLURSIZE = &g_pConfigManager->getConfigValuePtr("decoration:blur_size")->intValue;
- static auto* const PBLURPASSES = &g_pConfigManager->getConfigValuePtr("decoration:blur_passes")->intValue;
+ static auto* const PBLURSIZE = &g_pConfigManager->getConfigValuePtr("decoration:blur:size")->intValue;
+ static auto* const PBLURPASSES = &g_pConfigManager->getConfigValuePtr("decoration:blur:passes")->intValue;
const auto BLURRADIUS =
*PBLURPASSES > 10 ? pow(2, 15) : std::clamp(*PBLURSIZE, (int64_t)1, (int64_t)40) * pow(2, *PBLURPASSES); // is this 2^pass? I don't know but it works... I think.
diff --git a/src/render/Shader.hpp b/src/render/Shader.hpp
index c43147ab..01d35209 100644
--- a/src/render/Shader.hpp
+++ b/src/render/Shader.hpp
@@ -43,6 +43,10 @@ class CShader {
GLint distort = -1;
GLint output = -1;
+ GLint noise = -1;
+ GLint contrast = -1;
+ GLint brightness = -1;
+
GLint getUniformLocation(const std::string&);
void destroy();
diff --git a/src/render/shaders/Textures.hpp b/src/render/shaders/Textures.hpp
index 0928487f..98cd8907 100644
--- a/src/render/shaders/Textures.hpp
+++ b/src/render/shaders/Textures.hpp
@@ -225,6 +225,36 @@ void main() {
}
)#";
+inline const std::string FRAGBLURFINISH = R"#(
+precision mediump float;
+varying vec2 v_texcoord; // is in 0-1
+uniform sampler2D tex;
+
+uniform float contrast;
+uniform float noise;
+uniform float brightness;
+
+float hash(vec2 p) {
+ return fract(sin(dot(p, vec2(12.9898, 78.233))) * 43758.5453);
+}
+
+void main() {
+ vec4 pixColor = texture2D(tex, v_texcoord);
+
+ // contrast
+ pixColor.rgb = (pixColor.rgb - 0.5) * contrast + 0.5;
+
+ // brightness
+ pixColor.rgb *= brightness;
+
+ // noise
+ float noiseHash = hash(v_texcoord);
+ float noiseAmount = (mod(noiseHash, 1.0) - 0.5);
+ pixColor.rgb += noiseAmount * noise;
+
+ gl_FragColor = pixColor;
+})#";
+
inline const std::string TEXFRAGSRCEXT = R"#(
#extension GL_OES_EGL_image_external : require