Ejemplo n.º 1
0
        public Color3 Diffuse(Intersection intersection)
        {
            float killChance = 0;

            if (_russianRoulette)
            {
                killChance = GetKillChance(intersection.Material.Color);
                if (_rng.TestChance(killChance))
                {
                    return(Color4.Black);
                }
            }

            //random reflected ray
            Vector3 rDir;

            if (_cosineDist)
            {
                rDir = _rng.CosineDistributed(intersection.SurfaceNormal);
            }
            else
            {
                rDir = _rng.RandomVectorOnHemisphere(intersection.SurfaceNormal);
            }

            var reflected = Ray.CreateFromIntersection(intersection, rDir, goesIntoMaterial: true);

            //brdf of material
            var brdf = intersection.Material.CalculateColor(intersection) / MathHelper.Pi;

            //irradiance
            var nDotR = Vector3.Dot(intersection.SurfaceNormal, rDir);
            var Ei    = _scene.Sample(reflected, _rng, true) * nDotR;

            Color3 Ld = Color4.Black;

            //use next event estimation?
            if (_nee)
            {
                if (_scene.SurfaceLights.Count > 0)
                {
                    //sample light directly - next event estimation
                    var ranLight = _scene.SurfaceLights.GetRandom(_rng.R); //get random light
                    Ld = SampleLightDirectly(ranLight, brdf, intersection) * _scene.SurfaceLights.Count * ranLight.Brightness;
                }
            }

            Color3 result;

            if (_cosineDist)
            {
                //probability density function
                var pdf = nDotR / MathHelper.Pi;
                result = brdf * Ei / pdf + Ld;
            }
            else
            {
                result = MathHelper.TwoPi * brdf * Ei + Ld;
            }

            return(result / (1 - killChance));
        }