Pixi.js: PIXI no puede crear un filtro a partir del código de sombreado personalizado

Creado en 22 nov. 2017  ·  30Comentarios  ·  Fuente: pixijs/pixi.js

Estoy luchando por obtener un filtro personalizado con mi propio código de sombreado que funcione con este mensaje de error:

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)

Incluso el ejemplo oficial está fallando con este error:
http://pixijs.io/examples/#/filters/filter -mouse.js

Este mensaje de error se ha relacionado con algunas optimizaciones del compilador en las que glslify eliminó algunos uniformes sin usar, a los que pixi aún intentó acceder. Pero esto incluso ocurre con un fragShader completamente estático sin ningún uniforme. gl_FragColor = vec4(1.0, 1.0, 0.0, 1.0)

Todos 30 comentarios

El ejemplo me funciona, ¿en qué navegador te estás probando?

Versión de Google Chrome 62.0.3202.94 (compilación oficial) (64 bits)
2017-11-23-143829_667x172_scrot

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

SO: Ubuntu 17.10 ingenioso

@doebi buena captura! Sí, la optimización eliminó algo (apuesto a que es una muestra) y nos olvidamos de verificarlo.

Por ahora, ¿está seguro de que necesita un filtro sin usar muestreador? En algunos casos, es mejor hacer un complemento de renderizado como https://github.com/pixijs/pixi-plugin-example ?

La segunda vez en este día, lamento el lío que causan los sombreadores y los filtros en la versión 4. Lo arreglaremos en v5.

Para ser honesto, todavía no he profundizado en este tema. Solo quería experimentar con esa función el otro día. Haré algunas pruebas con el enfoque del complemento de renderizado. Gracias por la pista.

¿Existe ya algo de ETA para la v5?

2 meses más o menos :)

Hay muchos trucos sobre los filtros, por eso hice ese artículo: https://github.com/pixijs/pixi.js/wiki/v4-Creating-Filters

@ivanpopelyshev Siguiendo tu tutorial, me encontré con el mismo problema.
Apliqué un parche realmente hacky a pixi.js para que funcione para mí.

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,

Sé que esto no es una solución, pero me permite jugar con los códigos de sombreado en la v4 hasta que se acabe la v5. (posiblemente con una mejor solución) :)

¡Qué buen truco!

Puede moverlo a un archivo js separado:

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

Tengo el mismo problema. También con Ubuntu 17.10 artful. ¿Son los sombreadores estables en Pixi.js? ¿Puedo usarlos en producción? ¿Cómo importo un sombreador de píxeles?

Ya sea como filtro o como complemento de renderizador. Son estables pero requieren un conocimiento serio tanto sobre webgl como sobre la arquitectura pixi.

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

Por enésima vez le aseguro a la gente que será más fácil en 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];

Tanto código conduce a este error. ¿Quizás debería optar por un constructor diferente del filtro? ¿O debería sustituir nulo por algo?

Para un filtro, debe usar el coordinador de textura y el muestreador; de lo contrario, FilterManager no puede obtener la ubicación del atributo.

El plugin Renderer no tiene ese requisito, pruébalo. Sí, es una gran repetición.

Prueba eso: https://github.com/TazOen/createShaderPlugin . Sin embargo, ignora la textura, no hay bindTexture allí. Si necesita textura, tome el ejemplo completo de pixi-plugin-example.

Dices que necesita coords de textura y "sampler". ¿Fue muestra o muestreador? ¿Un error?
Me las arreglé para hacerlo funcionar con la ayuda del ejemplo. Gracias pero. ¿Por qué esta página no menciona estos detalles?
http://pixijs.io/examples/#/basics/custom -filter.js

Dechado. Sin embargo, es uniforme y no creo que nadie lo extrañe. Nuestro problema son los atributos.

Gracias a ti, lo hace :) https://github.com/pixijs/pixi.js/wiki/v4-Creating-Filters#cannot -read-property-location-of-undefined

