Lab6

预览
taska页面链接
taskb页面链接
taskc(1)页面链接
taskc(2)页面链接

任务a. 绘制空间中的一个球,基本思路参照教材描述。利用单位圆内接正四面体,以递归方式构建一个球体

通过递归方式细分三角形,将每个三角形分成四个更小的三角形,并将顶点投影到单位球面上

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
function divideTriangle(a, b, c, n) {
if (n > 0) {
var ab = vec4.create();
vec4.lerp(ab, a, b, 0.5);
var abt = vec3.fromValues(ab[0], ab[1], ab[2]);
vec3.normalize(abt, abt);
vec4.set(ab, abt[0], abt[1], abt[2], 1.0);

var bc = vec4.create();
vec4.lerp(bc, b, c, 0.5);
var bct = vec3.fromValues(bc[0], bc[1], bc[2]);
vec3.normalize(bct, bct);
vec4.set(bc, bct[0], bct[1], bct[2], 1.0);

var ac = vec4.create();
vec4.lerp(ac, a, c, 0.5);
var act = vec3.fromValues(ac[0], ac[1], ac[2]);
vec3.normalize(act, act);
vec4.set(ac, act[0], act[1], act[2], 1.0);

divideTriangle(a, ab, ac, n - 1);
divideTriangle(ab, b, bc, n - 1);
divideTriangle(bc, c, ac, n - 1);
divideTriangle(ab, bc, ac, n - 1);
} else {
triangle(a, b, c);
}
}

球体线框模型如图:

taska页面链接


任务b. 以球体作为模型,实现Phong光照模型,其中各项参数自定

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
function initSphere() {
canvas = document.getElementById("gl-canvas");

gl = canvas.getContext("webgl2");
if (!gl) {
alert("WebGL isn't available");
}

gl.viewport(0, 0, canvas.width, canvas.width);
gl.clearColor(1.0, 1.0, 1.0, 1.0);

var program = initShaders(gl, "vertex-shader", "fragment-shader");
gl.useProgram(program);

vBuffer = gl.createBuffer();
nBuffer = gl.createBuffer();

divideTetra(va, vb, vc, vd, numOfSubdivides);
gl.bindBuffer(gl.ARRAY_BUFFER, vBuffer);
gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(points), gl.STATIC_DRAW);

vPosition = gl.getAttribLocation(program, "vPosition");
gl.vertexAttribPointer(vPosition, 4, gl.FLOAT, false, 0, 0);
gl.enableVertexAttribArray(vPosition);

gl.bindBuffer(gl.ARRAY_BUFFER, nBuffer);
gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(normals), gl.STATIC_DRAW);

vNormal = gl.getAttribLocation(program, "vNormal");
gl.vertexAttribPointer(vNormal, 3, gl.FLOAT, false, 0, 0);
gl.enableVertexAttribArray(vNormal);

modelViewMatrixLoc = gl.getUniformLocation(program, "modelViewMatrix");
projectionMatrixLoc = gl.getUniformLocation(program, "projectionMatrix");
var normalMatrixLoc = gl.getUniformLocation(program, "normalMatrix");

var ambientProduct = vec4.create();
vec4.multiply(ambientProduct, lightAmbient, materialAmbient);
var diffuseProduct = vec4.create();
vec4.multiply(diffuseProduct, lightDiffuse, materialDiffuse);
var specularProduct = vec4.create();
vec4.multiply(specularProduct, lightSpecular, materialSpecular);

gl.uniform4fv(gl.getUniformLocation(program, "ambientProduct"), ambientProduct);
gl.uniform4fv(gl.getUniformLocation(program, "diffuseProduct"), diffuseProduct);
gl.uniform4fv(gl.getUniformLocation(program, "specularProduct"), specularProduct);
gl.uniform4fv(gl.getUniformLocation(program, "lightPosition"), lightPosition);
gl.uniform1f(gl.getUniformLocation(program, "shininess"), materialShininess);

modelViewMatrix = mat4.create();
projectionMatrix = mat4.create();

document.onkeydown = handleKeyDown;
document.onkeyup = handleKeyUp;

render();
}

球体Phong光照模型如图:

taskb页面链接


任务c. 在Lab5实现的交互式模型展示功能基础上,添加Phong光照模型效果

  1. 实现对材质的环境光反射系数、漫反射系数、高光反射系数以及高光亮度系数的调节
  2. 实现对材质的颜色三个分量的选择
  3. 实现对光源位置的调节
  4. 实现对光源颜色三个分量的选择
  5. 实现了Gouraud Shading和Phong Shading的效果切换

在立方体Phong模型着色demo的基础上,添加了控件实现以上功能,效果图如下:

taskc(1)页面链接


最后这个模块做不出来,直接搬了示例代码

taskc(2)页面链接