Skip to content

Commit 7b13226

Browse files
author
Matt Henderson
authored
add noise dodec animation (#2)
1 parent 67965ca commit 7b13226

File tree

5 files changed

+178
-3
lines changed

5 files changed

+178
-3
lines changed

.devcontainer/devcontainer.json

+2-1
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,8 @@
66
"image": "mcr.microsoft.com/devcontainers/typescript-node:1-20-bullseye",
77
// Features to add to the dev container. More info: https://containers.dev/features.
88
"features": {
9-
"ghcr.io/devcontainers-contrib/features/pnpm:2": {}
9+
"ghcr.io/devcontainers-contrib/features/pnpm:2": {},
10+
"ghcr.io/devcontainers-contrib/features/tmux-apt-get": {}
1011
},
1112
// Use 'forwardPorts' to make a list of ports inside the container available locally.
1213
"forwardPorts": [

.vscode/settings.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -5,5 +5,5 @@
55
"typescript",
66
"typescriptreact",
77
],
8-
"webgl-glsl-editor.format.placeSpaceAfterKeywords": true
8+
"webgl-glsl-editor.format.placeSpaceAfterKeywords": true,
99
}

src/animations/noiseDodecahedron.tsx

+94
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,94 @@
1+
// @ts-ignore
2+
import { GlslPipeline } from 'glsl-pipeline';
3+
import { WebGLRenderer } from 'three';
4+
5+
import { Animation, DrawArgs, DrawFn, MakeDrawFn, Parameter } from 'lib/Animation';
6+
import Utils from 'lib/utils';
7+
8+
import shader from './shaders/noiseDodecahedron.glsl';
9+
10+
const NoiseDodecahedron = () => {
11+
const duration = 20;
12+
13+
const canvasWidth = 768;
14+
const canvasHeight = 768;
15+
16+
const parameters: Parameter[] = [
17+
{
18+
name: 'theta_1',
19+
minValue: 0,
20+
maxValue: 2 * Math.PI,
21+
defaultValue: 0,
22+
compute: Utils.makeTransitionFunction([
23+
{
24+
easing: 'linear',
25+
startT: 0,
26+
endT: 20,
27+
startValue: 0.0,
28+
endValue: 0.1,
29+
},
30+
]),
31+
},
32+
{
33+
name: 'theta_2',
34+
minValue: 0,
35+
maxValue: 2 * Math.PI,
36+
defaultValue: 0,
37+
compute: Utils.makeTransitionFunction([
38+
{
39+
easing: 'linear',
40+
startT: 0,
41+
endT: 20,
42+
startValue: 1.0,
43+
endValue: 3.0,
44+
},
45+
]),
46+
},
47+
];
48+
49+
const makeDrawFn: MakeDrawFn = (canvas) => {
50+
const renderer = new WebGLRenderer({
51+
canvas,
52+
});
53+
let pipeline = new GlslPipeline(renderer, {
54+
u_t: { value: 0 },
55+
u_theta_1: { value: 0 },
56+
u_theta_2: { value: 0 },
57+
u_update: { value: 0 },
58+
});
59+
pipeline.load(shader);
60+
pipeline.renderMain();
61+
let lastUpdate = -1;
62+
63+
const drawFn: DrawFn = ({ t, theta_1, theta_2 }: DrawArgs) => {
64+
if (t == 0) {
65+
Utils.resetGlslPipeline(pipeline);
66+
lastUpdate = -1;
67+
}
68+
pipeline.uniforms.u_t.value = t;
69+
pipeline.uniforms.u_theta_1.value = theta_1;
70+
pipeline.uniforms.u_theta_2.value = theta_2;
71+
let update: number = 0;
72+
if (t - lastUpdate > 0.04) {
73+
update = 1;
74+
lastUpdate = t;
75+
}
76+
pipeline.uniforms.u_update.value = update;
77+
pipeline.renderMain();
78+
};
79+
80+
return drawFn;
81+
};
82+
83+
return (
84+
<Animation
85+
duration={duration}
86+
initialCanvasWidth={canvasWidth}
87+
initialCanvasHeight={canvasHeight}
88+
makeDrawFn={makeDrawFn}
89+
parameters={parameters}
90+
/>
91+
);
92+
};
93+
94+
export default NoiseDodecahedron;
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
uniform vec2 u_resolution;
2+
uniform float u_t;
3+
uniform float u_theta_1;
4+
uniform float u_theta_2;
5+
uniform float u_update;
6+
uniform sampler2D u_doubleBuffer0;
7+
8+
// Tells GlslPipeline that we are using the double buffer:
9+
#ifdef DOUBLE_BUFFER_0
10+
#endif
11+
12+
#define res 128.0
13+
#define rate 2
14+
#define TWOPI 6.28318530718
15+
16+
vec3 vertices[20] = vec3[](vec3(0, 0, 1), vec3(.58, .33, .75), vec3(0, -.67, .75), vec3(-.58, .33, .75), vec3(.36, .87, .33), vec3(.93, -.13, .33), vec3(.58, -.75, .33), vec3(-.58, -.75, .33), vec3(-.93, -.13, .33), vec3(-.36, .87, .33), vec3(.58, .75, -.33), vec3(.93, .13, -.33), vec3(.36, -.87, -.33), vec3(-.36, -.87, -.33), vec3(-.93, .13, -.33), vec3(-.58, .75, -.33), vec3(0, .67, -.75), vec3(.58, -.33, -.75), vec3(-.58, -.33, -.75), vec3(0, 0, -1));
17+
18+
int seg[] = int[](0, 2, 6, 5, 1 // 3 bottom
19+
, 0, 3, 8, 7, 2, 0, 1, 4, 9, 3, 2, 7, 13, 12, 6 // 6 crown
20+
, 8, 14, 18, 13, 7, 6, 12, 17, 11, 5, 3, 9, 15, 14, 8, 1, 5, 11, 10, 4, 4, 10, 16, 15, 9, 19, 18, 14, 15, 16 // 3 top
21+
, 19, 17, 12, 13, 18, 19, 16, 10, 11, 17);
22+
23+
float hash12(vec2 p) {
24+
vec3 p3 = fract(vec3(p.xyx) * .1031);
25+
p3 += dot(p3, p3.yzx + 33.33);
26+
return fract((p3.x + p3.y) * p3.z);
27+
}
28+
29+
float sdSegment(in vec2 p, in vec2 a, in vec2 b) {
30+
vec2 pa = p - a, ba = b - a;
31+
float h = clamp(dot(pa, ba) / dot(ba, ba), 0.0, 1.0);
32+
return length(pa - ba * h);
33+
}
34+
35+
#define rot(a) mat2(cos(a+vec4(0,33,11,0)))
36+
37+
vec3 T(vec3 p) {
38+
p.yz *= rot(TWOPI * u_theta_1 + 0.21);
39+
p.zx *= rot(TWOPI * u_theta_2 + 0.77);
40+
return p;
41+
}
42+
43+
void main() {
44+
// out vec4 fragColor, in vec2 fragCoord
45+
46+
vec2 uv = gl_FragCoord.xy / u_resolution.xy;
47+
vec2 uvI = floor(uv * res) / res;
48+
49+
vec3 col = texture(u_doubleBuffer0, uv).rgb;
50+
51+
if (u_t < 0.1) {
52+
col = vec3(step(0.5, hash12(u_resolution.xy * uvI)));
53+
}
54+
55+
vec3 _P, P, P0;
56+
float dodecCol = 0.;
57+
uvI -= 0.5;
58+
uvI *= 2.;
59+
for (int i; i <= seg.length(); i++) {
60+
_P = P;
61+
P = T(vertices[seg[i % 60]]);
62+
// P *= exp(iFloat2);
63+
P /= P.z - 1.7;
64+
if (i > 0) {
65+
dodecCol += .5 * smoothstep(0.01, 0., sdSegment(uvI, _P.xy, (i % 5 > 0 ? P : P0).xy) - 0.0001);
66+
}
67+
if (i % 5 < 1) {
68+
P0 = P;
69+
}
70+
}
71+
dodecCol = step(0.5, dodecCol);
72+
73+
col = mix(col, 1. - col, dodecCol * u_update);
74+
75+
gl_FragColor = vec4(step(0.5, col), 1.0);
76+
}

src/index.tsx

+5-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import Minimal2D from 'animations/minimal2D';
22
import MinimalShader from 'animations/minimalShader';
3+
import NoiseDodecahedron from 'animations/noiseDodecahedron';
34
import PiArcs from 'animations/piArcs';
45
import React, { ReactNode } from 'react';
56
import ReactDOM from 'react-dom/client';
@@ -15,11 +16,14 @@ const animations = [
1516
name: 'hypocycloids',
1617
component: Hypocycloids,
1718
},
18-
1919
{
2020
name: 'piArcs',
2121
component: PiArcs,
2222
},
23+
{
24+
name: 'noiseDodecahedron',
25+
component: NoiseDodecahedron,
26+
},
2327
{
2428
name: 'minimal2d',
2529
component: Minimal2D,

0 commit comments

Comments
 (0)