Due Tonight!

Quiz 6!

Patrick Cozzi and Liz Dailey

Today: e-visit at 1245pm!

Patrick Cozzi and Liz Dailey

Welcome!

Updates coming!

Transformations

Translate

Rotate

Scale

Transformations

Translate

Rotate

Scale

Matrix

1   0   0   0

0   1   0   0

0   0   1   0

0   0   0   1

x, y, z

x, y, z

new

Identity

matrix multiplication

Matrix

1   0   0   t_x

0   1   0   t_y

0   0   1   t_z

0   0   0   1    

x, y, z

x, y, z

new

Translation

Matrix

s_x   0   0   t_x

0   s_y   0   t_y

0   0   s_z   t_z

0   0      0     1  

x, y, z

x, y, z

new

Scaling

Matrix

r   r   r   t_x

r   r   r   t_y

r   r   r   t_z

 0   0   0     1  

x, y, z

x, y, z

new

Rotation

Sheer!

matrix.set(..) uses row-major ordering!

Three.js

var m = new THREE.Matrix4();
m.set(
  r, r, r, t_x, 
  r, r, r, t_y, 
  r, r, r, t_z, 
  0, 0, 0, 1
);

WebGL / GLSL

Matrix

1   0   0   t_x

0   1   0   t_y

0   0   1   t_z

0   0   0   1    

x, y, z

x, y, z

new

Translation

<html>
  <head>
    <meta content="text/html;charset=utf-8" http-equiv="Content-Type">
    <meta content="utf-8" http-equiv="encoding">
    <title>Default WebGL!</title>
    <style>
      html, body { 
        background-color:#000;
        margin: 0;
        padding: 0;
        height: 100%;
        overflow: hidden !important;  
      }

      #c {
        width: 100%;
        height: 100%;
      }
    </style>
  </head>
  <script type="text/javascript" src="https://cs460.org/js/glmatrix.js"></script>
  
  <script id="vertexshader" type="glsl">
    attribute vec3 a_position;

    uniform vec3 u_offset;

    void main(void) {

      vec3 final_position = a_position;
      final_position.x += u_offset.x;
      final_position.y += u_offset.y;
      final_position.z += u_offset.z;
    
      gl_Position = vec4( final_position, 1.);
    
    }
  </script>
  
  <script id="fragmentshader" type="glsl">
    precision mediump float;

    uniform vec4 u_color;

    void main(void) {

      gl_FragColor = u_color;

    }
  </script>
  
  <script>

    var c, gl;
    var v_shader, f_shader, shaderprogram;
    var vertices, indices, v_buffer, i_buffer;

    window.onload = function() {

      //************************************************************//
      //
      // INITIALIZE WEBGL
      //
      c = document.getElementById( 'c' ); // setup canvas
      c.width = window.innerWidth;
      c.height = window.innerHeight;

      gl = c.getContext( 'webgl' ); // setup GL context
      gl.viewport(0, 0, c.width, c.height );


      //************************************************************//
      //
      // SHADERS
      //
      v_shader = gl.createShader( gl.VERTEX_SHADER );
      f_shader = gl.createShader( gl.FRAGMENT_SHADER );
      
      // compile vertex shader
      gl.shaderSource( v_shader, document.getElementById( 'vertexshader' ).innerText );
      gl.compileShader( v_shader );

      if (!gl.getShaderParameter( v_shader, gl.COMPILE_STATUS)) {
        console.log(gl.getShaderInfoLog( v_shader ));
      }

      // compile fragment shader
      gl.shaderSource( f_shader, document.getElementById( 'fragmentshader' ).innerText );
      gl.compileShader( f_shader );

      if (!gl.getShaderParameter( f_shader, gl.COMPILE_STATUS)) {
        console.log(gl.getShaderInfoLog( f_shader ));
      }

      // attach and link the shaders
      shaderprogram = gl.createProgram();
      gl.attachShader( shaderprogram, v_shader );
      gl.attachShader( shaderprogram, f_shader );

      gl.linkProgram( shaderprogram );

      gl.useProgram( shaderprogram );


      // create multiple rectangles
      rectangles = [];
      rectangles.push( createRectangle( new Float32Array([-.2,-.2,0]), new Float32Array([1.,1.,1.,1.]) ) );
      rectangles.push( createRectangle( new Float32Array([0,0,0]), new Float32Array([1.,0.,0.,1.]) ) );


      animate();

    };


    function createRectangle(offset, color) {


      //************************************************************//
      //
      // CREATE GEOMETRY
      //
      var vertices = new Float32Array( [
                                     -0.5,  0.5, 0.0, // 0: V0
                                     -0.5, -0.5, 0.0, // 1: V1, V4
                                      0.5,  0.5, 0.0, // 2: V2, V3
                                      0.5, -0.5, 0.0  // 3: V5
                                    ] ); // 2 * 4 == 8 bytes

      // now use indices
      var indices = new Uint8Array( [ 0, 1, 2, 2, 1, 3 ] ); // 6 bytes

      var v_buffer = gl.createBuffer(); // create
      gl.bindBuffer( gl.ARRAY_BUFFER, v_buffer ); // bind
      gl.bufferData( gl.ARRAY_BUFFER, vertices, gl.STATIC_DRAW ); // put data in
      gl.bindBuffer( gl.ARRAY_BUFFER, null ); // unbind

      var i_buffer = gl.createBuffer(); // create
      gl.bindBuffer( gl.ELEMENT_ARRAY_BUFFER, i_buffer ); // bind
      gl.bufferData( gl.ELEMENT_ARRAY_BUFFER, indices, gl.STATIC_DRAW ); // put data in
      gl.bindBuffer( gl.ELEMENT_ARRAY_BUFFER, null ); // unbind


      return [v_buffer, i_buffer, offset, color];

    };

    var step_x = .01;
    var step_y = .01;
    var direction = -1;

    function animate() {

      requestAnimationFrame(animate);

      gl.clearColor( 0., 0., 0., 0.)
      gl.clear( gl.COLOR_BUFFER_BIT );



      for( var r = 0; r < rectangles.length; r++ ) {

        // current_buffers is a list of [v_buffer, i_buffer]-pairs
        var current_buffers = rectangles[r];
        var current_v_buffer = current_buffers[0];
        var current_i_buffer = current_buffers[1];
        var current_offset = current_buffers[2];
        var current_color = current_buffers[3];

        // update offsets
        if ( current_offset[0] <= -1. ) {
          // bumped into left end of screen
          direction = 1;
        } else if ( current_offset[0] >= 1. ) {
          // bumped into right end of screen
          direction = -1;
        }
        current_offset[0] += direction*step_x;

        if ( current_offset[1] <= -1. ) {
          // bumped into left end of screen
          direction = 1;
        } else if ( current_offset[1] >= 1. ) {
          // bumped into right end of screen
          direction = -1;
        }
        current_offset[1] += direction*step_y;
        



        //************************************************************//
        //
        // CONNECT SHADER WITH GEOMETRY
        //
        
        gl.bindBuffer( gl.ARRAY_BUFFER, current_v_buffer );

        gl.bindBuffer( gl.ELEMENT_ARRAY_BUFFER, current_i_buffer );

        // find the attribute in the shader source
        var a_position = gl.getAttribLocation( shaderprogram, 'a_position' );

        gl.vertexAttribPointer( a_position, 3, gl.FLOAT, false, 0, 0 );

        gl.enableVertexAttribArray ( a_position );

        // find the uniform in the shader source
        var u_offset = gl.getUniformLocation( shaderprogram, 'u_offset' );

        gl.uniform3fv( u_offset, current_offset)

        var u_color = gl.getUniformLocation( shaderprogram, 'u_color' );
        
        gl.uniform4fv( u_color, current_color );

        //************************************************************//
        //
        // DRAW!
        //


        // gl.drawArrays( gl.TRIANGLES, 0, 6 );
        gl.drawElements( gl.TRIANGLES, 6, gl.UNSIGNED_BYTE, 0);

      }


    };

  </script>
  <body>
    <canvas id="c"></canvas>
  </body>
</html>
  <script id="vertexshader" type="glsl">
    attribute vec3 position;

    uniform mat4 transform;

    void main(void) {

      vec4 final_position = transform * vec4( position, 1.);

      gl_Position = final_position;
    
    }
  </script>
