예제 #1
0
        private RecursiveRayTracer( SceneBase Scene, byte MaxDepth, byte CurrentDepth, float Epsilon, Random Rng,
                                    VisibilityTester VisibilityChecker, byte RussianRouletteDepth, float MaximumTerminationProbability )
            : base(Scene, Rng,
                    ( CurrentDepth == 0 || RussianRouletteDepth == 0 || CurrentDepth < RussianRouletteDepth ) ? 1.0f : 0.0f,
                    ( CurrentDepth == 0 || RussianRouletteDepth == 0 || CurrentDepth < RussianRouletteDepth ) ? 1.0f : MaximumTerminationProbability)
        {
            if ( Scene == null )
            {
                throw new ArgumentNullException( "Scene" );
            }

            if ( Rng == null )
            {
                throw new ArgumentNullException( "Rng" );
            }

            this.VisibilityTester = VisibilityChecker;
            this.Epsilon = Epsilon;
            this.ComputeEmissive = CurrentDepth == 0;

            if ( MaxDepth == 0 )
            {
                this.NextTracer = null;
            }
            else
            {
                this.NextTracer = new RecursiveRayTracer( Scene, (byte)( MaxDepth - 1 ), (byte)( CurrentDepth + 1 ), Epsilon, Rng,
                                                          VisibilityChecker, RussianRouletteDepth, MaximumTerminationProbability );
            }
        }
예제 #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
 protected RayTracerBase( SceneBase Scene, Random Rng, 
                          float MinimumTerminationProbability, float MaximumTerminationProbability )
 {
     this.Scene = Scene;
     this.Rng = Rng;
     this.MinimumTerminationProbability = Math.Max( Math.Min( 1.0f, MinimumTerminationProbability ), 0.0f );
     this.MaximumTerminationProbability = Math.Max( Math.Min( 1.0f, MaximumTerminationProbability ), 0.0f );
     this.DoRussianRouletteTermination = this.MinimumTerminationProbability != 1.0f && this.MaximumTerminationProbability != 1.0f;
 }
예제 #4
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 );
        }
예제 #5
0
        public IReadOnlyList<ObjectHit> Trace( SceneBase Scene, Ray WorldRay, bool SortHits )
        {
            if ( Scene == null )
            {
                throw new ArgumentNullException( "Scene" );
            }

            Scene.Trace( WorldRay, ShapeHits, GeometryHits, ObjectHits );

            if ( SortHits )
            {
                ObjectHits.Sort();
            }

            return ObjectHits;
        }
예제 #6
0
 public RecursiveRayTracer( SceneBase Scene, byte MaxDepth, float Epsilon, Random Rng, byte RussianRouletteDepth, float MaximumTerminationProbability )
     : this(Scene, MaxDepth, 0, Epsilon, Rng, new VisibilityTester( Scene, Epsilon ), RussianRouletteDepth, MaximumTerminationProbability)
 {
 }
예제 #7
0
 public RecursiveRayTracer( SceneBase Scene, byte MaxDepth, float Epsilon, Random Rng )
     : this(Scene, MaxDepth, Epsilon, Rng, (byte)0, 1.0f)
 {
 }
예제 #8
0
 public VisibilityTester( SceneBase Scene, float Epsilon )
 {
     this.Scene = Scene;
     this.Epsilon = Epsilon;
 }
예제 #9
0
            public ThreadLocalState( SceneBase Scene, RenderMethod Method, byte MaxDepth, float Epsilon, 
                                     byte RouletteDepth, float MaximumTerminationProbability )
            {
                this.Rng = new Random();

                switch ( Method )
                {
                    case RenderMethod.PathTrace:
                        this.RayTracer = new PathTracer( Scene, MaxDepth, Epsilon, Rng,
                                                         RouletteDepth, MaximumTerminationProbability );
                        break;
                    default: // RenderMethod.RecursiveRayTrace
                        this.RayTracer = new RecursiveRayTracer( Scene, MaxDepth, Epsilon, Rng,
                                                                 RouletteDepth, MaximumTerminationProbability );
                        break;
                }
            }
