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.

Next steps?

Dezember 9th, 2009 by admin

So, was steht denn auf der Liste? Ein Tutorial zur Interaktiviät in PV3D um den Grundlagenkomplex abzuschließen und dann ein paar weiterführende Themen dazu, die OoP Grundlagen dürfen ruhig nebenbei entstehen und hier wirds interessant: DisplacementMapFilter! Ein bisschen Lupen-, Feuer-, Wind-, Wasser- und Schockwelleneffekte, kann ja nicht schaden und dürfte für viele interessant sein. Ausserdem habe ich vor einigen Monaten fortlaufende perlinsche Störung beschrieben, was eine gute Grundlage bildet. Und das MVC ein klein wenig auseinanderzunehmen nützt sicher vielen, was denkst du? Wenn es einen Wunsch deinerseits gibt, nur raus damit!

Waving Leda

Dezember 8th, 2009 by admin

Jetzt habe ich die letzten Tage ein Paar tuts für meine geschätzten Leser produziert, doch es wurde Zeit mal wieder was Neues auszuprobieren. Und weil ich im Rahmen der Grundlagen-Tutorials für Papervision mal wieder ein paar Kleinigkeiten im 3D Bereich coden konnte, hab ich mich auch für ein 3D Experiment entschieden. Das Ergebnis ist “Wavin’ Leda”, Davinci wäre begeistert (oder er dreht sich gerade in Grabe um). Dabei stellt man schnell fest, dass Bitmapmaterials mit Shader und Modifikatoren die FrameRate in die Knie gehen lassen. Ich habe das Plane hier mit nur 10×10 Segmenten mit “Leda bezogen” (hoffentlich liest das ein Kunsthistoriker) und komplett auf shading verzichtet und ich merke wie meine Athlon CPU leidet. Mit einfachen ShadeMaterials läuft die Sache schon flüssiger, aber dass niemand einen falschen Eindruck von meiner Meinung bekommt: AS3Dmod ist großartig, seht selbst:

FlashPlayer starten

Hier könnt ihr könnt ihr WavinLeda downloaden.
Um den Code zu kompilieren, benötigt ihr AS3DMod und natürlich Papervision3D Great White

OoP Grundlagen Einführung

Dezember 7th, 2009 by admin

Wenn man über Objektorientierte Programmierung spricht, begibt man sich in ein komplexes Theoriekonstrukt, dass zunächsteinmal sehr abstrakt wirkt. Also pack ich die Sache andersherum an und versuche so praxisnah wie möglich zu schreiben, indem ich einfach davon ausgehe, dass sich der Rest in der Praxis ergibt.

Eines muss hier klar sein und zwar gibt es einen Unterschied, zwischen dem Produzieren von funktionsfähigen Code in einer Objektorientierten Sprache (darum geht es hier) und dem verinnerlichen des “Theoriemonsters”. Letzteres setzt meiner meinung nach ersteres voraus und wird überhaupt erst erreicht, wenn man sich an DesignPattern macht. DesignPattern schöpfen die Macht Objektorientierter Strukturen erst aus, ich plane auch hierzu noch das eine oder andere Tutorial.

Zurück zum Einstieg, hier werde ab und an eine Metapher nutzen, ich hoffe das ist kein Problem. Oder wenn ich etwas zehn mal nacheinander sage – hauptsache es bleibt hängen. In jedem Fall rate ich, sich die Sachen genau vorzustellen, denn eben so wird es am effektivsten hängen bleiben. Ok, dann mal los.

OoP Grundlagen Actionscript3 Klassen verstehen

Dezember 7th, 2009 by admin

Schon mal Matrix gesehen? Was wäre wenn eine der Maschienen mist gebaut hätte und die Matrix wäre ausgefallen, zack sind all die Menschlein in ihren schleimblasen wach und zappeln rum. Kein Problem, die AdministratorMaschiene kommt herbeigeeilt und drückt auf den Reload Button (den hat auch warnerbrothers gedrückt und wir haben uns den Mist angesehen). Reload läuft, aber jetzt müssen all die virtuellen körper für die ganzen Menschlein erst erstellt werden.
Also bitte, enter the matrix:

Was ist eine Klasse? Ich bin das Produkt einer Klasse, die Lukas heißt und du bist das Produkt von einer, deren Namen später vieleicht in den Kommentaren auftaucht. Jedenfalls kennst den Namen, also lass uns unsere Klassen vergleichen. Ich trinke meinen Kaffee mit Zucker, arbeite gern spät bis in die Nacht hinein und höre Limp Bizkit. Da sollte in der Mehrheit der Fälle schon mal ein Unterschied zu dir bestehen. Ausserdem habe ich zwei Arme mit Händen dran und so ein Teil zwischen meinen Augen, dass aus meinem Gesicht hervorschaut. Mein Gott, du auch!?

Offensichtlich haben unsere Klassen, die nichts anderes darstellen, als der Bauplan für die Objekte, die wir sind, ihre Gemeinsamkeiten und Unterschiede. Das lässt sich sehr simpel begründen. Klassen können ihren Bauplan vererben und unsere Klassen erben auch beide von der selben Klasse: Mensch. Allerdings erben wir nicht direkt von “Mensch”, es gibt schließlich nur zwei Klassen, die das unmittelbar können und zwar “Mann” und “Frau”, das sind die einzigen Klassen von denen unsere Klassen direkt erben. Mann und Frau besitzten alles, was die Klasse “Mensch” zur Verfügung stellt, haben aber auch ihre unterschiede. Dann kommen du und ich in der Hierarchie und haben/können alles was Frau oder Mann uns vererbt hat.

Nur was genau wird hier “zur Verfügung gestellt” wenn meine Klasse von der Klasse Frau oder Mann erbt? Das können nur zwei verschiedene Dinge sein: Eigenschaften und Methoden. Ich habe einige meiner Eigenschaften verraten, zum Beispiel “Limp Bizkit”. Doch diese Eigenschaft wurde direkt durch meine Klasse “Lukas” erstellt, denn weder die Klasse Mensch noch die Klasse Mann, deren Methoden und Eigenschaften in mich eingehen, erachten Limp Bizkit als unabdinglich, für die Objekte die aus ihnen erschaffen werden sollen. Anders die dazugehörige Methode: Das Hören, denn das kommt direkt aus der Klasse Mensch und steht somit allen Objekten zur Verfügung, deren Klasse von dieser Klasse abstammen.

Knock Knock, neo. Zeit den Stecker zu Ziehen und wieder in die Realität Objektorientierter Programmierung einzusteigen:

// Dieser Code wurde "maschinell" erstellt...
public class Mensch {
 
	function hoere(aritst:String)
	{
		trace(artist);
	}
}
// ...um anschließend erweitert zu werden...
public class Mann extends Mensch {
 
	// na? was macht einen echten Mann aus?
}
// ...damit ich neu erstellt werden kann...
public class Lukas extends Mann {
 
	var artist :String = "Limp Bizkit";
}

Alles klar, jetzt muss ich nur noch erstellt werden. Dazu wird eine Variable für mich angelegt, namens luke. Diese Variable repräsentiert den Arbeitsspeicher, in den das Objekt geladen wird, das von der Klasse Lukas erstellt worden ist. Dann kann man bequem über den punkt auf die funktionen oder eigenschaften des Objekts zugreifen.

var luke = new Lukas();
luke.hoere(luke.artist);

Fazit:
Klassen bestehen aus Methoden und eigenschaften, die sie vererben können, bzw. überhaupt erst bekommen, indem sie von klassen erben. Eigenschaften sind werte in form von variablen, methoden sind funktionen, die in aller regel mit diesen Werten abreiten. Doch eine Klasse ist nicht das Objekt selbst, sondern der Bauplan dazu.

In der Praxis
Das populärste Beispiel, man exportiert einen clip aus der Bibliothek, nennt ihn myClip und es wird einem weiter untent Prompt die BasisKlasse angezeigt, von der diese erbt: Der MovieClip. Flash erstellt an dieser stelle eine neue Klasse namens “myClip”. Und so produziert man dann das resultierende Objekt:

var clip = new myClip();

Wenn euch das geholfen hat, oder ihr euch auskotzen wollt: Hinterlasst einen Kommentar.

Euer weises Kaninchen.