Color shade(Hit hit)
        {
            // if no scObject was hit, return background color
            if (hit.scObject == null)
                return background;

            Color color = new Color(0,0,0);
            for(int i=0; i<numLights; i++){
                // convenience for cleaner code
                Vector liPos = lights[i].position;

                // ambient reflection
                color = color + hit.scObject.ambient * lights[i].ambient;
                Vector p = hit.HitPoint();
                Vector v = eye - p;

                Vector s = liPos - p;
                Vector m = hit.scObject.Normal(p);

                // make sure light hits the front face
                if (Vector.Dot(s, m) < 0)  continue;

                // cast a "shadow feeler" and find its closest hit position to light source
                Hit feeler = intersect(liPos, p - liPos);
                Vector feelerHit = feeler.HitPoint();

                // check that point is less 90 degrees therefore it is on the same side of light source as displayed point
                float dotLiFeel_LiPoint = Vector.Dot((liPos - feelerHit), liPos - p);
                bool correctLightSide = dotLiFeel_LiPoint >= 0;

                // check that the point is not the same point as the displayed point
                // and if it is closer to light source or further away
                float squaredLen_LiFeel = Vector.Dot((liPos - feelerHit), liPos - feelerHit);
                bool beforeObj  = Math.Abs(dotLiFeel_LiPoint - squaredLen_LiFeel) < 0.0001; //0.0001 to stop float round error for <=

                //if there is a collision and it is closer than the displayed scObject and it is on the same side of light as scObject
                if( (feeler.t<=0) || ((beforeObj) && (correctLightSide)) ){

                    //diffuse reflection
                    color = color + ( (hit.scObject.diffuse * lights[i].diffuse) * ( Vector.Dot(s, m) / Convert.ToSingle( (Math.Sqrt(Vector.Dot(s, s))*Math.Sqrt(Vector.Dot(m, m))) ) ));

                    //specular reflection
                    //h = normalized(normalized(s) + normalized(v))
                    Vector h = s.Normalize() + v.Normalize();
                    h = h.Normalize();
                    color = color + ( (hit.scObject.specular * lights[i].specular) * Convert.ToSingle( (Math.Pow(( Vector.Dot(h, m) / (Math.Sqrt(Vector.Dot(h, h))*Math.Sqrt(Vector.Dot(m, m))) ), hit.scObject.shininess) ) ));
                }
            }
            return color;
        }
        Hit intersect(Vector source, Vector d)
        {
            // initially hit scObject==NULL (no hit)
            Hit hit = new Hit(source, d, -1f, null);

            // for every scObject, check if ray hits it
            for(int i=0; i<numObjects; i++) {
                float t = sceneObjects[i].Intersect(source, d);

                // 1. only use hits visible for the camera
                // 2. only overwrite hit if either there is
                //     no hit yet, or the hit is closer
                if(t>0.00001 && (hit.scObject==null || t<hit.t))
                    hit = new Hit(source, d, t, sceneObjects[i]);
            }
            return hit;
        }