public void Precomputing_the_reflection_vector() { var shape = new Plane(); var ray = new Ray(new Point(0, 1, -1), new Vector(0, -Math.Sqrt(2) / 2, Math.Sqrt(2) / 2)); var hit = new Intersection(Math.Sqrt(2), shape); var state = IntersectionState.Create(hit, ray, new IntersectionList(hit)); state.Reflection.Should().Be(new Vector(0, Math.Sqrt(2) / 2, Math.Sqrt(2) / 2)); }
public void The_hit_should_be_preserved_when_calculating_the_intersection_state() { var hit = new Intersection(1, _triangle, 0.45, 0.25); var ray = new Ray(new Point(-0.2, 0.3, -2), Vector.UnitZ); var intersections = new IntersectionList(hit); var state = IntersectionState.Create(hit, ray, intersections); state.Normal.Should().Be(new Vector(-0.5547, 0.83205, 0)); }
public void Precomputing_the_hit_when_an_intersection_occurs_on_the_outside() { var ray = new Ray(new Point(0, 0, -5), new Vector(0, 0, 1)); var shape = new Sphere(); var hit = new Intersection(4, shape); var state = IntersectionState.Create(hit, ray, new IntersectionList(hit)); state.IsInside.Should().BeFalse(); }
public void Precomputing_the_hit_should_offset_the_point() { var ray = new Ray(new Point(0, 0, -5), Vector.UnitZ); var shape = new Sphere(transform: Matrix4x4.CreateTranslation(0, 0, 1)); var hit = new Intersection(5, shape); var state = IntersectionState.Create(hit, ray, new IntersectionList(hit)); state.OverPoint.Z.Should().BeLessThan(-NumberExtensions.Epsilon / 2); state.Point.Z.Should().BeGreaterThan(state.OverPoint.Z); }
public void ShadeHit_should_shade_an_intersection() { var world = World.CreateDefaultWorld(); var ray = new Ray(new Point(0, 0, -5), Vector.UnitZ); Shape shape = world.Shapes[0]; var intersection = new Intersection(4, shape); var state = IntersectionState.Create(intersection, ray, new IntersectionList(intersection)); Color color = world.ShadeHit(state); color.Should().Be(new Color(0.38066, 0.47583, 0.2855)); }
public void ShadeHit_should_shade_an_intersection_from_the_inside() { var world = World.CreateDefaultWorld().ChangeLights(new PointLight(new Point(0, 0.25, 0), Colors.White)); var ray = new Ray(new Point(0, 0, 0), Vector.UnitZ); Shape shape = world.Shapes[1]; var intersection = new Intersection(0.5, shape); var state = IntersectionState.Create(intersection, ray, new IntersectionList(intersection)); Color color = world.ShadeHit(state); color.Should().Be(new Color(0.90498, 0.90498, 0.90498)); }
public void RefractedColor_should_return_the_refracted_color_at_the_maximum_recursive_depth() { var world = World.CreateDefaultWorld(); var shape = world.Shapes[0].ChangeMaterial(m => m.WithTransparency(1.0).WithRefractiveIndex(1.5)); var ray = new Ray(new Point(0, 0, -5), Vector.UnitZ); var intersections = new IntersectionList((4, shape), (6, shape)); var state = IntersectionState.Create(intersections[0], ray, intersections); Color color = world.RefractedColor(state, 0); color.Should().Be(Colors.Black); }
public void RefractedColor_should_return_black_for_the_refracted_color_with_an_opaque_surface() { var world = World.CreateDefaultWorld(); var shape = world.Shapes[0]; var ray = new Ray(new Point(0, 0, -5), Vector.UnitZ); var intersections = new IntersectionList((4, shape), (6, shape)); var state = IntersectionState.Create(intersections[0], ray, intersections); Color color = world.RefractedColor(state, 5); color.Should().Be(Colors.Black); }
public void ReflectedColor_should_return_black_for_the_reflected_color_of_a_non_reflective_surface() { var world = World.CreateDefaultWorld(); var ray = new Ray(Point.Zero, Vector.UnitZ); var shape = world.Shapes[1].ChangeMaterial(m => m.WithAmbient(1)); var intersection = new Intersection(1, shape); var state = IntersectionState.Create(intersection, ray, new IntersectionList(intersection)); Color color = world.ReflectedColor(state); color.Should().Be(Colors.Black); }
public void Precomputing_the_state_of_an_intersection() { var ray = new Ray(new Point(0, 0, -5), new Vector(0, 0, 1)); var shape = new Sphere(); var hit = new Intersection(4, shape); var state = IntersectionState.Create(hit, ray, new IntersectionList(hit)); state.T.Should().Be(hit.T); state.Shape.Should().Be(hit.Shape); state.Point.Should().Be(new Point(0, 0, -1)); state.Eye.Should().Be(new Vector(0, 0, -1)); state.Normal.Should().Be(new Vector(0, 0, -1)); }
public void RefractedColor_should_return_the_refracted_color_with_a_refracted_ray() { var world = World.CreateDefaultWorld(); var a = world.Shapes[0].ChangeMaterial(m => m.WithAmbient(1).WithPattern(new PatternTests.TestPattern())); var b = world.Shapes[1].ChangeMaterial(m => m.WithTransparency(1).WithRefractiveIndex(1.5)); var ray = new Ray(new Point(0, 0, 0.1), Vector.UnitY); var intersections = new IntersectionList((-0.9899, a), (-0.4899, b), (0.4899, b), (0.9899, a)); var state = IntersectionState.Create(intersections[2], ray, intersections); Color color = world.RefractedColor(state, 5); color.Should().Be(new Color(0, 0.99887, 0.04722)); }
public void RefractedColor_should_return_black_for_the_refracted_color_under_total_internal_reflection() { var world = World.CreateDefaultWorld(); var shape = world.Shapes[0].ChangeMaterial(m => m.WithTransparency(1.0).WithRefractiveIndex(1.5)); var ray = new Ray(new Point(0, 0, Math.Sqrt(2) / 2), Vector.UnitY); var intersections = new IntersectionList((-Math.Sqrt(2) / 2, shape), (Math.Sqrt(2) / 2, shape)); // Note this time we're inside the sphere, so we need to look at intersections[1], not 0. var state = IntersectionState.Create(intersections[1], ray, intersections); Color color = world.RefractedColor(state, 5); color.Should().Be(Colors.Black); }
public void Precomputing_the_hit_when_an_intersection_occurs_on_the_inside() { var ray = new Ray(new Point(0, 0, 0), new Vector(0, 0, 1)); var shape = new Sphere(); var hit = new Intersection(1, shape); var state = IntersectionState.Create(hit, ray, new IntersectionList(hit)); state.Point.Should().Be(new Point(0, 0, 1)); state.Eye.Should().Be(new Vector(0, 0, -1)); state.IsInside.Should().BeTrue(); // Normal would have been (0, 0, 1) but is inverted! state.Normal.Should().Be(new Vector(0, 0, -1)); }
public void ShadeHit_should_calculate_the_reflected_color_for_a_reflective_material() { var world = World.CreateDefaultWorld(); var floor = new Plane("Floor", Matrix4x4.CreateTranslation(0, -1, 0), new Material(reflective: 0.5)); world = world.AddShapes(floor); var ray = new Ray(new Point(0, 0, -3), new Vector(0, -Math.Sqrt(2) / 2, Math.Sqrt(2) / 2)); var intersection = new Intersection(Math.Sqrt(2), floor); var state = IntersectionState.Create(intersection, ray, new IntersectionList(intersection)); var color = world.ShadeHit(state); color.Should().Be(new Color(0.87675, 0.92434, 0.82917)); }
public void ReflectedColor_should_only_allow_a_maximum_recursion_depth() { var world = World.CreateDefaultWorld(); var floor = new Plane("Floor", Matrix4x4.CreateTranslation(0, -1, 0), new Material(reflective: 0.5)); world = world.AddShapes(floor); var ray = new Ray(new Point(0, 0, -3), new Vector(0, -Math.Sqrt(2) / 2, Math.Sqrt(2) / 2)); var intersection = new Intersection(Math.Sqrt(2), floor); var state = IntersectionState.Create(intersection, ray, new IntersectionList(intersection)); Color color = world.ReflectedColor(state, 0); color.Should().Be(Colors.Black); }
public void ShadeHit_should_shade_an_intersection_in_shadow() { var sphere1 = new Sphere(); var sphere2 = new Sphere(transform: Matrix4x4.CreateTranslation(0, 0, 10)); var world = World.CreateDefaultWorld() .ChangeLights(new PointLight(new Point(0, 0, -10), Colors.White)) .AddShapes(sphere1, sphere2); var ray = new Ray(new Point(0, 0, 5), Vector.UnitZ); var intersection = new Intersection(4, sphere2); var state = IntersectionState.Create(intersection, ray, new IntersectionList(intersection)); Color color = world.ShadeHit(state); color.Should().Be(new Color(0.1, 0.1, 0.1)); }
public void ShadeHit_should_calculate_the_shade_color_with_a_reflective_and_transparent_material() { var floor = new Plane( "Floor", Matrix4x4.CreateTranslation(0, -1, 0), new Material(reflective: 0.5, transparency: 0.5, refractiveIndex: 1.5)); var ball = new Sphere( "Ball", Matrix4x4.CreateTranslation(0, -3.5, -0.5), new Material(Colors.Red, ambient: 0.5)); var world = World.CreateDefaultWorld().AddShapes(floor, ball); var ray = new Ray(new Point(0, 0, -3), new Vector(0, -Math.Sqrt(2) / 2, Math.Sqrt(2) / 2)); var intersections = new IntersectionList((Math.Sqrt(2), floor)); var state = IntersectionState.Create(intersections[0], ray, intersections); Color color = world.ShadeHit(state, 5); color.Should().Be(new Color(0.93391, 0.69643, 0.69243)); }