// ANIMATE..
var u_transform = gl.getUniformLocation( shaderprogram, 'transform' );

current_transform = new Float32Array([
  1, 0, 0, 0,
  0, 1, 0, 0,
  0, 0, 1, 0,
  OFFSET[0], OFFSET[1], 0, 1
]);

gl.uniformMatrix4fv( u_transform, false, current_transform );

Operator Overloading!

<html>
  <head>
    <meta content="text/html;charset=utf-8" http-equiv="Content-Type">
    <meta content="utf-8" http-equiv="encoding">
    <title>Vanilla WebGL!</title>
    <style>
      html, body { 
        background-color:#000;
        margin: 0;
        padding: 0;
        height: 100%;
        overflow: hidden !important;  
      }

      #c {
        width: 100%;
        height: 100%;
      }
    </style>
  </head>
  <script type="text/javascript" src="https://cs460.org/js/glmatrix.js"></script>
  
  <script id="vertexshader" type="glsl">
    attribute vec3 position;

    uniform mat4 transform;

    void main(void) {
    
      vec4 final_position = transform * vec4(position, 1.);
      
      gl_Position = final_position;
      gl_PointSize = 10.;
    
    }
  </script>
  
  <script id="fragmentshader" type="glsl">
    precision mediump float;

    uniform vec4 color;

    void main(void) {

      gl_FragColor = color; //vec4(1., 1., 1., 1.);

    }
  </script>

  <script>

    // VARIABLE DECLARATIONS
    var c, gl;
    var v_shader, f_shader, shaderprogram;
    // var vertices, v_buffer, indices, i_buffer;
    var objects;

    window.onload = function() {
      

      //************************************************************//
      //
      // INITIALIZE WEBGL
      //
      c = document.getElementById( 'c' );
      c.width = window.innerWidth;
      c.height = window.innerHeight;

      gl = c.getContext( 'webgl' );
      gl.viewport(0, 0, c.width, c.height);


      //************************************************************//
      //
      // SHADERS
      //
      v_shader = gl.createShader( gl.VERTEX_SHADER );

      f_shader = gl.createShader( gl.FRAGMENT_SHADER );

      // compile vertex shader
      gl.shaderSource( v_shader, document.getElementById( 'vertexshader' ).innerText );
      gl.compileShader( v_shader );

      if (!gl.getShaderParameter( v_shader, gl.COMPILE_STATUS )) {
        console.log(gl.getShaderInfoLog( v_shader ));
      }

      // compile fragment shader
      gl.shaderSource( f_shader, document.getElementById( 'fragmentshader' ).innerText );
      gl.compileShader( f_shader );

      if (!gl.getShaderParameter( f_shader, gl.COMPILE_STATUS )) {
        console.log(gl.getShaderInfoLog( f_shader ));
      }

      // attach and link the shaders
      shaderprogram = gl.createProgram();
      gl.attachShader( shaderprogram, v_shader );
      gl.attachShader( shaderprogram, f_shader );

      gl.linkProgram( shaderprogram );

      gl.useProgram( shaderprogram );


      // add objects
      objects = [];
      objects.push(createRectangle(new Float32Array( [1., 1., 0., 1.]), 
        new Float32Array( [-.3, -.2, 0 ] )));
      objects.push(createRectangle(new Float32Array( [1., 0., 0., 1.]),
        new Float32Array( [-.1, -.2, 0 ] )));


      animate();


    };


    function createRectangle(color, offset) {

      //************************************************************//
      //
      // CREATE GEOMETRY
      //
      vertices = new Float32Array( [
                                     -0.5,  0.5, 0.0, // V0.     // 0
                                     -0.5, -0.5, 0.0, // V1, V4. // 1
                                      0.5,  0.5, 0.0, // V2, V3. // 2
                                      0.5, -0.5, 0.0  // V5.     // 3
                                    ] );

      indices = new Uint8Array( [
                                0, 1, 2, 2, 1, 3
                                ] );

      var v_buffer = gl.createBuffer(); // create
      gl.bindBuffer( gl.ARRAY_BUFFER, v_buffer ); // bind
      gl.bufferData( gl.ARRAY_BUFFER, vertices, gl.STATIC_DRAW ); // put data in
      gl.bindBuffer( gl.ARRAY_BUFFER, null ); // unbind

      var i_buffer = gl.createBuffer(); // create
      gl.bindBuffer( gl.ELEMENT_ARRAY_BUFFER, i_buffer ); // bind
      gl.bufferData( gl.ELEMENT_ARRAY_BUFFER, indices, gl.STATIC_DRAW ); // put data in
      gl.bindBuffer( gl.ELEMENT_ARRAY_BUFFER, null ); // unbind



      return [v_buffer, i_buffer, color, offset];


    };



    function animate() {


      gl.clearColor( 0., 0., 0., 0. );
      gl.clear( gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT );



      // loop through all objects in the scene
      for (var o=0; o<objects.length; o++) {


        var current_object = objects[o];
        var v_buffer = current_object[0];
        var i_buffer = current_object[1];
        var current_color = current_object[2];
        var current_offset = current_object[3];
        // console.log(current_object);

        //************************************************************//
        //
        // CONNECT SHADER WITH GEOMETRY
        //
        
        gl.bindBuffer( gl.ARRAY_BUFFER, v_buffer );

        gl.bindBuffer( gl.ELEMENT_ARRAY_BUFFER, i_buffer );

        var a_position = gl.getAttribLocation( shaderprogram, 'position' );

        gl.vertexAttribPointer( a_position, 3, gl.FLOAT, false, 0, 0 );

        gl.enableVertexAttribArray( a_position );


        var u_color = gl.getUniformLocation( shaderprogram, 'color' );

        gl.uniform4fv( u_color, current_color );


        current_offset[0] -= .01;

        if (current_offset[0] < -1) {
          current_offset[0] = 1;          
        }


        var u_transform = gl.getUniformLocation( shaderprogram, 'transform' );

        current_transform = new Float32Array([
          .5, 0, 0, 0,
          0, .5, 0, 0,
          0, 0, .5, 0,
          current_offset[0], current_offset[1], 0, 1
          ]);

        gl.uniformMatrix4fv( u_transform, false, current_transform );


        //************************************************************//
        //
        // DRAW!
        //

        // gl.drawArrays( gl.LINE_LOOP, 0, 6);
        gl.drawElements( gl.TRIANGLES, 6, gl.UNSIGNED_BYTE, 0);



      }



      // THIS IS OUR LOOP
      requestAnimationFrame(animate);

    };

  </script>
  <body>
    <canvas id="c"></canvas>
  </body>
