\( \newcommand{\vecIII}[3]{\left[\begin{array}{c} #1\\#2\\#3 \end{array}\right]} \newcommand{\vecIV}[4]{\left[\begin{array}{c} #1\\#2\\#3\\#4 \end{array}\right]} \newcommand{\Choose}[2]{ { { #1 }\choose{ #2 } } } \newcommand{\vecII}[2]{\left[\begin{array}{c} #1\\#2 \end{array}\right]} \newcommand{\vecIII}[3]{\left[\begin{array}{c} #1\\#2\\#3 \end{array}\right]} \newcommand{\vecIV}[4]{\left[\begin{array}{c} #1\\#2\\#3\\#4 \end{array}\right]} \newcommand{\matIIxII}[4]{\left[ \begin{array}{cc} #1 & #2 \\ #3 & #4 \end{array}\right]} \newcommand{\matIIIxIII}[9]{\left[ \begin{array}{ccc} #1 & #2 & #3 \\ #4 & #5 & #6 \\ #7 & #8 & #9 \end{array}\right]} \)

CS307: Texture Mapping 1: Simple Image Mappings

Lit Scene Partners

  • 2 Ailie+Martha
  • 4 Alo+Genevieve
  • 6 Amy+Elisha
  • 8 Anastacia+Gabby
  • 10 Ari+Mulan
  • 12 Ariana+Jenny
  • 14 Claire M+Hana
  • 16 Claire T+Lana
  • 18 Emily+Marilyn
  • 20 Faith+Rik
  • 22 Heidi+Joyce
  • 24 Ingrid+Kate
  • 26 Lindsay+UGyeong
  • 28 solo Hae Rin

Plan

  • Overview of texture mapping
  • Mapping an image onto a plane
  • CORS and setting up a local server
  • Exercise: Load image files from your local machine
  • Exercise: Create a panoramic view of Wellesley

Texture Mapping Recap

  • At its most basic, a texture is an array of pixels. So is an image. A texture can be a synthetically generated pattern of lightness or color, or an image taken from a camera.
  • A texture pattern can be mapped or "painted" onto any surface. A texture pattern is typically a 2D thing, but can be mapped onto 2D or 3D surfaces.

    texture mapping        texture mapping

    texture mapping        texture mapping

  • Each vertex of a triangular face can have texture parameters. Typically, the texture parameters for a whole geometry go from 0-1 (but not always), and the texture parameters for faces are interpolated.
  • When loading textures from an image, we need to consider that it takes a non-negligible amount of time for the image to load, so we will need to write event handlers for the after load event.

Mapping an Image onto a Plane

Consider this relaxing floral scene in which a single image is mapped onto three planes.

Three.js has a THREE.TextureLoader class to load an image to be used for texture mapping, which enables us to provide an event handler that among other things, can render the scene after the image load is complete.

This is the key code in the floral display example:

var loader = new THREE.TextureLoader();

loader.load("relaxation.jpg",
            function (texture) {
                displayPanels(texture);
            } );

The image is stored in a THREE.Texture object that is passed as input to an anonymous function (the event handler) that is provided as the second input to the load() method.

Here is the definition of the displayPanels() function, which renders the scene at the end:

function displayPanels (texture) {
    // plane geometry with texture-mapped floral image
    var planeGeom = new THREE.PlaneGeometry(10,10);
    var planeMat = new THREE.MeshBasicMaterial(
                           {color: 0xffffff,
                            map: texture} );
    var planeMesh = new THREE.Mesh(planeGeom, planeMat);
    scene.add(planeMesh);

    // repeat texture mapping on right panel
    var planeMeshR = planeMesh.clone();
    var dist = 5*Math.cos(Math.PI/4);
    planeMeshR.position.set(5+dist, 0, dist);
    planeMeshR.rotation.y = -Math.PI/4;
    scene.add(planeMeshR);

    // repeat texture mapping on left panel
    var planeMeshL = planeMesh.clone();
    planeMeshL.position.set(-5-dist, 0, dist);
    planeMeshL.rotation.y = Math.PI/4;
    scene.add(planeMeshL);

    TW.render();    // render the scene
}

Three.js requires that images used for texture mapping have dimensions that are powers of 2. In this example, the image has 256x256 pixels, and it is mapped onto square planes.

Quiz Questions

I'll address your quiz questions now.

CORS and Setting up a Local Server

Before we launch into our first exercise, we need to deal with a bit of unpleasantness called CORS, for Cross-Origin Resource Sharing. The problem arises because, for security reasons, JavaScript is not allowed to do what the browser can do: request resources from another domain.

What this means for us is:

Your images and your html file have to be in the same domain.

This means you can't work with textures on your local machine without setting up a server. Fortunately, this is easy.

There's more about CORS in the reading, and we'll do an exercise here to demonstrate the problem and solution. We'll use the Run Local Server option, using Python, described in the Three.js documentation.

Exercise: Loading image files on your local machine

Save the flower-display.html code file on your Desktop (be sure to save it as Webpage, HTML Only). Also save this image into your Desktop (be sure to keep the same filename).

Open your local flower-display.html file in your browser and observe the error message that appears in the JavaScript Console.

Now follow these steps to run a local server on your Mac or laptop:

  • Start a terminal window
  • cd to the directory that has your downloaded HTML file in it, in this case cd ~/Desktop.
  • Start a web server on port 8000 (by default) using Python:
                  python -m SimpleHTTPServer
            

    OR, even better:

                  python3 -m http.server
            

    (We did this in the first week of class.)

  • Go back to your web browser and try the following URL:
                http://localhost:8000/flower-display.html
            

You should now see the display of three panels with the flower scene.

Mapping Multiple Images onto Scene Objects

The TW package provides a helper function, TW.loadTextures() that takes an array of URLs for multiple image files and a callback function as inputs, and invokes the function on an array of THREE.Texture objects that store the multiple images.

Here is some skeleton code:

TW.loadTextures(["image1.jpg", "image2.jpg", ...],
                function (textures) {
                    ...
                } );

You do not need to create a THREE.TextureLoader object in this case, as TW does this for you.

Exercise: Create a Wellesley Panorama

Save these wells1.png, wells2.png, and wells3.png images on your Desktop.

Create a copy of your flower-display.html code file under a new name, and modify the new file to load all three Wellesley images and place them on the three different planes, to create a panorama of campus:

texture mapping

Remember that the texture is part of the material, so you'll need to create three different materials, instead of just cloning the mesh.

Your solution might like like this wellesley3.html