Files |  Tutorials |  Articles |  Links |  Home |  Team |  Forum |  Wiki |  Impressum

Aktuelle Zeit: Sa Jul 05, 2025 16:05

Foren-Übersicht » Programmierung » Allgemein
Unbeantwortete Themen | Aktive Themen



Ein neues Thema erstellen Auf das Thema antworten  [ 18 Beiträge ]  Gehe zu Seite Vorherige  1, 2
Autor Nachricht
 Betreff des Beitrags: Re: Multithreaded Rendering
BeitragVerfasst: Mo Aug 13, 2012 10:01 
Offline
DGL Member

Registriert: Sa Mär 14, 2009 17:48
Beiträge: 99
Programmiersprache: D, Java, C++
TAK2004 hat geschrieben:
Ich kenne 2 größere Engines, da gibt es ein renderthread, der mit einer fixen fps läuft und bekommt nur durch die job-queue informationen.


Das hört sich ja auch vernünftig an, mein Problem ist nur leider eben genau diese JobQueue. Wie sieht diese aus? Steht da nur drin, "Render Objekt 1", "Render Objekt 2", ... Oder sind diese Jobs viel weiter aufgespalten? In der Form: "Erstelle Shader", "Buffere Geometry", "Binde Shader", "Binde Geometry", "Render Geometry".

Fall 1
Wenn ersteres der Fall ist: Wie krieg ich die Anweisungen zum erstellen von Shadern, Rendertargets, ... in den Renderthread? Da fällt mir nur sowas ein:

RenderJob Klasse:
Code:
  1. public void execute(Renderer r) {
  2.   if (vertexBuffer == null) {
  3.     vertexBuffer = r.createGeometryBuffer(geometry);
  4.   }
  5.   if (gpuProgram == null) {
  6.     gpuProgram = r.createProgram(program);
  7.   }
  8.   ...
  9.   r.drawGeometry(0, vertexCount);
  10. }


Also in jedem RenderJob immer wieder nachgucken ob die Geometry gepuffert ist, evtl. ob sie aktualisiert werden muss, ob das Program erstellt ist usw. usf. Das ist irgendwo ja auch unsinniger overhead für jeden RenderJob, da meistens ja alles schon erstellt ist und einfach gerendert werden kann.

Fall 2
Wenn die RenderJobs weiter aufgespalten sind gibt es enorm viele, würde dann wie folgt aussehen:

BufferGeometryJob
Code:
  1. public void execute(Renderer r) {
  2.   r.createGeometryBuffer(geometry);
  3. }


CreateShaderJob
Code:
  1. public void execute(Renderer r) {
  2.   r.createProgram(program);
  3. }


BindGeometryJob
Code:
  1. public void execute(Renderer r) {
  2.   r.bindVertexBuffer(geometry);
  3.  
  4.   if (usesIndices) {
  5.     r.bindIndexBuffer(geometry);
  6.   }
  7. }


DrawJob
Code:
  1. public void execute(Renderer r) {
  2.   r.drawGeometry(0, vertexCount);
  3. }


Der zweite Fall gefällt mir besser, weil man dadurch dann beliebige Jobs an den Renderer geben kann, man muss eben nur verdammt viele Objekte erzeugen und hat sehr viele Method Calls im Renderer.

Ich werde jetzt vermutlich erstmal die zweite Variante benutzen/umsetzen und schauen wie das Skaliert wenn die Szene mal größer als nur ~100 Test Objekte wird.


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags: Re: Multithreaded Rendering
BeitragVerfasst: Mo Aug 13, 2012 12:13 
Offline
DGL Member
Benutzeravatar

Registriert: Mi Jan 31, 2007 18:32
Beiträge: 150
Programmiersprache: Pascal
Ich würde das ganze eher über ein callback machen du hast ein object z.B. schader das implementiert ein interface ILoadable oder so, dann kannst du einfach einen load job schreiben und muss nicht so viele kleine klassen schreiben die alle ähnliches tun vorausgesetzt das passt zu deine OOP kapslung bzw. diese ist überhaupt vorhanden.

