diff --git a/.DS_Store b/.DS_Store new file mode 100644 index 0000000..5008ddf Binary files /dev/null and b/.DS_Store differ diff --git a/cloud_texture.jpg b/cloud_texture.jpg new file mode 100644 index 0000000..e195ce2 Binary files /dev/null and b/cloud_texture.jpg differ diff --git a/ellen.jpg b/ellen.jpg new file mode 100644 index 0000000..bb0fa39 Binary files /dev/null and b/ellen.jpg differ diff --git a/src/main.js b/src/main.js index 5fa221d..ef5ffed 100644 --- a/src/main.js +++ b/src/main.js @@ -2,6 +2,40 @@ const THREE = require('three'); // older modules are imported like this. You shouldn't have to worry about this much import Framework from './framework' + + + +var parameters = { + octaves: 2.0, + persistence: 4.0 +} + +var noiseMaterial = new THREE.ShaderMaterial({ + uniforms: { + // image: { // Check the Three.JS documentation for the different allows types and values + // type: "t", + // value: THREE.ImageUtils.loadTexture('./explosion.png') + // }, + time: { + type: "f", + value: 1.0 + }, + octaves: { + type: "f", + value: 3.0 + }, + persistence: { + type: "f", + value: 4.0 + } + }, + vertexShader: require('./shaders/ellen-vert.glsl'), + fragmentShader: require('./shaders/ellen-frag.glsl') + }); + +var startTime = new Date(); +var currentTime = new Date(); + // called after the scene loads function onLoad(framework) { var scene = framework.scene; @@ -10,41 +44,48 @@ function onLoad(framework) { var gui = framework.gui; var stats = framework.stats; - // 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 - 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 adamCube = new THREE.Mesh(box, adamMaterial); + var icosahedron = new THREE.IcosahedronGeometry(1, 6); + var noiseIcosahedron = new THREE.Mesh(icosahedron, noiseMaterial); // set camera position - camera.position.set(1, 1, 2); + camera.position.set(1, 1, 200); camera.lookAt(new THREE.Vector3(0,0,0)); - scene.add(adamCube); + // scene.add(adamCube); + scene.add(noiseIcosahedron); + // 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(parameters, 'octaves', 0, 10).onChange(function(newVal) { + noiseMaterial.uniforms['octaves'].value = newVal; + }); + + gui.add(parameters, 'persistence', 0, 10).onChange(function(newVal) { + noiseMaterial.uniforms['persistence'].value = newVal; + }); } // called on frame updates function onUpdate(framework) { - console.log(`the time is ${new Date()}`); + // console.log(`the time is ${new Date()}`); + currentTime = new Date(); + currentTime = currentTime - startTime; + + if (currentTime > 100000) { + startTime = new Date(); + } + + noiseMaterial.uniforms['time'].value = currentTime / 2000; } // when the scene is done initializing, it will call onLoad, then on frame updates, call onUpdate -Framework.init(onLoad, onUpdate); \ No newline at end of file +Framework.init(onLoad, onUpdate); + + +// WEBPACK FOOTER // +// ./src/main.js \ No newline at end of file diff --git a/src/shaders/ellen-frag.glsl b/src/shaders/ellen-frag.glsl new file mode 100644 index 0000000..6441f35 --- /dev/null +++ b/src/shaders/ellen-frag.glsl @@ -0,0 +1,11 @@ +varying vec2 vUv; +varying vec3 vNormal; +varying vec3 vPosition; +varying float noise; +uniform sampler2D image; +varying float vTime; + +void main() { + gl_FragColor = vec4(vNormal, 1.0); +} + diff --git a/src/shaders/ellen-vert.glsl b/src/shaders/ellen-vert.glsl new file mode 100644 index 0000000..05ea050 --- /dev/null +++ b/src/shaders/ellen-vert.glsl @@ -0,0 +1,128 @@ +#define M_PI 3.14159265 + +varying vec2 vUv; +varying vec3 vNormal; +varying vec3 vPosition; +varying float noise; +varying float vTime; + +uniform float time; +uniform float persistence; +uniform float octaves; +const int max_octaves = 30; + +float noise_gen2(int x, int y, int z) { + return fract(sin(dot(vec3(x, y, z), vec3(12.9898, 78.233, 43.29179))) * 43758.5453); +} + +// Smooth Noise +// Takes into account the surrounding noise +float smoothNoise(int x, int y, int z) { + // Non-smooth noise + // return noise_gen2(x, y, z); + + // Smooth Noise + float center = noise_gen2(x, y, z) / 8.0; + float adj = (noise_gen2(x + 1, y, z) + noise_gen2(x - 1, y, z) + + noise_gen2(x, y + 1, z) + noise_gen2(x, y - 1, z) + + noise_gen2(x, y, z + 1) + noise_gen2(x, y, z - 1)) / 16.0; + float diag = (noise_gen2(x + 1, y + 1, z) + + noise_gen2(x + 1, y - 1, z) + + noise_gen2(x - 1, y + 1, z) + + noise_gen2(x - 1, y - 1, z) + + noise_gen2(x + 1, y, z + 1) + + noise_gen2(x + 1, y, z - 1) + + noise_gen2(x - 1, y, z + 1) + + noise_gen2(x - 1, y, z - 1) + + noise_gen2(x, y + 1, z + 1) + + noise_gen2(x, y + 1, z - 1) + + noise_gen2(x, y - 1, z + 1) + + noise_gen2(x, y - 1, z - 1)) / 32.0; + float corners = (noise_gen2(x + 1, y + 1, z + 1) + + noise_gen2(x + 1, y + 1, z - 1) + + noise_gen2(x + 1, y - 1, z + 1) + + noise_gen2(x + 1, y - 1, z - 1) + + noise_gen2(x - 1, y + 1, z + 1) + + noise_gen2(x - 1, y + 1, z - 1) + + noise_gen2(x - 1, y - 1, z + 1) + + noise_gen2(x - 1, y - 1, z - 1)) / 64.0; + + return center + adj + diag + corners; +} + +// Cosine Interpolation +// Interpolates x, between [a, b] +// Typically use [-1, 1] +float cerp(float a, float b, float x) { + float y = x * M_PI; + y = (1.0 - cos(y)) * 0.5; // y is inbetween [0, 1] + return a * (1.0 - y) + b * y; // map y between and b +} + +float cerpNoise(float x, float y, float z) { + int x_whole = int(x); + float x_fract = fract(x); + + int y_whole = int(y); + float y_fract = fract(y); + + int z_whole = int(z); + float z_fract = fract(z); + + float v1 = smoothNoise(x_whole, y_whole, z_whole); + float v2 = smoothNoise(x_whole + 1, y_whole, z_whole); + + float v3 = smoothNoise(x_whole, y_whole + 1, z_whole); + float v4 = smoothNoise(x_whole + 1, y_whole + 1, z_whole); + + float v5 = smoothNoise(x_whole, y_whole, z_whole + 1); + float v6 = smoothNoise(x_whole + 1, y_whole, z_whole + 1); + + float v7 = smoothNoise(x_whole, y_whole + 1, z_whole + 1); + float v8 = smoothNoise(x_whole + 1, y_whole + 1, z_whole + 1); + + + // Cerp over the x axis + float x00 = cerp(v1, v2, x_fract); + float x01 = cerp(v3, v4, x_fract); + float x10 = cerp(v5, v6, x_fract); + float x11 = cerp(v7, v8, x_fract); + + float y0 = cerp(x00, x01, y_fract); + float y1 = cerp(x10, x11, y_fract); + + + return cerp(y0, y1, z_fract); +} + +// Noise +// Perlin Noise +// Fractional Brownian Motion +float fnoise(float x, float y, float z) { + float total = 0.0; + float p = persistence; + int n = int(octaves); + + for (int i = 0; i < max_octaves; i++) { + float frequency = pow(2.0, float(i)); + float amplitude = pow(p, float(i)); + total = total + cerpNoise(x * frequency, y * frequency, z * frequency) * amplitude; + + if (i >= n) { + break; + } + } + + return total; +} + +void main() { + vUv = uv; + vNormal = normal; + vTime = time; + + noise = fnoise(position[0] + vTime, position[1] + vTime, position[2] + vTime); + vec3 displacement = noise * normal; + gl_Position = projectionMatrix * modelViewMatrix * vec4(position + displacement, 1.0 ); + vPosition = vec3(gl_Position); +} \ No newline at end of file diff --git a/toolbox_functions.pdf b/toolbox_functions.pdf new file mode 100644 index 0000000..2059ada Binary files /dev/null and b/toolbox_functions.pdf differ