Beispiel #1
0
        private static void Main()
        {
            var materialIvory  = new Material(new ColorF(0.4f, 0.4f, 0.3f), new Albedo(0.6f, 0.3f, 0.1f, 0f), 50f, 1f);
            var materialRed    = new Material(new ColorF(0.3f, 0.1f, 0.1f), new Albedo(0.9f, 0.1f, 0.0f, 0f), 10f, 1f);
            var materialMirror = new Material(new ColorF(1.0f, 1.0f, 1.0f), new Albedo(0f, 10f, 0.8f, 0f), 1425f, 1f);
            var materialGlass  = new Material(
                new ColorF(0.6f, 0.7f, 0.8f), new Albedo(0f, 0.5f, 0.1f, 0.8f), 125f, 1.5f);

            var scene = new List <IObject3D>
            {
                new Sphere(new Vector3(-3f, 0f, -16f), 2, materialIvory),
                new Sphere(new Vector3(-1f, -1.5f, -12f), 2, materialGlass),
                new Sphere(new Vector3(1.5f, -0.5f, -18f), 3, materialRed),
                new Sphere(new Vector3(7f, 5f, -18f), 4, materialMirror)
            };

            var lightSources = new List <LightSource>
            {
                new LightSource(new Vector3(-20f, 20f, 20f), 1.5f),
                new LightSource(new Vector3(30f, 50f, -25f), 1.8f),
                new LightSource(new Vector3(30f, 20f, 30f), 1.7f)
            };

            var renderEngine   = new RenderEngine(Width, Height);
            var environmentMap = new ImageF(EnvMapPath);
            var frame          = renderEngine.Render(Vector3.Zero, scene, lightSources, environmentMap);

            frame.SaveToFile(ResultFramePath);
        }
Beispiel #2
0
        private ColorF CastRay(
            ref Vector3 origin, ref Vector3 projectionDirection, List <IObject3D> scene,
            List <LightSource> lightSources, ImageF environmentMap = null, int depth = 0)
        {
            RayIntersectionResult rayIntersectionResult;

            if (depth > RaycastDepth ||
                !(rayIntersectionResult = SceneIntersect(ref origin, ref projectionDirection, scene)).IsIntersect)
            {
                return(environmentMap == null
                    ? DefaultColor
                    : GetColorFromEnvironmentMap(projectionDirection, environmentMap));
            }

            CalculateLightIntensity(
                projectionDirection, scene, lightSources, rayIntersectionResult,
                out var diffuseLightIntensity,
                out var specularLightIntensity);

            var reflectionColor = GetReflectionColor(
                projectionDirection, scene, lightSources, environmentMap, depth, ref rayIntersectionResult);

            var refractionColor = GetRefractionColor(
                projectionDirection, scene, lightSources, environmentMap, depth, ref rayIntersectionResult);

            return(rayIntersectionResult.Material.DiffuseColor * diffuseLightIntensity * rayIntersectionResult.Material.Albedo.DiffuseKoef +
                   ColorF.White * specularLightIntensity * rayIntersectionResult.Material.Albedo.SpecularKoef +
                   reflectionColor * rayIntersectionResult.Material.Albedo.ReflectKoef +
                   refractionColor * rayIntersectionResult.Material.Albedo.RefractKoef);
        }
Beispiel #3
0
        private ColorF GetColorFromEnvironmentMap(Vector3 projectionDirection, ImageF environmentMap)
        {
            var x = (int)MathF.Max(
                0f,
                MathF.Min(
                    environmentMap.Width - 1,
                    (int)((Math.Atan2(projectionDirection.Z, projectionDirection.X) / (2 * MathF.PI) + 0.5f) *
                          environmentMap.Width)));

            var y = (int)MathF.Max(
                0f,
                MathF.Min(
                    environmentMap.Height - 1,
                    (int)(MathF.Acos(projectionDirection.Y) / MathF.PI * environmentMap.Height)));

            return(environmentMap.Buffer[x][y]);
        }
Beispiel #4
0
        public ImageF Render(
            Vector3 cameraPosition, List <IObject3D> scene, List <LightSource> lightSources, ImageF environmentMap = null)
        {
            var frame = new ImageF(FrameWidth, FrameHeight);

            Parallel.For(
                0, FrameHeight, j =>
            {
                for (var i = 0; i < FrameWidth; i++)
                {
                    var x = (2 * (i + 1e-3f) / FrameWidth - 1) * MathF.Tanh(Fov / 2f) *
                            (FrameWidth / (float)FrameHeight);

                    var y = -(2 * (j + 1e-3f) / FrameHeight - 1) * MathF.Tanh(Fov / 2f);

                    var projectionDirection = Vector3.Normalize(new Vector3(x, y, -1f));
                    frame.Buffer[i][j]      = CastRay(
                        ref cameraPosition, ref projectionDirection, scene, lightSources, environmentMap);
                }
            });

            return(frame);
        }
Beispiel #5
0
        private ColorF GetRefractionColor(
            Vector3 projectionDirection, List <IObject3D> scene, List <LightSource> lightSources, ImageF environmentMap,
            int depth, ref RayIntersectionResult rayIntersectionResult)
        {
            var refractDirection =
                Vector3.Normalize(
                    Refract(
                        projectionDirection, rayIntersectionResult.NormalVector,
                        rayIntersectionResult.Material.RefractiveIndex));

            var refractOrigin = Vector3.Dot(refractDirection, rayIntersectionResult.NormalVector) < 0
                ? rayIntersectionResult.HitPoint - rayIntersectionResult.NormalVector * 1e-3f
                : rayIntersectionResult.HitPoint + rayIntersectionResult.NormalVector * 1e-3f;

            return(CastRay(ref refractOrigin, ref refractDirection, scene, lightSources, environmentMap, depth + 1));
        }