Search code examples
webglorthographic

Setting up an Orthographic Top View Projection in WebGL


I've studied the example here: http://learningwebgl.com/lessons/lesson01/index.html

The matrix library in use is: http://glmatrix.net/

So the example is in clip space and I understand that. I would like to set up an orthographic projection using this example as my base. The Orthographic projection should have it's center at 0,0,0 with an eye location somewhere at +Z and looking down on 0,0,0. When I enter coordinates for my 3d faces in the buffers I would like to be able to enter those coordinates in model space units. Example for my mapping exhibit I have an area of 10,000 cubics x -5000 to +5000 y -5000 to +5000 and z -5000 to +5000 that is to be projected onto the canvas which is 500 x 500. So my 3d faces will have coordinates someplace within those 10,000 cubics and the 500 x 500 canvas will display all 10,000 cubics.

This is the same projection that a CAD program would use to start a scratch drawing. Does anyone know how to do this in WebGL with the glMatrix library? I am new to WebGL and I really could use some guidance on this topic.


Solution

  • For sake of simplicity you first should separate the camera transform matrix from it's projection matrix. You can then multiply them to get the "view-projection matrix" which transform world-space coordinates to screen-space.

    var cam = mat4.create();
    var proj = mat4.create();
    

    Start placing your camera (cam matrix)

    mat4.translate( cam, cam, position )
    mat4.rotate( ... )
    mat4.lookAt( .. )
    //...
    

    Setup othographic projection (proj matrix). You can see the ortho projection like a box aligned with the camera, you can expand each sides with the six parameters. Everything inside the box will show on screen.

    var ratio = screenWidth/screenHeight;
    var halfWorldWidth = 5000.0;
    
    // the near/far will depend on your camera position
    mat4.ortho( proj,
      -halfWorldWidth,
      halfWorldWidth,
      -halfWorldWidth / ratio,
      halfWorldWidth  /ratio,
      -50,
      50
    )
    

    Finally get the view-projection

    var view     = mat4.create()
    var viewProj = mat4.create()
    
    mat4.invert( view, cam );
    mat4.multiply( viewProj, proj, view );