Example #1
0
        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);
            }
        }
Example #2
0
        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();
        }
Example #3
0
        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;
                    }
                }
            }
Example #4
0
		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);
			}
		}