Help end child hunger
Jul 202013
 

The Demo

This demo uses multiple shaders, loaded models in JSON format and creates its own models (the grid and axis).

Use the left mouse button to rotate the camera around the object.
The middle mouse button allows for zooming in and out.
The following keys serve the same purpose:

  • A,D – move camera to the left/right
  • W,S – move the camera up and down
  • R,F – move the camera backward/forward.

Live WebGL
Your browser does not support the canvas tag.

WebGL – Importing a JSON model

JSON is a data exchange format, making it a simple solution to import 3D models in WebGL. It allows us to define JavaScript objects in textual format, which are then parsed and an object is returned. Once the parsing is concluded we can access the object properties in the same way as we do with regular JavaScript objects.

Consider for instance the following text in JSON format that defines a single triangle with normals and texture coordinates:

{
    "positions" : [0,0,1, 1,0,0, 0,0,0],
    "normals": [0,1,0,  0,1,0,  0,1,0],
    "texCoords": [0,1, 1,0, 0,0]
}

To load this text we can write a small function such as:

    var request = new XMLHttpRequest();
    request.open("GET",http://mySite.com/myModel.json");
    request.onreadystatechange = function () {
        if (request.readyState == 4) {
            handleLoadedModel(JSON.parse(request.responseText));
        }
    }
    request.send();

The request has several states (see here), and state 4 indicates that the request is completed. This is when we call the function to convert the received object into something meaningful to the application. Let’s assume the following JavaScript definitions:

function Model() {

    this.vbo = [-1,-1,-1]; // init an array with -1 
    this.vertexCount = 0; // this will be usefull for glDrawArrays
}

var m = new Model(); // a global var to hold our model data

Once the text gets imported, and parsed we would get an object, with three properties: positions, normals and texCoords. Considering the above JSON text we could have a simple handler such as:

handleLoadedModel(object) {
    var positionArray = new FLoat32Array(object.positions);
    m.vbo[0] = gl.createBuffer();
    gl.bindBuffer(gl.ARRAY_BUFFER, this.vbo[i]);
    gl.bufferData(gl.ARRAY_BUFFER, positionArray , gl.STATIC_DRAW);

    // do the same thing for "normals" and "texCoords" with vbo[1] and vbo[2]
    ...
    // finally let's keep track of the number of vertices
    m.vertexCount = object.normals.length / 3; // Normals have always 3 components
}

And that’s it. We’ve loaded a text file describing our model, and turned it into three VBOs. And we also kept track of the number of vertices.

The beauty of JSON is in its simplicity, and at the same time its potential. We can use JSON to describe 3D models with multiple meshes, specify a material per mesh, including a texture path, and why not, bounding boxes for the model and each mesh. The demo uses such a model definition, although it only contains a single mesh to keep things lite. Check out the model file here.

In order to keep the code simpler I wrote a small lib to deal with materials and models (l3dmodels.js). The source code for the javascript bit can be found in here. It assumes a canvas named “canvas” has been declared in HTML.

The demo also uses two third party libs:

The first library contains two functions which are really useful: WebGLUtils.setupWebGL and window.requestAnimFrame. jsMatrix is a great lib that supports the most common matrix and vector operations, namely in the context of GL, such as setting the projection matrix, placing the camera, and performing geometric transformations.

Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.

%d bloggers like this: