Ejercicio 9 - CVI

Sombras en WebGL

by Sebastian Martinez

HTML

<canvas id="scene" width="600px" height="500px"></canvas>
<script id="3d-vertex-shader" type="x-shader/x-vertex">
precision mediump float;

uniform mat4 mProj;
uniform mat4 mView;
uniform mat4 mWorld;

attribute vec3 a_position;
attribute vec3 a_normal;

varying vec3 fPos;
varying vec3 fNorm;

void main()
{
	fPos = (mWorld * vec4(a_position, 1.0)).xyz;
	fNorm = (mWorld * vec4(a_normal, 0.0)).xyz;

	gl_Position = mProj * mView * vec4(fPos, 1.0);
}
</script>
<script id="3d-fragment-shader" type="x-shader/x-fragment">
precision mediump float;

uniform vec3 pointLightPosition;
uniform vec4 meshColor;

uniform samplerCube lightShadowMap;

varying vec3 fPos;
varying vec3 fNorm;

void main()
{
	vec3 toLightNormal = normalize(pointLightPosition - fPos);

  float fromLightToFrag = length(fPos - pointLightPosition);

	float shadowMapValue = textureCube(lightShadowMap, -toLightNormal).r;

	float lightIntensity = 0.15;
	if (shadowMapValue >= fromLightToFrag) {
		lightIntensity += 0.75 * max(dot(fNorm, toLightNormal), 0.0);
	}

	gl_FragColor = vec4(meshColor.rgb * lightIntensity, meshColor.a);
}
</script>
<script id="shadowMap-vs" type="x-shader/x-vertex">
precision mediump float;

uniform mat4 mProj;
uniform mat4 mView;
uniform mat4 mWorld;

attribute vec3 a_position;

varying vec3 fPos;

void main()
{
	fPos = (mWorld * vec4(a_position, 1.0)).xyz;

	gl_Position = mProj * mView * vec4(fPos, 1.0);
}
</script>
<script id="shadowMap-fs" type="x-shader/x-fragment">
precision mediump float;

uniform vec3 pointLightPosition;

varying vec3 fPos;

void main()
{
	vec3 fromLightToFrag = (fPos - pointLightPosition);

  float lightFragDist =length(fromLightToFrag);

	gl_FragColor = vec4(lightFragDist, lightFragDist, lightFragDist, 1.0);
}
</script>
 <script src="https://webglfundamentals.org/webgl/resources/webgl-utils.js"></script> 
 <script src="https://webglfundamentals.org/webgl/resources/m4.js"></script>
 <script...

JavaScript

'use strict';

//Point
var pointLightPosition = [0, 5, 0];

//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');
  var gl = canvas.getContext('webgl');
  if (!gl) return;
  
  var programInfo = webglUtils.createProgramInfo(gl, [
    '3d-vertex-shader',
    '3d-fragment-shader'
  ]);
  
  var shadowMapProgramInfo = webglUtils.createProgramInfo(gl, [
    'shadowMap-vs',
    'shadowMap-fs'
  ]);
  // Fucniones utiles
  function degToRad(d) {
    return d * Math.PI / 180;
  }

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

  function emod(x, n) {
    return x >= 0 ? x % n : (n + x % n) % n;
  }
  
  // Interpolacion lineal entre vectores
  function lerp(a, b, t) {
    var len = a.length;
    if(b.length != len) return;

 ...