-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathwarpedFbm.comp
153 lines (123 loc) · 4.67 KB
/
warpedFbm.comp
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
//GLSL version to use
#version 460
#ifdef GL_ES
precision mediump float;
#endif
//size of a workgroup for compute
layout (local_size_x = 16, local_size_y = 16) in;
//descriptor bindings for the pipeline
layout(rgba16f, set = 0, binding = 0) uniform image2D image;
//push constants
layout( push_constant ) uniform constants
{
float uv_scale;
int fbm_octaves;
float fbm_amplitude;
float fbm_frequency;
float fbm_lacunarity;
float fbm_gain;
float fbm_shift;
float time;
int warp_iterations;
int warp_strength;
int warp_colorShade;
int warp_tintShade;
int warp_colorBalance;
float warp_tintStrength;
float th;
float fo;
vec2 uv_offset;
vec2 warp_offset;
vec4 warp_primaryColor;
vec4 warp_secondaryColor;
vec4 warp_tintColor;
} PushConstants;
/// Pseudo random number generator
/// by Patricio Gonzalez Vivo & Jen Lowe
/// https://thebookofshaders.com/10/
float hash (vec2 v) {
return fract(sin(dot(v.xy, vec2(12.9898,78.233))) * 10);
}
/// 2D Noise
/// Morgan McGuire
/// https://www.shadertoy.com/view/4dS3Wd
float noise(vec2 x) {
vec2 i = floor(x);
vec2 f = fract(x);
// Four corners in 2D of a tile
float a = hash(i);
float b = hash(i + vec2(1.0, 0.0));
float c = hash(i + vec2(0.0, 1.0));
float d = hash(i + vec2(1.0, 1.0));
// Simple 2D lerp using smoothstep envelope between the values.
// return vec3(mix(mix(a, b, smoothstep(0.0, 1.0, f.x)),
// mix(c, d, smoothstep(0.0, 1.0, f.x)),
// smoothstep(0.0, 1.0, f.y)));
// Same code, with the clamps in smoothstep and common subexpressions
// optimized away.
vec2 u = f * f * (3.0 - 2.0 * f);
return mix(a, b, u.x) + (c - a) * u.y * (1.0 - u.x) + (d - b) * u.x * u.y;
}
/// Adapted Fractal Brownian Motion
/// from Patricio Gonzalez Vivo & Jen Lowe | Morgan McGuire
/// https://thebookofshaders.com/13/
/// https://www.shadertoy.com/view/4dS3Wd
float fbm(vec2 x) {
float amplitude = PushConstants.fbm_amplitude;
float frequency = PushConstants.fbm_frequency;
float lacunarity = PushConstants.fbm_lacunarity;
float gain = PushConstants.fbm_gain;
float shift = PushConstants.fbm_shift;
float color = 0.0;
// Rotate to reduce axial bias
mat2 rot = mat2(cos(0.5), sin(0.5), -sin(0.5), cos(0.50));
// Loop of octaves
for (int i = 0; i < PushConstants.fbm_octaves; i++) {
color += amplitude * noise(frequency * x);
x = rot * x * shift;
frequency *= lacunarity;
amplitude *= gain;
}
return color;
}
vec3 warpColor(vec2 x) {
vec2 offset = PushConstants.warp_offset;//vec2(1.23, 4.56);
vec2 q = vec2( fbm( x + offset),
fbm( x + 2 * offset));
for (int i = 0; i < PushConstants.warp_iterations; i++) {
q = vec2( fbm( x + q * PushConstants.warp_strength + (i * offset)),
fbm( x + q * PushConstants.warp_strength + (2 * i * offset) ) );
}
float f = fbm( x + q * PushConstants.warp_strength );
vec3 color = mix(PushConstants.warp_primaryColor.xyz,
PushConstants.warp_secondaryColor.xyz,
clamp(pow(f, PushConstants.warp_colorBalance), 0.0, 1.0));
//clamp(f, 0.0, 1.0));
//clamp(f*f*f*f * PushConstants.warp_colorBalance, 0.0, 1.0));
//clamp(pow(f, PushConstants.warp_colorShade) * PushConstants.warp_colorBalance, 0.0, 1.0));
//clamp(pow(f, PushConstants.warp_colorShade) + 0.25 * pow(f, PushConstants.warp_colorShade) / PushConstants.warp_colorShade + PushConstants.warp_colorBalance, 0.0, 1.0));
//clamp(smoothstep(0.0, 1.0, pow(f, PushConstants.warp_colorShade)) * PushConstants.warp_colorStrength, 0.0, 1.0));
//clamp((f*f*f + 0.5 * f * f + 0.25 * f) * PushConstants.warp_colorBalance, 0.0, 1.0));
//clamp(pow(f, PushConstants.warp_colorShade) * PushConstants.warp_colorStrength, 0.0, 1.0));
color = mix(color,
PushConstants.warp_tintColor.xyz,
clamp(pow(length(q), PushConstants.warp_tintShade) * PushConstants.warp_tintStrength, 0.0, 1.0));
return color;
}
void main()
{
ivec2 texCoord = ivec2(gl_GlobalInvocationID.xy);
vec2 imgSize = imageSize(image);
// Calculate uv
vec2 uv = texCoord / imgSize;
uv.x *= imgSize.x / imgSize.y;
uv.y = 1 - uv.y;
// Modify uv
uv.x = uv.x * PushConstants.uv_scale + PushConstants.uv_offset.x;
uv.y = uv.y * PushConstants.uv_scale + PushConstants.uv_offset.y;
vec3 w = warpColor(uv);
vec4 color = vec4(w.xyz, 1.0);
// Gamma correction
color = vec4(pow(color.xyz,vec3(1./2.2)), 1.0);
imageStore(image, texCoord, color);
}