glm::vec3 radiance (const Ray & r, int iterations = 3) { float t = 1.0f; glm::vec3 normale, normale2; Object* o = intersect(r, t, normale); if (t == noIntersect) return glm::vec3(0,0,0); glm::vec3 pointIntersection = r.origin + t*r.direction; // Calcul pour les ombres douces, point aléatoire de lumière autour de scene::light float pdf = 0; glm::vec3 normaleSphereLumiere = glm::normalize(pointIntersection - scene::light); glm::vec3 vecLumiere = sample_sphere(10, random_u(), random_u(), pdf, normaleSphereLumiere); glm::vec3 light = scene::light + vecLumiere; glm::vec3 directionLum = light - pointIntersection; glm::vec3 directionLumNormalize = glm::normalize(directionLum); Ray rayLum{pointIntersection+directionLumNormalize*0.1f, directionLumNormalize}; intersect(rayLum, t, normale2); glm::vec3 direct(0,0,0); if (t*t > longueurCarree(directionLum)) { direct = o->direct(normale, directionLumNormalize) / (pdf*longueurCarree(directionLum)); } glm::vec3 indirect(0,0,0); if (iterations > 0) indirect = o->indirect(r.direction, pointIntersection, normale, iterations); return direct + indirect; }
glm::vec3 indirect(const glm::vec3 &c, const glm::vec3 &p, const glm::vec3 &n, const Diffuse &diffuse, int iterations) { float pdf; glm::vec3 directionRay = sample_sphere(1, random_u(), random_u(), pdf, n); Ray ray{p+directionRay*0.1f, directionRay}; return radiance(ray, iterations-1) * diffuse.color; }
glm::vec3 indirect(const Ray &rOrigine, const Ray &rReflect, const glm::vec3 &p, const glm::vec3 & n, int countdown, const Diffuse &diffuse) { float pdf; glm::vec3 w = glm::normalize(sample_sphere(1, random_u(), random_u(), pdf, n)); Ray rIndirect{p+0.1f*w, w}; return radiance(rIndirect, countdown); //return glm::vec3(0,0,0); }
/** Generate sample rays for AO * @param state global renderer state * @param sample_buffer sample buffer * @param isect_buffer hit buffer * @param ray_buffer sample ray buffer * @param mask_buffer the mask bitmap to write to * @param n_hits number of hits to work with */ void kernel_ao_gen_rays(state_t state, sample_t* sample_buffer, hit_t* isect_buffer, ray_t* ray_buffer, int* mask_buffer, int i) { //generate the sample if(isect_buffer[i].t == -1) { mask_buffer[i] = 1; } else { mask_buffer[i] = 0; vec3 d = sample_sphere(&sample_buffer[i]); if(dot(d,isect_buffer[i].n) < 0) { d = neg_vec3(d); } ray_buffer[i] = make_ray(isect_buffer[i].h, d); } }
__global__ void kernel_ao_gen_rays_gpu(state_t state, sample_t* sample_buffer, hit_t* isect_buffer, ray_t* ray_buffer, int* mask_buffer, int w) { int i = GET_INDEX(); if(isect_buffer[i].t == -1) { mask_buffer[i] = 1; } else { mask_buffer[i] = 0; vec3 d = sample_sphere(&sample_buffer[i]); if(dot(d,isect_buffer[i].n) < 0) { d = neg_vec3(d); } ray_buffer[i] = make_ray(isect_buffer[i].h, d); } }
// dirLux normalisé glm::vec3 random_light(const glm::vec3 dirLux, float &pdf) { float u = random_u(); float v = random_u(); return sample_sphere(10.f, u, v, pdf, -dirLux); }