Skip to content // StreakField — signal simulation
const GRID = 128; // flow potential lattice
let phase = 0; // A→B morph, ~14s per epoch
const curl = (x, y) => {
const dx = sample(x + h, y) - sample(x - h, y);
const dy = sample(x, y + h) - sample(x, y - h);
return [dy * FLOW, -dx * FLOW]; // divergence-free: pure swirl
};
for (let i = 0; i < P; i++) {
const [u, v] = curl(px[i], py[i]);
px[i] += (u + vortex.x + scatter.x) * dt * rush;
py[i] += (v + vortex.y + scatter.y) * dt * rush;
// cursor crush: flash teal, kick outward, spring home
if (d2(ptr, i) < R && ptr.speed > MIN) {
flash[i] = 1;
kick(i, ptr, (1 - d2 / R) * ptr.speed * IMPULSE);
}
charge[i] = Math.max(flash[i] *= COOL, trailGlow(px[i], py[i]));
}
// trails: fade pass 4.5% → filaments persist ~25 frames
fade(fbo, 0.045); draw(points, ADDITIVE); composite(fbo, screen);
// StreakField — signal simulation
const GRID = 128; // flow potential lattice
let phase = 0; // A→B morph, ~14s per epoch
const curl = (x, y) => {
const dx = sample(x + h, y) - sample(x - h, y);
const dy = sample(x, y + h) - sample(x, y - h);
return [dy * FLOW, -dx * FLOW]; // divergence-free: pure swirl
};
for (let i = 0; i < P; i++) {
const [u, v] = curl(px[i], py[i]);
px[i] += (u + vortex.x + scatter.x) * dt * rush;
py[i] += (v + vortex.y + scatter.y) * dt * rush;
// cursor crush: flash teal, kick outward, spring home
if (d2(ptr, i) < R && ptr.speed > MIN) {
flash[i] = 1;
kick(i, ptr, (1 - d2 / R) * ptr.speed * IMPULSE);
}
charge[i] = Math.max(flash[i] *= COOL, trailGlow(px[i], py[i]));
}
// trails: fade pass 4.5% → filaments persist ~25 frames
fade(fbo, 0.045); draw(points, ADDITIVE); composite(fbo, screen);
// StreakField — signal simulation
const GRID = 128; // flow potential lattice
let phase = 0; // A→B morph, ~14s per epoch
const curl = (x, y) => {
const dx = sample(x + h, y) - sample(x - h, y);
const dy = sample(x, y + h) - sample(x, y - h);
return [dy * FLOW, -dx * FLOW]; // divergence-free: pure swirl
};
for (let i = 0; i < P; i++) {
const [u, v] = curl(px[i], py[i]);
px[i] += (u + vortex.x + scatter.x) * dt * rush;
py[i] += (v + vortex.y + scatter.y) * dt * rush;
// cursor crush: flash teal, kick outward, spring home
if (d2(ptr, i) < R && ptr.speed > MIN) {
flash[i] = 1;
kick(i, ptr, (1 - d2 / R) * ptr.speed * IMPULSE);
}
charge[i] = Math.max(flash[i] *= COOL, trailGlow(px[i], py[i]));
}
// trails: fade pass 4.5% → filaments persist ~25 frames
fade(fbo, 0.045); draw(points, ADDITIVE); composite(fbo, screen);
// StreakField — signal simulation
const GRID = 128; // flow potential lattice
let phase = 0; // A→B morph, ~14s per epoch
const curl = (x, y) => {
const dx = sample(x + h, y) - sample(x - h, y);
const dy = sample(x, y + h) - sample(x, y - h);
return [dy * FLOW, -dx * FLOW]; // divergence-free: pure swirl
};
for (let i = 0; i < P; i++) {
const [u, v] = curl(px[i], py[i]);
px[i] += (u + vortex.x + scatter.x) * dt * rush;
py[i] += (v + vortex.y + scatter.y) * dt * rush;
// cursor crush: flash teal, kick outward, spring home
if (d2(ptr, i) < R && ptr.speed > MIN) {
flash[i] = 1;
kick(i, ptr, (1 - d2 / R) * ptr.speed * IMPULSE);
}
charge[i] = Math.max(flash[i] *= COOL, trailGlow(px[i], py[i]));
}
// trails: fade pass 4.5% → filaments persist ~25 frames
fade(fbo, 0.045); draw(points, ADDITIVE); composite(fbo, screen);
// StreakField — signal simulation
const GRID = 128; // flow potential lattice
let phase = 0; // A→B morph, ~14s per epoch
const curl = (x, y) => {
const dx = sample(x + h, y) - sample(x - h, y);
const dy = sample(x, y + h) - sample(x, y - h);
return [dy * FLOW, -dx * FLOW]; // divergence-free: pure swirl
};
for (let i = 0; i < P; i++) {
const [u, v] = curl(px[i], py[i]);
px[i] += (u + vortex.x + scatter.x) * dt * rush;
py[i] += (v + vortex.y + scatter.y) * dt * rush;
// cursor crush: flash teal, kick outward, spring home
if (d2(ptr, i) < R && ptr.speed > MIN) {
flash[i] = 1;
kick(i, ptr, (1 - d2 / R) * ptr.speed * IMPULSE);
}
charge[i] = Math.max(flash[i] *= COOL, trailGlow(px[i], py[i]));
}
// trails: fade pass 4.5% → filaments persist ~25 frames
fade(fbo, 0.045); draw(points, ADDITIVE); composite(fbo, screen);
// StreakField — signal simulation
const GRID = 128; // flow potential lattice
let phase = 0; // A→B morph, ~14s per epoch
const curl = (x, y) => {
const dx = sample(x + h, y) - sample(x - h, y);
const dy = sample(x, y + h) - sample(x, y - h);
return [dy * FLOW, -dx * FLOW]; // divergence-free: pure swirl
};
for (let i = 0; i < P; i++) {
const [u, v] = curl(px[i], py[i]);
px[i] += (u + vortex.x + scatter.x) * dt * rush;
py[i] += (v + vortex.y + scatter.y) * dt * rush;
// cursor crush: flash teal, kick outward, spring home
if (d2(ptr, i) < R && ptr.speed > MIN) {
flash[i] = 1;
kick(i, ptr, (1 - d2 / R) * ptr.speed * IMPULSE);
}
charge[i] = Math.max(flash[i] *= COOL, trailGlow(px[i], py[i]));
}
// trails: fade pass 4.5% → filaments persist ~25 frames
fade(fbo, 0.045); draw(points, ADDITIVE); composite(fbo, screen);
// StreakField — signal simulation
const GRID = 128; // flow potential lattice
let phase = 0; // A→B morph, ~14s per epoch
const curl = (x, y) => {
const dx = sample(x + h, y) - sample(x - h, y);
const dy = sample(x, y + h) - sample(x, y - h);
return [dy * FLOW, -dx * FLOW]; // divergence-free: pure swirl
};
for (let i = 0; i < P; i++) {
const [u, v] = curl(px[i], py[i]);
px[i] += (u + vortex.x + scatter.x) * dt * rush;
py[i] += (v + vortex.y + scatter.y) * dt * rush;
// cursor crush: flash teal, kick outward, spring home
if (d2(ptr, i) < R && ptr.speed > MIN) {
flash[i] = 1;
kick(i, ptr, (1 - d2 / R) * ptr.speed * IMPULSE);
}
charge[i] = Math.max(flash[i] *= COOL, trailGlow(px[i], py[i]));
}
// trails: fade pass 4.5% → filaments persist ~25 frames
fade(fbo, 0.045); draw(points, ADDITIVE); composite(fbo, screen);
// StreakField — signal simulation
const GRID = 128; // flow potential lattice
let phase = 0; // A→B morph, ~14s per epoch
const curl = (x, y) => {
const dx = sample(x + h, y) - sample(x - h, y);
const dy = sample(x, y + h) - sample(x, y - h);
return [dy * FLOW, -dx * FLOW]; // divergence-free: pure swirl
};
for (let i = 0; i < P; i++) {
const [u, v] = curl(px[i], py[i]);
px[i] += (u + vortex.x + scatter.x) * dt * rush;
py[i] += (v + vortex.y + scatter.y) * dt * rush;
// cursor crush: flash teal, kick outward, spring home
if (d2(ptr, i) < R && ptr.speed > MIN) {
flash[i] = 1;
kick(i, ptr, (1 - d2 / R) * ptr.speed * IMPULSE);
}
charge[i] = Math.max(flash[i] *= COOL, trailGlow(px[i], py[i]));
}
// trails: fade pass 4.5% → filaments persist ~25 frames
fade(fbo, 0.045); draw(points, ADDITIVE); composite(fbo, screen);
// StreakField — signal simulation
const GRID = 128; // flow potential lattice
let phase = 0; // A→B morph, ~14s per epoch
const curl = (x, y) => {
const dx = sample(x + h, y) - sample(x - h, y);
const dy = sample(x, y + h) - sample(x, y - h);
return [dy * FLOW, -dx * FLOW]; // divergence-free: pure swirl
};
for (let i = 0; i < P; i++) {
const [u, v] = curl(px[i], py[i]);
px[i] += (u + vortex.x + scatter.x) * dt * rush;
py[i] += (v + vortex.y + scatter.y) * dt * rush;
// cursor crush: flash teal, kick outward, spring home
if (d2(ptr, i) < R && ptr.speed > MIN) {
flash[i] = 1;
kick(i, ptr, (1 - d2 / R) * ptr.speed * IMPULSE);
}
charge[i] = Math.max(flash[i] *= COOL, trailGlow(px[i], py[i]));
}
// trails: fade pass 4.5% → filaments persist ~25 frames
fade(fbo, 0.045); draw(points, ADDITIVE); composite(fbo, screen);
VM
Kino Klub Sisak · 2025
Star Film Fest Vodio sam audio-vizualni tim za Star Film Fest, produkciju filmskog festivala koja je zahtijevala sveobuhvatnu tehničku koordinaciju kroz više mjesta prikazivanja i događanja. Bio sam odgovoran za osiguravanje besprijekornog audio-vizualnog izvođenja kroz cijelo iskustvo festivala.
Zadatak
Festival je zahtijevao koordinaciju složenih audio-vizualnih postavki kroz više mjesta istovremeno, svako s različitim tehničkim zahtjevima i ograničenjima. Trebao sam osigurati dosljedne standarde kvalitete dok sam upravljao logistikom opreme, tehničkim ekipama i rješavanjem problema u stvarnom vremenu tijekom uživo prikazivanja.
01
Filmski festivali izgubljeni u digitalnoj buci. Festival je zahtijevao koordinaciju složenih audio-vizualnih postavki kroz više mjesta istovremeno, svako s različitim tehničkim zahtjevima i ograničenjima. Trebao sam osigurati dosljedne standarde kvalitete dok sam upravljao logistikom opreme, tehničkim ekipama i rješavanjem problema u stvarnom vremenu tijekom uživo prikazivanja.
02
Reflektori na pripovijedanje, a ne na skrolanje. Razvio sam centralizirani sustav tehničke koordinacije koji je standardizirao specifikacije opreme i protokole ekipa kroz sva mjesta. Implementirao sam redundantne rezervne sustave za kritična prikazivanja i uspostavio jasne komunikacijske kanale između timova mjesta kako bih osigurao brzi odgovor na bilo koje tehničke probleme.
03
Od crvenog tepiha do crvenih piksela. Počeo sam provođenjem detaljnih tehničkih procjena svakog mjesta kako bih identificirao potrebe za opremom i potencijalne izazove. Zatim sam stvorio sveobuhvatne vodiče za postavljanje i obučio ekipe specifične za mjesta o standardiziranim postupcima, dok sam uspostavljao centralnu komandnu strukturu za praćenje u stvarnom vremenu i podršku kroz festival.
04
Ovacije u digitalnom obliku. Festival je postigao 100% radnog vremena kroz sva zakazana prikazivanja s nula tehničkih kašnjenja koja su utjecala na iskustvo publike. Uspješno sam upravljao koordinacijom opreme vrijedne više od šest brojeva dok sam gradio skalabilni okvir koji je organizacija festivala usvojila za buduće događanje.
Star Film Fest 2025 / Promo
KRONIKE 12. STAR FILM FEST 1
KRONIKE 12. STAR FILM FEST 2
KRONIKE 12. STAR FILM FEST 3
Do Not Touch