我已经阅读了有关此问题的先前StackOverflow帖子,但在使两个不同的着色器集在一个WebGL程序中正常工作时仍然存在问题。

下面是代码的框架。 我有两组独立的着色器,它们具有不同的变量名,以防止交叉污染。 我创建了两个initShader()函数,每个着色器集一个,然后调用initBuffers()和draw()函数。 结果是尽管着色器是在drawscene()中单独标识和调用的,但只有第二个着色器才生效,并且仅显示使用此着色器绘制的项目。

任何有关如何解决此问题的建议将不胜感激。

Declare: vertexShaderA
Declare: fragmentShaderA
Declare: vertexShaderB (use distinct variable names to that of vertexShaderA)
Declare: fragmentShaderB (use distinct variable names to that of fragmentShaderA)

// main script

initShadersA(){
…
    gl.useProgram(shaderProgramA);
…
}
initShadersB(){
…
    gl.useProgram(shaderProgramB);
…
}
…
setMatrixUniformsA();
setMatrixUniformsB();

function initBuffers(){
…
}

function drawScene(){
…
gl.bindBuffer(gl.ARRAY_BUFFER, vertexPositionBuffer);
gl.vertexAttribPointer(shaderProgramA.vertexPositionAttributeA, vertexPositionBuffer.itemSize, gl.FLOAT, false, 0, 0);
…
 gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, vertexIndexBuffer);
 gl.uniform1i(shaderProgramA.samplerUniform, 0);
 setMatrixUniformsA();
 gl.drawElements(gl.TRIANGLES, vertexIndexBuffer.numItems, gl.UNSIGNED_SHORT, 0);

…

gl.bindBuffer(gl.ARRAY_BUFFER, vertexPositionBuffer);
gl.vertexAttribPointer(shaderProgramB.vertexPositionAttributeB, vertexPositionBuffer.itemSize, gl.FLOAT, false, 0, 0);
…
gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, vertexIndexBuffer);
gl.uniform1i(shaderProgramB.samplerUniform, 0);
setMatrixUniformsB();
gl.drawElements(gl.TRIANGLES, vertexIndexBuffer.numItems, gl.UNSIGNED_SHORT, 0);
}

 function draw() {
        requestAnimFrame(draw);
        animate(); 
        drawScene();
    }       
function animate() { 
    …
} 
function webGLStart() {
        initGL(canvas);
        initShadersA();
        initShadersB();
        initBuffers();
        gl.clearColor(0.0, 0.0, 0.0, 1.0);
        gl.enable(gl.DEPTH_TEST);
        draw();
    }

#1楼 票数:8 已采纳

gl.useProgram(shaderProgram); 基本上说:“好的,从这一刻起,我将使用这种材料来遮蔽对象”。

就是说,您在webGLStart()中所做的是:initGL,使用A材质,使用B材质,创建对象,使用当前材质绘制对象(即材质B)。

OpenGL / webGL用作状态机。 当您尝试渲染某些内容时,将使用当前设置的该状态机的参数进行绘制。 例如,您说要在OpenGL上draw ,但是该方法正在寻找绑定到状态机的缓冲区,它也在寻找当前使用的材质(着色器)...等等。因此,您进行了所有设置并启动了一些操作。

因此,如果要使用两个不同的着色器渲染两个对象,则应绑定一个对象(实际上是缓冲区),使用第一个材质( gl.useProgram(shaderProgramA) )并分派绘制。 然后绑定第二个对象,设置第二个材质( gl.useProgram(shaderProgramB) )并调度另一个调用。 这就是OpenGL / WebGL的工作方式。

还有,一个建议。 尝试以其他方式命名函数。 initShadersA应该执行以下操作:获取源字符串,创建顶点和片段着色器,创建程序并链接所有内容,而诸如useShadersA功能应将当前材质设置为精确的着色器程序。

我希望这有帮助!

  ask by cadebe translate from so

未解决问题?本站智能推荐:

1回复

WebGL基本着色器混淆

我正在学习WebGL着色器,但是它们使我感到困惑。 这是我到目前为止所得到的: 到目前为止,一切顺利,它可以编译,并且我得到一个粉红色的立方体。 现在,混乱就解决了。 据我了解,片段着色器用于修改颜色,顶点着色器用于修改形状。 我不明白gl_FragColor是否设置整个
2回复

webGL着色器错误

这些着色器在我的游戏引擎中效果很好,但是当我尝试将它们与webGL一起使用时,它们会向我吐出很多错误, 那么,有人可以帮忙吗?
2回复

WebGL片段着色器可用于多个光源?

我希望能够将多个光源附加到场景图的每个节点上,但是我不知道该怎么做! 从learningwebgl.com上的教程中,我学会了使用定向照明还是位置照明,但是找不到如何实现多个光源的很好的解释。 因此,目标应该是,可以选择向每个节点附加任意数量的光源,该光源可以是定向照明或位置照明,并
1回复

如何在WebGL上向顶点着色器发送多个参数?

我正在学习OpenGL教程(因为WebGL教程很少见),它使用以下语法来表示多个参数: 但layout (location = #)语法在WebGL上不起作用。 这有什么替代品?
1回复

WebGL 着色器不尊重形状方向

我对 WebGL 非常陌生,我正在修改我在网上找到的一个现有项目以满足我的需求。 我的相机是等距的,我正在渲染两个立方体。 我想在“地面”上有一个无限网格,就像在许多 3d 编辑器中一样。 您可以在下面看到网格不是无限的(我知道这是因为顶点仅从 -1 到 1),并且它的方向不正确。 它直接在屏幕
1回复

webgl着色器-分割通道RGBA

只需将png图像的通道分开即可表示纹理散裂而不会相互融合。下面是一个代码示例,它表达了我为简单起见要实现的目标: 我已经尝试了许多变体,我只能设法获得两个纹理,但是alpha始终也是纹理,下面是图像alpha png: 我更感兴趣的是拆分通道以表示输出,只需要四个通道r,g,
3回复

在javascript中定义的webgl着色器

我看到的演示都在html中定义了着色器,并按名称获取它们。 javascript中有没有办法从字符串创建它们? 代替: 就像是:
1回复

流数据到WebGL着色器

我正在浏览器上下文中工作,摄像机图像通过二进制SocketIO通道进行流传输。 我正在处理的相机仅支持以Bayer格式(作为非常大的字节数组)输出其数据,如下所示: 我希望在浏览器的画布上实时显示相机图像流。 到目前为止,我的想法是使用WebGL作为渲染器(为了提高速度),并