~ubuntu-branches/ubuntu/trusty/blender/trusty

« back to all changes in this revision

Viewing changes to intern/cycles/kernel/kernel_light.h

  • Committer: Package Import Robot
  • Author(s): Jeremy Bicha
  • Date: 2013-03-06 12:08:47 UTC
  • mfrom: (1.5.1) (14.1.8 experimental)
  • Revision ID: package-import@ubuntu.com-20130306120847-frjfaryb2zrotwcg
Tags: 2.66a-1ubuntu1
* Resynchronize with Debian (LP: #1076930, #1089256, #1052743, #999024,
  #1122888, #1147084)
* debian/control:
  - Lower build-depends on libavcodec-dev since we're not
    doing the libav9 transition in Ubuntu yet

Show diffs side-by-side

added added

removed removed

Lines of Context:
18
18
 
19
19
CCL_NAMESPACE_BEGIN
20
20
 
 
21
/* Light Sample result */
 
22
 
21
23
typedef struct LightSample {
22
 
        float3 P;
23
 
        float3 D;
24
 
        float3 Ng;
25
 
        float t;
26
 
        int object;
27
 
        int prim;
28
 
        int shader;
29
 
        LightType type;
 
24
        float3 P;                       /* position on light, or direction for distant light */
 
25
        float3 Ng;                      /* normal on light */
 
26
        float3 D;                       /* direction from shading point to light */
 
27
        float t;                        /* distance to light (FLT_MAX for distant light) */
 
28
        float pdf;                      /* light sampling probability density function */
 
29
        float eval_fac;         /* intensity multiplier */
 
30
        int object;                     /* object id for triangle/curve lights */
 
31
        int prim;                       /* primitive id for triangle/curve ligths */
 
32
        int shader;                     /* shader id */
 
33
        int lamp;                       /* lamp id */
 
34
        LightType type;         /* type of light */
30
35
} LightSample;
31
36
 
32
 
/* Regular Light */
33
 
 
34
 
__device float3 disk_light_sample(float3 v, float randu, float randv)
35
 
{
36
 
        float3 ru, rv;
37
 
 
38
 
        make_orthonormals(v, &ru, &rv);
39
 
        to_unit_disk(&randu, &randv);
40
 
 
41
 
        return ru*randu + rv*randv;
42
 
}
43
 
 
44
 
__device float3 distant_light_sample(float3 D, float size, float randu, float randv)
45
 
{
46
 
        return normalize(D + disk_light_sample(D, randu, randv)*size);
47
 
}
48
 
 
49
 
__device float3 sphere_light_sample(float3 P, float3 center, float size, float randu, float randv)
50
 
{
51
 
        return disk_light_sample(normalize(P - center), randu, randv)*size;
52
 
}
53
 
 
54
 
__device float3 area_light_sample(float3 axisu, float3 axisv, float randu, float randv)
55
 
{
56
 
        randu = randu - 0.5f;
57
 
        randv = randv - 0.5f;
58
 
 
59
 
        return axisu*randu + axisv*randv;
60
 
}
 
37
/* Background Light */
 
38
 
 
39
#ifdef __BACKGROUND_MIS__
61
40
 
62
41
__device float3 background_light_sample(KernelGlobals *kg, float randu, float randv, float *pdf)
63
42
{
64
43
        /* for the following, the CDF values are actually a pair of floats, with the
65
 
           function value as X and the actual CDF as Y.  The last entry's function
66
 
           value is the CDF total. */
 
44
         * function value as X and the actual CDF as Y.  The last entry's function
 
45
         * value is the CDF total. */
67
46
        int res = kernel_data.integrator.pdf_background_res;
68
47
        int cdf_count = res + 1;
69
48
 
165
144
 
166
145
        return pdf * kernel_data.integrator.pdf_lights;
167
146
}
168
 
 
169
 
__device void regular_light_sample(KernelGlobals *kg, int point,
170
 
        float randu, float randv, float3 P, LightSample *ls, float *pdf)
171
 
{
172
 
        float4 data0 = kernel_tex_fetch(__light_data, point*LIGHT_SIZE + 0);
173
 
        float4 data1 = kernel_tex_fetch(__light_data, point*LIGHT_SIZE + 1);
 
147
#endif
 
148
 
 
149
/* Regular Light */
 
150
 
 
151
__device float3 disk_light_sample(float3 v, float randu, float randv)
 
152
{
 
153
        float3 ru, rv;
 
154
 
 
155
        make_orthonormals(v, &ru, &rv);
 
156
        to_unit_disk(&randu, &randv);
 
157
 
 
158
        return ru*randu + rv*randv;
 
159
}
 
160
 
 
161
__device float3 distant_light_sample(float3 D, float radius, float randu, float randv)
 
162
{
 
163
        return normalize(D + disk_light_sample(D, randu, randv)*radius);
 
164
}
 
165
 
 
166
__device float3 sphere_light_sample(float3 P, float3 center, float radius, float randu, float randv)
 
167
{
 
168
        return disk_light_sample(normalize(P - center), randu, randv)*radius;
 
169
}
 
170
 
 
171
__device float3 area_light_sample(float3 axisu, float3 axisv, float randu, float randv)
 
172
{
 
173
        randu = randu - 0.5f;
 
174
        randv = randv - 0.5f;
 
175
 
 
176
        return axisu*randu + axisv*randv;
 
177
}
 
178
 
 
179
__device float spot_light_attenuation(float4 data1, float4 data2, LightSample *ls)
 
180
{
 
181
        float3 dir = make_float3(data2.y, data2.z, data2.w);
 
182
        float3 I = ls->Ng;
 
183
 
 
184
        float spot_angle = data1.w;
 
185
        float spot_smooth = data2.x;
 
186
 
 
187
        float attenuation = dot(dir, I);
 
188
 
 
189
        if(attenuation <= spot_angle) {
 
190
                attenuation = 0.0f;
 
191
        }
 
192
        else {
 
193
                float t = attenuation - spot_angle;
 
194
 
 
195
                if(t < spot_smooth && spot_smooth != 0.0f)
 
196
                        attenuation *= smoothstepf(t/spot_smooth);
 
197
        }
 
198
 
 
199
        return attenuation;
 
200
}
 
201
 
 
202
__device float lamp_light_pdf(KernelGlobals *kg, const float3 Ng, const float3 I, float t)
 
203
{
 
204
        float cos_pi = dot(Ng, I);
 
205
 
 
206
        if(cos_pi <= 0.0f)
 
207
                return 0.0f;
 
208
        
 
209
        return t*t/cos_pi;
 
210
}
 
211
 
 
212
__device void lamp_light_sample(KernelGlobals *kg, int lamp,
 
213
        float randu, float randv, float3 P, LightSample *ls)
 
214
{
 
215
        float4 data0 = kernel_tex_fetch(__light_data, lamp*LIGHT_SIZE + 0);
 
216
        float4 data1 = kernel_tex_fetch(__light_data, lamp*LIGHT_SIZE + 1);
174
217
 
175
218
        LightType type = (LightType)__float_as_int(data0.x);
176
219
        ls->type = type;
 
220
        ls->shader = __float_as_int(data1.x);
 
221
        ls->object = ~0;
 
222
        ls->prim = ~0;
 
223
        ls->lamp = lamp;
177
224
 
178
225
        if(type == LIGHT_DISTANT) {
179
226
                /* distant light */
180
 
                float3 D = make_float3(data0.y, data0.z, data0.w);
181
 
                float size = data1.y;
 
227
                float3 lightD = make_float3(data0.y, data0.z, data0.w);
 
228
                float3 D = lightD;
 
229
                float radius = data1.y;
 
230
                float invarea = data1.w;
182
231
 
183
 
                if(size > 0.0f)
184
 
                        D = distant_light_sample(D, size, randu, randv);
 
232
                if(radius > 0.0f)
 
233
                        D = distant_light_sample(D, radius, randu, randv);
185
234
 
186
235
                ls->P = D;
187
236
                ls->Ng = D;
188
237
                ls->D = -D;
189
238
                ls->t = FLT_MAX;
 
239
 
 
240
                float costheta = dot(lightD, D);
 
241
                ls->pdf = invarea/(costheta*costheta*costheta);
 
242
                ls->eval_fac = ls->pdf*kernel_data.integrator.inv_pdf_lights;
190
243
        }
191
244
#ifdef __BACKGROUND_MIS__
192
245
        else if(type == LIGHT_BACKGROUND) {
193
246
                /* infinite area light (e.g. light dome or env light) */
194
 
                float3 D = background_light_sample(kg, randu, randv, pdf);
 
247
                float3 D = background_light_sample(kg, randu, randv, &ls->pdf);
195
248
 
196
249
                ls->P = D;
197
250
                ls->Ng = D;
198
251
                ls->D = -D;
199
252
                ls->t = FLT_MAX;
 
253
                ls->eval_fac = 1.0f;
200
254
        }
201
255
#endif
202
256
        else {
203
257
                ls->P = make_float3(data0.y, data0.z, data0.w);
204
258
 
205
 
                if(type == LIGHT_POINT) {
206
 
                        float size = data1.y;
207
 
 
208
 
                        /* sphere light */
209
 
                        if(size > 0.0f)
210
 
                                ls->P += sphere_light_sample(P, ls->P, size, randu, randv);
211
 
 
212
 
                        ls->Ng = normalize(P - ls->P);
 
259
                if(type == LIGHT_POINT || type == LIGHT_SPOT) {
 
260
                        float radius = data1.y;
 
261
 
 
262
                        if(radius > 0.0f)
 
263
                                /* sphere light */
 
264
                                ls->P += sphere_light_sample(P, ls->P, radius, randu, randv);
 
265
 
 
266
                        ls->D = normalize_len(ls->P - P, &ls->t);
 
267
                        ls->Ng = -ls->D;
 
268
 
 
269
                        float invarea = data1.z;
 
270
                        ls->eval_fac = (0.25f*M_1_PI_F)*invarea;
 
271
                        ls->pdf = invarea;
 
272
 
 
273
                        if(type == LIGHT_SPOT) {
 
274
                                /* spot light attentuation */
 
275
                                float4 data2 = kernel_tex_fetch(__light_data, lamp*LIGHT_SIZE + 2);
 
276
                                ls->eval_fac *= spot_light_attenuation(data1, data2, ls);
 
277
                        }
213
278
                }
214
279
                else {
215
280
                        /* area light */
216
 
                        float4 data2 = kernel_tex_fetch(__light_data, point*LIGHT_SIZE + 2);
217
 
                        float4 data3 = kernel_tex_fetch(__light_data, point*LIGHT_SIZE + 3);
 
281
                        float4 data2 = kernel_tex_fetch(__light_data, lamp*LIGHT_SIZE + 2);
 
282
                        float4 data3 = kernel_tex_fetch(__light_data, lamp*LIGHT_SIZE + 3);
218
283
 
219
 
                        float3 axisu = make_float3(data1.y, data1.z, data2.w);
 
284
                        float3 axisu = make_float3(data1.y, data1.z, data1.w);
220
285
                        float3 axisv = make_float3(data2.y, data2.z, data2.w);
221
286
                        float3 D = make_float3(data3.y, data3.z, data3.w);
222
287
 
223
288
                        ls->P += area_light_sample(axisu, axisv, randu, randv);
224
289
                        ls->Ng = D;
 
290
                        ls->D = normalize_len(ls->P - P, &ls->t);
 
291
 
 
292
                        float invarea = data2.x;
 
293
 
 
294
                        ls->eval_fac = 0.25f*invarea;
 
295
                        ls->pdf = invarea;
225
296
                }
226
297
 
227
 
                ls->t = 0.0f;
 
298
                ls->eval_fac *= kernel_data.integrator.inv_pdf_lights;
 
299
                ls->pdf *= lamp_light_pdf(kg, ls->Ng, -ls->D, ls->t);
228
300
        }
229
 
 
 
301
}
 
302
 
 
303
__device bool lamp_light_eval(KernelGlobals *kg, int lamp, float3 P, float3 D, float t, LightSample *ls)
 
304
{
 
305
        float4 data0 = kernel_tex_fetch(__light_data, lamp*LIGHT_SIZE + 0);
 
306
        float4 data1 = kernel_tex_fetch(__light_data, lamp*LIGHT_SIZE + 1);
 
307
 
 
308
        LightType type = (LightType)__float_as_int(data0.x);
 
309
        ls->type = type;
230
310
        ls->shader = __float_as_int(data1.x);
231
311
        ls->object = ~0;
232
312
        ls->prim = ~0;
233
 
}
234
 
 
235
 
__device float regular_light_pdf(KernelGlobals *kg,
236
 
        const float3 Ng, const float3 I, float t)
237
 
{
238
 
        float pdf = kernel_data.integrator.pdf_lights;
239
 
 
240
 
        if(t == FLT_MAX)
241
 
                return pdf;
242
 
 
243
 
        float cos_pi = dot(Ng, I);
244
 
 
245
 
        if(cos_pi <= 0.0f)
246
 
                return 0.0f;
247
 
 
248
 
        return t*t*pdf/cos_pi;
 
313
        ls->lamp = lamp;
 
314
 
 
315
        if(!(ls->shader & SHADER_USE_MIS))
 
316
                return false;
 
317
 
 
318
        if(type == LIGHT_DISTANT) {
 
319
                /* distant light */
 
320
                float radius = data1.y;
 
321
 
 
322
                if(radius == 0.0f)
 
323
                        return false;
 
324
                if(t != FLT_MAX)
 
325
                        return false;
 
326
 
 
327
                /* a distant light is infinitely far away, but equivalent to a disk
 
328
                 * shaped light exactly 1 unit away from the current shading point.
 
329
                 *
 
330
                 *     radius              t^2/cos(theta)
 
331
                 *  <---------->           t = sqrt(1^2 + tan(theta)^2)
 
332
                 *       tan(th)           area = radius*radius*pi
 
333
                 *       <----->
 
334
                 *        \    |           (1 + tan(theta)^2)/cos(theta)
 
335
                 *         \   |           (1 + tan(acos(cos(theta)))^2)/cos(theta)
 
336
                 *       t  \th| 1         simplifies to
 
337
                 *           \-|           1/(cos(theta)^3)
 
338
                 *            \|           magic!
 
339
                 *             P
 
340
                 */
 
341
 
 
342
                float3 lightD = make_float3(data0.y, data0.z, data0.w);
 
343
                float costheta = dot(-lightD, D);
 
344
                float cosangle = data1.z;
 
345
 
 
346
                if(costheta < cosangle)
 
347
                        return false;
 
348
 
 
349
                ls->P = -D;
 
350
                ls->Ng = -D;
 
351
                ls->D = D;
 
352
                ls->t = FLT_MAX;
 
353
 
 
354
                float invarea = data1.w;
 
355
                ls->pdf = invarea/(costheta*costheta*costheta);
 
356
                ls->eval_fac = ls->pdf;
 
357
        }
 
358
        else if(type == LIGHT_POINT || type == LIGHT_SPOT) {
 
359
                float3 lightP = make_float3(data0.y, data0.z, data0.w);
 
360
                float radius = data1.y;
 
361
 
 
362
                /* sphere light */
 
363
                if(radius == 0.0f)
 
364
                        return false;
 
365
 
 
366
                if(!ray_aligned_disk_intersect(P, D, t,
 
367
                        lightP, radius, &ls->P, &ls->t))
 
368
                        return false;
 
369
 
 
370
                ls->Ng = -D;
 
371
                ls->D = D;
 
372
 
 
373
                float invarea = data1.z;
 
374
                ls->eval_fac = (0.25f*M_1_PI_F)*invarea;
 
375
                ls->pdf = invarea;
 
376
 
 
377
                if(type == LIGHT_SPOT) {
 
378
                        /* spot light attentuation */
 
379
                        float4 data2 = kernel_tex_fetch(__light_data, lamp*LIGHT_SIZE + 2);
 
380
                        ls->eval_fac *= spot_light_attenuation(data1, data2, ls);
 
381
 
 
382
                        if(ls->eval_fac == 0.0f)
 
383
                                return false;
 
384
                }
 
385
        }
 
386
        else if(type == LIGHT_AREA) {
 
387
                /* area light */
 
388
                float4 data2 = kernel_tex_fetch(__light_data, lamp*LIGHT_SIZE + 2);
 
389
                float4 data3 = kernel_tex_fetch(__light_data, lamp*LIGHT_SIZE + 3);
 
390
 
 
391
                float invarea = data2.x;
 
392
                if(invarea == 0.0f)
 
393
                        return false;
 
394
 
 
395
                float3 axisu = make_float3(data1.y, data1.z, data1.w);
 
396
                float3 axisv = make_float3(data2.y, data2.z, data2.w);
 
397
                float3 Ng = make_float3(data3.y, data3.z, data3.w);
 
398
 
 
399
                /* one sided */
 
400
                if(dot(D, Ng) >= 0.0f)
 
401
                        return false;
 
402
 
 
403
                ls->P = make_float3(data0.y, data0.z, data0.w);
 
404
 
 
405
                if(!ray_quad_intersect(P, D, t,
 
406
                        ls->P, axisu, axisv, &ls->P, &ls->t))
 
407
                        return false;
 
408
 
 
409
                ls->D = D;
 
410
                ls->Ng = Ng;
 
411
                ls->pdf = invarea;
 
412
                ls->eval_fac = 0.25f*ls->pdf;
 
413
        }
 
414
        else
 
415
                return false;
 
416
 
 
417
        /* compute pdf */
 
418
        if(ls->t != FLT_MAX)
 
419
                ls->pdf *= lamp_light_pdf(kg, ls->Ng, -ls->D, ls->t);
 
420
        ls->eval_fac *= kernel_data.integrator.inv_pdf_lights;
 
421
 
 
422
        return true;
249
423
}
250
424
 
251
425
/* Triangle Light */
252
426
 
 
427
__device void object_transform_light_sample(KernelGlobals *kg, LightSample *ls, int object, float time)
 
428
{
 
429
#ifdef __INSTANCING__
 
430
        /* instance transform */
 
431
        if(object >= 0) {
 
432
#ifdef __OBJECT_MOTION__
 
433
                Transform itfm;
 
434
                Transform tfm = object_fetch_transform_motion_test(kg, object, time, &itfm);
 
435
#else
 
436
                Transform tfm = object_fetch_transform(kg, object, OBJECT_TRANSFORM);
 
437
                Transform itfm = object_fetch_transform(kg, object, OBJECT_INVERSE_TRANSFORM);
 
438
#endif
 
439
 
 
440
                ls->P = transform_point(&tfm, ls->P);
 
441
                ls->Ng = normalize(transform_direction(&tfm, ls->Ng));
 
442
        }
 
443
#endif
 
444
}
 
445
 
253
446
__device void triangle_light_sample(KernelGlobals *kg, int prim, int object,
254
 
        float randu, float randv, LightSample *ls)
 
447
        float randu, float randv, float time, LightSample *ls)
255
448
{
256
449
        /* triangle, so get position, normal, shader */
257
450
        ls->P = triangle_sample_MT(kg, prim, randu, randv);
258
451
        ls->Ng = triangle_normal_MT(kg, prim, &ls->shader);
259
452
        ls->object = object;
260
453
        ls->prim = prim;
 
454
        ls->lamp = ~0;
 
455
        ls->shader |= SHADER_USE_MIS;
261
456
        ls->t = 0.0f;
262
 
        ls->type = LIGHT_AREA;
 
457
        ls->type = LIGHT_TRIANGLE;
 
458
        ls->eval_fac = 1.0f;
263
459
 
264
 
#ifdef __INSTANCING__
265
 
        /* instance transform */
266
 
        if(ls->object >= 0) {
267
 
                object_position_transform(kg, ls->object, &ls->P);
268
 
                object_normal_transform(kg, ls->object, &ls->Ng);
269
 
        }
270
 
#endif
 
460
        object_transform_light_sample(kg, ls, object, time);
271
461
}
272
462
 
273
463
__device float triangle_light_pdf(KernelGlobals *kg,
274
464
        const float3 Ng, const float3 I, float t)
275
465
{
 
466
        float pdf = kernel_data.integrator.pdf_triangles;
276
467
        float cos_pi = fabsf(dot(Ng, I));
277
468
 
278
469
        if(cos_pi == 0.0f)
279
470
                return 0.0f;
280
471
        
281
 
        return (t*t*kernel_data.integrator.pdf_triangles)/cos_pi;
282
 
}
 
472
        return t*t*pdf/cos_pi;
 
473
}
 
474
 
 
475
/* Curve Light */
 
476
 
 
477
#ifdef __HAIR__
 
478
 
 
479
__device void curve_segment_light_sample(KernelGlobals *kg, int prim, int object,
 
480
        int segment, float randu, float randv, float time, LightSample *ls)
 
481
{
 
482
        /* this strand code needs completion */
 
483
        float4 v00 = kernel_tex_fetch(__curves, prim);
 
484
 
 
485
        int k0 = __float_as_int(v00.x) + segment;
 
486
        int k1 = k0 + 1;
 
487
 
 
488
        float4 P1 = kernel_tex_fetch(__curve_keys, k0);
 
489
        float4 P2 = kernel_tex_fetch(__curve_keys, k1);
 
490
 
 
491
        float l = len(P2 - P1);
 
492
 
 
493
        float r1 = P1.w;
 
494
        float r2 = P2.w;
 
495
        float3 tg = float4_to_float3(P2 - P1) / l;
 
496
        float3 xc = make_float3(tg.x * tg.z, tg.y * tg.z, -(tg.x * tg.x + tg.y * tg.y));
 
497
        if (dot(xc, xc) == 0.0f)
 
498
                xc = make_float3(tg.x * tg.y, -(tg.x * tg.x + tg.z * tg.z), tg.z * tg.y);
 
499
        xc = normalize(xc);
 
500
        float3 yc = cross(tg, xc);
 
501
        float gd = ((r2 - r1)/l);
 
502
 
 
503
        /* normal currently ignores gradient */
 
504
        ls->Ng = sinf(2 * M_PI_F * randv) * xc + cosf(2 * M_PI_F * randv) * yc;
 
505
        ls->P = randu * l * tg + (gd * l + r1) * ls->Ng;
 
506
        ls->object = object;
 
507
        ls->prim = prim;
 
508
        ls->lamp = ~0;
 
509
        ls->t = 0.0f;
 
510
        ls->type = LIGHT_STRAND;
 
511
        ls->eval_fac = 1.0f;
 
512
        ls->shader = __float_as_int(v00.z) | SHADER_USE_MIS;
 
513
 
 
514
        object_transform_light_sample(kg, ls, object, time);
 
515
}
 
516
 
 
517
#endif
283
518
 
284
519
/* Light Distribution */
285
520
 
286
521
__device int light_distribution_sample(KernelGlobals *kg, float randt)
287
522
{
288
523
        /* this is basically std::upper_bound as used by pbrt, to find a point light or
289
 
           triangle to emit from, proportional to area. a good improvement would be to
290
 
           also sample proportional to power, though it's not so well defined with
291
 
           OSL shaders. */
 
524
         * triangle to emit from, proportional to area. a good improvement would be to
 
525
         * also sample proportional to power, though it's not so well defined with
 
526
         * OSL shaders. */
292
527
        int first = 0;
293
528
        int len = kernel_data.integrator.num_distribution + 1;
294
529
 
305
540
                }
306
541
        }
