Einfache 3D Engine

Einstiegsfragen, Mathematik, Physik, künstliche Intelligenz, Engine Design
Antworten
Raven280438
Establishment
Beiträge: 140
Registriert: 03.10.2010, 20:14

Einfache 3D Engine

Beitrag von Raven280438 »

Hi,

kann mir jemand von euch alten Hasen ein paar Tipps geben, wie ich am besten eine (einfache) 3D Engine (DX) aufbaue?
Ich hab bisher nur mit 2D gearbeitet und hatte da einen Renderer, der die Kommunikation zwischen Engine und DX übernommen hat.
In 2D ging das ohne Probleme, allerdings weis ich nicht, ob es da bei 3D (was ja viel Resourcen-intensiver ist) zu langsam wird. Das Ganze soll dann auch mit wxWidgets kompatibel sein.

Wie baue ich am besten eine 3D Engine auf, was muss ich beachten, um am Ende nicht in ein Frame-Loch zu fallen?

Noch eine weitere Frage: lohnt es sich für eine einfach 3D Engine mit DX11 zu arbeiten? Oder sollte man doch aus Gründen der Kompatibilität mit DX9 oder 10 arbeiten? Ich hab bisher nur Erfahrung mit DX9.


Gruß
Benutzeravatar
Schrompf
Moderator
Beiträge: 4854
Registriert: 25.02.2009, 23:44
Benutzertext: Lernt nur selten dazu
Echter Name: Thomas Ziegenhagen
Wohnort: Dresden
Kontaktdaten:

Re: Einfache 3D Engine

Beitrag von Schrompf »

Das Letzte zuerst: Nimm DirectX11. Die schönere API, schneller, moderner, konsistenter, aber Du büßt aktuell noch etwa 15% des Kundenstamms ein. Daten laut Steam Hardware Survey.

Ein "einfacher" Renderer... hm. Halbwegs zukunftssicher würde ich das so aufbauen:

Engine:
- kann "Renderszene" anfangen, gibt ein entsprechendes Objekt zurück
- kann "Renderszene" beenden, nimmt Objekt entgegen und führt es aus

Renderszene:
- wird von Engine verwaltet
- wird initialisiert mit ViewMatrix, ProjectionMatrix, RenderTarget, plus Bonusparameter
- nimmt Lichter entgegen: Position, evtl. Kegelgrenzen für SpotLights, Farbe, evtl. Rotation, evtl. Farbtextur, evtl. Schatten-Textur-Referenzen als Ergebnis einer vorherigen Renderszene
- nimmt DrawCalls entgegen: Mesh, Material, WorldMatrix, SequenzID zum Sortieren untereinander
- macht bei Beenden durch Engine dann Folgendes: DrawCalls sortieren, ausführen

Mesh:
- für's erste ein VertexBuffer und evtl. ein IndexBuffer

Material:
- Shader
- Shader-Parameter
- Shader-Texturen

Ich würde außerdem so eine Art "Kontext"-ID erfinden. Das kann ein simpler Array-Index sein, wenn Du irgendwo vorab in der Engine alle möglichen Kontexte definierst. Im Shader speicherst Du dann pro KontextId einen alternativen Shader, der statt des eigentlichen Shaders eingesetzt wird. Das halte ich für Pflicht, wenn Du zum Beispiel einen Schatten-Pass für eine Lichtquelle machen willst. Es gibt dann einen Kontext "Schatten für Punktlichter" und jeder Shader gibt an, welcher Shader statt seiner selbst die ShadowMap für dieses Material ausrendert. Alle normalen Oberflächenshader verweisen dann auf einen Tiefen-Output, alle AlphaTest-Shader verweisen auf einen Tiefen-Output mit AlphaTest, usw. Darüber kann man auch Shader vereinfachen, wenn man zum Beispiel Spiegelungen ausrendert, weil viele subtile Effekte wie z.B. Reliefsimulation in flirrenden Spiegelungen verschwendete Rechenzeit sind.

Die konkrete Umsetzung der Lichter wird allerdings etwas komplizierter, je nachdem für welche Art von Renderer Du Dich entscheidest. Ich würde heutzutage wahrscheinlich wegen der einfacheren AntiAliasing-Methoden einen Tiled Forward Renderer anpeilen, aber wenn Du "einfach" willst, würde ich einen banalen MultiPass Forward Renderer nehmen und UNBEDINGT sicherstellen, dass ich in der ganzen Szene nie mehr als ein knappes Dutzend Lichtquellen verteile.
Früher mal Dreamworlds. Früher mal Open Asset Import Library. Heutzutage nur noch so rumwursteln.
Benutzeravatar
dot
Establishment
Beiträge: 1734
Registriert: 06.03.2004, 18:10
Echter Name: Michael Kenzel
Kontaktdaten:

