Example #1
0
 /// <summary>
 /// Transforms a vector by a matrix.
 /// </summary>
 public static Vector Transform(Matrix mat, Vector vec)
 {
     return vec.X * mat.U + vec.Y * mat.V + vec.Z * mat.W;
 }
Example #2
0
 /// <summary>
 /// Creates a translation matrix.
 /// </summary>
 public static Matrix Translation(Vector vec)
 {
     return new Matrix(new Vector(1, 0, 0),
                       new Vector(0, 1, 0),
                       new Vector(0, 0, 1),
                       vec);
 }
Example #3
0
 /// <summary>
 /// Creates a possibly non-uniform scaling matrix.
 /// </summary>
 public static Matrix Scaling(Vector scale)
 {
     return new Matrix(new Vector(scale.X, 0, 0),
                       new Vector(0, scale.Y, 0),
                       new Vector(0, 0, scale.Z),
                       Vector.Zero);
 }
Example #4
0
 /// <summary>
 /// Constructs a ray with an origin and a direction.
 /// </summary>
 public Ray(Point origin, Vector direction)
 {
     this.origin = origin;
     this.direction = direction.Normalize();
 }
Example #5
0
 /// <summary>
 /// Constructs a matrix from four column vectors.
 /// </summary>
 private Matrix(Vector u, Vector v, Vector w, Vector t)
 {
     this.u = u;
     this.v = v;
     this.w = w;
     this.t = t;
 }
Example #6
0
        /// <summary>
        /// Renders the scene into a pixel buffer.
        /// </summary>
        public void Render(PixelBuffer pixbuf)
        {
            float dx = 1.0f / pixbuf.Width, dy = 1.0f / pixbuf.Height;
            camera.AspectRatio = (float)pixbuf.Width / pixbuf.Height;

            // Free parallelism, why not! Note a Parallel.For loop
            // over each row is slightly faster but less readable.
            Parallel.ForEach(pixbuf, (pixel) =>
            {
                var color = Vector.Zero;
                float u = pixel.X * dx;
                float v = pixel.Y * dy;

                var rays = new[]
                {
                    camera.Trace(2 * (u - 0.25f * dx) - 1, 2 * (v - 0.25f * dy) - 1),
                    camera.Trace(2 * (u + 0.25f * dx) - 1, 2 * (v - 0.25f * dy) - 1),
                    camera.Trace(2 * (u - 0.25f * dx) - 1, 2 * (v + 0.25f * dy) - 1),
                    camera.Trace(2 * (u + 0.25f * dx) - 1, 2 * (v + 0.25f * dy) - 1),
                };

                // Trace a packet of 4 coherent AA rays
                var packet = scene.Intersects4(rays);

                // Convert the packet to a set of usable ray-geometry intersections
                Intersection<Model>[] hits = packet.ToIntersection<Model>(scene);

                for (int t = 0; t < 4; ++t)
                {
                    if (hits[t].HasHit)
                    {
                        color += new Vector(0.1f, 0.1f, 0.1f);

						var ray = rays[t];
                        var model = hits[t].Instance;

                        // Parse the surface normal returned and then process it manually
                        var rawNormal = new Vector(hits[t].NX, hits[t].NY, hits[t].NZ);
                        var normal = model.CorrectNormal(rawNormal); // Important!

                        // Calculate the new ray towards the light source
                        var hitPoint = ray.PointAt(hits[t].Distance);
                        var toLight = lightPosition - hitPoint; // from A to B = B - A
                        var lightRay = new Ray(hitPoint + normal * Constants.Epsilon, toLight);

                        // Is the light source occluded? If so, no point calculating any lighting
                        if (!scene.Occludes(lightRay, 0, toLight.Length()))
                        {
                            // Compute the Lambertian cosine term (rendering equation)
                            float cosLight = Vector.Dot(normal, toLight.Normalize());

                            // Calculate the total light attenuation (inverse square law + cosine law)
                            var attenuation = lightIntensity * cosLight / Vector.Dot(toLight, toLight);

                            color += model.Material(hits[t].Mesh).BRDF(toLight.Normalize(), ray.Direction, normal) * attenuation;
                        }
                    }
                }

                // Average the 4 per-pixel samples
                pixbuf.SetColor(pixel, color / 4);
            });
        }
Example #7
0
 /// <summary>
 /// Returns the length of a vector.
 /// </summary>
 public static float Length(Vector u)
 {
     return (float)Math.Sqrt(Dot(u, u));
 }
