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

Aktuelle Zeit: Fr Jul 18, 2025 08:47

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



Ein neues Thema erstellen Auf das Thema antworten  [ 20 Beiträge ]  Gehe zu Seite 1, 2  Nächste
Autor Nachricht
 Betreff des Beitrags: Raytracer liefert falsche Schatten
BeitragVerfasst: Do Jul 24, 2008 10:30 
Offline
DGL Member

Registriert: Di Mai 24, 2005 16:43
Beiträge: 710
hi,

Das Problem ist folgendes: Ich habe mich erst einmal ohne Hilfe von Tutorials etc. an einem Raytracer versucht, als ich dann feststellte, dass meine Schatten merkwürdig aussehen (siehe Bild) habe ich mir mal diverse Tutorials (auch das auf DGL) angeschaut. Allerdings konnte ich keinen groben Denkfehler entdecken, weshalb ich jetzt nicht weiß woran es liegt.

mfg


Zuletzt geändert von Seth am Fr Okt 15, 2010 15:16, insgesamt 3-mal geändert.

Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Fr Jul 25, 2008 19:38 
Offline
DGL Member

Registriert: Di Jun 06, 2006 09:59
Beiträge: 474
Grundsätzlich solltest du nicht das aktuelle Object ausschließen, sondern ein den Anfangspunkt des Strahls um ein Epsilon nach außer versetzen.
Insbesondere bin ich mir nicht sicher ob dein code Selbsbeschattung korrekt handhabt, z.B. wenn die Lichtquelle auf der anderen Seite der Kugel ist. Zum debuggen würde ich phong auch einmal ausmachen, damit du echte Beschattung von dunkler Beleuchtung trennen kannst.
Als optimierung würde ich später allerdings normale dot lichtvektor ausrechnen bevor du den Strahl losjagst und bei <0 ein early out machen für undurchsichtige Materialien.

_________________
Bild


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Sa Jul 26, 2008 08:59 
Offline
DGL Member

Registriert: Di Mai 24, 2005 16:43
Beiträge: 710
Selbstbeschattung ist dadurch ja erst einmal deaktiviert, dass das Objekt selbst ausgeschlossen wird, aber die Sache mit dem Epsilon werde ich mal probieren, ich muss ja nur den Punkt entlang der Normalen, die ich ja ohnehin berechnen muss, verschieben.

danke.


Zuletzt geändert von Seth am Sa Jul 26, 2008 21:37, insgesamt 1-mal geändert.

Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Sa Jul 26, 2008 16:49 
Offline
DGL Member

Registriert: Di Jun 06, 2006 09:59
Beiträge: 474
Ein paar allgemeine (performance) Tipps:
* Deklarier den Vektor als array[0..2]of single statt als record, damit lässt es sich imo leichter arbeiten
* Deine Nullmatrix etc als Konstante deklarieren mit {$WRITEABLECONST OFF}, gegen überschreiben ausversehen
* Konstante Vektorparameter als const übergeben, afaik ist das etwas schneller und hat keine Nachteile
* Rückgabewerde durch out parameter ersetzen, ist afaik ebenfalls schneller da ein kopiervorgang wegfällt allerdings unpraktisch, also nur umsetzen falls du die performance brauchst
* Kurze Funktionen als inline deklarieren, auch wenn das in Delphi nicht sonderlich viel bringt


Außerdem hat deine Abstandsberechnung einen bug wo du die indizes vertauscht hast. Du solltest deine hilfsfunktionen auch nutzen wenn du sie schon schreibst ;) Das ist die glaube ich Ursache für deine Probleme.
Wenn du die ersten 3 Zeilen von RaySphereIntersect ersetzt geht es:
Code:
  1.   a := v3f_sqr(ray.d);
  2.   b := 2 * v3f_dot(ray.d,v3f_sub(ray.p,sphere.position));
  3.   c := v3f_sqr(v3f_sub(sphere.position,ray.p)) - sqr(sphere.radius);


Epsilon ist üblicherweise SEHR klein und dient nur zur Kompensation von Floatingpoint fehlern.

Außerdem wäre etwas OOP bei deinen Objekttypen angebracht. Eine Baseklasse und die abgeleiteten objekte wie sphere die virtuelle Methoden überschreiben. Ist zwar nicht super schnell macht den code aber ordentlicher.

_________________
Bild


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Sa Jul 26, 2008 17:27 
Offline
DGL Member

Registriert: Di Jun 06, 2006 09:59
Beiträge: 474
Hab den code mal etwas umstrukturiert. Ist nur Pseudocode, die Struktur kannst du aber vllt als Grundlage für weiteres nutzen.
Code:
  1. unit UMain;
  2.  
  3. interface
  4.  
  5. uses
  6.   Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  7.   Dialogs, ExtCtrls, LinAlgebra, StdCtrls, math;
  8.  
  9. type
  10.  
  11.   TColor3f=array[0..2]of single;
  12.   // Strahl
  13.   TRay = record
  14.     p, d: TVector3f;
  15.     it: integer;
  16.   end;
  17.  
  18.   TLight = class
  19.     public
  20.       property Position:TVector3f;
  21.       function IsVisibleAt(const APosition:TVector3f):boolean;
  22.       function GetLightAt(const APosition:TVector3f):TColor3f;virtual;
  23.   end;
  24.  
  25.  
  26.   TIntersectInfo=record
  27.     Position:TVector3f;
  28.     Normal:TVector3f;
  29.     Obj:TTraceObj;
  30.     Material:TMaterial;
  31.   end;
  32.  
  33.   TMaterial=class
  34.     function GetFragmentColor(const IntersectInfo:TIntersectInfo):TColor3f;virtual;abstract;
  35.   end;
  36.  
  37.   // Objekte
  38.   TTraceObject = class
  39.   private
  40.   public
  41.     property Material:TMaterial;
  42.     function Intersect(const Ray:TRay;out IntersectInfo:TIntersectInfo):boolean;virtual;abstract;
  43.     constructor Create;
  44.   end;
  45.  
  46.   TTraceObjectArray = array of TTraceObject;
  47.  
  48.   // Kugel
  49.   TSphere = class(TTraceObject)
  50.     constructor Create;
  51.   private
  52.     FPosition: TVector3f;
  53.     FRadius: single;
  54.   public
  55.     function Intersect(const Ray:TRay;out IntersectInfo:TIntersectInfo):boolean;override;
  56.     property Position: TVector3f read FPosition write FPosition;
  57.     property Radius: single read FRadius write FRadius;
  58.   end;
  59.  
  60.   TDiffuseMaterial=class
  61.   private
  62.     FDiffuseColor: TColor3f;
  63.     procedure SetDiffuseColor(const Value: TColor3f);
  64.   published
  65.     public
  66.       function GetFragmentColor(const IntersectInfo:TIntersectInfo;const Lights:array of TLight):TColor3f;override;
  67.       property DiffuseColor:TColor3f read FDiffuseColor write SetDiffuseColor;
  68.   end;
  69.   // Licht
  70.  
  71.   TScene=class
  72.     RenderObjects: TTraceObjectArray;
  73.     Lights: array of TLight;
  74.     function ShootRay(const Ray:TRay;out IntersectInfo:TIntersectInfo):boolean;
  75.     function GetFragmentColor(const Ray:TRay):TColor3f;
  76.   end;
  77.  
  78.   TForm1 = class(TForm)
  79.     Image1: TImage;
  80.     Button1: TButton;
  81.     procedure FormCreate(Sender: TObject);
  82.     procedure FormDestroy(Sender: TObject);
  83.     procedure Button1Click(Sender: TObject);
  84.   private
  85.     FocalDistance: single;
  86.     function GetRay(x, y: integer): TRay;
  87.     procedure RayTracing;
  88.   public
  89.     { Public declarations }
  90.   end;
  91.  
  92. var
  93.   Form1: TForm1;
  94.  
  95. implementation
  96.  
  97. {$R *.dfm}
  98.  
  99. { TScene }
  100.  
  101. function TScene.GetFragmentColor(const Ray: TRay): TColor3f;
  102. var IntersectInfo:TIntersectInfo;
  103. begin
  104.   result:=BackgroundColor;
  105.   if ShootRay(Ray,IntersectInfo) then exit;//No hits
  106.   result:=IntersectInfo.Material.GetFragmentColor(IntersectInfo);
  107. end;
  108.  
  109.   { TDiffuseMaterial }
  110.  
  111. function TDiffuseMaterial.GetFragmentColor(const IntersectInfo: TIntersectInfo;
  112.   const Lights: array of TLight): TColor3f;
  113. var SumLight:TColor3f;
  114. begin
  115.   SumLight:=Scene.AmbientLight;
  116.   for each light in scene do
  117.     if light.isvisibleat(intersectInfo.position)
  118.       then Sumlight:=Sumlight+light.LightAtPosition*v3f_dot(Intersect.Normal,Vec(Intersect.Position,Light.Position))
  119.   result:=SumLight*Color;
  120. end;
  121.  
  122. procedure TDiffuseMaterial.SetDiffuseColor(const Value: TColor3f);
  123. begin
  124.   FDiffuseColor := Value;
  125. end;
  126.  
  127. function TScene.ShootRay(const Ray: TRay; out IntersectInfo: TIntersectInfo): boolean;
  128. var
  129.   closestIntersect,CurrentIntersect:TIntersection;
  130. begin
  131.   ClosestIntersect.dist:=+inf;
  132.   result:=false;
  133.   for each Trace object do
  134.     begin
  135.       if not object.intersect(Ray,CurrentIntersect) then continue;
  136.       result:=true;
  137.       if CurrentIntersect.dist<ClosestIntersect.dist then ClosestIntersect:=CurrentIntersect;
  138.     end;
  139.   if result then IntersectInfo:=ClosestItersect;
  140. end;
  141.  
  142. end.
  143.  

