コード例 #1
0
 public Direction(Vector vector, Basis basis)
 {
     this.vector   = vector; // assumed to be normalized
     this.cosTheta = Math.Max(0, Vector.Dot(basis.Normal, vector));
 }
コード例 #2
0
 public Vector Emittance(Direction outgoing, Basis basis)
 {
     return(emittance);
 }
コード例 #3
0
        public static Vector Radiance(Ray ray)
        {
            const int MAX_BOUNCES = 10;

            Vector weights  = new Vector(1.0f, 1.0f, 1.0f);
            Vector radiance = Vector.Zero;

            for (int bounce = 0; bounce < MAX_BOUNCES; ++bounce)
            {
                float distance;
                int   hitSphere;

                if (!Intersect(ray, out hitSphere, out distance))
                {
                    break;
                }

                Sphere    sphere   = geometry[hitSphere];
                IMaterial material = materials[hitSphere];
                var       hitPoint = Ray.PointAt(ray, distance);

                var basis    = new Basis(sphere.Normal(hitPoint));
                var outgoing = new Direction(-ray.Direction, basis);

                /* Include object emittance as light path */

                radiance += weights * material.Emittance(outgoing, basis);

                /* Include point light source light paths */

                foreach (var light in lights)
                {
                    var pointToLight  = light.position - hitPoint;
                    var lightDistance = pointToLight.Length();

                    if (!Occlude(new Ray(hitPoint, pointToLight), 1e-4f, lightDistance))
                    {
                        Direction incomimg = new Direction(pointToLight / lightDistance, basis);

                        radiance += weights * material.BRDF(incomimg, outgoing, basis) * incomimg.CosTheta
                                    * light.intensity / (lightDistance * lightDistance);
                    }
                }

                /* Russian roulette */

                Vector weight = material.WeightPDF(outgoing, basis);
                float  p      = Math.Max(weight.X, Math.Max(weight.Y, weight.Z));

                if (bounce > 2)
                {
                    if (random.NextDouble() <= p)
                    {
                        weight /= p;
                    }
                    else
                    {
                        break;
                    }
                }

                /* Update light path weights and prepare for next bounce */

                weights *= weight;

                var newDir = material.SamplePDF(outgoing, basis, random);

                ray = new Ray(hitPoint, newDir);
            }

            return(radiance);
        }
コード例 #4
0
 public Vector SamplePDF(Direction outgoing, Basis basis, Random random)
 {
     return(2 * basis.Normal * outgoing.CosTheta - outgoing.Vector);
 }
コード例 #5
0
 public Vector WeightPDF(Direction outgoing, Basis basis)
 {
     return(this.reflection);
 }
コード例 #6
0
 public Vector BRDF(Direction incoming, Direction outgoing, Basis basis)
 {
     return(this.albedo / (float)Math.PI);
 }
コード例 #7
0
 public Vector WeightPDF(Direction outgoing, Basis basis)
 {
     return(this.albedo);
 }
コード例 #8
0
ファイル: Materials.cs プロジェクト: war-man/SharpRT
 public Vector BRDF(Direction incoming, Direction outgoing, Basis basis)
 {
     return(Vector.Zero);
 }