Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- static vec4f trace_naive(const ptr::scene* scene, const ray3f& ray_,
- rng_state& rng, const trace_params& params) {
- // YOUR CODE GOES HERE ------------------------------------------------------
- // initialize
- auto radiance = zero3f;
- auto weight = vec3f{1, 1, 1};
- auto ray = ray_;
- auto hit = false;
- // trace path
- for (auto bounce : range(params.bounces)) {
- // intersect next point
- auto intersection = intersect_scene_bvh(scene, ray);
- if (!intersection.hit) {
- radiance += weight * eval_environment(scene, ray);
- break;
- }
- // prepare shading point
- auto outgoing = -ray.d;
- auto object = scene->objects[intersection.object];
- auto element = intersection.element;
- auto uv = intersection.uv;
- auto position = eval_position(object, element, uv);
- auto normal = eval_shading_normal(object, element, uv, outgoing);
- auto emission = eval_emission(object, element, uv, normal, outgoing);
- auto brdf = eval_brdf(object, element, uv, normal, outgoing);
- // handle opacity
- if (brdf.opacity < 1 && rand1f(rng) >= brdf.opacity) {
- ray = {position + ray.d * 1e-2f, ray.d};
- bounce -= 1;
- continue;
- }
- hit = true;
- // accumulate emission
- radiance += weight * eval_emission(emission, normal, outgoing);
- vec3f incoming = zero3f; //initialize incoming
- // next direction
- if (!is_delta(brdf)) { // sample smooth brdfs (fold cos into f)
- incoming = sample_brdfcos(brdf, normal, outgoing, rand1f(rng), rand2f(rng)); // incoming
- weight *= eval_brdfcos(brdf, normal, incoming, outgoing) /
- sample_brdfcos_pdf(brdf, normal, incoming, outgoing);
- } else { // sample sharp brdfs
- incoming = sample_delta(brdf, normal, outgoing, rand1f(rng)); // incoming
- weight *= eval_delta(brdf, normal, incoming, outgoing) /
- sample_delta_pdf(brdf, normal, incoming, outgoing);
- }
- // check weight
- if (weight == zero3f || !isfinite(weight)) break;
- // russian roulette
- if (max(weight) < 1 && bounce > 3) {
- auto rr_prob = max((float)0.05, 1 - max(weight));
- if (rand1f(rng) > rr_prob) break;
- weight *= 1 / rr_prob;
- }
- // setup next iteration
- ray = {position, incoming};
- }
- return {radiance, hit ? 1.0f : 0.0f};
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement