Ejemplo n.º 1
0
        private SampledSpectrum SampleLights(Scene scene, BSDF bsdf, ref Intersection intersection,
                                             ref Vector3 leaving)
        {
            var lights   = scene.Lights;
            var spectrum = SampledSpectrum.Black();

            foreach (var light in lights)
            {
                var nsamples          = _strategy == LightSamplingStrategy.Multiple ? light.NSamples : 1;
                var lightContribution = SampledSpectrum.Black();
                for (var i = 0; i < nsamples; ++i)
                {
                    Vector3          incoming;
                    VisibilityTester visibilityTester;
                    var lightSpectrum = light.Sample(ref intersection.Point, scene, out incoming, out visibilityTester);
                    if (lightSpectrum.IsBlack() || visibilityTester.Occluded())
                    {
                        continue;
                    }
                    var cosangle = Math.Abs(Vector3.Dot(incoming, intersection.NormalVector));
                    // we get the light coming to us from transmission + reflection
                    var distribution = bsdf.F(incoming, leaving, BxDF.BxDFType.All);
                    // we scale the light by the incident angle of light on the surface and by the distribution
                    // function from light to us and we add it to the spectrum
                    lightContribution += distribution * lightSpectrum * cosangle;
                }
                spectrum += lightContribution / nsamples;
            }
            return(spectrum);
        }
Ejemplo n.º 2
0
        public override SampledSpectrum Li(Scene scene, Ray ray, Renderer renderer, Sample sample, ref Intersection i)
        {
            var spectrum    = SampledSpectrum.Black();
            var lights      = scene.Lights;
            var bsdfAtPoint = i.GetBSDF();
            // we want to get the radiance coming from the surface to us, but the ray comes from us
            // to the surface
            var leaving = -ray.Direction;

            foreach (var light in lights)
            {
                Vector3          incoming;
                VisibilityTester visibilityTester;
                var lightSpectrum = light.Sample(ref i.Point, scene, out incoming, out visibilityTester);
                // We compute the BSDF value only if the light is not black and it is not occluded. Note that it is important
                // for the occlusion test to be after the test for black spectrum, because checking for intersection is an
                // expansive operation.
                if (!lightSpectrum.IsBlack() && !visibilityTester.Occluded())
                {
                    var cosangle = Math.Abs(Vector3.Dot(incoming, i.NormalVector));
                    // we get the light coming to us from transmission + reflection
                    var bsdf = bsdfAtPoint.F(incoming, leaving, BxDF.BxDFType.All);
                    // we scale the light by the incident angle of light on the surface and by the distribution
                    // function from light to us and we add it to the spectrum
                    spectrum += bsdf * lightSpectrum * cosangle;
                }
            }
            if (ray.Depth + 1 < MaxDepth)
            {
                spectrum += SpecularTransmit(ray, renderer, sample, bsdfAtPoint, ref i);
                spectrum += SpecularReflect(ray, renderer, sample, bsdfAtPoint, ref i);
            }
            return(spectrum);
        }
Ejemplo n.º 3
0
 public FresnelBlend(SampledSpectrum d, SampledSpectrum s, MicrofacetDistribution dist)
     : base(BxDFType.Reflection | BxDFType.Glossy)
 {
     _distribution = dist;
     _rd           = d;
     _rs           = s;
 }
Ejemplo n.º 4
0
 public Microfacet(SampledSpectrum reflectance, Fresnel f, MicrofacetDistribution d)
     : base(BxDFType.Reflection | BxDFType.Glossy)
 {
     _spectrum     = reflectance;
     _distribution = d;
     _fresnel      = f;
 }
Ejemplo n.º 5
0
 public DiskLight(Transformation objectToWorld, float radius = 1, SampledSpectrum spectrum = null)
     : base(objectToWorld, spectrum)
 {
     _radius  = radius;
     _normal  = ObjectToWorld.TransformNormal(new Vector3(0, -1, 0)).Normalized();
     NSamples = (uint)Math.Max(1, _radius / 4f);
 }
