Week 3

I was away sick this week, using the videos below as recommended by Tim I was able to have a go with Three.js.

My notes from the videos –

Week 3

Part 1

  • Code on the left is JavaScript code 
  • The basic code you need ti create a mesh or a 3d object in three.js

geometry = new THREE.CubeGeometry(200, 200, 200);

material = new THREE.MeshNormalMaterial({shading: THREE.FlatShading});

mesh = new THREE.Mesh(geometry, material);

scene.add(mesh);

  • The first line says create a new cube geometry with some parameters
  • The second line creates a new material which is the skin that wraps around new geometry 
  • Third line creates a new mesh which is the combination of the previously stated geometry and material
  • Last line just adds that mesh to your scene/sketch
  • In the menu there’s a drop-down with different geometry options and when you pick a different geometry from the list
  • A new menu with the parameters for that specific geometry opens up when you adjust the sliders for these parameters you’ll notice that the code on the left changes in real time 
  • The first parameter changes when adjustinh the radius slider so that’s what that number does and likewise with these other sliders you can see how they correspond to the parameters in the code
  • The materials drop down list changes your material the basic material and there’s these other two materials Lambert and Phong which have a few more parameters which shades it in response to any lights you add to your scene 
  • In materials you can change the colour, change it to a wireframe, transparency and textures
  • Adjusting stuff in the menu and any changes that are made are being reflected in the code this is important to keep an eye on because this is how you get a sense for what each line in the code does
  • There is a plain menu which lets you generate a wireframe plane. You could also generate a solid plane with some of those pre-loaded textures and colours
  • There’s an environment menu for adding fog or changing the background color
  • Lights menu for adding different kinds of lights into your scene as soon as you start to toggle these the code for your light objects gets rendered here then just like the geometries and materials menus
    • The meshes material has to be set to either Lambert or Phong if you want it to shade in response to any lights that you add to your scene.
  • Once you’re happy with your object click on the code menu at the top and then click select code and this is going to select all the code that you’ve generated then go ahead and click command C to copy that code and move onto step two which is the editor

Part 2

  • A basic template for a web page it’s got a head which has some CSS code in it and then it’s got a body which has our JavaScript 
  • There are two files being linked, the first is the three J’s library and the second is a script which detects whether or not the person loading your sketch has a browser that supports WebGL and then in the event that that it doesn’t shows them a detailed error message
  • There’s a set up function and there’s a draw function so the set up function is where you’re going to put anything that you want instantiated as soon as the page loads and the draw function is everything that’s going to be changing or animating
  • It is a live coding environment where the editor and the final rendered sketch share the same space so you have real-time feedback you can see your sketch change as you edit the code which lends itself to this more experimental

I named it Knot Explotion … was meant to be explosion but I wasn’t paying attention. Here is the code –

<pre class="wp-block-syntaxhighlighter-code">    <a href="http://threejsplaygnd.brangerbriz.net/js/three.min.js">http://threejsplaygnd.brangerbriz.net/js/three.min.js</a>
    <a href="http://threejsplaygnd.brangerbriz.net/js/Detector.js">http://threejsplaygnd.brangerbriz.net/js/Detector.js</a>
    <script>
        //thank you Nick Briz - Made by Georgia Ronalds

        if ( ! Detector.webgl ) Detector.addGetWebGLMessage();

        var camera, scene, renderer;
        var geometry, material, mesh;

        function setup() {

            var W = window.innerWidth, H = window.innerHeight;
            renderer = new THREE.WebGLRenderer( { preserveDrawingBuffer: true } );
            renderer.autoClearColor = false;
            renderer.setSize( W, H );
            document.body.appendChild( renderer.domElement );

            camera = new THREE.PerspectiveCamera( 50, W/H, 1, 10000 );
            camera.position.z = 500;

            scene = new THREE.Scene();


            // paste your code from the geometryGUI here
            for ( var i = 0; i < 300; i ++ ) {
                // your mesh code (from the geometry GUI) goes here

                    geometry = new THREE.TorusKnotGeometry(100, 40, 64, 8, 2, 3, 1);
                    material = new THREE.MeshNormalMaterial({shading: THREE.FlatShading});
                    mesh = new THREE.Mesh(geometry, material);
                    scene.add(mesh);

            }


        }

        function draw() {

            requestAnimationFrame( draw );

            // experiment with code from the snippets menu here
            mesh.rotation.x = Date.now() * 0.00010; 
            mesh.rotation.y = Date.now() * 0.0008;  
            mesh.rotation.z = Date.now() * 0.004;
            camera.position.y = Math.sin( Date.now() * 0.002 ) * 100;
            mesh.position.x = Math.random() * 1000 - 500;
                mesh.position.y = Math.random() * 1000 - 500;
                mesh.position.z = Math.random() * 1000 - 500;
                mesh.rotation.x = Math.random() * 2 * Math.PI;
                mesh.rotation.y = Math.random() * 2 * Math.PI;
                mesh.rotation.z = Math.random() * 2 * Math.PI;
                scene.add( mesh );

            renderer.render( scene, camera );

        }

        setup();
        draw();

    </script>

