WebGL复现重叠三角形渲染失败问题排查 待实现Z缓冲或画家算法
故障原因排查
你代码中的错误主要集中在属性匹配、常量拼写、数据格式三个方面,具体如下:
- 属性名不匹配:顶点着色器中声明的顶点位置属性名为
a_Position、颜色属性名为a_Color,但调用gl.getAttribLocation时传入的是"position"和"color",导致无法正确获取属性地址,顶点数据无法传入着色器 - 顶点数据分量不匹配:你顶点着色器里声明
a_Position为vec2(2分量),但调用gl.vertexAttribPointer设置位置属性时传入的分量数是3,导致顶点数据读取错位 - 清屏常量拼写错误:
gl.cbuffer_BIT是无效常量,正确的颜色缓冲区常量是gl.COLOR_BUFFER_BIT - 背景色设置错误:当前
gl.clearColor设置的是灰色背景,你需要的黑色背景应改为gl.clearColor(0, 0, 0, 1) - 程序激活顺序错误:
gl.useProgram需要在设置顶点属性、调用绘制接口之前执行,否则属性设置不会作用到当前激活的着色器程序上 - 颜色数组长度不匹配:原代码每个三角形对应的颜色值多写了一组,和顶点数量无法对应
修复后完整代码
<!doctype html> <html> <body> <canvas width = "500" height = "500" id = "canvas"></canvas> <script> var canvas = document.getElementById('canvas'); gl = canvas.getContext('webgl'); var positions = [ 0, 1, -1, -1, 1, -1, -1, -1, -0, -1, -1, -0.5, 1, -1, 0, -1, 1, -0.5, 1, 1, 0, 1, 1, -1, -1, 1, -1, 0, -0, 1 ]; var colors = [ 1,0,1, 1,0,1, 1,0,1, //purple 0,0,1, 0,0,1, 0,0,1, //blue 1,1,0, 1,1,0, 1,1,0, //yellow 1,0,0, 1,0,0, 1,0,0, //red 0,1,0, 0,1,0, 0,1,0 //green ]; //vertex buffer var vbuffer = gl.createBuffer (); gl.bindBuffer(gl.ARRAY_BUFFER, vbuffer); gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(positions), gl.STATIC_DRAW); //color buffer var cbuffer = gl.createBuffer (); gl.bindBuffer(gl.ARRAY_BUFFER, cbuffer); gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(colors), gl.STATIC_DRAW); //shaders var vCode = ` attribute vec2 a_Position; attribute vec3 a_Color; varying vec3 v_Color; void main() { gl_Position = vec4(a_Position, 0.0, 1.0); v_Color = a_Color; }`; var fragCode = ` precision mediump float; varying vec3 v_Color; void main() { gl_FragColor = vec4(v_Color, 1.0); }`; //vertex shader var vShader = gl.createShader(gl.VERTEX_SHADER); gl.shaderSource(vShader, vCode); gl.compileShader(vShader); //fragment shader var fShader = gl.createShader(gl.FRAGMENT_SHADER); gl.shaderSource(fShader, fragCode); gl.compileShader(fShader); var shaders = gl.createProgram(); gl.attachShader(shaders, vShader); gl.attachShader(shaders, fShader); gl.linkProgram(shaders); // 先激活着色器程序 gl.useProgram(shaders); //vertex buffer gl.bindBuffer(gl.ARRAY_BUFFER, vbuffer); var _position = gl.getAttribLocation(shaders, "a_Position"); gl.vertexAttribPointer(_position, 2, gl.FLOAT, false,0,0); gl.enableVertexAttribArray(_position); //color buffer gl.bindBuffer(gl.ARRAY_BUFFER, cbuffer); var _color = gl.getAttribLocation(shaders, "a_Color"); gl.vertexAttribPointer(_color, 3, gl.FLOAT, false,0,0) ; gl.enableVertexAttribArray(_color); //depth testing gl.disable(gl.DEPTH_TEST); gl.enable(gl.BLEND); // 补充混合因子,后续处理重叠时可根据需要调整 gl.blendFunc(gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA); gl.depthMask(gl.FALSE); //clears buffer gl.clearColor(0, 0, 0, 1); // 黑色背景 gl.clearDepth(1.0); gl.viewport(0, 0, canvas.width, canvas.height); gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT); gl.drawArrays(gl.TRIANGLES, 0, 15); </script> </body> </html>
内容的提问来源于stack exchange,提问作者KillerSheltie
相关产品推荐
相关产品推荐

