mirror of
https://github.com/RetroDECK/ES-DE.git
synced 2025-01-18 23:15:38 +00:00
Greatly improved the shader post processing code and fixed some related bugs.
This commit is contained in:
parent
f08b434bc6
commit
ded5b1d29b
|
@ -323,30 +323,39 @@ void Window::render()
|
|||
// Generate a cache texture of the shaded background when opening the menu, which
|
||||
// will remain valid until the menu is closed. This is way faster than having to
|
||||
// render the shaders for every frame.
|
||||
// const auto backgroundStartTime = std::chrono::system_clock::now();
|
||||
|
||||
std::shared_ptr<TextureResource> mPostprocessedBackground;
|
||||
mPostprocessedBackground = TextureResource::get("");
|
||||
unsigned char* processedTexture = new unsigned char[Renderer::getScreenWidth() *
|
||||
Renderer::getScreenHeight() * 4];
|
||||
|
||||
// Defocus the background using three passes of gaussian blur.
|
||||
Renderer::shaderParameters blurParameters;
|
||||
blurParameters.shaderPasses = 3;
|
||||
// Defocus the background using multiple passes of gaussian blur, with the number
|
||||
// of iterations relative to the screen resolution.
|
||||
Renderer::shaderParameters backgroundParameters;
|
||||
float heightModifier = Renderer::getScreenHeightModifier();
|
||||
|
||||
if (heightModifier < 1)
|
||||
backgroundParameters.blurPasses = 2; // Below 1080
|
||||
else if (heightModifier >= 4)
|
||||
backgroundParameters.blurPasses = 12; // 8K
|
||||
else if (heightModifier >= 2.9)
|
||||
backgroundParameters.blurPasses = 10; // 6K
|
||||
else if (heightModifier >= 2.6)
|
||||
backgroundParameters.blurPasses = 8; // 5K
|
||||
else if (heightModifier >= 2)
|
||||
backgroundParameters.blurPasses = 5; // 4K
|
||||
else if (heightModifier >= 1.3)
|
||||
backgroundParameters.blurPasses = 3; // 1440
|
||||
else if (heightModifier >= 1)
|
||||
backgroundParameters.blurPasses = 2; // 1080
|
||||
|
||||
// Also dim the background slightly.
|
||||
backgroundParameters.fragmentDimValue = 0.60f;
|
||||
|
||||
Renderer::shaderPostprocessing(Renderer::SHADER_BLUR_HORIZONTAL |
|
||||
Renderer::SHADER_BLUR_VERTICAL, blurParameters, processedTexture);
|
||||
|
||||
mPostprocessedBackground->initFromPixels(processedTexture,
|
||||
Renderer::getScreenWidth(), Renderer::getScreenHeight());
|
||||
|
||||
mBackgroundOverlay->setImage(mPostprocessedBackground);
|
||||
mBackgroundOverlay->render(transform);
|
||||
|
||||
// Dim the background. We need to do this as a separate step as combining
|
||||
// it with the blurring leads to very strange and severe artifacts.
|
||||
// This is for sure a bug that needs to be resolved at some later date.
|
||||
Renderer::shaderParameters blackParameters;
|
||||
blackParameters.fragmentDimValue = 0.6f;
|
||||
Renderer::shaderPostprocessing(Renderer::SHADER_DIM,
|
||||
blackParameters, processedTexture);
|
||||
Renderer::SHADER_BLUR_VERTICAL | Renderer::SHADER_DIM,
|
||||
backgroundParameters, processedTexture);
|
||||
|
||||
mPostprocessedBackground->initFromPixels(processedTexture,
|
||||
Renderer::getScreenWidth(), Renderer::getScreenHeight());
|
||||
|
@ -365,11 +374,18 @@ void Window::render()
|
|||
|
||||
delete[] processedTexture;
|
||||
mCachedBackground = true;
|
||||
|
||||
// const auto backgroundEndTime = std::chrono::system_clock::now();
|
||||
// LOG(LogDebug) << "Window::render(): Time to create cached background: " <<
|
||||
// std::chrono::duration_cast<std::chrono::milliseconds>
|
||||
// (backgroundEndTime - backgroundStartTime).count() << " ms";
|
||||
}
|
||||
// Fade in the cached background.
|
||||
// Fade in the cached background, unless the menu is set to open without any animation.
|
||||
if (Settings::getInstance()->getString("MenuOpeningEffect") != "none") {
|
||||
mBackgroundOverlay->setOpacity(mBackgroundOverlayOpacity);
|
||||
if (mBackgroundOverlayOpacity < 255)
|
||||
mBackgroundOverlayOpacity = Math::clamp(mBackgroundOverlayOpacity + 30, 0, 255);
|
||||
}
|
||||
#endif
|
||||
|
||||
mBackgroundOverlay->render(transform);
|
||||
|
|
|
@ -36,7 +36,7 @@ namespace Renderer
|
|||
float fragmentSaturation;
|
||||
float fragmentDimValue;
|
||||
float fragmentOpacity;
|
||||
unsigned int shaderPasses;
|
||||
unsigned int blurPasses;
|
||||
|
||||
shaderParameters()
|
||||
: textureSize({0.0f, 0.0f}),
|
||||
|
@ -44,7 +44,7 @@ namespace Renderer
|
|||
fragmentSaturation(1.0f),
|
||||
fragmentDimValue(0.4f),
|
||||
fragmentOpacity(1.0f),
|
||||
shaderPasses(1)
|
||||
blurPasses(1)
|
||||
{};
|
||||
};
|
||||
|
||||
|
|
|
@ -259,7 +259,6 @@ namespace Renderer
|
|||
GL_CHECK_ERROR(glDrawArrays(GL_TRIANGLE_STRIP, 0, _numVertices));
|
||||
}
|
||||
else {
|
||||
for (unsigned int i = 0; i < _parameters.shaderPasses; i++) {
|
||||
// If saturation is set below the maximum (default) value, run the
|
||||
// desaturation shader.
|
||||
if (_vertices->saturation < 1.0 || _parameters.fragmentSaturation < 1.0) {
|
||||
|
@ -336,7 +335,6 @@ namespace Renderer
|
|||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
|
@ -403,6 +401,7 @@ namespace Renderer
|
|||
unsigned char* textureRGBA)
|
||||
{
|
||||
Vertex vertices[4];
|
||||
std::vector<unsigned int>shaderList;
|
||||
GLuint width = getScreenWidth();
|
||||
GLuint height = getScreenHeight();
|
||||
float widthf = static_cast<float>(width);
|
||||
|
@ -415,7 +414,18 @@ namespace Renderer
|
|||
vertices[2] = { { widthf, 0 }, { 1, 1 }, 0 };
|
||||
vertices[3] = { { widthf, heightf }, { 1, 0 }, 0};
|
||||
|
||||
vertices[0].shaders = shaders;
|
||||
if (shaders & Renderer::SHADER_DESATURATE)
|
||||
shaderList.push_back(Renderer::SHADER_DESATURATE);
|
||||
if (shaders & Renderer::SHADER_OPACITY)
|
||||
shaderList.push_back(Renderer::SHADER_OPACITY);
|
||||
if (shaders & Renderer::SHADER_DIM)
|
||||
shaderList.push_back(Renderer::SHADER_DIM);
|
||||
if (shaders & Renderer::SHADER_BLUR_HORIZONTAL)
|
||||
shaderList.push_back(Renderer::SHADER_BLUR_HORIZONTAL);
|
||||
if (shaders & Renderer::SHADER_BLUR_VERTICAL)
|
||||
shaderList.push_back(Renderer::SHADER_BLUR_VERTICAL);
|
||||
if (shaders & Renderer::SHADER_SCANLINES)
|
||||
shaderList.push_back(Renderer::SHADER_SCANLINES);
|
||||
|
||||
if (parameters.fragmentSaturation < 1.0)
|
||||
vertices[0].saturation = parameters.fragmentSaturation;
|
||||
|
@ -424,6 +434,17 @@ namespace Renderer
|
|||
GLuint screenTexture = createTexture(Texture::RGBA, false, false, width, height, nullptr);
|
||||
|
||||
GL_CHECK_ERROR(glBindFramebuffer(GL_READ_FRAMEBUFFER, 0));
|
||||
|
||||
for (int i = 0; i < shaderList.size(); i++) {
|
||||
vertices[0].shaders = shaderList[i];
|
||||
int shaderPasses = 1;
|
||||
// For the blur shaders there is an optional variable to set the number of passes
|
||||
// to execute, which proportionally affects the blur amount.
|
||||
if (shaderList[i] == Renderer::SHADER_BLUR_HORIZONTAL ||
|
||||
shaderList[i] == Renderer::SHADER_BLUR_VERTICAL)
|
||||
shaderPasses = parameters.blurPasses;
|
||||
|
||||
for (int p = 0; p < shaderPasses; p++) {
|
||||
GL_CHECK_ERROR(glBindFramebuffer(GL_DRAW_FRAMEBUFFER, shaderFBO));
|
||||
|
||||
// Attach the texture to the shader framebuffer.
|
||||
|
@ -442,10 +463,10 @@ namespace Renderer
|
|||
drawTriangleStrips(vertices, 4, Transform4x4f::Identity(),
|
||||
Blend::SRC_ALPHA, Blend::ONE_MINUS_SRC_ALPHA, parameters);
|
||||
|
||||
// If textureRGBA has an address, it means that the output should go to this texture
|
||||
// rather than to the screen. The glReadPixels() function is slow, but since this would
|
||||
// typically only run every now and then to create a cached screen texture, it doesn't
|
||||
// really matter.
|
||||
// If textureRGBA has an address, it means that the output should go to this
|
||||
// texture rather than to the screen. The glReadPixels() function is slow, but
|
||||
// since this will typically only run every now and then to create a cached
|
||||
// screen texture, it doesn't really matter.
|
||||
if (textureRGBA) {
|
||||
GL_CHECK_ERROR(glBindFramebuffer(GL_READ_FRAMEBUFFER, shaderFBO));
|
||||
GL_CHECK_ERROR(glReadPixels(0, 0, width, height,
|
||||
|
@ -459,6 +480,8 @@ namespace Renderer
|
|||
GL_CHECK_ERROR(glBlitFramebuffer(0, 0, width, height, 0, 0, width, height,
|
||||
GL_COLOR_BUFFER_BIT, GL_NEAREST));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
GL_CHECK_ERROR(glBindFramebuffer(GL_READ_FRAMEBUFFER, 0));
|
||||
destroyTexture(screenTexture);
|
||||
|
|
Loading…
Reference in a new issue