Пример #1
0
        public void TestInterpolatedEmissiveWorldTriangle()
        {
            Triangle triangle = new Triangle( new Point( 0.0f, 0.0f, 3.0f ),
                                              new Point( 1.0f, 0.0f, 3.0f ),
                                              new Point( 1.0f, 1.0f, 3.0f ) );

            BarycentricInterpolatedEmissiveMaterial I = new BarycentricInterpolatedEmissiveMaterial( new Color3( 1.0f, 0.0f, 0.0f ),
                                                                                                     new Color3( 0.0f, 1.0f, 0.0f ),
                                                                                                     new Color3( 0.0f, 0.0f, 1.0f ) );

            SimpleObject so = new SimpleObject( triangle, null, new EmissiveMaterialBase[] { I, I }, null, null, null );

            ListScene scene = new ListScene();
            scene.Add( so );

            Framebuffer fb = new Framebuffer( Color3.Black, 500, 500 );

            Cameras.Pinhole( scene, RenderMethod.RecursiveRayTrace,
                             fb, 0, 0.0001f, 0, 1.0f, true,
                             1.0f, 1.0f, 1.0f,
                             new Point( 0.0f, 0.0f, -2.0f ),
                             new Vector( 0.0f, 0.0f, 1.0f ),
                             new Vector( 0.0f, 1.0f, 0.0f ),
                             1, 1, false );

            Assert.IsTrue( Pfm.Compare( fb, 0.01f, 0.02f, "..\\..\\TestImages\\TestInterpolatedEmissiveWorldTriangle.pfm" ) );
        }
Пример #2
0
        private static void Render( CameraBase CameraState, SceneBase Scene, RenderMethod Method, byte MaxDepth, float Epsilon,
                                    byte RouletteDepth, float MaximumTerminationProbability, Framebuffer Fb, bool UseMultithreading )
        {
            if ( UseMultithreading )
            {
                Parallel.For<ThreadLocalState>( 0, Fb.Rows,
                                               () => new ThreadLocalState( Scene, Method, MaxDepth, Epsilon, RouletteDepth, MaximumTerminationProbability ),
                                               ( Y, Loop, State ) =>
                                               {
                                                   for ( int X = 0; X < Fb.Columns; X++ )
                                                   {
                                                       Fb[Y, X] = CameraState.RenderPixel( Fb.Columns, Fb.Rows, X, Y, State );
                                                   }

                                                   return State;
                                               }, ( State ) => { } );
            }
            else
            {
                ThreadLocalState State = new ThreadLocalState( Scene, Method, MaxDepth, Epsilon, RouletteDepth, MaximumTerminationProbability );

                for ( int Y = 0; Y < Fb.Rows; Y++ )
                {
                    for ( int X = 0; X < Fb.Columns; X++ )
                    {
                        Fb[Y, X] = CameraState.RenderPixel( Fb.Columns, Fb.Rows, X, Y, State );
                    }
                }
            }
        }
Пример #3
0
        public static void Pinhole( SceneBase Scene, RenderMethod Method, Framebuffer Fb, byte MaxDepth, float Epsilon,
                                    byte RouletteDepth, float MaximumTerminationProbability, bool UseMultithreading,
                                    float ImagePlaneDistance, float ImagePlaneHeight, float ImagePlaneWidth,
                                    Point PinholeLocation, Vector CameraDirection, Vector Up,
                                    UInt16 XSamplesPerPixel, UInt16 YSamplesPerPixel, bool Jitter )
        {
            PinholeCamera Camera = new PinholeCamera( ImagePlaneDistance, ImagePlaneHeight, ImagePlaneWidth,
                                                      PinholeLocation, CameraDirection, Up,
                                                      XSamplesPerPixel, YSamplesPerPixel, Jitter );

            Render( Camera, Scene, Method, MaxDepth, Epsilon, RouletteDepth, MaximumTerminationProbability, Fb, UseMultithreading );
        }
Пример #4
0
        public static void Write( Framebuffer fb, string s )
        {
            Bitmap bmp = new Bitmap( fb.Columns, fb.Rows );
            int yMax = fb.Columns - 1;

            for ( UInt16 y = 0; y < fb.Columns; y++ )
            {
                for ( UInt16 x = 0; x < fb.Rows; x++ )
                {
                    Color3 color = fb[x, y];

                    int red = (int)Math.Min( 255f, Math.Max( 0.0f, color.R * 255f ) );
                    int green = (int)Math.Min( 255f, Math.Max( 0.0f, color.G * 255f ) );
                    int blue = (int)Math.Min( 255f, Math.Max( 0.0f, color.B * 255f ) );

                    bmp.SetPixel( x, yMax - y, System.Drawing.Color.FromArgb( (int)255, red, green, blue ) );
                }
            }

            bmp.Save( s, ImageFormat.Png );
            bmp.Dispose();
        }
