Changeset View
Changeset View
Standalone View
Standalone View
intern/cycles/kernel/kernel_path_surface.h
| Show First 20 Lines • Show All 64 Lines • ▼ Show 20 Lines | for(int i = 0; i < kernel_data.integrator.num_all_lights; i++) { | ||||
| ls.pdf *= 2.0f; | ls.pdf *= 2.0f; | ||||
| if(direct_emission(kg, sd, emission_sd, &ls, state, &light_ray, &L_light, &is_lamp, terminate)) { | if(direct_emission(kg, sd, emission_sd, &ls, state, &light_ray, &L_light, &is_lamp, terminate)) { | ||||
| /* trace shadow ray */ | /* trace shadow ray */ | ||||
| float3 shadow; | float3 shadow; | ||||
| if(!shadow_blocked(kg, emission_sd, state, &light_ray, &shadow)) { | if(!shadow_blocked(kg, emission_sd, state, &light_ray, &shadow)) { | ||||
| /* accumulate */ | /* accumulate */ | ||||
| path_radiance_accum_light(L, throughput*num_samples_inv, &L_light, shadow, num_samples_inv, state->bounce, is_lamp); | path_radiance_accum_light(L, state, throughput*num_samples_inv, &L_light, shadow, num_samples_inv, is_lamp); | ||||
| } | } | ||||
| else { | else { | ||||
| path_radiance_accum_total_light(L, throughput*num_samples_inv, &L_light); | path_radiance_accum_total_light(L, state, throughput*num_samples_inv, &L_light); | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| /* mesh light sampling */ | /* mesh light sampling */ | ||||
| if(kernel_data.integrator.pdf_triangles != 0.0f) { | if(kernel_data.integrator.pdf_triangles != 0.0f) { | ||||
| Show All 17 Lines | if(kernel_data.integrator.pdf_triangles != 0.0f) { | ||||
| ls.pdf *= 2.0f; | ls.pdf *= 2.0f; | ||||
| if(direct_emission(kg, sd, emission_sd, &ls, state, &light_ray, &L_light, &is_lamp, terminate)) { | if(direct_emission(kg, sd, emission_sd, &ls, state, &light_ray, &L_light, &is_lamp, terminate)) { | ||||
| /* trace shadow ray */ | /* trace shadow ray */ | ||||
| float3 shadow; | float3 shadow; | ||||
| if(!shadow_blocked(kg, emission_sd, state, &light_ray, &shadow)) { | if(!shadow_blocked(kg, emission_sd, state, &light_ray, &shadow)) { | ||||
| /* accumulate */ | /* accumulate */ | ||||
| path_radiance_accum_light(L, throughput*num_samples_inv, &L_light, shadow, num_samples_inv, state->bounce, is_lamp); | path_radiance_accum_light(L, state, throughput*num_samples_inv, &L_light, shadow, num_samples_inv, is_lamp); | ||||
| } | } | ||||
| else { | else { | ||||
| path_radiance_accum_total_light(L, throughput*num_samples_inv, &L_light); | path_radiance_accum_total_light(L, state, throughput*num_samples_inv, &L_light); | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| else { | else { | ||||
| /* sample one light at random */ | /* sample one light at random */ | ||||
| float light_t = path_state_rng_1D(kg, rng, state, PRNG_LIGHT); | float light_t = path_state_rng_1D(kg, rng, state, PRNG_LIGHT); | ||||
| float light_u, light_v; | float light_u, light_v; | ||||
| path_state_rng_2D(kg, rng, state, PRNG_LIGHT_U, &light_u, &light_v); | path_state_rng_2D(kg, rng, state, PRNG_LIGHT_U, &light_u, &light_v); | ||||
| float terminate = path_state_rng_light_termination(kg, rng, state); | float terminate = path_state_rng_light_termination(kg, rng, state); | ||||
| LightSample ls; | LightSample ls; | ||||
| if(light_sample(kg, light_t, light_u, light_v, sd->time, sd->P, state->bounce, &ls)) { | if(light_sample(kg, light_t, light_u, light_v, sd->time, sd->P, state->bounce, &ls)) { | ||||
| /* sample random light */ | /* sample random light */ | ||||
| if(direct_emission(kg, sd, emission_sd, &ls, state, &light_ray, &L_light, &is_lamp, terminate)) { | if(direct_emission(kg, sd, emission_sd, &ls, state, &light_ray, &L_light, &is_lamp, terminate)) { | ||||
| /* trace shadow ray */ | /* trace shadow ray */ | ||||
| float3 shadow; | float3 shadow; | ||||
| if(!shadow_blocked(kg, emission_sd, state, &light_ray, &shadow)) { | if(!shadow_blocked(kg, emission_sd, state, &light_ray, &shadow)) { | ||||
| /* accumulate */ | /* accumulate */ | ||||
| path_radiance_accum_light(L, throughput*num_samples_adjust, &L_light, shadow, num_samples_adjust, state->bounce, is_lamp); | path_radiance_accum_light(L, state, throughput*num_samples_adjust, &L_light, shadow, num_samples_adjust, is_lamp); | ||||
| } | } | ||||
| else { | else { | ||||
| path_radiance_accum_total_light(L, throughput*num_samples_adjust, &L_light); | path_radiance_accum_total_light(L, state, throughput*num_samples_adjust, &L_light); | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| #endif | #endif | ||||
| } | } | ||||
| /* branched path tracing: bounce off or through surface to with new direction stored in ray */ | /* branched path tracing: bounce off or through surface to with new direction stored in ray */ | ||||
| ccl_device bool kernel_branched_path_surface_bounce( | ccl_device bool kernel_branched_path_surface_bounce( | ||||
| KernelGlobals *kg, | KernelGlobals *kg, | ||||
| RNG *rng, | RNG *rng, | ||||
| ShaderData *sd, | ShaderData *sd, | ||||
| const ShaderClosure *sc, | const ShaderClosure *sc, | ||||
| int sample, | int sample, | ||||
| int num_samples, | int num_samples, | ||||
| ccl_addr_space float3 *throughput, | ccl_addr_space float3 *throughput, | ||||
| ccl_addr_space PathState *state, | ccl_addr_space PathState *state, | ||||
| PathRadiance *L, | PathRadiance *L, | ||||
| Ray *ray) | Ray *ray, | ||||
| float sum_sample_weight) | |||||
brecht: Indentation. | |||||
| { | { | ||||
| /* sample BSDF */ | /* sample BSDF */ | ||||
| float bsdf_pdf; | float bsdf_pdf; | ||||
| BsdfEval bsdf_eval; | BsdfEval bsdf_eval; | ||||
| float3 bsdf_omega_in; | float3 bsdf_omega_in; | ||||
| differential3 bsdf_domega_in; | differential3 bsdf_domega_in; | ||||
| float bsdf_u, bsdf_v; | float bsdf_u, bsdf_v; | ||||
| path_branched_rng_2D(kg, rng, state, sample, num_samples, PRNG_BSDF_U, &bsdf_u, &bsdf_v); | path_branched_rng_2D(kg, rng, state, sample, num_samples, PRNG_BSDF_U, &bsdf_u, &bsdf_v); | ||||
| int label; | int label; | ||||
| label = shader_bsdf_sample_closure(kg, sd, sc, bsdf_u, bsdf_v, &bsdf_eval, | label = shader_bsdf_sample_closure(kg, sd, sc, bsdf_u, bsdf_v, &bsdf_eval, | ||||
| &bsdf_omega_in, &bsdf_domega_in, &bsdf_pdf); | &bsdf_omega_in, &bsdf_domega_in, &bsdf_pdf); | ||||
| if(bsdf_pdf == 0.0f || bsdf_eval_is_zero(&bsdf_eval)) | if(bsdf_pdf == 0.0f || bsdf_eval_is_zero(&bsdf_eval)) | ||||
| return false; | return false; | ||||
| /* modify throughput */ | /* modify throughput */ | ||||
| path_radiance_bsdf_bounce(L, throughput, &bsdf_eval, bsdf_pdf, state->bounce, label); | path_radiance_bsdf_bounce(L, throughput, &bsdf_eval, bsdf_pdf, state->bounce, label); | ||||
| #ifdef __DENOISING_FEATURES__ | |||||
| state->denoising_feature_weight *= (sc->sample_weight / sum_sample_weight) * (1.0f / num_samples); | |||||
brechtUnsubmitted Not Done Inline Actionssc->sample_weight / (sum_sample_weight * num_samples) saves one division. I have some doubts about the correctness of this denoising_feature_weight though, as far as I can tell it does not take into account Russian roulette boosting the contribution of some BSDFs relative to others. I'm also a bit wary of adding another fragile tracking of contribution weights. Would it be possible to use average(throughput) as the weights for denoising depth/normal/albedo, sum these weights, and then do the normalization right before writing out the passes? brecht: `sc->sample_weight / (sum_sample_weight * num_samples)` saves one division.
I have some doubts… | |||||
| #endif | |||||
| /* modify path state */ | /* modify path state */ | ||||
| path_state_next(kg, state, label); | path_state_next(kg, state, label); | ||||
| /* setup ray */ | /* setup ray */ | ||||
| ray->P = ray_offset(sd->P, (label & LABEL_TRANSMIT)? -sd->Ng: sd->Ng); | ray->P = ray_offset(sd->P, (label & LABEL_TRANSMIT)? -sd->Ng: sd->Ng); | ||||
| ray->D = normalize(bsdf_omega_in); | ray->D = normalize(bsdf_omega_in); | ||||
| ray->t = FLT_MAX; | ray->t = FLT_MAX; | ||||
| #ifdef __RAY_DIFFERENTIALS__ | #ifdef __RAY_DIFFERENTIALS__ | ||||
| ▲ Show 20 Lines • Show All 66 Lines • ▼ Show 20 Lines | #endif | ||||
| if(light_sample(kg, light_t, light_u, light_v, sd->time, sd->P, state->bounce, &ls)) { | if(light_sample(kg, light_t, light_u, light_v, sd->time, sd->P, state->bounce, &ls)) { | ||||
| float terminate = path_state_rng_light_termination(kg, rng, state); | float terminate = path_state_rng_light_termination(kg, rng, state); | ||||
| if(direct_emission(kg, sd, emission_sd, &ls, state, &light_ray, &L_light, &is_lamp, terminate)) { | if(direct_emission(kg, sd, emission_sd, &ls, state, &light_ray, &L_light, &is_lamp, terminate)) { | ||||
| /* trace shadow ray */ | /* trace shadow ray */ | ||||
| float3 shadow; | float3 shadow; | ||||
| if(!shadow_blocked(kg, emission_sd, state, &light_ray, &shadow)) { | if(!shadow_blocked(kg, emission_sd, state, &light_ray, &shadow)) { | ||||
| /* accumulate */ | /* accumulate */ | ||||
| path_radiance_accum_light(L, throughput, &L_light, shadow, 1.0f, state->bounce, is_lamp); | path_radiance_accum_light(L, state, throughput, &L_light, shadow, 1.0f, is_lamp); | ||||
| } | } | ||||
| else { | else { | ||||
| path_radiance_accum_total_light(L, throughput, &L_light); | path_radiance_accum_total_light(L, state, throughput, &L_light); | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| #endif | #endif | ||||
| } | } | ||||
| /* path tracing: bounce off or through surface to with new direction stored in ray */ | /* path tracing: bounce off or through surface to with new direction stored in ray */ | ||||
| ccl_device bool kernel_path_surface_bounce(KernelGlobals *kg, | ccl_device bool kernel_path_surface_bounce(KernelGlobals *kg, | ||||
| ▲ Show 20 Lines • Show All 91 Lines • Show Last 20 Lines | |||||
Indentation.