diff --git a/README.md b/README.md
index 8c8429a..d57cc45 100644
--- a/README.md
+++ b/README.md
@@ -30,3 +30,7 @@ WebGL ([Three.js](https://threejs.org/), [SwissGL](https://google.github.io/swis
#### High-level architecture and modules:
![Architecture](media/LordTubeMaster.svg)
+
+
+
+Exhibited in /'fu:bar/ glitch art festival exhibition in 2024.
\ No newline at end of file
diff --git a/models/dotcamera.js b/models/dotcamera.js
index 0bcc358..b6714ba 100644
--- a/models/dotcamera.js
+++ b/models/dotcamera.js
@@ -12,9 +12,9 @@ export default class DotCamera {
this.rgbMode = rgbMode;
}
- frame(video, {canvasSize, DPR=devicePixelRatio, loop_start=0}) {
- const dayMode = loop_start ? loop_start % 2 : this.dayMode;
- const rgbMode = !!(loop_start ? (loop_start/2|0) % 2 : this.rgbMode);
+ frame(video, {canvasSize, DPR=devicePixelRatio, random_mode}) {
+ const dayMode = (random_mode/2|0) % 2 != this.dayMode;
+ const rgbMode = random_mode % 2 != this.rgbMode;
const tex = this.glsl({}, {data:video, tag:'video'});
canvasSize = canvasSize ?? tex.size;
const blendParams = dayMode ? {Clear:1, Blend:'d-s'} : {Clear:0, Blend:'d+s'};
diff --git a/models/ruttetraizer.js b/models/ruttetraizer.js
index e721413..57bdbf9 100644
--- a/models/ruttetraizer.js
+++ b/models/ruttetraizer.js
@@ -4,10 +4,10 @@
const scale_rate = .01
const min_scale = 1
const max_scale = 10
-const rot_rate_x = .0003
+const rot_rate_x = .0005
const rot_rate_y = .0002
-const min_rot = .33
-const max_rot = .66
+const min_rot = .4
+const max_rot = .6
let scale = 2
let pointer_x = .5
@@ -48,7 +48,7 @@ export default class RuttEtraIzer {
canvas.addEventListener('wheel', e => scale = Math.max(min_scale, Math.min(scale + e.deltaY*scale_rate, max_scale)), {passive: true})
}
- frame(W, H, rgbx, {scanStep=7, depth=100, loop_start=0}={}) {
+ frame(W, H, rgbx, {scanStep=7, depth=100, random_mode}={}) {
const THREE = this.THREE
if (this.lineGroup) {
@@ -72,7 +72,7 @@ export default class RuttEtraIzer {
geometry.setAttribute('color', new THREE.BufferAttribute(new Float32Array(colors), 3))
this.lineGroup.add(new THREE.Line(geometry, this.material))
}
- if (loop_start) {
+ if (random_mode) {
const rand = Math.random()
if (rand > .5) {
pointer_x += rot_dir_x * rot_rate_x
diff --git a/script.js b/script.js
index 54e566b..e9a0413 100644
--- a/script.js
+++ b/script.js
@@ -11,10 +11,10 @@ import {
ImageSegmenter,
FilesetResolver,
DrawingUtils
-} from 'https://cdn.jsdelivr.net/npm/@mediapipe/tasks-vision@0.10.15/vision_bundle.mjs'
-const mediapipe_wasm_url = 'https://cdn.jsdelivr.net/npm/@mediapipe/tasks-vision@0.10.15/wasm'
+} from 'https://cdn.jsdelivr.net/npm/@mediapipe/tasks-vision@0.10.17/vision_bundle.mjs'
+const mediapipe_wasm_url = 'https://cdn.jsdelivr.net/npm/@mediapipe/tasks-vision@0.10.17/wasm'
-import {AutoModel, AutoProcessor, RawImage, env as transformersEnv} from 'https://cdn.jsdelivr.net/npm/@huggingface/transformers@3.0.0-alpha.19/dist/transformers.min.js'
+import {AutoModel, AutoProcessor, RawImage, env as transformersEnv} from 'https://cdn.jsdelivr.net/npm/@huggingface/transformers@3.0.0-alpha.20/dist/transformers.min.js'
import 'https://cdn.jsdelivr.net/npm/@tensorflow/tfjs@4.21.0/dist/tf.min.js'
import 'https://cdn.jsdelivr.net/npm/@tensorflow/tfjs-backend-webgpu@4.21.0/dist/tf-backend-webgpu.min.js'
@@ -25,7 +25,7 @@ ort.env.wasm.wasmPaths = 'https://cdn.jsdelivr.net/npm/onnxruntime-web@1.19.2/di
import SwissGL from './libs/swissgl/swissgl.mjs'
import DotCamera from './models/dotcamera.js'
-import * as THREE from 'https://cdn.jsdelivr.net/npm/three@0.168.0/build/three.module.min.js'
+import * as THREE from 'https://cdn.jsdelivr.net/npm/three@0.169.0/build/three.module.min.js'
import RuttEtraIzer from './models/ruttetraizer.js'
function getGPUInfo() {
@@ -74,15 +74,14 @@ video_url.addEventListener('focus', e => {
e.currentTarget.select() // Broken in Chrome. See: https://issues.chromium.org/issues/40345011#comment45
})
-let loop_mode, loop_start
+let loop_mode, dotcamera_mode
effect.addEventListener('change', e => {
if (e.currentTarget.value)
capture()
loop_mode = null
- loop_start = 0
if (e.currentTarget.value == 'loop' || e.currentTarget.value == 'random') {
loop_mode = e.currentTarget.value
- loop_start = performance.now()
+ dotcamera_mode = 0
loop_effects()
}
})
@@ -98,6 +97,7 @@ document.addEventListener('keydown', e => {
function loop_effects() {
if (!loop_mode || !capture_started)
return
+ // dotcamera_mode += effect.value == 'dotcamera_swissgl'
const effects = [...effect.querySelectorAll('option:not([disabled]):not([label="meta" i] > *)')].map(e => e.value)
effect.value = effects[(effects.indexOf(effect.value)+(loop_mode == 'random' ? Math.random()*(effects.length-1) + 1 | 0 : 1)) % effects.length]
setTimeout(loop_effects, loop_secs * 1000)
@@ -293,7 +293,7 @@ const effect_funcs = {
canvas.width = gl_canvas.width = W
canvas.height = gl_canvas.height = H
}
- models.dotcamera.frame(videoFrame, {canvasSize: [W, H], DPR: 1.5, loop_start: loop_start})
+ models.dotcamera.frame(videoFrame, {canvasSize: [W, H], DPR: 1.5, random_mode: loop_mode ? dotcamera_mode : 0})
canvasCtx.drawImage(gl_canvas, 0, 0)
},
@@ -306,7 +306,7 @@ const effect_funcs = {
canvas.height = gl_canvas.height = H
renderer.setViewport(0, 0, W, H)
}
- models.ruttetra.frame(W, H, rgbx, {scanStep: 7, depth: 100, loop_start: loop_start})
+ models.ruttetra.frame(W, H, rgbx, {scanStep: 7, depth: 100, random_mode: loop_mode})
canvasCtx.drawImage(gl_canvas, 0, 0)
},
@@ -590,4 +590,6 @@ async function capture() {
})
trackProcessor.readable.pipeThrough(transformer).pipeTo(trackGenerator.writable)
out_video.srcObject = new MediaStream([trackGenerator])
+ if (loop_mode)
+ loop_effects()
}
\ No newline at end of file