From 796886b717f3d2292b6c3e6756b07b6074729ad8 Mon Sep 17 00:00:00 2001 From: Martin Felis Date: Tue, 10 Apr 2018 14:08:28 +0200 Subject: [PATCH] And after a great deal of slow debugging we have deferred blinn-phong. Yayso --- data/shaders/fs_blur_ssao.glsl | 38 ++++ data/shaders/fs_default.glsl | 12 +- data/shaders/fs_deferred_geometry.glsl | 19 ++ data/shaders/fs_deferred_lighting.glsl | 50 +++++ data/shaders/vs_deferred_geometry.glsl | 26 +++ src/modules/RenderModule.cc | 242 +++++++++++++++++++------ src/modules/RenderModule.h | 8 + src/modules/RenderUtils.cc | 34 ++-- src/modules/RenderUtils.h | 4 +- 9 files changed, 356 insertions(+), 77 deletions(-) create mode 100644 data/shaders/fs_blur_ssao.glsl create mode 100644 data/shaders/fs_deferred_geometry.glsl create mode 100644 data/shaders/fs_deferred_lighting.glsl create mode 100644 data/shaders/vs_deferred_geometry.glsl diff --git a/data/shaders/fs_blur_ssao.glsl b/data/shaders/fs_blur_ssao.glsl new file mode 100644 index 0000000..9641000 --- /dev/null +++ b/data/shaders/fs_blur_ssao.glsl @@ -0,0 +1,38 @@ +#version 150 core + +in vec2 ioFragTexCoords; + +out vec3 outColor; + +uniform sampler2D uColor; +uniform sampler2D uAmbientOcclusion; +uniform int uBlurSize; +uniform int uDisableColor; + +float box_blur_occlusion (sampler2D ambient_occlusion, vec2 tex_coord, int size) { + vec2 texel_size = 1.0 / vec2(textureSize(uAmbientOcclusion, 0)); + + float value = 0.; + int count = 0; + for (int i = -size; i < size; i++) { + for (int j = -size; j < size; j++) { + value += texture(ambient_occlusion, tex_coord + vec2(i,j) * texel_size).x; + count++; + } + } + + return value / (4 * size * size); +} + +void main() { + float occlusion; + if (uBlurSize > 0) { + occlusion = box_blur_occlusion(uAmbientOcclusion, ioFragTexCoords, uBlurSize); + } else { + occlusion = texture(uAmbientOcclusion, ioFragTexCoords).x; + } + + vec4 color = texture(uColor, ioFragTexCoords); + + outColor = color.xyz * (1.0 - uDisableColor) * occlusion + uDisableColor * vec3(occlusion); +} diff --git a/data/shaders/fs_default.glsl b/data/shaders/fs_default.glsl index 6603400..01fd5a5 100644 --- a/data/shaders/fs_default.glsl +++ b/data/shaders/fs_default.glsl @@ -13,6 +13,9 @@ uniform sampler2DShadow uShadowMap; uniform sampler2D uShadowMap; #endif +uniform mat4 uModelMatrix; +uniform mat4 uViewMatrix; + in vec3 ioFragPosition; in vec3 ioFragNormal; in vec2 ioFragTexCoords; @@ -78,15 +81,16 @@ void main() { // diffuse lighting vec3 normal_dir = normalize(ioFragNormal); - vec3 light_dir = normalize(uLightDirection); +// vec3 light_dir = normalize(uLightDirection); + vec3 light_dir = transpose(inverse(mat3(uViewMatrix * uModelMatrix))) * uLightDirection; float diff = max(dot(normal_dir, light_dir), 0.0); vec4 diffuse = diff * albedo_color; // specular lighting - vec3 view_dir = normalize(uViewPosition - ioFragPosition); + vec3 view_dir = normalize(-ioFragPosition); vec3 halfway_dir = normalize(light_dir + view_dir); - float spec = pow(max(dot(normal_dir, halfway_dir), 0.0), 32); + float spec = pow(max(dot(normal_dir, halfway_dir), 0.0), 64); vec4 specular = spec * vec4(0.5); // shadow @@ -94,5 +98,5 @@ void main() { outColor = ambient + (1.0 - shadow) * (diffuse + specular); outPosition = ioFragPosition.xyz; - outNormal = ioFragNormal; + outNormal = normalize(ioFragNormal); } diff --git a/data/shaders/fs_deferred_geometry.glsl b/data/shaders/fs_deferred_geometry.glsl new file mode 100644 index 0000000..32a78be --- /dev/null +++ b/data/shaders/fs_deferred_geometry.glsl @@ -0,0 +1,19 @@ +#version 150 core + +uniform vec4 uColor; +uniform sampler2D uAlbedoTexture; + +in vec3 ioFragPosition; +in vec3 ioFragNormal; +in vec2 ioFragTexCoords; +in vec4 ioFragColor; + +out vec4 outColor; +out vec3 outNormal; +out vec3 outPosition; + +void main() { + outColor = texture(uAlbedoTexture, ioFragTexCoords) * ioFragColor * uColor; + outNormal = normalize(ioFragNormal); + outPosition = ioFragPosition.xyz; +} diff --git a/data/shaders/fs_deferred_lighting.glsl b/data/shaders/fs_deferred_lighting.glsl new file mode 100644 index 0000000..9b9a11e --- /dev/null +++ b/data/shaders/fs_deferred_lighting.glsl @@ -0,0 +1,50 @@ +#version 150 core + +uniform sampler2D uColor; +uniform sampler2D uNormal; +uniform sampler2D uDepth; + +#define USE_SAMPLER2D_SHADOW 1 + +#ifdef USE_SAMPLER2D_SHADOW +uniform sampler2DShadow uShadowMap; +#else +uniform sampler2D uShadowMap; +#endif + +uniform sampler2D uPosition; +uniform vec3 uViewPosition; + +uniform vec3 uLightDirection; +uniform mat4 uLightSpaceMatrix; + +in vec2 ioFragTexCoords; + +out vec3 outColor; + +void main() { + vec3 color = texture(uColor, ioFragTexCoords).rgb; + vec3 normal = texture (uNormal, ioFragTexCoords).xyz; + float depth = texture (uDepth, ioFragTexCoords).r; + vec3 position = texture (uPosition, ioFragTexCoords).xyz; + + // ambient lighting + float ambient_strength = 0.2; + vec3 ambient = ambient_strength * color; + + vec3 light_dir = normalize(uLightDirection); + + // diffuse lighting + float diff = max(dot(normal, light_dir), 0.0); + vec3 diffuse = diff * color; + + // specular lighting + vec3 view_dir = normalize(-position); + vec3 halfway_dir = normalize(light_dir + view_dir); + + float spec = pow(max(dot(normal, halfway_dir), 0.0), 32); + vec3 specular = spec * vec3(0.5); + + // shadow + outColor = ambient + (diffuse + specular); +} diff --git a/data/shaders/vs_deferred_geometry.glsl b/data/shaders/vs_deferred_geometry.glsl new file mode 100644 index 0000000..60c8b83 --- /dev/null +++ b/data/shaders/vs_deferred_geometry.glsl @@ -0,0 +1,26 @@ +#version 150 core + +in vec4 inCoord; +in vec3 inNormal; +in vec2 inUV; +in vec4 inColor; + +uniform mat4 uModelMatrix; +uniform mat4 uViewMatrix; +uniform mat4 uProjectionMatrix; + +out vec3 ioFragPosition; +out vec3 ioFragNormal; +out vec2 ioFragTexCoords; +out vec4 ioFragColor; + +void main() { + mat4 model_view_matrix = uViewMatrix * uModelMatrix; + + ioFragPosition = (model_view_matrix * inCoord).xyz; + ioFragNormal = transpose(inverse(mat3(model_view_matrix))) * inNormal; + ioFragTexCoords = inUV; + ioFragColor = inColor; + + gl_Position = uProjectionMatrix * model_view_matrix * inCoord; +} diff --git a/src/modules/RenderModule.cc b/src/modules/RenderModule.cc index 7c549ad..c8caf8a 100644 --- a/src/modules/RenderModule.cc +++ b/src/modules/RenderModule.cc @@ -15,9 +15,18 @@ struct Renderer; float moving_factor = 1.0f; struct RendererSettings { - bool DrawDepth = false; bool DrawLightDepth = false; - bool DrawSSAO = false; + int RenderMode = 0; +}; + +enum SceneRenderMode { + SceneRenderModeDefault = 0, + SceneRenderModeColor = 1, + SceneRenderModeDepth = 2, + SceneRenderModeNormals = 3, + SceneRenderModePositions = 4, + SceneRenderModeAmbientOcclusion = 5, + SceneRenderModeCount }; static RendererSettings sRendererSettings; @@ -86,10 +95,10 @@ template static void module_serialize ( struct module_state *state, Serializer* serializer) { - SerializeBool(*serializer, "protot.RenderModule.DrawDepth", sRendererSettings.DrawDepth); SerializeBool(*serializer, "protot.RenderModule.DrawLightDepth", sRendererSettings.DrawLightDepth); - SerializeBool(*serializer, "protot.RenderModule.DrawSSAO", sRendererSettings.DrawSSAO); + SerializeInt(*serializer, "protot.RenderModule.RenderMode", sRendererSettings.RenderMode); + SerializeBool(*serializer, "protot.RenderModule.mUseDeferred", gRenderer->mUseDeferred); SerializeBool(*serializer, "protot.RenderModule.mIsSSAOEnabled", gRenderer->mIsSSAOEnabled); SerializeBool(*serializer, "protot.RenderModule.Camera.mIsOrthographic", gRenderer->mCamera.mIsOrthographic); SerializeFloat(*serializer, "protot.RenderModule.Camera.mFov", gRenderer->mCamera.mFov); @@ -374,12 +383,28 @@ void Renderer::Initialize(int width, int height) { mRenderQuadProgramDepth.RegisterFileModification(); assert(load_result); + // Deferred geomemtry pass + mDeferredGeometry = RenderProgram("data/shaders/vs_deferred_geometry.glsl", "data/shaders/fs_deferred_geometry.glsl"); + load_result = mDeferredGeometry.Load(); + mDeferredGeometry.RegisterFileModification(); + assert(load_result); + + mDeferredLighting = RenderProgram("data/shaders/vs_passthrough.glsl", "data/shaders/fs_deferred_lighting.glsl"); + load_result = mDeferredLighting.Load(); + mDeferredLighting.RegisterFileModification(); + assert(load_result); + // Program for SSAO mSSAOProgram = RenderProgram("data/shaders/vs_passthrough.glsl", "data/shaders/fs_ssao.glsl"); load_result = mSSAOProgram.Load(); mSSAOProgram.RegisterFileModification(); assert(load_result); + mBlurSSAOProgram = RenderProgram("data/shaders/vs_passthrough.glsl", "data/shaders/fs_blur_ssao.glsl"); + load_result = mBlurSSAOProgram.Load(); + mBlurSSAOProgram.RegisterFileModification(); + assert(load_result); + InitializeSSAOKernelAndNoise(); // Render Target @@ -403,6 +428,11 @@ void Renderer::Initialize(int width, int height) { // SSAO Target mSSAOTarget.Initialize(width, height, RenderTarget::EnableColor); + // Postprocess Target + mPostprocessTarget.Initialize(width, height, RenderTarget::EnableColor); + + mDeferredLightingTarget.Initialize(width, height, RenderTarget::EnableColor); + // Light mLight.Initialize(); mLight.mShadowMapTarget.mVertexArray = &gVertexArray; @@ -422,7 +452,6 @@ void Renderer::Shutdown() { } } - void Renderer::RenderGl() { mSceneAreaWidth = mSceneAreaWidth < 1 ? 1 : mSceneAreaWidth; mSceneAreaHeight = mSceneAreaHeight < 1 ? 1 : mSceneAreaHeight; @@ -438,13 +467,30 @@ void Renderer::RenderGl() { | RenderTarget::EnableNormalTexture; } + if (mUseDeferred) { + required_render_flags = RenderTarget::EnableColor + | RenderTarget::EnableDepthTexture + | RenderTarget::EnableNormalTexture + + // TODO: remove these + | RenderTarget::EnablePositionTexture + | RenderTarget::EnableLinearizedDepthTexture + ; + } + if (mSceneAreaWidth != mRenderTarget.mWidth || mSceneAreaHeight != mRenderTarget.mHeight || mRenderTarget.mFlags != required_render_flags ) { mRenderTarget.Resize(mSceneAreaWidth, mSceneAreaHeight, required_render_flags); + mPostprocessTarget.Resize(mSceneAreaWidth, mSceneAreaHeight, RenderTarget::EnableColor); + if (mIsSSAOEnabled) { mSSAOTarget.Resize(mSceneAreaWidth, mSceneAreaHeight, RenderTarget::EnableColor); } + + if (mUseDeferred) { + mDeferredLightingTarget.Resize(mSceneAreaWidth, mSceneAreaHeight, RenderTarget::EnableColor); + } } if (mCamera.mWidth != mSceneAreaWidth @@ -491,9 +537,29 @@ void Renderer::RenderGl() { gLog ("Cannot render: frame buffer invalid!"); } + glEnable(GL_DEPTH_TEST); + RenderProgram *program = &mDefaultProgram; + if (mUseDeferred) { + program = &mDeferredGeometry; + + GLenum buffers[] = { GL_COLOR_ATTACHMENT0, GL_COLOR_ATTACHMENT1, GL_COLOR_ATTACHMENT2 }; + glDrawBuffers(3, buffers); + glClear(GL_COLOR_BUFFER_BIT); + } else { + if (program->SetMat44("uLightSpaceMatrix", mLight.mLightSpaceMatrix) == -1) { + gLog ("Warning: Uniform %s not found!", "uLightSpaceMatrix"); + } + GLenum buffers[] = { GL_COLOR_ATTACHMENT0}; + glDrawBuffers (1, buffers); + } + // clear color and depth glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glEnable(GL_DEPTH_TEST); + glEnable(GL_LINE_SMOOTH); + glHint(GL_LINE_SMOOTH_HINT, GL_NICEST); + glEnable(GL_MULTISAMPLE); + glEnable(GL_CULL_FACE); glUseProgram(mSimpleProgram.mProgramId); mSimpleProgram.SetMat44("uModelViewProj", model_view_projection); @@ -515,32 +581,23 @@ void Renderer::RenderGl() { * mCamera.mViewMatrix * mCamera.mProjectionMatrix; mSimpleProgram.SetMat44("uModelViewProj", model_view_projection); - mSimpleProgram.SetVec4("uColor", Vector4f (1.0f, 1.0f, 1.0f, 0.4f)); + mSimpleProgram.SetVec4("uColor", Vector4f (1.0f, 1.0f, 1.0f, 0.1f)); gVertexArray.Bind(); gXZPlaneGrid.Draw(GL_LINES); // Scene - glUseProgram(mDefaultProgram.mProgramId); - glEnable(GL_DEPTH_TEST); + glUseProgram(program->mProgramId); - if (mDefaultProgram.SetMat44("uLightSpaceMatrix", mLight.mLightSpaceMatrix) == -1) { - gLog ("Warning: Uniform %s not found!", "uLightSpaceMatrix"); + RenderScene(*program, mCamera); + + if (mSettings->RenderMode == SceneRenderModeDepth) { + mRenderTarget.RenderToLinearizedDepth(mCamera.mNear, mCamera.mFar, mCamera.mIsOrthographic); } if (mIsSSAOEnabled) { GLenum buffers[] = { GL_COLOR_ATTACHMENT0, GL_COLOR_ATTACHMENT2, GL_COLOR_ATTACHMENT3 }; glDrawBuffers (3, buffers); - } else { - GLenum buffers[] = { GL_COLOR_ATTACHMENT0}; - glDrawBuffers (1, buffers); - } - RenderScene(mDefaultProgram, mCamera); - if (mSettings->DrawDepth) { - mRenderTarget.RenderToLinearizedDepth(mCamera.mNear, mCamera.mFar, mCamera.mIsOrthographic); - } - - if (mIsSSAOEnabled) { mSSAOTarget.Bind(); glViewport(0, 0, mCamera.mWidth, mCamera.mHeight); GLenum draw_attachment_0[] = {GL_COLOR_ATTACHMENT0 }; @@ -556,7 +613,7 @@ void Renderer::RenderGl() { glActiveTexture(GL_TEXTURE1); glBindTexture(GL_TEXTURE_2D, mRenderTarget.mNormalTexture); - // TODO: noise texture + // Noise glActiveTexture(GL_TEXTURE2); glBindTexture(GL_TEXTURE_2D, mSSAONoiseTexture); @@ -572,9 +629,74 @@ void Renderer::RenderGl() { mSSAOProgram.SetMat44("uProjection", mCamera.mProjectionMatrix); mSSAOProgram.SetVec3Array("uSamples", mSSAOKernel.size(), &mSSAOKernel[0][0]); -// for (int i = 0; i < mSSAOKernel.size(); ++i) { -// mSSAOProgram.SetVec3(std::string("uSamples[" + std::to_string(i) + "]").c_str(), mSSAOKernel[i]); -// } + + gVertexArray.Bind(); + gScreenQuad.Draw(GL_TRIANGLES); + + // Blur pass + mPostprocessTarget.Bind(); + glViewport(0, 0, mCamera.mWidth, mCamera.mHeight); + glDrawBuffers(1, draw_attachment_0); + glClear(GL_COLOR_BUFFER_BIT); + glDisable(GL_DEPTH_TEST); + + glActiveTexture(GL_TEXTURE0); + glBindTexture(GL_TEXTURE_2D, mRenderTarget.mColorTexture); + + glActiveTexture(GL_TEXTURE1); + glBindTexture(GL_TEXTURE_2D, mSSAOTarget.mColorTexture); + + glUseProgram(mBlurSSAOProgram.mProgramId); + mBlurSSAOProgram.SetInt("uColor", 0); + mBlurSSAOProgram.SetInt("uAmbientOcclusion", 1); + mBlurSSAOProgram.SetInt("uBlurSize", mSSAOBlurSize); + mBlurSSAOProgram.SetInt("uDisableColor", mSSAODisableColor); + + gScreenQuad.Draw(GL_TRIANGLES); + } + + if (mUseDeferred) { + GLenum buffers[] = { GL_COLOR_ATTACHMENT0}; + glDrawBuffers (1, buffers); + + mDeferredLightingTarget.Bind(); + glClear(GL_COLOR_BUFFER_BIT); + + glUseProgram(mDeferredLighting.mProgramId); + glActiveTexture(GL_TEXTURE0); + glBindTexture(GL_TEXTURE_2D, mRenderTarget.mColorTexture); + mDeferredLighting.SetInt("uColorTexture", 0); + + glActiveTexture(GL_TEXTURE1); + glBindTexture(GL_TEXTURE_2D, mRenderTarget.mNormalTexture); + mDeferredLighting.SetInt("uNormal", 1); + + glActiveTexture(GL_TEXTURE2); + glBindTexture(GL_TEXTURE_2D, mRenderTarget.mDepthTexture); + mDeferredLighting.SetInt("uDepth", 2); + + glActiveTexture(GL_TEXTURE3); + glBindTexture(GL_TEXTURE_2D, mLight.mShadowMapTarget.mDepthTexture); + mDeferredLighting.SetInt("uDepth", 3); + mDeferredLighting.SetMat44("uLightSpaceMatrix", mLight.mLightSpaceMatrix); + + // TODO: remove and reconstruct position from depth + glActiveTexture(GL_TEXTURE4); + glBindTexture(GL_TEXTURE_2D, mRenderTarget.mPositionTexture); + mDeferredLighting.SetInt("uPosition", 4); + + mDeferredLighting.SetMat44("uViewMatrix", mCamera.mViewMatrix); + Matrix33f view_mat_rot = mCamera.mViewMatrix.block<3,3>(0,0); + view_mat_rot = view_mat_rot.transpose(); + Vector3f light_direction = view_mat_rot * mLight.mDirection.normalized(); + +// gLog ("Light direction %3.4f, %3.4f, %3.4f", +// light_direction[0], +// light_direction[1], +// light_direction[2]); + + mDeferredLighting.SetVec3("uLightDirection", light_direction); + mDeferredLighting.SetVec3("uViewPosition", mCamera.mEye); gVertexArray.Bind(); gScreenQuad.Draw(GL_TRIANGLES); @@ -596,6 +718,13 @@ void Renderer::RenderScene(RenderProgram &program, const Camera& camera) { program.SetMat33("uNormalMatrix", normal_matrix); program.SetVec4("uColor", Vector4f (1.0f, 1.0f, 1.0f, 1.0f)); + Vector3f light_dir = (camera.mViewMatrix * Vector4f ( + mLight.mDirection[0], + mLight.mDirection[1], + mLight.mDirection[2], + 1.0f + )).block<3,1>(0,0); +// program.SetVec3("uLightDirection", light_dir.normalize()); program.SetVec3("uLightDirection", mLight.mDirection); program.SetVec3("uViewPosition", camera.mEye); @@ -614,7 +743,7 @@ void Renderer::RenderScene(RenderProgram &program, const Camera& camera) { program.SetMat44("uModelMatrix", RotateMat44(sin(0.3 * gTimer->mCurrentTime) * 180.0f, 0.0f, 1.0f, 0.0f) - * TranslateMat44(3.0, 1.0 + sin(2.0f * gTimer->mCurrentTime), 0.0)) ; + * TranslateMat44(5.0, 1.0 + sin(2.0f * gTimer->mCurrentTime), 0.0)) ; program.SetVec4("uColor", Vector4f (1.0f, 1.0f, 1.0f, 1.0f)); gUnitCubeMesh.Draw(GL_TRIANGLES); @@ -634,7 +763,7 @@ void Renderer::RenderScene(RenderProgram &program, const Camera& camera) { program.SetMat44("uModelMatrix", RotateMat44(200.0f, 0.0f, 1.0f, 0.0f) - * TranslateMat44(moving_factor * sin(gTimer->mCurrentTime), 1.0f, 0.0f) + * TranslateMat44(moving_factor * sin(gTimer->mCurrentTime), 1.0f, -3.0f) * ScaleMat44(0.5f, 0.5f, 0.5f)); program.SetVec4("uColor", Vector4f (1.0f, 1.0f, 1.0f, 1.0f)); @@ -650,35 +779,37 @@ void Renderer::RenderScene(RenderProgram &program, const Camera& camera) { void Renderer::DrawGui() { if (ImGui::BeginDock("Scene")) { - static int e = 0; - if (mSettings->DrawDepth) { - e = 1; - } else if (mSettings->DrawSSAO) { - e = 2; - } + ImGui::RadioButton("Default", &sRendererSettings.RenderMode, 0); ImGui::SameLine(); + ImGui::RadioButton("Color", &sRendererSettings.RenderMode, 1); ImGui::SameLine(); + ImGui::RadioButton("Depth", &sRendererSettings.RenderMode, 2); ImGui::SameLine(); + ImGui::RadioButton("Normals", &sRendererSettings.RenderMode, 3); ImGui::SameLine(); + ImGui::RadioButton("Positions", &sRendererSettings.RenderMode, 4); + + if (mIsSSAOEnabled) { + ImGui::SameLine(); + ImGui::RadioButton("AO", &sRendererSettings.RenderMode, 5); + }; - ImGui::RadioButton("Default", &e, 0); ImGui::SameLine(); - ImGui::RadioButton("Depth", &e, 1); ImGui::SameLine(); - ImGui::RadioButton("SSAO", &e, 2); - - switch (e) { - case 0: mSettings->DrawDepth = 0; - mSettings->DrawSSAO = 0; - break; - case 1: mSettings->DrawDepth = 1; - mSettings->DrawSSAO = 0; - break; - case 2: mSettings->DrawDepth = 0; - mSettings->DrawSSAO = 1; - break; - } - - if (mSettings->DrawDepth) { - mRenderTextureRef.mTextureIdPtr = &mRenderTarget.mLinearizedDepthTexture; - } else if (mSettings->DrawSSAO) { - mRenderTextureRef.mTextureIdPtr = &mSSAOTarget.mColorTexture; - } else { - mRenderTextureRef.mTextureIdPtr = &mRenderTarget.mColorTexture; + switch (sRendererSettings.RenderMode) { + case SceneRenderModeDefault: + mRenderTextureRef.mTextureIdPtr = + mUseDeferred ? &mDeferredLightingTarget.mColorTexture : &mPostprocessTarget.mColorTexture; + break; + case SceneRenderModeColor: + mRenderTextureRef.mTextureIdPtr = &mRenderTarget.mColorTexture; + break; + case SceneRenderModeDepth: + mRenderTextureRef.mTextureIdPtr = &mRenderTarget.mLinearizedDepthTexture; + break; + case SceneRenderModeNormals: + mRenderTextureRef.mTextureIdPtr = &mRenderTarget.mNormalTexture; + break; + case SceneRenderModePositions: + mRenderTextureRef.mTextureIdPtr = &mRenderTarget.mPositionTexture; + break; + case SceneRenderModeAmbientOcclusion: + mRenderTextureRef.mTextureIdPtr = &mSSAOTarget.mColorTexture; + break; } ImGui::Text("Scene"); @@ -705,12 +836,15 @@ void Renderer::DrawGui() { ImGui::Text("Camera"); mCamera.DrawGui(); + ImGui::Checkbox("Enable Deferred", &mUseDeferred); ImGui::Checkbox("Enable SSAO", &mIsSSAOEnabled); if (mIsSSAOEnabled) { ImGui::SliderFloat("Radius", &mSSAORadius, 0.0f, 1.0f); ImGui::SliderFloat("Bias", &mSSAOBias, 0.0f, 0.1f); ImGui::SliderInt("Samples", &mSSAOKernelSize, 1, 64); + ImGui::SliderInt("Blur Size", &mSSAOBlurSize, 0, 8); + ImGui::Checkbox("Disable Color", &mSSAODisableColor); if (mSSAOKernelSize != mSSAOKernel.size()) { InitializeSSAOKernelAndNoise(); diff --git a/src/modules/RenderModule.h b/src/modules/RenderModule.h index 3dce07b..84e2180 100644 --- a/src/modules/RenderModule.h +++ b/src/modules/RenderModule.h @@ -56,6 +56,7 @@ struct Renderer { bool mInitialized = false; bool mIsSSAOEnabled = false; + bool mUseDeferred = false; uint32_t mWidth = 1; uint32_t mHeight = 1; @@ -68,13 +69,18 @@ struct Renderer { Texture mDefaultTexture; RenderProgram mSimpleProgram; + RenderProgram mDeferredGeometry; + RenderProgram mDeferredLighting; RenderProgram mDefaultProgram; RenderProgram mRenderQuadProgramColor; RenderProgram mRenderQuadProgramDepth; RenderProgram mSSAOProgram; + RenderProgram mBlurSSAOProgram; RenderTarget mRenderTarget; + RenderTarget mDeferredLightingTarget; RenderTarget mSSAOTarget; + RenderTarget mPostprocessTarget; GLTextureRef mRenderTextureRef = { (int)0xbadface }; GLTextureRef mPositionTextureRef = { (int)0xbadface }; @@ -85,6 +91,8 @@ struct Renderer { int mSSAOKernelSize = 64; std::vector mSSAOKernel; GLuint mSSAONoiseTexture = -1; + int mSSAOBlurSize = 1; + bool mSSAODisableColor = false; Renderer() : mInitialized(false), diff --git a/src/modules/RenderUtils.cc b/src/modules/RenderUtils.cc index afe036d..6c52b07 100644 --- a/src/modules/RenderUtils.cc +++ b/src/modules/RenderUtils.cc @@ -154,8 +154,8 @@ GLuint RenderProgram::LinkProgram(GLuint vertex_shader, GLuint fragment_shader) glBindAttribLocation(ProgramID, 3, "inColor"); glBindFragDataLocation(ProgramID, 0, "outColor"); - glBindFragDataLocation(ProgramID, 1, "outPosition"); - glBindFragDataLocation(ProgramID, 2, "outNormal"); + glBindFragDataLocation(ProgramID, 1, "outNormal"); + glBindFragDataLocation(ProgramID, 2, "outPosition"); glLinkProgram(ProgramID); @@ -404,7 +404,7 @@ void RenderTarget::Resize(int width, int height, int flags) { glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); - glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT1, GL_TEXTURE_2D, mLinearizedDepthTexture, 0); + glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT4, GL_TEXTURE_2D, mLinearizedDepthTexture, 0); } } else if (mFlags & EnableDepth) { assert((mFlags & EnableDepthTexture) == false); @@ -414,6 +414,19 @@ void RenderTarget::Resize(int width, int height, int flags) { glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, mDepthBuffer); } + if (mFlags & EnableNormalTexture) { + glGenTextures(1, &mNormalTexture); + glBindTexture(GL_TEXTURE_2D, mNormalTexture); + + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB16F, mWidth, mHeight, 0, GL_RGB, GL_FLOAT, NULL); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); + + glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT1, GL_TEXTURE_2D, mNormalTexture, 0); + } + if (mFlags & EnablePositionTexture) { glGenTextures(1, &mPositionTexture); glBindTexture(GL_TEXTURE_2D, mPositionTexture); @@ -427,19 +440,6 @@ void RenderTarget::Resize(int width, int height, int flags) { glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT2, GL_TEXTURE_2D, mPositionTexture, 0); } - if (mFlags & EnableNormalTexture) { - glGenTextures(1, &mNormalTexture); - glBindTexture(GL_TEXTURE_2D, mNormalTexture); - - glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB16F, mWidth, mHeight, 0, GL_RGB, GL_FLOAT, NULL); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); - - glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT3, GL_TEXTURE_2D, mNormalTexture, 0); - } - GLenum result = glCheckFramebufferStatus(GL_FRAMEBUFFER); if (result != GL_FRAMEBUFFER_COMPLETE) { switch (result) { @@ -463,7 +463,7 @@ void RenderTarget::RenderToLinearizedDepth(const float& near, const float& far, assert(mQuadMesh != nullptr); glBindFramebuffer(GL_FRAMEBUFFER, mFrameBufferId); - GLenum draw_attachment_1[] = { GL_COLOR_ATTACHMENT1 }; + GLenum draw_attachment_1[] = { GL_COLOR_ATTACHMENT4 }; glDrawBuffers(1, draw_attachment_1); glClear(GL_COLOR_BUFFER_BIT); diff --git a/src/modules/RenderUtils.h b/src/modules/RenderUtils.h index 6725038..2c02a0d 100644 --- a/src/modules/RenderUtils.h +++ b/src/modules/RenderUtils.h @@ -151,8 +151,8 @@ struct Camera { Matrix44f mViewMatrix; Camera() : - mEye {5.f, 4.f, 5.f}, - mPoi {0.f, 2.f, 0.f}, + mEye {-4.f, 4.4f, 0.f}, + mPoi {-3.2f, 3.8f, 0.2f}, mUp {0.f, 1.f, 0.f}, mNear (0.1f), mFar (150.f),