| 67 | } |
| 68 | |
| 69 | SYCL_EXTERNAL Light_EvalRes PointLight_eval(const Light* super, |
| 70 | const DifferentialGeometry& dg, |
| 71 | const Vec3fa& dir) |
| 72 | { |
| 73 | const PointLight* self = (PointLight*)super; |
| 74 | Light_EvalRes res; |
| 75 | res.value = Vec3fa(0.f); |
| 76 | res.dist = inf; |
| 77 | res.pdf = 0.f; |
| 78 | |
| 79 | if (self->radius > 0.f) { |
| 80 | const Vec3fa A = self->position - dg.P; |
| 81 | const float a = dot(dir, dir); |
| 82 | const float b = 2.f * dot(dir, A); |
| 83 | const float centerDist2 = dot(A, A); |
| 84 | const float c = centerDist2 - sqr(self->radius); |
| 85 | const float radical = sqr(b) - 4.f*a*c; |
| 86 | |
| 87 | if (radical > 0.f) { |
| 88 | const float t_near = (b - sqrt(radical)) / (2.f*a); |
| 89 | const float t_far = (b + sqrt(radical)) / (2.f*a); |
| 90 | |
| 91 | if (t_far > 0.0f) { |
| 92 | // TODO: handle interior case |
| 93 | res.dist = t_near; |
| 94 | const float sinTheta2 = sqr(self->radius) * rcp(centerDist2); |
| 95 | const float cosTheta = sqrt(1.f - sinTheta2); |
| 96 | res.pdf = uniformSampleConePDF(cosTheta); |
| 97 | const float invdist = rcp(t_near); |
| 98 | res.value = self->power * res.pdf * sqr(invdist); |
| 99 | } |
| 100 | } |
| 101 | } |
| 102 | |
| 103 | return res; |
| 104 | } |
| 105 | |
| 106 | // Exports (called from C++) |
| 107 | ////////////////////////////////////////////////////////////////////////////// |