我现在已经重写了几次这段代码了,但是出现了与灯光相同的问题......我将这段代码与我几个月前编写的代码进行比较,这些代码执行相同的操作(点亮一个多维数据集)和我似乎没有遗漏任何东西。
立方体的正面和背面都没问题,但是左右两边都表现得很奇怪,而且顶部和底部......看起来像法线一样有问题,但它们没问题......检查它们并重写几次以确定。
着色器:
<script id="vShader" type="x-shader/x-vertex">
attribute vec3 aVertexPosition;
attribute vec2 aTextureCoord;
attribute vec3 aVertexNormal;
uniform mat4 uPMatrix;
uniform mat4 uMVMatrix;
uniform mat3 uNMatrix;
uniform vec3 uAmbientLightColor;
uniform vec3 uDirectionalLightColor;
uniform vec3 uLightDirection;
uniform bool uUseLighting;
varying vec2 vTextureCoord;
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{
vec3 transformedNormal = aVertexNormal * uNMatrix;
float directionalLightWeighting = max(dot(uLightDirection, transformedNormal), 0.0);
vLightWeighting = uAmbientLightColor + uDirectionalLightColor * directionalLightWeighting;
}
}
</script>
<script id="fShader" type="x-shader/x-fragment">
precision mediump float;
varying vec2 vTextureCoord;
varying vec3 vLightWeighting;
uniform sampler2D uSampler;
void main(void){
vec4 textureColor = texture2D(uSampler, vec2(vTextureCoord.s, vTextureCoord.t));
gl_FragColor = vec4(textureColor.rgb * vLightWeighting, textureColor.a);
}
</script>
代码:
var gl;
function initGL(canvas){
try{
gl = canvas.getContext("webgl");
gl.viewportWidth = canvas.width;
gl.viewportHeight = canvas.height;
}catch(e){
console.log("WebGL context was not initialized.");
return null;
}
}
function getShader(id, gl){
var shaderScript = document.getElementById(id);
if(!shaderScript){
console.log(id + " - invalid shader id.");
}
var shaderString = "";
var shaderChild = shaderScript.firstChild;
while(shaderChild){
if(shaderChild.nodeType == "3")
shaderString += shaderChild.textContent;
shaderChild = shaderChild.nextSibling;
}
var shader;
if(shaderScript.type == "x-shader/x-vertex")
shader = gl.createShader(gl.VERTEX_SHADER);
else if(shaderScript.type == "x-shader/x-fragment")
shader = gl.createShader(gl.FRAGMENT_SHADER);
else{
console.log(id + " - invalid shader id.");
return null;
}
gl.shaderSource(shader, shaderString);
gl.compileShader(shader);
if(!gl.getShaderParameter(shader, gl.COMPILE_STATUS)){
console.log(id + " error: " + gl.getShaderInfoLog(shader));
return null;
}
return shader;
}
var shaderProgram;
function initShaders(){
var vShader = getShader("vShader", gl);
var fShader = getShader("fShader", gl);
shaderProgram = gl.createProgram();
gl.attachShader(shaderProgram, vShader);
gl.attachShader(shaderProgram, fShader);
gl.linkProgram(shaderProgram);
if(!gl.getProgramParameter(shaderProgram, gl.LINK_STATUS)){
console.log("Shader program was not linked.");
return null;
}
gl.useProgram(shaderProgram);
shaderProgram.vertexPositionAttribute = gl.getAttribLocation(shaderProgram, "aVertexPosition");
gl.enableVertexAttribArray(shaderProgram.vertexPositionAttribute);
shaderProgram.textureCoordAttribute = gl.getAttribLocation(shaderProgram, "aTextureCoord");
gl.enableVertexAttribArray(shaderProgram.vertexColorAttribute);
shaderProgram.vertexNormalAttribute = gl.getAttribLocation(shaderProgram, "aVertexNormal");
gl.enableVertexAttribArray(shaderProgram.vertexNormalAttribute);
shaderProgram.pMatrixUniform = gl.getUniformLocation(shaderProgram, "uPMatrix");
shaderProgram.mvMatrixUniform = gl.getUniformLocation(shaderProgram, "uMVMatrix");
shaderProgram.nMatrixUniform = gl.getUniformLocation(shaderProgram, "uNMatrix");
shaderProgram.samplerUniform = gl.getUniformLocation(shaderProgram, "uSampler");
shaderProgram.lightDirectionUniform = gl.getUniformLocation(shaderProgram, "uLightDirection");
shaderProgram.directionalLightColorUniform = gl.getUniformLocation(shaderProgram, "uDirectionalLightColor");
shaderProgram.ambientLightColorUniform = gl.getUniformLocation(shaderProgram, "uAmbientLightColor");
shaderProgram.useLightingUniform = gl.getUniformLocation(shaderProgram, "uUseLighting");
}
var cubeVertexPositionBuffer, cubeVertexIndexBuffer, cubeVertexTextureCoordBuffer, cubeVertexNormalBuffer;
function initBuffers(){
// Cube.
cubeVertexPositionBuffer = gl.createBuffer();
vertices = [
// Front face.
-1.0, 1.0, 1.0,
1.0, 1.0, 1.0,
1.0, -1.0, 1.0,
-1.0, -1.0, 1.0,
// Back face.
-1.0, 1.0, -1.0,
1.0, 1.0, -1.0,
1.0, -1.0, -1.0,
-1.0, -1.0, -1.0,
// Left face.
-1.0, 1.0, -1.0,
-1.0, 1.0, 1.0,
-1.0, -1.0, 1.0,
-1.0, -1.0, -1.0,
// Right face.
1.0, 1.0, -1.0,
1.0, 1.0, 1.0,
1.0, -1.0, 1.0,
1.0, -1.0, -1.0,
// Top face.
1.0, 1.0, -1.0,
-1.0, 1.0, -1.0,
-1.0, 1.0, 1.0,
1.0, 1.0, 1.0,
// Bottom face.
1.0, -1.0, -1.0,
-1.0, -1.0, -1.0,
-1.0, -1.0, 1.0,
1.0, -1.0, 1.0
]
gl.bindBuffer(gl.ARRAY_BUFFER, cubeVertexPositionBuffer);
gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(vertices), gl.STATIC_DRAW);
cubeVertexPositionBuffer.itemSize = 3;
cubeVertexPositionBuffer.rotAngle = 0;
cubeVertexIndexBuffer = gl.createBuffer();
var indices = [
0, 1, 2, 0, 2, 3,
4, 5, 6, 4, 6, 7,
8, 9, 10, 8, 10, 11,
12, 13, 14, 12, 14, 15,
16, 17, 18, 16, 18, 19,
20, 21, 22, 20, 22, 23
];
gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, cubeVertexIndexBuffer);
gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, new Uint16Array(indices), gl.STATIC_DRAW);
cubeVertexIndexBuffer.numItems = 36;
cubeVertexTextureCoordBuffer = gl.createBuffer();
textureCoords = [
0.0, 0.0,
1.0, 0.0,
1.0, 1.0,
0.0, 1.0,
0.0, 0.0,
1.0, 0.0,
1.0, 1.0,
0.0, 1.0,
0.0, 0.0,
1.0, 0.0,
1.0, 1.0,
0.0, 1.0,
0.0, 0.0,
1.0, 0.0,
1.0, 1.0,
0.0, 1.0,
0.0, 0.0,
1.0, 0.0,
1.0, 1.0,
0.0, 1.0,
0.0, 0.0,
1.0, 0.0,
1.0, 1.0,
0.0, 1.0
];
gl.bindBuffer(gl.ARRAY_BUFFER, cubeVertexTextureCoordBuffer);
gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(textureCoords), gl.STATIC_DRAW);
cubeVertexTextureCoordBuffer.itemSize = 2;
cubeVertexNormalBuffer = gl.createBuffer();
var normals = [
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, -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,
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, -1.0, 0.0,
0.0, -1.0, 0.0,
0.0, -1.0, 0.0,
0.0, -1.0, 0.0,
]
gl.bindBuffer(gl.ARRAY_BUFFER, cubeVertexNormalBuffer);
gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(normals), gl.STATIC_DRAW);
cubeVertexNormalBuffer.itemSize = 3;
}
var pMatrix = mat4.create();
var mvMatrixStack = [];
var mvMatrix = mat4.create();
var nMatrix = mat3.create();
function setMatrixUniforms(){
gl.uniformMatrix4fv(shaderProgram.pMatrixUniform, false, pMatrix);
gl.uniformMatrix4fv(shaderProgram.mvMatrixUniform, false, mvMatrix);
mat3.normalFromMat4(nMatrix, mvMatrix);
gl.uniformMatrix3fv(shaderProgram.nMatrixUniform, false, nMatrix);
}
function mvPushMatrix(){
var copy = mat4.create();
mat4.copy(copy, mvMatrix);
mvMatrixStack.push(copy);
}
function mvPopMatrix(){
mvMatrix = mvMatrixStack.pop();
}
function drawScene(){
gl.viewport(0, 0, gl.viewportWidth, gl.viewportHeight);
gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
mat4.perspective(pMatrix, 45, gl.viewportWidth / gl.viewportHeight, 0.1, 100.0);
mat4.identity(mvMatrix);
// Draw cube.
mvPushMatrix();
mat4.translate(mvMatrix, mvMatrix, [0.0, 0.0, -7.0]);
mat4.rotate(mvMatrix, mvMatrix, degToRad(cubeVertexPositionBuffer.rotAngle), [0.0, 1.0, 0.0]);
gl.bindBuffer(gl.ARRAY_BUFFER, cubeVertexPositionBuffer);
gl.vertexAttribPointer(shaderProgram.vertexPositionAttribute, cubeVertexPositionBuffer.itemSize, gl.FLOAT, false, 0, 0);
gl.bindBuffer(gl.ARRAY_BUFFER, cubeVertexTextureCoordBuffer);
gl.vertexAttribPointer(shaderProgram.textureCoordAttribute, cubeVertexTextureCoordBuffer.itemSize, gl.FLOAT, false, 0, 0);
gl.bindBuffer(gl.ARRAY_BUFFER, cubeVertexNormalBuffer);
gl.vertexAttribPointer(shaderProgram.vertexNormalAttribute, cubeVertexNormalBuffer.itemSize, gl.FLOAT, false, 0, 0);
gl.activeTexture(gl.TEXTURE0);
gl.bindTexture(gl.TEXTURE_2D, cubeTexture);
gl.uniform1i(shaderProgram.samplerUniform, 0);
// Lighting.
gl.uniform1i(shaderProgram.useLightingUniform, true);
gl.uniform3f(shaderProgram.ambientLightColorUniform, 0.2, 0.2, 0.2);
gl.uniform3f(shaderProgram.directionalLightColorUniform, 0.8, 0.8, 0.8);
var lightingDirection = [0.0, 0.0, -1.0];
var adjustedLD = vec3.create();
vec3.normalize(adjustedLD, lightingDirection);
vec3.scale(adjustedLD, adjustedLD, -1);
gl.uniform3fv(shaderProgram.lightDirectionUniform, adjustedLD);
setMatrixUniforms();
gl.drawElements(gl.TRIANGLES, cubeVertexIndexBuffer.numItems, gl.UNSIGNED_SHORT, 0);
mvPopMatrix();
}
var lastTime = 0;
function animate(){
var timeNow = new Date().getTime();
if(lastTime != 0){
var elapsed = timeNow - lastTime;
if(cubeVertexPositionBuffer.rotAngle > 360) cubeVertexPositionBuffer.rotAngle = 0;
cubeVertexPositionBuffer.rotAngle += 45 * elapsed / 1000;
}
lastTime = timeNow;
}
function tick(){
animate();
drawScene();
requestAnimFrame(tick);
}
function degToRad(degrees){
return degrees * Math.PI / 180;
}
var cubeTexture;
function initTextures(){
cubeTexture = gl.createTexture();
cubeTexture.image = new Image();
cubeTexture.image.onload = function(){
handleLoadedTexture(cubeTexture);
}
cubeTexture.image.src = "textures/cube.png";
}
function handleLoadedTexture(texture){
gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, true);
gl.bindTexture(gl.TEXTURE_2D, texture);
gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, texture.image);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST);
gl.bindTexture(gl.TEXTURE_2D, null);
}
function webGLStart(){
initGL(document.getElementById("glCanvas"));
initShaders();
initBuffers();
initTextures();
gl.clearColor(0.0, 0.0, 0.0, 1.0);
gl.enable(gl.DEPTH_TEST);
tick();
}
照明代码是:initShaders()中的引用,initBuffers()中的普通和顶点缓冲区,以及drawScene()中的均匀变量,还在setMatrixUniforms()中创建normalMatrix。
如果有人花时间看看它并告诉我出了什么问题,我将感激不尽。
答案 0 :(得分:0)
好吧..再次生气并重写代码,然后一点一点地用一些工作示例中的代码替换代码......伙计们告诉我!问题出在顶点着色器中,请告诉我
之间的区别vec3 transformedNormal = uNMatrix * aVertexNormal;
和
vec3 transformedNormal = aVertexNormal * uNMatrix;
......第二个创建了这个bug,但没有任何意义......我的乘法顺序有多重要。