예제 #1
0
        internal static System.Drawing.Color[,] Render(int screenWidth, int screenHeight, int numSamples, Scene scene)
        {
            System.Drawing.Color[,] pixels = new System.Drawing.Color[screenWidth, screenHeight];
            Camera camera       = scene.Camera;
            F64    sx           = F64.Ratio(1, 2 * screenWidth);
            F64    ox           = F64.Half * F64.FromInt(screenWidth);
            F64    sy           = -F64.Ratio(1, 2 * screenHeight);
            F64    oy           = F64.Half * F64.FromInt(screenHeight);
            F32    ooNumSamples = F32.Ratio(1, numSamples);

            //for (int y = 0; y < screenHeight; y++)
            Parallel.For(0, screenHeight, y =>
            {
                Random rnd = new Random(y * 29827341 + 23427343);
                for (int x = 0; x < screenWidth; x++)
                {
                    Color accum = Color.Black;
                    for (int i = 0; i < numSamples; i++)
                    {
                        // rx, ry == random offset in range [-0.5, 0.5]
                        F64 rx         = F64.FromRaw(rnd.Next()) * 2 - F64.Half;
                        F64 ry         = F64.FromRaw(rnd.Next()) * 2 - F64.Half;
                        F64 xx         = (F64.FromInt(x) + rx - ox) * sx;
                        F64 yy         = (F64.FromInt(y) + ry - oy) * sy;
                        F64Vec3 rayDir = F64Vec3.Normalize(camera.Forward + xx * camera.Right + yy * camera.Up);
                        Color color    = TraceRay(new Ray(camera.Pos, rayDir), scene, 0);
                        accum         += color;
                    }
                    pixels[x, y] = (ooNumSamples * accum).ToDrawingColor();
                }
            });
            return(pixels);
        }
예제 #2
0
        private static Color Shade(Ray ray, ISect isect, Scene scene, int depth)
        {
            var      pos        = isect.Pos;
            var      normal     = isect.Normal;
            var      reflectDir = ray.Dir - 2 * F64Vec3.Dot(normal, ray.Dir) * normal;
            Color    ret        = Color.Black;
            Material material   = isect.Material;

            ret += GetNaturalColor(material, pos, normal, reflectDir, scene);
            if (depth >= MaxDepth)
            {
                return(ret + new Color(F32.Half, F32.Half, F32.Half));
            }
            return(ret + GetReflectionColor(material, pos + F64.Ratio(1, 1000) * reflectDir, normal, reflectDir, scene, depth));
        }