# 未命名

Luz3周前 (01-05)实验87

了解简单光照明模型的基本原理；

掌握简单光照明模型的计算方法；

根据WebGL光照示范代码，实现简单物体的光照效果。

(1) 示范代码为立方体在一束平行光照射下的漫反射光照效果。结合所给示范代码，学习掌握简单光照明模型的基本原理与算法实现；

(2) 修改示范代码，给出不同光照参数和立方体位置，观察与验证光照效果；

(3) 示范代码仅有漫反射光的光照效果，请尝试为其添加环境反射光和镜面反射光效果。







（关键代码）

var gl;

function startup(){

var canvas =

document.getElementById('myGLCanvas');//获取<canvas>元素

gl = createGLContext(canvas);

var n = initVertexBuffers(gl);

if (n < 0) {

console.log('Failed to set the positions of the vertices');

return;

}

gl.clearColor(0.8, 0.8, 0.8, 1.0);

gl.enable(gl.DEPTH_TEST);

var u_MvpMatrix =

gl.getUniformLocation(gl.program, 'u_MvpMatrix');

var u_LightColor =

gl.getUniformLocation(gl.program, 'u_LightColor');

var u_LightDirection =

gl.getUniformLocation(gl.program, 'u_LightDirection');

if (!u_MvpMatrix || !u_LightColor || !u_LightDirection) {

console.log('Failed to get the storage location');   return;

}

gl.uniform3f(u_LightColor, 1.0, 1.0, 1.0); // Set the light color (white)

var lightDirection =

vec3.fromValues(-0.5, 1, 1);

vec3.normalize(lightDirection,lightDirection); // Normalize

gl.uniform3fv(u_LightDirection, lightDirection);

var eye = vec3.fromValues(0.0, 0.0, 5.0);

var center = vec3.fromValues(0.0, 0.0, 0.0);

var up = vec3.fromValues(0.0, 1.0, 0.0);

var vMatrix = mat4.create();

mat4.lookAt(vMatrix, eye, center, up);

// Model Matrix

var mMatrix = mat4.create();

mat4.scale(mMatrix, mMatrix, [1.0, 1.0, 1.0]);

mat4.rotate(mMatrix, mMatrix,

Math.PI/4, [0.0, 1.0, 0.0]);

var pMatrix = mat4.create();

mat4.frustum(pMatrix, -1.0, 1.0, -1.0, 1.0, 1.5, 20.0);

var mvpMatrix = mat4.create();

mat4.multiply(mvpMatrix, vMatrix,

mMatrix);

mat4.multiply(mvpMatrix, pMatrix,

mvpMatrix);

gl.uniformMatrix4fv(u_MvpMatrix, false, mvpMatrix);

gl.drawElements(gl.TRIANGLES, n,

gl.UNSIGNED_BYTE, 0);

}

// 立方体绘制

function initVertexBuffers(gl) {

// Create a cube

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,  1.0, 1.0, 1.0,  1.0,-1.0, 1.0,

1.0,-1.0,-1.0,  1.0, 1.0,-1.0, 1.0,1.0,1.0,

1.0, 1.0,-1.0, -1.0, 1.0,-1.0, -1.0, 1.0, 1.0,

-1.0, 1.0, 1.0,-1.0, 1.0,-1.0,  -1.0,-1.0,-1.0,

-1.0,-1.0,1.0,-1.0,-1.0,-1.0,   1.0,-1.0,-1.0,

1.0,-1.0,1.0,-1.0,-1.0,1.0, 1.0,-1.0,-1.0,

-1.0,-1.0,-1.0,-1.0, 1.0,-1.0,1.0, 1.0,-1.0

]);

var colors = new Float32Array([

1, 0, 0,   1, 0, 0,   1, 0, 0,  1, 0, 0,

1, 0, 0,   1, 0, 0,   1, 0, 0,  1, 0, 0,

1, 0, 0,   1, 0, 0,   1, 0, 0,  1, 0, 0,

1, 0, 0,   1, 0, 0,   1, 0, 0,  1, 0, 0,

1, 0, 0,   1, 0, 0,   1, 0, 0,  1, 0, 0,

1, 0, 0,   1, 0, 0,   1, 0, 0,  1, 0, 0

]);

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,

1.0, 0.0, 0.0,   1.0, 0.0, 0.0,

1.0, 0.0, 0.0,   1.0, 0.0, 0.0,

0.0, 1.0, 0.0,   0.0, 1.0, 0.0,

0.0, 1.0, 0.0,   0.0, 1.0, 0.0,

