예제 #1
0
        public Point RayTrace(Ray r, int iter, float env)
        {
            if (iter <= 0)
            {
                return(new Point(0, 0, 0));
            }

            float    t                     = 0; // позиция точки пересечения луча с фигурой на луче
            Point    normal                = null;
            Material m                     = new Material();
            Point    res_color             = new Point(0, 0, 0);
            bool     refract_out_of_figure = false;
            float    intersect;
            Point    n;

            foreach (Shape fig in scene)
            {
                if (fig.figure_intersection(r, out intersect, out n))
                {
                    if (intersect < t || t == 0)   // нужна ближайшая фигура к точке наблюдения
                    {
                        t      = intersect;
                        normal = n;
                        m      = new Material(fig.figure_material);
                    }
                }
            }

            if (t == 0)
            {
                return(new Point(0, 0, 0));
            }

            if (Point.scalar(r.direction, normal) > 0)
            {
                normal *= -1;
                refract_out_of_figure = true;
            }

            Point hit_point = r.start + r.direction * t;

            foreach (Light l in lights)
            {
                Point amb = l.color_light * m.ambient;
                amb.x      = (amb.x * m.clr.x);
                amb.y      = (amb.y * m.clr.y);
                amb.z      = (amb.z * m.clr.z);
                res_color += amb;

                // диффузное освещение
                if (is_visible(l.point_light, hit_point))
                {
                    res_color += l.shade(hit_point, normal, m.clr, m.diffuse);
                }
            }

            if (m.reflection > 0)
            {
                Ray reflected_ray = r.reflect(hit_point, normal);
                res_color += m.reflection * RayTrace(reflected_ray, iter - 1, env);
            }

            if (m.refraction > 0)
            {
                float eta = 0;
                if (refract_out_of_figure)
                {
                    eta = m.environment;
                }
                else
                {
                    eta = 1 / m.environment;
                }

                Ray refracted_ray = r.refract(hit_point, normal, eta);
                if (refracted_ray != null)
                {
                    res_color += m.refraction * RayTrace(refracted_ray, iter - 1, m.environment);
                }
            }

            return(res_color);
        }
예제 #2
0
        public Point3D RayTrace(Ray r, int iter, float env)
        {
            if (iter <= 0)
            {
                return(new Point3D(0, 0, 0));
            }

            float    t                     = 0; // позиция точки пересечения луча с фигурой на луче
            Point3D  normal                = null;
            Material m                     = new Material();
            Point3D  res_color             = new Point3D(0, 0, 0);
            bool     refract_out_of_figure = false; //  луч преломления выходит из объекта?

            foreach (Figure fig in scene)
            {
                if (fig.figure_intersection(r, out float intersect, out Point3D n))
                {
                    if (intersect < t || t == 0)     // нужна ближайшая фигура к точке наблюдения
                    {
                        t      = intersect;
                        normal = n;
                        m      = new Material(fig.figure_material);
                    }
                }
            }

            if (t == 0)
            {
                return(new Point3D(0, 0, 0));
            }
            //если угол между нормалью к поверхности объекта и направлением луча положительный, => угол острый, => луч выходит из объекта в среду
            if (Point3D.scalar(r.direction, normal) > 0)
            {
                normal *= -1;
                refract_out_of_figure = true;
            }

            Point3D hit_point = r.start + r.direction * t;

            foreach (Light l in lights)
            {
                Point3D amb = l.color_light * m.ambient;
                amb.x      = (amb.x * m.clr.x);
                amb.y      = (amb.y * m.clr.y);
                amb.z      = (amb.z * m.clr.z);
                res_color += amb;

                // диффузное освещение
                if (is_visible(l.point_light, hit_point))
                {
                    res_color += l.shade(hit_point, normal, m.clr, m.diffuse);
                }
            }

            if (m.reflection > 0)
            {
                Ray reflected_ray = r.reflect(hit_point, normal);
                res_color += m.reflection * RayTrace(reflected_ray, iter - 1, env);
            }

            if (m.refraction > 0)
            {
                float eta;                 //коэффициент преломления
                if (refract_out_of_figure) //луч выходит в среду
                {
                    eta = m.environment;
                }
                else
                {
                    eta = 1 / m.environment;
                }

                Ray refracted_ray = r.refract(hit_point, normal, eta);
                if (refracted_ray != null)
                {
                    res_color += m.refraction * RayTrace(refracted_ray, iter - 1, m.environment);
                }
            }

            return(res_color);
        }