mirror of
https://github.com/ZDoom/qzdoom.git
synced 2024-11-29 07:22:05 +00:00
Added SceneData texture as the second colorbuffer when rendering a scene and placed fog data into it
This commit is contained in:
parent
24f748da03
commit
b6c64416be
10 changed files with 150 additions and 32 deletions
|
@ -138,9 +138,6 @@ void FGLRenderer::PostProcessScene()
|
|||
|
||||
void FGLRenderer::AmbientOccludeScene()
|
||||
{
|
||||
if (!gl_ssao || !FGLRenderBuffers::IsEnabled())
|
||||
return;
|
||||
|
||||
FGLDebug::PushGroup("AmbientOccludeScene");
|
||||
|
||||
FGLPostProcessState savedState;
|
||||
|
@ -227,20 +224,27 @@ void FGLRenderer::AmbientOccludeScene()
|
|||
RenderScreenQuad();
|
||||
|
||||
// Add SSAO back to scene texture:
|
||||
mBuffers->BindSceneFB();
|
||||
mBuffers->BindSceneFB(false);
|
||||
GLenum buffers[] = { GL_COLOR_ATTACHMENT0 };
|
||||
glDrawBuffers(1, buffers);
|
||||
glViewport(mSceneViewport.left, mSceneViewport.top, mSceneViewport.width, mSceneViewport.height);
|
||||
glEnable(GL_BLEND);
|
||||
glBlendEquation(GL_FUNC_ADD);
|
||||
if (gl_ssao_debug)
|
||||
glBlendFunc(GL_ONE, GL_ZERO);
|
||||
else
|
||||
glBlendFunc(GL_ZERO, GL_SRC_COLOR);
|
||||
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
||||
glActiveTexture(GL_TEXTURE0);
|
||||
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);
|
||||
mSSAOCombineShader->Bind();
|
||||
mSSAOCombineShader->AODepthTexture.Set(0);
|
||||
mBuffers->BindSceneDataTexture(1);
|
||||
mSSAOCombineShader->Bind(multisample);
|
||||
mSSAOCombineShader->AODepthTexture[multisample].Set(0);
|
||||
mSSAOCombineShader->SceneDataTexture[multisample].Set(1);
|
||||
if (multisample) mSSAOCombineShader->SampleCount[multisample].Set(gl_multisample);
|
||||
mSSAOCombineShader->Scale[multisample].Set(mBuffers->AmbientWidth * 2.0f / (float)mScreenViewport.width, mBuffers->AmbientHeight * 2.0f / (float)mScreenViewport.height);
|
||||
mSSAOCombineShader->Offset[multisample].Set(mSceneViewport.left / (float)mScreenViewport.width, mSceneViewport.top / (float)mScreenViewport.height);
|
||||
RenderScreenQuad();
|
||||
|
||||
FGLDebug::PopGroup();
|
||||
|
|
|
@ -82,7 +82,9 @@ FGLRenderBuffers::~FGLRenderBuffers()
|
|||
void FGLRenderBuffers::ClearScene()
|
||||
{
|
||||
DeleteFrameBuffer(mSceneFB);
|
||||
DeleteFrameBuffer(mSceneDataFB);
|
||||
DeleteTexture(mSceneMultisample);
|
||||
DeleteTexture(mSceneData);
|
||||
DeleteTexture(mSceneDepthStencil);
|
||||
}
|
||||
|
||||
|
@ -253,13 +255,16 @@ void FGLRenderBuffers::CreateScene(int width, int height, int samples)
|
|||
{
|
||||
mSceneMultisample = Create2DMultisampleTexture("SceneMultisample", GL_RGBA16F, width, height, samples, false);
|
||||
mSceneDepthStencil = Create2DMultisampleTexture("SceneDepthStencil", GL_DEPTH24_STENCIL8, width, height, samples, false);
|
||||
mSceneData = Create2DMultisampleTexture("SceneSSAOData", GL_RGBA8, width, height, samples, false);
|
||||
}
|
||||
else
|
||||
{
|
||||
mSceneDepthStencil = Create2DTexture("SceneDepthStencil", GL_DEPTH24_STENCIL8, width, height);
|
||||
mSceneData = Create2DTexture("SceneSSAOData", GL_RGBA8, width, height);
|
||||
}
|
||||
|
||||
mSceneFB = CreateFrameBuffer("SceneFB", samples > 1 ? mSceneMultisample : mPipelineTexture[0], mSceneDepthStencil, samples > 1);
|
||||
mSceneFB = CreateFrameBuffer("SceneFB", samples > 1 ? mSceneMultisample : mPipelineTexture[0], 0, mSceneDepthStencil, samples > 1);
|
||||
mSceneDataFB = CreateFrameBuffer("SSAOSceneFB", samples > 1 ? mSceneMultisample : mPipelineTexture[0], mSceneData, mSceneDepthStencil, samples > 1);
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
|
@ -512,7 +517,7 @@ GLuint FGLRenderBuffers::CreateFrameBuffer(const FString &name, GLuint colorbuff
|
|||
return handle;
|
||||
}
|
||||
|
||||
GLuint FGLRenderBuffers::CreateFrameBuffer(const FString &name, GLuint colorbuffer, GLuint depthstencil, bool multisample)
|
||||
GLuint FGLRenderBuffers::CreateFrameBuffer(const FString &name, GLuint colorbuffer0, GLuint colorbuffer1, GLuint depthstencil, bool multisample)
|
||||
{
|
||||
GLuint handle = 0;
|
||||
glGenFramebuffers(1, &handle);
|
||||
|
@ -520,12 +525,16 @@ GLuint FGLRenderBuffers::CreateFrameBuffer(const FString &name, GLuint colorbuff
|
|||
FGLDebug::LabelObject(GL_FRAMEBUFFER, handle, name);
|
||||
if (multisample)
|
||||
{
|
||||
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D_MULTISAMPLE, colorbuffer, 0);
|
||||
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D_MULTISAMPLE, colorbuffer0, 0);
|
||||
if (colorbuffer1 != 0)
|
||||
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT1, GL_TEXTURE_2D_MULTISAMPLE, colorbuffer1, 0);
|
||||
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_TEXTURE_2D_MULTISAMPLE, depthstencil, 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, colorbuffer, 0);
|
||||
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, colorbuffer0, 0);
|
||||
if (colorbuffer1 != 0)
|
||||
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT1, GL_TEXTURE_2D, colorbuffer1, 0);
|
||||
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_TEXTURE_2D, depthstencil, 0);
|
||||
}
|
||||
if (CheckFrameBufferCompleteness())
|
||||
|
@ -668,9 +677,9 @@ void FGLRenderBuffers::BindEyeFB(int eye, bool readBuffer)
|
|||
//
|
||||
//==========================================================================
|
||||
|
||||
void FGLRenderBuffers::BindSceneFB()
|
||||
void FGLRenderBuffers::BindSceneFB(bool sceneData)
|
||||
{
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, mSceneFB);
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, sceneData ? mSceneDataFB : mSceneFB);
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
|
@ -688,6 +697,21 @@ void FGLRenderBuffers::BindSceneColorTexture(int index)
|
|||
glBindTexture(GL_TEXTURE_2D, mPipelineTexture[0]);
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// Binds the scene data texture to the specified texture unit
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
void FGLRenderBuffers::BindSceneDataTexture(int index)
|
||||
{
|
||||
glActiveTexture(GL_TEXTURE0 + index);
|
||||
if (mSamples > 1)
|
||||
glBindTexture(GL_TEXTURE_2D_MULTISAMPLE, mSceneData);
|
||||
else
|
||||
glBindTexture(GL_TEXTURE_2D, mSceneData);
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// Binds the depth texture to the specified texture unit
|
||||
|
|
|
@ -31,8 +31,9 @@ public:
|
|||
|
||||
bool Setup(int width, int height, int sceneWidth, int sceneHeight);
|
||||
|
||||
void BindSceneFB();
|
||||
void BindSceneFB(bool sceneData);
|
||||
void BindSceneColorTexture(int index);
|
||||
void BindSceneDataTexture(int index);
|
||||
void BindSceneDepthTexture(int index);
|
||||
void BlitSceneToTexture();
|
||||
|
||||
|
@ -90,7 +91,7 @@ private:
|
|||
GLuint CreateRenderBuffer(const FString &name, GLuint format, int width, int height);
|
||||
GLuint CreateRenderBuffer(const FString &name, GLuint format, int samples, int width, int height);
|
||||
GLuint CreateFrameBuffer(const FString &name, GLuint colorbuffer);
|
||||
GLuint CreateFrameBuffer(const FString &name, GLuint colorbuffer, GLuint depthstencil, bool multisample);
|
||||
GLuint CreateFrameBuffer(const FString &name, GLuint colorbuffer0, GLuint colorbuffer1, GLuint depthstencil, bool multisample);
|
||||
bool CheckFrameBufferCompleteness();
|
||||
void ClearFrameBuffer(bool stencil, bool depth);
|
||||
void DeleteTexture(GLuint &handle);
|
||||
|
@ -110,7 +111,9 @@ private:
|
|||
// Buffers for the scene
|
||||
GLuint mSceneMultisample = 0;
|
||||
GLuint mSceneDepthStencil = 0;
|
||||
GLuint mSceneData = 0;
|
||||
GLuint mSceneFB = 0;
|
||||
GLuint mSceneDataFB = 0;
|
||||
|
||||
// Effect/HUD buffers
|
||||
GLuint mPipelineTexture[NumPipelineTextures];
|
||||
|
|
|
@ -320,7 +320,7 @@ void FGLRenderer::Begin2D()
|
|||
if (mBuffers->Setup(mScreenViewport.width, mScreenViewport.height, mSceneViewport.width, mSceneViewport.height))
|
||||
{
|
||||
if (mDrawingScene2D)
|
||||
mBuffers->BindSceneFB();
|
||||
mBuffers->BindSceneFB(false);
|
||||
else
|
||||
mBuffers->BindCurrentFB();
|
||||
}
|
||||
|
|
|
@ -157,7 +157,11 @@ void FGLRenderer::Set3DViewport(bool mainview)
|
|||
{
|
||||
if (mainview && mBuffers->Setup(mScreenViewport.width, mScreenViewport.height, mSceneViewport.width, mSceneViewport.height))
|
||||
{
|
||||
mBuffers->BindSceneFB();
|
||||
mBuffers->BindSceneFB(gl_ssao);
|
||||
GLenum buffers[] = { GL_COLOR_ATTACHMENT0, GL_COLOR_ATTACHMENT1 };
|
||||
glDrawBuffers(gl_ssao ? 2 : 1, buffers);
|
||||
gl_RenderState.SetPassType(gl_ssao ? GBUFFER_PASS : NORMAL_PASS);
|
||||
gl_RenderState.Apply();
|
||||
}
|
||||
|
||||
// Always clear all buffers with scissor test disabled.
|
||||
|
@ -490,7 +494,13 @@ void FGLRenderer::DrawScene(int drawmode)
|
|||
|
||||
RenderScene(recursion);
|
||||
|
||||
bool applySSAO = gl_ssao && FGLRenderBuffers::IsEnabled() && drawmode != DM_PORTAL;
|
||||
if (applySSAO)
|
||||
{
|
||||
AmbientOccludeScene();
|
||||
gl_RenderState.SetPassType(GBUFFER_PASS);
|
||||
gl_RenderState.Apply();
|
||||
}
|
||||
|
||||
// Handle all portals after rendering the opaque objects but before
|
||||
// doing all translucent stuff
|
||||
|
@ -498,6 +508,15 @@ void FGLRenderer::DrawScene(int drawmode)
|
|||
GLPortal::EndFrame();
|
||||
recursion--;
|
||||
RenderTranslucent();
|
||||
|
||||
if (applySSAO)
|
||||
{
|
||||
mBuffers->BindSceneFB(true);
|
||||
GLenum buffers[] = { GL_COLOR_ATTACHMENT0, GL_COLOR_ATTACHMENT1 };
|
||||
glDrawBuffers(2, buffers);
|
||||
gl_RenderState.SetPassType(NORMAL_PASS);
|
||||
gl_RenderState.Apply();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -120,16 +120,21 @@ void FDepthBlurShader::Bind(bool vertical)
|
|||
shader.Bind();
|
||||
}
|
||||
|
||||
void FSSAOCombineShader::Bind()
|
||||
void FSSAOCombineShader::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/ssaocombine.fp", "", 330);
|
||||
mShader.SetFragDataLocation(0, "FragColor");
|
||||
mShader.Link("shaders/glsl/ssaocombine");
|
||||
mShader.SetAttribLocation(0, "PositionInProjection");
|
||||
AODepthTexture.Init(mShader, "AODepthTexture");
|
||||
shader.Compile(FShaderProgram::Vertex, "shaders/glsl/screenquad.vp", "", 330);
|
||||
shader.Compile(FShaderProgram::Fragment, "shaders/glsl/ssaocombine.fp", multisample ? "#define MULTISAMPLE\n" : "", 330);
|
||||
shader.SetFragDataLocation(0, "FragColor");
|
||||
shader.Link("shaders/glsl/ssaocombine");
|
||||
shader.SetAttribLocation(0, "PositionInProjection");
|
||||
AODepthTexture[multisample].Init(shader, "AODepthTexture");
|
||||
SceneDataTexture[multisample].Init(shader, "SceneDataTexture");
|
||||
SampleCount[multisample].Init(shader, "SampleCount");
|
||||
Scale[multisample].Init(shader, "Scale");
|
||||
Offset[multisample].Init(shader, "Offset");
|
||||
}
|
||||
mShader.Bind();
|
||||
shader.Bind();
|
||||
}
|
||||
|
|
|
@ -59,12 +59,16 @@ private:
|
|||
class FSSAOCombineShader
|
||||
{
|
||||
public:
|
||||
void Bind();
|
||||
void Bind(bool multisample);
|
||||
|
||||
FBufferedUniformSampler AODepthTexture;
|
||||
FBufferedUniformSampler AODepthTexture[2];
|
||||
FBufferedUniformSampler SceneDataTexture[2];
|
||||
FBufferedUniform1i SampleCount[2];
|
||||
FBufferedUniform2f Scale[2];
|
||||
FBufferedUniform2f Offset[2];
|
||||
|
||||
private:
|
||||
FShaderProgram mShader;
|
||||
FShaderProgram mShader[2];
|
||||
};
|
||||
|
||||
#endif
|
|
@ -51,6 +51,12 @@ EXTERN_CVAR(Bool, gl_lens)
|
|||
EXTERN_CVAR(Float, gl_lens_k)
|
||||
EXTERN_CVAR(Float, gl_lens_kcube)
|
||||
EXTERN_CVAR(Float, gl_lens_chromatic)
|
||||
EXTERN_CVAR(Bool, gl_ssao)
|
||||
EXTERN_CVAR(Float, gl_ssao_strength)
|
||||
EXTERN_CVAR(Bool, gl_ssao_debug)
|
||||
EXTERN_CVAR(Float, gl_ssao_bias)
|
||||
EXTERN_CVAR(Float, gl_ssao_radius)
|
||||
EXTERN_CVAR(Float, gl_ssao_blur_amount)
|
||||
|
||||
EXTERN_CVAR(Int, gl_debug_level)
|
||||
EXTERN_CVAR(Bool, gl_debug_breakpoint)
|
||||
|
|
|
@ -315,6 +315,32 @@ vec4 applyFog(vec4 frag, float fogfactor)
|
|||
return vec4(mix(uFogColor.rgb, frag.rgb, fogfactor), frag.a);
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
//
|
||||
// The color of the fragment if it is fully occluded by ambient lighting
|
||||
//
|
||||
//===========================================================================
|
||||
|
||||
vec3 AmbientOcclusionColor()
|
||||
{
|
||||
float fogdist;
|
||||
float fogfactor;
|
||||
|
||||
//
|
||||
// calculate fog factor
|
||||
//
|
||||
if (uFogEnabled == -1)
|
||||
{
|
||||
fogdist = pixelpos.w;
|
||||
}
|
||||
else
|
||||
{
|
||||
fogdist = max(16.0, length(pixelpos.xyz));
|
||||
}
|
||||
fogfactor = exp2 (uFogDensity * fogdist);
|
||||
|
||||
return mix(uFogColor.rgb, vec3(0.0), fogfactor);
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
//
|
||||
|
@ -437,7 +463,7 @@ void main()
|
|||
}
|
||||
FragColor = frag;
|
||||
#ifdef GBUFFER_PASS
|
||||
FragData = vec4(uFogColor.rgb, 1.0);
|
||||
FragData = vec4(AmbientOcclusionColor(), 1.0);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
|
|
@ -4,8 +4,35 @@ out vec4 FragColor;
|
|||
|
||||
uniform sampler2D AODepthTexture;
|
||||
|
||||
#if defined(MULTISAMPLE)
|
||||
uniform sampler2DMS SceneDataTexture;
|
||||
uniform int SampleCount;
|
||||
#else
|
||||
uniform sampler2D SceneDataTexture;
|
||||
#endif
|
||||
|
||||
uniform vec2 Scale;
|
||||
uniform vec2 Offset;
|
||||
|
||||
void main()
|
||||
{
|
||||
vec2 uv = Offset + TexCoord * Scale;
|
||||
#if defined(MULTISAMPLE)
|
||||
ivec2 texSize = textureSize(SceneDataTexture);
|
||||
#else
|
||||
ivec2 texSize = textureSize(SceneDataTexture, 0);
|
||||
#endif
|
||||
ivec2 ipos = ivec2(max(floor(uv * vec2(texSize) - 0.75), vec2(0.0)));
|
||||
|
||||
#if defined(MULTISAMPLE)
|
||||
vec3 fogColor = vec3(0.0);
|
||||
for (int i = 0; i < SampleCount; i++)
|
||||
fogColor += texelFetch(SceneDataTexture, ipos, i).rgb;
|
||||
fogColor /= float(SampleCount);
|
||||
#else
|
||||
vec3 fogColor = texelFetch(SceneDataTexture, ipos, 0).rgb;
|
||||
#endif
|
||||
|
||||
float attenutation = texture(AODepthTexture, TexCoord).x;
|
||||
FragColor = vec4(attenutation, attenutation, attenutation, 0.0);
|
||||
FragColor = vec4(fogColor, 1.0 - attenutation);
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue