Pixi.js: PIXI kann keinen Filter aus benutzerdefiniertem Shader-Code erstellen

Erstellt am 22. Nov. 2017  ·  30Kommentare  ·  Quelle: pixijs/pixi.js

Ich habe Schwierigkeiten, einen benutzerdefinierten Filter mit meinem eigenen Shader-Code zu erhalten, der mit dieser Fehlermeldung funktioniert:

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)

Sogar das offizielle Beispiel scheitert an diesem Fehler:
http://pixijs.io/examples/#/filters/filter -mouse.js

Diese Fehlermeldung bezieht sich auf einige Compiler-Optimierungen, bei denen glslify einige ungenutzte Uniformen entfernt hat, auf die pixi immer noch zugreifen wollte. Dies geschieht aber sogar bei einem völlig statischen fragShader ohne Uniformen. gl_FragColor = vec4(1.0, 1.0, 0.0, 1.0)

Alle 30 Kommentare

Das Beispiel funktioniert für mich, in welchem ​​Browser testest du dich?

Google Chrome-Version 62.0.3202.94 (offizieller Build) (64-Bit)
2017-11-23-143829_667x172_scrot

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

Betriebssystem: Ubuntu 17.10 kunstvoll

@doebi schöner Fang! Ja, die Optimierung hat etwas entfernt (ich wette, der Sampler) und wir haben vergessen, es zu überprüfen.

Sind Sie im Moment sicher, dass Sie einen Filter ohne Verwendung eines Samplers benötigen? In einigen Fällen ist es besser, ein Renderer-Plugin wie https://github.com/pixijs/pixi-plugin-example zu erstellen ?

Zum zweiten Mal an diesem Tag tut es mir leid, dass Shader und Filter in v4. Wir werden es in v5 beheben.

Ehrlich gesagt habe ich mich mit diesem Thema noch nicht wirklich beschäftigt. Wollte neulich mit dieser Funktion experimentieren. Ich werde einige Tests mit dem Renderer-Plugin-Ansatz durchführen. Danke für den Tipp.

Gibt es schon eine ETA für v5?

2 Monate oder so :)

Es gibt viele Tricks über Filter, deshalb habe ich diesen Artikel erstellt: https://github.com/pixijs/pixi.js/wiki/v4-Creating-Filters

@ivanpopelyshev Nach Ihrem Tutorial gestoßen .
Ich habe pixi.js mit einem wirklich hackigen Patch versehen, damit es für mich funktioniert.

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,

Ich weiß, dass dies keine Lösung ist, aber es ermöglicht mir, mit Shader-Codes in v4 zu spielen, bis v5 herauskommt. (mit möglicherweise einer besseren Lösung) :)

Das ist ein guter Hack!

Sie können es in eine separate js-Datei verschieben:

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

Ich habe das gleiche Problem. Auch mit Ubuntu 17.10 kunstvoll. Sind Shader in Pixi.js überhaupt stabil? Kann ich sie in der Produktion verwenden? Wie importiere ich einen Pixelshader?

Entweder als Filter oder als Renderer-Plugin. Sie sind stabil, erfordern aber fundierte Kenntnisse sowohl über Webgl als auch über die Pixelarchitektur.

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

Zum N-ten Mal versichere ich den Leuten, dass es in v5 einfacher sein wird.

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];

So viel Code führt zu diesem Fehler. Vielleicht sollte ich mich für einen anderen Konstruktor des Filters entscheiden? Oder soll ich null durch etwas ersetzen?

Für einen Filter müssen Sie texture coord und sampler verwenden, andernfalls kann FilterManager die Position des Attributs nicht ermitteln.

Das Renderer-Plugin hat diese Anforderung nicht, probieren Sie es aus. Ja, seine große Boilerplate.

Versuchen Sie das Ding: https://github.com/TazOen/createShaderPlugin . Es ignoriert jedoch die Textur, es gibt dort kein bindTexture . Wenn Sie eine Textur benötigen, nehmen Sie das gesamte pixi-plugin-Beispiel.

Sie sagen, es braucht Texturkoordinaten und "Sampler". War Probe oder Sampler? Ein Tippfehler?
Ich habe es geschafft, es mit Hilfe von Beispielen zum Laufen zu bringen. Danke, aber. Warum werden diese Details auf dieser Seite nicht erwähnt?
http://pixijs.io/examples/#/basics/custom -filter.js

Sampler. Es ist jedoch einheitlich und ich glaube nicht, dass jemand es vermissen wird. Bei unserem Problem geht es um Attribute.

