示例#1
0
        /// <summary>
        /// Creates bounced vector (directing from intersection) from given input vector (direction towards intersection)
        /// </summary>
        /// <param name="p">Input vector</param>
        /// <returns>bounced vector</returns>
        private Vector bounceVector(Intersection p)
        {
            Vector smer = p.ray.direction;

            smer.Normalize();
            Vector n = new Vector(p.normal);

            n.Normalize();

            Vector en = 2 * Vector.CrossProduct(smer, n);
            Vector v  = Vector.CrossProduct(en, n) + smer;

            return(v);
        }
示例#2
0
        public static Matrix ViewTransform(Point from, Point to, Vector up)
        {
            var forward     = (to - from).Normalize();
            var upn         = up.Normalize();
            var left        = forward.Cross(upn);
            var true_up     = left.Cross(forward);
            var orientation = new Matrix(new double[, ] {
                { left.x, left.y, left.z, 0 },
                { true_up.x, true_up.y, true_up.z, 0 },
                { -forward.x, -forward.y, -forward.z, 0 },
                { 0, 0, 0, 1 }
            });

            return(orientation * Transformation.Translation(-from.x, -from.y, -from.z));
        }
        public static Matrix ViewTransform(Point from, Point to, Vector up)
        {
            var forward = to.Subtract(from).Normalize().ToPoint();
            var upN     = up.Normalize();
            var left    = forward.Cross(upN);
            var trueUp  = left.Cross(forward);

            var orientation = new Matrix(new double[, ]
            {
                { left.X, left.Y, left.Z, 0 },
                { trueUp.X, trueUp.Y, trueUp.Z, 0 },
                { -forward.X, -forward.Y, -forward.Z, 0 },
                { 0.0, 0.0, 0.0, 1.0 }
            });

            return(orientation.Multiply(Matrix.Translation(-from.X, -from.Y, -from.Z)));
        }
示例#4
0
        static public Vector CalculateSurfaceNormal(Vertex[] v)
        {
            Vector rtn = new Vector();

            for (int i = 0; i < v.Length; i++)
            {
                Vector current = v[i].m_pos;
                Vector next    = v[(i + 1) % v.Length].m_pos;

                rtn.m_x = rtn.m_x + ((current.m_y - next.m_y) * (current.m_z + next.m_z));
                rtn.m_y = rtn.m_y + ((current.m_z - next.m_z) * (current.m_x + next.m_x));
                rtn.m_z = rtn.m_z + ((current.m_x - next.m_x) * (current.m_y + next.m_y));
                //rtn.PrintVector();
            }
            rtn = rtn.Normalize();

            return(rtn);
            //return rtn;
        }
示例#5
0
        /// <summary>
        /// some helper functions to calculate the refraction rays
        /// </summary>
        /// <param name="P"></param>
        /// <param name="N"></param>
        /// <param name="V"></param>
        /// <param name="refraction"></param>
        /// <returns></returns>
        private Ray GetRefractionRay(Vector P, Vector N, Vector V, double refraction)
        {
            //V = V * -1;
            //double n = -0.55; // refraction constant for now
            //if (n < 0 || n > 1) return new Ray(P, V); // no refraction

            double c1 = N.Dot(V);
            double c2 = 1 - refraction * refraction * (1 - c1 * c1);

            if (c2 < 0)
            {
                c2 = Math.Sqrt(c2);
            }
            Vector T = (N * (refraction * c1 - c2) - V * refraction) * -1;

            T.Normalize();

            return(new Ray(P, T)); // no refraction
        }
示例#6
0
        static Color GetNaturalColor(ISceneObject thing, Vector pos, Vector norm, Vector rd, Scene scene)
        {
            Color ret = Color.Black;

            foreach (Light light in scene.Lights)
            {
                Vector ldis      = light.Pos - pos;
                Vector livec     = ldis.Normalize();
                double neatIsect = TestRay(new Ray {
                    Refraction = 1, Start = pos, Dir = livec
                }, scene);
                bool isInShadow = !((neatIsect > ldis.GetLength()) || (neatIsect == 0));
                if (!isInShadow)
                {
                    double illum    = livec.DotProduct(norm);
                    Color  lcolor   = illum > 0 ? illum * light.Color : Color.Black;
                    double specular = rd.Normalize().DotProduct(livec);
                    Color  scolor   = specular > 0 ? Math.Pow(specular, thing.Surface.Roughness) * light.Color : Color.Black;
                    var    power    = 4 / ldis.DotProduct(ldis);
                    ret += power * (thing.Surface.Diffuse(pos) * lcolor + thing.Surface.Specular(pos) * scolor);
                }
            }
            return(ret);
        }
示例#7
0
        /// <summary>
        /// Render and create window with set pixels
        /// </summary>
        /// <returns>Rendered window</returns>
        public RenderWindow Render()
        {
            RenderWindow window = new RenderWindow(s.width, s.height);

            Point cameraPosition = GetCamera().location;

            float h = (float)(2 * Math.Tan((Math.PI / 180) * (GetCamera().fovy / 2)));

            float w = (h * width) / (height);
            Point S = cameraPosition + GetCamera().direction;                                     //Get position of point S

            Point origin = S + (((0.5 * h) * GetCamera().up) + ((-0.5 * w) * GetCamera().right)); // Find 0,0 on canvas

            float dx = w / width;
            float dy = h / height;

            //for (int i = 0; i < height; i++)
            Parallel.For(0, height, i =>      //Cycle
            {
                if (ct.IsCancellationRequested)
                {
                    return;
                }
                for (int j = 0; j < width; j++)    //Cycle
                {
                    if (ct.IsCancellationRequested)
                    {
                        return;
                    }
                    Intersection p;
                    Color c;

                    Point pixel      = origin + j * dx * GetCamera().right - i * (dy * GetCamera().up);                                //Position of rendered pixel
                    Vector direction = new Vector(pixel.X - cameraPosition.X, pixel.Y - cameraPosition.Y, pixel.Z - cameraPosition.Z); //Actual direction
                    direction.Normalize();

                    Ray ray = new Ray(cameraPosition, direction); //Make ray

                    p = null;
                    for (int k = 0; k < renderedObjects.Count; k++) //For each object check if there is intersection
                    {
                        s.intersectionCalculationCount++;
                        var intersection = renderedObjects[k].GetIntersection(ray);

                        if (intersection != null)
                        {
                            intersection.indexOfCrossedObj = k;
                        }
                        if (p == null)
                        {
                            if (intersection != null && intersection.t >= 0.001)
                            {
                                p = intersection;
                            }
                        }
                        else if (intersection != null)
                        {
                            if (p.t > intersection.t && intersection.t >= 0.001)
                            {
                                p = intersection;
                            }
                        }
                    }
                    if (p != null)
                    {
                        ray.p            = p;
                        ray.rayIntensity = 1;
                        c = getColor(ray, 1); //Get color of given pixel
                    }
                    else
                    {
                        c = s.backgroundColor;
                    }
                    window.SetPixel(i, j, c);       //Set color of given pixel
                }
            });
            //}
            if (ct.IsCancellationRequested)
            {
                return(null);
            }
            return(window);
        }