public void FiltersIntersections() { var s1 = new Sphere(); var s2 = new Cube(); var xs = Intersections.Create(new Intersection(1, s1), new Intersection(2, s2), new Intersection(3, s1), new Intersection(4, s2)); var c = new ConstructiveSolid(ConstructiveOp.Union, s1, s2); var result = c.FilterIntersections(xs); result.Count.Should().Be(2); result[0].Should().Be(xs[0]); result[1].Should().Be(xs[3]); c = new ConstructiveSolid(ConstructiveOp.Intersection, s1, s2); result = c.FilterIntersections(xs); result.Count.Should().Be(2); result[0].Should().Be(xs[1]); result[1].Should().Be(xs[2]); c = new ConstructiveSolid(ConstructiveOp.Difference, s1, s2); result = c.FilterIntersections(xs); result.Count.Should().Be(2); result[0].Should().Be(xs[0]); result[1].Should().Be(xs[1]); }
public void ReflectanceIsSignificantAtSmallViewAngles() { var s = Spheres.GlassSphere(); var r = new Ray(new Point(0, 0.99f, -2f), new Vector(0, 0, 1)); var xs = Intersections.Create(new Intersection(1.8589f, s)); var comps = new IntersectionInfo(xs[0], r, xs); var reflectance = PhongShading.Schlick(comps); reflectance.Should().BeApproximately(0.48873f, 0.0001f); }
public void RefractedColorOfOpaqueSurfaceIsBlack() { var w = World.Default(); var s = w.Objects[0]; var r = new Ray(new Point(0, 0, -5), new Vector(0, 0, 1)); var xs = Intersections.Create(new Intersection(4f, s), new Intersection(6f, s)); var comps = new IntersectionInfo(xs[0], r, xs); PhongShading.RefractedColor(w, comps, 5).Should().Be(Colors.Black); }
public void InterpolatesNormalsForIntersections() { var tri = DefaultTriangle(); var i = new Intersection(1, tri, 0.45f, 0.25f); var r = new Ray(new Point(-0.2f, 0.3f, -2), new Vector(0, 0, 1)); var xs = Intersections.Create(i); var comps = new IntersectionInfo(i, r, xs); comps.Normal.Should().Be(new Normal(-0.5547f, 0.83205f, 0)); }
public void HitNoneOnAllNegativeIntersections() { var s = new Sphere(); var i1 = new Intersection(-2f, s); var i2 = new Intersection(-1f, s); var xs = Intersections.Create(i1, i2); var hit = xs.Hit(); hit.HasValue.Should().BeFalse(); }
public void HitOnlyPositiveIntersection() { var s = new Sphere(); var i1 = new Intersection(-1f, s); var i2 = new Intersection(1f, s); var xs = Intersections.Create(i1, i2); var hit = xs.Hit(); hit?.Should().Be(i2); }
public void ReflectanceIsSmallAtPerpendicularViewAngles() { var s = Spheres.GlassSphere(); var r = new Ray(new Point(0, 0, 0), new Vector(0, 1, 0)); var xs = Intersections.Create(new Intersection(-1f, s), new Intersection(1f, s)); var comps = new IntersectionInfo(xs[1], r, xs); var reflectance = PhongShading.Schlick(comps); reflectance.Should().BeApproximately(0.04f, 0.0001f); }
public void SchlickApproximationForTotalInternalReflectionIsOne() { var s = Spheres.GlassSphere(); var r = new Ray(new Point(0, 0, MathF.Sqrt(2f) / 2f), new Vector(0, 1, 0)); var xs = Intersections.Create(new Intersection(-MathF.Sqrt(2f) / 2f, s), new Intersection(MathF.Sqrt(2f) / 2f, s)); var comps = new IntersectionInfo(xs[1], r, xs); var reflectance = PhongShading.Schlick(comps); reflectance.Should().Be(1f); }
public void SortsIntersectionsByT() { var s = new Sphere(); var i1 = new Intersection(5f, s); var i2 = new Intersection(7f, s); var i3 = new Intersection(-3f, s); var i4 = new Intersection(2f, s); var xs = Intersections.Create(i1, i2, i3, i4); var hit = xs.Hit(); hit?.Should().Be(i4); }
public void RefractedColorIsBlackIfRemainingBouncesIsZero() { var w = World.Default(); var s = w.Objects[0]; s.Material.Transparency = 1.0f; s.Material.RefractiveIndex = 1.5f; var r = new Ray(new Point(0, 0, -5), new Vector(0, 0, 1)); var xs = Intersections.Create(new Intersection(4f, s), new Intersection(6f, s)); var comps = new IntersectionInfo(xs[0], r, xs); PhongShading.RefractedColor(w, comps, 0).Should().Be(Colors.Black); }
public void RefractedColorIsBlackForTotalInternalRefraction() { var w = World.Default(); var s = w.Objects[0]; s.Material.Transparency = 1.0f; s.Material.RefractiveIndex = 1.5f; var r = new Ray(new Point(0, 0, MathF.Sqrt(2f) / 2f), new Vector(0, 1, 0)); var xs = Intersections.Create( new Intersection(-MathF.Sqrt(2f) / 2f, s), new Intersection(MathF.Sqrt(2f) / 2f, s)); // Inside sphere so look at second intersection. var comps = new IntersectionInfo(xs[1], r, xs); PhongShading.RefractedColor(w, comps, 5).Should().Be(Colors.Black); }
public void DeterminesN1AndN2() { var a = Spheres.GlassSphere(); a.SetTransform(Transform.Scale(2f)); a.Material.RefractiveIndex = 1.5f; var b = Spheres.GlassSphere(); b.SetTransform(Transform.TranslateZ(-0.25f)); b.Material.RefractiveIndex = 2.0f; var c = Spheres.GlassSphere(); c.SetTransform(Transform.TranslateZ(0.25f)); c.Material.RefractiveIndex = 2.5f; var r = new Ray(new Point(0, 0, -4), new Vector(0, 0, 1)); var xs = Intersections.Create( new Intersection(2.00f, a), new Intersection(2.75f, b), new Intersection(3.25f, c), new Intersection(4.75f, b), new Intersection(5.25f, c), new Intersection(6.00f, a) ); var comps = new List <IntersectionInfo>(); for (var i = 0; i < xs.Count; i++) { comps.Add(new IntersectionInfo(xs[i], r, xs)); } comps[0].N1.Should().Be(1.0f); comps[0].N2.Should().Be(1.5f); comps[1].N1.Should().Be(1.5f); comps[1].N2.Should().Be(2.0f); comps[2].N1.Should().Be(2.0f); comps[2].N2.Should().Be(2.5f); comps[3].N1.Should().Be(2.5f); comps[3].N2.Should().Be(2.5f); comps[4].N1.Should().Be(2.5f); comps[4].N2.Should().Be(1.5f); comps[5].N1.Should().Be(1.5f); comps[5].N2.Should().Be(1.0f); }
public void HitColorIncludesFresnelEffectOnReflectiveTransparentSurface() { var w = World.Default(); var floor = new Plane { Material = { Transparency = 0.5f, Reflective = 0.5f, RefractiveIndex = 1.5f } }; floor.SetTransform(Transform.Translate(0, -1, 0)); w.AddObject(floor); var ball = new Sphere { Material = { Texture = new SolidColor(new Color(1, 0, 0)), Ambient = 0.5f } }; ball.SetTransform(Transform.Translate(0, -3.5f, -0.5f)); w.AddObject(ball); var r = new Ray(new Point(0, 0, -3), new Vector(0, -MathF.Sqrt(2f) / 2f, MathF.Sqrt(2f) / 2f)); var i = new Intersection(MathF.Sqrt(2f), floor); var xs = Intersections.Create(i); var comps = new IntersectionInfo(xs[0], r, xs); PhongShading.HitColor(w, comps, 5).Should().Be(new Color(0.93391f, 0.69643f, 0.69243f)); }
public void RefractsRayWhenHitsTransparentSurface() { var w = World.Default(); var a = w.Objects[0]; a.Material.Ambient = 1.0f; a.Material.Texture = new TestTexture(); var b = w.Objects[1]; b.Material.Transparency = 1.0f; b.Material.RefractiveIndex = 1.5f; var r = new Ray(new Point(0, 0, 0.1f), new Vector(0, 1, 0)); var xs = Intersections.Create( new Intersection(-0.9899f, a), new Intersection(-0.4899f, b), new Intersection(0.4899f, b), new Intersection(0.9899f, a)); var comps = new IntersectionInfo(xs[2], r, xs); var c = PhongShading.RefractedColor(w, comps, 5); c.Red.Should().BeApproximately(0f, 0.001f); c.Green.Should().BeApproximately(0.99888f, 0.001f); c.Blue.Should().BeApproximately(0.04725f, 0.001f); }
public IntersectionInfo(Intersection intersection, Ray ray) : this( intersection, ray, Intersections.Create(intersection)) { }