Ejercicio 8 - CVI

Iluminacion

by Sebastian Martinez

HTML

<canvas id="scene" width="600px" height="500px"></canvas>
<div class="btn-group">
  <button onclick="changeShader('dir');">Directional</button>
  <button onclick="changeShader('point');">Point</button>
  <button onclick="changeShader('spot');">Spot</button>
</div>
<!-- vertex shader -->
<script id="3d-vertex-shader_dir" type="x-shader/x-vertex">
attribute vec4 a_position;
attribute vec3 a_normal;

uniform mat4 u_worldViewProjection;
uniform mat4 u_worldInverseTranspose;

varying vec3 v_normal;

void main() {
  // Multiply the position by the matrix.
  gl_Position = u_worldViewProjection * a_position;

  // orient the normals and pass to the fragment shader
  v_normal = mat3(u_worldInverseTranspose) * a_normal;
}
</script>
<!-- fragment shader -->
<script id="3d-fragment-shader_dir" type="x-shader/x-fragment">
precision mediump float;

// Passed in from the vertex shader.
varying vec3 v_normal;

uniform vec3 u_reverseLightDirection;
uniform vec4 u_color;

void main() {

  vec3 normal = normalize(v_normal);

  float light = dot(normal, u_reverseLightDirection);
  float ambientLightfactor = 0.3;
  vec3 ambientLight = vec3(ambientLightfactor, ambientLightfactor, ambientLightfactor);
  gl_FragColor = u_color;
  gl_FragColor.rgb *= light + ambientLight;
}
</script>
<script id="3d-vertex-shader_point" type="x-shader/x-vertex">
    attribute vec4 a_position;
    attribute vec3 a_normal;
     
    uniform vec3 u_lightWorldPosition;
     
    uniform mat4 u_world;
    uniform mat4 u_worldViewProjection;
    uniform mat4 u_worldInverseTranspose;
     
    varying vec3 v_normal;
     
    varying vec3 v_surfaceToLight;
     
    void main() {
      gl_Position = u_worldViewProjection * a_position;
     
      v_normal = mat3(u_worldInverseTranspose) * a_normal;
     
      vec3 surfaceWorldPosition = (u_world * a_position).xyz;
      v_surfaceToLight = u_lightWorldPosition - surfaceWorldPosition;
    }
</script>
<script id="3d-fragment-shader_point"...

CSS

.btn-group button {
    background-color: #4CAF50; /* Green background */
    border: 1px solid green; /* Green border */
    color: white; /* White text */
    padding: 10px 24px; /* Some padding */
    cursor: pointer; /* Pointer/hand icon */
    float: left; /* Float the buttons side by side */
}

.btn-group button:not(:last-child) {
    border-right: none; /* Prevent double borders */
}

/* Clear floats (clearfix hack) */
.btn-group:after {
    content: "";
    clear: both;
    display: table;
}

/* Add a background color on hover */
.btn-group button:hover {
    background-color: #3e8e41;
}

.btn-group
{
  position: fixed;
  top: 0;
  width: 100vw;
  display: flex;
  justify-content: center;
}

JavaScript

'use strict';
//Directional
var reverseLightDirection = m4.normalize([0, 0.5, 1]);
//Point
var pointLightPosition = [0, 5, 0];
//Spot
var spotDirection = m4.normalize([-1, -0.25, -1]);
var spotLimit = 0.93;

var programInfo = null;
var gl = null;
var lightType = 'dir';

function changeShader(shader) {
  lightType = shader;
  programInfo = webglUtils.createProgramInfo(gl, [
    '3d-vertex-shader_'+shader,
    '3d-fragment-shader_'+shader
  ]);
}
//Puntos de la curva
var startP = [-10, 0, 0];
var endP = [10, 0, -25];
var c1P = [-10, 0, -15];
var c2P = [-10, 0, -15];

var t = 0; //Tiempo animación actual
var animacion = 5000; //Tiempo de animacion
var tiempo = Date.now(); //Tiempo actual
var regreso = false; //Animacion de regreso
  
// Clases del grafo de escena
var Node = function() {
  this.children = [];
  this.localMatrix = m4.identity();
  this.worldMatrix = m4.identity();
};

Node.prototype.setParent = function(parent) {
  if (this.parent) {
    var ndx = this.parent.children.indexOf(this);
    if (ndx >= 0) {
      this.parent.children.splice(ndx, 1);
    }
  }

  if (parent) {
    parent.children.push(this);
  }
  this.parent = parent;
};

Node.prototype.updateWorldMatrix = function(parentWorldMatrix) {
  if (parentWorldMatrix) {
    // a matrix was passed in so do the math
    m4.multiply(parentWorldMatrix, this.localMatrix, this.worldMatrix);
  } else {
    // no matrix was passed in so just copy local to world
    m4.copy(this.localMatrix, this.worldMatrix);
  }
  
  // now process all the children
  var worldMatrix = this.worldMatrix;
  this.children.forEach(function(child) {
    child.updateWorldMatrix(worldMatrix);
  });
};

// Main
function main() {
  var canvas = document.getElementById('scene');
  gl = canvas.getContext('webgl');
  if (!gl) return;
  
  changeShader('dir');

  // Fucniones utiles
  function degToRad(d) {
    return d * Math.PI / 180;
  }

  function rand(min, max) {
    return Math.random() * (max - min) + min;
  }

  function...