Last active
February 24, 2021 05:31
-
-
Save Efetivos/46abca8a702545aade334f33e93dac0c to your computer and use it in GitHub Desktop.
DDD Transition
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <!DOCTYPE html> | |
| <html lang="en" > | |
| <head> | |
| <meta charset="UTF-8"> | |
| <title>[DDD] WebGL Transiton</title> | |
| <link rel="stylesheet" href="./style.css"> | |
| </head> | |
| <body> | |
| <!-- partial:index.partial.html --> | |
| <button class="play">PLAY</button> | |
| <script type="x-shader/x-vertex" id="vertex"> | |
| attribute vec3 position; | |
| attribute vec3 normal; | |
| attribute vec2 uv; | |
| uniform mat4 modelViewMatrix; | |
| uniform mat4 projectionMatrix; | |
| uniform mat3 normalMatrix; | |
| varying vec3 vNormal; | |
| varying vec2 vUv; | |
| void main() { | |
| vNormal = normalize(normalMatrix * normal); | |
| vUv = uv; | |
| gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0); | |
| } | |
| </script> | |
| <script type="x-shader/x-fragment" id="fragment"> | |
| precision highp float; | |
| // 2D Random | |
| float random (in vec2 st) { return fract(sin(dot(st.xy, vec2(12.9898,78.233))) * 43758.5453123); } | |
| // 2D Noise based on Morgan McGuire @morgan3d | |
| // https://www.shadertoy.com/view/4dS3Wd | |
| float noise (in vec2 st) { | |
| vec2 i = floor(st); | |
| vec2 f = fract(st); | |
| // Four corners in 2D of a tile | |
| float a = random(i); | |
| float b = random(i + vec2(1.0, 0.0)); | |
| float c = random(i + vec2(0.0, 1.0)); | |
| float d = random(i + vec2(1.0, 1.0)); | |
| // Smooth Interpolation | |
| // Cubic Hermine Curve. Same as SmoothStep() | |
| vec2 u = f*f*(3.0-2.0*f); | |
| // u = smoothstep(0.,1.,f); | |
| // Mix 4 coorners percentages | |
| return mix(a, b, u.x) + (c - a)* u.y * (1.0 - u.x) + (d - b) * u.x * u.y; | |
| } | |
| // Comes from the Pixel Spirit Deck by Patricio Gonzalez Vivo | |
| float stroke(float x, float s, float w) { | |
| float d = step(s, x + w * .5) - step(s, x - w * .5); | |
| return clamp(d, 0., 1.); | |
| } | |
| // https://github.com/msfeldstein/glsl-map/blob/master/index.glsl#L1 | |
| float map(float value, float inMin, float inMax, float outMin, float outMax) { | |
| return outMin + (outMax - outMin) * (value - inMin) / (inMax - inMin); | |
| } | |
| uniform float uProgress; | |
| uniform float uNoiseAmp; | |
| uniform float uNoiseFreq; | |
| uniform sampler2D uTexture; | |
| varying vec2 vUv; | |
| varying vec2 v_texCoords; | |
| uniform sampler2D u_texture; | |
| void main() { | |
| vec3 color1 = vec3(1, 1, 1); | |
| vec3 color2 = vec3(1, 0.5, 0.5); | |
| //vec3 color2; | |
| float noisyX = vUv.x + noise(vUv * vec2(uNoiseFreq)) * uNoiseAmp; | |
| // Now that we added noise, we want to remap progress to take into account the noise amplitude | |
| // to ensure that our transition runs all the way through | |
| float progress = map(uProgress, 0., 1., 0. - uNoiseAmp, 1. + uNoiseAmp); | |
| // https://thebookofshaders.com/glossary/?search=step | |
| // Basically, returns 0 if progress > vUv.x, returns 1 otherwise. | |
| float weight = step(noisyX, progress); | |
| // https://thebookofshaders.com/glossary/?search=mix | |
| // The mix method will perform a linear interpolation between color1 and color2, based on the weight parameter. | |
| // In this specific case, since we're using step to compute the weight value (and step only returns 0 or 1), it will either be fully color1 or fully color2. | |
| vec3 tex = texture2D(uTexture, vUv).rgb; | |
| vec3 color = mix(color1, tex, weight); | |
| gl_FragColor = vec4(color, 1.); | |
| } | |
| </script> | |
| <!-- partial --> | |
| <script src='https://unpkg.co/gsap@3/dist/gsap.min.js'></script> | |
| <script src='https://cdnjs.cloudflare.com/ajax/libs/jquery/3.5.1/jquery.min.js'></script><script type="module" src="./script.js"></script> | |
| </body> | |
| </html> |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| //Using OGL (very light WebGL Lib | |
| // https://oframe.github.io/ogl/ | |
| import { | |
| Renderer, | |
| Program, | |
| Mesh, | |
| Camera, | |
| Transform, | |
| Plane, | |
| TextureLoader, | |
| Texture, | |
| } from "https://cdn.skypack.dev/ogl@0.0.65"; | |
| import Tweakpane from "https://cdn.skypack.dev/tweakpane@1.5.9"; | |
| const PARAMS = { | |
| //progress: 0.5, | |
| progress: 0, | |
| noiseAmp: 1.5, | |
| //noiseFreq: 1, | |
| noiseFreq: .956, | |
| } | |
| const vertex = document.getElementById("vertex").textContent; | |
| const fragment = document.getElementById("fragment").textContent; | |
| // Classic OGL setup, nothing fancy here... | |
| // This is not related to the transition logic | |
| const renderer = new Renderer({ | |
| alpha: true, | |
| antialias: true, | |
| }); | |
| const gl = renderer.gl; | |
| document.body.appendChild(gl.canvas); | |
| const camera = new Camera(gl, { fov: 35 }); | |
| camera.position.set(0, 0, 10); | |
| const scene = new Transform(); | |
| const texture = new Texture(gl); | |
| // update image value with source once loaded | |
| const img = new Image(); | |
| img.crossOrigin = "anonymous"; | |
| img.src = 'https://raw.githubusercontent.com/Efetivos/gallery/master/houses/house2.jpg'; | |
| img.onload = () => (texture.image = img); | |
| const program = new Program(gl, { | |
| alpha: true, | |
| vertex, | |
| fragment, | |
| uniforms: { | |
| uProgress: { value: PARAMS.progress }, | |
| uNoiseAmp: { value: PARAMS.noiseAmp }, | |
| uNoiseFreq: { value: PARAMS.noiseFreq }, | |
| uTexture: { value: texture } | |
| }, | |
| }); | |
| console.log(program) | |
| // Here we're computing the dimensions of the viewport in OGL units. | |
| // We do so in order to create a plane covers exactly the size of the screen. | |
| let aspect = window.innerWidth / window.innerHeight; | |
| let vFov = (camera.fov * Math.PI) / 180; | |
| let height = 2 * Math.tan(vFov / 2) * camera.position.z; | |
| let width = height * aspect; | |
| let geometry = new Plane(gl, { width, height }); | |
| let plane = new Mesh(gl, { | |
| geometry, | |
| program, | |
| }); | |
| plane.position.set(0, 0, 0); | |
| plane.setParent(scene); | |
| renderer.setSize(window.innerWidth, window.innerHeight); | |
| camera.perspective({ | |
| aspect: gl.canvas.width / gl.canvas.height, | |
| }); | |
| // | |
| // onClick | |
| //____________________________ | |
| let animating = false | |
| document.querySelector('.play').addEventListener("click", function() { | |
| let time = 3 | |
| if(!animating) { | |
| let puuv = program.uniforms.uNoiseAmp.value | |
| animating = true | |
| gsap.fromTo(program.uniforms.uNoiseAmp, { value: 1.5 }, {delay: time * 0.5, value: 0, duration: time * 0.5 , ease: 'expo.out'}) | |
| gsap.fromTo(program.uniforms.uProgress, { value: .374 }, { value: 1, duration: time , ease: 'expo.inOut', onUpdate: ()=>{ | |
| renderer.render({ scene, camera }) | |
| }, onComplete: ()=> { animating = false } }) | |
| } | |
| }, false) | |
| // | |
| // resize | |
| //____________________________ | |
| window.addEventListener("resize", onResize, false) | |
| function onResize() { | |
| aspect = window.innerWidth / window.innerHeight; | |
| renderer.setSize(window.innerWidth, window.innerHeight); | |
| camera.perspective({ | |
| aspect: gl.canvas.width / gl.canvas.height, | |
| }); | |
| } | |
| // | |
| // Control GUI | |
| //____________________________ | |
| const gui = new Tweakpane(); | |
| gui.addInput(PARAMS, 'progress', { | |
| label: 'Progress', | |
| min: 0, | |
| max: 1, | |
| step: 0.001, | |
| }) | |
| .on("change", (value) => { | |
| program.uniforms.uProgress.value = value; | |
| renderer.render({ scene, camera }); | |
| }); | |
| gui.addInput(PARAMS, 'noiseAmp', { | |
| label: 'Noise amplitude', | |
| min: 0, | |
| max: 1.5, | |
| step: 0.0001, | |
| }) | |
| .on("change", (value) => { | |
| program.uniforms.uNoiseAmp.value = value; | |
| renderer.render({ scene, camera }); | |
| }); | |
| gui.addInput(PARAMS, 'noiseFreq', { | |
| label: 'Noise frequency', | |
| min: 0, | |
| max: 5, | |
| step: 0.001, | |
| }) | |
| .on("change", (value) => { | |
| program.uniforms.uNoiseFreq.value = value; | |
| renderer.render({ scene, camera }); | |
| }); | |
| renderer.render({ scene, camera }); | |
| // | |
| // rAF | |
| //____________________________ | |
| function update() { | |
| requestAnimationFrame(update); | |
| renderer.render({ scene, camera }) | |
| } | |
| //requestAnimationFrame(update) |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| body { | |
| font-family: 'Cardo', serif; | |
| background: #fff; | |
| } | |
| canvas { | |
| position: fixed; | |
| top: 0; | |
| left: 0; | |
| } | |
| .play { | |
| position: absolute; | |
| z-index: 1; | |
| left: 2vw; | |
| bottom: 2vw; | |
| padding: 10px 15px; | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment