Böses, böses Flash!

August 27th, 2010 by admin

Vor Kurzem hat eine kleine Revolution statt gefunden. Denn früher war das Textfeld der wahrhaftigste Feind des Flashers, aber nun, da Adobe ein brandneues Textrendering nachgelegt hat, nimmt Steve Jobs diesen Platz feierlich ein. Und zwar wohl verdient. Denn der tut alles, um die innovativste Webtechnologie aller Zeiten zu schwächen. Und scheitert konsequent. Böses, böses Flash. Als wir Flasher uns noch über schwammigen Text und inkomatible bitmap-fonts geärgert haben, hörte man diese Worte nur von HTML-Nerds, für die alle Designs gleichwertig waren und die genauso viel von Webexperience verstanden haben, wie ich von Pferdezucht. Das heißt, wahrscheinlich noch weniger.

Wenn man sich die Entwicklung des Internets ansieht, erkennt man dass es mehr und mehr zum Unterhaltungsmedium schlechthin mutiert. Ich persönlich begrüße das, denn mit ein wenig Glück wird es dazu führen, dass unser vor Dummheit strotzendes TV-Programm bald der Vergangenheit angehört. Internt – Unterhaltung – Flash. Passt wunderbar zusammen, nicht? Die mächtigsten Konzerne des Planeten entwickeln laufend neue Produkte und wenn es darum geht diese ansprechend (im Internet und darüber hinaus) zu präsentieren – ist Flash die Waffe Ihrer Wahl. Warum? Weil es um Unterhaltung geht, es geht um Emotionen.

Geht man noch einen Schritt weiter und sieht sich die Menschen damals und heute an, dann erkennt man, dass die Leute immer nach neuen, spannenden “Inhalten” zur Unterhaltung geschriehen und laut gejubelt haben, wann immer Sie sie bekamen. Zumindest im Übertragenen Sinne, denn von Gladiatorenkämpfen sind wir weitestgehend abgerückt. Das Internet ist die neue Arena und Flash ist sein mächtigster Gladiator. Nicht im Übertragenen Sinne, wortwörtlich. Und der wird die Waffen nicht niederlegen, weil ein paar IPhone Fans ihrem Steve alles nachquatschen, was der von sich gibt.

Ungeachtet dessen, dürfte die nächste große Revolution im Unterhaltungssektor GoogleTV werden. Kaum Werbung, keine Zeitliche Bindung und freie Auswahl – wer wird dem das Kabelfernsehen vorziehen wollen? Man kann vieles von Google behaupten, zum Beispiel, dass Sie zu mächtig geworden sind, aber eines steht fest: Wenn google etwas macht, dann richtig, ergo wählt es die besten ihm zur verfügung stehenden möglichkeiten (statt Milliarden in werbung für gleichwertiges zu investieren). Und für das Interface Ihres GoogleTV wählten Sie Flash. Sie wissen schon, warum. Und wir Flasher wissen es auch.

Displacementmapfilter – Dynamischen Nebel erzeugen

Mai 20th, 2010 by admin

In diesem Displacementmapfilter Tutorial geht es um die Erzeugung von dynamischen Nebeleffekten. Hierzu erzeuge ich erst eine Nebelwand mittels einer Perlinschen Störung, in der ich zunächst die Dunklen bereiche transparent mache (je dunkler desto durchsichtiger) und anschließend deren Farbwerte durch Weiß ersetze. Das Ergebniss ist ein durchgehend weißes Bild, mit durchsichtigen Verläufen, wo sich zuvor dunkle Bereiche befanden.

FlashPlayer starten

Hier das Script:

 var fogData : BitmapData;
 var fog : Bitmap;
 var _w : int = 550;
 var _h : int = 400;
 
 var _perlinData : BitmapData ;
 var _dispFilter : DisplacementMapFilter ;
 
 var _perlinOff : Array = new Array;
 var _numOctaves : int = 3 ;
 
 var _baseX : int = 100 ;
 var _baseY : int = 100 ;
 var _strength : int = 50 ;
 
 
 createFogData() ;
 createFog() ;
 createDisplacement() ;
 addChild(fog);
 
 
 function createFogData() : void {
 
	fogData = new BitmapData( _w, _h ) ;
 	fogData.perlinNoise( _baseX, _baseY, _numOctaves, 10, true, true, 7, true, [new Point(0, 0) ] ) ;	
 }
 
 function createFog() : void {
 
	var rect : Rectangle = new Rectangle( 0, 0, _w, _h ) ;
	var old_bytes : ByteArray = fogData.getPixels( rect ) ;
	var new_bytes : ByteArray = new ByteArray();
 
	old_bytes.position = 0 ;
 
	for (var i:int = 0; i < old_bytes.length; i+=4) 
	{				
		new_bytes[i + 0] = 255 - old_bytes[i + 1] ; // alpha is negated R (R == G == B)
 
		new_bytes[i + 1] = 255 ; 
		new_bytes[i + 2] = 255 ;
		new_bytes[i + 3] = 255 ; // RGB = 0xffffff
	}
 
	fogData.setPixels( rect, new_bytes ) ;
	fog = new Bitmap( fogData ) ;
	fog.alpha = .5;
}
 
 function createDisplacement() : void {
 
		_perlinOff = new Array ;
		_perlinOff.push( new Point ) ;
		_perlinData = new BitmapData( _w , _h, false ) ;
		_dispFilter = new DisplacementMapFilter( _perlinData, new Point( ), BitmapDataChannel.RED, BitmapDataChannel.GREEN, _strength, _strength, "color" ) ;
 
		this.addEventListener( Event.ENTER_FRAME, perlinize );
}
 
 function perlinize( e:Event ) : void {
			_perlinOff[0].x++;
			_perlinOff[0].y++;
			_perlinData.perlinNoise( _baseX, _baseY, 1, 50, true, true, 7, false, _perlinOff ) ;
			fog.filters = [ _dispFilter ] ;
		}

Das Ganze funktioniert folgdender Maßen: Man lädt die Pixelwerte des Perlin-Bildes in ein Bytearray. Hier stehen immer vier bytes (8 Bits, also werte zwischen 0 und 255) für einen Kanal, ALPHA – RED – GREEN – BLUE, in dieser Reihenfolge. Da in der perlin() funktion der parameter Grayscale aktiviert ist, entsprechen die bytes 2-4 einander (R = G = B), somit ist jeder Pixel grau, weil kein Farbkanal den anderen überwiegt.
Ersetzt man nun das erste Byte ALPHA mit 255 (nicht transparent) durch 255 – R (je dunkler desto durchsichtiger), muss man nur noch die Übrigen bytes R G und B auf 255 (ergibt weiß) setzen und schon hat man die besagte Nebelwand.

Anschließend wird eine weitere, diesmal in einer ENTER_FRAME Schleife fortlaufend gemachte Perlinsche Störung in Kombination mit einem Displacementmapfilter dazu benutzt, der Nebelwand eine realistische, dynamische Bewegung zu geben.

Das Ergebniss ist schaurig schön, nicht wahr?

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