Пример #5
0
        public static void Write( Framebuffer fb, string s )
        {
            FileStream fileStream = new FileStream( s, FileMode.Create );

            int scale = ( !BitConverter.IsLittleEndian ) ? 1 : -1;

            string header = "PF\n" + fb.Columns.ToString() + "\n" + fb.Rows.ToString() + "\n" + scale.ToString() + "\n";
            byte[] headerBytes = Encoding.ASCII.GetBytes( header );

            try
            {
                fileStream.Write( headerBytes, 0, headerBytes.Length );

                for ( UInt16 y = 0; y < fb.Columns; y++ )
                {
                    for ( UInt16 x = 0; x < fb.Rows; x++ )
                    {
                        Color3 color = fb[fb.Columns - y - 1, x];

                        byte[] red = BitConverter.GetBytes( color.R );
                        byte[] green = BitConverter.GetBytes( color.G );
                        byte[] blue = BitConverter.GetBytes( color.B );

                        fileStream.Write( red, 0, 4 );
                        fileStream.Write( green, 0, 4 );
                        fileStream.Write( blue, 0, 4 );
                    }
                }
            }
            finally
            {
                fileStream.Close();
            }
        }
Пример #6
0
        public static bool Compare( Framebuffer fb, float componentTolerance, float incorrectTolerance, string s )
        {
            FileStream file = new FileStream( s, FileMode.Open );

            // Verify Header
            byte[] headerBytes = Encoding.ASCII.GetBytes( "PF\n" );

            foreach ( byte b in headerBytes )
            {
                if ( b != file.ReadByte() )
                {
                    throw new Exception("s is not a properly formed Portable Float Map");
                }
            }

            if ( fb.Columns != ReadNumber( file ) || fb.Rows != ReadNumber( file ) )
                return false;

            int endianness = ReadNumber( file );
            bool byteFlip = ( endianness > 0 && BitConverter.IsLittleEndian ) || ( endianness < 0 && !BitConverter.IsLittleEndian );

            byte[] redBytes = new byte[4];
            byte[] greenBytes = new byte[4];
            byte[] blueBytes = new byte[4];

            UInt32 incorrectCount = 0;

            try
            {
                for ( int i = 0; i < fb.Columns; i++ )
                {
                    for ( int j = 0; j < fb.Rows; j++ )
                    {
                        Color3 color = fb[fb.Columns - i - 1, j];

                        file.Read( redBytes, 0, 4 );
                        file.Read( greenBytes, 0, 4 );
                        file.Read( blueBytes, 0, 4 );

                        if ( byteFlip )
                        {
                            Array.Reverse( redBytes );
                            Array.Reverse( greenBytes );
                            Array.Reverse( blueBytes );
                        }

                        float red = BitConverter.ToSingle( redBytes, 0 );
                        if ( Math.Abs( red - color.R ) > componentTolerance )
                            incorrectCount++;

                        float green = BitConverter.ToSingle( greenBytes, 0 );
                        if ( Math.Abs( green - color.G ) > componentTolerance )
                            incorrectCount++;

                        float blue = BitConverter.ToSingle( blueBytes, 0 );
                        if ( Math.Abs( blue - color.B ) > componentTolerance )
                            incorrectCount++;
                    }
                }
            }
            catch ( Exception )
            {
                throw new Exception( "s is not a properly formed Portable Float Map" );
            }
            finally
            {
                file.Close();
            }

            return incorrectCount < (float)(fb.Columns * fb.Rows) * incorrectTolerance;
        }
