HTML5header

Computer generated 3D is just a house of cards translated, rotated and shaded to create the illusion of solid objects moving in space and time.

Creating 3D is a significantly different process than creating 2D on the HTML5 canvas . With 2D we can just use functions in javascript to draw lines, add images, and move objects around. For 3D we utilizes the graphics processing unit (GPU) hardware in your computer and use a combination of HTML5, Javascript, WebGL (based on OpenGl ES), and the OpenGL ES shading language. The graphics processing unit consists of parallel processors which perform high speed computations and accomplish much of the work for 3d graphics.

dividerline
GPU Figure 1. - A view of a graphics processing unit (GPU)
dividerline
Let's start from the beginning by initializing the canvas for WEBGL and changing it's color and and transparency.
red grn blue alpha
Figure 2. - A canvas for WEBGL 3D (change the colors and transparency to see the effect)
dividerline
Next we need some object to put on the canvas. Figure 3 shows a simple spacecraft. Models are built by specifying the vertexes of triangles (primitives) in 3D space. Fragments are then the areas bordered by the vertexes. Shown at right is the code for a simple spacecraft and colors for each vertex. It contains 10 triangles.
Space Ship Figure 3. -Layout for a simple space ship with vertexes listed
Next the arrays of data for position and color are are placed in the WEBGL "gl.ARRAY_BUFFER:
dividerline
dividerline
The last thing we have to do before the rendering loop is to take our compiled shaders from above and link them to a program object. At that point the program can be downloaded to the GPU before the drawing process can be accomplished.
dividerline
With a very small amount of code we can produce a space ship spiraling out of the pipeline. There are so many other things which can be done such as implementing textures, multiple objects, providing user interaction, spot lighting,establishing a camera and much more. Hopefully this helps in introducing the subject.
deltax rotX x
deltay rotY y
deltaz rotZ z
Frames per second
dividerline
CODE YOU CAN COPY AND USE FOR TESTING

____HTML5 CODE___SAVE AS: 3D.html

<!DOCTYPE html>
<html>
<head>
     <meta http-equiv="content-type" content="text/html; charset=UTF-8">
     <meta name="description" content="3d TEST"/>
     <title>www.corehtml5.com</title>
    <script src="gl-matrix.js" type="text/javascript"></script>
    <script src="3d.js" type="text/javascript"></script>
</head>
<body>
    <section>
    <canvas id="canvas3D" width="500" height="500" ></canvas>
     </section>
</body>
</html>

____JAVASCRIPT CODE___SAVE AS: 3D.JS
window.onload = initialize;

function initialize()
{
     initialize3DCanvas();
     initializeModels();
     initializeShaders();
     initializeProgram();
     render();
}

var can3D=null;
var gl=null;

function initialize3DCanvas()
{
     var can3D=document.getElementById('canvas3D');
    gl = can3D.getContext("webgl") || can3D.getContext('experimental-webgl');
    if(gl)
    {
        gl.viewportWidth=can3D.width;
        gl.viewportHeight=can3D.height;
         gl.viewport(0,0,gl.viewportWidth,gl.viewportHeight);
         gl.enable(gl.DEPTH_TEST);
         gl.depthFunc(gl.LEQUAL);
         gl.clearColor(0.5,0.5,0.5,1.0);
         gl.clear(gl.COLOR_BUFFER_BIT|gl.DEPTH_BUFFER_BIT);
     }
}

var verticeBufferObject=null;
var verticeColorBufferObject=null;

function initializeModels()
{
    var verticeArray =new Float32Array(
     [
    -0.1,0.0,0.1, -0.5,0.0,-0.5, -0.1,0.0,-0.5, //left wing
    0.1,0.0,0.1, 0.1,0.0,-0.5, 0.5,0.0,-0.5, //right wing
    -0.1,0.0,0.2, -0.1,0.0,-0.2, 0.0,0.3,0.0, //left cockpit
    0.1,0.0,-0.2, 0.1,0.0,0.2, 0.0,0.3,0.0, //right cockpit
     0.1,0.0,0.2, -0.1,0.0,0.2, 0.0,0.3,0.0, //front cockpit
     -0.1,0.0,-0.2, 0.1,0.0,-0.2, 0.0,0.3,0.0, //rear cockpit
     0.1,0.0,0.2, -0.1,0.0,0.2, -0.1,0.0,-0.2, //bottom cockpit
    -0.1,0.0,-0.2, 0.1,0.0,-0.2, 0.1,0.0,0.2, //bottom cockpit
    0.0,0.4,-0.4, 0.0,0.4,-0.1, 0.0,0.3,-0.35, //tail end
    0.0,0.0,-0.2, 0.0,0.0,-0.5, 0.0,0.4,-0.4 //tail stand
    ]);

    var verticeColorArray =new Float32Array(
    [
    1.0,0.0,0.0,1.0,1.0,0.0,0.0,1.0,1.0,0.0,0.0,1.0, //left wing
    1.0,0.0,0.0,1.0,1.0,0.0,0.0,1.0,1.0,0.0,0.0,1.0, //right wing
    0.0,0.0,1.0,1.0, 0.0,0.0,1.0,1.0 ,0.0,0.0,1.0,1.0, //left cockpit
    0.0,0.0,1.0,1.0, 0.0,0.0,1.0,1.0 ,0.0,0.0,1.0,1.0, //right cockpit
    1.0,1.0,1.0,0.2, 0.0,0.0,1.0,0.2 ,0.0,0.0,1.0,1.0, //front cockpit
    1.0,1.0,1.0,0.2, 0.0,0.0,1.0,0.2 ,0.0,0.0,1.0,1.0, //rear cockpit
    0.0,0.0,0.0,1.0,0.0,0.0,0.0,1.0,0.0,0.0,0.0,1.0, //bottom cockpit
    0.0,0.0,0.0,1.0,0.0,0.0,0.0,1.0,0.0,0.0,0.0,1.0, //bottom cockpit
    1.0,0.0,0.0,1.0,1.0,0.0,0.0,1.0,1.0,0.0,0.0,1.0, //tail end
    1.0,0.0,0.0,1.0,1.0,0.0,0.0,1.0,1.0,0.0,0.0,1.0 //tail stand
    ]);
    verticeBufferObject=gl.createBuffer();
    gl.bindBuffer(gl.ARRAY_BUFFER, verticeBufferObject);
    gl.bufferData(gl.ARRAY_BUFFER, verticeArray, gl.STATIC_DRAW);
    verticeColorBufferObject=gl.createBuffer();
    gl.bindBuffer(gl.ARRAY_BUFFER, verticeColorBufferObject);
    gl.bufferData(gl.ARRAY_BUFFER, verticeColorArray, gl.STATIC_DRAW);
}

var vertexShader = null;
var fragmentShader = null;
function initializeShaders()
{
    var vertexShaderCode=
    'attribute vec3 aVertexPosition;'+
    'attribute vec4 aVertexColor;'+
    'uniform mat4 uMVMatrix;'+
    'uniform mat4 uPMatrix;'+
    'varying lowp vec4 vertexColor;'+
    'void main(void)'+
    '{'+
        'gl_Position = uPMatrix * uMVMatrix * vec4(aVertexPosition, 1.0);'+
    'vertexColor = aVertexColor;'+
'}';
    vertexShader = gl.createShader(gl.VERTEX_SHADER);
    gl.shaderSource(vertexShader, vertexShaderCode);
    gl.compileShader(vertexShader);
    var fragmentShaderCode=
'    varying lowp vec4 vertexColor;'+
    'void main(void)'+
    '{'+
        'gl_FragColor = vertexColor;'+
    '}';
    fragmentShader = gl.createShader(gl.FRAGMENT_SHADER);
    gl.shaderSource(fragmentShader, fragmentShaderCode);
    gl.compileShader(fragmentShader);
}

var program = null;

function initializeProgram()
{
    program = gl.createProgram();
    gl.attachShader(program, vertexShader);
    gl.attachShader(program, fragmentShader);
    gl.linkProgram(program);
    gl.useProgram(program);
    program.vertexPositionAttribute = gl.getAttribLocation( program, "aVertexPosition");
    gl.enableVertexAttribArray( program.vertexPositionAttribute);
    program.vertexColorAttribute = gl.getAttribLocation( program, "aVertexColor");
    gl.enableVertexAttribArray( program.vertexColorAttribute);
    program.pMatrixUniform = gl.getUniformLocation( program, "uPMatrix");
    program.mvMatrixUniform = gl.getUniformLocation( program, "uMVMatrix");
}

var mvMatrix=mat4.create();
var pMatrix=mat4.create();

var x=-1.2, y=-1.5, z=-15.0;
var deltax=0.02, deltay=0.025, deltaz=0.2;
var rotX=-1, rotY=1, rotZ=1;
var rotateDegrees=0;
var verticesize=3, numVertices=30, fps=15;

function render()
{
     x+=deltax;
     y+=deltay;
     z+=deltaz;
     if(z>0.0)
     {
        x=-1.2;
        y=-1.5;
         z=-15.0;
         rotateDegrees=0;
    }
    rotateDegrees++;
     if(rotateDegrees>=360)rotateDegrees=0;
    mat4.perspective(pMatrix,45*Math.PI/180,gl.viewportWidth / gl.viewportHeight, 0.1, 100.0);
    mat4.identity(mvMatrix);
    mat4.translate(mvMatrix,mvMatrix,[x,y,z]);
    mat4.rotate(mvMatrix,mvMatrix,rotateDegrees*Math.PI/180, [rotX,rotY,rotZ]);
    gl.bindBuffer(gl.ARRAY_BUFFER, verticeBufferObject);
    gl.vertexAttribPointer( program.vertexPositionAttribute, verticesize, gl.FLOAT, false,0,0);
    gl.bindBuffer(gl.ARRAY_BUFFER, verticeColorBufferObject);
    gl.vertexAttribPointer(program.vertexColorAttribute, 4, gl.FLOAT, false, 0, 0);
    gl.uniformMatrix4fv(program.pMatrixUniform, false, pMatrix);
    gl.uniformMatrix4fv(program.mvMatrixUniform, false, mvMatrix);
    gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
    gl.drawArrays(gl.TRIANGLES, 0, numVertices);
    setTimeout("render()",1000/fps);
}
dividerline