~vladh/peony

peony/src_shaders/common.glsl -rw-r--r-- 11.2 KiB
7fc9922bVlad-Stefan Harbuz changes shaders namespace into class a month ago
                                                                                
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
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
/*
  Peony Game Engine
  Copyright (C) 2020 Vlad-Stefan Harbuz <vlad@vladh.net>
  All rights reserved.
*/

#version 410 core

#define M_PI 3.14159265358979323846
#define M_EPSILON 1e-5
#define MAX_N_LIGHTS 8
#define MAX_N_BONES_PER_VERTEX 4
#define MAX_N_BONES 128
#define SHOULD_CALCULATE_TANGENT_IN_VERTEX_SHADER 0
#define USE_BLOOM 1
#define USE_FOG 0

#define LIGHT_POINT 1
#define LIGHT_DIRECTIONAL 2

#define TEXTURETYPE_NONE 0
#define TEXTURETYPE_ALBEDO 1
#define TEXTURETYPE_METALLIC 2
#define TEXTURETYPE_ROUGHNESS 3
#define TEXTURETYPE_AO 4
#define TEXTURETYPE_NORMAL 5
#define TEXTURETYPE_SHADOWMAPS_3D 6
#define TEXTURETYPE_SHADOWMAPS_2D 7
#define TEXTURETYPE_OTHER 8
#define TEXTURETYPE_G_POSITION 9
#define TEXTURETYPE_G_NORMAL 10
#define TEXTURETYPE_G_ALBEDO 11
#define TEXTURETYPE_G_PBR 12
#define TEXTURETYPE_L_COLOR 13
#define TEXTURETYPE_L_BRIGHT_COLOR 14
#define TEXTURETYPE_L_DEPTH 15
#define TEXTURETYPE_BLUR1 16
#define TEXTURETYPE_BLUR2 17

layout (std140) uniform shader_common {
  mat4 view;
  mat4 projection;
  mat4 ui_projection;
  mat4 shadowmap_3d_transforms[6 * MAX_N_LIGHTS];
  mat4 shadowmap_2d_transforms[MAX_N_LIGHTS];

  vec3 camera_position;
  float camera_pitch;

  float camera_horizontal_fov;
  float camera_vertical_fov;
  float camera_near_clip_dist;
  float camera_far_clip_dist;

  int n_point_lights;
  int n_directional_lights;
  int current_shadow_light_idx;
  int current_shadow_light_type;

  float shadow_far_clip_dist;
  bool is_blur_horizontal;
  int renderdebug_displayed_texture_type;
  int unused_pad;

  float exposure;
  float t;
  int window_width;
  int window_height;

  vec4 point_light_position[MAX_N_LIGHTS];
  vec4 point_light_color[MAX_N_LIGHTS];
  vec4 point_light_attenuation[MAX_N_LIGHTS];

  vec4 directional_light_position[MAX_N_LIGHTS];
  vec4 directional_light_direction[MAX_N_LIGHTS];
  vec4 directional_light_color[MAX_N_LIGHTS];
  vec4 directional_light_attenuation[MAX_N_LIGHTS];
};

/* uniform float BLUR_WEIGHTS[5] = float[] ( */
/*   0.227027, 0.1945946, 0.1216216, 0.054054, 0.016216 */
/* ); */
uniform float BLUR_WEIGHTS[3] = float[] (
  0.2270270270, 0.3162162162, 0.0702702703
);
uniform float BLUR_OFFSETS[3] = float[] (
  0.0, 1.3846153846, 3.2307692308
);

struct WaveParameterSet {
  vec2 direction;
  float amplitude;
  float steepness;
  float frequency;
  float speed;
};