Re: Einfache 3D Engine

Beitrag von dot »

Eine kleinere 3D Engine baust du am besten, indem du viele kleinere 3D Spiele programmierst...

http://scientificninja.com/blog/write-games-not-engines ;)
Raven280438
Establishment
Beiträge: 140
Registriert: 03.10.2010, 20:14

Re: Einfache 3D Engine

Beitrag von Raven280438 »

Hi,

danke für die schnellen Antworten.

@Schrompf:
Ok, dann werd ich DX11 nehmen. Bis mein Spiel fertig ist (wenn überhaupt ;)) dauert es ja eh noch lange. Bis dahin sinken die 15% ja sicher noch.
Wenn ich dich richtig verstehe, könnte ich meine 3D Engine fast genauso aufbaun wie meine 2D Engine. Da gabs auch BeginScene, EndScene etc. und dazwischen DrawRectange, DrawLine, DrawText etc.
Das sollte ja auch auf 3D Objekte anwendbar sein. Meine Befürchtung war halt die Performanz gegenüber einem direkten Arbeiten mit DirectX (anstatt den Zwischenschritt über den Renderer). Der Renderer hatte halt den Vorteil, dass man die Engine auch ohne Probleme auf zB OpenGL umstellen konnte, ohne an der Engine selbst was ändern zu müssen.

@dot:
Natürlich ist mein Endziel ein Spiel zu programmieren. ;)
Allerdings möchte ich dafür erstmal eine Engine programmieren um in die 3D Programmierung einzusteigen.


Noch eine Frage zu den Mashes hab ich: Wie funktioniert das mit dem Vertex- und Indexbuffer? Erstellt man für jedes Mesh einen neuen Buffer oder schmeist man alles in Einen rein? Das ständige Lock und Unlock geht ja extrem auf die Resourcen (so zumindest die DX Warnung, wenn man einen Vertextbuffer mehrmals lockt und unlockt.


Gruß
Benutzeravatar
Schrompf
Moderator
Beiträge: 4854
Registriert: 25.02.2009, 23:44
Benutzertext: Lernt nur selten dazu
Echter Name: Thomas Ziegenhagen
Wohnort: Dresden
Kontaktdaten:

Re: Einfache 3D Engine

Beitrag von Schrompf »

Raven280438 hat geschrieben:Wenn ich dich richtig verstehe, könnte ich meine 3D Engine fast genauso aufbaun wie meine 2D Engine. Da gabs auch BeginScene, EndScene etc. und dazwischen DrawRectange, DrawLine, DrawText etc.
Das ist die Grundform, da wird man kaum drumrum kommen. Es ist also klar, dass die alle ähnlich aussehen. Die eigentliche Intelligenz steckt in den Datenzuordnungen und in der Struktur. Die Datenzuordnungen werden Dir noch einiges an Freude machen, die habe ich ja nur grob skizziert und man kann da unglaublich viel gestalten. Und die Struktur... siehe unten.
Das sollte ja auch auf 3D Objekte anwendbar sein. Meine Befürchtung war halt die Performanz gegenüber einem direkten Arbeiten mit DirectX (anstatt den Zwischenschritt über den Renderer).
Zum Einen ist eine etwas abstrakte Render-Methodik bei 3D viel notwendiger als bei 2D, weil Du heutzutage üblicherweise viele grundverschiedene Passes machst, ehe Du ein Bild erhälst. Ich wollte eine grundlegende Struktur vorschlagen, so dass Du Shadow Passes, Reflection Maps usw. halbwegs einfach integrieren kannst. Und zum Anderen wirst Du durch einen Renderer einiges an Performance gewinnen, nicht verlieren. Das Sortieren der DrawCalls und die gemeinsame Datenhaltung der States, Meshes, Texturen, Daten bringt Dir üblicherweise einiges an Rendertempo.
Der Renderer hatte halt den Vorteil, dass man die Engine auch ohne Probleme auf zB OpenGL umstellen konnte, ohne an der Engine selbst was ändern zu müssen.
Urg... Du machst Späße. Wenn Du Linux und Konsorten brauchst, nimm nur OpenGL. Wenn Du nur Windows brauchst, nimm nur DirectX. Alles andere ist meiner Meinung nach eine Übung in akademischem Masturbieren, und ganz nebenbei eine Garantie für Jahre weiterer Pflegearbeit, die Du eigentlich ins Spiel investieren willst.

Zur Erinnerung: Du wolltest eine *einfache* 3D-Engine anfangen. Ich habe Dir (meine) Wege dargelegt, wie man eine einfache Engine bauen könnte, ohne beim ersten Extrawunsch alles wegschmeißen zu müssen. API-Abstrahierung und ähnliche Späße sind weder einfach noch notwendig.
Noch eine Frage zu den Mashes hab ich: Wie funktioniert das mit dem Vertex- und Indexbuffer? Erstellt man für jedes Mesh einen neuen Buffer oder schmeist man alles in Einen rein? Das ständige Lock und Unlock geht ja extrem auf die Resourcen (so zumindest die DX Warnung, wenn man einen Vertextbuffer mehrmals lockt und unlockt.
Pro Modell ein VertexBuffer und ein IndexBuffer. Die sind nach dem Laden dann ja üblicherweise statisch, die verändert man gar nicht mehr. Darüberhinaus gibt es dann eine Menge Methoden, Bewegung ins Bild zu bekommen. Die gängigsten Methoden sind Displacement im Shader (für im Wind wiegende Vegetation z.B.), Vertex Skinning (Deformieren eines Meshes anhand eines Skeletts) oder halt dynamisch befüllte VertexBuffer (für Partikel wie Feuer, Rauch, Nebel usw.). Nur letzteres erfordert, dass man einen Buffer nach dem Erstellen nochmal locked. Und dafür sollte man entsprechende Flags bei der Buffererzeugung setzen, so dass der Grafikkartentreiber sich darauf einstellen kann, dass dieser Buffer oft neu befüllt wird. Die DirectX-Doku kann Dir dazu eine Menge erzählen.
Früher mal Dreamworlds. Früher mal Open Asset Import Library. Heutzutage nur noch so rumwursteln.
Benutzeravatar
dot
Establishment
Beiträge: 1734
Registriert: 06.03.2004, 18:10
Echter Name: Michael Kenzel
Kontaktdaten:

Re: Einfache 3D Engine

Beitrag von dot »

Raven280438 hat geschrieben:@dot:
Natürlich ist mein Endziel ein Spiel zu programmieren. ;)
Allerdings möchte ich dafür erstmal eine Engine programmieren um in die 3D Programmierung einzusteigen.
Und das ist imo genau der falsche Ansatz (take it from someone who tried ;)). Begründung siehe verlinkter Artikel...

