diff --git a/fragment.glsl b/fragment.glsl index f452449..e16425f 100644 --- a/fragment.glsl +++ b/fragment.glsl @@ -79,20 +79,17 @@ float limit(float val, float min, float max) { } void main() { - vec2 uv = gl_FragCoord.xy / WindowSize; + vec2 screen_uv = gl_FragCoord.xy / WindowSize; // We'll make origin in the top-left. - uv.y = 1.0 - uv.y; - uv.x *= WindowSize.x / WindowSize.y; + screen_uv.y = 1.0 - screen_uv.y; + screen_uv.x *= WindowSize.x / WindowSize.y; + vec2 uv = vec2(screen_uv.x, screen_uv.y); uv.y += sin(uv.x * 2.0 + time * 0.2) * 0.47; uv.y += sin(uv.x * 4.3 + time * 1.34) * 0.09; uv += 100.0; - //uv.x += time / 20.0; float out_val = perlin_noise(uv, vec2(0.0, 0.0), time / 1.0); float min = 0.42 + sin(time)/8.0; float max = 0.58 + sin(time)/8.0; - //float min = 0.42; - //float max = 0.58; - //out_val = out_val + sin(uv.y + time) / 15.2; out_val = limit(out_val, min, max); color = vec4(out_val, 0.4, 0.8, 1.0); } diff --git a/perlin-pink-wave.glsl b/perlin-pink-wave.glsl new file mode 100644 index 0000000..f452449 --- /dev/null +++ b/perlin-pink-wave.glsl @@ -0,0 +1,98 @@ +#version 320 es + +precision highp float; +precision highp int; +precision lowp sampler2D; +precision lowp samplerCube; + +uniform vec2 WindowSize; +uniform float time; +layout(location = 0) out vec4 color; + +float lerp(float a, float b, float x) { + return a + x*(b-a); +} + +uint xxhash32(uvec2 p) { + const uint PRIME32_2 = 2246822519U, PRIME32_3 = 3266489917U; + const uint PRIME32_4 = 668265263U, PRIME32_5 = 374761393U; + uint h32 = p.y + PRIME32_5 + p.x*PRIME32_3; + h32 = PRIME32_4*((h32 << 17) | (h32 >> (32 - 17))); + h32 = PRIME32_2*(h32^(h32 >> 15)); + h32 = PRIME32_3*(h32^(h32 >> 13)); + return h32^(h32 >> 16); +} + + +float rand(vec2 v, vec2 offset) { + uint hash = xxhash32(uvec2(v * 10000.0 + offset * 10000.0)); + return float(hash) * (1.0/float(0xffffffffu)); +} + +float cell_size = 0.04; +#define PI 3.1415926538 + +// whatever that corner contributes +// vector_offset and angle_offset are optional variation variables +float c_dot(vec2 point, vec2 corner, vec2 vector_offset, float angle_offset) { + vec2 c = vec2(ivec2(round(corner * 100.0))); + float angle = rand(c, vec2(0.0, 0.0)) * 2.0*PI + angle_offset; + vec2 random_corner_vec = vec2(cos(angle), sin(angle)) + vector_offset; + vec2 offset = (point - corner) / cell_size; + float dot_product = dot(random_corner_vec, offset); + // for now just return something + return dot_product; +} + +// better than built in smoothstep. +float fade(float t) { + return ((6.0*t - 15.0)*t + 10.0)*t*t*t; +} + +float perlin_noise(vec2 uv, vec2 vector_offset, float angle_offset) { + vec2 grid_edge_offset = mod(uv, cell_size); + // c: corner + vec2 c_tl = uv - grid_edge_offset; + vec2 c_tr = uv - grid_edge_offset + vec2(cell_size, 0); + vec2 c_bl = uv - grid_edge_offset + vec2(0, cell_size); + vec2 c_br = uv - grid_edge_offset + vec2(cell_size, cell_size); + float c_tl_dot = c_dot(uv, c_tl, vector_offset, angle_offset); + float c_tr_dot = c_dot(uv, c_tr, vector_offset, angle_offset); + float c_bl_dot = c_dot(uv, c_bl, vector_offset, angle_offset); + float c_br_dot = c_dot(uv, c_br, vector_offset, angle_offset); + + // the uv within the tile (0 to 1) + vec2 tile_uv = (uv - c_tl) / cell_size; + + // lerp index + float u = fade(tile_uv.x); + float v = fade(tile_uv.y); + float val = lerp(lerp(c_tl_dot, c_bl_dot, v), lerp(c_tr_dot, c_br_dot, v), u); + return val /2.0 + 0.5; +} + +float limit(float val, float min, float max) { + float out_val = clamp(val, min, max); + out_val -= min; + out_val *= (1.0 - (max - min)) / (max - min); + return out_val; +} + +void main() { + vec2 uv = gl_FragCoord.xy / WindowSize; + // We'll make origin in the top-left. + uv.y = 1.0 - uv.y; + uv.x *= WindowSize.x / WindowSize.y; + uv.y += sin(uv.x * 2.0 + time * 0.2) * 0.47; + uv.y += sin(uv.x * 4.3 + time * 1.34) * 0.09; + uv += 100.0; + //uv.x += time / 20.0; + float out_val = perlin_noise(uv, vec2(0.0, 0.0), time / 1.0); + float min = 0.42 + sin(time)/8.0; + float max = 0.58 + sin(time)/8.0; + //float min = 0.42; + //float max = 0.58; + //out_val = out_val + sin(uv.y + time) / 15.2; + out_val = limit(out_val, min, max); + color = vec4(out_val, 0.4, 0.8, 1.0); +} diff --git a/renderer.c b/renderer.c index 01dad63..9b1a4bc 100644 --- a/renderer.c +++ b/renderer.c @@ -63,29 +63,31 @@ GLuint load_shader(const char *path) { fseek(handle, 0L, SEEK_END); long length = ftell(handle); fseek(handle, 0L, SEEK_SET); - char *string = malloc(length * sizeof(char)); + char *string = malloc((length + 1) * sizeof(char)); if (!fread(string, sizeof(char), length, handle)) { printf("failed to read shader file\n"); exit(1); } + // I love C + string[length] = '\0'; fclose(handle); GLuint shader = create_shader(string); - //if (shader == 0) { - // // print file - // int line_count = 1; - // printf("%i\t", line_count); - // line_count++; - // for (int i = 0; i < length; i++) { - // printf("%c", string[i]); - // if (string[i] == '\n') { - // printf("%i\t", line_count); - // line_count++; - // } - // } - // printf("\n"); - //} + if (shader == 0) { + // print file + int line_count = 1; + printf("%i\t", line_count); + line_count++; + for (int i = 0; i < length; i++) { + printf("%c", string[i]); + if (string[i] == '\n') { + printf("%i\t", line_count); + line_count++; + } + } + printf("\n"); + } free(string); return shader; @@ -147,11 +149,8 @@ int shader_file_was_modified(Renderer *state) { /// shader_path cannot be NULL. void render(Renderer *state, int w, int h, double time, char *shader_path, int reload_shader) { int m = shader_file_was_modified(state); - if (m) { - printf("AWOOGA\n"); - } - if (m || reload_shader || strcmp(state->shader_path, shader_path)) { + printf("reloading!\n"); state->shader = load_shader(shader_path); state->shader_path = shader_path; }