ich bastel (wie man evtl anhand meiner letzten fragen sehen konnte) z.Z. wie Nico auch an nem Raytracer... wollt ich schon immer mal ausprobieren sowas Na ja, jedenfalls.. klappt alles soweit wunderbar (Soft Shadows, Reflektionen, Multisampling etc kann er schon), nur... geschwindigkeitstechnisch ist er doch noch irgendwie... lahm..
Ich hab - anders als Nico - direkt von anfang an auf Poly-Objekte gesetzt, sprich ich Trianguliere das Mesh und teste dann alle Rays mit den Triangles.
Das ist natürlich relativ langsam, daher hab ich schon nen Octree eingebaut, welcher das ganze auch ein ganzes stück beschleunigt hat.. aber trotzdem, verglichen mit MentalRay etc (den aktuellen Raytracern) ist es super lahm...
z.B. nen Objekt mit 10.000 Triangles und nem BlinnShader, das rendert MentalRay in 1sek... mein Raytracer brauch da gern mal ne minute.
Generell sagt man ja, das der Polycount bei heutigen renderern keine Zeit kostet, sondern nur die Shader etc... aber, wie machen die das? Ich meine, die müßen doch auch nen Ray mit nem Triangle auf intersection testen.
Selbst wenn ich pro Pixel nur 3 Triangles testen müßte würde es wahrscheinlich länger als 1sek dauern..
Wenn da jemand ne idee hat, wie die das machen... bitte sagt es mir
Aya~
PS: Für das Bild hier hat mein Raytracer 9min gerendert (!!!) und das sind gradmal 7800 Triangles mit 0..16x Multisampling. MentalRay würde das denk ich in 10sek rendern. (Zumal das Antialiasing nochnichtmal hoch genug ist)
Hm, wahrscheinlich werden sie v.a. ihre Strukturen effizienter Abarbeiten als Du. Testest du z.B. ddie Kinder der Octrees immer der Schnittreihenfolge mit dem Strahl, so kannst du sofort alle Quader die noch zu tun sind, die aber hinter deinem ersten gefundenen Schnitt liegen, abhaken. Evtl. muss man die Octress auch noch effizient genug verpacken und die Zerlegungstiefe des Octrees und wie man diese automatisch lokal bestimmt, spielt sicherlich auch eine sehr entscheidende Rolle. Wenn ein Blatt nur noch zerteilte Dreiecke enthaelt, dann ist z.B. sicherlich was ziemlich faul und man hat zuviel zerlegt, bzw. wenn man die Ecken nicht zerteilt sondern nur immer ganze ablegt, dann ist man spaetestens dann zuweit, wenn kein Eck mehr vollstaendig im Quader liegt. Besser ist es wohl auch ein bischen vorher mit dem Zerlgen aufzuhoeren. Auch sonst lassen sich vielleicht einige der Rechnungen deutlich beschleunigen - ganz besonders die Schnittests sind hier sicherlich interessant und wenn einiges der Vektormathematik auf den Multimediaeinheiten gemacht wird, ist man auch nicht verkehrt. Ein anderer Trick ist z.B. das Bild auch vorher einmal per Hardware zu rechnen und so schon in etwa zu wissen, wos sich denn schneidet. bzw. die Grafikhardware zum Tracen zu verwenden - bei Poly-Ojekten ist sie da sicher das Richtige Werkzeug, aber auch einiger anderer kram laesst sich Prima auf Grafikhardware abwaelzen. Und wenn mehrere Prozessoren zur Verfuegung stehen, dann ist sicher auch die Parallelisierung die man einsetzt auch nicht ganz unerheblich. Aber das kann sehr viel sein, wo es da hakt und wo es langsam sein koennte. Das ganze durch einen Profiler jagen hilft haefig ja auch um Funktionen die einer Ueberarbeitung wert sind zu finden und an manchen stellen ist vielleicht eine erzwungene Iteration statt rekursion auch sinnvoll.
Registriert: Do Dez 05, 2002 10:35 Beiträge: 4234 Wohnort: Dortmund
Mit RayTracern kenne ich mich überhaupt nicht aus aber vielleicht solltest du dir das einmal in einen Profiler anschauen. Die Testversion von AQtime von AutomatedQA kannst du 15 Tage kostenlos nutzen und sollte dir auf jeden Fall einiges an Informationen anzeigen können. Unter anderem welche Methoden wie häufig aufgerufen wurden und wo die meiste Zeit verbraucht wurde. Anhand von den Informationen solltest du in der Lage sein dagegen eine sinnvolle Strategie entwickeln zu können. Aber Vorsicht die Informationen die du bekommst sind nicht ohne. Das ist am Anfang alles sehr verwirrend. Als Ansicht empfehle ich dir den "Call Graph". Den Finde ich am Übersichtlichsten.
Damit das funktioniert solltest du TD32 Debuginfos anstellen und nicht zu große Szenen rendern. Die Laufzeit wird sich in jedem Fall verlängern. Je nach System kann das bis zu 4 oder 5 Mal so lange dauern.
Was mir noch eingefallen ist.. Man betreibt für jeden Renderthread einen hitcache - man speichert die zuletzt getroffenen objekte der rekursionstiefe nach ab, weil man davon ausgehen kann, daß beim nächsten tracer durchgang diese wieder zuerst getroffen werden - man rendert ja meist direkt nebenan weiter - wenn man diese objekte immer zuerst wieder auf schnitt prüft, dann kann man schon ordentlich tempo noch zusätzlich bekommen.
ich hab mir das jetzt mal mit dem Profiler angeschaut.. die renderzeit wurde dabei gleich etwa 100x so lang :p
Aber, was mir aufgefallen ist, die meiste zeit geht drauf bei meinen "Objects"..
also z.B.
Code:
type
TBla = Object
A, B, C: Single;
procedure Reset;
end;
procedure TBla.Reset;
begin
A:=0;
B:=0;
C:=0;
end;
Wenn ich dann dashier mache:
Code:
var
Bla: TBla;
begin
Bla.Reset;
scheint das sehr viel zeit zu verschlucken...
Ist das normal? Oder liegt das an den "Objects" welche man ja so eigentlich nichtmehr verwenden soll...?
Allerdings, Classen finde ich in dem fall sehr unpraktisch.. und Rekords können keine Proceduren haben
Falls das jetzt ne doofe eigenart von "Object" is, wär es evtl doch sinnvoll auf C++ umzusteigen (hab nur D6, und ihr glaubt garnich wie stark ich beim Raytracer überladene Operatoren vermisse -.-)
Registriert: Do Dez 05, 2002 10:35 Beiträge: 4234 Wohnort: Dortmund
Also das kann ich dir nicht sagen ob das ein Phänomen von Objekts sind, denn ich benutze gar keine Objects. Nie. Aber ich denke wenn du daraus eine Klasse machst wirds auch nicht besser, weil da erst Speicher angelegt wird etc. Evtl versuchst du auch mal den FastMem Speichermanager. Der dürfte bei so mikrosachen durchaus noch etwas rausholen können.
Viel interessanter dürfte da wohl die Frage sein wie häufig so etwas aufegrufen wird? Denn 100mal langsamer sagt mir jetzt so spontan, dass du richtig viele kleine Methoden aufrufst, oder? Evtl kannst/solltest du daran noch etwas drehen.
Bei meiner glBitmap habe ich bei den Funktionen knapp 30-40% mehr Leistung herrausholen können in dem ich die Parameter anders übergeben habe. Vorher alles einzeln. 4 Records + Variablen und anschließend alles in einem Record. Denn so musste nur noch ein Parameter ständig auf den Stack gepackt werden.
Registriert: Di Jun 27, 2006 11:43 Beiträge: 22 Wohnort: Berlin
Hi, Aya,
Du mußt deshalb noch lange nicht zu C++ wechseln
Ich weiß leider nicht genau, ab wann dies dazukam, aber im Delphi 2006, das ich beruflich nutze, gibt es
a) Records mit Proceduren
Zitat aus der Hilfe: "In addition to fields, records may have properties and
methods (including constructors), class properties, class methods, class fields,
and nested types (...) Record types cannot have destructors"
b) Operator overloading (OK, nicht ganz so weit gehend, wie bei C++, aber bisher stets ausreichend...)
Happy programming und - ach ja:
Ein frohes neues Jahr Euch allen!
Ich halte es für sehr unwahrscheinlich dass es eine Eigenart von Objects ist. Die sind mehr oder weniger records mit Proceduren/Funktionen. Es liegt wahrscheinlich an den vielen funktionsaufrufen. Außerdem weiß ich nicht ob der Profiler sich selbst aus den Statistiken herausrechnet. Viele kleine funktionsaufrufe können aber trotzdem auf die Zeit gehen.
Registriert: Do Dez 05, 2002 10:35 Beiträge: 4234 Wohnort: Dortmund
The-Winner: Höchstwahrscheinlich wird der sich nicht 100%tig genau raus rechnen können aber solange das Verhältniss stimmt sollte sich ja an der Grundaussage nichts ändern. Und an Aussagen, dass die ein oder andere Methode 10-200 Mio mal aufgerufen wurde ändert sich eh nix.
apo_pq: Wenn ich mich nicht vertue sind die beiden Sachen erst ab D2006 verfügbar. Also vorher noch nicht.
Da Objects wie Classes eine Vererbungsstruktur haben (ja auch hier gehen virtuelle Methoden) werden sie auch bei Aufrufen sehr ähnlich wie Classes behandelt. Und das frisst Zeit (nachschauen, welche Methode nun wirkllich gerufen werden muss, Datenraum der Instanz mappen, usw.).
Wenns wirklich schnell gehen muss und Du nicht sooo viele Methoden dran hast, dann nimm Records und und manipuliere sie mit globalen Methoden. Dabei musst Du allerdings drauf achten, die Dinger mit new() zu alloziieren, wenn sie ausserhalb der aktuelen Methode weiterhin Bestand haben sollen.
Objekte solte man sowieso nicht mehr nehmen, das ist ne Altlast aus ObjectPascal. Wenn man Vererbungsstrukturen usw. braucht sollte man gleich Klassen nehmen. Geschwindigkeitstechnisch nehmen die sich nicht viel, aber Klassen sind viel sauberer. Hier kann man auch mit d'ynamic' geschwindigkeitsorientiert vererben, was imho bei Objekten nicht geht.
_________________ Manchmal sehen Dinge, die wie Dinge aussehen wollen, mehr wie Dinge aus, als Dinge.
<Esmerelda Wetterwax>
Es kann vorkommen, dass die Nachkommen trotz Abkommen mit ihrem Einkommen nicht auskommen und umkommen.
Die Methode Reset ist nicht virtuell und damit steht schon zur Kompilierzeit fest, dass sie aufgerufen wird.
Zitat:
Datenraum der Instanz mappen
Auch wenn man globale Funktionen verwendet, braucht man einen Self Zeiger oder ähnliches. Schließlich muss die Funktion wissen, welchen Record man verändern möchte.
Zitat:
d'ynamic'
Bei dynamic muss die Methode erst aus einer Tabelle anhand eines Nummer, die nicht zwangsläufig dem Index in der Tabelle entspricht, gesucht werden.
ich hab jetzt mal alles von den Objects auf Records umgestellt. Eine Scene die davor 40sek gerendert hat, hat dannach nurnoch 30sek gebraucht, also 25% Zeit gespart
Dann jetzt noch die restlichen sachen die ihr hier angesprochen habt, und dann müßte das doch durchaus ne menge bringen ^.^
Mitglieder in diesem Forum: 0 Mitglieder und 6 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.