307
542
 
308
 
        first = max(0, first-1);
309
 
        kernel_assert(first >= 0 && first < kernel_data.integrator.num_distribution);
310
 
 
311
 
        return first;
 
543
        /* clamping should not be needed but float rounding errors seem to
 
544
         * make this fail on rare occasions */
 
545
        return clamp(first-1, 0, kernel_data.integrator.num_distribution-1);
312
546
}
313
547
 
314
548
/* Generic Light */
315
549
 
316
 
__device void light_sample(KernelGlobals *kg, float randt, float randu, float randv, float3 P, LightSample *ls, float *pdf)
 
550
__device void light_sample(KernelGlobals *kg, float randt, float randu, float randv, float time, float3 P, LightSample *ls)
317
551
{
318
552
        /* sample index */
319
553
        int index = light_distribution_sample(kg, randt);
324
558
 
325
559
        if(prim >= 0) {
326
560
                int object = __float_as_int(l.w);
327
 
                triangle_light_sample(kg, prim, object, randu, randv, ls);
328
 
        }
329
 
        else {
330
 
                int point = -prim-1;
331
 
                regular_light_sample(kg, point, randu, randv, P, ls, pdf);
332
 
        }
333
 
 
334
 
        /* compute incoming direction and distance */
335
 
        if(ls->t != FLT_MAX)
 
561
#ifdef __HAIR__
 
562
                int segment = __float_as_int(l.z);
 
563
#endif
 
564
 
 
565
#ifdef __HAIR__
 
566
                if (segment != ~0)
 
567
                        curve_segment_light_sample(kg, prim, object, segment, randu, randv, time, ls);
 
568
                else
 
569
#endif
 
570
                        triangle_light_sample(kg, prim, object, randu, randv, time, ls);
 
571
 
 
572
                /* compute incoming direction, distance and pdf */
336
573
                ls->D = normalize_len(ls->P - P, &ls->t);
337
 
}
338
 
 
339
 
