我在尝试编译片段着色器时遇到问题。我一直收到这个错误:
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中试用它。)
答案 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。
简而言之(也指历史上的第一个链接):
我的着色器代码是为使用扩展程序在WebGL 1(OpenGL ES 2)中看到的示例而设计的。这很好用,因为OpenGL 2.0通过gl_FragData
支持多种颜色值。
切换到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指令必须先于其他任何内容发生,但注释和空格除外
对于顶点着色器,如果为WebGL 2(ES 3)编译,请注意attribute
现在是in
。顶点着色器的版本必须与正在编译的片段的版本相匹配,否则你将得到这个:
错误:着色器链接错误:链接着色器的版本必须匹配。
我希望将所有这些混乱粘在一起有助于为其他人节省大量时间。 ;)