Example #1
0
		public static void Start()
		#endif
		{
			// create objects
			var scene = new Scene();
			scene.Objects = new Sphere[]
			{
				new Sphere(new Vec3(0.0f, -10002.0f, -20.0f), 10000, new Vec3(.8f, .8f, .8f)),
				new Sphere(new Vec3(0.0f, 2.0f, -20.0f), 4, new Vec3(.8f, .5f, .5f), 0.5f),
				new Sphere(new Vec3(5.0f, 0.0f, -15.0f), 2, new Vec3(.3f, .8f, .8f), 0.2f),
				new Sphere(new Vec3(-5.0f, 0.0f, -15.0f), 2, new Vec3(.3f, .5f, .8f), 0.2f),
				new Sphere(new Vec3(-2.0f, -1.0f, -10.0f), 1, new Vec3(.1f, .1f, .1f), 0.1f, 0.8f)
			};

			scene.Lights = new Light[]{new Light(new Vec3(-10, 20, 30), new Vec3(2, 2, 2))};
			
			int pixelsLength = Benchmark.Width * Benchmark.Height * 3;
			byte[] pixels = new byte[pixelsLength];

			// give the system a little time
			#if !JSIL
			GC.Collect();
			Console.WriteLine("Give the system a little time...");
			Thread.Sleep(2000);
			#endif
			Console.WriteLine("Starting test...");

			// run test
			#if WIN32
			Win32OptimizedStopwatch();
			#endif

			var watch = new Stopwatch();
			watch.Start();
			var data = Benchmark.Render(scene, pixels);
			watch.Stop();
			Console.WriteLine("Sec: " + (watch.ElapsedMilliseconds / 1000d));

			#if WIN32
			Win32EndOptimizedStopwatch();
			#endif

			// save image
			#if WIN8 || WP8 || WP7 || ANDROID || IOS || VITA
			if (SaveImageCallback != null) SaveImageCallback(data);
			#elif !JSIL
			Console.ReadLine();
			using (var file = new FileStream("Image.raw", FileMode.Create, FileAccess.Write))
			using (var writer = new BinaryWriter(file))
			{
				for (int i = 0; i != pixelsLength; ++i)
				{
					file.WriteByte(data[i]);
				}
			}
			#else
			return pixels;
			#endif
		}
Example #2
0
		public static byte[] Render(Scene scene, byte[] pixels)
		{
			var eye = Vec3.Zero;
			Num h = (Num)Math.Tan(((fov / 360) * (2 * PI)) / 2) * 2;
			Num w = h * Width / Height;

			for (int y = 0; y != Height; ++y)
			{
				for (int x = 0; x != Width; ++x)
				{
					Num xx = x, yy = y, ww = Width, hh = Height;
					Vec3 dir;
					dir.X = ((xx - (ww / 2.0f)) / ww)  * w;
					dir.Y = (((hh/2.0f) - yy) / hh) * h;
					dir.Z = -1.0f;
					dir = Vec3.Normalize(dir);

					Ray r;
					r.Org = eye;
					r.Dir = dir;
					var pixel = trace(r, scene, 0);
					int i = (x*3) + (y*Width*3);
					pixels[i] = (byte)Math.Min(pixel.X * 255, 255);
					pixels[i+1] = (byte)Math.Min(pixel.Y * 255, 255);
					pixels[i+2] = (byte)Math.Min(pixel.Z * 255, 255);
				}
			}

			return pixels;
		}
