Seite 7 von 10

Verfasst: 06.10.2005 20:00
von Kaeru Gaman
@Nic

manche Raytracer arbeiten da mit ner art 'bounding box'
(in games heißt es so, wies jetzt beim RT wirklich heißt, fällt mir grad net ein)

es wird also vorher gecheckt, ob das betreffende objekt überhaupt in der nähe ist,
bevor es auf kollision geprüft wird. also werden nicht für jedes pixel alle 100 objekte gecheckt.
wie genau das jetzt läuft, weiß ich auch nicht,
vllt findest du in der anleitung zu POV-Ray ne erklärung, die ist eigentlich ziemlich ausführlich.

http://www.povray.org/ftp/pub/povray/Of ... a4-pdf.zip

Verfasst: 06.10.2005 20:12
von NicTheQuick
@Kaeru:
Ich hab vergessen zu erwähnen, dass ich mir der zahlreichen
Möglichkeiten durchaus bewusst bin. Nur hatte ich leider noch keine Zeit
etwas derartiges einzubauen. :|

Ich werde wohl in Zukunft verschiedene Methoden gleichzeitig benutzen.
Aber bis dahin werden noch Monate vergehen.

Das Problem bei meiner Fortschrittsvorhersage ist eben, dass ich mir
keine Zeit fürs Programmieren einteile, sondern lediglich programmiere,
wenn ich dazu in der Stimmung bin. Solange ich an keinem
Auftragsprojekt arbeite, ist das nämlich Gott sei Dank nicht von
Bedeutung. :allright:

Verfasst: 06.10.2005 20:54
von Kaeru Gaman
@Nic

yo, dachte mir schon, daß du ne menge hintergründe weißt..

vielleicht bekommst du ja trotzdem ein paar anregungen aus der doku von pov...

weiterhin viel erfolg! :allright:

Verfasst: 08.12.2006 16:01
von NicTheQuick
Bin wieder dran.

Ich hab Passagen in meiner Engine gefunden, die alles etwas ausbremsen
und teilweise auch zu viel Speicher fressen. Die hab ich teilweise schon
schneller gemacht. Außerdem hab ich mir schon einige Makros gebastelte,
die ich statt langsamen Procedures benutzen kann.

Außerdem wird jetzt bald alles als Interface zur Verfügung stehen. Die
Interfaces für Kamera und Licht sind fertig. Es fehlen noch die Interfaces für
Texturen, Objekte und allgemein das Raytracing-Haupt-Interface.

Ich hoffe, dass ich so schon bald eine schnellere Engine präsentieren kann.

Also bis dann.

Verfasst: 19.12.2006 19:35
von NicTheQuick
Kurzer Zwischenstand:

Sie ist schon lauffähig, aber noch voller wirrer Bugs. Kein Wunder bei dem
Gepointere. :wink:

Hier ein paar Fakten:
Insgesamt 151.641 Bytes Quellcode für Engine, Testcode und
Startrequester. Die Engine alleine hat 130.722 Bytes. Da aber noch ein
paar Sachen implementiert werden sollen, wird das ja noch weiter
wachsen.

Hier die Interfaces, damit man sich ein Bild machen kann, wie alles
aufgebaut ist:

Das Haupt-Interface:

Code: Alles auswählen