</html>

Operator Overloading!

Matrix Games

winner gets extra credit or candy

1   0   0   0

0   1   0   0

0   0   1   0

0   0   0   1

0, 0, 0

?

1   0   0   0

0   1   0   0

0   0   1   0

0   0   0   1

0, 0, 0

0, 0, 0

0.5   0   0   0

0   0.5   0   0

0   0   0.5   0

0   0   0   1

2, 2, 2

?

1, 1, 1

0.5   0   0   0

0   0.5   0   0

0   0   0.5   0

0   0   0   1

2, 2, 2

1   0   0   -1

0   1   0   -1

0   0   1   -1

0   0   0   1

2, 2, 2

?

1, 1, 1

2, 2, 2

1   0   0   -1

0   1   0   -1

0   0   1   -1

0   0   0   1

0.5   0   0   -1

0   0.5   0   -1

0   0   0.5   -1

0    0    0    1

2, 2, 2

?

0.5   0   0   -1

0   0.5   0   -1

0   0   0.5   -1

0    0    0    1

2, 2, 2

0, 0, 0

cos(T)   -sin(T)   0   0

sin(T)   cos(T)   0    0

    0          0        1    0

    0          0       0     1

2, 2, 2

?

with T = Pi/2

 = 90°

X

Y

Z

cos(T)   -sin(T)   0   0

sin(T)   cos(T)   0    0

    0          0        1    0

    0          0       0     1

2, 2, 2

with T = Pi/2

 = 90°

-2, 2, 2

Scene Graph

Scene

1   0   0   0

0   1   0   0

0   0   1   0

0   0   0   1

1   0   0   0

0   1   0   0

0   0   1   0

