1 /*
2 * Copyright 2011-2013 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 CCL_NAMESPACE_BEGIN
18
19 /* Direction Emission */
direct_emissive_eval(KernelGlobals * kg,ShaderData * emission_sd,LightSample * ls,ccl_addr_space PathState * state,float3 I,differential3 dI,float t,float time)20 ccl_device_noinline_cpu float3 direct_emissive_eval(KernelGlobals *kg,
21 ShaderData *emission_sd,
22 LightSample *ls,
23 ccl_addr_space PathState *state,
24 float3 I,
25 differential3 dI,
26 float t,
27 float time)
28 {
29 /* setup shading at emitter */
30 float3 eval = make_float3(0.0f, 0.0f, 0.0f);
31
32 if (shader_constant_emission_eval(kg, ls->shader, &eval)) {
33 if ((ls->prim != PRIM_NONE) && dot(ls->Ng, I) < 0.0f) {
34 ls->Ng = -ls->Ng;
35 }
36 }
37 else {
38 /* Setup shader data and call shader_eval_surface once, better
39 * for GPU coherence and compile times. */
40 #ifdef __BACKGROUND_MIS__
41 if (ls->type == LIGHT_BACKGROUND) {
42 Ray ray;
43 ray.D = ls->D;
44 ray.P = ls->P;
45 ray.t = 1.0f;
46 ray.time = time;
47 ray.dP = differential3_zero();
48 ray.dD = dI;
49
50 shader_setup_from_background(kg, emission_sd, &ray);
51 }
52 else
53 #endif
54 {
55 shader_setup_from_sample(kg,
56 emission_sd,
57 ls->P,
58 ls->Ng,
59 I,
60 ls->shader,
61 ls->object,
62 ls->prim,
63 ls->u,
64 ls->v,
65 t,
66 time,
67 false,
68 ls->lamp);
69
70 ls->Ng = emission_sd->Ng;
71 }
72
73 /* No proper path flag, we're evaluating this for all closures. that's
74 * weak but we'd have to do multiple evaluations otherwise. */
75 path_state_modify_bounce(state, true);
76 shader_eval_surface(kg, emission_sd, state, NULL, PATH_RAY_EMISSION);
77 path_state_modify_bounce(state, false);
78
79 /* Evaluate closures. */
80 #ifdef __BACKGROUND_MIS__
81 if (ls->type == LIGHT_BACKGROUND) {
82 eval = shader_background_eval(emission_sd);
83 }
84 else
85 #endif
86 {
87 eval = shader_emissive_eval(emission_sd);
88 }
89 }
90
91 eval *= ls->eval_fac;
92
93 if (ls->lamp != LAMP_NONE) {
94 const ccl_global KernelLight *klight = &kernel_tex_fetch(__lights, ls->lamp);
95 eval *= make_float3(klight->strength[0], klight->strength[1], klight->strength[2]);
96 }
97
98 return eval;
99 }
100
direct_emission(KernelGlobals * kg,ShaderData * sd,ShaderData * emission_sd,LightSample * ls,ccl_addr_space PathState * state,Ray * ray,BsdfEval * eval,bool * is_lamp,float rand_terminate)101 ccl_device_noinline_cpu bool direct_emission(KernelGlobals *kg,
102 ShaderData *sd,
103 ShaderData *emission_sd,
104 LightSample *ls,
105 ccl_addr_space PathState *state,
106 Ray *ray,
107 BsdfEval *eval,
108 bool *is_lamp,
109 float rand_terminate)
110 {
111 if (ls->pdf == 0.0f)
112 return false;
113
114 /* todo: implement */
115 differential3 dD = differential3_zero();
116
117 /* evaluate closure */
118
119 float3 light_eval = direct_emissive_eval(
120 kg, emission_sd, ls, state, -ls->D, dD, ls->t, sd->time);
121
122 if (is_zero(light_eval))
123 return false;
124
125 /* evaluate BSDF at shading point */
126
127 #ifdef __VOLUME__
128 if (sd->prim != PRIM_NONE)
129 shader_bsdf_eval(kg, sd, ls->D, eval, ls->pdf, ls->shader & SHADER_USE_MIS);
130 else {
131 float bsdf_pdf;
132 shader_volume_phase_eval(kg, sd, ls->D, eval, &bsdf_pdf);
133 if (ls->shader & SHADER_USE_MIS) {
134 /* Multiple importance sampling. */
135 float mis_weight = power_heuristic(ls->pdf, bsdf_pdf);
136 light_eval *= mis_weight;
137 }
138 }
139 #else
140 shader_bsdf_eval(kg, sd, ls->D, eval, ls->pdf, ls->shader & SHADER_USE_MIS);
141 #endif
142
143 bsdf_eval_mul3(eval, light_eval / ls->pdf);
144
145 #ifdef __PASSES__
146 /* use visibility flag to skip lights */
147 if (ls->shader & SHADER_EXCLUDE_ANY) {
148 if (ls->shader & SHADER_EXCLUDE_DIFFUSE)
149 eval->diffuse = make_float3(0.0f, 0.0f, 0.0f);
150 if (ls->shader & SHADER_EXCLUDE_GLOSSY)
151 eval->glossy = make_float3(0.0f, 0.0f, 0.0f);
152 if (ls->shader & SHADER_EXCLUDE_TRANSMIT)
153 eval->transmission = make_float3(0.0f, 0.0f, 0.0f);
154 if (ls->shader & SHADER_EXCLUDE_SCATTER)
155 eval->volume = make_float3(0.0f, 0.0f, 0.0f);
156 }
157 #endif
158
159 if (bsdf_eval_is_zero(eval))
160 return false;
161
162 if (kernel_data.integrator.light_inv_rr_threshold > 0.0f
163 #ifdef __SHADOW_TRICKS__
164 && (state->flag & PATH_RAY_SHADOW_CATCHER) == 0
165 #endif
166 ) {
167 float probability = max3(fabs(bsdf_eval_sum(eval))) *
168 kernel_data.integrator.light_inv_rr_threshold;
169 if (probability < 1.0f) {
170 if (rand_terminate >= probability) {
171 return false;
172 }
173 bsdf_eval_mul(eval, 1.0f / probability);
174 }
175 }
176
177 if (ls->shader & SHADER_CAST_SHADOW) {
178 /* setup ray */
179 bool transmit = (dot(sd->Ng, ls->D) < 0.0f);
180 ray->P = ray_offset(sd->P, (transmit) ? -sd->Ng : sd->Ng);
181
182 if (ls->t == FLT_MAX) {
183 /* distant light */
184 ray->D = ls->D;
185 ray->t = ls->t;
186 }
187 else {
188 /* other lights, avoid self-intersection */
189 ray->D = ray_offset(ls->P, ls->Ng) - ray->P;
190 ray->D = normalize_len(ray->D, &ray->t);
191 }
192
193 ray->dP = sd->dP;
194 ray->dD = differential3_zero();
195 }
196 else {
197 /* signal to not cast shadow ray */
198 ray->t = 0.0f;
199 }
200
201 /* return if it's a lamp for shadow pass */
202 *is_lamp = (ls->prim == PRIM_NONE && ls->type != LIGHT_BACKGROUND);
203
204 return true;
205 }
206
207 /* Indirect Primitive Emission */
208
indirect_primitive_emission(KernelGlobals * kg,ShaderData * sd,float t,int path_flag,float bsdf_pdf)209 ccl_device_noinline_cpu float3 indirect_primitive_emission(
210 KernelGlobals *kg, ShaderData *sd, float t, int path_flag, float bsdf_pdf)
211 {
212 /* evaluate emissive closure */
213 float3 L = shader_emissive_eval(sd);
214
215 #ifdef __HAIR__
216 if (!(path_flag & PATH_RAY_MIS_SKIP) && (sd->flag & SD_USE_MIS) &&
217 (sd->type & PRIMITIVE_ALL_TRIANGLE))
218 #else
219 if (!(path_flag & PATH_RAY_MIS_SKIP) && (sd->flag & SD_USE_MIS))
220 #endif
221 {
222 /* multiple importance sampling, get triangle light pdf,
223 * and compute weight with respect to BSDF pdf */
224 float pdf = triangle_light_pdf(kg, sd, t);
225 float mis_weight = power_heuristic(bsdf_pdf, pdf);
226
227 return L * mis_weight;
228 }
229
230 return L;
231 }
232
233 /* Indirect Lamp Emission */
234
indirect_lamp_emission(KernelGlobals * kg,ShaderData * emission_sd,ccl_addr_space PathState * state,PathRadiance * L,Ray * ray,float3 throughput)235 ccl_device_noinline_cpu void indirect_lamp_emission(KernelGlobals *kg,
236 ShaderData *emission_sd,
237 ccl_addr_space PathState *state,
238 PathRadiance *L,
239 Ray *ray,
240 float3 throughput)
241 {
242 for (int lamp = 0; lamp < kernel_data.integrator.num_all_lights; lamp++) {
243 LightSample ls ccl_optional_struct_init;
244
245 if (!lamp_light_eval(kg, lamp, ray->P, ray->D, ray->t, &ls))
246 continue;
247
248 #ifdef __PASSES__
249 /* use visibility flag to skip lights */
250 if (ls.shader & SHADER_EXCLUDE_ANY) {
251 if (((ls.shader & SHADER_EXCLUDE_DIFFUSE) && (state->flag & PATH_RAY_DIFFUSE)) ||
252 ((ls.shader & SHADER_EXCLUDE_GLOSSY) &&
253 ((state->flag & (PATH_RAY_GLOSSY | PATH_RAY_REFLECT)) ==
254 (PATH_RAY_GLOSSY | PATH_RAY_REFLECT))) ||
255 ((ls.shader & SHADER_EXCLUDE_TRANSMIT) && (state->flag & PATH_RAY_TRANSMIT)) ||
256 ((ls.shader & SHADER_EXCLUDE_SCATTER) && (state->flag & PATH_RAY_VOLUME_SCATTER)))
257 continue;
258 }
259 #endif
260
261 float3 lamp_L = direct_emissive_eval(
262 kg, emission_sd, &ls, state, -ray->D, ray->dD, ls.t, ray->time);
263
264 #ifdef __VOLUME__
265 if (state->volume_stack[0].shader != SHADER_NONE) {
266 /* shadow attenuation */
267 Ray volume_ray = *ray;
268 volume_ray.t = ls.t;
269 float3 volume_tp = make_float3(1.0f, 1.0f, 1.0f);
270 kernel_volume_shadow(kg, emission_sd, state, &volume_ray, &volume_tp);
271 lamp_L *= volume_tp;
272 }
273 #endif
274
275 if (!(state->flag & PATH_RAY_MIS_SKIP)) {
276 /* multiple importance sampling, get regular light pdf,
277 * and compute weight with respect to BSDF pdf */
278 float mis_weight = power_heuristic(state->ray_pdf, ls.pdf);
279 lamp_L *= mis_weight;
280 }
281
282 path_radiance_accum_emission(kg, L, state, throughput, lamp_L);
283 }
284 }
285
286 /* Indirect Background */
287
indirect_background(KernelGlobals * kg,ShaderData * emission_sd,ccl_addr_space PathState * state,ccl_global float * buffer,ccl_addr_space Ray * ray)288 ccl_device_noinline_cpu float3 indirect_background(KernelGlobals *kg,
289 ShaderData *emission_sd,
290 ccl_addr_space PathState *state,
291 ccl_global float *buffer,
292 ccl_addr_space Ray *ray)
293 {
294 #ifdef __BACKGROUND__
295 int shader = kernel_data.background.surface_shader;
296
297 /* Use visibility flag to skip lights. */
298 if (shader & SHADER_EXCLUDE_ANY) {
299 if (((shader & SHADER_EXCLUDE_DIFFUSE) && (state->flag & PATH_RAY_DIFFUSE)) ||
300 ((shader & SHADER_EXCLUDE_GLOSSY) &&
301 ((state->flag & (PATH_RAY_GLOSSY | PATH_RAY_REFLECT)) ==
302 (PATH_RAY_GLOSSY | PATH_RAY_REFLECT))) ||
303 ((shader & SHADER_EXCLUDE_TRANSMIT) && (state->flag & PATH_RAY_TRANSMIT)) ||
304 ((shader & SHADER_EXCLUDE_CAMERA) && (state->flag & PATH_RAY_CAMERA)) ||
305 ((shader & SHADER_EXCLUDE_SCATTER) && (state->flag & PATH_RAY_VOLUME_SCATTER)))
306 return make_float3(0.0f, 0.0f, 0.0f);
307 }
308
309 /* Evaluate background shader. */
310 float3 L = make_float3(0.0f, 0.0f, 0.0f);
311 if (!shader_constant_emission_eval(kg, shader, &L)) {
312 # ifdef __SPLIT_KERNEL__
313 Ray priv_ray = *ray;
314 shader_setup_from_background(kg, emission_sd, &priv_ray);
315 # else
316 shader_setup_from_background(kg, emission_sd, ray);
317 # endif
318
319 path_state_modify_bounce(state, true);
320 shader_eval_surface(kg, emission_sd, state, buffer, state->flag | PATH_RAY_EMISSION);
321 path_state_modify_bounce(state, false);
322
323 L = shader_background_eval(emission_sd);
324 }
325
326 /* Background MIS weights. */
327 # ifdef __BACKGROUND_MIS__
328 /* Check if background light exists or if we should skip pdf. */
329 if (!(state->flag & PATH_RAY_MIS_SKIP) && kernel_data.background.use_mis) {
330 /* multiple importance sampling, get background light pdf for ray
331 * direction, and compute weight with respect to BSDF pdf */
332 float pdf = background_light_pdf(kg, ray->P, ray->D);
333 float mis_weight = power_heuristic(state->ray_pdf, pdf);
334
335 return L * mis_weight;
336 }
337 # endif
338
339 return L;
340 #else
341 return make_float3(0.8f, 0.8f, 0.8f);
342 #endif
343 }
344
345 CCL_NAMESPACE_END
346