Beispiel #1
0
 static void Main(string[] args)
 {
     RayObjects = new List<SLRayPrimitive>();
     Lights = new List<SLLight>();
     ReadScene("scene.urt");
     dir = EYE - SPOT;
     right = UP.Cross(dir);
     right.Normalize();
     screenCenter = dir.Cross(right);
     screenV = screenCenter * (float)Math.Tan(FOVY * 0.5f);
     screenU = right * screenV.Magnitude() * ASPECT;
     WIDTH_DIV_2 = ImageWidth / 2;
     HEIGHT_DIV_2 = ImageHeight / 2;
     random = new Random(01478650229);
     Bitmap outputImage = new Bitmap(ImageWidth, ImageHeight);
     // add some objects
     float distance = 20.0f;
     float offset = distance / 2.0f;
     for (int i = 0; i < 5; i++)
     {
         float x = (float)(random.NextDouble() * distance) - offset;
         float y = (float)(random.NextDouble() * distance) - offset;
         float z = (float)(random.NextDouble() * 10.0f + 2.0f);
         Color c = Color.FromArgb(255, random.Next(255), random.Next(255), random.Next(255));
         SLSphere s = new SLSphere(new SLVector3f(x, y, z), (float)(random.NextDouble() + 0.5), c);
         RayObjects.Add(s);
     }
     int dotPeriod = ImageHeight / 10;
     Stopwatch stopwatch = new Stopwatch();
     System.Console.WriteLine("Rendering...\n");
     System.Console.WriteLine("|0%---100%|");
     stopwatch.Start();
     for (int j = 0; j < ImageHeight; j++)
     {
         if ((j % dotPeriod) == 0) System.Console.Write("*");
         for (int i = 0; i < ImageWidth; i++)
         {
             // Go through each pixel to get the color
             Color c = Render(i, j);
             outputImage.SetPixel(i, j, c);
         }
     }
     stopwatch.Stop();
     TimeSpan ts = stopwatch.Elapsed;
     string output = ts.Minutes.ToString() + "_" + ts.Seconds.ToString() + ".png";
     outputImage.Save(output);
 }
Beispiel #2
0
        static Color SetPixelColor(SLRay ray, int depth)
        {
            // Get closest intersection IF ANY
            GetClosestIntersection(ref ray);

            // Return if the ray didn't hit anything
            if (ray.ClosestPointDistance >= SLRay.Max_Distance || ray.ClosestPrimitive == null)
                return BG_COLOR;

            // Set ambient light
            float r = LaR * ray.ClosestPrimitive.PrimitiveColor.R;
            float g = LaG * ray.ClosestPrimitive.PrimitiveColor.G;
            float b = LaB * ray.ClosestPrimitive.PrimitiveColor.B;

            // Add contributions of each light
            SLVector3f normal = ray.ClosestPrimitive.PointNormal(ray.ClosestPoint);
            SLVector3f viewDir = -ray.Direction;

            foreach (SLLight light in Lights)
            {
                SLVector3f lightDir = new SLVector3f();
                float lightDistance;

                // Find light direction and distance
                lightDir = light.position - ray.ClosestPoint;

                lightDistance = lightDir.Magnitude();
                lightDir.Normalize();

                SLRay pointToLight = new SLRay(ray.ClosestPoint + (lightDir * TINY), lightDir);
                pointToLight.ClosestPointDistance = lightDistance;
                GetClosestIntersection(ref pointToLight);

                if (pointToLight.ClosestPrimitive != null)
                    continue;

                // DIFFUSE LIGHTING
                float lDotN = normal.Dot(lightDir);

                // Clamp
                if (lDotN <= 0)
                    continue;

                float diffColorContrR = (light.color.R * lDotN)/255.0f;
                float diffColorContrG = (light.color.G * lDotN)/ 255.0f;
                float diffColorContrB = (light.color.B * lDotN)/ 255.0f;

                // Add this light's diffuse contribution to our running totals
                r += diffColorContrR * ray.ClosestPrimitive.PrimitiveColor.R;
                g += diffColorContrG * ray.ClosestPrimitive.PrimitiveColor.G;
                b += diffColorContrB * ray.ClosestPrimitive.PrimitiveColor.B;

                if (MATERIAL_SPECULAR_COEFFICIENT > TINY)
                {
                    // Specular component - dot product of light's reflection vector and viewer direction
                    // Direction to the viewer is simply negative of the ray direction
                    SLVector3f lightReflectionDir = normal * (lDotN * 2) - lightDir;
                    float specularFactor = viewDir.Dot(lightReflectionDir);
                    if (specularFactor > 0)
                    {
                        // To get smaller, sharper highlights we raise it to a power and multiply it
                        specularFactor = MATERIAL_SPECULAR_COEFFICIENT * (float)Math.Pow(specularFactor, MATERIAL_SPECULAR_POWER);

                        // Add the specular contribution to our running totals
                        r += MATERIAL_SPECULAR_COEFFICIENT * specularFactor * ray.ClosestPrimitive.PrimitiveColor.R;
                        g += MATERIAL_SPECULAR_COEFFICIENT * specularFactor * ray.ClosestPrimitive.PrimitiveColor.G;
                        b += MATERIAL_SPECULAR_COEFFICIENT * specularFactor * ray.ClosestPrimitive.PrimitiveColor.B;
                    }
                }

                if (depth < MAX_DEPTH && MATERIAL_REFLECTION_COEFFICIENT > TINY)
                {
                    // Set up the reflected ray - notice we move the origin out a tiny bit again
                    SLVector3f reflectedDir = ray.Direction.Reflection(normal);
                    SLRay reflectionRay = new SLRay(ray.ClosestPoint + reflectedDir * TINY, reflectedDir);

                    // And trace!
                    Color reflectionCol = SetPixelColor(reflectionRay, depth + 1);

                    // Add reflection results to running totals, scaling by reflect coeff.
                    r += MATERIAL_REFLECTION_COEFFICIENT * reflectionCol.R;
                    g += MATERIAL_REFLECTION_COEFFICIENT * reflectionCol.G;
                    b += MATERIAL_REFLECTION_COEFFICIENT * reflectionCol.B;
                }

            }
            // Clamp
            if (r > 255) r = 255;
            if (g > 255) g = 255;
            if (b > 255) b = 255;

            // Take care of NaN
            if (r < 0) r = 0;
            if (g < 0) g = 0;
            if (b < 0) b = 0;

            return (Color.FromArgb(255, (int)r, (int)g, (int)b));
        }