— boreal-kiss.com

[AS3]DisplacementMapFilterメモ

定義を誤解しやすい

Adobe – ActionScript 3.0 コンポーネントリファレンスガイドの説明によると、フィルター処理に使われる式は以下のとおり。


dstPixel[x, y] = srcPixel[x + ((componentX(x, y) - 128) * scaleX) / 256,
y + ((componentY(x, y) - 128) * scaleY) / 256)]

ごちゃごちゃしている部分をdx, dy(dx, dyの中身については後ほど説明するとしてここでは何らかの変位量と思ってもらえればok)に書き換えて見やすくするとこんな感じ。


dstPixel[x, y] = srcPixel[x + dx, y + dy]

ここでdstPixelとsrcPixelを一般的な形で説明すると

  • dstPixel[x, y]はx-y座標(x, y)におけるフィルター処理後の表示画像のピクセル値
  • srcPixel[x, y]はx-y座標(x, y)におけるフィルター処理前の表示画像のピクセル値

したがって上式を翻訳すると「位置(x, y)におけるフィルター処理後の画像のピクセル値は、位置(x+dx, y+dy)におけるフィルター処理前の画像のピクセル値を採用している」となる。座標系がフィルター処理後の画像を元にしているところがポイント。「位置(x, y)におけるフィルター処理前の画像のピクセルを(x+dx, y+dy)に移動させてその結果を処理後の画像として採用する」演算ではない。まとめておくとDisplacementMapFilterは

  • (正) 位置(x, y)におけるフィルター処理後の画像のピクセル値に、位置(x+dx, y+dy)におけるフィルター処理前の画像のピクセル値を採用するフィルター
  • (誤) 位置(x, y)におけるフィルター処理前の画像のピクセルを(x+dx, y+dy)に移動させてその結果を処理後の画像として採用するフィルター

となる。ここの仕組みが直感的ではないのでわかりにくい。他にも元画像の位置(x+dx, y+dy)にピクセル情報がないことにはフィルター処理不可能なことがわかる。つまり、元画像のサイズ以上に引き延ばしたりする変形を表現することはできない。

変位(dx, dy)の求め方

フィルター処理前・後のピクセルの変位量の分布さえわかれば意図したフィルター効果を表現できる。具体的な関係式の求め方はpsyark.jp – DMFチュートリアル1がわかりやすい。

置き換えマップイメージ

さて画像は2Dなので各ピクセルごとにx, y方向の2成分の変位量(dx, dy)がわからないといけない。各ピクセルごとの変位情報を(手軽に)2成分もたせるためにはどうすればよいか。そこで登場するのが置き換えマップイメージ。各ピクセルにアルファ、R、G、Bの情報を独立して持たせることができるという画像の性質を利用して、(dx, dy)の変位分布を画像情報として押し込めてしまうわけ。独立して格納したい情報は(dx, dy)の2成分なので、置き換えマップイメージのアルファ、R、G、Bチャンネルの4チャンネルのうちお好みの2チャンネルに格納すればよい(例えばdx情報をR、dy情報をBなど。dx, dyに同じチャンネルを使う場合も含めれば選択肢は4×4=16通りもある)。この中途半端に選択肢の自由度があるところがわかりにくい。([dx, dy]分布情報を格納できれば原理的には二次元配列などでもよいが、配列に格納するのが面倒くさいし、そもそもこのフィルターの演算に採用されていないので意味がない)

Adobeが定義している式に戻ってみると、(dx, dy)は次のような式であることがわかる。


dx = (componentX(x, y) - 128) * scaleX / 256
dy = (componentY(x, y) - 128) * scaleY / 256

ここでcomponentX(x, y)は位置(x,y)におけるマップイメージのdxを格納したチャンネル(つまりアルファ、R、G、Bのどれか)のピクセル値(0-255)、componentY(x, y)は位置(x,y)におけるマップイメージのdyを格納したチャンネルのピクセル値(0-255)が入る。scaleX, scaleYはフィルター使用時に後から好きな値が入れられる(0以上の数値)のでわかりやすくするため1を代入しよう。そうすると、上式は以下のようになる。


dx = (componentX(x, y) - 128) / 256
dy = (componentY(x, y) - 128) / 256

画像の各チャンネルは0-255の数値しかとれないので、この場合変位量は-1/2から1/2の値をとることがわかる。変位幅を大きくしたいならscaleXとscaleYをフィルター利用時に調整すればよい(これは例えば、-10から10までの乱数を得るのに(Math.random()-0.5)*20と書くのに似ているかな)。置き換えマップイメージと変位の関係はmiscellaneous [ActionScript 3.0] DisplacementMapFilterがわかりやすい。

2 comments
  1. […] 久しぶりに ActionScript の話題。 こないだ何の気なしにネットをウロウロしてたら [AS3]DisplacementMapFilterメモ というページに行き当たり、以下の文章を拝見しました。 (正) 位置(x, y)におけ […]

  2. パーリンノイズで遊ぶ1 | log says: 2015年1月18日4:53 PM

    […] ? boreal-kiss.com |?[AS3]DisplacementMapFilterメモ […]

Submit comment