1.Buffer中每个顶点的法向量数据
cubeNormalVertexBuffer = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER,cubeNormalVertexBuffer);
var normalVertices = [
// Front face
0.0, 0.0, 1.0,
0.0, 0.0, 1.0,
0.0, 0.0, 1.0,
0.0, 0.0, 1.0,
// Back face
0.0, 0.0, -1.0,
0.0, 0.0, -1.0,
0.0, 0.0, -1.0,
0.0, 0.0, -1.0,
// Top face
0.0, 1.0, 0.0,
0.0, 1.0, 0.0,
0.0, 1.0, 0.0,
0.0, 1.0, 0.0,
// Bottom face
0.0, -1.0, 0.0,
0.0, -1.0, 0.0,
0.0, -1.0, 0.0,
0.0, -1.0, 0.0,
// Right face
1.0, 0.0, 0.0,
1.0, 0.0, 0.0,
1.0, 0.0, 0.0,
1.0, 0.0, 0.0,
// Left face
-1.0, 0.0, 0.0,
-1.0, 0.0, 0.0,
-1.0, 0.0, 0.0,
-1.0, 0.0, 0.0
]
gl.bufferData(gl.ARRAY_BUFFER,new Float32Array(normalVertices),gl.STATIC_DRAW);
cubeNormalVertexBuffer.itemSize = 3;
cubeNormalVertexBuffer.numItems = cubeNormalVertexBuffer.length/3;
2.drawScene中绑定法向量buffer
gl.bindBuffer(gl.ARRAY_BUFFER,cubeNormalVertexBuffer);
gl.vertexAttribPointer(shaderProgram.vertexNormalAttribute,cubeNormalVertexBuffer.itemSize,gl.FLOAT,false,0,0);
声明环境光ambient RGB 和定向光的方向和RGB
//设置light
var lighting = document.getElementById("lighting").checked;
gl.uniform1i(shaderProgram.useLightingUniform,lighting);
if (lighting){
// ambient lighting RGB
gl.uniform3f(
shaderProgram.ambientColorUniform,
parseFloat(document.getElementById("ambientR").value),
parseFloat(document.getElementById("ambientG").value),
parseFloat(document.getElementById("ambientB").value)
);
//设置direction lighting的方向向量
var lightingDirection = [
parseFloat(document.getElementById("lightDirectionX").value),
parseFloat(document.getElementById("lightDirectionY").value),
parseFloat(document.getElementById("lightDirectionZ").value)
];
//以下三句定义了direction lighting的法线向量
//定义一个vec3向量
var adjustedLD = vec3.create();
//使adjustedLD与lightingDirection单位法线
//vec3.normalize=function(a,b)
// {b||(b=a);
// var c=a[0],d=a[1],e=a[2],
// g=Math.sqrt(c*c+d*d+e*e);i
// f(g){if(g==1){b[0]=c;b[1]=d;b[2]=e;return b}}else{b[0]=0;b[1]=0;b[2]=0;return b}
// g=1/g;b[0]=c*g;b[1]=d*g;b[2]=e*g;return b}
vec3.normalize(lightingDirection, adjustedLD);
//改变adjustedLD方向
vec3.scale(adjustedLD, -1);
gl.uniform3fv(shaderProgram.lightingDirectionUniform, adjustedLD);
gl.uniform3f(
shaderProgram.directionalColorUniform,
parseFloat(document.getElementById("directionalR").value),
parseFloat(document.getElementById("directionalG").value),
parseFloat(document.getElementById("directionalB").value)
);
}
3.setMatrixUniforms()中声明
function setMatrixUniforms() {
gl.uniformMatrix4fv(shaderProgram.pMatrixUniform, false, pMatrix);
gl.uniformMatrix4fv(shaderProgram.mvMatrixUniform, false, mvMatrix);
//法线矩阵不能像顶点vertex那样直接translate平移
//可以借助model-view矩阵???
//eg:mvTranslate (0,0,-5) nomorMatrix 将从(0,0,1)移到(0,0,-4)
//inverse 逆矩阵
//tarnspose 转置矩阵?
var normalMatrix = mat3.create();
//mat4.toInverseMat3=function(a,b)
// {var c=a[0],d=a[1],e=a[2],g=a[4],f=a[5],h=a[6],i=a[8],j=a[9],k=a[10],
// l=k*f-h*j,o=-k*g+h*i,m=j*g-f*i,n=c*l+d*o+e*m;if(!n)return null;n=1/n;b||(b=mat3.create());
// b[0]=l*n;b[1]=(-k*d+e*j)*n;b[2]=(h*d-e*f)*n;b[3]=o*n;b[4]=(k*c-e*i)*n;b[5]=(-h*c+e*g)*n;b[6]=m*n;b[7]=(-j*c+d*i)*n;
// b[8]=(f*c-d*g)*n;
// return b};
mat4.toInverseMat3(mvMatrix,normalMatrix);
mat3.transpose(normalMatrix);
gl.uniformMatrix3fv(shaderProgram.nMatrixUniform, false, normalMatrix);
}
4.在vertex shader中声明
<script id="shader-vs" type="x-shader/x-vertex">
attribute vec3 aVertexPosition;
attribute vec2 aTextureCoord;
attribute vec3 aVertexNormal;
uniform mat4 uMVMatrix;
uniform mat4 uPMatrix;
//法线矩阵 3*3
uniform mat3 uNMatrix;
//环境光源
uniform vec3 uAmbientColor;
//平行光源的方向
uniform vec3 uLightingDirection;
//平行光源的颜色
uniform vec3 uDirectionalColor;
//chebox 是否使用光源
uniform bool uUseLighting;
varying vec2 vTextureCoord;
//传给fragment的光源
varying vec3 vLightWeighting;
void main(void) {
gl_Position = uPMatrix * uMVMatrix * vec4(aVertexPosition, 1.0);
vTextureCoord = aTextureCoord;
if(!uUseLighting){
vLightWeighting = vec3(1.0, 1.0, 1.0);
}else{
//定义transformedNormal = 法线矩阵*顶点法线向量
vec3 transformedNormal = uNMatrix * aVertexNormal;
float directionalLightWeighting = max(dot(transformedNormal, uLightingDirection), 0.0);
//传给fragment的light强度 由环境RGB 定向光RGB*光照强度
vLightWeighting = uAmbientColor + uDirectionalColor * directionalLightWeighting;
}
}
</script>
5.fragment shader
<script id="shader-fs" type="x-shader/x-fragment">
precision mediump float;
varying vec2 vTextureCoord;
varying vec3 vLightWeighting;
uniform sampler2D uSampler;
//设置透明度(depth buffer)
// uniform float uAlpha;
void main(void) {
// gl_FragColor = texture2D(uSampler, vec2(vTextureCoord.s, vTextureCoord.t));
vec4 textureColor = texture2D(uSampler, vec2(vTextureCoord.s, vTextureCoord.t));
// gl_FragColor = vec4(textureColor.rgb * vLightWeighting, textureColor.a*uAlpha);
gl_FragColor = vec4(textureColor.rgb * vLightWeighting, textureColor.a);
}
</script>
6.shaderProgram添加语句
shaderProgram.nMatrixUniform = gl.getUniformLocation(shaderProgram, "uNMatrix");
shaderProgram.useLightingUniform = gl.getUniformLocation(shaderProgram, "uUseLighting");
shaderProgram.ambientColorUniform = gl.getUniformLocation(shaderProgram, "uAmbientColor");
shaderProgram.lightingDirectionUniform = gl.getUniformLocation(shaderProgram, "uLightingDirection");
shaderProgram.directionalColorUniform = gl.getUniformLocation(shaderProgram, "uDirectionalColor");