Ray-tracing in GrCis library

GrCis library

Basic interfaces and classes are in the common folder: more abstract ones (interfaces, default classes) are in the RayCastingCommon.cs source file, basic implementations are in the RayCastingBasic.cs file (your will sometimes need to expand these classes).

Most of the ray-tracer architecture is covered by the PDF slideshow.

Important interfaces

  • IIntersectable - any entity able to be intersected by an ray in 3D space (function Intersect() returns a list of the Intersection objects)
  • ICamera - general primary ray generator (e.g. StaticCamera)
  • ILightSource - general light source
  • IReflectanceModel - general local reflectance model (BRDF)
  • IMaterial - material attributes of a specific material (has to be in unity with some concrete IReflectanceModel implementation)
  • ITexture - general texture prototype. Texture is any object able to change (modulate) arbitrary quantity/quantities stored in a Intersection object
  • ITimeDependent - any entity able to change in time (animation via time variable). It must be able to clone itself ("clone on demand" for multi-thread computation)
  • IRayScene - general prototype for ray-tracing rendering job data: scene geometry Intersectable, background color BackgroundColor, ray generator Camera and list of light sources Sources. Individual members can be animated (if they implement interface ITimeDependent)

3D scene definition (scene geometry)

  • ISceneNode - general scene graph node, can have ancestors (hierarchy) and attributed associated (GetAttribute(), SetAttribute(), ..), is able to be intersected by a ray (interface IIntersectable)
  • ISolid - scene hierarchy leaf (CSG-tree leaf) defining geometry of a solid (it has to implement mainly interface IIntersectable). Examples of solids: Plane, Sphere or BezierSurface
  • DefaultSceneNode - default implementation of interface ISceneNode, serves as a predecessor for more classes, e.g. leaves (ISolid)
  • CSGInnerNode - inner CSG-tree node

Important classes

  • Intersection - data object storing all information about single ray-scene intersection. Two-phase evaluation (laisy evaluation), primary instance holds only mandatory data, to complete all the information you need to call CompleteIntersection()..

Ray-based rendering algorithms

  • IImageFunction - abstract concept of image-function with continuous image plane - mapping from continuous image rectangle to a general color space (double[])
  • IRenderer - able to synthesize raster image from associated IImageFunction
  • SimpleImageSynthesizer - implements IRenderer, uses only one sample per pixel (1spp)
  • SupersamplingImageSynthesizer - ancestor of SimpleImageSynthesizer, able to use jittered supersampling in each pixel (independently)
  • RayCasting - implements IImageFunction, ray-casting algorithm
  • RayTracing - ancestor of RayCasting, implements recursive backward ray-tracing (Whitted)

Details

Intersection object

Intersection instance holds information about concrete ray-scene intersection. Two-phase computation is used:

  1. In the 1st phase only the most important data are computed (e.g. 1D coordinate of the intersection = t) and a reference to hit scene object is stored, optionally the object involved could store additional information for later use in the 2nd phase
  2. The 2nd phase means we will actually use this intersection. We need to compute everything - this is what the CompleteIntersection() function is for. Many support procedures, transform matrices, attribute processing, etc. - are already present in the core system and there is no need to reimplement them
Mandatory data items of the Intersection object (assigned in the 1st phase):
  • bool Enter [mandatory] - true if a ray enters an object from outer space ("air-solid" interface)
  • bool Front [mandatory] - true if a ray entered an elementary solid (ISolid) from outside to inside: it is equal to Enter at first but later it might be negated by a CSG set operation (negative CSG operation)
  • double T [mandatory] - parametric coordinate of the intersection point on the ray. Usually we are interested only in positive values T > 0.0 (but generally the system must deal with arbitrary values of T - e.g. for set operation implementation)
  • ISolid Solid [mandatory] - reference to a solid which has generated the intersection (which was intersected first by a ray). The reference will be utilised in the 2nd phase, the Solid.CompleteIntersection( this ) will be called.
  • object SolidData [mandatory, can be null] - support data stored here by a solid generating the intersection (for later use in the 2nd phase)

Datové položky počítané typicky až při kompletaci průsečíku:
  • Vector3d CoordWorld [odložená] - světové souřadnice průsečíku
  • Vector3d CoordObject [odložená] - relativní souřadnice v rámci objektu (animační jednotka, objekt se ve scéně hýbe jako jeden celek)
  • Vector3d CoordLocal [odložená] - lokální souřadnice průsečíku (v rámci elementárního tělesa)
  • Vector2d TextureCoord [odložená] - 2D texturové souřadnice na poverchu tělesa
  • Vector3d Normal [odložená] - normálový vektor (ve světových souřadnicích)
  • Matrix4d LocalToWorld, WorldToLocal [odložená] - transformační matice mezi lokálním (Solid) a světovým souřadným systémem
  • Matrix4d LocalToObject [odložená] - transformační matice z lokálního do objektového (animačního) prostoru
  • double [] SurfaceColor [odložená] - pracovní kopie barvy povrchu tělesa (může se mnohokrát přepisovat, proto se musí okopírovat ze sdílených datových struktur)
  • IReflectanceModel ReflectanceModel [odložená] - platný model odrazu světla (= světelný model)
  • IMaterial Material [odložená] - materiálové konstanty pro aktuální světelný model
  • LinkedList<ITexture> Textures [odložená] - seznam textur v pořadí, ve kterém se mají aplikovat (tj. od nižších priorit k vyšším)

