mirror of
https://github.com/hyprwm/Hyprland
synced 2024-11-26 05:45:59 +01:00
renderer: added new customization options to the blur shaders (#3650)
Adds to `decoration:blur:` `vibrancy` and `vibrancy_darkness`
This commit is contained in:
parent
a1b7a5a53d
commit
29e0a7112e
6 changed files with 266 additions and 80 deletions
|
@ -63,6 +63,8 @@ decoration {
|
||||||
enabled = true
|
enabled = true
|
||||||
size = 3
|
size = 3
|
||||||
passes = 1
|
passes = 1
|
||||||
|
|
||||||
|
vibrancy = 0.1696
|
||||||
}
|
}
|
||||||
|
|
||||||
drop_shadow = true
|
drop_shadow = true
|
||||||
|
|
|
@ -160,9 +160,11 @@ void CConfigManager::setDefaultVars() {
|
||||||
configValues["decoration:blur:ignore_opacity"].intValue = 0;
|
configValues["decoration:blur:ignore_opacity"].intValue = 0;
|
||||||
configValues["decoration:blur:new_optimizations"].intValue = 1;
|
configValues["decoration:blur:new_optimizations"].intValue = 1;
|
||||||
configValues["decoration:blur:xray"].intValue = 0;
|
configValues["decoration:blur:xray"].intValue = 0;
|
||||||
configValues["decoration:blur:noise"].floatValue = 0.0117;
|
|
||||||
configValues["decoration:blur:contrast"].floatValue = 0.8916;
|
configValues["decoration:blur:contrast"].floatValue = 0.8916;
|
||||||
configValues["decoration:blur:brightness"].floatValue = 0.8172;
|
configValues["decoration:blur:brightness"].floatValue = 1.0;
|
||||||
|
configValues["decoration:blur:vibrancy"].floatValue = 0.1696;
|
||||||
|
configValues["decoration:blur:vibrancy_darkness"].floatValue = 0.0;
|
||||||
|
configValues["decoration:blur:noise"].floatValue = 0.0117;
|
||||||
configValues["decoration:blur:special"].intValue = 0;
|
configValues["decoration:blur:special"].intValue = 0;
|
||||||
configValues["decoration:active_opacity"].floatValue = 1;
|
configValues["decoration:active_opacity"].floatValue = 1;
|
||||||
configValues["decoration:inactive_opacity"].floatValue = 1;
|
configValues["decoration:inactive_opacity"].floatValue = 1;
|
||||||
|
|
|
@ -316,6 +316,9 @@ void CHyprOpenGLImpl::initShaders() {
|
||||||
m_RenderData.pCurrentMonData->m_shBLUR1.texAttrib = glGetAttribLocation(prog, "texcoord");
|
m_RenderData.pCurrentMonData->m_shBLUR1.texAttrib = glGetAttribLocation(prog, "texcoord");
|
||||||
m_RenderData.pCurrentMonData->m_shBLUR1.radius = glGetUniformLocation(prog, "radius");
|
m_RenderData.pCurrentMonData->m_shBLUR1.radius = glGetUniformLocation(prog, "radius");
|
||||||
m_RenderData.pCurrentMonData->m_shBLUR1.halfpixel = glGetUniformLocation(prog, "halfpixel");
|
m_RenderData.pCurrentMonData->m_shBLUR1.halfpixel = glGetUniformLocation(prog, "halfpixel");
|
||||||
|
m_RenderData.pCurrentMonData->m_shBLUR1.passes = glGetUniformLocation(prog, "passes");
|
||||||
|
m_RenderData.pCurrentMonData->m_shBLUR1.vibrancy = glGetUniformLocation(prog, "vibrancy");
|
||||||
|
m_RenderData.pCurrentMonData->m_shBLUR1.vibrancy_darkness = glGetUniformLocation(prog, "vibrancy_darkness");
|
||||||
|
|
||||||
prog = createProgram(TEXVERTSRC, FRAGBLUR2);
|
prog = createProgram(TEXVERTSRC, FRAGBLUR2);
|
||||||
m_RenderData.pCurrentMonData->m_shBLUR2.program = prog;
|
m_RenderData.pCurrentMonData->m_shBLUR2.program = prog;
|
||||||
|
@ -327,15 +330,23 @@ void CHyprOpenGLImpl::initShaders() {
|
||||||
m_RenderData.pCurrentMonData->m_shBLUR2.radius = glGetUniformLocation(prog, "radius");
|
m_RenderData.pCurrentMonData->m_shBLUR2.radius = glGetUniformLocation(prog, "radius");
|
||||||
m_RenderData.pCurrentMonData->m_shBLUR2.halfpixel = glGetUniformLocation(prog, "halfpixel");
|
m_RenderData.pCurrentMonData->m_shBLUR2.halfpixel = glGetUniformLocation(prog, "halfpixel");
|
||||||
|
|
||||||
|
prog = createProgram(TEXVERTSRC, FRAGBLURPREPARE);
|
||||||
|
m_RenderData.pCurrentMonData->m_shBLURPREPARE.program = prog;
|
||||||
|
m_RenderData.pCurrentMonData->m_shBLURPREPARE.tex = glGetUniformLocation(prog, "tex");
|
||||||
|
m_RenderData.pCurrentMonData->m_shBLURPREPARE.proj = glGetUniformLocation(prog, "proj");
|
||||||
|
m_RenderData.pCurrentMonData->m_shBLURPREPARE.posAttrib = glGetAttribLocation(prog, "pos");
|
||||||
|
m_RenderData.pCurrentMonData->m_shBLURPREPARE.texAttrib = glGetAttribLocation(prog, "texcoord");
|
||||||
|
m_RenderData.pCurrentMonData->m_shBLURPREPARE.contrast = glGetUniformLocation(prog, "contrast");
|
||||||
|
m_RenderData.pCurrentMonData->m_shBLURPREPARE.brightness = glGetUniformLocation(prog, "brightness");
|
||||||
|
|
||||||
prog = createProgram(TEXVERTSRC, FRAGBLURFINISH);
|
prog = createProgram(TEXVERTSRC, FRAGBLURFINISH);
|
||||||
m_RenderData.pCurrentMonData->m_shBLURFINISH.program = prog;
|
m_RenderData.pCurrentMonData->m_shBLURFINISH.program = prog;
|
||||||
m_RenderData.pCurrentMonData->m_shBLURFINISH.tex = glGetUniformLocation(prog, "tex");
|
m_RenderData.pCurrentMonData->m_shBLURFINISH.tex = glGetUniformLocation(prog, "tex");
|
||||||
m_RenderData.pCurrentMonData->m_shBLURFINISH.proj = glGetUniformLocation(prog, "proj");
|
m_RenderData.pCurrentMonData->m_shBLURFINISH.proj = glGetUniformLocation(prog, "proj");
|
||||||
m_RenderData.pCurrentMonData->m_shBLURFINISH.posAttrib = glGetAttribLocation(prog, "pos");
|
m_RenderData.pCurrentMonData->m_shBLURFINISH.posAttrib = glGetAttribLocation(prog, "pos");
|
||||||
m_RenderData.pCurrentMonData->m_shBLURFINISH.texAttrib = glGetAttribLocation(prog, "texcoord");
|
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");
|
m_RenderData.pCurrentMonData->m_shBLURFINISH.brightness = glGetUniformLocation(prog, "brightness");
|
||||||
|
m_RenderData.pCurrentMonData->m_shBLURFINISH.noise = glGetUniformLocation(prog, "noise");
|
||||||
|
|
||||||
prog = createProgram(QUADVERTSRC, FRAGSHADOW);
|
prog = createProgram(QUADVERTSRC, FRAGSHADOW);
|
||||||
m_RenderData.pCurrentMonData->m_shSHADOW.program = prog;
|
m_RenderData.pCurrentMonData->m_shSHADOW.program = prog;
|
||||||
|
@ -914,6 +925,8 @@ CFramebuffer* CHyprOpenGLImpl::blurMainFramebufferWithDamage(float a, CRegion* o
|
||||||
// get the config settings
|
// get the config settings
|
||||||
static auto* const PBLURSIZE = &g_pConfigManager->getConfigValuePtr("decoration:blur:size")->intValue;
|
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 PBLURPASSES = &g_pConfigManager->getConfigValuePtr("decoration:blur:passes")->intValue;
|
||||||
|
static auto* const PBLURVIBRANCY = &g_pConfigManager->getConfigValuePtr("decoration:blur:vibrancy")->floatValue;
|
||||||
|
static auto* const PBLURVIBRANCYDARKNESS = &g_pConfigManager->getConfigValuePtr("decoration:blur:vibrancy_darkness")->floatValue;
|
||||||
|
|
||||||
// prep damage
|
// prep damage
|
||||||
CRegion damage{*originalDamage};
|
CRegion damage{*originalDamage};
|
||||||
|
@ -927,7 +940,7 @@ CFramebuffer* CHyprOpenGLImpl::blurMainFramebufferWithDamage(float a, CRegion* o
|
||||||
|
|
||||||
CFramebuffer* currentRenderToFB = PMIRRORFB;
|
CFramebuffer* currentRenderToFB = PMIRRORFB;
|
||||||
|
|
||||||
// begin with color adjustments
|
// Begin with base color adjustments - global brightness and contrast
|
||||||
// TODO: make this a part of the first pass maybe to save on a drawcall?
|
// TODO: make this a part of the first pass maybe to save on a drawcall?
|
||||||
{
|
{
|
||||||
static auto* const PBLURCONTRAST = &g_pConfigManager->getConfigValuePtr("decoration:blur:contrast")->floatValue;
|
static auto* const PBLURCONTRAST = &g_pConfigManager->getConfigValuePtr("decoration:blur:contrast")->floatValue;
|
||||||
|
@ -941,24 +954,23 @@ CFramebuffer* CHyprOpenGLImpl::blurMainFramebufferWithDamage(float a, CRegion* o
|
||||||
|
|
||||||
glTexParameteri(m_RenderData.pCurrentMonData->primaryFB.m_cTex.m_iTarget, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
glTexParameteri(m_RenderData.pCurrentMonData->primaryFB.m_cTex.m_iTarget, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||||
|
|
||||||
glUseProgram(m_RenderData.pCurrentMonData->m_shBLURFINISH.program);
|
glUseProgram(m_RenderData.pCurrentMonData->m_shBLURPREPARE.program);
|
||||||
|
|
||||||
#ifndef GLES2
|
#ifndef GLES2
|
||||||
glUniformMatrix3fv(m_RenderData.pCurrentMonData->m_shBLURFINISH.proj, 1, GL_TRUE, glMatrix);
|
glUniformMatrix3fv(m_RenderData.pCurrentMonData->m_shBLURPREPARE.proj, 1, GL_TRUE, glMatrix);
|
||||||
#else
|
#else
|
||||||
wlr_matrix_transpose(glMatrix, glMatrix);
|
wlr_matrix_transpose(glMatrix, glMatrix);
|
||||||
glUniformMatrix3fv(m_RenderData.pCurrentMonData->m_shBLURFINISH.proj, 1, GL_FALSE, glMatrix);
|
glUniformMatrix3fv(m_RenderData.pCurrentMonData->m_shBLURFINISH.proj, 1, GL_FALSE, glMatrix);
|
||||||
#endif
|
#endif
|
||||||
glUniform1f(m_RenderData.pCurrentMonData->m_shBLURFINISH.contrast, *PBLURCONTRAST);
|
glUniform1f(m_RenderData.pCurrentMonData->m_shBLURPREPARE.contrast, *PBLURCONTRAST);
|
||||||
glUniform1f(m_RenderData.pCurrentMonData->m_shBLURFINISH.brightness, *PBLURBRIGHTNESS);
|
glUniform1f(m_RenderData.pCurrentMonData->m_shBLURPREPARE.brightness, *PBLURBRIGHTNESS);
|
||||||
|
glUniform1i(m_RenderData.pCurrentMonData->m_shBLURPREPARE.tex, 0);
|
||||||
|
|
||||||
glUniform1i(m_RenderData.pCurrentMonData->m_shBLURFINISH.tex, 0);
|
glVertexAttribPointer(m_RenderData.pCurrentMonData->m_shBLURPREPARE.posAttrib, 2, GL_FLOAT, GL_FALSE, 0, fullVerts);
|
||||||
|
glVertexAttribPointer(m_RenderData.pCurrentMonData->m_shBLURPREPARE.texAttrib, 2, GL_FLOAT, GL_FALSE, 0, fullVerts);
|
||||||
|
|
||||||
glVertexAttribPointer(m_RenderData.pCurrentMonData->m_shBLURFINISH.posAttrib, 2, GL_FLOAT, GL_FALSE, 0, fullVerts);
|
glEnableVertexAttribArray(m_RenderData.pCurrentMonData->m_shBLURPREPARE.posAttrib);
|
||||||
glVertexAttribPointer(m_RenderData.pCurrentMonData->m_shBLURFINISH.texAttrib, 2, GL_FLOAT, GL_FALSE, 0, fullVerts);
|
glEnableVertexAttribArray(m_RenderData.pCurrentMonData->m_shBLURPREPARE.texAttrib);
|
||||||
|
|
||||||
glEnableVertexAttribArray(m_RenderData.pCurrentMonData->m_shBLURFINISH.posAttrib);
|
|
||||||
glEnableVertexAttribArray(m_RenderData.pCurrentMonData->m_shBLURFINISH.texAttrib);
|
|
||||||
|
|
||||||
if (!damage.empty()) {
|
if (!damage.empty()) {
|
||||||
for (auto& RECT : damage.getRects()) {
|
for (auto& RECT : damage.getRects()) {
|
||||||
|
@ -967,8 +979,8 @@ CFramebuffer* CHyprOpenGLImpl::blurMainFramebufferWithDamage(float a, CRegion* o
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
glDisableVertexAttribArray(m_RenderData.pCurrentMonData->m_shBLURFINISH.posAttrib);
|
glDisableVertexAttribArray(m_RenderData.pCurrentMonData->m_shBLURPREPARE.posAttrib);
|
||||||
glDisableVertexAttribArray(m_RenderData.pCurrentMonData->m_shBLURFINISH.texAttrib);
|
glDisableVertexAttribArray(m_RenderData.pCurrentMonData->m_shBLURPREPARE.texAttrib);
|
||||||
|
|
||||||
currentRenderToFB = PMIRRORSWAPFB;
|
currentRenderToFB = PMIRRORSWAPFB;
|
||||||
}
|
}
|
||||||
|
@ -996,10 +1008,13 @@ CFramebuffer* CHyprOpenGLImpl::blurMainFramebufferWithDamage(float a, CRegion* o
|
||||||
glUniformMatrix3fv(pShader->proj, 1, GL_FALSE, glMatrix);
|
glUniformMatrix3fv(pShader->proj, 1, GL_FALSE, glMatrix);
|
||||||
#endif
|
#endif
|
||||||
glUniform1f(pShader->radius, *PBLURSIZE * a); // this makes the blursize change with a
|
glUniform1f(pShader->radius, *PBLURSIZE * a); // this makes the blursize change with a
|
||||||
if (pShader == &m_RenderData.pCurrentMonData->m_shBLUR1)
|
if (pShader == &m_RenderData.pCurrentMonData->m_shBLUR1) {
|
||||||
glUniform2f(m_RenderData.pCurrentMonData->m_shBLUR1.halfpixel, 0.5f / (m_RenderData.pMonitor->vecPixelSize.x / 2.f),
|
glUniform2f(m_RenderData.pCurrentMonData->m_shBLUR1.halfpixel, 0.5f / (m_RenderData.pMonitor->vecPixelSize.x / 2.f),
|
||||||
0.5f / (m_RenderData.pMonitor->vecPixelSize.y / 2.f));
|
0.5f / (m_RenderData.pMonitor->vecPixelSize.y / 2.f));
|
||||||
else
|
glUniform1i(m_RenderData.pCurrentMonData->m_shBLUR1.passes, *PBLURPASSES);
|
||||||
|
glUniform1f(m_RenderData.pCurrentMonData->m_shBLUR1.vibrancy, *PBLURVIBRANCY);
|
||||||
|
glUniform1f(m_RenderData.pCurrentMonData->m_shBLUR1.vibrancy_darkness, *PBLURVIBRANCYDARKNESS);
|
||||||
|
} else
|
||||||
glUniform2f(m_RenderData.pCurrentMonData->m_shBLUR2.halfpixel, 0.5f / (m_RenderData.pMonitor->vecPixelSize.x * 2.f),
|
glUniform2f(m_RenderData.pCurrentMonData->m_shBLUR2.halfpixel, 0.5f / (m_RenderData.pMonitor->vecPixelSize.x * 2.f),
|
||||||
0.5f / (m_RenderData.pMonitor->vecPixelSize.y * 2.f));
|
0.5f / (m_RenderData.pMonitor->vecPixelSize.y * 2.f));
|
||||||
glUniform1i(pShader->tex, 0);
|
glUniform1i(pShader->tex, 0);
|
||||||
|
@ -1045,9 +1060,10 @@ CFramebuffer* CHyprOpenGLImpl::blurMainFramebufferWithDamage(float a, CRegion* o
|
||||||
drawPass(&m_RenderData.pCurrentMonData->m_shBLUR2, &tempDamage); // up
|
drawPass(&m_RenderData.pCurrentMonData->m_shBLUR2, &tempDamage); // up
|
||||||
}
|
}
|
||||||
|
|
||||||
// finalize with noise
|
// finalize the image
|
||||||
{
|
{
|
||||||
static auto* const PBLURNOISE = &g_pConfigManager->getConfigValuePtr("decoration:blur:noise")->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)
|
if (currentRenderToFB == PMIRRORFB)
|
||||||
PMIRRORSWAPFB->bind();
|
PMIRRORSWAPFB->bind();
|
||||||
|
@ -1069,6 +1085,7 @@ CFramebuffer* CHyprOpenGLImpl::blurMainFramebufferWithDamage(float a, CRegion* o
|
||||||
glUniformMatrix3fv(m_RenderData.pCurrentMonData->m_shBLURFINISH.proj, 1, GL_FALSE, glMatrix);
|
glUniformMatrix3fv(m_RenderData.pCurrentMonData->m_shBLURFINISH.proj, 1, GL_FALSE, glMatrix);
|
||||||
#endif
|
#endif
|
||||||
glUniform1f(m_RenderData.pCurrentMonData->m_shBLURFINISH.noise, *PBLURNOISE);
|
glUniform1f(m_RenderData.pCurrentMonData->m_shBLURFINISH.noise, *PBLURNOISE);
|
||||||
|
glUniform1f(m_RenderData.pCurrentMonData->m_shBLURFINISH.brightness, *PBLURBRIGHTNESS);
|
||||||
|
|
||||||
glUniform1i(m_RenderData.pCurrentMonData->m_shBLURFINISH.tex, 0);
|
glUniform1i(m_RenderData.pCurrentMonData->m_shBLURFINISH.tex, 0);
|
||||||
|
|
||||||
|
|
|
@ -64,6 +64,7 @@ struct SMonitorRenderData {
|
||||||
CShader m_shEXT;
|
CShader m_shEXT;
|
||||||
CShader m_shBLUR1;
|
CShader m_shBLUR1;
|
||||||
CShader m_shBLUR2;
|
CShader m_shBLUR2;
|
||||||
|
CShader m_shBLURPREPARE;
|
||||||
CShader m_shBLURFINISH;
|
CShader m_shBLURFINISH;
|
||||||
CShader m_shSHADOW;
|
CShader m_shSHADOW;
|
||||||
CShader m_shBORDER1;
|
CShader m_shBORDER1;
|
||||||
|
|
|
@ -46,9 +46,17 @@ class CShader {
|
||||||
GLint distort = -1;
|
GLint distort = -1;
|
||||||
GLint output = -1;
|
GLint output = -1;
|
||||||
|
|
||||||
GLint noise = -1;
|
// Blur prepare
|
||||||
GLint contrast = -1;
|
GLint contrast = -1;
|
||||||
|
|
||||||
|
// Blur
|
||||||
|
GLint passes = -1; // Used by `vibrancy`
|
||||||
|
GLint vibrancy = -1;
|
||||||
|
GLint vibrancy_darkness = -1;
|
||||||
|
|
||||||
|
// Blur finish
|
||||||
GLint brightness = -1;
|
GLint brightness = -1;
|
||||||
|
GLint noise = -1;
|
||||||
|
|
||||||
GLint getUniformLocation(const std::string&);
|
GLint getUniformLocation(const std::string&);
|
||||||
|
|
||||||
|
|
|
@ -186,6 +186,110 @@ uniform sampler2D tex;
|
||||||
|
|
||||||
uniform float radius;
|
uniform float radius;
|
||||||
uniform vec2 halfpixel;
|
uniform vec2 halfpixel;
|
||||||
|
uniform int passes;
|
||||||
|
uniform float vibrancy;
|
||||||
|
uniform float vibrancy_darkness;
|
||||||
|
|
||||||
|
// see http://alienryderflex.com/hsp.html
|
||||||
|
const float Pr = 0.299;
|
||||||
|
const float Pg = 0.587;
|
||||||
|
const float Pb = 0.114;
|
||||||
|
|
||||||
|
// Y is "v" ( brightness ). X is "s" ( saturation )
|
||||||
|
// see https://www.desmos.com/3d/a88652b9a4
|
||||||
|
// Determines if high brightness or high saturation is more important
|
||||||
|
const float a = 0.93;
|
||||||
|
const float b = 0.11;
|
||||||
|
const float c = 0.66; // Determines the smoothness of the transition of unboosted to boosted colors
|
||||||
|
//
|
||||||
|
|
||||||
|
// http://www.flong.com/archive/texts/code/shapers_circ/
|
||||||
|
float doubleCircleSigmoid(float x, float a) {
|
||||||
|
float min_param_a = 0.0;
|
||||||
|
float max_param_a = 1.0;
|
||||||
|
a = max(min_param_a, min(max_param_a, a));
|
||||||
|
|
||||||
|
float y = .0;
|
||||||
|
if (x <= a) {
|
||||||
|
y = a - sqrt(a * a - x * x);
|
||||||
|
} else {
|
||||||
|
y = a + sqrt(pow(1. - a, 2.) - pow(x - 1., 2.));
|
||||||
|
}
|
||||||
|
return y;
|
||||||
|
}
|
||||||
|
|
||||||
|
vec3 rgb2hsl(vec3 col) {
|
||||||
|
float red = col.r;
|
||||||
|
float green = col.g;
|
||||||
|
float blue = col.b;
|
||||||
|
|
||||||
|
float minc = min(col.r, min(col.g, col.b));
|
||||||
|
float maxc = max(col.r, max(col.g, col.b));
|
||||||
|
float delta = maxc - minc;
|
||||||
|
|
||||||
|
float lum = (minc + maxc) * 0.5;
|
||||||
|
float sat = 0.0;
|
||||||
|
float hue = 0.0;
|
||||||
|
|
||||||
|
if (lum > 0.0 && lum < 1.0) {
|
||||||
|
float mul = (lum < 0.5) ? (lum) : (1.0 - lum);
|
||||||
|
sat = delta / (mul * 2.0);
|
||||||
|
}
|
||||||
|
|
||||||
|
vec3 masks = vec3((maxc == red && maxc != green) ? 1.0 : 0.0, (maxc == green && maxc != blue) ? 1.0 : 0.0, (maxc == blue && maxc != red) ? 1.0 : 0.0);
|
||||||
|
|
||||||
|
vec3 adds = vec3(((green - blue) / delta), 2.0 + ((blue - red) / delta), 4.0 + ((red - green) / delta));
|
||||||
|
|
||||||
|
float deltaGtz = (delta > 0.0) ? 1.0 : 0.0;
|
||||||
|
|
||||||
|
hue += dot(adds, masks);
|
||||||
|
hue *= deltaGtz;
|
||||||
|
hue /= 6.0;
|
||||||
|
|
||||||
|
if (hue < 0.0)
|
||||||
|
hue += 1.0;
|
||||||
|
|
||||||
|
return vec3(hue, sat, lum);
|
||||||
|
}
|
||||||
|
vec3 hsl2rgb(vec3 col) {
|
||||||
|
const float onethird = 1.0 / 3.0;
|
||||||
|
const float twothird = 2.0 / 3.0;
|
||||||
|
const float rcpsixth = 6.0;
|
||||||
|
|
||||||
|
float hue = col.x;
|
||||||
|
float sat = col.y;
|
||||||
|
float lum = col.z;
|
||||||
|
|
||||||
|
vec3 xt = vec3(rcpsixth * (hue - twothird), 0.0, rcpsixth * (1.0 - hue));
|
||||||
|
|
||||||
|
if (hue < twothird) {
|
||||||
|
xt.r = 0.0;
|
||||||
|
xt.g = rcpsixth * (twothird - hue);
|
||||||
|
xt.b = rcpsixth * (hue - onethird);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (hue < onethird) {
|
||||||
|
xt.r = rcpsixth * (onethird - hue);
|
||||||
|
xt.g = rcpsixth * hue;
|
||||||
|
xt.b = 0.0;
|
||||||
|
}
|
||||||
|
|
||||||
|
xt = min(xt, 1.0);
|
||||||
|
|
||||||
|
float sat2 = 2.0 * sat;
|
||||||
|
float satinv = 1.0 - sat;
|
||||||
|
float luminv = 1.0 - lum;
|
||||||
|
float lum2m1 = (2.0 * lum) - 1.0;
|
||||||
|
vec3 ct = (sat2 * xt) + satinv;
|
||||||
|
|
||||||
|
vec3 rgb;
|
||||||
|
if (lum >= 0.5)
|
||||||
|
rgb = (luminv * ct) + lum2m1;
|
||||||
|
else
|
||||||
|
rgb = lum * ct;
|
||||||
|
|
||||||
|
return rgb;
|
||||||
|
}
|
||||||
|
|
||||||
void main() {
|
void main() {
|
||||||
vec2 uv = v_texcoord * 2.0;
|
vec2 uv = v_texcoord * 2.0;
|
||||||
|
@ -196,7 +300,28 @@ void main() {
|
||||||
sum += texture2D(tex, uv + vec2(halfpixel.x, -halfpixel.y) * radius);
|
sum += texture2D(tex, uv + vec2(halfpixel.x, -halfpixel.y) * radius);
|
||||||
sum += texture2D(tex, uv - vec2(halfpixel.x, -halfpixel.y) * radius);
|
sum += texture2D(tex, uv - vec2(halfpixel.x, -halfpixel.y) * radius);
|
||||||
|
|
||||||
gl_FragColor = sum / 8.0;
|
vec4 color = sum / 8.0;
|
||||||
|
|
||||||
|
if (vibrancy == 0.0) {
|
||||||
|
gl_FragColor = color;
|
||||||
|
} else {
|
||||||
|
// Invert it so that it correctly maps to the config setting
|
||||||
|
float vibrancy_darkness1 = 1.0 - vibrancy_darkness;
|
||||||
|
|
||||||
|
// Decrease the RGB components based on their perceived brightness, to prevent visually dark colors from overblowing the rest.
|
||||||
|
vec3 hsl = rgb2hsl(color.rgb);
|
||||||
|
// Calculate perceived brightness, as not boost visually dark colors like deep blue as much as equally saturated yellow
|
||||||
|
float perceivedBrightness = doubleCircleSigmoid(sqrt(color.r * color.r * Pr + color.g * color.g * Pg + color.b * color.b * Pb), 0.8 * vibrancy_darkness1);
|
||||||
|
|
||||||
|
float b1 = b * vibrancy_darkness1;
|
||||||
|
float boostBase = hsl[1] > 0.0 ? smoothstep(b1 - c * 0.5, b1 + c * 0.5, 1.0 - (pow(1.0 - hsl[1] * cos(a), 2.0) + pow(1.0 - perceivedBrightness * sin(a), 2.0))) : 0.0;
|
||||||
|
|
||||||
|
float saturation = clamp(hsl[1] + (boostBase * vibrancy) / float(passes), 0.0, 1.0);
|
||||||
|
|
||||||
|
vec3 newColor = hsl2rgb(vec3(hsl[0], saturation, hsl[2]));
|
||||||
|
|
||||||
|
gl_FragColor = vec4(newColor, color[3]);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
)#";
|
)#";
|
||||||
|
|
||||||
|
@ -226,12 +351,43 @@ void main() {
|
||||||
}
|
}
|
||||||
)#";
|
)#";
|
||||||
|
|
||||||
inline const std::string FRAGBLURFINISH = R"#(
|
inline const std::string FRAGBLURPREPARE = R"#(
|
||||||
precision mediump float;
|
precision mediump float;
|
||||||
varying vec2 v_texcoord; // is in 0-1
|
varying vec2 v_texcoord; // is in 0-1
|
||||||
uniform sampler2D tex;
|
uniform sampler2D tex;
|
||||||
|
|
||||||
uniform float contrast;
|
uniform float contrast;
|
||||||
|
uniform float brightness;
|
||||||
|
|
||||||
|
float gain(float x, float k) {
|
||||||
|
float a = 0.5 * pow(2.0 * ((x < 0.5) ? x : 1.0 - x), k);
|
||||||
|
return (x < 0.5) ? a : 1.0 - a;
|
||||||
|
}
|
||||||
|
|
||||||
|
void main() {
|
||||||
|
vec4 pixColor = texture2D(tex, v_texcoord);
|
||||||
|
|
||||||
|
// contrast
|
||||||
|
if (contrast != 1.0) {
|
||||||
|
pixColor.r = gain(pixColor.r, contrast);
|
||||||
|
pixColor.g = gain(pixColor.g, contrast);
|
||||||
|
pixColor.b = gain(pixColor.b, contrast);
|
||||||
|
}
|
||||||
|
|
||||||
|
// brightness
|
||||||
|
if (brightness > 1.0) {
|
||||||
|
pixColor.rgb *= brightness;
|
||||||
|
}
|
||||||
|
|
||||||
|
gl_FragColor = pixColor;
|
||||||
|
}
|
||||||
|
)#";
|
||||||
|
|
||||||
|
inline const std::string FRAGBLURFINISH = R"#(
|
||||||
|
precision mediump float;
|
||||||
|
varying vec2 v_texcoord; // is in 0-1
|
||||||
|
uniform sampler2D tex;
|
||||||
|
|
||||||
uniform float noise;
|
uniform float noise;
|
||||||
uniform float brightness;
|
uniform float brightness;
|
||||||
|
|
||||||
|
@ -242,19 +398,19 @@ float hash(vec2 p) {
|
||||||
void main() {
|
void main() {
|
||||||
vec4 pixColor = texture2D(tex, v_texcoord);
|
vec4 pixColor = texture2D(tex, v_texcoord);
|
||||||
|
|
||||||
// contrast
|
|
||||||
pixColor.rgb = (pixColor.rgb - 0.5) * contrast + 0.5;
|
|
||||||
|
|
||||||
// brightness
|
|
||||||
pixColor.rgb *= brightness;
|
|
||||||
|
|
||||||
// noise
|
// noise
|
||||||
float noiseHash = hash(v_texcoord);
|
float noiseHash = hash(v_texcoord);
|
||||||
float noiseAmount = (mod(noiseHash, 1.0) - 0.5);
|
float noiseAmount = (mod(noiseHash, 1.0) - 0.5);
|
||||||
pixColor.rgb += noiseAmount * noise;
|
pixColor.rgb += noiseAmount * noise;
|
||||||
|
|
||||||
|
// brightness
|
||||||
|
if (brightness < 1.0) {
|
||||||
|
pixColor.rgb *= brightness;
|
||||||
|
}
|
||||||
|
|
||||||
gl_FragColor = pixColor;
|
gl_FragColor = pixColor;
|
||||||
})#";
|
}
|
||||||
|
)#";
|
||||||
|
|
||||||
inline const std::string TEXFRAGSRCEXT = R"#(
|
inline const std::string TEXFRAGSRCEXT = R"#(
|
||||||
#extension GL_OES_EGL_image_external : require
|
#extension GL_OES_EGL_image_external : require
|
||||||
|
|
Loading…
Reference in a new issue