|
|
|
@@ -59,28 +59,28 @@ ccl_device void kernel_lamp_emission(
|
|
|
|
|
IS_STATE(ray_state, ray_index, RAY_HIT_BACKGROUND))
|
|
|
|
|
{
|
|
|
|
|
PathRadiance *L = &PathRadiance_coop[ray_index];
|
|
|
|
|
ccl_global PathState *state = &PathState_coop[ray_index];
|
|
|
|
|
|
|
|
|
|
float3 throughput = throughput_coop[ray_index];
|
|
|
|
|
Ray ray = Ray_coop[ray_index];
|
|
|
|
|
PathState state = PathState_coop[ray_index];
|
|
|
|
|
|
|
|
|
|
#ifdef __LAMP_MIS__
|
|
|
|
|
if(kernel_data.integrator.use_lamp_mis && !(state.flag & PATH_RAY_CAMERA)) {
|
|
|
|
|
if(kernel_data.integrator.use_lamp_mis && !(state->flag & PATH_RAY_CAMERA)) {
|
|
|
|
|
/* ray starting from previous non-transparent bounce */
|
|
|
|
|
Ray light_ray;
|
|
|
|
|
|
|
|
|
|
light_ray.P = ray.P - state.ray_t*ray.D;
|
|
|
|
|
state.ray_t += Intersection_coop[ray_index].t;
|
|
|
|
|
light_ray.P = ray.P - state->ray_t*ray.D;
|
|
|
|
|
state->ray_t += Intersection_coop[ray_index].t;
|
|
|
|
|
light_ray.D = ray.D;
|
|
|
|
|
light_ray.t = state.ray_t;
|
|
|
|
|
light_ray.t = state->ray_t;
|
|
|
|
|
light_ray.time = ray.time;
|
|
|
|
|
light_ray.dD = ray.dD;
|
|
|
|
|
light_ray.dP = ray.dP;
|
|
|
|
|
/* intersect with lamp */
|
|
|
|
|
float3 emission;
|
|
|
|
|
|
|
|
|
|
if(indirect_lamp_emission(kg, &state, &light_ray, &emission, sd)) {
|
|
|
|
|
path_radiance_accum_emission(L, throughput, emission, state.bounce);
|
|
|
|
|
if(indirect_lamp_emission(kg, state, &light_ray, &emission, sd)) {
|
|
|
|
|
path_radiance_accum_emission(L, throughput, emission, state->bounce);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
#endif /* __LAMP_MIS__ */
|
|
|
|
@@ -89,14 +89,14 @@ ccl_device void kernel_lamp_emission(
|
|
|
|
|
#if 0
|
|
|
|
|
#ifdef __VOLUME__
|
|
|
|
|
/* volume attenuation, emission, scatter */
|
|
|
|
|
if(state.volume_stack[0].shader != SHADER_NONE) {
|
|
|
|
|
if(state->volume_stack[0].shader != SHADER_NONE) {
|
|
|
|
|
Ray volume_ray = ray;
|
|
|
|
|
volume_ray.t = (hit)? isect.t: FLT_MAX;
|
|
|
|
|
|
|
|
|
|
bool heterogeneous = volume_stack_is_heterogeneous(kg, state.volume_stack);
|
|
|
|
|
bool heterogeneous = volume_stack_is_heterogeneous(kg, state->volume_stack);
|
|
|
|
|
|
|
|
|
|
#ifdef __VOLUME_DECOUPLED__
|
|
|
|
|
int sampling_method = volume_stack_sampling_method(kg, state.volume_stack);
|
|
|
|
|
int sampling_method = volume_stack_sampling_method(kg, state->volume_stack);
|
|
|
|
|
bool decoupled = kernel_volume_use_decoupled(kg, heterogeneous, true, sampling_method);
|
|
|
|
|
|
|
|
|
|
if(decoupled) {
|
|
|
|
@@ -104,15 +104,15 @@ ccl_device void kernel_lamp_emission(
|
|
|
|
|
VolumeSegment volume_segment;
|
|
|
|
|
ShaderData volume_sd;
|
|
|
|
|
|
|
|
|
|
shader_setup_from_volume(kg, &volume_sd, &volume_ray, state.bounce, state.transparent_bounce);
|
|
|
|
|
kernel_volume_decoupled_record(kg, &state,
|
|
|
|
|
shader_setup_from_volume(kg, &volume_sd, &volume_ray);
|
|
|
|
|
kernel_volume_decoupled_record(kg, state,
|
|
|
|
|
&volume_ray, &volume_sd, &volume_segment, heterogeneous);
|
|
|
|
|
|
|
|
|
|
volume_segment.sampling_method = sampling_method;
|
|
|
|
|
|
|
|
|
|
/* emission */
|
|
|
|
|
if(volume_segment.closure_flag & SD_EMISSION)
|
|
|
|
|
path_radiance_accum_emission(&L, throughput, volume_segment.accum_emission, state.bounce);
|
|
|
|
|
path_radiance_accum_emission(&L, throughput, volume_segment.accum_emission, state->bounce);
|
|
|
|
|
|
|
|
|
|
/* scattering */
|
|
|
|
|
VolumeIntegrateResult result = VOLUME_PATH_ATTENUATED;
|
|
|
|
@@ -122,16 +122,16 @@ ccl_device void kernel_lamp_emission(
|
|
|
|
|
|
|
|
|
|
/* direct light sampling */
|
|
|
|
|
kernel_branched_path_volume_connect_light(kg, rng, &volume_sd,
|
|
|
|
|
throughput, &state, &L, 1.0f, all, &volume_ray, &volume_segment);
|
|
|
|
|
throughput, state, &L, 1.0f, all, &volume_ray, &volume_segment);
|
|
|
|
|
|
|
|
|
|
/* indirect sample. if we use distance sampling and take just
|
|
|
|
|
* one sample for direct and indirect light, we could share
|
|
|
|
|
* this computation, but makes code a bit complex */
|
|
|
|
|
float rphase = path_state_rng_1D_for_decision(kg, rng, &state, PRNG_PHASE);
|
|
|
|
|
float rscatter = path_state_rng_1D_for_decision(kg, rng, &state, PRNG_SCATTER_DISTANCE);
|
|
|
|
|
float rphase = path_state_rng_1D_for_decision(kg, rng, state, PRNG_PHASE);
|
|
|
|
|
float rscatter = path_state_rng_1D_for_decision(kg, rng, state, PRNG_SCATTER_DISTANCE);
|
|
|
|
|
|
|
|
|
|
result = kernel_volume_decoupled_scatter(kg,
|
|
|
|
|
&state, &volume_ray, &volume_sd, &throughput,
|
|
|
|
|
state, &volume_ray, &volume_sd, &throughput,
|
|
|
|
|
rphase, rscatter, &volume_segment, NULL, true);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@@ -142,7 +142,7 @@ ccl_device void kernel_lamp_emission(
|
|
|
|
|
kernel_volume_decoupled_free(kg, &volume_segment);
|
|
|
|
|
|
|
|
|
|
if(result == VOLUME_PATH_SCATTERED) {
|
|
|
|
|
if(kernel_path_volume_bounce(kg, rng, &volume_sd, &throughput, &state, &L, &ray))
|
|
|
|
|
if(kernel_path_volume_bounce(kg, rng, &volume_sd, &throughput, state, &L, &ray))
|
|
|
|
|
continue;
|
|
|
|
|
else
|
|
|
|
|
break;
|
|
|
|
@@ -154,15 +154,15 @@ ccl_device void kernel_lamp_emission(
|
|
|
|
|
/* integrate along volume segment with distance sampling */
|
|
|
|
|
ShaderData volume_sd;
|
|
|
|
|
VolumeIntegrateResult result = kernel_volume_integrate(
|
|
|
|
|
kg, &state, &volume_sd, &volume_ray, &L, &throughput, rng, heterogeneous);
|
|
|
|
|
kg, state, &volume_sd, &volume_ray, &L, &throughput, rng, heterogeneous);
|
|
|
|
|
|
|
|
|
|
#ifdef __VOLUME_SCATTER__
|
|
|
|
|
if(result == VOLUME_PATH_SCATTERED) {
|
|
|
|
|
/* direct lighting */
|
|
|
|
|
kernel_path_volume_connect_light(kg, rng, &volume_sd, throughput, &state, &L);
|
|
|
|
|
kernel_path_volume_connect_light(kg, rng, &volume_sd, throughput, state, &L);
|
|
|
|
|
|
|
|
|
|
/* indirect light bounce */
|
|
|
|
|
if(kernel_path_volume_bounce(kg, rng, &volume_sd, &throughput, &state, &L, &ray))
|
|
|
|
|
if(kernel_path_volume_bounce(kg, rng, &volume_sd, &throughput, state, &L, &ray))
|
|
|
|
|
continue;
|
|
|
|
|
else
|
|
|
|
|
break;
|
|
|
|
|