diff --git a/v1-com-officielle/glitcher/glitcher.js b/v1-com-officielle/glitcher/glitcher.js index 17a9e49..99bd0dc 100644 --- a/v1-com-officielle/glitcher/glitcher.js +++ b/v1-com-officielle/glitcher/glitcher.js @@ -14,7 +14,7 @@ async function updateFromForm(){ } else { UI_GLITCHER.clearImage() } - + UI_GLITCHER.render() } @@ -46,7 +46,7 @@ CANVAS.addEventListener("pointerdown", e => { let now = Date.now() if(lastCommit === null || now - lastCommit > 100){ - let width = 20; + let width = 50; if(e.pointerType == "touch"){ width *= 2 } @@ -55,8 +55,8 @@ CANVAS.addEventListener("pointerdown", e => { let deltaY = lastY !== undefined ? y - lastY : 0 width += Math.max(Math.abs(deltaX), Math.abs(deltaY)) + width += Math.random()*2 - //UI_GLITCHER.addGlitch(x + (Math.random() * width) - width/2, y + (Math.random() * width) - width/2, width) UI_GLITCHER.addGlitch(x, y, width) UI_GLITCHER.render() @@ -82,5 +82,11 @@ CANVAS.addEventListener("pointerdown", e => { applyGlitch(e) }) +/*function startRendering(){ + UI_GLITCHER.render() + requestAnimationFrame(startRendering) +} +startRendering()*/ +setInterval(() => UI_GLITCHER.render(), 500) updateFromForm() \ No newline at end of file diff --git a/v1-com-officielle/glitcher/lib/base.frag b/v1-com-officielle/glitcher/lib/base.frag index a5db85e..b497e6e 100644 --- a/v1-com-officielle/glitcher/lib/base.frag +++ b/v1-com-officielle/glitcher/lib/base.frag @@ -1,5 +1,6 @@ varying highp vec2 vTextureCoord; uniform sampler2D uImageSampler; +uniform highp vec2 uWindowSize; void main() { gl_FragColor = texture2D(uImageSampler, vTextureCoord); diff --git a/v1-com-officielle/glitcher/lib/glitch.frag b/v1-com-officielle/glitcher/lib/glitch.frag index 45da7f3..7d89115 100644 --- a/v1-com-officielle/glitcher/lib/glitch.frag +++ b/v1-com-officielle/glitcher/lib/glitch.frag @@ -1,3 +1,10 @@ +uniform highp vec2 uWindowSize; +uniform sampler2D uVideoSampler; +uniform sampler2D uNoiseSampler; +uniform lowp vec4 uRandom; + void main() { - gl_FragColor = vec4(0.0, 0.0, 0.0, 1.0); + gl_FragColor = texture2D(uVideoSampler, gl_FragCoord.xy/uWindowSize.xy) + + (texture2D(uNoiseSampler, (gl_FragCoord.xy/vec2(128, 128))+uRandom.zw) - 0.75) + * texture2D(uNoiseSampler, (gl_FragCoord.xy/vec2(128, 128))+uRandom.xw); } \ No newline at end of file diff --git a/v1-com-officielle/glitcher/lib/glitch.vert b/v1-com-officielle/glitcher/lib/glitch.vert index 847dc61..52b3582 100644 --- a/v1-com-officielle/glitcher/lib/glitch.vert +++ b/v1-com-officielle/glitcher/lib/glitch.vert @@ -1,9 +1,13 @@ -attribute vec4 aVertexPosition; +attribute vec2 aVertexPosition; +attribute vec2 aTextureCoord; uniform vec2 uGlitchPosition; uniform float uGlitchWidth; +uniform lowp vec4 uRandom; uniform vec2 uImageRatio; +varying highp vec2 vTextureCoord; + void main() { vec2 vertex = aVertexPosition.xy; @@ -11,6 +15,7 @@ void main() { vertex *= 0.001; vertex *= uGlitchWidth; vertex += uGlitchPosition; + vertex += uRandom.xy*0.01; gl_Position = vec4(vertex, -1.0, 1.0); } diff --git a/v1-com-officielle/glitcher/lib/glitcher.js b/v1-com-officielle/glitcher/lib/glitcher.js index 4ead33d..fbfb691 100644 --- a/v1-com-officielle/glitcher/lib/glitcher.js +++ b/v1-com-officielle/glitcher/lib/glitcher.js @@ -1,5 +1,7 @@ import resizeToFit from 'intrinsic-scale' +import noiseUrl from "../noise-power.png" + import baseVertSource from "./base.vert?raw" import baseFragSource from "./base.frag?raw" @@ -11,17 +13,25 @@ export class Glitcher { /** @type {HTMLCanvasElement} */ canvas - gliches = [] + glitches = [] /** * @param {HTMLCanvasElement} canvas */ constructor(canvas) { this.canvas = canvas + this.videoCanvas = new OffscreenCanvas(10, 10); + this.video = document.createElement("video") this.init() } init(){ + this.video.muted = true + this.video.loop = true + this.video.autoplay = true + this.video.src = "/background.webm" + this.video.addEventListener("canplay", e => this.video.play()) + this.ctx = this.canvas.getContext("webgl") if(!this.ctx){ throw new Error("WebGL isn't supported") @@ -56,13 +66,13 @@ export class Glitcher { aVertexPosition: this.ctx.getAttribLocation(baseProgram, "aVertexPosition"), aTextureCoord: this.ctx.getAttribLocation(baseProgram, "aTextureCoord"), uImageSampler: this.ctx.getUniformLocation(baseProgram, "uImageSampler"), + uWindowSize: this.ctx.getUniformLocation(baseProgram, "uWindowSize"), imageTexture: imageTexture, panelUVBuffer: panelUVBuffer, - panelPositionsBuffer: panelPositionBuffer + panelPositionsBuffer: panelPositionBuffer, } this.clearImage(); - let glitchPositionBuffer = this.ctx.createBuffer() this.ctx.bindBuffer(this.ctx.ARRAY_BUFFER, glitchPositionBuffer) const glitchPosition = [ @@ -72,8 +82,41 @@ export class Glitcher { 1.0, -1.0, ] this.ctx.bufferData(this.ctx.ARRAY_BUFFER, new Float32Array(glitchPosition), this.ctx.STATIC_DRAW) - + let glitchProgram = createProgram(this.ctx, glitchVertSource, glitchFragSource) + let videoFrameTexture = this.ctx.createTexture() + + let noiseTexture = this.ctx.createTexture() + this.ctx.bindTexture(this.ctx.TEXTURE_2D, noiseTexture) + this.ctx.texImage2D( + this.ctx.TEXTURE_2D, + 0, + this.ctx.RGBA, + 1, 1, + 0, + this.ctx.RGBA, + this.ctx.UNSIGNED_BYTE, + new Uint8Array([0, 0, 0, 0]) + ) + + let noiseImage = new Image() + noiseImage.addEventListener("load", () => { + this.ctx.bindTexture(this.ctx.TEXTURE_2D, this.glitch.noiseTexture) + this.ctx.texImage2D( + this.ctx.TEXTURE_2D, + 0, + this.ctx.RGBA, + this.ctx.RGBA, + this.ctx.UNSIGNED_BYTE, + noiseImage + ) + + this.ctx.texParameteri(this.ctx.TEXTURE_2D, this.ctx.TEXTURE_WRAP_S, this.ctx.REPEAT); + this.ctx.texParameteri(this.ctx.TEXTURE_2D, this.ctx.TEXTURE_WRAP_T, this.ctx.REPEAT); + this.ctx.texParameteri(this.ctx.TEXTURE_2D, this.ctx.TEXTURE_MIN_FILTER, this.ctx.NEAREST); + this.ctx.texParameteri(this.ctx.TEXTURE_2D, this.ctx.TEXTURE_MAG_FILTER, this.ctx.NEAREST); + }) + noiseImage.src = noiseUrl this.glitch = { program: glitchProgram, @@ -81,12 +124,20 @@ export class Glitcher { uGlitchPosition: this.ctx.getUniformLocation(glitchProgram, "uGlitchPosition"), uGlitchWidth: this.ctx.getUniformLocation(glitchProgram, "uGlitchWidth"), uImageRatio: this.ctx.getUniformLocation(glitchProgram, "uImageRatio"), - glitchPositionBuffer: glitchPositionBuffer + uWindowSize: this.ctx.getUniformLocation(glitchProgram, "uWindowSize"), + uVideoSampler: this.ctx.getUniformLocation(glitchProgram, "uVideoSampler"), + uNoiseSampler: this.ctx.getUniformLocation(glitchProgram, "uNoiseSampler"), + uRandom: this.ctx.getUniformLocation(glitchProgram, "uRandom"), + glitchPositionBuffer: glitchPositionBuffer, + videoFrameTexture: videoFrameTexture, + noiseTexture: noiseTexture } + + console.log(this.glitch) } clearImage(){ - this.ctx.bindTexture(this.ctx.TEXTURE_2D, this.imageTexture) + this.ctx.bindTexture(this.ctx.TEXTURE_2D, this.base.imageTexture) this.ctx.texImage2D( this.ctx.TEXTURE_2D, 0, @@ -192,14 +243,39 @@ export class Glitcher { this.canvas.width = resize.width this.canvas.height = resize.height + this.videoCanvas.width = this.canvas.width + this.videoCanvas.height = this.canvas.height this.ctx.viewport(0, 0, this.canvas.width, this.canvas.height); } + updateVideoTexture(){ + let vctx = this.videoCanvas.getContext("2d") + vctx.clearRect(0, 0, this.videoCanvas.width, this.videoCanvas.height) + vctx.drawImage(this.video, 0, 0, this.videoCanvas.width, this.videoCanvas.height); + + this.ctx.bindTexture(this.ctx.TEXTURE_2D, this.glitch.videoFrameTexture) + this.ctx.texImage2D( + this.ctx.TEXTURE_2D, + 0, + this.ctx.RGBA, + this.ctx.RGBA, + this.ctx.UNSIGNED_BYTE, + this.videoCanvas + ) + + this.ctx.texParameteri(this.ctx.TEXTURE_2D, this.ctx.TEXTURE_WRAP_S, this.ctx.CLAMP_TO_EDGE); + this.ctx.texParameteri(this.ctx.TEXTURE_2D, this.ctx.TEXTURE_WRAP_T, this.ctx.CLAMP_TO_EDGE); + this.ctx.texParameteri(this.ctx.TEXTURE_2D, this.ctx.TEXTURE_MIN_FILTER, this.ctx.LINEAR); + this.ctx.texParameteri(this.ctx.TEXTURE_2D, this.ctx.TEXTURE_MAG_FILTER, this.ctx.LINEAR); + } + render(){ if(!this.ctx){ throw new Error("Glitcher not initialized, please run init()") } + this.updateVideoTexture() + this.ctx.clearColor(0.0, 0.0, 0.0, 0.0) this.ctx.clearDepth(1.0) this.ctx.enable(this.ctx.DEPTH_TEST) @@ -233,7 +309,8 @@ export class Glitcher { this.ctx.activeTexture(this.ctx.TEXTURE0) this.ctx.bindTexture(this.ctx.TEXTURE_2D, this.base.imageTexture) - + + this.ctx.uniform2f(this.base.uWindowSize, this.canvas.width, this.canvas.height) this.ctx.uniform1i(this.base.uImageSampler, 0) this.ctx.drawArrays( @@ -254,8 +331,17 @@ export class Glitcher { 0, // (stride) how many bytes to get from one set of values to the next 0, // Start offset ) - this.ctx.enableVertexAttribArray(this.glitch.aVertexPosition) + + this.ctx.activeTexture(this.ctx.TEXTURE0) + this.ctx.bindTexture(this.ctx.TEXTURE_2D, this.glitch.videoFrameTexture) + this.ctx.uniform1i(this.glitch.uVideoSampler, 0) + + this.ctx.activeTexture(this.ctx.TEXTURE1) + this.ctx.bindTexture(this.ctx.TEXTURE_2D, this.glitch.noiseTexture) + this.ctx.uniform1i(this.glitch.uNoiseSampler, 1) + + this.ctx.uniform2f(this.glitch.uWindowSize, this.canvas.width, this.canvas.height) if(this.canvas.width > this.canvas.height){ this.ctx.uniform2f(this.glitch.uImageRatio, 1.0, this.canvas.width/this.canvas.height) } else { @@ -263,6 +349,9 @@ export class Glitcher { } for(let glitch of this.glitches) { + this.ctx.uniform4f(this.glitch.uRandom, + Math.random(), Math.random(), Math.random(), Math.random() + ) this.ctx.uniform2f(this.glitch.uGlitchPosition, glitch.x, glitch.y) this.ctx.uniform1f(this.glitch.uGlitchWidth, glitch.width) this.ctx.drawArrays( diff --git a/v1-com-officielle/glitcher/noise-power.png b/v1-com-officielle/glitcher/noise-power.png new file mode 100644 index 0000000..47a02c5 Binary files /dev/null and b/v1-com-officielle/glitcher/noise-power.png differ