public Color CalcPixelColor(ref long seed, ref int maxDepth, int x, int y, PixelDebugData debug) { if (debug != null) { debug.Points.Add(Origin); } Color accumulateColor = Color.black; int c = debug == null ? AntiAliasRayCount : 1; for (int i = 0; i < c; ++i) { var offsetx = (debug == null ? SimpleRandom.RandNorm(ref seed) : 0.5f) * StepX; var offsety = (debug == null ? SimpleRandom.RandNorm(ref seed) : 0.5f) * StepY; var dir = new Vector4(StartX + x * StepX + offsetx, StartY + y * StepY + offsety, 1, 0); var dir2 = CameraLocal2World * dir; Ray ray = new Ray(Origin, dir2.normalized); accumulateColor += TraceScene(ref seed, ref maxDepth, ray, 0, debug); } Color col = accumulateColor / c; if (GammarCorrection) { col.r = Mathf.Sqrt(col.r); col.g = Mathf.Sqrt(col.g); col.b = Mathf.Sqrt(col.b); } col.a = 1; return(col); }
public bool Scatter(PixelDebugData debug, ref long seed, Ray rayIn, ref HitRecord hit, out Color atten, out Ray scattered) { switch (MatType) { case RayTracingMaterialType.Lambert: { Vector3 dir = hit.Normal * 1.0001f; if (debug == null) { dir += SimpleRandom.RandomInsideUnitSphere(ref seed); } Ray rayOut = new Ray(); rayOut.origin = hit.Point; rayOut.direction = Vector3.Normalize(dir); scattered = rayOut; atten = Albedo; return(true); } case RayTracingMaterialType.Metal: { Vector3 dir = Reflect(rayIn.direction, hit.Normal); Ray rayOut = new Ray(); rayOut.origin = hit.Point; rayOut.direction = Vector3.Normalize(dir); scattered = rayOut; atten = Albedo; return(Vector3.Dot(rayOut.direction, hit.Normal) > 0); } case RayTracingMaterialType.Dielectric: { Vector3 N = hit.Normal; Vector3 R = Reflect(rayIn.direction, N); atten = Color.white; float ni_over_nt = Mathf.Max(0.1f, RefractionIndex); if (Vector3.Dot(rayIn.direction, N) > 0) { // Ray travel through inside N = -N; } else { // Ray comming from outside ni_over_nt = 1.0f / ni_over_nt; } Vector3 refracted; float reflect_prob = 1.0f; if (Refract(rayIn.direction, N, ni_over_nt, out refracted)) { reflect_prob = Schlick(Vector3.Dot(N, -rayIn.direction), RefractionIndex); } if (SimpleRandom.RandNorm(ref seed) < reflect_prob) { scattered = new Ray(hit.Point, R); } else { scattered = new Ray(hit.Point, refracted); } return(true); } } atten = Color.black; scattered = new Ray(); return(false); }