diff --git a/lab4/src/lab4.js b/lab4/src/lab4.js index 87c4822e49a12a4a157f254e5bf3a36a0481c351..ac88cf40853f2962b85b47939a4b46190e136b28 100644 --- a/lab4/src/lab4.js +++ b/lab4/src/lab4.js @@ -23,21 +23,21 @@ const VSHADER_SOURCE = // TODO: Implement your vertex shader code here 'attribute vec3 a_Position;\n' + 'attribute vec3 a_Normal;\n' + - 'attribute vec4 a_Color_tmp;\n' + + //'attribute vec4 a_Color_tmp;\n' + 'uniform mat4 u_View;\n' + 'uniform mat4 u_Projection;\n' + 'uniform mat4 u_Model;\n' + 'uniform mat4 u_MvpMatrixFromLight;\n' + - 'varying vec4 v_Color;\n' + + //'varying vec4 v_Color;\n' + 'varying vec3 v_Vertex;\n' + 'varying vec3 v_Normal;\n' + 'varying vec4 v_PositionFromLight;\n' + 'void main() {\n' + - ' v_Color = a_Color_tmp;\n' + + //' v_Color = u_Color;\n' + ' v_Vertex = vec3(u_View * u_Model * vec4(a_Position, 1.0));\n' + ' v_Normal = vec3(u_View * u_Model * vec4(a_Normal, 0.0));\n' + @@ -59,9 +59,11 @@ const FSHADER_SOURCE = 'uniform vec3 u_Light_position;\n' + 'uniform float u_Directionnel;\n' + 'uniform sampler2D u_ShadowMap;\n' + + 'uniform float u_Clicked;\n' + + 'uniform vec4 u_Color;\n' + // TODO: Implement your fragment shader code here - 'varying vec4 v_Color;\n' + + //'varying vec4 v_Color;\n' + 'varying vec3 v_Vertex;\n' + 'varying vec3 v_Normal;\n' + 'varying vec4 v_PositionFromLight;\n' + @@ -80,70 +82,75 @@ const FSHADER_SOURCE = ' vec3 color;\n' + ' float d;\n' + ' float attenuation;\n' + + ' vec4 color_tmp;\n' + ' vec3 shadowCoord = (v_PositionFromLight.xyz/v_PositionFromLight.w)/2.0 + 0.5;\n' + ' vec4 rgbaDepth = texture2D(u_ShadowMap, shadowCoord.xy);\n' + ' float depth = rgbaDepth.r;\n' + // Retrieve the z-value from R ' float visibility = (shadowCoord.z > depth + 0.005) ? 0.6 : 1.0;\n' + + ' if(u_Clicked > 0.5) {\n' + + ' gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0);\n' + + ' } else {\n' + - ' ambient_color = vec3(0.0, 0.0, 0.0);\n' + - ' light_color = vec3(1.0, 1.0, 1.0);\n' + - ' shininess = 10.0;\n' + + ' ambient_color = vec3(0.0, 0.0, 0.0);\n' + + ' light_color = vec3(1.0, 1.0, 1.0);\n' + + ' shininess = 10.0;\n' + // Calculate the ambient color as a percentage of the surface color - ' ambient_color = ambient_color * vec3(v_Color);\n' + + ' ambient_color = ambient_color * vec3(u_Color);\n' + // Calculate a vector from the fragment location to the light source - ' if(u_Directionnel > 0.5) {\n' + - ' to_light = normalize(u_Light_position + v_Vertex);\n' + - ' } else {\n' + - ' to_light = normalize(u_Light_position - v_Vertex);\n' + - ' }\n' + + ' if(u_Directionnel > 0.5) {\n' + + ' to_light = normalize(u_Light_position + v_Vertex);\n' + + ' } else {\n' + + ' to_light = normalize(u_Light_position - v_Vertex);\n' + + ' }\n' + // The vertex's normal vector is being interpolated across the primitive // which can make it un-normalized. So normalize the vertex's normal vector. - ' vertex_normal = normalize(v_Normal);\n' + + ' vertex_normal = normalize(v_Normal);\n' + // Calculate the cosine of the angle between the vertex's normal vector // and the vector going to the light. - ' cos_angle = dot(vertex_normal, to_light);\n' + - ' cos_angle = clamp(cos_angle, 0.0, 1.0);\n' + + ' cos_angle = dot(vertex_normal, to_light);\n' + + ' cos_angle = clamp(cos_angle, 0.0, 1.0);\n' + // Scale the color of this fragment - ' diffuse_color = vec3(v_Color) * cos_angle; \n' + + ' diffuse_color = vec3(u_Color) * cos_angle; \n' + // Calculate the reflection vector - ' reflection = 2.0 * dot(vertex_normal, to_light) * vertex_normal - to_light;\n' + + ' reflection = 2.0 * dot(vertex_normal, to_light) * vertex_normal - to_light;\n' + // Calculate a vector from fragment location to the camera. // The camera is at the origin, so negating the vertex location gives the vector - ' to_camera = -1.0 * v_Vertex;\n' + + ' to_camera = -1.0 * v_Vertex;\n' + // Calculate the cosine of the angle between the reflection vector // and the vector going to the camera. - ' reflection = normalize(reflection);\n' + - ' to_camera = normalize(to_camera);\n' + - ' cos_angle = dot(reflection, to_camera);\n' + - ' cos_angle = clamp(cos_angle, 0.0, 1.0);\n' + - ' cos_angle = pow(cos_angle, shininess);\n' + + ' reflection = normalize(reflection);\n' + + ' to_camera = normalize(to_camera);\n' + + ' cos_angle = dot(reflection, to_camera);\n' + + ' cos_angle = clamp(cos_angle, 0.0, 1.0);\n' + + ' cos_angle = pow(cos_angle, shininess);\n' + // The specular color is from the light source, not the object - ' if(cos_angle > 0.0) {\n' + - ' specular_color = light_color * cos_angle;\n' + - ' diffuse_color = diffuse_color * (1.0 - cos_angle);\n' + - ' } else {\n' + - ' specular_color = vec3(0.0, 0.0, 0.0);\n' + - ' }\n' + + ' if(cos_angle > 0.0) {\n' + + ' specular_color = light_color * cos_angle;\n' + + ' diffuse_color = diffuse_color * (1.0 - cos_angle);\n' + + ' } else {\n' + + ' specular_color = vec3(0.0, 0.0, 0.0);\n' + + ' }\n' + //Atténuation - ' to_light = u_Light_position - v_Vertex;\n' + - ' d = length(to_light);\n' + - ' attenuation = clamp(10.0 / d, 0.0, 1.0);\n' + + ' to_light = u_Light_position - v_Vertex;\n' + + ' d = length(to_light);\n' + + ' attenuation = clamp(10.0 / d, 0.0, 1.0);\n' + - ' color = attenuation * (ambient_color + diffuse_color + specular_color);\n' + - //' color = (ambient_color + diffuse_color + specular_color);\n' + - ' gl_FragColor = vec4(color.rgb * visibility, v_Color.a);\n' + + ' color = attenuation * (ambient_color + diffuse_color + specular_color);\n' + + //' color = attenuation * (ambient_color + u_Color.rgb);\n' + + ' gl_FragColor = vec4(color.rgb * visibility, u_Color.a);\n' + + ' }\n' + '}\n' + '\n'; @@ -246,13 +253,13 @@ const vertices = new Float32Array([ // This is the model const verticesSurface = new Float32Array([ - 100, -4/7, 100, 1.0, 1.0, 1.0, 1.0, 0.0, 1.0, 0.0, - 100, -4/7, -100, 1.0, 1.0, 1.0, 1.0, 0.0, 1.0, 0.0, - -100, -4/7, 100, 1.0, 1.0, 1.0, 1.0, 0.0, 1.0, 0.0, + 100, -6/7, 100, 1.0, 1.0, 1.0, 1.0, 0.0, 1.0, 0.0, + 100, -6/7, -100, 1.0, 1.0, 1.0, 1.0, 0.0, 1.0, 0.0, + -100, -6/7, 100, 1.0, 1.0, 1.0, 1.0, 0.0, 1.0, 0.0, - 100, -4/7, -100, 1.0, 1.0, 1.0, 1.0, 0.0, 1.0, 0.0, - -100, -4/7, 100, 1.0, 1.0, 1.0, 1.0, 0.0, 1.0, 0.0, - -100, -4/7, -100, 1.0, 1.0, 1.0, 1.0, 0.0, 1.0, 0.0, + 100, -6/7, -100, 1.0, 1.0, 1.0, 1.0, 0.0, 1.0, 0.0, + -100, -6/7, 100, 1.0, 1.0, 1.0, 1.0, 0.0, 1.0, 0.0, + -100, -6/7, -100, 1.0, 1.0, 1.0, 1.0, 0.0, 1.0, 0.0, ]); var OFFSCREEN_WIDTH = 2048, OFFSCREEN_HEIGHT = 2048; @@ -295,15 +302,16 @@ function drawShadowSurface(gl, program, surface, viewMatrix, projectionMatrix, m } -function drawFrustum(gl, program, frustum, viewMatrix, projectionMatrix, modelMatrix, light, shadow) { +function drawFrustum(gl, program, frustum, viewMatrix, projectionMatrix, modelMatrix, light, shadow, clicked, color) { gl.useProgram(program); gl.uniform1i(program.u_ShadowMap, 0); initAttributeVariable(gl, program.a_Position, frustum.buffer, 3, 10*4, 0); initAttributeVariable(gl, program.a_Color, frustum.buffer, 4, 10*4, 3*4); initAttributeVariable(gl, program.a_Normal, frustum.buffer, 3, 10*4, 7*4); - + // Color + gl.uniform4fv(program.u_Color, color); // Light gl.uniform3fv(program.u_Light_position, light.position.elements); @@ -314,7 +322,8 @@ function drawFrustum(gl, program, frustum, viewMatrix, projectionMatrix, modelMa gl.uniformMatrix4fv(program.u_Projection, false, projectionMatrix.elements); gl.uniformMatrix4fv(program.u_Model, false, modelMatrix.elements); gl.uniformMatrix4fv(program.u_MvpMatrixFromLight, false, shadow.mvpMatrixFromLight_f.elements); - + + gl.uniform1f(program.u_Clicked, clicked); // Draw the rectangle gl.drawArrays(gl.TRIANGLES, 0, frustum.numberIndices); @@ -322,13 +331,16 @@ function drawFrustum(gl, program, frustum, viewMatrix, projectionMatrix, modelMa } -function drawSurface(gl, program, surface, viewMatrix, projectionMatrix, modelMatrix, light, shadow) { +function drawSurface(gl, program, surface, viewMatrix, projectionMatrix, modelMatrix, light, shadow, color) { gl.useProgram(program); gl.uniform1i(program.u_ShadowMap, 0); initAttributeVariable(gl, program.a_Position, surface.buffer, 3, 10*4, 0); initAttributeVariable(gl, program.a_Color, surface.buffer, 4, 10*4, 3*4); initAttributeVariable(gl, program.a_Normal, surface.buffer, 3, 10*4, 7*4); + + // Color + gl.uniform4fv(program.u_Color, color); // Pass the rotation matrix to the vertex shader gl.uniformMatrix4fv(program.u_View, false, viewMatrix.elements); @@ -340,6 +352,8 @@ function drawSurface(gl, program, surface, viewMatrix, projectionMatrix, modelMa gl.uniform3fv(program.u_Light_position, light.position.elements); gl.uniform1f(program.u_Directionnel, light.directionnel); + gl.uniform1f(program.u_Clicked, 0); + // Draw the rectangle gl.drawArrays(gl.TRIANGLES, 0, surface.numberIndices); @@ -451,6 +465,44 @@ function initFramebufferObject(gl) { return framebuffer; } +function drawScene(gl, canvas, fbo, program, shadowProgram, frustum, surface, projectionMatrix, light, shadow) { + gl.bindFramebuffer(gl.FRAMEBUFFER, fbo); // Change the drawing destination to FBO + + gl.viewport(0, 0, OFFSCREEN_HEIGHT, OFFSCREEN_HEIGHT); // Set view port for FBO + + gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT); // Clear FBO + + // Draw the triangle and the plane (for generating a shadow map) + drawShadowFrustum(gl, shadowProgram, frustum.vertex, frustum.viewMatrix, projectionMatrix, frustum.modelMatrix, shadow); + drawShadowSurface(gl, shadowProgram, surface.vertex, surface.viewMatrix, projectionMatrix, surface.modelMatrix, shadow); + + + gl.bindFramebuffer(gl.FRAMEBUFFER, null); // Change the drawing destination to color buffer + + gl.viewport(0, 0, canvas.width, canvas.height); + + gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT); // Clear color and depth buffer + + drawFrustum(gl, program, frustum.vertex, frustum.viewMatrix, projectionMatrix, frustum.modelMatrix, light, shadow, 0, frustum.color); + drawSurface(gl, program, surface.vertex, surface.viewMatrix, projectionMatrix, surface.modelMatrix, light, shadow, surface.color); +} + +// must call drawScene after its usage +function check(x, y, gl, fbo, program, frustum, projectionMatrix, light, shadow) { + let picked = false; + + drawFrustum(gl, program, frustum.vertex, frustum.viewMatrix, projectionMatrix, frustum.modelMatrix, light, shadow, 1, [1.0, 0.0, 0.0, 1.0]); + + // Read pixel at the clicked position + let pixels = new Uint8Array(4); // Array for storing the pixel value y, 1, 1, gl.RGBA, gl.UNSIGNED_BYTE, pixels); + gl.readPixels(x, y, 1, 1, gl.RGBA, gl.UNSIGNED_BYTE, pixels); + + if (pixels[0] == 255 && pixels[1] == 0 && pixels[2] == 0 && pixels[3] == 255) // The mouse in on frustume + picked = true; + + return picked; +} + function main() { // Retrieve <canvas> element const canvas = document.getElementById('my-canvas'); @@ -487,11 +539,11 @@ function main() { } //Colors - program.a_Color = gl.getAttribLocation(program, 'a_Color_tmp'); - if (program.a_Color < 0) { - console.log('Failed to get the storage location of a_Color_tmp'); - return -1; - } + // program.a_Color = gl.getAttribLocation(program, 'a_Color_tmp'); + // if (program.a_Color < 0) { + // console.log('Failed to get the storage location of a_Color_tmp'); + // return -1; + // } // Get storage location of u_View program.u_View = gl.getUniformLocation(program, 'u_View'); @@ -543,6 +595,18 @@ function main() { return; } + program.u_Clicked = gl.getUniformLocation(program, 'u_Clicked'); + if (program.u_Clicked < 0) { + console.log('Failed to get the storage location of attribute or uniform variable from u_ShadowMap'); + return; + } + + program.u_Color = gl.getUniformLocation(program, 'u_Color'); + if (program.u_Color < 0) { + console.log('Failed to get the storage location of attribute or uniform variable from u_ShadowMap'); + return; + } + // Initialize framebuffer object (FBO) var fbo = initFramebufferObject(gl); if (!fbo) { @@ -557,37 +621,37 @@ function main() { gl.clearColor(0, 0, 0, 1); gl.enable(gl.DEPTH_TEST); + let frustum = new Object(); + let surface = new Object(); // Write the positions of vertices to a vertex shader - var frustum = initVertexBuffers(gl, program, vertices); + frustum.vertex = initVertexBuffers(gl, program, vertices); // Write the positions of vertices to a vertex shader - var surface = initVertexBuffers(gl, program, verticesSurface); - - - - // Clear <canvas> - //gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT); + surface.vertex = initVertexBuffers(gl, program, verticesSurface); // Model matrix - let viewMatrix_Frustum = new Matrix4(); - // Model matrix - let viewMatrix_Surface = new Matrix4(); + frustum.viewMatrix = new Matrix4(); + surface.viewMatrix = new Matrix4(); + let projectionMatrix = new Matrix4(); - let modelMatrix_Frustum = new Matrix4(); - let modelMatrix_Surface = new Matrix4(); + frustum.modelMatrix = new Matrix4(); + surface.modelMatrix = new Matrix4(); // Light let light = new Object(); + light.init = [0.0, 1.0, -2.0]; light.position = new Vector3([0.0, 1.0, -2.0]); light.directionnel = 0.0; // Set the rotation matrix projectionMatrix.setPerspective(40, 1, 0.1, 10); // 1, 0, -3 - viewMatrix_Frustum.setLookAt(1, 2, -3, 0, 0, 0, 0, 1, 0); - viewMatrix_Surface.setLookAt(1, 2, -3, 0, 0, 0, 0, 1, 0); + let initCamera = [1, 2, -3]; + + frustum.viewMatrix.setLookAt(initCamera[0], initCamera[1], initCamera[2], 0, 0, 0, 0, 1, 0); + surface.viewMatrix.setLookAt(initCamera[0], initCamera[1], initCamera[2], 0, 0, 0, 0, 1, 0); let shadow = new Object(); shadow.viewProjMatrixFromLight = new Matrix4(); @@ -598,47 +662,47 @@ function main() { shadow.mvpMatrixFromLight_f = new Matrix4(); shadow.mvpMatrixFromLight_s = new Matrix4(); - gl.bindFramebuffer(gl.FRAMEBUFFER, fbo); // Change the drawing destination to FBO - - gl.viewport(0, 0, OFFSCREEN_HEIGHT, OFFSCREEN_HEIGHT); // Set view port for FBO - - gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT); // Clear FBO - - // Draw the triangle and the plane (for generating a shadow map) - drawShadowFrustum(gl, shadowProgram, frustum, viewMatrix_Frustum, projectionMatrix, modelMatrix_Frustum, shadow); - - drawShadowSurface(gl, shadowProgram, surface, viewMatrix_Surface, projectionMatrix, modelMatrix_Surface, shadow); - + frustum.color = [1.0, 0.0, 0.0, 1.0]; + surface.color = [1.0, 1.0, 1.0, 1.0]; - gl.bindFramebuffer(gl.FRAMEBUFFER, null); // Change the drawing destination to color buffer - - gl.viewport(0, 0, canvas.width, canvas.height); - - gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT); // Clear color and depth buffer - - drawFrustum(gl, program, frustum, viewMatrix_Frustum, projectionMatrix, modelMatrix_Frustum, light, shadow); - - drawSurface(gl, program, surface, viewMatrix_Surface, projectionMatrix, modelMatrix_Surface, light, shadow); + let clicked = 0; + drawScene(gl, canvas, fbo, program, shadowProgram, frustum, surface, projectionMatrix, light, shadow) var onCanvas = false; + let newX; let newY; let newZ; let position_x = document.getElementById("position-x"); let position_y = document.getElementById("position-y"); - position_x.value = 0.0; - position_y.value = 0.0; - - canvas.addEventListener("mousedown", function(e) { - onCanvas = true; + position_x.value = light.init[0]; + position_y.value = light.init[1]; + + canvas.addEventListener("mousedown", function(event) { + let x = event.clientX, y = event.clientY; + let rect = event.target.getBoundingClientRect(); + if (rect.left <= x && x < rect.right && rect.top <= y && y < rect.bottom) { + // If pressed position is inside <canvas>, check if it is above object + let x_in_canvas = x - rect.left, y_in_canvas = rect.bottom - y; + let picked = check(x_in_canvas, y_in_canvas, gl, fbo, program, frustum, projectionMatrix, light, shadow) + drawScene(gl, canvas, fbo, program, shadowProgram, frustum, surface, projectionMatrix, light, shadow) + if(picked) { + //change color + frustum.color = frustum.color[0] == 1.0 ? [0.0, 0.0, 1.0, 1.0] : [1.0, 0.0, 0.0, 1.0]; + drawScene(gl, canvas, fbo, program, shadowProgram, frustum, surface, projectionMatrix, light, shadow) + } else { + onCanvas = true; // si c'est pas un click sur le frustum on effectue une rotation de la camera normal + } + } }); canvas.addEventListener("mouseup", function(e) { onCanvas = false; }); - canvas.addEventListener("mousemove", function(e) { + canvas.addEventListener("mousemove", function(event) { + if(onCanvas) { bounds = canvas.getBoundingClientRect(); let x = (event.clientX - bounds.left - canvas.clientLeft)/canvas.width; @@ -651,32 +715,10 @@ function main() { gl.enable(gl.DEPTH_TEST); // Set the rotation matrix - viewMatrix_Frustum.setLookAt(newX, newY, newZ, 0, 0, 0, 0, 1, 0); - viewMatrix_Surface.setLookAt(newX, newY, newZ, 0, 0, 0, 0, 1, 0); - - // Clear <canvas> - gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT); - - - - gl.bindFramebuffer(gl.FRAMEBUFFER, fbo); // Change the drawing destination to FBO - gl.viewport(0, 0, OFFSCREEN_HEIGHT, OFFSCREEN_HEIGHT); // Set view port for FBO - gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT); // Clear FBO - - // Draw the triangle and the plane (for generating a shadow map) - drawShadowFrustum(gl, shadowProgram, frustum, viewMatrix_Frustum, projectionMatrix, modelMatrix_Frustum, shadow); - drawShadowSurface(gl, shadowProgram, surface, viewMatrix_Surface, projectionMatrix, modelMatrix_Surface, shadow); - - gl.bindFramebuffer(gl.FRAMEBUFFER, null); // Change the drawing destination to color buffer - gl.viewport(0, 0, canvas.width, canvas.height); - - gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT); // Clear FBO - - - drawFrustum(gl, program, frustum, viewMatrix_Frustum, projectionMatrix, modelMatrix_Frustum, light, shadow); - - drawSurface(gl, program, surface, viewMatrix_Surface, projectionMatrix, modelMatrix_Surface, light, shadow); + frustum.viewMatrix.setLookAt(newX, newY, newZ, 0, 0, 0, 0, 1, 0); + surface.viewMatrix.setLookAt(newX, newY, newZ, 0, 0, 0, 0, 1, 0); + drawScene(gl, canvas, fbo, program, shadowProgram, frustum, surface, projectionMatrix, light, shadow) } }); @@ -684,43 +726,43 @@ function main() { switch(e.key) { case "ArrowUp": let up = light.position.elements[1] + 0.1; - if(up <= 1) { + if(up <= 1 + light.init[1]) { position_y.value = up.toFixed(2); light.position.elements[1] = up; + shadow.viewProjMatrixFromLight.setPerspective(70, OFFSCREEN_WIDTH/OFFSCREEN_HEIGHT, 1.0, 100.0); + shadow.viewProjMatrixFromLight.lookAt(light.position.elements[0], light.position.elements[1], light.position.elements[2], 0.0, 0.0, 0.0, 0.0, 1.0, 0.0); } - gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT); - drawSurface(gl, programSurface, surface, viewMatrix_Surface, projectionMatrix, modelMatrix_Surface, light); - drawFrustum(gl, program, frustum, viewMatrix_Frustum, projectionMatrix, modelMatrix_Frustum, light); + drawScene(gl, canvas, fbo, program, shadowProgram, frustum, surface, projectionMatrix, light, shadow) break; case "ArrowDown": let down = light.position.elements[1] - 0.1; - if(down >= -1) { + if(down >= - 1 + light.init[1]) { position_y.value = down.toFixed(2); light.position.elements[1] = down; + shadow.viewProjMatrixFromLight.setPerspective(70, OFFSCREEN_WIDTH/OFFSCREEN_HEIGHT, 1.0, 100.0); + shadow.viewProjMatrixFromLight.lookAt(light.position.elements[0], light.position.elements[1], light.position.elements[2], 0.0, 0.0, 0.0, 0.0, 1.0, 0.0); } - gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT); - drawSurface(gl, programSurface, surface, viewMatrix_Surface, projectionMatrix, modelMatrix_Surface, light); - drawFrustum(gl, program, frustum, viewMatrix_Frustum, projectionMatrix, modelMatrix_Frustum, light); + drawScene(gl, canvas, fbo, program, shadowProgram, frustum, surface, projectionMatrix, light, shadow) break; case "ArrowRight": let right = light.position.elements[0] + 0.1; - if(right <= 1) { + if(right <= 1 + light.init[0]) { position_x.value = right.toFixed(2); light.position.elements[0] = right; + shadow.viewProjMatrixFromLight.setPerspective(70, OFFSCREEN_WIDTH/OFFSCREEN_HEIGHT, 1.0, 100.0); + shadow.viewProjMatrixFromLight.lookAt(light.position.elements[0], light.position.elements[1], light.position.elements[2], 0.0, 0.0, 0.0, 0.0, 1.0, 0.0); } - gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT); - drawSurface(gl, programSurface, surface, viewMatrix_Surface, projectionMatrix, modelMatrix_Surface, light); - drawFrustum(gl, program, frustum, viewMatrix_Frustum, projectionMatrix, modelMatrix_Frustum, light); + drawScene(gl, canvas, fbo, program, shadowProgram, frustum, surface, projectionMatrix, light, shadow) break; case "ArrowLeft": let left = light.position.elements[0] - 0.1; - if(left >= -1) { + if(left >= -1 + light.init[0]) { position_x.value = left.toFixed(2); light.position.elements[0] = left; + shadow.viewProjMatrixFromLight.setPerspective(70, OFFSCREEN_WIDTH/OFFSCREEN_HEIGHT, 1.0, 100.0); + shadow.viewProjMatrixFromLight.lookAt(light.position.elements[0], light.position.elements[1], light.position.elements[2], 0.0, 0.0, 0.0, 0.0, 1.0, 0.0); } - gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT); - drawSurface(gl, programSurface, surface, viewMatrix_Surface, projectionMatrix, modelMatrix_Surface, light); - drawFrustum(gl, program, frustum, viewMatrix_Frustum, projectionMatrix, modelMatrix_Frustum, light); + drawScene(gl, canvas, fbo, program, shadowProgram, frustum, surface, projectionMatrix, light, shadow) break; default: } @@ -730,30 +772,8 @@ function main() { for(let i = 0; i < directionnels_radio.length; i++) { directionnels_radio[i].addEventListener("click", function() { light.directionnel = this.value; - gl.bindFramebuffer(gl.FRAMEBUFFER, fbo); // Change the drawing destination to FBO - - gl.viewport(0, 0, OFFSCREEN_HEIGHT, OFFSCREEN_HEIGHT); // Set view port for FBO - - gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT); // Clear FBO - - // Draw the triangle and the plane (for generating a shadow map) - drawShadowFrustum(gl, shadowProgram, frustum, viewMatrix_Frustum, projectionMatrix, modelMatrix_Frustum, shadow); - - drawShadowSurface(gl, shadowProgram, surface, viewMatrix_Surface, projectionMatrix, modelMatrix_Surface, shadow); - - - gl.bindFramebuffer(gl.FRAMEBUFFER, null); // Change the drawing destination to color buffer - - gl.viewport(0, 0, canvas.width, canvas.height); - - gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT); // Clear color and depth buffer - - - - drawSurface(gl, program, surface, viewMatrix_Surface, projectionMatrix, modelMatrix_Surface, light, shadow); - - drawFrustum(gl, program, frustum, viewMatrix_Frustum, projectionMatrix, modelMatrix_Frustum, light, shadow); + drawScene(gl, canvas, fbo, program, shadowProgram, frustum, surface, projectionMatrix, light, shadow) }); } }