Answered step by step
Verified Expert Solution
Question
1 Approved Answer
Write a webGL program that displays the graph of a bivariate function: z = f(x,y) for (x,y) in D = [0,1] X [0,1]. Use the
Write a webGL program that displays the graph of a bivariate function: z = f(x,y) for (x,y) in D = [0,1] X [0,1]. Use the following test function: f(x,y) = .5*exp[-.04*sqrt((80x-40)^2 + (90y-45)^2)] * cos[0.15*sqrt((80x-40)^2 + (90y-45)^2)] The following procedure creates the polygonal (triangle mesh) surface: partition D into a k+1 by k+1 uniform rectangular grid, and partition each of the k*k squares into a pair of triangles. Then call f to obtain a z value at each of the (k+1)^2 grid points. A reasonable value is k = 50. Use filled triangles with Gouraud shading and lighting. Note that each vertex normal must be computed by averaging the normals of the triangular faces that share the vertex. Use a depth buffer for hidden surface removal. A good template for this program is LightedCube_animation in Matsuda Chapter 8. It is sufficient to replace function initVertexBuffers to create typed arrays of vertex positions, colors, normals, and indices for the triangle mesh surface rather than a cube. Note, however, that the indices cannot be stored as 8-bit unsigned integers, and the third argument in function gl.drawElements must be changed from gl.UNSIGNED_BYTE to short or int.
Lightedcube_animation.js
// LightedCube_ambient.js (c) 2012 matsuda | ||||||||||||||||||||||||||||||||||||||
// Vertex shader program | ||||||||||||||||||||||||||||||||||||||
var VSHADER_SOURCE = | ||||||||||||||||||||||||||||||||||||||
'attribute vec4 a_Position; ' + | ||||||||||||||||||||||||||||||||||||||
'attribute vec4 a_Color; ' + | ||||||||||||||||||||||||||||||||||||||
'attribute vec4 a_Normal; ' + // Normal | ||||||||||||||||||||||||||||||||||||||
'uniform mat4 u_MvpMatrix; ' + | ||||||||||||||||||||||||||||||||||||||
'uniform vec3 u_DiffuseLight; ' + // Diffuse light color | ||||||||||||||||||||||||||||||||||||||
'uniform vec3 u_LightDirection; ' + // Diffuse light direction (in the world coordinate, normalized) | ||||||||||||||||||||||||||||||||||||||
'uniform vec3 u_AmbientLight; ' + // Color of an ambient light | ||||||||||||||||||||||||||||||||||||||
'varying vec4 v_Color; ' + | ||||||||||||||||||||||||||||||||||||||
'void main() { ' + | ||||||||||||||||||||||||||||||||||||||
' gl_Position = u_MvpMatrix * a_Position; ' + | ||||||||||||||||||||||||||||||||||||||
// Make the length of the normal 1.0 | ||||||||||||||||||||||||||||||||||||||
' vec3 normal = normalize(a_Normal.xyz); ' + | ||||||||||||||||||||||||||||||||||||||
// The dot product of the light direction and the normal (the orientation of a surface) | ||||||||||||||||||||||||||||||||||||||
' float nDotL = max(dot(u_LightDirection, normal), 0.0); ' + | ||||||||||||||||||||||||||||||||||||||
// Calculate the color due to diffuse reflection | ||||||||||||||||||||||||||||||||||||||
' vec3 diffuse = u_DiffuseLight * a_Color.rgb * nDotL; ' + | ||||||||||||||||||||||||||||||||||||||
// Calculate the color due to ambient reflection | ||||||||||||||||||||||||||||||||||||||
' vec3 ambient = u_AmbientLight * a_Color.rgb; ' + | ||||||||||||||||||||||||||||||||||||||
// Add the surface colors due to diffuse reflection and ambient reflection | ||||||||||||||||||||||||||||||||||||||
' v_Color = vec4(diffuse + ambient, a_Color.a); ' + | ||||||||||||||||||||||||||||||||||||||
'} '; | ||||||||||||||||||||||||||||||||||||||
// Fragment shader program | ||||||||||||||||||||||||||||||||||||||
var FSHADER_SOURCE = | ||||||||||||||||||||||||||||||||||||||
'#ifdef GL_ES ' + | ||||||||||||||||||||||||||||||||||||||
'precision mediump float; ' + | ||||||||||||||||||||||||||||||||||||||
'#endif ' + | ||||||||||||||||||||||||||||||||||||||
'varying vec4 v_Color; ' + | ||||||||||||||||||||||||||||||||||||||
'void main() { ' + | ||||||||||||||||||||||||||||||||||||||
' gl_FragColor = v_Color; ' + | ||||||||||||||||||||||||||||||||||||||
'} '; | ||||||||||||||||||||||||||||||||||||||
function main() { | ||||||||||||||||||||||||||||||||||||||
// Retrieve | ||||||||||||||||||||||||||||||||||||||
var canvas = document.getElementById('webgl'); | ||||||||||||||||||||||||||||||||||||||
// Get the rendering context for WebGL | ||||||||||||||||||||||||||||||||||||||
var gl = getWebGLContext(canvas); | ||||||||||||||||||||||||||||||||||||||
if (!gl) { | ||||||||||||||||||||||||||||||||||||||
console.log('Failed to get the rendering context for WebGL'); | ||||||||||||||||||||||||||||||||||||||
return; | ||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||
// Initialize shaders | ||||||||||||||||||||||||||||||||||||||
if (!initShaders(gl, VSHADER_SOURCE, FSHADER_SOURCE)) { | ||||||||||||||||||||||||||||||||||||||
console.log('Failed to intialize shaders.'); | ||||||||||||||||||||||||||||||||||||||
return; | ||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||
// | ||||||||||||||||||||||||||||||||||||||
var n = initVertexBuffers(gl); | ||||||||||||||||||||||||||||||||||||||
if (n < 0) { | ||||||||||||||||||||||||||||||||||||||
console.log('Failed to set the vertex information'); | ||||||||||||||||||||||||||||||||||||||
return; | ||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||
// Set the clear color and enable the depth test | ||||||||||||||||||||||||||||||||||||||
gl.clearColor(0, 0, 0, 1); | ||||||||||||||||||||||||||||||||||||||
gl.enable(gl.DEPTH_TEST); | ||||||||||||||||||||||||||||||||||||||
// Get the storage locations of uniform variables and so on | ||||||||||||||||||||||||||||||||||||||
var u_MvpMatrix = gl.getUniformLocation(gl.program, 'u_MvpMatrix'); | ||||||||||||||||||||||||||||||||||||||
var u_DiffuseLight = gl.getUniformLocation(gl.program, 'u_DiffuseLight'); | ||||||||||||||||||||||||||||||||||||||
var u_LightDirection = gl.getUniformLocation(gl.program, 'u_LightDirection'); | ||||||||||||||||||||||||||||||||||||||
var u_AmbientLight = gl.getUniformLocation(gl.program, 'u_AmbientLight'); | ||||||||||||||||||||||||||||||||||||||
if (!u_MvpMatrix || !u_DiffuseLight || !u_LightDirection || !u_AmbientLight) { | ||||||||||||||||||||||||||||||||||||||
console.log('Failed to get the storage location'); | ||||||||||||||||||||||||||||||||||||||
return; | ||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||
// Set the light color (white) | ||||||||||||||||||||||||||||||||||||||
gl.uniform3f(u_DiffuseLight, 1.0, 1.0, 1.0); | ||||||||||||||||||||||||||||||||||||||
// Set the light direction (in the world coordinate) | ||||||||||||||||||||||||||||||||||||||
var lightDirection = new Vector3([0.5, 3.0, 4.0]); | ||||||||||||||||||||||||||||||||||||||
lightDirection.normalize(); // Normalize | ||||||||||||||||||||||||||||||||||||||
gl.uniform3fv(u_LightDirection, lightDirection.elements); | ||||||||||||||||||||||||||||||||||||||
// Set the ambient light | ||||||||||||||||||||||||||||||||||||||
gl.uniform3f(u_AmbientLight, 0.2, 0.2, 0.2); | ||||||||||||||||||||||||||||||||||||||
// Calculate the view projection matrix | ||||||||||||||||||||||||||||||||||||||
var mvpMatrix = new Matrix4(); // Model view projection matrix | ||||||||||||||||||||||||||||||||||||||
mvpMatrix.setPerspective(30, canvas.width/canvas.height, 1, 100); | ||||||||||||||||||||||||||||||||||||||
mvpMatrix.lookAt(3, 3, 7, 0, 0, 0, 0, 1, 0); | ||||||||||||||||||||||||||||||||||||||
// Pass the model view projection matrix to the variable u_MvpMatrix | ||||||||||||||||||||||||||||||||||||||
gl.uniformMatrix4fv(u_MvpMatrix, false, mvpMatrix.elements); | ||||||||||||||||||||||||||||||||||||||
// Clear color and depth buffer | ||||||||||||||||||||||||||||||||||||||
gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT); | ||||||||||||||||||||||||||||||||||||||
// Draw the cube | ||||||||||||||||||||||||||||||||||||||
gl.drawElements(gl.TRIANGLES, n, gl.UNSIGNED_BYTE, 0); | ||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||
function initVertexBuffers(gl) { | ||||||||||||||||||||||||||||||||||||||
// Create a cube | ||||||||||||||||||||||||||||||||||||||
// v6----- v5 | ||||||||||||||||||||||||||||||||||||||
// /| /| | ||||||||||||||||||||||||||||||||||||||
// v1------v0| | ||||||||||||||||||||||||||||||||||||||
// | | | | | ||||||||||||||||||||||||||||||||||||||
// | |v7---|-|v4 | ||||||||||||||||||||||||||||||||||||||
// |/ |/ | ||||||||||||||||||||||||||||||||||||||
// v2------v3 | ||||||||||||||||||||||||||||||||||||||
// Coordinates | ||||||||||||||||||||||||||||||||||||||
var vertices = new Float32Array([ | ||||||||||||||||||||||||||||||||||||||
1.0, 1.0, 1.0, -1.0, 1.0, 1.0, -1.0,-1.0, 1.0, 1.0,-1.0, 1.0, // v0-v1-v2-v3 front | ||||||||||||||||||||||||||||||||||||||
1.0, 1.0, 1.0, 1.0,-1.0, 1.0, 1.0,-1.0,-1.0, 1.0, 1.0,-1.0, // v0-v3-v4-v5 right | ||||||||||||||||||||||||||||||||||||||
1.0, 1.0, 1.0, 1.0, 1.0,-1.0, -1.0, 1.0,-1.0, -1.0, 1.0, 1.0, // v0-v5-v6-v1 up | ||||||||||||||||||||||||||||||||||||||
-1.0, 1.0, 1.0, -1.0, 1.0,-1.0, -1.0,-1.0,-1.0, -1.0,-1.0, 1.0, // v1-v6-v7-v2 left | ||||||||||||||||||||||||||||||||||||||
-1.0,-1.0,-1.0, 1.0,-1.0,-1.0, 1.0,-1.0, 1.0, -1.0,-1.0, 1.0, // v7-v4-v3-v2 down | ||||||||||||||||||||||||||||||||||||||
1.0,-1.0,-1.0, -1.0,-1.0,-1.0, -1.0, 1.0,-1.0, 1.0, 1.0,-1.0 // v4-v7-v6-v5 back | ||||||||||||||||||||||||||||||||||||||
]); | ||||||||||||||||||||||||||||||||||||||
// Colors | ||||||||||||||||||||||||||||||||||||||
var colors = new Float32Array([ | ||||||||||||||||||||||||||||||||||||||
1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, // v0-v1-v2-v3 front | ||||||||||||||||||||||||||||||||||||||
1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, // v0-v3-v4-v5 right | ||||||||||||||||||||||||||||||||||||||
1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, // v0-v5-v6-v1 up | ||||||||||||||||||||||||||||||||||||||
1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, // v1-v6-v7-v2 left | ||||||||||||||||||||||||||||||||||||||
1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, // v7-v4-v3-v2 down | ||||||||||||||||||||||||||||||||||||||
1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0 // v4-v7-v6-v5 back | ||||||||||||||||||||||||||||||||||||||
]); | ||||||||||||||||||||||||||||||||||||||
// Normal | ||||||||||||||||||||||||||||||||||||||
var normals = new Float32Array([ | ||||||||||||||||||||||||||||||||||||||
0.0, 0.0, 1.0, 0.0, 0.0, 1.0, 0.0, 0.0, 1.0, 0.0, 0.0, 1.0, // v0-v1-v2-v3 front | ||||||||||||||||||||||||||||||||||||||
1.0, 0.0, 0.0, 1.0, 0.0, 0.0, 1.0, 0.0, 0.0, 1.0, 0.0, 0.0, // v0-v3-v4-v5 right | ||||||||||||||||||||||||||||||||||||||
0.0, 1.0, 0.0, 0.0, 1.0, 0.0, 0.0, 1.0, 0.0, 0.0, 1.0, 0.0, // v0-v5-v6-v1 up | ||||||||||||||||||||||||||||||||||||||
-1.0, 0.0, 0.0, -1.0, 0.0, 0.0, -1.0, 0.0, 0.0, -1.0, 0.0, 0.0, // v1-v6-v7-v2 left | ||||||||||||||||||||||||||||||||||||||
0.0,-1.0, 0.0, 0.0,-1.0, 0.0, 0.0,-1.0, 0.0, 0.0,-1.0, 0.0, // v7-v4-v3-v2 down | ||||||||||||||||||||||||||||||||||||||
0.0, 0.0,-1.0, 0.0, 0.0,-1.0, 0.0, 0.0,-1.0, 0.0, 0.0,-1.0 // v4-v7-v6-v5 back | ||||||||||||||||||||||||||||||||||||||
]); | ||||||||||||||||||||||||||||||||||||||
// Indices of the vertices | ||||||||||||||||||||||||||||||||||||||
var indices = new Uint8Array([ | ||||||||||||||||||||||||||||||||||||||
0, 1, 2, 0, 2, 3, // front | ||||||||||||||||||||||||||||||||||||||
4, 5, 6, 4, 6, 7, // right | ||||||||||||||||||||||||||||||||||||||
8, 9,10, 8,10,11, // up | ||||||||||||||||||||||||||||||||||||||
12,13,14, 12,14,15, // left | ||||||||||||||||||||||||||||||||||||||
16,17,18, 16,18,19, // down | ||||||||||||||||||||||||||||||||||||||
20,21,22, 20,22,23 // back | ||||||||||||||||||||||||||||||||||||||
]); | ||||||||||||||||||||||||||||||||||||||
// Write the vertex property to buffers (coordinates, colors and normals) | ||||||||||||||||||||||||||||||||||||||
if (!initArrayBuffer(gl, 'a_Position', vertices, 3)) return -1; | ||||||||||||||||||||||||||||||||||||||
if (!initArrayBuffer(gl, 'a_Color', colors, 3)) return -1; | ||||||||||||||||||||||||||||||||||||||
if (!initArrayBuffer(gl, 'a_Normal', normals, 3)) return -1; | ||||||||||||||||||||||||||||||||||||||
// Unbind the buffer object | ||||||||||||||||||||||||||||||||||||||
gl.bindBuffer(gl.ARRAY_BUFFER, null); | ||||||||||||||||||||||||||||||||||||||
// Write the indices to the buffer object | ||||||||||||||||||||||||||||||||||||||
var indexBuffer = gl.createBuffer(); | ||||||||||||||||||||||||||||||||||||||
if (!indexBuffer) { | ||||||||||||||||||||||||||||||||||||||
console.log('Failed to create the buffer object'); | ||||||||||||||||||||||||||||||||||||||
return false; | ||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||
gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, indexBuffer); | ||||||||||||||||||||||||||||||||||||||
gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, indices, gl.STATIC_DRAW); | ||||||||||||||||||||||||||||||||||||||
return indices.length; | ||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||
function initArrayBuffer(gl, attribute, data, num) { | ||||||||||||||||||||||||||||||||||||||
// Create a buffer object | ||||||||||||||||||||||||||||||||||||||
var buffer = gl.createBuffer(); | ||||||||||||||||||||||||||||||||||||||
if (!buffer) { | ||||||||||||||||||||||||||||||||||||||
console.log('Failed to create the buffer object'); | ||||||||||||||||||||||||||||||||||||||
return false; | ||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||
// Write date into the buffer object | ||||||||||||||||||||||||||||||||||||||
gl.bindBuffer(gl.ARRAY_BUFFER, buffer); | ||||||||||||||||||||||||||||||||||||||
gl.bufferData(gl.ARRAY_BUFFER, data, gl.STATIC_DRAW); | ||||||||||||||||||||||||||||||||||||||
// Assign the buffer object to the attribute variable | ||||||||||||||||||||||||||||||||||||||
var a_attribute = gl.getAttribLocation(gl.program, attribute); | ||||||||||||||||||||||||||||||||||||||
if (a_attribute < 0) { | ||||||||||||||||||||||||||||||||||||||
console.log('Failed to get the storage location of ' + attribute); | ||||||||||||||||||||||||||||||||||||||
return false; | ||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||
gl.vertexAttribPointer(a_attribute, num, gl.FLOAT, false, 0, 0); | ||||||||||||||||||||||||||||||||||||||
// Enable the assignment of the buffer object to the attribute variable | ||||||||||||||||||||||||||||||||||||||
gl.enableVertexAttribArray(a_attribute); | ||||||||||||||||||||||||||||||||||||||
return true; | ||||||||||||||||||||||||||||||||||||||
} LightedCube_animation.html
|
Step by Step Solution
There are 3 Steps involved in it
Step: 1
Get Instant Access to Expert-Tailored Solutions
See step-by-step solutions with expert insights and AI powered tools for academic success
Step: 2
Step: 3
Ace Your Homework with AI
Get the answers you need in no time with our AI-driven, step-by-step assistance
Get Started