Du bist nicht angemeldet.

Stilllegung des Forums
Das Forum wurde am 05.06.2023 nach über 20 Jahren stillgelegt (weitere Informationen und ein kleiner Rückblick).
Registrierungen, Anmeldungen und Postings sind nicht mehr möglich. Öffentliche Inhalte sind weiterhin zugänglich.
Das Team von spieleprogrammierer.de bedankt sich bei der Community für die vielen schönen Jahre.
Wenn du eine deutschsprachige Spieleentwickler-Community suchst, schau doch mal im Discord und auf ZFX vorbei!

Werbeanzeige

21

28.08.2014, 22:04

Du hast an dem aktuell gerenderten Pixel auf dem Boden (an der Wand ganz unten, wenn sie zum Boden übergeht) nicht direkt die Höhe mit gezeigter Heightmap. Das hat mit deferred nichts zu tun
EnvisionGame(); EnableGame(); AchieveGame(); - Visionen kann man viele haben. Sie umzusetzen und auf das Ergebnis stolz zu sein ist die eigentliche Kunst.

Schrompf

Alter Hase

Beiträge: 1 470

Wohnort: Dresden

Beruf: Softwareentwickler

  • Private Nachricht senden

22

28.08.2014, 22:30

Doch, warum nicht? Jede Art von Isometrischer Projektion bildet die "Säulen" mit gleicher Bodenposition in einer Linie ab. Also kannst Du pro Pixel einfach die Höhe über dem Boden ausrendern. Was natürlich ne Extra Grafik ist, genauso wie die Normal Map oder Specular Map. Und dann kannst Du anhand der Höhe und der Bildschirmkoordinate (und der Projektionsrichtung, also in welche Richtung es räumlich abwärts geht) ausrechnen, auf welcher Bodenposition Du bist. Und damit die 2D-Schatten anwenden.
Häuptling von Dreamworlds. Baut aktuell an nichts konkretem, weil das Vollzeitangestelltenverhältnis ihn fest im Griff hat. Baut daneben nur noch sehr selten an der Open Asset Import Library mit.

23

29.08.2014, 00:03

Vielen Dank, ich bin ganz gerührt, dass es sogar Bildchen gibt.

Man könnte die max. Höhenwerte pro Bodenpixel schon aus den Heightmaps ausrendern, aber wäre das eigentliche Problem nicht das, dass man wegen der Verdeckung nicht zu jedem Bodenpixel / für jede Pixelsäule einen Wert hat? Oder sehe ich das falsch? Es ist ja keine vollwertige 3d-Repräsentation, sondern quasi nur "Fassade".

Schrompf, dein Ansatz ist aber interessant.

Ich hatte jetzt mit line of sight nur gemeint, für jedes Boden-Pixel, also jede Pixelsäule die "Schattigkeit" (bzw. Sichtbarkeit der Lichtquelle) anhand einer Textur zu berechnen, die nur die Grundrisse der Wände etc. am Boden enthält, ausgehend von den Kollisionsdaten (= Flächen / Grundrisse am Boden). Auf dieser Textur kann ich ja den Shader line-of-sight laufen lassen, um für jedes Boden-Pixel (ergo jede darauf stehende Pixelsäule) die "Schattigkeit" zu ermitteln. Das müsste gehen. Ich weiß aber nicht, wie effizient das ist. Pro Pixelsäule wäre ja dann der gleiche los-Test h (=Höhe) mal zu durchlaufen. Das gefällt mir gar nicht. Oder ich mache vorher einen los-Schattenpass für jede Lichtquelle auf der 2D-Boden-Grundrisstextur...

Bei diesem Ansatz wären Pixel-Säulen also immer vollständig (nicht) im Schatten.

Bei Schrompfs sehr schönem Ansatz, so er denn funktioniert, wäre der Vorteil, dass die Eigenschaft "im Schatten" über die Pixelsäule quasi anhand eines Grenzwerts festgelegt würde. Die eine Hälfte der Pixelsäule (unten) im Schatten, der obere Teil im Licht, also eine Art Schatten-Heightmap insgesamt, korrekt?
Das ist interessant. Mir ging es ja jetzt erst einmal darum, grob falsche Beleuchtung (durch Wände hindurch) zu eliminieren. Da sich richtige Schatten aber wohl ohnehin so nicht erzeugen lassen, frage ich mich (trotzdem vielen Dank, Schrompf), was der Ansatz für Vorteile hätte. Es beginnen ja nicht alle Objekte am Boden, z. B. ein Wandschrank... Da müsste ja dann "hinter" dem Schrank "drunter" qua Grenzwert fälschlicherweise dunkel sein...

24

29.08.2014, 00:22

@Schrompf: Achso meinst du das. Ja, stimmt das "Zurück"-Rechnen klingt logisch.

Zitat

Ich weiß aber nicht, wie effizient das ist.

