1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69
| Vector3f Scene::castRay(const Ray &ray, int depth) const {
Vector3f hitColor = this->backgroundColor; Intersection shade_point_inter = Scene::intersect(ray); if (shade_point_inter.happened) { Vector3f p = shade_point_inter.coords; Vector3f wo = ray.direction; Vector3f N = shade_point_inter.normal; Vector3f L_dir(0), L_indir(0);
Intersection light_point_inter; float pdf_light; sampleLight(light_point_inter, pdf_light); Vector3f x = light_point_inter.coords; Vector3f ws = normalize(x - p); Vector3f NN = light_point_inter.normal; Vector3f emit = light_point_inter.emit; float distance_pTox = (x - p).norm(); Vector3f p_deviation = (dotProduct(ray.direction, N) < 0) ? p + N * EPSILON : p - N * EPSILON;
Ray ray_pTox(p_deviation, ws); Intersection blocked_point_inter = Scene::intersect(ray_pTox); if (abs(distance_pTox - blocked_point_inter.distance < 0.01)) { L_dir = emit * shade_point_inter.m->eval(wo, ws, N) * dotProduct(ws, N) * dotProduct(-ws, NN) / (distance_pTox * distance_pTox * pdf_light); } float ksi = get_random_float(); if (ksi < RussianRoulette) { Vector3f wi = normalize(shade_point_inter.m->sample(wo, N)); Ray ray_pTowi(p_deviation, wi); Intersection bounce_point_inter = Scene::intersect(ray_pTowi); if (bounce_point_inter.happened && !bounce_point_inter.m->hasEmission()) { float pdf = shade_point_inter.m->pdf(wo, wi, N); if (pdf > EPSILON) L_indir = castRay(ray_pTowi, depth + 1) * shade_point_inter.m->eval(wo, wi, N) * dotProduct(wi, N) / (pdf * RussianRoulette); } } hitColor = shade_point_inter.m->getEmission() + L_dir + L_indir; } return hitColor; }
|