Example #3
0
        public static void Start()
                #endif
        {
            // create objects
            var scene = new Scene();

            scene.Objects = new Sphere[]
            {
                new Sphere(new Vec3(0.0f, -10002.0f, -20.0f), 10000, new Vec3(.8f, .8f, .8f)),
                new Sphere(new Vec3(0.0f, 2.0f, -20.0f), 4, new Vec3(.8f, .5f, .5f), 0.5f),
                new Sphere(new Vec3(5.0f, 0.0f, -15.0f), 2, new Vec3(.3f, .8f, .8f), 0.2f),
                new Sphere(new Vec3(-5.0f, 0.0f, -15.0f), 2, new Vec3(.3f, .5f, .8f), 0.2f),
                new Sphere(new Vec3(-2.0f, -1.0f, -10.0f), 1, new Vec3(.1f, .1f, .1f), 0.1f, 0.8f)
            };

            scene.Lights = new Light[] { new Light(new Vec3(-10, 20, 30), new Vec3(2, 2, 2)) };

            int pixelsLength = Benchmark.Width * Benchmark.Height * 3;

            byte[] pixels = new byte[pixelsLength];

            // give the system a little time
                        #if !JSIL
            GC.Collect();
            Console.WriteLine("Give the system a little time...");
            Thread.Sleep(2000);
                        #endif
            Console.WriteLine("Starting test...");

            // run test
                        #if WIN32
            Win32OptimizedStopwatch();
                        #endif

            var watch = new Stopwatch();
            watch.Start();
            var data = Benchmark.Render(scene, pixels);
            watch.Stop();
            Console.WriteLine("Sec: " + (watch.ElapsedMilliseconds / 1000d));

                        #if WIN32
            Win32EndOptimizedStopwatch();
                        #endif

            // save image
                        #if UWP || WIN8 || WP8 || WP7 || ANDROID || IOS || VITA
            if (SaveImageCallback != null)
            {
                SaveImageCallback(data);
            }
                        #elif !JSIL
            Console.ReadLine();
            using (var file = new FileStream("Image.raw", FileMode.Create, FileAccess.Write))
                using (var writer = new BinaryWriter(file))
                {
                    for (int i = 0; i != pixelsLength; ++i)
                    {
                        file.WriteByte(data[i]);
                    }
                }
                        #else
            return(pixels);
                        #endif
        }
Example #4
0
		private static Vec3 trace (Ray ray, Scene scene, int depth)
		{
			var nearest = Num.MaxValue;
			Sphere obj = null;

			// search the scene for nearest intersection
			foreach(var o in scene.Objects)
			{
				var distance = Num.MaxValue;
				if (Sphere.Intersect(o, ray, out distance))
				{
					if (distance < nearest)
					{
						nearest = distance;
						obj = o;
					}
				}
			}

			if (obj == null) return Vec3.Zero;

			var point_of_hit = ray.Org + (ray.Dir * nearest);
			var normal = Sphere.Normal(obj, point_of_hit);
			bool inside = false;

			if (Vec3.Dot(normal, ray.Dir) > 0)
			{
				inside = true;
				normal = -normal;
			}

			Vec3 color = Vec3.Zero;
			var reflection_ratio = obj.Reflection;

			foreach(var l in scene.Lights)
			{
				var light_direction = Vec3.Normalize(l.Position - point_of_hit);
				Ray r;
				r.Org = point_of_hit + (normal * 1e-5f);
				r.Dir = light_direction;

				// go through the scene check whether we're blocked from the lights
				bool blocked = false;
				foreach (var o in scene.Objects)
				{
					if (Sphere.Intersect(o, r))
					{
						blocked = true;
						break;
					}
				}

				if (!blocked)
				{
					color += l.Color
						* Math.Max(0, Vec3.Dot(normal, light_direction))
						* obj.Color
						* (1.0f - reflection_ratio);
				}
			}

			var rayNormDot = Vec3.Dot(ray.Dir, normal);
			Num facing = Math.Max(0, -rayNormDot);
			Num fresneleffect = reflection_ratio + ((1 - reflection_ratio) * (Num)Math.Pow((1 - facing), 5));

			// compute reflection
			if (depth < maxDepth && reflection_ratio > 0)
			{
				var reflection_direction = ray.Dir + (normal * 2 * rayNormDot * (-1.0f));
				Ray r;
				r.Org = point_of_hit + (normal * 1e-5f);
				r.Dir = reflection_direction;
				var reflection = trace(r, scene, depth + 1);
				color += reflection * fresneleffect;
			}

			// compute refraction
			if (depth < maxDepth && (obj.Transparency > 0))
			{
				var ior = 1.5f;
				var CE = Vec3.Dot(ray.Dir, normal) * (-1.0f);
				ior = inside ? (1.0f) / ior : ior;
				var eta = (1.0f) / ior;
				var GF = (ray.Dir + normal * CE) * eta;
				var sin_t1_2 = 1 - (CE * CE);
				var sin_t2_2 = sin_t1_2 * (eta * eta);
				if (sin_t2_2 < 1)
				{
					var GC = normal * (Num)Math.Sqrt(1 - sin_t2_2);
					var refraction_direction = GF - GC;
					Ray r;
					r.Org = point_of_hit - (normal * 1e-4f);
					r.Dir = refraction_direction;
					var refraction = trace(r, scene, depth + 1);
					color += refraction * (1 - fresneleffect) * obj.Transparency;
				}
			}
			return color;
		}
