只有第一次调用才能在具有相同顶点缓冲区的多个drawElements调用中工作

时间:2015-04-13 09:57:48

标签: javascript graphics 3d webgl shader

我正在尝试使用具有不同光源的多个drawElement调用在多个光源下渲染模型。代码的要点如下。

    this.setUniform("u_matrix", "Matrix4fv", false, matrix);
    this.setUniform("u_nMatrix", "Matrix3fv", false, nMatrix);

    this.setUniform("u_kSpecular", "3fv", material.specular);
    this.setUniform("u_kDiffuse", "3fv", material.diffuse);
    this.setUniform("u_kAmbient", "3fv", material.ambient);
    this.setUniform("u_shininess", "1f", material.shininess);

    this.setVertexAttribArray("a_position", new Float32Array(mesh.vertices), 3);
    this.setVertexAttribArray("a_normal", new Float32Array(mesh.vertexNormals), 3);
    this.setElementArray(new Uint16Array(mesh.indices));

    for(var i = 0;i < lights.length;i++) {
        if(i == 1) {
            gl.enable(gl.BLEND);
            gl.blendFunc(gl.ONE, gl.ONE);
            gl.blendEquation(gl.FUNC_ADD);
        }
        var light = lights[i];
        console.dir(light);
        this.setUniform("u_lightType", "1i", light.type);
        this.setUniform("u_lightVector", "3fv", light.vector);
        this.setUniform("u_lightColor", "3fv", light.color);
        gl.drawElements(gl.TRIANGLES, mesh.indices.length, gl.UNSIGNED_SHORT, 0);
    }
    gl.disable(gl.BLEND);

这里的问题是只渲染第一个灯光。后续的drawElements不会呈现任何内容。我认为问题不在于我的着色器代码,因为即使我将着色器剥离为仅设置等于灯光类型或某些此类参数的片段颜色,问题仍然存在。

setUniform setVertexAttribArraysetElementArray是我写过的一些助手。他们基本上看起来像这样:

setElementArray: function(array) {
    var gl = this.gl;
    var buffer = this._arrBuffers.__indexBuffer;
    if(_.isUndefined(buffer)) {
        buffer = gl.createBuffer();
        this._arrBuffers.__indexBuffer = buffer;
    }
    gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, buffer);
    gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, array, gl.STATIC_DRAW);
}

setVertexAttribArray: function(name, array, size, type, normalized, stride, offset) {
    var gl = this.gl;
    size = size || 2;
    type = type || gl.FLOAT;
    normalized = normalized || false;
    stride = stride || 0;
    offset = offset || 0;

    var buffer = this._arrBuffers[name];
    if(_.isUndefined(buffer)) {
        buffer = gl.createBuffer();
        this._arrBuffers[name] = buffer;
    }
    var location = this.getLocation(name, true);

    gl.bindBuffer(gl.ARRAY_BUFFER, buffer);
    gl.bufferData(gl.ARRAY_BUFFER, array, gl.STATIC_DRAW);
    gl.enableVertexAttribArray(location);
    gl.vertexAttribPointer(location, size, type, normalized, stride, offset);
}

1 个答案:

答案 0 :(得分:1)

我找到了解决方案。我设置了gl.depthFunc(gl.LESS),因此后续渲染未通过深度测试。设置gl.depthFunc(gl.LEQUAL)解决了问题。