mfg FrenK


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags: Re: Multithreaded Rendering
BeitragVerfasst: Mo Aug 13, 2012 19:13 
Offline
DGL Member
Benutzeravatar

Registriert: Di Mai 18, 2004 16:45
Beiträge: 2623
Wohnort: Berlin
Programmiersprache: Go, C/C++
Eigentlich tust du sehr grobe Befehle verwenden und nur für spezielle Anwendungsfälle, schreibst du zusätzliche jobs, die dann optimierungen darstellen.
Also loadTexture, generateRendertarget, loadMaterial oder endFrame.
LoadTexture würde nur eine Textur im renderer anlegen, uploaden, evtl. MipMaps generieren.
Das ist ein low level command, den wird man allerdings brauchen.
Üblicher weise wirst du ein loadMaterial verwenden, welches, shader, texturen lädt, objekte erstellt(z.B. fbo) und übliche fehlerbehandlung.
Du solltest so viel wie möglich in ein Command packen und bei bedarf weitere bauen, die nur ein teil davon machen.

Ich würde z.B. ein initForwardRendering, load/drawCharacter, start/endFrame anfangen.
Nun würde ich zuerst im renderer ein batching fähigkeit hinzufügen und erst wenn die performance nicht mehr reicht weiter gehen, z.b. neben load/drawCharacter noch load/drawStaticObject einbauen. Nun kann ich entsprechend dynamische und statische objekte trennen, gucken ob es sich lohnt statische objekte zu instanziieren, zusammen zu legen und so weiter.
Die commands sollten nicht einfach rein geprügelt werden, in der hoffmung, man wird sie brauchen, sondern die einbauen, die performance probleme lösen.

Der renderer ist keines wegs ein dummer wrapper, das ist viel mehr ne intelligentes framework, welches wissen über geometry, kartenspezifische features und einiges mehr hat.
Occlusion query, frustum culling sind sachen, die ich dort unter bringen würde, erst ohne commands, alles nur hinter der API versteckt und bei bedarf kann man es nach aussen legen.

Ein praktisches Beispiel wäre Animationen, solange du kein rigid body hast, kannst du die animationen auf renderer seiter verwalten, key-frame interpolation machen, updates und so weiter. Solltest du aber rigid body haben wollen, dann spielt die physik animation ab, also brauchst du eine Möglichkeit nun die Bones zu updaten, dafür brauchst du nun mindestens Command, der über das load/drawCharacter hinaus geht. Es liegt immer noch alles auf der renderer seite, du kannst ledeglich mehr rein fummeln.

Kleiner tip zum absetzen der Befehle.
Das hoch laden von ressourcen dauert sehr lange, pack diese immer an den anfang eines frames, dann die drawcommands und als letztes endframe.
Ideal wäre es vieleicht sogar die load commands auf den nächsten frame zu verschieben und damit verbundene draw calls zu verwerfen oder halt 2 stufen.
Dann kannst du besser im hintergrund optimieren.

_________________
"Wer die Freiheit aufgibt um Sicherheit zu gewinnen, der wird am Ende beides verlieren"
Benjamin Franklin

Projekte: https://github.com/tak2004


Nach oben
 Profil  
Mit Zitat antworten  
Beiträge der letzten Zeit anzeigen:  Sortiere nach  
Ein neues Thema erstellen Auf das Thema antworten  [ 18 Beiträge ]  Gehe zu Seite Vorherige  1, 2
Foren-Übersicht » Programmierung » Allgemein


Wer ist online?

Mitglieder in diesem Forum: Google [Bot] und 5 Gäste


Du darfst keine neuen Themen in diesem Forum erstellen.
Du darfst keine Antworten zu Themen in diesem Forum erstellen.
Du darfst deine Beiträge in diesem Forum nicht ändern.
Du darfst deine Beiträge in diesem Forum nicht löschen.
Du darfst keine Dateianhänge in diesem Forum erstellen.

Suche nach:
Gehe zu:  
  Powered by phpBB® Forum Software © phpBB Group
Deutsche Übersetzung durch phpBB.de
[ Time : 0.006s | 15 Queries | GZIP : On ]