0

比方說,你的八哥顯示列表如下:在Starling中,你如何轉換過濾器以匹配目標Sprite的旋轉和位置?

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通知模糊的強勁水平值如何繼續,儘管父對象旋轉90度水平只適用)。

在獲取父對象之前,需要更改過濾器以將其應用於目標對象?這樣(我假設)過濾器的結果將被父對象轉換。

任何有關如何做到這一點的猜測?

https://github.com/bigp/StarlingShaderIssue

(PS:我實際上使用的過濾器是定做的,但這種使用BlurFilter例子顯示我與自定義一個有同樣的問題如果有任何修補,起來做。着色器代碼,至少它不一定必須在內置的BlurFilter上專門完成)。

回答

0

我自己解決了這個問題,在幾個小時的時間內進行了大量的試驗和錯誤嘗試。

因爲我只需要着色器在0或90度下運行(實際上並不像在問題中顯示的gif演示那樣),所以我使用兩組專業的AGAL指令創建了着色器。

沒有太多的細節去,經旋轉版本基本上需要一些額外的指令翻轉的頂點和片段着色器的X和Y字段(或者通過與mov移動它們或直接計算muldiv結果進x或y字段)。

例如,比較0度頂點着色器...

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

...與90度頂點着色器:

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

可以忽略的特殊別名AGAL的例子,他們本質上是posOriginal = v0, posScaled = v1變體和viewportScale = vc4常數,然後我做一個字符串替換將它們更改回它們各自的寄存器&字段)。

只是一個人類可讀的技巧,我用它來避免瘋狂。\ ☻/

,我最是計算正確的比例來調整UV的規模(用正確檢測到舞臺/視口調整大小和渲染,紋理大小的變化)的努力的一部分。

最終,這就是我想出了在AS3代碼:

var pt:Texture = _passTexture, 
    dt:RenderTexture = _displacement.texture, 
    notReady:Boolean = pt == null, 
    star:Starling = Starling.current; 

var finalScaleX:Number, viewRatioX:Number = star.viewPort.width/star.stage.stageWidth; 
var finalScaleY:Number, viewRatioY:Number = star.viewPort.height/star.stage.stageHeight; 

if (notReady) { 
    finalScaleX = finalScaleY = 1.0; 
} else if (isRotated) { 
    //NOTE: Notice how the native width is divided with height, instead of same side. Weird, but it works! 
    finalScaleY = pt.nativeWidth/dt.nativeHeight/_imageRatio/paramScaleX/viewRatioX; //Eureka! 
    finalScaleX = pt.nativeHeight/dt.nativeWidth/_imageRatio/paramScaleY/viewRatioY; //Eureka x2! 
} else { 
    finalScaleX = pt.nativeWidth/dt.nativeWidth/_imageRatio/viewRatioX/paramScaleX; 
    finalScaleY = pt.nativeHeight/dt.nativeHeight/_imageRatio/viewRatioY/paramScaleY; 
} 

希望這些提取出的代碼段可以幫助他人與類似着色器的問題。

祝你好運!

相關問題