public override Vector3 GetColor(ShadeRec sr) { float x = sr.LocalHitPoint.X; float y = sr.LocalHitPoint.Y; float z = sr.LocalHitPoint.Z; float x_size = b.X / num_x_checkers; // in radians - azimuth angle float z_size = a.Z / num_z_checkers; int i_phi = MathHelper.Floor(x / x_size); int i_theta = MathHelper.Floor(z / z_size); float f_phi = x / x_size - i_phi; float f_theta = z / z_size - i_theta; float phi_line_width = 0.5f * x_line_width; float theta_line_width = 0.5f * z_line_width; bool in_outline = (f_phi < phi_line_width || f_phi > 1.0 - phi_line_width) || (f_theta < theta_line_width || f_theta > 1.0 - theta_line_width); if ((i_phi + i_theta) % 2 == 0) { if (!in_outline) return (color1); } else { if (!in_outline) return (color2); } return (line_color); }
public override bool Hit(Ray ray, ref float tmin, ref ShadeRec sr) { if (bbox.Hit(ray)) return base.Hit(ray, ref tmin, ref sr); else return false; }
public override Vector3 Global_Shade(ShadeRec sr) { if (sr.Depth == 1) return (Vector3.Zero); else return ls * t.GetColor(sr); }
public override Vector3 Area_Light_Shade(ShadeRec sr) { Vector3 wo = -sr.Ray.Direction; Vector3 L = ambient.RHO(sr, wo) * sr.World.AmbientLight.L(sr); int num_lights = sr.World.Lights.Count; for (int j = 0; j < num_lights; j++) { Light light_ptr = sr.World.Lights[j]; Vector3 wi = light_ptr.GetDirection(sr); //compute_direction ? wi.Normalize(); float ndotwi = Vector3.Dot(sr.Normal, wi); float ndotwo = Vector3.Dot(sr.Normal, wo); if (ndotwi > 0.0 && ndotwo > 0.0) { bool in_shadow = false; if (sr.World.Lights[j].Shadows) { Ray shadow_ray = new Ray(sr.HitPoint, wi); in_shadow = light_ptr.InShadow(shadow_ray, sr); } if (!in_shadow) L += diffuse.F(sr, wo, wi) * light_ptr.L(sr) * light_ptr.G(sr) * ndotwi / sr.World.Lights[j].PDF(sr); } } return (L); }
public override Vector3 GetColor(ShadeRec sr) { float x = sr.LocalHitPoint.X - center.X; float y = sr.LocalHitPoint.Y - center.Y; float z = sr.LocalHitPoint.Z - center.Z; float phi = MathHelper.Atan2(x, z); float phi_size = 2 * MathHelper.PI / num_angular_checkers; float theta_size = radius / num_radial_checkers; float ra = MathHelper.Sqrt(x * x + z * z) / radius; int i_phi = MathHelper.Floor(phi / phi_size); int i_theta = MathHelper.Floor(ra / theta_size); float f_phi = phi / phi_size - i_phi; float f_theta = ra / theta_size - i_theta; float phi_line_width = 0.5f * angular_line_width; float theta_line_width = 0.5f * radial_line_width; bool in_outline = (f_phi < phi_line_width || f_phi > 1.0 - phi_line_width) || (f_theta < theta_line_width || f_theta > 1.0 - theta_line_width); if ((i_phi + i_theta) % 2 == 0) { if (!in_outline) return (color1); } else { if (!in_outline) return (color2); } return (line_color); }
public override bool Hit(Ray ray, ref float tmin, ref ShadeRec sr) { Vector3 v0 = (Mesh.Vertices[index0]); Vector3 v1 = (Mesh.Vertices[index1]); Vector3 v2 = (Mesh.Vertices[index2]); float a = v0.X - v1.X, b = v0.X - v2.X, c = ray.Direction.X, d = v0.X - ray.Position.X; float e = v0.Y - v1.Y, f = v0.Y - v2.Y, g = ray.Direction.Y, h = v0.Y - ray.Position.Y; float i = v0.Z - v1.Z, j = v0.Z - v2.Z, k = ray.Direction.Z, l = v0.Z - ray.Position.Z; float m = f * k - g * j, n = h * k - g * l, p = f * l - h * j; float q = g * i - e * k, s = e * j - f * i; float inv_denom = 1.0f / (a * m + b * q + c * s); float e1 = d * m - b * n - c * p; float beta = e1 * inv_denom; if (beta < 0.0) return (false); float r = e * l - h * i; float e2 = a * n + d * q + c * r; float gamma = e2 * inv_denom; if (gamma < 0.0) return (false); if (beta + gamma > 1.0) return (false); float e3 = a * p - b * r + d * s; float t = e3 * inv_denom; if (t < MathHelper.Epsilon) return (false); tmin = t; sr.Normal = interpolate_normal(beta, gamma); // for smooth shading sr.LocalHitPoint = ray.Position + t * ray.Direction; return (true); }
public override Vector3 Sample_F(ShadeRec sr, Vector3 wo, ref Vector3 wi, ref float pdf) { float ndotwo = Vector3.Dot(sr.Normal, wo); wi = -wo + 2.0f * sr.Normal * ndotwo; pdf = Vector3.AbsDot(sr.Normal, wi); return kr * cr.GetColor(sr); }
public override Vector3 Area_Light_Shade(ShadeRec sr) { Vector3 wo = -sr.Ray.Direction; Vector3 L = ambient.RHO(sr, wo) * sr.World.AmbientLight.L(sr); int num_lights = sr.World.Lights.Count; for (int j = 0; j < num_lights; j++) { Vector3 wi = sr.World.Lights[j].GetDirection(sr); float ndotwi = Vector3.Dot(sr.Normal, wi); if (ndotwi > 0.0) { if (Shadows) { bool in_shadow = false; if (sr.World.Lights[j].Shadows) { Ray shadowRay = new Ray(sr.HitPoint, wi); in_shadow = sr.World.Lights[j].InShadow(shadowRay, sr); } if (!in_shadow) L += (diffuse.F(sr, wo, wi) + specular.F(sr, wo, wi)) * sr.World.Lights[j].L(sr) * ndotwi * sr.World.Lights[j].G(sr) / sr.World.Lights[j].PDF(sr); } else { L += (diffuse.F(sr, wo, wi) + specular.F(sr, wo, wi)) * sr.World.Lights[j].L(sr) * ndotwi * sr.World.Lights[j].G(sr) / sr.World.Lights[j].PDF(sr); } } } return (L); }
public override Vector3 Area_Light_Shade(ShadeRec sr) { if (Vector3.Dot(-sr.Normal, sr.Ray.Direction) > 0.0f) //here may be ConcaveSphere not support return (Radiance * Color); else return (Vector3.Zero); }
public ShadeRec HitObjects(Ray ray) { ShadeRec sr = new ShadeRec(this); float t = 0; Vector3 normal = Vector3.Zero; Vector3 local_hit_point = Vector3.Zero; float tmin = float.MaxValue; int num_objects = Objects.Count; for (int j = 0; j < num_objects; j++) { if (Objects[j].Hit(ray, ref t, ref sr) && (t < tmin)) { sr.Hit_an_object = true; tmin = t; sr.Material = Objects[j].GetMaterial(); sr.HitPoint = ray.Position + t * ray.Direction; normal = sr.Normal; local_hit_point = sr.LocalHitPoint; } } if (sr.Hit_an_object) { sr.T = tmin; sr.Normal = normal; sr.LocalHitPoint = local_hit_point; } return (sr); }
public override Vector3 Shade(ShadeRec sr) { if (Vector3.Dot(-sr.Normal, sr.Ray.Direction) > 0.0f) return (Radiance * Color); else return (Vector3.Zero); }
public override Vector3 Sample_F(ShadeRec sr, Vector3 wo, ref Vector3 wi, ref float pdf) { float ndotwo = Vector3.Dot(sr.Normal, wo); wi = -wo + 2.0f * sr.Normal * ndotwo; pdf = MathHelper.Abs(Vector3.Dot(sr.Normal, wi)); return (ReflectionCoefficient * Color); }
public override bool Hit(Ray ray, ref float tmin, ref ShadeRec sr) { if (!bbox.Hit(ray)) return false; float t = 0; Vector3 normal = new Vector3(), local_hit_point = Vector3.Zero; bool hit = false; tmin = float.MaxValue; int num_objects = Objects.Count; for (int j = 0; j < num_objects; j++) if (Objects[j].Hit(ray, ref t,ref sr) && (t < tmin)) { hit = true; tmin = t; Material = Objects[j].GetMaterial(); normal = sr.Normal; local_hit_point = sr.LocalHitPoint; } if (hit) { sr.T = tmin; sr.Normal = normal; sr.LocalHitPoint = local_hit_point; } return (hit); }
public override bool Hit(Ray ray, ref float tmin, ref ShadeRec sr) { if (!bbox.Hit(ray)) return (false); float t = Vector3.Dot((center - ray.Position), normal) / Vector3.Dot(ray.Direction, normal); if (t <= MathHelper.Epsilon) return (false); Vector3 p = ray.Position + t * ray.Direction; float v = center.DistanceSquared(p); if (v < w_squared && v > i_squared) { double phi =MathHelper.Atan2(p.X, p.Z); if (phi < 0.0) phi += MathHelper.TwoPI; if (phi <= max_azimuth && phi >= min_azimuth) { tmin = t; sr.Normal = normal; sr.LocalHitPoint = p; return (true); } else return false; } else return (false); }
public override bool Hit(Ray ray, ref float tmin, ref ShadeRec sr) { float t; Vector3 temp = ray.Position - center; float a = Vector3.Dot(ray.Direction, ray.Direction); float b = 2.0f * Vector3.Dot(temp, ray.Direction); float c = Vector3.Dot(temp, temp) - radius * radius; float disc = b * b - 4.0f * a * c; if (disc < 0.0) return (false); else { float e = MathHelper.Sqrt(disc); float denom = 2.0f * a; t = (-b - e) / denom; if (t > MathHelper.BigEpsilon) { tmin = t; sr.Normal = -(temp + t * ray.Direction) / radius; sr.LocalHitPoint = ray.Position + t * ray.Direction; return (true); } t = (-b + e) / denom; if (t > MathHelper.BigEpsilon) { tmin = t; sr.Normal = -(temp + t * ray.Direction) / radius; sr.LocalHitPoint = ray.Position + t * ray.Direction; return (true); } } return (false); }
public override Vector3 GetColor(ShadeRec sr) { float x = sr.LocalHitPoint.X; float y = sr.LocalHitPoint.Y; float z = sr.LocalHitPoint.Z; float ph = y; float phi = MathHelper.Atan2(x, z); if (phi < 0.0) phi += 2.0f * MathHelper.PI; float phi_size = 2.0f * MathHelper.PI / num_horizontal_checkers; // in radians - azimuth angle float theta_size = h / num_vertical_checkers; // in radians - polar angle int i_phi = MathHelper.Floor(phi / phi_size); int i_theta = MathHelper.Floor(ph / theta_size); float f_phi = phi / phi_size - i_phi; float f_theta = ph / theta_size - i_theta; float phi_line_width = 0.5f * vertical_line_width; float theta_line_width = 0.5f * horizontal_line_width; bool in_outline = (f_phi < phi_line_width || f_phi > 1.0 - phi_line_width) || (f_theta < theta_line_width || f_theta > 1.0 - theta_line_width); if ((i_phi + i_theta) % 2 == 0) { if (!in_outline) return (color1); } else { if (!in_outline) return (color2); } return (line_color); }
internal static ShadeRec trace(Tracer tr, Ray ray) { ShadeRec sr = new ShadeRec(tr.World); float t = 0; Vector3 normal = Vector3.Zero; Vector3 local_hit_point = Vector3.Zero; float tmin = float.MaxValue; int num_objects = tr.World.Objects.Count; for (int j = 0; j < num_objects; j++) if (tr.World.Objects[j].Hit(ray, ref t, ref sr) && (t < tmin)) { sr.Hit_an_object = true; tmin = t; sr.Material = tr.World.Objects[j].Material; sr.HitPoint = ray.Position + t * ray.Direction; normal = sr.Normal; local_hit_point = sr.LocalHitPoint; } if (sr.Hit_an_object) { sr.T = tmin; sr.Normal = normal; sr.LocalHitPoint = local_hit_point; } return sr; }
public override bool Hit(Ray ray, ref float tmin, ref ShadeRec sr) { if (box.Hit(ray)) { return m.Hit(ray, ref tmin, ref sr); } return false; }
public override Vector3 Path_Shade(ShadeRec sr) { Vector3 wo = -sr.Ray.Direction; Vector3 wi = Vector3.Zero; float pdf = 0; Vector3 fr = reflective.Sample_F(sr, wo, ref wi, ref pdf); Ray reflected_ray = new Ray(sr.HitPoint, wi); return (fr * sr.World.Tracer.TraceRay(reflected_ray, sr.Depth + 1) * (sr.Normal * wi) / pdf); }
public override Vector3 GetDirection(ShadeRec sr) { float r = Radius; Vector3 new_location = Vector3.Zero; new_location.X = Location.X + r * (2.0f * MathHelper.RandomFloat() - 1.0f); new_location.Y = Location.Y + r * (2.0f * MathHelper.RandomFloat() - 1.0f); new_location.Z = Location.Z + r * (2.0f * MathHelper.RandomFloat() - 1.0f); return (Vector3.Normalize(new_location - sr.LocalHitPoint)); }
public override Vector3 GetDirection(ShadeRec sr) { Vector3 finaldir = Vector3.Zero; finaldir.X = Direction.X + r * (2.0f * MathHelper.RandomFloat() - 1.0f); finaldir.Y = Direction.Y + r * (2.0f * MathHelper.RandomFloat() - 1.0f); finaldir.Z = Direction.Z + r * (2.0f * MathHelper.RandomFloat() - 1.0f); finaldir.Normalize(); return finaldir; }
public bool TIR(ShadeRec sr) { Vector3 wo = (-sr.Ray.Direction); float cos_thetai = Vector3.Dot(sr.Normal, wo); float eta = eta_in / eta_out; if (cos_thetai < 0.0) eta = 1.0f / eta; return (1.0f - (1.0f - cos_thetai * cos_thetai) / (eta * eta) < 0.0f); }
public override bool Hit(Ray ray, ref float tmin, ref ShadeRec sr) { float t; Vector3 temp = ray.Position - center; float a = Vector3.Dot(ray.Direction, ray.Direction); float b = 2.0f * Vector3.Dot(temp, ray.Direction); float c = Vector3.Dot(temp, temp) - radius * radius; float disc = b * b - 4.0f * a * c; if (disc < 0.0) return (false); else { float e = MathHelper.Sqrt(disc); float denom = 2.0f * a; t = (-b - e) / denom; // smaller root if (t > MathHelper.Epsilon) { Vector3 hit = ray.Position + t * ray.Direction - center; float phi = MathHelper.Atan2(hit.X, hit.Z); if (phi < 0.0) phi += MathHelper.TwoPI; if (hit.Y <= radius * cos_theta_min && hit.Y >= radius * cos_theta_max && phi >= phi_min && phi <= phi_max) { tmin = t; sr.Normal = (temp + t * ray.Direction) / radius; // points outwards sr.LocalHitPoint = ray.Position + tmin * ray.Direction; return (true); } } t = (-b + e) / denom; // larger root if (t > MathHelper.Epsilon) { Vector3 hit = ray.Position + t * ray.Direction - center; float phi = MathHelper.Atan2(hit.X, hit.Z); if (phi < 0.0) phi += MathHelper.TwoPI; if (hit.Y <= radius * cos_theta_min && hit.Y >= radius * cos_theta_max && phi >= phi_min && phi <= phi_max) { tmin = t; sr.Normal = (temp + t * ray.Direction) / radius; // points outwards sr.LocalHitPoint = ray.Position + tmin * ray.Direction; return (true); } } } return (false); }
public override bool InShadow(Ray ray, ShadeRec sr) { float t = float.MaxValue; int num_objects = sr.World.Objects.Count; float d = Vector3.Distance(Location, (ray.Position)); for (int j = 0; j < num_objects; j++) if (sr.World.Objects[j].ShadowHit(ray, ref t) && t < d) return (true); return (false); }
public override Vector3 L(ShadeRec sr) { if (!DistanceAttenuation) return (Radiance * Color); else { float d = Vector3.Distance(sr.HitPoint, (Location)); return (Radiance * Color / (d * d)); } }
public override Vector3 F(ShadeRec sr, Vector3 wo, Vector3 wi) { Vector3 L = Vector3.Zero; float ndotwi = Vector3.Dot(sr.Normal, wi); Vector3 r = -wi + 2.0f * sr.Normal * ndotwi; float rdotwo = Vector3.Dot(r, wo); if (rdotwo > 0.0) L = ReflectionCoefficient * SpecularTexture.GetColor(sr) * MathHelper.Pow(rdotwo, Exponent); return (L); }
public override Vector3 GetDirection(ShadeRec sr) { w = sr.Normal; v = Vector3.Cross(new Vector3(0.0034f, 1, 0.0071f), w); v.Normalize(); u = Vector3.Cross(v, w); Vector3 sp = sampler.SampleHemisphere(); wi = sp.X * u + sp.Y * v + sp.Z * w; return (wi); }
public override bool InShadow(Ray ray, ShadeRec sr) { float t = float.MaxValue; // may be need an initialization int num_objects = sr.World.Objects.Count; float d = (Position - ray.Position).Length(); for (int j = 0; j < num_objects; j++) if (sr.World.Objects[j].ShadowHit(ray, ref t) && t < d) return (true); return (false); }
public override bool Hit(Ray ray, ref float tmin, ref ShadeRec sr) { float t; float ox = ray.Position.X; float oy = ray.Position.Y; float oz = ray.Position.Z; float dx = ray.Direction.X; float dy = ray.Direction.Y; float dz = ray.Direction.Z; float a = dx * dx + dz * dz; float b = 2.0f * (ox * dx + oz * dz); float c = ox * ox + oz * oz - radius * radius; float disc = b * b - 4.0f * a * c; if (disc < 0.0) return (false); else { float e = MathHelper.Sqrt(disc); float denom = 2.0f * a; t = (-b - e) / denom; // smaller root if (t > MathHelper.Epsilon) { float yhit = oy + t * dy; if (yhit > y0 && yhit < y1) { tmin = t; sr.Normal = new Vector3((ox + t * dx) * inv_radius, 0.0f, (oz + t * dz) * inv_radius); sr.Normal.Normalize(); if (Vector3.Dot(-ray.Direction, sr.Normal) < 0.0f) sr.Normal = -sr.Normal; sr.LocalHitPoint = ray.Position + tmin * ray.Direction; return (true); } } t = (-b + e) / denom; // larger root if (t > MathHelper.Epsilon) { float yhit = oy + t * dy; if (yhit > y0 && yhit < y1) { tmin = t; sr.Normal = new Vector3((ox + t * dx) * inv_radius, 0.0f, (oz + t * dz) * inv_radius); sr.Normal.Normalize(); if (Vector3.Dot(-ray.Direction, sr.Normal) < 0.0f) sr.Normal = -sr.Normal; sr.LocalHitPoint = ray.Position + tmin * ray.Direction; return (true); } } } return (false); }
public override bool InShadow(Ray ray, ShadeRec sr) { float t = float.MaxValue; int num_objects = sr.World.Objects.Count; for (int j = 0; j < num_objects; j++) { if (sr.World.Objects[j].ShadowHit(ray, ref t)) return true; } return (false); }