Created
July 29, 2020 04:39
-
-
Save wonglok/3b9033a250926b52771e92c2cbcbbc35 to your computer and use it in GitHub Desktop.
FastFlame by Wong Lok @wonglok831 on IG
This file contains 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
// import { PlaneBufferGeometry } from 'three/build/three.module' | |
import { ShaderMaterial, PlaneBufferGeometry, Mesh } from 'three' | |
let glsl = v => v[0] | |
export class FastFlame { | |
constructor ({ onLoop, onResize, onClean, resX = 128, resY = 128 }) { | |
this.onLoop = onLoop | |
this.onClean = onClean | |
this.onResize = onResize | |
this.out = {} | |
this.works = [] | |
this.addWork = v => this.works.push(v) | |
let displayMaterial = new ShaderMaterial({ | |
transparent: true, | |
wireframe: true, | |
uniforms: { | |
textureOutput: { value: null }, | |
textureSimulation: { value: null }, | |
time: { value: null } | |
}, | |
vertexShader: this.getDisplayVert(), | |
fragmentShader: this.getDisplayFrag() | |
}) | |
this.onResize(() => { | |
let dpi = 1 / 1.5 | |
let rect = { | |
width: resX, | |
height: resY | |
} | |
displayMaterial.defines.resolution = `vec2(${(rect.width * dpi).toFixed(1)},${(rect.height * dpi).toFixed(1)})` | |
}) | |
// let makeGeo = () => { | |
// let getUVandPosition = () => { | |
// let newArr = [] | |
// var na = 0 | |
// let nn = resX * resY | |
// var idx = 0 | |
// for (var j = 0; j < resY; j++) { | |
// for (var i = 0; i < resX; i++) { | |
// newArr[na + 0] = i / resX | |
// newArr[na + 1] = j / resY | |
// newArr[na + 2] = idx / nn | |
// na += 3 | |
// idx++ | |
// } | |
// } | |
// // console.log('total points', idx) | |
// return new Float32Array(newArr) | |
// } | |
// let makePosition = () => { | |
// let newArr = [] | |
// var na = 0 | |
// // let nn = resX * resY | |
// // var idx = 0 | |
// for (var j = 0; j < resY; j++) { | |
// for (var i = 0; i < resX; i++) { | |
// newArr[na + 0] = ((i / resX) - 0.5) * 256 | |
// newArr[na + 1] = ((j / resY) - 0.5) * 256 | |
// newArr[na + 2] = 0 | |
// na += 3 | |
// // idx++ | |
// } | |
// } | |
// // console.log('total points', idx) | |
// return new Float32Array(newArr) | |
// } | |
// var geometry = new BufferGeometry() | |
// geometry.setAttribute('position', new BufferAttribute(makePosition(), 3)) | |
// geometry.setAttribute('uvv', new BufferAttribute(getUVandPosition(), 3)) | |
// return geometry | |
// } | |
let geometry = new PlaneBufferGeometry(400, 400, resX / 4, resY / 4) | |
this.addWork(() => { | |
let time = window.performance.now() * 0.001 | |
displayMaterial.uniforms.time.value = time * 0.43 | |
}) | |
this.onLoop(() => { | |
this.works.forEach((v) => { v() }) | |
}) | |
this.out.mesh = new Mesh(geometry, displayMaterial) | |
} | |
getDisplayVert () { | |
return glsl` | |
uniform float dpi; | |
varying vec4 posData; | |
// attribute vec3 uvv; | |
uniform float time; | |
const mat2 m = mat2( 0.80, 0.60, -0.60, 0.80 ); | |
float noise( in vec2 p ) { | |
return sin(p.x)*sin(p.y); | |
} | |
float fbm4( vec2 p ) { | |
float f = 0.0; | |
f += 0.5000 * noise( p ); p = m * p * 2.02; | |
f += 0.2500 * noise( p ); p = m * p * 2.03; | |
f += 0.1250 * noise( p ); p = m * p * 2.01; | |
f += 0.0625 * noise( p ); | |
return f / 0.9375; | |
} | |
float fbm6( vec2 p ) { | |
float f = 0.0; | |
f += 0.500000*(0.5+0.5*noise( p )); p = m*p*2.02; | |
f += 0.250000*(0.5+0.5*noise( p )); p = m*p*2.03; | |
f += 0.125000*(0.5+0.5*noise( p )); p = m*p*2.01; | |
f += 0.062500*(0.5+0.5*noise( p )); p = m*p*2.04; | |
f += 0.031250*(0.5+0.5*noise( p )); p = m*p*2.01; | |
f += 0.015625*(0.5+0.5*noise( p )); | |
return f/0.96875; | |
} | |
float pattern (vec2 p) { | |
float vout = fbm4( p + time + fbm6( p + fbm4( p + time )) ); | |
return abs(vout); | |
} | |
void main (void) { | |
vec4 outputData = vec4(0.0); | |
float dynamo = 200.0 * (0.5 - 1.5 * pattern(uv.xy + cos(0.1 + time * 0.3))); | |
outputData.x = mix(position.x, dynamo, 0.9); | |
outputData.y = mix(position.y, dynamo, 0.05); | |
outputData.z = mix(position.z, dynamo, 0.05); | |
gl_Position = projectionMatrix * modelViewMatrix * vec4(outputData.xyz, 1.0); | |
posData = gl_Position; | |
gl_PointSize = 3.5; | |
} | |
` | |
} | |
getDisplayFrag () { | |
return glsl` | |
uniform float time; | |
// varying vec4 simData; | |
// varying vec4 outData; | |
varying vec4 posData; | |
const mat2 m = mat2( 0.80, 0.60, -0.60, 0.80 ); | |
float noise( in vec2 p ) { | |
return sin(p.x)*sin(p.y); | |
} | |
float fbm4( vec2 p ) | |
{ | |
float f = 0.0; | |
f += 0.5000 * noise( p ); p = m * p * 2.02; | |
f += 0.2500 * noise( p ); p = m * p * 2.03; | |
f += 0.1250 * noise( p ); p = m * p * 2.01; | |
f += 0.0625 * noise( p ); | |
return f / 0.9375; | |
} | |
float fbm6( vec2 p ) | |
{ | |
float f = 0.0; | |
f += 0.500000*(0.5+0.5*noise( p )); p = m*p*2.02; | |
f += 0.250000*(0.5+0.5*noise( p )); p = m*p*2.03; | |
f += 0.125000*(0.5+0.5*noise( p )); p = m*p*2.01; | |
f += 0.062500*(0.5+0.5*noise( p )); p = m*p*2.04; | |
f += 0.031250*(0.5+0.5*noise( p )); p = m*p*2.01; | |
f += 0.015625*(0.5+0.5*noise( p )); | |
return f/0.96875; | |
} | |
float pattern (vec2 p) { | |
float vout = fbm4( p + time + fbm6( p + fbm4( p + time )) ); | |
return abs(vout); | |
} | |
void main (void) { | |
// vec2 pt = gl_FragCoord.xy / resolution.xy; | |
float rx = 0.9 - pattern((posData.xy / resolution.xy) + cos(0.1 + time * 0.3)); | |
float ry = 0.9 - pattern((posData.xy / resolution.xy) + cos(0.2 + time * 0.3)); | |
float rz = 0.9 - pattern((posData.xy / resolution.xy) + cos(0.3 + time * 0.3)); | |
gl_FragColor = vec4(rx, ry, rz, 0.5); | |
// vec2 hpt = gl_PointCoord.xy - vec2(0.5, 0.5); | |
// if (length(hpt) < 0.5) { | |
// } else { | |
// discard; | |
// } | |
} | |
` | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
https://www.instagram.com/p/CDNngW7Ht5v/