</body></pre>

The link so you can see it in action –threejsplaygnd.brangerbriz.com/s/?id=8024 it posted twice to the archive which wasn’t meant to.

Off the bat, the website (http://threejsplaygnd.brangerbriz.net/) introduced us to what Three.js is able to do. The home page is interactive and as you move your cursor around the screen the squares change colours and move with you. I thought this was a great way to a possibility of what we could do. I loved that it was interactive and colorful.

Here are the different things that I created using Three.js following the videos.

Click here to see Knot Explosion it in full –

You can see flower power by clicking here

Adding mouse Input 

The following is a snippet for mouse input in Three.JS. Please note that this will not work in the Playground, you need to take your code outside the playground, as outlined above.

// Add the following code above function setup(), and below 

var mouseX = 0, mouseY = 0;

// Add the following code inside function setup(), below document.body

document.addEventListener( ‘mousemove’, onMouseMove, false );

// Add the following as a separate function. This should ideally go between function setup() and function draw() This is

mouseX = event.clientX;

mouseY = event.clientY; 

mouse = true; 

}

// Now you can refer to mouseX and mouseY in the function draw() section of your script. For example:

mesh.position.x = (mouseX-(window.innerWidth/2)); mesh.position.y = -(mouseY-(window.innerHeight/2));

mouseX and mouseY can be seen being used in the video. Since mouseX and mouseY can’t be used in threeJS you would have to copy the code and insert into brackets or similar applications.

<pre class="wp-block-syntaxhighlighter-code">    <a href="http://threejsplaygnd.brangerbriz.net/js/three.min.js">http://threejsplaygnd.brangerbriz.net/js/three.min.js</a>
    <a href="http://threejsplaygnd.brangerbriz.net/js/Detector.js">http://threejsplaygnd.brangerbriz.net/js/Detector.js</a>
    <a href="http://threejs.org/examples/fonts/helvetiker_bold.typeface.js">http://threejs.org/examples/fonts/helvetiker_bold.typeface.js</a>
        <a href="http://threejs.org/examples/fonts/helvetiker_regular.typeface.js">http://threejs.org/examples/fonts/helvetiker_regular.typeface.js</a>
    <script>

        if ( ! Detector.webgl ) Detector.addGetWebGLMessage();

        var camera, scene, renderer;
        var geometry, material, mesh;</pre>

var mouseX = 0, mouseY = 0;

        function setup() {

            var W = window.innerWidth, H = window.innerHeight;
            renderer = new THREE.WebGLRenderer( { preserveDrawingBuffer: true } );
            renderer.autoClearColor = false;
            renderer.setSize( W, H );
            document.body.appendChild( renderer.domElement );

document.addEventListener( ‘mousemove’, onMouseMove, false );

            camera = new THREE.PerspectiveCamera( 50, W/H, 1, 10000 );
            camera.position.z = 500;

            scene = new THREE.Scene();


            // paste your code from the geometryGUI here

            geometry = new THREE.TorusGeometry(160.6, 91.59, 40, 13, 21.99);
            material = new THREE.MeshLambertMaterial({shading: THREE.FlatShading, color: 0xdcdcdc});
            mesh = new THREE.Mesh(geometry, material);
            mesh.rotation.x = 2.29;
            scene.add(mesh);

            scene.fog = new THREE.Fog( 0x136bf7, 1, 9000 );ambientLight = new THREE.AmbientLight( 0x000000 );
            scene.add( ambientLight );

            hemisphereLight = new THREE.HemisphereLight(0xc292ed, 0x000000, 0.2);
            scene.add( hemisphereLight );

            directionalLight = new THREE.DirectionalLight(0xffffff, 0.38);
            directionalLight.position.set( 0, 1, 0 );
            directionalLight.castShadow = true;
            scene.add( directionalLight );

            spotLight1 = new THREE.SpotLight( 0xffffff, 0.1 );
            spotLight1.position.set( 100, 1000, 100 );
            spotLight1.castShadow = true;
            spotLight1.shadowDarkness = 0.2;
            scene.add( spotLight1 );

            spotLight2 = new THREE.SpotLight( 0xffffff, 0.1 );
            spotLight2.position.set( 100, 1000, 100 );
            spotLight2.castShadow = true;
            spotLight2.shadowDarkness = 0.2;
            scene.add( spotLight2 );





        }

        function onMouseMove(event)
        {
        mouseX = event.clientX;
        mouseY = event.clientY;
        mouse = true;
        }

        function draw() {

            requestAnimationFrame( draw );



            // experiment with code from the snippets menu here
            mesh.rotation.x = Date.now() * 0.0000;
            mesh.rotation.y = Date.now() * 0.0005;
            mesh.rotation.z = Date.now() * 0.001;
            var time = Date.now() * 0.0005;
            h = ( 360 * ( 1.0 + time ) % 360 ) / 360;
            mesh.material.color.setHSL(h, 0.5, 0.5 );
            mesh.position.x = Math.sin( Date.now() * 0.001 ) * 50;
            mesh.rotation.z = Date.now() * 0.0005;
            camera.position.x = Math.sin( Date.now() * 0.002 ) * 50;
            camera.position.y = Math.sin( Date.now() * 0.002 ) * 50;

            renderer.render( scene, camera );

            mesh.position.x = (mouseX-(window.innerWidth/2));

mesh.position.y = -(mouseY-(window.innerHeight/2));

        }

        setup();
        draw();

    </script>

