【问题标题】:Switch shader program in WebGL在 WebGL 中切换着色器程序
【发布时间】:2012-02-05 03:48:38
【问题描述】:

我有一个现有的 WebGL 渲染器(太多代码无法共享),它曾经非常简单:它只有一个顶点着色器、一个片段着色器和一个着色器程序,两者兼有。用于渲染四边形。

我正在尝试对其进行扩展,使其具有第二个可以切换的着色器程序,用于渲染点精灵。它有自己的顶点属性数组,以及第二个顶点着色器、片段着色器和着色器程序。

我似乎无法在两者之间正确切换:我不断收到显示故障、随机消失的对象等等。这是我必须在它们之间切换的两个功能。知道我错过了什么吗?

GLWrapProto.switchQuadProgram = function ()
{
    var gl = this.gl;

    gl.useProgram(this.shaderProgramPoint);

    gl.disableVertexAttribArray(this.locAPosPoint);

    gl.useProgram(this.shaderProgram);

    gl.enableVertexAttribArray(this.locAPos);
    gl.bindBuffer(gl.ARRAY_BUFFER, this.vertexBuffer);
    gl.vertexAttribPointer(this.locAPos, 2, gl.FLOAT, false, 0, 0);

    gl.enableVertexAttribArray(this.locATex);
    gl.bindBuffer(gl.ARRAY_BUFFER, this.texcoordBuffer);
    gl.vertexAttribPointer(this.locATex, 2, gl.FLOAT, false, 0, 0);
};

GLWrapProto.switchPointProgram = function ()
{
    var gl = this.gl;

    gl.useProgram(this.shaderProgram);

    gl.disableVertexAttribArray(this.locAPos);
    gl.disableVertexAttribArray(this.locATex);

    gl.useProgram(this.shaderProgramPoint);

    gl.enableVertexAttribArray(this.locAPosPoint);
    gl.bindBuffer(gl.ARRAY_BUFFER, this.pointBuffer);
    gl.vertexAttribPointer(this.locAPosPoint, 4, gl.FLOAT, false, 0, 0);
};

【问题讨论】:

    标签: javascript glsl shader webgl


    【解决方案1】:

    从那段代码中很难判断问题出在哪里,但让我提出一些建议来帮助您找到问题。

    首先,您不必担心每次切换着色器时都执行 disableVertexAttribArray。启用/禁用数组是与着色器相关联的状态,因此更改绑定程序无论如何都会使您之前启用的数组无效。

    (实际上,有没有人知道一个像样的引文,我正试图找到一个,但目前找不到。)

    考虑到这一点,您可以将上述代码简化为:

    GLWrapProto.switchQuadProgram = function ()
    {
        var gl = this.gl;
    
        gl.useProgram(this.shaderProgram);
    
        gl.enableVertexAttribArray(this.locAPos);
        gl.bindBuffer(gl.ARRAY_BUFFER, this.vertexBuffer);
        gl.vertexAttribPointer(this.locAPos, 2, gl.FLOAT, false, 0, 0);
    
        gl.enableVertexAttribArray(this.locATex);
        gl.bindBuffer(gl.ARRAY_BUFFER, this.texcoordBuffer);
        gl.vertexAttribPointer(this.locATex, 2, gl.FLOAT, false, 0, 0);
    };
    
    GLWrapProto.switchPointProgram = function ()
    {
        var gl = this.gl;
    
        gl.useProgram(this.shaderProgramPoint);
    
        gl.enableVertexAttribArray(this.locAPosPoint);
        gl.bindBuffer(gl.ARRAY_BUFFER, this.pointBuffer);
        gl.vertexAttribPointer(this.locAPosPoint, 4, gl.FLOAT, false, 0, 0);
    };
    

    不过,我很好奇您提到的“显示故障”问题。我想不出切换着色器会导致对象随机停止并开始渲染的任何原因。尝试首先使用一个着色器仅渲染几何体,然后切换并仅渲染使用另一个着色器的几何体。如果其中任何一个有问题,那么您就知道不是着色器切换导致了您的问题。如果只在同时渲染两组几何体时出现问题,则可能是两者之间的状态管理存在一些错误。

    【讨论】:

    • 感谢您的帮助 - 他们自己工作得很好,当场景在两个渲染之间切换时,有些东西会消失。所以我认为正如你所说,两者之间的状态管理存在问题。我很好奇您对 disableVertexAttribArray 的评论 - 我假设程序的状态持续存在!准确调用 useProgram 时会丢失什么状态?我找不到任何关于它的文档,我想那里丢失的某些状态会导致问题!
    猜你喜欢
    • 1970-01-01
    • 2013-05-02
    • 1970-01-01
    • 2017-04-08
    • 2014-03-24
    • 1970-01-01
    • 1970-01-01
    • 2017-07-03
    • 1970-01-01
    相关资源
    最近更新 更多