Also habe ich eine Animation, die ich in Javascript und HTML5 (keine Bibliotheken, keine Plugins, nichts und ich würde es gerne so bleiben). Die Animation verwendet die Physik (im Prinzip eine Reihe ungewöhnlicher Federn, die an Massen befestigt sind), um eine einfache Flüssigkeit zu simulieren. Die Ausgabe von diesem Teil des Programms ist ein Raster (2d-Array) von Objekten mit jeweils einem z-Wert. Das funktioniert ganz gut. Mein Problem tritt auf, wenn die Daten zu einem HTML5 Canvas gezeichnet werden.HTML5 Leinwand Creative Alpha-Blending
Das ist, wie es aussieht. Vertrau mir, es ist besser, wenn es animiert wird.
Für jeden Datenpunkt zeichnet das Programm einen Kreis mit einer Farbe, die durch den z-Wert bestimmt wird. Beim Zeichnen dieser Punkte ist das Gittermuster jedoch schmerzhaft offensichtlich und es ist schwierig, die Flüssigkeit zu erkennen, die es darstellt. Um das zu lösen, habe ich die Kreise größer und transparenter gemacht, so dass sie sich überlappen und die Farben ineinander übergehen, wodurch eine einfache Faltungsunschärfe entsteht. Das Ergebnis war sowohl schnell als auch schön, aber für einen kleinen Fehler:
Da die Kreise in der Reihenfolge gezeichnet werden, stapeln sich ihre Farbwerte nicht gleichmäßig, und so verdecken später gezeichnete Kreise die früher gezeichneten Kreise. Mathematisch nimmt der Renderer wiederholte gewichtete Mittelwerte der Farbwerte der Kreise an. Dies funktioniert gut für zwei Kreise und gibt jedem einen Wert von 0,5 * alpha_n, aber für drei Kreise nimmt der Renderer den Durchschnitt des neuesten Kreises mit dem Durchschnitt der anderen zwei, was dem neuesten Kreis einen Wert von 0,5 * alpha_n gibt, aber die früheren Kreise hatten jeweils einen Wert von 0,25 * alpha_n. Wenn sich mehr Kreise überschneiden, geht der Prozess weiter und erzeugt eine Tendenz zu neueren Kreisen und zu älteren Kreisen. Was ich will, ist stattdessen, dass jeder von drei oder mehr Kreisen einen Wert von 0,33 * alpha_n erhält, so dass frühere Kreise nicht verdeckt werden.
Hier ist ein Bild von Alpha-Blending in Aktion. Beachten Sie, dass der spätere blauen Kreis früher roten und grünen gezogen verschleiert:
Hier ist, was das Problem wie in Aktion sieht. Beachten Sie das unterschiedliche Aussehen der linken Seite der Beule.
- Mit verschiedener Leinwand "blend-Modi":
Um dieses Problem zu lösen, ich verschiedene Methoden ausprobiert habe. "Multiplizieren" (wie im obigen Bild zu sehen) hat den Trick gemacht, aber unglückliche Farbverzerrungen verursacht.
- Sammeln Zeichnung Aufrufe. Anstatt jeden Kreis zu einem separaten Leinwandpfad zu machen, habe ich versucht, sie alle zu einem zusammenzufassen. Leider ist dies nicht mit separaten Füllfarben zu vereinbaren, und der Pfad verschmilzt überhaupt nicht mit sich selbst und erzeugt eine matte, monotone Silhouette.
- Interlacing Zeichnungsreihenfolge. Anstatt die Kreise in der Reihenfolge von 0 bis n zu zeichnen, habe ich zuerst versucht, die Evens und dann die Odds zu zeichnen. Dies löste das Problem nur teilweise und erzeugte ein unansehnliches Schichtmuster, in dem die Chancen schienen, über den Gleichen zu schweben.
- Erstellen eines eigenen Mischmodus mit putImageData. Ich habe versucht, einen manuellen Pixel-Shader zu erstellen, der meinen Bedürfnissen mit Javascript entspricht, aber wie erwartet war es viel zu langsam.
An diesem Punkt bin ich ein bisschen fest. Ich suche nach kreativen Wegen, um dieses Problem zu lösen oder zu umgehen, und ich begrüße Ihre Ideen. Ich bin nicht sehr daran interessiert zu erfahren, dass das unmöglich ist, weil ich das selbst herausfinden kann.Wie würden Sie aus solchen Datenpunkten elegant eine Flüssigkeit ziehen?
PS: Ich bin ziemlich begabt bei Javascript und HTML5, also müssen Sie mir nichts beibringen. Wenn Ihnen das wie ein triviales Problem erscheint, denken Sie daran, dass ich Sie nicht zur Antwort zwinge. Es stört mich nur und ich möchte daran arbeiten, es zu lösen. – mindoftea
verdammt optische Täuschungen, Ihre Bilder sehen animiert aus, auch wenn sie nicht sind. – Philipp
Kann mir jemand sagen warum die down vote? – mindoftea