12/11/2015

PixPart II, 3D Brownsche Planetoid Particles

PixPart Part II. Meine kleine JavaScript Engine für Partikel ist zwar noch lange nicht fertig, aber die Entwicklung schreitet voran. Einige Komponenten wie die Vector3 und die Matrix4 Klassen aus der three.js Engine hab ich nun doch wieder rausgeworfen und durch eigene Lösungen ersetzt. Damit ist die Engine wieder komplett frei von externen Komponenten anderer Engines und Pakete. Insgesamt läuft die Engine nun performanter und bietet mehr Möglichkeiten, bei gleichzeitiger Reduktion der Gesamtgröße.
Zum Testen hab ich eine kleine Anwendung geschrieben. Auch hier könnt ihr wieder einige Parameter anpassen und mit der Maus Einfluss aufs Geschehen nehmen. Das Ganze könnt ihr euch direkt hier anschauen oder in einem neuen Fenster betrachten.
     
Bei der Testanwendung handelt es sich um eine Kombination von zwei verschiedenen Techniken.
Zum einen werden die Farbinformationen einzelner Pixel aus einer 2D Grafik entnommen und auf eine 3D Sphere übertragen. Und zum anderen hab ich die Brownsche Bewegung wieder einmal eingesetzt, um bei gedrückter Maustaste die einzelnen Partikel aus der Sphere heraus zu bewegen.

Die Grafik, bzw. Textur aus der ich z.B. die Erde erzeuge sieht so aus:
Alle 5 Texturen stammen übrigens aus der Planet Texture Map Collection und sind natürlich auch in deutlich besseren Auflösungen verfügbar.

Interessant ist mit Sicherheit das Auslesen der 2D Pixelinformationen, um diese dann auf die 3D Partikel zu übertragen. Folgend der entscheidene Part aus dem Code der dafür verantwortlich ist:
var w = sourceImage.width;
var h = sourceImage.height;

for ( var x = 0; x < w; x++ ) {

    for ( var y = 0; y < h; y++ ) {

        //Farbwerte aus Grafik entnehmen
        var c = getSourceImagePixel( x, y );

        //Latitude und Longitude berechnen
        var latitude  = y / ( h / 180 ) - 90;
        var longitude = x / ( w / 360 ) - 180;

        var la = Math.radians( latitude );
        var lo = Math.radians( longitude );

        //Latitude und Longitude auf Sphere übertragen mit einem Radius
        var xP = radius * Math.cos( la ) * Math.cos( lo );
        var yP = radius * Math.sin( la );
        var zP = radius * Math.cos( la ) * Math.sin( lo );

        var particle = addParticle( xP, yP, zP, c.R, c.G, c.B, c.A );

        particleHolder.push( particle );

    }

}
An die Farbinformationen der einzelnen Pixel gelangt man beispielhaft wie folgt:  
function getSourceImagePixel( imageData, x, y ) {

    var i = ( x + y * imageData.width ) * 4;

    return { R:imageData.data[ i ],
             G:imageData.data[ i + 1 ],
             B:imageData.data[ i + 2 ],
             A:imageData.data[ i + 3 ] }

}
Zum Thema „Pixel manipulation with canvas“ findet man so viele gute Beiträge im Netz, da möchte ich an dieser Stelle nicht näher drauf eingehen.
Demnächst geht es hoffentlich weiter und ich kann mehr von der PixPart Engine zeigen. Und vielleicht erreicht die Engine auch irgendwann mal einen Stand, der sich lohnt ihn z.B. bei GitHub hochzuladen.

Keine Kommentare: