3d 切换GLSL程序时的WebGL状态管理

3d 切换GLSL程序时的WebGL状态管理,3d,glsl,webgl,3d,Glsl,Webgl,因此,这是一个有点模糊的问题,可能是因为我对WebGL(OpenGL)的内部知识仍然有限(但正在提高),特别是在GL上下文中管理状态的方式。请让我澄清或/并添加更多细节。因为我不知道问题出在哪里,所以我尽可能多地提供信息 我遇到了这样一种情况,我在一个小小的渲染引擎中执行拾取。 当我有一个简单的着色器,其中每个对象都以恒定的颜色渲染时,一切都很好。 每个对象有2个缓冲区,一个数组缓冲区和一个元素数组缓冲区。 拾取方面通过一个附加的帧缓冲区实现,其中使用“拾取”着色器将场景渲染到该帧缓冲区。当我需

因此,这是一个有点模糊的问题,可能是因为我对WebGL(OpenGL)的内部知识仍然有限(但正在提高),特别是在GL上下文中管理状态的方式。请让我澄清或/并添加更多细节。因为我不知道问题出在哪里,所以我尽可能多地提供信息

我遇到了这样一种情况,我在一个小小的渲染引擎中执行拾取。 当我有一个简单的着色器,其中每个对象都以恒定的颜色渲染时,一切都很好。 每个对象有2个缓冲区,一个数组缓冲区和一个元素数组缓冲区。 拾取方面通过一个附加的帧缓冲区实现,其中使用“拾取”着色器将场景渲染到该帧缓冲区。当我需要渲染拾取帧时,我切换到备用帧缓冲区,然后切换到拾取着色器(gl.useProgram()),渲染场景,然后切换回默认画布帧缓冲区。然后,我读取单击画布坐标处的像素值,并使用该值查找特定元素的ID。。。作为调试步骤,我甚至将整个帧缓冲区渲染到一个单独的画布上,并在DOM中显示该画布,以查看in是否确实正确地渲染了内容

当我打开顶点着色时,麻烦就来了。颜色值按顶点指定,并作为VertexAttributeArray(与顶点坐标相同)传递到着色器中。但是,启用着色后,拾取渲染不会渲染任何内容(输出为空白的白色屏幕)

我已经隔离了导致出现此错误的着色函数部分(拾取帧的空白渲染):

因此,很明显,在这些行中设置了一些GL状态,也就是说,当着色器从顶点着色着色器(正确显示事物)切换到拾取着色器时,导致场景无法渲染。 我认为我的顶点变换可能有问题,但是着色着色器和拾取着色器之间是相同的,但是着色着色器显示得很好,而拾取着色器则没有


请让我知道我还需要包括什么,以使这个问题更清楚。我花了好几天的时间试着调试这个,但仍然没有任何想法。(注:代码是用Dart编写的)

可能“color\u attr\u location”和拾取着色器中的某些属性共享同一位置(很难从该代码中分辨),因此在指定数组时,一个属性替换另一个属性。如果只设置一次阵列,然后切换程序,而不重新设置阵列,那么问题很可能就出在这里

在WebGL中,您需要在每次绘制调用之前手动设置顶点数组(与使用顶点数组对象相反),这意味着最好的做法是在调用之后再次禁用它们


使用程序->设置数组->渲染->禁用数组->使用其他程序->设置数组

所以我听到了响铃。。。我会根据这个问题答案的建议稍微改变一下,并将结果发布在这里。。。(特别是答案的结论“基本上,你想把每次改变计划都当作是第一次打平局。”)是的,这确实是个问题。现在,每次更改shadergreat时,我都会设置顶点数组属性。谢谢你的信息。。。这也是我在阅读了另一个问题的答案后所怀疑的。是的,“颜色属性”和“拾取颜色属性”(在拾取着色器中)共享相同的位置(1),尽管其中一个作为属性数组传入,而另一个是单个浮点值。。。但是,是的,我只设置一次数组并多次切换程序。单浮点值应作为统一值而不是属性传递,这可能会在以后给您带来问题。是的,我将单浮点值作为统一值传递。。。虽然我很好奇为什么使用属性会引起问题。属性是逐顶点的,这就是为什么它们使用数组。可以将单个浮点作为属性传递,但需要每个顶点复制一次浮点。
Buffer vertex_color_buffer = gl.createBuffer();
gl.bindBuffer(RenderingContext.ARRAY_BUFFER,vertex_color_buffer);

gl.bufferData(RenderingContext.ARRAY_BUFFER,
              new Float32List.fromList(unpacked_colors_lst), 
              RenderingContext.STATIC_DRAW); 

int color_attr_location = gl.getAttribLocation(p_shader, 
                                               "a_vertex_color");
gl.enableVertexAttribArray(color_attr_location);    
gl.vertexAttribPointer(color_attr_location,
                       4,
                       RenderingContext.FLOAT, 
                       false, 
                       4*Float32List.BYTES_PER_ELEMENT, //stride
                       0);                              //offset within the buffer