diff --git a/include/Engine/Rendering/DrawFinalPass.h b/include/Engine/Rendering/DrawFinalPass.h index 1d91f6a2..e3389471 100644 --- a/include/Engine/Rendering/DrawFinalPass.h +++ b/include/Engine/Rendering/DrawFinalPass.h @@ -18,7 +18,7 @@ public: void InitializeTextures(); void InitializeFrameBuffers(); void InitializeShaderPrograms(); - void Draw(RenderScene& scene); + void Draw(RenderScene& scene, GLuint SSAOTexture); void ClearBuffer(); void OnWindowResize(); @@ -37,7 +37,7 @@ private: void GenerateMipMapTexture(GLuint* texture, GLenum wrapping, glm::vec2 dimensions, GLint format, GLenum type, GLint numMipMaps) const; void DrawSprites(std::list>&jobs, RenderScene& scene); - void DrawModelRenderQueues(std::list>& jobs, RenderScene& scene); + void DrawModelRenderQueues(std::list>& jobs, RenderScene& scene, GLuint SSAOTexture); void DrawShieldToStencilBuffer(std::list>& jobs, RenderScene& scene); void DrawShieldedModelRenderQueue(std::list>& jobs, RenderScene& scene); void DrawToDepthBuffer(std::list>& jobs, RenderScene& scene); diff --git a/include/Engine/Rendering/Renderer.h b/include/Engine/Rendering/Renderer.h index 2f42bad2..aa87536b 100644 --- a/include/Engine/Rendering/Renderer.h +++ b/include/Engine/Rendering/Renderer.h @@ -16,6 +16,7 @@ #include "DrawScreenQuadPass.h" #include "DrawBloomPass.h" #include "DrawColorCorrectionPass.h" +#include "SSAOPass.h" #include "../Core/EventBroker.h" #include "ImGuiRenderPass.h" #include "Camera.h" @@ -58,6 +59,12 @@ private: int m_DebugTextureToDraw = 0; bool m_ResizeWindow = false; + float m_SSAO_Radius = 1.0f; + float m_SSAO_Bias = 0.05f; + float m_SSAO_Contrast = 1.5f; + float m_SSAO_IntensityScale = 1.0f; + int m_SSAO_NumOfSamples = 24; + int m_SSAO_NumOfTurns = 7; PickingPass* m_PickingPass; LightCullingPass* m_LightCullingPass; @@ -66,6 +73,7 @@ private: DrawScreenQuadPass* m_DrawScreenQuadPass; DrawBloomPass* m_DrawBloomPass; DrawColorCorrectionPass* m_DrawColorCorrectionPass; + SSAOPass* m_SSAOPass; //----------------------Functions----------------------// void InitializeWindow(); diff --git a/include/Engine/Rendering/SSAOPass.h b/include/Engine/Rendering/SSAOPass.h new file mode 100644 index 00000000..f15e20d3 --- /dev/null +++ b/include/Engine/Rendering/SSAOPass.h @@ -0,0 +1,61 @@ +#ifndef SSAOPass_h__ +#define SSAOPass_h__ + +#include "IRenderer.h" +#include "SSAOPassState.h" +//#include "LightCullingPass.h" Finalpass om den skall skickas in +#include "FrameBuffer.h" +#include "ShaderProgram.h" +#include "DrawBloomPass.h" +//#include "Util/UnorderedMapVec2.h" +#include "Texture.h" + +class SSAOPass +{ +public: + SSAOPass(IRenderer* rendere); + ~SSAOPass() { }; + + void Draw(GLuint depthBuffer, Camera* camera); + void Setting(float radius, float bias, float contrast, float intensityScale, int numOfSamples, int NumOfTurns); + void ClearBuffer(); + + //Return the SSAO of the texture sent to Draw + GLuint SSAOTexture() const { return m_DrawBloomPass->GaussianTexture(); } + +private: + void InitializeTexture(); + void InitializeFrameBuffer(); + void InitializeShaderProgram(); + void InitializeBuffer(); + + void GenerateTexture(GLuint* texture, GLenum wrapping, GLenum filtering, glm::vec2 dimensions, GLint internalFormat, GLint format, GLenum type) const; + + void ComputeAO(GLuint depthBuffer, Camera* camera); + //void blurHorizontal(GLuint depthBuffer); + //void blurVertical(GLuint depthBuffer); + + Model* m_ScreenQuad; + + const IRenderer* m_Renderer; + + float m_Radius; + float m_Bias; + float m_Contrast; + float m_IntensityScale; + int m_NumOfSamples; + int m_NumOfTurns; + + GLuint m_SSAOTexture; + FrameBuffer m_SSAOFramBuffer; + + GLuint m_SSAOViewSpaceZTexture; + FrameBuffer m_SSAOViewSpaceZFramBuffer; + + ShaderProgram* m_SSAOProgram; + ShaderProgram* m_SSAOViewSpaceZProgram; + + DrawBloomPass* m_DrawBloomPass; +}; + +#endif \ No newline at end of file diff --git a/include/Engine/Rendering/SSAOPassState.h b/include/Engine/Rendering/SSAOPassState.h new file mode 100644 index 00000000..115fdcf7 --- /dev/null +++ b/include/Engine/Rendering/SSAOPassState.h @@ -0,0 +1,15 @@ +#ifndef SSAOPassState_h__ +#define SSAOPassState_h__ + +#include "Rendering/RenderState.h" + +class SSAOPassState : public RenderState +{ +public: + SSAOPassState(); + ~SSAOPassState(); +private: + +}; + +#endif \ No newline at end of file diff --git a/resources/Schema/Entities/Player.xml b/resources/Schema/Entities/Player.xml index 22fa3bd8..5b09c595 100644 --- a/resources/Schema/Entities/Player.xml +++ b/resources/Schema/Entities/Player.xml @@ -348,13 +348,12 @@ Idle - 1.6050530664521858 + 1.8314163732853146 1 Models/Characters/Assault/FirstPerson.mesh - true @@ -366,11 +365,10 @@ Models/Weapons/Blue/AssaultWeaponBlue.mesh - true - - + + @@ -476,7 +474,7 @@ Idle - 1.620305457513453 + 0.16333512901638159 1 @@ -500,8 +498,8 @@ Models/Weapons/Blue/AssaultWeaponBlue.mesh - - + + diff --git a/resources/Schema/Entities/PlayerRed.xml b/resources/Schema/Entities/PlayerRed.xml index d9839e9f..4be8fc26 100644 --- a/resources/Schema/Entities/PlayerRed.xml +++ b/resources/Schema/Entities/PlayerRed.xml @@ -349,13 +349,12 @@ Idle - 1.6050530664521858 + 0.018170670865885086 1 Models/Characters/Assault/FirstPerson.mesh - true @@ -367,11 +366,10 @@ Models/Weapons/Red/AssaultWeaponRed.mesh - true - - + + @@ -477,7 +475,7 @@ Idle - 1.620305457513453 + 0.11675631578762591 1 @@ -501,8 +499,8 @@ Models/Weapons/Red/AssaultWeaponRed.mesh - - + + diff --git a/resources/Shaders/DrawColorCorrection.frag.glsl b/resources/Shaders/DrawColorCorrection.frag.glsl index 76db3e82..bae50887 100644 --- a/resources/Shaders/DrawColorCorrection.frag.glsl +++ b/resources/Shaders/DrawColorCorrection.frag.glsl @@ -19,6 +19,8 @@ void main() vec4 bloomColor = texture(BloomTexture, Input.TextureCoordinate); vec4 hdrColorLowRes = texture(SceneTextureLowRes, Input.TextureCoordinate); vec4 bloomColorLowRes = texture(BloomTextureLowRes, Input.TextureCoordinate); + + //hdrColor = hdrColor * SSAO; hdrColor += bloomColor; hdrColorLowRes; @@ -33,7 +35,6 @@ void main() //gamme correction result = pow(result, vec3(1.0 / Gamma)); - fragmentColor = vec4(result, 1.0); //fragmentColor = hdrColor; //fragmentColor = bloomColor; diff --git a/resources/Shaders/ForwardPlus.frag.glsl b/resources/Shaders/ForwardPlus.frag.glsl index d757ff36..47da7480 100644 --- a/resources/Shaders/ForwardPlus.frag.glsl +++ b/resources/Shaders/ForwardPlus.frag.glsl @@ -1,5 +1,7 @@ #version 430 +#define MIN_AMBIENT_LIGHT 0.3 + uniform mat4 M; uniform mat4 V; uniform mat4 P; @@ -15,10 +17,11 @@ uniform vec2 DiffuseUVRepeat; uniform vec2 NormalUVRepeat; uniform vec2 SpecularUVRepeat; uniform vec2 GlowUVRepeat; -layout (binding = 0) uniform sampler2D DiffuseTexture; -layout (binding = 1) uniform sampler2D NormalMapTexture; -layout (binding = 2) uniform sampler2D SpecularMapTexture; -layout (binding = 3) uniform sampler2D GlowMapTexture; +layout (binding = 0) uniform sampler2D AOTexture; +layout (binding = 1) uniform sampler2D DiffuseTexture; +layout (binding = 2) uniform sampler2D NormalMapTexture; +layout (binding = 3) uniform sampler2D SpecularMapTexture; +layout (binding = 4) uniform sampler2D GlowMapTexture; #define TILE_SIZE 16 @@ -120,6 +123,8 @@ vec4 CalcNormalMappedValue(vec3 normal, vec3 tangent, vec3 bitangent, vec2 textu void main() { + float ao = texelFetch(AOTexture, ivec2(gl_FragCoord.xy), 0).r; + ao = (clamp(1.0 - (1.0 - ao), 0.0, 1.0) + MIN_AMBIENT_LIGHT) / (1.0 + MIN_AMBIENT_LIGHT); vec4 diffuseTexel = texture2D(DiffuseTexture, Input.TextureCoordinate * DiffuseUVRepeat); vec4 glowTexel = texture2D(GlowMapTexture, Input.TextureCoordinate * GlowUVRepeat); vec4 specularTexel = texture2D(SpecularMapTexture, Input.TextureCoordinate * SpecularUVRepeat); @@ -134,7 +139,7 @@ void main() tilePos.y = int(gl_FragCoord.y/TILE_SIZE); LightResult totalLighting; - totalLighting.Diffuse = vec4(AmbientColor.rgb, 1.0); + totalLighting.Diffuse = vec4(AmbientColor.rgb * ao, 1.0); int currentTile = int(floor(gl_FragCoord.x/TILE_SIZE) + (floor(gl_FragCoord.y/TILE_SIZE) * int(ScreenDimensions.x/TILE_SIZE))); int start = int(LightGrids.Data[currentTile].Start); @@ -152,8 +157,8 @@ void main() } else if (light.Type == 2) { //Directional light_result = CalcDirectionalLightSource(V * light.Direction, light.Color, light.Intensity, viewVec, normal); } - totalLighting.Diffuse += light_result.Diffuse; - totalLighting.Specular += light_result.Specular; + totalLighting.Diffuse += vec4(light_result.Diffuse.rgb * ao, light_result.Diffuse.a); + totalLighting.Specular += vec4(light_result.Specular.rgb * ao, light_result.Specular.a); } vec4 color_result = mix((Color * diffuseTexel * DiffuseColor), Input.ExplosionColor, Input.ExplosionPercentageElapsed); diff --git a/resources/Shaders/ForwardPlusSplatMapRGB.frag.glsl b/resources/Shaders/ForwardPlusSplatMapRGB.frag.glsl index e862d926..cf358b96 100644 --- a/resources/Shaders/ForwardPlusSplatMapRGB.frag.glsl +++ b/resources/Shaders/ForwardPlusSplatMapRGB.frag.glsl @@ -1,5 +1,7 @@ #version 430 +#define MIN_AMBIENT_LIGHT 0.3 + uniform mat4 M; uniform mat4 V; uniform mat4 P; @@ -23,19 +25,20 @@ uniform vec2 SpecularUVRepeat3; uniform vec2 GlowUVRepeat1; uniform vec2 GlowUVRepeat2; uniform vec2 GlowUVRepeat3; -layout (binding = 0) uniform sampler2D SplatMapTexture; -layout (binding = 1) uniform sampler2D DiffuseTexture1; -layout (binding = 2) uniform sampler2D DiffuseTexture2; -layout (binding = 3) uniform sampler2D DiffuseTexture3; -layout (binding = 4) uniform sampler2D NormalMapTexture1; -layout (binding = 5) uniform sampler2D NormalMapTexture2; -layout (binding = 6) uniform sampler2D NormalMapTexture3; -layout (binding = 7) uniform sampler2D SpecularMapTexture1; -layout (binding = 8) uniform sampler2D SpecularMapTexture2; -layout (binding = 9) uniform sampler2D SpecularMapTexture3; -layout (binding = 10) uniform sampler2D GlowMapTexture1; -layout (binding = 11) uniform sampler2D GlowMapTexture2; -layout (binding = 12) uniform sampler2D GlowMapTexture3; +layout (binding = 0) uniform sampler2D AOTexture; +layout (binding = 1) uniform sampler2D SplatMapTexture; +layout (binding = 2) uniform sampler2D DiffuseTexture1; +layout (binding = 3) uniform sampler2D DiffuseTexture2; +layout (binding = 4) uniform sampler2D DiffuseTexture3; +layout (binding = 5) uniform sampler2D NormalMapTexture1; +layout (binding = 6) uniform sampler2D NormalMapTexture2; +layout (binding = 7) uniform sampler2D NormalMapTexture3; +layout (binding = 8) uniform sampler2D SpecularMapTexture1; +layout (binding = 9) uniform sampler2D SpecularMapTexture2; +layout (binding = 10) uniform sampler2D SpecularMapTexture3; +layout (binding = 11) uniform sampler2D GlowMapTexture1; +layout (binding = 12) uniform sampler2D GlowMapTexture2; +layout (binding = 13) uniform sampler2D GlowMapTexture3; #define TILE_SIZE 16 @@ -174,6 +177,9 @@ vec4 CalcBlendedNormal(vec4 blendValue, sampler2D R, sampler2D G, sampler2D B, void main() { + float ao = texelFetch(AOTexture, ivec2(gl_FragCoord.xy), 0).r; + ao = (clamp(1.0 - (1.0 - ao), 0.0, 1.0) + MIN_AMBIENT_LIGHT) / (1.0 + MIN_AMBIENT_LIGHT); + vec4 splatTexel = texture2D(SplatMapTexture, Input.TextureCoordinate); vec4 diffuseTexel = CalcBlendedTexel(splatTexel, DiffuseTexture1, DiffuseTexture2, DiffuseTexture3, @@ -195,7 +201,7 @@ void main() tilePos.y = int(gl_FragCoord.y/TILE_SIZE); LightResult totalLighting; - totalLighting.Diffuse = vec4(AmbientColor.rgb, 1.0); + totalLighting.Diffuse = vec4(AmbientColor.rgb * ao, 1.0); int currentTile = int(floor(gl_FragCoord.x/TILE_SIZE) + (floor(gl_FragCoord.y/TILE_SIZE) * int(ScreenDimensions.x/TILE_SIZE))); int start = int(LightGrids.Data[currentTile].Start); @@ -213,8 +219,8 @@ void main() } else if (light.Type == 2) { //Directional light_result = CalcDirectionalLightSource(V * light.Direction, light.Color, light.Intensity, viewVec, normal); } - totalLighting.Diffuse += light_result.Diffuse; - totalLighting.Specular += light_result.Specular; + totalLighting.Diffuse += vec4(light_result.Diffuse.rgb * ao, light_result.Diffuse.a); + totalLighting.Specular += vec4(light_result.Specular.rgb * ao, light_result.Specular.a); } vec4 color_result = mix((Color * diffuseTexel * DiffuseColor), Input.ExplosionColor, Input.ExplosionPercentageElapsed); diff --git a/resources/Shaders/SSAO.frag.glsl b/resources/Shaders/SSAO.frag.glsl new file mode 100644 index 00000000..68c830f8 --- /dev/null +++ b/resources/Shaders/SSAO.frag.glsl @@ -0,0 +1,114 @@ +#version 430 + +//Number of samples per pixel +uniform int uNumOfSamples; +//#define NUM_SAMPLES (11) + +//Number of turns around the cirle +uniform int uNumOfTurns; +//#define NUM_TURNS (7) + +layout (binding = 0) uniform sampler2D ViewSpaceZ; + +uniform vec4 uProjInfo; + +uniform float uProjScale; +//#define ProjScale 500 + +uniform float uRadius; +//#define Radius 1.0f + +uniform float uBias; +//#define Bias 0.012f + +uniform float uContrast; +//#define IntensityDivR6 1 + +uniform float uIntensityScale; + +out float AO; + +vec3 getVSPosition(ivec2 ScreenSpaceCoord) { + float z = texelFetch(ViewSpaceZ, ScreenSpaceCoord, 0).r; + //Get the xy view space coordinates and add the z value from ViewSpaceZ buffer. + return vec3((uProjInfo[0] + (ScreenSpaceCoord.x * uProjInfo[1])) * z, (uProjInfo[2] + (ScreenSpaceCoord.y * uProjInfo[3])) * z, z); +} + +vec3 getVSFaceNormal(vec3 ViewSpacePosition) { + // Get tangets vector for the plane and ViewSpacePositin... don't ask how this functions works. It's pure magic. + // They do this and it just works... I would guess that they approximate the function of a plane from pixels close to the pixel were on now. + return normalize(cross(dFdx(ViewSpacePosition), dFdy(ViewSpacePosition))); +} + + +vec3 getSampleViewSpacePos(ivec2 ScreenSpaceCoord, int SampleIndex, float RotationAngle, float ScreenSpaceSampleRadius){ + // Pure Magic... + float alpha = float(SampleIndex) * (1.0 / uNumOfSamples); + + // Angle to where to sample + float angle = alpha * (uNumOfTurns * 6.28) + RotationAngle; + + //Lenght to were to sample + ScreenSpaceSampleRadius = ScreenSpaceSampleRadius * alpha; + + vec2 screenSpaceSampleOffsetVecor = vec2(cos(angle), sin(angle)); + + // Get texel coordinate on where to sample by going screenSpaceSampleOffsetVecor direction in ScreenSpaceSampleRadius units from ScreenSpaceCoord (the point being shaded); + ivec2 screenSpaceSampleTexel = ivec2(ScreenSpaceSampleRadius * screenSpaceSampleOffsetVecor) + ScreenSpaceCoord; + + return getVSPosition(screenSpaceSampleTexel); +} + + + +float sampleAO(ivec2 ScreenSpaceCoord, vec3 Origin, vec3 OriginNormal, float ScreenSpaceSampleRadius, int SampleIndex, float RotationAngle, float Radius) { + float radius2 = Radius * Radius; + vec3 sampleViewSpacePosition = getSampleViewSpacePos(ScreenSpaceCoord, SampleIndex, RotationAngle, ScreenSpaceSampleRadius); + + vec3 sampleVector = Origin - sampleViewSpacePosition; + + // vv = sampleVectorLenght ^ 2 + float vv = dot(sampleVector, sampleVector); + // vn = angle between sampleVector and Normal + float vn = dot(sampleVector, OriginNormal); + + const float epsilon = 0.0001f; + + // vv < radius2 if the vector is shorter then the radius; + // vn - bias, offset the angle to reduse self occlusion. + // epsilon is here to make divison by 0 impossible. + return float(vv < radius2) * max((vn - uBias) / (epsilon + vv), 0.0); + //float f = max(radius2 - vv, 0.0); + //return f * f * f * max((vn - uBias) / (epsilon + vv), 0.0); +} + + +void main() { + ivec2 originScreenCoord = ivec2(gl_FragCoord.xy); + + vec3 origin = getVSPosition(originScreenCoord); + + float radius; + if(origin.z < uRadius){ + radius = origin.z; + } else { + radius = uRadius; + } + + + vec3 originNormal = getVSFaceNormal(origin); + + float screenSpaceSampleRadius = -uProjScale * radius / origin.z; + + float rotationAngleOffset = 30 * originScreenCoord.x ^ originScreenCoord.y + 10 * originScreenCoord.x * originScreenCoord.y; + + float sum = 0.0; + for (int i = 0; i < uNumOfSamples; i++) { + sum += sampleAO(originScreenCoord, origin, originNormal, screenSpaceSampleRadius, i, rotationAngleOffset, radius); + } + + //float A = max(0.0, 1.0 - sum * (2.0f / uNumOfSamples)); + float A = 1.0 - sum * (2.0f * uIntensityScale / float(uNumOfSamples)); + AO = clamp(pow(A, uContrast), 0.0f, 1.0f); + //AO = vec4(originNormal, 1.0f); +} diff --git a/resources/Shaders/SSAO.vert.glsl b/resources/Shaders/SSAO.vert.glsl new file mode 100644 index 00000000..a019c5ef --- /dev/null +++ b/resources/Shaders/SSAO.vert.glsl @@ -0,0 +1,8 @@ +#version 430 + +layout (location = 0) in vec3 Position; + +void main() +{ + gl_Position = vec4(Position, 1.0); +} \ No newline at end of file diff --git a/resources/Shaders/SSAOViewSpaceZ.frag.glsl b/resources/Shaders/SSAOViewSpaceZ.frag.glsl new file mode 100644 index 00000000..dbcfd899 --- /dev/null +++ b/resources/Shaders/SSAOViewSpaceZ.frag.glsl @@ -0,0 +1,14 @@ +#version 430 + +layout (binding = 0) uniform sampler2D DepthBuffer; +uniform vec3 ClipInfo; + +out float depthLinear; +//Just for Debug, should be depthLinear +//out vec4 fragmentColor; +void main() { + float depthSample = texelFetch(DepthBuffer, ivec2(gl_FragCoord.xy), 0).r; + depthLinear = ClipInfo[0] / (ClipInfo[1] * depthSample + ClipInfo[2]); + //float depthLinear = (NearClip) / ( -depthSample + 1.0f); + //fragmentColor = vec4(depthLinear, depthLinear, depthLinear, 1.0f); +} \ No newline at end of file diff --git a/resources/Shaders/Sprite.frag.glsl b/resources/Shaders/Sprite.frag.glsl index 9ce2bbdf..754be6ac 100644 --- a/resources/Shaders/Sprite.frag.glsl +++ b/resources/Shaders/Sprite.frag.glsl @@ -7,8 +7,8 @@ uniform mat4 M; uniform mat4 V; uniform mat4 P; -layout (binding = 0) uniform sampler2D DiffuseTexture; -layout (binding = 1) uniform sampler2D GlowMapTexture; +layout (binding = 1) uniform sampler2D DiffuseTexture; +layout (binding = 2) uniform sampler2D GlowMapTexture; in VertexData{ diff --git a/src/Engine/Rendering/DrawBloomPass.cpp b/src/Engine/Rendering/DrawBloomPass.cpp index 1855a653..6bfb58eb 100644 --- a/src/Engine/Rendering/DrawBloomPass.cpp +++ b/src/Engine/Rendering/DrawBloomPass.cpp @@ -19,16 +19,20 @@ void DrawBloomPass::InitializeTextures() void DrawBloomPass::InitializeShaderPrograms() { m_GaussianProgram_horiz = ResourceManager::Load("##GaussianProgramHoriz"); - m_GaussianProgram_horiz->AddShader(std::shared_ptr(new VertexShader("Shaders/Gaussian_horiz.vert.glsl"))); - m_GaussianProgram_horiz->AddShader(std::shared_ptr(new FragmentShader("Shaders/Gaussian_horiz.frag.glsl"))); - m_GaussianProgram_horiz->Compile(); - m_GaussianProgram_horiz->Link(); + if (m_GaussianProgram_horiz->GetHandle() == 0) { + m_GaussianProgram_horiz->AddShader(std::shared_ptr(new VertexShader("Shaders/Gaussian_horiz.vert.glsl"))); + m_GaussianProgram_horiz->AddShader(std::shared_ptr(new FragmentShader("Shaders/Gaussian_horiz.frag.glsl"))); + m_GaussianProgram_horiz->Compile(); + m_GaussianProgram_horiz->Link(); + } - m_GaussianProgram_vert = ResourceManager::Load("##GaussianProgramVert"); - m_GaussianProgram_vert->AddShader(std::shared_ptr(new VertexShader("Shaders/Gaussian_vert.vert.glsl"))); - m_GaussianProgram_vert->AddShader(std::shared_ptr(new FragmentShader("Shaders/Gaussian_vert.frag.glsl"))); - m_GaussianProgram_vert->Compile(); - m_GaussianProgram_vert->Link(); + m_GaussianProgram_vert = ResourceManager::Load("##GaussianProgramVert"); + if (m_GaussianProgram_vert->GetHandle() == 0) { + m_GaussianProgram_vert->AddShader(std::shared_ptr(new VertexShader("Shaders/Gaussian_vert.vert.glsl"))); + m_GaussianProgram_vert->AddShader(std::shared_ptr(new FragmentShader("Shaders/Gaussian_vert.frag.glsl"))); + m_GaussianProgram_vert->Compile(); + m_GaussianProgram_vert->Link(); + } } @@ -71,15 +75,12 @@ void DrawBloomPass::Draw(GLuint texture) //Horizontal pass, first use the given texture then save it to the horizontal framebuffer. m_GaussianFrameBuffer_horiz.Bind(); m_GaussianProgram_horiz->Bind(); - glActiveTexture(GL_TEXTURE0); glBindTexture(GL_TEXTURE_2D, texture); - glBindVertexArray(m_ScreenQuad->VAO); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_ScreenQuad->ElementBuffer); glDrawElementsBaseVertex(GL_TRIANGLES, m_ScreenQuad->MaterialGroups()[0].material->EndIndex - m_ScreenQuad->MaterialGroups()[0].material->StartIndex +1 , GL_UNSIGNED_INT, 0, m_ScreenQuad->MaterialGroups()[0].material->StartIndex); - //Iterate some times to make it more gaussian. for (int i = 1; i < m_iterations; i++) { //Vertical pass @@ -92,7 +93,6 @@ void DrawBloomPass::Draw(GLuint texture) glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_ScreenQuad->ElementBuffer); glDrawElementsBaseVertex(GL_TRIANGLES, m_ScreenQuad->MaterialGroups()[0].material->EndIndex - m_ScreenQuad->MaterialGroups()[0].material->StartIndex +1 , GL_UNSIGNED_INT, 0, m_ScreenQuad->MaterialGroups()[0].material->StartIndex); - //horizontal pass m_GaussianFrameBuffer_horiz.Bind(); @@ -112,7 +112,6 @@ void DrawBloomPass::Draw(GLuint texture) m_GaussianProgram_vert->Bind(); glBindTexture(GL_TEXTURE_2D, m_GaussianTexture_horiz); - glBindVertexArray(m_ScreenQuad->VAO); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_ScreenQuad->ElementBuffer); glDrawElementsBaseVertex(GL_TRIANGLES, m_ScreenQuad->MaterialGroups()[0].material->EndIndex - m_ScreenQuad->MaterialGroups()[0].material->StartIndex +1 diff --git a/src/Engine/Rendering/DrawFinalPass.cpp b/src/Engine/Rendering/DrawFinalPass.cpp index d46f9591..a12c52b1 100644 --- a/src/Engine/Rendering/DrawFinalPass.cpp +++ b/src/Engine/Rendering/DrawFinalPass.cpp @@ -27,6 +27,7 @@ void DrawFinalPass::InitializeFrameBuffers() glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH24_STENCIL8, m_Renderer->GetViewportSize().Width, m_Renderer->GetViewportSize().Height); GLERROR("RenderBuffer generation"); + GenerateTexture(&m_SceneTexture, GL_CLAMP_TO_EDGE, GL_LINEAR, glm::vec2(m_Renderer->GetViewportSize().Width, m_Renderer->GetViewportSize().Height), GL_RGB16F, GL_RGB, GL_FLOAT); //GenerateTexture(&m_BloomTexture, GL_CLAMP_TO_EDGE, GL_LINEAR, glm::vec2(m_Renderer->GetViewPortSize().Width, m_Renderer->GetViewPortSize().Height), GL_RGB16F, GL_RGB, GL_FLOAT); GenerateTexture(&m_BloomTexture, GL_CLAMP_TO_EDGE, GL_LINEAR, glm::vec2(m_Renderer->GetViewportSize().Width, m_Renderer->GetViewportSize().Height), GL_RGB16F, GL_RGB, GL_FLOAT); @@ -173,25 +174,25 @@ void DrawFinalPass::InitializeShaderPrograms() GLERROR("Creating DepthFill program"); } -void DrawFinalPass::Draw(RenderScene& scene) +void DrawFinalPass::Draw(RenderScene& scene, GLuint SSAOTexture) { GLERROR("Pre"); - DrawFinalPassState* state = new DrawFinalPassState(m_FinalPassFrameBuffer.GetHandle()); if (scene.ClearDepth) { - glClear(GL_DEPTH_BUFFER_BIT); + //glClear(GL_DEPTH_BUFFER_BIT); + state->Disable(GL_DEPTH_TEST); + state->DepthMask(GL_FALSE); } //TODO: Do we need check for this or will it be per scene always? glClearStencil(0x00); glClear(GL_STENCIL_BUFFER_BIT); //Fill depth buffer - - + state->StencilMask(0x00); - DrawModelRenderQueues(scene.Jobs.OpaqueObjects, scene); + DrawModelRenderQueues(scene.Jobs.OpaqueObjects, scene, SSAOTexture); GLERROR("OpaqueObjects"); - DrawModelRenderQueues(scene.Jobs.TransparentObjects, scene); + DrawModelRenderQueues(scene.Jobs.TransparentObjects, scene, SSAOTexture); GLERROR("TransparentObjects"); DrawSprites(scene.Jobs.SpriteJob, scene); GLERROR("SpriteJobs"); @@ -206,11 +207,11 @@ void DrawFinalPass::Draw(RenderScene& scene) //Draw Opaque shielded objects state->StencilFunc(GL_NOTEQUAL, 1, 0xFF); state->StencilMask(0x00); - DrawModelRenderQueues(scene.Jobs.OpaqueShieldedObjects, scene); //might need changing + DrawModelRenderQueues(scene.Jobs.OpaqueShieldedObjects, scene, SSAOTexture); //might need changing GLERROR("Shielded Opaque object"); //Draw Transparen Shielded objects - DrawModelRenderQueues(scene.Jobs.TransparentShieldedObjects, scene); //might need changing + DrawModelRenderQueues(scene.Jobs.TransparentShieldedObjects, scene, SSAOTexture); //might need changing GLERROR("Shielded Transparent objects"); GLERROR("END"); @@ -241,14 +242,14 @@ void DrawFinalPass::Draw(RenderScene& scene) DrawShieldToStencilBuffer(scene.Jobs.ShieldObjects, scene); GLERROR("StencilPass"); - glClear(GL_DEPTH_BUFFER_BIT); + //glClear(GL_DEPTH_BUFFER_BIT); stateLowRes->Enable(GL_DEPTH_TEST); stateLowRes->StencilFunc(GL_LEQUAL, 1, 0xFF); stateLowRes->StencilMask(0x00); - DrawModelRenderQueues(scene.Jobs.OpaqueObjects, scene); + DrawModelRenderQueues(scene.Jobs.OpaqueObjects, scene, SSAOTexture); GLERROR("OpaqueObjects"); - DrawModelRenderQueues(scene.Jobs.TransparentObjects, scene); + DrawModelRenderQueues(scene.Jobs.TransparentObjects, scene, SSAOTexture); GLERROR("TransparentObjects"); glViewport(0, 0, m_Renderer->GetViewportSize().Width, m_Renderer->GetViewportSize().Height); glScissor(0, 0, m_Renderer->GetViewportSize().Width, m_Renderer->GetViewportSize().Height); @@ -321,7 +322,7 @@ void DrawFinalPass::GenerateMipMapTexture(GLuint* texture, GLenum wrapping, glm: GLERROR("MipMap Texture initialization failed"); } -void DrawFinalPass::DrawModelRenderQueues(std::list>& jobs, RenderScene& scene) +void DrawFinalPass::DrawModelRenderQueues(std::list>& jobs, RenderScene& scene, GLuint SSAOTexture) { GLuint forwardHandle = m_ForwardPlusProgram->GetHandle(); GLERROR("forwardHandle"); @@ -344,6 +345,9 @@ void DrawFinalPass::DrawModelRenderQueues(std::list>& glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 2, m_LightCullingPass->LightGridSSBO()); glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 4, m_LightCullingPass->LightIndexSSBO()); + glActiveTexture(GL_TEXTURE0); + glBindTexture(GL_TEXTURE_2D, SSAOTexture); + for (auto &job : jobs) { auto explosionEffectJob = std::dynamic_pointer_cast(job); if (explosionEffectJob) { @@ -690,14 +694,14 @@ void DrawFinalPass::DrawSprites(std::list>&jobs, Rend glUniform4fv(glGetUniformLocation(shaderHandle, "FillColor"), 1, glm::value_ptr(spriteJob->FillColor)); glUniform1f(glGetUniformLocation(shaderHandle, "FillPercentage"), spriteJob->FillPercentage); - glActiveTexture(GL_TEXTURE0); + glActiveTexture(GL_TEXTURE1); if (spriteJob->DiffuseTexture != nullptr) { glBindTexture(GL_TEXTURE_2D, spriteJob->DiffuseTexture->m_Texture); } else { glBindTexture(GL_TEXTURE_2D, m_ErrorTexture->m_Texture); } - glActiveTexture(GL_TEXTURE1); + glActiveTexture(GL_TEXTURE2); if (spriteJob->IncandescenceTexture != nullptr) { glBindTexture(GL_TEXTURE_2D, spriteJob->IncandescenceTexture->m_Texture); } else { @@ -807,7 +811,7 @@ void DrawFinalPass::BindExplosionTextures(GLuint shaderHandle, std::shared_ptrDiffuseTexture.size() > 0 && job->DiffuseTexture[0]->Texture != nullptr) { glBindTexture(GL_TEXTURE_2D, job->DiffuseTexture[0]->Texture->m_Texture); glUniform2fv(glGetUniformLocation(shaderHandle, "DiffuseUVRepeat"), 1, glm::value_ptr(job->DiffuseTexture[0]->UVRepeat)); @@ -817,7 +821,7 @@ void DrawFinalPass::BindExplosionTextures(GLuint shaderHandle, std::shared_ptrNormalTexture.size() > 0 && job->NormalTexture[0]->Texture != nullptr) { glBindTexture(GL_TEXTURE_2D, job->NormalTexture[0]->Texture->m_Texture); glUniform2fv(glGetUniformLocation(shaderHandle, "NormalUVRepeat"), 1, glm::value_ptr(job->NormalTexture[0]->UVRepeat)); @@ -827,7 +831,7 @@ void DrawFinalPass::BindExplosionTextures(GLuint shaderHandle, std::shared_ptrSpecularTexture.size() > 0 && job->SpecularTexture[0]->Texture != nullptr) { glBindTexture(GL_TEXTURE_2D, job->SpecularTexture[0]->Texture->m_Texture); glUniform2fv(glGetUniformLocation(shaderHandle, "SpecularUVRepeat"), 1, glm::value_ptr(job->SpecularTexture[0]->UVRepeat)); @@ -837,7 +841,7 @@ void DrawFinalPass::BindExplosionTextures(GLuint shaderHandle, std::shared_ptrIncandescenceTexture.size() > 0 && job->IncandescenceTexture[0]->Texture != nullptr) { glBindTexture(GL_TEXTURE_2D, job->IncandescenceTexture[0]->Texture->m_Texture); glUniform2fv(glGetUniformLocation(shaderHandle, "GlowUVRepeat"), 1, glm::value_ptr(job->IncandescenceTexture[0]->UVRepeat)); @@ -850,7 +854,7 @@ void DrawFinalPass::BindExplosionTextures(GLuint shaderHandle, std::shared_ptrSplatMap->Texture->m_Texture); int texturePosition = GL_TEXTURE1; @@ -925,7 +929,7 @@ void DrawFinalPass::BindModelTextures(GLuint shaderHandle, std::shared_ptrDiffuseTexture.size() > 0 && job->DiffuseTexture[0]->Texture != nullptr) { glBindTexture(GL_TEXTURE_2D, job->DiffuseTexture[0]->Texture->m_Texture); glUniform2fv(glGetUniformLocation(shaderHandle, "DiffuseUVRepeat"), 1, glm::value_ptr(job->DiffuseTexture[0]->UVRepeat)); @@ -935,7 +939,7 @@ void DrawFinalPass::BindModelTextures(GLuint shaderHandle, std::shared_ptrNormalTexture.size() > 0 && job->NormalTexture[0]->Texture != nullptr) { glBindTexture(GL_TEXTURE_2D, job->NormalTexture[0]->Texture->m_Texture); glUniform2fv(glGetUniformLocation(shaderHandle, "NormalUVRepeat"), 1, glm::value_ptr(job->NormalTexture[0]->UVRepeat)); @@ -945,7 +949,7 @@ void DrawFinalPass::BindModelTextures(GLuint shaderHandle, std::shared_ptrSpecularTexture.size() > 0 && job->SpecularTexture[0]->Texture != nullptr) { glBindTexture(GL_TEXTURE_2D, job->SpecularTexture[0]->Texture->m_Texture); glUniform2fv(glGetUniformLocation(shaderHandle, "SpecularUVRepeat"), 1, glm::value_ptr(job->SpecularTexture[0]->UVRepeat)); @@ -955,7 +959,7 @@ void DrawFinalPass::BindModelTextures(GLuint shaderHandle, std::shared_ptrIncandescenceTexture.size() > 0 && job->IncandescenceTexture[0]->Texture != nullptr) { glBindTexture(GL_TEXTURE_2D, job->IncandescenceTexture[0]->Texture->m_Texture); glUniform2fv(glGetUniformLocation(shaderHandle, "GlowUVRepeat"), 1, glm::value_ptr(job->IncandescenceTexture[0]->UVRepeat)); @@ -968,10 +972,10 @@ void DrawFinalPass::BindModelTextures(GLuint shaderHandle, std::shared_ptrSplatMap->Texture->m_Texture); - int texturePosition = GL_TEXTURE1; + int texturePosition = GL_TEXTURE2; //Bind 5 diffuse textures std::string UniformName = "DiffuseUVRepeat"; diff --git a/src/Engine/Rendering/PickingPass.cpp b/src/Engine/Rendering/PickingPass.cpp index 40509d0c..d1ed73dd 100644 --- a/src/Engine/Rendering/PickingPass.cpp +++ b/src/Engine/Rendering/PickingPass.cpp @@ -25,11 +25,20 @@ void PickingPass::InitializeTextures() void PickingPass::InitializeFrameBuffers() { - glGenRenderbuffers(1, &m_DepthBuffer); + /* glGenRenderbuffers(1, &m_DepthBuffer); glBindRenderbuffer(GL_RENDERBUFFER, m_DepthBuffer); - glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT, m_Renderer->GetViewportSize().Width, m_Renderer->GetViewportSize().Height); + glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT, m_Renderer->GetViewportSize().Width, m_Renderer->GetViewportSize().Height);*/ - m_PickingBuffer.AddResource(std::shared_ptr(new RenderBuffer(&m_DepthBuffer, GL_DEPTH_ATTACHMENT))); + glGenTextures(1, &m_DepthBuffer); + + glBindTexture(GL_TEXTURE_2D, m_DepthBuffer); + glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH24_STENCIL8, (int)(m_Renderer->GetViewportSize().Width), (int)(m_Renderer->GetViewportSize().Height), 0, GL_DEPTH_STENCIL, GL_UNSIGNED_INT_24_8, nullptr); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER); + + m_PickingBuffer.AddResource(std::shared_ptr(new Texture2D(&m_DepthBuffer, GL_DEPTH_ATTACHMENT))); m_PickingBuffer.AddResource(std::shared_ptr(new Texture2D(&m_PickingTexture, GL_COLOR_ATTACHMENT0))); m_PickingBuffer.Generate(); } @@ -63,7 +72,9 @@ void PickingPass::Draw(RenderScene& scene) m_PickingProgram->Bind(); if (scene.ClearDepth) { - glClear(GL_DEPTH_BUFFER_BIT); + //glClear(GL_DEPTH_BUFFER_BIT); + state->Disable(GL_DEPTH_TEST); + state->DepthMask(GL_FALSE); } m_Camera = scene.Camera; diff --git a/src/Engine/Rendering/Renderer.cpp b/src/Engine/Rendering/Renderer.cpp index b8665fce..0c668cad 100644 --- a/src/Engine/Rendering/Renderer.cpp +++ b/src/Engine/Rendering/Renderer.cpp @@ -108,7 +108,15 @@ void Renderer::Update(double dt) void Renderer::Draw(RenderFrame& frame) { - ImGui::Combo("Draw textures", &m_DebugTextureToDraw, "Final\0Scene\0Bloom\0SceneLowRes\0BloomLowRes\0Gaussian\0Picking"); + ImGui::Combo("Draw textures", &m_DebugTextureToDraw, "Final\0Scene\0Bloom\0SceneLowRes\0BloomLowRes\0Gaussian\0Picking\0Ambient Occlusion"); + + ImGui::SliderFloat("SSAO sample radius", &m_SSAO_Radius, 0.01f, 5.0f); + ImGui::SliderFloat("SSAO bias", &m_SSAO_Bias, 0.0f, 0.1f); + ImGui::SliderFloat("SSAO contrast", &m_SSAO_Contrast, 0.0f, 10.0f); + ImGui::SliderFloat("SSAO IntensityScale", &m_SSAO_IntensityScale, 0.0f, 10.0f); + ImGui::SliderInt("SSAO Number of Samples", &m_SSAO_NumOfSamples, 2, 100); + ImGui::SliderInt("SSAO Number of Turns", &m_SSAO_NumOfTurns, 0, 50); + m_SSAOPass->Setting(m_SSAO_Radius, m_SSAO_Bias, m_SSAO_Contrast, m_SSAO_IntensityScale, m_SSAO_NumOfSamples, m_SSAO_NumOfTurns); //clear buffer 0 glClearColor(0.f, 0.f, 0.f, 0.f); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); @@ -119,15 +127,21 @@ void Renderer::Draw(RenderFrame& frame) m_DrawFinalPass->ClearBuffer(); m_DrawBloomPass->ClearBuffer(); PerformanceTimer::StopTimer("Renderer-ClearBuffers"); - + for (auto scene : frame.RenderScenes) { + PerformanceTimer::StartTimer("Renderer-Depth"); + m_PickingPass->Draw(*scene); + GLERROR("Drawing pickingpass"); + PerformanceTimer::StopTimer("Renderer-Depth"); + } + PerformanceTimer::StartTimer("AO generation"); + m_SSAOPass->Draw(m_PickingPass->DepthBuffer(), frame.RenderScenes.front()->Camera); + GLuint ao = m_SSAOPass->SSAOTexture(); + PerformanceTimer::StopTimer("AO generation"); for (auto scene : frame.RenderScenes){ - PerformanceTimer::StartTimer("Renderer-Depth"); + PerformanceTimer::StartTimer("Renderer-Drawing PickingPass"); SortRenderJobsByDepth(*scene); GLERROR("SortByDepth"); - PerformanceTimer::StartTimerAndStopPrevious("Renderer-Drawing PickingPass"); - m_PickingPass->Draw(*scene); - GLERROR("Drawing pickingpass"); PerformanceTimer::StartTimerAndStopPrevious("Renderer-Generate Frustrums"); m_LightCullingPass->GenerateNewFrustum(*scene); GLERROR("Generate frustums"); @@ -137,8 +151,8 @@ void Renderer::Draw(RenderFrame& frame) PerformanceTimer::StartTimerAndStopPrevious("Renderer-Light Culling"); m_LightCullingPass->CullLights(*scene); GLERROR("LightCulling"); + m_DrawFinalPass->Draw(*scene, ao); PerformanceTimer::StartTimerAndStopPrevious("Renderer-Draw Geometry+Light"); - m_DrawFinalPass->Draw(*scene); GLERROR("Draw Geometry+Light"); //m_DrawScenePass->Draw(*scene); @@ -147,14 +161,17 @@ void Renderer::Draw(RenderFrame& frame) GLERROR("Draw Text"); PerformanceTimer::StopTimer("Renderer-Draw Text"); } + PerformanceTimer::StartTimer("Renderer-Draw Bloom"); m_DrawBloomPass->Draw(m_DrawFinalPass->BloomTexture()); PerformanceTimer::StopTimer("Renderer-Draw Bloom"); + if (m_DebugTextureToDraw == 0) { PerformanceTimer::StartTimer("Renderer-Color Correction Pass"); m_DrawColorCorrectionPass->Draw(m_DrawFinalPass->SceneTexture(), m_DrawBloomPass->GaussianTexture(), m_DrawFinalPass->SceneTextureLowRes(), m_DrawFinalPass->BloomTextureLowRes(), frame.Gamma, frame.Exposure); PerformanceTimer::StopTimer("Renderer-Color Correction Pass"); } + PerformanceTimer::StartTimer("Renderer-Misc Debug Draws"); if (m_DebugTextureToDraw == 1) { m_DrawScreenQuadPass->Draw(m_DrawFinalPass->SceneTexture()); @@ -174,7 +191,10 @@ void Renderer::Draw(RenderFrame& frame) if (m_DebugTextureToDraw == 6) { m_DrawScreenQuadPass->Draw(m_PickingPass->PickingTexture()); } - PerformanceTimer::StopTimer("Renderer-Misc Debug Draws"); + if (m_DebugTextureToDraw == 7) { + m_DrawScreenQuadPass->Draw(m_SSAOPass->SSAOTexture()); + } + PerformanceTimer::StopTimer("Renderer-Misc Debug Draws"); PerformanceTimer::StartTimer("Renderer-ImGuiRenderPass"); m_ImGuiRenderPass->Draw(); @@ -223,4 +243,5 @@ void Renderer::InitializeRenderPasses() m_DrawScreenQuadPass = new DrawScreenQuadPass(this); m_DrawBloomPass = new DrawBloomPass(this); m_DrawColorCorrectionPass = new DrawColorCorrectionPass(this); + m_SSAOPass = new SSAOPass(this); } diff --git a/src/Engine/Rendering/SSAOPass.cpp b/src/Engine/Rendering/SSAOPass.cpp new file mode 100644 index 00000000..331e040f --- /dev/null +++ b/src/Engine/Rendering/SSAOPass.cpp @@ -0,0 +1,141 @@ +#include "Rendering/SSAOPass.h" + +SSAOPass::SSAOPass(IRenderer* renderer) +{ + m_Renderer = renderer; + + m_ScreenQuad = ResourceManager::Load("Models/Core/ScreenQuad.mesh"); + + InitializeBuffer(); + InitializeShaderProgram(); + Setting(0.1f, 0.012f, 1.0f, 1.0f, 13, 7); + + m_DrawBloomPass = new DrawBloomPass(renderer); +} + +void SSAOPass::InitializeShaderProgram() +{ + m_SSAOProgram = ResourceManager::Load("##SSAOProgram"); + m_SSAOProgram->AddShader(std::shared_ptr(new VertexShader("Shaders/SSAO.vert.glsl"))); + m_SSAOProgram->AddShader(std::shared_ptr(new FragmentShader("Shaders/SSAO.frag.glsl"))); + m_SSAOProgram->Compile(); + m_SSAOProgram->Link(); + + m_SSAOViewSpaceZProgram = ResourceManager::Load("##SSAOViewSpaceZProgram"); + m_SSAOViewSpaceZProgram->AddShader(std::shared_ptr(new VertexShader("Shaders/SSAO.vert.glsl"))); + m_SSAOViewSpaceZProgram->AddShader(std::shared_ptr(new FragmentShader("Shaders/SSAOViewSpaceZ.frag.glsl"))); + m_SSAOViewSpaceZProgram->Compile(); + m_SSAOViewSpaceZProgram->Link(); +} + + +void SSAOPass::InitializeBuffer() +{ + GenerateTexture(&m_SSAOTexture, GL_CLAMP_TO_EDGE, GL_LINEAR, glm::vec2(m_Renderer->GetViewportSize().Width, m_Renderer->GetViewportSize().Height), GL_R8, GL_RED, GL_FLOAT); + + m_SSAOFramBuffer.AddResource(std::shared_ptr(new Texture2D(&m_SSAOTexture, GL_COLOR_ATTACHMENT0))); + m_SSAOFramBuffer.Generate(); + + GenerateTexture(&m_SSAOViewSpaceZTexture, GL_CLAMP_TO_EDGE, GL_LINEAR, glm::vec2(m_Renderer->GetViewportSize().Width, m_Renderer->GetViewportSize().Height), GL_R32F, GL_RED, GL_FLOAT); + + m_SSAOViewSpaceZFramBuffer.AddResource(std::shared_ptr(new Texture2D(&m_SSAOViewSpaceZTexture, GL_COLOR_ATTACHMENT0))); + m_SSAOViewSpaceZFramBuffer.Generate(); +} + +void SSAOPass::ClearBuffer() +{ + m_SSAOFramBuffer.Bind(); + glClearColor(0.f, 0.f, 0.f, 0.f); + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + m_SSAOFramBuffer.Unbind(); + + m_SSAOViewSpaceZFramBuffer.Bind(); + glClearColor(0.f, 0.f, 0.f, 0.f); + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + m_SSAOViewSpaceZFramBuffer.Unbind(); +} + +void SSAOPass::Setting(float radius, float bias, float contrast, float intensityScale, int numOfSamples, int NumOfTurns) { + m_Radius = radius; + m_Bias = bias; + m_Contrast = contrast; + m_IntensityScale = intensityScale; + m_NumOfSamples = numOfSamples; + m_NumOfTurns = NumOfTurns; +} + +void SSAOPass::GenerateTexture(GLuint* texture, GLenum wrapping, GLenum filtering, glm::vec2 dimensions, GLint internalFormat, GLint format, GLenum type) const +{ + glGenTextures(1, texture); + glBindTexture(GL_TEXTURE_2D, *texture); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, wrapping); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, wrapping); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, filtering); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, filtering); + glTexImage2D(GL_TEXTURE_2D, 0, internalFormat, dimensions.x, dimensions.y, 0, format, type, nullptr); + GLERROR("Texture initialization failed"); +} + +void SSAOPass::Draw(GLuint depthBuffer, Camera* camera) +{ + SSAOPassState state; + GLuint viewSpaceZPShaderHandle = m_SSAOViewSpaceZProgram->GetHandle(); + GLuint SSAOShaderHandle = m_SSAOProgram->GetHandle(); + + m_SSAOViewSpaceZFramBuffer.Bind(); + m_SSAOViewSpaceZProgram->Bind(); + + glActiveTexture(GL_TEXTURE0); + glBindTexture(GL_TEXTURE_2D, depthBuffer); + glm::vec3 clipInfo = glm::vec3( + (camera->NearClip() * camera->FarClip()), + (camera->NearClip() - camera->FarClip()), + (camera->FarClip()) + ); + /*glm::vec3 clipInfo = glm::vec3( + (camera->NearClip()), + (-1.0f), + (+1.0f) + );*/ + glUniform3fv(glGetUniformLocation(viewSpaceZPShaderHandle, "ClipInfo"), 1, glm::value_ptr(clipInfo)); + + glBindVertexArray(m_ScreenQuad->VAO); + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_ScreenQuad->ElementBuffer); + glDrawElementsBaseVertex(GL_TRIANGLES, m_ScreenQuad->MaterialGroups()[0].material->EndIndex - m_ScreenQuad->MaterialGroups()[0].material->StartIndex + 1 + , GL_UNSIGNED_INT, 0, m_ScreenQuad->MaterialGroups()[0].material->StartIndex); + + glm::vec4 projInfo = glm::vec4( + ((1.0 - camera->ProjectionMatrix()[0][2]) / camera->ProjectionMatrix()[0][0]), + (-2.0 / (m_Renderer->GetViewportSize().Width * camera->ProjectionMatrix()[0][0])), + ((1.0 + camera->ProjectionMatrix()[1][2]) / camera->ProjectionMatrix()[1][1]), + (-2.0 / (m_Renderer->GetViewportSize().Height * camera->ProjectionMatrix()[1][1])) + ); + + + m_SSAOFramBuffer.Bind(); + m_SSAOProgram->Bind(); + + glActiveTexture(GL_TEXTURE0); + glBindTexture(GL_TEXTURE_2D, m_SSAOViewSpaceZTexture); + + // How many pixel there are in a 1m long object 1m away from the camera + glUniform1f(glGetUniformLocation(SSAOShaderHandle, "uProjScale"), m_Renderer->GetViewportSize().Height / (-2.0f * glm::tan(camera->FOV() * 0.5f))); + + glUniform1f(glGetUniformLocation(SSAOShaderHandle, "uRadius"), m_Radius); + glUniform1f(glGetUniformLocation(SSAOShaderHandle, "uBias"), m_Bias); + glUniform1f(glGetUniformLocation(SSAOShaderHandle, "uContrast"), m_Contrast); + glUniform1f(glGetUniformLocation(SSAOShaderHandle, "uIntensityScale"), m_IntensityScale); + glUniform1i(glGetUniformLocation(SSAOShaderHandle, "uNumOfSamples"), m_NumOfSamples); + glUniform1i(glGetUniformLocation(SSAOShaderHandle, "uNumOfTurns"), m_NumOfTurns);; + + glUniform4fv(glGetUniformLocation(SSAOShaderHandle, "uProjInfo"), 1, glm::value_ptr(projInfo)); + glDrawElementsBaseVertex(GL_TRIANGLES, m_ScreenQuad->MaterialGroups()[0].material->EndIndex - m_ScreenQuad->MaterialGroups()[0].material->StartIndex + 1 + , GL_UNSIGNED_INT, 0, m_ScreenQuad->MaterialGroups()[0].material->StartIndex); + + m_DrawBloomPass->ClearBuffer(); + m_DrawBloomPass->Draw(m_SSAOTexture); +} + +void ComputeAO(GLuint depthBuffer, Camera* camera) { + +} \ No newline at end of file diff --git a/src/Engine/Rendering/SSAOPassState.cpp b/src/Engine/Rendering/SSAOPassState.cpp new file mode 100644 index 00000000..7dd49841 --- /dev/null +++ b/src/Engine/Rendering/SSAOPassState.cpp @@ -0,0 +1,16 @@ +#include "Rendering/SSAOPassState.h" + + +SSAOPassState::SSAOPassState() +{ + //BindFramebuffer(0); + Disable(GL_BLEND); + Disable(GL_DEPTH_TEST); + Disable(GL_CULL_FACE); +} + +SSAOPassState::~SSAOPassState() +{ + +} + diff --git a/src/Engine/Rendering/ShaderProgram.cpp b/src/Engine/Rendering/ShaderProgram.cpp index 9c26c15c..ae536bc0 100644 --- a/src/Engine/Rendering/ShaderProgram.cpp +++ b/src/Engine/Rendering/ShaderProgram.cpp @@ -98,8 +98,7 @@ void ShaderProgram::AddShader(std::shared_ptr shader) void ShaderProgram::Compile() { - if (m_ShaderProgramHandle == 0) - { + if (m_ShaderProgramHandle == 0) { m_ShaderProgramHandle = glCreateProgram(); }