Browse Source

shader improvements

Kajetan Johannes Hammerle 4 years ago
parent
commit
c710444575

+ 85 - 74
client/GameClient.cpp

@@ -4,6 +4,7 @@
 #include <unordered_map>
 #include <cmath>
 #include <cstring>
+#include <array>
 
 #include "common/utils/Types.h"
 #include "client/GameClient.h"
@@ -62,6 +63,13 @@ struct Shaders
         postWorld("resources/shader/worldPostVertex.vs", "resources/shader/worldPostFragment.fs"),
         text("resources/shader/textVertex.vs", "resources/shader/textFragment.fs")
     {
+        worldProj.set(11, -1.0f);
+        worldProj.set(14, 1.0f);
+        worldProj.set(15, 0.0f);
+        
+        worldShadowProj.set(11, -1.0f);
+        worldShadowProj.set(14, 1.0f);
+        worldShadowProj.set(15, 0.0f);
     }
     
     Shader world;
@@ -72,37 +80,12 @@ struct Shaders
     Shader text;
     bool once = true;
     
-    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
-    };
+    Matrix worldProj;
+    Matrix worldView;
     
-    float worldShadowProj[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 worldShadowView[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
-    };
+    Matrix worldShadowProj;
+    Matrix worldShadowView;
+    Matrix worldShadowProjView;
     
     bool isValid() const
     {
@@ -115,17 +98,17 @@ struct Shaders
         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);
+        worldProj.set(0, q / aspect);
+        worldProj.set(5, q);
+        worldProj.set(10,(nearClip + farClip) / (nearClip - farClip));
+        worldProj.set(14, (2.0f * nearClip * farClip) / (nearClip - farClip));
         
         if(once)
         {
-            worldShadowProj[0] = q / aspect;
-            worldShadowProj[5] = q;
-            worldShadowProj[10] = (nearClip + farClip) / (nearClip - farClip);
-            worldShadowProj[14] = (2.0f * nearClip * farClip) / (nearClip - farClip);
+            worldShadowProj.set(0, q / aspect);
+            worldShadowProj.set(5, q);
+            worldShadowProj.set(10,(nearClip + farClip) / (nearClip - farClip));
+            worldShadowProj.set(14, (2.0f * nearClip * farClip) / (nearClip - farClip));
         }
     }
 
@@ -136,44 +119,45 @@ struct Shaders
         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);
