1.3.7
by Kevin Roy
Import upstream version 2.61 |
1 |
/*
|
1.5.4
by Matteo F. Vescovi
Import upstream version 2.69 |
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
|
|
1.3.7
by Kevin Roy
Import upstream version 2.61 |
15 |
*/
|
16 |
||
1.3.11
by Matteo F. Vescovi
Import upstream version 2.65a+svn53743 |
17 |
#ifdef __OSL__
|
18 |
#include "osl_shader.h" |
|
19 |
#endif
|
|
20 |
||
1.3.7
by Kevin Roy
Import upstream version 2.61 |
21 |
#include "kernel_differential.h" |
22 |
#include "kernel_montecarlo.h" |
|
1.3.11
by Matteo F. Vescovi
Import upstream version 2.65a+svn53743 |
23 |
#include "kernel_projection.h" |
24 |
#include "kernel_object.h" |
|
1.3.7
by Kevin Roy
Import upstream version 2.61 |
25 |
#include "kernel_triangle.h" |
1.3.11
by Matteo F. Vescovi
Import upstream version 2.65a+svn53743 |
26 |
#include "kernel_curve.h" |
27 |
#include "kernel_primitive.h" |
|
28 |
#include "kernel_projection.h" |
|
1.5.2
by Matteo F. Vescovi
Import upstream version 2.67b |
29 |
#include "kernel_random.h" |
1.3.7
by Kevin Roy
Import upstream version 2.61 |
30 |
#include "kernel_bvh.h" |
1.3.8
by Matteo F. Vescovi
Import upstream version 2.62 |
31 |
#include "kernel_accumulate.h" |
1.3.7
by Kevin Roy
Import upstream version 2.61 |
32 |
#include "kernel_camera.h" |
33 |
#include "kernel_shader.h" |
|
34 |
#include "kernel_light.h" |
|
35 |
#include "kernel_emission.h" |
|
1.3.8
by Matteo F. Vescovi
Import upstream version 2.62 |
36 |
#include "kernel_passes.h" |
1.5.4
by Matteo F. Vescovi
Import upstream version 2.69 |
37 |
#include "kernel_path_state.h" |
1.3.7
by Kevin Roy
Import upstream version 2.61 |
38 |
|
1.5.2
by Matteo F. Vescovi
Import upstream version 2.67b |
39 |
#ifdef __SUBSURFACE__
|
40 |
#include "kernel_subsurface.h" |
|
41 |
#endif
|
|
42 |
||
1.3.7
by Kevin Roy
Import upstream version 2.61 |
43 |
CCL_NAMESPACE_BEGIN
|
44 |
||
1.3.9
by Matteo F. Vescovi
Import upstream version 2.63 |
45 |
__device_inline bool shadow_blocked(KernelGlobals *kg, PathState *state, Ray *ray, float3 *shadow) |
1.3.7
by Kevin Roy
Import upstream version 2.61 |
46 |
{
|
1.3.9
by Matteo F. Vescovi
Import upstream version 2.63 |
47 |
*shadow = make_float3(1.0f, 1.0f, 1.0f); |
48 |
||
1.3.7
by Kevin Roy
Import upstream version 2.61 |
49 |
if(ray->t == 0.0f) |
50 |
return false; |
|
51 |
||
1.3.9
by Matteo F. Vescovi
Import upstream version 2.63 |
52 |
Intersection isect; |
1.5.3
by Matteo F. Vescovi
Import upstream version 2.68a |
53 |
#ifdef __HAIR__
|
54 |
bool result = scene_intersect(kg, ray, PATH_RAY_SHADOW_OPAQUE, &isect, NULL, 0.0f, 0.0f); |
|
55 |
#else
|
|
1.3.9
by Matteo F. Vescovi
Import upstream version 2.63 |
56 |
bool result = scene_intersect(kg, ray, PATH_RAY_SHADOW_OPAQUE, &isect); |
1.5.3
by Matteo F. Vescovi
Import upstream version 2.68a |
57 |
#endif
|
1.3.7
by Kevin Roy
Import upstream version 2.61 |
58 |
|
59 |
#ifdef __TRANSPARENT_SHADOWS__
|
|
60 |
if(result && kernel_data.integrator.transparent_shadows) { |
|
61 |
/* transparent shadows work in such a way to try to minimize overhead
|
|
1.3.11
by Matteo F. Vescovi
Import upstream version 2.65a+svn53743 |
62 |
* in cases where we don't need them. after a regular shadow ray is
|
63 |
* cast we check if the hit primitive was potentially transparent, and
|
|
64 |
* only in that case start marching. this gives on extra ray cast for
|
|
65 |
* the cases were we do want transparency.
|
|
66 |
*
|
|
67 |
* also note that for this to work correct, multi close sampling must
|
|
68 |
* be used, since we don't pass a random number to shader_eval_surface */
|
|
1.3.9
by Matteo F. Vescovi
Import upstream version 2.63 |
69 |
if(shader_transparent_shadow(kg, &isect)) { |
1.3.7
by Kevin Roy
Import upstream version 2.61 |
70 |
float3 throughput = make_float3(1.0f, 1.0f, 1.0f); |
71 |
float3 Pend = ray->P + ray->D*ray->t; |
|
72 |
int bounce = state->transparent_bounce; |
|
73 |
||
74 |
for(;;) { |
|
75 |
if(bounce >= kernel_data.integrator.transparent_max_bounce) { |
|
76 |
return true; |
|
77 |
}
|
|
78 |
else if(bounce >= kernel_data.integrator.transparent_min_bounce) { |
|
79 |
/* todo: get random number somewhere for probabilistic terminate */
|
|
80 |
#if 0
|
|
81 |
float probability = average(throughput);
|
|
82 |
float terminate = 0.0f;
|
|
83 |
||
84 |
if(terminate >= probability)
|
|
85 |
return true;
|
|
86 |
||
87 |
throughput /= probability;
|
|
88 |
#endif
|
|
89 |
}
|
|
90 |
||
1.5.3
by Matteo F. Vescovi
Import upstream version 2.68a |
91 |
#ifdef __HAIR__
|
92 |
if(!scene_intersect(kg, ray, PATH_RAY_SHADOW_TRANSPARENT, &isect, NULL, 0.0f, 0.0f)) { |
|
93 |
#else
|
|
1.3.9
by Matteo F. Vescovi
Import upstream version 2.63 |
94 |
if(!scene_intersect(kg, ray, PATH_RAY_SHADOW_TRANSPARENT, &isect)) { |
1.5.3
by Matteo F. Vescovi
Import upstream version 2.68a |
95 |
#endif
|
1.3.9
by Matteo F. Vescovi
Import upstream version 2.63 |
96 |
*shadow *= throughput; |
1.3.7
by Kevin Roy
Import upstream version 2.61 |
97 |
return false; |
98 |
}
|
|
99 |
||
1.3.9
by Matteo F. Vescovi
Import upstream version 2.63 |
100 |
if(!shader_transparent_shadow(kg, &isect)) |
1.3.7
by Kevin Roy
Import upstream version 2.61 |
101 |
return true; |
102 |
||
103 |
ShaderData sd; |
|
1.5.4
by Matteo F. Vescovi
Import upstream version 2.69 |
104 |
shader_setup_from_ray(kg, &sd, &isect, ray, state->bounce+1); |
1.3.11
by Matteo F. Vescovi
Import upstream version 2.65a+svn53743 |
105 |
shader_eval_surface(kg, &sd, 0.0f, PATH_RAY_SHADOW, SHADER_CONTEXT_SHADOW); |
1.3.7
by Kevin Roy
Import upstream version 2.61 |
106 |
|
107 |
throughput *= shader_bsdf_transparency(kg, &sd); |
|
108 |
||
109 |
ray->P = ray_offset(sd.P, -sd.Ng); |
|
110 |
if(ray->t != FLT_MAX) |
|
111 |
ray->D = normalize_len(Pend - ray->P, &ray->t); |
|
112 |
||
113 |
bounce++; |
|
114 |
}
|
|
115 |
}
|
|
116 |
}
|
|
117 |
#endif
|
|
118 |
||
119 |
return result; |
|
120 |
}
|
|
121 |
||
1.5.4
by Matteo F. Vescovi
Import upstream version 2.69 |
122 |
|
123 |
#if defined(__BRANCHED_PATH__) || defined(__SUBSURFACE__)
|
|
124 |
||
125 |
__device void kernel_path_indirect(KernelGlobals *kg, RNG *rng, int sample, Ray ray, __global float *buffer, |
|
126 |
float3 throughput, int num_samples, int num_total_samples, |
|
127 |
float min_ray_pdf, float ray_pdf, PathState state, int rng_offset, PathRadiance *L) |
|
128 |
{
|
|
129 |
#ifdef __LAMP_MIS__
|
|
130 |
float ray_t = 0.0f; |
|
131 |
#endif
|
|
132 |
||
133 |
/* path iteration */
|
|
134 |
for(;; rng_offset += PRNG_BOUNCE_NUM) { |
|
135 |
/* intersect scene */
|
|
136 |
Intersection isect; |
|
137 |
uint visibility = path_state_ray_visibility(kg, &state); |
|
138 |
#ifdef __HAIR__
|
|
139 |
bool hit = scene_intersect(kg, &ray, visibility, &isect, NULL, 0.0f, 0.0f); |
|
140 |
#else
|
|
141 |
bool hit = scene_intersect(kg, &ray, visibility, &isect); |
|
142 |
#endif
|
|
143 |
||
144 |
#ifdef __LAMP_MIS__
|
|
145 |
if(kernel_data.integrator.use_lamp_mis && !(state.flag & PATH_RAY_CAMERA)) { |
|
146 |
/* ray starting from previous non-transparent bounce */
|
|
147 |
Ray light_ray; |
|
148 |
||
149 |
light_ray.P = ray.P - ray_t*ray.D; |
|
150 |
ray_t += isect.t; |
|
151 |
light_ray.D = ray.D; |
|
152 |
light_ray.t = ray_t; |
|
153 |
light_ray.time = ray.time; |
|
154 |
light_ray.dD = ray.dD; |
|
155 |
light_ray.dP = ray.dP; |
|
156 |
||
157 |
/* intersect with lamp */
|
|
158 |
float light_t = path_rng_1D(kg, rng, sample, num_total_samples, rng_offset + PRNG_LIGHT); |
|
159 |
float3 emission; |
|
160 |
||
161 |
if(indirect_lamp_emission(kg, &light_ray, state.flag, ray_pdf, light_t, &emission, state.bounce)) |
|
162 |
path_radiance_accum_emission(L, throughput, emission, state.bounce); |
|
163 |
}
|
|
164 |
#endif
|
|
165 |
||
166 |
if(!hit) { |
|
167 |
#ifdef __BACKGROUND__
|
|
168 |
/* sample background shader */
|
|
169 |
float3 L_background = indirect_background(kg, &ray, state.flag, ray_pdf, state.bounce); |
|
170 |
path_radiance_accum_background(L, throughput, L_background, state.bounce); |
|
171 |
#endif
|
|
172 |
||
173 |
break; |
|
174 |
}
|
|
175 |
||
176 |
/* setup shading */
|
|
177 |
ShaderData sd; |
|
178 |
shader_setup_from_ray(kg, &sd, &isect, &ray, state.bounce); |
|
179 |
float rbsdf = path_rng_1D(kg, rng, sample, num_total_samples, rng_offset + PRNG_BSDF); |
|
180 |
shader_eval_surface(kg, &sd, rbsdf, state.flag, SHADER_CONTEXT_INDIRECT); |
|
181 |
#ifdef __BRANCHED_PATH__
|
|
182 |
shader_merge_closures(kg, &sd); |
|
183 |
#endif
|
|
184 |
||
185 |
/* blurring of bsdf after bounces, for rays that have a small likelihood
|
|
186 |
* of following this particular path (diffuse, rough glossy) */
|
|
187 |
if(kernel_data.integrator.filter_glossy != FLT_MAX) { |
|
188 |
float blur_pdf = kernel_data.integrator.filter_glossy*min_ray_pdf; |
|
189 |
||
190 |
if(blur_pdf < 1.0f) { |
|
191 |
float blur_roughness = sqrtf(1.0f - blur_pdf)*0.5f; |
|
192 |
shader_bsdf_blur(kg, &sd, blur_roughness); |
|
193 |
}
|
|
194 |
}
|
|
195 |
||
196 |
#ifdef __EMISSION__
|
|
197 |
/* emission */
|
|
198 |
if(sd.flag & SD_EMISSION) { |
|
199 |
float3 emission = indirect_primitive_emission(kg, &sd, isect.t, state.flag, ray_pdf); |
|
200 |
path_radiance_accum_emission(L, throughput, emission, state.bounce); |
|
201 |
}
|
|
202 |
#endif
|
|
203 |
||
204 |
/* path termination. this is a strange place to put the termination, it's
|
|
205 |
* mainly due to the mixed in MIS that we use. gives too many unneeded
|
|
206 |
* shader evaluations, only need emission if we are going to terminate */
|
|
207 |
float probability = path_state_terminate_probability(kg, &state, throughput*num_samples); |
|
208 |
||
209 |
if(probability == 0.0f) { |
|
210 |
break; |
|
211 |
}
|
|
212 |
else if(probability != 1.0f) { |
|
213 |
float terminate = path_rng_1D(kg, rng, sample, num_total_samples, rng_offset + PRNG_TERMINATE); |
|
214 |
||
215 |
if(terminate >= probability) |
|
216 |
break; |
|
217 |
||
218 |
throughput /= probability; |
|
219 |
}
|
|
220 |
||
221 |
#ifdef __AO__
|
|
222 |
/* ambient occlusion */
|
|
223 |
if(kernel_data.integrator.use_ambient_occlusion || (sd.flag & SD_AO)) { |
|
224 |
float bsdf_u, bsdf_v; |
|
225 |
path_rng_2D(kg, rng, sample, num_total_samples, rng_offset + PRNG_BSDF_U, &bsdf_u, &bsdf_v); |
|
226 |
||
227 |
float ao_factor = kernel_data.background.ao_factor; |
|
228 |
float3 ao_N; |
|
229 |
float3 ao_bsdf = shader_bsdf_ao(kg, &sd, ao_factor, &ao_N); |
|
230 |
float3 ao_D; |
|
231 |
float ao_pdf; |
|
232 |
float3 ao_alpha = make_float3(0.0f, 0.0f, 0.0f); |
|
233 |
||
234 |
sample_cos_hemisphere(ao_N, bsdf_u, bsdf_v, &ao_D, &ao_pdf); |
|
235 |
||
236 |
if(dot(sd.Ng, ao_D) > 0.0f && ao_pdf != 0.0f) { |
|
237 |
Ray light_ray; |
|
238 |
float3 ao_shadow; |
|
239 |
||
240 |
light_ray.P = ray_offset(sd.P, sd.Ng); |
|
241 |
light_ray.D = ao_D; |
|
242 |
light_ray.t = kernel_data.background.ao_distance; |
|
243 |
#ifdef __OBJECT_MOTION__
|
|
244 |
light_ray.time = sd.time; |
|
245 |
#endif
|
|
246 |
light_ray.dP = sd.dP; |
|
247 |
light_ray.dD = differential3_zero(); |
|
248 |
||
249 |
if(!shadow_blocked(kg, &state, &light_ray, &ao_shadow)) |
|
250 |
path_radiance_accum_ao(L, throughput, ao_alpha, ao_bsdf, ao_shadow, state.bounce); |
|
251 |
}
|
|
252 |
}
|
|
253 |
#endif
|
|
254 |
||
255 |
#ifdef __SUBSURFACE__
|
|
256 |
/* bssrdf scatter to a different location on the same object, replacing
|
|
257 |
* the closures with a diffuse BSDF */
|
|
258 |
if(sd.flag & SD_BSSRDF) { |
|
259 |
float bssrdf_probability; |
|
260 |
ShaderClosure *sc = subsurface_scatter_pick_closure(kg, &sd, &bssrdf_probability); |
|
261 |
||
262 |
/* modify throughput for picking bssrdf or bsdf */
|
|
263 |
throughput *= bssrdf_probability; |
|
264 |
||
265 |
/* do bssrdf scatter step if we picked a bssrdf closure */
|
|
266 |
if(sc) { |
|
267 |
uint lcg_state = lcg_init(*rng + rng_offset + sample*0x68bc21eb); |
|
268 |
||
269 |
if(old_subsurface_scatter_use(&sd)) { |
|
270 |
old_subsurface_scatter_step(kg, &sd, state.flag, sc, &lcg_state, false); |
|
271 |
}
|
|
272 |
else { |
|
273 |
float bssrdf_u, bssrdf_v; |
|
274 |
path_rng_2D(kg, rng, sample, num_total_samples, rng_offset + PRNG_BSDF_U, &bssrdf_u, &bssrdf_v); |
|
275 |
subsurface_scatter_step(kg, &sd, state.flag, sc, &lcg_state, bssrdf_u, bssrdf_v, false); |
|
276 |
}
|
|
277 |
||
278 |
state.flag |= PATH_RAY_BSSRDF_ANCESTOR; |
|
279 |
}
|
|
280 |
}
|
|
281 |
#endif
|
|
282 |
||
283 |
#ifdef __EMISSION__
|
|
284 |
if(kernel_data.integrator.use_direct_light) { |
|
285 |
/* sample illumination from lights to find path contribution */
|
|
286 |
if(sd.flag & SD_BSDF_HAS_EVAL) { |
|
287 |
float light_t = path_rng_1D(kg, rng, sample, num_total_samples, rng_offset + PRNG_LIGHT); |
|
288 |
#ifdef __MULTI_CLOSURE__
|
|
289 |
float light_o = 0.0f; |
|
290 |
#else
|
|
291 |
float light_o = path_rng_1D(kg, rng, sample, num_total_samples, rng_offset + PRNG_LIGHT_F); |
|
292 |
#endif
|
|
293 |
float light_u, light_v; |
|
294 |
path_rng_2D(kg, rng, sample, num_total_samples, rng_offset + PRNG_LIGHT_U, &light_u, &light_v); |
|
295 |
||
296 |
Ray light_ray; |
|
297 |
BsdfEval L_light; |
|
298 |
bool is_lamp; |
|
299 |
||
300 |
#ifdef __OBJECT_MOTION__
|
|
301 |
light_ray.time = sd.time; |
|
302 |
#endif
|
|
303 |
||
304 |
/* sample random light */
|
|
305 |
if(direct_emission(kg, &sd, -1, light_t, light_o, light_u, light_v, &light_ray, &L_light, &is_lamp, state.bounce)) { |
|
306 |
/* trace shadow ray */
|
|
307 |
float3 shadow; |
|
308 |
||
309 |
if(!shadow_blocked(kg, &state, &light_ray, &shadow)) { |
|
310 |
/* accumulate */
|
|
311 |
path_radiance_accum_light(L, throughput, &L_light, shadow, 1.0f, state.bounce, is_lamp); |
|
312 |
}
|
|
313 |
}
|
|
314 |
}
|
|
315 |
}
|
|
316 |
#endif
|
|
317 |
||
318 |
/* no BSDF? we can stop here */
|
|
319 |
if(!(sd.flag & SD_BSDF)) |
|
320 |
break; |
|
321 |
||
322 |
/* sample BSDF */
|
|
323 |
float bsdf_pdf; |
|
324 |
BsdfEval bsdf_eval; |
|
325 |
float3 bsdf_omega_in; |
|
326 |
differential3 bsdf_domega_in; |
|
327 |
float bsdf_u, bsdf_v; |
|
328 |
path_rng_2D(kg, rng, sample, num_total_samples, rng_offset + PRNG_BSDF_U, &bsdf_u, &bsdf_v); |
|
329 |
int label; |
|
330 |
||
331 |
label = shader_bsdf_sample(kg, &sd, bsdf_u, bsdf_v, &bsdf_eval, |
|
332 |
&bsdf_omega_in, &bsdf_domega_in, &bsdf_pdf); |
|
333 |
||
334 |
if(bsdf_pdf == 0.0f || bsdf_eval_is_zero(&bsdf_eval)) |
|
335 |
break; |
|
336 |
||
337 |
/* modify throughput */
|
|
338 |
path_radiance_bsdf_bounce(L, &throughput, &bsdf_eval, bsdf_pdf, state.bounce, label); |
|
339 |
||
340 |
/* set labels */
|
|
341 |
if(!(label & LABEL_TRANSPARENT)) { |
|
342 |
ray_pdf = bsdf_pdf; |
|
343 |
#ifdef __LAMP_MIS__
|
|
344 |
ray_t = 0.0f; |
|
345 |
#endif
|
|
346 |
min_ray_pdf = fminf(bsdf_pdf, min_ray_pdf); |
|
347 |
}
|
|
348 |
||
349 |
/* update path state */
|
|
350 |
path_state_next(kg, &state, label); |
|
351 |
||
352 |
/* setup ray */
|
|
353 |
ray.P = ray_offset(sd.P, (label & LABEL_TRANSMIT)? -sd.Ng: sd.Ng); |
|
354 |
ray.D = bsdf_omega_in; |
|
355 |
ray.t = FLT_MAX; |
|
356 |
#ifdef __RAY_DIFFERENTIALS__
|
|
357 |
ray.dP = sd.dP; |
|
358 |
ray.dD = bsdf_domega_in; |
|
359 |
#endif
|
|
360 |
}
|
|
361 |
}
|
|
362 |
||
363 |
#endif
|
|
364 |
||
365 |
#ifdef __SUBSURFACE__
|
|
366 |
||
367 |
__device_inline bool kernel_path_integrate_lighting(KernelGlobals *kg, RNG *rng, |
|
368 |
int sample, int num_samples, |
|
369 |
ShaderData *sd, float3 *throughput, |
|
370 |
float *min_ray_pdf, float *ray_pdf, PathState *state, |
|
371 |
int rng_offset, PathRadiance *L, Ray *ray, float *ray_t) |
|
372 |
{
|
|
373 |
#ifdef __EMISSION__
|
|
374 |
if(kernel_data.integrator.use_direct_light) { |
|
375 |
/* sample illumination from lights to find path contribution */
|
|
376 |
if(sd->flag & SD_BSDF_HAS_EVAL) { |
|
377 |
float light_t = path_rng_1D(kg, rng, sample, num_samples, rng_offset + PRNG_LIGHT); |
|
378 |
#ifdef __MULTI_CLOSURE__
|
|
379 |
float light_o = 0.0f; |
|
380 |
#else
|
|
381 |
float light_o = path_rng_1D(kg, rng, sample, num_samples, rng_offset + PRNG_LIGHT_F); |
|
382 |
#endif
|
|
383 |
float light_u, light_v; |
|
384 |
path_rng_2D(kg, rng, sample, num_samples, rng_offset + PRNG_LIGHT_U, &light_u, &light_v); |
|
385 |
||
386 |
Ray light_ray; |
|
387 |
BsdfEval L_light; |
|
388 |
bool is_lamp; |
|
389 |
||
390 |
#ifdef __OBJECT_MOTION__
|
|
391 |
light_ray.time = sd->time; |
|
392 |
#endif
|
|
393 |
||
394 |
if(direct_emission(kg, sd, -1, light_t, light_o, light_u, light_v, &light_ray, &L_light, &is_lamp, state->bounce)) { |
|
395 |
/* trace shadow ray */
|
|
396 |
float3 shadow; |
|
397 |
||
398 |
if(!shadow_blocked(kg, state, &light_ray, &shadow)) { |
|
399 |
/* accumulate */
|
|
400 |
path_radiance_accum_light(L, *throughput, &L_light, shadow, 1.0f, state->bounce, is_lamp); |
|
401 |
}
|
|
402 |
}
|
|
403 |
}
|
|
404 |
}
|
|
405 |
#endif
|
|
406 |
||
407 |
/* no BSDF? we can stop here */
|
|
408 |
if(!(sd->flag & SD_BSDF)) |
|
409 |
return false; |
|
410 |
||
411 |
/* sample BSDF */
|
|
412 |
float bsdf_pdf; |
|
413 |
BsdfEval bsdf_eval; |
|
414 |
float3 bsdf_omega_in; |
|
415 |
differential3 bsdf_domega_in; |
|
416 |
float bsdf_u, bsdf_v; |
|
417 |
path_rng_2D(kg, rng, sample, num_samples, rng_offset + PRNG_BSDF_U, &bsdf_u, &bsdf_v); |
|
418 |
int label; |
|
419 |
||
420 |
label = shader_bsdf_sample(kg, sd, bsdf_u, bsdf_v, &bsdf_eval, |
|
421 |
&bsdf_omega_in, &bsdf_domega_in, &bsdf_pdf); |
|
422 |
||
423 |
if(bsdf_pdf == 0.0f || bsdf_eval_is_zero(&bsdf_eval)) |
|
424 |
return false; |
|
425 |
||
426 |
/* modify throughput */
|
|
427 |
path_radiance_bsdf_bounce(L, throughput, &bsdf_eval, bsdf_pdf, state->bounce, label); |
|
428 |
||
429 |
/* set labels */
|
|
430 |
if(!(label & LABEL_TRANSPARENT)) { |
|
431 |
*ray_pdf = bsdf_pdf; |
|
432 |
#ifdef __LAMP_MIS__
|
|
433 |
*ray_t = 0.0f; |
|
434 |
#endif
|
|
435 |
*min_ray_pdf = fminf(bsdf_pdf, *min_ray_pdf); |
|
436 |
}
|
|
437 |
||
438 |
/* update path state */
|
|
439 |
path_state_next(kg, state, label); |
|
440 |
||
441 |
/* setup ray */
|
|
442 |
ray->P = ray_offset(sd->P, (label & LABEL_TRANSMIT)? -sd->Ng: sd->Ng); |
|
443 |
ray->D = bsdf_omega_in; |
|
444 |
||
445 |
if(state->bounce == 0) |
|
446 |
ray->t -= sd->ray_length; /* clipping works through transparent */ |
|
447 |
else
|
|
448 |
ray->t = FLT_MAX; |
|
449 |
||
450 |
#ifdef __RAY_DIFFERENTIALS__
|
|
451 |
ray->dP = sd->dP; |
|
452 |
ray->dD = bsdf_domega_in; |
|
453 |
#endif
|
|
454 |
||
455 |
return true; |
|
456 |
}
|
|
457 |
||
458 |
#endif
|
|
459 |
||
460 |
__device float4 kernel_path_integrate(KernelGlobals *kg, RNG *rng, int sample, Ray ray, __global float *buffer) |
|
1.3.7
by Kevin Roy
Import upstream version 2.61 |
461 |
{
|
462 |
/* initialize */
|
|
1.3.8
by Matteo F. Vescovi
Import upstream version 2.62 |
463 |
PathRadiance L; |
464 |
float3 throughput = make_float3(1.0f, 1.0f, 1.0f); |
|
465 |
float L_transparent = 0.0f; |
|
466 |
||
467 |
path_radiance_init(&L, kernel_data.film.use_light_pass); |
|
468 |
||
1.3.11
by Matteo F. Vescovi
Import upstream version 2.65a+svn53743 |
469 |
float min_ray_pdf = FLT_MAX; |
1.3.7
by Kevin Roy
Import upstream version 2.61 |
470 |
float ray_pdf = 0.0f; |
1.3.11
by Matteo F. Vescovi
Import upstream version 2.65a+svn53743 |
471 |
#ifdef __LAMP_MIS__
|
472 |
float ray_t = 0.0f; |
|
473 |
#endif
|
|
1.3.7
by Kevin Roy
Import upstream version 2.61 |
474 |
PathState state; |
475 |
int rng_offset = PRNG_BASE_NUM; |
|
1.5.3
by Matteo F. Vescovi
Import upstream version 2.68a |
476 |
#ifdef __CMJ__
|
477 |
int num_samples = kernel_data.integrator.aa_samples; |
|
478 |
#else
|
|
479 |
int num_samples = 0; |
|
480 |
#endif
|
|
1.3.7
by Kevin Roy
Import upstream version 2.61 |
481 |
|
482 |
path_state_init(&state); |
|
483 |
||
484 |
/* path iteration */
|
|
485 |
for(;; rng_offset += PRNG_BOUNCE_NUM) { |
|
486 |
/* intersect scene */
|
|
487 |
Intersection isect; |
|
1.3.8
by Matteo F. Vescovi
Import upstream version 2.62 |
488 |
uint visibility = path_state_ray_visibility(kg, &state); |
1.5.2
by Matteo F. Vescovi
Import upstream version 2.67b |
489 |
|
490 |
#ifdef __HAIR__
|
|
491 |
float difl = 0.0f, extmax = 0.0f; |
|
492 |
uint lcg_state = 0; |
|
493 |
||
494 |
if(kernel_data.bvh.have_curves) { |
|
495 |
if((kernel_data.cam.resolution == 1) && (state.flag & PATH_RAY_CAMERA)) { |
|
496 |
float3 pixdiff = ray.dD.dx + ray.dD.dy; |
|
497 |
/*pixdiff = pixdiff - dot(pixdiff, ray.D)*ray.D;*/
|
|
1.5.4
by Matteo F. Vescovi
Import upstream version 2.69 |
498 |
difl = kernel_data.curve.minimum_width * len(pixdiff) * 0.5f; |
1.5.2
by Matteo F. Vescovi
Import upstream version 2.67b |
499 |
}
|
500 |
||
1.5.4
by Matteo F. Vescovi
Import upstream version 2.69 |
501 |
extmax = kernel_data.curve.maximum_width; |
1.5.2
by Matteo F. Vescovi
Import upstream version 2.67b |
502 |
lcg_state = lcg_init(*rng + rng_offset + sample*0x51633e2d); |
503 |
}
|
|
504 |
||
505 |
bool hit = scene_intersect(kg, &ray, visibility, &isect, &lcg_state, difl, extmax); |
|
506 |
#else
|
|
1.3.11
by Matteo F. Vescovi
Import upstream version 2.65a+svn53743 |
507 |
bool hit = scene_intersect(kg, &ray, visibility, &isect); |
1.5.2
by Matteo F. Vescovi
Import upstream version 2.67b |
508 |
#endif
|
1.3.11
by Matteo F. Vescovi
Import upstream version 2.65a+svn53743 |
509 |
|
510 |
#ifdef __LAMP_MIS__
|
|
1.3.12
by Matteo F. Vescovi
Import upstream version 2.66 |
511 |
if(kernel_data.integrator.use_lamp_mis && !(state.flag & PATH_RAY_CAMERA)) { |
1.3.11
by Matteo F. Vescovi
Import upstream version 2.65a+svn53743 |
512 |
/* ray starting from previous non-transparent bounce */
|
513 |
Ray light_ray; |
|
514 |
||
515 |
light_ray.P = ray.P - ray_t*ray.D; |
|
516 |
ray_t += isect.t; |
|
517 |
light_ray.D = ray.D; |
|
518 |
light_ray.t = ray_t; |
|
519 |
light_ray.time = ray.time; |
|
1.5.2
by Matteo F. Vescovi
Import upstream version 2.67b |
520 |
light_ray.dD = ray.dD; |
521 |
light_ray.dP = ray.dP; |
|
1.3.11
by Matteo F. Vescovi
Import upstream version 2.65a+svn53743 |
522 |
|
523 |
/* intersect with lamp */
|
|
1.5.3
by Matteo F. Vescovi
Import upstream version 2.68a |
524 |
float light_t = path_rng_1D(kg, rng, sample, num_samples, rng_offset + PRNG_LIGHT); |
1.3.11
by Matteo F. Vescovi
Import upstream version 2.65a+svn53743 |
525 |
float3 emission; |
526 |
||
1.5.4
by Matteo F. Vescovi
Import upstream version 2.69 |
527 |
if(indirect_lamp_emission(kg, &light_ray, state.flag, ray_pdf, light_t, &emission, state.bounce)) |
1.3.11
by Matteo F. Vescovi
Import upstream version 2.65a+svn53743 |
528 |
path_radiance_accum_emission(&L, throughput, emission, state.bounce); |
529 |
}
|
|
530 |
#endif
|
|
531 |
||
532 |
if(!hit) { |
|
1.3.7
by Kevin Roy
Import upstream version 2.61 |
533 |
/* eval background shader if nothing hit */
|
534 |
if(kernel_data.background.transparent && (state.flag & PATH_RAY_CAMERA)) { |
|
1.3.8
by Matteo F. Vescovi
Import upstream version 2.62 |
535 |
L_transparent += average(throughput); |
1.3.11
by Matteo F. Vescovi
Import upstream version 2.65a+svn53743 |
536 |
|
537 |
#ifdef __PASSES__
|
|
538 |
if(!(kernel_data.film.pass_flag & PASS_BACKGROUND)) |
|
539 |
#endif
|
|
540 |
break; |
|
1.3.7
by Kevin Roy
Import upstream version 2.61 |
541 |
}
|
1.3.11
by Matteo F. Vescovi
Import upstream version 2.65a+svn53743 |
542 |
|
1.3.8
by Matteo F. Vescovi
Import upstream version 2.62 |
543 |
#ifdef __BACKGROUND__
|
1.3.11
by Matteo F. Vescovi
Import upstream version 2.65a+svn53743 |
544 |
/* sample background shader */
|
1.5.4
by Matteo F. Vescovi
Import upstream version 2.69 |
545 |
float3 L_background = indirect_background(kg, &ray, state.flag, ray_pdf, state.bounce); |
1.3.11
by Matteo F. Vescovi
Import upstream version 2.65a+svn53743 |
546 |
path_radiance_accum_background(&L, throughput, L_background, state.bounce); |
1.3.7
by Kevin Roy
Import upstream version 2.61 |
547 |
#endif
|
548 |
||
549 |
break; |
|
550 |
}
|
|
551 |
||
552 |
/* setup shading */
|
|
553 |
ShaderData sd; |
|
1.5.4
by Matteo F. Vescovi
Import upstream version 2.69 |
554 |
shader_setup_from_ray(kg, &sd, &isect, &ray, state.bounce); |
1.5.3
by Matteo F. Vescovi
Import upstream version 2.68a |
555 |
float rbsdf = path_rng_1D(kg, rng, sample, num_samples, rng_offset + PRNG_BSDF); |
1.3.11
by Matteo F. Vescovi
Import upstream version 2.65a+svn53743 |
556 |
shader_eval_surface(kg, &sd, rbsdf, state.flag, SHADER_CONTEXT_MAIN); |
1.3.7
by Kevin Roy
Import upstream version 2.61 |
557 |
|
1.3.11
by Matteo F. Vescovi
Import upstream version 2.65a+svn53743 |
558 |
/* holdout */
|
1.3.7
by Kevin Roy
Import upstream version 2.61 |
559 |
#ifdef __HOLDOUT__
|
1.3.11
by Matteo F. Vescovi
Import upstream version 2.65a+svn53743 |
560 |
if((sd.flag & (SD_HOLDOUT|SD_HOLDOUT_MASK)) && (state.flag & PATH_RAY_CAMERA)) { |
561 |
if(kernel_data.background.transparent) { |
|
562 |
float3 holdout_weight; |
|
563 |
||
564 |
if(sd.flag & SD_HOLDOUT_MASK) |
|
565 |
holdout_weight = make_float3(1.0f, 1.0f, 1.0f); |
|
566 |
else
|
|
567 |
holdout_weight = shader_holdout_eval(kg, &sd); |
|
1.3.7
by Kevin Roy
Import upstream version 2.61 |
568 |
|
1.3.8
by Matteo F. Vescovi
Import upstream version 2.62 |
569 |
/* any throughput is ok, should all be identical here */
|
570 |
L_transparent += average(holdout_weight*throughput); |
|
1.3.11
by Matteo F. Vescovi
Import upstream version 2.65a+svn53743 |
571 |
}
|
572 |
||
1.5.2
by Matteo F. Vescovi
Import upstream version 2.67b |
573 |
if(sd.flag & SD_HOLDOUT_MASK) |
1.3.11
by Matteo F. Vescovi
Import upstream version 2.65a+svn53743 |
574 |
break; |
1.3.7
by Kevin Roy
Import upstream version 2.61 |
575 |
}
|
576 |
#endif
|
|
577 |
||
1.5.3
by Matteo F. Vescovi
Import upstream version 2.68a |
578 |
/* holdout mask objects do not write data passes */
|
579 |
kernel_write_data_passes(kg, buffer, &L, &sd, sample, state.flag, throughput); |
|
580 |
||
581 |
/* blurring of bsdf after bounces, for rays that have a small likelihood
|
|
582 |
* of following this particular path (diffuse, rough glossy) */
|
|
583 |
if(kernel_data.integrator.filter_glossy != FLT_MAX) { |
|
584 |
float blur_pdf = kernel_data.integrator.filter_glossy*min_ray_pdf; |
|
585 |
||
586 |
if(blur_pdf < 1.0f) { |
|
587 |
float blur_roughness = sqrtf(1.0f - blur_pdf)*0.5f; |
|
588 |
shader_bsdf_blur(kg, &sd, blur_roughness); |
|
589 |
}
|
|
590 |
}
|
|
591 |
||
1.3.7
by Kevin Roy
Import upstream version 2.61 |
592 |
#ifdef __EMISSION__
|
593 |
/* emission */
|
|
1.3.8
by Matteo F. Vescovi
Import upstream version 2.62 |
594 |
if(sd.flag & SD_EMISSION) { |
1.3.11
by Matteo F. Vescovi
Import upstream version 2.65a+svn53743 |
595 |
/* todo: is isect.t wrong here for transparent surfaces? */
|
596 |
float3 emission = indirect_primitive_emission(kg, &sd, isect.t, state.flag, ray_pdf); |
|
1.3.8
by Matteo F. Vescovi
Import upstream version 2.62 |
597 |
path_radiance_accum_emission(&L, throughput, emission, state.bounce); |
598 |
}
|
|
1.3.7
by Kevin Roy
Import upstream version 2.61 |
599 |
#endif
|
600 |
||
601 |
/* path termination. this is a strange place to put the termination, it's
|
|
1.3.11
by Matteo F. Vescovi
Import upstream version 2.65a+svn53743 |
602 |
* mainly due to the mixed in MIS that we use. gives too many unneeded
|
603 |
* shader evaluations, only need emission if we are going to terminate */
|
|
1.3.7
by Kevin Roy
Import upstream version 2.61 |
604 |
float probability = path_state_terminate_probability(kg, &state, throughput); |
605 |
||
1.5.3
by Matteo F. Vescovi
Import upstream version 2.68a |
606 |
if(probability == 0.0f) { |
1.3.7
by Kevin Roy
Import upstream version 2.61 |
607 |
break; |
1.5.3
by Matteo F. Vescovi
Import upstream version 2.68a |
608 |
}
|
609 |
else if(probability != 1.0f) { |
|
610 |
float terminate = path_rng_1D(kg, rng, sample, num_samples, rng_offset + PRNG_TERMINATE); |
|
611 |
||
612 |
if(terminate >= probability) |
|
613 |
break; |
|
614 |
||
615 |
throughput /= probability; |
|
616 |
}
|
|
1.5.2
by Matteo F. Vescovi
Import upstream version 2.67b |
617 |
|
1.3.9
by Matteo F. Vescovi
Import upstream version 2.63 |
618 |
#ifdef __AO__
|
619 |
/* ambient occlusion */
|
|
1.3.11
by Matteo F. Vescovi
Import upstream version 2.65a+svn53743 |
620 |
if(kernel_data.integrator.use_ambient_occlusion || (sd.flag & SD_AO)) { |
1.3.9
by Matteo F. Vescovi
Import upstream version 2.63 |
621 |
/* todo: solve correlation */
|
1.5.3
by Matteo F. Vescovi
Import upstream version 2.68a |
622 |
float bsdf_u, bsdf_v; |
623 |
path_rng_2D(kg, rng, sample, num_samples, rng_offset + PRNG_BSDF_U, &bsdf_u, &bsdf_v); |
|
1.3.9
by Matteo F. Vescovi
Import upstream version 2.63 |
624 |
|
1.3.11
by Matteo F. Vescovi
Import upstream version 2.65a+svn53743 |
625 |
float ao_factor = kernel_data.background.ao_factor; |
626 |
float3 ao_N; |
|
627 |
float3 ao_bsdf = shader_bsdf_ao(kg, &sd, ao_factor, &ao_N); |
|
1.3.9
by Matteo F. Vescovi
Import upstream version 2.63 |
628 |
float3 ao_D; |
629 |
float ao_pdf; |
|
1.5.4
by Matteo F. Vescovi
Import upstream version 2.69 |
630 |
float3 ao_alpha = shader_bsdf_alpha(kg, &sd); |
1.3.9
by Matteo F. Vescovi
Import upstream version 2.63 |
631 |
|
1.3.11
by Matteo F. Vescovi
Import upstream version 2.65a+svn53743 |
632 |
sample_cos_hemisphere(ao_N, bsdf_u, bsdf_v, &ao_D, &ao_pdf); |
1.3.9
by Matteo F. Vescovi
Import upstream version 2.63 |
633 |
|
634 |
if(dot(sd.Ng, ao_D) > 0.0f && ao_pdf != 0.0f) { |
|
635 |
Ray light_ray; |
|
636 |
float3 ao_shadow; |
|
637 |
||
638 |
light_ray.P = ray_offset(sd.P, sd.Ng); |
|
639 |
light_ray.D = ao_D; |
|
640 |
light_ray.t = kernel_data.background.ao_distance; |
|
1.3.11
by Matteo F. Vescovi
Import upstream version 2.65a+svn53743 |
641 |
#ifdef __OBJECT_MOTION__
|
642 |
light_ray.time = sd.time; |
|
643 |
#endif
|
|
1.5.2
by Matteo F. Vescovi
Import upstream version 2.67b |
644 |
light_ray.dP = sd.dP; |
645 |
light_ray.dD = differential3_zero(); |
|
1.3.9
by Matteo F. Vescovi
Import upstream version 2.63 |
646 |
|
1.3.11
by Matteo F. Vescovi
Import upstream version 2.65a+svn53743 |
647 |
if(!shadow_blocked(kg, &state, &light_ray, &ao_shadow)) |
1.5.4
by Matteo F. Vescovi
Import upstream version 2.69 |
648 |
path_radiance_accum_ao(&L, throughput, ao_alpha, ao_bsdf, ao_shadow, state.bounce); |
649 |
}
|
|
650 |
}
|
|
651 |
#endif
|
|
652 |
||
653 |
#ifdef __SUBSURFACE__
|
|
654 |
/* bssrdf scatter to a different location on the same object, replacing
|
|
655 |
* the closures with a diffuse BSDF */
|
|
656 |
if(sd.flag & SD_BSSRDF) { |
|
657 |
float bssrdf_probability; |
|
658 |
ShaderClosure *sc = subsurface_scatter_pick_closure(kg, &sd, &bssrdf_probability); |
|
659 |
||
660 |
/* modify throughput for picking bssrdf or bsdf */
|
|
661 |
throughput *= bssrdf_probability; |
|
662 |
||
663 |
/* do bssrdf scatter step if we picked a bssrdf closure */
|
|
664 |
if(sc) { |
|
665 |
uint lcg_state = lcg_init(*rng + rng_offset + sample*0x68bc21eb); |
|
666 |
||
667 |
if(old_subsurface_scatter_use(&sd)) { |
|
668 |
old_subsurface_scatter_step(kg, &sd, state.flag, sc, &lcg_state, false); |
|
669 |
}
|
|
670 |
else { |
|
671 |
ShaderData bssrdf_sd[BSSRDF_MAX_HITS]; |
|
672 |
float bssrdf_u, bssrdf_v; |
|
673 |
path_rng_2D(kg, rng, sample, num_samples, rng_offset + PRNG_BSDF_U, &bssrdf_u, &bssrdf_v); |
|
674 |
int num_hits = subsurface_scatter_multi_step(kg, &sd, bssrdf_sd, state.flag, sc, &lcg_state, bssrdf_u, bssrdf_v, false); |
|
675 |
||
676 |
/* compute lighting with the BSDF closure */
|
|
677 |
for(int hit = 0; hit < num_hits; hit++) { |
|
678 |
float3 tp = throughput; |
|
679 |
PathState hit_state = state; |
|
680 |
Ray hit_ray = ray; |
|
681 |
float hit_ray_t = ray_t; |
|
682 |
float hit_ray_pdf = ray_pdf; |
|
683 |
float hit_min_ray_pdf = min_ray_pdf; |
|
684 |
||
685 |
hit_state.flag |= PATH_RAY_BSSRDF_ANCESTOR; |
|
686 |
||
687 |
if(kernel_path_integrate_lighting(kg, rng, sample, num_samples, &bssrdf_sd[hit], |
|
688 |
&tp, &hit_min_ray_pdf, &hit_ray_pdf, &hit_state, rng_offset+PRNG_BOUNCE_NUM, &L, &hit_ray, &hit_ray_t)) { |
|
689 |
kernel_path_indirect(kg, rng, sample, hit_ray, buffer, |
|
690 |
tp, num_samples, num_samples, |
|
691 |
hit_min_ray_pdf, hit_ray_pdf, hit_state, rng_offset+PRNG_BOUNCE_NUM*2, &L); |
|
692 |
||
693 |
/* for render passes, sum and reset indirect light pass variables
|
|
694 |
* for the next samples */
|
|
695 |
path_radiance_sum_indirect(&L); |
|
696 |
path_radiance_reset_indirect(&L); |
|
697 |
}
|
|
698 |
}
|
|
699 |
||
700 |
break; |
|
701 |
}
|
|
702 |
}
|
|
703 |
}
|
|
704 |
#endif
|
|
705 |
||
706 |
/* The following code is the same as in kernel_path_integrate_lighting(),
|
|
707 |
but for CUDA the function call is slower. */
|
|
1.3.7
by Kevin Roy
Import upstream version 2.61 |
708 |
#ifdef __EMISSION__
|
709 |
if(kernel_data.integrator.use_direct_light) { |
|
710 |
/* sample illumination from lights to find path contribution */
|
|
711 |
if(sd.flag & SD_BSDF_HAS_EVAL) { |
|
1.5.3
by Matteo F. Vescovi
Import upstream version 2.68a |
712 |
float light_t = path_rng_1D(kg, rng, sample, num_samples, rng_offset + PRNG_LIGHT); |
713 |
#ifdef __MULTI_CLOSURE__
|
|
714 |
float light_o = 0.0f; |
|
715 |
#else
|
|
716 |
float light_o = path_rng_1D(kg, rng, sample, num_samples, rng_offset + PRNG_LIGHT_F); |
|
717 |
#endif
|
|
718 |
float light_u, light_v; |
|
719 |
path_rng_2D(kg, rng, sample, num_samples, rng_offset + PRNG_LIGHT_U, &light_u, &light_v); |
|
1.3.7
by Kevin Roy
Import upstream version 2.61 |
720 |
|
721 |
Ray light_ray; |
|
1.3.8
by Matteo F. Vescovi
Import upstream version 2.62 |
722 |
BsdfEval L_light; |
1.3.12
by Matteo F. Vescovi
Import upstream version 2.66 |
723 |
bool is_lamp; |
1.3.11
by Matteo F. Vescovi
Import upstream version 2.65a+svn53743 |
724 |
|
725 |
#ifdef __OBJECT_MOTION__
|
|
726 |
light_ray.time = sd.time; |
|
1.3.7
by Kevin Roy
Import upstream version 2.61 |
727 |
#endif
|
1.3.11
by Matteo F. Vescovi
Import upstream version 2.65a+svn53743 |
728 |
|
1.5.4
by Matteo F. Vescovi
Import upstream version 2.69 |
729 |
if(direct_emission(kg, &sd, -1, light_t, light_o, light_u, light_v, &light_ray, &L_light, &is_lamp, state.bounce)) { |
1.3.11
by Matteo F. Vescovi
Import upstream version 2.65a+svn53743 |
730 |
/* trace shadow ray */
|
731 |
float3 shadow; |
|
732 |
||
733 |
if(!shadow_blocked(kg, &state, &light_ray, &shadow)) { |
|
734 |
/* accumulate */
|
|
1.3.12
by Matteo F. Vescovi
Import upstream version 2.66 |
735 |
path_radiance_accum_light(&L, throughput, &L_light, shadow, 1.0f, state.bounce, is_lamp); |
1.3.7
by Kevin Roy
Import upstream version 2.61 |
736 |
}
|
737 |
}
|
|
738 |
}
|
|
739 |
}
|
|
740 |
#endif
|
|
741 |
||
742 |
/* no BSDF? we can stop here */
|
|
1.5.2
by Matteo F. Vescovi
Import upstream version 2.67b |
743 |
if(!(sd.flag & SD_BSDF)) |
1.3.7
by Kevin Roy
Import upstream version 2.61 |
744 |
break; |
745 |
||
746 |
/* sample BSDF */
|
|
747 |
float bsdf_pdf; |
|
1.3.8
by Matteo F. Vescovi
Import upstream version 2.62 |
748 |
BsdfEval bsdf_eval; |
1.3.7
by Kevin Roy
Import upstream version 2.61 |
749 |
float3 bsdf_omega_in; |
750 |
differential3 bsdf_domega_in; |
|
1.5.3
by Matteo F. Vescovi
Import upstream version 2.68a |
751 |
float bsdf_u, bsdf_v; |
752 |
path_rng_2D(kg, rng, sample, num_samples, rng_offset + PRNG_BSDF_U, &bsdf_u, &bsdf_v); |
|
1.3.7
by Kevin Roy
Import upstream version 2.61 |
753 |
int label; |
754 |
||
755 |
label = shader_bsdf_sample(kg, &sd, bsdf_u, bsdf_v, &bsdf_eval, |
|
756 |
&bsdf_omega_in, &bsdf_domega_in, &bsdf_pdf); |
|
757 |
||
1.3.8
by Matteo F. Vescovi
Import upstream version 2.62 |
758 |
if(bsdf_pdf == 0.0f || bsdf_eval_is_zero(&bsdf_eval)) |
1.3.7
by Kevin Roy
Import upstream version 2.61 |
759 |
break; |
760 |
||
761 |
/* modify throughput */
|
|
1.3.8
by Matteo F. Vescovi
Import upstream version 2.62 |
762 |
path_radiance_bsdf_bounce(&L, &throughput, &bsdf_eval, bsdf_pdf, state.bounce, label); |
1.3.7
by Kevin Roy
Import upstream version 2.61 |
763 |
|
764 |
/* set labels */
|
|
1.3.11
by Matteo F. Vescovi
Import upstream version 2.65a+svn53743 |
765 |
if(!(label & LABEL_TRANSPARENT)) { |
766 |
ray_pdf = bsdf_pdf; |
|
767 |
#ifdef __LAMP_MIS__
|
|
768 |
ray_t = 0.0f; |
|
769 |
#endif
|
|
770 |
min_ray_pdf = fminf(bsdf_pdf, min_ray_pdf); |
|
771 |
}
|
|
772 |
||
773 |
/* update path state */
|
|
774 |
path_state_next(kg, &state, label); |
|
775 |
||
776 |
/* setup ray */
|
|
777 |
ray.P = ray_offset(sd.P, (label & LABEL_TRANSMIT)? -sd.Ng: sd.Ng); |
|
778 |
ray.D = bsdf_omega_in; |
|
779 |
||
780 |
if(state.bounce == 0) |
|
781 |
ray.t -= sd.ray_length; /* clipping works through transparent */ |
|
782 |
else
|
|
783 |
ray.t = FLT_MAX; |
|
784 |
||
785 |
#ifdef __RAY_DIFFERENTIALS__
|
|
786 |
ray.dP = sd.dP; |
|
787 |
ray.dD = bsdf_domega_in; |
|
788 |
#endif
|
|
789 |
}
|
|
790 |
||
791 |
float3 L_sum = path_radiance_sum(kg, &L); |
|
792 |
||
793 |
#ifdef __CLAMP_SAMPLE__
|
|
794 |
path_radiance_clamp(&L, &L_sum, kernel_data.integrator.sample_clamp); |
|
795 |
#endif
|
|
796 |
||
797 |
kernel_write_light_passes(kg, buffer, &L, sample); |
|
798 |
||
799 |
return make_float4(L_sum.x, L_sum.y, L_sum.z, 1.0f - L_transparent); |
|
800 |
}
|
|
801 |
||
1.5.4
by Matteo F. Vescovi
Import upstream version 2.69 |
802 |
#ifdef __BRANCHED_PATH__
|
803 |
||
804 |
__device_noinline void kernel_branched_path_integrate_lighting(KernelGlobals *kg, RNG *rng, |
|
805 |
int sample, int aa_samples, |
|
1.5.2
by Matteo F. Vescovi
Import upstream version 2.67b |
806 |
ShaderData *sd, float3 throughput, float num_samples_adjust, |
807 |
float min_ray_pdf, float ray_pdf, PathState state, |
|
808 |
int rng_offset, PathRadiance *L, __global float *buffer) |
|
809 |
{
|
|
810 |
#ifdef __EMISSION__
|
|
811 |
/* sample illumination from lights to find path contribution */
|
|
812 |
if(sd->flag & SD_BSDF_HAS_EVAL) { |
|
813 |
Ray light_ray; |
|
814 |
BsdfEval L_light; |
|
815 |
bool is_lamp; |
|
816 |
||
817 |
#ifdef __OBJECT_MOTION__
|
|
818 |
light_ray.time = sd->time; |
|
819 |
#endif
|
|
820 |
||
821 |
/* lamp sampling */
|
|
822 |
for(int i = 0; i < kernel_data.integrator.num_all_lights; i++) { |
|
1.5.3
by Matteo F. Vescovi
Import upstream version 2.68a |
823 |
int num_samples = ceil_to_int(num_samples_adjust*light_select_num_samples(kg, i)); |
1.5.2
by Matteo F. Vescovi
Import upstream version 2.67b |
824 |
float num_samples_inv = num_samples_adjust/(num_samples*kernel_data.integrator.num_all_lights); |
1.5.3
by Matteo F. Vescovi
Import upstream version 2.68a |
825 |
RNG lamp_rng = cmj_hash(*rng, i); |
1.5.2
by Matteo F. Vescovi
Import upstream version 2.67b |
826 |
|
827 |
if(kernel_data.integrator.pdf_triangles != 0.0f) |
|
828 |
num_samples_inv *= 0.5f; |
|
829 |
||
830 |
for(int j = 0; j < num_samples; j++) { |
|
1.5.3
by Matteo F. Vescovi
Import upstream version 2.68a |
831 |
float light_u, light_v; |
832 |
path_rng_2D(kg, &lamp_rng, sample*num_samples + j, aa_samples*num_samples, rng_offset + PRNG_LIGHT_U, &light_u, &light_v); |
|
1.5.2
by Matteo F. Vescovi
Import upstream version 2.67b |
833 |
|
1.5.4
by Matteo F. Vescovi
Import upstream version 2.69 |
834 |
if(direct_emission(kg, sd, i, 0.0f, 0.0f, light_u, light_v, &light_ray, &L_light, &is_lamp, state.bounce)) { |
1.5.2
by Matteo F. Vescovi
Import upstream version 2.67b |
835 |
/* trace shadow ray */
|
836 |
float3 shadow; |
|
837 |
||
838 |
if(!shadow_blocked(kg, &state, &light_ray, &shadow)) { |
|
839 |
/* accumulate */
|
|
840 |
path_radiance_accum_light(L, throughput*num_samples_inv, &L_light, shadow, num_samples_inv, state.bounce, is_lamp); |
|
841 |
}
|
|
842 |
}
|
|
843 |
}
|
|
844 |
}
|
|
845 |
||
846 |
/* mesh light sampling */
|
|
847 |
if(kernel_data.integrator.pdf_triangles != 0.0f) { |
|
1.5.3
by Matteo F. Vescovi
Import upstream version 2.68a |
848 |
int num_samples = ceil_to_int(num_samples_adjust*kernel_data.integrator.mesh_light_samples); |
1.5.2
by Matteo F. Vescovi
Import upstream version 2.67b |
849 |
float num_samples_inv = num_samples_adjust/num_samples; |
850 |
||
851 |
if(kernel_data.integrator.num_all_lights) |
|
852 |
num_samples_inv *= 0.5f; |
|
853 |
||
854 |
for(int j = 0; j < num_samples; j++) { |
|
1.5.3
by Matteo F. Vescovi
Import upstream version 2.68a |
855 |
float light_t = path_rng_1D(kg, rng, sample*num_samples + j, aa_samples*num_samples, rng_offset + PRNG_LIGHT); |
856 |
float light_u, light_v; |
|
857 |
path_rng_2D(kg, rng, sample*num_samples + j, aa_samples*num_samples, rng_offset + PRNG_LIGHT_U, &light_u, &light_v); |
|
1.5.2
by Matteo F. Vescovi
Import upstream version 2.67b |
858 |
|
859 |
/* only sample triangle lights */
|
|
860 |
if(kernel_data.integrator.num_all_lights) |
|
861 |
light_t = 0.5f*light_t; |
|
862 |
||
1.5.4
by Matteo F. Vescovi
Import upstream version 2.69 |
863 |
if(direct_emission(kg, sd, -1, light_t, 0.0f, light_u, light_v, &light_ray, &L_light, &is_lamp, state.bounce)) { |
1.5.2
by Matteo F. Vescovi
Import upstream version 2.67b |
864 |
/* trace shadow ray */
|
865 |
float3 shadow; |
|
866 |
||
867 |
if(!shadow_blocked(kg, &state, &light_ray, &shadow)) { |
|
868 |
/* accumulate */
|
|
869 |
path_radiance_accum_light(L, throughput*num_samples_inv, &L_light, shadow, num_samples_inv, state.bounce, is_lamp); |
|
870 |
}
|
|
871 |
}
|
|
872 |
}
|
|
873 |
}
|
|
874 |
}
|
|
875 |
#endif
|
|
876 |
||
877 |
for(int i = 0; i< sd->num_closure; i++) { |
|
878 |
const ShaderClosure *sc = &sd->closure[i]; |
|
879 |
||
880 |
if(!CLOSURE_IS_BSDF(sc->type)) |
|
881 |
continue; |
|
882 |
/* transparency is not handled here, but in outer loop */
|
|
883 |
if(sc->type == CLOSURE_BSDF_TRANSPARENT_ID) |
|
884 |
continue; |
|
885 |
||
886 |
int num_samples; |
|
887 |
||
888 |
if(CLOSURE_IS_BSDF_DIFFUSE(sc->type)) |
|
889 |
num_samples = kernel_data.integrator.diffuse_samples; |
|
1.5.4
by Matteo F. Vescovi
Import upstream version 2.69 |
890 |
else if(CLOSURE_IS_BSDF_BSSRDF(sc->type)) |
891 |
num_samples = 1; |
|
1.5.2
by Matteo F. Vescovi
Import upstream version 2.67b |
892 |
else if(CLOSURE_IS_BSDF_GLOSSY(sc->type)) |
893 |
num_samples = kernel_data.integrator.glossy_samples; |
|
894 |
else
|
|
895 |
num_samples = kernel_data.integrator.transmission_samples; |
|
896 |
||
1.5.3
by Matteo F. Vescovi
Import upstream version 2.68a |
897 |
num_samples = ceil_to_int(num_samples_adjust*num_samples); |
1.5.2
by Matteo F. Vescovi
Import upstream version 2.67b |
898 |
|
899 |
float num_samples_inv = num_samples_adjust/num_samples; |
|
1.5.3
by Matteo F. Vescovi
Import upstream version 2.68a |
900 |
RNG bsdf_rng = cmj_hash(*rng, i); |
1.5.2
by Matteo F. Vescovi
Import upstream version 2.67b |
901 |
|
902 |
for(int j = 0; j < num_samples; j++) { |
|
903 |
/* sample BSDF */
|
|
904 |
float bsdf_pdf; |
|
905 |
BsdfEval bsdf_eval; |
|
906 |
float3 bsdf_omega_in; |
|
907 |
differential3 bsdf_domega_in; |
|
1.5.3
by Matteo F. Vescovi
Import upstream version 2.68a |
908 |
float bsdf_u, bsdf_v; |
909 |
path_rng_2D(kg, &bsdf_rng, sample*num_samples + j, aa_samples*num_samples, rng_offset + PRNG_BSDF_U, &bsdf_u, &bsdf_v); |
|
1.5.2
by Matteo F. Vescovi
Import upstream version 2.67b |
910 |
int label; |
911 |
||
912 |
label = shader_bsdf_sample_closure(kg, sd, sc, bsdf_u, bsdf_v, &bsdf_eval, |
|
913 |
&bsdf_omega_in, &bsdf_domega_in, &bsdf_pdf); |
|
914 |
||
915 |
if(bsdf_pdf == 0.0f || bsdf_eval_is_zero(&bsdf_eval)) |
|
916 |
continue; |
|
917 |
||
918 |
/* modify throughput */
|
|
919 |
float3 tp = throughput; |
|
920 |
path_radiance_bsdf_bounce(L, &tp, &bsdf_eval, bsdf_pdf, state.bounce, label); |
|
921 |
||
922 |
/* set labels */
|
|
1.5.4
by Matteo F. Vescovi
Import upstream version 2.69 |
923 |
float min_ray_pdf = fminf(bsdf_pdf, FLT_MAX); |
1.5.2
by Matteo F. Vescovi
Import upstream version 2.67b |
924 |
|
925 |
/* modify path state */
|
|
926 |
PathState ps = state; |
|
927 |
path_state_next(kg, &ps, label); |
|
928 |
||
929 |
/* setup ray */
|
|
930 |
Ray bsdf_ray; |
|
931 |
||
932 |
bsdf_ray.P = ray_offset(sd->P, (label & LABEL_TRANSMIT)? -sd->Ng: sd->Ng); |
|
933 |
bsdf_ray.D = bsdf_omega_in; |
|
934 |
bsdf_ray.t = FLT_MAX; |
|
935 |
#ifdef __RAY_DIFFERENTIALS__
|
|
936 |
bsdf_ray.dP = sd->dP; |
|
937 |
bsdf_ray.dD = bsdf_domega_in; |
|
938 |
#endif
|
|
939 |
#ifdef __OBJECT_MOTION__
|
|
940 |
bsdf_ray.time = sd->time; |
|
941 |
#endif
|
|
942 |
||
943 |
kernel_path_indirect(kg, rng, sample*num_samples + j, bsdf_ray, buffer, |
|
1.5.3
by Matteo F. Vescovi
Import upstream version 2.68a |
944 |
tp*num_samples_inv, num_samples, aa_samples*num_samples, |
1.5.2
by Matteo F. Vescovi
Import upstream version 2.67b |
945 |
min_ray_pdf, bsdf_pdf, ps, rng_offset+PRNG_BOUNCE_NUM, L); |
946 |
||
947 |
/* for render passes, sum and reset indirect light pass variables
|
|
948 |
* for the next samples */
|
|
949 |
path_radiance_sum_indirect(L); |
|
950 |
path_radiance_reset_indirect(L); |
|
951 |
}
|
|
952 |
}
|
|
953 |
}
|
|
954 |
||
1.5.4
by Matteo F. Vescovi
Import upstream version 2.69 |
955 |
__device float4 kernel_branched_path_integrate(KernelGlobals *kg, RNG *rng, int sample, Ray ray, __global float *buffer) |
1.3.11
by Matteo F. Vescovi
Import upstream version 2.65a+svn53743 |
956 |
{
|
957 |
/* initialize */
|
|
958 |
PathRadiance L; |
|
959 |
float3 throughput = make_float3(1.0f, 1.0f, 1.0f); |
|
960 |
float L_transparent = 0.0f; |
|
961 |
||
962 |
path_radiance_init(&L, kernel_data.film.use_light_pass); |
|
963 |
||
964 |
float ray_pdf = 0.0f; |
|
965 |
PathState state; |
|
966 |
int rng_offset = PRNG_BASE_NUM; |
|
1.5.3
by Matteo F. Vescovi
Import upstream version 2.68a |
967 |
#ifdef __CMJ__
|
968 |
int aa_samples = kernel_data.integrator.aa_samples; |
|
969 |
#else
|
|
970 |
int aa_samples = 0; |
|
971 |
#endif
|
|
1.3.11
by Matteo F. Vescovi
Import upstream version 2.65a+svn53743 |
972 |
|
973 |
path_state_init(&state); |
|
974 |
||
975 |
for(;; rng_offset += PRNG_BOUNCE_NUM) { |
|
976 |
/* intersect scene */
|
|
977 |
Intersection isect; |
|
978 |
uint visibility = path_state_ray_visibility(kg, &state); |
|
979 |
||
1.5.2
by Matteo F. Vescovi
Import upstream version 2.67b |
980 |
#ifdef __HAIR__
|
981 |
float difl = 0.0f, extmax = 0.0f; |
|
982 |
uint lcg_state = 0; |
|
983 |
||
984 |
if(kernel_data.bvh.have_curves) { |
|
985 |
if((kernel_data.cam.resolution == 1) && (state.flag & PATH_RAY_CAMERA)) { |
|
986 |
float3 pixdiff = ray.dD.dx + ray.dD.dy; |
|
987 |
/*pixdiff = pixdiff - dot(pixdiff, ray.D)*ray.D;*/
|
|
1.5.4
by Matteo F. Vescovi
Import upstream version 2.69 |
988 |
difl = kernel_data.curve.minimum_width * len(pixdiff) * 0.5f; |
1.5.2
by Matteo F. Vescovi
Import upstream version 2.67b |
989 |
}
|
990 |
||
1.5.4
by Matteo F. Vescovi
Import upstream version 2.69 |
991 |
extmax = kernel_data.curve.maximum_width; |
1.5.2
by Matteo F. Vescovi
Import upstream version 2.67b |
992 |
lcg_state = lcg_init(*rng + rng_offset + sample*0x51633e2d); |
993 |
}
|
|
994 |
||
995 |
if(!scene_intersect(kg, &ray, visibility, &isect, &lcg_state, difl, extmax)) { |
|
996 |
#else
|
|
1.3.11
by Matteo F. Vescovi
Import upstream version 2.65a+svn53743 |
997 |
if(!scene_intersect(kg, &ray, visibility, &isect)) { |
1.5.2
by Matteo F. Vescovi
Import upstream version 2.67b |
998 |
#endif
|
1.3.11
by Matteo F. Vescovi
Import upstream version 2.65a+svn53743 |
999 |
/* eval background shader if nothing hit */
|
1000 |
if(kernel_data.background.transparent) { |
|
1001 |
L_transparent += average(throughput); |
|
1002 |
||
1003 |
#ifdef __PASSES__
|
|
1004 |
if(!(kernel_data.film.pass_flag & PASS_BACKGROUND)) |
|
1005 |
#endif
|
|
1006 |
break; |
|
1007 |
}
|
|
1008 |
||
1009 |
#ifdef __BACKGROUND__
|
|
1010 |
/* sample background shader */
|
|
1.5.4
by Matteo F. Vescovi
Import upstream version 2.69 |
1011 |
float3 L_background = indirect_background(kg, &ray, state.flag, ray_pdf, state.bounce); |
1.3.11
by Matteo F. Vescovi
Import upstream version 2.65a+svn53743 |
1012 |
path_radiance_accum_background(&L, throughput, L_background, state.bounce); |
1013 |
#endif
|
|
1014 |
||
1015 |
break; |
|
1016 |
}
|
|
1017 |
||
1018 |
/* setup shading */
|
|
1019 |
ShaderData sd; |
|
1.5.4
by Matteo F. Vescovi
Import upstream version 2.69 |
1020 |
shader_setup_from_ray(kg, &sd, &isect, &ray, state.bounce); |
1.5.3
by Matteo F. Vescovi
Import upstream version 2.68a |
1021 |
shader_eval_surface(kg, &sd, 0.0f, state.flag, SHADER_CONTEXT_MAIN); |
1.3.11
by Matteo F. Vescovi
Import upstream version 2.65a+svn53743 |
1022 |
shader_merge_closures(kg, &sd); |
1023 |
||
1024 |
/* holdout */
|
|
1025 |
#ifdef __HOLDOUT__
|
|
1026 |
if((sd.flag & (SD_HOLDOUT|SD_HOLDOUT_MASK))) { |
|
1027 |
if(kernel_data.background.transparent) { |
|
1028 |
float3 holdout_weight; |
|
1029 |
||
1030 |
if(sd.flag & SD_HOLDOUT_MASK) |
|
1031 |
holdout_weight = make_float3(1.0f, 1.0f, 1.0f); |
|
1032 |
else
|
|
1033 |
holdout_weight = shader_holdout_eval(kg, &sd); |
|
1034 |
||
1035 |
/* any throughput is ok, should all be identical here */
|
|
1036 |
L_transparent += average(holdout_weight*throughput); |
|
1037 |
}
|
|
1038 |
||
1.5.2
by Matteo F. Vescovi
Import upstream version 2.67b |
1039 |
if(sd.flag & SD_HOLDOUT_MASK) |
1.3.11
by Matteo F. Vescovi
Import upstream version 2.65a+svn53743 |
1040 |
break; |
1041 |
}
|
|
1042 |
#endif
|
|
1043 |
||
1.5.3
by Matteo F. Vescovi
Import upstream version 2.68a |
1044 |
/* holdout mask objects do not write data passes */
|
1045 |
kernel_write_data_passes(kg, buffer, &L, &sd, sample, state.flag, throughput); |
|
1046 |
||
1.3.11
by Matteo F. Vescovi
Import upstream version 2.65a+svn53743 |
1047 |
#ifdef __EMISSION__
|
1048 |
/* emission */
|
|
1049 |
if(sd.flag & SD_EMISSION) { |
|
1050 |
float3 emission = indirect_primitive_emission(kg, &sd, isect.t, state.flag, ray_pdf); |
|
1051 |
path_radiance_accum_emission(&L, throughput, emission, state.bounce); |
|
1052 |
}
|
|
1053 |
#endif
|
|
1054 |
||
1055 |
/* transparency termination */
|
|
1056 |
if(state.flag & PATH_RAY_TRANSPARENT) { |
|
1057 |
/* path termination. this is a strange place to put the termination, it's
|
|
1058 |
* mainly due to the mixed in MIS that we use. gives too many unneeded
|
|
1059 |
* shader evaluations, only need emission if we are going to terminate */
|
|
1060 |
float probability = path_state_terminate_probability(kg, &state, throughput); |
|
1061 |
||
1.5.3
by Matteo F. Vescovi
Import upstream version 2.68a |
1062 |
if(probability == 0.0f) { |
1.3.11
by Matteo F. Vescovi
Import upstream version 2.65a+svn53743 |
1063 |
break; |
1.5.3
by Matteo F. Vescovi
Import upstream version 2.68a |
1064 |
}
|
1065 |
else if(probability != 1.0f) { |
|
1066 |
float terminate = path_rng_1D(kg, rng, sample, aa_samples, rng_offset + PRNG_TERMINATE); |
|
1067 |
||
1068 |
if(terminate >= probability) |
|
1069 |
break; |
|
1070 |
||
1071 |
throughput /= probability; |
|
1072 |
}
|
|
1.3.11
by Matteo F. Vescovi
Import upstream version 2.65a+svn53743 |
1073 |
}
|
1074 |
||
1.5.4
by Matteo F. Vescovi
Import upstream version 2.69 |
1075 |
#ifdef __AO__
|
1076 |
/* ambient occlusion */
|
|
1077 |
if(kernel_data.integrator.use_ambient_occlusion || (sd.flag & SD_AO)) { |
|
1078 |
int num_samples = kernel_data.integrator.ao_samples; |
|
1079 |
float num_samples_inv = 1.0f/num_samples; |
|
1080 |
float ao_factor = kernel_data.background.ao_factor; |
|
1081 |
float3 ao_N; |
|
1082 |
float3 ao_bsdf = shader_bsdf_ao(kg, &sd, ao_factor, &ao_N); |
|
1083 |
float3 ao_alpha = shader_bsdf_alpha(kg, &sd); |
|
1084 |
||
1085 |
for(int j = 0; j < num_samples; j++) { |
|
1086 |
float bsdf_u, bsdf_v; |
|
1087 |
path_rng_2D(kg, rng, sample*num_samples + j, aa_samples*num_samples, rng_offset + PRNG_BSDF_U, &bsdf_u, &bsdf_v); |
|
1088 |
||
1089 |
float3 ao_D; |
|
1090 |
float ao_pdf; |
|
1091 |
||
1092 |
sample_cos_hemisphere(ao_N, bsdf_u, bsdf_v, &ao_D, &ao_pdf); |
|
1093 |
||
1094 |
if(dot(sd.Ng, ao_D) > 0.0f && ao_pdf != 0.0f) { |
|
1095 |
Ray light_ray; |
|
1096 |
float3 ao_shadow; |
|
1097 |
||
1098 |
light_ray.P = ray_offset(sd.P, sd.Ng); |
|
1099 |
light_ray.D = ao_D; |
|
1100 |
light_ray.t = kernel_data.background.ao_distance; |
|
1101 |
#ifdef __OBJECT_MOTION__
|
|
1102 |
light_ray.time = sd.time; |
|
1103 |
#endif
|
|
1104 |
light_ray.dP = sd.dP; |
|
1105 |
light_ray.dD = differential3_zero(); |
|
1106 |
||
1107 |
if(!shadow_blocked(kg, &state, &light_ray, &ao_shadow)) |
|
1108 |
path_radiance_accum_ao(&L, throughput*num_samples_inv, ao_alpha, ao_bsdf, ao_shadow, state.bounce); |
|
1109 |
}
|
|
1110 |
}
|
|
1111 |
}
|
|
1112 |
#endif
|
|
1113 |
||
1.5.2
by Matteo F. Vescovi
Import upstream version 2.67b |
1114 |
#ifdef __SUBSURFACE__
|
1115 |
/* bssrdf scatter to a different location on the same object */
|
|
1116 |
if(sd.flag & SD_BSSRDF) { |
|
1117 |
for(int i = 0; i< sd.num_closure; i++) { |
|
1118 |
ShaderClosure *sc = &sd.closure[i]; |
|
1119 |
||
1120 |
if(!CLOSURE_IS_BSSRDF(sc->type)) |
|
1121 |
continue; |
|
1122 |
||
1123 |
/* set up random number generator */
|
|
1124 |
uint lcg_state = lcg_init(*rng + rng_offset + sample*0x68bc21eb); |
|
1125 |
int num_samples = kernel_data.integrator.subsurface_samples; |
|
1.3.11
by Matteo F. Vescovi
Import upstream version 2.65a+svn53743 |
1126 |
float num_samples_inv = 1.0f/num_samples; |
1.5.4
by Matteo F. Vescovi
Import upstream version 2.69 |
1127 |
RNG bssrdf_rng = cmj_hash(*rng, i); |
1128 |
||
1129 |
state.flag |= PATH_RAY_BSSRDF_ANCESTOR; |
|
1.3.11
by Matteo F. Vescovi
Import upstream version 2.65a+svn53743 |
1130 |
|
1.5.2
by Matteo F. Vescovi
Import upstream version 2.67b |
1131 |
/* do subsurface scatter step with copy of shader data, this will
|
1132 |
* replace the BSSRDF with a diffuse BSDF closure */
|
|
1.3.11
by Matteo F. Vescovi
Import upstream version 2.65a+svn53743 |
1133 |
for(int j = 0; j < num_samples; j++) { |
1.5.4
by Matteo F. Vescovi
Import upstream version 2.69 |
1134 |
if(old_subsurface_scatter_use(&sd)) { |
1135 |
ShaderData bssrdf_sd = sd; |
|
1136 |
old_subsurface_scatter_step(kg, &bssrdf_sd, state.flag, sc, &lcg_state, true); |
|
1137 |
||
1138 |
/* compute lighting with the BSDF closure */
|
|
1139 |
kernel_branched_path_integrate_lighting(kg, rng, sample*num_samples + j, |
|
1140 |
aa_samples*num_samples, |
|
1141 |
&bssrdf_sd, throughput, num_samples_inv, |
|
1142 |
ray_pdf, ray_pdf, state, rng_offset, &L, buffer); |
|
1143 |
}
|
|
1144 |
else { |
|
1145 |
ShaderData bssrdf_sd[BSSRDF_MAX_HITS]; |
|
1146 |
float bssrdf_u, bssrdf_v; |
|
1147 |
path_rng_2D(kg, &bssrdf_rng, sample*num_samples + j, aa_samples*num_samples, rng_offset + PRNG_BSDF_U, &bssrdf_u, &bssrdf_v); |
|
1148 |
int num_hits = subsurface_scatter_multi_step(kg, &sd, bssrdf_sd, state.flag, sc, &lcg_state, bssrdf_u, bssrdf_v, true); |
|
1149 |
||
1150 |
/* compute lighting with the BSDF closure */
|
|
1151 |
for(int hit = 0; hit < num_hits; hit++) |
|
1152 |
kernel_branched_path_integrate_lighting(kg, rng, sample*num_samples + j, |
|
1153 |
aa_samples*num_samples, |
|
1154 |
&bssrdf_sd[hit], throughput, num_samples_inv, |
|
1155 |
ray_pdf, ray_pdf, state, rng_offset+PRNG_BOUNCE_NUM, &L, buffer); |
|
1156 |
}
|
|
1.3.11
by Matteo F. Vescovi
Import upstream version 2.65a+svn53743 |
1157 |
}
|
1.5.4
by Matteo F. Vescovi
Import upstream version 2.69 |
1158 |
|
1159 |
state.flag &= ~PATH_RAY_BSSRDF_ANCESTOR; |
|
1.3.11
by Matteo F. Vescovi
Import upstream version 2.65a+svn53743 |
1160 |
}
|
1161 |
}
|
|
1162 |
#endif
|
|
1163 |
||
1.5.2
by Matteo F. Vescovi
Import upstream version 2.67b |
1164 |
/* lighting */
|
1.5.4
by Matteo F. Vescovi
Import upstream version 2.69 |
1165 |
kernel_branched_path_integrate_lighting(kg, rng, sample, aa_samples, |
1166 |
&sd, throughput, 1.0f, ray_pdf, ray_pdf, state, rng_offset, &L, buffer); |
|
1.3.11
by Matteo F. Vescovi
Import upstream version 2.65a+svn53743 |
1167 |
|
1168 |
/* continue in case of transparency */
|
|
1169 |
throughput *= shader_bsdf_transparency(kg, &sd); |
|
1170 |
||
1171 |
if(is_zero(throughput)) |
|
1172 |
break; |
|
1173 |
||
1174 |
path_state_next(kg, &state, LABEL_TRANSPARENT); |
|
1175 |
ray.P = ray_offset(sd.P, -sd.Ng); |
|
1176 |
ray.t -= sd.ray_length; /* clipping works through transparent */ |
|
1177 |
}
|
|
1178 |
||
1179 |
float3 L_sum = path_radiance_sum(kg, &L); |
|
1.3.8
by Matteo F. Vescovi
Import upstream version 2.62 |
1180 |
|
1.3.9
by Matteo F. Vescovi
Import upstream version 2.63 |
1181 |
#ifdef __CLAMP_SAMPLE__
|
1182 |
path_radiance_clamp(&L, &L_sum, kernel_data.integrator.sample_clamp); |
|
1183 |
#endif
|
|
1184 |
||
1.3.8
by Matteo F. Vescovi
Import upstream version 2.62 |
1185 |
kernel_write_light_passes(kg, buffer, &L, sample); |
1186 |
||
1187 |
return make_float4(L_sum.x, L_sum.y, L_sum.z, 1.0f - L_transparent); |
|
1.3.7
by Kevin Roy
Import upstream version 2.61 |
1188 |
}
|
1189 |
||
1.3.11
by Matteo F. Vescovi
Import upstream version 2.65a+svn53743 |
1190 |
#endif
|
1191 |
||
1.5.4
by Matteo F. Vescovi
Import upstream version 2.69 |
1192 |
__device_inline void kernel_path_trace_setup(KernelGlobals *kg, __global uint *rng_state, int sample, int x, int y, RNG *rng, Ray *ray) |
1.3.7
by Kevin Roy
Import upstream version 2.61 |
1193 |
{
|
1194 |
float filter_u; |
|
1195 |
float filter_v; |
|
1.5.3
by Matteo F. Vescovi
Import upstream version 2.68a |
1196 |
#ifdef __CMJ__
|
1197 |
int num_samples = kernel_data.integrator.aa_samples; |
|
1198 |
#else
|
|
1199 |
int num_samples = 0; |
|
1200 |
#endif
|
|
1.3.7
by Kevin Roy
Import upstream version 2.61 |
1201 |
|
1.5.4
by Matteo F. Vescovi
Import upstream version 2.69 |
1202 |
path_rng_init(kg, rng_state, sample, num_samples, rng, x, y, &filter_u, &filter_v); |
1.3.7
by Kevin Roy
Import upstream version 2.61 |
1203 |
|
1204 |
/* sample camera ray */
|
|
1205 |
||
1.5.3
by Matteo F. Vescovi
Import upstream version 2.68a |
1206 |
float lens_u = 0.0f, lens_v = 0.0f; |
1207 |
||
1208 |
if(kernel_data.cam.aperturesize > 0.0f) |
|
1.5.4
by Matteo F. Vescovi
Import upstream version 2.69 |
1209 |
path_rng_2D(kg, rng, sample, num_samples, PRNG_LENS_U, &lens_u, &lens_v); |
1.5.3
by Matteo F. Vescovi
Import upstream version 2.68a |
1210 |
|
1211 |
float time = 0.0f; |
|
1.3.7
by Kevin Roy
Import upstream version 2.61 |
1212 |
|
1.3.11
by Matteo F. Vescovi
Import upstream version 2.65a+svn53743 |
1213 |
#ifdef __CAMERA_MOTION__
|
1.5.3
by Matteo F. Vescovi
Import upstream version 2.68a |
1214 |
if(kernel_data.cam.shuttertime != -1.0f) |
1.5.4
by Matteo F. Vescovi
Import upstream version 2.69 |
1215 |
time = path_rng_1D(kg, rng, sample, num_samples, PRNG_TIME); |
1216 |
#endif
|
|
1217 |
||
1218 |
camera_sample(kg, x, y, filter_u, filter_v, lens_u, lens_v, time, ray); |
|
1219 |
}
|
|
1220 |
||
1221 |
__device void kernel_path_trace(KernelGlobals *kg, |
|
1222 |
__global float *buffer, __global uint *rng_state, |
|
1223 |
int sample, int x, int y, int offset, int stride) |
|
1224 |
{
|
|
1225 |
/* buffer offset */
|
|
1226 |
int index = offset + x + y*stride; |
|
1227 |
int pass_stride = kernel_data.film.pass_stride; |
|
1228 |
||
1229 |
rng_state += index; |
|
1230 |
buffer += index*pass_stride; |
|
1231 |
||
1232 |
/* initialize random numbers and ray */
|
|
1233 |
RNG rng; |
|
1234 |
Ray ray; |
|
1235 |
||
1236 |
kernel_path_trace_setup(kg, rng_state, sample, x, y, &rng, &ray); |
|
1237 |
||
1238 |
/* integrate */
|
|
1239 |
float4 L; |
|
1240 |
||
1241 |
if (ray.t != 0.0f) |
|
1242 |
L = kernel_path_integrate(kg, &rng, sample, ray, buffer); |
|
1243 |
else
|
|
1244 |
L = make_float4(0.0f, 0.0f, 0.0f, 0.0f); |
|
1245 |
||
1246 |
/* accumulate result in output buffer */
|
|
1247 |
kernel_write_pass_float4(buffer, sample, L); |
|
1248 |
||
1249 |
path_rng_end(kg, rng_state, rng); |
|
1250 |
}
|
|
1251 |
||
1252 |
#ifdef __BRANCHED_PATH__
|
|
1253 |
__device void kernel_branched_path_trace(KernelGlobals *kg, |
|
1254 |
__global float *buffer, __global uint *rng_state, |
|
1255 |
int sample, int x, int y, int offset, int stride) |
|
1256 |
{
|
|
1257 |
/* buffer offset */
|
|
1258 |
int index = offset + x + y*stride; |
|
1259 |
int pass_stride = kernel_data.film.pass_stride; |
|
1260 |
||
1261 |
rng_state += index; |
|
1262 |
buffer += index*pass_stride; |
|
1263 |
||
1264 |
/* initialize random numbers and ray */
|
|
1265 |
RNG rng; |
|
1266 |
Ray ray; |
|
1267 |
||
1268 |
kernel_path_trace_setup(kg, rng_state, sample, x, y, &rng, &ray); |
|
1269 |
||
1270 |
/* integrate */
|
|
1271 |
float4 L; |
|
1272 |
||
1273 |
if (ray.t != 0.0f) |
|
1274 |
L = kernel_branched_path_integrate(kg, &rng, sample, ray, buffer); |
|
1275 |
else
|
|
1276 |
L = make_float4(0.0f, 0.0f, 0.0f, 0.0f); |
|
1277 |
||
1278 |
/* accumulate result in output buffer */
|
|
1279 |
kernel_write_pass_float4(buffer, sample, L); |
|
1280 |
||
1281 |
path_rng_end(kg, rng_state, rng); |
|
1282 |
}
|
|
1283 |
#endif
|
|
1.3.7
by Kevin Roy
Import upstream version 2.61 |
1284 |
|
1285 |
CCL_NAMESPACE_END
|
|
1286 |