Beispiel #1
0
        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]);
        }
Beispiel #2
0
        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);
        }
Beispiel #3
0
        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);
        }
Beispiel #4
0
        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));
        }
Beispiel #5
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();
        }
Beispiel #6
0
        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);
        }
Beispiel #7
0
        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);
        }
Beispiel #8
0
        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);
        }
Beispiel #9
0
        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);
        }
Beispiel #10
0
        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);
        }
Beispiel #11
0
        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);
        }
Beispiel #12
0
        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);
        }
Beispiel #13
0
        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));
        }
Beispiel #14
0
        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);
        }
Beispiel #15
0
 public IntersectionInfo(Intersection intersection, Ray ray) : this(
         intersection, ray, Intersections.Create(intersection))
 {
 }