Added SceneData texture as the second colorbuffer when rendering a scene and placed fog data into it

This commit is contained in:
Magnus Norddahl 2016-09-21 02:04:56 +02:00
parent 9af34bac69
commit d774136282
8 changed files with 115 additions and 24 deletions

View file

@ -137,9 +137,6 @@ void FGLRenderer::PostProcessScene()
void FGLRenderer::AmbientOccludeScene() void FGLRenderer::AmbientOccludeScene()
{ {
if (!gl_ssao || !FGLRenderBuffers::IsEnabled())
return;
FGLDebug::PushGroup("AmbientOccludeScene"); FGLDebug::PushGroup("AmbientOccludeScene");
FGLPostProcessState savedState; FGLPostProcessState savedState;
@ -226,20 +223,27 @@ void FGLRenderer::AmbientOccludeScene()
RenderScreenQuad(); RenderScreenQuad();
// Add SSAO back to scene texture: // 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); glViewport(mSceneViewport.left, mSceneViewport.top, mSceneViewport.width, mSceneViewport.height);
glEnable(GL_BLEND); glEnable(GL_BLEND);
glBlendEquation(GL_FUNC_ADD); glBlendEquation(GL_FUNC_ADD);
if (gl_ssao_debug) if (gl_ssao_debug)
glBlendFunc(GL_ONE, GL_ZERO); glBlendFunc(GL_ONE, GL_ZERO);
else else
glBlendFunc(GL_ZERO, GL_SRC_COLOR); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glActiveTexture(GL_TEXTURE0); glActiveTexture(GL_TEXTURE0);
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);
mSSAOCombineShader->Bind(); mBuffers->BindSceneDataTexture(1);
mSSAOCombineShader->AODepthTexture.Set(0); 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(); RenderScreenQuad();
FGLDebug::PopGroup(); FGLDebug::PopGroup();

View file

@ -323,7 +323,7 @@ void FGLRenderer::Begin2D()
if (mBuffers->Setup(mScreenViewport.width, mScreenViewport.height, mSceneViewport.width, mSceneViewport.height)) if (mBuffers->Setup(mScreenViewport.width, mScreenViewport.height, mSceneViewport.width, mSceneViewport.height))
{ {
if (mDrawingScene2D) if (mDrawingScene2D)
mBuffers->BindSceneFB(); mBuffers->BindSceneFB(false);
else else
mBuffers->BindCurrentFB(); mBuffers->BindCurrentFB();
} }

View file

@ -158,7 +158,11 @@ void FGLRenderer::Set3DViewport(bool mainview)
{ {
if (mainview && mBuffers->Setup(mScreenViewport.width, mScreenViewport.height, mSceneViewport.width, mSceneViewport.height)) 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. // Always clear all buffers with scissor test disabled.
@ -491,7 +495,13 @@ void FGLRenderer::DrawScene(int drawmode)
RenderScene(recursion); RenderScene(recursion);
bool applySSAO = gl_ssao && FGLRenderBuffers::IsEnabled() && drawmode != DM_PORTAL;
if (applySSAO)
{
AmbientOccludeScene(); AmbientOccludeScene();
gl_RenderState.SetPassType(GBUFFER_PASS);
gl_RenderState.Apply();
}
// Handle all portals after rendering the opaque objects but before // Handle all portals after rendering the opaque objects but before
// doing all translucent stuff // doing all translucent stuff
@ -499,6 +509,15 @@ void FGLRenderer::DrawScene(int drawmode)
GLPortal::EndFrame(); GLPortal::EndFrame();
recursion--; recursion--;
RenderTranslucent(); 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();
}
} }

View file

@ -120,16 +120,21 @@ void FDepthBlurShader::Bind(bool vertical)
shader.Bind(); 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); shader.Compile(FShaderProgram::Vertex, "shaders/glsl/screenquad.vp", "", 330);
mShader.Compile(FShaderProgram::Fragment, "shaders/glsl/ssaocombine.fp", "", 330); shader.Compile(FShaderProgram::Fragment, "shaders/glsl/ssaocombine.fp", multisample ? "#define MULTISAMPLE\n" : "", 330);
mShader.SetFragDataLocation(0, "FragColor"); shader.SetFragDataLocation(0, "FragColor");
mShader.Link("shaders/glsl/ssaocombine"); shader.Link("shaders/glsl/ssaocombine");
mShader.SetAttribLocation(0, "PositionInProjection"); shader.SetAttribLocation(0, "PositionInProjection");
AODepthTexture.Init(mShader, "AODepthTexture"); 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();
} }

View file

@ -59,12 +59,16 @@ private:
class FSSAOCombineShader class FSSAOCombineShader
{ {
public: 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: private:
FShaderProgram mShader; FShaderProgram mShader[2];
}; };
#endif #endif

View file

@ -50,6 +50,12 @@ EXTERN_CVAR(Bool, gl_lens)
EXTERN_CVAR(Float, gl_lens_k) EXTERN_CVAR(Float, gl_lens_k)
EXTERN_CVAR(Float, gl_lens_kcube) EXTERN_CVAR(Float, gl_lens_kcube)
EXTERN_CVAR(Float, gl_lens_chromatic) 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(Int, gl_debug_level)
EXTERN_CVAR(Bool, gl_debug_breakpoint) EXTERN_CVAR(Bool, gl_debug_breakpoint)

View file

@ -233,6 +233,32 @@ vec4 applyFog(vec4 frag, float fogfactor)
return vec4(mix(uFogColor.rgb, frag.rgb, fogfactor), frag.a); 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);
}
//=========================================================================== //===========================================================================
// //
@ -349,7 +375,7 @@ void main()
} }
FragColor = frag; FragColor = frag;
#ifdef GBUFFER_PASS #ifdef GBUFFER_PASS
FragData = vec4(uFogColor.rgb, 1.0); FragData = vec4(AmbientOcclusionColor(), 1.0);
#endif #endif
} }

View file

@ -4,8 +4,35 @@ out vec4 FragColor;
uniform sampler2D AODepthTexture; 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() 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; float attenutation = texture(AODepthTexture, TexCoord).x;
FragColor = vec4(attenutation, attenutation, attenutation, 0.0); FragColor = vec4(fogColor, 1.0 - attenutation);
} }