WebGL点光源问题



我曾尝试在WebGL中创建一个旋转立方体,并使用纹理映射技术对其进行纹理处理,我认为效果很好。立方体旋转是为了尝试和演示我试图实现的(点(照明,但它似乎以一种意想不到的方式起作用,我真的不确定是什么原因造成的。任何提示都将不胜感激,谢谢。

// Vertex shader program
var VSHADER_SOURCE = `
attribute vec4 a_Position;
attribute vec4 a_Color;
attribute vec4 a_Normal;        
attribute vec2 vertTexCoord;   
uniform mat4 u_ModelMatrix;
uniform mat4 u_NormalMatrix;
uniform mat4 u_ProjMatrix;
varying vec4 v_Color;
varying vec3 v_Normal;
varying vec2 fragTexCoord; 
varying vec3 v_Position;
void main() {
gl_Position = u_ProjMatrix * u_ModelMatrix * a_Position;
v_Normal = normalize(vec3(u_NormalMatrix * a_Normal));
v_Color = a_Color;
fragTexCoord = vertTexCoord;
}
`;
// Fragment shader program
var FSHADER_SOURCE = `
precision mediump float;
uniform sampler2D sampler;
varying vec3 v_Normal;
varying vec3 v_Position;
varying vec2 fragTexCoord;
varying vec4 v_Color;
uniform vec3 u_LightColor;
uniform vec3 u_LightPosition;
uniform vec3 u_AmbientLight;
void main() {
vec3 normal = normalize(v_Normal);
vec3 u_LightDirection = normalize(u_LightPosition - v_Position);
float nDotL = max(dot(u_LightDirection, normal), 0.0);
vec4 TexColor = texture2D(sampler, fragTexCoord);
vec3 diffuse;
diffuse = u_LightColor * TexColor.rgb * nDotL * 1.2;
vec3 ambient = u_AmbientLight * v_Color.rgb;
gl_FragColor = vec4(diffuse + ambient, v_Color.a);
}
`;
var modelMatrix = new Matrix4(); // The model matrix
var projMatrix = new Matrix4();  // The projection matrix
var g_normalMatrix = new Matrix4();  // Coordinate transformation matrix for normals
var g_xAngle = 0.0;    // The rotation x angle (degrees)
function main() {
// Retrieve <canvas> element
var canvas = document.getElementById('webgl');
canvas.width=document.body.clientWidth;
canvas.height=document.body.clientHeight;
// Get the rendering context for WebGL
gl = getWebGLContext(canvas);
if (!gl) {
console.log('Failed to get the rendering context for WebGL');
return;
}
// Initialize shaders
if (!initShaders(gl, VSHADER_SOURCE, FSHADER_SOURCE)) {
console.log('Failed to intialize shaders.');
return;
}
// Set clear color and enable hidden surface removal
gl.clearColor(1, 1, 1, 1.0);
gl.enable(gl.DEPTH_TEST);
// Clear color and depth buffer
gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
// Get the storage locations of uniform attributes
u_ModelMatrix = gl.getUniformLocation(gl.program, 'u_ModelMatrix');
u_NormalMatrix = gl.getUniformLocation(gl.program, 'u_NormalMatrix');
u_ProjMatrix = gl.getUniformLocation(gl.program, 'u_ProjMatrix');
u_LightColor = gl.getUniformLocation(gl.program, 'u_LightColor');
u_LightPosition = gl.getUniformLocation(gl.program, 'u_LightPosition');
u_AmbientLight = gl.getUniformLocation(gl.program, 'u_AmbientLight');
if (!u_ModelMatrix || !u_ProjMatrix|| !u_NormalMatrix || !u_LightColor || !u_LightPosition || !u_AmbientLight) { 
console.log('Failed to get the storage location');
return;
}

// Set the light color (white)
gl.uniform3f(u_LightColor, 1.0, 1.0, 1.0);
// Set the light direction (in the world coordinate)
gl.uniform3f(u_LightPosition, 1, 1, 1);
// Set the ambient light
gl.uniform3f(u_AmbientLight, 0.2, 0.2, 0.2);
projMatrix.setPerspective(30, canvas.width/canvas.height, 1, 100);
function render(now) {
now *= 0.001;  // convert to seconds
g_xAngle = (g_xAngle + 1) % 360
draw();
requestAnimationFrame(render);
}
requestAnimationFrame(render);
}
function initVertexBuffers(gl) {
var vertices = new Float32Array([   // Coordinates
-0.5, 0.5, -0.5,   //top
-0.5, 0.5, 0.5,  
0.5, 0.5, 0.5,  
0.5, 0.5, -0.5,
-0.5, 0.5, 0.5,  //right
-0.5,-0.5, 0.5,  
-0.5,-0.5,-0.5,  
-0.5, 0.5, -0.5,
0.5, 0.5, 0.5,   //left
0.5,-0.5, 0.5,   
0.5,-0.5,-0.5,   
0.5, 0.5,-0.5,
0.5, 0.5, 0.5,  //front
0.5, -0.5, 0.5,  
-0.5,-0.5, 0.5,   
-0.5, 0.5, 0.5,
0.5, 0.5,-0.5,  //back
0.5,-0.5,-0.5,  
-0.5, -0.5,-0.5,   
-0.5, 0.5,-0.5,
-0.5,-0.5,-0.5,  //bottom
-0.5,-0.5, 0.5,   
0.5,-0.5, 0.5,  
0.5,-0.5, -0.5,
]);
var texcoords = new Float32Array([
//u, v : u across, v down. 0,0 top left, 0,1 bottom left etc.
// Blue
0.0,  0.0,
1/3,  0.0,
1/3,  1/3,
0,  1/3,
// Green
0.0,  1/3,
1/3,  1/3,
1/3,  2/3,
0.0,  2/3,
// Orange
1/3,  1/3,
2/3,  1/3,
2/3,  2/3,
1/3,  2/3,
// Red
0.0,  2/3,
1/3,  2/3,
1/3,  1.0,
0.0,  1.0,
// White
1/3,  2/3,
2/3,  2/3,
2/3,  1.0,
1/3,  1.0,
// Yellow
2/3,  2/3,
1.0,  2/3,
1.0,  1.0,
2/3,  1.0,
])
var normals = new Float32Array([    // Normal
0.0, 0.0, 1.0,   0.0, 0.0, 1.0,   0.0, 0.0, 1.0,   0.0, 0.0, 1.0,  // v0-v1-v2-v3 front
1.0, 0.0, 0.0,   1.0, 0.0, 0.0,   1.0, 0.0, 0.0,   1.0, 0.0, 0.0,  // v0-v3-v4-v5 right
0.0, 1.0, 0.0,   0.0, 1.0, 0.0,   0.0, 1.0, 0.0,   0.0, 1.0, 0.0,  // v0-v5-v6-v1 up
-1.0, 0.0, 0.0,  -1.0, 0.0, 0.0,  -1.0, 0.0, 0.0,  -1.0, 0.0, 0.0,  // v1-v6-v7-v2 left
0.0,-1.0, 0.0,   0.0,-1.0, 0.0,   0.0,-1.0, 0.0,   0.0,-1.0, 0.0,  // v7-v4-v3-v2 down
0.0, 0.0,-1.0,   0.0, 0.0,-1.0,   0.0, 0.0,-1.0,   0.0, 0.0,-1.0   // v4-v7-v6-v5 back
]);
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
]);

// Write the vertex property to buffers (coordinates, colors and normals)
if (!initArrayBuffer(gl, 'a_Position', vertices, 3, gl.FLOAT)) return -1;
if (!initArrayBuffer(gl, 'vertTexCoord', texcoords, 2, gl.FLOAT)) return -1; 
if (!initArrayBuffer(gl, 'a_Normal', normals, 3, gl.FLOAT)) return -1;
// Write the indices to the buffer object
var indexBuffer = gl.createBuffer();
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) {
// Create a buffer object
var buffer = gl.createBuffer();
if (!buffer) {
console.log('Failed to create the buffer object');
return false;
}
// Write date into the buffer object
gl.bindBuffer(gl.ARRAY_BUFFER, buffer);
gl.bufferData(gl.ARRAY_BUFFER, data, gl.STATIC_DRAW);
// Assign the buffer object to the attribute variable
var a_attribute = gl.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;
}
var g_matrixStack = []; // Array for storing a matrix
function pushMatrix(m) { // Store the specified matrix to the array
var m2 = new Matrix4(m);
g_matrixStack.push(m2);
}
function popMatrix() { // Retrieve the matrix from the array
return g_matrixStack.pop();
}
function draw(){
gl.uniformMatrix4fv(u_ProjMatrix, false, projMatrix.elements);
// Clear color and depth buffer
gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
var n = initVertexBuffers(gl);
if (n < 0) {
console.log('Failed to set the vertex information');
return;
}
var boxTexture = setTexture(gl,'cube');
modelMatrix.setTranslate(0, 0, -5);  // Translation (No translation is supported here)
modelMatrix.rotate(g_xAngle, 1, 1, 0); // Rotate along y axis
// Model the cube
pushMatrix(modelMatrix);
modelMatrix.scale(1,1,1); // Scale
drawCube(gl, u_ModelMatrix, u_NormalMatrix, n, boxTexture);
modelMatrix = popMatrix();
}
function drawCube(gl, u_ModelMatrix, u_NormalMatrix, n, texture) {
pushMatrix(modelMatrix);
// Pass the model matrix to the uniform variable
gl.uniformMatrix4fv(u_ModelMatrix, false, modelMatrix.elements);
// Calculate the normal transformation matrix and pass it to u_NormalMatrix
g_normalMatrix.setInverseOf(modelMatrix);
g_normalMatrix.transpose();
gl.uniformMatrix4fv(u_NormalMatrix, false, g_normalMatrix.elements);
gl.bindTexture(gl.TEXTURE_2D, texture);
gl.activeTexture(gl.TEXTURE0);
gl.drawElements(gl.TRIANGLES, n, gl.UNSIGNED_BYTE, 0);
modelMatrix = popMatrix();
}

