public void RayTraceScene(RectangleInt viewport, Scene scene) { int maxsamples = (int)AntiAliasing; // graphics2D.FillRectangle(viewport, RGBA_Floats.Black); if (ColorBuffer == null || ColorBuffer.Length < viewport.Width || ColorBuffer[0].Length < viewport.Height) { ColorBuffer = new ColorF[viewport.Width][]; for (int i = 0; i < viewport.Width; i++) { ColorBuffer[i] = new ColorF[viewport.Height]; } NormalBuffer = new Vector3[viewport.Width][]; for (int i = 0; i < viewport.Width; i++) { NormalBuffer[i] = new Vector3[viewport.Height]; } DepthBuffer = new double[viewport.Width][]; for (int i = 0; i < viewport.Width; i++) { DepthBuffer[i] = new double[viewport.Height]; } } if (TraceWithRayBundles) { int yStep = 8; int xStep = 8; for (int y = viewport.Bottom; y < viewport.Height; y += yStep) { for (int x = viewport.Left; x < viewport.Right; x += xStep) { try { int bundleWidth = Math.Min(xStep, viewport.Right - x); int bundleHeight = Math.Min(yStep, viewport.Top - y); var rayBundle = new FrustumRayBundle(bundleWidth * bundleHeight); var intersectionsForBundle = new IntersectInfo[bundleWidth * bundleHeight]; // Calculate all the initial rays for (int rayY = 0; rayY < bundleHeight; rayY++) { for (int rayX = 0; rayX < bundleWidth; rayX++) { rayBundle.rayArray[rayX + rayY * bundleWidth] = scene.camera.GetRay(x + rayX, y + rayY); intersectionsForBundle[rayX + rayY * bundleWidth] = new IntersectInfo(); } } // get a ray to find the origin (every ray comes from the camera and should have the same origin) rayBundle.CalculateFrustum(bundleWidth, bundleHeight, rayBundle.rayArray[0].origin); FullyTraceRayBundle(rayBundle, intersectionsForBundle, scene); // get the color data out of the traced rays for (int rayY = 0; rayY < bundleHeight; rayY++) { for (int rayX = 0; rayX < bundleWidth; rayX++) { ColorBuffer[x + rayX][y + rayY] = intersectionsForBundle[rayX + rayY * bundleWidth].TotalColor; } } } catch { } } } } else { if (MultiThreaded) { System.Threading.Tasks.Parallel.For(viewport.Bottom, viewport.Height, y => { TraceXSpan(viewport, scene, y); }); } else { for (int y = viewport.Bottom; y < viewport.Height; y++) { TraceXSpan(viewport, scene, y); } } } if (AntiAliasing != AntiAliasing.None) { AntiAliasScene(viewport, scene, ColorBuffer, (int)AntiAliasing); } }
public void RayTraceScene(Graphics2D graphics2D, RectangleInt viewport, Scene scene) { int maxsamples = (int)AntiAliasing; //graphics2D.FillRectangle(viewport, RGBA_Floats.Black); if (imageBufferAsDoubles == null || imageBufferAsDoubles.Length < viewport.Width || imageBufferAsDoubles[0].Length < viewport.Height) { imageBufferAsDoubles = new RGBA_Floats[viewport.Width][]; for (int i = 0; i < viewport.Width; i++) { imageBufferAsDoubles[i] = new RGBA_Floats[viewport.Height]; } } IImageByte destImage = (IImageByte)graphics2D.DestImage; if (destImage.BitDepth != 32) { throw new Exception("We can only render to 32 bit dest at the moment."); } Byte[] destBuffer = destImage.GetBuffer(); viewport.Bottom = Math.Max(0, Math.Min(destImage.Height, viewport.Bottom)); viewport.Top = Math.Max(0, Math.Min(destImage.Height, viewport.Top)); #if MULTI_THREAD System.Threading.Tasks.Parallel.For(viewport.Bottom, viewport.Height, y => // #else for (int y = viewport.Bottom; y < viewport.Height; y++) #endif { for (int x = viewport.Left; x < viewport.Right; x++) { if (traceWithRayBundles) { int width = Math.Min(8, viewport.Right - x); int height = Math.Min(8, viewport.Top - y); FrustumRayBundle rayBundle = new FrustumRayBundle(width * height); IntersectInfo[] intersectionsForBundle = new IntersectInfo[width * height]; for (int rayY = 0; rayY < height; rayY++) { for (int rayX = 0; rayX < width; rayX++) { rayBundle.rayArray[rayX + rayY * width] = scene.camera.GetRay(x + rayX, y + rayY); intersectionsForBundle[rayX + rayY * width] = new IntersectInfo(); } } rayBundle.CalculateFrustum(width, height, scene.camera.Origin); FullyTraceRayBundle(rayBundle, intersectionsForBundle, scene); for (int rayY = 0; rayY < height; rayY++) { int bufferOffset = destImage.GetBufferOffsetY(y + rayY); for (int rayX = 0; rayX < width; rayX++) { imageBufferAsDoubles[x + rayX][y + rayY] = intersectionsForBundle[rayX + rayY * width].totalColor; // we don't need to set this if we are anti-aliased int totalOffset = bufferOffset + (x + rayX) * 4; destBuffer[totalOffset++] = (byte)imageBufferAsDoubles[x + rayX][y + rayY].Blue0To255; destBuffer[totalOffset++] = (byte)imageBufferAsDoubles[x + rayX][y + rayY].Green0To255; destBuffer[totalOffset++] = (byte)imageBufferAsDoubles[x + rayX][y + rayY].Red0To255; destBuffer[totalOffset] = 255; } } x += width - 1; // skip all the pixels we bundled y += height - 1; // skip all the pixels we bundled } else { int bufferOffset = destImage.GetBufferOffsetY(y); Ray ray = scene.camera.GetRay(x, y); imageBufferAsDoubles[x][y] = FullyTraceRay(ray, scene); // we don't need to set this if we are anti-aliased int totalOffset = bufferOffset + x * 4; destBuffer[totalOffset++] = (byte)imageBufferAsDoubles[x][y].Blue0To255; destBuffer[totalOffset++] = (byte)imageBufferAsDoubles[x][y].Green0To255; destBuffer[totalOffset++] = (byte)imageBufferAsDoubles[x][y].Red0To255; destBuffer[totalOffset] = 255; } } } #if MULTI_THREAD ); #endif if (AntiAliasing != AntiAliasing.None) { AntiAliasScene(graphics2D, viewport, scene, imageBufferAsDoubles, (int)AntiAliasing); } destImage.MarkImageChanged(); }
public void RayTraceScene(ImageBuffer destImage, RectangleInt viewport, Scene scene) { int maxsamples = (int)AntiAliasing; //graphics2D.FillRectangle(viewport, RGBA_Floats.Black); if (imageBufferAsDoubles == null || imageBufferAsDoubles.Length < viewport.Width || imageBufferAsDoubles[0].Length < viewport.Height) { imageBufferAsDoubles = new RGBA_Floats[viewport.Width][]; for (int i = 0; i < viewport.Width; i++) { imageBufferAsDoubles[i] = new RGBA_Floats[viewport.Height]; } } if (destImage.BitDepth != 32) { throw new Exception("We can only render to 32 bit dest at the moment."); } Byte[] destBuffer = destImage.GetBuffer(); viewport.Bottom = Math.Max(0, Math.Min(destImage.Height, viewport.Bottom)); viewport.Top = Math.Max(0, Math.Min(destImage.Height, viewport.Top)); #if MULTI_THREAD System.Threading.Tasks.Parallel.For(viewport.Bottom, viewport.Height, y => // #else for (int y = viewport.Bottom; y < viewport.Height; y++) #endif { for (int x = viewport.Left; x < viewport.Right; x++) { if (traceWithRayBundles) { int width = Math.Min(8, viewport.Right - x); int height = Math.Min(8, viewport.Top - y); FrustumRayBundle rayBundle = new FrustumRayBundle(width * height); IntersectInfo[] intersectionsForBundle = new IntersectInfo[width * height]; for (int rayY = 0; rayY < height; rayY++) { for (int rayX = 0; rayX < width; rayX++) { rayBundle.rayArray[rayX + rayY * width] = scene.camera.GetRay(x + rayX, y + rayY); intersectionsForBundle[rayX + rayY * width] = new IntersectInfo(); } } rayBundle.CalculateFrustum(width, height, scene.camera.Origin); FullyTraceRayBundle(rayBundle, intersectionsForBundle, scene); for (int rayY = 0; rayY < height; rayY++) { int bufferOffset = destImage.GetBufferOffsetY(y + rayY); for (int rayX = 0; rayX < width; rayX++) { imageBufferAsDoubles[x + rayX][y + rayY] = intersectionsForBundle[rayX + rayY * width].totalColor; if (AntiAliasing == AntiAliasing.None) { // we don't need to set this if we are anti-aliased int totalOffset = bufferOffset + (x + rayX) * 4; destBuffer[totalOffset++] = (byte)imageBufferAsDoubles[x + rayX][y + rayY].Blue0To255; destBuffer[totalOffset++] = (byte)imageBufferAsDoubles[x + rayX][y + rayY].Green0To255; destBuffer[totalOffset++] = (byte)imageBufferAsDoubles[x + rayX][y + rayY].Red0To255; destBuffer[totalOffset] = 255; } } } x += width - 1; // skip all the pixels we bundled y += height - 1; // skip all the pixels we bundled } else { int bufferOffset = destImage.GetBufferOffsetY(y); Ray ray = scene.camera.GetRay(x, y); imageBufferAsDoubles[x][y] = FullyTraceRay(ray, scene); // we don't need to set this if we are anti-aliased int totalOffset = bufferOffset + x * 4; destBuffer[totalOffset++] = (byte)imageBufferAsDoubles[x][y].Blue0To255; destBuffer[totalOffset++] = (byte)imageBufferAsDoubles[x][y].Green0To255; destBuffer[totalOffset++] = (byte)imageBufferAsDoubles[x][y].Red0To255; destBuffer[totalOffset] = 255; } } }
public void RayTraceScene(RectangleInt viewport, Scene scene) { int maxsamples = (int)AntiAliasing; //graphics2D.FillRectangle(viewport, RGBA_Floats.Black); if (colorBuffer == null || colorBuffer.Length < viewport.Width || colorBuffer[0].Length < viewport.Height) { colorBuffer = new RGBA_Floats[viewport.Width][]; for (int i = 0; i < viewport.Width; i++) { colorBuffer[i] = new RGBA_Floats[viewport.Height]; } normalBuffer = new Vector3[viewport.Width][]; for (int i = 0; i < viewport.Width; i++) { normalBuffer[i] = new Vector3[viewport.Height]; } depthBuffer = new double[viewport.Width][]; for (int i = 0; i < viewport.Width; i++) { depthBuffer[i] = new double[viewport.Height]; } } #if MULTI_THREAD System.Threading.Tasks.Parallel.For(viewport.Bottom, viewport.Height, y => // #else for (int y = viewport.Bottom; y < viewport.Height; y++) #endif { for (int x = viewport.Left; x < viewport.Right; x++) { if (traceWithRayBundles) { int width = Math.Min(8, viewport.Right - x); int height = Math.Min(8, viewport.Top - y); FrustumRayBundle rayBundle = new FrustumRayBundle(width * height); IntersectInfo[] intersectionsForBundle = new IntersectInfo[width * height]; for (int rayY = 0; rayY < height; rayY++) { for (int rayX = 0; rayX < width; rayX++) { rayBundle.rayArray[rayX + rayY * width] = scene.camera.GetRay(x + rayX, y + rayY); intersectionsForBundle[rayX + rayY * width] = new IntersectInfo(); } } // get a ray to find the origin (every ray comes from the camera and should have the same origin) Ray screenRay = scene.camera.GetRay(0, 0); rayBundle.CalculateFrustum(width, height, screenRay.origin); FullyTraceRayBundle(rayBundle, intersectionsForBundle, scene); for (int rayY = 0; rayY < height; rayY++) { for (int rayX = 0; rayX < width; rayX++) { colorBuffer[x + rayX][y + rayY] = intersectionsForBundle[rayX + rayY * width].totalColor; } } x += width - 1; // skip all the pixels we bundled y += height - 1; // skip all the pixels we bundled } else { Ray ray = scene.camera.GetRay(x, y); IntersectInfo primaryInfo; colorBuffer[x][y] = FullyTraceRay(ray, scene, out primaryInfo); if (false) { if (primaryInfo != null) { normalBuffer[x][y] = primaryInfo.normalAtHit; depthBuffer[x][y] = primaryInfo.distanceToHit; } else { normalBuffer[x][y] = Vector3.UnitZ; depthBuffer[x][y] = double.PositiveInfinity; } } } } } #if MULTI_THREAD ); #endif if (AntiAliasing != AntiAliasing.None) { AntiAliasScene(viewport, scene, colorBuffer, (int)AntiAliasing); } }