예제 #10
0
        public static void CreateScene( SceneBase Scene )
        {
            List<Triangle> ShortBox = new List<Triangle>();
            List<Triangle> WhiteWalls = new List<Triangle>();
            List<Triangle> TallBox = new List<Triangle>();
            List<Triangle> RedWall = new List<Triangle>();
            List<Triangle> BlueWall = new List<Triangle>();
            List<Triangle> Light = new List<Triangle>();

            WhiteWalls.AddRange( TriangleCreator.CreateQuad( 550.000000f, 0.000000f, 0.000000f,
                                                             0.000000f, 0.000000f, 0.000000f,
                                                             0.000000f, 0.000000f, 560.000000f,
                                                             550.000000f, 0.000000f, 560.000000f ) );

            WhiteWalls.AddRange( TriangleCreator.CreateQuad( 560.000000f, 550.000000f, 0.000000f,
                                                             560.000000f, 550.000000f, 560.000000f,
                                                             0.000000f, 550.000000f, 560.000000f,
                                                             0.000000f, 550.000000f, 0.000000f ) );

            WhiteWalls.AddRange( TriangleCreator.CreateQuad( 550.000000f, 0.000000f, 560.000000f,
                                                             0.000000f, 0.000000f, 560.000000f,
                                                             0.000000f, 550.000000f, 560.000000f,
                                                             560.000000f, 550.000000f, 560.000000f ) );

            BlueWall.AddRange( TriangleCreator.CreateQuad( 0.000000f, 0.000000f, 560.000000f,
                                                           0.000000f, 0.000000f, 0.000000f,
                                                           0.000000f, 550.000000f, 0.000000f,
                                                           0.000000f, 550.000000f, 560.000000f ) );

            RedWall.AddRange( TriangleCreator.CreateQuad( 550.000000f, 0.000000f, 0.000000f,
                                                          550.000000f, 0.000000f, 560.000000f,
                                                          560.000000f, 550.000000f, 560.000000f,
                                                          560.000000f, 550.000000f, 0.000000f ) );

            ShortBox.AddRange( TriangleCreator.CreateQuad( 130.000000f, 165.000000f, 65.000000f,
                                                           82.000000f, 165.000000f, 225.000000f,
                                                           240.000000f, 165.000000f, 272.000000f,
                                                           290.000000f, 165.000000f, 114.000000f ) );

            ShortBox.AddRange( TriangleCreator.CreateQuad( 290.000000f, 0.000000f, 114.000000f,
                                                           290.000000f, 165.000000f, 114.000000f,
                                                           240.000000f, 165.000000f, 272.000000f,
                                                           240.000000f, 0.000000f, 272.000000f ) );

            ShortBox.AddRange( TriangleCreator.CreateQuad( 130.000000f, 0.000000f, 65.000000f,
                                                           130.000000f, 165.000000f, 65.000000f,
                                                           290.000000f, 165.000000f, 114.000000f,
                                                           290.000000f, 0.000000f, 114.000000f ) );

            ShortBox.AddRange( TriangleCreator.CreateQuad( 82.000000f, 0.000000f, 225.000000f,
                                                           82.000000f, 165.000000f, 225.000000f,
                                                           130.000000f, 165.000000f, 65.000000f,
                                                           130.000000f, 0.000000f, 65.000000f ) );

            ShortBox.AddRange( TriangleCreator.CreateQuad( 240.000000f, 0.000000f, 272.000000f,
                                                           240.000000f, 165.000000f, 272.000000f,
                                                           82.000000f, 165.000000f, 225.000000f,
                                                           82.000000f, 0.000000f, 225.000000f ) );

            TallBox.AddRange( TriangleCreator.CreateQuad( 423.000000f, 330.000000f, 247.000000f,
                                                          265.000000f, 330.000000f, 296.000000f,
                                                          314.000000f, 330.000000f, 456.000000f,
                                                          472.000000f, 330.000000f, 406.000000f ) );

            TallBox.AddRange( TriangleCreator.CreateQuad( 423.000000f, 0.000000f, 247.000000f,
                                                          423.000000f, 330.000000f, 247.000000f,
                                                          472.000000f, 330.000000f, 406.000000f,
                                                          472.000000f, 0.000000f, 406.000000f ) );

            TallBox.AddRange( TriangleCreator.CreateQuad( 472.000000f, 0.000000f, 406.000000f,
                                                          472.000000f, 330.000000f, 406.000000f,
                                                          314.000000f, 330.000000f, 456.000000f,
                                                          314.000000f, 0.000000f, 456.000000f ) );

            TallBox.AddRange( TriangleCreator.CreateQuad( 314.000000f, 0.000000f, 456.000000f,
                                                          314.000000f, 330.000000f, 456.000000f,
                                                          265.000000f, 330.000000f, 296.000000f,
                                                          265.000000f, 0.000000f, 296.000000f ) );

            TallBox.AddRange( TriangleCreator.CreateQuad( 265.000000f, 0.000000f, 296.000000f,
                                                          265.000000f, 330.000000f, 296.000000f,
                                                          423.000000f, 330.000000f, 247.000000f,
                                                          423.000000f, 0.000000f, 247.000000f ) );

            Light.AddRange( TriangleCreator.CreateQuad( 303.000000f, 549.900000f, 247.000000f,
                                                        303.000000f, 549.900000f, 303.000000f,
                                                        247.000000f, 549.900000f, 303.000000f,
                                                        247.000000f, 549.900000f, 247.000000f ) );

            foreach ( Triangle T in Light )
            {
                ConstantEmissiveMaterial Emissive = new ConstantEmissiveMaterial( new Color3( 12.0f, 12.0f, 12.0f ) );

                Scene.Add( new SimpleObject( T, null, new EmissiveMaterialBase[] { Emissive, Emissive }, null, null, null ) );
            }

            foreach ( Triangle T in TallBox )
            {
                LambertianIndirectMaterial Indirect = new LambertianIndirectMaterial( new Color3( 0.75f, 0.75f, 0.75f ) );

                Scene.Add( new SimpleObject( T, T.CreateNormals(), null, null, new IndirectlyLitMaterialBase[] { Indirect, Indirect }, null ) );
            }

            foreach ( Triangle T in ShortBox )
            {
                LambertianIndirectMaterial Indirect = new LambertianIndirectMaterial( new Color3( 0.75f, 0.75f, 0.75f ) );

                Scene.Add( new SimpleObject( T, T.CreateNormals(), null, null, new IndirectlyLitMaterialBase[] { Indirect, Indirect }, null ) );
            }

            foreach ( Triangle T in BlueWall )
            {
                LambertianIndirectMaterial Indirect = new LambertianIndirectMaterial( new Color3( 0.25f, 0.25f, 0.75f ) );

                Scene.Add( new SimpleObject( T, T.CreateNormals(), null, null, new IndirectlyLitMaterialBase[] { Indirect, Indirect }, null ) );
            }

            foreach ( Triangle T in RedWall )
            {
                LambertianIndirectMaterial Indirect = new LambertianIndirectMaterial( new Color3( 0.75f, 0.25f, 0.25f ) );

                Scene.Add( new SimpleObject( T, T.CreateNormals(), null, null, new IndirectlyLitMaterialBase[] { Indirect, Indirect }, null ) );
            }

            foreach ( Triangle T in WhiteWalls )
            {
                LambertianIndirectMaterial Indirect = new LambertianIndirectMaterial( new Color3( 0.75f, 0.75f, 0.75f ) );

                Scene.Add( new SimpleObject( T, T.CreateNormals(), null, null, new IndirectlyLitMaterialBase[] { Indirect, Indirect }, null ) );
            }
        }