#include "Rendering/SSAOPass.h" SSAOPass::SSAOPass(IRenderer* renderer) { m_Renderer = renderer; m_ScreenQuad = ResourceManager::Load("Models/Core/ScreenQuad.mesh"); InitializeTexture(); 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::InitializeTexture() { 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); 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); } void SSAOPass::InitializeBuffer() { m_SSAOFramBuffer.AddResource(std::shared_ptr(new Texture2D(&m_SSAOTexture, GL_COLOR_ATTACHMENT0))); m_SSAOFramBuffer.Generate(); m_SSAOViewSpaceZFramBuffer.AddResource(std::shared_ptr(new Texture2D(&m_SSAOViewSpaceZTexture, GL_COLOR_ATTACHMENT0))); m_SSAOViewSpaceZFramBuffer.Generate(); } void SSAOPass::ClearBuffer() { m_SSAOFramBuffer.Bind(); glClearColor(1.f, 1.f, 1.f, 1.f); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); m_SSAOFramBuffer.Unbind(); m_SSAOViewSpaceZFramBuffer.Bind(); glClearColor(1.f, 1.f, 1.f, 1.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 SSAOPass::OnWindowResize() { m_DrawBloomPass->OnWindowResize(); InitializeTexture(); m_SSAOFramBuffer.Generate(); m_SSAOViewSpaceZFramBuffer.Generate(); }