2017-10-14 253 views
2

我遇到了一个试图编译片段着色器的问题。我不断收到此错误:gl_FragData必须为零

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

如果使用WebGL2我认为你必须从根本上改变你的语法,以适应GLSL 3.3标准...看看这里:http://io7m.com/documents/fso-tta/在'GLSL 3.30( OpenGL 3.3)'章节,也就是说:“在OpenGL [3.3,4.4]和OpenGL ES 3.0上,分配给指定的片段着色器输出,通过使用布局限定符将指定的输出与已编号的绘制缓冲区相关联。 – 2017-10-14 09:48:22

+2

WebGL2不支持GLSL 3.3。它支持[GLSL ES 3.0](https://www.khronos.org/registry/OpenGL/specs/es/3.0/GLSL_ES_Specification_3.00.pdf)。引用GLSL 3.3规范只会发现大量的东西不起作用,因为这是错误的规范,这会非常混乱。 – gman

回答

1

所以看起来有一些变化可以考虑从WebGL1到WebGL2。鉴于@ gman的评论,我认为最好链接到他的文章,因为我知道他真的是这里的专家。 ;)

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

我还发现它有助于记住differences版本:

WebGL 1.0 is based on OpenGL ES 2.0 and provides an API for 3D graphics. It uses the HTML5 canvas element and is accessed using Document Object Model (DOM) interfaces.

WebGL 2.0 is based on OpenGL ES 3.0 and made guaranteed availability of many optional extensions of WebGL 1.0 and exposes new APIs.

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

  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); }。但我仍然有一些问题。看来我需要指定缓冲区位置。另外,我得到这个错误:

    ERROR: must explicitly specify all locations when using multiple fragment outputs

    这意味着我需要添加#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); 
    } 
    

    在有一点我有错版本,导致了这一错误:

    invalid version directive ERROR: 0:24: 'out' : storage qualifier supported in GLSL ES 3.00 and above only

    但是我发现该版本的WebGL 2特别是#version 300 es(注意es部分),哪些工作!

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

    #version directive must occur before anything else, except for comments and white space

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

    ERROR: Shader Linking Error: Versions of linked shaders have to match.

我希望胶合这一切混乱在一起有助于节省别人很多的时间。 ;)

+0

这里没有*改变历史*。该文档与WebGL或WebGL2完全无关。这完全是关于OpenGL,它不是同一件事,它甚至与WebGL相关。 WebGL和WebGL2与OpenGL ** ES **相关。 Sedenion没有把你指向正确的方向。他指出你的方向不对。你很幸运,它帮助你解决了你的问题。答案中的第一个链接是关于OpenGL而不是OpenGL ES。 OpenGL与WebGL无关。引用它只会导致混淆。你的回答表明,你尝试了各种相关的OpenGL版本 – gman

+0

您还关联到了OpenGL ES的转换的文章,但你使用WebGL2不是OpenGL ES的,所以你真的应该寻找一个[WebGL2转换文章(https://开头webgl2fundamentals。 org/webgl/lessons/webgl1-to-webgl2.html) – gman

+0

感谢您的详细信息。在我离开它太久之后,我开始重新回到所有这一切,这完全是模糊的。写这些答案(我找不到任何好的答案)也帮助我学习。如果我早些时候遇到你的文章,我会省下很多时间,我想大声笑。 ;) –

相关问题