Interface RT
  Free()
  
  NewCam(Width.l, Height.l)
  NewObject(Type.l)
  NewLight(Type.l)
  NewTexture()
  
  EnumCams(*CBProc = #RT_Ignore)
  EnumObjects(*CBProc = #RT_Ignore)
  EnumLights(*CBProc = #RT_Ignore)
  EnumTextures(*CBProc = #RT_Ignore)
  
  Background(*Color.RTC3F = #RT_Ignore)
  BackgroundRGB(r.f, g.f, b.f)
  AmbientLight(*Color.RTC3F = #RT_Ignore)
  AmbientLightRGB(r.f, g.f, b.f)
  
  MovePoint(*Pos.RTP3D, *angle.RTA3D, *Move.RTP3D)
EndInterface
Das Kamera-Interface:

Code: Alles auswählen

Interface RTCam
  Free()                                  ;Löscht die Kamera und gibt den Speicher wieder frei
  Gamma(Gamma.f = #RT_Ignore)             ;Setzt einen neuen Gammawert und gibt den alten zurück
  Size(Width.l = #RT_Ignore, Height.l = #RT_Ignore)
                                          ;Setzt die Größe der Kamera
  Width()
  Height()
  Position(*Position.RTP3D = #RT_Ignore)  ;Setzt die neue Position und gibt den Pointer zur neuen zurück
  Angle(*angle.RTA3D = #RT_Ignore)        ;Setzt die neuen Winkel und gibt den Pointer zu den neuen zurück
  RecursionDepth(RecursionDepth.l = #RT_Ignore)
                                          ;Setzt die neue Rekursionstiefe und gibt die alte zurück
  FOV.d(FOV.d = #RT_Ignore)                 ;Setzt neuen FOV und gibt den alten zurück
  Direction(*Direction.RTP3D)             ;Gibt die Richtung der Kamera zurück
  Move(*Move.RTP3D)                       ;Verschiebt die Kamera relativ zur Blickrichtung und Drehung
  
  CalculateRays()                         ;Berechnet die Strahlen zum Rendern (muss nach jeder Positions- und
                                          ;Winkel-Änderung vor dem Rendern neu aufgerufen werden)
  Draw(x.l = 0, y.l = 0)                  ;Rendert die Kamera auf einen Output, der mit StartDrawing()
                                          ;geöffnet wurde
EndInterface
Das Objekt-Interface:

Code: Alles auswählen

Interface RTObject
  Free()                                  ;Löscht das Objekt und gibt den Speicher wieder frei
  
  Render(mode.l = #RT_Ignore)             ;#RT_Activate:Rendern, #RT_Deactivate:Nicht rendern
                                          ;#RT_Toggle:Togglen, #RT_Ignore:Rückgabe
  
  Type()                                  ;Gibt den Typ des Objektes zurück
  
  Radius.d(Radius.d = #RT_Ignore)           ;Gibt den Radius für das Objekt an und den alten zurück
  length.d(length.d = #RT_Ignore)           ;Gibt die Länge für das Objekt an und die alte zurück
  Angle.d(Angle.d = #RT_Ignore)             ;Gibt den Öffnungswinkel des Objektes an (0..360)
  
  Position(*Position.RTP3D = #RT_Ignore)  ;Gibt die Position für das Objekt an und den Pointer dazu zurück
  PositionN(n.l, *Position.RTP3D = #RT_Ignore)
                                          ;Gibt die Position einer bestimmten Ecke an und den Pointer dazu zurück
  PositionXYZ(x.d, y.d, z.d)
  PositionNXYZ(n.l, x.d, y.d, z.d)
  
  Direction(*Direction.RTP3D = #RT_Ignore);Gibt die Richtung des Objektes an und gibt den Pointer dazu zurück
  DirectionXYZ(x.d, y.d, z.d)
  
  Normal(*Normal.RTP3D = #RT_Ignore)      ;Gibt die Normale für das Objekt an und gibt den Pointer dazu zurück
  NormalXYZ(x.d, y.d, z.d)
  
  Color(*Color.RTC3F = #RT_Ignore)        ;Gibt die Farbe für das Objekt an und gibt den Pointer dazu zurück
  ColorN(n.l, *Color.RTC3F = #RT_Ignore)  ;Gibt die Farbe eines bestimmten Punktes des Objektes an 
                                          ;und gibt den Pointer zurück
  ColorRGB(r.f, g.f, b.f)
  ColorNRGB(n.l, r.f, g.f, b.f)
  
  DirectLight.f(Direct.f = #RT_Ignore)      ;Gibt die Stärke des direkten Lichts an (0..1) und die alte zurück
  DirectLightN.f(n.l, Direct.f = #RT_Ignore);s.o.
  
  Transparency.f(Transparency.f = #RT_Ignore)
                                          ;Gibt die Transparenz (Alpha) des Objektes an (0..1) und die alte zurück
  TransparencyN.f(n.l, Transparency.f = #RT_Ignore) ;s.o.
  
  Reflection.f(Reflection.f = #RT_Ignore)   ;Gibt die Reflektion des Objektes an (0..1) und die alte zurück
  ReflectionN.f(n.l, Reflection.f = #RT_Ignore)
  
  Refraction.f(Refraction.f = #RT_Ignore)   ;Gibt die Brechzahl des Objektes an (0..oo?) und die alte zurück
  
  Attributes(Direct.f = #RT_Ignore, Reflection.f = #RT_Ignore, Transparency.f = #RT_Ignore, Refraction.f = #RT_Ignore)
  
  Texture(*Texture = #RT_Ignore)          ;Gibt die Texture für das Objekt an und die alte zurück
  TextureOffset(*Offset.RTOffset = #RT_Ignore)
                                          ;Gibt das Offset zum Anzeigen der Textur an und den Pointer dazu zurück
  TextureGamma.f(Gamma.f = #RT_Ignore)      ;Gibt das Gamma zum Anzeigen der Texture an und das alte zurück
  TextureScale.f(Scale.f = #RT_Ignore)      ;Gibt die Skalierung zum Anzeigen der Texture an und die alte zurück
EndInterface
Das Licht-Interface:

Code: Alles auswählen

Interface RTLight
  Free()                                  ;Löscht das Licht und gibt den Speicher wieder frei
  Render(mode.l = #RT_Toggle)             ;#RT_Activate:Rendern, #RT_Deactivate:Nicht rendern
                                          ;#RT_Toggle:Togglen, #RT_Ignore:Rückgabe
  Type()                                  ;Gibt den Typ des Lichtes zurück
  Color(*Color.RTC3F = #RT_Ignore)        ;Setzt die Farbe des Lichtes und gibt den Pointer zurück
  ColorRGB(r.f = #RT_Ignore, g.f = #RT_Ignore, b.f = #RT_Ignore)
                                          ;Setzt die Farbe des Lichtes und gibt den Pointer zurück
  Position(*Position.RTP3D = #RT_Ignore)  ;Setzt die neue Position und gibt den Pointer dazu zurück
  PositionXYZ(x.d, y.d, z.d)
  FOV.d(FOV.d = #PB_Ignore)                 ;Setzt neuen FOV (0..360) und gibt den alten zurück
  Direction(*Direction.RTP3D = #RT_Ignore);Setzt die Richtung des Lichtes und gibt den Pointer zurück
  DirectionXYZ(x.d, y.d, z.d)
  Move(*Move.RTP3D)                       ;Bewegt ein Licht in Richtung des Vektors
EndInterface
Das Textur-Interface:

Code: Alles auswählen

Interface RTTexture
  Free()                                  ;Löscht die Textur und gibt den Speicher wieder frei
  Render(mode.l = #RT_Ignore)             ;#RT_Activate:Rendern, #RT_Deactivate:Nicht rendern
                                          ;#RT_Toggle:Togglen, #RT_Ignore:Rückgabe
  Load(File.s)                            ;Läd eine Textur aus einer Bilddatei in den Speicher
  Catch(*Pointer, length.l = #RT_Ignore)  ;Läd eine Textur aus einer Bilddatei im Speicher
  Offset(*Offset.RTOffset = #RT_Ignore)   ;Ändert das Offset zum Anzeigen der Textur auf einem 
                                          ;Objekt und gibt den Pointer dazu zurück
  Gamma.f(Gamma.f = #RT_Ignore)             ;Ändert den Gamma-Wert und gibt den alten zurück
EndInterface
Auch wenn ich glaube, dass es nicht grad sehr viele interessiert. Mir
macht's einfach Spaß sowas zu basteln. <)

Verfasst: 19.12.2006 20:46
von Kekskiller
Ich finds schön, dass du die Interfaces hier reinpostest, einen ähnlichen Umfang hatte der Quellcode meines 1. großen Spiels ^_^

Verfasst: 20.12.2006 01:51
von NicTheQuick
Hier mal der erste Screenshot, der noch nicht ganz ausgereiften Engine.

Bild

Wie man sieht, sind die Verspiegelungen noch falsch. Darum kümmer ich
mich dann aber morgen.

Was mich freut ist der Glanz der Objekte, den es in der alten Engine nicht
gab.
Ich werde auch in naher Zukunft mehrere Glanz-Methoden einbauen für
matte (z.B. Plastik) bis glänzende Oberflächen (z.B. Glas), damit nicht alles
so nach Christbaumkugeln aussieht. :)

Verfasst: 20.12.2006 02:36
von RaVeN99
RESPEKT dass du dein Projekt so weit führst und immernoch weiter machst :)
Ich finde die Ergebnisse mehr als interessant, allerdings würden mich vergleichswerte zur alten Version interessieren...
Sprich irgend eine standartisierte szenerie durchlaufen lassen und die avg. FPS angeben. Du meintest ja dass durch die Umstellung auf PB4 das ganze zum teil schneller wurde (also manche dinge).
Hier wirklich mal n paar zahlen zu lesen wäre für mich persönlich das interessanteste - da kann auch der leser der weniger der weniger ahn von der komplexen materie hat (wie ich eben zum beispiel ;)) deine fortschritte leichter verfolgen und bei größeren sprüngen auch mitfiebern wie schnell das Endergebnis wird :)

Btw.: Könnte man nicht durch benutzen von MMX/3DNow!, SSE I, II, III o.ä. nochmal geschwindigkeit rauskitzeln? Weiss ja nicht wie die berechnungen ablaufen, aber ich denke dass sich da mit mmx durchaus was machen ließe, da du ja sicher viele multiplikationen und additionen hast? Zudem ist zumindest MMX so ziemlich auf jeder halbwegs aktuellen CPU verfügbar, also wäre die kompatibilität ja auch nicht das riesen problem.

Auf jedenfall:
Good work :allright:
Und mach weiter! =) *gespanntbin*



Greetz
RaVeN

Verfasst: 20.12.2006 11:24
von NicTheQuick
Danke RaVeN99 für deine Worte. :)

Dass mit MMX, 3DNow!, SSE, SSE2 und/oder SSE3 noch mehr rauszuholen
ist, ist klar. Da ich mich aber mit ASM soweit nicht auskenne, bleibt das erst
einmal auf der Strecke, bis ich die Aufgabe wohl jemand anderem übergebe.

Das meiste sind tatächlich nur Additionen, Subtraktionen, Multiplikationen und
ganz wenige Divisionen und ein paar Wurzelziehen.

Wenn alles funktioniert, werde ich mal die Stellen herausholen, bei denen die
Geschwindigkeit eine große Rolle spielt und werde sie optimieren, bevor ein
ASM-Freak sich da heran wagt.

Verfasst: 20.12.2006 16:50
von NicTheQuick
Die Verspiegelung funktioniert jetzt richtig. Es werden die richtigen
Spiegelstrahlen berechnet. Ein Screenshot dazu lad ich hoch, wenn ich zu
Hause bin.

Jetzt bin ich an der Implementierung der Lichtbrechung, also der Berechnung
für die gebrochenen Strahlen. Im 2D-Raum ist das ein Leichtes, im 3D-Raum
wird es schwieriger, aber ich denke, meine Rechnung stimmt schon. Muss sie
nur noch einbauen.

Danach hatte ich vor noch ein paar mehr geometrische Formen einzubauen.
Zum Beispiel einen Kegelstumpf, eine Kreisfläche, eine geöffnete Kugel.
Einen Torus würde ich auch interessant finden, aber ich wüsste nicht, wie ich
den berechnen könnte. Da hat nicht zufällig jemand eine Idee?