Changeset View
Changeset View
Standalone View
Standalone View
intern/cycles/kernel/kernel_path.h
| Show First 20 Lines • Show All 127 Lines • ▼ Show 20 Lines | #endif | ||||
| return true; | return true; | ||||
| } | } | ||||
| #endif | #endif | ||||
| #if defined(__BRANCHED_PATH__) || defined(__SUBSURFACE__) | #if defined(__BRANCHED_PATH__) || defined(__SUBSURFACE__) | ||||
| ccl_device void kernel_branched_path_integrate_direct_lighting(KernelGlobals *kg, RNG *rng, | |||||
| ShaderData *sd, PathState *state, float3 throughput, float num_samples_adjust, PathRadiance *L) | |||||
| { | |||||
| /* sample illumination from lights to find path contribution */ | |||||
| if(sd->flag & SD_BSDF_HAS_EVAL) { | |||||
| Ray light_ray; | |||||
| BsdfEval L_light; | |||||
| bool is_lamp; | |||||
| #ifdef __OBJECT_MOTION__ | |||||
| light_ray.time = sd->time; | |||||
| #endif | |||||
| /* lamp sampling */ | |||||
| for(int i = 0; i < kernel_data.integrator.num_all_lights; i++) { | |||||
| int num_samples = ceil_to_int(num_samples_adjust*light_select_num_samples(kg, i)); | |||||
| float num_samples_inv = num_samples_adjust/(num_samples*kernel_data.integrator.num_all_lights); | |||||
| RNG lamp_rng = cmj_hash(*rng, i); | |||||
| if(kernel_data.integrator.pdf_triangles != 0.0f) | |||||
| num_samples_inv *= 0.5f; | |||||
| for(int j = 0; j < num_samples; j++) { | |||||
| float light_u, light_v; | |||||
| path_branched_rng_2D(kg, &lamp_rng, state, j, num_samples, PRNG_LIGHT_U, &light_u, &light_v); | |||||
| if(direct_emission(kg, sd, i, 0.0f, 0.0f, light_u, light_v, &light_ray, &L_light, &is_lamp, state->bounce)) { | |||||
| /* trace shadow ray */ | |||||
| float3 shadow; | |||||
| if(!shadow_blocked(kg, state, &light_ray, &shadow)) { | |||||
| /* accumulate */ | |||||
| path_radiance_accum_light(L, throughput*num_samples_inv, &L_light, shadow, num_samples_inv, state->bounce, is_lamp); | |||||
| } | |||||
| } | |||||
| } | |||||
| } | |||||
| /* mesh light sampling */ | |||||
| if(kernel_data.integrator.pdf_triangles != 0.0f) { | |||||
| int num_samples = ceil_to_int(num_samples_adjust*kernel_data.integrator.mesh_light_samples); | |||||
| float num_samples_inv = num_samples_adjust/num_samples; | |||||
| if(kernel_data.integrator.num_all_lights) | |||||
| num_samples_inv *= 0.5f; | |||||
| for(int j = 0; j < num_samples; j++) { | |||||
| float light_t = path_branched_rng_1D(kg, rng, state, j, num_samples, PRNG_LIGHT); | |||||
| float light_u, light_v; | |||||
| path_branched_rng_2D(kg, rng, state, j, num_samples, PRNG_LIGHT_U, &light_u, &light_v); | |||||
| /* only sample triangle lights */ | |||||
| if(kernel_data.integrator.num_all_lights) | |||||
| light_t = 0.5f*light_t; | |||||
| if(direct_emission(kg, sd, -1, light_t, 0.0f, light_u, light_v, &light_ray, &L_light, &is_lamp, state->bounce)) { | |||||
| /* trace shadow ray */ | |||||
| float3 shadow; | |||||
| if(!shadow_blocked(kg, state, &light_ray, &shadow)) { | |||||
| /* accumulate */ | |||||
| path_radiance_accum_light(L, throughput*num_samples_inv, &L_light, shadow, num_samples_inv, state->bounce, is_lamp); | |||||
| } | |||||
| } | |||||
| } | |||||
| } | |||||
| } | |||||
| } | |||||
| ccl_device void kernel_path_indirect(KernelGlobals *kg, RNG *rng, Ray ray, ccl_global float *buffer, | ccl_device void kernel_path_indirect(KernelGlobals *kg, RNG *rng, Ray ray, ccl_global float *buffer, | ||||
| float3 throughput, int num_samples, PathState state, PathRadiance *L) | float3 throughput, int num_samples, PathState state, PathRadiance *L) | ||||
| { | { | ||||
| /* path iteration */ | /* path iteration */ | ||||
| for(;;) { | for(;;) { | ||||
| /* intersect scene */ | /* intersect scene */ | ||||
| Intersection isect; | Intersection isect; | ||||
| uint visibility = path_state_ray_visibility(kg, &state); | uint visibility = path_state_ray_visibility(kg, &state); | ||||
| ▲ Show 20 Lines • Show All 152 Lines • ▼ Show 20 Lines | if(sd.flag & SD_BSSRDF) { | ||||
| subsurface_scatter_step(kg, &sd, state.flag, sc, &lcg_state, bssrdf_u, bssrdf_v, false); | subsurface_scatter_step(kg, &sd, state.flag, sc, &lcg_state, bssrdf_u, bssrdf_v, false); | ||||
| state.flag |= PATH_RAY_BSSRDF_ANCESTOR; | state.flag |= PATH_RAY_BSSRDF_ANCESTOR; | ||||
| } | } | ||||
| } | } | ||||
| #endif | #endif | ||||
| #ifdef __EMISSION__ | #ifdef __EMISSION__ | ||||
| if(kernel_data.integrator.use_direct_light) { | if(kernel_data.integrator.use_direct_light) | ||||
| /* sample illumination from lights to find path contribution */ | kernel_branched_path_integrate_direct_lighting(kg, rng, &sd, &state, throughput, 1.0f, L); | ||||
| if(sd.flag & SD_BSDF_HAS_EVAL) { | |||||
| float light_t = path_state_rng_1D(kg, rng, &state, PRNG_LIGHT); | |||||
| #ifdef __MULTI_CLOSURE__ | |||||
| float light_o = 0.0f; | |||||
| #else | |||||
| float light_o = path_state_rng_1D(kg, rng, &state, PRNG_LIGHT_F); | |||||
| #endif | |||||
| float light_u, light_v; | |||||
| path_state_rng_2D(kg, rng, &state, PRNG_LIGHT_U, &light_u, &light_v); | |||||
| Ray light_ray; | |||||
| BsdfEval L_light; | |||||
| bool is_lamp; | |||||
| #ifdef __OBJECT_MOTION__ | |||||
| light_ray.time = sd.time; | |||||
| #endif | |||||
| /* sample random light */ | |||||
| if(direct_emission(kg, &sd, -1, light_t, light_o, light_u, light_v, &light_ray, &L_light, &is_lamp, state.bounce)) { | |||||
| /* trace shadow ray */ | |||||
| float3 shadow; | |||||
| if(!shadow_blocked(kg, &state, &light_ray, &shadow)) { | |||||
| /* accumulate */ | |||||
| path_radiance_accum_light(L, throughput, &L_light, shadow, 1.0f, state.bounce, is_lamp); | |||||
| } | |||||
| } | |||||
| } | |||||
| } | |||||
| #endif | #endif | ||||
| /* no BSDF? we can stop here */ | /* no BSDF? we can stop here */ | ||||
| if(sd.flag & SD_BSDF) { | if(sd.flag & SD_BSDF) { | ||||
| /* sample BSDF */ | /* sample BSDF */ | ||||
| float bsdf_pdf; | float bsdf_pdf; | ||||
| BsdfEval bsdf_eval; | BsdfEval bsdf_eval; | ||||
| float3 bsdf_omega_in; | float3 bsdf_omega_in; | ||||
| ▲ Show 20 Lines • Show All 549 Lines • ▼ Show 20 Lines | |||||
| #ifdef __BRANCHED_PATH__ | #ifdef __BRANCHED_PATH__ | ||||
| ccl_device_noinline void kernel_branched_path_integrate_lighting(KernelGlobals *kg, | ccl_device_noinline void kernel_branched_path_integrate_lighting(KernelGlobals *kg, | ||||
| RNG *rng, ShaderData *sd, float3 throughput, float num_samples_adjust, | RNG *rng, ShaderData *sd, float3 throughput, float num_samples_adjust, | ||||
| PathState *state, PathRadiance *L, ccl_global float *buffer) | PathState *state, PathRadiance *L, ccl_global float *buffer) | ||||
| { | { | ||||
| #ifdef __EMISSION__ | #ifdef __EMISSION__ | ||||
| /* sample illumination from lights to find path contribution */ | kernel_branched_path_integrate_direct_lighting(kg, rng, sd, state, throughput, num_samples_adjust, L); | ||||
| if(sd->flag & SD_BSDF_HAS_EVAL) { | |||||
| Ray light_ray; | |||||
| BsdfEval L_light; | |||||
| bool is_lamp; | |||||
| #ifdef __OBJECT_MOTION__ | |||||
| light_ray.time = sd->time; | |||||
| #endif | |||||
| /* lamp sampling */ | |||||
| for(int i = 0; i < kernel_data.integrator.num_all_lights; i++) { | |||||
| int num_samples = ceil_to_int(num_samples_adjust*light_select_num_samples(kg, i)); | |||||
| float num_samples_inv = num_samples_adjust/(num_samples*kernel_data.integrator.num_all_lights); | |||||
| RNG lamp_rng = cmj_hash(*rng, i); | |||||
| if(kernel_data.integrator.pdf_triangles != 0.0f) | |||||
| num_samples_inv *= 0.5f; | |||||
| for(int j = 0; j < num_samples; j++) { | |||||
| float light_u, light_v; | |||||
| path_branched_rng_2D(kg, &lamp_rng, state, j, num_samples, PRNG_LIGHT_U, &light_u, &light_v); | |||||
| if(direct_emission(kg, sd, i, 0.0f, 0.0f, light_u, light_v, &light_ray, &L_light, &is_lamp, state->bounce)) { | |||||
| /* trace shadow ray */ | |||||
| float3 shadow; | |||||
| if(!shadow_blocked(kg, state, &light_ray, &shadow)) { | |||||
| /* accumulate */ | |||||
| path_radiance_accum_light(L, throughput*num_samples_inv, &L_light, shadow, num_samples_inv, state->bounce, is_lamp); | |||||
| } | |||||
| } | |||||
| } | |||||
| } | |||||
| /* mesh light sampling */ | |||||
| if(kernel_data.integrator.pdf_triangles != 0.0f) { | |||||
| int num_samples = ceil_to_int(num_samples_adjust*kernel_data.integrator.mesh_light_samples); | |||||
| float num_samples_inv = num_samples_adjust/num_samples; | |||||
| if(kernel_data.integrator.num_all_lights) | |||||
| num_samples_inv *= 0.5f; | |||||
| for(int j = 0; j < num_samples; j++) { | |||||
| float light_t = path_branched_rng_1D(kg, rng, state, j, num_samples, PRNG_LIGHT); | |||||
| float light_u, light_v; | |||||
| path_branched_rng_2D(kg, rng, state, j, num_samples, PRNG_LIGHT_U, &light_u, &light_v); | |||||
| /* only sample triangle lights */ | |||||
| if(kernel_data.integrator.num_all_lights) | |||||
| light_t = 0.5f*light_t; | |||||
| if(direct_emission(kg, sd, -1, light_t, 0.0f, light_u, light_v, &light_ray, &L_light, &is_lamp, state->bounce)) { | |||||
| /* trace shadow ray */ | |||||
| float3 shadow; | |||||
| if(!shadow_blocked(kg, state, &light_ray, &shadow)) { | |||||
| /* accumulate */ | |||||
| path_radiance_accum_light(L, throughput*num_samples_inv, &L_light, shadow, num_samples_inv, state->bounce, is_lamp); | |||||
| } | |||||
| } | |||||
| } | |||||
| } | |||||
| } | |||||
| #endif | #endif | ||||
| for(int i = 0; i< sd->num_closure; i++) { | for(int i = 0; i< sd->num_closure; i++) { | ||||
| const ShaderClosure *sc = &sd->closure[i]; | const ShaderClosure *sc = &sd->closure[i]; | ||||
| if(!CLOSURE_IS_BSDF(sc->type)) | if(!CLOSURE_IS_BSDF(sc->type)) | ||||
| continue; | continue; | ||||
| /* transparency is not handled here, but in outer loop */ | /* transparency is not handled here, but in outer loop */ | ||||
| ▲ Show 20 Lines • Show All 450 Lines • Show Last 20 Lines | |||||