实验内容
1.对实验二绘制的正三棱锥增加光照,实现点光源的光照效果,分别在顶点着色器和片元着色器中实现,观察有什么区别。把点光源改成平行光,观察有什么变化。
2.使点光源围绕三棱锥旋转,呈现在不同位置照射三棱锥的效果。
实验设计思路
光照处理:采用Blinn-Phong反射模型,在着色器中计算三种光的光强,将三种光相加并与物体的原色相乘得到最终的着色。
环境光反射光强Ia由表面的环境光反射系数ka确定
漫反射光的颜色Id取决于入射光光强Ld、材质反射系数kd、入射光与表面形成的入射角θ
增加距离衰减因子后为
镜面反射光的颜色Is取决于入射光光强Ls、材质反射系数ks、半角向量h与法向量n的夹角ψ、高光指数a
增加距离衰减因子后为
因此最终计算出的光强为
本实验中不考虑距离衰减因子
在着色器中比实验三的程序多了①相机位置②光源位置③光色(默认白色即1.0,1.0,1.0)④法线变换矩阵
根据Blinn-Phong模型的图示
归一化:向一个向量转化为对应方向的单位向量
入射光方向I = 归一化(光源位置 - 着色点位置)
视线方向 v= 归一化(相机位置 - 着色点位置)
半程向量h = 归一化(入射光方向+视线方向)
最后利用这些数据代入公式即可算出最终反射的光强。
在顶点着色器中实现光照操作,只计算了几个点的最终颜色值,最后的结果会进行插值操作,导致结果不真实
在片段着色器中实现光照操作,对每个像素都计算的其颜色值,最终的结果会更加真实。
平行光源的实现:将上述点光源的着色器中的光照方向改为一个固定的值即可。
光源的旋转操作:为光源额外设置一个旋转矩阵,并传入着色器与光源位置相乘即可得到变化后的光源位置。
实验结果
点光源+旋转(顶点着色器实现)
点光源+旋转(片段着色器实现)
平行光源(片段着色器实现)
实验代码
点光源+旋转(顶点着色器)
// 获取WebGL上下文
const canvas = document.getElementById('webglCanvas');
const gl = canvas.getContext('webgl');
// 初始化着色器
const vertexShaderSource = `
attribute vec3 position;
attribute vec3 normal;
attribute vec3 color;
uniform mat4 modelMatrix;
uniform mat4 visionMatrix;
uniform mat4 perspectiveMatrix;
uniform mat4 lightTransformMatrix;
uniform mat4 normalMatrix;
uniform vec3 cameraPosition;
uniform vec3 lightColor;
uniform vec3 lightPosition;
varying vec3 vColor;
varying vec3 vNormal;
void main() {
gl_Position =perspectiveMatrix* visionMatrix * modelMatrix * vec4(position, 1.0);
vec3 transformedPoint = (modelMatrix * vec4(position, 1.0)).xyz;
vNormal = normalize((normalMatrix * vec4(normal,1.0)).xyz);
vec3 transLight = (lightTransformMatrix * vec4(lightPosition, 1.0)).xyz;
vec3 lightVec = normalize(transLight-transformedPoint);
vec3 cameraVec = normalize(cameraPosition-transformedPoint);
vec3 halfVec = normalize(lightVec+cameraVec);
float lightCos = max(dot(lightVec,normal),0.0);
float lightCosHalf = max(dot(lightVec,halfVec),0.0);
vec3 ambientLight = lightColor*0.3;
vec3 diffuseLight = lightColor*lightCos*1.0;
vec3 specularLight = lightColor*pow(lightCosHalf,20.0)*0.5;
vColor =(ambientLight + specularLight + diffuseLight)*color;
}
`;
const vertexShader = gl.createShader(gl.VERTEX_SHADER);
gl.shaderSource(vertexShader, vertexShaderSource);
gl.compileShader(vertexShader);
const fragmentShaderSource = `
precision mediump float;
varying vec3 vNormal;
varying vec3 vColor;
void main() {
gl_FragColor = vec4(vColor ,1.0);
}
`;
const fragmentShader = gl.createShader(gl.FRAGMENT_SHADER);
gl.shaderSource(fragmentShader, fragmentShaderSource);
gl.compileShader(fragmentShader);
const shaderProgram = gl.createProgram();
gl.attachShader(shaderProgram, vertexShader);
gl.attachShader(shaderProgram, fragmentShader);
gl.linkProgram(shaderProgram);
gl.useProgram(shaderProgram);
//初始化数据
var transformMatrix = glMatrix.mat4.create();
var t1, t2, t3 = null
const vertices = new Float32Array([
0, 0, -1,
0, 0.942809, 0.333333,
-0.816497, -0.471405, 0.333333,
0.816497, -0.471405, 0.333333,
]);
const indices = new Uint16Array([
1, 2, 3,
1, 2, 0,
1, 3, 0,
2, 3, 0,
]);
const colors = new Float32Array([
1, 0, 0,
0, 1, 0,
0, 0, 1,
1, 1, 0,
])
const normal = new Float32Array(
[
0, 0, -1,
0, 0.942809, 0.333333,
-0.816496, -0.471404, 0.333333,
0.816496, -0.471404, 0.333333,
]
)
// 传入数据
const vertexBuffer = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, vertexBuffer);
gl.bufferData(gl.ARRAY_BUFFER, vertices, gl.STATIC_DRAW);
const positionAttributeLocation = gl.getAttribLocation(shaderProgram, 'position');
gl.vertexAttribPointer(positionAttributeLocation, 3, gl.FLOAT, false, 0, 0);
gl.enableVertexAttribArray(positionAttributeLocation);
const indicesBuffer = gl.createBuffer();
gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, indicesBuffer);
gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, indices, gl.STATIC_DRAW);
const colorBuffer = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, colorBuffer);
gl.bufferData(gl.ARRAY_BUFFER, colors, gl.STATIC_DRAW);
const colorAttributeLocation = gl.getAttribLocation(shaderProgram, 'color');
gl.vertexAttribPointer(colorAttributeLocation, 3, gl.FLOAT, false, 0, 0);
gl.enableVertexAttribArray(colorAttributeLocation);
const normalBuffer = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, normalBuffer);
gl.bufferData(gl.ARRAY_BUFFER, normal, gl.STATIC_DRAW);
const normalAttributeLocation = gl.getAttribLocation(shaderProgram, 'normal');
gl.vertexAttribPointer(normalAttributeLocation, 3, gl.FLOAT, false, 0, 0);
gl.enableVertexAttribArray(normalAttributeLocation);
//传入相机位置数据
const cameraPoint = glMatrix.vec3.fromValues(2.0, 2.0, 3.0);
const cameraPositionVecUniformLocation = gl.getUniformLocation(shaderProgram, 'cameraPosition');
gl.uniform3fv(cameraPositionVecUniformLocation, cameraPoint);
//传入光源颜色数据
const lightColor = glMatrix.vec3.fromValues(1.0, 1.0, 1.0);
const lightColorVecUniformLocation = gl.getUniformLocation(shaderProgram, 'lightColor');
gl.uniform3fv(lightColorVecUniformLocation, lightColor);
//传入光源位置数据
const lightPosition = glMatrix.vec3.fromValues(0.0, 5.0, 0.0);
const lightPositionVecUniformLocation = gl.getUniformLocation(shaderProgram, 'lightPosition');
gl.uniform3fv(lightPositionVecUniformLocation, lightPosition);
//传入模型变换矩阵
const modelMatrixUniformLocation = gl.getUniformLocation(shaderProgram, 'modelMatrix');
var modelMatrix = glMatrix.mat4.create();
gl.uniformMatrix4fv(modelMatrixUniformLocation, false, modelMatrix);
//传入视图变换矩阵
const visionMatrixUniformLocation = gl.getUniformLocation(shaderProgram, 'visionMatrix');
const eye = cameraPoint;
const look = glMatrix.vec3.fromValues(0, 0, 0);
const up = glMatrix.vec3.fromValues(0, 1, 0);
const visionMatrix = glMatrix.mat4.lookAt(glMatrix.mat4.create(), eye, look, up);
gl.uniformMatrix4fv(visionMatrixUniformLocation, false, visionMatrix);
//传入透视矩阵
const perspectiveMatrixUniformLocation = gl.getUniformLocation(shaderProgram, 'perspectiveMatrix');
const perspectiveMatrix = glMatrix.mat4.perspective(glMatrix.mat4.create(), Math.PI / 2, 1 / 1, 1, -100);
gl.uniformMatrix4fv(perspectiveMatrixUniformLocation, false, perspectiveMatrix);
//传入光照方向变换矩阵
const lightTransformMatrixUniformLocation = gl.getUniformLocation(shaderProgram, 'lightTransformMatrix');
gl.uniformMatrix4fv(lightTransformMatrixUniformLocation, false, transformMatrix);
//传入法线变换矩阵
const normalMatrixUniformLocation = gl.getUniformLocation(shaderProgram, 'normalMatrix');
gl.uniformMatrix4fv(normalMatrixUniformLocation, false, getNormalMatrix(modelMatrix));
//绘制初始图形
gl.clearColor(0, 0, 0, 0.5);
gl.enable(gl.DEPTH_TEST)
gl.clear(gl.COLOR_BUFFER_BIT);
gl.drawElements(gl.TRIANGLES, indices.length, gl.UNSIGNED_SHORT, 0);
//功能相关函数
function rotate_x() {
clearInterval(t1);
clearInterval(t2);
clearInterval(t3);
t1 = setInterval(function () {
let rotateMatrix = glMatrix.mat4.rotateX(glMatrix.mat4.create(), glMatrix.mat4.create(), -Math.PI / 200);
transformMatrix = glMatrix.mat4.multiply(glMatrix.mat4.create(), rotateMatrix, transformMatrix);
drawTriangle();
}, 10)
}
function rotate_y() {
clearInterval(t1);
clearInterval(t2);
clearInterval(t3);
t2 = setInterval(function () {
let rotateMatrix = glMatrix.mat4.rotateY(glMatrix.mat4.create(), glMatrix.mat4.create(), -Math.PI / 200);
transformMatrix = glMatrix.mat4.multiply(glMatrix.mat4.create(), rotateMatrix, transformMatrix);
drawTriangle();
}, 10)
}
function rotate_z() {
clearInterval(t1);
clearInterval(t2);
clearInterval(t3);
t3 = setInterval(function () {
let rotateMatrix = glMatrix.mat4.rotateZ(glMatrix.mat4.create(), glMatrix.mat4.create(), -Math.PI / 200);
transformMatrix = glMatrix.mat4.multiply(glMatrix.mat4.create(), rotateMatrix, transformMatrix);
drawTriangle();
}, 10)
}
function stopRotate() {
clearInterval(t1);
clearInterval(t2);
clearInterval(t3);
}
function drawTriangle() {
gl.clear(gl.COLOR_BUFFER_BIT);
gl.uniformMatrix4fv(lightTransformMatrixUniformLocation, false, transformMatrix);
gl.uniformMatrix4fv(normalMatrixUniformLocation, false, getNormalMatrix(modelMatrix));
gl.drawElements(gl.TRIANGLES, 12, gl.UNSIGNED_SHORT, 0)
}
function getNormalMatrix(modelMatrix) {
let invertMatrix = glMatrix.mat4.invert(glMatrix.mat4.create(), modelMatrix);
return glMatrix.mat4.transpose(glMatrix.mat4.create(), invertMatrix);
}
点光源+旋转(片段着色器)
// 获取WebGL上下文
const canvas = document.getElementById('webglCanvas');
const gl = canvas.getContext('webgl');
// 初始化着色器
const vertexShaderSource = `
attribute vec3 position;
uniform mat4 modelMatrix;
uniform mat4 visionMatrix;
uniform mat4 perspectiveMatrix;
uniform mat4 normalMatrix;
attribute vec3 normal;
attribute vec3 color;
varying vec3 vColor;
varying vec3 vNormal;
varying vec3 vPosition;
void main() {
gl_Position =perspectiveMatrix* visionMatrix * modelMatrix* vec4(position, 1.0);
vColor = color;
vPosition = position;
vNormal = normalize((normalMatrix * vec4(normal,1.0)).xyz);
}
`;
const vertexShader = gl.createShader(gl.VERTEX_SHADER);
gl.shaderSource(vertexShader, vertexShaderSource);
gl.compileShader(vertexShader);
const fragmentShaderSource = `
precision mediump float;
uniform vec3 lightPosition;
uniform vec3 cameraPosition;
uniform vec3 lightColor;
uniform mat4 lightTransformMatrix;
varying vec3 vNormal;
varying vec3 vColor;
varying vec3 vPosition;
void main() {
vec3 finalNormal = normalize(vNormal);
vec3 transLight = (lightTransformMatrix* vec4(lightPosition, 1.0)).xyz;
vec3 lightVec = normalize(transLight-vPosition);
vec3 cameraVec = normalize(cameraPosition-vPosition);
vec3 halfVec = normalize(lightVec+cameraVec);
float lightCos = max(dot(lightVec,vNormal),0.0);
float lightCosHalf = max(dot(lightVec,halfVec),0.0);
vec3 ambientLight = lightColor*0.5;
vec3 diffuseLight = lightColor*lightCos*1.0;
vec3 specularLight = lightColor*pow(lightCosHalf,20.0)*0.5;
vec3 finalColor =(ambientLight+diffuseLight+specularLight)*vColor;
gl_FragColor = vec4(finalColor ,1.0);
}
`;
const fragmentShader = gl.createShader(gl.FRAGMENT_SHADER);
gl.shaderSource(fragmentShader, fragmentShaderSource);
gl.compileShader(fragmentShader);
const shaderProgram = gl.createProgram();
gl.attachShader(shaderProgram, vertexShader);
gl.attachShader(shaderProgram, fragmentShader);
gl.linkProgram(shaderProgram);
gl.useProgram(shaderProgram);
//初始化数据
var transformMatrix = glMatrix.mat4.create();
var t1, t2, t3 = null
const vertices = new Float32Array([
0, 0, -1,
0, 0.942809, 0.333333,
-0.816497, -0.471405, 0.333333,
0.816497, -0.471405, 0.333333,
]);
const indices = new Uint16Array([
1, 2, 3,
1, 2, 0,
1, 3, 0,
2, 3, 0,
]);
const colors = new Float32Array([
1, 0, 0,
0, 1, 0,
0, 0, 1,
1, 1, 0,
])
const normal = new Float32Array(
[
0, 0, -1,
0, 0.942809, 0.333333,
-0.816496, -0.471404, 0.333333,
0.816496, -0.471404, 0.333333,
]
)
// 传入数据
const vertexBuffer = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, vertexBuffer);
gl.bufferData(gl.ARRAY_BUFFER, vertices, gl.STATIC_DRAW);
const positionAttributeLocation = gl.getAttribLocation(shaderProgram, 'position');
gl.vertexAttribPointer(positionAttributeLocation, 3, gl.FLOAT, false, 0, 0);
gl.enableVertexAttribArray(positionAttributeLocation);
const indicesBuffer = gl.createBuffer();
gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, indicesBuffer);
gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, indices, gl.STATIC_DRAW);
const colorBuffer = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, colorBuffer);
gl.bufferData(gl.ARRAY_BUFFER, colors, gl.STATIC_DRAW);
const colorAttributeLocation = gl.getAttribLocation(shaderProgram, 'color');
gl.vertexAttribPointer(colorAttributeLocation, 3, gl.FLOAT, false, 0, 0);
gl.enableVertexAttribArray(colorAttributeLocation);
const normalBuffer = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, normalBuffer);
gl.bufferData(gl.ARRAY_BUFFER, normal, gl.STATIC_DRAW);
const normalAttributeLocation = gl.getAttribLocation(shaderProgram, 'normal');
gl.vertexAttribPointer(normalAttributeLocation, 3, gl.FLOAT, false, 0, 0);
gl.enableVertexAttribArray(normalAttributeLocation);
//传入相机位置数据
const cameraPoint = glMatrix.vec3.fromValues(2.0, 2.0, 3.0);
const cameraPositionVecUniformLocation = gl.getUniformLocation(shaderProgram, 'cameraPosition');
gl.uniform3fv(cameraPositionVecUniformLocation, cameraPoint);
//传入光源颜色数据
const lightColor = glMatrix.vec3.fromValues(1.0, 1.0, 1.0);
const lightColorVecUniformLocation = gl.getUniformLocation(shaderProgram, 'lightColor');
gl.uniform3fv(lightColorVecUniformLocation, lightColor);
//传入光源位置数据
const lightPosition = glMatrix.vec3.fromValues(0.0, 5.0, 0.0);
const lightPositionVecUniformLocation = gl.getUniformLocation(shaderProgram, 'lightPosition');
gl.uniform3fv(lightPositionVecUniformLocation, lightPosition);
//传入模型变换矩阵
const modelMatrixUniformLocation = gl.getUniformLocation(shaderProgram, 'modelMatrix');
var modelMatrix = glMatrix.mat4.create();
gl.uniformMatrix4fv(modelMatrixUniformLocation, false, modelMatrix);
//传入视图变换矩阵
const visionMatrixUniformLocation = gl.getUniformLocation(shaderProgram, 'visionMatrix');
const eye = cameraPoint;
const look = glMatrix.vec3.fromValues(0, 0, 0);
const up = glMatrix.vec3.fromValues(0, 1, 0);
const visionMatrix = glMatrix.mat4.lookAt(glMatrix.mat4.create(), eye, look, up);
gl.uniformMatrix4fv(visionMatrixUniformLocation, false, visionMatrix);
//传入透视矩阵
const perspectiveMatrixUniformLocation = gl.getUniformLocation(shaderProgram, 'perspectiveMatrix');
const perspectiveMatrix = glMatrix.mat4.perspective(glMatrix.mat4.create(), Math.PI / 2, 1 / 1, 1, -100);
gl.uniformMatrix4fv(perspectiveMatrixUniformLocation, false, perspectiveMatrix);
//传入光照方向变换矩阵
const lightTransformMatrixUniformLocation = gl.getUniformLocation(shaderProgram, 'lightTransformMatrix');
gl.uniformMatrix4fv(lightTransformMatrixUniformLocation, false, transformMatrix);
//传入法线变换矩阵
const normalMatrixUniformLocation = gl.getUniformLocation(shaderProgram, 'normalMatrix');
gl.uniformMatrix4fv(normalMatrixUniformLocation, false, getNormalMatrix(modelMatrix));
//绘制初始图形
gl.clearColor(0, 0, 0, 0.5);
gl.enable(gl.DEPTH_TEST)
gl.clear(gl.COLOR_BUFFER_BIT);
gl.drawElements(gl.TRIANGLES, indices.length, gl.UNSIGNED_SHORT, 0);
//功能相关函数
function rotate_x() {
clearInterval(t1);
clearInterval(t2);
clearInterval(t3);
t1 = setInterval(function () {
let rotateMatrix = glMatrix.mat4.rotateX(glMatrix.mat4.create(), glMatrix.mat4.create(), -Math.PI / 200);
transformMatrix = glMatrix.mat4.multiply(glMatrix.mat4.create(), rotateMatrix, transformMatrix);
drawTriangle();
}, 10)
}
function rotate_y() {
clearInterval(t1);
clearInterval(t2);
clearInterval(t3);
t2 = setInterval(function () {
let rotateMatrix = glMatrix.mat4.rotateY(glMatrix.mat4.create(), glMatrix.mat4.create(), -Math.PI / 200);
transformMatrix = glMatrix.mat4.multiply(glMatrix.mat4.create(), rotateMatrix, transformMatrix);
drawTriangle();
}, 10)
}
function rotate_z() {
clearInterval(t1);
clearInterval(t2);
clearInterval(t3);
t3 = setInterval(function () {
let rotateMatrix = glMatrix.mat4.rotateZ(glMatrix.mat4.create(), glMatrix.mat4.create(), -Math.PI / 200);
transformMatrix = glMatrix.mat4.multiply(glMatrix.mat4.create(), rotateMatrix, transformMatrix);
drawTriangle();
}, 10)
}
function stopRotate() {
clearInterval(t1);
clearInterval(t2);
clearInterval(t3);
}
function drawTriangle() {
gl.clear(gl.COLOR_BUFFER_BIT);
gl.uniformMatrix4fv(lightTransformMatrixUniformLocation, false, transformMatrix);
gl.uniformMatrix4fv(normalMatrixUniformLocation, false, getNormalMatrix(modelMatrix));
gl.drawElements(gl.TRIANGLES, 12, gl.UNSIGNED_SHORT, 0)
}
function getNormalMatrix(modelMatrix) {
let invertMatrix = glMatrix.mat4.invert(glMatrix.mat4.create(), modelMatrix);
return glMatrix.mat4.transpose(glMatrix.mat4.create(), invertMatrix);
}
平行光(片段着色器)
// 获取WebGL上下文
const canvas = document.getElementById('webglCanvas');
const gl = canvas.getContext('webgl');
// 初始化着色器
const vertexShaderSource = `
attribute vec3 position;
uniform mat4 modelMatrix;
uniform mat4 visionMatrix;
uniform mat4 perspectiveMatrix;
uniform mat4 normalMatrix;
attribute vec3 normal;
attribute vec3 color;
varying vec3 vColor;
varying vec3 vNormal;
varying vec3 vPosition;
void main() {
gl_Position =perspectiveMatrix* visionMatrix * modelMatrix* vec4(position, 1.0);
vColor = color;
vPosition = position;
vNormal = normalize((normalMatrix * vec4(normal,1.0)).xyz);
}
`;
const vertexShader = gl.createShader(gl.VERTEX_SHADER);
gl.shaderSource(vertexShader, vertexShaderSource);
gl.compileShader(vertexShader);
const fragmentShaderSource = `
precision mediump float;
uniform vec3 lightPosition;
uniform vec3 cameraPosition;
uniform vec3 lightColor;
uniform mat4 lightTransformMatrix;
varying vec3 vNormal;
varying vec3 vColor;
varying vec3 vPosition;
void main() {
vec3 finalNormal = normalize(vNormal);
vec3 transLight = (lightTransformMatrix* vec4(lightPosition, 1.0)).xyz;
vec3 lightVec = normalize(vec3(0.0,1.0,0.0)); //在此处直接将光源替换成固定方向即可
vec3 cameraVec = normalize(cameraPosition-vPosition);
vec3 halfVec = normalize(lightVec+cameraVec);
float lightCos = max(dot(lightVec,vNormal),0.0);
float lightCosHalf = max(dot(lightVec,halfVec),0.0);
vec3 ambientLight = lightColor*0.5;
vec3 diffuseLight = lightColor*lightCos*1.0;
vec3 specularLight = lightColor*pow(lightCosHalf,20.0)*0.5;
vec3 finalColor =(ambientLight+diffuseLight+specularLight)*vColor;
gl_FragColor = vec4(finalColor ,1.0);
}
`;
const fragmentShader = gl.createShader(gl.FRAGMENT_SHADER);
gl.shaderSource(fragmentShader, fragmentShaderSource);
gl.compileShader(fragmentShader);
const shaderProgram = gl.createProgram();
gl.attachShader(shaderProgram, vertexShader);
gl.attachShader(shaderProgram, fragmentShader);
gl.linkProgram(shaderProgram);
gl.useProgram(shaderProgram);
//初始化数据
var transformMatrix = glMatrix.mat4.create();
var t1, t2, t3 = null
const vertices = new Float32Array([
0, 0, -1,
0, 0.942809, 0.333333,
-0.816497, -0.471405, 0.333333,
0.816497, -0.471405, 0.333333,
]);
const indices = new Uint16Array([
1, 2, 3,
1, 2, 0,
1, 3, 0,
2, 3, 0,
]);
const colors = new Float32Array([
1, 0, 0,
0, 1, 0,
0, 0, 1,
1, 1, 0,
])
const normal = new Float32Array(
[
0, 0, -1,
0, 0.942809, 0.333333,
-0.816496, -0.471404, 0.333333,
0.816496, -0.471404, 0.333333,
]
)
// 传入数据
const vertexBuffer = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, vertexBuffer);
gl.bufferData(gl.ARRAY_BUFFER, vertices, gl.STATIC_DRAW);
const positionAttributeLocation = gl.getAttribLocation(shaderProgram, 'position');
gl.vertexAttribPointer(positionAttributeLocation, 3, gl.FLOAT, false, 0, 0);
gl.enableVertexAttribArray(positionAttributeLocation);
const indicesBuffer = gl.createBuffer();
gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, indicesBuffer);
gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, indices, gl.STATIC_DRAW);
const colorBuffer = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, colorBuffer);
gl.bufferData(gl.ARRAY_BUFFER, colors, gl.STATIC_DRAW);
const colorAttributeLocation = gl.getAttribLocation(shaderProgram, 'color');
gl.vertexAttribPointer(colorAttributeLocation, 3, gl.FLOAT, false, 0, 0);
gl.enableVertexAttribArray(colorAttributeLocation);
const normalBuffer = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, normalBuffer);
gl.bufferData(gl.ARRAY_BUFFER, normal, gl.STATIC_DRAW);
const normalAttributeLocation = gl.getAttribLocation(shaderProgram, 'normal');
gl.vertexAttribPointer(normalAttributeLocation, 3, gl.FLOAT, false, 0, 0);
gl.enableVertexAttribArray(normalAttributeLocation);
//传入相机位置数据
const cameraPoint = glMatrix.vec3.fromValues(2.0, 2.0, 3.0);
const cameraPositionVecUniformLocation = gl.getUniformLocation(shaderProgram, 'cameraPosition');
gl.uniform3fv(cameraPositionVecUniformLocation, cameraPoint);
//传入光源颜色数据
const lightColor = glMatrix.vec3.fromValues(1.0, 1.0, 1.0);
const lightColorVecUniformLocation = gl.getUniformLocation(shaderProgram, 'lightColor');
gl.uniform3fv(lightColorVecUniformLocation, lightColor);
//传入光源位置数据
const lightPosition = glMatrix.vec3.fromValues(0.0, 5.0, 0.0);
const lightPositionVecUniformLocation = gl.getUniformLocation(shaderProgram, 'lightPosition');
gl.uniform3fv(lightPositionVecUniformLocation, lightPosition);
//传入模型变换矩阵
const modelMatrixUniformLocation = gl.getUniformLocation(shaderProgram, 'modelMatrix');
var modelMatrix = glMatrix.mat4.create();
gl.uniformMatrix4fv(modelMatrixUniformLocation, false, modelMatrix);
//传入视图变换矩阵
const visionMatrixUniformLocation = gl.getUniformLocation(shaderProgram, 'visionMatrix');
const eye = cameraPoint;
const look = glMatrix.vec3.fromValues(0, 0, 0);
const up = glMatrix.vec3.fromValues(0, 1, 0);
const visionMatrix = glMatrix.mat4.lookAt(glMatrix.mat4.create(), eye, look, up);
gl.uniformMatrix4fv(visionMatrixUniformLocation, false, visionMatrix);
//传入透视矩阵
const perspectiveMatrixUniformLocation = gl.getUniformLocation(shaderProgram, 'perspectiveMatrix');
const perspectiveMatrix = glMatrix.mat4.perspective(glMatrix.mat4.create(), Math.PI / 2, 1 / 1, 1, -100);
gl.uniformMatrix4fv(perspectiveMatrixUniformLocation, false, perspectiveMatrix);
//传入光照方向变换矩阵
const lightTransformMatrixUniformLocation = gl.getUniformLocation(shaderProgram, 'lightTransformMatrix');
gl.uniformMatrix4fv(lightTransformMatrixUniformLocation, false, transformMatrix);
//传入法线变换矩阵
const normalMatrixUniformLocation = gl.getUniformLocation(shaderProgram, 'normalMatrix');
gl.uniformMatrix4fv(normalMatrixUniformLocation, false, getNormalMatrix(modelMatrix));
//绘制初始图形
gl.clearColor(0, 0, 0, 0.5);
gl.enable(gl.DEPTH_TEST)
gl.clear(gl.COLOR_BUFFER_BIT);
gl.drawElements(gl.TRIANGLES, indices.length, gl.UNSIGNED_SHORT, 0);
//功能相关函数
function rotate_x() {
clearInterval(t1);
clearInterval(t2);
clearInterval(t3);
t1 = setInterval(function () {
let rotateMatrix = glMatrix.mat4.rotateX(glMatrix.mat4.create(), glMatrix.mat4.create(), -Math.PI / 200);
transformMatrix = glMatrix.mat4.multiply(glMatrix.mat4.create(), rotateMatrix, transformMatrix);
drawTriangle();
}, 10)
}
function rotate_y() {
clearInterval(t1);
clearInterval(t2);
clearInterval(t3);
t2 = setInterval(function () {
let rotateMatrix = glMatrix.mat4.rotateY(glMatrix.mat4.create(), glMatrix.mat4.create(), -Math.PI / 200);
transformMatrix = glMatrix.mat4.multiply(glMatrix.mat4.create(), rotateMatrix, transformMatrix);
drawTriangle();
}, 10)
}
function rotate_z() {
clearInterval(t1);
clearInterval(t2);
clearInterval(t3);
t3 = setInterval(function () {
let rotateMatrix = glMatrix.mat4.rotateZ(glMatrix.mat4.create(), glMatrix.mat4.create(), -Math.PI / 200);
transformMatrix = glMatrix.mat4.multiply(glMatrix.mat4.create(), rotateMatrix, transformMatrix);
drawTriangle();
}, 10)
}
function stopRotate() {
clearInterval(t1);
clearInterval(t2);
clearInterval(t3);
}
function drawTriangle() {
gl.clear(gl.COLOR_BUFFER_BIT);
gl.uniformMatrix4fv(lightTransformMatrixUniformLocation, false, transformMatrix);
gl.uniformMatrix4fv(normalMatrixUniformLocation, false, getNormalMatrix(modelMatrix));
gl.drawElements(gl.TRIANGLES, 12, gl.UNSIGNED_SHORT, 0)
}
function getNormalMatrix(modelMatrix) {
let invertMatrix = glMatrix.mat4.invert(glMatrix.mat4.create(), modelMatrix);
return glMatrix.mat4.transpose(glMatrix.mat4.create(), invertMatrix);
}