From 9447fa485f9a1e0c081b49c7f1d55ba6b65951cf Mon Sep 17 00:00:00 2001 From: Alex Kempton Date: Sun, 4 Apr 2021 19:51:19 +0200 Subject: [PATCH] Added basic noise shader example --- src/glsl/noise/fragment.glsl | 22 +++++++++++++++++ src/glsl/noise/vertex.glsl | 10 ++++++++ src/sketches/Noise.js | 48 ++++++++++++++++++++++++++++++++++++ src/sketches/index.ts | 5 ++++ 4 files changed, 85 insertions(+) create mode 100644 src/glsl/noise/fragment.glsl create mode 100644 src/glsl/noise/vertex.glsl create mode 100644 src/sketches/Noise.js diff --git a/src/glsl/noise/fragment.glsl b/src/glsl/noise/fragment.glsl new file mode 100644 index 0000000..440b906 --- /dev/null +++ b/src/glsl/noise/fragment.glsl @@ -0,0 +1,22 @@ +#pragma glslify: import('../../glsl/common.glsl') + +uniform sampler2D faceHighlightsTex; + +uniform float time; +varying vec2 vUv; + +void main( void ) { + // We use this texture to get soft edges of face + float edgeCol = texture2D(faceHighlightsTex, vUv).r; + + // Get some noise + float hue = snoise(vec3(vUv * 5., time * 0.5)); + + // Multiple edge alpha with noise to get final alpha + float a = edgeCol * hue; + + // Rainbow colors :P + vec3 rgb = hsl2rgb(vec3(hue, 1., 0.5)); + + gl_FragColor = vec4(rgb, a); +} \ No newline at end of file diff --git a/src/glsl/noise/vertex.glsl b/src/glsl/noise/vertex.glsl new file mode 100644 index 0000000..a52641e --- /dev/null +++ b/src/glsl/noise/vertex.glsl @@ -0,0 +1,10 @@ +varying vec2 vUv; + +void main() +{ + // We have to give the UV from vertex to fragment shader, using a "varying" + vUv = uv; + + // Usual vertex shader projection stuff + gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.); +} \ No newline at end of file diff --git a/src/sketches/Noise.js b/src/sketches/Noise.js new file mode 100644 index 0000000..777993a --- /dev/null +++ b/src/sketches/Noise.js @@ -0,0 +1,48 @@ +import { EffectPass } from 'postprocessing'; + +import { Mesh, TextureLoader, ShaderMaterial } from 'three'; + +import { renderPass, webcamEffect } from '../setup'; + +import { faceGeometry } from '../faceMesh'; + +import faceHighlightsUrl from '../assets/face_highlights.jpg'; + +import vert from '../glsl/noise/vertex.glsl'; +import frag from '../glsl/noise/fragment.glsl'; + +// Soft edges of face texture +const faceHighlightsTex = new TextureLoader().load(faceHighlightsUrl); + +export class Noise { + constructor({ composer, scene }) { + this.mat = new ShaderMaterial({ + uniforms: { + time: { value: 1.0 }, + faceHighlightsTex: { value: faceHighlightsTex }, + }, + vertexShader: vert, + fragmentShader: frag, + transparent: true, // Important to blend with webcam behind using alpha in shader + }); + + // Add mesh with ShaderMaterial + const mesh = new Mesh(faceGeometry, this.mat); + scene.add(mesh); + + // Setup all the passes used below + const camPass = new EffectPass(null, webcamEffect); + + // Need these settings to stop buffers getting cleared, etc + camPass.renderToScreen = true; + renderPass.renderToScreen = true; + renderPass.clear = false; + + composer.addPass(camPass); // Webcam background + composer.addPass(renderPass); // Shader mesh + } + + update({ elapsedS }) { + this.mat.uniforms.time.value = elapsedS; + } +} diff --git a/src/sketches/index.ts b/src/sketches/index.ts index 93a3bc4..deaff54 100644 --- a/src/sketches/index.ts +++ b/src/sketches/index.ts @@ -8,6 +8,7 @@ import { Tunnel } from './Tunnel'; import { Lumpy } from './Lumpy'; import { Drift } from './Drift'; import { Devil } from './Devil'; +import { Noise } from './Noise'; interface SketchConstructorArgs { composer: EffectComposer; @@ -54,4 +55,8 @@ export const sketches: SketchItem[] = [ Module: Devil, icon: '👹', }, + { + Module: Noise, + icon: '✨', + }, ];