Browse Source

ssao cleanup

Kajetan Johannes Hammerle 2 years ago
parent
commit
58019f2b9c

+ 105 - 71
client/GameClient.cpp

@@ -3,6 +3,7 @@
 #include <GLFW/glfw3.h>
 #include <unordered_map>
 #include <cmath>
+#include <cstring>
 
 #include "common/utils/Types.h"
 #include "client/GameClient.h"
@@ -56,6 +57,7 @@ struct Shaders
         world("resources/shader/worldVertex.vs", "resources/shader/worldFragment.fs"),
         ssao("resources/shader/ssaoVertex.vs", "resources/shader/ssaoFragment.fs"),
         ssaoBlur("resources/shader/ssaoBlurVertex.vs", "resources/shader/ssaoBlurFragment.fs"),
+        postWorld("resources/shader/worldPostVertex.vs", "resources/shader/worldPostFragment.fs"),
         text("resources/shader/textVertex.vs", "resources/shader/textFragment.fs")
     {
     }
@@ -63,11 +65,60 @@ struct Shaders
     Shader world;
     Shader ssao;
     Shader ssaoBlur;
+    Shader postWorld;
     Shader text;
     
+    float worldProj[16] = 
+    {
+        1.0f, 0.0f, 0.0f, 0.0f,
+        0.0f, 1.0f, 0.0f, 0.0f,
+        0.0f, 0.0f, 1.0f, -1.0f,
+        0.0f, 0.0f, 1.0, 0.0f
+    };
+    
+    float worldView[16]= 
+    {
+        1.0f, 0.0f, 0.0f, 0.0f,
+        0.0f, 1.0f, 0.0f, 0.0f,
+        0.0f, 0.0f, 1.0f, 0.0f,
+        0.0f, 0.0f, 0.0f, 1.0f
+    };
+    
     bool isValid() const
     {
-        return world.isValid() && ssao.isValid() && ssaoBlur.isValid() && text.isValid();
+        return world.isValid() && ssao.isValid() && ssaoBlur.isValid() && postWorld.isValid() && text.isValid();
+    }
+    
+    void updateWorldProjection()
+    {
+        float tan = tanf((0.5f * fovY) * M_PI / 180.0f);
+        float q = 1.0f / tan;
+        float aspect = (float) width / height;
+        worldProj[0] = q / aspect;
+        worldProj[5] = q;
+        worldProj[10] = (nearClip + farClip) / (nearClip - farClip);
+        worldProj[14] = (2.0f * nearClip * farClip) / (nearClip - farClip);
+    }
+
+    void updateWorldView(float lag, Camera& cam)
+    {
+        cam.update(lag);
+        const Vector right = cam.getRight();
+        const Vector up = cam.getUp();
+        const Vector back = cam.getBack();
+        const Vector pos = cam.getPosition();
+        worldView[0] = right.getX();
+        worldView[1] = up.getX();
+        worldView[2] = back.getX();
+        worldView[4] = right.getY();
+        worldView[5] = up.getY();
+        worldView[6] = back.getY();
+        worldView[8] = right.getZ();
+        worldView[9] = up.getZ();
+        worldView[10] = back.getZ();
+        worldView[12] = right.dotInverse(pos);
+        worldView[13] = up.dotInverse(pos);
+        worldView[14] = back.dotInverse(pos);
     }
 };
 
@@ -100,6 +151,13 @@ struct InternGame
 {
     InternGame() : ssaoNoise(4, 4)
     {
+        rectangle.add({-1, -1, 0, 0, 0, 0, 0, 0});
+        rectangle.add({ 1,  1, 0, 1, 1, 0, 0, 0});
+        rectangle.add({-1,  1, 0, 0, 1, 0, 0, 0});
+        rectangle.add({-1, -1, 0, 0, 0, 0, 0, 0});
+        rectangle.add({ 1, -1, 0, 1, 0, 0, 0, 0});
+        rectangle.add({ 1,  1, 0, 1, 1, 0, 0, 0});
+        rectangle.build();
     }
     
     Game game;
@@ -107,6 +165,7 @@ struct InternGame
     MatrixStack model;
     FontRenderer fontRenderer;
     NoiseTexture ssaoNoise;
+    Mesh rectangle;
 };
 
 static u64 getTimeNanos()