Interface IIntersectable

Každá třída, která se umí protnout daným paprskem.

  • LinkedList<Intersection> Intersect ( Vector3d p0, Vector3d p1 ) - výpočet průsečíků daného paprsku s objektem. Vrací jen průsečíky s vyplněnými povinnými položkami (první fáze). Souřadnice paprsku jsou lokální = přizpůsobené elementárnímu tělesu!
  • CompleteIntersection ( Intersection inter ) - kompletace daného průsečíku (druhá fáze), je třeba dopočítat všechny odložené položky

Interface ICamera

Ve skutečnosti se v zobrazovači používá jako generátor primárních paprsků, to je jediná funkce objektů tohoto typu. Vstupem je souřadnice bodu v průmětně, výstupem paprsek zadaný počátečním bodem a směrovým vektorem:

  • bool GetRay ( double x, double y, out Vector3d p0, out Vector3d p1 ) - vrací true, pokud zadaná poloha bodu v průmětně ([x,y]) byla přípustná (výjimky např. objektiv typu "rybí oko")
  • double Width, Height, AspectRatio - parametry oblasti průmětny, která se má používat pro zobrazení. Tato tři čísla jsou na sobě závislá: AspectRatio = Width / Height

Interface ITimeDependent

Každá třída implementující tento interface se umí měnit v čase (animovat). Obsahuje vlastnosti:

  • double Start - počáteční čas ve sekundách, spíše informativní údaj říkající, v jakém intervalu je akceptován čas (Time).
  • double End - koncový čas ve sekundách (délka cyklu animace), spíše informativní údaj říkající, v jakém intervalu (periodě) je akceptován čas (Time).
  • double Time - vlastní nastavení vnitřního času instance. Pokud objekt obsahuje odkazy na další podobjekty (komponenty), musí se do nich čas propagovat!
Interface ITimeDependent je potomkem ICloneable. Význam je následující: pokud je výpočet obrázku prováděn ve více vláknech, musí se naklonovat všechny datové struktury, které by se případně v jednotlivých vláknech mohly individuálně modifikovat. Například při výpočtu animace má každé vlákno za úkol počítat jiný snímek animační sekvence. K tomu se používá vlastnost Time, při jejím nastavování by tudíž docházelo ke konfliktu.
Implementace metody Clone() musí být přítomna u všech objektů, které se v průběhu výpočtu mění a do kterých se ukládají nějaké mezivýsledky (stavové API). Musí se jednat o tzv. "deep-copy", to znamená, že se objekt musí při klonování postarat o to, aby všechny jeho komponenty implementující interface ITimeDependent byly rovněž naklonovány!

Konkrétní třídy

Nejdříve několik elementárních těles, všechna implementují ISolid (tj. nepřímo i interface IIntersectable) a jsou potomky DefaultSceneNode, to znamená, že mají implicitně implementované všechny funkce potřebné pro začlenění do grafu scény.

Sphere

Jednotlová koule se středem v pořátku. Prototyp elementárního tělesa, obsahuje všechny potřebné implementace v metodách Intersect() i CompleteIntersection().

Plane, Cube, Cylinder, Torus

Další jednoduchá tělesa, jejichž průsečíky lze spočítat analyticky.

TriangleMesh

Trojúhelníková síť uložená v datovém objektu SceneBrep (Corner Table, lze ji načíst z OBJ formátu, ...). Výpočet průsečíků je naivní, bez urychlovacích metod, není to tedy prakticky použitelný objekt.

BezierSurface

Síť bikubických Bézierových plátů. Ukázka optimalizovaného výpočtu průsečíků - pláty se dělí (subdivision) a výsledné menší pláty jsou ukládány do R-tree pro větší efektivitu při hledání průsečíku.


Následuje několik základních implementačních tříd, většinou realizují nejjednodušší variantu daného interface. Při rozšiřování ray-traceru je vhodné z jejich implementace vycházet, protože je přímočará a ověřená.

StaticCamera : ICamera

Nejjednodušší implementace generátoru primárních paprsků (interface ICamera). Simulace ideálního objektivu pro středové promítání do rovinné průmětny (lineární perspektiva). Geometrie je zadána středem projekce, směrem pohledu a Up vektorem. Dále je definován zorný úhel pomocí třech na sobě závislých parametrů: Width, Height a AspectRatio.


Copyright (C) 2011-2017 J.Pelikán, last change: 2017-03-13 02:24:29 +0100 (Mon, 13 Mar 2017)