Пример #7
0
        public void TestMirrorPhongCheckerboardSpheres()
        {
            // Create Shapes
            Sphere s1 = new Sphere( new Point( 0.0f, 1.0f, 0.0f ), 1.0f );
            Sphere s2 = new Sphere( new Point( -1.0f, 0.5f, 1.5f ), 0.5f );
            InfinitePlane p1 = new InfinitePlane( new Point( 0.0f, 0.0f, 0.0f ), new Vector( 0.0f, 1.0f, 0.0f ) );

            // Create Lights
            List<PhongLight> Lights = new List<PhongLight>();

            Lights.Add( new PointPhongLight( new Point( -2.0f, 2.5f, 0.0f ),
                                             Color3.Black,
                                             new Color3( 0.49f, 0.07f, 0.07f ),
                                             new Color3( 0.49f, 0.07f, 0.07f ) ) );

            Lights.Add( new PointPhongLight( new Point( 1.5f, 2.5f, 1.5f ),
                                             Color3.Black,
                                             new Color3( 0.07f, 0.07f, 0.49f ),
                                             new Color3( 0.07f, 0.07f, 0.49f ) ) );

            Lights.Add( new PointPhongLight( new Point( 1.5f, 2.5f, -1.5f ),
                                             Color3.Black,
                                             new Color3( 0.07f, 0.49f, 0.07f ),
                                             new Color3( 0.07f, 0.49f, 0.07f ) ) );

            Lights.Add( new PointPhongLight( new Point( 0.0f, 3.5f, 0.0f ),
                                             Color3.Black,
                                             new Color3( 0.21f, 0.21f, 0.35f ),
                                             new Color3( 0.21f, 0.21f, 0.35f ) ) );

            // Create Materials
            CheckerboardPhongDirectMaterial checkerboardDirect = new CheckerboardPhongDirectMaterial( Color3.Black, Color3.Black, Color3.White, 150.0f,
                                                                                                      Color3.Black, Color3.White, Color3.White, 150.0f,
                                                                                                      Lights );

            CheckerboardSpecularIndirectMaterial checkerboardIndirect = new CheckerboardSpecularIndirectMaterial( new Color3( 0.1f, 0.1f, 0.1f ),
                                                                                                                  new Color3( 0.7f, 0.7f, 0.7f ) );

            PhongDirectMaterial sphereDirect = new PhongDirectMaterial( Color3.Black, Color3.White, new Color3( 0.5f, 0.5f, 0.5f ), 50.0f, Lights );

            PerfectSpecularIndirectMaterial sphereIndirect = new PerfectSpecularIndirectMaterial( new Color3( 0.6f, 0.6f, 0.6f ) );

            // Create Objects
            SimpleObject so1 = new SimpleObject( s1, s1.CreateNormals(), null, new DirectlyLitMaterialBase[] { sphereDirect, sphereDirect }, new IndirectlyLitMaterialBase[] { sphereIndirect, sphereIndirect }, null );
            SimpleObject so2 = new SimpleObject( s2, s2.CreateNormals(), null, new DirectlyLitMaterialBase[] { sphereDirect, sphereDirect }, new IndirectlyLitMaterialBase[] { sphereIndirect, sphereIndirect }, null );
            SimpleObject so3 = new SimpleObject( p1, p1.CreateNormals(), null, new DirectlyLitMaterialBase[] { checkerboardDirect, checkerboardDirect }, new IndirectlyLitMaterialBase[] { checkerboardIndirect, checkerboardIndirect }, null );

            // Create Scene
            ListScene scene = new ListScene();
            scene.Add( so1 );
            scene.Add( so2 );
            scene.Add( so3 );

            // Trace
            Framebuffer fb = new Framebuffer( Color3.Black, 500, 500 );

            Point LensLocation = new Point( 3.0f, 2.0f, 4.0f );
            Point LookAt = new Point( -1.0f, 0.45f, 0.0f );

            Cameras.Pinhole( scene, RenderMethod.RecursiveRayTrace,
                             fb, 5, 0.0001f, 0, 1.0f, true,
                             1.3f, 1.0f, 1.0f,
                             LensLocation,
                             LookAt - LensLocation,
                             new Vector( 0.0f, 1.0f, 0.0f ),
                             1, 1, false );

            Assert.IsTrue( Pfm.Compare( fb, 0.1f, 0.02f, "..\\..\\TestImages\\TestMirrorPhongCheckerboardSpheres.pfm" ) );
        }
Пример #8
0
        public void TestRedEmissiveWorldSphere()
        {
            Sphere sphere = new Sphere( new Point( 0.0f, 0.0f, 3.0f ), 1.0f );
            ConstantEmissiveMaterial s = new ConstantEmissiveMaterial( new Color3( 1.0f, 0.0f, 0.0f ) );

            SimpleObject so = new SimpleObject( sphere, null, new EmissiveMaterialBase[] { s, s }, null, null, null );

            ListScene scene = new ListScene();
            scene.Add( so );

            Framebuffer fb = new Framebuffer( Color3.Black, 500, 500 );

            Cameras.Pinhole( scene, RenderMethod.RecursiveRayTrace,
                             fb, 0, 0.0001f, 0, 1.0f, true,
                             1.0f, 1.0f, 1.0f,
                             new Point( 0.0f, 0.0f, -2.0f ),
                             new Vector( 0.0f, 0.0f, 1.0f ),
                             new Vector( 0.0f, 1.0f, 0.0f ),
                             1, 1, false );

            Assert.IsTrue( Pfm.Compare( fb, 0.01f, 0.02f, "..\\..\\TestImages\\TestRedEmissiveWorldSphere.pfm" ) );
        }
