From 09bec67821f6ac1a78aab3bfbd037b1397721b2a Mon Sep 17 00:00:00 2001 From: Magnus Norddahl Date: Sat, 3 Sep 2016 04:12:00 +0200 Subject: [PATCH] Resolve multisampling depth in shader --- src/gl/renderer/gl_postprocess.cpp | 21 +++++++++-------- src/gl/shaders/gl_ambientshader.cpp | 28 ++++++++++++----------- src/gl/shaders/gl_ambientshader.h | 15 ++++++------ wadsrc/static/shaders/glsl/lineardepth.fp | 19 +++++++++++++++ 4 files changed, 54 insertions(+), 29 deletions(-) diff --git a/src/gl/renderer/gl_postprocess.cpp b/src/gl/renderer/gl_postprocess.cpp index 97491cb58..8282bc387 100644 --- a/src/gl/renderer/gl_postprocess.cpp +++ b/src/gl/renderer/gl_postprocess.cpp @@ -127,8 +127,7 @@ void FGLRenderer::RenderScreenQuad() void FGLRenderer::PostProcessScene() { - if (FGLRenderBuffers::IsEnabled()) mBuffers->BlitSceneToTexture(); - AmbientOccludeScene(); + mBuffers->BlitSceneToTexture(); UpdateCameraExposure(); BloomScene(); TonemapScene(); @@ -156,6 +155,7 @@ void FGLRenderer::AmbientOccludeScene() const float blurAmount = gl_ssao_blur_amount; int blurSampleCount = gl_ssao_blur_samples; float aoStrength = gl_ssao_strength; + bool multisample = gl_multisample > 1; //float tanHalfFovy = tan(fovy * (M_PI / 360.0f)); float tanHalfFovy = 1.0f / 1.33333302f; // 1.0f / gl_RenderState.mProjectionMatrix.get()[5]; @@ -168,12 +168,15 @@ void FGLRenderer::AmbientOccludeScene() glBindFramebuffer(GL_FRAMEBUFFER, mBuffers->AmbientFB0); glViewport(0, 0, mBuffers->AmbientWidth, mBuffers->AmbientHeight); mBuffers->BindSceneDepthTexture(0); - mLinearDepthShader->Bind(); - mLinearDepthShader->DepthTexture.Set(0); - mLinearDepthShader->LinearizeDepthA.Set(1.0f / GetZFar() - 1.0f / GetZNear()); - mLinearDepthShader->LinearizeDepthB.Set(MAX(1.0f / GetZNear(), 1.e-8f)); - mLinearDepthShader->InverseDepthRangeA.Set(1.0f); - mLinearDepthShader->InverseDepthRangeB.Set(0.0f); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + mLinearDepthShader->Bind(multisample); + mLinearDepthShader->DepthTexture[multisample].Set(0); + if (multisample) mLinearDepthShader->SampleCount[multisample].Set(gl_multisample); + mLinearDepthShader->LinearizeDepthA[multisample].Set(1.0f / GetZFar() - 1.0f / GetZNear()); + mLinearDepthShader->LinearizeDepthB[multisample].Set(MAX(1.0f / GetZNear(), 1.e-8f)); + mLinearDepthShader->InverseDepthRangeA[multisample].Set(1.0f); + mLinearDepthShader->InverseDepthRangeB[multisample].Set(0.0f); RenderScreenQuad(); // Apply ambient occlusion @@ -218,7 +221,7 @@ void FGLRenderer::AmbientOccludeScene() RenderScreenQuad(); // Add SSAO back to scene texture: - mBuffers->BindCurrentFB(); + mBuffers->BindSceneFB(); glViewport(mSceneViewport.left, mSceneViewport.top, mSceneViewport.width, mSceneViewport.height); glEnable(GL_BLEND); glBlendEquation(GL_FUNC_ADD); diff --git a/src/gl/shaders/gl_ambientshader.cpp b/src/gl/shaders/gl_ambientshader.cpp index 6b8c9cc48..f3b6eced6 100644 --- a/src/gl/shaders/gl_ambientshader.cpp +++ b/src/gl/shaders/gl_ambientshader.cpp @@ -49,22 +49,24 @@ #include "gl/system/gl_cvars.h" #include "gl/shaders/gl_ambientshader.h" -void FLinearDepthShader::Bind() +void FLinearDepthShader::Bind(bool multisample) { - if (!mShader) + auto &shader = mShader[multisample]; + if (!shader) { - mShader.Compile(FShaderProgram::Vertex, "shaders/glsl/screenquad.vp", "", 330); - mShader.Compile(FShaderProgram::Fragment, "shaders/glsl/lineardepth.fp", "", 330); - mShader.SetFragDataLocation(0, "FragColor"); - mShader.Link("shaders/glsl/lineardepth"); - mShader.SetAttribLocation(0, "PositionInProjection"); - DepthTexture.Init(mShader, "DepthTexture"); - LinearizeDepthA.Init(mShader, "LinearizeDepthA"); - LinearizeDepthB.Init(mShader, "LinearizeDepthB"); - InverseDepthRangeA.Init(mShader, "InverseDepthRangeA"); - InverseDepthRangeB.Init(mShader, "InverseDepthRangeB"); + shader.Compile(FShaderProgram::Vertex, "shaders/glsl/screenquad.vp", "", 330); + shader.Compile(FShaderProgram::Fragment, "shaders/glsl/lineardepth.fp", multisample ? "#define MULTISAMPLE\n" : "", 330); + shader.SetFragDataLocation(0, "FragColor"); + shader.Link("shaders/glsl/lineardepth"); + shader.SetAttribLocation(0, "PositionInProjection"); + DepthTexture[multisample].Init(shader, "DepthTexture"); + SampleCount[multisample].Init(shader, "SampleCount"); + LinearizeDepthA[multisample].Init(shader, "LinearizeDepthA"); + LinearizeDepthB[multisample].Init(shader, "LinearizeDepthB"); + InverseDepthRangeA[multisample].Init(shader, "InverseDepthRangeA"); + InverseDepthRangeB[multisample].Init(shader, "InverseDepthRangeB"); } - mShader.Bind(); + shader.Bind(); } void FSSAOShader::Bind() diff --git a/src/gl/shaders/gl_ambientshader.h b/src/gl/shaders/gl_ambientshader.h index 419ca939e..5f9ef630b 100644 --- a/src/gl/shaders/gl_ambientshader.h +++ b/src/gl/shaders/gl_ambientshader.h @@ -6,16 +6,17 @@ class FLinearDepthShader { public: - void Bind(); + void Bind(bool multisample); - FBufferedUniformSampler DepthTexture; - FBufferedUniform1f LinearizeDepthA; - FBufferedUniform1f LinearizeDepthB; - FBufferedUniform1f InverseDepthRangeA; - FBufferedUniform1f InverseDepthRangeB; + FBufferedUniformSampler DepthTexture[2]; + FBufferedUniform1i SampleCount[2]; + FBufferedUniform1f LinearizeDepthA[2]; + FBufferedUniform1f LinearizeDepthB[2]; + FBufferedUniform1f InverseDepthRangeA[2]; + FBufferedUniform1f InverseDepthRangeB[2]; private: - FShaderProgram mShader; + FShaderProgram mShader[2]; }; class FSSAOShader diff --git a/wadsrc/static/shaders/glsl/lineardepth.fp b/wadsrc/static/shaders/glsl/lineardepth.fp index f61bb3995..31df9dc32 100644 --- a/wadsrc/static/shaders/glsl/lineardepth.fp +++ b/wadsrc/static/shaders/glsl/lineardepth.fp @@ -2,7 +2,12 @@ in vec2 TexCoord; out vec4 FragColor; +#if defined(MULTISAMPLE) +uniform sampler2DMS DepthTexture; +uniform int SampleCount; +#else uniform sampler2D DepthTexture; +#endif uniform float LinearizeDepthA; uniform float LinearizeDepthB; uniform float InverseDepthRangeA; @@ -10,7 +15,21 @@ uniform float InverseDepthRangeB; void main() { +#if defined(MULTISAMPLE) + ivec2 texSize = textureSize(DepthTexture); + ivec2 ipos = ivec2(TexCoord * vec2(texSize)); + float depth = 0.0; + for (int i = 0; i < SampleCount; i++) + depth += texelFetch(DepthTexture, ipos, i).x; + depth /= float(SampleCount); +#else + /*ivec2 texSize = textureSize(DepthTexture, 0); + ivec2 ipos = ivec2(TexCoord * vec2(texSize)); + if (ipos.x < 0) ipos.x += texSize.x; + if (ipos.y < 0) ipos.y += texSize.y; + float depth = texelFetch(DepthTexture, ipos, 0).x;*/ float depth = texture(DepthTexture, TexCoord).x; +#endif float normalizedDepth = clamp(InverseDepthRangeA * depth + InverseDepthRangeB, 0.0, 1.0); FragColor = vec4(1.0 / (normalizedDepth * LinearizeDepthA + LinearizeDepthB), 0.0, 0.0, 1.0); }