Welcome to mirror list, hosted at ThFree Co, Russian Federation.

point.h « light « kernel « cycles « intern - git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
blob: abec114501fc33b906236ab0586aa37425e97f03 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
/* SPDX-License-Identifier: Apache-2.0
 * Copyright 2011-2022 Blender Foundation */

#pragma once

#include "kernel/light/common.h"

CCL_NAMESPACE_BEGIN

template<bool in_volume_segment>
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