public override void GenerateSamples() { //Generate samples along diagonal and then shuffle coordinates for(int n = 0; n < _numSets; n++) { for(int j = 0; j < _numSamples; j++) { Point2D p = new Point2D((j + (float)randomgen.NextDouble()) / _numSamples, (j + (float)randomgen.NextDouble()) / _numSamples); _samples.Add(p); } } //shuffle_x_coords(); //shuffle_y_coords(); }
public virtual void MapSamplesToDisk() { for(int i = 0; i < (_numSamples*_numSets); i++) { _diskSamples.Add(new Point2D()); float r; float phi; //Determine the quadrant for which to map according to the Shirley concentric map //Quadrant 1 and 2: if(_samples[i].coords.X > -_samples[i].coords.Y) { //Conditions for quadrant 1 if(_samples[i].coords.X > _samples[i].coords.Y) { r = _samples[i].coords.X; phi = (_samples[i].coords.Y / _samples[i].coords.X) * ((float)Math.PI / 4.0f); } //Otherwise in quadrant 2 else { r = _samples[i].coords.Y; phi = (_samples[i].coords.Y != 0.0f) ? (2 - _samples[i].coords.X / _samples[i].coords.Y) * ((float)Math.PI / 4.0f) : 0.0f; //Don't divide by zero } } //Quadrant 3 and 4 else { //Conditions for quadrant 3 if(_samples[i].coords.X < _samples[i].coords.Y) { r = -_samples[i].coords.X; phi = (_samples[i].coords.X != 0.0f) ? (4 + _samples[i].coords.Y / _samples[i].coords.X) * ((float)Math.PI / 4.0f) : 0.0f; //Don't divide by zero } //Otherwise in quadrant 4 else { r = -_samples[i].coords.Y; phi = (_samples[i].coords.Y != 0.0f) ? (6 - _samples[i].coords.X / _samples[i].coords.Y) * ((float)Math.PI / 4.0f) : 0.0f; //Don't divide by zero } } _diskSamples[i] = new Point2D(r * (float)Math.Cos(phi), r * (float)Math.Sin(phi)); } }
/// <summary> /// Renders a single rectangular chunk of the scene /// </summary> /// <param name="worldRef">Reference to the world</param> /// <param name="xCoord1">Smallest x coordinate</param> /// <param name="xCoord2">Largest x coordinate</param> /// <param name="yCoord1">Smallest y coordinate</param> /// <param name="yCoord2">Largest y coordinate</param> /// <param name="threadNum">Thread number</param> public override void RenderSceneFragment(World worldRef, int xCoord1, int xCoord2, int yCoord1, int yCoord2, int threadNum) { RGBColor L = new RGBColor(); Ray ray = new Ray(); ViewPlane vp = worldRef.CurrentViewPlane; int depth = 0; Point2D samplePoint = new Point2D(); Point2D samplePointPixelSpace = new Point2D(); Point2D samplePointOnDisk = new Point2D(); Point2D samplePointOnLens = new Point2D(); Sampler screenSamplerClone = GlobalVars.VIEWPLANE_SAMPLER.Clone(); Sampler lensSamplerClone = depthSampler.Clone(); //vp.s /= zoom; //Vector2 tmp2 = new Vector2(vp.hres * 0.5f, vp.vres*0.5f); for (int r = yCoord1; r < yCoord2; r++) { for (int c = xCoord1; c < xCoord2; c++) { L = GlobalVars.COLOR_BLACK; for (int n = 0; n < vp.NumSamples; n++) { //Sample on unit square samplePoint = screenSamplerClone.SampleUnitSquare(); //Sample in screenspace //Vector2 tmp1 = new Vector2(c, r); //pp.coords = vp.s * (tmp1 - tmp2 * sp.coords); samplePointPixelSpace.coords.X = vp.PixelSize * (c - vp.HorizontalResolution * 0.5f + samplePoint.coords.X); samplePointPixelSpace.coords.Y = vp.PixelSize * (r - vp.VerticalResolution * 0.5f + samplePoint.coords.Y); samplePointOnDisk = lensSamplerClone.SampleDisk(); samplePointOnLens.coords.X = samplePointOnDisk.coords.X * radius; samplePointOnLens.coords.Y = samplePointOnDisk.coords.Y * radius; //lp.coords = dp.coords * radius; ray.Origin = _eye + samplePointOnLens.coords.X * u + samplePointOnLens.coords.Y * v; ray.Direction = GetRayDirection(samplePointPixelSpace, samplePointOnLens); L += worldRef.CurrentTracer.TraceRay(ray, depth); } L /= vp.NumSamples; L *= _exposureTime; worldRef.DisplayPixel(r, c, L); } } DequeueNextRenderFragment(); }
/// <summary> /// Gets the direction of a ray given a pixel and a point on a lens /// </summary> /// <param name="pixel">Pixel</param> /// <param name="lens">Lens</param> /// <returns>Normalized vector describing direction of ray</returns> private Vect3D GetRayDirection(Point2D pixel, Point2D lens) { Point2D p = new Point2D(pixel.coords.X*(focalPlaneDistance/viewPlaneDistance),pixel.coords.Y*(focalPlaneDistance/viewPlaneDistance)); Vect3D dir = (p.coords.X - lens.coords.X) * u + (p.coords.Y - lens.coords.Y) * v - focalPlaneDistance * w; //Vector2 res = pixel.coords * FOVERD - lens.coords; //Vect3D dir = res.X * u + res.Y * v - f * w; dir.Normalize(); return dir; }
public override void RenderScene(World w) { RGBColor L = new RGBColor(); Ray ray = new Ray(); ViewPlane vp = w.CurrentViewPlane; int depth = 0; Point2D sp = new Point2D(); Point2D pp = new Point2D(); Point2D dp = new Point2D(); Point2D lp = new Point2D(); //w.open_window(vp.hres, vp.vres); vp.PixelSize /= _zoom; for(int r = 0; r < vp.VerticalResolution-1; r++) { for(int c = 0; c < vp.HorizontalResolution-1; c++) { L = GlobalVars.COLOR_BLACK; for(int n = 0; n < vp.NumSamples; n++) { //Sample on unit square sp = vp.ViewPlaneSampler.SampleUnitSquare(); //Sample in screenspace pp.coords.X = vp.PixelSize * (c - vp.HorizontalResolution * 0.5f + sp.coords.X); pp.coords.Y = vp.PixelSize * (r - vp.VerticalResolution * 0.5f + sp.coords.Y); dp = depthSampler.SampleDisk(); lp.coords.X = dp.coords.X * radius; lp.coords.Y = dp.coords.Y * radius; ray.Origin = _eye + lp.coords.X * u + lp.coords.Y * v; ray.Direction = GetRayDirection(pp, lp); L += w.CurrentTracer.TraceRay(ray, depth); } L /= vp.NumSamples; L *= _exposureTime; w.DisplayPixel(r, c, L); w.PollEvents(); } } }
/// <summary> /// Renders the world on a single thread [deprecated, use RenderSceneMultiThreaded] /// </summary> /// <param name="world">World reference</param> public override void RenderScene(World worldRef) { RGBColor lightingSum; ViewPlane vp = worldRef.CurrentViewPlane; Ray ray = new Ray(_eye,new Vect3D(0,0,0)); int depth = 0; //Depth of recursion Point2D sp = new Point2D(); //Sample point on a unit square Point2D pp = new Point2D(); ; //Sample point translated into screen space worldRef.OpenWindow(vp.HorizontalResolution, vp.VerticalResolution); vp.PixelSize /= _zoom; for(int row = 0; row < vp.VerticalResolution; row++) { for(int column = 0; column < vp.HorizontalResolution; column++) { lightingSum = GlobalVars.COLOR_BLACK; //Start with no color, everything is additive for(int sample = 0; sample < vp.NumSamples; sample ++) { sp = worldRef.CurrentViewPlane.ViewPlaneSampler.SampleUnitSquare(); pp.coords.X = worldRef.CurrentViewPlane.PixelSize * (column - 0.5f * vp.HorizontalResolution + sp.coords.X); pp.coords.Y = worldRef.CurrentViewPlane.PixelSize * (row - 0.5f * vp.VerticalResolution + sp.coords.Y); ray.Direction = GetRayDirection(pp); lightingSum = lightingSum + worldRef.CurrentTracer.TraceRay(ray, depth); } lightingSum /= vp.NumSamples; lightingSum *= _exposureTime; worldRef.DisplayPixel(row, column, lightingSum); //Poll events in live render view worldRef.PollEvents(); } } }
private Vect3D GetRayDirection(Point2D point) { Vect3D dir = point.coords.X * u + point.coords.Y * v - pinholeViewPlaneDistance * w; dir.Normalize(); return dir; }
/// <summary> /// Renders a single rectangular chunk of the scene /// </summary> /// <param name="worldRef">Reference to the world</param> /// <param name="xCoord1">Smallest x coordinate</param> /// <param name="xCoord2">Largest x coordinate</param> /// <param name="yCoord1">Smallest y coordinate</param> /// <param name="yCoord2">Largest y coordinate</param> /// <param name="threadNum">Thread number</param> public override void RenderSceneFragment(World worldRef, int xCoord1, int xCoord2, int yCoord1, int yCoord2, int threadNum) { //To avoid clashes with other threads accessing sampler, clone the main world sampler Sampler localSampler = worldRef.CurrentViewPlane.ViewPlaneSampler.Clone(); RGBColor L; ViewPlane vp = worldRef.CurrentViewPlane; Ray ray = new Ray(_eye, new Vect3D(0, 0, 0)); int depth = 0; //Depth of recursion Point2D unitSquareSample = new Point2D(); //Sample point on a unit square Point2D sampleInScreenSpace = new Point2D(); ; //Sample point translated into screen space int height = yCoord2 - yCoord1; int width = xCoord2 - xCoord1; for (int row = 0; row < height; row++) { for (int column = 0; column < width; column++) { L = GlobalVars.COLOR_BLACK; //Start with no color, everything is additive for (int sample = 0; sample < vp.NumSamples; sample++) { unitSquareSample = localSampler.SampleUnitSquare(); sampleInScreenSpace.coords.X = worldRef.CurrentViewPlane.PixelSize * (column + xCoord1 - 0.5f * vp.HorizontalResolution + unitSquareSample.coords.X); sampleInScreenSpace.coords.Y = worldRef.CurrentViewPlane.PixelSize * (row + yCoord1 - 0.5f * vp.VerticalResolution + unitSquareSample.coords.Y); ray.Direction = GetRayDirection(sampleInScreenSpace); L = L + worldRef.CurrentTracer.TraceRay(ray, depth); } L /= vp.NumSamples; L *= _exposureTime; worldRef.DisplayPixel(row + yCoord1, column + xCoord1, L); } } DequeueNextRenderFragment(); }
public Point2D(Point2D p) { coords = p.coords; }