flash as3 變形特效(DisplacementMapFilter原理&應用)
球狀 http://homepage.ntu.edu.tw/~b95901008/bbsfiles/AS/DisplacementMapFilter/DisplacementMapFilter%20test.swf
水波 http://homepage.ntu.edu.tw/~b95901008/bbsfiles/AS/DisplacementMapFilter/DisplacementMapFilter%20test2.swf
震波 http://homepage.ntu.edu.tw/~b95901008/bbsfiles/AS/DisplacementMapFilter/DisplacementMapFilter%20test3.swf
然後是原始檔
http://homepage.ntu.edu.tw/~b95901008/bbsfiles/AS/DisplacementMapFilter/DisplacementMapFilter%20test.rar
http://homepage.ntu.edu.tw/~b95901008/bbsfiles/AS/DisplacementMapFilter/DisplacementMapFilter%20test2.rar
http://homepage.ntu.edu.tw/~b95901008/bbsfiles/AS/DisplacementMapFilter/DisplacementMapFilter%20test3.rar
最後是DisplacementMapFilter講解~
----------------------講解開始----------------------
DisplacementmapFilter 藉由讀取的 BitmapData 資料來把一個圖片的像素搬移位置
每個像素搬移的方式不同就會造成 "圖片的扭曲效果"
DisplacementMapFilter 所使用的公式是下面這條:
(不要被他醜陋的外表嚇到,我下面會盡量簡單地解釋)
dstPixel[x, y] = srcPixel[x + ((componentX(x, y) - 128) * scaleX) / 256, y + ((componentY(x, y) - 128) * scaleY) / 256]
(以上的公式意思是把 srcPixel 搬移到 dstPixel 所使用的公式)
以下開始解說:
先來解釋一下代表 color channel 的 componentX, componentY
在 Flash 裡面所謂的 color channel 有分四個
也就是 Red, Green, Blue, Alpha
所對應到的 channel value 是 1, 2, 4, 8
要指複數個 color channels 的話,把兩個數字加起來就可以了
像是 1 + 4 + 8 == 13 → 13 就直接代表 R, B, A 三個 channels
(各種組合方式都不會產生同樣的數字)
又 RGBA 顏色分為 256 種量值大小,取一半就是128
componentX, componentY 所要參考的就是
被參考的 BitmapData 上面座標為 (x, y) 的像素的 color channel
比方說 componentX == 1 就代表要參考 BitmapData 上面的 Ren channel 就好
還有 scaleX, scaleY 則是設定像素搬移的比率
假如在被參考的 BitmapData 中 scaleX == 10, componentX(10, 10) == 1
然後這 BitmapData 在 (10, 10) 的 Red 值是 256
則使用這個 DisplacementManFilter 的物件
它的 (10, 10) 像素就會被往右搬移搬移 ((256 - 128)/128)*10 == 10 像素
所以利用外部匯入或者在Flash內部繪製不同的參考 BitmapData
可以產生多樣的 DisplacementMapFilter 變形特效
參考用的 BitmapData 只要參考他的 Red channel 就夠了
(因為一般參考用 BitmapData 習慣設成灰階的)
就像一般 filter 一樣
DisplacementMapFilter 也有建構式:
DisplacementMapFilter(mapBitmap:BitmapData, mapPoint:Point, componentX:Number, componentY:Number, scaleX:Number, scaleY:Number, [mode:String], [color:Number], [alpha:Number])
前面當然要加上 var myFilter:DisplacementMapFilter = new XXX 來宣告變數
mapBitmap 就是傳入參考用的 BitmapData
mapPoint 是你要從 mapBipmap 的哪個像素開始參考
(假如你從 (5, 5) 開始參考一個100X100的 mapBitmap,那 mapBitmap 的尺寸感覺上就是 95X95)
componentX, componentY 就是在決定像素位移個時候要參考mapBitmap 像素的 color channel
scaleX, scaleY 是決定 "位移百分比(0.0~1.0)" 之後要乘上的倍率
mode, color, alpha 比較複雜且不重要,可以不要寫,有興趣也可以參考help file
接下來就是大致的 coding 流程了:
1.先匯入一個當作"變形參考圖"的圖檔(習慣用灰階,並且記得設定 linkage ID)
2.宣告一個含有該圖檔的 BitmapData
3.宣告 DisplacementMapFilter並且指定該 BitmapData 為參考圖
4.設定目標 mc 的 filter == [myFilter]
(其中 myFilter 就是上一步建構的DisplacementMapFilter)
最後提一下"震波"範例的原理:
之前提到DisplacementMapFilter的參考用BitmapData
可以選擇參照RGB channels其中的任何一個(或多個)
中間值是128,比128大或小決定位移的量值
256代表位移scaleX/scale的100%,0帶表 -100%
所以在參考用BitmapData的設計上就需要利用以上原理
繪製參考用BitmapData的參考mc就是library裡面的displacer
裡面用兩個圓形shape帶有線性漸層(R & G from 0~256)用add blender疊加
外面再用圓形漸層從 (R, G, B, A) = (128, 128, 128, 0) 到 (128, 128, 128, 100)
這樣就可以讓參考BitmapData的外為不要有明顯的截痕
(因為0x808080的RGB值都是128,代表DisplacementMapFilter無法作用)
其他displacer的位置變換、大小修改實際情形請參照原始檔
簡單講一下我用的"震波漸弱"技巧
其實也是把之前物理課學到的"阻尼震盪(damped oscillation)"...拿來現學現賣而已XD
我的震盪是用最大震盪值乘上Math.cos()函數已達到簡協效果(應該很明顯...)
然後在乘上Math.pow(Math.E, damping)的阻尼常數
damping會隨著時間越來越小(從0開始變成負的)
就會有阻尼震盪的效果啦~
P.S.上課數學&物理專心聽,還是會受用的~XDD
----------------------講解結束----------------------
本文章來自於神魂顛倒論壇 http://bbs.flash2u.com.tw
原文網址:http://bbs.flash2u.com.tw/dispbbs_181_75038_1_17.html