Browse Source

further improved noise

Kajetan Johannes Hammerle 2 years ago
parent
commit
149ae055f2
1 changed files with 57 additions and 34 deletions
  1. 57 34
      Main.c

+ 57 - 34
Main.c

@@ -1,12 +1,13 @@
 #include <GL/glew.h>
 #include <GLFW/glfw3.h>
+#include <math.h>
 #include <stdbool.h>
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
 
-#define WIDTH 400
-#define HEIGHT 400
+#define WIDTH 800
+#define HEIGHT 800
 
 static const GLchar* vertexShaderCode = "#version 430\n"
                                         "layout(location = 0) in vec2 pos;"
@@ -37,11 +38,11 @@ static const GLchar* fragmentShaderCode =
     ""
     "void main(void) {"
     "    float f = texture(samp, varTex).r;"
-    "    //color = vec4(f, f, f, 1.0);\n"
+    "    color = vec4(f, f, f, 1.0);\n"
     "    //color = heightColors[min(int(5 * f), 4)];\n"
-    "    int a = int(min(floor(5 * f), 4));"
-    "    int b = int(min(ceil(5 * f), 4));"
-    "    color = mix(heightColors[a], heightColors[b], 5 * f - a);\n"
+    "    //int a = int(min(floor(5 * f), 4));"
+    "    //int b = int(min(ceil(5 * f), 4));"
+    "    //color = mix(heightColors[a], heightColors[b], 5 * f - a);\n"
     "}";
 
 static GLFWwindow* window = NULL;
@@ -52,28 +53,49 @@ static GLuint vertexArray = 0;
 static GLuint vertexBuffer = 0;
 static GLuint texture = 0;
 static GLfloat noise[WIDTH][HEIGHT];
-static unsigned long long seed = 0;
+static unsigned int seed = 1;
 
-static float nextFloat() {
-    seed = seed * 534492383lu + 31;
-    return (unsigned int)(seed >> 16) / (float)(-1u);
+static float nextSeededFloat(unsigned int x, unsigned int y) {
+    unsigned int s = y + ((x + y) * (x + y + 1)) / 2;
+    s ^= s * (x + seed) * 534492383u;
+    s ^= s * (y + seed) * 23537u;
+    return s / (float)(-1u);
 }
 
-static void smooth(int size) {
-    float divider = 1.0f / (size * size);
-    static GLfloat newNoise[WIDTH][HEIGHT];
-    for(int x = 0; x < WIDTH; x++) {
-        for(int y = 0; y < HEIGHT; y++) {
-            float sum = 0.0f;
-            for(int mx = 0; mx < size; mx++) {
-                for(int my = 0; my < size; my++) {
-                    sum += noise[(x + mx) % WIDTH][(y + my) % HEIGHT];
-                }
-            }
-            newNoise[x][y] = sum * divider;
-        }
-    }
-    memcpy(noise, newNoise, sizeof(newNoise));
+static float interpolate(float a, float b, float f) {
+    return (b - a) * (3.0 - f * 2.0) * f * f + a;
+}
+
+static float dot(int ix, int iy, float x, float y, float zoom) {
+    float f =
+        nextSeededFloat(ix % (int)(WIDTH / zoom), iy % (int)(HEIGHT / zoom)) *
+        M_PI * 2.0f;
+    return (x - ix) * cosf(f) + (y - iy) * sinf(f);
+}
+
+float perlin(float x, float y, float zoom) {
+    x /= zoom;
+    y /= zoom;
+    int ix = x;
+    int iy = y;
+    int ix1 = ix + 1;
+    int iy1 = iy + 1;
+    float sx = x - ix;
+    return interpolate(
+        interpolate(dot(ix, iy, x, y, zoom), dot(ix1, iy, x, y, zoom), sx),
+        interpolate(dot(ix, iy1, x, y, zoom), dot(ix1, iy1, x, y, zoom), sx),
+        y - iy);
+}
+
+float transform(float x, float y, float zoom) {
+    return (perlin(x, y, zoom) + 1.0f) * 0.5f;
+}
+
+float turbulence(int x, int y) {
+    float sum = transform(x, y, 80.0f);
+    sum += transform(x, y, 200.0f);
+    sum += transform(x, y, 400.0f);
+    return sum / 3.0f;
 }
 
 static void normalize() {
@@ -96,19 +118,12 @@ static void normalize() {
 static void generateNoise() {
     for(int x = 0; x < WIDTH; x++) {
         for(int y = 0; y < HEIGHT; y++) {
-            noise[x][y] = nextFloat();
+            noise[x][y] = turbulence(x, y);
         }
     }
-    smooth(2);
-    smooth(4);
-    smooth(8);
-    smooth(16);
-    smooth(32);
-    smooth(64);
     normalize();
 
     (void)normalize;
-    (void)smooth;
 }
 
 static bool checkShaderError(GLuint shader, const char* name) {
@@ -177,7 +192,7 @@ static void initTexture() {
     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
     generateNoise();
-    glTexImage2D(GL_TEXTURE_2D, 0, GL_RED, WIDTH, HEIGHT, 0, GL_RED, GL_FLOAT,
+    glTexImage2D(GL_TEXTURE_2D, 0, GL_RED, HEIGHT, WIDTH, 0, GL_RED, GL_FLOAT,
                  noise);
 }
 
@@ -222,10 +237,18 @@ static void start() {
     if(createWindow() || init()) {
         return;
     }
+    int i = 0;
     while(!glfwWindowShouldClose(window)) {
         glClear(GL_COLOR_BUFFER_BIT);
 
         glBindTexture(GL_TEXTURE_2D, texture);
+        if(i++ == 100) {
+            seed++;
+            i = 0;
+            generateNoise();
+            glTexImage2D(GL_TEXTURE_2D, 0, GL_RED, HEIGHT, WIDTH, 0, GL_RED,
+                         GL_FLOAT, noise);
+        }
         glActiveTexture(GL_TEXTURE0);
         glBindVertexArray(vertexArray);
         glDrawArrays(GL_TRIANGLES, 0, 6);