Ejemplo n.º 6
0
        public override SampledSpectrum Sample(Vector3 leaving, out Vector3 incoming)
        {
            var   entering = CosTheta(ref leaving) > 0;
            float ei, et;

            if (entering)
            {
                ei = IndexOfRefractionIncident;
                et = IndexOfRefractionTransmitted;
            }
            else
            {
                et = IndexOfRefractionIncident;
                ei = IndexOfRefractionTransmitted;
            }
            var sinIncidentSquared = SinThetaSquared(ref leaving);
            var eta = ei / et;
            var sinTransmittedSquared = eta * eta * sinIncidentSquared;
            var cosTransmitted        = (float)Math.Sqrt(1 - sinTransmittedSquared);

            if (entering)
            {
                cosTransmitted = -cosTransmitted;
            }
            var sinTOversinI = eta;

            incoming = new Vector3(sinTOversinI * -leaving.X, sinTOversinI * -leaving.Y, cosTransmitted);
            if (sinTransmittedSquared >= 1)
            {
                return(SampledSpectrum.Black());
            }
            var f = _fresnel.Evaluate(CosTheta(ref leaving));

            return((new SampledSpectrum(1) - f) * _s / AbsCosTheta(ref incoming) * (et * et) / (ei * ei));
        }
Ejemplo n.º 7
0
        /// <summary>
        ///     Compute the fresnel reflectance for dielectric materials
        /// </summary>
        /// <param name="cosi">the angle between incoming ray and normal</param>
        /// <param name="cost">the angle between outgoing ray and normal's inverse</param>
        /// <param name="si">the index of refraction of the first medium</param>
        /// <param name="st">the index of refraction of the second medium</param>
        /// <returns>the reflectance</returns>
        public static SampledSpectrum DielectricFresnel(float cosi, float cost, SampledSpectrum si, SampledSpectrum st)
        {
            var parallel      = ((st * cosi) - (si * cost)) / ((st * cosi) + (si * cost));
            var perpendicular = ((si * cosi) - (st * cost)) / ((si * cosi) + (st * cost));

            return(parallel * parallel + perpendicular * perpendicular);
        }
Ejemplo n.º 8
0
        /// <summary>
        ///     Choose an incoming direction on the view from a BxDF matching a type
        ///     and returns its contribution
        /// </summary>
        /// <param name="leaving">the vector leaving the surface</param>
        /// <param name="incoming">the vector arriving at the surface, the function will set it</param>
        /// <param name="type">the type of scattering</param>
        /// <returns></returns>
        public SampledSpectrum Sample(Vector3 leaving, ref Vector3 incoming, BxDF.BxDFType type)
        {
            /* we randomly choose a BxDF that matches the type */
            var matchingBxDFs = _bxdfs.Where(f => type.HasFlag(f.Type)).ToList(); // the list of bxdf matching the type

            if (matchingBxDFs.Count == 0)
            {
                return(SampledSpectrum.Black());
            }
            // random selection over matching bxdfs
            var bxdf =
                matchingBxDFs.ElementAt(Math.Min((int)(StaticRandom.NextFloat() * matchingBxDFs.Count), matchingBxDFs.Count - 1));
            var     leavingLocal = WorldToLocal(ref leaving);
            Vector3 incomingLocal;
            // we sample the chosen bxdf
            var spectrum = bxdf.Sample(leavingLocal, out incomingLocal);

            // we transform the incoming ray returned by the sampling to world space
            incoming = LocalToWorld(ref incomingLocal);
            // is the reflection is not specular, we add contribution from other bxdfs of the same type
            if (!bxdf.Type.HasFlag(BxDF.BxDFType.Reflection))
            {
                spectrum = _bxdfs.Where(b => type.HasFlag(b.Type))
                           .Aggregate(spectrum, (current, b) => current + b.F(incomingLocal, leavingLocal));
            }
            return(spectrum);
        }
Ejemplo n.º 9
0
 public SpecularTransmission(float indexOfRefractionIncident, float indexOfRefractionTransmitted,
                             SampledSpectrum s = null) : base(BxDFType.Transmission | BxDFType.Specular)
 {
     _fresnel = new FresnelDielectric(indexOfRefractionIncident, indexOfRefractionTransmitted);
     _s       = s ?? SampledSpectrum.Random();
     IndexOfRefractionIncident    = indexOfRefractionIncident;
     IndexOfRefractionTransmitted = indexOfRefractionTransmitted;
 }
Ejemplo n.º 10
0
        public SampledSpectrum F(Vector3 incoming, Vector3 leaving, BxDF.BxDFType type)
        {
            var s             = SampledSpectrum.Black();
            var incomingLocal = WorldToLocal(ref incoming);
            var leavingLocal  = WorldToLocal(ref leaving);

            return(_bxdfs.Where(bxdf => type.HasFlag(bxdf.Type))
                   .Aggregate(s, (current, bxdf) => current + bxdf.F(incomingLocal, leavingLocal)));
        }
