From 6c6701a47f81d03296aef6594699d1550569e083 Mon Sep 17 00:00:00 2001 From: gracexu94 Date: Sun, 22 Jan 2017 01:09:08 -0500 Subject: [PATCH 01/13] changed shaders and started work on noise generation functions --- src/main.js | 23 +++---- src/noise.js | 66 ++++++++++++++++++-- src/shaders/adam-frag.glsl | 13 ---- src/shaders/my-frag.glsl | 10 +++ src/shaders/{adam-vert.glsl => my-vert.glsl} | 3 + 5 files changed, 83 insertions(+), 32 deletions(-) delete mode 100644 src/shaders/adam-frag.glsl create mode 100644 src/shaders/my-frag.glsl rename src/shaders/{adam-vert.glsl => my-vert.glsl} (73%) diff --git a/src/main.js b/src/main.js index 92b19a4..4d42b61 100644 --- a/src/main.js +++ b/src/main.js @@ -16,25 +16,22 @@ function onLoad(framework) { // var {scene, camera, renderer, gui, stats} = framework; // initialize a simple box and material - var box = new THREE.BoxGeometry(1, 1, 1); - - var adamMaterial = new THREE.ShaderMaterial({ - uniforms: { - image: { // Check the Three.JS documentation for the different allowed types and values - type: "t", - value: THREE.ImageUtils.loadTexture('./adam.jpg') - } - }, - vertexShader: require('./shaders/adam-vert.glsl'), - fragmentShader: require('./shaders/adam-frag.glsl') + var icosahedron = new THREE.IcosahedronGeometry(1, 0); + + var myMaterial = new THREE.ShaderMaterial({ + vertexShader: require('./shaders/my-vert.glsl'), + fragmentShader: require('./shaders/my-frag.glsl') }); - var adamCube = new THREE.Mesh(box, adamMaterial); + + var meshMaterial = new THREE.MeshNormalMaterial(); + + var texturedIcosahedron = new THREE.Mesh(icosahedron, myMaterial); // set camera position camera.position.set(1, 1, 2); camera.lookAt(new THREE.Vector3(0,0,0)); - scene.add(adamCube); + scene.add(texturedIcosahedron); // edit params and listen to changes like this // more information here: https://workshop.chromeexperiments.com/examples/gui/#1--Basic-Usage diff --git a/src/noise.js b/src/noise.js index 2ba8699..03eae71 100644 --- a/src/noise.js +++ b/src/noise.js @@ -1,16 +1,70 @@ +// a bunch of 3d pseudo-random noise functions that return floating point numbers between -1.0 and 1.0 +function generateNoise1(x, y, z) { + var n = x + y + z * 57; + n = (n<<13) ^ n; + return ( 1.0 - (n * (n * n * 15731 + 789221) + 1376312589) / 1073741824.0); +} + +function linearInterpolate(a, b, t) { + return a * (1 - t) + b * t; +} + +function cosineInterpolate(a, b, t) { + var cos_t = (1 - cos(t * Math.PI)) * 0.5; + return linearInterpolate(a, b, cos_t); +} + +// given a point in 3d space, produces a noise value by interpolating surrounding points +function interpolateNoise(x, y, z) { + var integerX = Math.floor(x); + var weightX = x - integerX; + + var integerY = Math.floor(y); + var weightY = y - integerY; + var integerZ = Math.floor(Z); + var weightZ = z - integerZ; -function generateNoise() { - return Math.random() + var v1 = generateNoise1(integerX, integerY, integerZ); + var v2 = generateNoise1(integerX, integerY, integerZ + 1); + var v3 = generateNoise1(integerX, integerY + 1, integerZ + 1); + var v4 = generateNoise1(integerX, integerY + 1, integerZ); + + var v5 = generateNoise1(integerX + 1, integerY, integerZ); + var v6 = generateNoise1(integerX + 1, integerY, integerZ + 1); + var v7 = generateNoise1(integerX + 1, integerY + 1, integerZ + 1); + var v8 = generateNoise1(integerX + 1, integerY + 1, integerZ); + + var i1 = cosineInterpolate(v1, v5, weightX); + var i2 = cosineInterpolate(v2, v6, weightX); + var i3 = cosineInterpolate(v3, v7, weightX); + var i4 = cosineInterpolate(v4, v8, weightX); + + var ii1 = cosineInterpolate(i1, i4, weightY); + var ii2 = cosineInterpolate(i2, i3, weightY); + + return cosineInterpolate(ii1, ii2 , weightZ); } -function whatever() { - console.log('hi'); +// a multi-octave noise generation function that sums multiple noise functions together +// with each subsequent noise function increasing in frequency and decreasing in amplitude +function generateMultiOctaveNoise(x, y, z, numOctaves) { + var total = 0; + var persistence = 1/2.0; + + //loop for some number of octaves + for (var i = 0; i < numOctaves; i++) { + var frequency = Math.pow(2, i); + var amplitude = Math.pow(persistence, i); + + total += interpolateNoise(x * frequency, y * frequency, z * frequency) * amplitude; + } + + return total; } export default { - generateNoise: generateNoise, - whatever: whatever + generateNoise1: generateNoise1 } export function other() { diff --git a/src/shaders/adam-frag.glsl b/src/shaders/adam-frag.glsl deleted file mode 100644 index 5dfa18c..0000000 --- a/src/shaders/adam-frag.glsl +++ /dev/null @@ -1,13 +0,0 @@ -varying vec2 vUv; -varying float noise; -uniform sampler2D image; - - -void main() { - - vec2 uv = vec2(1,1) - vUv; - vec4 color = texture2D( image, uv ); - - gl_FragColor = vec4( color.rgb, 1.0 ); - -} \ No newline at end of file diff --git a/src/shaders/my-frag.glsl b/src/shaders/my-frag.glsl new file mode 100644 index 0000000..78fefb6 --- /dev/null +++ b/src/shaders/my-frag.glsl @@ -0,0 +1,10 @@ +varying vec2 vUv; +varying float noise; +uniform sampler2D image; +varying vec3 vNormal; + +void main() { + + gl_FragColor = vec4( vNormal.rgb, 1.0 ); + +} \ No newline at end of file diff --git a/src/shaders/adam-vert.glsl b/src/shaders/my-vert.glsl similarity index 73% rename from src/shaders/adam-vert.glsl rename to src/shaders/my-vert.glsl index e4b8cc0..01fa426 100644 --- a/src/shaders/adam-vert.glsl +++ b/src/shaders/my-vert.glsl @@ -1,6 +1,9 @@ varying vec2 vUv; +varying vec3 vNormal; + void main() { vUv = uv; + vNormal = normal; gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 ); } \ No newline at end of file From 23dfbd76f033ff8a9aa17ea1a367ae4ebc51eb33 Mon Sep 17 00:00:00 2001 From: gracexu94 Date: Sun, 22 Jan 2017 02:12:43 -0500 Subject: [PATCH 02/13] static offset working for one octave case --- src/main.js | 56 +++++++++++++++++++++++++++++++++++++++++++--------- src/noise.js | 8 ++++---- 2 files changed, 51 insertions(+), 13 deletions(-) diff --git a/src/main.js b/src/main.js index 4d42b61..7e766b4 100644 --- a/src/main.js +++ b/src/main.js @@ -17,6 +17,50 @@ function onLoad(framework) { // initialize a simple box and material var icosahedron = new THREE.IcosahedronGeometry(1, 0); + icosahedron.computeFaceNormals(); + icosahedron.computeVertexNormals(); + + var vertexOffsets = {}; + var vertexNormals = {}; + for (var i = 0; i < icosahedron.faces.length; i++) { + var vertices = icosahedron.vertices; + var face = icosahedron.faces[i]; + console.log(face); + var v1 = vertices[face.a]; + var v2 = vertices[face.b]; + var v3 = vertices[face.c]; + + var vertexNormal1 = face.vertexNormals[0]; + var vertexNormal2 = face.vertexNormals[1]; + var vertexNormal3 = face.vertexNormals[2]; + + vertexNormals[face.a] = vertexNormal1; + vertexNormals[face.b] = vertexNormal2; + vertexNormals[face.c] = vertexNormal3; + + var offset1 = Noise.generateMultiOctaveNoise(v1.x, v1.y, v1.z, 1); + var offset2 = Noise.generateMultiOctaveNoise(v2.x, v2.y, v2.z, 1); + var offset3 = Noise.generateMultiOctaveNoise(v3.x, v3.y, v3.z, 1); + + vertexOffsets[face.a] = offset1; + vertexOffsets[face.b] = offset2; + vertexOffsets[face.c] = offset3; + } + + console.log(vertexOffsets); + console.log(vertexNormals); + for (var j = 0; j < icosahedron.vertices.length; j++) { + console.log(vertexOffsets[j]); + var offset = vertexOffsets[j]; + var normal = vertexNormals[j]; + //normal = normal.multiplyScalar(-1.0); + + var offsetAlongNormal = normal.multiplyScalar(offset); + + icosahedron.vertices[j] = icosahedron.vertices[j].add(offsetAlongNormal); + } + icosahedron.verticesNeedUpdate = true; + var myMaterial = new THREE.ShaderMaterial({ vertexShader: require('./shaders/my-vert.glsl'), @@ -25,13 +69,15 @@ function onLoad(framework) { var meshMaterial = new THREE.MeshNormalMaterial(); - var texturedIcosahedron = new THREE.Mesh(icosahedron, myMaterial); + var texturedIcosahedron = new THREE.Mesh(icosahedron, meshMaterial); + var helper = new THREE.VertexNormalsHelper(texturedIcosahedron); // set camera position camera.position.set(1, 1, 2); camera.lookAt(new THREE.Vector3(0,0,0)); scene.add(texturedIcosahedron); + scene.add(helper); // edit params and listen to changes like this // more information here: https://workshop.chromeexperiments.com/examples/gui/#1--Basic-Usage @@ -47,11 +93,3 @@ function onUpdate(framework) { // when the scene is done initializing, it will call onLoad, then on frame updates, call onUpdate Framework.init(onLoad, onUpdate); - -// console.log('hello world'); - -// console.log(Noise.generateNoise()); - -// Noise.whatever() - -// console.log(other()) \ No newline at end of file diff --git a/src/noise.js b/src/noise.js index 03eae71..7464a8c 100644 --- a/src/noise.js +++ b/src/noise.js @@ -2,7 +2,7 @@ function generateNoise1(x, y, z) { var n = x + y + z * 57; n = (n<<13) ^ n; - return ( 1.0 - (n * (n * n * 15731 + 789221) + 1376312589) / 1073741824.0); + return ( 1.0 - ((n * (n * n * 15731 + 789221) + 1376312589) & 0x7FFFFFFF) / 1073741824.0); } function linearInterpolate(a, b, t) { @@ -10,7 +10,7 @@ function linearInterpolate(a, b, t) { } function cosineInterpolate(a, b, t) { - var cos_t = (1 - cos(t * Math.PI)) * 0.5; + var cos_t = (1 - Math.cos(t * Math.PI)) * 0.5; return linearInterpolate(a, b, cos_t); } @@ -22,7 +22,7 @@ function interpolateNoise(x, y, z) { var integerY = Math.floor(y); var weightY = y - integerY; - var integerZ = Math.floor(Z); + var integerZ = Math.floor(z); var weightZ = z - integerZ; var v1 = generateNoise1(integerX, integerY, integerZ); @@ -64,7 +64,7 @@ function generateMultiOctaveNoise(x, y, z, numOctaves) { } export default { - generateNoise1: generateNoise1 + generateMultiOctaveNoise: generateMultiOctaveNoise } export function other() { From 2993d47706600212d7a0d2d14b87aa39400614ff Mon Sep 17 00:00:00 2001 From: gracexu94 Date: Tue, 24 Jan 2017 11:27:06 -0500 Subject: [PATCH 03/13] transferred noise to shaders --- src/main.js | 56 +++----------------------------- src/shaders/my-vert.glsl | 69 +++++++++++++++++++++++++++++++++++++++- 2 files changed, 72 insertions(+), 53 deletions(-) diff --git a/src/main.js b/src/main.js index 7e766b4..c2da823 100644 --- a/src/main.js +++ b/src/main.js @@ -15,70 +15,22 @@ function onLoad(framework) { // LOOK: the line below is synyatic sugar for the code above. Optional, but I sort of recommend it. // var {scene, camera, renderer, gui, stats} = framework; - // initialize a simple box and material + // initialize icosahedron var icosahedron = new THREE.IcosahedronGeometry(1, 0); - icosahedron.computeFaceNormals(); - icosahedron.computeVertexNormals(); - - var vertexOffsets = {}; - var vertexNormals = {}; - for (var i = 0; i < icosahedron.faces.length; i++) { - var vertices = icosahedron.vertices; - var face = icosahedron.faces[i]; - console.log(face); - var v1 = vertices[face.a]; - var v2 = vertices[face.b]; - var v3 = vertices[face.c]; - - var vertexNormal1 = face.vertexNormals[0]; - var vertexNormal2 = face.vertexNormals[1]; - var vertexNormal3 = face.vertexNormals[2]; - - vertexNormals[face.a] = vertexNormal1; - vertexNormals[face.b] = vertexNormal2; - vertexNormals[face.c] = vertexNormal3; - - var offset1 = Noise.generateMultiOctaveNoise(v1.x, v1.y, v1.z, 1); - var offset2 = Noise.generateMultiOctaveNoise(v2.x, v2.y, v2.z, 1); - var offset3 = Noise.generateMultiOctaveNoise(v3.x, v3.y, v3.z, 1); - - vertexOffsets[face.a] = offset1; - vertexOffsets[face.b] = offset2; - vertexOffsets[face.c] = offset3; - } - - console.log(vertexOffsets); - console.log(vertexNormals); - for (var j = 0; j < icosahedron.vertices.length; j++) { - console.log(vertexOffsets[j]); - var offset = vertexOffsets[j]; - var normal = vertexNormals[j]; - //normal = normal.multiplyScalar(-1.0); - - var offsetAlongNormal = normal.multiplyScalar(offset); - - icosahedron.vertices[j] = icosahedron.vertices[j].add(offsetAlongNormal); - } - icosahedron.verticesNeedUpdate = true; - var myMaterial = new THREE.ShaderMaterial({ vertexShader: require('./shaders/my-vert.glsl'), fragmentShader: require('./shaders/my-frag.glsl') }); - var meshMaterial = new THREE.MeshNormalMaterial(); - - var texturedIcosahedron = new THREE.Mesh(icosahedron, meshMaterial); - var helper = new THREE.VertexNormalsHelper(texturedIcosahedron); - + var texturedIcosahedron = new THREE.Mesh(icosahedron, myMaterial); + // set camera position camera.position.set(1, 1, 2); camera.lookAt(new THREE.Vector3(0,0,0)); scene.add(texturedIcosahedron); - scene.add(helper); - + // edit params and listen to changes like this // more information here: https://workshop.chromeexperiments.com/examples/gui/#1--Basic-Usage gui.add(camera, 'fov', 0, 180).onChange(function(newVal) { diff --git a/src/shaders/my-vert.glsl b/src/shaders/my-vert.glsl index 01fa426..3542aad 100644 --- a/src/shaders/my-vert.glsl +++ b/src/shaders/my-vert.glsl @@ -1,9 +1,76 @@ varying vec2 vUv; varying vec3 vNormal; +const int numOctaves = 1; + +float generateNoise1(int x, int y, int z) { + return fract(sin(dot(vec3(x,y,z), vec3(12.9898, 78.23, 107.0))) * 43758.5453); +} + +float linearInterpolate(float a, float b, float t) { + return a * (1.0 - t) + b * t; +} + +float cosineInterpolate(float a, float b, float t) { + float cos_t = (1.0 - cos(t * 3.14159265359879323846264)) * 0.5; + return linearInterpolate(a, b, cos_t); +} + +// given a point in 3d space, produces a noise value by interpolating surrounding points +float interpolateNoise(float x, float y, float z) { + int integerX = int(floor(x)); + float weightX = x - float(integerX); + + int integerY = int(floor(y)); + float weightY = y - float(integerY); + + int integerZ = int(floor(z)); + float weightZ = z - float(integerZ); + + float v1 = generateNoise1(integerX, integerY, integerZ); + float v2 = generateNoise1(integerX, integerY, integerZ + 1); + float v3 = generateNoise1(integerX, integerY + 1, integerZ + 1); + float v4 = generateNoise1(integerX, integerY + 1, integerZ); + + float v5 = generateNoise1(integerX + 1, integerY, integerZ); + float v6 = generateNoise1(integerX + 1, integerY, integerZ + 1); + float v7 = generateNoise1(integerX + 1, integerY + 1, integerZ + 1); + float v8 = generateNoise1(integerX + 1, integerY + 1, integerZ); + + float i1 = cosineInterpolate(v1, v5, weightX); + float i2 = cosineInterpolate(v2, v6, weightX); + float i3 = cosineInterpolate(v3, v7, weightX); + float i4 = cosineInterpolate(v4, v8, weightX); + + float ii1 = cosineInterpolate(i1, i4, weightY); + float ii2 = cosineInterpolate(i2, i3, weightY); + + return cosineInterpolate(ii1, ii2 , weightZ); +} + +// a multi-octave noise generation function that sums multiple noise functions together +// with each subsequent noise function increasing in frequency and decreasing in amplitude +float generateMultiOctaveNoise(float x, float y, float z) { + float total = 0.0; + float persistence = 1.0/2.0; + + //loop for some number of octaves + for (int i = 0; i < numOctaves; i++) { + float frequency = pow(2.0, float(i)); + float amplitude = pow(persistence, float(i)); + + total += interpolateNoise(x * frequency, y * frequency, z * frequency) * amplitude; + } + + return total; +} void main() { vUv = uv; vNormal = normal; - gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 ); + + float offset = generateMultiOctaveNoise(position[0], position[1], position[2]); + vec3 newPosition = position + offset * normal; + + gl_Position = projectionMatrix * modelViewMatrix * vec4( newPosition, 1.0 ); } \ No newline at end of file From 9fddfbac188fc93c397fa33993059a54c5ea9029 Mon Sep 17 00:00:00 2001 From: gracexu94 Date: Tue, 24 Jan 2017 12:03:04 -0500 Subject: [PATCH 04/13] added icosahedron level of detail to gui controls --- src/main.js | 20 +++++++++++++++----- 1 file changed, 15 insertions(+), 5 deletions(-) diff --git a/src/main.js b/src/main.js index c2da823..6515e4a 100644 --- a/src/main.js +++ b/src/main.js @@ -15,27 +15,37 @@ function onLoad(framework) { // LOOK: the line below is synyatic sugar for the code above. Optional, but I sort of recommend it. // var {scene, camera, renderer, gui, stats} = framework; - // initialize icosahedron - var icosahedron = new THREE.IcosahedronGeometry(1, 0); + // initialize icosahedron object + var icosahedron = { + radius: 1, + detail: 0 + } + var icosahedronGeometry = new THREE.IcosahedronGeometry(icosahedron.radius, icosahedron.detail); var myMaterial = new THREE.ShaderMaterial({ vertexShader: require('./shaders/my-vert.glsl'), fragmentShader: require('./shaders/my-frag.glsl') }); - var texturedIcosahedron = new THREE.Mesh(icosahedron, myMaterial); + var texturedIcosahedron = new THREE.Mesh(icosahedronGeometry, myMaterial); + scene.add(texturedIcosahedron); // set camera position camera.position.set(1, 1, 2); camera.lookAt(new THREE.Vector3(0,0,0)); - - scene.add(texturedIcosahedron); // edit params and listen to changes like this // more information here: https://workshop.chromeexperiments.com/examples/gui/#1--Basic-Usage gui.add(camera, 'fov', 0, 180).onChange(function(newVal) { camera.updateProjectionMatrix(); }); + + gui.add(icosahedron, 'detail', 0, 5).step(1).onFinishChange(function(newVal) { + scene.remove(texturedIcosahedron); + icosahedronGeometry = new THREE.IcosahedronGeometry(1, newVal); + texturedIcosahedron = new THREE.Mesh(icosahedronGeometry, myMaterial); + scene.add(texturedIcosahedron); + }); } // called on frame updates From 7aa62ecce65d5f9e3833264f09ceb341dd9e75f6 Mon Sep 17 00:00:00 2001 From: gracexu94 Date: Tue, 24 Jan 2017 13:21:08 -0500 Subject: [PATCH 05/13] added displacement over time --- src/main.js | 23 ++++++++++++++++------- src/shaders/my-vert.glsl | 3 ++- 2 files changed, 18 insertions(+), 8 deletions(-) diff --git a/src/main.js b/src/main.js index 6515e4a..0eea954 100644 --- a/src/main.js +++ b/src/main.js @@ -4,6 +4,18 @@ import Framework from './framework' import Noise from './noise' import {other} from './noise' +var d = new Date(); +var myMaterial = new THREE.ShaderMaterial({ + uniforms: { + time: { // Check the Three.JS documentation for the different allowed types and values + type: "f", + value: d.getMilliseconds() + } + }, + vertexShader: require('./shaders/my-vert.glsl'), + fragmentShader: require('./shaders/my-frag.glsl') +}); + // called after the scene loads function onLoad(framework) { var scene = framework.scene; @@ -18,15 +30,10 @@ function onLoad(framework) { // initialize icosahedron object var icosahedron = { radius: 1, - detail: 0 + detail: 2 } var icosahedronGeometry = new THREE.IcosahedronGeometry(icosahedron.radius, icosahedron.detail); - var myMaterial = new THREE.ShaderMaterial({ - vertexShader: require('./shaders/my-vert.glsl'), - fragmentShader: require('./shaders/my-frag.glsl') - }); - var texturedIcosahedron = new THREE.Mesh(icosahedronGeometry, myMaterial); scene.add(texturedIcosahedron); @@ -50,7 +57,9 @@ function onLoad(framework) { // called on frame updates function onUpdate(framework) { - // console.log(`the time is ${new Date()}`); + d = new Date(); + myMaterial.uniforms.time.value = d.getMilliseconds(); + myMaterial.needsUpdate = true; } // when the scene is done initializing, it will call onLoad, then on frame updates, call onUpdate diff --git a/src/shaders/my-vert.glsl b/src/shaders/my-vert.glsl index 3542aad..8b7fa40 100644 --- a/src/shaders/my-vert.glsl +++ b/src/shaders/my-vert.glsl @@ -2,6 +2,7 @@ varying vec2 vUv; varying vec3 vNormal; const int numOctaves = 1; +uniform float time; float generateNoise1(int x, int y, int z) { return fract(sin(dot(vec3(x,y,z), vec3(12.9898, 78.23, 107.0))) * 43758.5453); @@ -69,7 +70,7 @@ void main() { vUv = uv; vNormal = normal; - float offset = generateMultiOctaveNoise(position[0], position[1], position[2]); + float offset = generateMultiOctaveNoise(position[0] + time/999.0, position[1] + time/999.0, position[2] + time/999.0); vec3 newPosition = position + offset * normal; gl_Position = projectionMatrix * modelViewMatrix * vec4( newPosition, 1.0 ); From 745edb9d8fb13061ecd3eecbc81970ea9dc78361 Mon Sep 17 00:00:00 2001 From: gracexu94 Date: Tue, 24 Jan 2017 13:38:58 -0500 Subject: [PATCH 06/13] animate doesn't reset --- src/main.js | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/src/main.js b/src/main.js index 0eea954..6d264dc 100644 --- a/src/main.js +++ b/src/main.js @@ -4,20 +4,22 @@ import Framework from './framework' import Noise from './noise' import {other} from './noise' -var d = new Date(); var myMaterial = new THREE.ShaderMaterial({ uniforms: { time: { // Check the Three.JS documentation for the different allowed types and values type: "f", - value: d.getMilliseconds() + value: Date.now() } }, vertexShader: require('./shaders/my-vert.glsl'), fragmentShader: require('./shaders/my-frag.glsl') }); +var programStartTime; + // called after the scene loads function onLoad(framework) { + programStartTime = Date.now(); var scene = framework.scene; var camera = framework.camera; var renderer = framework.renderer; @@ -57,8 +59,7 @@ function onLoad(framework) { // called on frame updates function onUpdate(framework) { - d = new Date(); - myMaterial.uniforms.time.value = d.getMilliseconds(); + myMaterial.uniforms.time.value = Date.now() - programStartTime; myMaterial.needsUpdate = true; } From ea11fe95eb5e6ee056ed5a8b4aa88081572df1dc Mon Sep 17 00:00:00 2001 From: gracexu94 Date: Tue, 24 Jan 2017 13:56:50 -0500 Subject: [PATCH 07/13] added multiple noise functions --- src/main.js | 3 ++- src/shaders/my-vert.glsl | 32 +++++++++++++++++++------------- 2 files changed, 21 insertions(+), 14 deletions(-) diff --git a/src/main.js b/src/main.js index 6d264dc..672a6ef 100644 --- a/src/main.js +++ b/src/main.js @@ -15,6 +15,7 @@ var myMaterial = new THREE.ShaderMaterial({ fragmentShader: require('./shaders/my-frag.glsl') }); +// used to animate the icosahedron var programStartTime; // called after the scene loads @@ -42,7 +43,7 @@ function onLoad(framework) { // set camera position camera.position.set(1, 1, 2); camera.lookAt(new THREE.Vector3(0,0,0)); - + // edit params and listen to changes like this // more information here: https://workshop.chromeexperiments.com/examples/gui/#1--Basic-Usage gui.add(camera, 'fov', 0, 180).onChange(function(newVal) { diff --git a/src/shaders/my-vert.glsl b/src/shaders/my-vert.glsl index 8b7fa40..8ef182b 100644 --- a/src/shaders/my-vert.glsl +++ b/src/shaders/my-vert.glsl @@ -1,11 +1,17 @@ varying vec2 vUv; varying vec3 vNormal; -const int numOctaves = 1; +const int numOctaves = 3; uniform float time; -float generateNoise1(int x, int y, int z) { - return fract(sin(dot(vec3(x,y,z), vec3(12.9898, 78.23, 107.0))) * 43758.5453); +float generateNoise(int x, int y, int z, int numOctave) { + if (numOctave == 0) { + return fract(sin(dot(vec3(x,y,z), vec3(12.9898, 78.23, 107.81))) * 43758.5453); + } else if (numOctave == 1) { + return fract(sin(dot(vec3(z,x,y), vec3(16.363, 43.597, 199.73))) * 69484.7539); + } else if (numOctave == 2) { + return fract(sin(dot(vec3(y,x,z), vec3(13.0, 68.819, 90.989))) * 92041.9823); + } } float linearInterpolate(float a, float b, float t) { @@ -18,7 +24,7 @@ float cosineInterpolate(float a, float b, float t) { } // given a point in 3d space, produces a noise value by interpolating surrounding points -float interpolateNoise(float x, float y, float z) { +float interpolateNoise(float x, float y, float z, int numOctave) { int integerX = int(floor(x)); float weightX = x - float(integerX); @@ -28,15 +34,15 @@ float interpolateNoise(float x, float y, float z) { int integerZ = int(floor(z)); float weightZ = z - float(integerZ); - float v1 = generateNoise1(integerX, integerY, integerZ); - float v2 = generateNoise1(integerX, integerY, integerZ + 1); - float v3 = generateNoise1(integerX, integerY + 1, integerZ + 1); - float v4 = generateNoise1(integerX, integerY + 1, integerZ); + float v1 = generateNoise(integerX, integerY, integerZ, numOctave); + float v2 = generateNoise(integerX, integerY, integerZ + 1, numOctave); + float v3 = generateNoise(integerX, integerY + 1, integerZ + 1, numOctave); + float v4 = generateNoise(integerX, integerY + 1, integerZ, numOctave); - float v5 = generateNoise1(integerX + 1, integerY, integerZ); - float v6 = generateNoise1(integerX + 1, integerY, integerZ + 1); - float v7 = generateNoise1(integerX + 1, integerY + 1, integerZ + 1); - float v8 = generateNoise1(integerX + 1, integerY + 1, integerZ); + float v5 = generateNoise(integerX + 1, integerY, integerZ, numOctave); + float v6 = generateNoise(integerX + 1, integerY, integerZ + 1, numOctave); + float v7 = generateNoise(integerX + 1, integerY + 1, integerZ + 1, numOctave); + float v8 = generateNoise(integerX + 1, integerY + 1, integerZ, numOctave); float i1 = cosineInterpolate(v1, v5, weightX); float i2 = cosineInterpolate(v2, v6, weightX); @@ -60,7 +66,7 @@ float generateMultiOctaveNoise(float x, float y, float z) { float frequency = pow(2.0, float(i)); float amplitude = pow(persistence, float(i)); - total += interpolateNoise(x * frequency, y * frequency, z * frequency) * amplitude; + total += interpolateNoise(x * frequency, y * frequency, z * frequency, i) * amplitude; } return total; From 435e833ca9e0728c4dbfa9795c7ffc5692bc3271 Mon Sep 17 00:00:00 2001 From: gracexu94 Date: Tue, 24 Jan 2017 14:21:33 -0500 Subject: [PATCH 08/13] added noise to fragment shader for coloring as well --- src/main.js | 2 +- src/shaders/my-frag.glsl | 12 +++++++++--- src/shaders/my-vert.glsl | 7 ++++--- 3 files changed, 14 insertions(+), 7 deletions(-) diff --git a/src/main.js b/src/main.js index 672a6ef..35f4d1c 100644 --- a/src/main.js +++ b/src/main.js @@ -41,7 +41,7 @@ function onLoad(framework) { scene.add(texturedIcosahedron); // set camera position - camera.position.set(1, 1, 2); + camera.position.set(1, 1, 5); camera.lookAt(new THREE.Vector3(0,0,0)); // edit params and listen to changes like this diff --git a/src/shaders/my-frag.glsl b/src/shaders/my-frag.glsl index 78fefb6..9cdeb9a 100644 --- a/src/shaders/my-frag.glsl +++ b/src/shaders/my-frag.glsl @@ -1,10 +1,16 @@ varying vec2 vUv; -varying float noise; +varying float vNoise; uniform sampler2D image; varying vec3 vNormal; -void main() { +float linearInterpolate(float a, float b, float t) { + return a * (1.0 - t) + b * t; +} - gl_FragColor = vec4( vNormal.rgb, 1.0 ); +void main() { + float r = linearInterpolate(vNormal.rgb[0], 0.9, vNoise); + float g = linearInterpolate(vNormal.rgb[1], 0.9, vNoise); + float b = linearInterpolate(vNormal.rgb[2], 0.9, vNoise); + gl_FragColor = vec4( r, g, b, 1.0 ); } \ No newline at end of file diff --git a/src/shaders/my-vert.glsl b/src/shaders/my-vert.glsl index 8ef182b..f366b8e 100644 --- a/src/shaders/my-vert.glsl +++ b/src/shaders/my-vert.glsl @@ -1,6 +1,7 @@ varying vec2 vUv; varying vec3 vNormal; +varying float vNoise; const int numOctaves = 3; uniform float time; @@ -73,11 +74,11 @@ float generateMultiOctaveNoise(float x, float y, float z) { } void main() { - vUv = uv; - vNormal = normal; - float offset = generateMultiOctaveNoise(position[0] + time/999.0, position[1] + time/999.0, position[2] + time/999.0); vec3 newPosition = position + offset * normal; gl_Position = projectionMatrix * modelViewMatrix * vec4( newPosition, 1.0 ); + vUv = uv; + vNormal = normal; + vNoise = offset; } \ No newline at end of file From f4f1784a14c9c5753dac7d54304aacee96f9b7de Mon Sep 17 00:00:00 2001 From: gracexu94 Date: Tue, 24 Jan 2017 14:36:27 -0500 Subject: [PATCH 09/13] added gui control for noise strength --- src/main.js | 9 +++++++++ src/shaders/my-vert.glsl | 3 ++- 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/src/main.js b/src/main.js index 35f4d1c..ee8b3ff 100644 --- a/src/main.js +++ b/src/main.js @@ -9,6 +9,10 @@ var myMaterial = new THREE.ShaderMaterial({ time: { // Check the Three.JS documentation for the different allowed types and values type: "f", value: Date.now() + }, + noiseStrength: { + type: "f", + value: 2.0 } }, vertexShader: require('./shaders/my-vert.glsl'), @@ -56,6 +60,11 @@ function onLoad(framework) { texturedIcosahedron = new THREE.Mesh(icosahedronGeometry, myMaterial); scene.add(texturedIcosahedron); }); + + gui.add(myMaterial.uniforms.noiseStrength, 'value', 1.0, 8.0).onFinishChange(function(newVal) { + myMaterial.uniforms.noiseStrength.value = newVal; + myMaterial.needsUpdate = true; + }); } // called on frame updates diff --git a/src/shaders/my-vert.glsl b/src/shaders/my-vert.glsl index f366b8e..e012d5b 100644 --- a/src/shaders/my-vert.glsl +++ b/src/shaders/my-vert.glsl @@ -4,6 +4,7 @@ varying vec3 vNormal; varying float vNoise; const int numOctaves = 3; uniform float time; +uniform float noiseStrength; float generateNoise(int x, int y, int z, int numOctave) { if (numOctave == 0) { @@ -60,7 +61,7 @@ float interpolateNoise(float x, float y, float z, int numOctave) { // with each subsequent noise function increasing in frequency and decreasing in amplitude float generateMultiOctaveNoise(float x, float y, float z) { float total = 0.0; - float persistence = 1.0/2.0; + float persistence = 1.0/noiseStrength; //loop for some number of octaves for (int i = 0; i < numOctaves; i++) { From 2aa0536f87c1e9641e4884c9558e56ae66c2c5ec Mon Sep 17 00:00:00 2001 From: gracexu94 Date: Tue, 24 Jan 2017 14:40:42 -0500 Subject: [PATCH 10/13] updated README --- README.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/README.md b/README.md index d4ef264..4d5407a 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,9 @@ # [Project 1: Noise](https://github.com/CIS700-Procedural-Graphics/Project1-Noise) +## Updates +Name: Grace Xu +Implemented 3 octaves of noise and gui controls for level of detail for the icosahedron geometry ('detail') and the strength of the noise ('value'). Color is linear interpolated between rgb value of the normal and white (1.0,1.0,1.0). + ## Objective Get comfortable with using three.js and its shader support and generate an interesting 3D, continuous surface using a multi-octave noise algorithm. From 46784a8375ccbea894ac39fd2cdd3b8e4c3421da Mon Sep 17 00:00:00 2001 From: gracexu94 Date: Tue, 24 Jan 2017 21:37:53 -0500 Subject: [PATCH 11/13] changed color to look more like smoke and added more octaves of noise --- src/main.js | 11 ++++++++++- src/shaders/my-frag.glsl | 6 +++--- src/shaders/my-vert.glsl | 10 ++++++++-- 3 files changed, 21 insertions(+), 6 deletions(-) diff --git a/src/main.js b/src/main.js index ee8b3ff..3300f7c 100644 --- a/src/main.js +++ b/src/main.js @@ -13,6 +13,10 @@ var myMaterial = new THREE.ShaderMaterial({ noiseStrength: { type: "f", value: 2.0 + }, + numOctaves: { + type: "f", + value: 3 } }, vertexShader: require('./shaders/my-vert.glsl'), @@ -37,7 +41,7 @@ function onLoad(framework) { // initialize icosahedron object var icosahedron = { radius: 1, - detail: 2 + detail: 3 } var icosahedronGeometry = new THREE.IcosahedronGeometry(icosahedron.radius, icosahedron.detail); @@ -65,6 +69,11 @@ function onLoad(framework) { myMaterial.uniforms.noiseStrength.value = newVal; myMaterial.needsUpdate = true; }); + + gui.add(myMaterial.uniforms.numOctaves, 'value', 0, 5).step(1).onFinishChange(function(newVal) { + myMaterial.uniforms.numOctaves.value = newVal; + myMaterial.needsUpdate = true; + }); } // called on frame updates diff --git a/src/shaders/my-frag.glsl b/src/shaders/my-frag.glsl index 9cdeb9a..e43ac85 100644 --- a/src/shaders/my-frag.glsl +++ b/src/shaders/my-frag.glsl @@ -8,9 +8,9 @@ float linearInterpolate(float a, float b, float t) { } void main() { - float r = linearInterpolate(vNormal.rgb[0], 0.9, vNoise); - float g = linearInterpolate(vNormal.rgb[1], 0.9, vNoise); - float b = linearInterpolate(vNormal.rgb[2], 0.9, vNoise); + float r = linearInterpolate(0.0, 0.9, vNoise); + float g = linearInterpolate(0.0, 0.9, vNoise); + float b = linearInterpolate(0.0, 0.9, vNoise); gl_FragColor = vec4( r, g, b, 1.0 ); } \ No newline at end of file diff --git a/src/shaders/my-vert.glsl b/src/shaders/my-vert.glsl index e012d5b..6196751 100644 --- a/src/shaders/my-vert.glsl +++ b/src/shaders/my-vert.glsl @@ -2,9 +2,10 @@ varying vec2 vUv; varying vec3 vNormal; varying float vNoise; -const int numOctaves = 3; +uniform int numOctaves; uniform float time; uniform float noiseStrength; +const int aLargeNumber = 10; float generateNoise(int x, int y, int z, int numOctave) { if (numOctave == 0) { @@ -13,6 +14,10 @@ float generateNoise(int x, int y, int z, int numOctave) { return fract(sin(dot(vec3(z,x,y), vec3(16.363, 43.597, 199.73))) * 69484.7539); } else if (numOctave == 2) { return fract(sin(dot(vec3(y,x,z), vec3(13.0, 68.819, 90.989))) * 92041.9823); + } else if (numOctave == 3) { + return fract(sin(dot(vec3(x,y,z), vec3(98.1577, 47.45029, 154.85161))) * 84499.0); + } else if (numOctave == 4) { + return fract(sin(dot(vec3(z,x,y), vec3(9.75367, 83.3057, 390.353))) * 15485.653); } } @@ -64,7 +69,8 @@ float generateMultiOctaveNoise(float x, float y, float z) { float persistence = 1.0/noiseStrength; //loop for some number of octaves - for (int i = 0; i < numOctaves; i++) { + for (int i = 0; i < aLargeNumber; i++) { + if (i == numOctaves) break; float frequency = pow(2.0, float(i)); float amplitude = pow(persistence, float(i)); From ad29070bbe07ca1c8f65ba41b8290ebbd5098ee0 Mon Sep 17 00:00:00 2001 From: gracexu94 Date: Tue, 24 Jan 2017 21:51:46 -0500 Subject: [PATCH 12/13] cleaned up gui variables and updated README --- README.md | 2 +- src/main.js | 56 ++++++++++++++++++++++------------------ src/shaders/my-frag.glsl | 4 +-- src/shaders/my-vert.glsl | 1 - 4 files changed, 34 insertions(+), 29 deletions(-) diff --git a/README.md b/README.md index 4d5407a..5a189f1 100644 --- a/README.md +++ b/README.md @@ -2,7 +2,7 @@ ## Updates Name: Grace Xu -Implemented 3 octaves of noise and gui controls for level of detail for the icosahedron geometry ('detail') and the strength of the noise ('value'). Color is linear interpolated between rgb value of the normal and white (1.0,1.0,1.0). +Implemented up to 5 octaves of noise and gui controls for level of detail for the icosahedron geometry and strength of the noise (via persistence and number of octaves). Color is linear interpolated between black and white using the same noise strength. ## Objective diff --git a/src/main.js b/src/main.js index 3300f7c..cb4972c 100644 --- a/src/main.js +++ b/src/main.js @@ -4,27 +4,27 @@ import Framework from './framework' import Noise from './noise' import {other} from './noise' +// used to animate the icosahedron +var programStartTime; + var myMaterial = new THREE.ShaderMaterial({ uniforms: { - time: { // Check the Three.JS documentation for the different allowed types and values - type: "f", - value: Date.now() + time: { // Check the Three.JS documentation for the different allowed types and values + type: "f", + value: Date.now() + }, + noiseStrength: { + type: "f", + value: 2.0 + }, + numOctaves: { + type: "f", + value: 3 + } }, - noiseStrength: { - type: "f", - value: 2.0 - }, - numOctaves: { - type: "f", - value: 3 - } - }, - vertexShader: require('./shaders/my-vert.glsl'), - fragmentShader: require('./shaders/my-frag.glsl') -}); - -// used to animate the icosahedron -var programStartTime; + vertexShader: require('./shaders/my-vert.glsl'), + fragmentShader: require('./shaders/my-frag.glsl') + }); // called after the scene loads function onLoad(framework) { @@ -39,11 +39,13 @@ function onLoad(framework) { // var {scene, camera, renderer, gui, stats} = framework; // initialize icosahedron object - var icosahedron = { - radius: 1, - detail: 3 + var guiFields = { + icosahedronDetail: 3, + noiseStrength: 2.0, + numOctaves: 3 } - var icosahedronGeometry = new THREE.IcosahedronGeometry(icosahedron.radius, icosahedron.detail); + + var icosahedronGeometry = new THREE.IcosahedronGeometry(1, guiFields.icosahedronDetail); var texturedIcosahedron = new THREE.Mesh(icosahedronGeometry, myMaterial); scene.add(texturedIcosahedron); @@ -58,19 +60,22 @@ function onLoad(framework) { camera.updateProjectionMatrix(); }); - gui.add(icosahedron, 'detail', 0, 5).step(1).onFinishChange(function(newVal) { + gui.add(guiFields, 'icosahedronDetail', 0, 5).step(1).onFinishChange(function(newVal) { scene.remove(texturedIcosahedron); + guiFields.icosahedronDetail = newVal; icosahedronGeometry = new THREE.IcosahedronGeometry(1, newVal); texturedIcosahedron = new THREE.Mesh(icosahedronGeometry, myMaterial); scene.add(texturedIcosahedron); }); - gui.add(myMaterial.uniforms.noiseStrength, 'value', 1.0, 8.0).onFinishChange(function(newVal) { + // changes persistence of noise + gui.add(guiFields, 'noiseStrength', 1.0, 8.0).onFinishChange(function(newVal) { myMaterial.uniforms.noiseStrength.value = newVal; myMaterial.needsUpdate = true; }); - gui.add(myMaterial.uniforms.numOctaves, 'value', 0, 5).step(1).onFinishChange(function(newVal) { + // determines number of octaves of noise + gui.add(guiFields, 'numOctaves', 0, 5).step(1).onFinishChange(function(newVal) { myMaterial.uniforms.numOctaves.value = newVal; myMaterial.needsUpdate = true; }); @@ -78,6 +83,7 @@ function onLoad(framework) { // called on frame updates function onUpdate(framework) { + // animates icosahedron myMaterial.uniforms.time.value = Date.now() - programStartTime; myMaterial.needsUpdate = true; } diff --git a/src/shaders/my-frag.glsl b/src/shaders/my-frag.glsl index e43ac85..20fb1bd 100644 --- a/src/shaders/my-frag.glsl +++ b/src/shaders/my-frag.glsl @@ -1,6 +1,5 @@ varying vec2 vUv; varying float vNoise; -uniform sampler2D image; varying vec3 vNormal; float linearInterpolate(float a, float b, float t) { @@ -12,5 +11,6 @@ void main() { float g = linearInterpolate(0.0, 0.9, vNoise); float b = linearInterpolate(0.0, 0.9, vNoise); - gl_FragColor = vec4( r, g, b, 1.0 ); + gl_FragColor = vec4(r, g, b, 1.0); + //gl_FragColor = vec4(vNormal.rgb, 1.0); } \ No newline at end of file diff --git a/src/shaders/my-vert.glsl b/src/shaders/my-vert.glsl index 6196751..7649826 100644 --- a/src/shaders/my-vert.glsl +++ b/src/shaders/my-vert.glsl @@ -1,4 +1,3 @@ - varying vec2 vUv; varying vec3 vNormal; varying float vNoise; From c07272e13b802414b6cb85a310bb1fecf0266399 Mon Sep 17 00:00:00 2001 From: gracexu94 Date: Tue, 24 Jan 2017 21:57:07 -0500 Subject: [PATCH 13/13] made some edits to gui constraints --- src/main.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main.js b/src/main.js index cb4972c..379be9e 100644 --- a/src/main.js +++ b/src/main.js @@ -69,13 +69,13 @@ function onLoad(framework) { }); // changes persistence of noise - gui.add(guiFields, 'noiseStrength', 1.0, 8.0).onFinishChange(function(newVal) { + gui.add(guiFields, 'noiseStrength', 0.6, 8.0).onFinishChange(function(newVal) { myMaterial.uniforms.noiseStrength.value = newVal; myMaterial.needsUpdate = true; }); // determines number of octaves of noise - gui.add(guiFields, 'numOctaves', 0, 5).step(1).onFinishChange(function(newVal) { + gui.add(guiFields, 'numOctaves', 1, 5).step(1).onFinishChange(function(newVal) { myMaterial.uniforms.numOctaves.value = newVal; myMaterial.needsUpdate = true; });