-
Notifications
You must be signed in to change notification settings - Fork 5
/
Copy pathteleport_effect.shadron
221 lines (172 loc) · 6.24 KB
/
teleport_effect.shadron
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
#include <math_constants>
#include <affine_transform>
#include <linearstep>
#include <multisample>
#include <perlin>
#extension ffmpeg
#extension gif
// Near/far values for projection (minimum and maximum draw distance)
const float NEAR = 1.0/256.0, FAR = 256.0;
const int WAVECOUNT = 4;
const ivec2 RESOLUTION = ivec2(512, 512);
param int Sections = 80 : range(4, 80);
param float Width = 0.056 : range(0.02, 0.3);
param float Spacing = 4 : range(1, 10);
param float Strength = 32 : range(1, 60);
param vec3 Color = vec3(1) : color();
param bool Wireframe = false;
#define Vertices (2+Sections*2)
glsl struct WaveParticleData {
float index;
float height;
float time;
};
glsl struct FragmentData {
float height;
};
glsl vec4 vertexShader(int index, float time, float offset, float shift) {
const float multiplier = 0.4;
int edgeIndex = int(index / 2);
float radius = 1 + (index % 2)*Width - offset*0.4;
vec3 coord = vec3(radius, offset*Spacing, radius);
float timeAdj = time * 1.5 + shift * 5;
coord = rotateY(coord, TAU/Sections * edgeIndex);
float edgeWrapped = (edgeIndex % Sections) / float(Sections) * Strength;
coord = translate(coord, vec3(
sin((edgeWrapped * 0.05 + 0.381)*20 + timeAdj) * 0.2, // In/out
sin(edgeWrapped * 0.5 + timeAdj) * sin(edgeWrapped * 0.05 + timeAdj) * 0.3, // Up/down
sin(edgeWrapped * 0.1 + timeAdj) * 0.05)); // Along edge
coord = rotateY(coord, time*0.5);
coord = rotateX(coord, 0.3);
coord = translate(coord, vec3(0, -2, -7.0));
float fov = 0.5*PI-atan(0.75+0.0625*shadron_Mouse.z);
return projectPerspectiveHFOV(coord, fov, NEAR, FAR);
}
glsl vec4 m_vert(out FragmentData fd, int index, float time) {
fd.height = 0.5;
return vertexShader(index, time, 0, 0);
}
glsl vec3 fragmentShader(in FragmentData fd) {
const vec3 transparent = vec3(0);
float heightFade = 0.8 * linearstep(0, 0.15, fd.height) * linearstep(1, 0.9, fd.height);
return mix(transparent, Color, heightFade);
}
glsl vec4 p_vert(out FragmentData fd, in WaveParticleData p, int index) {
fd.height = p.height;
return vertexShader(index, p.time, p.height, p.index);
}
glsl void initialize(out WaveParticleData p, int i) {
p.index = i;
p.height = float(i) / WAVECOUNT;
p.time = i * 2;
}
glsl void update(inout WaveParticleData p, float dt) {
p.time += dt;
p.height = mod(p.height + dt / 3, 1);
}
model WaveCircle :
vertex_animated(m_vert, triangle_strip, Vertices),
fragment_data(FragmentData),
fragment(fragmentShader),
wireframe(Wireframe);
particle_system animation WaveParticles :
dimensions(RESOLUTION),
particle_data(WaveParticleData),
initialize(initialize),
update(update),
vertex(p_vert, triangle_strip, Vertices),
fragment_data(FragmentData),
fragment(fragmentShader),
count(WAVECOUNT),
background(vec3(0.0)),
multisample(4);
glsl struct DustParticleData {
vec2 pos;
float phase;
float size;
};
glsl float random(int seed, int salt) {
vec2 pCoord = mod(vec2(1949.1797*float(seed), 33.1478221*float(salt)), 1823.5355121);
return 0.5*(perlinNoise(pCoord)+1.0);
}
glsl void particle_initialize(out DustParticleData p, int i) {
p.pos = vec2(random(i, 0) - 0.5, random(i, 1) - 0.5) * vec2(1.5, 12);
p.phase = TAU*random(i, 2);
float baseSize = 0.05+random(i, 3) * 0.05;
p.size = 0.15*baseSize;
}
glsl void particle_update(inout DustParticleData p, float dt) {
float y = 0.5*(1.0-p.pos.y);
p.pos += dt*vec2(sin(p.phase)*0.05, 0.45);
p.pos = mod(p.pos+1, 2)-1;
p.phase += dt;
}
const int particleVertexCount = 16;
glsl vec2 vertex(out float height, in DustParticleData p, int i) {
vec2 coord = vec2(0.0);
if (i > 0) {
float a = 1.0/(particleVertexCount-2)*TAU*float(i-1);//+p.rot;
float aspect = shadron_PixelSize.x/shadron_PixelSize.y;
coord = p.size*vec2(aspect*sin(a), cos(a));
}
coord = p.pos+coord;
height = p.pos.y * 0.8 + 0.5;
return coord;
}
glsl vec3 fragment(in float height) {
const vec3 transparent = vec3(0);
float heightFade = 0.6 * linearstep(0, 0.15, height) * linearstep(1, 0.9, height);
return mix(transparent, Color, heightFade);
}
const int PARTICLE_COUNT = 10;
particle_system animation Particles :
dimensions(RESOLUTION),
particle_data(DustParticleData),
fragment_data(vec3),
initialize(particle_initialize),
update(particle_update),
vertex(vertex, triangle_fan, particleVertexCount),
fragment_data(float),
fragment(fragment),
count(PARTICLE_COUNT),
background(vec3(0.0)),
blend(additive),
multisample(4);
glsl vec4 combinedOutput(vec2 pos, float time) {
vec4 p1 = texture(WaveParticles, pos);
vec4 p2 = texture(Particles, pos);
return p1 + p2;
}
animation Combined = glsl(combinedOutput, RESOLUTION);
param int STEPS = 8;
param float SIGMA = 0.288;
param float blurRange = 4 : range(64);
const vec2 DIRECTION = vec2(1, 0.0);
#define PXSIZE shadron_PixelSize
glsl float blurWeight(float x) {
return exp(-0.5*(x*x)/(SIGMA*SIGMA));
}
glsl vec4 blurredOutput(vec2 pos, float time) {
vec4 total = vec4(0.0);
float totalWeight = 0.0;
for (int step = -STEPS; step <= STEPS; ++step) {
vec2 texCoord = pos + DIRECTION*float(step)/float(STEPS)*blurRange*PXSIZE;
float weight = blurWeight(float(step)/float(STEPS));
total += weight*texture(Combined, texCoord);
totalWeight += weight;
}
return total / totalWeight;
}
animation Blurred = glsl(blurredOutput, RESOLUTION) : map(clamp);
glsl vec4 finalOutput(vec2 pos, float time) {
vec2 toCenter = pos - vec2(0.5);
float vignette = 1.2 - sqrt(toCenter.x * toCenter.x + toCenter.y * toCenter.y);
vec3 backgroundColor = vec3(0.6, 0.6, 0.65);
vec4 effectTexture = texture(Blurred, pos);
vec4 combined = (vec4(backgroundColor, 1 - effectTexture.a) + effectTexture);
return vec4(vec3(combined.xyz * vignette), 1);
}
animation Final = glsl(multisampleAnimation<finalOutput, 4, 4>, RESOLUTION) : map(clamp);
//animation QuantizedOutputAnimation = quantize(Final, 64);
//export gif(QuantizedOutputAnimation, "output/teleport_effect.gif", 30, 6, true);
export mp4(Final, "output/teleport_effect.mp4", h264, yuv420, "preset=slow,crf=4", 30, 8);