_________________
Bild


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Sa Jul 26, 2008 19:34 
Offline
DGL Member

Registriert: Di Mai 24, 2005 16:43
Beiträge: 710
Vielen Dank erstmal für die viele Mühe. Erstmal wollte ich meinen Code zum laufen kriegen, schauen wie ichs am besten anstelle und mich dann ans Optimieren machen. Das gleiche gilt für die Struktur, ich hatte vorher noch eine Version in der es nur nen Code in nem Onclick eines Buttons gab.

Mit der Berechnung hast du recht, die hätte ich wirklich nicht kompliziert ausschreiben müssen, besonders die Berechnung von c geht auch deutlich kürzer ;) Allerdings falsch war es nicht, deshalb bringt dies auch keine Änderung, was die Berechnung der Schatten angeht.

Deine Strukturtipps sind auch sehr nützlich, danke ;)

€: Ich glaub ich weiß den Fehler ;) Ich muss mit Halbgeraden arbeiten. Sonst bekomme ich ja immer einen Schnitt.
€2: Ja das wars ;) ein einfaches Skalarprodukt hat das Problem behoben ;) (welches ich mir auch noch sparen kann, wenn ich das in der Intersection Routine vornehme)

Das Ergebnis der Lösung sieht wie folgt aus (Anhang):


mfg


Du hast keine ausreichende Berechtigung, um die Dateianhänge dieses Beitrags anzusehen.


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: So Jul 27, 2008 08:40 
Offline
DGL Member

Registriert: Di Jun 06, 2006 09:59
Beiträge: 474
Doch, bei der berechnung von c hattest du einmal y statt x geschrieben. Dadurch wurde in deinem hochgeladenen Beispiel die Kugel nicht korrekt dargestellt und hatte diese seltsamen Einschnitte an der Seite.

_________________
Bild


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: So Jul 27, 2008 08:58 
Offline
DGL Member

Registriert: Di Mai 24, 2005 16:43
Beiträge: 710
Stimmt da war ein y zuviel ;) danke

What a difference a line makes ;)


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: So Jul 27, 2008 23:50 
Offline
DGL Member
Benutzeravatar

Registriert: Sa Aug 18, 2007 18:47
Beiträge: 694
Wohnort: Köln
Programmiersprache: Java
Ui! Das sieht schick aus.
Hast du das noch nachbearbeitet, oder ist das Antialiasing schon mit drin?

Und wie lange dauert es bis das Bild berechnet ist?

_________________
Es werde Licht.
glEnable(GL_LIGHTING);
Und es ward Licht.


