Browse Source

shadow experiments

Kajetan Johannes Hammerle 4 years ago
parent
commit
b8262b7356

+ 38 - 37
client/Game.cpp

@@ -23,59 +23,60 @@ Game::Game() : lengthAngle(0.0f), widthAngle(0.0f), texture("resources/textures.
 
 void Game::addCube(float x, float y, float z)
 {
+    const float ERROR = 1.0f / 1024.0f;
     // bottom
-    m.add({x, y, z, 0.125f, 0.0f, 1, 0, 0});
-    m.add({x + 1, y, z, 0.1875f, 0.0f, 1, 0, 0});
-    m.add({x, y, z + 1, 0.125f, 0.0625f, 1, 0, 0});
+    m.add({x - ERROR, y - ERROR, z - ERROR, 0.125f, 0.0f, 0, -1, 0});
+    m.add({x + 1 + ERROR, y - ERROR, z - ERROR, 0.1875f, 0.0f, 0, -1, 0});
+    m.add({x - ERROR, y - ERROR, z + 1 + ERROR, 0.125f, 0.0625f, 0, -1, 0});
     
-    m.add({x + 1, y, z, 0.1875f, 0.0f, 1, 0, 0});
-    m.add({x + 1, y, z + 1, 0.1875f, 0.0625f, 1, 0, 0});
-    m.add({x, y, z + 1, 0.125f, 0.0625f, 1, 0, 0});
+    m.add({x + 1 + ERROR, y - ERROR, z - ERROR, 0.1875f, 0.0f, 0, -1, 0});
+    m.add({x + 1 + ERROR, y - ERROR, z + 1 + ERROR, 0.1875f, 0.0625f, 0, -1, 0});
+    m.add({x - ERROR, y - ERROR, z + 1 + ERROR, 0.125f, 0.0625f, 0, -1, 0});
     
     // top
-    m.add({x, y + 1, z, 0.25f, 0.0f, 1, 0, 0});
-    m.add({x, y + 1, z + 1, 0.25f, 0.0625f, 1, 0, 0});
-    m.add({x + 1, y + 1, z, 0.3125f, 0.0f, 1, 0, 0});
+    m.add({x - ERROR, y + 1 + ERROR, z - ERROR, 0.25f, 0.0f, 0, 1, 0});
+    m.add({x - ERROR, y + 1 + ERROR, z + 1 + ERROR, 0.25f, 0.0625f, 0, 1, 0});
+    m.add({x + 1 + ERROR, y + 1 + ERROR, z - ERROR, 0.3125f, 0.0f, 0, 1, 0});
     
-    m.add({x + 1, y + 1, z, 0.3125f, 0.0f, 1, 0, 0});
-    m.add({x, y + 1, z + 1, 0.25f, 0.0625f, 1, 0, 0});
-    m.add({x + 1, y + 1, z + 1, 0.3125f, 0.0625f, 1, 0, 0});
+    m.add({x + 1 + ERROR, y + 1 + ERROR, z - ERROR, 0.3125f, 0.0f, 0, 1, 0});
+    m.add({x - ERROR, y + 1 + ERROR, z + 1 + ERROR, 0.25f, 0.0625f, 0, 1, 0});
+    m.add({x + 1 + ERROR, y + 1 + ERROR, z + 1 + ERROR, 0.3125f, 0.0625f, 0, 1, 0});
     
     // left
-    m.add({x, y, z, 0.1875f, 0.0625f, 1, 0, 0});
-    m.add({x, y, z + 1, 0.25f, 0.0625f, 1, 0, 0});
-    m.add({x, y + 1, z, 0.1875f, 0.0f, 1, 0, 0});
+    m.add({x - ERROR, y - ERROR, z - ERROR, 0.1875f, 0.0625f, -1, 0, 0});
+    m.add({x - ERROR, y - ERROR, z + 1 + ERROR, 0.25f, 0.0625f, -1, 0, 0});
+    m.add({x - ERROR, y + 1 + ERROR, z - ERROR, 0.1875f, 0.0f, -1, 0, 0});
     
-    m.add({x, y, z + 1, 0.25f, 0.0625f, 1, 0, 0});
-    m.add({x, y + 1, z + 1, 0.25f, 0.0f, 1, 0, 0});
-    m.add({x, y + 1, z, 0.1875f, 0.0f, 1, 0, 0});
+    m.add({x - ERROR, y - ERROR, z + 1 + ERROR, 0.25f, 0.0625f, -1, 0, 0});
+    m.add({x - ERROR, y + 1 + ERROR, z + 1 + ERROR, 0.25f, 0.0f, -1, 0, 0});
+    m.add({x - ERROR, y + 1 + ERROR, z - ERROR, 0.1875f, 0.0f, -1, 0, 0});
     
     // right
-    m.add({x + 1, y, z, 0.25f, 0.0625f, 1, 0, 0});
-    m.add({x + 1, y + 1, z, 0.25f, 0.0f, 1, 0, 0});
-    m.add({x + 1, y, z + 1, 0.1875f, 0.0625f, 1, 0, 0});
+    m.add({x + 1 + ERROR, y - ERROR, z - ERROR, 0.25f, 0.0625f, 1, 0, 0});
+    m.add({x + 1 + ERROR, y + 1 + ERROR, z - ERROR, 0.25f, 0.0f, 1, 0, 0});
+    m.add({x + 1 + ERROR, y - ERROR, z + 1 + ERROR, 0.1875f, 0.0625f, 1, 0, 0});
     
-    m.add({x + 1, y, z + 1, 0.1875f, 0.0625f, 1, 0, 0});
-    m.add({x + 1, y + 1, z, 0.25f, 0.0f, 1, 0, 0});
-    m.add({x + 1, y + 1, z + 1, 0.1875f, 0.0f, 1, 0, 0});
+    m.add({x + 1 + ERROR, y - ERROR, z + 1 + ERROR, 0.1875f, 0.0625f, 1, 0, 0});
+    m.add({x + 1 + ERROR, y + 1 + ERROR, z - ERROR, 0.25f, 0.0f, 1, 0, 0});
+    m.add({x + 1 + ERROR, y + 1 + ERROR, z + 1 + ERROR, 0.1875f, 0.0f, 1, 0, 0});
     
     // front
-    m.add({x, y, z + 1, 0.1875f, 0.0625f, 1, 0, 0});
-    m.add({x + 1, y, z + 1, 0.25f, 0.0625f, 1, 0, 0});
-    m.add({x, y + 1, z + 1, 0.1875f, 0.0f, 1, 0, 0});
+    m.add({x - ERROR, y - ERROR, z + 1 + ERROR, 0.1875f, 0.0625f, 0, 0, 1});
+    m.add({x + 1 + ERROR, y - ERROR, z + 1 + ERROR, 0.25f, 0.0625f, 0, 0, 1});
+    m.add({x - ERROR, y + 1 + ERROR, z + 1 + ERROR, 0.1875f, 0.0f, 0, 0, 1});
     
-    m.add({x + 1, y + 1, z + 1, 0.25f, 0.0f, 1, 0, 0});
-    m.add({x, y + 1, z + 1, 0.1875f, 0.0f, 1, 0, 0});
-    m.add({x + 1, y, z + 1, 0.25f, 0.0625f, 1, 0, 0});
+    m.add({x + 1 + ERROR, y + 1 + ERROR, z + 1 + ERROR, 0.25f, 0.0f, 0, 0, 1});
+    m.add({x - ERROR, y + 1 + ERROR, z + 1 + ERROR, 0.1875f, 0.0f, 0, 0, 1});
+    m.add({x + 1 + ERROR, y - ERROR, z + 1 + ERROR, 0.25f, 0.0625f, 0, 0, 1});
     
     // back
-    m.add({x, y, z, 0.25f, 0.0625f, 1, 0, 0});
-    m.add({x, y + 1, z, 0.25f, 0.0f, 1, 0, 0});
-    m.add({x + 1, y, z, 0.1875f, 0.0625f, 1, 0, 0});
+    m.add({x - ERROR, y - ERROR, z - ERROR, 0.25f, 0.0625f, 0, 0, -1});
+    m.add({x - ERROR, y + 1 + ERROR, z - ERROR, 0.25f, 0.0f, 0, 0, -1});
+    m.add({x + 1 + ERROR, y - ERROR, z - ERROR, 0.1875f, 0.0625f, 0, 0, -1});
     
-    m.add({x + 1, y + 1, z, 0.1875f, 0.0f, 1, 0, 0});
-    m.add({x + 1, y, z, 0.1875f, 0.0625f, 1, 0, 0}); 
-    m.add({x, y + 1, z, 0.25f, 0.0f, 1, 0, 0});
+    m.add({x + 1 + ERROR, y + 1 + ERROR, z - ERROR, 0.1875f, 0.0f, 0, 0, -1});
+    m.add({x + 1 + ERROR, y - ERROR, z - ERROR, 0.1875f, 0.0625f, 0, 0, -1}); 
+    m.add({x - ERROR, y + 1 + ERROR, z - ERROR, 0.25f, 0.0f, 0, 0, -1});
 }
 
 void Game::tick(const Keys& keys, const MouseButtons& mButtons, Camera& cam)
@@ -125,7 +126,7 @@ void Game::tick(const Keys& keys, const MouseButtons& mButtons, Camera& cam)
     {
         widthAngle += rotation;
     }
-
+    
     cam.storePosition();
     cam.setPosition(pos, lengthAngle, widthAngle);
 }

