From c7a97ef061534321596aa440b8d88003ec83b8d0 Mon Sep 17 00:00:00 2001 From: fncischen Date: Wed, 25 Nov 2020 20:48:30 -0800 Subject: [PATCH 1/3] Set up Vertex Shader to built in Three.js Standard Material --- src/components/particles/rainParticles.js | 61 ++++----- .../shaders/RainParticleMaterial.js | 21 +++- .../shaders/RainParticleMaterialTwo.js | 118 ++++++++++++++++++ src/index.js | 2 +- 4 files changed, 166 insertions(+), 36 deletions(-) create mode 100644 src/components/shaders/RainParticleMaterialTwo.js diff --git a/src/components/particles/rainParticles.js b/src/components/particles/rainParticles.js index dcb2398..8371851 100644 --- a/src/components/particles/rainParticles.js +++ b/src/components/particles/rainParticles.js @@ -2,6 +2,7 @@ import * as THREE from 'three'; import React, {useRef,useEffect} from 'react' import {useFrame} from 'react-three-fiber' import RainMat from "../shaders/RainParticleMaterial.js"; +import RainMat2 from "../shaders/RainParticleMaterialTwo.js"; export default function RainParticles({enabled}) { @@ -17,7 +18,7 @@ export default function RainParticles({enabled}) { var particleCount; var mTime = 0; var mDuration = 0.5; - var mTimeStep = (1/2000); + var mTimeStep = (1/60); var S = 80; // particleDimension var progress = 0; @@ -77,7 +78,7 @@ export default function RainParticles({enabled}) { for (let x = -S; x < S; x += 1) { for (let z = -S; z < S; z += 1) { - xzcoords.push(x / (S / 150) + 1, z / (S / 150) + 1); + xzcoords.push(x / (S / 100) + 1, z / (S / 100) + 1); // this meanss between -S and S, the xz coordinates will // x/4 + 1 , z/4 + 1 // iterate every z/4 + 1 (offset). // -19 .... 1, 5/4, 6/4, 7/4, 2, 9/4, 10/4, 11/4, 3 ... -19 (difference of 1/4) // @@ -93,14 +94,14 @@ export default function RainParticles({enabled}) { // prefabBufferGeometry.setAttribute('position', new THREE.BufferAttribute(new Float32Array(particleCount * prefabVerticiesLength),3)); // keep for consistency prefabBufferGeometry.setAttribute('aPositionStart', new THREE.BufferAttribute(new Float32Array(multiplier *3 * prefabVerticiesLength),3)); prefabBufferGeometry.setAttribute('aPositionEnd', new THREE.BufferAttribute(new Float32Array(multiplier *3 * prefabVerticiesLength),3)); - prefabBufferGeometry.setAttribute('color', new THREE.BufferAttribute(new Float32Array(multiplier *3 * prefabVerticiesLength),3)); + // prefabBufferGeometry.setAttribute('color', new THREE.BufferAttribute(new Float32Array(multiplier *3 * prefabVerticiesLength),3)); prefabBufferGeometry.setAttribute("aOffset", new THREE.BufferAttribute(new Float32Array(multiplier * prefabVerticiesLength),1)); // var posBuffer = prefabBufferGeometry.getAttribute('position'); var aStartPosBuffer = prefabBufferGeometry.getAttribute('aPositionStart'); var aEndPosBuffer = prefabBufferGeometry.getAttribute('aPositionEnd'); var aOffset = prefabBufferGeometry.getAttribute('aOffset'); - var aColor = prefabBufferGeometry.getAttribute('color'); + // var aColor = prefabBufferGeometry.getAttribute('color'); @@ -147,29 +148,29 @@ export default function RainParticles({enabled}) { // value: [0, 0, 0] // } // }; - var color = new THREE.Color(); - var h,s,l; - - for(var i = 0, offset = 0; i < multiplier; i++) { - // h = i/particleCount * 50; - // // s = THREE.MathUtils.randFloatSpread(0.59, 0.61); - // l = THREE.MathUtils.randFloatSpread(0.7, 0.9); - // s = 0.8; - // l = 0.5; - h = 0.7; - l = 0.6; - s = 0.8; - - color.setHSL(h,s,l); - // console.log("loop") - for(var j = 0; j < prefabGeometry.vertices.length; j++) { - aColor.array[offset++] = 0.5; - aColor.array[offset++] = 0; - aColor.array[offset++] = 0; - // console.log('loop'); - } + // var color = new THREE.Color(); + // var h,s,l; + + // for(var i = 0, offset = 0; i < multiplier; i++) { + // // h = i/particleCount * 50; + // // // s = THREE.MathUtils.randFloatSpread(0.59, 0.61); + // // l = THREE.MathUtils.randFloatSpread(0.7, 0.9); + // // s = 0.8; + // // l = 0.5; + // h = 0.7; + // l = 0.6; + // s = 0.8; + + // color.setHSL(h,s,l); + // // console.log("loop") + // for(var j = 0; j < prefabGeometry.vertices.length; j++) { + // aColor.array[offset++] = 0.5; + // aColor.array[offset++] = 0; + // aColor.array[offset++] = 0; + // // console.log('loop'); + // } - } + // } }) @@ -233,13 +234,13 @@ export default function RainParticles({enabled}) { metalness: 0.7 })} position={[0,0,0]}/> - + - {/* */} + - - + + ) diff --git a/src/components/shaders/RainParticleMaterial.js b/src/components/shaders/RainParticleMaterial.js index ff06347..105277b 100644 --- a/src/components/shaders/RainParticleMaterial.js +++ b/src/components/shaders/RainParticleMaterial.js @@ -66,8 +66,8 @@ const RainMat = new RainParticleMaterial({ uPosition: {type: 'v3', value: [0,0,0]}, uDuration: {type: 'f', value: 0.5}, uProgress: {type: 'f', value: 0}, - color: {type: 'v3', value: [0.7,0.1,0]}, - opacity: {type: 'f', value: 0.1} + color: {type: 'v3', value: [1,0,0]}, + opacity: {type: 'f', value: 0} }, emissive: "#212121", @@ -104,7 +104,7 @@ const RainMat = new RainParticleMaterial({ 'basePosition *= scale;', 'basePosition *= min(1.0, max(0.0, -10.0 + distance(vec3(uPosition.x, uPosition.y, newPosition.z), newPosition)));', 'vec3 finalPos = newPosition + basePosition;', - 'gl_Position = projectionMatrix * viewMatrix * modelMatrix * vec4(finalPos, 1.0);' + 'gl_Position = projectionMatrix * viewMatrix * modelMatrix * vec4(finalPos, 1.0);' ] }, { @@ -113,8 +113,19 @@ const RainMat = new RainParticleMaterial({ // shininess: 50 }) -console.log(RainMat.fragmentShader); -console.log(THREE.ShaderLib['shadow'].fragmentShader); +// console.log(RainMat.fragmentShader); +// console.log(THREE.ShaderChunk['common']) +// console.log(THREE.ShaderChunk['packing']) +// console.log(THREE.ShaderChunk['bsdfs']); +// console.log(THREE.ShaderChunk['shadowmap_pars_fragment']) +// console.log(THREE.ShaderChunk['shadowmask_pars_fragment']) +// console.log(THREE.ShaderLib['shadow'].fragmentShader); +// console.log(THREE.ShaderChunk['tonemapping_fragment']) +// console.log(THREE.ShaderChunk['encodings_fragment']) +// console.log(THREE.ShaderChunk['fog_fragment']) + + + // const vertexShader = ` // attribute vec3 aPositionStart; // attribute vec3 aPositionEnd; diff --git a/src/components/shaders/RainParticleMaterialTwo.js b/src/components/shaders/RainParticleMaterialTwo.js new file mode 100644 index 0000000..3c5668d --- /dev/null +++ b/src/components/shaders/RainParticleMaterialTwo.js @@ -0,0 +1,118 @@ +import * as THREE from "three"; +import particleMaterial from "./ParticleMaterial"; + +var ShaderChunk = {}; + +ShaderChunk['quat_from_axis_angle'] = "vec4 quatFromAxisAngle(vec3 axis, float angle) \n {\n float halfAngle = angle * 0.5; \n return vec4(axis.xyz * sin(halfAngle), cos(halfAngle));\n}\n"; + +ShaderChunk['rotate_vector'] = "vec3 rotateVector(vec4 q, vec3 v) \n { \n return v + 2.0 * cross(q.xyz, cross(q.xyz, v) + q.w * v); \n} \n"; + +ShaderChunk['ease_in_ease_out_sin'] = "float easeInOutSin(float t) \n{ \n return (1.0 + sin(3.141618 * t - 3.141618/ 2.0)) / 2.0; \n} \n"; + +const vertex = ` + attribute vec3 aPositionStart; + attribute vec3 aPositionEnd; + attribute float aOffset; + + uniform vec3 uPosition; + uniform float uProgress; + uniform float mDuration; + + vec4 quatFromAxisAngle(vec3 axis, float angle) { + float halfAngle = angle * 0.5; + return vec4(axis.xyz * sin(halfAngle), cos(halfAngle)); + } + + vec3 rotateVector(vec4 q, vec3 v) { + return v + 2.0 * cross(q.xyz, cross(q.xyz, v) + q.w * v); + } + + float easeInOutSin(float t){ + return (1.0 + sin(3.1416 * t - 3.1416 / 2.0)) / 2.0; + } + + void main(){ + float tProgress = easeInOutSin(min(1.0, max(0.0, (uProgress - aOffset))/mDuration)); + vec3 newPosition = mix(aPositionStart, aPositionEnd, tProgress); + + vec4 quatX = quatFromAxisAngle(vec3(1.0, 0.0, 0.0), 3.1416 / 2.0); + vec3 basePosition = rotateVector(quatX, position); + + float scale = tProgress * 2.0 - 1.0; + scale = 1.0 - scale * scale; + basePosition *= scale; + basePosition *= min(1.0, max(0.0, -10.0 + distance(vec3(uPosition.x, uPosition.y, newPosition.z), newPosition))); + gl_Position = newPosition + basePosition; + } + `; + +class RainParticleMaterialTwo extends THREE.MeshStandardMaterial { + constructor(params, uniformValues) { + super(params); + + this.uniforms = params.uniforms; + + this.vertexShader = params.vertexShader; + this.fragmentShader = null; + this.replacedShader = null; + // this.onBeforeCompile(s); // compilethe + + } + + // https://codepen.io/prisoner849/pen/BvxBPW + + // why this is built in /// modify built in material's shaders before compilation + // https://github.com/mrdoob/three.js/issues/11475 + + + + // for this to work, + // you have to know which shaders to replace + onBeforeCompile(shader){ + + Object.assign(shader.uniforms, this.uniforms); + + // retrieve the shader from existing vertex shader + const vertexShader = this.vertexShader.replace(/(\r\n|\n|\r)/gm, ''); + // console.log('vertex shader :' + vertexShader) + + // matching regex https://www.w3schools.com/jsref/jsref_obj_regexp.asp + // get the attribtues + const attributes = vertexShader.match(/.+?(?=void)/)[0]; + + // console.log('attributes ' + attributes) + + // get the main function from the vertex function + const main = vertexShader.match(/main\(\){(.*?)}/)[1]; + // console.log('main '+ main); + + shader.vertexShader = `${attributes} \n ${shader.vertexShader}`; + + // add the main function + shader.vertexShader = shader.vertexShader.replace( + '#include ', + main.replace('gl_Position =', 'vec3 transformed =') + ); + } + +} + +var RainMat2 = new RainParticleMaterialTwo({ + color: "#EFEFEF", + emissive: "#212121", + flatShading: true, + roughness: 0.1, + metalness: 0.7, + + uniforms: { + uPosition: {type: 'v3', value: [0,0,0]}, + mDuration: {type: 'f', value: 0.5}, + uProgress: {type: 'f', value: 0}, + }, + + vertexShader: vertex + +}) + + +export default RainMat2; \ No newline at end of file diff --git a/src/index.js b/src/index.js index 5b7fa3b..15b5d8a 100644 --- a/src/index.js +++ b/src/index.js @@ -62,7 +62,7 @@ function App() { return (
- + {/* */} From 4535e3f267c160da9dc3aeb0203107faba9b8f1d Mon Sep 17 00:00:00 2001 From: fncischen Date: Wed, 25 Nov 2020 22:16:45 -0800 Subject: [PATCH 2/3] Procedural waterfall complete! --- src/components/particles/rainParticles.js | 44 +++++++++++++------ .../shaders/RainParticleMaterialTwo.js | 7 ++- src/index.js | 4 +- 3 files changed, 38 insertions(+), 17 deletions(-) diff --git a/src/components/particles/rainParticles.js b/src/components/particles/rainParticles.js index 8371851..50f0c46 100644 --- a/src/components/particles/rainParticles.js +++ b/src/components/particles/rainParticles.js @@ -1,6 +1,6 @@ import * as THREE from 'three'; -import React, {useRef,useEffect} from 'react' -import {useFrame} from 'react-three-fiber' +import React, {useRef,useEffect, useFrame} from 'react' +// import {useFrame} from 'react-three-fiber' import RainMat from "../shaders/RainParticleMaterial.js"; import RainMat2 from "../shaders/RainParticleMaterialTwo.js"; @@ -9,17 +9,18 @@ export default function RainParticles({enabled}) { var mParticleSystem; var prefabGeometry; var prefabBufferGeometry; + var mSphere; - var startYheight = 20; - var endYheight = -20; + var startYheight = 50; + var endYheight = -50; var multiplier; var particleCount; var mTime = 0; - var mDuration = 0.5; - var mTimeStep = (1/60); - var S = 80; // particleDimension + var mDuration = 100; + var mTimeStep = 1/5; + var S = 120; // particleDimension var progress = 0; var pLight; @@ -78,7 +79,7 @@ export default function RainParticles({enabled}) { for (let x = -S; x < S; x += 1) { for (let z = -S; z < S; z += 1) { - xzcoords.push(x / (S / 100) + 1, z / (S / 100) + 1); + xzcoords.push(x / (S / 30) + 1, z / (S / 30) + 1); // this meanss between -S and S, the xz coordinates will // x/4 + 1 , z/4 + 1 // iterate every z/4 + 1 (offset). // -19 .... 1, 5/4, 6/4, 7/4, 2, 9/4, 10/4, 11/4, 3 ... -19 (difference of 1/4) // @@ -179,6 +180,7 @@ export default function RainParticles({enabled}) { mParticleSystem = useRef(); pLight = useRef(); + mSphere = useRef(); // particleDimension; // check prefabGeometry = new THREE.OctahedronGeometry(1,0) // dont use buffer geometries // since we want verticies @@ -218,7 +220,7 @@ export default function RainParticles({enabled}) { // console.log(newColor); let color = [newColor.r, newColor.g, newColor.b] pLight.current.color = newColor; - + mSphere.current.material.emissive = newColor; // mParticleSystem.current.material.uniforms['color'].value = color; }) @@ -228,7 +230,7 @@ export default function RainParticles({enabled}) { // mParticleSystem.current.material.uniforms['uProgress'] = return ( - - + + + + + + + + + + + + + + {/* + + + */} + + - - ) diff --git a/src/components/shaders/RainParticleMaterialTwo.js b/src/components/shaders/RainParticleMaterialTwo.js index 3c5668d..dada0a6 100644 --- a/src/components/shaders/RainParticleMaterialTwo.js +++ b/src/components/shaders/RainParticleMaterialTwo.js @@ -93,12 +93,15 @@ class RainParticleMaterialTwo extends THREE.MeshStandardMaterial { '#include ', main.replace('gl_Position =', 'vec3 transformed =') ); + + console.log(shader.fragmentShader); } } var RainMat2 = new RainParticleMaterialTwo({ - color: "#EFEFEF", + color: "#0037b4", + // color: "#27408B", emissive: "#212121", flatShading: true, roughness: 0.1, @@ -106,7 +109,7 @@ var RainMat2 = new RainParticleMaterialTwo({ uniforms: { uPosition: {type: 'v3', value: [0,0,0]}, - mDuration: {type: 'f', value: 0.5}, + mDuration: {type: 'f', value: 100}, uProgress: {type: 'f', value: 0}, }, diff --git a/src/index.js b/src/index.js index 15b5d8a..98c218d 100644 --- a/src/index.js +++ b/src/index.js @@ -23,7 +23,7 @@ const CameraControls = (() => { // const Camera = new THREE.PerspectiveCamera({fov: 60, position: [0, 600, 600], near: 0.1, far: 5000}); camera.position.x = 0; camera.position.y = 0; - camera.position.z = 20; + camera.position.z = 120; camera.fov = 40; camera.near = 0.1; camera.far = 10000; @@ -63,7 +63,7 @@ function App() { return (
{/* */} - + From d37a35f658fc05dad89d396d138bff9285d66e68 Mon Sep 17 00:00:00 2001 From: fncischen Date: Fri, 27 Nov 2020 11:59:59 -0800 Subject: [PATCH 3/3] modified color and particle box dimensions --- src/components/particles/rainParticles.js | 6 +++--- src/components/shaders/RainParticleMaterialTwo.js | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/components/particles/rainParticles.js b/src/components/particles/rainParticles.js index 50f0c46..0938ed5 100644 --- a/src/components/particles/rainParticles.js +++ b/src/components/particles/rainParticles.js @@ -19,8 +19,8 @@ export default function RainParticles({enabled}) { var particleCount; var mTime = 0; var mDuration = 100; - var mTimeStep = 1/5; - var S = 120; // particleDimension + var mTimeStep = 1/20; + var S = 100; // particleDimension var progress = 0; var pLight; @@ -79,7 +79,7 @@ export default function RainParticles({enabled}) { for (let x = -S; x < S; x += 1) { for (let z = -S; z < S; z += 1) { - xzcoords.push(x / (S / 30) + 1, z / (S / 30) + 1); + xzcoords.push(x / (S / 200) + 2, z / (S / 200) + 2); // this meanss between -S and S, the xz coordinates will // x/4 + 1 , z/4 + 1 // iterate every z/4 + 1 (offset). // -19 .... 1, 5/4, 6/4, 7/4, 2, 9/4, 10/4, 11/4, 3 ... -19 (difference of 1/4) // diff --git a/src/components/shaders/RainParticleMaterialTwo.js b/src/components/shaders/RainParticleMaterialTwo.js index dada0a6..5db42e4 100644 --- a/src/components/shaders/RainParticleMaterialTwo.js +++ b/src/components/shaders/RainParticleMaterialTwo.js @@ -100,7 +100,7 @@ class RainParticleMaterialTwo extends THREE.MeshStandardMaterial { } var RainMat2 = new RainParticleMaterialTwo({ - color: "#0037b4", + color: "#4EEE94", // color: "#27408B", emissive: "#212121", flatShading: true,