Browse Source

experimental parallax mapping

Kajetan Johannes Hammerle 3 years ago
parent
commit
dce849b71b
9 changed files with 123 additions and 88 deletions
  1. 30 57
      Game.cpp
  2. 8 1
      Game.h
  3. 4 1
      meson.build
  4. BIN
      resources/bricks.png
  5. BIN
      resources/bricks_bump.png
  6. BIN
      resources/bricks_normal.png
  7. 38 6
      resources/fragment.fs
  8. 34 15
      resources/geometry.gs
  9. 9 8
      resources/vertex.vs

+ 30 - 57
Game.cpp

@@ -12,11 +12,14 @@
 Game::Game(Shader& shader, Shader& noiceShader, LayeredFramebuffer& buffer,
            Buttons& buttons, const Size& size)
     : shader(shader), noiceShader(noiceShader), noiceBuffer(buffer),
-      buttons(buttons), size(size), frustum(60, 0.1f, 1000.0f, size),
-      up(GLFW_KEY_SPACE, "Up"), down(GLFW_KEY_LEFT_SHIFT, "Down"),
-      left(GLFW_KEY_A, "left"), right(GLFW_KEY_D, "right"),
-      front(GLFW_KEY_W, "front"), back(GLFW_KEY_S, "back"),
-      toggle(GLFW_KEY_T, "toggle"), oldHeight(0.0f), height(0.0f) {
+      bricks("resources/bricks.png"), bricksBump("resources/bricks_bump.png"),
+      bricksNormal("resources/bricks_normal.png"), buttons(buttons), size(size),
+      frustum(60, 0.1f, 1000.0f, size), up(GLFW_KEY_SPACE, "Up"),
+      down(GLFW_KEY_LEFT_SHIFT, "Down"), left(GLFW_KEY_A, "left"),
+      right(GLFW_KEY_D, "right"), front(GLFW_KEY_W, "front"),
+      back(GLFW_KEY_S, "back"), toggle(GLFW_KEY_T, "toggle"),
+      scaleUp(GLFW_KEY_G, "scale up"), scaleDown(GLFW_KEY_H, "scale down"),
+      oldHeight(0.0f), height(0.0f), heightScale(0.0f) {
     buttons.add(up);
     buttons.add(down);
     buttons.add(left);
@@ -24,60 +27,16 @@ Game::Game(Shader& shader, Shader& noiceShader, LayeredFramebuffer& buffer,
     buttons.add(front);
     buttons.add(back);
     buttons.add(toggle);
+    buttons.add(scaleUp);
+    buttons.add(scaleDown);
+
+    position = Vector3(0.0f, 0.0f, -40.0f);
 
     rectangleBuffer.setAttributes(Attributes().addFloat(2));
     float recData[6][2] = {{-1.0f, -1.0f}, {-1.0, 1.0}, {1.0, -1.0},
                            {1.0f, 1.0f},   {-1.0, 1.0}, {1.0, -1.0}};
     rectangleBuffer.setStaticData(sizeof(recData), recData);
     noiceBuffer.bindTextureTo(0);
-
-    Random r;
-    const int textureSize = 64;
-    float tData[textureSize][textureSize][textureSize][3];
-    for(int x = 0; x < textureSize; x++) {
-        for(int y = 0; y < textureSize; y++) {
-            for(int z = 0; z < textureSize; z++) {
-                tData[x][y][z][0] = r.nextFloat();
-            }
-        }
-    }
-    for(int k = 1; k < 3; k++) {
-        int factor = (k * 2 + 1) * (k * 2 + 1) * (k * 2 + 1);
-        for(int x = 0; x < textureSize; x++) {
-            for(int y = 0; y < textureSize; y++) {
-                for(int z = 0; z < textureSize; z++) {
-                    float sum = 0.0f;
-                    for(int mx = -k; mx <= k; mx++) {
-                        for(int my = -k; my <= k; my++) {
-                            for(int mz = -k; mz <= k; mz++) {
-                                int rx = std::abs(x + mx);
-                                int ry = std::abs(y + my);
-                                int rz = std::abs(z + mz);
-                                rx = rx >= 64 ? 127 - rx : rx;
-                                ry = ry >= 64 ? 127 - ry : ry;
-                                rz = rz >= 64 ? 127 - rz : rz;
-                                sum += tData[rx][ry][rz][0];
-                            }
-                        }
-                    }
-                    tData[x][y][z][0] = sum / factor;
-                }
-            }
-        }
-    }
-    for(int x = 0; x < textureSize; x++) {
-        for(int y = 0; y < textureSize; y++) {
-            for(int z = 0; z < textureSize; z++) {
-                float v = tData[x][y][z][0];
-                float vvv = v * v * v;
-                v = 6.0f * vvv * v * v - 15.0f * vvv * v + 10.0f * vvv;
-                tData[x][y][z][0] = v;
-                tData[x][y][z][1] = v;
-                tData[x][y][z][2] = v;
-            }
-        }
-    }
-    texture.setData(textureSize, textureSize, textureSize, tData);
 }
 
 void Game::render(float lag) {
@@ -100,17 +59,21 @@ void Game::render(float lag) {
 
     Matrix m;
     m.translate(Utils::interpolate(oldPosition, position, lag));
-    m.translateZ(-32.0f);
     m.translateY(-32.0f + (oldHeight - height) * lag);
-    m.translateX(-32.0f);
     shader.setMatrix("view", m.getValues());
     shader.setFloat("height", oldHeight * step * 0.5f);
 
+    shader.setVector("viewPos", -position + Vector3(0.0f, 32.0f, 0.0f));
+    shader.setVector("lightPos", Vector3());
+    shader.setFloat("heightScale", heightScale);
+
     if(toggle.isDown()) {
         glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
     }
     noiceBuffer.bindTextureTo(0);
-    texture.bindTo(1);
+    bricks.bindTo(1);
+    bricksBump.bindTo(2);
+    bricksNormal.bindTo(3);
     emptyBuffer.drawPoints(64 * 64 * 64);
     glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
 }
@@ -124,7 +87,7 @@ void Game::tick() {
     if(down.isDown()) {
         height -= 1.0f;
     }
-    const float speed = 2.5f;
+    const float speed = 1.15f;
     if(left.isDown()) {
         position += Vector3(speed, 0.0f, 0.0f);
     }
@@ -137,6 +100,16 @@ void Game::tick() {
     if(back.isDown()) {
         position -= Vector3(0.0f, 0.0f, speed);
     }
+
+    if(scaleUp.isDown()) {
+        heightScale += 0.005f;
+    }
+    if(scaleDown.isDown()) {
+        heightScale -= 0.005f;
+        if(heightScale < 0.0f) {
+            heightScale = 0.0f;
+        }
+    }
 }
 
 bool Game::isRunning() const {

+ 8 - 1
Game.h

@@ -5,6 +5,7 @@
 #include "Texture3D.h"
 #include "gaming-core/input/Buttons.h"
 #include "gaming-core/math/Frustum.h"
+#include "gaming-core/rendering/FileTexture.h"
 #include "gaming-core/rendering/Shader.h"
 #include "gaming-core/rendering/VertexBuffer.h"
 #include "gaming-core/utils/Size.h"
@@ -13,7 +14,9 @@ class Game final {
     Shader& shader;
     Shader& noiceShader;
     LayeredFramebuffer& noiceBuffer;
-    Texture3D texture;
+    FileTexture bricks;
+    FileTexture bricksBump;
+    FileTexture bricksNormal;
     Buttons& buttons;
     const Size& size;
     VertexBuffer rectangleBuffer;
@@ -27,10 +30,14 @@ class Game final {
     Button front;
     Button back;
     Button toggle;
+    Button scaleUp;
+    Button scaleDown;
     Vector3 oldPosition;
     Vector3 position;
+
     float oldHeight;
     float height;
+    float heightScale;
 
 public:
     Game(Shader& shader, Shader& noiceShader, LayeredFramebuffer& buffer,

+ 4 - 1
meson.build

@@ -17,6 +17,8 @@ sources = ['Main.cpp',
     'gaming-core/rendering/Attributes.cpp',
     'gaming-core/rendering/Texture.cpp',
     'gaming-core/rendering/TextureFormat.cpp',
+    'gaming-core/rendering/FileTexture.cpp',
+    'gaming-core/images/PNGReader.cpp',
     'gaming-core/math/Frustum.cpp',
     'gaming-core/math/Plane.cpp',
     'gaming-core/math/Matrix.cpp',
@@ -28,9 +30,10 @@ sources = ['Main.cpp',
 
 glewDep = dependency('glew')
 glfwDep = dependency('glfw3')
+pngDep = dependency('libpng')
 
 executable('demo', 
     sources: sources,
-    dependencies : [glewDep, glfwDep],
+    dependencies : [glewDep, glfwDep, pngDep],
     include_directories : include_directories('gaming-core'),
     cpp_args: ['-Wall', '-Wextra', '-pedantic', '-Werror'])

BIN
resources/bricks.png


BIN
resources/bricks_bump.png


BIN
resources/bricks_normal.png


+ 38 - 6
resources/fragment.fs

@@ -1,19 +1,51 @@
 #version 430
 
 layout (binding = 0) uniform sampler3D noiseSamp;
-layout (binding = 1) uniform sampler3D textureSamp;
+layout (binding = 1) uniform sampler2D textureSamp;
+layout (binding = 2) uniform sampler2D bumpSamp;
+layout (binding = 3) uniform sampler2D normalSamp;
 
 uniform float height;
 
-in vec3 varTextureG;
-in vec3 varNormalG;
+in vec3 varPositionG;
+in vec2 varTextureG;
+in vec3 tangentLightPosG;
+in vec3 tangentViewPosG;
+in vec3 tangentFragPosG;
+
+uniform vec3 viewPos;
 
 out vec4 color;
 
 const vec3 light = vec3(-0.746, -0.373, -0.224);
 
+uniform float heightScale;
+
+vec2 ParallaxMapping(vec2 texCoords, vec3 viewDir) { 
+    float height = texture(bumpSamp, texCoords, 0.0).r;    
+    vec2 p = viewDir.xy / viewDir.z * (height * heightScale);
+    return texCoords - p;    
+} 
+
 void main(void) {
-    vec3 f = texture(textureSamp, (varTextureG + vec3(0.0, height, 0.0)) * 8.0).xyz;
-    float l = max(dot(light, varNormalG), 0.0) * 0.7 + 0.3;
-    color = vec4(f * l, 1.0);
+    vec2 tex = varTextureG + vec2(0.0, height);
+    //float depth = texture(textureSamp, tex).x;
+    //vec3 dir = (camPosition - varPositionG) * depth * 0.05;
+
+    //vec3 f = texture(textureSamp, tex).xyz;
+    //float l = max(dot(light, varNormalG), 0.0) * 0.7 + 0.3;
+    //color = vec4(f, 1.0);
+
+    // offset texture coordinates with Parallax Mapping
+    vec3 viewDir = normalize(tangentViewPosG - tangentFragPosG);
+    vec2 texCoords = ParallaxMapping(tex.xy, viewDir);
+
+    // then sample textures with new texture coords
+    //vec3 diffuse = texture(diffuseMap, texCoords);
+    vec3 normal  = texture(normalSamp, texCoords).xyz;
+    normal = normalize(normal * 2.0 - 1.0);
+
+    float l = max(dot(-light, normal), 0.0) * 0.7 + 0.3;
+
+    color = vec4(texture(textureSamp, texCoords).xyz * l, 1.0);
 }

+ 34 - 15
resources/geometry.gs

@@ -6,10 +6,17 @@ layout (triangle_strip, max_vertices = 12) out;
 uniform mat4 proj;
 uniform mat4 view;
 
+uniform vec3 lightPos;
+uniform vec3 viewPos;
+
 in vec3 varTexture[];
 in int varIndex[];
-out vec3 varTextureG;
-out vec3 varNormalG;
+
+out vec3 varPositionG;
+out vec2 varTextureG;
+out vec3 tangentLightPosG;
+out vec3 tangentViewPosG;
+out vec3 tangentFragPosG;
 
 vec3 vectors[13] = {
     vec3(0.0, 0.0, 0.0), vec3(0.5, 1.0, 1.0), vec3(0.0, 0.5, 1.0), 
@@ -164,35 +171,47 @@ void main(void) {
         vec3 b = base.xyz + offsetB;
         vec3 c = base.xyz + offsetC;
         // texture coords
-        vec3 ta = varTexture[0] + offsetA * step;
-        vec3 tb = varTexture[0] + offsetB * step;
-        vec3 tc = varTexture[0] + offsetC * step;
+        vec2 ta = (varTexture[0] + offsetA * step).xy;
+        vec2 tb = (varTexture[0] + offsetB * step).xy;
+        vec2 tc = (varTexture[0] + offsetC * step).xy;
         // normal, same for all vertices
         vec3 ab = b - a;
         vec3 ac = c - a;
         vec3 normal = normalize(cross(ab, ac));
         // tangent, same for all vertices
-        //Vector2 abt = b.texture - a.texture;
-        //Vector2 act = c.texture - a.texture;
-        //float f = 1.0f / (abt[0] * act[1] - act[0] * abt[1]);
-        //tangentA = f * (act[1] * ab - abt[1] * ac);
-        //tangentA.normalize();
-        //tangentB = tangentA;
-        //tangentC = tangentA;
+        vec2 abt = tb - ta;
+        vec2 act = tc - ta;
+        float f = 1.0f / (abt.x * act.y - act.x * abt.y);
+        vec3 tangent = normalize(f * (act.y * ab - abt.y * ac));
+
+        vec3 biTangent = cross(normal, tangent);
+
+        mat3 TBN = transpose(mat3(tangent, biTangent, normal));
+        vec3 tangentLightPos = TBN * lightPos;
+        vec3 tangentViewPos  = TBN * viewPos;
 
         gl_Position = proj * view * vec4(a, 1.0);
+        varPositionG = a;
         varTextureG = ta;
-        varNormalG = normal;
+        tangentLightPosG = tangentLightPos;
+        tangentViewPosG = tangentViewPos;
+        tangentFragPosG = TBN * a;
         EmitVertex();
 
         gl_Position = proj * view * vec4(b, 1.0);
+        varPositionG = b;
         varTextureG = tb;
-        varNormalG = normal;
+        tangentLightPosG = tangentLightPos;
+        tangentViewPosG = tangentViewPos;
+        tangentFragPosG = TBN * b;
         EmitVertex();
 
         gl_Position = proj * view * vec4(c, 1.0);
+        varPositionG = c;
         varTextureG = tc;
-        varNormalG = normal;
+        tangentLightPosG = tangentLightPos;
+        tangentViewPosG = tangentViewPos;
+        tangentFragPosG = TBN * c;
         EmitVertex();
 
         EndPrimitive();

+ 9 - 8
resources/vertex.vs

@@ -17,14 +17,15 @@ void main(void) {
     gl_Position = vec4(xyz, 1.0);
     varTexture = xyz * step;
 
-    int b1 = int(texture(samp, varTexture).r < 0.5f);
-    int b2 = int(texture(samp, varTexture + vec3(step, 0.0, 0.0)).r < 0.5f);
-    int b3 = int(texture(samp, varTexture + vec3(step, 0.0, step)).r < 0.5f);
-    int b4 = int(texture(samp, varTexture + vec3(0.0, 0.0, step)).r < 0.5f);
-    int b5 = int(texture(samp, varTexture + vec3(0.0, step, 0.0)).r < 0.5f);
-    int b6 = int(texture(samp, varTexture + vec3(step, step, 0.0)).r < 0.5f);
-    int b7 = int(texture(samp, varTexture + vec3(step, step, step)).r < 0.5f);
-    int b8 = int(texture(samp, varTexture + vec3(0.0, step, step)).r < 0.5f);
+    const float limit = 0.5f;
+    int b1 = int(texture(samp, varTexture).r < limit);
+    int b2 = int(texture(samp, varTexture + vec3(step, 0.0, 0.0)).r < limit);
+    int b3 = int(texture(samp, varTexture + vec3(step, 0.0, step)).r < limit);
+    int b4 = int(texture(samp, varTexture + vec3(0.0, 0.0, step)).r < limit);
+    int b5 = int(texture(samp, varTexture + vec3(0.0, step, 0.0)).r < limit);
+    int b6 = int(texture(samp, varTexture + vec3(step, step, 0.0)).r < limit);
+    int b7 = int(texture(samp, varTexture + vec3(step, step, step)).r < limit);
+    int b8 = int(texture(samp, varTexture + vec3(0.0, step, step)).r < limit);
     varIndex = (b1 << 7) | (b2 << 6) | (b3 << 5) | (b4 << 4) | 
                (b5 << 3) | (b6 << 2) | (b7 << 1) | b8;
 }