mirror of
https://github.com/ZDoom/gzdoom.git
synced 2024-11-10 14:51:40 +00:00
Change SSAO blur to be depth aware
This commit is contained in:
parent
5a0c61a2d5
commit
98032bc73f
9 changed files with 184 additions and 14 deletions
|
@ -209,8 +209,22 @@ void FGLRenderer::AmbientOccludeScene()
|
|||
RenderScreenQuad();
|
||||
|
||||
// Blur SSAO texture
|
||||
mBlurShader->BlurHorizontal(this, blurAmount, blurSampleCount, mBuffers->AmbientTexture1, mBuffers->AmbientFB0, mBuffers->AmbientWidth, mBuffers->AmbientHeight);
|
||||
mBlurShader->BlurVertical(this, blurAmount, blurSampleCount, mBuffers->AmbientTexture0, mBuffers->AmbientFB1, mBuffers->AmbientWidth, mBuffers->AmbientHeight);
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, mBuffers->AmbientFB0);
|
||||
glBindTexture(GL_TEXTURE_2D, mBuffers->AmbientTexture1);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
||||
mDepthBlurShader->Bind(false);
|
||||
mDepthBlurShader->BlurSharpness[false].Set(blurAmount);
|
||||
mDepthBlurShader->InvFullResolution[false].Set(1.0f / mBuffers->AmbientWidth, 1.0f / mBuffers->AmbientHeight);
|
||||
RenderScreenQuad();
|
||||
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, mBuffers->AmbientFB1);
|
||||
glBindTexture(GL_TEXTURE_2D, mBuffers->AmbientTexture0);
|
||||
mDepthBlurShader->Bind(true);
|
||||
mDepthBlurShader->BlurSharpness[true].Set(blurAmount);
|
||||
mDepthBlurShader->InvFullResolution[true].Set(1.0f / mBuffers->AmbientWidth, 1.0f / mBuffers->AmbientHeight);
|
||||
mDepthBlurShader->PowExponent[true].Set(1.8f);
|
||||
RenderScreenQuad();
|
||||
|
||||
// Add SSAO back to scene texture:
|
||||
mBuffers->BindCurrentFB();
|
||||
|
@ -225,8 +239,8 @@ void FGLRenderer::AmbientOccludeScene()
|
|||
glBindTexture(GL_TEXTURE_2D, mBuffers->AmbientTexture1);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||
mBloomCombineShader->Bind();
|
||||
mBloomCombineShader->BloomTexture.Set(0);
|
||||
mSSAOCombineShader->Bind();
|
||||
mSSAOCombineShader->AODepthTexture.Set(0);
|
||||
RenderScreenQuad();
|
||||
glViewport(mScreenViewport.left, mScreenViewport.top, mScreenViewport.width, mScreenViewport.height);
|
||||
|
||||
|
|
|
@ -313,8 +313,8 @@ void FGLRenderBuffers::CreateAmbientOcclusion(int width, int height)
|
|||
|
||||
AmbientWidth = width / 2;
|
||||
AmbientHeight = height / 2;
|
||||
AmbientTexture0 = Create2DTexture("AmbientTexture0", GL_RGBA32F, AmbientWidth, AmbientHeight);
|
||||
AmbientTexture1 = Create2DTexture("AmbientTexture1", GL_RGBA32F, AmbientWidth, AmbientHeight);
|
||||
AmbientTexture0 = Create2DTexture("AmbientTexture0", GL_RG32F, AmbientWidth, AmbientHeight);
|
||||
AmbientTexture1 = Create2DTexture("AmbientTexture1", GL_RG32F, AmbientWidth, AmbientHeight);
|
||||
AmbientFB0 = CreateFrameBuffer("AmbientFB0", AmbientTexture0);
|
||||
AmbientFB1 = CreateFrameBuffer("AmbientFB1", AmbientTexture1);
|
||||
|
||||
|
@ -370,6 +370,8 @@ GLuint FGLRenderBuffers::Create2DTexture(const FString &name, GLuint format, int
|
|||
case GL_RGBA16: dataformat = GL_RGBA; datatype = GL_UNSIGNED_SHORT; break;
|
||||
case GL_RGBA16F: dataformat = GL_RGBA; datatype = GL_FLOAT; break;
|
||||
case GL_RGBA32F: dataformat = GL_RGBA; datatype = GL_FLOAT; break;
|
||||
case GL_R32F: dataformat = GL_RED; datatype = GL_FLOAT; break;
|
||||
case GL_RG32F: dataformat = GL_RG; datatype = GL_FLOAT; break;
|
||||
case GL_DEPTH_COMPONENT24: dataformat = GL_DEPTH_COMPONENT; datatype = GL_FLOAT; break;
|
||||
case GL_STENCIL_INDEX8: dataformat = GL_STENCIL_INDEX; datatype = GL_INT; break;
|
||||
case GL_DEPTH24_STENCIL8: dataformat = GL_DEPTH_STENCIL; datatype = GL_UNSIGNED_INT_24_8; break;
|
||||
|
|
|
@ -123,6 +123,10 @@ FGLRenderer::FGLRenderer(OpenGLFrameBuffer *fb)
|
|||
mTonemapPalette = nullptr;
|
||||
mColormapShader = nullptr;
|
||||
mLensShader = nullptr;
|
||||
mLinearDepthShader = nullptr;
|
||||
mDepthBlurShader = nullptr;
|
||||
mSSAOShader = nullptr;
|
||||
mSSAOCombineShader = nullptr;
|
||||
}
|
||||
|
||||
void gl_LoadModels();
|
||||
|
@ -132,7 +136,9 @@ void FGLRenderer::Initialize(int width, int height)
|
|||
{
|
||||
mBuffers = new FGLRenderBuffers();
|
||||
mLinearDepthShader = new FLinearDepthShader();
|
||||
mDepthBlurShader = new FDepthBlurShader();
|
||||
mSSAOShader = new FSSAOShader();
|
||||
mSSAOCombineShader = new FSSAOCombineShader();
|
||||
mBloomExtractShader = new FBloomExtractShader();
|
||||
mBloomCombineShader = new FBloomCombineShader();
|
||||
mBlurShader = new FBlurShader();
|
||||
|
@ -194,7 +200,9 @@ FGLRenderer::~FGLRenderer()
|
|||
if (mBuffers) delete mBuffers;
|
||||
if (mPresentShader) delete mPresentShader;
|
||||
if (mLinearDepthShader) delete mLinearDepthShader;
|
||||
if (mDepthBlurShader) delete mDepthBlurShader;
|
||||
if (mSSAOShader) delete mSSAOShader;
|
||||
if (mSSAOCombineShader) delete mSSAOCombineShader;
|
||||
if (mBloomExtractShader) delete mBloomExtractShader;
|
||||
if (mBloomCombineShader) delete mBloomCombineShader;
|
||||
if (mBlurShader) delete mBlurShader;
|
||||
|
|
|
@ -20,7 +20,9 @@ class FSamplerManager;
|
|||
class DPSprite;
|
||||
class FGLRenderBuffers;
|
||||
class FLinearDepthShader;
|
||||
class FDepthBlurShader;
|
||||
class FSSAOShader;
|
||||
class FSSAOCombineShader;
|
||||
class FBloomExtractShader;
|
||||
class FBloomCombineShader;
|
||||
class FBlurShader;
|
||||
|
@ -94,6 +96,8 @@ public:
|
|||
FGLRenderBuffers *mBuffers;
|
||||
FLinearDepthShader *mLinearDepthShader;
|
||||
FSSAOShader *mSSAOShader;
|
||||
FDepthBlurShader *mDepthBlurShader;
|
||||
FSSAOCombineShader *mSSAOCombineShader;
|
||||
FBloomExtractShader *mBloomExtractShader;
|
||||
FBloomCombineShader *mBloomCombineShader;
|
||||
FBlurShader *mBlurShader;
|
||||
|
|
|
@ -96,3 +96,35 @@ void FSSAOShader::Bind()
|
|||
}
|
||||
mShader.Bind();
|
||||
}
|
||||
|
||||
void FDepthBlurShader::Bind(bool vertical)
|
||||
{
|
||||
auto &shader = mShader[vertical];
|
||||
if (!shader)
|
||||
{
|
||||
shader.Compile(FShaderProgram::Vertex, "shaders/glsl/screenquad.vp", "", 330);
|
||||
shader.Compile(FShaderProgram::Fragment, "shaders/glsl/depthblur.fp", vertical ? "#define BLUR_VERTICAL\n" : "#define BLUR_HORIZONTAL\n", 330);
|
||||
shader.SetFragDataLocation(0, "FragColor");
|
||||
shader.Link("shaders/glsl/depthblur");
|
||||
shader.SetAttribLocation(0, "PositionInProjection");
|
||||
AODepthTexture[vertical].Init(shader, "AODepthTexture");
|
||||
BlurSharpness[vertical].Init(shader, "BlurSharpness");
|
||||
InvFullResolution[vertical].Init(shader, "InvFullResolution");
|
||||
PowExponent[vertical].Init(shader, "PowExponent");
|
||||
}
|
||||
shader.Bind();
|
||||
}
|
||||
|
||||
void FSSAOCombineShader::Bind()
|
||||
{
|
||||
if (!mShader)
|
||||
{
|
||||
mShader.Compile(FShaderProgram::Vertex, "shaders/glsl/screenquad.vp", "", 330);
|
||||
mShader.Compile(FShaderProgram::Fragment, "shaders/glsl/ssaocombine.fp", "", 330);
|
||||
mShader.SetFragDataLocation(0, "FragColor");
|
||||
mShader.Link("shaders/glsl/ssaocombine");
|
||||
mShader.SetAttribLocation(0, "PositionInProjection");
|
||||
AODepthTexture.Init(mShader, "AODepthTexture");
|
||||
}
|
||||
mShader.Bind();
|
||||
}
|
||||
|
|
|
@ -38,4 +38,29 @@ private:
|
|||
FShaderProgram mShader;
|
||||
};
|
||||
|
||||
class FDepthBlurShader
|
||||
{
|
||||
public:
|
||||
void Bind(bool vertical);
|
||||
|
||||
FBufferedUniformSampler AODepthTexture[2];
|
||||
FBufferedUniform1f BlurSharpness[2];
|
||||
FBufferedUniform2f InvFullResolution[2];
|
||||
FBufferedUniform1f PowExponent[2];
|
||||
|
||||
private:
|
||||
FShaderProgram mShader[2];
|
||||
};
|
||||
|
||||
class FSSAOCombineShader
|
||||
{
|
||||
public:
|
||||
void Bind();
|
||||
|
||||
FBufferedUniformSampler AODepthTexture;
|
||||
|
||||
private:
|
||||
FShaderProgram mShader;
|
||||
};
|
||||
|
||||
#endif
|
81
wadsrc/static/shaders/glsl/depthblur.fp
Normal file
81
wadsrc/static/shaders/glsl/depthblur.fp
Normal file
|
@ -0,0 +1,81 @@
|
|||
|
||||
in vec2 TexCoord;
|
||||
out vec4 FragColor;
|
||||
|
||||
uniform sampler2D AODepthTexture;
|
||||
uniform float BlurSharpness;
|
||||
uniform vec2 InvFullResolution;
|
||||
uniform float PowExponent;
|
||||
|
||||
#define KERNEL_RADIUS 3.0
|
||||
|
||||
struct CenterPixelData
|
||||
{
|
||||
vec2 UV;
|
||||
float Depth;
|
||||
float Sharpness;
|
||||
};
|
||||
|
||||
float CrossBilateralWeight(float r, float sampleDepth, CenterPixelData center)
|
||||
{
|
||||
const float blurSigma = KERNEL_RADIUS * 0.5;
|
||||
const float blurFalloff = 1.0 / (2.0 * blurSigma * blurSigma);
|
||||
|
||||
float deltaZ = (sampleDepth - center.Depth) * center.Sharpness;
|
||||
|
||||
return exp2(-r * r * blurFalloff - deltaZ * deltaZ);
|
||||
}
|
||||
|
||||
void ProcessSample(float ao, float z, float r, CenterPixelData center, inout float totalAO, inout float totalW)
|
||||
{
|
||||
float w = CrossBilateralWeight(r, z, center);
|
||||
totalAO += w * ao;
|
||||
totalW += w;
|
||||
}
|
||||
|
||||
void ProcessRadius(vec2 deltaUV, CenterPixelData center, inout float totalAO, inout float totalW)
|
||||
{
|
||||
for (float r = 1; r <= KERNEL_RADIUS; r += 1.0)
|
||||
{
|
||||
vec2 uv = r * deltaUV + center.UV;
|
||||
vec2 aoZ = texture(AODepthTexture, uv).xy;
|
||||
ProcessSample(aoZ.x, aoZ.y, r, center, totalAO, totalW);
|
||||
}
|
||||
}
|
||||
|
||||
vec2 ComputeBlur(vec2 deltaUV)
|
||||
{
|
||||
vec2 aoZ = texture(AODepthTexture, TexCoord).xy;
|
||||
|
||||
CenterPixelData center;
|
||||
center.UV = TexCoord;
|
||||
center.Depth = aoZ.y;
|
||||
center.Sharpness = BlurSharpness;
|
||||
|
||||
float totalAO = aoZ.x;
|
||||
float totalW = 1.0;
|
||||
|
||||
ProcessRadius(deltaUV, center, totalAO, totalW);
|
||||
ProcessRadius(-deltaUV, center, totalAO, totalW);
|
||||
|
||||
return vec2(totalAO / totalW, aoZ.y);
|
||||
}
|
||||
|
||||
vec2 BlurX()
|
||||
{
|
||||
return ComputeBlur(vec2(InvFullResolution.x, 0.0));
|
||||
}
|
||||
|
||||
float BlurY()
|
||||
{
|
||||
return pow(clamp(ComputeBlur(vec2(0.0, InvFullResolution.y)).x, 0.0, 1.0), PowExponent);
|
||||
}
|
||||
|
||||
void main()
|
||||
{
|
||||
#if defined(BLUR_HORIZONTAL)
|
||||
FragColor = vec4(BlurX(), 0.0, 1.0);
|
||||
#else
|
||||
FragColor = vec4(BlurY(), 0.0, 0.0, 1.0);
|
||||
#endif
|
||||
}
|
|
@ -108,12 +108,5 @@ void main()
|
|||
vec3 viewPosition = FetchViewPos(TexCoord);
|
||||
vec3 viewNormal = ReconstructNormal(viewPosition);
|
||||
float occlusion = ComputeAO(viewPosition, viewNormal) * AOStrength + (1.0 - AOStrength);
|
||||
|
||||
// GZDoom does not use linear buffers at the moment, apply some gamma to get it closer to correct
|
||||
occlusion = occlusion * occlusion;
|
||||
|
||||
//FragColor = vec4(viewPosition.x * 0.001 + 0.5, viewPosition.y * 0.001 + 0.5, viewPosition.z * 0.001, 1.0);
|
||||
//FragColor = vec4(viewNormal.x * 0.5 + 0.5, viewNormal.y * 0.5 + 0.5, viewNormal.z * 0.5 + 0.5, 1.0);
|
||||
//FragColor = vec4(occlusion, viewPosition.z, 0.0, 1.0);
|
||||
FragColor = vec4(occlusion, occlusion, occlusion, 1.0);
|
||||
FragColor = vec4(occlusion, viewPosition.z, 0.0, 1.0);
|
||||
}
|
||||
|
|
11
wadsrc/static/shaders/glsl/ssaocombine.fp
Normal file
11
wadsrc/static/shaders/glsl/ssaocombine.fp
Normal file
|
@ -0,0 +1,11 @@
|
|||
|
||||
in vec2 TexCoord;
|
||||
out vec4 FragColor;
|
||||
|
||||
uniform sampler2D AODepthTexture;
|
||||
|
||||
void main()
|
||||
{
|
||||
float attenutation = texture(AODepthTexture, TexCoord).x;
|
||||
FragColor = vec4(attenutation, attenutation, attenutation, 0.0);
|
||||
}
|
Loading…
Reference in a new issue