Пример #9
0
        public void TestPhongSphere()
        {
            Color3 a = new Color3( 0.0f, 0.0f, 0.0f );
            Color3 ds = new Color3( 1.0f, 1.0f, 1.0f );
            Vector dir = new Vector( 0.0f, 0.0f, -1.0f );

            Color3 am = new Color3( 0.2f, 0.2f, 0.2f );
            Color3 dsm = new Color3( 0.8f, 0.8f, 0.8f );

            Point center = new Point( 0.0f, 0.0f, 3.3f );

            Sphere sphere = new Sphere( center, 1.0f );

            PhongDirectMaterial mat = new PhongDirectMaterial( am, dsm, Color3.Black, 0.0f, new PhongLight[] { new DirectionalPhongLight( dir, a, ds, ds, false ) } );

            SimpleObject so = new SimpleObject( sphere, sphere.CreateNormals(), null, new DirectlyLitMaterialBase[] { mat, mat }, null, null );

            ListScene scene = new ListScene();
            scene.Add( so );

            Framebuffer fb = new Framebuffer( Color3.Black, 500, 500 );

            Cameras.Pinhole( scene, RenderMethod.RecursiveRayTrace,
                             fb, 0, 0.0001f, 0, 1.0f, true,
                             1.0f, 1.0f, 1.0f,
                             new Point( 0.0f, 0.0f, -2.0f ),
                             new Vector( 0.0f, 0.0f, 1.0f ),
                             new Vector( 0.0f, 1.0f, 0.0f ),
                             1, 1, false );

            Assert.IsTrue( Pfm.Compare( fb, 0.01f, 0.02f, "..\\..\\TestImages\\TestPhongSphere.pfm" ) );
        }
Пример #10
0
        public void TestPathTracedCornellBox()
        {
            ListScene scene = new ListScene();

            CornellBox.CreateScene( scene );

            Framebuffer Fb = new Framebuffer( Color3.Black, 500, 500 );

            Point CameraPosition = new Point( 278.0f, 273.0f, -500.0f );
            Vector CameraDirection = new Vector( 0.0f, 0.0f, 1.0f );
            Vector Up = new Vector( 0f, 1f, 0f );

            Cameras.Pinhole( scene, RenderMethod.PathTrace,
                             Fb, 10, 0.0001f, 5, 0.5f, true,
                             500f, 546f, 546f,
                             new Point( 278.0f, 273.0f, -500.0f ),
                             new Vector( 0.0f, 0.0f, 1.0f ),
                             new Vector( 0f, 1f, 0f ),
                             3, 3, false );

            Pfm.Write( Fb, "TestPathTracedCornellBox.pfm" );
        }
Пример #11
0
        public void TestMirrorPhongSphere()
        {
            Sphere s1 = new Sphere( new Point( 1.0f, 0.0f, 3.0f ), 1.0f );
            Sphere s2 = new Sphere( new Point( -1.0f, 0.0f, 3.0f ), 1.0f );

            ConstantEmissiveMaterial es = new ConstantEmissiveMaterial( new Color3( 1.0f, 0.0f, 0.0f ) );
            IndirectlyLitMaterialBase Mirror = new PerfectSpecularIndirectMaterial( Color3.White );

            EmissiveMaterialBase[] array1 = new EmissiveMaterialBase[] { es, null };
            IndirectlyLitMaterialBase[] array2 = new IndirectlyLitMaterialBase[] { Mirror, null };

            SimpleObject so1 = new SimpleObject( s1, null, array1, null, null, null );
            SimpleObject so2 = new SimpleObject( s2, s2.CreateNormals(), null, null, array2, null );

            ListScene scene = new ListScene();
            scene.Add( so1 );
            scene.Add( so2 );

            Framebuffer fb = new Framebuffer( Color3.Black, 500, 500 );

            Cameras.Pinhole( scene, RenderMethod.RecursiveRayTrace,
                             fb, 1, 0.0001f, 0, 1.0f, true,
                             1.0f, 1.0f, 1.0f,
                             new Point( 0.0f, 0.0f, -2.0f ),
                             new Vector( 0.0f, 0.0f, 1.0f ),
                             new Vector( 0.0f, 1.0f, 0.0f ),
                             1, 1, false );

            Assert.IsTrue( Pfm.Compare( fb, 0.01f, 0.02f, "..\\..\\TestImages\\TestMirrorPhongSphere.pfm" ) );
        }