public override bool scatter(Ray r_in, Hit_Record rec, ref Vec3 attenuation, ref Ray scattered) { Vec3 reflected = Vec3.reflect(Vec3.unit_vector(r_in.direction()), rec.normal); scattered = new Ray(rec.p, reflected + fuzz * Vec3.random_in_unit_sphere()); attenuation = albedo; return(Vec3.dot(scattered.direction(), rec.normal) > 0.0f); }
public override bool hit(Ray r, float t_min, float t_max, ref Hit_Record rec) { Vec3 oc = r.origin() - center; float a = r.direction().x() * r.direction().x() + r.direction().z() * r.direction().z(); float b = 2.0f * (oc.x() * r.direction().x() + oc.z() * r.direction().z()); float c = oc.x() * oc.x() + oc.z() * oc.z() - radius * radius; float discriminant = b * b - 4 * a * c; if (discriminant > 0.0f) { float temp = (-b - (float)Math.Sqrt(b * b - 4 * a * c)) / (2 * a); if (temp < t_max && temp > t_min) { rec.t = temp; rec.p = r.point_at_parameter(rec.t); rec.normal = (rec.p - center) / radius; rec.normal[1] = 0.0f; rec.mat_type = mat_type; Helper.get_sphere_uv(rec.p, ref rec.u, ref rec.v); return(true); } temp = (-b + (float)Math.Sqrt(b * b - 4 * a * c)) / (2 * a); if (temp < t_max && temp > t_min) { rec.t = temp; rec.p = r.point_at_parameter(rec.t); rec.normal = (rec.p - center) / radius; rec.normal[1] = 0.0f; rec.mat_type = mat_type; Helper.get_sphere_uv(rec.p, ref rec.u, ref rec.v); return(true); } } return(false); }
public override bool hit(Ray r, float t_min, float t_max, ref Hit_Record rec) { // Perform a simplified Pythagorean in 3D to determine if // the ray vector intersects with the sphere. Vec3 oc = r.origin() - center; float a = Vec3.dot(r.direction()); float b = Vec3.dot(oc, r.direction()); float c = Vec3.dot(oc) - radius * radius; float discriminant = b * b - a * c; if (discriminant > 0.0f) { float temp = (-b - (float)Math.Sqrt(b * b - a * c)) / a; if (temp < t_max && temp > t_min) { rec.t = temp; rec.p = r.point_at_parameter(rec.t); rec.normal = (rec.p - center) / radius; rec.mat_type = mat_type; Helper.get_sphere_uv(rec.p, ref rec.u, ref rec.v); return(true); } temp = (-b + (float)Math.Sqrt(b * b - a * c)) / a; if (temp < t_max && temp > t_min) { rec.t = temp; rec.p = r.point_at_parameter(rec.t); rec.normal = (rec.p - center) / radius; rec.mat_type = mat_type; Helper.get_sphere_uv(rec.p, ref rec.u, ref rec.v); return(true); } } return(false); }
public override bool scatter(Ray r_in, Hit_Record rec, ref Vec3 attenuation, ref Ray scattered) { Vec3 outward_normal; Vec3 reflected = Vec3.reflect(r_in.direction(), rec.normal); float ni_over_nt; attenuation = color; Vec3 refracted = new Vec3(1.0f, 0.0f, 0.0f); float reflect_prob; float cosine; if (Vec3.dot(r_in.direction(), rec.normal) > 0.0f) { outward_normal = -rec.normal; ni_over_nt = ref_idx; cosine = ref_idx * Vec3.dot(r_in.direction(), rec.normal) / r_in.direction().length(); } else { outward_normal = rec.normal; ni_over_nt = 1.0f / ref_idx; cosine = -Vec3.dot(r_in.direction(), rec.normal) / r_in.direction().length(); } if (refract(r_in.direction(), outward_normal, ni_over_nt, ref refracted)) { reflect_prob = schlick(cosine, ref_idx); } else { scattered = new Ray(rec.p, reflected); reflect_prob = 1.0f; } if (Rng.f() < reflect_prob) { scattered = new Ray(rec.p, reflected); // reFLEcted } else { scattered = new Ray(rec.p, refracted); // reFRActed } return(true); }
public static Vec3 color(Ray r, int depth) { Hit_Record rec; rec.t = 0.0f; rec.u = rec.v = 0.0f; rec.p = null; rec.normal = null; rec.mat_type = null; if (world.hit(r, 0.001f, float.MaxValue, ref rec)) { Ray scattered = new Ray(); Vec3 attenuation = new Vec3(); Vec3 emitted = rec.mat_type.emitted(rec.u, rec.v, rec.p); if (depth < ConfigParams.max_bounces && rec.mat_type.scatter(r, rec, ref attenuation, ref scattered)) { // recursive call, finding color of each object hit return(emitted + attenuation * color(scattered, depth + 1)); } else { // too many bounces, or did not scatter (it absorbed the photon) //return new Vec3(0.0f, 0.0f, 0.0f); // return black return(emitted); } } else { // we hit nothing, so now hit the outer sky if (sky_active_flag) { Vec3 unit_direction = Vec3.unit_vector(r.direction()); // Return a linear interpolation of the sky, based on Y (vertical) // Higher is more white, lower is more blue-gray. float t = 0.5f * (unit_direction.y() + 1.0f); return((1.0f - t) * new Vec3(1.0f, 1.0f, 1.0f) + t * new Vec3(0.5f, 0.7f, 1.0f)); } return(new Vec3(0.0f, 0.0f, 0.0f)); // black sky } }