diff options
author | Lizzy Fleckenstein <lizzy@vlhl.dev> | 2024-01-28 22:47:07 +0100 |
---|---|---|
committer | Lizzy Fleckenstein <lizzy@vlhl.dev> | 2024-01-28 22:47:07 +0100 |
commit | a9cb135ffb53d7473c9db6a9a04b73d1272beb59 (patch) | |
tree | fb60f74fb29ce47543f396860b4311fda6409634 | |
parent | c47a562e00488575cfde58fd1d2f84c3ab66883f (diff) | |
download | juxtapos-master.tar.xz |
-rw-r--r-- | assets/wood.glsl | 144 | ||||
-rw-r--r-- | src/main.c | 9 |
2 files changed, 127 insertions, 26 deletions
diff --git a/assets/wood.glsl b/assets/wood.glsl index 5ec6265..b89a579 100644 --- a/assets/wood.glsl +++ b/assets/wood.glsl @@ -2,39 +2,137 @@ layout(local_size_x = 1, local_size_y = 1) in; layout(rgba32f, binding = 0) uniform image2D texture; -// perlin noise taken from https://gist.github.com/patriciogonzalezvivo/670c22f3966e662d2f83 - #define M_PI 3.14159265358979323846 -float rand(vec2 co){return fract(sin(dot(co.xy ,vec2(12.9898,78.233))) * 43758.5453);} -float rand (vec2 co, float l) {return rand(vec2(rand(co), l));} -float rand (vec2 co, float l, float t) {return rand(vec2(rand(co, l), t));} -float perlin(vec2 p, float dim, float time) { - vec2 pos = floor(p * dim); - vec2 posx = pos + vec2(1.0, 0.0); - vec2 posy = pos + vec2(0.0, 1.0); - vec2 posxy = pos + vec2(1.0); +// +// Description : Array and textureless GLSL 2D simplex noise function. +// Author : Ian McEwan, Ashima Arts. +// Maintainer : stegu +// Lastmod : 20110822 (ijm) +// License : Copyright (C) 2011 Ashima Arts. All rights reserved. +// Distributed under the MIT License. See LICENSE file. +// https://github.com/ashima/webgl-noise +// https://github.com/stegu/webgl-noise +// + +vec3 mod289(vec3 x) { + return x - floor(x * (1.0 / 289.0)) * 289.0; +} + +vec2 mod289(vec2 x) { + return x - floor(x * (1.0 / 289.0)) * 289.0; +} + +vec3 permute(vec3 x) { + return mod289(((x*34.0)+10.0)*x); +} + +float rawsnoise(vec2 v) + { + const vec4 C = vec4(0.211324865405187, // (3.0-sqrt(3.0))/6.0 + 0.366025403784439, // 0.5*(sqrt(3.0)-1.0) + -0.577350269189626, // -1.0 + 2.0 * C.x + 0.024390243902439); // 1.0 / 41.0 +// First corner + vec2 i = floor(v + dot(v, C.yy) ); + vec2 x0 = v - i + dot(i, C.xx); + +// Other corners + vec2 i1; + //i1.x = step( x0.y, x0.x ); // x0.x > x0.y ? 1.0 : 0.0 + //i1.y = 1.0 - i1.x; + i1 = (x0.x > x0.y) ? vec2(1.0, 0.0) : vec2(0.0, 1.0); + // x0 = x0 - 0.0 + 0.0 * C.xx ; + // x1 = x0 - i1 + 1.0 * C.xx ; + // x2 = x0 - 1.0 + 2.0 * C.xx ; + vec4 x12 = x0.xyxy + C.xxzz; + x12.xy -= i1; + +// Permutations + i = mod289(i); // Avoid truncation effects in permutation + vec3 p = permute( permute( i.y + vec3(0.0, i1.y, 1.0 )) + + i.x + vec3(0.0, i1.x, 1.0 )); + + vec3 m = max(0.5 - vec3(dot(x0,x0), dot(x12.xy,x12.xy), dot(x12.zw,x12.zw)), 0.0); + m = m*m ; + m = m*m ; + +// Gradients: 41 points uniformly over a line, mapped onto a diamond. +// The ring size 17*17 = 289 is close to a multiple of 41 (41*7 = 287) - float c = rand(pos, dim, time); - float cx = rand(posx, dim, time); - float cy = rand(posy, dim, time); - float cxy = rand(posxy, dim, time); + vec3 x = 2.0 * fract(p * C.www) - 1.0; + vec3 h = abs(x) - 0.5; + vec3 ox = floor(x + 0.5); + vec3 a0 = x - ox; - vec2 d = fract(p * dim); - d = -0.5 * cos(d * M_PI) + 0.5; +// Normalise gradients implicitly by scaling m +// Approximation of: m *= inversesqrt( a0*a0 + h*h ); + m *= 1.79284291400159 - 0.85373472095314 * ( a0*a0 + h*h ); - float ccx = mix(c, cx, d.x); - float cycxy = mix(cy, cxy, d.x); - float center = mix(ccx, cycxy, d.y); +// Compute final noise value at P + vec3 g; + g.x = a0.x * x0.x + h.x * x0.y; + g.yz = a0.yz * x12.xz + h.yz * x12.yw; + return 130.0 * dot(m, g); +} + +#define profile_id 0 +#define profile_wave 1 +#define profile_step 2 + +float profile(float x, int prof) { + switch (prof) { + case profile_id: + return x; + case profile_wave: + return sin(x * M_PI * 2 * 4); + case profile_step: + return smoothstep(0.1, 0.4, 0.5 + 0.5 * x) * 2.0 - 1.0; + } +} + +float snoise(vec2 p, float persistence, int octaves, int prof) { + float total = 0.0; + float frequency = 1.0; + float amplitude = 1.0; + + for (int i = 0; i < octaves; i++) { + total += profile(rawsnoise(p * frequency - vec2(100 * i)), prof) * amplitude; + frequency *= 2; + amplitude *= persistence; + } - return center * 2.0 - 1.0; + return total; +} + +float overlay(float a, float b) { + if (a < 0.5) + return 2*a*b; + else + return 1-2*(1-a)*(1-b); } void main() { ivec2 pixelCoords = ivec2(gl_GlobalInvocationID.xy); - vec2 coords = vec2(pixelCoords) / vec2(512); + vec2 coords = vec2(pixelCoords) / vec2(480); + + float bottom = mix(0.2, 0.8, 0.5 + 0.5 * + snoise(coords * vec2(5.0, 0.4), 0.6, 11, profile_id)); + float zebra = mix(0.2, 0.8, 0.5 + 0.5 * + snoise(coords * vec2(2.5, 0.4) + vec2(123, 456), 0.5, 8, profile_wave)); + float grains = 0.5 + 0.5 * + snoise(coords * vec2(150, 10) + vec2(789, 420), 0.6, 8, profile_step); + + float factor = overlay(bottom, zebra) * grains; + + // normal, high contrast + // vec3 dark = vec3(90, 47, 12) / 255; + // vec3 light = vec3(171, 116, 52) / 255; + vec3 light = vec3(0x59, 0x39, 0x2e) / 0xff; + vec3 dark = vec3(0x39, 0x22, 0x1c) / 0xff; + + vec3 color = mix(dark, light, factor); - // TODO: proper wood texture generation - imageStore(texture, pixelCoords, (0.5+perlin(coords / 25, 512.0, 0.0)) * vec4(110, 51, 7, 255) / 255); + imageStore(texture, pixelCoords, vec4(color, 1.0)); } @@ -97,8 +97,8 @@ int main() glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 4); glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3); - int win_w = 900; - int win_h = 900; + int win_w = 1000; + int win_h = 1000; GLFWwindow *window = glfwCreateWindow(win_w, win_h, "Juxtapos", NULL, NULL); if (window == NULL) { @@ -117,7 +117,7 @@ int main() glfwSetFramebufferSizeCallback(window, &framebuffer_size_callback); // dimensions of the image - int tex_w = 512, tex_h = 512; + int tex_w = 1000, tex_h = 1000; GLuint wood_texture; glGenTextures(1, &wood_texture); @@ -194,6 +194,9 @@ int main() glMemoryBarrier(GL_SHADER_IMAGE_ACCESS_BARRIER_BIT); while (!glfwWindowShouldClose(window)) { + if (glfwGetKey(window, GLFW_KEY_ESCAPE) == GLFW_PRESS) + glfwSetWindowShouldClose(window, GLFW_TRUE); + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // preview wood texture |