const int N_WAVES = 19;
const float a = 0.9; // amplitude factor
WaveParameterSet WAVE_PARAMETER_SETS[N_WAVES] = WaveParameterSet[N_WAVES](
  // Choppy small waves
  /* WaveParameterSet(vec2(0.8, 0.1),  0.02 * amplitude_factor, 0.001, 7.8, 0.5), */
  /* WaveParameterSet(vec2(0.2, 0.0),  0.03 * amplitude_factor, 0.003, 5.2, 0.3), */
  /* WaveParameterSet(vec2(0.0, 1.0),  0.02 * amplitude_factor, 0.002, 4.3, 0.1) */
  // Choppy small waves v2
  WaveParameterSet(vec2(1.0 + sin(t / 12) / 8, 0.00 + cos(t / 15) / 5), 0.004 * a, 0.01, 17.8, 0.3 + sin(t / 11) / 400),
  WaveParameterSet(vec2(1.0 + cos(t / 13) / 8, 0.01 + cos(t / 13) / 5), 0.005 * a, 0.03, 15.2, 0.2 + sin(t / 13) / 500),
  WaveParameterSet(vec2(1.0 + cos(t / 12) / 8, 0.02 + cos(t / 12) / 5), 0.004 * a, 0.02, 14.3, 0.1 + sin(t / 12) / 600),
  WaveParameterSet(vec2(0.0 + sin(t / 11) / 8, 1.00 + cos(t / 11) / 5), 0.005 * a, 0.01, 15.8, 0.4 + sin(t / 13) / 700),
  WaveParameterSet(vec2(0.1 + cos(t / 14) / 8, 1.00 + cos(t / 14) / 5), 0.004 * a, 0.03, 14.2, 0.2 + sin(t / 11) / 400),
  WaveParameterSet(vec2(0.2 + sin(t / 13) / 8, 1.00 + cos(t / 16) / 5), 0.005 * a, 0.02, 13.3, 0.1 + sin(t / 12) / 700),
  WaveParameterSet(vec2(0.4 + sin(t / 12) / 8, 0.06 + cos(t / 15) / 5), 0.005 * a, 0.02, 13.8, 0.2 + sin(t / 15) / 800),
  WaveParameterSet(vec2(0.4 + cos(t / 13) / 8, 0.06 + cos(t / 17) / 5), 0.004 * a, 0.03, 11.2, 0.2 + sin(t / 15) / 900),
  WaveParameterSet(vec2(0.4 + cos(t / 15) / 8, 0.06 + cos(t / 18) / 5), 0.005 * a, 0.02, 12.3, 0.1 + sin(t / 13) / 700),
  // Steep high-frequency waves
  WaveParameterSet(vec2(0.30, 0.50), 0.1 * a, 1.20, 5.3, 0.1),
  WaveParameterSet(vec2(0.30, 0.50), 0.1 * a, 1.20, 4.3, 0.1),
  WaveParameterSet(vec2(0.60, 0.10), 0.1 * a, 1.20, 4.3, 0.2),
  WaveParameterSet(vec2(0.60, 0.10), 0.1 * a, 1.20, 3.3, 0.2),
  // Big waves
  WaveParameterSet(vec2(0.00, 0.80), 0.3 * a, 0.41, 0.8, 0.8),
  WaveParameterSet(vec2(0.80, 0.00), 0.3 * a, 0.31, 0.9, 0.7),
  WaveParameterSet(vec2(0.10, 0.70), 0.3 * a, 0.25, 0.9, 1.5),
  WaveParameterSet(vec2(0.75, 0.10), 0.2 * a, 0.12, 0.8, 0.5),
  WaveParameterSet(vec2(0.50, 0.50), 0.2 * a, 0.20, 0.3, 0.1),
  // Slow large waves
  WaveParameterSet(vec2(0.5, 0.5),  0.3 * a, 0.12, 0.4, 0.25)
);

vec3 water_make_normal_gerstner_osgw(vec3 water_position) {
  vec3 wave_normal = vec3(0.0, 1.0, 0.0);

  for (int idx = 0; idx < N_WAVES; idx++) {
    float proj = dot(water_position.xz, WAVE_PARAMETER_SETS[idx].direction);
    float phase = t * WAVE_PARAMETER_SETS[idx].speed;
    float psi = proj * WAVE_PARAMETER_SETS[idx].frequency + phase;
    float amp_freq = WAVE_PARAMETER_SETS[idx].amplitude *
      WAVE_PARAMETER_SETS[idx].frequency;
    float alpha = amp_freq * sin(psi);

    wave_normal.y -= WAVE_PARAMETER_SETS[idx].steepness * alpha;

    float x = WAVE_PARAMETER_SETS[idx].direction.x;
    float y = WAVE_PARAMETER_SETS[idx].direction.y;
    float omega = amp_freq * cos(psi);

    wave_normal.x -= x * omega;
    wave_normal.z -= y * omega;
  }

  return wave_normal;
}