0   0   0   1

1   0   0   0

0   1   0   0

0   0   1   0

0   0   0   1

Scene

1   0   0   0

0   1   0   0

0   0   1   0

0   0   0   1

1   0   0   0

0   1   0   0

0   0   1   0

0   0   0   1

1   0   0   0

0   1   0   0

0   0   1   0

0   0   0   1

1   0   0   0

0   1   0   0

0   0   1   0

0   0   0   1

1   0   0   0

0   1   0   0

0   0   1   0

0   0   0   1

1   0   0   0

0   1   0   0

0   0   1   0

0   0   0   1

Scene

1   0   0   0

0   1   0   0

0   0   1   0

0   0   0   1

1   0   0   0

0   1   0   0

0   0   1   0

0   0   0   1

1   0   0   0

0   1   0   0

0   0   1   0

0   0   0   1

1   0   0   0

0   1   0   0

0   0   1   0

0   0   0   1

1   0   0   0

0   1   0   0

0   0   1   0

0   0   0   1

1   0   0   0

0   1   0   0

0   0   1   0

0   0   0   1

1   0   0   0

0   1   0   0

0   0   1   0

0   0   0   1

1   0   0   0

0   1   0   0

0   0   1   0

0   0   0   1

1   0   0   0

0   1   0   0

0   0   1   0

0   0   0   1

*

1   0   0   0

0   1   0   0

0   0   1   0

0   0   0   1

Scene

1   0   0   0

0   1   0   0

0   0   1   0

0   0   0   1

1   0   0   0

0   1   0   0

0   0   1   0

0   0   0   1

1   0   0   0

0   1   0   0

0   0   1   0

0   0   0   1

1   0   0   0

0   1   0   0

0   0   1   0

0   0   0   1

1   0   0   0

0   1   0   0

0   0   1   0

0   0   0   1

1   0   0   0

0   1   0   0

0   0   1   0

0   0   0   1

1   0   0   0

0   1   0   0

0   0   1   0

0   0   0   1

1   0   0   0

0   1   0   0

0   0   1   0

0   0   0   1

1   0   0   0

0   1   0   0

0   0   1   0

0   0   0   1

1   0   0   0

0   1   0   0

0   0   1   0

0   0   0   1

1   0   0   0

0   1   0   0

0   0   1   0

0   0   0   1

1   0   0   0

0   1   0   0

0   0   1   0

0   0   0   1

1   0   0   0

0   1   0   0

0   0   1   0

0   0   0   1

1   0   0   0

0   1   0   0

0   0   1   0

0   0   0   1

1   0   0   0

0   1   0   0

0   0   1   0

0   0   0   1

*

*

*

Scene

1   0   0   0

0   1   0   0

0   0   1   0

0   0   0   1

1   0   0   0

0   1   0   0

0   0   1   0

0   0   0   1

1   0   0   0

0   1   0   0

0   0   1   0

0   0   0   1

1   0   0   0

0   1   0   0

0   0   1   0

0   0   0   1

1   0   0   0

0   1   0   0

0   0   1   0

0   0   0   1

1   0   0   0

0   1   0   0

0   0   1   0

0   0   0   1

1   0   0   0

0   1   0   0

0   0   1   0

0   0   0   1

1   0   0   0

0   1   0   0

0   0   1   0

0   0   0   1

1   0   0   0

0   1   0   0

0   0   1   0

0   0   0   1

1   0   0   0

0   1   0   0

0   0   1   0

0   0   0   1

1   0   0   0

0   1   0   0

0   0   1   0

0   0   0   1

1   0   0   0

0   1   0   0

0   0   1   0

0   0   0   1

1   0   0   0

0   1   0   0

0   0   1   0

0   0   0   1

1   0   0   0

0   1   0   0

0   0   1   0

0   0   0   1

1   0   0   0

0   1   0   0

0   0   1   0

0   0   0   1

Scene Graph is a Tree-like Hierarchy!

*

*

*

Inverse Kinematics

submit your music

Quiz 6 and Assignment 4 Due Today!

Lecture 13

By Daniel Haehn

Lecture 13

Slides for CS460 Computer Graphics at UMass Boston. See https://cs460.org!

  • 134