3/11/2016

Up to 1.572.864 Particles with custom Displacement Shader

Bei diesem Experiment habe ich seit längerer Pause mal wieder mit ThreeJS gearbeitet.
Nach den ganzen Canvas Experimenten zuletzt war es mal wieder an der Zeit auf die volle Leistung von WebGL Zugriff zu haben.
Ich habe dazu mein „Distorted Sphere“ Canvas Experiment für ThreeJS portiert.
Wo bei den Canvas Experimenten bei 50.000 bis maximal 100.000 Partikeln Schluss war, geht es nun auch mit bis zu 1.572.864 Partikeln, und dass bei 60FPS (auf einer flotten Maschine).
Ich habe dazu meine ersten (Displacement Particle) Shader geschrieben, damit die ganzen Berechnungen nicht auf der CPU, sondern der GPU berechnet werden. Die beiden Shader (vertex und fragment) sind bestimmt noch nicht perfekt, aber ich stell die euch hier weiter unten zur freien Verfügung. 


Die Partikel habe ich mit Hilfe der „Points“-Klasse, dem ShaderMaterial und der BufferGeometry von ThreeJS realisiert. Auch hier gibt es die entscheidenen Code-Schnipsel weiter unten mit dazu. Die Berechnung, bzw. Anordnung, der Partikel wird hier nicht näher erklärt, aber dafür seht ihr wie ihr Partikel adden könnt und was nötig ist um diese mit den beiden Shadern zu animieren.
 

Wie immer könnt ihr über das Menü diverse Einstellungen vornehmen und so das Experiment aktiv beeinflussen. Die Steuerung erfolgt per Maus (Klick + Drag und Srollrad) oder Touch-Gesten.

Hier geht es direkt zum Experiment. Besonders zu empfehlen für Mobile User/Touch Devices!
Der Fullscreen-Modus funktioniert im Moment leider nur im Chrome Browser fehlerfrei.


Hier die beiden Shader (vertex und fragment):
uniform float size;

varying float distance;
uniform float distanceMax;

uniform float amplitude;
uniform float d;
uniform float pi;

varying vec3 v;

void main() {

    float x = position.x;
    float y = position.y;
    float z = position.z;

    distance = cos( x * d * pi ) * cos( y * d * pi ) * cos( z * d * pi ) * amplitude;

    v = vec3( x, y, z );
    v = normalize( v );
    v *= distance;

    vec3 pos = position + v;

    gl_PointSize = size;
    gl_Position = projectionMatrix * modelViewMatrix * vec4( pos, 1.0 );

}
varying float distance;
uniform float distanceMax;

uniform int colorScheme;

void main() {

    float percent = ( distance + distanceMax ) / ( distanceMax * 2.0 );

    if ( colorScheme == 0 ) {

        gl_FragColor = vec4( 1.0, percent, 0.0, 1.0 );

    } else if ( colorScheme == 1 ) { 

        gl_FragColor = vec4( 1.0 - percent, 1.0 - percent, 1.0 - percent, 1.0 );

    } else if ( colorScheme == 2 ) { 

        gl_FragColor = vec4( 0.0, percent, 1.0 - percent, 1.0 );

    } else if ( colorScheme == 3 ) { 

        gl_FragColor = vec4( percent, 0.0, 0.0, 1.0 );

    } else if ( colorScheme == 4 ) { 

        gl_FragColor = vec4( 0.0, percent, 0.0, 1.0 );

    } else if ( colorScheme == 5 ) { 

        gl_FragColor = vec4( 0.0, 0.0, percent, 1.0 );

    } else if ( colorScheme == 6 ) { 

        gl_FragColor = vec4( percent, 0.0, 1.0 - percent, 1.0 );

    } else if ( colorScheme == 7 ) { 

        gl_FragColor = vec4( 1.0 - percent, percent, percent, 1.0 );

    }

}
Und hier die entscheidene Code Passage zum erstellen der Partikel:
var geometry = new THREE.BufferGeometry();

var positions = new Float32Array( particles * 3 );

var index = 0;

for ( var i = 0, l = positions.length; i < l; i += 3 ) {

    // positions

    var phi = Math.acos( -1 + ( 2 * index ) / particles );
    var theta = Math.sqrt( particles * Math.PI ) * phi;

    var x = radius * Math.cos( theta ) * Math.sin( phi );
    var y = radius * Math.sin( theta ) * Math.sin( phi );
    var z = radius * Math.cos( phi );

    positions[ i     ] = x;
    positions[ i + 1 ] = y;
    positions[ i + 2 ] = z;

    index++;

}

geometry.addAttribute( 'position', new THREE.BufferAttribute( positions, 3 ) );

uniforms = {

    amplitude: { type: 'f', value: 0 },
    d: { type: 'f', value: d },
    pi: { type: 'f', value: Math.MATHPI180 },
    distanceMax: { type: 'f', value: sinusMaxAmplitude },
    size: { type: 'f', value: particleSize },
    colorScheme: { type: 'i', value: colorScheme }

}

var shaderMaterial = new THREE.ShaderMaterial( {

    uniforms: uniforms,
    vertexShader: document.getElementById( 'vertexshader' ).textContent,
    fragmentShader: document.getElementById( 'fragmentshader' ).textContent

} );

points = new THREE.Points( geometry, shaderMaterial );

scene.add( points );
An dieser Stelle wird der Wert für die Amplitude in der render Function an die Shader übergeben:
uniforms.amplitude.value = sinusAmplitude;

3/04/2016

23 Amazing And Inspiring HTML5 Canvas Experiments

In diesem Beitrag möchte ich euch eine Auswahl meiner Favoriten im Bereich kreativer Canvas Experimente vorstellen. Mit dabei sind ältere Experimente, aber das Alter spielt hierbei eigentlich gar keine Rolle. Genauso wenig das Thema. Egal ob Partikel-Effekt, Physik-Simulation, oder was auch immer. Vor allem wichtig, die Experimente sollen inspirieren, überraschen und begeistern. 

Daneben gab es bei der Zusammenstellung dieser Liste eigentlich nur ein Kriterium. Für die Darstellung der Inhalte muss das Canvas-Element verwendet werden.
Bei der riesengroßen Auswahl und den wirklich super tollen WebGL Experimenten, die in letzter Zeit erschienen sind und fast täglich neu erscheinen, gerät die Canvas etwas ins Hintertreffen. Natürlich kann die Canvas, nicht nur was die Performance usw. angeht, nicht mit WebGL mithalten, aber dafür ist das Canvas-Element weiter verbreitet und wird, jedenfalls noch, von mehr Browsern (brauchbar) unterstützt. Und daher wollte ich mit dieser kleinen Liste eine Lanze brechen für die Canvas.


Aber zurück zum Thema, den Experimenten. Ich habe hier, wie gesagt, meine 23 Favoriten zusammengestellt. Die Reihenfolge spielt keine Rolle und auch nicht die Titel oder die Autoren. Und bevor ich euch jetzt weiter zutexte, wünsche ich einfach viel Spaß mit den Canvas Experimenten.


Color Cycle by Mark Ferrari & Joseph Huckaby

http://www.effectgames.com/demos/canvascycle/

Tearable Cloth by Adam Brooks

http://codepen.io/dissimulate/full/KrAwx

Cloth Simulation by gyuque


http://gyu.que.jp/jscloth/

Hypnos by Hakim


http://lab.hakim.se/hypnos/


Motion Graphic Typeface II by ara


http://codepen.io/ara_machine/full/EwfpL

Flat Surface Shader by Matthew Wagerfield & Tobias van Schneider

http://matthew.wagerfield.com/flat-surface-shader/

Ball pool by Mr.doob

http://mrdoob.com/projects/chromeexperiments/ball-pool/

prometheus II by Gerard Ferrandez

http://codepen.io/ge1doot/full/bEgLaM

approaching by Gerard Ferrandez

http://codepen.io/ge1doot/full/PPzRdL

way back by Gerard Ferrandez

http://codepen.io/ge1doot/full/OypQdy

what power by Gerard Ferrandez

http://codepen.io/ge1doot/full/LpLLQa

CanvasMol by AlteredQualia

http://alteredqualia.com/canvasmol/#Chlorophyll

javascript 3d model viewer by Giuseppe Sicari

http://www.giuseppesicari.it/progetti/javascript-3d-model-viewer/

Or so they say by xplsv

http://xplsv.com/prods/demos/xplsv_orsotheysay/

Strange Attractor by Mr.doob

http://mrdoob.com/#/107/strange_attractor

Flying Particles by Lucas Motta

http://codepen.io/lucasmotta/full/dpDqB

Particle Plasma Terrain by Loktar

http://codepen.io/loktar00/full/Ggolp

Simple Audio Visualisation by Justin Windle

http://codepen.io/soulwire/full/Dscga

Gravitational Field by Justin Windle

http://codepen.io/soulwire/full/begkI

olympic circles logo by Volodymyr

http://codepen.io/tvolodimir/full/AkzGo

Physical Typography - Resonate 2014 by Justin Windle

http://codepen.io/soulwire/full/ezpuK

Subdivision by Justin Windle

http://codepen.io/soulwire/full/mfkHo

Colorful Cloth Ribbons by Loktar

http://codepen.io/loktar00/full/lxEJc

Morphing Fractal Curves, version 2 by Dan Gries

http://rectangleworld.com/demos/MorphingCurve2/MorphingCurves2_black.html

Particle Galaxy by Sebastian Schepis

http://codepen.io/sschepis/full/ErFen

Underwater Effect by Ariya Hidayat

http://ariya.ofilabs.com/2012/03/underwater-effect-with-html5-canvas.html

Ende.

Vielleicht ergänze ich die Liste irgendwann noch einmal mit weiteren Experimenten. Obwohl, dann wäre der Titel "23 Amazing And Inspiring HTML5 Canvas Experiments" falsch. Naja, vielleicht wird es einfach ein neuer Beitrag werden. Und vielleicht, oder besser, sehr wahrscheinlich, kommt noch eine Liste mit meinen WebGL Favoriten.

Bis dahin viel Spaß mit den Canvas Experimenten.
Wenn ihr noch andere Beispiele habt postet diese gerne hier in den Kommentaren und schaut euch auch ein paar von meinen Experimenten an.

3/01/2016

Distorted Sphere

Ein weiteres kleines Experiment mit Partikeln.
Dieses Mal habe ich aus Partikeln eine Sphere „geformt“, die mit Hilfe der Sinus-, bzw. Kosinusfunktion deformiert wird.
Im Prinzip ist dieses Experiment eine Fortführung vom „Sinus Landscape“ Experiment. Nur wird in diesem Fall keine Plane, sondern eine Sphere deformiert. 


Die Herausforderungen hierbei waren die Partikel, egal welche Anzahl, gleichmäßig auf der Sphere zu verteilen und natürlich das Anwenden der Kosinusfunktion auf die Sphere. Wobei sich letzteres als erstaunlich einfach herausstellte, weil bereits fast alles aus dem
„Sinus Landscape“ Experiment gegeben war. Ich musste lediglich noch die z-Position (neben x und y) mit in die Berechnung für die Amplitude/Höhe der Sinuswellen mit einbeziehen.

Aber seht einfach selbst:
Mit Hilfe der Einstellungen, die ihr unter „Open Controls“ findet, könnt ihr den Grad der Deformierung frei bestimmen. Unter dem Punkt „Sphere Settings“ könnt ihr die Anzahl an Partikeln bestimmen, die Stärke/Höhe der Deformationen, die Wiederholungen/Anzahl der Deformationen, den Radius der Sphere, die Animation pausieren und die Geschwindigkeit der Animationen steuern.

Die Einstellungen unter dem Punkt „Display Settings“ sind euch bestimmt schon aus den anderen Experimenten vertraut. Hierbei besonders interessant sind „Invert Output“ und „Pixel Size“.
Wie immer gilt, einfach mal mit den Reglern spielen und schauen was passiert. 

 
Per Mausklick/Touch auf die Sphere wechselt ihr durch verschiedene Farbeschemen. Die Drehung der Sphere bestimmt ihr mit der Position eurer Maus, bzw. ist abhängig von der Position eures Fingers, wenn ihr mit einem Touch-Device unterwegs seid.

Falls ihr das Experiment in einem neuen Fenster betrachten wollt (besonders zu empfehlen für Touch-Devices und User mit mobilen Endgeräten), dann klickt einfach hier.


Und hier noch ein recht schöner Screenshot von der Sphere mit veränderten Einstellungen:
Und noch ein Screenshot, wieder mit anderen Einstellungen: