Schatten im HTML5-Canvas-Spiel

7

Ich möchte um Referenz bitten. Ich habe einen Artikel darüber getroffen, wie man Schatten in Spielen wirft. Ich verwende HTML5-Canvas (derzeit ohne Webgl) mit Javascript für meine Projekte.

Der oben erwähnte Artikel befindet sich unter http://willyg302.wordpress.com/2012/11/04/2d-visibility/ .

Ich dachte, ob diese Methode mit Canvas (ohne Webgl) und Javascript angewendet werden kann?

Genauer gesagt habe ich nur wenige Formen auf Leinwand gezeichnet, von denen einige komplex sind und durch Bogen und ähnliche Methoden hergestellt wurden. Daher habe ich keine einfache Möglichkeit, eine Form mit einer Gleichung zu beschreiben, in der ich nur wenige Parameter speichern kann (dh der Kreis wird als centerX, centerY, radius beschrieben, mit denen ich ihn leicht zeichnen kann, aber mit komplexeren Formen, die ich nicht trage Ich habe mir überlegt, die gesamten Canvas-Daten mit context.getImageData.data pixelweise zu speichern, dann die im Artikel beschriebene Methode (polare Transformation, ..., zurück zum kartesischen System) zu verwenden und die gesamte Szene in zu setzen Zeichenfläche mit canvas.putImageData-Methode.

Aber bevor ich dies tatsächlich anwende, möchte ich fragen, ob es überhaupt mit Canvas (kein Webgl) und Javascript möglich ist, Schatten dynamisch (Lichtquelle, die sich über den Bildschirm bewegt) auf diese Weise ohne starken FPS-Verlust zu erzeugen (ich kann mir vorstellen, dass diese Methode ziemlich gut funktioniert Für Standbilder, aber in dem Moment, in dem ich es jedes Mal tun muss, wenn sich eine Lichtquelle bewegt, bin ich mir nicht sicher, ob Javascript + Canvas dies in angemessener Zeit bewältigen kann, insbesondere wenn ich Informationen gefunden habe, dass putImageData und getImageData ziemlich langsam sind.

Oder wenn jemand versucht hat, dynamische Schatten in HTML5 + js auf unterschiedliche Weise zu erstellen, würde ich mich auch über Ihre Vorschläge dazu freuen (ich mache das derzeit auf ähnliche Weise wie unter http://ncase.me/sight-and- beschrieben) Licht / , obwohl ich einige Probleme mit konkaven Formen habe :().

Das wird furchtbar lang, ich hoffe ich habe mich gut genug erklärt.

Vielen Dank für jeden Rat, den Sie uns geben können, und es tut mir leid, dass mein Beitrag so groß geworden ist, obwohl ich nur eine Frage stelle.

EDIT: Vergessen zu erwähnen, ich suche nur nach 2d Lösung.

Petr
quelle
Was für "Probleme" haben Sie mit konkaven Formen?
Philipp
Nun, momentan habe ich Probleme mit einer komplexeren Form, die nicht aus Liniensegmenten besteht (nicht nur konkav, ich habe sie nur als Referenz verwendet). Ich verwende Bogen für einige Formen, was zu Halbmondformen führt. Diese Formen sind für mich schwer zu handhaben, da ich keine Zwei-Punkte-Strategie verwenden kann, wie in dem Link beschrieben, den ich zuvor gepostet habe (ich dachte, ich könnte sie für Kreise anwenden, wenn es um Halbkreise geht - halbmondförmig - I. bin verloren), also suchte ich nach einer anderen Lösung zum Ausprobieren.
Petr
Alte Frage, aber für SVG-Pfade habe ich hier eine Sammlung von Algorithmen: github.com/sirisian/svg-shadows , die nützlich sein können, wenn Sie versuchen, beliebige 2D-Schatten zu implementieren. Dieses Projekt wurde nur entwickelt, um Schatten in einem Winkel von 45 Grad zu werfen, aber die meisten Algorithmen sind generisch. Ich habe auch folgendes: sirisian.com/javascript/lighting.html, aber es funktioniert nur für Linien und erzeugt Lichtvolumenbereiche . Könnte mit ein wenig Arbeit dazu gebracht werden, mit Kurven zu arbeiten. Der dort verwendete Algorithmus ist generisch.
Sirisian

Antworten:

1

Nun, das ist eine schwierige Frage, aber ich werde von vorne beginnen.

  • Get / Put imageData ist schneller als Sie denken, aber wenn Sie es auf effiziente Weise tun möchten, würde ich Ihnen empfehlen, einen Doppelpuffer zu erstellen und Ihre Formen darin zu rastern (hier ist ein Doppelpuffermodul, das ich geschrieben habe, werfen Sie einen Blick darauf ). .

  • Das Abschatten von seltsamen Formen ist genauso schwierig wie das Abschatten von Rechtecken. Sie müssen nur einen Lichtpunkt festlegen und ihn dann raycasten ( Raycast- Modul, das ich geschrieben habe, vielleicht hilft es Ihnen dabei, herauszufinden, wie es geht) und den Winkel des Schatten für jedes Objekt projizieren dann, wenn sie in Objekten als 3D denken und die 3D-Koordinaten des Lichtpunkts haben, den Schatten des Objekts in diesem Winkel von unten in den Boden.

Normalerweise verwenden 2D-Spiele jedoch gebackene Schatten, da diese einfacher zu verwalten und zu implementieren sind als dynamische Schatten.

Wenn Sie dynamische Schatten machen möchten, würde ich Ihnen empfehlen, alles in 3D zu erstellen und dann durch Projektion zu rendern. Ich habe einen 3D-Rasterizer für Vanille-2D-Leinwand erstellt , der Ihnen helfen könnte. Er rendert dreieckige 3D-Netze in 2D-Leinwand durch Projektion. Ich habe eine aktualisierte Version mit dynamischem Shadowing und einigen anderen Dingen. Sagen Sie mir, wenn Sie interessiert sind, und ich werde sie später hochladen. Ja, sie funktioniert mit einer guten FPS-Rate, aber Sie können die Canvas-Rendering-API dafür nicht verwenden Zweck, da Sie Pixel verwalten müssen.

Viel Glück.

PRDeving
quelle
0

Ich habe eine Weile darüber nachgedacht, ich habe ein bisschen zu diesem Thema recherchiert. Abgesehen von der Verwendung eines Frameworks und dem Schreiben von superkomplexem / langem Code gibt es zwei Möglichkeiten, die ich mir vorstellen kann:

  1. Verwenden Sie Schattenunschärfe
  2. Verwenden Sie radiale / lineare Verläufe

http://www.w3schools.com/tags/canvas_createradialgradient.asp

Eine andere Möglichkeit besteht darin, Alpa-Farben zu verwenden, um verschiedene Dunkelheitsstufen wie Quadrate oder Kreise zu zeichnen:

context.save();
context.globalAlpha = 0.5;
context.fillStyle = "#000000";
// draw a whole ton of shapes with 50% transparency with a black color...
context.restore();
DUUUDE123
quelle