public static Color32 GetColor(Ray r, HitableList hitableList, Hitable importance, int depth) { var hrec = new HitRecord(); if (hitableList.Hit(r, 0.00001f, float.MaxValue, ref hrec)) { var srec = new ScatterRecord(); var emitted = hrec.shader.emitted(r, hrec, hrec.u, hrec.v, hrec.p); if (depth < Configuration.MAX_SCATTER_TIME) { if (hrec.shader.scatter(r, ref hrec, ref srec)) { if (srec.is_specular) { return(srec.attenuation * GetColor(srec.specular_ray, Scene.main.world, importance, depth + 1)); } var p = new MixturePdf(new HitablePdf(importance, hrec.p), srec.pdf); var scattered = new Ray(hrec.p, p.Generate(), r.time); var pdf = p.Value(scattered.direction); return(emitted + srec.attenuation * hrec.shader.scattering_pdf(r, hrec, scattered) * GetColor(scattered, Scene.main.world, importance, depth + 1) / pdf); } else { return(depth == 0 ? emitted.Aravge() : emitted); } } else { return(depth == 0?emitted.Aravge():emitted); } } return(Scene.main.Skybox ? Scene.main.sky.Value(r.direction.Normalized()) : Color32.Black); #pragma warning disable CS0162 // 检测到无法访问的代码 var t = 0.5f * r.normal_direction.y + 1f; #pragma warning restore CS0162 // 检测到无法访问的代码 return(Scene.main.Skybox ? (1 - t) * new Color32(2, 2, 2) + t * new Color32(0.5f, 0.7f, 1) : Color32.Black); }
private ColorVector GetRayColor(Ray ray, IHitable world, PixelData pixelData, int depth) { Debug.WriteLine($"Depth: {depth}"); pixelData.SetDepth(depth); try { // the 0.001 corrects for the "shadow acne" HitRecord hr = world.Hit(ray, 0.001f, float.MaxValue); if (hr != null) { var emitted = hr.Material.Emitted(ray, hr, hr.UvCoords, hr.P); if (hr.Material is DiffuseLight) { Debug.WriteLine($"HIT A LIGHT. Emitted: {emitted}"); } if (depth < _renderConfig.RayTraceDepth) { var scatterResult = hr.Material.Scatter(ray, hr); if (scatterResult.IsScattered) { if (scatterResult.IsSpecular) { return(scatterResult.Attenuation * GetRayColor(scatterResult.SpecularRay, world, pixelData, depth + 1)); } else { var p0 = new HitablePdf(_lightHitable, hr.P); var p = new MixturePdf(p0, scatterResult.Pdf); var scattered = new Ray(hr.P, p.Generate()); float pdfValue = p.GetValue(scattered.Direction); var scatteringPdf = hr.Material.ScatteringPdf(ray, hr, scattered); if (scatteringPdf < 0.01f) { scatteringPdf = 0.01f; // //pdfValue = 1.0f; } { //pdfValue = 1.0f; } var depthRayColor = GetRayColor(scattered, world, pixelData, depth + 1); ColorVector recurseColor = ((scatterResult.Attenuation * scatteringPdf * depthRayColor) / pdfValue); Debug.WriteLine($"Attenuation ({scatterResult.Attenuation}) ScatteringPdf ({scatteringPdf}) DepthRayColor({depthRayColor}) PdfValue({pdfValue})"); Debug.WriteLine($"emitted: {emitted}"); Debug.WriteLine($"RecurseColor: {recurseColor}"); return(emitted + recurseColor); } } else { Debug.WriteLine("NOT SCATTERED"); } } return(emitted); } if (depth == 0) { Debug.WriteLine("depth at 0..."); } Debug.WriteLine("returning backgroundfunc"); return(_backgroundFunc(ray)); } finally { Debug.WriteLine($"Exiting Depth: {depth}"); } }