+ 25 - 14
client/GameClient.cpp

@@ -64,11 +64,9 @@ struct Shaders
         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);
     }
     
@@ -98,27 +96,29 @@ struct Shaders
         float tan = tanf((0.5f * fovY) * M_PI / 180.0f);
         float q = 1.0f / tan;
         float aspect = (float) width / height;
+        
         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.set(0, q / aspect);
-            worldShadowProj.set(5, q);
-            worldShadowProj.set(10,(nearClip + farClip) / (nearClip - farClip));
-            worldShadowProj.set(14, (2.0f * nearClip * farClip) / (nearClip - farClip));
+            worldShadowProj.setToIdentity();
+            worldShadowProj.set(0, 2.0f / (10.0f * aspect));
+            worldShadowProj.set(5, 2.0f / (10.0f));
+            worldShadowProj.set(10, -2.0f / (farClip - nearClip));
         }
     }
 
     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();
+        Vector right = cam.getRight();
+        Vector up = cam.getUp();
+        Vector back = cam.getBack();
+        Vector pos = cam.getPosition();
+        
         worldView.set(0, right.getX());
         worldView.set(1, up.getX());
         worldView.set(2, back.getX());
@@ -134,6 +134,12 @@ struct Shaders
         
         if(once)
         {
+            // lengthAngle = 20; widthAngle = 35;
+            right.set(0.939693f, 0.0f, -0.34202f);
+            back.set(0.280166f, 0.573576f, 0.769751f);
+            up.set(-0.196175f, 0.819152f, -0.538986f);
+            pos.set(0.0f, 2.5f, 0.0f);
+            
             once = false;
             worldShadowView.set(0, right.getX());
             worldShadowView.set(1, up.getX());
@@ -315,10 +321,14 @@ static void renderShadow(float lag, Shaders& shaders, InternGame& game, Framebuf
     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);
+    
+    //glEnable(GL_CULL_FACE);
+    //glCullFace(GL_FRONT);
+    //glEnable(GL_POLYGON_OFFSET_FILL);
+    //glPolygonOffset(2.0f, 4.0f);
     game.game.renderWorld(lag, game.model, shaders.shadow);
-    glDisable(GL_POLYGON_OFFSET_FILL);
+    //glCullFace(GL_BACK);
+    //glDisable(GL_POLYGON_OFFSET_FILL);
 }
 
 static void renderWorld(float lag, Shaders& shaders, InternGame& game, Framebuffers& fb)