vec3 water_make_position_gerstner_osgw(vec2 vertex_position) {
  vec3 wave_position = vec3(vertex_position.x, 0, vertex_position.y);

  for (int idx = 0; idx < N_WAVES; idx++) {
    float proj = dot(vertex_position, WAVE_PARAMETER_SETS[idx].direction);
    float phase = t * WAVE_PARAMETER_SETS[idx].speed;
    float theta = proj * WAVE_PARAMETER_SETS[idx].frequency + phase;
    float height = WAVE_PARAMETER_SETS[idx].amplitude * sin(theta);

    wave_position.y += height;

    float maximum_width = WAVE_PARAMETER_SETS[idx].steepness *
      WAVE_PARAMETER_SETS[idx].amplitude;
    float width = maximum_width * cos(theta);
    float x = WAVE_PARAMETER_SETS[idx].direction.x;
    float y = WAVE_PARAMETER_SETS[idx].direction.y;

    wave_position.x += x * width;
    wave_position.z += y * width;
  }

  return wave_position;
}

// (x, y) = vertex_position
// Q = steepness
// A = amplitude
// D = direction
// L = wavelength
// S = speed
// w = frequency = 2 / L
// phi = phase-constant = S * w
vec3 water_make_position_gerstner_vlad(vec2 vertex_position) {
  vec3 wave_position = vec3(vertex_position.x, 0, vertex_position.y);

  for (int idx = 0; idx < N_WAVES; idx++) {
    float amplitude = WAVE_PARAMETER_SETS[idx].amplitude;
    float frequency = WAVE_PARAMETER_SETS[idx].frequency;
    vec2 direction = WAVE_PARAMETER_SETS[idx].direction;
    float speed = WAVE_PARAMETER_SETS[idx].speed;
    float phi = speed * frequency;
    float steepness = WAVE_PARAMETER_SETS[idx].steepness;

    float sin_cos_argument = dot(frequency * direction, vertex_position) + phi * t;

    wave_position.x += steepness * amplitude * direction.x *
      cos(sin_cos_argument);
    wave_position.z += steepness * amplitude * direction.y *
      cos(sin_cos_argument);
    wave_position.y += amplitude *
      sin(sin_cos_argument);
  }

  return wave_position;
}

// P = wave position
// WA = w * A
// S() = sin term
// C() = cos term
vec3 water_make_normal_gerstner_vlad(
  vec3 wave_position, out vec3 normal, out vec3 bitangent, out vec3 tangent
) {
  normal = vec3(0.0, 1.0, 0.0);
#if SHOULD_CALCULATE_TANGENT_IN_VERTEX_SHADER
  bitangent = vec3(1.0, 0.0, 0.0);
  tangent = vec3(0.0, 0.0, 1.0);
#endif

  for (int idx = 0; idx < N_WAVES; idx++) {
    float amplitude = WAVE_PARAMETER_SETS[idx].amplitude;
    float frequency = WAVE_PARAMETER_SETS[idx].frequency;
    vec2 direction = WAVE_PARAMETER_SETS[idx].direction;
    float speed = WAVE_PARAMETER_SETS[idx].speed;
    float phi = speed * frequency;
    float steepness = WAVE_PARAMETER_SETS[idx].steepness;

    float wa = frequency * amplitude;
    float sin_cos_argument = frequency * dot(direction, wave_position.xz) + phi * t;
    float sin_term = sin(sin_cos_argument);
    float cos_term = cos(sin_cos_argument);

    normal.x -= direction.x * wa * cos_term;
    normal.z -= direction.y * wa * cos_term;
    normal.y -= steepness * wa * sin_term;

#if SHOULD_CALCULATE_TANGENT_IN_VERTEX_SHADER
    bitangent.x -= steepness * pow(direction.x, 2) * wa * sin_term;
    bitangent.y += direction.x * wa * cos_term;
    bitangent.z -= steepness * direction.x * direction.y * wa * sin_term;

    tangent.x -= steepness * direction.x * direction.y * wa * sin_term;
    tangent.y += direction.y * wa * cos_term;
    tangent.z -= steepness * pow(direction.y, 2) * wa * sin_term;
#endif
  }

  return normalize(normal);
}

