private Vector3D GetColor(Ray r, HitableList world, Hitable lightShape, int depth) { HitRecord hRec; /*这里的0.001不能改为0,当tmin设0的时候会导致,遍历hitlist时候,ray的t求解出来是0, * hit的时候全走了else,导致递归到50层的时候,最后return的是0,* attenuation结果还是0。 * 距离越远,散射用到random_in_unit_sphere生成的ray误差越大 */ if (world.Hit(r, 0.001f, float.MaxValue, out hRec)) { ScatterRecord sRec; Vector3D emitted = hRec.matPtr.Emitted(r, hRec, hRec.u, hRec.v, hRec.p); if (depth < 50 && hRec.matPtr.Scatter(r, hRec, out sRec)) { if (sRec.isSpecular) { Vector3D c = GetColor(sRec.specularRay, world, lightShape, depth + 1); return(new Vector3D(sRec.attenuation.X * c.X, sRec.attenuation.Y * c.Y, sRec.attenuation.Z * c.Z)); } HitablePDF p0 = new HitablePDF(lightShape, hRec.p); MixturePDF p = new MixturePDF(p0, sRec.pdfPtr); //CosinePDF p = new CosinePDF(hRec.normal); Ray scattered = new Ray(hRec.p, p.Generate(), r.Time); float pdfVal = p.Value(scattered.Direction); Vector3D color = GetColor(scattered, world, lightShape, depth + 1); //每次光线衰减之后深度加一 return(emitted + hRec.matPtr.ScatteringPDF(r, hRec, scattered) * new Vector3D(sRec.attenuation.X * color.X, sRec.attenuation.Y * color.Y, sRec.attenuation.Z * color.Z) / pdfVal); } else { return(emitted); } } else { if (isSky) { Vector3D unitDirection = r.Direction.UnitVector(); float t = 0.5f * (unitDirection.Y + 1f); return((1 - t) * new Vector3D(1, 1, 1) + t * new Vector3D(0.5f, 0.7f, 1)); } return(new Vector3D(0, 0, 0)); } }
private Vector3D GetColor(Ray r, HitableList world, int depth) { HitRecord rec; /*这里的0.001不能改为0,当tmin设0的时候会导致,遍历hitlist时候,ray的t求解出来是0, * hit的时候全走了else,导致递归到50层的时候,最后return的是0,* attenuation结果还是0。 * 距离越远,散射用到random_in_unit_sphere生成的ray误差越大 */ if (world.Hit(r, 0.001f, float.MaxValue, out rec)) { Ray scattered; Vector3D emitted = rec.matPtr.Emitted(r, rec, rec.u, rec.v, rec.p); Vector3D albedo; float pdfVal; if (depth < 50 && rec.matPtr.Scatter(r, rec, out albedo, out scattered, out pdfVal)) { Hitable lightSphape = new XZRect(213, 343, 227, 332, 554, new Lambertian()); HitablePDF p0 = new HitablePDF(lightSphape, rec.p); CosinePDF p1 = new CosinePDF(rec.normal); MixturePDF p = new MixturePDF(p0, p1); scattered = new Ray(rec.p, p.Generate(), r.Time); pdfVal = p.Value(scattered.Direction); Vector3D color = GetColor(scattered, world, depth + 1); //每次光线衰减之后深度加一 return(emitted + rec.matPtr.ScatteringPDF(r, rec, scattered) * new Vector3D(albedo.X * color.X, albedo.Y * color.Y, albedo.Z * color.Z) / pdfVal); } else { return(emitted); } } else { //Vector3D unitDirection = r.Direction.UnitVector(); //float t = 0.5f * (unitDirection.Y + 1f); //return (1 - t) * new Vector3D(1, 1, 1) + t * new Vector3D(0.5f, 0.7f, 1); return(new Vector3D(0, 0, 0)); } }