Changeset View
Changeset View
Standalone View
Standalone View
intern/cycles/kernel/kernel_path.h
| Context not available. | |||||
| #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, bool sample_all_lights) | |||||
| { | |||||
| /* 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 | |||||
| if(sample_all_lights) { | |||||
| /* 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); | |||||
| } | |||||
| } | |||||
| } | |||||
| } | |||||
| } | |||||
| else { | |||||
| float light_t = path_state_rng_1D(kg, rng, state, PRNG_LIGHT); | |||||
| float light_u, light_v; | |||||
| path_state_rng_2D(kg, rng, state, PRNG_LIGHT_U, &light_u, &light_v); | |||||
| /* sample random light */ | |||||
| 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, &L_light, shadow, 1.0f, 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) | ||||
| { | { | ||||
| Context not available. | |||||
| #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 */ | bool all = kernel_data.integrator.sample_all_lights_indirect; | ||||
| if(sd.flag & SD_BSDF_HAS_EVAL) { | kernel_branched_path_integrate_direct_lighting(kg, rng, &sd, &state, throughput, 1.0f, L, all); | ||||
| 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 | ||||
| Context not available. | |||||
| 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, true); | ||||
| 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++) { | ||||
| Context not available. | |||||