</body>
        function draw() {

            requestAnimationFrame( draw );

            // experiment with code from the snippets menu here
            mesh.rotation.x = Date.now() * 0.00010;
            mesh.rotation.y = Date.now() * 0.0008;
            mesh.rotation.z = Date.now() * 0.004;
            camera.position.y = Math.sin( Date.now() * 0.002 ) * 100;
            mesh.position.x = Math.random() * 1000 - 500;
                mesh.position.y = Math.random() * 1000 - 500;
                mesh.position.z = Math.random() * 1000 - 500;
                mesh.rotation.x = Math.random() * 2 * Math.PI;
                mesh.rotation.y = Math.random() * 2 * Math.PI;
                mesh.rotation.z = Math.random() * 2 * Math.PI;
                scene.add( mesh );

            renderer.render( scene, camera );

        }

        setup();
        draw();

    </script>

</body>

Adding extra meshes

Below you can see me moving the circle and then playing the addition of another shape. I struggled with getting the shapes right… not sure how I ended up with 1 sphere that collided with a cube and another cube that I could move around. I struggled understanding how to “correctly” add in extra meshes which created some interesting, accidental outcomes. It was frustrating to not end up with an outcome that I was wanting or happy with but that is about of the process.

mouseX and mouseY

Code for the two circles –

<pre class="wp-block-syntaxhighlighter-code">    <a href="http://threejsplaygnd.brangerbriz.net/js/three.min.js">http://threejsplaygnd.brangerbriz.net/js/three.min.js</a>
    <a href="http://threejsplaygnd.brangerbriz.net/js/Detector.js">http://threejsplaygnd.brangerbriz.net/js/Detector.js</a>
    <script>

        if ( ! Detector.webgl ) Detector.addGetWebGLMessage();

        var camera, scene, renderer;
        var sphere_geometry, sphere_material, sphere_mesh;

        var mouseX = 0, mouseY = 0;

        function setup() {

            var W = window.innerWidth, H = window.innerHeight;
            renderer = new THREE.WebGLRenderer();
            renderer.setSize( W, H );
            document.body.appendChild( renderer.domElement );</pre>

document.addEventListener( ‘mousemove’, onMouseMove, false );

            camera = new THREE.PerspectiveCamera( 50, W/H, 1, 10000 );
            camera.position.z = 500;

            scene = new THREE.Scene();


            // paste your code from the geometryGUI here

            geometry = new THREE.SphereGeometry(150, 100, 100);
            sphere_geometry = new THREE.SphereGeometry(200, 200, 200);
            material = new THREE.MeshNormalMaterial({shading:
            THREE.FlatShading});
            sphere_material = new THREE.MeshNormalMaterial({shading:
            THREE.FlatShading});
            mesh = new THREE.Mesh(geometry, material);
            sphere_mesh = new THREE.Mesh(sphere_geometry, sphere_material);
            scene.add(mesh);
            scene.add(sphere_mesh);

        }

        function onMouseMove(event)

{
mouseX = event.clientX;
mouseY = event.clientY;
mouse = true;
}

        function draw() {

            requestAnimationFrame( draw );

            // experiment with code from the snippets menu here
            camera.position.x = Math.sin( Date.now() * 0.002 ) * 50;

            renderer.render( scene, camera );

            mesh.position.x = (mouseX-(window.innerWidth/2));

mesh.position.y = -(mouseY-(window.innerHeight/2));

        }

        setup();
        draw();

    </script><canvas width="1327" height="765"></canvas>

Rotating individual mesh objects in a for loop TODO

Add this below snippet to the function draw() section of your code.

 for ( var i = 0; i < scene.children.length; i ++ ) { var meshSel = scene.children[ i ]; 

// add rotations, scales, position code here. Incorporate the ā€˜iā€™ in the code to make the movements different, as with my below example. 

meshSel.rotation.x = Math.sin( Date.now() * 0.0001 ) *i; }

Example

For the example that I liked this week is from https://threejs.org/examples/#webgl_animation_keyframes

In the video I looked at a few different examples but the first clip is amazing. I love the detail and how it has moving parts such as the tram and being able to look around and examine the scene makes it much more exciting. The code for this can be seen here