Seite 1 von 1

Artefakte beim Ray Casting

Verfasst: 31.07.2013, 09:03
von Matthias Gubisch
Hallo zusammen

ich bastel gerade an einem Volume Renderer auf RayCasting Basis.
Soweit funktionert er eigentlich ganz gut nur erhalte ich diverse Artefakte die ich mir nicht erklären kann und deshalb auch keine Lösung finde.

1. Ringförmige Artefakte auf dem Volumen
Auf dem Screenshot sieht man schön die Ringe die entstehen wenn man das Volumen dreht.
Rings.PNG

2. Falsch detektierte Pixel
Das Volumen hier im zweiten Teil besteht eigentlich nur aus dem hinteren bereich. Die grauen Pixel davor die sich wie eine Box um das Volumen Aufbauen sind eigentlich gar nicht da, werden aber trotzdem gerendert...
FalseVoxels.PNG
Wäre super wenn der ein oder andere eine Idee hätte woher diese Artefakte kommen damit ich weiß wo ich zum Suchen anfangen muss.

Re: Artefakte beim Ray Casting

Verfasst: 31.07.2013, 09:06
von Artificial Mind
Die ringförmigen Artefakte sind in solchen Szenarien eigentlich immer Resultat der Schrittweite. Dein Raycasting ist wahrscheinlich durch eine fixe Schrittweite implementiert, richtig?

Re: Artefakte beim Ray Casting

Verfasst: 31.07.2013, 09:07
von Matthias Gubisch
Jap ist es, was hätte ich da für alternativen?
Ist die Schrittweite dann allgemein zu groß oder zu klein gewählt, oder hängt das noch von anderen Faktoren ab?

Re: Artefakte beim Ray Casting

Verfasst: 31.07.2013, 09:29
von Schrompf
Nein, das ist primär dem Zugriffsmuster geschuldet. Der Shader samplet linear entlang einer Geraden durch das Volumen. Die gesampleten Bereiche sind also quasi 2D-Ebenen-Querschnitte durch das Volumen. Und wenn Du von vorn durch diese Ebenen schaust, ergibt das auf dem Schirm eine Reihe Schnittkanten, wo die Grenze zwischen "x Samples im Volumen" und "x+1 Samples innerhalb des Volumens" erkennbar ist. Wird dementsprechend geringer, je mehr Samples man nimmt. Kann man auch etwas verrauschen, in dem man die Sample-Position pseudozufällig etwas vor und zurück verschiebt. Oder Du machst schlicht den trilinearen Texturfilter an.

Zum dunkelgrauen Quaderbereich rund um das Rendering: hier rate ich jetzt völlig, weil ich nicht verstanden habe, was davon Absicht ist und was nicht. Schau mal nach, ob das Samplen aus dem Volumen wirklich 0 ergibt oder vielleicht nur einen minimal kleinen Wert über 0. Prüfe außerdem, ob Du vielleicht irgendwo im Shader aus Versehen einen festen Wert addierst oder sowas.

Re: Artefakte beim Ray Casting

Verfasst: 31.07.2013, 09:30
von Jonathan
Wir hatten bei unserem Volume-Ray-Caster die selben Effekte. Die Ursache ist halt, das wir den Strahl in einer festen Schrittweite abgetastet haben und alle Punkte, die außerhalb des Volumens lagen, verworfen haben. Und wenn du jetzt langsam am Objekt entlang gehst, ist halt irgendwann ein Punkt knapp hinter der Grenze und somit nicht mehr drin, du hast also einen unstetigen Übergang bzw. schlagartig einen Summanden weniger in deiner Summe. Ein paar Pixel weiter fällt halt der nächste Punkt raus, und so entstehen dann die Streifen bzw. Ringe.

Lösungen? Hm, kniffelig. Wir haben einfach gar nichts gemacht :D. Im Grunde genommen musst du ja entlang des Strahls integrieren, was du aber nicht wirklich kannst, weswegen man ja ursächlich auf die schrittweise Abtastung umgestiegen ist. Mir fällt gerade ein, dass es im Grunde genommen, das selbe Problem wie Pixeltreppen bei rasterisierten Bildern ist. Da schraubt man halt die Auflösung hoch, bzw. macht später noch AA, vielleicht kann man das irgendwie aufs Volume-Raycasting übertragen?

