WebGL魔方添加法线实现光照时出现显示异常求助
魔方添加法线后显示异常的修复方案
核心问题分析与修复
1. Buffer绑定与顶点属性设置顺序错误
在dibujar函数中,连续绑定ARRAY_BUFFER会覆盖当前绑定对象,导致后续vertexAttribPointer调用都指向最后绑定的normalBuffer——这会让颜色属性错误读取法线数据,完全打乱渲染结果。
修复后代码:
dibujar(program) { if (typeof this.positionBuffer === 'undefined') { // 初始化buffer的原有代码保持不变 } // 绑定位置Buffer并设置对应顶点属性 gl.bindBuffer(gl.ARRAY_BUFFER, this.positionBuffer); gl.vertexAttribPointer(program.positionLocation, 3, gl.FLOAT, false, 0, 0); // 绑定颜色Buffer并设置对应顶点属性 gl.bindBuffer(gl.ARRAY_BUFFER, this.colorBuffer); gl.vertexAttribPointer(program.colorLocation, 4, gl.FLOAT, false, 0, 0); // 绑定法线Buffer并设置对应顶点属性 gl.bindBuffer(gl.ARRAY_BUFFER, this.normalBuffer); gl.vertexAttribPointer(program.normalAttributeLocation, 3, gl.FLOAT, false, 0, 0); gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, this.indexBuffer); gl.uniformMatrix4fv(program.matrixLocation, false, this.matrix); gl.drawElements(gl.TRIANGLES, this.indices.length, gl.UNSIGNED_SHORT, 0); }
2. 颜色数组初始化问题
this.colores通过索引赋值时,未被赋值的位置会保留undefined,转成Float32Array时会变为NaN,导致部分面颜色异常或透明。
修复后代码:
在Cubo构造函数中,先初始化颜色数组为全透明黑色,再覆盖需要的颜色:
// 替换原有this.colores = []; this.colores = new Array(24 * 4).fill(0); // 24个顶点,每个顶点4个RGBA分量 // 后续颜色赋值逻辑保持不变
3. Program类中的拼写错误
viexMatrix是viewMatrix的拼写错误,导致视图矩阵Uniform无法正确设置。
修复后代码:
class Program{ constructor(){ // 原有代码不变 this.viewMatrix = new Mat4([ // 修正拼写 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0 ]); // 原有代码不变 } setViewMat( new_view_mat ){ this.viewMatrix = new_view_mat; gl.uniformMatrix4fv(this.viewMatrixLocation, false, this.viewMatrix); // 使用this而非全局program,修正拼写 } // setProjMat方法保持不变 }
4. 法线矩阵优化(可选)
如果模型矩阵包含非等比例缩放,mat3(u_viewMatrix * u_matrix)会导致法线方向错误,需要使用逆转置矩阵。可以修改顶点着色器:
// 替换原有法线计算代码 v_normal = transpose(inverse(mat3(u_viewMatrix * u_matrix))) * a_normal;
若仅为等比例缩放,当前代码可正常工作,但添加逆转置能兼容所有缩放场景。
验证效果
修复以上问题后,魔方颜色会恢复正常,法线可正确参与光照计算,呈现符合预期的光影效果。
内容的提问来源于stack exchange,提问作者PAULA HERNANDEZ LOZANO
相关产品推荐
相关产品推荐

