DisplacementMapFilter Tutorial Wellenbewegung

Dezember 13th, 2009 by admin

DisplacementMapFilter Tutorial Nummer eins: Der Effekt ist beinahe klassisch, man nehme eine fortlaufende perlinsche Störung und verwende sie als DisplacementMap für für einen DisplacementMapFilter. Diesen wendet man dann in einer EnterFrame Schleife auf ein Bild an, beispielsweise ein Foto:

FlashPlayer starten

Ein geradezu halluzinogener Effekt, doch schon eilt die Ernüchterung:

import flash.display.Bitmap;
import flash.display.BitmapData;
import flash.display.BitmapDataChannel;
import flash.filters.DisplacementMapFilter;
import flash.display.DisplayObject;
 
import flash.events.MouseEvent;
import flash.events.Event;
 
var pic:DisplayObject = new luke_pic;
var bitdata :BitmapData = new BitmapData(pic.width + 30, pic.height + 30);
var displacement :DisplacementMapFilter;
var perlinCounter :uint = 0;
var displacementIntensity :uint = 50;
 
addChild(pic);
addEventListener(Event.ENTER_FRAME, wave);
 
function wave(e:Event) {
	perlinCounter += 6;
	bitdata.perlinNoise(200, 200, 1, 5, true, true, 3, false, [new Point(perlinCounter, perlinCounter)]);
	displacement = new DisplacementMapFilter(bitdata, new Point( -15, -15), BitmapDataChannel.GREEN, BitmapDataChannel.RED, displacementIntensity, displacementIntensity, "color");
	pic.filters = [displacement];
}

Hier werden sowohl das Perlinbild, wie auch der DisplacementmapFilter in jedem Frame aktualisiert. Das Perlinbild dient dem DisplacementMapFilter als DisplacementMap. Der DisplacementMapFilter nutzt die Farben aus der DisplacementMap als Grundlage, für die Verzerrungen im Bild. Diese Verzerrungen entstehen wiederum dadurch, dass anhand der Farbwerte aus der neue Dimensionen für die einzelnen Pixel errechnet werden, dass heißt sie vergrößern oder verkleinern sich und schieben die umliegenden Pixel einfach zur Seite.

Dazu muss man dem DisplacementMapFilter zunächst mitteilen, welche Farbe für verzerrungen auf der x-Achse und welche für solche auf der y-Achse genutzt werden sollen. In diesem Fall soll grün auf der x-achse und rot auf der y-achse verzerren, das sind die Parameter 3 und 4.

new DisplacementMapFilter(bitdata, new Point( -15, -15), BitmapDataChannel.GREEN, BitmapDataChannel.RED, displacementIntensity, displacementIntensity, "color")

Parameter 1 ist die DisplacementMap, aus der die Farbinformationen genommen werden, wie gesagt handelt es sich hier um ein bild, das mit der BitmapData.perlinNoise funktion generiert wurde. Hierzu gibt es Näheres in diesem Tutorial. Der darauffolgende Punkt mit den x und y = -15 besagt, wo die DisplacementMap auf dem pic liegt: Im grunde bedeutet das, dass das Perlinbild, 15 pixel über und 15 pixel links von dem Registrierungspunkt des Objekts angesetzt wird, dass gefiltert wird, also das pic.

new DisplacementMapFilter(bitdata, new Point( -15, -15), ...

Dann noch die Intensität, mit der verzerrt werden soll, auch jeweils auf den x und y achsen. Je höher dieser Wert, desto stärker die Verzerrung. Am Schluss des Funktionsaufrufes kann noch ein Modus übergeben werden, Color ist in der Regel der Beste, bei weiterem Interesse an den Modi, möchte ich auf die Adobe Docs verweisen.

Jetzt nochmal zum besseren Verständnis am Stück:
Der DisplacementMapFilter wird auf (-15|-15) relativ zum RegistrierungsPunkt des Bildes (0|0) gelegt. Jetzt liegt die DisplacementMap über dem Pic, es liegen also auch immer ein Farbiger Pixel aus dem PerlinBild (= die DisplacementMap) über jedem Pixel des Pics. Also beginnt der Filter damit, jeden Pixel im Bild, mit der Farbe des Pixels aus dem Perlinbild zu vergleichen. Ist die Farbe im PerlinBild knallrot, wird der Pixel auf der y-Achse gestreckt, alle Pixel über und unter ihm werden einfach zur Seite geschoben. Ist die Farbe dagegen braun und enthält folglich sowohl rot, als auch grün, wird der Pixel in dem zu filterenden Bild auf x und y gestreckt, in dem entsprechenden Verhältnis von rot und Grün in dem Braunton.

Neutral verhält sich der Filter zu der zu folgendem Grauton: 0×808080, also das grau, das exakt zwischen schwarz und weiß liegt. Und übrigens: der DisplacementMapFilter ist ein echter PerformanceKiller, wenn man es damit übertreibt.

Bleibt noch zu sagen, dass dieser Filter von allen der komplizierteste ist und man erst damit experimentiert, ehe man das Gefühl dafür bekommt. Einfach ein bisschen mit den Parametern zu spielen, ist auch ein guter Anfang. Anschließend lohnt es sich bestimmt, dieses Tutorial nochmals zu lesen. Und keine Sorge, es sind bereits weitere Tuts zu dem Thema in der Schmiede.