From bd27c0d2707d55c4457a9ef283050f767610a49b Mon Sep 17 00:00:00 2001 From: Anselme Date: Thu, 19 Oct 2017 22:46:19 +0200 Subject: [PATCH] added fog, added possibility to customize imgui depth --- shaders/posteffects.frag.glsl | 42 ++++++++++++++++++++++++++ shaders/skybox.frag.glsl | 5 +++ shaders/skybox.vert.glsl | 8 +++-- src/deferredpipeline.cpp | 57 +++++++++++++++++++++++++++++------ src/deferredpipeline.h | 7 +++++ src/guimesh.cpp | 9 +----- src/scene.h | 2 ++ src/skybox.cpp | 13 +++++--- src/skybox.h | 8 +++-- 9 files changed, 124 insertions(+), 27 deletions(-) diff --git a/shaders/posteffects.frag.glsl b/shaders/posteffects.frag.glsl index 5429f81..210bddf 100644 --- a/shaders/posteffects.frag.glsl +++ b/shaders/posteffects.frag.glsl @@ -1,17 +1,59 @@ +// G BUFFER + +uniform sampler2DRect positionBuffer; +// - Albedo + Roughness +uniform sampler2DRect albedoBuffer; +// - Normal buffer +uniform sampler2DRect normalBuffer; +// - Emission + Metallic +uniform sampler2DRect emissionBuffer; + // LIGHT BUFFER uniform sampler2DRect lightBuffer; +// FOG PARAMETERS + +uniform vec3 be; +uniform vec3 bi; +uniform vec3 fogColor; + // OUTPUT LIGHT layout(location = 0)out vec4 outColor; +// FUNCTIONS + +vec3 applyFog( in vec3 rgb, + in float distance) +{ + vec3 extColor = vec3( exp(-distance*be.x), exp(-distance*be.y), exp(-distance*be.z) ); + vec3 insColor = vec3( exp(-distance*bi.x), exp(-distance*bi.y), exp(-distance*bi.z) ); + return rgb*extColor + fogColor*(1.0-insColor); +} + // MAIN PROGRAM void main(void) { ivec2 texCoord = ivec2(gl_FragCoord.xy); vec3 color = texelFetch(lightBuffer, texCoord).xyz; + // gbuffer variables + /* + vec3 ambientColor = texelFetch(emissionBuffer, texCoord).rgb; + vec3 normal = texelFetch(normalBuffer, texCoord).xyz; + vec4 albedoTexel = texelFetch(albedoBuffer, texCoord); + vec3 albedo = albedoTexel.rgb; + float roughness = albedoTexel.a; + vec4 emissionTexel = texelFetch(emissionBuffer, texCoord); + vec3 emission = emissionTexel.rgb; + float metallic = emissionTexel.a; + */ + vec4 fragPos = texelFetch(positionBuffer, texCoord); + + // fog + color = applyFog(color, -fragPos.z); + // HDR tonemapping #ifdef HDR_TONEMAPPING color = color / (color + vec3(1.0)); diff --git a/shaders/skybox.frag.glsl b/shaders/skybox.frag.glsl index ec35fd2..0b7660c 100644 --- a/shaders/skybox.frag.glsl +++ b/shaders/skybox.frag.glsl @@ -11,12 +11,17 @@ layout (location = 3) out vec4 outEmission; in vec3 varTexCoord; +in vec4 posInView; + out vec4 outColor; uniform samplerCube skybox; +uniform float skybox_distance; void main() { + outPosition = posInView; + outPosition.z = -skybox_distance; outAlbedo.rgb = vec3(0., 0., 0.); // black outAlbedo.a = 1.; // full roughness outEmission.a = 0.; // not metallic diff --git a/shaders/skybox.vert.glsl b/shaders/skybox.vert.glsl index 575d693..eee78ec 100644 --- a/shaders/skybox.vert.glsl +++ b/shaders/skybox.vert.glsl @@ -4,10 +4,14 @@ layout(location = 0)in vec3 inPosition; out vec3 varTexCoord; -uniform mat4 MVP; +out vec4 posInView; + +uniform mat4 projectionMatrix; +uniform mat4 modelViewMatrix; void main() { - gl_Position = MVP * vec4(inPosition, 1.0); + posInView = modelViewMatrix * vec4(inPosition, 1); + gl_Position = projectionMatrix * posInView; varTexCoord = inPosition; } diff --git a/src/deferredpipeline.cpp b/src/deferredpipeline.cpp index cee38e9..753dd1c 100644 --- a/src/deferredpipeline.cpp +++ b/src/deferredpipeline.cpp @@ -91,6 +91,10 @@ DeferredPipeline::DeferredPipeline() : m_width(512), m_height(512), m_postEffectsShader(nullptr), + m_imguiDepth(7.5f), + m_fogBe(0.f), + m_fogBi(0.f), + m_fogColor(0.5f), m_depth_stencil_renderBuffer(0), m_gBuffer(nullptr), m_lightingBuffer(nullptr), @@ -128,7 +132,7 @@ DeferredPipeline::DeferredPipeline() : } bool depthCompare(const GeometryNode* firstElem, const GeometryNode* secondElem) { - return firstElem->mesh->getDepth() < secondElem->mesh->getDepth(); + return firstElem->mesh->getDepth() < secondElem->mesh->getDepth(); } void DeferredPipeline::renderGL(Scene *scene) @@ -236,26 +240,58 @@ void DeferredPipeline::renderGL(Scene *scene) // compute fragments SparrowRenderer::drawQuad(); } - m_gBuffer->unbindTextures(); + // POST EFFECTS PASS m_renderTarget->bindFBO(); glDisable(GL_BLEND); glDisable(GL_STENCIL_TEST); glStencilMask(0); - m_lightingBuffer->getTexture(0)->bind(0); + m_lightingBuffer->getTexture(0)->bind(GBuffer::NB_BUFFERS); m_postEffectsShader->bind(); - m_postEffectsShader->bindInteger(m_postEffectsShader->getLocation("lightBuffer"), 0); + + // bind GBuffer + m_postEffectsShader->bindInteger(m_postEffectsShader->getLocation("positionBuffer"), GBuffer::POSITION); + m_postEffectsShader->bindInteger(m_postEffectsShader->getLocation("albedoBuffer"), GBuffer::ALBEDO); + m_postEffectsShader->bindInteger(m_postEffectsShader->getLocation("normalBuffer"), GBuffer::NORMAL); + m_postEffectsShader->bindInteger(m_postEffectsShader->getLocation("emissionBuffer"), GBuffer::EMISSION); + + // bind lighting buffer + m_postEffectsShader->bindInteger(m_postEffectsShader->getLocation("lightBuffer"), GBuffer::NB_BUFFERS); + + // bind fog parameters + m_postEffectsShader->bindVec3(m_postEffectsShader->getLocation("be"), m_fogBe); + m_postEffectsShader->bindVec3(m_postEffectsShader->getLocation("bi"), m_fogBi); + m_postEffectsShader->bindVec3(m_postEffectsShader->getLocation("fogColor"), m_fogColor); + + // compute post effects SparrowRenderer::drawQuad(); + + // unbind m_lightingBuffer->getTexture(0)->unbind(); + m_gBuffer->unbindTextures(); + + // if enabled, update the pipeline debug gui + if(m_debugGuiEnabled) + gui(); // 2D PASS + bool imguiRendered = false; glClear(GL_DEPTH_BUFFER_BIT); glEnable(GL_BLEND); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + glBlendEquation(GL_FUNC_ADD); + glDisable(GL_CULL_FACE); + glDisable(GL_DEPTH_TEST); std::sort(mesh2D.begin(), mesh2D.end(), depthCompare); for(GeometryNode* node : mesh2D) { + if(!imguiRendered && node->mesh->getDepth() > m_imguiDepth) + { + m_guiMesh->drawGL(); + imguiRendered = true; + } + Shader *shader = m_mesh2DShaders[node->mesh->getFlags()]; if(shader == NULL) { @@ -269,12 +305,9 @@ void DeferredPipeline::renderGL(Scene *scene) // draw geometry node->mesh->draw(shader); } - - if(m_debugGuiEnabled) - gui(); - - // IMGUI PASS - m_guiMesh->drawGL(); + // make sure imgui is rendered even is no 2d meshes exist in the scene + if(!imguiRendered) + m_guiMesh->drawGL(); } struct DebugCanvas @@ -331,6 +364,10 @@ void DeferredPipeline::gui() recompilePostEffectsShader(); if(ImGui::Checkbox("HDR tonemapping", &m_hdrTonemappingEnabled)) recompilePostEffectsShader(); + ImGui::SliderFloat("ImGui depth", &m_imguiDepth, 0.f, 30.f); + ImGui::ColorEdit3("Fog Be", glm::value_ptr(m_fogBe)); + ImGui::ColorEdit3("Fog Bi", glm::value_ptr(m_fogBi)); + ImGui::ColorEdit3("Fog Color", glm::value_ptr(m_fogColor)); if(ImGui::Button("Add a debug canvas")) { diff --git a/src/deferredpipeline.h b/src/deferredpipeline.h index 8e93450..ccf9d64 100644 --- a/src/deferredpipeline.h +++ b/src/deferredpipeline.h @@ -53,6 +53,11 @@ class DeferredPipeline : public Pipeline ShaderSource *m_debugShaders; GuiMesh * m_guiMesh; + float m_imguiDepth; + + glm::vec3 m_fogBe; + glm::vec3 m_fogBi; + glm::vec3 m_fogColor; // framebuffers GLuint m_depth_stencil_renderBuffer; @@ -77,6 +82,8 @@ public: void setRenderTarget(const FrameBuffer *fbo) { m_renderTarget = fbo; } void setSkybox(Texture* texture); void refreshScene(Scene *scene); + float getIMGuiDepth() { return m_imguiDepth; } + void setIMGuiDepth(float depth) { m_imguiDepth = depth; } virtual void renderGL(Scene *scene); virtual void resizeGL(int w, int h); diff --git a/src/guimesh.cpp b/src/guimesh.cpp index d865bd9..29fdcdc 100644 --- a/src/guimesh.cpp +++ b/src/guimesh.cpp @@ -93,12 +93,7 @@ void GuiMesh::drawGL() return; draw_data->ScaleClipRects(io.DisplayFramebufferScale); - // Setup render state: alpha-blending enabled, no face culling, no depth testing, scissor enabled - glEnable(GL_BLEND); - glBlendEquation(GL_FUNC_ADD); - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - glDisable(GL_CULL_FACE); - glDisable(GL_DEPTH_TEST); + // Setup render state: scissor enabled glEnable(GL_SCISSOR_TEST); glActiveTexture(GL_TEXTURE0); @@ -144,8 +139,6 @@ void GuiMesh::drawGL() } } - glDisable(GL_BLEND); - glEnable(GL_DEPTH_TEST); glDisable(GL_SCISSOR_TEST); } diff --git a/src/scene.h b/src/scene.h index 92e69ef..8b9f806 100644 --- a/src/scene.h +++ b/src/scene.h @@ -66,6 +66,8 @@ class BasicScene : public Scene protected: std::vector lights; // fast node access for rendering std::vector geometry; + + // this is used when geometrynodes are added AND allocated by the scene (with addMesh(Mesh* m, glm::mat4 transform)) std::vector allocations; public: BasicScene() : Scene() {} diff --git a/src/skybox.cpp b/src/skybox.cpp index 6039b75..ab0dfe9 100644 --- a/src/skybox.cpp +++ b/src/skybox.cpp @@ -12,7 +12,8 @@ RESOURCE_PACK(shaders) -Skybox::Skybox(Texture* myCubeMap) +Skybox::Skybox(Texture* myCubeMap, float distance) : + m_distance(distance) { cubeMap = myCubeMap; @@ -32,7 +33,9 @@ Skybox::Skybox(Texture* myCubeMap) std::string vertSource = shaderMap["shaders/skybox.vert.glsl"]; std::string fragSource = shaderMap["shaders/skybox.frag.glsl"]; shader = new Shader(vertSource, fragSource); - mvpLocation = shader->getLocation("MVP"); + viewLocation = shader->getLocation("modelViewMatrix"); + projectionLocation = shader->getLocation("projectionMatrix"); + skyboxDistanceLocation = shader->getLocation("skybox_distance"); cubemapLocation = shader->getLocation("skybox"); glBindVertexArray(0); @@ -46,11 +49,11 @@ Skybox::~Skybox() void Skybox::renderGL(Camera* myCamera) { - glm::mat4 viewMatrix = glm::mat4(glm::mat3(myCamera->getViewMatrix())); - shader->bind(); - shader->bindMat4(mvpLocation, myCamera->getProjectionMatrix() * viewMatrix); + shader->bindMat4(viewLocation, glm::mat4(glm::mat3(myCamera->getViewMatrix()))); + shader->bindMat4(projectionLocation, myCamera->getProjectionMatrix()); shader->bindInteger(cubemapLocation, 0); + shader->bindFloat(skyboxDistanceLocation, m_distance); cubeMap->bind(0); glBindVertexArray(vao); diff --git a/src/skybox.h b/src/skybox.h index c773f29..9d73897 100644 --- a/src/skybox.h +++ b/src/skybox.h @@ -16,15 +16,19 @@ class Skybox int width; int height; + float m_distance; + GLuint vao; GLuint vbos[2]; - GLuint mvpLocation; + GLuint viewLocation; + GLuint projectionLocation; + GLuint skyboxDistanceLocation; GLuint cubemapLocation; Shader* shader; Texture* cubeMap; public: - Skybox(Texture* myCubeMap); + Skybox(Texture* myCubeMap, float distance = 100.f); ~Skybox(); void renderGL(Camera* myCamera); void resizeGL(int w, int h) {width = w; height = h;}