Skip to content

Commit

Permalink
0.5.1
Browse files Browse the repository at this point in the history
  • Loading branch information
parameterized committed Aug 4, 2024
1 parent 1250696 commit dfe7942
Show file tree
Hide file tree
Showing 4 changed files with 145,782 additions and 0 deletions.
Binary file added favicon.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
300 changes: 300 additions & 0 deletions index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,300 @@
<title>cells</title>
<link rel="icon" type="image/png" href="favicon.png" />
<style>
html,
body {
padding: 0;
margin: 0;
overflow: hidden;
background-color: #262626;
}

canvas {
display: block;
}
</style>

<!-- fallback to cdn -->
<script src="lib/p5.js"></script>
<script>window.p5 || document.write('<script src="https://cdn.jsdelivr.net/npm/[email protected]/lib/p5.js">\x3C/script>')</script>
<script src="lib/swissgl.js"></script>
<script>window.SwissGL || document.write('<script src="https://cdn.jsdelivr.net/gh/google/swissgl@main/swissgl.js">\x3C/script>')</script>

<script>
let glsl, cells, targetMass;
let pause = false;

const cellsTargetParams = {
scale: 1 / 6,
format: "rgba16f",
story: 2,
tag: "cells",
};

const kernels = {};
const weights = {};
const bias = [];

function setup() {
const canvas = createCanvas(windowWidth, windowHeight, WEBGL);
glsl = SwissGL(canvas.elt);
cells = glsl({
seed: Math.random() * 12417,
FP: "hash(ivec3(I, seed)), 1"
}, { ...cellsTargetParams });

initParams();
};

function initParams() {
for (const c of "rgb") {
kernels[c] = {
centerVals: [],
controlDists: [],
controlVals: [],
};
for (let i = 0; i < 4; i++) {
kernels[c].centerVals.push(random(-1, 1) * 1);
kernels[c].controlDists.push(random(0.1, 0.9));
kernels[c].controlVals.push(random(-1, 1) * 1);
}

weights[c] = [];
for (let i = 0; i < 3 * 4; i++) {
weights[c].push(random(-1, 1));
}
weights[c] = new Float32Array(weights[c]);

bias.length = 0;
for (let i = 0; i < 4; i++) {
bias.push(random());
}
}
}

function keyPressed() {
if (key === " ") {
pause = !pause;
} else if (key === "r") {
glsl({ FP: "0" }, cells);
step();
} else if (key === "f") {
glsl({ FP: "0" }, cells);
initParams();
step();
} else if (key === "ArrowRight") {
step();
}
}

