mirror of
https://github.com/ZDoom/gzdoom-gles.git
synced 2024-12-01 16:41:22 +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();
|
RenderScreenQuad();
|
||||||
|
|
||||||
// Blur SSAO texture
|
// Blur SSAO texture
|
||||||
mBlurShader->BlurHorizontal(this, blurAmount, blurSampleCount, mBuffers->AmbientTexture1, mBuffers->AmbientFB0, mBuffers->AmbientWidth, mBuffers->AmbientHeight);
|
glBindFramebuffer(GL_FRAMEBUFFER, mBuffers->AmbientFB0);
|
||||||
mBlurShader->BlurVertical(this, blurAmount, blurSampleCount, mBuffers->AmbientTexture0, mBuffers->AmbientFB1, mBuffers->AmbientWidth, mBuffers->AmbientHeight);
|
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:
|
// Add SSAO back to scene texture:
|
||||||
mBuffers->BindCurrentFB();
|
mBuffers->BindCurrentFB();
|
||||||
|
@ -225,8 +239,8 @@ void FGLRenderer::AmbientOccludeScene()
|
||||||
glBindTexture(GL_TEXTURE_2D, mBuffers->AmbientTexture1);
|
glBindTexture(GL_TEXTURE_2D, mBuffers->AmbientTexture1);
|
||||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||||
mBloomCombineShader->Bind();
|
mSSAOCombineShader->Bind();
|
||||||
mBloomCombineShader->BloomTexture.Set(0);
|
mSSAOCombineShader->AODepthTexture.Set(0);
|
||||||
RenderScreenQuad();
|
RenderScreenQuad();
|
||||||
glViewport(mScreenViewport.left, mScreenViewport.top, mScreenViewport.width, mScreenViewport.height);
|
glViewport(mScreenViewport.left, mScreenViewport.top, mScreenViewport.width, mScreenViewport.height);
|
||||||
|
|
||||||
|
|
|
@ -313,8 +313,8 @@ void FGLRenderBuffers::CreateAmbientOcclusion(int width, int height)
|
||||||
|
|
||||||
AmbientWidth = width / 2;
|
AmbientWidth = width / 2;
|
||||||
AmbientHeight = height / 2;
|
AmbientHeight = height / 2;
|
||||||
AmbientTexture0 = Create2DTexture("AmbientTexture0", GL_RGBA32F, AmbientWidth, AmbientHeight);
|
AmbientTexture0 = Create2DTexture("AmbientTexture0", GL_RG32F, AmbientWidth, AmbientHeight);
|
||||||
AmbientTexture1 = Create2DTexture("AmbientTexture1", GL_RGBA32F, AmbientWidth, AmbientHeight);
|
AmbientTexture1 = Create2DTexture("AmbientTexture1", GL_RG32F, AmbientWidth, AmbientHeight);
|
||||||
AmbientFB0 = CreateFrameBuffer("AmbientFB0", AmbientTexture0);
|
AmbientFB0 = CreateFrameBuffer("AmbientFB0", AmbientTexture0);
|
||||||
AmbientFB1 = CreateFrameBuffer("AmbientFB1", AmbientTexture1);
|
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_RGBA16: dataformat = GL_RGBA; datatype = GL_UNSIGNED_SHORT; break;
|
||||||
case GL_RGBA16F: dataformat = GL_RGBA; datatype = GL_FLOAT; break;
|
case GL_RGBA16F: dataformat = GL_RGBA; datatype = GL_FLOAT; break;
|
||||||
case GL_RGBA32F: 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_DEPTH_COMPONENT24: dataformat = GL_DEPTH_COMPONENT; datatype = GL_FLOAT; break;
|
||||||
case GL_STENCIL_INDEX8: dataformat = GL_STENCIL_INDEX; datatype = GL_INT; 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;
|
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;
|
mTonemapPalette = nullptr;
|
||||||
mColormapShader = nullptr;
|
mColormapShader = nullptr;
|
||||||
mLensShader = nullptr;
|
mLensShader = nullptr;
|
||||||
|
mLinearDepthShader = nullptr;
|
||||||
|
mDepthBlurShader = nullptr;
|
||||||
|
mSSAOShader = nullptr;
|
||||||
|
mSSAOCombineShader = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
void gl_LoadModels();
|
void gl_LoadModels();
|
||||||
|
@ -132,7 +136,9 @@ void FGLRenderer::Initialize(int width, int height)
|
||||||
{
|
{
|
||||||
mBuffers = new FGLRenderBuffers();
|
mBuffers = new FGLRenderBuffers();
|
||||||
mLinearDepthShader = new FLinearDepthShader();
|
mLinearDepthShader = new FLinearDepthShader();
|
||||||
|
mDepthBlurShader = new FDepthBlurShader();
|
||||||
mSSAOShader = new FSSAOShader();
|
mSSAOShader = new FSSAOShader();
|
||||||
|
mSSAOCombineShader = new FSSAOCombineShader();
|
||||||
mBloomExtractShader = new FBloomExtractShader();
|
mBloomExtractShader = new FBloomExtractShader();
|
||||||
mBloomCombineShader = new FBloomCombineShader();
|
mBloomCombineShader = new FBloomCombineShader();
|
||||||
mBlurShader = new FBlurShader();
|
mBlurShader = new FBlurShader();
|
||||||
|
@ -194,7 +200,9 @@ FGLRenderer::~FGLRenderer()
|
||||||
if (mBuffers) delete mBuffers;
|
if (mBuffers) delete mBuffers;
|
||||||
if (mPresentShader) delete mPresentShader;
|
if (mPresentShader) delete mPresentShader;
|
||||||
if (mLinearDepthShader) delete mLinearDepthShader;
|
if (mLinearDepthShader) delete mLinearDepthShader;
|
||||||
|
if (mDepthBlurShader) delete mDepthBlurShader;
|
||||||
if (mSSAOShader) delete mSSAOShader;
|
if (mSSAOShader) delete mSSAOShader;
|
||||||
|
if (mSSAOCombineShader) delete mSSAOCombineShader;
|
||||||
if (mBloomExtractShader) delete mBloomExtractShader;
|
if (mBloomExtractShader) delete mBloomExtractShader;
|
||||||
if (mBloomCombineShader) delete mBloomCombineShader;
|
if (mBloomCombineShader) delete mBloomCombineShader;
|
||||||
if (mBlurShader) delete mBlurShader;
|
if (mBlurShader) delete mBlurShader;
|
||||||
|
|
|
@ -20,7 +20,9 @@ class FSamplerManager;
|
||||||
class DPSprite;
|
class DPSprite;
|
||||||
class FGLRenderBuffers;
|
class FGLRenderBuffers;
|
||||||
class FLinearDepthShader;
|
class FLinearDepthShader;
|
||||||
|
class FDepthBlurShader;
|
||||||
class FSSAOShader;
|
class FSSAOShader;
|
||||||
|
class FSSAOCombineShader;
|
||||||
class FBloomExtractShader;
|
class FBloomExtractShader;
|
||||||
class FBloomCombineShader;
|
class FBloomCombineShader;
|
||||||
class FBlurShader;
|
class FBlurShader;
|
||||||
|
@ -94,6 +96,8 @@ public:
|
||||||
FGLRenderBuffers *mBuffers;
|
FGLRenderBuffers *mBuffers;
|
||||||
FLinearDepthShader *mLinearDepthShader;
|
FLinearDepthShader *mLinearDepthShader;
|
||||||
FSSAOShader *mSSAOShader;
|
FSSAOShader *mSSAOShader;
|
||||||
|
FDepthBlurShader *mDepthBlurShader;
|
||||||
|
FSSAOCombineShader *mSSAOCombineShader;
|
||||||
FBloomExtractShader *mBloomExtractShader;
|
FBloomExtractShader *mBloomExtractShader;
|
||||||
FBloomCombineShader *mBloomCombineShader;
|
FBloomCombineShader *mBloomCombineShader;
|
||||||
FBlurShader *mBlurShader;
|
FBlurShader *mBlurShader;
|
||||||
|
|
|
@ -96,3 +96,35 @@ void FSSAOShader::Bind()
|
||||||
}
|
}
|
||||||
mShader.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;
|
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
|
#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 viewPosition = FetchViewPos(TexCoord);
|
||||||
vec3 viewNormal = ReconstructNormal(viewPosition);
|
vec3 viewNormal = ReconstructNormal(viewPosition);
|
||||||
float occlusion = ComputeAO(viewPosition, viewNormal) * AOStrength + (1.0 - AOStrength);
|
float occlusion = ComputeAO(viewPosition, viewNormal) * AOStrength + (1.0 - AOStrength);
|
||||||
|
FragColor = vec4(occlusion, viewPosition.z, 0.0, 1.0);
|
||||||
// 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);
|
|
||||||
}
|
}
|
||||||
|
|
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