Pixi.js: PIXI 无法从自定义着色器代码创建过滤器

创建于 2017-11-22  ·  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 已经有一些 ETA 了吗?

2个月左右:)

关于过滤器有很多技巧,这就是我写那篇文章的原因: https :

@ivanpopelyshev按照您的教程,我遇到了同样的问题。
我在 pixi.js 上应用了一个非常hacky 的补丁来让它对我有用。

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,

我知道这不是一个解决方案,但它使我能够在 v4 中使用着色器代码,直到 v5 结束。 (可能有更好的修复):)

这是一个很好的黑客!

您可以将其移动到单独的 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-plugin-example。

你说它需要纹理坐标和“采样器”。 是样品还是取样器? 错别字?
我设法在示例的帮助下使其工作。 谢谢但是。 为什么这个页面没有提到这些细节?
http://pixijs.io/examples/#/basics/custom -filter.js

取样器。 然而它的制服,我不认为有人会想念它。 我们的问题是关于属性的。

谢谢你,它确实 :) https://github.com/pixijs/pixi.js/wiki/v4-Creating-Filters#cannot -read-property-location-of-undefined

哦,原来是这样。 我错过了维基。

多亏了你,它确实

我刚刚添加了它。

还在过滤鼠标演示中添加了通知。 我们无法解决 v4 中的问题。 我们将在 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 。 好像我最多只能更改 4 个坐标中的 3 个。 这是什么? 怎么了?

@germansokolov13这种行为完全有道理。 考虑一下:
正如我在原帖中提到的,这个错误是由于 glsify 优化了着色器代码而发生的。

如果你添加gl_FragColor.a = 0.0;它可以优化你对texture2D调用,因为它被完全覆盖,但在那之前它从texture2D获取alpha通道

如果 glsify 优化了对 texture2D 的调用,则 webgl 不会为uSampler分配内存,因此当 pixi 想要将数据上传到该统一时它会失败,因为根本没有分配的空间。

你有一些选择:

  • 应用与我(目前)相同的 hack,它基本上检查是否在将数据上传到属性之前分配了属性。
  • 使用 uSampler,所以 glsify 不会优化它。
  • 或者只是等待 v5。

希望这会有所帮助。

不错的收获,@doebi!

或者使用渲染器插件。

哦,现在我明白了! 也许我们应该将 Doebi 的补丁添加到 Pixi.js 的下一个小版本中? 我应该创建一个 PR 吗?

你好呀,
我的着色器代码遇到了类似的问题。 它是默认 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你确定是同样的问题吗? 你在控制台看到了什么?

编辑:
没关系,我发现了这个问题,对于 iOS 来说,15 的内核大小似乎太大了,如果我将内核大小减少到 7,它就可以正常工作。

<-----原帖---------->
你好,
很抱歉回复晚了,周末我无法制作一些屏幕截图。 在我看来,它好像在同一条线上失败了。 “属性”未定义。 以下是远程控制台的屏幕截图:
image
image

@ivanpopelyshev我们
我不会再认为这是一个问题,因为我得到了你的承诺,它将在 v5 中修复。

@doebi关闭。

@tyleet从纹理中获取的样本数量在不同的系统上是有限制的。

由于关闭后没有任何近期活动,因此该线程已自动锁定。 请为相关错误打开一个新问题。

此页面是否有帮助?
0 / 5 - 0 等级

相关问题

samueller picture samueller  ·  3评论

zcr1 picture zcr1  ·  3评论

SebastienFPRousseau picture SebastienFPRousseau  ·  3评论

softshape picture softshape  ·  3评论

readygosports picture readygosports  ·  3评论