Wenn du einfach nur in die 3D Programmierung einsteigen willst, dann brauchst du weder eine Engine noch solltest du gleich ein Spiel schreiben. Fang lieber mit ein paar kleinen Demos an, rotierende Würfel und so...
Raven280438
Establishment
Beiträge: 140
Registriert: 03.10.2010, 20:14

Re: Einfache 3D Engine

Beitrag von Raven280438 »

Hi,

na dann Danke euch beiden für die Hilfe (und Kritik).

Ich werd mir Beides zu Herzen nehmen.



Gruß
Seku
Beiträge: 7
Registriert: 02.02.2004, 20:02

Re: Einfache 3D Engine

Beitrag von Seku »

Ich kann mich dot nur anschließen und seine Aussage bekräftigen. Ich habe selber viel Zeit verschwendet Engines zu schreiben, die am Ende doch nicht für meine Spielideen geeignet waren. Schreibe lieber kleine Spielchen angefangen bei nem 3D-Tetris, Breakout oder was auch immer, und arbeite dich langsam vorwärts. Weil kompliziert werden die notwendigen Datenstrukturen (wie das vorhin schon angedeutet wurde) erstens von ganz allein und zweitens wahnsinnig schnell. Quasi kleine Erfolgserlebnisse sammeln statt mit dem berühmt-berüchtigten eigenen MMO anfangen :)
Gruß und viel Erfolg
Das beste Snake der Welt: www . easysnake . org
Benutzeravatar
Zudomon
Establishment
Beiträge: 2254
Registriert: 25.03.2009, 07:20
Kontaktdaten:

Re: Einfache 3D Engine

Beitrag von Zudomon »

Man sollte einfach das machen, was einem am meisten Spass macht! Wenn er ne Engine bauen möchte, soll er es probieren.

Und wenn es gleich ein 3D MMORPG werden sollte, noch besser, dann können wir das gemeinsam zocken! :)
Benutzeravatar
Jeason
Beiträge: 41
Registriert: 07.09.2010, 22:58

Re: Einfache 3D Engine

Beitrag von Jeason »

Zudomon hat geschrieben:Man sollte einfach das machen, was einem am meisten Spass macht! Wenn er ne Engine bauen möchte, soll er es probieren.

Und wenn es gleich ein 3D MMORPG werden sollte, noch besser, dann können wir das gemeinsam zocken! :)
Dem kann ich nur zustimmen ;)
Ich verkaufe diese feinen Lederjacken.
Antworten