diff --git a/src/gl/renderer/gl_postprocess.cpp b/src/gl/renderer/gl_postprocess.cpp index 2d62a8d02..c6535c2df 100644 --- a/src/gl/renderer/gl_postprocess.cpp +++ b/src/gl/renderer/gl_postprocess.cpp @@ -143,6 +143,8 @@ void FGLRenderer::BloomScene() mBloomExtractShader->Bind(); mBloomExtractShader->SceneTexture.Set(0); mBloomExtractShader->Exposure.Set(mCameraExposure); + mBloomExtractShader->Scale.Set(mSceneViewport.width / (float)mScreenViewport.width, mSceneViewport.height / (float)mScreenViewport.height); + mBloomExtractShader->Offset.Set(mSceneViewport.left / (float)mScreenViewport.width, mSceneViewport.top / (float)mScreenViewport.height); RenderScreenQuad(); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); @@ -182,7 +184,7 @@ void FGLRenderer::BloomScene() // Add bloom back to scene texture: mBuffers->BindCurrentFB(); - glViewport(mScreenViewport.left, mScreenViewport.top, mScreenViewport.width, mScreenViewport.height); + glViewport(mSceneViewport.left, mSceneViewport.top, mSceneViewport.width, mSceneViewport.height); glEnable(GL_BLEND); glBlendEquation(GL_FUNC_ADD); glBlendFunc(GL_ONE, GL_ONE); @@ -193,6 +195,7 @@ void FGLRenderer::BloomScene() mBloomCombineShader->Bind(); mBloomCombineShader->BloomTexture.Set(0); RenderScreenQuad(); + glViewport(mScreenViewport.left, mScreenViewport.top, mScreenViewport.width, mScreenViewport.height); } //----------------------------------------------------------------------------- diff --git a/src/gl/renderer/gl_renderbuffers.cpp b/src/gl/renderer/gl_renderbuffers.cpp index 3b402d801..918850e31 100644 --- a/src/gl/renderer/gl_renderbuffers.cpp +++ b/src/gl/renderer/gl_renderbuffers.cpp @@ -139,7 +139,7 @@ void FGLRenderBuffers::DeleteFrameBuffer(GLuint &handle) // //========================================================================== -void FGLRenderBuffers::Setup(int width, int height) +void FGLRenderBuffers::Setup(int width, int height, int sceneWidth, int sceneHeight) { if (!IsEnabled()) return; @@ -151,16 +151,23 @@ void FGLRenderBuffers::Setup(int width, int height) CreateScene(mWidth, mHeight, samples); mSamples = samples; } - else if (width > mWidth || height > mHeight) + else if (width != mWidth || height != mHeight) { CreatePipeline(width, height); CreateScene(width, height, samples); - CreateBloom(width, height); mWidth = width; mHeight = height; mSamples = samples; } + // Bloom bluring buffers need to match the scene to avoid bloom bleeding artifacts + if (mBloomWidth != sceneWidth || mBloomHeight != sceneHeight) + { + CreateBloom(sceneWidth, sceneHeight); + mBloomWidth = sceneWidth; + mBloomHeight = sceneHeight; + } + glActiveTexture(GL_TEXTURE0); glBindTexture(GL_TEXTURE_2D, 0); glBindRenderbuffer(GL_RENDERBUFFER, 0); diff --git a/src/gl/renderer/gl_renderbuffers.h b/src/gl/renderer/gl_renderbuffers.h index 8b3001c96..68c4b2a31 100644 --- a/src/gl/renderer/gl_renderbuffers.h +++ b/src/gl/renderer/gl_renderbuffers.h @@ -20,7 +20,7 @@ public: FGLRenderBuffers(); ~FGLRenderBuffers(); - void Setup(int width, int height); + void Setup(int width, int height, int sceneWidth, int sceneHeight); void BindSceneFB(); void BlitSceneToTexture(); @@ -64,6 +64,8 @@ private: int mWidth = 0; int mHeight = 0; int mSamples = 0; + int mBloomWidth = 0; + int mBloomHeight = 0; static const int NumPipelineTextures = 2; int mCurrentPipelineTexture = 0; diff --git a/src/gl/renderer/gl_renderer.cpp b/src/gl/renderer/gl_renderer.cpp index 7a4dbab55..84d02159f 100644 --- a/src/gl/renderer/gl_renderer.cpp +++ b/src/gl/renderer/gl_renderer.cpp @@ -286,7 +286,7 @@ void FGLRenderer::Begin2D() { if (FGLRenderBuffers::IsEnabled()) { - mBuffers->Setup(framebuffer->GetWidth(), framebuffer->GetHeight()); + mBuffers->Setup(mScreenViewport.width, mScreenViewport.height, mSceneViewport.width, mSceneViewport.height); if (mDrawingScene2D) mBuffers->BindSceneFB(); else diff --git a/src/gl/scene/gl_scene.cpp b/src/gl/scene/gl_scene.cpp index 4ba181656..751a74c09 100644 --- a/src/gl/scene/gl_scene.cpp +++ b/src/gl/scene/gl_scene.cpp @@ -170,7 +170,7 @@ void FGLRenderer::Set3DViewport(bool mainview) { if (mainview && FGLRenderBuffers::IsEnabled()) { - mBuffers->Setup(mScreenViewport.width, mScreenViewport.height); + mBuffers->Setup(mScreenViewport.width, mScreenViewport.height, mSceneViewport.width, mSceneViewport.height); mBuffers->BindSceneFB(); } diff --git a/src/gl/shaders/gl_bloomshader.cpp b/src/gl/shaders/gl_bloomshader.cpp index f9e38e0c3..9e8f60133 100644 --- a/src/gl/shaders/gl_bloomshader.cpp +++ b/src/gl/shaders/gl_bloomshader.cpp @@ -60,6 +60,8 @@ void FBloomExtractShader::Bind() mShader.SetAttribLocation(0, "PositionInProjection"); SceneTexture.Init(mShader, "SceneTexture"); Exposure.Init(mShader, "ExposureAdjustment"); + Scale.Init(mShader, "Scale"); + Offset.Init(mShader, "Offset"); } mShader.Bind(); } diff --git a/src/gl/shaders/gl_bloomshader.h b/src/gl/shaders/gl_bloomshader.h index a8e93df83..cbc740ab6 100644 --- a/src/gl/shaders/gl_bloomshader.h +++ b/src/gl/shaders/gl_bloomshader.h @@ -10,6 +10,8 @@ public: FBufferedUniform1i SceneTexture; FBufferedUniform1f Exposure; + FBufferedUniform2f Scale; + FBufferedUniform2f Offset; private: FShaderProgram mShader; diff --git a/wadsrc/static/shaders/glsl/bloomextract.fp b/wadsrc/static/shaders/glsl/bloomextract.fp index dc753ce49..bc94c3c0e 100644 --- a/wadsrc/static/shaders/glsl/bloomextract.fp +++ b/wadsrc/static/shaders/glsl/bloomextract.fp @@ -4,9 +4,11 @@ out vec4 FragColor; uniform sampler2D SceneTexture; uniform float ExposureAdjustment; +uniform vec2 Scale; +uniform vec2 Offset; void main() { - vec4 color = texture(SceneTexture, TexCoord); + vec4 color = texture(SceneTexture, Offset + TexCoord * Scale); FragColor = max(vec4(color.rgb * ExposureAdjustment - 1, 1), vec4(0)); }