3

我在尝试编译片段着色器时遇到问题。我不断收到此错误:

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 中尝试)。

4

1 回答 1

3

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

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

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

WebGL 1.0 基于 OpenGL ES 2.0 并为 3D 图形提供 API。它使用 HTML5 画布元素并使用文档对象模型 (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部分),它有效!

    注意:版本说明符必须在第一行,不幸的是,不能在预处理器指令中(即#ifdef),所以我必须在发送它进行编译之前动态更改字符串。如果没有,你会得到这个:

    #version 指令必须出现在其他任何内容之前,注释和空格除外

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

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

我希望将所有这些混淆在一起有助于节省其他人的大量时间。;)

于 2017-10-14T14:22:38.240 回答