Cycles: Remove few function arguments needed only for the split kernel
[blender.git] / intern / cycles / kernel / split / kernel_lamp_emission.h
1 /*
2  * Copyright 2011-2015 Blender Foundation
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16
17 #include "kernel_split_common.h"
18
19 /* Note on kernel_lamp_emission
20  * This is the 3rd kernel in the ray-tracing logic. This is the second of the
21  * path-iteration kernels. This kernel takes care of the indirect lamp emission logic.
22  * This kernel operates on QUEUE_ACTIVE_AND_REGENERATED_RAYS. It processes rays of state RAY_ACTIVE
23  * and RAY_HIT_BACKGROUND.
24  * We will empty QUEUE_ACTIVE_AND_REGENERATED_RAYS queue in this kernel.
25  * The input/output of the kernel is as follows,
26  * Throughput_coop ------------------------------------|--- kernel_lamp_emission --|--- PathRadiance_coop
27  * Ray_coop -------------------------------------------|                           |--- Queue_data(QUEUE_ACTIVE_AND_REGENERATED_RAYS)
28  * PathState_coop -------------------------------------|                           |--- Queue_index(QUEUE_ACTIVE_AND_REGENERATED_RAYS)
29  * kg (globals) ---------------------------------------|                           |
30  * Intersection_coop ----------------------------------|                           |
31  * ray_state ------------------------------------------|                           |
32  * Queue_data (QUEUE_ACTIVE_AND_REGENERATED_RAYS) -----|                           |
33  * Queue_index (QUEUE_ACTIVE_AND_REGENERATED_RAYS) ----|                           |
34  * queuesize ------------------------------------------|                           |
35  * use_queues_flag ------------------------------------|                           |
36  * sw -------------------------------------------------|                           |
37  * sh -------------------------------------------------|                           |
38  * parallel_samples -----------------------------------|                           |
39  */
40 ccl_device void kernel_lamp_emission(
41         KernelGlobals *kg,
42         ccl_global float3 *throughput_coop,    /* Required for lamp emission */
43         PathRadiance *PathRadiance_coop,       /* Required for lamp emission */
44         ccl_global Ray *Ray_coop,              /* Required for lamp emission */
45         ccl_global PathState *PathState_coop,  /* Required for lamp emission */
46         Intersection *Intersection_coop,       /* Required for lamp emission */
47         ccl_global char *ray_state,            /* Denotes the state of each ray */
48         int sw, int sh,
49         ccl_global char *use_queues_flag,      /* Used to decide if this kernel should use
50                                                 * queues to fetch ray index
51                                                 */
52         int parallel_samples,                  /* Number of samples to be processed in parallel */
53         int ray_index)
54 {
55         if(IS_STATE(ray_state, ray_index, RAY_ACTIVE) ||
56            IS_STATE(ray_state, ray_index, RAY_HIT_BACKGROUND))
57         {
58                 PathRadiance *L = &PathRadiance_coop[ray_index];
59                 ccl_global PathState *state = &PathState_coop[ray_index];
60
61                 float3 throughput = throughput_coop[ray_index];
62                 Ray ray = Ray_coop[ray_index];
63
64 #ifdef __LAMP_MIS__
65                 if(kernel_data.integrator.use_lamp_mis && !(state->flag & PATH_RAY_CAMERA)) {
66                         /* ray starting from previous non-transparent bounce */
67                         Ray light_ray;
68
69                         light_ray.P = ray.P - state->ray_t*ray.D;
70                         state->ray_t += Intersection_coop[ray_index].t;
71                         light_ray.D = ray.D;
72                         light_ray.t = state->ray_t;
73                         light_ray.time = ray.time;
74                         light_ray.dD = ray.dD;
75                         light_ray.dP = ray.dP;
76                         /* intersect with lamp */
77                         float3 emission;
78
79                         if(indirect_lamp_emission(kg, state, &light_ray, &emission)) {
80                                 path_radiance_accum_emission(L, throughput, emission, state->bounce);
81                         }
82                 }
83 #endif  /* __LAMP_MIS__ */
84
85                 /* __VOLUME__ feature is disabled */
86 #if 0
87 #ifdef __VOLUME__
88                 /* volume attenuation, emission, scatter */
89                 if(state->volume_stack[0].shader != SHADER_NONE) {
90                         Ray volume_ray = ray;
91                         volume_ray.t = (hit)? isect.t: FLT_MAX;
92
93                         bool heterogeneous = volume_stack_is_heterogeneous(kg, state->volume_stack);
94
95 #ifdef __VOLUME_DECOUPLED__
96                         int sampling_method = volume_stack_sampling_method(kg, state->volume_stack);
97                         bool decoupled = kernel_volume_use_decoupled(kg, heterogeneous, true, sampling_method);
98
99                         if(decoupled) {
100                                 /* cache steps along volume for repeated sampling */
101                                 VolumeSegment volume_segment;
102                                 ShaderData volume_sd;
103
104                                 shader_setup_from_volume(kg, &volume_sd, &volume_ray);
105                                 kernel_volume_decoupled_record(kg, state,
106                                         &volume_ray, &volume_sd, &volume_segment, heterogeneous);
107
108                                 volume_segment.sampling_method = sampling_method;
109
110                                 /* emission */
111                                 if(volume_segment.closure_flag & SD_EMISSION)
112                                         path_radiance_accum_emission(&L, throughput, volume_segment.accum_emission, state->bounce);
113
114                                 /* scattering */
115                                 VolumeIntegrateResult result = VOLUME_PATH_ATTENUATED;
116
117                                 if(volume_segment.closure_flag & SD_SCATTER) {
118                                         bool all = false;
119
120                                         /* direct light sampling */
121                                         kernel_branched_path_volume_connect_light(kg, rng, &volume_sd,
122                                                 throughput, state, &L, 1.0f, all, &volume_ray, &volume_segment);
123
124                                         /* indirect sample. if we use distance sampling and take just
125                                          * one sample for direct and indirect light, we could share
126                                          * this computation, but makes code a bit complex */
127                                         float rphase = path_state_rng_1D_for_decision(kg, rng, state, PRNG_PHASE);
128                                         float rscatter = path_state_rng_1D_for_decision(kg, rng, state, PRNG_SCATTER_DISTANCE);
129
130                                         result = kernel_volume_decoupled_scatter(kg,
131                                                 state, &volume_ray, &volume_sd, &throughput,
132                                                 rphase, rscatter, &volume_segment, NULL, true);
133                                 }
134
135                                 if(result != VOLUME_PATH_SCATTERED)
136                                         throughput *= volume_segment.accum_transmittance;
137
138                                 /* free cached steps */
139                                 kernel_volume_decoupled_free(kg, &volume_segment);
140
141                                 if(result == VOLUME_PATH_SCATTERED) {
142                                         if(kernel_path_volume_bounce(kg, rng, &volume_sd, &throughput, state, &L, &ray))
143                                                 continue;
144                                         else
145                                                 break;
146                                 }
147                         }
148                         else
149 #endif  /* __VOLUME_DECOUPLED__ */
150                         {
151                                 /* integrate along volume segment with distance sampling */
152                                 ShaderData volume_sd;
153                                 VolumeIntegrateResult result = kernel_volume_integrate(
154                                         kg, state, &volume_sd, &volume_ray, &L, &throughput, rng, heterogeneous);
155
156 #ifdef __VOLUME_SCATTER__
157                                 if(result == VOLUME_PATH_SCATTERED) {
158                                         /* direct lighting */
159                                         kernel_path_volume_connect_light(kg, rng, &volume_sd, throughput, state, &L);
160
161                                         /* indirect light bounce */
162                                         if(kernel_path_volume_bounce(kg, rng, &volume_sd, &throughput, state, &L, &ray))
163                                                 continue;
164                                         else
165                                                 break;
166                                 }
167 #endif  /* __VOLUME_SCATTER__ */
168                         }
169                 }
170 #endif  /* __VOLUME__ */
171 #endif
172         }
173 }