Example #8
0
 /// <summary>
 /// Reflects this vector about a normal.
 /// </summary>
 public Vector Reflect(Vector n)
 {
     return Reflect(this, n);
 }
Example #9
0
 /// <summary>
 /// Returns the dot product of this vector with another.
 /// </summary>
 public float Dot(Vector v)
 {
     return Dot(this, v);
 }
Example #10
0
 /// <summary>
 /// Returns the dot product of two vectors.
 /// </summary>
 public static float Dot(Vector u, Vector v)
 {
     return u.X * v.X + u.Y * v.Y + u.Z * v.Z;
 }
Example #11
0
 /// <summary>
 /// Returns the cross product of two vectors.
 /// </summary>
 public static Vector Cross(Vector u, Vector v)
 {
     return new Vector(u.Y * v.Z - u.Z * v.Y,
                       u.Z * v.X - u.X * v.Z,
                       u.X * v.Y - u.Y * v.X);
 }
Example #12
0
 /// <summary>
 /// Returns the azimuth of a vector.
 /// </summary>
 /// <remarks>
 /// Horizontal angle, zero towards the z-axis.
 /// </remarks>
 public static float Azimuth(Vector u)
 {
     var len = Length(u);
     if (len > 0) return (float)Math.Atan2(u.Z, u.X);
     else throw new InvalidOperationException("Vector has no direction");
 }
Example #13
0
 /// <summary>
 /// Returns the inclination of a vector.
 /// </summary>
 /// <remarks>
 /// Vertical angle, zero on the xz-plane.
 /// </remarks>
 public static float Inclination(Vector u)
 {
     var len = Length(u);
     if (len > 0) return (float)(Math.Acos(u.Y / len) - Math.PI / 2);
     else throw new InvalidOperationException("Vector has no direction");
 }
Example #14
0
 /// <summary>
 /// Normalizes a vector to unit length.
 /// </summary>
 public static Vector Normalize(Vector u)
 {
     var len = Length(u);
     if (len > 0) return u / len;
     else throw new InvalidOperationException("Vector has no direction");
 }
Example #15
0
 /// <summary>
 /// Transforms a vector by this matrix.
 /// </summary>
 public Vector Transform(Vector vec)
 {
     return Transform(this, vec);
 }
Example #16
0
 /// <summary>
 /// Returns the cross product of this vector with another.
 /// </summary>
 public Vector Cross(Vector v)
 {
     return Cross(this, v);
 }
Example #17
0
        /// <summary>
        /// Returns the inverse of a matrix.
        /// </summary>
        public static Matrix Invert(Matrix mat)
        {
            // Work out determinant of the 3x3 submatrix.
            var det = mat.U.X * (mat.V.Y * mat.W.Z - mat.W.Y * mat.V.Z)
                    - mat.V.X * (mat.W.Z * mat.U.Y - mat.W.Y * mat.U.Z)
                    + mat.W.X * (mat.U.Y * mat.V.Z - mat.V.Y * mat.U.Z);

            if (Math.Abs(det) < 0)
                throw new ArgumentException("Matrix is not invertible");

            // Compute inv(submatrix) = transpose(submatrix) / det.
            var inv_u = new Vector(mat.U.X, mat.V.X, mat.W.X) / det;
            var inv_v = new Vector(mat.U.Y, mat.V.Y, mat.W.Y) / det;
            var inv_w = new Vector(mat.U.Z, mat.V.Z, mat.W.Z) / det;

            // Transform the translation column by this inverse matrix.
            var inv_t = -(mat.T.X * inv_u + mat.T.Y * inv_v + mat.T.Z * inv_w);

            return new Matrix(inv_u, inv_v, inv_w, inv_t);
        }
Example #18
0
 /// <summary>
 /// Converts a vector into a point.
 /// </summary>
 /// <remarks>
 /// This is meaningless mathematically.
 /// </remarks>
 public static Point ToPoint(Vector u)
 {
     return Point.Zero + u;
 }
Example #19
0
 /// <summary>
 /// Corrects an Embree.NET normal, which is unnormalized
 /// and in object space, to a world space normal vector.
 /// </summary>
 public Vector CorrectNormal(Vector normal)
 {
     return (inverseTranspose * normal).Normalize();
 }
Example #20
0
 /// <summary>
 /// Reflects a vector about a normal.
 /// </summary>
 public static Vector Reflect(Vector i, Vector n)
 {
     return i - 2 * n * Dot(i, n);
 }