From 615217b23785db8574bd230e95ccd95984cffe9a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tristan=20Dani=C3=ABl=20Maat?= Date: Tue, 9 Aug 2022 00:40:27 +0100 Subject: [PATCH] temp --- src/lib/js/index.ts | 2 +- src/music/features/visualizer/Renderer.ts | 64 +++++++++++++++++--- src/music/features/visualizer/fragments.glsl | 4 +- src/music/features/visualizer/vertices.glsl | 23 +++++-- 4 files changed, 74 insertions(+), 19 deletions(-) diff --git a/src/lib/js/index.ts b/src/lib/js/index.ts index 1d12680..5047237 100644 --- a/src/lib/js/index.ts +++ b/src/lib/js/index.ts @@ -36,7 +36,7 @@ document.addEventListener("DOMContentLoaded", () => { // Get the containing element const block = flash.parentNode; - // flash.parentNode.parentNode.removeChild(block); + flash.parentNode.parentNode.removeChild(block); } }); }); diff --git a/src/music/features/visualizer/Renderer.ts b/src/music/features/visualizer/Renderer.ts index e57ea5a..bfc688d 100644 --- a/src/music/features/visualizer/Renderer.ts +++ b/src/music/features/visualizer/Renderer.ts @@ -5,19 +5,22 @@ import { Cube } from "./cube"; import vertexSource from "./vertices.glsl"; import fragmentSource from "./fragments.glsl"; +const ROTATION_SPEED = 0.0005; + class RendererError extends Error {} class Renderer { private canvas: HTMLCanvasElement; private analyser: AnalyserNode; - private analyserData: Float32Array; + private analyserData: Uint8Array; private time: number; private buffers: { indices?: WebGLBuffer; positions?: WebGLBuffer; normals?: WebGLBuffer; + fft?: WebGLBuffer; }; constructor( @@ -32,10 +35,10 @@ class Renderer { this.canvas = canvas; this.analyser = analyser; - this.analyserData = new Float32Array(analyser.frequencyBinCount); + this.analyserData = new Uint8Array(analyser.frequencyBinCount); this.time = 0; - this.buffers = { indices: undefined, positions: undefined }; + this.buffers = {}; } resize() { @@ -56,6 +59,7 @@ class Renderer { .addShader(fragmentSource, gl.FRAGMENT_SHADER) .addAttribute("aVertexPosition") .addAttribute("aVertexNormal") + .addAttribute("aHeight") .addUniforms("uProjectionMatrix") .addUniforms("uModelViewMatrix") .addUniforms("uNormalMatrix") @@ -67,6 +71,11 @@ class Renderer { } initBuffers(gl: WebGLRenderingContext) { + // Scale down the unit cube before we use it + Cube.vertices = Cube.vertices.map( + (num: number) => num / this.analyser.frequencyBinCount + ); + // Position buffer const positionBuffer = gl.createBuffer(); @@ -99,6 +108,17 @@ class Renderer { gl.bindBuffer(gl.ARRAY_BUFFER, normalBuffer); gl.bufferData(gl.ARRAY_BUFFER, Cube.normals, gl.STATIC_DRAW); this.buffers.normals = normalBuffer; + + // fft data buffer + const fftBuffer = gl.createBuffer(); + + if (fftBuffer === null) { + throw new Error("could not initialize fft buffer"); + } + + // No need to initialize this buffer here since we will be + // updating it as soon as we start rendering anyway. + this.buffers.fft = fftBuffer; } initGL(gl: WebGLRenderingContext, shader: Shader) { @@ -106,7 +126,7 @@ class Renderer { gl.clearColor(0.0, 0.0, 0.0, 1.0); gl.clearDepth(1.0); gl.enable(gl.DEPTH_TEST); - gl.depthFunc(gl.LEQUAL); + gl.depthFunc(gl.LESS); } updateMatrices(gl: WebGLRenderingContext, shader: Shader) { @@ -125,13 +145,14 @@ class Renderer { ); const modelViewMatrix = mat4.create(); - mat4.translate(modelViewMatrix, modelViewMatrix, [0.0, 1.0, -8.0]); - mat4.rotateY(modelViewMatrix, modelViewMatrix, this.time / 1000); - mat4.rotateX( + mat4.translate(modelViewMatrix, modelViewMatrix, [0.0, 0.0, -1.5]); + mat4.rotateX(modelViewMatrix, modelViewMatrix, Math.PI / 6); + mat4.rotateY( modelViewMatrix, modelViewMatrix, - (this.time / 1000) * 0.7 + this.time * ROTATION_SPEED ); + mat4.translate(modelViewMatrix, modelViewMatrix, [-1.0, 0.0, 0.0]); gl.uniformMatrix4fv( shader.getUniform("uModelViewMatrix"), false, @@ -152,7 +173,8 @@ class Renderer { if ( this.buffers.indices === undefined || this.buffers.positions === undefined || - this.buffers.normals === undefined + this.buffers.normals === undefined || + this.buffers.fft === undefined ) { throw new Error("failed to create buffers before rendering"); } @@ -184,8 +206,30 @@ class Renderer { ); gl.enableVertexAttribArray(shader.getAttribute("aVertexNormal")); + // Update fft + this.analyser.getByteFrequencyData(this.analyserData); + + gl.bindBuffer(gl.ARRAY_BUFFER, this.buffers.fft); + gl.bufferData(gl.ARRAY_BUFFER, this.analyserData, gl.STREAM_DRAW); + gl.vertexAttribPointer( + shader.getAttribute("aHeight"), + 1, + gl.UNSIGNED_BYTE, + false, + 0, + 0 + ); + gl.vertexAttribDivisor(shader.getAttribute("aHeight"), 1); + gl.enableVertexAttribArray(shader.getAttribute("aHeight")); + gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT); - gl.drawElementsInstanced(gl.TRIANGLES, 36, gl.UNSIGNED_SHORT, 0, 2); + gl.drawElementsInstanced( + gl.TRIANGLES, + 36, + gl.UNSIGNED_SHORT, + 0, + this.analyser.frequencyBinCount + ); requestAnimationFrame((time) => { this.time = time; diff --git a/src/music/features/visualizer/fragments.glsl b/src/music/features/visualizer/fragments.glsl index f6b9b8d..b0d6784 100644 --- a/src/music/features/visualizer/fragments.glsl +++ b/src/music/features/visualizer/fragments.glsl @@ -2,7 +2,7 @@ precision highp float; -flat in vec3 vColor; +flat in vec4 vColor; out vec4 color; -void main() { color = vec4(vColor, 1.0); } +void main() { color = vColor; } diff --git a/src/music/features/visualizer/vertices.glsl b/src/music/features/visualizer/vertices.glsl index 51e81de..8a66554 100644 --- a/src/music/features/visualizer/vertices.glsl +++ b/src/music/features/visualizer/vertices.glsl @@ -9,21 +9,32 @@ precision highp float; layout(location = 0) in vec4 aVertexPosition; layout(location = 1) in vec3 aVertexNormal; -flat out vec3 vColor; +layout(location = 2) in float aHeight; +flat out vec4 vColor; uniform mat4 uModelViewMatrix; uniform mat4 uProjectionMatrix; uniform mat4 uNormalMatrix; void main() { - vec4 instancePosition = - vec4(float(gl_InstanceID) * aVertexPosition.x + aVertexPosition.x, - aVertexPosition.yzw); - gl_Position = uProjectionMatrix * uModelViewMatrix * instancePosition; + float instanceX = + aVertexPosition.x + float(gl_InstanceID) * 2.0 * abs(aVertexPosition.x); + float vertexY = + aVertexPosition.y > 0.0 ? aVertexPosition.y * aHeight : aVertexPosition.y; + + gl_Position = uProjectionMatrix * uModelViewMatrix * + vec4(instanceX, vertexY, aVertexPosition.zw); vec4 transformedNormal = uNormalMatrix * vec4(aVertexNormal, 1.0); float directionalLight = max(dot(transformedNormal.xyz, LIGHT_DIRECTION), 0.0); - vColor = AMBIENT_LIGHT + (directionalLight * LIGHT_COLOR); + if (aHeight == 0.0) { + vColor = vec4(0.0, 0.0, 0.0, 0.0); + } else { + vec4 transformedNormal = uNormalMatrix * vec4(aVertexNormal, 1.0); + float directionalLight = + max(dot(transformedNormal.xyz, LIGHT_DIRECTION), 0.0); + vColor = vec4(AMBIENT_LIGHT + (directionalLight * LIGHT_COLOR), 1.0); + } }