public override bool Hit(Ray r, float tMin, float tMax, out HitRecord rec) { rec = new HitRecord(); HitRecord rec1, rec2; if (boundary.Hit(r, float.MinValue, float.MaxValue, out rec1)) { if (boundary.Hit(r, rec1.t + 0.0001f, float.MaxValue, out rec2)) { rec1.t = Mathf.Max(rec1.t, tMin); rec2.t = Mathf.Min(rec2.t, tMax); if (rec1.t >= rec2.t) { return(false); } rec1.t = Mathf.Max(rec1.t, 0); float distanceInsideBoundary = (rec2.t - rec1.t) * r.Direction.Length(); float hitDistance = -(1 / density) * Mathf.Log(Mathf.Randomfloat()); if (hitDistance < distanceInsideBoundary) { rec.t = rec1.t + hitDistance / r.Direction.Length(); rec.p = r.GetPoint(rec.t); rec.normal = new Vector3D(1, 0, 0); rec.matPtr = phaseFunction; return(true); } } } return(false); }
public bool Hit(Ray ray, float min, float max, out HitRecord r) { r = null; if (!_box.Hit(ray, min, max)) { return(false); } HitRecord leftHitRec = null; bool hitLeft = _left.Hit(ray, min, max, out leftHitRec); HitRecord rightHitRec = null; bool hitRight = _right.Hit(ray, min, max, out rightHitRec); if (hitLeft && hitRight) { r = leftHitRec.t < rightHitRec.t ? leftHitRec : rightHitRec; return(true); } else if (hitLeft) { r = leftHitRec; return(true); } else if (hitRight) { r = rightHitRec; return(true); } return(false); }
public override HitRecord Hit(Ray ray, float tMin, float tMax) { var origin = ray.Origin.ToSingleArray(); var dir = ray.Direction.ToSingleArray(); origin[0] = (CosTheta * ray.Origin.X) - (SinTheta * ray.Origin.Z); origin[2] = (SinTheta * ray.Origin.X) + (CosTheta * ray.Origin.Z); dir[0] = (CosTheta * ray.Direction.X) - (SinTheta * ray.Direction.Z); dir[2] = (SinTheta * ray.Direction.X) + (CosTheta * ray.Direction.Z); var rotatedRay = new Ray(new Vector3(origin[0], origin[1], origin[2]), new Vector3(dir[0], dir[1], dir[2])); var hitRecord = Hitable.Hit(rotatedRay, tMin, tMax); if (hitRecord == null) { return(null); } var p = hitRecord.P.ToSingleArray(); var normal = hitRecord.Normal.ToSingleArray(); p[0] = (CosTheta * hitRecord.P.X) + (SinTheta * hitRecord.P.Z); p[2] = (-SinTheta * hitRecord.P.X) + (CosTheta * hitRecord.P.Z); normal[0] = (CosTheta * hitRecord.Normal.X) + (SinTheta * hitRecord.Normal.Z); normal[2] = (-SinTheta * hitRecord.Normal.X) + (CosTheta * hitRecord.Normal.Z); return(new HitRecord(hitRecord.T, new Vector3(p[0], p[1], p[2]), new Vector3(normal[0], normal[1], normal[2]), hitRecord.UvCoords, hitRecord.Material)); }
public override bool Hit(Ray r, double tMin, double tMax, out HitRecord rec) { Vector3D origin = new Vector3D(r.Origin); Vector3D direction = new Vector3D(r.Direction); origin.X = cosTheta * r.Origin.X - sinTheta * r.Origin.Z; origin.Z = sinTheta * r.Origin.X + cosTheta * r.Origin.Z; direction.X = cosTheta * r.Direction.X - sinTheta * r.Direction.Z; direction.Z = sinTheta * r.Direction.X + cosTheta * r.Direction.Z; Ray rotatedR = new Ray(origin, direction, r.Time); if (ptr.Hit(rotatedR, tMin, tMax, out rec)) { Vector3D p = new Vector3D(rec.p); Vector3D normal = new Vector3D(rec.normal); p.X = cosTheta * rec.p.X + sinTheta * rec.p.Z; p.Z = -sinTheta * rec.p.X + cosTheta * rec.p.Z; normal.X = cosTheta * rec.normal.X + sinTheta * rec.normal.Z; normal.Z = -sinTheta * rec.normal.X + cosTheta * rec.normal.Z; rec.p = p; rec.normal = normal; return(true); } else { return(false); } }
public bool Hit(Ray ray, float min, float max, out HitRecord r) { vec3 origin = ray.position; vec3 direction = ray.direction; origin[0] = cos_theta * ray.position[0] - sin_theta * ray.position[2]; origin[2] = sin_theta * ray.position[0] + cos_theta * ray.position[2]; direction[0] = cos_theta * ray.direction[0] - sin_theta * ray.direction[2]; direction[2] = sin_theta * ray.direction[0] + cos_theta * ray.direction[2]; var rotated_r = new Ray(origin, direction, ray.time); if (_inner.Hit(rotated_r, min, max, out r)) { vec3 normal = r.normal; var x = cos_theta * r.point[0] + sin_theta * r.point[2]; var z = -sin_theta * r.point[0] + cos_theta * r.point[2]; r.point = new vec3(x, r.point.y, z); x = cos_theta * r.normal[0] + sin_theta * r.normal[2]; z = -sin_theta * r.normal[0] + cos_theta * r.normal[2]; r.normal = glm.normalize(new vec3(x, r.normal.y, z)); return(true); } else { return(false); } }
public static Vector3 RayCast(Ray ray, Hitable world, int depth) { Hit_record rec; float min = 0; float max = float.MaxValue; if (world.Hit(ray, ref min, ref max, out rec)) { Ray scattered = new Ray(); Vector3 attenuation = Vector3.one; if (depth < MaxDepth && rec.mat.Scatter(ref ray, ref rec, ref attenuation, ref scattered)) { var color = RayCast(scattered, world, depth + 1); attenuation.x *= color.x; attenuation.y *= color.y; attenuation.z *= color.z; return(attenuation); } else { return(Vector3.zero); } } else { Vector3 unit_direction = ray.direction.normalized; float t = 0.5f * (unit_direction.y + 1.0f); return(Vector3.Lerp(topColor, bottomColor, t)); } }
public override bool Hit(Ray ray, float t_min, float t_max, ref HitRecord rec) { var origin = new Vector3(ray.origin); var direction = new Vector3(ray.direction); origin[0] = cos_theta * ray.origin[0] - sin_theta * ray.origin[2]; origin[2] = sin_theta * ray.origin[0] + cos_theta * ray.origin[2]; direction[0] = cos_theta * ray.direction[0] - sin_theta * ray.direction[2]; direction[2] = sin_theta * ray.direction[0] + cos_theta * ray.direction[2]; var rotatedR = new Ray(origin, direction, ray.time); var r = new HitRecord(rec); if (Object.Hit(rotatedR, t_min, t_max, ref rec)) { var p = new Vector3(rec.p); var normal = new Vector3(rec.normal); p[0] = cos_theta * rec.p[0] + sin_theta * rec.p[2]; p[2] = -sin_theta * rec.p[0] + cos_theta * rec.p[2]; normal[0] = cos_theta * rec.normal[0] + sin_theta * rec.normal[2]; normal[2] = -sin_theta * rec.normal[0] + cos_theta * rec.normal[2]; rec.p = p; rec.normal = normal; return(true); } rec = r; return(false); }
Color color(Ray r, Hitable world, int depth) { //RaycastHit rh = new RaycastHit(); HitRecord hr = new HitRecord(); if (world.Hit(r, t_min, t_max, ref hr)) { Ray scattered; Color attenuation; if (depth < 50 && hr.material.scatter(r, ref hr, out attenuation, out scattered)) { return(attenuation * color(scattered, world, depth + 1)); } else { return(Color.black); } } else { Vector3 unit_direction = r.direction.normalized; float t = 0.5f * (unit_direction.y + 1f); return(Color.Lerp(c1, c2, t)); } }
public override void Hit(Ray ray, HitRecord hit) { if (!boundary_.Hit(ray, HitRecord.tMin, hit.t)) { return; } left_.Hit(ray, hit); right_.Hit(ray, hit); }
static vec3 RayTracing(Ray r, int depth) { HitRecord record; if (scene.Hit(r, 0.001f, 100000.0f, out record)) { Ray nextRay; var emmited = record.mat.Emitted(r, record, record.u, record.v, record.point); ScatterRecord sRecord; if (depth < 50 && record.mat.Scatter(r, record, out sRecord)) { //if(Exten.rand01() < 0.5) //{ // //hard code light // //554, 213, 343, 227, 332 // vec3 pointOnLight = new vec3(Exten.randRange(213, 343), 554, Exten.randRange(227, 332)); // vec3 toLight = pointOnLight - record.point; // if(glm.dot(toLight,record.normal) <= 0) // { // return emmited; // } // nextRay = new Ray(record.point, toLight, nextRay.time); // if(nextRay.direction.y <0.0001f) // { // return emmited; // } // float area = (343 - 213) * (332 - 227); // float l = toLight.length(); // pdf = l * l /(nextRay.direction.y * area); //} var mixturePdf = sRecord.pdf; //if (!mixturePdf.IsConst()) //{ // mixturePdf = new MixPDF(sRecord.pdf, _spherePDF, _spherePDF); //} var nextdir = mixturePdf.Generate(record.point, record.normal); nextRay = new Ray(record.point, nextdir, r.time); float pdf = mixturePdf.Value(nextRay, record.normal); var nextColor = RayTracing(nextRay, depth + 1); float scatterPdf = record.mat.Scatter_PDf(r, record, nextRay); return(emmited + sRecord.attenuation.mul(nextColor) * scatterPdf / pdf); } else { return(emmited); } } return(new vec3()); vec3 d = r.direction; float f = 0.5f * (d.y + 1.0f); return(0.3f * ((1 - f) * new vec3(1, 1, 1) + f * new vec3(0.5f, 0.7f, 1.0f))); }
public override bool Hit(Ray ray, float t_min, float t_max, ref HitRecord rec) { HitRecord rec1 = new HitRecord(), rec2 = new HitRecord(); if (boundary.Hit(ray, -float.MaxValue, float.MaxValue, ref rec1)) { if (boundary.Hit(ray, rec1.t + 0.0001f, float.MaxValue, ref rec2)) { rec1.t = Mathf.Range(rec1.t, t_min, t_max); if (rec1.t < t_min) { rec1.t = t_min; } if (rec2.t > t_max) { rec2.t = t_max; } if (rec1.t >= rec2.t) { return(false); } if (rec1.t < 0) { rec1.t = 0; } float distance_inside_boundary = (rec2.t - rec1.t) * ray.direction.length(); float hit_distance = -(1 / density) * Mathf.Log(Mathematics.Random.Get()); if (hit_distance < distance_inside_boundary) { rec.t = rec1.t + hit_distance / ray.direction.length(); rec.p = ray.GetPoint(rec.t); rec.normal = new Vector3(1, 0, 0); // arbitrary rec.shader = phase_function; return(true); } } } return(false); }
public bool Hit(Ray ray, float min, float max, out HitRecord r) { var newRay = new Ray(ray.position - _offset, ray.direction, ray.time); if (_inner.Hit(newRay, min, max, out r)) { r.point += _offset; return(true); } return(false); }
public override bool Hit(Ray ray, float t_min, float t_max, ref HitRecord rec) { var moved = new Ray(ray.origin - offset, ray.direction, ray.time); if (!Object.Hit(moved, t_min, t_max, ref rec)) { return(false); } rec.p += offset; return(true); }
public override bool Hit(Ray r, double tMin, double tMax, out HitRecord rec) { if (ptr.Hit(r, tMin, tMax, out rec)) { rec.normal = -rec.normal; return(true); } else { return(false); } }
public override bool Hit(Ray r, double tMin, double tMax, out HitRecord rec) { if (box.Hit(r, tMin, tMax)) { HitRecord leftRecord, rightRecord; bool hitLeft = left.Hit(r, tMin, tMax, out leftRecord); bool hitRight = right.Hit(r, tMin, tMax, out rightRecord); if (hitLeft && hitRight) { if (leftRecord.T < rightRecord.T) { rec = leftRecord; } else { rec = rightRecord; } return(true); } else if (hitLeft) { rec = leftRecord; return(true); } else if (hitRight) { rec = rightRecord; return(true); } else { rec.Material = null; rec.Normal = null; rec.P = null; rec.T = 0.0; rec.U = 0.0; rec.V = 0.0; return(false); } } else { rec.Material = null; rec.Normal = null; rec.P = null; rec.T = 0.0; rec.U = 0.0; rec.V = 0.0; return(false); } }
static Vector3 GetColor(Hitable world, Ray ray) { HitResult result = world.Hit(ray); Vector3 normal = result.Normal; if (result.IsHited) { return(new Vector3(0.5f * (normal.X + 1), 0.5f * (normal.Y + 1), 0.5f * (normal.Z + 1))); } return(Camera.GetSkyColor(ray)); }
public override bool Hit(Ray r, double tMin, double tMax, out HitRecord rec) { Ray movedR = new Ray(r.Origin - offset, r.Direction, r.Time); if (ptr.Hit(movedR, tMin, tMax, out rec)) { rec.p += offset; return(true); } else { return(false); } }
public static Vector3 GetColor(Ray ray, Hitable world) { HitRecord rec; float min = 0; float max = float.MaxValue; if (world.Hit(ray, ref min, ref max, out rec)) { return(0.5f * (rec.normal.normalized + Vector3.one)); } Vector3 unitDirection = ray.direction.normalized; float t = 0.5f * (unitDirection.y + 1); // -1~1 -> 0~1 return(Vector3.Lerp(topColor, bottomColor, t)); }
public override HitRecord Hit(Ray ray, float tMin, float tMax) { var movedRay = new Ray(ray.Origin - Displacement, ray.Direction); var hitRecord = Hitable.Hit(movedRay, tMin, tMax); if (hitRecord == null) { return(null); } return(new HitRecord( hitRecord.T, hitRecord.P + Displacement, hitRecord.Normal, hitRecord.UvCoords, hitRecord.Material)); }
public static Vector3 GetColor(Ray ray, Hitable world) { HitRecord rec; float min = 0; float max = float.MaxValue; if (world.Hit(ray, ref min, ref max, out rec)) { Vector3 target = rec.normal.normalized + RandomInUnitSphere(); return(0.5f * GetColor(new Ray(rec.hitPoint, target), world)); } Vector3 unitDirection = ray.direction.normalized; float t = 0.5f * (unitDirection.y + 1); // -1~1 -> 0~1 return(Vector3.Lerp(topColor, bottomColor, t)); }
public static Vector3 RayCast(Ray ray, Hitable world) { Hit_record rec; float min = 0; float max = float.MaxValue; if (world.Hit(ray, ref min, ref max, out rec)) { return(0.5f * (rec.normal.normalized + Vector3.one)); } else { Vector3 unit_direction = ray.direction.normalized; float t = 0.5f * (unit_direction.y + 1.0f); return(Vector3.Lerp(topColor, bottomColor, t)); } }
private void OnTriggerStay(Collider other) { rb.constraints = RigidbodyConstraints.FreezeAll; transform.parent = other.transform; GetComponent <Collider>().enabled = false; frozen = true; Hitable hitable = other.GetComponentInParent <Hitable>(); if (hitable != null) { Transform blood = Instantiate <Transform>(bloodSplatterPrefab, transform.position, transform.rotation); blood.Rotate(0, 180, 0); if (hitable.Alive) { hitable.Hit(); } } }
Color color(Ray r, Hitable world) { RaycastHit rh = new RaycastHit(); if (world.Hit(r, t_min, t_max, ref rh)) { //point射线与球面的交点,normal是球指向外的法线,point + normal表示与球面相切的单位球的圆心o //圆心o加上随机生成的单位球内的一个点s,可以模拟出随机反射方向 //最终得到以球面交点为起点,s-p为方向的射线,继续寻找射线接触的点 Vector3 target = rh.point + rh.normal + Common.random_int_unit_sphere(); Color c = atten * color(new Ray(rh.point, target - rh.point), world); c.a = 1;//atten的系数会影响aplha值 return(c); } Vector3 unit_direction = r.direction.normalized; float t = 0.5f * (unit_direction.y + 1f); return(Color.Lerp(c1, c2, t)); }
Color GetColor(Ray r, Hitable world) { HitRecord hrc = new HitRecord(); if (world.Hit(r, 0, float.MaxValue, hrc)) { Vector3 normal = r.PointAtParameter(hrc.t) - new Vector3(0, 0, -1); normal.Normalize(); Vector3 c = (normal + Vector3.one) * 0.5f; return(new Color(c.x, c.y, c.z)); } else { Vector3 unitDirection = r.direction; unitDirection.Normalize(); float c = 0.5f * (unitDirection.y + 1); Vector3 col = (1 - c) * Vector3.one + c * new Vector3(0.5f, 0.7f, 1.0f); return(new Color(col.x, col.y, col.z)); } }
public static Vector3 RayCast(Ray ray, Hitable world) { Hit_record rec; float min = 0; float max = float.MaxValue; if (world.Hit(ray, ref min, ref max, out rec)) { var target = rec.normal.normalized + new Vector3(Random.Range(-1, 1f), Random.Range(-1f, 1f), Random.Range(-1f, 1f)).normalized; return(0.5f * RayCast(new Ray(rec.hitpoint, target), world)); } else { Vector3 unit_direction = ray.direction.normalized; float t = 0.5f * (unit_direction.y + 1.0f); return(Vector3.Lerp(topColor, bottomColor, t)); } }
public override bool Hit(RTRay ray, float t_min, float t_max, out HitRecord rec) { rec = new HitRecord(); HitRecord hit; bool hitAnything = false; float t_closest = t_max; int numItems = list == null ? 0 : list.Count; for (int i = 0; i < numItems; ++i) { Hitable hitable = list[i]; if (hitable != null && hitable.Hit(ray, t_min, t_closest, out hit)) { hitAnything = true; t_closest = hit.t; rec = hit; } } return(hitAnything); }
public override bool Hit(Ray r, float tMin, float tMax, out HitRecord rec) { rec = new HitRecord(); if (box.Hit(r, tMin, tMax)) { HitRecord leftRec, rightRec; bool hitLeft = left.Hit(r, tMin, tMax, out leftRec); bool hitRight = right.Hit(r, tMin, tMax, out rightRec); if (hitLeft && hitRight) //击中重叠部分 { if (leftRec.t < rightRec.t) { rec = leftRec; //左子树在前 } else { rec = rightRec; //右子树在前 } return(true); } else if (hitLeft) { rec = leftRec; //击中左子树 return(true); } else if (hitRight) { rec = rightRec; //击中右子树 return(true); } else { return(false); } } else { return(false); //未击中任何物体 } }
static UnityEngine.Vector3 RayTracing(Ray r, int depth) { HitRecord record; Profiler.BeginSample("HitTest"); bool hited = scene.Hit(r, 0.001f, 100000.0f, out record); Profiler.EndSample(); if (hited) { Ray nextRay; UnityEngine.Vector3 color; Profiler.BeginSample("mat.Scatter"); bool isScattered = record.mat.Scatter(r, record.point, record.normal, out color, out nextRay); Profiler.EndSample(); if (depth < 50 && isScattered) { var nextColor = RayTracing(nextRay, depth + 1); Profiler.BeginSample("color multiply"); var c = new UnityEngine.Vector3(color.x * nextColor.x, color.y * nextColor.y, color.z * nextColor.z); Profiler.EndSample(); return(c); } else { Profiler.BeginSample("BlackColor"); var c = new UnityEngine.Vector3(); Profiler.EndSample(); return(c); } } Profiler.BeginSample("background"); UnityEngine.Vector3 d = r.direction; float f = 0.5f * (d.y + 1.0f); var backgroundColor = (1 - f) * new UnityEngine.Vector3(1, 1, 1) + f * new UnityEngine.Vector3(0.5f, 0.7f, 1.0f); Profiler.EndSample(); return(backgroundColor); }
public override bool Hit(Ray r, double tMin, double tMax, out HitRecord rec) { Vec3 origin = new Vec3(r.Origin()[0], r.Origin()[1], r.Origin()[2]); Vec3 direction = new Vec3(r.Direction()[0], r.Direction()[1], r.Direction()[2]); origin[0] = _cosTheta * r.Origin()[0] - _sinTheta * r.Origin()[2]; origin[2] = _sinTheta * r.Origin()[0] + _cosTheta * r.Origin()[2]; // TODO Check if this needs to be prefixed with a minus direction[0] = _cosTheta * r.Direction()[0] - _sinTheta * r.Direction()[2]; direction[2] = _sinTheta * r.Direction()[0] + _cosTheta * r.Direction()[2]; // TODO see above Ray rotatedR = new Ray(origin, direction, r.Time()); if (_hitable.Hit(rotatedR, tMin, tMax, out rec)) { Vec3 p = new Vec3(rec.P[0], rec.P[1], rec.P[2]); Vec3 normal = new Vec3(rec.Normal[0], rec.Normal[1], rec.Normal[2]); p[0] = _cosTheta * rec.P[0] + _sinTheta * rec.P[2]; p[2] = -_sinTheta * rec.P[0] + _cosTheta * rec.P[2]; normal[0] = _cosTheta * rec.Normal[0] + _sinTheta * rec.Normal[2]; normal[2] = -_sinTheta * rec.Normal[2] + _cosTheta * rec.Normal[2]; rec.P = p; rec.Normal = normal; return(true); } else { rec.P = null; rec.Normal = null; rec.T = 0; rec.U = 0; rec.V = 0; return(false); } }
public override bool Hit(ref Ray ray, float min, float max, ref HitRecord record) { if (m_BoundingBox.Hit(ref ray, min, max)) { var leftRecord = new HitRecord(); var rightRecord = new HitRecord(); var hitLeft = m_Left.Hit(ref ray, min, max, ref leftRecord); var hitRight = m_Right.Hit(ref ray, min, max, ref rightRecord); if (hitLeft && hitRight) { if (leftRecord.T < rightRecord.T) { record = leftRecord; } else { record = rightRecord; } return(true); } else if (hitLeft) { record = leftRecord; return(true); } else if (hitRight) { record = rightRecord; return(true); } } return(false); }