YafaRay Core  v3.2.0
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros
sample_utils.h
Go to the documentation of this file.
1 #ifndef Y_SAMPLEUTILS_H
2 #define Y_SAMPLEUTILS_H
3 
4 #include <core_api/ray.h>
5 #include <algorithm>
6 #include <string.h>
7 
9 
11 inline float kernel(float r_photon2, float ir_gather2)
12 {
13  float s = (1.f - r_photon2 * ir_gather2);
14  return 3.f * ir_gather2 * M_1_PI * s * s;
15 }
16 
17 inline float ckernel(float r_photon2, float r_gather2, float ir_gather2)
18 {
19  float r_p=fSqrt(r_photon2), ir_g=1.f/fSqrt(r_gather2);
20  return 3.f * (1.f - r_p*ir_g) * ir_gather2 * M_1_PI;
21 }
22 
24 
25 vector3d_t inline SampleCosHemisphere(const vector3d_t &N,const vector3d_t &Ru,const vector3d_t &Rv, float s1, float s2)
26 {
27  if(s1>=1.0f) return N; //Fix for some white/black dots when s1>1.0. Also, this returns a fast trivial value when s1=1.0.
28  else
29  {
30  float z1 = s1;
31  float z2 = s2*M_2PI;
32  return (Ru*fCos(z2) + Rv*fSin(z2))*fSqrt(1.0-z1) + N*fSqrt(z1);
33  }
34 }
35 
37 
38 vector3d_t inline SampleSphere(float s1, float s2)
39 {
40  vector3d_t dir;
41  dir.z = 1.0f - 2.0f*s1;
42  float r = 1.0f - dir.z*dir.z;
43  if(r>0.0f)
44  {
45  r = fSqrt(r);
46  float a = M_2PI * s2;
47  dir.x = fCos(a) * r;
48  dir.y = fSin(a) * r;
49  }
50  else
51  {
52  dir.x = 0.0f;
53  dir.y = 0.0f;
54  }
55  return dir;
56 }
57 
59 
60 vector3d_t inline sampleCone(const vector3d_t &D, const vector3d_t &U, const vector3d_t &V, float maxCosAng, float s1, float s2)
61 {
62  float cosAng = 1.f - (1.f - maxCosAng) * s2;
63  float sinAng = fSqrt(1.f - cosAng * cosAng);
64  float t1 = M_2PI * s1;
65  return (U * fCos(t1) + V * fSin(t1)) * sinAng + D * cosAng;
66 }
67 
68 
69 void inline CumulateStep1dDF(const float *f, int nSteps, float *integral, float *cdf)
70 {
71  int i;
72  double c = 0.0, delta = 1.0/(double)nSteps;
73  cdf[0] = 0.0;
74  for (i = 1; i < nSteps+1; ++i)
75  {
76  c += (double)f[i-1] * delta;
77  cdf[i] = float(c);
78  }
79  *integral = (float)c;// * delta;
80  for (i = 1; i < nSteps+1; ++i)
81  cdf[i] /= *integral;
82 }
83 
89 class pdf1D_t
90 {
91 public:
92  pdf1D_t() {}
93  pdf1D_t(float *f, int n)
94  {
95  func = new float[n];
96  cdf = new float[n+1];
97  count = n;
98  memcpy(func, f, n*sizeof(float));
100  invIntegral = 1.f / integral;
101  invCount = 1.f / count;
102  }
104  {
105  delete[] func, delete[] cdf;
106  }
107  float Sample(float u, float *pdf)const
108  {
109  // Find surrounding cdf segments
110  float *ptr = std::lower_bound(cdf, cdf+count+1, u);
111  int index = (int) (ptr-cdf-1);
112  if(index<0) //Hopefully this should no longer be necessary from now on, as a minimum value slightly over 0.f has been set to the scrHalton function to avoid ptr and cdf to coincide (which caused index = -1)
113  {
114  Y_ERROR << "Index out of bounds in pdf1D_t::Sample: index, u, ptr, cdf = " << index << ", " << u << ", " << ptr << ", " << cdf << yendl;
115  index=0;
116  }
117  // Return offset along current cdf segment
118  float delta = (u - cdf[index]) / (cdf[index+1] - cdf[index]);
119  if(pdf) *pdf = func[index] * invIntegral;
120  return index + delta;
121  }
122  // take a discrete sample.
123  // determines an index in the array from which the CDF was taked from, rather than a sample in [0;1]
124  int DSample(float u, float *pdf)const
125  {
126  if(u == 0.f)
127  {
128  *pdf = func[0] * invIntegral;
129  return 0;
130  }
131  float *ptr = std::lower_bound(cdf, cdf+count+1, u);
132  int index = (int) (ptr-cdf-1);
133  if(index<0)
134  {
135  Y_ERROR << "Index out of bounds in pdf1D_t::Sample: index, u, ptr, cdf = " << index << ", " << u << ", " << ptr << ", " << cdf << yendl;
136  index=0;
137  }
138  if(pdf) *pdf = func[index] * invIntegral;
139  return index;
140  }
141  // Distribution1D Data
142  float *func, *cdf;
144  int count;
145 };
146 
147 // rotate the coord-system D, U, V with minimum rotation so that D gets
148 // mapped to D2, i.e. rotate around D^D2.
149 // V is assumed to be D^U, accordingly V2 is D2^U2; all input vectors must be normalized!
150 
151 void inline minRot(const vector3d_t &D, const vector3d_t &U,
152  const vector3d_t &D2, vector3d_t &U2, vector3d_t &V2)
153 {
154  float cosAlpha = D*D2;
155  float sinAlpha = fSqrt(1 - cosAlpha*cosAlpha);
156  vector3d_t v = D^D2;
157  U2 = cosAlpha*U + (1.f-cosAlpha) * (v*U) + sinAlpha * (v^U);
158  V2 = D2^U2;
159 }
160 
162 
163 inline float addMod1(float a, float b)
164 {
165  float s = a+b;
166  return s>1 ? s-1.f : s;
167 }
168 
170 
171 #endif // Y_SAMPLEUTILS_H
float fCos(float x)
float ckernel(float r_photon2, float r_gather2, float ir_gather2)
Definition: sample_utils.h:17
vector3d_t sampleCone(const vector3d_t &D, const vector3d_t &U, const vector3d_t &V, float maxCosAng, float s1, float s2)
uniformly sample a cone. Using doubles because for small cone angles the cosine is very close to one...
Definition: sample_utils.h:60
__BEGIN_YAFRAY float kernel(float r_photon2, float ir_gather2)
r_photon2: Square distance of photon path; ir_gather2: inverse of square gather radius ...
Definition: sample_utils.h:11
vector3d_t SampleCosHemisphere(const vector3d_t &N, const vector3d_t &Ru, const vector3d_t &Rv, float s1, float s2)
Sample a cosine-weighted hemisphere given the the coordinate system built by N, Ru, Rv.
Definition: sample_utils.h:25
#define __BEGIN_YAFRAY
float integral
Definition: sample_utils.h:143
void minRot(const vector3d_t &D, const vector3d_t &U, const vector3d_t &D2, vector3d_t &U2, vector3d_t &V2)
Definition: sample_utils.h:151
float fSin(float x)
float addMod1(float a, float b)
Just a &quot;modulo 1&quot; float addition, assumed that both values are in range [0;1].
Definition: sample_utils.h:163
#define M_2PI
float z
Definition: vector3d.h:92
float Sample(float u, float *pdf) const
Definition: sample_utils.h:107
void CumulateStep1dDF(const float *f, int nSteps, float *integral, float *cdf)
Definition: sample_utils.h:69
float x
Definition: vector3d.h:92
#define M_1_PI
float invIntegral
Definition: sample_utils.h:143
vector3d_t SampleSphere(float s1, float s2)
Uniform sample a sphere.
Definition: sample_utils.h:38
float * cdf
Definition: sample_utils.h:142
int DSample(float u, float *pdf) const
Definition: sample_utils.h:124
float y
Definition: vector3d.h:92
float invCount
Definition: sample_utils.h:143
float fSqrt(float a)
pdf1D_t(float *f, int n)
Definition: sample_utils.h:93
float * func
Definition: sample_utils.h:142
#define __END_YAFRAY