Naja überlegen wir mal: Im worst-case ist deine Lichtquelle in einer Bildecke und das Pixel in der gegenüberliegenden. Bei einer Auflösung von 800x600 macht das §\sqrt{800^2 + 600^2} = 1000§. 1000 Samples worst case, 1 sample (direkt neben dem Licht) best case. Bei einer Linearen Attenuation des Lichts macht das im Durchschnitt 500 Samples pro Pixel. Für ein performantes Realtime Rendering (nur für den Schatten!) viel zu viel laut Rechnung.

Du kannst es ja dennoch mal ausprobieren, wäre sicher interessant ;)
EnvisionGame(); EnableGame(); AchieveGame(); - Visionen kann man viele haben. Sie umzusetzen und auf das Ergebnis stolz zu sein ist die eigentliche Kunst.

Schrompf

Alter Hase

Beiträge: 1 470

Wohnort: Dresden

Beruf: Softwareentwickler

  • Private Nachricht senden

25

29.08.2014, 13:53

Aber genau wegen dieser Effizienz habe ich doch die kaskadierende Multipass-Methode vorgeschlagen. Die funktioniert, und sie ist effizient. Das weiß ich mit Sicherheit, weil sie nämlich bei Splatter für >10 Lichtquellen pro Frame mit 200Hz rendert. Bei Splatter arbeite ich mit maximal 1920x1200 Pixeln, der Schatten wird allerdings in 4:1-reduzierter Auflösung gerendert. Und das merkt keiner, weil die Auswertung anhand der Pixel-Heightmap ja wieder in voller Auflösung passiert.

Beispielrechnung analog zu Smokiie: Schattentest-Strecke von 1000 Samples: erster Pass mit 8 Samples kommt acht Pixel weit, zweiter Pass mit 8 Samples kommt 32 weit, dritter dann 128, vierter dann 512, und mit dem fünften hat man selbst FullHD abgedeckt. Fünf Passes mal 8 Samples macht 40 Samples für den ganzen verdammten Bildschirm. Das ist der Trick, und der ist völlig unabhängig von HeightMaps oder sowas. Den Trick kannst Du auch anwenden, wenn Du wirklich nur ne Verdeckung pro Bodenpixel ausrenderst und daraus bodenbasierte An/Aus-Schatten extrudierst. Dann berechnest Du halt keine Schattenkanten-Höhen, sondern verlängerst mit den kaskadierenden Passes nur die Schatten. Geht auch.

Die "Bildchen" waren übrigens verdammte Arbeit :-)

Das sind also zwei getrennte Vorschläge in meinem Beitrag:

a) Anstatt Schatten/Licht eine Schattenhöhe über Boden berechnen und nach Geradengleichung hinter Hindernissen verlängern, um herauszufinden, wie hoch ein Pixel über Boden sein muss, um Licht abzubekommen.

b) Beliebige Parameter entlang Sichtlinien durch mehrere Renderpasses verlängern, um drastisch Rechenzeit zu sparen.

Bei a) könnte man noch streiten, ob es bei dieser isometrischen Perspektive funktioniert. Ich denke, es geht, aber es ist sicher nicht so einfach wie bei einer strikten TopDown-Perspektive. b) dagegen funktioniert immer und ist absolut notwendig, damit das ganze Ding überhaupt performant läuft. Ich betreibe bei Splatter sogar noch ein erweitertes b), bei dem ich nicht einen Strahl, sondern 5 leicht gestreute Strahlen aussende. Daraus entsteht dann eine Schattenkantenhöhe und eine anteiliger Verdeckungswert, der über weitere Passes immer weiter aufgefächert wird, so dass ich damit recht billig volumetrische Lichtquellen abdecken kann.

Für die volumetrischen Lichtquellen habe ich vor Urzeiten mal ein Beispielbild ausgerendert:

(Link)


Mein Schattenshader macht also fünfmal 7 Samples pro Pass und braucht bei 4:1 reduzierter Auflösung vier Passes, um den kompletten Bildschirm und etwas mehr noch für Schatten, der von außerhalb des Bildschirms ins Bild fällt, abzudecken. Und das geht trotzdem noch in Mehr-Als-Echtzeit auf durchschnittlichen Gamer-Grafikkarten.

@DerKlaus: Du hast aber korrekt erkannt, dass es keine Schatten "unter" Objekten zulässt. Das ist in der Praxis nur sehr selten ein Problem, aber prinzipiell schon. Das selbe Problem hat ja aber der schlichte Ansatz über An/Aus Verdeckung auch. Die Schatten-HeightMap, wie Du sie richtig genannt hast, leistet dagegen bei kleinen Hindernissen sehr gute Arbeit. Bei Splatter benutzen wir das, um die ganzen Trümmer und Leichenteile auf dem Boden Schatten werfen zu lassen. Die Schatten von so kleinen Hindernissen sind dann meist recht kurz, aber geben der ganzen Szene einen schönen Tiefeneindruck.
Häuptling von Dreamworlds. Baut aktuell an nichts konkretem, weil das Vollzeitangestelltenverhältnis ihn fest im Griff hat. Baut daneben nur noch sehr selten an der Open Asset Import Library mit.

Werbeanzeige