mirror of
https://github.com/RetroDECK/ES-DE.git
synced 2024-11-22 06:05:38 +00:00
Improved the blur shaders to run faster at higher resolutions and to look identical regardless of display resolution
Also improved the blur shaders rendering quality when rotating the screen 90 or 270 degrees
This commit is contained in:
parent
a8d20549a5
commit
9e277ed1ff
|
@ -199,26 +199,16 @@ void MediaViewer::render(const glm::mat4& /*parentTrans*/)
|
|||
if (Settings::getInstance()->getBool("MediaViewerVideoScanlines"))
|
||||
shaders = Renderer::Shader::SCANLINES;
|
||||
if (Settings::getInstance()->getBool("MediaViewerVideoBlur")) {
|
||||
if (mRenderer->getScreenRotation() == 90 || mRenderer->getScreenRotation() == 270)
|
||||
shaders |= Renderer::Shader::BLUR_VERTICAL;
|
||||
else
|
||||
shaders |= Renderer::Shader::BLUR_HORIZONTAL;
|
||||
const float resolutionModifier {mRenderer->getScreenResolutionModifier()};
|
||||
// clang-format off
|
||||
if (resolutionModifier < 1)
|
||||
videoParameters.blurPasses = 2; // Below 1080
|
||||
else if (resolutionModifier >= 4)
|
||||
videoParameters.blurPasses = 12; // 8K
|
||||
else if (resolutionModifier >= 2.9)
|
||||
videoParameters.blurPasses = 10; // 6K
|
||||
else if (resolutionModifier >= 2.6)
|
||||
videoParameters.blurPasses = 8; // 5K
|
||||
else if (resolutionModifier >= 2)
|
||||
videoParameters.blurPasses = 5; // 4K
|
||||
else if (resolutionModifier >= 1.3)
|
||||
videoParameters.blurPasses = 3; // 1440
|
||||
else if (resolutionModifier >= 1)
|
||||
videoParameters.blurPasses = 2; // 1080
|
||||
// clang-format on
|
||||
}
|
||||
|
||||
// We run two passes to make the blur smoother.
|
||||
videoParameters.blurPasses = 2;
|
||||
videoParameters.blurStrength = 1.35f;
|
||||
|
||||
if (shaders != 0)
|
||||
mRenderer->shaderPostprocessing(shaders, videoParameters);
|
||||
}
|
||||
|
|
|
@ -324,26 +324,17 @@ void Screensaver::renderScreensaver()
|
|||
if (Settings::getInstance()->getBool("ScreensaverVideoScanlines"))
|
||||
shaders = Renderer::Shader::SCANLINES;
|
||||
if (Settings::getInstance()->getBool("ScreensaverVideoBlur")) {
|
||||
if (mRenderer->getScreenRotation() == 90 ||
|
||||
mRenderer->getScreenRotation() == 270)
|
||||
shaders |= Renderer::Shader::BLUR_VERTICAL;
|
||||
else
|
||||
shaders |= Renderer::Shader::BLUR_HORIZONTAL;
|
||||
const float resolutionModifier {mRenderer->getScreenResolutionModifier()};
|
||||
// clang-format off
|
||||
if (resolutionModifier < 1)
|
||||
videoParameters.blurPasses = 2; // Below 1080
|
||||
else if (resolutionModifier >= 4)
|
||||
videoParameters.blurPasses = 12; // 8K
|
||||
else if (resolutionModifier >= 2.9)
|
||||
videoParameters.blurPasses = 10; // 6K
|
||||
else if (resolutionModifier >= 2.6)
|
||||
videoParameters.blurPasses = 8; // 5K
|
||||
else if (resolutionModifier >= 2)
|
||||
videoParameters.blurPasses = 5; // 4K
|
||||
else if (resolutionModifier >= 1.3)
|
||||
videoParameters.blurPasses = 3; // 1440
|
||||
else if (resolutionModifier >= 1)
|
||||
videoParameters.blurPasses = 2; // 1080
|
||||
// clang-format on
|
||||
}
|
||||
|
||||
// We run two passes to make the blur smoother.
|
||||
videoParameters.blurPasses = 2;
|
||||
videoParameters.blurStrength = 1.35f;
|
||||
|
||||
if (shaders != 0)
|
||||
mRenderer->shaderPostprocessing(shaders, videoParameters);
|
||||
|
||||
|
|
|
@ -513,23 +513,10 @@ void Window::render()
|
|||
// degrees.
|
||||
if (Settings::getInstance()->getBool("MenuBlurBackground") ||
|
||||
mRenderer->getScreenRotation() == 90 || mRenderer->getScreenRotation() == 270) {
|
||||
const float resolutionModifier {mRenderer->getScreenResolutionModifier()};
|
||||
// clang-format off
|
||||
if (resolutionModifier < 1)
|
||||
backgroundParameters.blurPasses = 2; // Below 1080
|
||||
else if (resolutionModifier >= 4)
|
||||
backgroundParameters.blurPasses = 12; // 8K
|
||||
else if (resolutionModifier >= 2.9)
|
||||
backgroundParameters.blurPasses = 10; // 6K
|
||||
else if (resolutionModifier >= 2.6)
|
||||
backgroundParameters.blurPasses = 8; // 5K
|
||||
else if (resolutionModifier >= 2)
|
||||
backgroundParameters.blurPasses = 5; // 4K
|
||||
else if (resolutionModifier >= 1.3)
|
||||
backgroundParameters.blurPasses = 3; // 1440
|
||||
else if (resolutionModifier >= 1)
|
||||
backgroundParameters.blurPasses = 2; // 1080
|
||||
// clang-format on
|
||||
|
||||
// We run two passes to make the blur smoother.
|
||||
backgroundParameters.blurPasses = 2;
|
||||
backgroundParameters.blurStrength = 1.35f;
|
||||
|
||||
// Also dim the background slightly.
|
||||
if (Settings::getInstance()->getString("MenuColorScheme") == "light")
|
||||
|
|
|
@ -67,6 +67,7 @@ public:
|
|||
float saturation;
|
||||
float dimming;
|
||||
float reflectionsFalloff;
|
||||
float blurStrength;
|
||||
unsigned int shaders;
|
||||
unsigned int shaderFlags;
|
||||
|
||||
|
@ -76,6 +77,7 @@ public:
|
|||
, saturation {1.0f}
|
||||
, dimming {1.0f}
|
||||
, reflectionsFalloff {0.0f}
|
||||
, blurStrength {0.0f}
|
||||
, shaders {0}
|
||||
, shaderFlags {0}
|
||||
{
|
||||
|
@ -94,6 +96,7 @@ public:
|
|||
, saturation {1.0f}
|
||||
, dimming {1.0f}
|
||||
, reflectionsFalloff {0.0f}
|
||||
, blurStrength {0.0f}
|
||||
, shaders {0}
|
||||
, shaderFlags {0}
|
||||
{
|
||||
|
@ -104,6 +107,7 @@ public:
|
|||
float opacity;
|
||||
float saturation;
|
||||
float dimming;
|
||||
float blurStrength;
|
||||
unsigned int blurPasses;
|
||||
unsigned int shaders;
|
||||
|
||||
|
@ -111,6 +115,7 @@ public:
|
|||
: opacity {1.0f}
|
||||
, saturation {1.0f}
|
||||
, dimming {1.0f}
|
||||
, blurStrength {0.0f}
|
||||
, blurPasses {1}
|
||||
, shaders {0}
|
||||
{
|
||||
|
|
|
@ -294,9 +294,9 @@ bool RendererOpenGL::createContext()
|
|||
textureHeight = static_cast<unsigned int>(getScreenWidth());
|
||||
}
|
||||
|
||||
mPostProcTexture1 = createTexture(TextureType::BGRA, false, false, false, false, textureWidth,
|
||||
mPostProcTexture1 = createTexture(TextureType::BGRA, false, true, false, false, textureWidth,
|
||||
textureHeight, nullptr);
|
||||
mPostProcTexture2 = createTexture(TextureType::BGRA, false, false, false, false, textureWidth,
|
||||
mPostProcTexture2 = createTexture(TextureType::BGRA, false, true, false, false, textureWidth,
|
||||
textureHeight, nullptr);
|
||||
|
||||
// Attach textures to the shader framebuffers.
|
||||
|
@ -522,7 +522,8 @@ void RendererOpenGL::drawTriangleStrips(const Vertex* vertices,
|
|||
mBlurHorizontalShader->setAttribPointers();
|
||||
GL_CHECK_ERROR(glBufferData(GL_ARRAY_BUFFER, sizeof(Vertex) * numVertices, vertices,
|
||||
GL_DYNAMIC_DRAW));
|
||||
mBlurHorizontalShader->setTextureSize({width, height});
|
||||
mBlurHorizontalShader->setBlurStrength((vertices->blurStrength / getScreenWidth()) *
|
||||
getScreenResolutionModifier());
|
||||
mBlurHorizontalShader->setFlags(vertices->shaderFlags);
|
||||
GL_CHECK_ERROR(glDrawArrays(GL_TRIANGLE_STRIP, 0, numVertices));
|
||||
mLastShader = mBlurHorizontalShader;
|
||||
|
@ -540,7 +541,8 @@ void RendererOpenGL::drawTriangleStrips(const Vertex* vertices,
|
|||
mBlurVerticalShader->setAttribPointers();
|
||||
GL_CHECK_ERROR(glBufferData(GL_ARRAY_BUFFER, sizeof(Vertex) * numVertices, vertices,
|
||||
GL_DYNAMIC_DRAW));
|
||||
mBlurVerticalShader->setTextureSize({width, height});
|
||||
mBlurVerticalShader->setBlurStrength((vertices->blurStrength / getScreenHeight()) *
|
||||
getScreenResolutionModifier());
|
||||
mBlurVerticalShader->setFlags(vertices->shaderFlags);
|
||||
GL_CHECK_ERROR(glDrawArrays(GL_TRIANGLE_STRIP, 0, numVertices));
|
||||
mLastShader = mBlurVerticalShader;
|
||||
|
@ -621,6 +623,7 @@ void RendererOpenGL::shaderPostprocessing(unsigned int shaders,
|
|||
vertices->opacity = parameters.opacity;
|
||||
vertices->saturation = parameters.saturation;
|
||||
vertices->dimming = parameters.dimming;
|
||||
vertices->blurStrength = parameters.blurStrength;
|
||||
vertices->shaderFlags = ShaderFlags::POST_PROCESSING | ShaderFlags::PREMULTIPLIED;
|
||||
|
||||
if (screenRotation == 90 || screenRotation == 270)
|
||||
|
|
|
@ -24,6 +24,7 @@ ShaderOpenGL::ShaderOpenGL()
|
|||
, mShaderSaturation {0}
|
||||
, mShaderDimming {0}
|
||||
, mShaderReflectionsFalloff {0}
|
||||
, mBlurStrength {0}
|
||||
, mShaderFlags {0}
|
||||
{
|
||||
}
|
||||
|
@ -128,6 +129,7 @@ void ShaderOpenGL::getVariableLocations(GLuint programID)
|
|||
mShaderSaturation = glGetUniformLocation(mProgramID, "saturation");
|
||||
mShaderDimming = glGetUniformLocation(mProgramID, "dimming");
|
||||
mShaderReflectionsFalloff = glGetUniformLocation(mProgramID, "reflectionsFalloff");
|
||||
mBlurStrength = glGetUniformLocation(mProgramID, "blurStrength");
|
||||
mShaderFlags = glGetUniformLocation(mProgramID, "shaderFlags");
|
||||
}
|
||||
|
||||
|
@ -198,6 +200,12 @@ void ShaderOpenGL::setReflectionsFalloff(GLfloat falloff)
|
|||
GL_CHECK_ERROR(glUniform1f(mShaderReflectionsFalloff, falloff));
|
||||
}
|
||||
|
||||
void ShaderOpenGL::setBlurStrength(GLfloat blurStrength)
|
||||
{
|
||||
if (mBlurStrength != -1)
|
||||
GL_CHECK_ERROR(glUniform1f(mBlurStrength, blurStrength));
|
||||
}
|
||||
|
||||
void ShaderOpenGL::setFlags(GLuint flags)
|
||||
{
|
||||
if (mShaderFlags != -1)
|
||||
|
|
|
@ -74,6 +74,7 @@ public:
|
|||
void setSaturation(GLfloat saturation);
|
||||
void setDimming(GLfloat dimming);
|
||||
void setReflectionsFalloff(GLfloat falloff);
|
||||
void setBlurStrength(GLfloat blurStrength);
|
||||
void setFlags(GLuint flags);
|
||||
// Sets the shader program to use the loaded shaders.
|
||||
void activateShaders();
|
||||
|
@ -101,6 +102,7 @@ private:
|
|||
GLint mShaderSaturation;
|
||||
GLint mShaderDimming;
|
||||
GLint mShaderReflectionsFalloff;
|
||||
GLint mBlurStrength;
|
||||
GLint mShaderFlags;
|
||||
};
|
||||
|
||||
|
|
|
@ -1,14 +1,11 @@
|
|||
// SPDX-License-Identifier: MIT
|
||||
//
|
||||
// Implementation based on the article "Efficient Gaussian blur with linear sampling"
|
||||
// http://rastergrid.com/blog/2010/09/efficient-gaussian-blur-with-linear-sampling/
|
||||
// A version for MasterEffect Reborn, a standalone version, and a custom shader version for SweetFX
|
||||
// can be found at http://reshade.me/forum/shader-presentation/27-gaussian-blur-bloom-unsharpmask
|
||||
// EmulationStation Desktop Edition
|
||||
// blur_horizontal.glsl
|
||||
//
|
||||
// Taken from the RetroArch project and modified for ES-DE.
|
||||
// Horizontal gaussian blur.
|
||||
//
|
||||
|
||||
#define HW 1.00
|
||||
|
||||
// Vertex section of code:
|
||||
#if defined(VERTEX)
|
||||
|
||||
|
@ -31,8 +28,8 @@ precision mediump float;
|
|||
#endif
|
||||
|
||||
uniform uint shaderFlags;
|
||||
uniform vec2 textureSize;
|
||||
uniform sampler2D textureSampler;
|
||||
uniform float blurStrength;
|
||||
in vec2 texCoord;
|
||||
out vec4 FragColor;
|
||||
|
||||
|
@ -45,32 +42,48 @@ out vec4 FragColor;
|
|||
|
||||
void main()
|
||||
{
|
||||
vec4 SourceSize;
|
||||
vec2 PIXEL_SIZE;
|
||||
vec4 color = vec4(0.0);
|
||||
float hstep = 1.0f;
|
||||
float vstep = 0.0f;
|
||||
vec2 tc;
|
||||
|
||||
if (0x0u != (shaderFlags & 0x10u)) {
|
||||
SourceSize = vec4(textureSize.yx, 1.0 / textureSize.xy);
|
||||
PIXEL_SIZE = vec2(SourceSize.w, SourceSize.z);
|
||||
// Screen rotated 90 or 270 degrees.
|
||||
tc = texCoord.yx;
|
||||
}
|
||||
else {
|
||||
SourceSize = vec4(textureSize.xy, 1.0 / textureSize.xy);
|
||||
PIXEL_SIZE = vec2(SourceSize.z, SourceSize.w);
|
||||
tc = texCoord.xy;
|
||||
}
|
||||
|
||||
float sampleOffsets[5] = float[5](0.0, 1.4347826, 3.3478260, 5.2608695, 7.1739130);
|
||||
float sampleWeights[5] =
|
||||
float[5](0.16818994, 0.27276957, 0.11690125, 0.024067905, 0.0021112196);
|
||||
// 9-tap filter.
|
||||
color += texture(textureSampler,
|
||||
vec2(tc.x - 4.0 * blurStrength * hstep, tc.y - 4.0 * blurStrength * vstep)) *
|
||||
0.0162162162;
|
||||
color += texture(textureSampler,
|
||||
vec2(tc.x - 3.0 * blurStrength * hstep, tc.y - 3.0 * blurStrength * vstep)) *
|
||||
0.0540540541;
|
||||
color += texture(textureSampler,
|
||||
vec2(tc.x - 2.0 * blurStrength * hstep, tc.y - 2.0 * blurStrength * vstep)) *
|
||||
0.1216216216;
|
||||
color += texture(textureSampler,
|
||||
vec2(tc.x - 1.0 * blurStrength * hstep, tc.y - 1.0 * blurStrength * vstep)) *
|
||||
0.1945945946;
|
||||
|
||||
vec4 color = texture(textureSampler, texCoord) * sampleWeights[0];
|
||||
for (int i = 1; i < 5; i++) {
|
||||
color +=
|
||||
texture(textureSampler, texCoord + vec2(sampleOffsets[i] * HW * PIXEL_SIZE.x, 0.0)) *
|
||||
sampleWeights[i];
|
||||
color +=
|
||||
texture(textureSampler, texCoord - vec2(sampleOffsets[i] * HW * PIXEL_SIZE.x, 0.0)) *
|
||||
sampleWeights[i];
|
||||
}
|
||||
color += texture(textureSampler, vec2(tc.x, tc.y)) * 0.2270270270;
|
||||
|
||||
FragColor = vec4(color);
|
||||
color += texture(textureSampler,
|
||||
vec2(tc.x + 1.0 * blurStrength * hstep, tc.y + 1.0 * blurStrength * vstep)) *
|
||||
0.1945945946;
|
||||
color += texture(textureSampler,
|
||||
vec2(tc.x + 2.0 * blurStrength * hstep, tc.y + 2.0 * blurStrength * vstep)) *
|
||||
0.1216216216;
|
||||
color += texture(textureSampler,
|
||||
vec2(tc.x + 3.0 * blurStrength * hstep, tc.y + 3.0 * blurStrength * vstep)) *
|
||||
0.0540540541;
|
||||
color += texture(textureSampler,
|
||||
vec2(tc.x + 4.0 * blurStrength * hstep, tc.y + 4.0 * blurStrength * vstep)) *
|
||||
0.0162162162;
|
||||
|
||||
FragColor = vec4(color.rgb, 1.0);
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -1,14 +1,11 @@
|
|||
// SPDX-License-Identifier: MIT
|
||||
//
|
||||
// Implementation based on the article "Efficient Gaussian blur with linear sampling"
|
||||
// http://rastergrid.com/blog/2010/09/efficient-gaussian-blur-with-linear-sampling/
|
||||
// A version for MasterEffect Reborn, a standalone version, and a custom shader version for SweetFX
|
||||
// can be found at http://reshade.me/forum/shader-presentation/27-gaussian-blur-bloom-unsharpmask
|
||||
// EmulationStation Desktop Edition
|
||||
// blur_vertical.glsl
|
||||
//
|
||||
// Taken from the RetroArch project and modified for ES-DE.
|
||||
// Vertical gaussian blur.
|
||||
//
|
||||
|
||||
#define VW 1.00
|
||||
|
||||
// Vertex section of code:
|
||||
#if defined(VERTEX)
|
||||
|
||||
|
@ -31,8 +28,8 @@ precision mediump float;
|
|||
#endif
|
||||
|
||||
uniform uint shaderFlags;
|
||||
uniform vec2 textureSize;
|
||||
uniform sampler2D textureSampler;
|
||||
uniform float blurStrength;
|
||||
in vec2 texCoord;
|
||||
out vec4 FragColor;
|
||||
|
||||
|
@ -45,32 +42,48 @@ out vec4 FragColor;
|
|||
|
||||
void main()
|
||||
{
|
||||
vec4 SourceSize;
|
||||
vec2 PIXEL_SIZE;
|
||||
vec4 color = vec4(0.0);
|
||||
float hstep = 0.0f;
|
||||
float vstep = 1.0f;
|
||||
vec2 tc;
|
||||
|
||||
if (0x0u != (shaderFlags & 0x10u)) {
|
||||
SourceSize = vec4(textureSize.xy, 1.0 / textureSize.yx);
|
||||
PIXEL_SIZE = vec2(SourceSize.w, SourceSize.z);
|
||||
// Screen rotated 90 or 270 degrees.
|
||||
tc = texCoord.yx;
|
||||
}
|
||||
else {
|
||||
SourceSize = vec4(textureSize.xy, 1.0 / textureSize.xy);
|
||||
PIXEL_SIZE = vec2(SourceSize.z, SourceSize.w);
|
||||
tc = texCoord.xy;
|
||||
}
|
||||
|
||||
float sampleOffsets[5] = float[5](0.0, 1.4347826, 3.3478260, 5.2608695, 7.1739130);
|
||||
float sampleWeights[5] =
|
||||
float[5](0.16818994, 0.27276957, 0.11690125, 0.024067905, 0.0021112196);
|
||||
// 9-tap filter.
|
||||
color += texture(textureSampler,
|
||||
vec2(tc.x - 4.0 * blurStrength * hstep, tc.y - 4.0 * blurStrength * vstep)) *
|
||||
0.0162162162;
|
||||
color += texture(textureSampler,
|
||||
vec2(tc.x - 3.0 * blurStrength * hstep, tc.y - 3.0 * blurStrength * vstep)) *
|
||||
0.0540540541;
|
||||
color += texture(textureSampler,
|
||||
vec2(tc.x - 2.0 * blurStrength * hstep, tc.y - 2.0 * blurStrength * vstep)) *
|
||||
0.1216216216;
|
||||
color += texture(textureSampler,
|
||||
vec2(tc.x - 1.0 * blurStrength * hstep, tc.y - 1.0 * blurStrength * vstep)) *
|
||||
0.1945945946;
|
||||
|
||||
vec4 color = texture(textureSampler, texCoord) * sampleWeights[0];
|
||||
for (int i = 1; i < 5; i++) {
|
||||
color +=
|
||||
texture(textureSampler, texCoord + vec2(0.0, sampleOffsets[i] * VW * PIXEL_SIZE.y)) *
|
||||
sampleWeights[i];
|
||||
color +=
|
||||
texture(textureSampler, texCoord - vec2(0.0, sampleOffsets[i] * VW * PIXEL_SIZE.y)) *
|
||||
sampleWeights[i];
|
||||
}
|
||||
color += texture(textureSampler, vec2(tc.x, tc.y)) * 0.2270270270;
|
||||
|
||||
FragColor = vec4(color);
|
||||
color += texture(textureSampler,
|
||||
vec2(tc.x + 1.0 * blurStrength * hstep, tc.y + 1.0 * blurStrength * vstep)) *
|
||||
0.1945945946;
|
||||
color += texture(textureSampler,
|
||||
vec2(tc.x + 2.0 * blurStrength * hstep, tc.y + 2.0 * blurStrength * vstep)) *
|
||||
0.1216216216;
|
||||
color += texture(textureSampler,
|
||||
vec2(tc.x + 3.0 * blurStrength * hstep, tc.y + 3.0 * blurStrength * vstep)) *
|
||||
0.0540540541;
|
||||
color += texture(textureSampler,
|
||||
vec2(tc.x + 4.0 * blurStrength * hstep, tc.y + 4.0 * blurStrength * vstep)) *
|
||||
0.0162162162;
|
||||
|
||||
FragColor = vec4(color.rgb, 1.0);
|
||||
}
|
||||
#endif
|
||||
|
|
Loading…
Reference in a new issue