Dank dir tut es das :) https://github.com/pixijs/pixi.js/wiki/v4-Creating-Filters#cannot -read-property-location-of-undefined

Oh, da war es also. Ich habe das Wiki vermisst.

Dank dir geht es

Ich habe es gerade hinzugefügt.

Hinweis auch in der Filtermaus-Demo hinzugefügt. Wir können das Problem in v4 nicht beheben. Wir werden in v5 etwas dagegen tun.

Dies erscheint, wenn einige der von FilterManager benötigten Eigenschaften im Shader nicht verwendet werden.

Wie wäre es, diese Eigenschaften dort aufzulisten?

nur das Attribut aTextureCoord -> vTextureCoord

Das wird sehr seltsam.
Dieser Code funktioniert gut:

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

Aber wenn ich am Ende gl_FragColor.a = 0.0; hinzufüge, heißt es Cannot read property 'location' of undefined . Es scheint, als ob ich höchstens 3 von 4 Koordinaten ändern kann. Was ist das? Was ist falsch?

@germansokolov13 dieses Verhalten macht
Wie ich im ursprünglichen Beitrag erwähnt habe, tritt dieser Fehler auf, weil glsify den Shader-Code optimiert.

Wenn Sie gl_FragColor.a = 0.0; hinzufügen, kann es Ihren Aufruf zu texture2D optimieren, da es vollständig überschrieben wird, aber bis dahin dauert es den Alphakanal von texture2D

Wenn glsify den Aufruf von texture2D optimiert, weist webgl keinen Speicher für uSampler .

Sie haben einige Möglichkeiten:

  • Wenden Sie den gleichen Hack wie ich (vorerst) an, der im Wesentlichen überprüft, ob ein Attribut zugewiesen ist, bevor Daten darauf hochgeladen werden.
  • Verwenden Sie uSampler, damit glsify es nicht wegoptimiert.
  • Oder warte einfach auf v5.

Hoffentlich hilft das.

Schöner Fang, @doebi!

Oder verwenden Sie das Renderer-Plugin.

Oh, jetzt habe ich es verstanden! Vielleicht sollten wir Doebis Patch zum nächsten Minor-Release von Pixi.js hinzufügen? Soll ich eine PR erstellen?

Ja, PR, aber ein anderer Ort.

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

Ich schlage eine zusätzliche Klasse vor, die die Methode überschreibt und die in FilterManager verwendet wird.

Hi,
Ich habe ein ähnliches Problem mit meinem Shader-Code. Es ist eine Variation des standardmäßigen BlurYFilter-Shader-Codes, nur mit einem größeren Kernel und einer kleinen Variation der Gaußschen Variablen, daher bin ich mir nicht ganz sicher, warum es nicht funktioniert.

Es funktioniert gut unter Windows, MacOS und Android, soweit ich es getestet habe, ich habe nur Probleme mit iOS.
Hier ist der Shader-Code:
Scheitel:

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

zum Vergleich hier die Shader des Standard BlurYFilters:
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;

}

Hat jemand eine Idee, warum das schief gehen könnte?

@tyleet bist du sicher, dass es das gleiche Problem ist? Was siehst du in der Konsole?

BEARBEITEN:
Egal, ich habe das Problem gefunden, es scheint, dass die Kernelgröße von 15 für iOS zu viel ist, wenn ich die Kernelgröße auf 7 reduziere, funktioniert es gut.

<-----Originalpost--------->
Hi,
sorry für die späte Antwort, ich konnte am Wochenende keine Screenshots machen. Es sieht für mich so aus, als ob es auf derselben Leitung fehlschlägt. "Attribut" ist undefiniert. Hier sind die Screenshots von der Remote-Konsole:
image
image

@ivanpopelyshev sollen wir dieses Problem schließen, um zu verhindern, dass andere es mit ähnlichen Problemen
Ich würde es nicht mehr als Problem betrachten, da ich Ihr Versprechen erhalten habe, dass es in v5 behoben wird.

@doebi schließt.

@tyleet Die Anzahl der von der Textur entnommenen Samples kann auf verschiedenen Systemen begrenzt werden.

Dieser Thread wurde automatisch gesperrt, da nach dem Schließen in letzter Zeit keine Aktivität stattgefunden hat. Bitte öffnen Sie eine neue Ausgabe für verwandte Fehler.

War diese Seite hilfreich?
0 / 5 - 0 Bewertungen