__device float light_sample_pdf(KernelGlobals *kg, LightSample *ls, float3 I, float t)
340
 
{
341
 
        float pdf;
342
 
 
343
 
        if(ls->prim != ~0)
344
 
                pdf = triangle_light_pdf(kg, ls->Ng, I, t);
 
574
                ls->pdf = triangle_light_pdf(kg, ls->Ng, -ls->D, ls->t);
 
575
        }
 
576
        else {
 
577
                int lamp = -prim-1;
 
578
                lamp_light_sample(kg, lamp, randu, randv, P, ls);
 
579
        }
 
580
}
 
581
 
 
582
__device int light_select_num_samples(KernelGlobals *kg, int index)
 
583
{
 
584
        float4 data3 = kernel_tex_fetch(__light_data, index*LIGHT_SIZE + 3);
 
585
        return __float_as_int(data3.x);
 
586
}
 
587
 
 
588
__device void light_select(KernelGlobals *kg, int index, float randu, float randv, float3 P, LightSample *ls)
 
589
{
 
590
        lamp_light_sample(kg, index, randu, randv, P, ls);
 
591
}
 
592
 
 
593
__device int lamp_light_eval_sample(KernelGlobals *kg, float randt)
 
594
{
 
595
        /* sample index */
 
596
        int index = light_distribution_sample(kg, randt);
 
597
 
 
598
        /* fetch light data */
 
599
        float4 l = kernel_tex_fetch(__light_distribution, index);
 
600
        int prim = __float_as_int(l.y);
 
601
 
 
602
        if(prim < 0) {
 
603
                int lamp = -prim-1;
 
604
                return lamp;
 
605
        }
345
606
        else
346
 
                pdf = regular_light_pdf(kg, ls->Ng, I, t);
347
 
        
348
 
        return pdf;
349
 
}
350
 
 
351
 
__device void light_select(KernelGlobals *kg, int index, float randu, float randv, float3 P, LightSample *ls, float *pdf)
352
 
{
353
 
        regular_light_sample(kg, index, randu, randv, P, ls, pdf);
354
 
}
355
 
 
356
 
__device float light_select_pdf(KernelGlobals *kg, LightSample *ls, float3 I, float t)
357
 
{
358
 
        return regular_light_pdf(kg, ls->Ng, I, t);
 
607
                return ~0;
359
608
}
360
609
 
361
610
CCL_NAMESPACE_END