Ejemplo n.º 11
0
        public OrenNayar(SampledSpectrum spectrum, float sigma) : base(BxDFType.Reflection | BxDFType.Diffuse)
        {
            var sig     = MathHelper.DegreesToRadians(sigma);
            var sigsqrd = sig * sig;

            _a        = 1f - (sigsqrd / (2 * (sigsqrd + 0.33f)));
            _b        = (0.45f * sigsqrd) / (sigsqrd + 0.09f);
            _spectrum = spectrum;
        }
Ejemplo n.º 12
0
            public override void AddSample(Sample sample, SampledSpectrum spectrum)
            {
                var color = Colors[(int)sample.Y, (int)sample.X];

                if (color != null)
                {
                    color.AddSample(spectrum.ToRGB());
                }
            }
Ejemplo n.º 13
0
 public ClementiteMaterial(Vector3 ka, Vector3 kd, Vector3 ks, uint ns, float d, uint illum)
 {
     _ka    = SampledSpectrum.FromRGB(new[] { ka.X, ka.Y, ka.Z });
     _kd    = SampledSpectrum.FromRGB(new[] { kd.X, kd.Y, kd.Z });
     _ks    = SampledSpectrum.FromRGB(new[] { ks.X, ks.Y, ks.Z });
     _ns    = ns;
     _illum = illum;
     _d     = d;
 }