Example #5
0
        private static Vec3 trace(Ray ray, Scene scene, int depth)
        {
            var    nearest = Num.MaxValue;
            Sphere obj     = null;

            // search the scene for nearest intersection
            foreach (var o in scene.Objects)
            {
                var distance = Num.MaxValue;
                if (Sphere.Intersect(o, ray, out distance))
                {
                    if (distance < nearest)
                    {
                        nearest = distance;
                        obj     = o;
                    }
                }
            }

            if (obj == null)
            {
                return(Vec3.Zero);
            }

            var  point_of_hit = ray.Org + (ray.Dir * nearest);
            var  normal       = Sphere.Normal(obj, point_of_hit);
            bool inside       = false;

            if (Vec3.Dot(normal, ray.Dir) > 0)
            {
                inside = true;
                normal = -normal;
            }

            Vec3 color            = Vec3.Zero;
            var  reflection_ratio = obj.Reflection;

            foreach (var l in scene.Lights)
            {
                var light_direction = Vec3.Normalize(l.Position - point_of_hit);
                Ray r;
                r.Org = point_of_hit + (normal * 1e-5f);
                r.Dir = light_direction;

                // go through the scene check whether we're blocked from the lights
                bool blocked = false;
                foreach (var o in scene.Objects)
                {
                    if (Sphere.Intersect(o, r))
                    {
                        blocked = true;
                        break;
                    }
                }

                if (!blocked)
                {
                    color += l.Color
                             * Math.Max(0, Vec3.Dot(normal, light_direction))
                             * obj.Color
                             * (1.0f - reflection_ratio);
                }
            }

            var rayNormDot    = Vec3.Dot(ray.Dir, normal);
            Num facing        = Math.Max(0, -rayNormDot);
            Num fresneleffect = reflection_ratio + ((1 - reflection_ratio) * (Num)Math.Pow((1 - facing), 5));

            // compute reflection
            if (depth < maxDepth && reflection_ratio > 0)
            {
                var reflection_direction = ray.Dir + (normal * 2 * rayNormDot * (-1.0f));
                Ray r;
                r.Org = point_of_hit + (normal * 1e-5f);
                r.Dir = reflection_direction;
                var reflection = trace(r, scene, depth + 1);
                color += reflection * fresneleffect;
            }

            // compute refraction
            if (depth < maxDepth && (obj.Transparency > 0))
            {
                var ior = 1.5f;
                var CE  = Vec3.Dot(ray.Dir, normal) * (-1.0f);
                ior = inside ? (1.0f) / ior : ior;
                var eta      = (1.0f) / ior;
                var GF       = (ray.Dir + normal * CE) * eta;
                var sin_t1_2 = 1 - (CE * CE);
                var sin_t2_2 = sin_t1_2 * (eta * eta);
                if (sin_t2_2 < 1)
                {
                    var GC = normal * (Num)Math.Sqrt(1 - sin_t2_2);
                    var refraction_direction = GF - GC;
                    Ray r;
                    r.Org = point_of_hit - (normal * 1e-4f);
                    r.Dir = refraction_direction;
                    var refraction = trace(r, scene, depth + 1);
                    color += refraction * (1 - fresneleffect) * obj.Transparency;
                }
            }
            return(color);
        }