aboutsummaryrefslogtreecommitdiff
path: root/src/main/resources/shaders/vacation.glsl
blob: 567815873b1b6cba533298d4fbaee80558be18c9 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
#version 430
layout(local_size_x = 1, local_size_y = 1) in;

#include <sdf>
#include <noise>
#include <utils>

uniform float seconds = 0;
uniform bool enable_antialiasing = false;
layout(rgba8) uniform readonly image2D noise_texture;
layout(rgba8) uniform writeonly image2D output_image;

const float antialiasing = 0.28;

float sample_noise(in vec2 p) {
  vec4 noise = imageLoad(noise_texture, ivec2(p * imageSize(noise_texture)));
  return noise.x;
}

mat2x2 rot_matrix(float angle) {
  return mat2x2(cos(angle), -sin(angle), sin(angle), cos(angle));
}

vec3 image(vec2 uv) {
  const vec3 sky_color = srgb(0.57, 0.7, 0.91);
  const vec3 dark_water_color = srgb(0.02, 0.36, 0.6);
  const vec3 water_color = srgb(0.05, 0.62, 0.67);
  const vec3 sand_color = srgb(0.73, 0.62, 0.5);
  const vec3 sun_color = srgb(0.97, 0.97, 0.67);
  const vec3 dark_sand_color = srgb(0.38, 0.31, 0.26);
  const vec3 sand_shadow_color = srgb(vec3(0.40, 0.33, 0.28));
  const vec3 sunshine_color = srgb(0.96, 0.78, 0.31);
  const vec3 sunshine_cloud_color = srgb(0.98, 0.64, 0.23);
  const vec3 tree_trunk_color = srgb(0.73, 0.56, 0.46);
  const vec3 dark_tree_trunk_color = srgb(vec3(0.73, 0.56, 0.46) / 2.6);
  const vec3 tree_trunk_ring_color = srgb(vec3(0.73, 0.56, 0.46) / 2.9);
  const vec3 cloud_color = srgb(1, 1, 1);
  const vec3 dark_cloud_color = srgb(0.34, 0.55, 0.71);
  const vec3 leaf_color = srgb(0.0, 0.4, 0.0);

  vec3 color = sky_color;

  vec2 sunpos = vec2(0.2, 0.1);
  float sunsize = 0.05;
  float sun = sdf_circle(uv - sunpos, sunsize);
  float sunshine = sdf_circle((uv - sunpos) * vec2(0.4, 1.2), sunsize) * 3;
  color = mix(color, sunshine_color, 1 - clamp(sunshine, 0, 1));
  color = mix(color, sun_color, step(sun, 0));

  {
    float dark_cloud = clamp(sample_noise((uv + 0.4) * 0.8 + vec2(0.28, 0)) - 0.1, 0, 1);
    color = mix(color, dark_cloud_color, dark_cloud);
    float cloud = clamp(sample_noise((uv + vec2(0.5, 0.5)) * 0.6 + vec2(0.18, 0)) - 0.2, 0, 1);
    color = mix(color, mix(cloud_color, sunshine_cloud_color, 1. - clamp(sunshine * 2, 0, 1)), cloud);
  }

  float water = uv.y - 0.03 + sin(uv.x * 3 - 1) * 0.01 + fbm(uv * 40) * 0.004;
  vec2 water_noise_seed = uv - 2;
  vec3 shaded_water_color = water_color;
  shaded_water_color = mix(shaded_water_color, dark_water_color, clamp(exp((uv.y - 0.03) / 0.1), 0, 1));
  vec2 sunrefpos = sunpos - vec2((fbm(30 * water_noise_seed) - 0.6) / 10, 1) * vec2(1, 0.2) + vec2(uv.y * 0.2, 0);
  float sunshine_reflection = sdf_circle(uv - sunrefpos, sunsize - 0.02) * 16;
  float sunshine_reflection_wide = sdf_circle((uv - sunrefpos) * vec2(0.48, 1.6), sunsize) * 16;
  shaded_water_color = mix(shaded_water_color, sunshine_color, 1 - clamp(sunshine_reflection_wide * 0.45, 0, 1));
  shaded_water_color = mix(shaded_water_color, clamp(sun_color * vec3(1, 0.8, 0.8), 0, 1), 1 - clamp(sunshine_reflection, 0, 1));

  color = mix(color, shaded_water_color, step(water, 0));

  vec3 shaded_wet_sand_color = dark_sand_color;
  shaded_wet_sand_color = mix(shaded_wet_sand_color, clamp(dark_sand_color * 1.5, 0, 1), clamp(abs(uv.y * (uv.x - 0.3)) * 4, 0, 1));
  shaded_wet_sand_color = mix(shaded_wet_sand_color, dark_sand_color, clamp(fbm(uv * 600) * fbm(uv * 10 - 8), 0, 1));

  float wet_sand = uv.y + 0.;
  color = mix(color, mix(shaded_wet_sand_color, shaded_water_color, clamp(((uv.y - 0.04) * 4 + 1.2), 0, 1)), step(wet_sand, 0));

  float wshadow_noise = clamp(fbm(80 * water_noise_seed) * noise(8 * water_noise_seed), 0, 1);
  color = mix(color, dark_water_color, step(-uv.y - 0.19, 0) * step(water, 0) * clamp((uv.y - 0.08) * sin((uv.x / 5 + wshadow_noise - 1.84) * sin(uv.y * 2.4) * 40), 0, 1));
  float wfoam_noise = clamp(fbm(100 * water_noise_seed) * noise(8 * water_noise_seed), 0, 1);
  color = mix(color, vec3(1), step(water, 0) * clamp((uv.y - 0.0) * sin((uv.x / 5 + wfoam_noise - 2.2) * sin(uv.y * 2.4) * 25), 0, 1));

  {
    float sand = uv.y - 0.08 + sin(uv.x * 3 + 0.) * 0.09 + fbm(uv * 40) * 0.012 + fbm(uv * 4) * 0.034;
    vec3 shaded_sand_color = sand_color;
    float sand_shine = clamp(abs((uv.y + 0.5) * (uv.x + 0.5) * 12), 0, 1);
    shaded_sand_color = mix(shaded_sand_color, mix(sunshine_color, sand_color, 0.5), sand_shine);
    float sand_shadow = sdf_circle(uv * vec2(0.3, 1) + vec2(0.16, 0.4), 0.1);
    shaded_sand_color = mix(shaded_sand_color, sand_shadow_color, 1 - smoothstep(sand_shadow, -0.1, -0.04));
    shaded_sand_color = mix(shaded_sand_color, dark_sand_color, clamp(fbm(uv * 600) * fbm(uv * 40 + 9), 0, 1));
    color = mix(color, shaded_sand_color, step(sand, -0.33));
  }

  {
    vec2 boatpos = uv - vec2(0.14, 0.0);
    float boatrefgap = 0.012;
    float boatid = clamp(round(boatpos.y / boatrefgap), -1, 0);
    boatpos.y -= boatid * boatrefgap;
    boatid += 1;
    boatpos.y *= boatid * 2 - 1 + (1 - boatid) * 0.4;
    boatpos.x += (1 - boatid) * (0.02 * wfoam_noise + boatpos.y * 0.3);
    float boatsize = 0.005;
    float boatsail = sdf_box(boatpos - vec2(-1.8 + boatpos.y * 20, 5.3) * boatsize, vec2(2 * (1 - boatpos.y * 18), 4) * boatsize, 0.006);
    boatsail = min(boatsail, sdf_box(boatpos - vec2(-1.0, 1) * boatsize, vec2(0.4, 2) * boatsize, 0.0));
    float boat = sdf_box(boatpos - vec2(boatpos.y * 50, -0.1) * boatsize, vec2(5 * (1 + boatpos.y * 20), 1.2) * boatsize, 0.0);
    vec3 boat_refl_color = mix(shaded_water_color, vec3(0), clamp(uv.y * 2 + 0.5, 0, 1));
    color = mix(color, mix(boat_refl_color, vec3(0), boatid), step(min(boatsail, boat), 0));
  }

  {
    vec2 islandpos = uv * vec2(0.25, 1.0) + vec2(0.06, -0.00);
    float island = sdf_circle(islandpos, 0.05 - fbm((islandpos + 0.09) * 27) * 0.04);
    vec3 shaded_island_color = sand_color;
    shaded_island_color = mix(shaded_island_color, clamp(dark_sand_color * 1.5, 0, 1), clamp(abs(uv.y * (uv.x - 0.3)) * 4, 0, 1));
    shaded_island_color = mix(shaded_island_color, dark_sand_color, clamp(fbm(uv * 600) * fbm(uv * 10 - 8), 0, 1));
    color = mix(color, shaded_island_color, step(island, -0.01));
  }

  {
    float treesize = 0.01;
    vec2 treepos = uv - vec2(-15, 3) * treesize;
    float trunk = sdf_box(treepos - vec2(sin(uv.y * 30 - 1.5), 0) * treesize,
        treesize * vec2(0.2 + abs((uv.y - 0.03) * 5 - 0.3) * 0.3, 2.4),
        0.003);
    vec3 shaded_trunk_color = dark_tree_trunk_color;
    color = mix(color, shaded_trunk_color, step(trunk, 0));

    vec2 leafpos = treepos - vec2(0.1, 2.6) * treesize;
    vec2 lp = leafpos * 200.0 + vec2(0, fbm(leafpos * 600) - 0.5);
    float leafs = cos(atan((lp.y + 0.25 * lp.x * lp.x) / lp.x) * 20) + 0.4;
    float leafbox = sdf_box(leafpos + 0.018 * (fbm(leafpos * 100) - 0.5), (vec2(2.1, 1.6) + 1.0 * fbm(leafpos * 20)) * treesize, 1.4 * treesize);
    leafs = max(-leafs, leafbox);
    vec3 shaded_leaf_color = mix(leaf_color, mix(leaf_color, sunshine_color, 0.2), clamp((leafpos.x - 0.016) * 500, 0, 1));
    shaded_leaf_color = mix(mix(leaf_color, vec3(0), 0.6), shaded_leaf_color, clamp(((leafpos.y + 0.028) + 2 * leafpos.x) * 500, 0, 1));
    color = mix(color, shaded_leaf_color, step(leafs, 0));
  }

  return color;
}

vec3 antialiased_image(vec2 uv) {
  vec2 resolution = vec2(imageSize(output_image).xy);
  float s = antialiasing / max(resolution.x, resolution.y);
  vec3 sum = vec3(0);
  int count = 0;
  for (int i = -2; i < 2; i++)
    for (int j = -2; j < 2; j++, count++)
      sum += image(uv + vec2(i, j) * s);
  return sum / count;
}

void main() {
  vec2 resolution = vec2(imageSize(output_image).xy);
  float aspect_ratio = resolution.y / resolution.x;
  vec2 uv = (gl_GlobalInvocationID.xy - resolution * 0.5) * vec2(1.0, aspect_ratio) / resolution;

  vec3 color = enable_antialiasing ? antialiased_image(uv) : image(uv);
  imageStore(output_image, ivec2(gl_GlobalInvocationID.xy), vec4(color, 1));
}