Pixi.js: PIXI ne parvient pas à créer un filtre à partir du code de shader personnalisé

Créé le 22 nov. 2017  ·  30Commentaires  ·  Source: pixijs/pixi.js

J'ai du mal à obtenir un filtre personnalisé avec mon propre code de shader fonctionnant avec ce message d'erreur :

VertexArrayObject.js:171 Uncaught TypeError: Cannot read property 'location' of undefined
    at VertexArrayObject.addAttribute (VM1006 pixi.js:2348)
    at Quad.initVao (VM1006 pixi.js:19874)
    at FilterManager.applyFilter (VM1006 pixi.js:18947)
    at Filter.apply (VM1006 pixi.js:18420)
    at FilterManager.popFilter (VM1006 pixi.js:18877)
    at Container.renderAdvancedWebGL (VM1006 pixi.js:9423)
    at Container.renderWebGL (VM1006 pixi.js:9360)
    at Container.renderWebGL (VM1006 pixi.js:9366)
    at WebGLRenderer.render (VM1006 pixi.js:17563)
    at Application.render (VM1006 pixi.js:8043)

Même l'exemple officiel échoue avec ce bogue :
http://pixijs.io/examples/#/filters/filter-mouse.js

Ce message d'erreur était lié à certaines optimisations du compilateur où glslify a supprimé certains uniformes inutilisés, auxquels pixi essayait toujours d'accéder. Mais cela se produit même avec un fragShader complètement statique sans aucun uniforme. gl_FragColor = vec4(1.0, 1.0, 0.0, 1.0)

Tous les 30 commentaires

L'exemple fonctionne pour moi, dans quel navigateur vous testez-vous ?

Version de Google Chrome 62.0.3202.94 (version officielle) (64 bits)
2017-11-23-143829_667x172_scrot

Firefox Quantum 57.0 (64 bits)
2017-11-23-143957_741x236_scrot

OS : Ubuntu 17.10 astucieux

@doebi belle prise ! Ouais, l'optimisation a supprimé quelque chose (je parie que son échantillonneur) et nous avons oublié de le vérifier.

Pour l'instant, êtes-vous sûr d'avoir besoin d'un filtre sans utiliser d'échantillonneur ? Dans certains cas, il vaut mieux créer un plugin de rendu comme https://github.com/pixijs/pixi-plugin-example ?

Deuxième fois ce jour, je suis désolé pour le désordre que le shader et les filtres sont dans la v4. Nous allons le corriger dans la v5.

Pour être honnête, je n'ai pas encore vraiment approfondi ce sujet. Je voulais juste expérimenter cette fonctionnalité l'autre jour. Je vais faire quelques tests avec l'approche du plugin de rendu. Merci pour l'astuce.

Existe-t-il déjà un ETA pour la v5 ?

2 mois environ :)

Il existe de nombreuses astuces sur les filtres, c'est pourquoi j'ai fait cet article : https://github.com/pixijs/pixi.js/wiki/v4-Creating-Filters

@ivanpopelyshev Suite à votre tutoriel, j'ai rencontré le même problème.
J'ai appliqué un patch vraiment hack à pixi.js pour le faire fonctionner pour moi.

