Pixi.js: PIXI не может создать фильтр из пользовательского кода шейдера

Созданный на 22 нояб. 2017  ·  30Комментарии  ·  Источник: pixijs/pixi.js

Я изо всех сил пытаюсь получить настраиваемый фильтр с моим собственным кодом шейдера, работающий с этим сообщением об ошибке:

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)

Даже официальный пример не работает с этой ошибкой:
http://pixijs.io/examples/#/filters/filter -mouse.js

Это сообщение об ошибке было связано с некоторыми оптимизациями компилятора, когда glslify удалила некоторые неиспользуемые униформы, к которым pixi все еще пытался получить доступ. Но это происходит даже с полностью статичным fragShader без какой-либо униформы. gl_FragColor = vec4(1.0, 1.0, 0.0, 1.0)

Все 30 Комментарий

У меня пример работает, в каком браузере вы себя тестируете?

Google Chrome версии 62.0.3202.94 (официальная сборка) (64-разрядная версия)
2017-11-23-143829_667x172_scrot

Firefox Quantum 57.0 (64-разрядная версия)
2017-11-23-143957_741x236_scrot

ОС: Ubuntu 17.10 хитрый

@doebi хороший улов! Ага, оптимизация что-то удалила (держу пари, пробоотборник), и мы забыли это проверить.

А пока вы уверены, что вам нужен фильтр без использования сэмплера? В некоторых случаях лучше сделать плагин рендеринга, например https://github.com/pixijs/pixi-plugin-example ?

Второй раз за день прошу прощения за беспорядок, связанный с шейдером и фильтрами в v4. Мы исправим это в v5.

Если честно, я еще не особо углубился в эту тему. Просто хотел поэкспериментировать с этой функцией на днях. Я проведу небольшое тестирование с использованием плагина рендерера. Спасибо за подсказку.

Есть ли уже какое-то расчетное время прибытия для v5?

2 месяца или около того :)

Есть много уловок с фильтрами, поэтому я написал эту статью: https://github.com/pixijs/pixi.js/wiki/v4-Creating-Filters

@ivanpopelyshev Следуя вашему руководству, я столкнулся с той же проблемой.
Я применил к pixi.js действительно хитрый патч, чтобы он работал у меня.

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,

Я знаю, что это не решение, но оно позволяет мне играть с кодами шейдеров в версии 4, пока не будет выпущена версия 5. (возможно, с лучшим исправлением) :)

Хороший хак!

Вы можете переместить его в отдельный файл js:

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

У меня та же проблема. Тоже с Ubuntu 17.10 хитрый. Стабильны ли шейдеры в Pixi.js? Могу ли я использовать их в производстве? Как импортировать пиксельный шейдер?

Либо как фильтр, либо как плагин рендеринга. Они стабильны, но требуют серьезных знаний как о webgl, так и об архитектуре pixi.

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

В N-й раз заверяю людей, что в 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];

Такой объем кода приводит к этой ошибке. Может, мне стоит использовать другой конструктор фильтра? Или я должен чем-то заменить null?

Для фильтра вы должны использовать координаты текстуры и сэмплер, иначе FilterManager не сможет получить местоположение атрибута.

Плагин Renderer не требует этого, попробуйте. Да, это большой шаблон.

Попробуйте это: https://github.com/TazOen/createShaderPlugin . Однако он игнорирует текстуру, там нет bindTexture . Если вам нужна текстура, возьмите весь пример плагина pixi.

Вы говорите, что ему нужны координаты текстуры и «сэмплер». Был образец или пробоотборник? Опечатка?
Мне удалось заставить это работать с помощью примера. Спасибо, но. Почему на этой странице не упоминаются эти детали?
http://pixijs.io/examples/#/basics/custom -filter.js

Сэмплер. Однако его форма, и я не думаю, что кто-то пропустит ее. Наша проблема в атрибутах.

Спасибо вам :) https://github.com/pixijs/pixi.js/wiki/v4-Creating-Filters#cannot -read-property-location-of-undefined

