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); }
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); }