vec3 water_make_position(vec2 vertex_position) {
  return water_make_position_gerstner_vlad(vertex_position);
}

vec3 water_make_normal(
  vec3 water_position, inout vec3 normal, inout vec3 bitangent, inout vec3 tangent
) {
  return water_make_normal_gerstner_vlad(water_position, normal, bitangent, tangent);
}

float normalize_angle(float angle) {
  if (angle > 90.0) {
    return 180.0 - angle;
  }
  if (angle < -90.0) {
    return -180.0 - angle;
  }
  return angle;
}

float linearize_depth(float depth, float near_clip_dist, float far_clip_dist) {
  float z = depth * 2.0 - 1.0;
  return (2.0 * near_clip_dist * far_clip_dist) /
    (far_clip_dist + near_clip_dist - z * (far_clip_dist - near_clip_dist));
}

float to_unit_interval(float x, float min_val, float max_val) {
  return clamp(
    (x - min_val) / (max_val - min_val),
    0, 1
  );
}

float hash(vec2 p) {
  // https://stackoverflow.com/q/12964279/3803222
  float h = dot(p, vec2(127.1,311.7));
  return fract(sin(h) * 43758.5453123);
}


vec2 hash_iq(vec2 x) {
  const vec2 k = vec2(0.3183099, 0.3678794);
  x = x * k + k.yx;
  return -1.0 + 2.0 * fract(16.0 * k * fract(x.x * x.y * (x.x + x.y)));
}


vec3 noised(vec2 x) {
  // https://www.iquilezles.org/www/articles/gradientnoise/gradientnoise.htm
  vec2 i = floor(x);
  vec2 f = fract(x);

  vec2 u = f * f * f * (f * (f * 6.0 - 15.0) + 10.0);
  vec2 du = 30.0 * f * f * (f * (f - 2.0) + 1.0);

  vec2 ga = hash_iq(i + vec2(0.0, 0.0));
  vec2 gb = hash_iq(i + vec2(1.0, 0.0));
  vec2 gc = hash_iq(i + vec2(0.0, 1.0));
  vec2 gd = hash_iq(i + vec2(1.0, 1.0));

  float va = dot(ga, f - vec2(0.0, 0.0));
  float vb = dot(gb, f - vec2(1.0, 0.0));
  float vc = dot(gc, f - vec2(0.0, 1.0));
  float vd = dot(gd, f - vec2(1.0, 1.0));

  return vec3(
    // Value
    va + u.x * (vb - va) + u.y * (vc - va) + u.x * u.y * (va - vb - vc + vd),
    // Derivatives
    ga + u.x * (gb - ga) + u.y * (gc - ga) + u.x * u.y * (ga - gb - gc + gd) +
    du * (u.yx * (va - vb - vc + vd) + vec2(vb, vc) - va)
  );
}



vec2 random2(vec2 st){
  st = vec2(
    dot(st, vec2(127.1, 311.7)),
    dot(st, vec2(269.5, 183.3))
  );
  return -1.0 + 2.0 * fract(sin(st) * 43758.5453123);
}


float noise(vec2 st) {
  // Gradient Noise by Inigo Quilez - iq/2013
  // https://www.shadertoy.com/view/XdXGW8
  vec2 i = floor(st);
  vec2 f = fract(st);

  vec2 u = f * f * (3.0 - 2.0 * f);

  return mix(
    mix(
      dot(random2(i + vec2(0.0, 0.0)), f - vec2(0.0, 0.0)),
      dot(random2(i + vec2(1.0, 0.0)), f - vec2(1.0, 0.0)),
      u.x
    ),
    mix(
      dot(random2(i + vec2(0.0, 1.0)), f - vec2(0.0, 1.0)),
      dot(random2(i + vec2(1.0, 1.0)), f - vec2(1.0, 1.0)),
      u.x
    ),
    u.y
  );
}