Zitat aus einem Java Buch: "C makes it easy to shoot yourself in the foot; C++ makes it harder, but when you do it blows your whole leg off"

on error goto next


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Mo Jul 28, 2008 12:58 
Offline
DGL Member

Registriert: Di Mai 24, 2005 16:43
Beiträge: 710
Antialiasing ist schon drin, aber gerade das ist nicht die schnellste Variante ;) Es wird nicht nachträglich auf das Bild angewandt, ist also in dem Sinne kein Antialiasing, sondern einfach eine etwas exaktere Berechnung des Bildes. In diesem Fall wurden Pro Pixel 4*4 Strahlen losgeschickt und miteinander verrechnet. Ein paar Sekunden dauert es schon. Das Bild ist (bis auf die JPEG Kompression) so mit dem Raytracer berechnet worden.

Schade, dass solch schöne Schatten in OpenGL (und in Echtzeit) nicht so leicht zu berechnen sind :(

mfg


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Mo Jul 28, 2008 15:39 
Offline
DGL Member
Benutzeravatar

Registriert: Do Sep 02, 2004 19:42
Beiträge: 4158
Programmiersprache: FreePascal, C++
Seth hat geschrieben:
Antialiasing ist schon drin, aber gerade das ist nicht die schnellste Variante ;) Es wird nicht nachträglich auf das Bild angewandt, ist also in dem Sinne kein Antialiasing, sondern einfach eine etwas exaktere Berechnung des Bildes. In diesem Fall wurden Pro Pixel 4*4 Strahlen losgeschickt und miteinander verrechnet. Ein paar Sekunden dauert es schon. Das Bild ist (bis auf die JPEG Kompression) so mit dem Raytracer berechnet worden.


Ist nicht genau das das, was das Antialiasing ausmacht? Anstatt einen Wert pro Pixel zu berechnen, werden mehrere Berechnet und deren Mittelwert wird dann genommen, oder?

Gruß Lord Horazont

_________________
If you find any deadlinks, please send me a notification – Wenn du tote Links findest, sende mir eine Benachrichtigung.
current projects: ManiacLab; aioxmpp
zombofant networkmy photostream
„Writing code is like writing poetry“ - source unknown


„Give a man a fish, and you feed him for a day. Teach a man to fish and you feed him for a lifetime. “ ~ A Chinese Proverb


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Mo Jul 28, 2008 15:44 
Offline
DGL Member

Registriert: Di Mai 24, 2005 16:43
Beiträge: 710
Bin mit den Begrifflichkeiten nicht so vertraut. Wenn mans nachträglich anwenden würde (sprich mit den Nachbarpixel verrechnet) wäre es wohl kein Antialiasing, sondern einfach Blur.


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Mo Jul 28, 2008 15:46 
Offline
DGL Member

Registriert: Di Jun 06, 2006 09:59
Beiträge: 474
woher kommt denn die Scharfe Kante des Schattens bei der Selbstbeschattung? Das sollte normal nicht vorkommen.

_________________
Bild


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Mo Jul 28, 2008 18:34 
Offline
DGL Member
Benutzeravatar

Registriert: Sa Aug 18, 2007 18:47
Beiträge: 694
Wohnort: Köln
Programmiersprache: Java
Uiui!

Ich wusste garnicht, dass es bei Antialiasing sooo viele Unterschiede bzw Techniken gibt: Wikipedia

_________________
Es werde Licht.
glEnable(GL_LIGHTING);
Und es ward Licht.


Zitat aus einem Java Buch: "C makes it easy to shoot yourself in the foot; C++ makes it harder, but when you do it blows your whole leg off"

on error goto next


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Mo Jul 28, 2008 20:53 
Offline
DGL Member

Registriert: Di Jun 06, 2006 09:59
Beiträge: 474
zu AA gibt es papers welche sparsed Masks am günstigsten sind. Wenn dann die Farbunterschiede groß sind kann man ja auch noch adaptiv die Anzahl der Strahlen erhöhen.

_________________
Bild


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


Wer ist online?

Mitglieder in diesem Forum: 0 Mitglieder und 1 Gast


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.010s | 15 Queries | GZIP : On ]