-1.0, 0.0, 0.0,  -1.0, 0.0, 0.0,

-1.0, 0.0, 0.0,  -1.0, 0.0, 0.0,

0.0,-1.0, 0.0,   0.0,-1.0, 0.0,

0.0,-1.0, 0.0,   0.0,-1.0, 0.0,

0.0, 0.0,-1.0,   0.0, 0.0,-1.0,

0.0, 0.0,-1.0,   0.0, 0.0,-1.0

]);

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

]);

var indexBuffer = gl.createBuffer();

if (!indexBuffer)

return -1;

if (!initArrayBuffer(gl, 'a_Position', vertices, 3, gl.FLOAT)) return -1;

if (!initArrayBuffer(gl, 'a_Color', colors, 3, gl.FLOAT)) return -1;

if (!initArrayBuffer(gl, 'a_Normal', normals, 3, gl.FLOAT)) return -1;

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, type) {

var buffer = gl.createBuffer();

if (!buffer) {

console.log('Failed to create the buffer object');

return false;

}

gl.bindBuffer(gl.ARRAY_BUFFER, buffer);

gl.bufferData(gl.ARRAY_BUFFER, data, gl.STATIC_DRAW);

var a_attribute =

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, type, false, 0, 0);

gl.enableVertexAttribArray(a_attribute);

gl.bindBuffer(gl.ARRAY_BUFFER, null);

return true;

}



在球体上实现简单光照明的实现与效果验证。

<!DOCTYPE html>

<html>

<meta charset="UTF-8">

<title></title>

<style>

body{

margin: 0;

}

</style>

<body>

<canvas id="cvs" width="800" height="800"></canvas>

<div></div>

precision highp float;

attribute vec3 position;

uniform mat4 mat;

varying vec4 color;

void main(){

gl_Position=mat*vec4(position,1.0);

//color=vec4(gl_Position.x,gl_Position.y,gl_Position.z,0.8);

color=vec4(1,0,0,0.8);

}

</script>

#ifdef GL_ES

precision mediump float;

#endif

varying vec4 color;

void main(){

gl_FragColor=color;

}

</script>

<script type="text/javascript">

