added fog, added possibility to customize imgui depth

This commit is contained in:
Anselme 2017-10-19 22:46:19 +02:00
parent 0ad3a417d8
commit bd27c0d270
9 changed files with 124 additions and 27 deletions

View File

@ -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));

View File

@ -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

View File

@ -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;
}

View File

@ -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),
@ -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,11 +305,8 @@ void DeferredPipeline::renderGL(Scene *scene)
// draw geometry
node->mesh->draw(shader);
}
if(m_debugGuiEnabled)
gui();
// IMGUI PASS
// make sure imgui is rendered even is no 2d meshes exist in the scene
if(!imguiRendered)
m_guiMesh->drawGL();
}
@ -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"))
{

View File

@ -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);

View File

@ -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);
}

View File

@ -66,6 +66,8 @@ class BasicScene : public Scene
protected:
std::vector<Light*> lights; // fast node access for rendering
std::vector<GeometryNode*> geometry;
// this is used when geometrynodes are added AND allocated by the scene (with addMesh(Mesh* m, glm::mat4 transform))
std::vector<GeometryNode*> allocations;
public:
BasicScene() : Scene() {}

View File

@ -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);

View File

@ -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;}