Oh, ahí es donde estaba. Echaba de menos la wiki.

Gracias a ti lo hace

Lo acabo de agregar.

También se agregó un aviso en la demostración del mouse de filtro. No podemos solucionar el problema en v4. Haremos algo al respecto en v5.

Eso aparece cuando algunas de las propiedades requeridas por FilterManager no se utilizan en el sombreador.

¿Qué tal si enumeramos estas propiedades allí?

solo el atributo, aTextureCoord -> vTextureCoord

Esto se está volviendo muy extraño.
Este código funciona 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;
}

Pero si agrego gl_FragColor.a = 0.0; al final, entonces dice Cannot read property 'location' of undefined . Parece que solo puedo cambiar 3 de 4 coords como máximo. ¿Que es esto? ¿Qué está mal?

@ germansokolov13 este comportamiento tiene mucho sentido. Solo piensa en ello:
Como mencioné en la publicación original, este error se produce debido a que glsify optimiza el código de sombreado.

Si agrega gl_FragColor.a = 0.0; , puede optimizar su llamada a texture2D , porque se sobrescribe completamente, pero hasta entonces toma el canal alfa de texture2D

Si glsify optimiza la llamada a texture2D, webgl no asigna memoria para uSampler , por lo tanto, cuando pixi quiere cargar datos en ese uniforme, falla, porque simplemente no hay espacio para eso asignado.

Tienes algunas opciones:

  • Aplique el mismo truco que hice (por ahora), que básicamente verifica si se asigna un atributo antes de cargarle datos.
  • Use uSampler, para que glsify no lo optimice.
  • O simplemente espere a que v5.

Con suerte, esto ayuda.

¡Buen partido, @doebi!

O use el complemento de renderizador.

¡Oh, ahora lo entiendo! ¿Quizás deberíamos agregar el parche de Doebi a la próxima versión menor de Pixi.js? ¿Debería crear un PR?

Hola,
Estoy experimentando un problema similar con mi código de sombreado. Es una variación del código de sombreado de BlurYFilter predeterminado solo con un kernel más grande y una pequeña variación en la variable gaussiana, por lo que no estoy del todo seguro de por qué no funciona.

Está funcionando bien en Windows, MacOS y Android, por lo que probé, solo tengo problemas en iOS.
Aquí está el código de sombreado:
vértice:

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

fragmento:

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

para comparar, aquí están los sombreadores del BlurYFilter predeterminado:
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;

}

¿Alguien tiene alguna idea de por qué esto podría salir mal?

@tyleet, ¿estás seguro de que es el mismo problema? ¿Qué ves en la consola?

EDITAR:
No importa, encontré el problema, parece que el tamaño del kernel de 15 es demasiado para iOS, si reduzco el tamaño del kernel a 7, funciona bien.

<----- Publicación original --------->
Hola,
perdón por la respuesta tardía, no pude hacer algunas capturas de pantalla durante el fin de semana. Me parece que falla en la misma línea. "atributo" no está definido. Aquí están las capturas de pantalla de la consola remota:
image
image

@ivanpopelyshev, ¿deberíamos cerrar este problema para evitar que otros lo
Ya no lo consideraría un problema, ya que recibí tu promesa de que se solucionará en la v5.

@doebi cerrando.

@tyleet el número de muestras tomadas de la textura se puede limitar en diferentes sistemas.

Este hilo se ha bloqueado automáticamente ya que no ha habido ninguna actividad reciente después de que se cerró. Abra un nuevo problema para errores relacionados.

¿Fue útil esta página
0 / 5 - 0 calificaciones

Temas relacionados

Darker picture Darker  ·  3Comentarios

madroneropaulo picture madroneropaulo  ·  3Comentarios

distinctdan picture distinctdan  ·  3Comentarios

lunabunn picture lunabunn  ·  3Comentarios

courtneyvigo picture courtneyvigo  ·  3Comentarios