Re: Artefakte beim Ray Casting

Verfasst: 31.07.2013, 09:44
von Matthias Gubisch
Danke für die Antworten

Trilinerer Texturfilter: da der Kernel der das Raycasting durchführt auf CUDA 4.2 läuft hab ich den leider nicht zur Verfügung :(
Die Idee mit der pseudozufälligen Startposition klingt gut, werde ich mal probieren ;)

Aktuell Taste ich auch in einer festen Schrittweite ab, die einzige Möglichkeit die ich bei meinen Recherchen gefunden habe die Schrittweite zu verändern wär mit Hilfe eines Importance Volumes, das ist aber leider keine Möglichkeit da ich Speicherbedingt keine Möglichkeit habe noch ein weiteres Volumen auf der Grafikkarte unterzubekommen. Kennt jemand hierzu eine alternative?

Das gleiche Problem hab ich bei der Preintegration die ich auch noch gefunden habe, die diese Sampling Effekte angeblich verbessern soll.

Es werden also weiter Ideen gesucht, und das zweite Problem ist immer noch nicht gelöst, hier nochmal kurz als Erklärung: der Weisse Bereich ist der Bereich der Sichtbar sein soll, alles drum herum im Zweifel nicht um die Erklärung zu vereinfachen.

Re: Artefakte beim Ray Casting

Verfasst: 31.07.2013, 10:05
von Schrompf
Keine Ahnung, woher die zweiten Artefakte kommen. Aber diese Moiree-Muster sehen vertraut aus... könnte es sein, dass ein einzelnes Samples aus der Kette 1 liefert? Wie eine dünne Schicht aus Werten, die beim Samples zufällig mal getroffen wird und mal nicht.

Nebenbei: wäre es nicht effizienter, das Volumen wirklich als Bounding Box mit Dreiecken zu rendern und die Raycasts nur für die betroffenen Bildschirmpixel im Pixelshader zu machen? Mir erscheint das so... verschwenderisch, einfach alles zu samplen.

Re: Artefakte beim Ray Casting

Verfasst: 31.07.2013, 10:15
von Artificial Mind
Es gibt noch ne andere Alternative zu fester Schrittweite: "einfach" immer direkt ins nächste Voxel gehen und den zurückgelegten Weg als "Integrationsstrecke" nutzen.

Das hab ich in meiner BA so gemacht und funktionierte gut auf der Grafikkarte. Ist auch nicht allzu teuer.
Grundidee: wenn du d = (dx, dy, dz) als "Rest" zum nächsten (integer-Koordinaten) Voxel hast und v = (vx, vy, vz) deine Strahlrichtung ist, dann sind (dx / vx, dy / vy, dz / vz) = (tx, ty, tz) die "Zeiten" die man jeweils zur nächsten Koordinate braucht. Ergo ist t = min(tx, ty, tz) der Zeitpunkt zu dem man den nächsten Voxel trifft.
Jetzt kann man also mit pos' <- pos + t * v direkt in den nächsten Voxel "springen". dabei ist t direkt der zurückgelegte Weg (wenn v normiert ist) und kann damit für die Integration genommen werden.
(Den "Restvektor" d kann man mit etwas sign und fract Gebastel auch direkt ohne Sprünge berechnen)

Re: Artefakte beim Ray Casting

