From 3e301e9e58c68ed30e2589a61c02b9b578dbb09c Mon Sep 17 00:00:00 2001 From: Rezmason Date: Tue, 2 Aug 2022 09:56:13 -0700 Subject: [PATCH] code brightness is now intensified by the ripples. Added webcam support. --- js/regl/ripplesPass.js | 46 ++++++++++++++++++++++++++++-- shaders/glsl/ripplesPass.frag.glsl | 26 +++++++++++++---- 2 files changed, 63 insertions(+), 9 deletions(-) diff --git a/js/regl/ripplesPass.js b/js/regl/ripplesPass.js index ac31795..c0a6d01 100644 --- a/js/regl/ripplesPass.js +++ b/js/regl/ripplesPass.js @@ -1,6 +1,6 @@ import { loadImage, loadText, makePassFBO, makePass } from "./utils.js"; -const start = Date.now(); +let start = Date.now(); const numClicks = 5; const clicks = Array(numClicks).fill([0, 0, -Infinity]).flat(); let aspectRatio = 1; @@ -13,7 +13,41 @@ window.onclick = (e) => { index = (index + 1) % numClicks; } +// TODO: switch to video-based texture +// TODO: mipmap? +const video = document.createElement("video"); +const canvas = document.createElement("canvas"); +const context = canvas.getContext("2d"); +let cameraAspectRatio = 1.0; + +const getCameraFeed = async () => { + try { + const stream = await navigator.mediaDevices.getUserMedia({video: { + width: { min: 800, ideal: 1280 }, + frameRate: { ideal: 60 } + }, audio: false}); + const videoTrack = stream.getVideoTracks()[0]; + const {width, height} = videoTrack.getSettings(); + console.log(videoTrack.getSettings()); + + video.width = width; + video.height = height; + canvas.width = width; + canvas.height = height; + cameraAspectRatio = width / height; + + video.srcObject = stream; + video.play(); + } catch (e) {} +}; + export default ({ regl, config }, inputs) => { + + getCameraFeed(); + const cameraTex = regl.texture(canvas); + + start = Date.now(); + const output = makePassFBO(regl, config.useHalfFloat); const ripplesPassFrag = loadText("shaders/glsl/ripplesPass.frag.glsl"); const render = regl({ @@ -22,8 +56,10 @@ export default ({ regl, config }, inputs) => { time: regl.context("time"), tex: inputs.primary, bloomTex: inputs.bloom, + cameraTex, clicks: () => clicks, - aspectRatio: () => aspectRatio + aspectRatio: () => aspectRatio, + cameraAspectRatio: () => cameraAspectRatio }, framebuffer: output, }); @@ -36,6 +72,10 @@ export default ({ regl, config }, inputs) => { output.resize(w, h); aspectRatio = w / h; }, - () => render({ frag: ripplesPassFrag.text() }) + () => { + context.drawImage(video, 0, 0); + cameraTex(canvas); + render({ frag: ripplesPassFrag.text() }); + } ); }; diff --git a/shaders/glsl/ripplesPass.frag.glsl b/shaders/glsl/ripplesPass.frag.glsl index e38ff70..2f95912 100644 --- a/shaders/glsl/ripplesPass.frag.glsl +++ b/shaders/glsl/ripplesPass.frag.glsl @@ -1,25 +1,39 @@ precision mediump float; varying vec2 vUV; -uniform float aspectRatio; +uniform float aspectRatio, cameraAspectRatio; uniform float time; uniform vec3 clicks[5]; uniform sampler2D tex; uniform sampler2D bloomTex; +uniform sampler2D cameraTex; void main() { - float total = 0.0; + float intensity = 0.0; for (int i = 0; i < 5; i++) { vec3 click = clicks[i]; float distanceToClick = length((click.xy - vUV) * vec2(aspectRatio, 1.0)); float elapsedTime = clamp(time - click.z, -100.0, 100.0); float t = distanceToClick - elapsedTime * 0.5; - total += sin(t * 40.0) / t; + intensity += sin(t * 40.0) / t; } - total *= 0.2; + intensity *= 0.2; - vec2 uv = vUV + total * 0.001; - gl_FragColor = vec4(mix(vec3(0.0), vec3(0.3, 1.0, 0.2), texture2D(tex, uv).r + texture2D(bloomTex, uv).r * 0.5), 1.0); + vec2 uv = vUV + intensity * 0.001; + + float webcamAspectAdjust = cameraAspectRatio / aspectRatio; + vec2 webcamTransform = vec2(1.0, webcamAspectAdjust); + if (webcamAspectAdjust > 1.0) { + webcamTransform = vec2(1.0 / webcamAspectAdjust, 1.0); + } + vec2 webcamUV = ((uv - 0.5) * webcamTransform) + 0.5; + + vec3 webcam = texture2D(cameraTex, 1.0 - webcamUV).rgb; + webcam *= mix(vec3(0.1, 0.3, 0.0), vec3(0.9, 1.0, 0.7), 1.0 - length(vUV - 0.5) * 1.5); + + vec3 code = mix(webcam, vec3(0.7, 1.0, 0.4), texture2D(tex, uv).r * (1.0 + intensity * 0.3) + texture2D(bloomTex, uv).r * 0.5); + + gl_FragColor = vec4(code, 1.0); // gl_FragColor = vec4(uv, 0.5, 1.0); }