假设你的Starling显示列表如下:
Stage
|___MainApp
|______Canvas (filter's target)
然后,您决定将MainApp
旋转90度并略微偏移:
mainApp.rotation = Math.PI * 0.5;
mainApp.x = stage.stageWidth;
但是突然之间,过滤器继续以最初的角度将目标(画布)应用于目标(画布)(好像MainApp仍处于0度)。
(请注意GIF中Blur的强水平值如何继续仅水平应用,尽管父对象旋转了90度)。
在获取父目标变换之前,需要更改将过滤器应用于目标对象的内容?这样(我假设)过滤器的结果将被父对象转换。
有关如何做到这一点的任何猜测?
https://github.com/bigp/StarlingShaderIssue
(PS:我实际使用的过滤器是定制的,但是这个BlurFilter示例显示了我在自定义过程中遇到的相同问题。如果在着色器代码中有任何修补,至少它不一定要在内置的BlurFilter上完成。)
答案 0 :(得分:0)
我在几个小时的过程中经过多次尝试和错误尝试解决了这个问题。
由于我只需要在0或90度下运行着色器(实际上没有像问题中显示的gif演示那样进行补间),我创建了一个带有两组专用AGAL指令的着色器。
没有太多细节,旋转版本基本上需要一些额外的指令来翻转顶点和片段着色器中的x和y字段(通过用mov
移动它们或直接计算{{1 }或mul
导致x或y字段)。
例如,比较0度顶点着色器...
div
...使用90度顶点着色器:
_vertexShader = [
"m44 op, va0, vc0", // 4x4 matrix transform to output space
"mov posOriginal, va1", // pass texture positions to fragment program
"mul posScaled, va1, viewportScale", // pass displacement positions (scaled)
].join("\n");
您可以忽略AGAL示例中的特殊别名,它们基本上是
_vertexShader = [ "m44 op, va0, vc0", // 4x4 matrix transform to output space "mov posOriginal, va1", // pass texture positions to fragment program //Calculate the rotated vertex "displacement" UVs "mov temp1, va1", "mov temp2, va1", "mul temp2.y, temp1.x, viewportScale.y", //Flip X to Y, and scale with viewport Y "mul temp2.x, temp1.y, viewportScale.x", //Flip Y to X, and scale with viewport X "sub temp2.y, 1.0, temp2.y", //Invert the UV for the Y axis. "mov posScaled, temp2", ].join("\n");
变体和posOriginal = v0, posScaled = v1
常量,然后我执行字符串替换以将它们更改回各自的寄存器和放大器;领域)。我用一个人类可读的技巧来避免疯狂。的 \☻/ 强>
我最挣扎的部分是计算正确的比例以调整UV的比例(正确检测到舞台/视口调整大小和渲染纹理大小的变化)。
最终,这是我在AS3代码中提出的:
viewportScale = vc4
希望这些提取的代码片段对于具有类似着色器问题的其他人有用。
祝你好运!