Ejemplo n.º 14
0
 /// <summary>
 ///     This function is used to parse a .poule file.
 /// </summary>
 private void ParsePoule(Scene scene, string filename)
 {
     string[] lines = File.ReadAllLines(filename);
     foreach (string str in lines)
     {
         if (_pointLightReg.Match(str).Success)
         {
             string[] array = str.Split(' ');
             scene.Lights.Add(new PointLight(Transformation.Translation(
                                                 float.Parse(array[1], CultureInfo.InvariantCulture.NumberFormat),
                                                 float.Parse(array[2], CultureInfo.InvariantCulture.NumberFormat),
                                                 float.Parse(array[3], CultureInfo.InvariantCulture.NumberFormat)),
                                             SampledSpectrum.White()));
         }
         else if (_diskLightReg.Match(str).Success)
         {
             string[] array = str.Split(' ');
             scene.Lights.Add(new PointLight(Transformation.Translation(
                                                 float.Parse(array[1], CultureInfo.InvariantCulture.NumberFormat),
                                                 float.Parse(array[2], CultureInfo.InvariantCulture.NumberFormat),
                                                 float.Parse(array[3], CultureInfo.InvariantCulture.NumberFormat)),
                                             SampledSpectrum.White()));
         }
         else if (_cameraReg.Match(str).Success)
         {
             string[] array = str.Split(' ');
             _camera = new SimpleCamera(_screen,
                                        Transformation.Compose(
                                            Transformation.Translation(
                                                Convert.ToInt32(array[1]),
                                                Convert.ToInt32(array[2]),
                                                Convert.ToInt32(array[3])
                                                ),
                                            Transformation.RotateX(float.Parse(array[4], CultureInfo.InvariantCulture.NumberFormat)),
                                            Transformation.RotateY(float.Parse(array[5], CultureInfo.InvariantCulture.NumberFormat)),
                                            Transformation.RotateZ(float.Parse(array[6], CultureInfo.InvariantCulture.NumberFormat))
                                            ));
         }
         else if (_objReg.Match(str).Success == true)
         {
             string[] array = str.Split(' ');
             try
             {
                 string     path   = array[1].Replace(@"\\", @"\");
                 ParsingObj parser = new ParsingObj(path);
                 parser.AddToScene(scene);
             }
             catch (Exception e)
             {
                 FileName.Text = e.Message;
             }
         }
     }
 }
Ejemplo n.º 15
0
 public AccumulatedSpectrum Mul(ref SampledSpectrum sp)
 {
     if (storeInRgb)
     {
         this.rgbAcc *= sp.ToRgb();
     }
     else
     {
         this.spAcc *= sp;
     }
     return this;     
 }
Ejemplo n.º 16
0
        public override SampledSpectrum F(Vector3 incoming, Vector3 leaving)
        {
            var diffuse = _rd * (float)(28f / (23 * Math.PI)) * (new SampledSpectrum(1) - _rs) *
                          (1f - (float)Math.Pow(1 - 0.5 * AbsCosTheta(ref incoming), 5)) *
                          (1f - (float)Math.Pow(1 - 0.5 * AbsCosTheta(ref leaving), 5));
            var half     = (incoming + leaving).Normalized();
            var specular = new SampledSpectrum(_distribution.D(ref half)) /
                           (new SampledSpectrum(4 * AbsDot(ref incoming, ref leaving) *
                                                Math.Max(AbsCosTheta(ref incoming), AbsCosTheta(ref leaving))) *
                            SchlickFresnel(Vector3.Dot(incoming, half)));

            return(diffuse + specular);
        }
Ejemplo n.º 17
0
        public AccumulatedSpectrum Mul(ref RgbSpectrum rgb, SpectrumType t)
        {
            if (storeInRgb)
            {
                this.rgbAcc *= rgb;
            }
            else
            {
                this.spAcc *= new SampledSpectrum(ref rgb, t);
            }
            return this;

        }
Ejemplo n.º 18
0
        public override SampledSpectrum Li(Scene scene, Ray ray, Renderer renderer, Sample sample,
                                           ref Intersection intersection)
        {
            var spectrum    = SampledSpectrum.Black();
            var bsdfAtPoint = intersection.GetBSDF();
            var leaving     = -ray.Direction;

            spectrum += SampleLights(scene, bsdfAtPoint, ref intersection, ref leaving);
            if (ray.Depth + 1 < MaxDepth)
            {
                spectrum += SpecularTransmit(ray, renderer, sample, bsdfAtPoint, ref intersection);
                spectrum += SpecularReflect(ray, renderer, sample, bsdfAtPoint, ref intersection);
            }
            return(spectrum);
        }
Ejemplo n.º 19
0
        public SampledSpectrum SpecularTransmit(Ray ray, Renderer renderer, Sample sample, BSDF bsdf, ref Intersection i)
        {
            var leaving  = -ray.Direction;
            var incoming = new Vector3();
            var f        = bsdf.Sample(leaving, ref incoming, BxDF.BxDFType.Transmission | BxDF.BxDFType.Specular);
            var angle    = Math.Abs(Vector3.Dot(incoming.Normalized(), i.NormalVector));

            if (f.IsBlack() || angle == 0f)
            {
                return(SampledSpectrum.Black());
            }
            var reflectedRay = new Ray(incoming.Normalized(), i.Point, 0.1f, Ray.DefaultEndValue, ray.Depth + 1);
            var li           = renderer.Li(sample, reflectedRay);

            return(f * li * angle);
        }
Ejemplo n.º 20
0
        /// <summary>
        ///     Compute radiance for a sample
        /// </summary>
        /// <param name="sample"></param>
        /// <param name="ray"></param>
        /// <returns></returns>
        public SampledSpectrum Li(Sample sample, Ray ray = null)
        {
            ray = ray ?? Camera.GenerateRay(sample);
            var intersection = new Intersection();
            var spectrum     = SampledSpectrum.Black();

            if (Scene.TryToIntersect(ray, ref intersection))
            {
                spectrum = Integrator.Li(Scene, ray, this, sample, ref intersection);
            }
            else
            {
                spectrum = Scene.Lights.Aggregate(spectrum, (current, light) => current + light.Le(ray));
            }
            return(spectrum);
        }
        /// <summary>
        /// </summary>
        /// <remarks>This function let us choose the incoming vector</remarks>
        /// <param name="leaving"></param>
        /// <param name="incoming"></param>
        /// <returns></returns>
        public override SampledSpectrum Sample(Vector3 leaving, out Vector3 incoming)
        {
            /* Since we are in the reflection system, rotating the vector by PI radians
             * around the normal consists of negating its x component and its y component */
            incoming = new Vector3(-leaving.X, -leaving.Y, leaving.Z);
            var abscostheta = AbsCosTheta(ref incoming);

            var reflectedLight = SampledSpectrum.Black();

            if (_fresnel != null)
            {
                var reflectedAmount = _fresnel.Evaluate(CosTheta(ref incoming));
                reflectedLight = _spectrum * reflectedAmount / abscostheta;
            }
            else
            {
                reflectedLight = _spectrum * _reflectiveness / abscostheta;
            }
            return(reflectedLight);
        }
Ejemplo n.º 22
0
        private void InitNewScene()
        {
            _scene = new Scene();
            var screen = new raytracer.core.Screen(1024, 768);

            _film = new MyFilm(screen, NSamples);
            Camera camera = new SimpleCamera(screen,
                                             Transformation.Translation((float)PositionX.Value, (float)PositionY.Value, (float)PositionZ.Value) *
                                             Transformation.RotateX((float)(RotationX.Value % 360)) *
                                             Transformation.RotateY((float)(RotationY.Value % 360)) *
                                             Transformation.RotateZ((float)(RotationZ.Value % 360)));

            _renderer = new Renderer(_scene,
                                     new GridSampler(screen), camera, _film,
                                     new WhittedIntegrator());
            _scene.Lights.Add(new PointLight(Transformation.Translation(100, 650, -500), SampledSpectrum.White() * 2000000));
            _scene.Lights.Add(new PointLight(Transformation.Translation(0, 0, -1000), SampledSpectrum.Random() * 200000));
            SimpleObjParser(_scene, _file);
        }
Ejemplo n.º 23
0
 public TestMaterial(float?reflectiveness = null, SampledSpectrum spectrum = null)
 {
     _reflectiveness = reflectiveness ?? StaticRandom.NextFloat();
     _spectrum       = spectrum ?? SampledSpectrum.Random() * 0.3f;
 }
Ejemplo n.º 24
0
 /// <summary>
 ///     Create a light from a transformation
 /// </summary>
 /// <param name="objectToWorld">the light-to-world transformation</param>
 /// <param name="spectrum">the spectrum of the light</param>
 /// <param name="nsamples">the number of samples to take from the light</param>
 protected Light(Transformation objectToWorld = null, SampledSpectrum spectrum = null, uint nsamples = 1)
 {
     ObjectToWorld = objectToWorld ?? Transformation.Identity;
     Spectrum      = spectrum ?? SampledSpectrum.White();
     NSamples      = Math.Max(1, nsamples);
 }
 /// <summary>
 /// </summary>
 /// <remarks>
 ///     This function returns nothing since it is nearly impossible to have
 ///     a correct incoming vector (there is only a single incoming vector)
 /// </remarks>
 /// <param name="incoming"></param>
 /// <param name="leaving"></param>
 /// <returns></returns>
 public override SampledSpectrum F(Vector3 incoming, Vector3 leaving)
 {
     return(SampledSpectrum.Black());
 }
 /// <summary>
 ///     Create a specular reflection model based on Snell's laws.
 /// </summary>
 /// <param name="fresnel">the fresnel properties of the material</param>
 /// <param name="spectrum">a scaling spectrum</param>
 public SpecularReflection(Fresnel fresnel = null, SampledSpectrum spectrum = null)
     : base(BxDFType.Reflection | BxDFType.Specular)
 {
     _spectrum = spectrum ?? new SampledSpectrum(1);
     _fresnel  = fresnel;
 }
 /// <summary>
 ///     Creates a specular reflection model based on unrealistic properties
 /// </summary>
 /// <param name="reflectiveness">the reflectiveness (between 0 and 1000)</param>
 /// <param name="spectrum">a scaling spectrum</param>
 public SpecularReflection(float reflectiveness = 1, SampledSpectrum spectrum = null)
     : base(BxDFType.Reflection | BxDFType.Specular)
 {
     _spectrum       = spectrum ?? new SampledSpectrum(1);
     _reflectiveness = MathHelper.Clamp(reflectiveness, 0, 1000);
 }
Ejemplo n.º 28
0
 public LambertianReflection(SampledSpectrum spectrum) : base(BxDFType.Reflection | BxDFType.Diffuse)
 {
     _spectrum = spectrum ?? SampledSpectrum.Random();
 }
Ejemplo n.º 29
0
 /// <summary>
 ///     Return the spectrum of light when ray does not hit anything.
 /// </summary>
 /// <param name="ray">the ray</param>
 /// <returns></returns>
 public virtual SampledSpectrum Le(Ray ray)
 {
     return(SampledSpectrum.Black());
 }
Ejemplo n.º 30
0
 protected AreaLight(Transformation objectToWorld = null, SampledSpectrum spectrum = null, uint nsamples = 1)
     : base(objectToWorld, spectrum, nsamples)
 {
 }
Ejemplo n.º 31
0
 public GlassMaterial(float refractionIndex1, float refractionIndex2, SampledSpectrum spectrum = null)
 {
     _transmission = new SpecularTransmission(refractionIndex1, refractionIndex2, spectrum);
 }
Ejemplo n.º 32
0
 /// <summary>
 ///     Adds the result of the ray casting (a spectrum) for the ray generated
 ///     by a sample
 ///     <seealso cref="CoefficientSpectrum" />
 ///     <seealso cref="Sample" />
 /// </summary>
 /// <param name="sample">the sample from which the ray was generated</param>
 /// <param name="spectrum">the result of the casting of the ray in the scene</param>
 public abstract void AddSample(Sample sample, SampledSpectrum spectrum);