2017-10-14 103 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

感謝您的詳細信息。在我離開它太久之後,我開始重新回到所有這一切,這完全是模糊的。寫這些答案(我找不到任何好的答案)也幫助我學習。如果我早些時候遇到你的文章,我會省下很多時間,我想大聲笑。 ;) –

相關問題