Verfasst: 31.07.2013, 10:38
von Matthias Gubisch
Schrompf hat geschrieben:Keine Ahnung, woher die zweiten Artefakte kommen. Aber diese Moiree-Muster sehen vertraut aus... könnte es sein, dass ein einzelnes Samples aus der Kette 1 liefert? Wie eine dünne Schicht aus Werten, die beim Samples zufällig mal getroffen wird und mal nicht.
Daran hab ich auch schon gedacht, aber bisher noch nichts gefunden wo das herkommen könnte :(
Schrompf hat geschrieben:Nebenbei: wäre es nicht effizienter, das Volumen wirklich als Bounding Box mit Dreiecken zu rendern und die Raycasts nur für die betroffenen Bildschirmpixel im Pixelshader zu machen? Mir erscheint das so... verschwenderisch, einfach alles zu samplen.
Sowas ähnliches mache ich hier bereits, ich führe als allererstes für jeden Strahl einen Test durch ob die BoundingBox des Volumens getroffen wird und nur dann wird weitergesamplet. Von daher wird das Volumen also wirklich nur für die betroffenen Bildschrimpixel gesampelt

@ ArtificialMind:
Der Restvector ist ja dann eigentlich nur je nach Vorzeichen der richtung Auf bzw abgerundet auf die nächste Ganzzahl oder?
Und t ist dann im endefekt nochmal ein Faktor für die Integration?
Hab ich das so richtig verstanden?

Re: Artefakte beim Ray Casting

Verfasst: 31.07.2013, 10:53
von Artificial Mind
Matthias Gubisch hat geschrieben: @ ArtificialMind:
Der Restvector ist ja dann eigentlich nur je nach Vorzeichen der richtung Auf bzw abgerundet auf die nächste Ganzzahl oder?
Und t ist dann im endefekt nochmal ein Faktor für die Integration?
Hab ich das so richtig verstanden?
Genau. Also den Restvektor kriegt man recht einfach raus indem man die Position abrundet "fract(pos)" und dann für alle positiven Richtungsanteile eins drauf addiert. Damit bekommt man die Position des nächsten Voxels. Davon kann man dann die aktuelle position abziehen. (Das gibt für negative Richtungen natürlich negative Werte, aber das ist gut so, da man durch dx / vx wieder positiv wird, t also immer >= 0 ist)
Grundsätzlich also: "fract(pos) + vec3(v > vec3(0)) - pos"
Wenn ich mich nicht täusche sollte "v > vec3(0)" einen bool-Vektor zurückgeben der true in den positiven Komponenten hat und false in den negativen. vec3(..) darauf sollte das dann in 1 für true und 0 für false umwandeln.
Das ist jetzt natürlich GLSL Syntax, aber es sollte in CUDA ähnlich gehen.

Ob t wirklich ein Faktor ist, hängt davon ab wie du genau integrierst. Sollte aber nicht so schwer sein das mit einzubauen.

Re: Artefakte beim Ray Casting

Verfasst: 31.07.2013, 12:10
von Schrompf
Matthias Gubisch hat geschrieben:Sowas ähnliches mache ich hier bereits, ich führe als allererstes für jeden Strahl einen Test durch ob die BoundingBox des Volumens getroffen wird und nur dann wird weitergesamplet. Von daher wird das Volumen also wirklich nur für die betroffenen Bildschrimpixel gesampelt
Dann ist es das vielleicht? Die Schnittpunktberechnung Strahl mit Quader liefert je nach Rundungsfehlern mal Ergebnisse jenseits der Ebene und mal Ergebnisse diesseits. Wenn Du dann direkt von diesem Punkt aus anfängst zu sampeln, ist wahrscheinlich die Hälfte der Samples am Startpunkt außerhalb des Volumens. Aber was Du dann bei CUDA an Werten zurückbekommst, weiß ich nicht... kann sein, dass es dafür definitierte Standardwerte gibt, oder eine festlegbare Randfarbe wie bei normalen Textursamplern.

Re: Artefakte beim Ray Casting

Verfasst: 13.08.2013, 07:31
von Matthias Gubisch
Erstmal danke für die vielen Antworten.
Das Problem mit den Ringartefakten habe ich aktuell durch die Methode von ArtitficialMind und eine geringfügig veränderte Sample Frequenz ganz gut in den Griff bekommen.

Das Box Artefakt ist leider immer noch da, hier werd ich noch ein paar Tests machen, bin aber immer no auf der Suche nach intelligenten Lösungen.