diff --git a/js/pixi.js b/js/pixi.js
index 363f09c..d0a321b 100644
--- a/js/pixi.js
+++ b/js/pixi.js
@@ -2344,6 +2344,9 @@ VertexArrayObject.prototype.activate = function()
  */
 VertexArrayObject.prototype.addAttribute = function(buffer, attribute, type, normalized, stride, start)
 {
+  if (!attribute) {
+    return this;
+  }
     this.attributes.push({
         buffer:     buffer,
         attribute:  attribute,

Je sais que ce n'est pas une solution, mais cela me permet de jouer avec les codes de shader dans la v4 jusqu'à la sortie de la v5. (avec peut-être une meilleure solution) :)

C'est une bonne astuce !

Vous pouvez le déplacer dans un fichier js séparé :

PIXI.glCore.VertexArrayObject.prototype.addAttribute = ...

J'ai le même problème. Aussi avec Ubuntu 17.10 astucieux. Les shaders sont-ils stables dans Pixi.js ? Puis-je les utiliser en production ? Comment importer un pixel shader ?

Soit en tant que filtre soit en tant que plugin de rendu. Ils sont stables mais nécessitent de sérieuses connaissances à la fois sur webgl et sur l'architecture pixi.

https://github.com/pixijs/pixi.js/wiki/v4-Creating-Filters
https://github.com/pixijs/pixi-plugin-example/

Pour la énième fois, j'assure aux gens que ce sera plus facile dans la v5.

const filterCode = `void main(){
   gl_FragColor = vec4(1.0, 1.0, 1.0, 1.0);
}`;
const filter = new PIXI.Filter(null, filterCode);
someSprite.filters = [filter];

Cette quantité de code conduit à cette erreur. Peut-être devrais-je opter pour un autre constructeur du filtre ? Ou dois-je remplacer null par quelque chose ?

Pour un filtre, vous devez utiliser texture coord et sampler , sinon FilterManager ne parvient pas à obtenir l'emplacement de l'attribut.

Le plugin Renderer n'a pas cette exigence, essayez-le. Ouais, c'est un gros passe-partout.

Essayez cette chose : https://github.com/TazOen/createShaderPlugin . Cependant, il ignore la texture, il n'y a pas de bindTexture là-bas. Si vous avez besoin de texture, prenez l'exemple entier de pixi-plugin.

Vous dites qu'il a besoin de coordonnées de texture et d'un "échantillonneur". Était échantillon ou échantillonneur? Une faute de frappe?
J'ai réussi à le faire fonctionner à l'aide d'exemples. Je vous remercie, mais. Pourquoi cette page ne mentionne-t-elle pas ces détails ?
http://pixijs.io/examples/#/basics/custom-filter.js

Échantillonneur. Cependant, c'est un uniforme et je ne pense pas que quelqu'un le manquera. Notre problème concerne les attributs.

Grâce à vous, c'est le cas :) https://github.com/pixijs/pixi.js/wiki/v4-Creating-Filters#cannot -read-property-location-of-undefined

Oh, c'est donc là que c'était. J'ai raté le wiki.

Grâce à vous, c'est le cas

Je viens de l'ajouter.

A également ajouté un avis dans la démo filtre-souris. Nous ne pouvons pas résoudre le problème dans la v4. Nous ferons quelque chose à ce sujet dans la v5.

Cela apparaît lorsque certaines des propriétés requises par FilterManager ne sont pas utilisées dans le shader.

Que diriez-vous de lister ces propriétés là-dedans ?

uniquement l'attribut, aTextureCoord -> vTextureCoord

Cela devient très étrange.
Ce code fonctionne bien :

varying vec2 vTextureCoord;
varying vec4 vColor;

uniform sampler2D uSampler;
uniform vec4 uTextureClamp;
uniform vec4 uColor;

void main(void)
{
    gl_FragColor = texture2D(uSampler, vTextureCoord);
    gl_FragColor.r = 0.0;
    gl_FragColor.g = 0.0;
    gl_FragColor.b = 0.0;
}

Mais si j'ajoute gl_FragColor.a = 0.0; à la fin, alors ça dit Cannot read property 'location' of undefined . Il me semble que je ne peux changer que 3 coordonnées sur 4 au maximum. Qu'est-ce que c'est? Qu'est-ce qui ne va pas?

@ germansokolov13 ce comportement est tout à fait logique. Pensez-y :
Comme je l'ai mentionné dans le message d'origine, cette erreur se produit en raison de l'optimisation du code de shader par glsify.

Si vous ajoutez gl_FragColor.a = 0.0; cela peut optimiser votre appel à texture2D , car il est complètement écrasé, mais jusque-là, il faut le canal alpha de texture2D

Si glsify optimise l'appel à texture2D, webgl n'alloue pas de mémoire pour uSampler , donc lorsque pixi veut télécharger des données vers cet uniforme, il échoue, car il n'y a tout simplement pas d'espace pour cet alloué.

Vous avez quelques options :

  • Appliquez le même hack que j'ai fait (pour l'instant), qui vérifie essentiellement si un attribut est alloué avant de télécharger des données dessus.
  • Utilisez uSampler pour que glsify ne l'optimise pas de suite.
  • Ou attendez simplement la v5.

Espérons que cela aide.

Belle prise, @doebi !

Ou utilisez le plugin de rendu.

Oh, maintenant je comprends ! Peut-être devrions-nous ajouter le correctif de Doebi à la prochaine version mineure de Pixi.js ? Dois-je créer un RP ?

Oui, PR, mais un endroit différent.

https://github.com/pixijs/pixi.js/blob/dev/src/core/renderers/webgl/utils/Quad.js#L93
https://github.com/pixijs/pixi.js/blob/dev/src/core/renderers/webgl/managers/FilterManager.js#L242

Je suggère une classe supplémentaire qui remplace la méthode et qui est utilisée dans FilterManager.

Salut,
Je rencontre un problème similaire avec mon code shader. Il s'agit d'une variante du code de shader BlurYFilter par défaut avec un noyau plus gros et une petite variation sur la variable gaussienne, donc je ne sais pas exactement pourquoi cela ne fonctionne pas.

Cela fonctionne bien sur Windows, MacOS et Android pour autant que j'ai testé, je n'ai que des problèmes avec iOS.
Voici le code du shader :
sommet:

attribute vec2 aVertexPosition;
attribute vec2 aTextureCoord;
uniform float strength;
uniform mat3 projectionMatrix;
varying vec2 vBlurTexCoords[15];
void main(void){
   gl_Position = vec4((projectionMatrix * vec3((aVertexPosition), 1.0)).xy, 0.0, 1.0);
   vBlurTexCoords[0] = aTextureCoord + vec2(0.0, -7.0 * strength);
   vBlurTexCoords[1] = aTextureCoord + vec2(0.0, -6.0 * strength);
   vBlurTexCoords[2] = aTextureCoord + vec2(0.0, -5.0 * strength);
   vBlurTexCoords[3] = aTextureCoord + vec2(0.0, -4.0 * strength);
   vBlurTexCoords[4] = aTextureCoord + vec2(0.0, -3.0 * strength);
   vBlurTexCoords[5] = aTextureCoord + vec2(0.0, -2.0 * strength);
   vBlurTexCoords[6] = aTextureCoord + vec2(0.0, -1.0 * strength);
   vBlurTexCoords[7] = aTextureCoord + vec2(0.0, 0.0 * strength);
   vBlurTexCoords[8] = aTextureCoord + vec2(0.0, 1.0 * strength);
   vBlurTexCoords[9] = aTextureCoord + vec2(0.0, 2.0 * strength);
   vBlurTexCoords[10] = aTextureCoord + vec2(0.0, 3.0 * strength);
   vBlurTexCoords[11] = aTextureCoord + vec2(0.0, 4.0 * strength);
   vBlurTexCoords[12] = aTextureCoord + vec2(0.0, 5.0 * strength);
   vBlurTexCoords[13] = aTextureCoord + vec2(0.0, 6.0 * strength);
   vBlurTexCoords[14] = aTextureCoord + vec2(0.0, 7.0 * strength);
}

fragment:

varying vec2 vBlurTexCoords[15];
uniform sampler2D uSampler;
void main(void){
   gl_FragColor = vec4(0.0);
   gl_FragColor += texture2D(uSampler, vBlurTexCoords[0]) * 0.013068780984604511;
   gl_FragColor += texture2D(uSampler, vBlurTexCoords[1]) * 0.013907007172070673;
   gl_FragColor += texture2D(uSampler, vBlurTexCoords[2]) * 0.017439264394216315;
   gl_FragColor += texture2D(uSampler, vBlurTexCoords[3]) * 0.028762309061254498;
   gl_FragColor += texture2D(uSampler, vBlurTexCoords[4]) * 0.05603114255667656;
   gl_FragColor += texture2D(uSampler, vBlurTexCoords[5]) * 0.10421702583793174;
   gl_FragColor += texture2D(uSampler, vBlurTexCoords[6]) * 0.163461199220823;
   gl_FragColor += texture2D(uSampler, vBlurTexCoords[7]) * 0.2062265415448454;
   gl_FragColor += texture2D(uSampler, vBlurTexCoords[8]) * 0.163461199220823;
   gl_FragColor += texture2D(uSampler, vBlurTexCoords[9]) * 0.10421702583793174;
   gl_FragColor += texture2D(uSampler, vBlurTexCoords[10]) * 0.05603114255667656;
   gl_FragColor += texture2D(uSampler, vBlurTexCoords[11]) * 0.028762309061254498;
   gl_FragColor += texture2D(uSampler, vBlurTexCoords[12]) * 0.017439264394216315;
   gl_FragColor += texture2D(uSampler, vBlurTexCoords[13]) * 0.013907007172070673;
   gl_FragColor += texture2D(uSampler, vBlurTexCoords[14]) * 0.013068780984604511;
}

à titre de comparaison voici les shaders du BlurYFilter par défaut :
vert :

attribute vec2 aVertexPosition;
attribute vec2 aTextureCoord;
uniform float strength;
uniform mat3 projectionMatrix;
varying vec2 vBlurTexCoords[5];
void main(void)
{
  gl_Position = vec4((projectionMatrix * vec3((aVertexPosition), 1.0)).xy, 0.0, 1.0);
  vBlurTexCoords[0] = aTextureCoord + vec2(0.0, -2.0 * strength);
  vBlurTexCoords[1] = aTextureCoord + vec2(0.0, -1.0 * strength);
  vBlurTexCoords[2] = aTextureCoord + vec2(0.0, 0.0 * strength);
  vBlurTexCoords[3] = aTextureCoord + vec2(0.0, 1.0 * strength);
  vBlurTexCoords[4] = aTextureCoord + vec2(0.0, 2.0 * strength);

}

frag :

varying vec2 vBlurTexCoords[5];
uniform sampler2D uSampler;
void main(void)
{
    gl_FragColor = vec4(0.0);
    gl_FragColor += texture2D(uSampler, vBlurTexCoords[0]) * 0.153388;
    gl_FragColor += texture2D(uSampler, vBlurTexCoords[1]) * 0.221461;
    gl_FragColor += texture2D(uSampler, vBlurTexCoords[2]) * 0.250301;
    gl_FragColor += texture2D(uSampler, vBlurTexCoords[3]) * 0.221461;
    gl_FragColor += texture2D(uSampler, vBlurTexCoords[4]) * 0.153388;

}

Quelqu'un a-t-il une idée de pourquoi cela pourrait mal tourner?

@tyleet es-tu sûr que c'est le même problème ? Que voyez-vous dans la console ?

ÉDITER:
Peu importe, j'ai trouvé le problème, il semble que la taille du noyau de 15 soit trop pour iOS, si je réduis la taille du noyau à 7, cela fonctionne bien.

<-----Post d'origine --------->
Salut,
désolé pour la réponse tardive, je n'ai pas pu faire de captures d'écran ce week-end. Il me semble qu'il échoue sur la même ligne. "attribut" n'est pas défini. Voici les captures d'écran de la console distante :
image
image

@ivanpopelyshev devons-nous fermer ce problème pour empêcher d'autres de le réchauffer avec des problèmes similaires ?
Je ne considérerais plus cela comme un problème, puisque j'ai reçu votre promesse, que ce sera corrigé dans la v5.

@doebi clôture.

@tyleet le nombre d'échantillons prélevés sur la texture peut être limité sur différents systèmes.

Ce fil a été automatiquement verrouillé car il n'y a eu aucune activité récente après sa fermeture. Veuillez ouvrir un nouveau problème pour les bogues liés.

Cette page vous a été utile?
0 / 5 - 0 notes

Questions connexes

gigamesh picture gigamesh  ·  3Commentaires

YuryKuvetski picture YuryKuvetski  ·  3Commentaires

Makio64 picture Makio64  ·  3Commentaires

softshape picture softshape  ·  3Commentaires

lucap86 picture lucap86  ·  3Commentaires