@@ -376,6 +386,7 @@ static void renderPostWorld(Shaders& shaders, InternGame& game, Framebuffers& fb
     fb.world.bindColorTexture(0);
     fb.ssaoBlur.bindRedTexture(1);
     fb.world.bindRedTexture(2);
+    fb.world.bindNormalTexture(3);
     shaders.postWorld.setInt("useSSAO", useSSAO);
     game.rectangle.draw();
 }

+ 11 - 0
client/math/Vector.cpp

@@ -92,6 +92,17 @@ void Vector::mul(float f)
     z *= f;
 }
 
+void Vector::mul(const Matrix& m)
+{
+    const float* d = m.getValues();
+    const float w = 1.0f;
+    float nx = x * d[0] + y * d[4] + z * d[8] + w * d[12];
+    float ny = x * d[1] + y * d[5] + z * d[9] + w * d[13];
+    float nz = x * d[2] + y * d[6] + z * d[10] + w * d[14];
+    float nw = x * d[3] + y * d[7] + z * d[11] + w * d[15];
+    set(nx / nw, ny / nw, nz / nw);
+}
+
 void Vector::addMul(const Vector& v, float f)
 {
     x += v.x * f;

+ 3 - 0
client/math/Vector.h

@@ -3,6 +3,8 @@
 
 #include <iostream>
 
+#include "client/math/Matrix.h"
+
 class Vector final
 {
 public:
@@ -25,6 +27,7 @@ public:
     void add(const Vector& v);
     void sub(const Vector& v);
     void mul(float f);
+    void mul(const Matrix& m);
     void addMul(const Vector& v, float f);
     
     void cross(float ix, float iy, float iz);

+ 4 - 4
client/rendering/Framebuffer.cpp

@@ -72,8 +72,8 @@ Framebuffer::Framebuffer(u32 width, u32 height, u32 mode, int textureCompareFunc
         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_LINEAR);
-        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
+        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);
         if(textureCompareFunc != 0)
@@ -119,7 +119,7 @@ void Framebuffer::resize(u32 width, u32 height) const
     if(mode & POSITION) // position texture
     {
         glBindTexture(GL_TEXTURE_2D, textures[0]);
-        glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB16F, width, height, 0, GL_RGB, GL_FLOAT, nullptr);
+        glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB32F, width, height, 0, GL_RGB, GL_FLOAT, nullptr);
     }
     if(mode & NORMAL) // normal texture
     {
@@ -139,7 +139,7 @@ void Framebuffer::resize(u32 width, u32 height) const
     if(mode & DEPTH24_STENCIL8) // depth texture
     {
         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);
     }
 }
 