(function(global){

var cvs = document.getElementById("cvs");

var gl = cvs.getContext("experimental-webgl");

var paogram = gl.createProgram();

gl.useProgram(paogram);

var drawQiu02=function(rX,rY,rZ,r,m){

var arr= new Array();

var bufR=-r;

function getMaxY(a,z,r){

var angle=0;

var d=new Array();

for(var i =0;i<a;i++){

d.push(Math.sin(Math.PI/180*angle)*r,Math.cos(Math.PI/180*angle)*r,z);

}

return d;

}

var angle=0;

var bufR = r;

var angle02=0;

for(var i = 0;i<m/2;i++){

if(i>=m/4){

var z =Math.sin(Math.PI/180*angle)*-r;

}else{

var z =Math.sin(Math.PI/180*angle)*-r;

}

console.log(z);

var arr1=getMaxY(m,z,bufR);

if(i>=m/4){

z=Math.sin(Math.PI/180*angle)*-r

}else{

z=-Math.sin(Math.PI/180*angle)*-r;

}

bufR=Math.sqrt(r*r-r*Math.sin(Math.PI/180*angle)*r*Math.sin(Math.PI/180*angle));

var arr2=getMaxY(m,z,bufR);

for(var q=0;q<arr1.length;q+=3){

if(q==0){

arr.push(arr1[q],arr1[q+1],arr1[q+2]);

arr.push(arr2[q],arr2[q+1],arr2[q+2]);

arr.push(arr1[arr1.length-3],arr1[arr1.length-2],arr1[arr1.length-1]);

arr.push(arr1[q],arr1[q+1],arr1[q+2]);

arr.push(arr2[q],arr2[q+1],arr2[q+2]);

arr.push(arr2[q+3],arr2[q+4],arr2[q+5]);

}else if(q==arr1.length-3){

arr.push(arr1[q],arr1[q+1],arr1[q+2]);

arr.push(arr2[q],arr2[q+1],arr2[q+2]);

arr.push(arr1[q-3],arr1[q-2],arr1[q-1]);

arr.push(arr1[q],arr1[q+1],arr1[q+2]);

arr.push(arr2[q],arr2[q+1],arr2[q+2]);

arr.push(arr2[0],arr2[1],arr2[2]);

}else{

arr.push(arr1[q],arr1[q+1],arr1[q+2]);

arr.push(arr2[q],arr2[q+1],arr2[q+2]);

arr.push(arr1[q-3],arr1[q-2],arr1[q-1]);

arr.push(arr1[q],arr1[q+1],arr1[q+2]);

arr.push(arr2[q],arr2[q+1],arr2[q+2]);

arr.push(arr2[q+3],arr2[q+4],arr2[q+5]);

}

}

}

return arr;

}

data=drawQiu02(0,0,0,0.5,180);

var positionIndex = gl.getAttribLocation(paogram,"position");

var matIndex = gl.getUniformLocation(paogram,"mat");

var mM=[

1,0,0,0,

0,1,0,0,

0,0,1,0,

0,0,0,1

];

global.rotateX=function (angle){

var c = Math.cos(Math.PI/180*angle);

var s = Math.sin(Math.PI/180*angle);

var mM1=mM[1],mM5=mM[5],mM9=mM[9];

mM[1] = c*mM[1] - s*mM[2];

mM[5] = c*mM[5] - s*mM[6];

mM[9] = c*mM[9] - s*mM[10];

mM[2]=s*mM1+c*mM[2];

mM[6]=s*mM5+c*mM[6];

mM[10]=s*mM9+c*mM[10];

};

global.rotateY=function (angle){

var c = Math.cos(Math.PI/180*angle);

var s = Math.sin(Math.PI/180*angle);

var mM0=mM[0],mM8=mM[8],mM4=mM[4];

mM[0] = c*mM[0] + s*mM[2];

mM[4] = c*mM[4] + s*mM[6];

mM[8] = c*mM[8] + s*mM[10];

mM[2] = c*mM[2]-s*mM0;

mM[6] = c*mM[6]-s*mM4;

mM[10] = c*mM[10]-s*mM8;

};

global.rotateZ=function (angle){

var c = Math.cos(Math.PI/180*angle);

var s = Math.sin(Math.PI/180*angle);

var mM0=mM[0],mM4=mM[4],mM8=mM[8];

mM[0] = c*mM[0]-s*mM[1];

mM[4] =  c*mM[4]-s*mM[5];

mM[8] =  c*mM[8]-s*mM[9];

mM[1]=s*mM0+c*mM[1];

mM[5]=s*mM4+c*mM[5];

mM[9]=s*mM8+c*mM[9];

};

global.moveX= function(distance){

mM[0]=mM[0]+distance*mM[3];

mM[4]=mM[4]+distance*mM[7];

mM[8]=mM[8]+distance*mM[11];

mM[12]=mM[12]+distance*mM[15];

};

global.moveY= function(distance){

mM[1]=distance*mM[3]+mM[1];

mM[5]=distance*mM[7]+mM[5];

mM[9]=distance*mM[11]+mM[9];

mM[13]=distance*mM[15]+mM[13];

};

global.moveZ= function(distance){

mM[2]=distance*mM[3]+mM[2];

mM[6]=distance*mM[7]+mM[6];

mM[10]=distance*mM[11]+mM[10];

mM[14]=distance*mM[15]+mM[14];

};

global.scaleFun=function(scale){

mM[0]=scale*mM[0];

mM[4]=scale*mM[4];

mM[8]=scale*mM[8];

mM[12]=scale*mM[12];

mM[1]=scale*mM[1];

mM[5]=scale*mM[5];

mM[9]=scale*mM[9];

mM[13]=scale*mM[13];

mM[2]=scale*mM[2];

mM[6]=scale*mM[6];

mM[10]=scale*mM[10];

mM[14]=scale*mM[14];

};

var buffer = gl.createBuffer();

gl.bindBuffer(gl.ARRAY_BUFFER,buffer);

gl.bufferData(gl.ARRAY_BUFFER,new Float32Array(data),gl.STATIC_DRAW);

gl.vertexAttribPointer(positionIndex,3,gl.FLOAT,false,0,0);

gl.enableVertexAttribArray(positionIndex);

var dis= 0.05;

var angle=0.5;

function fun(){

rotateX(angle);

rotateY(angle);

rotateZ(angle);

gl.uniformMatrix4fv(matIndex,false,new Float32Array(mM));

gl.clearColor(0.5, 0.5, 0.5, 1);

gl.clear(gl.COLOR_BUFFER_BIT);

gl.drawArrays(gl.LINE_STRIP,0,data.length/3);

requestAnimationFrame(fun);

}

fun();

})(window);

</script>

</body>

</html>

#### 发表评论

◎欢迎参与讨论，请在这里发表您的看法和观点。