mirror of
https://github.com/hyprwm/Hyprland
synced 2024-12-22 22:49:48 +01:00
renderer: Various Blur Improvements (#2877)
* move blur to its own category * blur improvements, contrast, brightness, noise
This commit is contained in:
parent
5c50fac907
commit
d96f8ff0fe
6 changed files with 127 additions and 26 deletions
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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.
|
||||
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
Loading…
Reference in a new issue