+        worldView.set(0, right.getX());
+        worldView.set(1, up.getX());
+        worldView.set(2, back.getX());
+        worldView.set(4, right.getY());
+        worldView.set(5, up.getY());
+        worldView.set(6, back.getY());
+        worldView.set(8, right.getZ());
+        worldView.set(9, up.getZ());
+        worldView.set(10, back.getZ());
+        worldView.set(12, right.dotInverse(pos));
+        worldView.set(13, up.dotInverse(pos));
+        worldView.set(14, back.dotInverse(pos));
         
         if(once)
         {
             once = false;
-            worldShadowView[0] = right.getX();
-            worldShadowView[1] = up.getX();
-            worldShadowView[2] = back.getX();
-            worldShadowView[4] = right.getY();
-            worldShadowView[5] = up.getY();
-            worldShadowView[6] = back.getY();
-            worldShadowView[8] = right.getZ();
-            worldShadowView[9] = up.getZ();
-            worldShadowView[10] = back.getZ();
-            worldShadowView[12] = right.dotInverse(pos);
-            worldShadowView[13] = up.dotInverse(pos);
-            worldShadowView[14] = back.dotInverse(pos);
+            worldShadowView.set(0, right.getX());
+            worldShadowView.set(1, up.getX());
+            worldShadowView.set(2, back.getX());
+            worldShadowView.set(4, right.getY());
+            worldShadowView.set(5, up.getY());
+            worldShadowView.set(6, back.getY());
+            worldShadowView.set(8, right.getZ());
+            worldShadowView.set(9, up.getZ());
+            worldShadowView.set(10, back.getZ());
+            worldShadowView.set(12, right.dotInverse(pos));
+            worldShadowView.set(13, up.dotInverse(pos));
+            worldShadowView.set(14, back.dotInverse(pos));
         }
     }
 };
 
 struct Framebuffers
 {
-    Framebuffers(u32 w, u32 h) : world(w, h, Framebuffer::POSITION | 
-        Framebuffer::NORMAL | Framebuffer::COLOR | Framebuffer::RED | Framebuffer::DEPTH24_STENCIL8),
-        ssao(w, h, Framebuffer::RED), ssaoBlur(w, h, Framebuffer::RED),
-        shadow(w, h, Framebuffer::DEPTH24_STENCIL8)
+    Framebuffers(u32 w, u32 h) : 
+        world(w, h, Framebuffer::POSITION | Framebuffer::NORMAL | Framebuffer::COLOR | Framebuffer::RED | Framebuffer::DEPTH24_STENCIL8, 0),
+        ssao(w, h, Framebuffer::RED, 0), 
+        ssaoBlur(w, h, Framebuffer::RED, 0),
+        shadow(w, h, Framebuffer::DEPTH24_STENCIL8, GL_LEQUAL)
     {
     }
     
@@ -328,8 +312,9 @@ static void renderShadow(float lag, Shaders& shaders, InternGame& game, Framebuf
     fb.shadow.bind();
     glEnable(GL_DEPTH_TEST);
     shaders.shadow.use();
-    shaders.shadow.setMatrix("proj", shaders.worldShadowProj);
-    shaders.shadow.setMatrix("view", shaders.worldShadowView);
+    shaders.worldShadowProjView = shaders.worldShadowProj;
+    shaders.worldShadowProjView.mul(shaders.worldShadowView);
+    shaders.shadow.setMatrix("projView", shaders.worldShadowProjView.getValues());
     glEnable(GL_POLYGON_OFFSET_FILL);
     glPolygonOffset(2.0f, 4.0f);
     game.game.renderWorld(lag, game.model, shaders.shadow);
@@ -341,10 +326,15 @@ static void renderWorld(float lag, Shaders& shaders, InternGame& game, Framebuff
     fb.world.bind();
     glEnable(GL_DEPTH_TEST);
     shaders.world.use();
-    shaders.world.setMatrix("projShadow", shaders.worldShadowProj);
-    shaders.world.setMatrix("viewShadow", shaders.worldShadowView);
-    shaders.world.setMatrix("proj", shaders.worldProj);
-    shaders.world.setMatrix("view", shaders.worldView);
+    
+    Matrix rWorldShadowProjView;
+    rWorldShadowProjView.translate(0.5f, 0.5f, 0.5f);
+    rWorldShadowProjView.scale(0.5f, 0.5f, 0.5f);
+    rWorldShadowProjView.mul(shaders.worldShadowProjView);
+    
+    shaders.world.setMatrix("projViewShadow", rWorldShadowProjView.getValues());
+    shaders.world.setMatrix("proj", shaders.worldProj.getValues());
+    shaders.world.setMatrix("view", shaders.worldView.getValues());
     game.model.clear();
     shaders.world.setMatrix("model", game.model.get().getValues());
     fb.shadow.bindDepthTexture(1);
@@ -355,8 +345,13 @@ static void renderSSAO(Shaders& shaders, InternGame& game, Framebuffers& fb)
 {
     // ssao
     shaders.ssao.use();
-    shaders.ssao.setMatrix("view", shaders.worldView);
-    shaders.ssao.setMatrix("proj", shaders.worldProj);
+    
+    Matrix rProj;
+    rProj.translate(0.5f, 0.5f, 0.5f);
+    rProj.scale(0.5f, 0.5f, 0.5f);
+    rProj.mul(shaders.worldProj);
+    
+    shaders.ssao.setMatrix("proj", rProj.getValues());
     shaders.ssao.setInt("width", width);
     shaders.ssao.setInt("height", height);
     fb.world.bindPositionTexture(0);
@@ -385,6 +380,11 @@ static void renderPostWorld(Shaders& shaders, InternGame& game, Framebuffers& fb
     game.rectangle.draw();
 }
 
+static u64 last = 0;
+static u64 sum = 0;
+static u64 tindex = 0;
+static std::array<u64, 128> values;
+
 static void renderTextOverlay(float lag, Shaders& shaders, InternGame& game)
 {
     glDisable(GL_DEPTH_TEST);
@@ -402,12 +402,22 @@ static void renderTextOverlay(float lag, Shaders& shaders, InternGame& game)
     glEnable(GL_BLEND);
     glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
     glBlendEquation(GL_FUNC_ADD);
+    char buffer[50];
+    snprintf(buffer, 50, "FPS: %f", 128000000000.0f / sum);
+    game.fontRenderer.drawString(20, 20, buffer);
     game.game.renderTextOverlay(lag, game.model, shaders.text, game.fontRenderer);
     glDisable(GL_BLEND);
 }
 
 static void renderTick(float lag, Shaders& shaders, InternGame& game, Framebuffers& fb)
 {
+    u64 current = getTimeNanos();
+    sum -= values[tindex];
+    values[tindex] = current - last;
+    sum += values[tindex];
+    last = current;
+    tindex = (tindex + 1) & (127);
+    
     if(resize)
     {
         fb.resize(width, height);
@@ -440,6 +450,7 @@ static void loop()
     }
     InternGame game;
     
+    last = getTimeNanos();
     u64 lastTime = getTimeNanos();
     u64 lag = 0;
     while(!glfwWindowShouldClose(client.window))

+ 5 - 0
client/math/Matrix.cpp

@@ -29,6 +29,11 @@ void Matrix::setToIdentity()
     data[15] = 1.0f;
 }
 
+void Matrix::set(unsigned int index, float f)
+{
+    data[index] = f;
+}
+
 const float* Matrix::getValues() const
 {
     return data;

+ 1 - 0
client/math/Matrix.h

@@ -9,6 +9,7 @@ public:
     Matrix();
     
     void setToIdentity();
+    void set(unsigned int index, float f);
     
     const float* getValues() const;
     

+ 8 - 3
client/rendering/Framebuffer.cpp

@@ -3,7 +3,7 @@
 #include "Framebuffer.h"
 #include "client/Utils.h"
 
-Framebuffer::Framebuffer(u32 width, u32 height, u32 mode) : mode(mode), buffer(0), valid(false)
+Framebuffer::Framebuffer(u32 width, u32 height, u32 mode, int textureCompareFunc) : mode(mode), buffer(0), valid(false)
 {
     glGenFramebuffers(1, &buffer);
     glBindFramebuffer(GL_FRAMEBUFFER, buffer);
@@ -72,10 +72,15 @@ 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_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_MIN_FILTER, GL_LINEAR);
+        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
+        if(textureCompareFunc != 0)
+        {
+            glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE, GL_COMPARE_REF_TO_TEXTURE);
+            glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_FUNC, textureCompareFunc);
+        }
         glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_TEXTURE_2D, textures[4], 0);
     }
     

+ 1 - 1
client/rendering/Framebuffer.h

@@ -15,7 +15,7 @@ public:
     static const u32 RED = 8;
     static const u32 DEPTH24_STENCIL8 = 16;
     
-    Framebuffer(u32 width, u32 height, u32 mode);
+    Framebuffer(u32 width, u32 height, u32 mode, int textureCompareFunc);
     ~Framebuffer();
     
     bool isValid() const;

+ 0 - 2
resources/shader/ssaoFragment.fs

@@ -27,7 +27,6 @@ const vec3 ssaoKernel[64] =
     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;
 
 uniform int width;
 uniform int height;
@@ -46,7 +45,6 @@ void main()
     {
         vec4 projFragPos = proj * vec4(fragPos + ssaoKernel[i] * radius + random, 1.0);
         projFragPos.xyz /= projFragPos.w;
-        projFragPos.xyz = projFragPos.xyz * 0.5 + 0.5;
 
         float depth1 = texture(worldDepthSamp, projFragPos.xy).x;
         float depth2 = projFragPos.z;

+ 2 - 2
resources/shader/worldFragment.fs

@@ -6,7 +6,7 @@ layout (location = 2) out vec4 worldColor;
 layout (location = 3) out float worldShadow;
 
 layout (binding = 0) uniform sampler2D samp;
-layout (binding = 1) uniform sampler2D shadowSamp;
+layout (binding = 1) uniform sampler2DShadow shadowSamp;
 
 uniform mat4 proj;
 uniform mat4 view;
@@ -22,6 +22,6 @@ void main(void)
     worldPosition = varPosition;
     worldNormal = normalize(varNormal);
 
-    worldShadow = float(varShadow.z < texture(shadowSamp, varShadow.xy).x);
+    worldShadow = textureProj(shadowSamp, varShadow);
     worldColor = texture(samp, varTex);
 }

+ 3 - 4
resources/shader/worldShadowVertex.vs

@@ -4,10 +4,9 @@ layout (location = 0) in vec3 position;
 layout (location = 1) in vec2 tex;
 layout (location = 2) in vec3 normal;
 
-uniform mat4 proj;
-uniform mat4 view;
+uniform mat4 projView;
 
 void main(void)
 { 
-    gl_Position = proj * view * vec4(position, 1.0);
-}
+    gl_Position = projView * vec4(position, 1.0);
+}

+ 2 - 3
resources/shader/worldVertex.vs

@@ -10,6 +10,7 @@ uniform mat4 model;
 
 uniform mat4 projShadow;
 uniform mat4 viewShadow;
+uniform mat4 projViewShadow;
 
 out vec3 varPosition;
 out vec2 varTex;
@@ -28,7 +29,5 @@ void main(void)
     varPosition = worldPos.xyz;
     gl_Position = proj * worldPos;
 
-    varShadow = projShadow * viewShadow * vec4(position, 1.0);
-    varShadow /= varShadow.w;
-    varShadow = varShadow * 0.5 + 0.5;
+    varShadow = projViewShadow * vec4(position, 1.0);
 }