I have to add a spotlight to my rotating cube so this is my code:HTML        <!DOCTYPE html><html><button id = ButtonX>Rotate X</button><button id = ButtonY>Rotate Y</button><button id = ButtonZ>Rotate Z</button><button id = ButtonT>Toggle Rotation</button><script id=vertex-shader type=x-shader/x-vertex>attribute  vec4 vPosition;attribute  vec4 vColor;attribute  vec2 vTexCoord;attribute  vec3 vNormal;uniform float shininess;uniform vec4 posLightPosition;uniform vec4 posAmbientProduct, posDiffuseProduct,      posSpecularProduct;uniform vec4 dirLightPosition;uniform vec4 dirAmbientProduct, dirDiffuseProduct,      dirSpecularProduct;uniform vec4 spotLightPosition;uniform vec4 spotAmbientProduct, spotDiffuseProduct,spotSpecularProduct;uniform vec4 spotLightDirection;uniform float lCutOff;varying vec4 fColor;varying vec2 fTexCoord;uniform vec3 theta;void main(){    // Compute the sines and cosines of theta for each of    //   the three axes in one computation.    vec3 angles = radians( theta );    vec3 c = cos( angles );    vec3 s = sin( angles );    // Remeber: thse matrices are column-major    mat4 rx = mat4( 1.0,  0.0,  0.0, 0.0,            0.0,  c.x,  s.x, 0.0,            0.0, -s.x,  c.x, 0.0,            0.0,  0.0,  0.0, 1.0 );    mat4 ry = mat4( c.y, 0.0, -s.y, 0.0,            0.0, 1.0,  0.0, 0.0,            s.y, 0.0,  c.y, 0.0,            0.0, 0.0,  0.0, 1.0 );    mat4 rz = mat4( c.z, s.z, 0.0, 0.0,            -s.z,  c.z, 0.0, 0.0,            0.0,  0.0, 1.0, 0.0,            0.0,  0.0, 0.0, 1.0 );    vec3 N=normalize((rz*ry*rx*vNormal).xyz);    // positional light    vec3 pos=-(rz*ry*rx*vPosition).xyz;    vec3 posLight=posLightPosition.xyz;    vec3 posL=normalize(posLight-pos);    vec3 posE=normalize(-pos);    vec3 posH=normalize(posL+posE);    vec4 posAmbient=posAmbientProduct;    float posKd=max(dot(posL,N),0.0);    vec4 posDiffuse=posKd*posDiffuseProduct;    float posKs=pow(max(dot(N,posH),0.0), shininess);    vec4 posSpecular=posKs*posSpecularProduct;    if(dot(posL,N)<0.0){    posSpecular=vec4(0.0,0.0,0.0,1.0);    }    // directional light    vec3 dirLight=dirLightPosition.xyz;    vec3 dirL=normalize(dirLight);    vec3 dirE=normalize(-pos);    vec3 dirH=normalize(dirL+dirE);    vec4 dirAmbient=dirAmbientProduct;    float dirKd=max(dot(dirL,N),0.0);    vec4 dirDiffuse=dirKd*dirDiffuseProduct;    float dirKs=pow(max(dot(N,dirH),0.0), shininess);    vec4 dirSpecular=dirKs*dirSpecularProduct;    if(dot(dirL,N)<0.0){    dirSpecular=vec4(0.0,0.0,0.0,1.0);    }    //spotlight    vec3 spotLight=spotLightPosition.xyz;    vec3 spotL=normalize(spotLight);    vec3 spotE=normalize(-pos);    vec3 spotH=normalize(spotL+spotE);    vec3 spotD=spotLightDirection.xyz;    vec4 spotAmbient=spotAmbientProduct;    float spotKd=max(dot(spotL,N),0.0);    vec4 spotDiffuse=spotKd*spotDiffuseProduct;    float spotKs=pow(max(dot(N,spotH),0.0), shininess);    vec4 spotSpecular=spotKs*spotSpecularProduct;    if(dot(spotL,N)<0.0){    spotSpecular=vec4(0.0,0.0,0.0,1.0);    }    float lEffect= dot(normalize(spotD), -spotH);    if(lEffect>lCutOff)    {    vec4 ambient=posAmbient+dirAmbient+spotAmbient;    vec4 diffuse=posDiffuse+dirDiffuse+spotDiffuse;    vec4 specular=posSpecular+dirSpecular+spotSpecular;    fColor = ambient+vColor*(diffuse+specular);    fColor.a = 1.0;    }    else{    vec4 ambient=posAmbient+dirAmbient;    vec4 diffuse=posDiffuse+dirDiffuse;    vec4 specular=posSpecular+dirSpecular;    fColor = ambient+vColor*(diffuse+specular);    fColor.a = 1.0;        }        fTexCoord = vTexCoord;    gl_Position = rz * ry * rx * vPosition;    gl_Position.z = -gl_Position.z;}</script><script id=fragment-shader type=x-shader/x-fragment>precision mediump float;varying vec4 fColor;varying  vec2 fTexCoord;uniform sampler2D Tex0;uniform sampler2D Tex1;voidmain(){    gl_FragColor = fColor*(texture2D(Tex0, fTexCoord)*texture2D(Tex1, fTexCoord));}</script><script type=text/javascript src=../Common/webgl-utils.js></script><script type=text/javascript src=../Common/initShaders.js></script><script type=text/javascript src=../Common/MV.js></script><script type=text/javascript src=Homework1.js></script><body><canvas id=gl-canvas width=1024 height=1024>Oops ... your browser doesn't support the HTML5 canvas element</canvas></body></html>JAVASCRIPTuse strict;var canvas;var gl;var numVertices  = 36;var texSize = 256;var numChecks = 8;var program;var texture1, texture2;var t1, t2;var normalsArray = [];var dirLightPosition = vec4(1.0, 1.0, 1.0, 0.0 );var dirLightAmbient = vec4(0.2, 0.2, 0.2, 1.0 );var dirLightDiffuse = vec4( 1.0, 1.0, 1.0, 1.0 );var dirLightSpecular = vec4( 1.0, 1.0, 1.0, 1.0 );var posLightPosition = vec4(1.0, 1.0, 1.0, 1.0 );var posLightAmbient = vec4(0.2, 0.2, 0.2, 1.0 );var posLightDiffuse = vec4( 1.0, 1.0, 1.0, 1.0 );var posLightSpecular = vec4( 1.0, 1.0, 1.0, 1.0 );var materialAmbient = vec4( 1.0, 0.0, 1.0, 1.0 );var materialDiffuse = vec4( 1.0, 0.8, 0.0, 1.0 );var materialSpecular = vec4( 1.0, 1.0, 1.0, 1.0 );var materialShininess = 20.0;var spotLightPosition = vec4(1.0, 2.0, 3.0, 1.0 );var spotLightAmbient = vec4(0.2, 0.2, 0.2, 1.0 );var spotLightDiffuse = vec4( 1.0, 1.0, 1.0, 1.0 );var spotLightSpecular = vec4( 1.0, 1.0, 1.0, 1.0 );var spotLightDirection = vec4(-0.5,1.0,2.0,1.0);var lCutOff=0.867;var c;var flag = true;var image1 = new Uint8Array(4*texSize*texSize);    for ( var i = 0; i < texSize; i++ ) {        for ( var j = 0; j <texSize; j++ ) {            var patchx = Math.floor(i/(texSize/numChecks));            var patchy = Math.floor(j/(texSize/numChecks));            if(patchx%2 ^ patchy%2) c = 255;            else c = 0;            //c = 255*(((i & 0x8) == 0) ^ ((j & 0x8)  == 0))            image1[4*i*texSize+4*j] = c;            image1[4*i*texSize+4*j+1] = c;            image1[4*i*texSize+4*j+2] = c;            image1[4*i*texSize+4*j+3] = 255;        }    }var image2 = new Uint8Array(4*texSize*texSize);    // Create a checkerboard pattern    for ( var i = 0; i < texSize; i++ ) {        for ( var j = 0; j <texSize; j++ ) {            image2[4*i*texSize+4*j] = 127+127*Math.sin(0.1*i*j);            image2[4*i*texSize+4*j+1] = 127+127*Math.sin(0.1*i*j);            image2[4*i*texSize+4*j+2] = 127+127*Math.sin(0.1*i*j);            image2[4*i*texSize+4*j+3] = 255;           }    }var pointsArray = [];var colorsArray = [];var texCoordsArray = [];var texCoord = [    vec2(0, 0),    vec2(0, 1),    vec2(1, 1),    vec2(1, 0)];var vertices = [    vec4( -0.5, -0.5,  0.5, 1.0 ),    vec4( -0.5,  0.5,  0.5, 1.0 ),    vec4( 0.5,  0.5,  0.5, 1.0 ),    vec4( 0.5, -0.5,  0.5, 1.0 ),    vec4( -0.5, -0.5, -0.5, 1.0 ),    vec4( -0.5,  0.5, -0.5, 1.0 ),    vec4( 0.5,  0.5, -0.5, 1.0 ),    vec4( 0.5, -0.5, -0.5, 1.0 )];var vertexColors = [    vec4( 0.0, 0.0, 0.0, 1.0 ),  // black    vec4( 1.0, 0.0, 0.0, 1.0 ),  // red    vec4( 1.0, 1.0, 0.0, 1.0 ),  // yellow    vec4( 0.0, 1.0, 0.0, 1.0 ),  // green    vec4( 0.0, 0.0, 1.0, 1.0 ),  // blue    vec4( 1.0, 0.0, 1.0, 1.0 ),  // magenta    vec4( 0.0, 1.0, 1.0, 1.0 ),  // white    vec4( 0.0, 1.0, 1.0, 1.0 )   // cyan];var xAxis = 0;var yAxis = 1;var zAxis = 2;var axis = xAxis;var theta = [45.0, 45.0, 45.0];var thetaLoc;function configureTexture() {    texture1 = gl.createTexture();    gl.bindTexture( gl.TEXTURE_2D, texture1 );    gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, true);    gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, texSize, texSize, 0, gl.RGBA, gl.UNSIGNED_BYTE, image1);    gl.generateMipmap( gl.TEXTURE_2D );    gl.texParameteri( gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER,                      gl.NEAREST_MIPMAP_LINEAR );    gl.texParameteri( gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST);    texture2 = gl.createTexture();    gl.bindTexture( gl.TEXTURE_2D, texture2 );    gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, true);    gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, texSize, texSize, 0, gl.RGBA, gl.UNSIGNED_BYTE, image2);    gl.generateMipmap( gl.TEXTURE_2D );    gl.texParameteri( gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER,                      gl.NEAREST_MIPMAP_LINEAR );    gl.texParameteri( gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST);}function quad(a, b, c, d) {     var t1 = subtract(vertices[b], vertices[a]);     var t2 = subtract(vertices[c], vertices[b]);     var normal = cross(t1, t2);     var normal = vec3(normal);     pointsArray.push(vertices[a]);     colorsArray.push(vertexColors[a]);     texCoordsArray.push(texCoord[0]);     normalsArray.push(normal);     pointsArray.push(vertices[b]);     colorsArray.push(vertexColors[a]);     texCoordsArray.push(texCoord[1]);     normalsArray.push(normal);     pointsArray.push(vertices[c]);     colorsArray.push(vertexColors[a]);     texCoordsArray.push(texCoord[2]);     normalsArray.push(normal);     pointsArray.push(vertices[a]);     colorsArray.push(vertexColors[a]);     texCoordsArray.push(texCoord[0]);     normalsArray.push(normal);     pointsArray.push(vertices[c]);     colorsArray.push(vertexColors[a]);     texCoordsArray.push(texCoord[2]);     normalsArray.push(normal);     pointsArray.push(vertices[d]);     colorsArray.push(vertexColors[a]);     texCoordsArray.push(texCoord[3]);     normalsArray.push(normal);}function colorCube(){    quad( 1, 0, 3, 2 );    quad( 2, 3, 7, 6 );    quad( 3, 0, 4, 7 );    quad( 6, 5, 1, 2 );    quad( 4, 5, 6, 7 );    quad( 5, 4, 0, 1 );}window.onload = function init() {    canvas = document.getElementById( gl-canvas );    gl = WebGLUtils.setupWebGL( canvas );    if ( !gl ) { alert( WebGL isn't available ); }    gl.viewport( 0, 0, canvas.width, canvas.height );    gl.clearColor( 1.0, 1.0, 1.0, 1.0 );    gl.enable(gl.DEPTH_TEST);    //    //  Load shaders and initialize attribute buffers    //    program = initShaders( gl, vertex-shader, fragment-shader );    gl.useProgram( program );    colorCube();    var nBuffer = gl.createBuffer();    gl.bindBuffer( gl.ARRAY_BUFFER, nBuffer );    gl.bufferData( gl.ARRAY_BUFFER, flatten(normalsArray), gl.STATIC_DRAW );    var vNormal = gl.getAttribLocation( program, vNormal );    gl.vertexAttribPointer( vNormal, 3, gl.FLOAT, false, 0, 0 );    gl.enableVertexAttribArray( vNormal );    var cBuffer = gl.createBuffer();    gl.bindBuffer( gl.ARRAY_BUFFER, cBuffer );    gl.bufferData( gl.ARRAY_BUFFER, flatten(colorsArray), gl.STATIC_DRAW );    var vColor = gl.getAttribLocation( program, vColor );    gl.vertexAttribPointer( vColor, 4, gl.FLOAT, false, 0, 0 );    gl.enableVertexAttribArray( vColor );    var vBuffer = gl.createBuffer();    gl.bindBuffer( gl.ARRAY_BUFFER, vBuffer);    gl.bufferData( gl.ARRAY_BUFFER, flatten(pointsArray), gl.STATIC_DRAW );    var vPosition = gl.getAttribLocation( program, vPosition );    gl.vertexAttribPointer( vPosition, 4, gl.FLOAT, false, 0, 0 );    gl.enableVertexAttribArray( vPosition );    var tBuffer = gl.createBuffer();    gl.bindBuffer( gl.ARRAY_BUFFER, tBuffer);    gl.bufferData( gl.ARRAY_BUFFER, flatten(texCoordsArray), gl.STATIC_DRAW );    var vTexCoord = gl.getAttribLocation( program, vTexCoord );    gl.vertexAttribPointer( vTexCoord, 2, gl.FLOAT, false, 0, 0 );    gl.enableVertexAttribArray( vTexCoord );    var dirAmbientProduct = mult(dirLightAmbient, materialAmbient);    var dirDiffuseProduct = mult(dirLightDiffuse, materialDiffuse);    var dirSpecularProduct = mult(dirLightSpecular, materialSpecular);    var posAmbientProduct = mult(posLightAmbient, materialAmbient);    var posDiffuseProduct = mult(posLightDiffuse, materialDiffuse);    var posSpecularProduct = mult(posLightSpecular, materialSpecular);    var spotAmbientProduct = mult(spotLightAmbient, materialAmbient);    var spotDiffuseProduct = mult(spotLightDiffuse, materialDiffuse);    var spotSpecularProduct = mult(spotLightSpecular, materialSpecular);    configureTexture();    gl.activeTexture( gl.TEXTURE0 );    gl.bindTexture( gl.TEXTURE_2D, texture1 );    gl.uniform1i(gl.getUniformLocation( program, Tex0), 0);    gl.activeTexture( gl.TEXTURE1 );    gl.bindTexture( gl.TEXTURE_2D, texture2 );    gl.uniform1i(gl.getUniformLocation( program, Tex1), 1);    thetaLoc = gl.getUniformLocation(program, theta);    gl.uniform4fv( gl.getUniformLocation(program,       dirAmbientProduct),flatten(dirAmbientProduct) );    gl.uniform4fv( gl.getUniformLocation(program,       posAmbientProduct),flatten(posAmbientProduct) );    gl.uniform4fv( gl.getUniformLocation(program,       spotAmbientProduct),flatten(spotAmbientProduct) );    gl.uniform4fv( gl.getUniformLocation(program,       dirDiffuseProduct),flatten(dirDiffuseProduct) );    gl.uniform4fv( gl.getUniformLocation(program,       posDiffuseProduct),flatten(posDiffuseProduct) );    gl.uniform4fv( gl.getUniformLocation(program,       spotDiffuseProduct),flatten(spotDiffuseProduct) );    gl.uniform4fv( gl.getUniformLocation(program,       dirSpecularProduct),flatten(dirSpecularProduct) );    gl.uniform4fv( gl.getUniformLocation(program,       posSpecularProduct),flatten(posSpecularProduct) );    gl.uniform4fv( gl.getUniformLocation(program,       spotSpecularProduct),flatten(spotSpecularProduct) );    gl.uniform4fv( gl.getUniformLocation(program,       posLightPosition),flatten(posLightPosition) );    gl.uniform4fv( gl.getUniformLocation(program,       dirLightPosition),flatten(dirLightPosition) );    gl.uniform4fv( gl.getUniformLocation(program,       spotLightPosition),flatten(spotLightPosition) );    gl.uniform1f( gl.getUniformLocation(program,       shininess),materialShininess );    gl.uniform1f( gl.getUniformLocation(program,       lCutOff),lCutOff );    gl.uniform1f( gl.getUniformLocation(program,       spotLightDirection),spotLightDirection ); document.getElementById(ButtonX).onclick = function(){axis = xAxis;}; document.getElementById(ButtonY).onclick = function(){axis = yAxis;}; document.getElementById(ButtonZ).onclick = function(){axis = zAxis;}; document.getElementById(ButtonT).onclick = function(){flag = !flag;};    render();}var render = function() {    gl.clear( gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);    if(flag) theta[axis] += 2.0;    gl.uniform3fv(thetaLoc, theta);    gl.drawArrays( gl.TRIANGLES, 0, numVertices );    requestAnimFrame(render);}So I computed tha angle between the spotlight direction and the vector to light source from vertex and if this angle is greater than the cutoff angle defined by the spotlight I compute the three products for the Phong lighting model.Where am I wrong?
WebGL Spotlight
lighting;webgl