+ 12 - 15
resources/shader/worldPostFragment.fs

@@ -3,6 +3,7 @@
 layout (binding = 0) uniform sampler2D colorSamp;
 layout (binding = 1) uniform sampler2D ssaoSamp;
 layout (binding = 2) uniform sampler2D shadowSamp;
+layout (binding = 3) uniform sampler2D worldNormalSamp;
 
 uniform bool useSSAO;
 
@@ -10,6 +11,8 @@ in vec2 varTex;
 
 out vec4 color;
 
+const vec3 light = vec3(-0.280166, -0.573576, -0.769751);
+
 void main()
 {
     if(useSSAO)
@@ -21,18 +24,12 @@ void main()
         color = vec4(texture(colorSamp, varTex).xyz, 1.0);
     }
 
-    vec2 texelSize = 1.0 / vec2(textureSize(shadowSamp, 0));
-    float result = 0.0;
-    const int radius = 5;
-    for(int x = -radius; x < radius; x++) 
-    {
-        for(int y = -radius; y < radius; y++) 
-        {
-            vec2 offset = vec2(float(x), float(y)) * texelSize;
-            result += texture(shadowSamp, varTex + offset).r;
-        }
-    }
-    result /= (radius * radius * 4);
-    result = result * 0.5 + 0.5;
-    color *= result;
-}  
+    float diffuseLight = float(dot(texture(worldNormalSamp, varTex).xyz, -light) > 0);
+    float f = diffuseLight * texture(shadowSamp, varTex).r;
+
+    color *= f * 0.5 + 0.5;
+
+    //color *= f * 0.5 + 0.5;
+
+    //color = texture(worldNormalSamp, varTex);
+}  

+ 4 - 2
resources/shader/worldVertex.vs

@@ -17,11 +17,13 @@ out vec2 varTex;
 out vec3 varNormal;
 out vec4 varShadow;
 
+const vec3 light = vec3(-0.280166, -0.573576, -0.769751);
+
 void main(void)
 { 
     // transforming normals must not use the fourth dimension
     // should be the inverse transposed matrix
-    varNormal = (view * model * vec4(normal, 0.0)).xyz;
+    varNormal = (model * vec4(normal, 0.0)).xyz;
     
     varTex = tex; 
     
@@ -29,5 +31,5 @@ void main(void)
     varPosition = worldPos.xyz;
     gl_Position = proj * worldPos;
 
-    varShadow = projViewShadow * vec4(position, 1.0);
+    varShadow = projViewShadow * vec4(position - light * 0.05, 1.0);
 }