О, вот где это было. Я пропустил вики.

Благодаря тебе это так

Я его только что добавил.

Также добавлено уведомление в демонстрации мыши с фильтром. Мы не можем исправить проблему в версии 4. Мы что-нибудь сделаем с этим в v5.

Это появляется, когда некоторые свойства, требуемые FilterManager, не используются в шейдере.

Как насчет того, чтобы перечислить эти свойства там?

только атрибут aTextureCoord -> vTextureCoord

Это становится очень странным.
Этот код отлично работает:

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

Но если я добавлю gl_FragColor.a = 0.0; в конец, будет написано Cannot read property 'location' of undefined . Кажется, что я могу изменить максимум 3 координаты из 4. Что это? Что случилось?

@ germansokolov13 такое поведение имеет смысл. Просто подумай об этом:
Как я уже упоминал в исходном сообщении, эта ошибка возникает из-за того, что glsify оптимизирует код шейдера.

Если вы добавите gl_FragColor.a = 0.0; он может оптимизировать ваш вызов до texture2D , потому что он будет полностью перезаписан, но до тех пор он берет альфа-канал из texture2D

Если glsify оптимизирует вызов texture2D, webgl не выделяет память для uSampler , поэтому, когда pixi хочет загрузить данные в эту униформу, он терпит неудачу, потому что для этого просто нет места.

У вас есть несколько вариантов:

  • Примените тот же прием, что и я (на данный момент), который в основном проверяет, выделен ли атрибут перед загрузкой в ​​него данных.
  • Используйте uSampler, поэтому glsify не оптимизирует его.
  • Или просто дождитесь v5.

Надеюсь, это поможет.

Хороший улов, @doebi!

Или используйте плагин рендерера.

О, теперь я понял! Может быть, нам стоит добавить патч Doebi в следующий второстепенный выпуск Pixi.js? Стоит ли создавать пиар?

Ага, пиар, но другое место.

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

Я предлагаю дополнительный класс, который переопределяет метод и используется в FilterManager.

Всем привет,
У меня аналогичная проблема с кодом шейдера. Это вариант кода шейдера BlurYFilter по умолчанию, только с большим ядром и небольшим изменением гауссовой переменной, поэтому я не совсем уверен, почему он не работает.

Он отлично работает на Windows, MacOS и Android, насколько я тестировал, у меня проблемы только с iOS.
Вот код шейдера:
вершина:

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

фрагмент:

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

для сравнения - шейдеры стандартного BlurYFilter:
верт:

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

}

фраг:

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;

}

Есть ли у кого-нибудь идеи, почему это может пойти не так?

@tyleet , вы уверены, что это та же проблема? Что ты видишь в консоли?

РЕДАКТИРОВАТЬ:
Неважно, я обнаружил проблему, кажется, размер ядра 15 - это слишком много для iOS, если я уменьшу размер ядра до 7, он будет работать нормально.

<----- Исходное сообщение --------->
Привет,
извините за поздний ответ, я не смог сделать несколько снимков экрана за выходные. Мне кажется, что он не работает на той же линии. "атрибут" не определен. Вот скриншоты с удаленной консоли:
image
image

@ivanpopelyshev, должны ли мы закрыть эту проблему, чтобы другие не разогревали ее подобными проблемами?
Я бы больше не считал это проблемой, поскольку я получил ваше обещание, что это будет исправлено в v5.

@doebi закрытие.

@tyleet количество сэмплов, взятых из текстуры, может быть ограничено на разных системах.

Этот поток был автоматически заблокирован, поскольку после его закрытия в последнее время не было никаких действий. Пожалуйста, откройте новую проблему для связанных ошибок.

Была ли эта страница полезной?
0 / 5 - 0 рейтинги

Смежные вопросы

zcr1 picture zcr1  ·  3Комментарии

samueller picture samueller  ·  3Комментарии

gigamesh picture gigamesh  ·  3Комментарии

madroneropaulo picture madroneropaulo  ·  3Комментарии

readygosports picture readygosports  ·  3Комментарии