在Starling中,如何变换滤镜以匹配目标精灵的旋转和放大?位置?

时间:2015-12-14 20:01:30

标签: actionscript-3 flash shader fragment-shader starling-framework

假设你的Starling显示列表如下:

Stage
  |___MainApp
         |______Canvas (filter's target)

然后,您决定将MainApp旋转90度并略微偏移:

 mainApp.rotation = Math.PI * 0.5;
 mainApp.x = stage.stageWidth;

但是突然之间,过滤器继续以最初的角度将目标(画布)应用于目标(画布)(好像MainApp仍处于0度)。

enter image description here

(请注意GIF中Blur的强水平值如何继续仅水平应用,尽管父对象旋转了90度)。

在获取父目标变换之前,需要更改将过滤器应用于目标对象的内容?这样(我假设)过滤器的结果将被父对象转换。

有关如何做到这一点的任何猜测?

https://github.com/bigp/StarlingShaderIssue

(PS:我实际使用的过滤器是定制的,但是这个BlurFilter示例显示了我在自定义过程中遇到的相同问题。如果在着色器代码中有任何修补,至少它不一定要在内置的BlurFilter上完成。)

1 个答案:

答案 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

希望这些提取的代码片段对于具有类似着色器问题的其他人有用。

祝你好运!