/* SPDX-License-Identifier: Apache-2.0 * Copyright 2011-2022 Blender Foundation */ #pragma once #include "kernel/light/common.h" CCL_NAMESPACE_BEGIN template ccl_device_inline bool point_light_sample(const ccl_global KernelLight *klight, const float randu, const float randv, const float3 P, ccl_private LightSample *ls) { ls->P = make_float3(klight->co[0], klight->co[1], klight->co[2]); float3 center = make_float3(klight->co[0], klight->co[1], klight->co[2]); float radius = klight->spot.radius; /* disk oriented normal */ const float3 lightN = normalize(P - center); ls->P = center; if (radius > 0.0f) { ls->P += disk_light_sample(lightN, randu, randv) * radius; } ls->pdf = klight->spot.invarea; ls->D = normalize_len(ls->P - P, &ls->t); /* we set the light normal to the outgoing direction to support texturing */ ls->Ng = -ls->D; ls->eval_fac = M_1_PI_F * 0.25f * klight->spot.invarea; if (!in_volume_segment && ls->eval_fac == 0.0f) { return false; } float2 uv = map_to_sphere(ls->Ng); ls->u = uv.x; ls->v = uv.y; ls->pdf *= lamp_light_pdf(lightN, -ls->D, ls->t); return true; } ccl_device_forceinline void point_light_update_position(const ccl_global KernelLight *klight, ccl_private LightSample *ls, const float3 P) { ls->D = normalize_len(ls->P - P, &ls->t); ls->Ng = -ls->D; float2 uv = map_to_sphere(ls->Ng); ls->u = uv.x; ls->v = uv.y; float invarea = klight->spot.invarea; ls->eval_fac = (0.25f * M_1_PI_F) * invarea; ls->pdf = invarea; } ccl_device_inline bool point_light_intersect(const ccl_global KernelLight *klight, const ccl_private Ray *ccl_restrict ray, ccl_private float *t) { /* Sphere light (aka, aligned disk light). */ const float3 lightP = make_float3(klight->co[0], klight->co[1], klight->co[2]); const float radius = klight->spot.radius; if (radius == 0.0f) { return false; } /* disk oriented normal */ const float3 lightN = normalize(ray->P - lightP); float3 P; return ray_disk_intersect(ray->P, ray->D, ray->tmin, ray->tmax, lightP, lightN, radius, &P, t); } ccl_device_inline bool point_light_sample_from_intersection( const ccl_global KernelLight *klight, ccl_private const Intersection *ccl_restrict isect, const float3 ray_P, const float3 ray_D, ccl_private LightSample *ccl_restrict ls) { const float3 center = make_float3(klight->co[0], klight->co[1], klight->co[2]); const float3 lighN = normalize(ray_P - center); /* We set the light normal to the outgoing direction to support texturing. */ ls->Ng = -ls->D; float invarea = klight->spot.invarea; ls->eval_fac = (0.25f * M_1_PI_F) * invarea; ls->pdf = invarea; if (ls->eval_fac == 0.0f) { return false; } float2 uv = map_to_sphere(ls->Ng); ls->u = uv.x; ls->v = uv.y; /* compute pdf */ if (ls->t != FLT_MAX) { ls->pdf *= lamp_light_pdf(lighN, -ls->D, ls->t); } else { ls->pdf = 0.f; } return true; } CCL_NAMESPACE_END