Intro to Three.JS Concepts

In class we will explore the following concepts - you will have the opportunity to edit the code directly here or to copy & paste code into your own codepen to play with three.js.

In codepen, underneath the JavaScript settings, you will need to add the Three.JS library in order for your code to work.

Three.JS

Three.JS Getting Started

Three.JS Fundamentals

Three.JS Examples

Getting Started
Three.JS Fundamentals


  • Scene Setup
    const scene = new THREE.Scene();

    The THREE.Scene() function creates a new scene, a container where all the objects, cameras, and lights will be placed.
  • Camera Setup
    const camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000);

    THREE.PerspectiveCamera defines the type of camera used to view the scene. This camera mimics human eye perspective, giving a sense of depth. The parameters include the field of view, aspect ratio, and the near and far clipping planes.
  • Renderer Setup
    const renderer = new THREE.WebGLRenderer();

    THREE.WebGLRenderer handles the rendering of the scene using WebGL. It creates a canvas element in the web page where the scene will be drawn. The size of the renderer is set to fill the browser window.
  • Creating a Cube

    const geometry = new THREE.BoxGeometry(); creates the cube's geometry (its shape and size).

    const material = new THREE.MeshBasicMaterial({ color: 0x00ff00 }); defines the material of the cube, setting its color to green.

    const cube = new THREE.Mesh(geometry, material); combines the geometry and the material to create a mesh – the actual object to be added to the scene.
  • Adding the Cube to the Scene
    scene.add(cube);

    The cube mesh is added to the scene, making it part of the world we are creating.
  • Animation Function
    function animate() {...}

    The animate function is a loop that causes the cube to rotate. It's called repeatedly using requestAnimationFrame(animate);, a method that tells the browser to perform an animation and requests that the browser calls a specified function to update the animation before the next repaint.
  • Rotation Logic

    Inside the animate function, cube.rotation.x += 0.01; and cube.rotation.y += 0.01; continuously update the cube's rotation around the x and y axes.
  • Rendering the Scene
    renderer.render(scene, camera);

    This command renders the scene from the perspective of the camera. It's called every time the animate function is executed.
  • Handling Browser Resize
    The event listener window.addEventListener('resize', ...);

    ensures that the camera's aspect ratio and the renderer's size are adjusted when the browser window is resized.
  • See the Pen Three.JS Intro - Rotating Cube by Sophia Sobers (@Sophia-Sobers) on CodePen.

    Shapes in Three.JS

    This code shows four different primitive shapes available in WebGL:


  • Cube (Box)
    THREE.BoxGeometry

    A simple cube shape.
  • Sphere
    THREE.SphereGeometry

    A sphere, defined by its radius and the number of segmented faces.
  • Cylinder
    THREE.CylinderGeometry

    A cylinder, defined by top and bottom radius, height, and the number of segmented faces.
  • Torus
    THREE.TorusGeometry

    A donut-like shape, defined by its radius, tube radius, and the number of segmented faces.
  • See the Pen Untitled by Sophia Sobers (@Sophia-Sobers) on CodePen.

    Materials in Three.JS

    This code explore the use of Basic, Lambert, Phong, and Standard material. Each material has a different color. An ambient light is used to illuminate the scene. A point light is attached to the mouse. Move your mouse to see how the different materials interact with light.


  • Materials
    We will look at four different materials, each with a different color:

    MeshBasicMaterial,

    MeshLambertMaterial,

    MeshPhongMaterial, and

    MeshStandardMaterial,

  • Spheres
    Four spheres are created, each with a different material.
  • Positioning
    The spheres are positioned along the x-axis for comparison.
  • Light
    A point light is added to show how some materials interact with light (especially Lambert, Phong, and Standard materials).
  • Notes

    The MeshBasicMaterial will not respond to the scene's lighting, making it appear flat.

    The MeshLambertMaterial and MeshPhongMaterial will reflect the light, showing how different materials react to light sources.

    The MeshStandardMaterial is a physically-based rendering (PBR) material, providing more realistic lighting and shading.

  • See the Pen Untitled by Sophia Sobers (@Sophia-Sobers) on CodePen.

    Exploring Basic Animation: Circular Motion

    In this example, a box is animated using sin() and cos() to create a circular path.


  • Animation Variables

    angle This variable will change over time to update the cube's position.

    radius The radius of the circle along which the cube will move.

  • Animation Loop

    requestAnimationFrame(animate) This is a standard JavaScript function for creating smooth animations. It calls the animate function repeatedly.

    Inside animate, we update the angle and use it to calculate the new x and y positions of the cube, making it move in a circular path. We also optionally rotate the cube for a more dynamic effect. Finally, we render the scene with the updated cube position and rotation.
  • Modify the radius and the rate of change of angle to control the path and speed of the cube's movement.
  • See the Pen Untitled by Sophia Sobers (@Sophia-Sobers) on CodePen.

    Updated Code for Back & Forth Animation

    In this example, a box is animated using sin() and cos() to create a circular path.


  • Animation Variables

    speed Controls how fast the cube moves.

    cubeMaxBoundary Defines the maximum distance the cube can move along the x-axis before it should "bounce" back.

    direction A multiplier that will alternate between 1 and -1 to change the direction of the cube's movement.

  • Animation Loop

    cube.position.x += speed * direction;

    Moves the cube along the x-axis. The direction changes when the cube hits the boundary. The if statement checks if the cube's x-position has reached the boundary (cubeMaxBoundary). If it has, the direction is reversed by multiplying it by -1.
  • The speed and cubeMaxBoundary variables can be adjusted to change the dynamics of the animation, such as making the cube move faster or bounce within a larger area.
  • See the Pen Untitled by Sophia Sobers (@Sophia-Sobers) on CodePen.

    Basic Mouse Tracking Example

  • This example demonstrates a basic approach to easing motion in response to mouse movement. Adjust the easing factor in the easeTowardsTarget function to change the smoothness of the motion.
  • Elements

    Mouse Position Tracking The onMouseMove function updates the mouse vector with the current mouse position, normalized to the range [-1, 1].

    Easing Function easeTowardsTarget is a simple linear interpolation function that gradually changes the cube's position to the target position, creating a smooth transition.

  • Animation Loop

    The target position is set based on the mouse position, scaled to match the 3D space.

    The cube's position is updated using the easing function, moving it towards the target position.

    The renderer.render call updates the scene.

  • See the Pen Untitled by Sophia Sobers (@Sophia-Sobers) on CodePen.

    Lights and Shadows

  • Types of Lights
    Ambient light, point light, directional light, etc., each affecting the scene in different ways.
  • Shadows
    Shadows need to be enabled as casting and receiving on both the renderer and the objects.
  • Elements

    Renderer
    renderer.shadowMap.enabled = true; is crucial for enabling shadow rendering in the scene.

    Ambient Light
    Provides indirect, soft light that doesn't cast shadows. It's used to simulate the light that bounces off surfaces in the real world.

    Point Light
    A light that emits from a single point in all directions. pointLight.castShadow = true; enables this light to cast shadows.

    Cube
    A simple cube that will cast shadows. cube.castShadow = true; enables shadow casting for the cube.

    Plane
    A flat surface that receives shadows. plane.receiveShadow = true; enables shadow receiving for the plane.

    Animation Loop
    The cube rotates continuously. The point light moves in a circular path, creating dynamic shadows as its position changes relative to the cube and plane.

    See the Pen Untitled by Sophia Sobers (@Sophia-Sobers) on CodePen.

    Orbit Control with Mouse

    OrbitControls is Three.js class that allows the camera to orbit around a target point. You can interact with the scene using your mouse: left-click and drag to orbit, right-click and drag to pan, and scroll to zoom. You can further customize the behavior of OrbitControls by adjusting its properties, such as controls.minDistance, controls.maxDistance, controls.enableDamping, etc.


    Elements

    OrbitControls
    This class allows the camera to orbit around a target (the center of the scene by default). The user can rotate, zoom, and pan the scene using the mouse.

    Camera Position and LookAt
    Setting up the initial position of the camera and the point it should look at.

    Scene and Objects
    The scene contains a cube and a sphere for demonstration purposes.

    Camera Setup
    The camera is positioned to view the entire scene initially.

    Animation Loop
    The animate function updates the controls and renders the scene. The controls.update() call is necessary if damping (inertia) or auto-rotation is enabled in the controls.

    See the Pen Untitled by Sophia Sobers (@Sophia-Sobers) on CodePen.

    Web Integration with Transparent Background

    With this setup, the Three.js scene will appear as part of a webpage, overlaying the background color or any other HTML content you have.

    Renderer Transparency
    By setting { alpha: true } in the renderer and using renderer.setClearColor(0x000000, 0), the background of the Three.js canvas is fully transparent, allowing the webpage's background to show through.

    See the Pen Untitled by Sophia Sobers (@Sophia-Sobers) on CodePen.