@@ -211,48 +270,55 @@ static void tick(InternGame& game)
     mButtons.postTick();
 }
 
-static void renderWorld(float lag, Shaders& shaders, InternGame& game)
+static void renderWorld(float lag, Shaders& shaders, InternGame& game, Framebuffers& fb)
 {
+    fb.worldBuffer.bind();
     glEnable(GL_DEPTH_TEST);
-    // use world program
     shaders.world.use();
-    // send projection matrix
-    float tan = tanf((0.5f * fovY) * M_PI / 180.0f);
-    float q = 1.0f / tan;
-    float aspect = (float) width / height;
-    float proj[] = 
-    {
-        q / aspect, 0.0f, 0.0f, 0.0f,
-        0.0f, q, 0.0f, 0.0f,
-        0.0f, 0.0f, (nearClip + farClip) / (nearClip - farClip), -1.0f,
-        0.0f, 0.0f, (2.0f * nearClip * farClip) / (nearClip - farClip), 0.0f
-    };
-    shaders.world.setMatrix("proj", proj);
-    // send view matrix
-    game.cam.update(lag);
-    const Vector right = game.cam.getRight();
-    const Vector up = game.cam.getUp();
-    const Vector back = game.cam.getBack();
-    const Vector pos = game.cam.getPosition();
-    float view[] = 
-    {
-        right.getX(), up.getX(), back.getX(), 0.0f,
-        right.getY(), up.getY(), back.getY(), 0.0f,
-        right.getZ(), up.getZ(), back.getZ(), 0.0f,
-        right.dotInverse(pos), up.dotInverse(pos), back.dotInverse(pos), 1.0f
-    };
-    shaders.world.setMatrix("view", view);
-    // clear and send model matrix
+    shaders.world.setMatrix("proj", shaders.worldProj);
+    shaders.world.setMatrix("view", shaders.worldView);
     game.model.clear();
     shaders.world.setMatrix("model", game.model.get().getValues());
-    // call high level world renderer
     game.game.renderWorld(lag, game.model, shaders.world);
+}
 