function step() {
targetMass = glsl({
cells: cells[0],

rCenterVals: kernels.r.centerVals,
gCenterVals: kernels.g.centerVals,
bCenterVals: kernels.b.centerVals,
rControlDists: kernels.r.controlDists,
gControlDists: kernels.g.controlDists,
bControlDists: kernels.b.controlDists,
rControlVals: kernels.r.controlVals,
gControlVals: kernels.g.controlVals,
bControlVals: kernels.b.controlVals,
rW: weights.r,
gW: weights.g,
bW: weights.b,
bias,

FP: `
uniform vec4 rW[3];
uniform vec4 gW[3];
uniform vec4 bW[3];
void fragment() {
// FOut = vec4(rW[0].xyz, 1.0);
// return;
vec4 rK = vec4(0);
vec4 gK = vec4(0);
vec4 bK = vec4(0);
float totalContrib = 0.0;
for (int k = 0; k < 81; k++) {
ivec2 offset = ivec2(k % 9 - 4, k / 9 - 4);
if (offset == ivec2(0)) { continue; }
float dist = length(vec2(offset)) / 5.0;
float contrib = dist <= 1.0 ? 1.0 : 0.0;
ivec2 neighborPos = (I + offset + cells_size()) % cells_size();
rK += vec4(
cells(neighborPos).r * (
dist < rControlDists[0]
? mix(rCenterVals[0], rControlVals[0], dist / rControlDists[0])
: mix(rControlVals[0], 0.0, (dist - rControlDists[0]) / (1.0 - rControlDists[0]))
),
cells(neighborPos).r * (
dist < rControlDists[1]
? mix(rCenterVals[1], rControlVals[1], dist / rControlDists[1])
: mix(rControlVals[1], 0.0, (dist - rControlDists[0]) / (1.0 - rControlDists[1]))
),
cells(neighborPos).r * (
dist < rControlDists[2]
? mix(rCenterVals[2], rControlVals[2], dist / rControlDists[2])
: mix(rControlVals[2], 0.0, (dist - rControlDists[2]) / (1.0 - rControlDists[2]))
),
cells(neighborPos).r * (
dist < rControlDists[3]
? mix(rCenterVals[3], rControlVals[3], dist / rControlDists[3])
: mix(rControlVals[3], 0.0, (dist - rControlDists[3]) / (1.0 - rControlDists[3]))
)
) * contrib;
gK += vec4(
cells(neighborPos).g * (
dist < gControlDists[0]
? mix(gCenterVals[0], gControlVals[0], dist / gControlDists[0])
: mix(gControlVals[0], 0.0, (dist - gControlDists[0]) / (1.0 - gControlDists[0]))
),
cells(neighborPos).g * (
dist < gControlDists[1]
? mix(gCenterVals[1], gControlVals[1], dist / gControlDists[1])
: mix(gControlVals[1], 0.0, (dist - gControlDists[0]) / (1.0 - gControlDists[1]))
),
cells(neighborPos).g * (
dist < gControlDists[2]
? mix(gCenterVals[2], gControlVals[2], dist / gControlDists[2])
: mix(gControlVals[2], 0.0, (dist - gControlDists[2]) / (1.0 - gControlDists[2]))
),
cells(neighborPos).g * (
dist < gControlDists[3]
? mix(gCenterVals[3], gControlVals[3], dist / gControlDists[3])
: mix(gControlVals[3], 0.0, (dist - gControlDists[3]) / (1.0 - gControlDists[3]))
)
) * contrib;
bK += vec4(
cells(neighborPos).b * (
dist < bControlDists[0]
? mix(bCenterVals[0], bControlVals[0], dist / bControlDists[0])
: mix(bControlVals[0], 0.0, (dist - bControlDists[0]) / (1.0 - bControlDists[0]))
),
cells(neighborPos).b * (
dist < bControlDists[1]
? mix(bCenterVals[1], bControlVals[1], dist / bControlDists[1])
: mix(bControlVals[1], 0.0, (dist - bControlDists[0]) / (1.0 - bControlDists[1]))
),
cells(neighborPos).b * (
dist < bControlDists[2]
? mix(bCenterVals[2], bControlVals[2], dist / bControlDists[2])
: mix(bControlVals[2], 0.0, (dist - bControlDists[2]) / (1.0 - bControlDists[2]))
),
cells(neighborPos).b * (
dist < bControlDists[3]
? mix(bCenterVals[3], bControlVals[3], dist / bControlDists[3])
: mix(bControlVals[3], 0.0, (dist - bControlDists[3]) / (1.0 - bControlDists[3]))
)
) * contrib;
totalContrib += contrib;
}
// FOut = vec4(rK.x, gK.x, bK.x, 1.0);
// rK /= totalContrib;
// gK /= totalContrib;
// bK /= totalContrib;
float rTarget = (
bias.r
+ rW[0].x * rK.x + rW[0].y * rK.y + rW[0].z * rK.z + rW[0].w * rK.w
+ rW[1].x * gK.x + rW[1].y * gK.y + rW[1].z * gK.z + rW[1].w * gK.w
+ rW[2].x * bK.x + rW[2].y * bK.y + rW[2].z * bK.z + rW[2].w * bK.w
);
float gTarget = (
bias.g
+ gW[0].x * rK.x + gW[0].y * rK.y + gW[0].z * rK.z + gW[0].w * rK.w
+ gW[1].x * gK.x + gW[1].y * gK.y + gW[1].z * gK.z + gW[1].w * gK.w
+ gW[2].x * bK.x + gW[2].y * bK.y + gW[2].z * bK.z + gW[2].w * bK.w
);
float bTarget = (
bias.b
+ bW[0].x * rK.x + bW[0].y * rK.y + bW[0].z * rK.z + bW[0].w * rK.w
+ bW[1].x * gK.x + bW[1].y * gK.y + bW[1].z * gK.z + bW[1].w * gK.w
+ bW[2].x * bK.x + bW[2].y * bK.y + bW[2].z * bK.z + bW[2].w * bK.w
);
vec3 targetMass = clamp(
vec3(rTarget, gTarget, bTarget),
0.0,
1.0
);
targetMass += vec3(0.5);
FOut = vec4(targetMass, 1.0);
}
`}, {
size: cells[0].size,
format: "rgba16f",
tag: "targetMass",
});

cells = glsl({
targetMass,
seed: Math.random() * 12417,
FP: `
vec3 massTransfer(ivec2 pos, ivec2 dir) {
pos = (pos + Src_size()) % Src_size();
vec3 iWants = targetMass(pos).rgb - Src(pos).rgb;
ivec2 dirPos = (pos + dir + Src_size()) % Src_size();
vec3 dirWants = targetMass(dirPos).rgb - Src(dirPos).rgb;
vec3 iMassClamped = clamp(Src(pos).rgb, 0.0, 1.0);
vec3 dirMassClamped = clamp(Src(dirPos).rgb, 0.0, 1.0);
vec3 maxDirAccept = (1.0 - dirMassClamped) / 8.0;
vec3 minDirAccept = -dirMassClamped / 8.0;
vec3 maxIAccept = (1.0 - iMassClamped) / 8.0;
vec3 minIAccept = -iMassClamped / 8.0;
vec3 giveDir = clamp(
(dirWants - iWants) / 32.0,
max(minDirAccept, -maxIAccept),
min(maxDirAccept, -minIAccept)
);
return giveDir;
}
void fragment() {
FOut = Src(I);
if (FOut.a == 0.0) {
FOut = vec4(hash(ivec3(I, seed)), 1);
return;
}
for (int k = 0; k < 9; k++) {
ivec2 offset = ivec2(k % 3 - 1, k / 3 - 1);
if (offset == ivec2(0)) { continue; }
FOut.rgb += (
massTransfer(I + offset, -offset)
- massTransfer(I, offset)
);
}
// TODO: fix evaporation
FOut.rgb += vec3(0.00013);
}
`}, { ...cellsTargetParams });
}

function draw() {
if (!pause) { step(); }

glsl({
cells: cells[0],
FP: "cells(UV)",
});
};

function windowResized() {
resizeCanvas(windowWidth, windowHeight);
};
</script>
Loading

0 comments on commit dfe7942

Please sign in to comment.