gl_FragData必须为常数零

时间:2017-10-14 04:17:44

标签: webgl webgl2

我在尝试编译片段着色器时遇到问题。我一直收到这个错误:

Uncaught Error: Fragment Shader Compiler Error: ERROR: 0:21: '[' :
array index for gl_FragData must be constant zero ERROR: 0:21: '[' :
array index for gl_FragData must be constant zero ERROR: 0:21: '[' :
array index for gl_FragData must be constant zero

这是代码:

#ifdef GL_EXT_draw_buffers
#extension GL_EXT_draw_buffers : require
#endif
#ifdef GL_ES
precision highp float;
#endif
void main() {
    gl_FragData[0] = vec4(1.,2.,3.,4.);
    gl_FragData[1] = vec4(1.,2.,3.,4.);
    gl_FragData[2] = vec4(1.,2.,3.,4.);
    gl_FragData[3] = vec4(1.,2.,3.,4.);
}

如果我设置gl_FragColor(将4个纹理附加到帧缓冲区),整个设置工作正常,但尝试执行上面的代码(索引缓冲区以输出到)似乎无法编译。我已经看到这在使用扩展的WebGL1中正常工作。我正在使用WebGL2,所以在这种情况下可能会有所不同? (我在最新版本的Chrome中试用它。)

1 个答案:

答案 0 :(得分:2)

因此,考虑从WebGL1到WebGL2会出现一些变化。鉴于@ gman的评论,我认为最好链接到他的文章,因为我知道他真的是这里的专家。 ;)

WebGL 1到WebGL 2的转换:https://webgl2fundamentals.org/webgl/lessons/webgl1-to-webgl2.html

我还发现记住版本differences很有帮助:

  

WebGL 1.0基于OpenGL ES 2.0并提供3D API   图形。它使用HTML5 canvas元素并使用   文档对象模型(DOM)接口。

     

WebGL 2.0基于OpenGL ES 3.0,保证了可用性   WebGL 1.0的许多可选扩展,并公开新的API。

简而言之(也指历史上的第一个链接):

  1. 我的着色器代码是为使用扩展程序在WebGL 1(OpenGL ES 2)中看到的示例而设计的。这很好用,因为OpenGL 2.0通过gl_FragData支持多种颜色值。

  2. 切换到WebGL 2(OpenGL ES 3)时,这会以不同的方式折旧。现在需要out声明,例如out vec4 out_0; main(void) { out_0 = vec4(1.0, 0.0, 0.0, 1.0); }。但我还是遇到了一些问题。我似乎需要指定缓冲区位置。另外,我收到了这个错误:

      

    错误:使用多个片段输出时必须明确指定所有位置

    这意味着我需要将#version 300 es添加到我的程序顶部,因此WebGL 2的正确代码看起来更像是这样:

    #version 300 es
    layout(location = 0) out vec4 out_0;
    layout(location = 1) out vec4 out_1;
    main(void) {
        out_0 = vec4(1.0, 0.0, 0.0, 1.0);
        out_1 = vec4(1.0, 0.0, 0.0, 1.0);
    }
    

    有一次,我的版本错误,导致了这个错误:

      

    无效的版本指令错误:0:24:' out' :存储限定符   仅在GLSL ES 3.00及以上版本中支持

    但是我发现WebGL 2的版本具体是#version 300 es(注意es部分),这是有效的!

    注意:版本说明符必须在FIRST行上,并且遗憾的是,它不能在预处理程序指令中(即#ifdef),因此我必须在发送字符串之前动态更改字符串以进行编译。如果没有,你会得到这个:

      

    #version指令必须先于其他任何内容发生,但注释和空格除外

  3. 对于顶点着色器,如果为WebGL 2(ES 3)编译,请注意attribute现在是in。顶点着色器的版本必须与正在编译的片段的版本相匹配,否则你将得到这个:

      

    错误:着色器链接错误:链接着色器的版本必须匹配。

  4. 我希望将所有这些混乱粘在一起有助于为其他人节省大量时间。 ;)