/** * Framework function for debugging. * @param traceObj * @private */ #if DEBUG static void debug(TraceObj traceObj) { if (debugFunction != null) { if (traceObj.canPrint) { debugFunction(traceObj.toString()); } } loggerFunction?.Invoke(traceObj); }
bool Scatter(ref RaycastHit hit, ref Ray ray, ref TraceObj obj, out Color atten, out Ray scatter, out Color light, ref int rayCount) { var mat = obj.mat; light = Color.black; atten = default(Color); scatter = default(Ray); switch (mat.type) { case MaterialWrap.Type.Lambert: var hitpos = hit.point; var target = hitpos + hit.normal + Random.insideUnitSphere; scatter = new Ray(hitpos, (target - hitpos).normalized); atten = mat.albedo; return(true); case MaterialWrap.Type.Metal: var reflect = Vector3.Reflect(ray.direction, hit.normal); scatter = new Ray(hit.point, (reflect + mat.roughness * Random.insideUnitSphere).normalized); // 随机发射,模拟粗糙的表面 atten = mat.albedo; return(Vector3.Dot(reflect, hit.normal) > 0); case MaterialWrap.Type.Dielectric: atten = Color.white; float nint; Vector3 normal; float cosine; if (Vector3.Dot(ray.direction, hit.normal) > 0) { normal = -hit.normal; nint = mat.ri; cosine = mat.ri * Vector3.Dot(ray.direction, hit.normal); } else { normal = hit.normal; nint = 1 / mat.ri; cosine = -Vector3.Dot(ray.direction, hit.normal); } float reflProb; Vector3 refracted; if (Refract(ray.direction, normal, nint, out refracted)) { reflProb = Schlick(cosine, mat.ri); } else { reflProb = 1; } if (Random.Range(0, 1.0f) < reflProb) { scatter = new Ray(hit.point, Vector3.Reflect(ray.direction, hit.normal)); } else { scatter = new Ray(hit.point, refracted.normalized); } break; default: return(false); } return(true); }