View Matrix

This fiddle is part of the MDN content kit for WebGL Model View Projection. https://github.com/TatumCreative/mdn-model-view-projection

by tatumcreative

HTML

<!-- The vertex shader operates on individual vertices in our model data by setting gl_Position -->
<script id="vertex-shader" type="x-shader/x-vertex">
  //Each point has a position and color
  attribute vec3 position;
  attribute vec4 color;

  // The transformation matrices
  uniform mat4 model;
  uniform mat4 view;
  uniform mat4 projection;

  // Pass the color attribute down to the fragment shader
  varying vec4 vColor;

  void main() {
    
    // Pass the color down to the fragment shader
    vColor = color;
    
    // Read the multiplication in reverse order, the point is taken from
    // the original model space and moved into world space. It is then
    // projected into clip space as a homogeneous point. Generally the
    // W value will be something other than 1 at the end of it.
    gl_Position = projection * view * model * vec4( position, 1.0 );
  }
</script>

<!-- The fragment shader determines the color of the final pixel by setting gl_FragColor -->
<script id="fragment-shader" type="x-shader/x-fragment">
  precision mediump float;
  varying vec4 vColor;
  
  void main() {
    gl_FragColor = vColor;
    // gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0);
  }
</script>
  
<canvas id="canvas"></canvas>

<h1 class='lesson-title'>
  View Matrix
</h1>

<script>
  //Shared code for the examples
    
    
  // Define the MDN global
  var MDN = {};

  // Define the data that is needed to make a 3d cube
  MDN.createCubeData = function() {
  
    var positions = [
      // Front face
      -1.0, -1.0,  1.0,
       1.0, -1.0,  1.0,
       1.0,  1.0,  1.0,
      -1.0,  1.0,  1.0,

      // Back face
      -1.0, -1.0, -1.0,
      -1.0,  1.0, -1.0,
       1.0,  1.0, -1.0,
       1.0, -1.0, -1.0,

      // Top face
      -1.0,  1.0, -1.0,
      -1.0,  1.0,  1.0,
       1.0,  1.0,  1.0,
       1.0,  1.0, -1.0,

      // Bottom face
      -1.0, -1.0, -1.0,
       1.0, -1.0, -1.0,
       1.0, -1.0,  1.0,
      -1.0, -1.0,  1.0,

      // Right face
       1.0, -1.0,...

CSS

html, body {
	width:100%;
	height:100%;
	margin: 0;
}
canvas {
	width: 100% !important;
	height: 100% !important;
}
.lesson-title {
  position: absolute;
  bottom: 0;
  left: 0;
  margin: 0.7em;
  font-family: sans-serif;
  font-size: 1em;
  color: #888;
  font-weight: normal;
}
.lesson-title a {
	text-decoration: none;
	color: #668;
}
.lesson-title a:hover {
	color: #338;
}

JavaScript

/*
The final step in all of this is to create the view matrix. Right now we can move the cube around world space. We can project everything to have perspective, but we still can't move the camera.

The final matrix is the view matrix that represents the camera's position. Imagine shooting a movie with a physical camera. This matrix represents the position and rotation of that physical camera.

At this point it would be beneficial to take a step back and look at and label the various coordinate systems. First off the cube's vertices are in model space. To move the model around the scene these vertices need to be converted into world space.

  model space -> model matrix -> world space

The camera hasn't done anything yet, and the points need to be moved again. Currently they are in world space, but then need to be moved to view space.

  world space -> view matrix -> view space

Finally a projection or perspective needs to be added. This final step will move it into clip space.

  view space -> projection matrix -> clip space

After this step the GPU will clip the out of range vertices, and send the model down to the fragment shader for rasterization.

Exercise:

1) Move the camera around the scene. Add some rotation matrices to the view matrix to look around.

2) Track the mouse's position. Use 2 rotation matrices to have the camera look up and down based on where the user's mouse is on the screen.
*/

function CubeDemo () {
  
  // Prep the canvas
  this.canvas = document.getElementById("canvas");
  this.canvas.width = window.innerWidth;
  this.canvas.height = window.innerHeight;
  
  // Grab a context
  this.gl = MDN.createContext(this.canvas);

  this.transforms = {}; // All of the matrix transforms
  this.locations = {}; //All of the shader locations
  
  // Get the rest going
  this.buffers = MDN.createBuffersForCube(this.gl, MDN.createCubeData() );
  this.webglProgram = this.setupProgram();
  
}

CubeDemo.prototype.setupProgram = function() {
  
  var gl =...