+static void renderSSAO(Shaders& shaders, InternGame& game, Framebuffers& fb)
+{
+    // ssao
     shaders.ssao.use();
-    shaders.ssao.setMatrix("view", view);
-    shaders.ssao.setMatrix("proj", proj);
+    shaders.ssao.setMatrix("view", shaders.worldView);
+    shaders.ssao.setMatrix("proj", shaders.worldProj);
     shaders.ssao.setInt("width", width);
     shaders.ssao.setInt("height", height);
+    fb.worldBuffer.bindPositionTexture(0);
+    fb.worldBuffer.bindNormalTexture(1);
+    fb.worldBuffer.bindColorTexture(2);
+    fb.worldBuffer.bindDepthTexture(3);
+    game.ssaoNoise.bind(4);
+    fb.ssaoBuffer.bind();
+    game.rectangle.draw();
+    // ssao blur
+    shaders.ssaoBlur.use();
+    fb.ssaoBuffer.bindRedTexture(0);
+    fb.worldBuffer.bindColorTexture(1);
+    fb.ssaoBlurBuffer.bind();
+    game.rectangle.draw();
+}
+
+static void renderPostWorld(Shaders& shaders, InternGame& game, Framebuffers& fb)
+{
+    glBindFramebuffer(GL_FRAMEBUFFER, 0);
+    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
+    fb.worldBuffer.bindColorTexture(0);
+    fb.ssaoBlurBuffer.bindRedTexture(1);
+    shaders.postWorld.use();
+    //glDisable(GL_CULL_FACE);
+    glDisable(GL_DEPTH_TEST);
+    glEnable(GL_BLEND);
+    glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+    glBlendEquation(GL_FUNC_ADD);
+    game.rectangle.draw();
+    glDisable(GL_BLEND);
 }
 
 /*static void renderTextOverlay(float lag, Shaders& shaders, InternGame& game)
@@ -283,8 +349,12 @@ static void renderTick(float lag, Shaders& shaders, InternGame& game, Framebuffe
         fb.resize(width, height);
         resize = false;
     }
-    fb.worldBuffer.bind();
-    renderWorld(lag, shaders, game);
+    shaders.updateWorldProjection();
+    shaders.updateWorldView(lag, game.cam);
+    
+    renderWorld(lag, shaders, game, fb);
+    renderSSAO(shaders, game, fb);
+    renderPostWorld(shaders, game, fb);
 }
 
 static void loop()
@@ -301,47 +371,11 @@ static void loop()
     }
     InternGame game;
     
-    Shader sh("resources/shader/test2Vertex.vs", "resources/shader/test2Fragment.fs");
-    Mesh m;
-    m.add({-1, -1, 0, 0, 0, 0, 0, 0});
-    m.add({ 1,  1, 0, 1, 1, 0, 0, 0});
-    m.add({-1,  1, 0, 0, 1, 0, 0, 0});
-    m.add({-1, -1, 0, 0, 0, 0, 0, 0});
-    m.add({ 1, -1, 0, 1, 0, 0, 0, 0});
-    m.add({ 1,  1, 0, 1, 1, 0, 0, 0});
-    m.build();
-    
     u64 lastTime = getTimeNanos();
     u64 lag = 0;
     while(!glfwWindowShouldClose(client.window))
     {
         renderTick(lag * lagFactor, shaders, game, fb);
-        
-        fb.worldBuffer.bindPositionTexture(0);
-        fb.worldBuffer.bindNormalTexture(1);
-        fb.worldBuffer.bindColorTexture(2);
-        fb.worldBuffer.bindDepthTexture(3);
-        game.ssaoNoise.bind(4);
-        fb.ssaoBuffer.bind();
-        m.draw();
-        
-        shaders.ssaoBlur.use();
-        fb.ssaoBuffer.bindRedTexture(0);
-        fb.worldBuffer.bindColorTexture(1);
-        fb.ssaoBlurBuffer.bind();
-        m.draw();
-
-        glBindFramebuffer(GL_FRAMEBUFFER, 0);
-        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
-        fb.ssaoBlurBuffer.bindRedTexture(1);
-        sh.use();
-        //glDisable(GL_CULL_FACE);
-        glDisable(GL_DEPTH_TEST);
-        glEnable(GL_BLEND);
-        glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
-        glBlendEquation(GL_FUNC_ADD);
-        m.draw();
-        glDisable(GL_BLEND);
         glfwSwapBuffers(client.window);
         
         u64 newTime = getTimeNanos();

+ 2 - 2
client/rendering/Framebuffer.cpp

@@ -71,12 +71,12 @@ Framebuffer::Framebuffer(u32 width, u32 height, u32 mode) : mode(mode), buffer(0
     {
         glGenTextures(1, &textures[4]);
         glBindTexture(GL_TEXTURE_2D, textures[4]);
-        glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH24_STENCIL8, width, height, 0, GL_DEPTH_STENCIL, GL_UNSIGNED_INT_24_8, nullptr);
+        glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_STENCIL, width, height, 0, GL_DEPTH_STENCIL, GL_UNSIGNED_INT_24_8, nullptr);
         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_DEPTH_STENCIL_ATTACHMENT, GL_TEXTURE_2D, textures[4], 0); 
+        glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_TEXTURE_2D, textures[4], 0);
     }
     
     glDrawBuffers(counter, attachments);   

+ 3 - 3
client/rendering/Mesh.cpp

@@ -8,13 +8,13 @@ Mesh::Mesh() : vba(0), vbo(0)
     glGenBuffers(1, &vbo);
     glBindBuffer(GL_ARRAY_BUFFER, vbo);
 
-    glVertexAttribPointer(0, 3, GL_FLOAT, false, sizeof(VertexData), (GLvoid*) (sizeof(float) * 0));
+    glVertexAttribPointer(0, 3, GL_FLOAT, false, sizeof(VertexData), static_cast<GLfloat*>(0));
     glEnableVertexAttribArray(0);
 
-    glVertexAttribPointer(1, 2, GL_FLOAT, false, sizeof(VertexData), (GLvoid*) (sizeof(float) * 3));
+    glVertexAttribPointer(1, 2, GL_FLOAT, false, sizeof(VertexData), static_cast<GLfloat*>(0) + 3);
     glEnableVertexAttribArray(1);  
     
-    glVertexAttribPointer(2, 3, GL_FLOAT, false, sizeof(VertexData), (GLvoid*) (sizeof(float) * 5));
+    glVertexAttribPointer(2, 3, GL_FLOAT, false, sizeof(VertexData), static_cast<GLfloat*>(0) + 5);
     glEnableVertexAttribArray(2);
 }
 

+ 1 - 0
client/rendering/NoiseTexture.cpp

@@ -1,6 +1,7 @@
 #include <png.h>
 #include <vector>
 #include <cstdlib>
+#include <iostream>
 
 #include "client/rendering/NoiseTexture.h"
 

+ 2 - 3
resources/shader/ssaoBlurFragment.fs

@@ -20,6 +20,5 @@ void main()
         }
     }
     result /= (radius * radius * 4);
-    color = result * texture(test, varTex).r;
-    //color = texture(ssaoSamp, varTex).r;
-}  
+    color = result;
+}  

+ 21 - 13
resources/shader/ssaoFragment.fs

@@ -6,17 +6,25 @@ layout (binding = 2) uniform sampler2D worldColorSamp;
 layout (binding = 3) uniform sampler2D worldDepthSamp;
 layout (binding = 4) uniform sampler2D ssaoNoise;
 
-const int numberOfSamples = 32;
-const vec3 ssaoKernel[32] =
+const int numberOfSamples = 64;
+const vec3 ssaoKernel[64] =
 {
-    vec3( 0.001,  0.000, -0.000), vec3(-0.002,  0.002, -0.003), vec3( 0.004, -0.007,  0.002), vec3(-0.002,  0.012,  0.010), 
-    vec3(-0.012,  0.018, -0.011), vec3(-0.013,  0.023, -0.023), vec3(-0.005, -0.021,  0.043), vec3( 0.034, -0.039,  0.034), 
-    vec3(-0.063, -0.040,  0.027), vec3( 0.095, -0.025, -0.001), vec3( 0.048, -0.089,  0.062), vec3(-0.084,  0.041, -0.105), 
-    vec3(-0.148, -0.047, -0.056), vec3(-0.039,  0.026, -0.186), vec3(-0.161,  0.065, -0.135), vec3(-0.203,  0.123, -0.079), 
-    vec3( 0.216,  0.091, -0.157), vec3( 0.066,  0.305, -0.051), vec3(-0.084, -0.332,  0.083), vec3(-0.050,  0.351, -0.165), 
-    vec3(-0.330,  0.127, -0.245), vec3(-0.020,  0.319,  0.348), vec3(-0.396,  0.281, -0.178), vec3(-0.376, -0.413, -0.069), 
-    vec3( 0.510,  0.153, -0.298), vec3(-0.451, -0.476, -0.074), vec3(-0.596, -0.302,  0.245), vec3( 0.311, -0.490, -0.499), 
-    vec3(-0.439,  0.464,  0.517), vec3( 0.397, -0.557,  0.551), vec3( 0.632, -0.677,  0.151), vec3( 0.574, -0.246,  0.781)
+    vec3( 0.009,  0.006, -0.007), vec3( 0.008, -0.003,  0.014), vec3( 0.004, -0.005, -0.019), vec3( 0.016, -0.012, -0.014), 
+    vec3(-0.022, -0.018, -0.007), vec3(-0.018, -0.028, -0.006), vec3( 0.023, -0.028,  0.016), vec3( 0.010, -0.044,  0.000), 
+    vec3( 0.037, -0.035,  0.007), vec3( 0.028,  0.015, -0.048), vec3( 0.030, -0.023,  0.053), vec3(-0.003,  0.042,  0.059), 
+    vec3( 0.077, -0.020, -0.010), vec3( 0.029, -0.053,  0.064), vec3( 0.043,  0.058, -0.064), vec3( 0.102,  0.004,  0.028), 
+    vec3(-0.014, -0.110,  0.029), vec3(-0.019,  0.056, -0.110), vec3(-0.094,  0.019, -0.095), vec3(-0.092,  0.030, -0.108), 
+    vec3(-0.072, -0.120,  0.070), vec3(-0.071,  0.091, -0.121), vec3(-0.096,  0.148, -0.033), vec3(-0.080,  0.160, -0.068), 
+    vec3(-0.037,  0.189, -0.066), vec3( 0.024, -0.038, -0.212), vec3(-0.228, -0.018,  0.021), vec3(-0.169,  0.175,  0.007), 
+    vec3( 0.064, -0.150,  0.200), vec3(-0.017, -0.156, -0.223), vec3(-0.092,  0.240,  0.128), vec3(-0.264, -0.140,  0.044), 
+    vec3(-0.063, -0.311, -0.024), vec3(-0.232, -0.199,  0.136), vec3(-0.333, -0.005,  0.111), vec3( 0.245, -0.255,  0.099), 
+    vec3( 0.214,  0.198, -0.251), vec3( 0.192, -0.325,  0.139), vec3(-0.270,  0.294, -0.131), vec3( 0.303, -0.281, -0.147), 
+    vec3(-0.140, -0.275,  0.338), vec3( 0.387, -0.147,  0.237), vec3( 0.380, -0.260,  0.185), vec3(-0.172,  0.292, -0.390), 
+    vec3( 0.307, -0.081, -0.433), vec3( 0.065, -0.492,  0.256), vec3( 0.224,  0.274, -0.458), vec3( 0.131, -0.370, -0.455), 
+    vec3( 0.113, -0.508, -0.341), vec3(-0.012,  0.573,  0.295), vec3( 0.028, -0.417, -0.521), vec3(-0.555,  0.409, -0.037), 
+    vec3(-0.372,  0.605,  0.075), vec3( 0.352, -0.567, -0.316), vec3( 0.507,  0.558,  0.118), vec3( 0.460,  0.548,  0.329), 
+    vec3(-0.414, -0.391,  0.580), vec3( 0.792,  0.248, -0.122), vec3( 0.207, -0.654, -0.526), vec3( 0.223, -0.713, -0.485), 
+    vec3(-0.333, -0.446, -0.729), vec3( 0.757,  0.249,  0.506), vec3(-0.896, -0.145, -0.349), vec3(-0.125, -0.870, -0.476)
 };
 uniform mat4 proj;
 uniform mat4 view;
@@ -31,7 +39,7 @@ out float color;
 void main()
 {     
     vec3 fragPos = texture(worldPositionSamp, varTex).xyz;
-    vec3 random = texture(ssaoNoise, varTex * vec2(width * 0.25, height * 0.25)).xyz * radius * 0.5; 
+    vec3 random = texture(ssaoNoise, varTex * vec2(width * 0.25, height * 0.25)).xyz * radius * 0.25; 
 
     float occlusion = 0.0;
     for(int i = 0; i < numberOfSamples; i++)
@@ -44,7 +52,7 @@ void main()
         float depth2 = projFragPos.z;
 
         float rangeCheck = float(abs(depth2 - depth1) < radius);
-        occlusion += float(depth2 > depth1) * rangeCheck;
+        occlusion += float(depth2 >= depth1) * rangeCheck;
     }
     color = 1 - occlusion / numberOfSamples;
-} 
+} 

+ 0 - 13
resources/shader/test2Fragment.fs

@@ -1,13 +0,0 @@
-#version 430
-
-layout (binding = 1) uniform sampler2D samp;
-
-in vec2 varTex;
-
-out vec4 color;
-
-void main()
-{
-    float f = texture(samp, varTex).x;
-    color = vec4(f, f, f, 1.0);
-}  

+ 0 - 13
resources/shader/test2Vertex.vs

@@ -1,13 +0,0 @@
-#version 430
-
-layout (location = 0) in vec3 position;
-layout (location = 1) in vec2 tex;
-layout (location = 2) in vec3 normals;
-
-out vec2 varTex;
-
-void main(void)
-{ 
-    varTex = tex;
-    gl_Position = vec4(position, 1.0);
-}

+ 0 - 11
resources/shader/testFragment.fs

@@ -1,11 +0,0 @@
-#version 430
-
-layout (binding = 0) uniform sampler2D samp;
-
-in vec2 varTex;
-out vec4 color;
-
-void main(void)
-{
-    color = texture(samp, varTex);
-}

+ 0 - 16
resources/shader/testVertex.vs

@@ -1,16 +0,0 @@
-#version 430
-
-layout (location = 0) in vec3 position;
-layout (location = 1) in vec2 tex;
-layout (location = 2) in vec3 normals;
-
-uniform mat4 proj;
-uniform mat4 view;
-
-out vec2 varTex;
-
-void main(void)
-{
-    gl_Position = proj * view * vec4(position, 1.0);
-    varTex = tex;
-}

+ 5 - 10
resources/shader/worldPostFragment.fs

@@ -1,18 +1,13 @@
 #version 430
 
-layout (binding = 1) uniform sampler2D worldPositionSamp;
-layout (binding = 2) uniform sampler2D worldNormalSamp;
-layout (binding = 3) uniform sampler2D worldColorSamp;
-layout (binding = 4) uniform sampler2D worldDepthSamp;
-layout (binding = 5) uniform sampler2D noiseSamp;
-layout (binding = 6) uniform sampler2D ssaoSamp;
-layout (binding = 7) uniform sampler2D ssaoBlurSamp;
+layout (binding = 0) uniform sampler2D colorSamp;
+layout (binding = 1) uniform sampler2D ssaoSamp;
+
+in vec2 varTex;
 
-in vec2 varTextureCoord;
 out vec4 color;
 
 void main()
 {
-    float ssaoBlur = texture(ssaoBlurSamp, varTextureCoord).r;
-    color = vec4(texture(worldColorSamp, varTextureCoord).xyz * ssaoBlur, 1);
+    color = vec4(texture(colorSamp, varTex).xyz * (texture(ssaoSamp, varTex).r + 0.5), 1.0);
 }  

+ 4 - 5
resources/shader/worldPostVertex.vs

@@ -1,14 +1,13 @@
 #version 430
 
 layout (location = 0) in vec3 position;
-layout (location = 1) in vec4 color;
-layout (location = 2) in vec2 textureCoord;
-layout (location = 3) in vec3 normal;
+layout (location = 1) in vec2 tex;
+layout (location = 2) in vec3 normals;
 
-out vec2 varTextureCoord;
+out vec2 varTex;
 
 void main(void)
 { 
+    varTex = tex;
     gl_Position = vec4(position, 1.0);
-    varTextureCoord = textureCoord;
 }