代码有3个问题

问题1:正常计算错误

v_Normal = normalize(vec3(u_NormalMatrix * a_Normal));

不会起作用。它取一个向量4a_Normal,w=1(默认值(,这意味着。您需要将a_Normal.w设置为0

v_Normal = normalize(vec3(u_NormalMatrix * vec4(a_Normal,0)));

或者只使用正常矩阵的旋转传送

v_Normal = normalize(mat3(u_NormalMatrix) * a_Normal.xyz);

注意:如果a_Normal被声明为vec3,则不需要.xyz

问题2:正常数据错误。

通过将法线添加到顶点着色器中的位置,可以很容易地进行检查

gl_Position = u_ProjMatrix * u_ModelMatrix * (a_Position + vec4(a_Normal.xyz * 0.1, 0));

在这种情况下,立方体的每个面都应该沿法线的方向移动。他们没有这样做,这表明正常情况很糟糕。

当然,作为一个立方体,只看数据也很容易。

Issse#3:代码在每帧创建一个新的纹理。

它应该创建一次纹理。

至于步骤。

  • 我让代码工作(发布工作代码很有帮助(
  • 发现你的数学库使用度数而不是弧度(这很糟糕(
  • 尝试仅使用纹理绘制

    注意:如果属性和统一位置没有显示,这是一个不失败运行的参数

    问题是我想做的只是键入gl_FragColor = TexColor,但一旦我这样做,JS代码就失败了,因为WebGL优化了所有的统一,而严格的代码也失败了。

    最好只打印一个警告,因为这样可以更容易地调试着色器。

    为了解决这个问题,我不得不总是使用每一个属性和制服通过乘以零。

    gl_FragColor = TexColor + 0. * vec4(diffuse + ambient, v_Color.a);
    

    此外,在您的示例中确实没有理由使用纹理。你可以很容易地摆脱纹理代码或使用1像素的白色纹理。堆栈溢出要求您发布最小示例是有原因的。

  • 尝试只绘制法线

    gl_FragColor = normal * 0.5 + 0.5 + 0. * ....
    

    很难看出发生了什么,所以将代码更改为仅围绕Y 旋转

    modelMatrix.rotate(g_xAngle, /* 1 */ 0, 1, 0); 
    

    当它们面向同一个方向时,颜色应该总是相同的。事实并非如此。

  • 这就引出了另外两个问题。

const m4 = twgl.m4;
class Matrix4 {
constructor() {
this.elements = m4.identity();
}
setPerspective(fov, aspect, near, far) {
m4.perspective(fov * Math.PI / 180, aspect, near, far, this.elements);
}
setTranslate(x, y, z) {
m4.translation([x, y, z], this.elements);
}
rotate(angle, x, y, z) {
m4.axisRotate(this.elements, [x, y, z], angle * Math.PI / 180, this.elements);
}
scale(x, y, z) {
m4.scale(this.elements, [x, y, z], this.elements);
}
setInverseOf(src) {
m4.inverse(src.elements, this.elements);
}
transpose() {
m4.transpose(this.elements, this.elements);
}
}
{
const ctx = document.querySelector('#cube').getContext('2d');
for (let i = 0; i < 9; ++i) {
ctx.fillStyle = `hsl(${i *360 / 9},100%,50%)`;
ctx.fillRect(i % 3 * 100, (i / 3 | 0) * 50, 100, 50);
}
}
let boxTexture;
// Vertex shader program
var VSHADER_SOURCE = `
attribute vec4 a_Position;
attribute vec4 a_Color;
attribute vec4 a_Normal;        
attribute vec2 vertTexCoord;   
uniform mat4 u_ModelMatrix;
uniform mat4 u_NormalMatrix;
uniform mat4 u_ProjMatrix;
varying vec4 v_Color;
varying vec3 v_Normal;
varying vec2 fragTexCoord; 
varying vec3 v_Position;
void main() {
gl_Position = u_ProjMatrix * u_ModelMatrix * a_Position;
v_Position = (u_ModelMatrix * a_Position).xyz;
v_Normal = normalize(mat3(u_ModelMatrix) * a_Normal.xyz);
v_Color = a_Color + u_NormalMatrix[0][0] * 0.;
fragTexCoord = vertTexCoord;
}
`;
// Fragment shader program
var FSHADER_SOURCE = `
precision highp float;
uniform sampler2D sampler;
varying vec3 v_Normal;
varying vec3 v_Position;
varying vec2 fragTexCoord;
varying vec4 v_Color;
uniform vec3 u_LightColor;
uniform vec3 u_LightPosition;
uniform vec3 u_AmbientLight;
void main() {
vec3 normal = normalize(v_Normal);
vec3 u_LightDirection = normalize(u_LightPosition - v_Position);
float nDotL = max(dot(u_LightDirection, normal), 0.0);
vec4 TexColor = texture2D(sampler, fragTexCoord);
vec3 diffuse;
diffuse = u_LightColor * TexColor.rgb * nDotL * 1.2;
vec3 ambient = u_AmbientLight * v_Color.rgb;
gl_FragColor = vec4(diffuse + ambient, v_Color.a);
}
`;
var modelMatrix = new Matrix4(); // The model matrix
var projMatrix = new Matrix4();  // The projection matrix
var g_normalMatrix = new Matrix4();  // Coordinate transformation matrix for normals
var g_xAngle = 0.0;    // The rotation x angle (degrees)
function main() {
// Retrieve <canvas> element
var canvas = document.getElementById('webgl');
canvas.width=document.body.clientWidth;
canvas.height=document.body.clientHeight;
// Get the rendering context for WebGL
gl = getWebGLContext(canvas);
if (!gl) {
console.log('Failed to get the rendering context for WebGL');
return;
}
// Initialize shaders
if (!initShaders(gl, VSHADER_SOURCE, FSHADER_SOURCE)) {
console.log('Failed to intialize shaders.');
return;
}
// Set clear color and enable hidden surface removal
gl.clearColor(1, 1, 1, 1.0);
gl.enable(gl.DEPTH_TEST);
// Clear color and depth buffer
gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
// Get the storage locations of uniform attributes
u_ModelMatrix = gl.getUniformLocation(gl.program, 'u_ModelMatrix');
u_NormalMatrix = gl.getUniformLocation(gl.program, 'u_NormalMatrix');
u_ProjMatrix = gl.getUniformLocation(gl.program, 'u_ProjMatrix');
u_LightColor = gl.getUniformLocation(gl.program, 'u_LightColor');
u_LightPosition = gl.getUniformLocation(gl.program, 'u_LightPosition');
u_AmbientLight = gl.getUniformLocation(gl.program, 'u_AmbientLight');
if (!u_ModelMatrix || !u_ProjMatrix|| !u_NormalMatrix || !u_LightColor || !u_LightPosition || !u_AmbientLight) { 
console.log('Failed to get the storage location');
return;
}
// Set the light color (white)
gl.uniform3f(u_LightColor, 1.0, 1.0, 1.0);
// Set the light direction (in the world coordinate)
gl.uniform3f(u_LightPosition, 1, 1, 1);
// Set the ambient light
gl.uniform3f(u_AmbientLight, 0.2, 0.2, 0.2);
projMatrix.setPerspective(30, canvas.width/canvas.height, 1, 100);

boxTexture = setTexture(gl,'cube');
function render(now) {
now *= 0.001;  // convert to seconds
g_xAngle = (g_xAngle + 1) % 360
draw();
requestAnimationFrame(render);
}
requestAnimationFrame(render);
}
function setTexture(gl, texturetype){
var texture = gl.createTexture();
gl.bindTexture(gl.TEXTURE_2D, texture);
gl.texImage2D(
gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA,
gl.UNSIGNED_BYTE, document.getElementById(texturetype)
);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR);
gl.bindTexture(gl.TEXTURE_2D, null);
return texture;
}
function initVertexBuffers(gl) {
var vertices = new Float32Array([   // Coordinates
-0.5, 0.5, -0.5,   //top
-0.5, 0.5, 0.5,  
0.5, 0.5, 0.5,  
0.5, 0.5, -0.5,
-0.5, 0.5, 0.5,  //right
-0.5,-0.5, 0.5,  
-0.5,-0.5,-0.5,  
-0.5, 0.5, -0.5,
0.5, 0.5, 0.5,   //left
0.5,-0.5, 0.5,   
0.5,-0.5,-0.5,   
0.5, 0.5,-0.5,
0.5, 0.5, 0.5,  //front
0.5, -0.5, 0.5,  
-0.5,-0.5, 0.5,   
-0.5, 0.5, 0.5,
0.5, 0.5,-0.5,  //back
0.5,-0.5,-0.5,  
-0.5, -0.5,-0.5,   
-0.5, 0.5,-0.5,
-0.5,-0.5,-0.5,  //bottom
-0.5,-0.5, 0.5,   
0.5,-0.5, 0.5,  
0.5,-0.5, -0.5,
]);
var texcoords = new Float32Array([
//u, v : u across, v down. 0,0 top left, 0,1 bottom left etc.
// Blue
0.0,  0.0,
1/3,  0.0,
1/3,  1/3,
0,  1/3,
// Green
0.0,  1/3,
1/3,  1/3,
1/3,  2/3,
0.0,  2/3,
// Orange
1/3,  1/3,
2/3,  1/3,
2/3,  2/3,
1/3,  2/3,
// Red
0.0,  2/3,
1/3,  2/3,
1/3,  1.0,
0.0,  1.0,
// White
1/3,  2/3,
2/3,  2/3,
2/3,  1.0,
1/3,  1.0,
// Yellow
2/3,  2/3,
1.0,  2/3,
1.0,  1.0,
2/3,  1.0,
])
var normals = new Float32Array([    // Normal
0.0, 1.0, 0.0,   0.0, 1.0, 0.0,   0.0, 1.0, 0.0,   0.0, 1.0, 0.0,  // v0-v5-v6-v1 up
-1.0, 0.0, 0.0,  -1.0, 0.0, 0.0,  -1.0, 0.0, 0.0,  -1.0, 0.0, 0.0,  // v1-v6-v7-v2 left
1.0, 0.0, 0.0,   1.0, 0.0, 0.0,   1.0, 0.0, 0.0,   1.0, 0.0, 0.0,  // v0-v3-v4-v5 right
0.0, 0.0, 1.0,   0.0, 0.0, 1.0,   0.0, 0.0, 1.0,   0.0, 0.0, 1.0,  // v0-v1-v2-v3 front
0.0, 0.0,-1.0,   0.0, 0.0,-1.0,   0.0, 0.0,-1.0,   0.0, 0.0,-1.0,   // v4-v7-v6-v5 back
0.0,-1.0, 0.0,   0.0,-1.0, 0.0,   0.0,-1.0, 0.0,   0.0,-1.0, 0.0,  // v7-v4-v3-v2 down
]);
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
]);
// Write the vertex property to buffers (coordinates, colors and normals)
if (!initArrayBuffer(gl, 'a_Position', vertices, 3, gl.FLOAT)) return -1;
if (!initArrayBuffer(gl, 'vertTexCoord', texcoords, 2, gl.FLOAT)) return -1; 
if (!initArrayBuffer(gl, 'a_Normal', normals, 3, gl.FLOAT)) return -1;
// Write the indices to the buffer object
var indexBuffer = gl.createBuffer();
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) {
// Create a buffer object
var buffer = gl.createBuffer();
if (!buffer) {
console.log('Failed to create the buffer object');
return false;
}
// Write date into the buffer object
gl.bindBuffer(gl.ARRAY_BUFFER, buffer);
gl.bufferData(gl.ARRAY_BUFFER, data, gl.STATIC_DRAW);
// Assign the buffer object to the attribute variable
var a_attribute = gl.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;
}
var g_matrixStack = []; // Array for storing a matrix
function pushMatrix(m) { // Store the specified matrix to the array
var m2 = new Matrix4(m);
g_matrixStack.push(m2);
}
function popMatrix() { // Retrieve the matrix from the array
return g_matrixStack.pop();
}
function draw(){
gl.uniformMatrix4fv(u_ProjMatrix, false, projMatrix.elements);
// Clear color and depth buffer
gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
var n = initVertexBuffers(gl);
if (n < 0) {
console.log('Failed to set the vertex information');
return;
}
modelMatrix.setTranslate(0, 0, -5);  // Translation (No translation is supported here)
modelMatrix.rotate(g_xAngle, 1, 1, 0); // Rotate along y axis
// Model the cube
pushMatrix(modelMatrix);
modelMatrix.scale(1,1,1); // Scale
drawCube(gl, u_ModelMatrix, u_NormalMatrix, n, boxTexture);
modelMatrix = popMatrix();
}
function drawCube(gl, u_ModelMatrix, u_NormalMatrix, n, texture) {
pushMatrix(modelMatrix);
// Pass the model matrix to the uniform variable
gl.uniformMatrix4fv(u_ModelMatrix, false, modelMatrix.elements);
// Calculate the normal transformation matrix and pass it to u_NormalMatrix
g_normalMatrix.setInverseOf(modelMatrix);
g_normalMatrix.transpose();
gl.uniformMatrix4fv(u_NormalMatrix, false, g_normalMatrix.elements);
gl.bindTexture(gl.TEXTURE_2D, texture);
gl.activeTexture(gl.TEXTURE0);
gl.drawElements(gl.TRIANGLES, n, gl.UNSIGNED_BYTE, 0);
modelMatrix = popMatrix();
}
function getWebGLContext(canvas) { return canvas.getContext('webgl'); }
function initShaders(gl, vs, fs) { 
// This is BAD!!!!!!! Real WebGL apps have more than one program
// adding properties to builtins is bad as well.
gl.program = twgl.createProgram(gl, [vs, fs]); 
// This is BAD!!!!!!!
gl.useProgram(gl.program);
return gl.program;
}
main();
<script src="https://twgljs.org/dist/4.x/twgl-full.min.js"></script>
<canvas id="webgl"></canvas>
<canvas id="cube" style="display: none;"></canvas>

我还应该指出,你没有提供顶点颜色,这意味着环境颜色正在乘以0,0,0。

您可能会发现这些教程很有帮助。

最新更新