2017-10-14 7 views
2

J'ai un problème en essayant de compiler un fragment shader. Je continue à obtenir cette erreur:gl_FragData doit être une constante 0

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 

Voici le code:

#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.); 
} 

L'ensemble de l'installation fonctionne très bien si je suis la mise en gl_FragColor (avec les 4 textures attachées à la mémoire tampon de trame), mais essayer pour faire le code ci-dessus (indexer les tampons à la sortie) semble ne pas compiler. J'ai vu cela fonctionner correctement dans WebGL1 en utilisant des extensions. J'utilise WebGL2, alors peut-être que quelque chose est différent dans ce contexte? (Je l'essaie dans la dernière version de Chrome).

+1

Si vous utilisez WebGL2, je pense que vous devez changer radicalement votre syntaxe pour l'adapter à la norme GLSL 3.3 ... regardez ici: http://io7m.com/documents/fso-tta/ au GLSL 3.30 (OpenGL 3.3) 'chapitre, aussi qui dit:" Sur OpenGL [3.3, 4.4] et OpenGL ES 3.0, assigner aux sorties de shader de fragments nommés, en associant les sorties nommées avec des tampons de tirage numérotés en utilisant des qualificateurs de mise en page. " –

+2

WebGL2 ne prend pas en charge GLSL 3.3. Il prend en charge [GLSL ES 3.0] (https://www.khronos.org/registry/OpenGL/specs/es/3.0/GLSL_ES_Specification_3.00.pdf). Il serait très déroutant de se référer à la spécification GLSL 3.3 seulement pour constater que des tonnes de choses ne fonctionnent pas parce que c'est la mauvaise spécification. – gman

Répondre

1

Il semble donc qu'il y ait quelques changements à envisager de passer de WebGL1 à WebGL2. Étant donné le commentaire de @ gman, j'ai pensé qu'il était préférable de lier son article, car je sais qu'il est vraiment l'expert ici. ;)

WebGL 1 à WebGL 2 conversion: https://webgl2fundamentals.org/webgl/lessons/webgl1-to-webgl2.html

J'ai aussi trouvé utile de se rappeler la version 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.

En un mot (se référant également au premier lien sur l'histoire) :

  1. Mon code shader a été conçu pour des exemples que j'ai vus pour WebGL 1 (OpenGL ES 2) en utilisant des extensions. Cela a fonctionné correctement car OpenGL 2.0 prenait en charge plusieurs valeurs de couleur via gl_FragData.

  2. En basculant vers WebGL 2 (OpenGL ES 3), cette méthode est dépréciée au profit d'une autre méthode. Maintenant, il y a out déclarations requises, comme out vec4 out_0; main(void) { out_0 = vec4(1.0, 0.0, 0.0, 1.0); }. Mais j'avais encore quelques problèmes. Il semble que je devais spécifier les emplacements de tampon. De plus, je recevais cette erreur:

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

    Ce qui signifie que je devais ajouter #version 300 es au sommet de mon programme, de sorte que le code correct pour WebGL 2 ressemble plus à ceci:

    #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); 
    } 
    

    A un point que j'avais la mauvaise version, ce qui a provoqué cette erreur:

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

    Mais je trouve que la version pour WebGL 2 est spécifiquement #version 300 es (notez le es partie), qui a fonctionné! Remarque: Le spécificateur de version doit figurer sur la première ligne et, malheureusement, ne peut pas figurer dans une directive de préprocesseur (par exemple, #ifdef). J'ai donc dû modifier dynamiquement la chaîne avant de l'envoyer à compiler. Sinon, vous obtiendrez ceci:

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

  3. Pour vertex shaders, si compilé pour WebGL 2 (ES 3) note que attribute est maintenant in à la place.La version du vertex shader doit également correspondre à celle du fragment en cours de compilation, ou bien vous obtiendrez ceci:

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

J'espère que toute cette confusion coller ensemble aide à sauver quelqu'un d'autre beaucoup de temps. ;)

+0

Il n'y a pas d'historique de * changements brisés *. Ce document lié à n'a absolument rien à voir avec WebGL ou WebGL2. Tout tourne autour d'OpenGL, ce qui n'est pas la même chose et n'est même pas lié à WebGL. WebGL et WebGL2 sont liés à OpenGL ** ES **. Sedenion ne vous a pas indiqué la bonne direction. Il vous a indiqué dans la mauvaise direction. Vous avez juste eu de la chance, cela vous a aidé à comprendre vos problèmes. Ce premier lien dans votre réponse concerne OpenGL et non OpenGL ES. OpenGL n'a rien à voir avec WebGL. Le référencer ne fait que créer de la confusion. Votre réponse montre que lorsque vous avez essayé différentes versions liées à OpenGL – gman

+0

Vous avez également lié à un article de conversion OpenGL ES mais vous utilisez WebGL2 et non OpenGL ES, donc vous devriez vraiment regarder un [article de conversion WebGL2] (https: // webgl2fundamentals. org/webgl/lessons/webgl1-to-webgl2.html) – gman

+0

Merci pour les détails. Je commence à rentrer dans tout ça après être parti trop longtemps et tout est flou. Ecrire ces réponses (là où je ne trouve pas de bonne réponse) m'aide aussi à apprendre. Si j'avais rencontré vos articles plus tôt, cela m'aurait permis de gagner beaucoup de temps, je pense que lol. ;) –