Fermat
lambert.h
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2010-2016, NVIDIA Corporation
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions are met:
7  * * Redistributions of source code must retain the above copyright
8  * notice, this list of conditions and the following disclaimer.
9  * * Redistributions in binary form must reproduce the above copyright
10  * notice, this list of conditions and the following disclaimer in the
11  * documentation and/or other materials provided with the distribution.
12  * * Neither the name of NVIDIA Corporation nor the
13  * names of its contributors may be used to endorse or promote products
14  * derived from this software without specific prior written permission.
15  *
16  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
17  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19  * DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
20  * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26  */
27 
34 #pragma once
35 
36 #include <cugar/linalg/vector.h>
37 #include <cugar/basic/numbers.h>
38 #include <cugar/bsdf/differential_geometry.h>
40 
41 
42 namespace cugar {
43 
56 
61 struct LambertBsdf
65 {
66  CUGAR_FORCEINLINE CUGAR_HOST_DEVICE
67  LambertBsdf(const Vector3f _color) :
68  color(_color) {}
69 
72  CUGAR_FORCEINLINE CUGAR_HOST_DEVICE
73  Vector3f f(const DifferentialGeometry& geometry, const Vector3f V, const Vector3f L) const
74  {
75  const Vector3f N = geometry.normal_s;
76 
77  const float NoL = dot(N,L);
78  const float NoV = dot(N,V);
79 
80  return NoL * NoV > 0.0f ? color : Vector3f(0.0f);
81  }
82 
85  CUGAR_FORCEINLINE CUGAR_HOST_DEVICE
86  Vector3f f_over_p(const DifferentialGeometry& geometry, const Vector3f V, const Vector3f L) const
87  {
88  const Vector3f N = geometry.normal_s;
89 
90  const float NoL = dot(N,L);
91  const float NoV = dot(N,V);
92 
93  return NoL * NoV >= 0.0f ? color * M_PIf : Vector3f(0.0f);
94  }
95 
98  CUGAR_FORCEINLINE CUGAR_HOST_DEVICE
99  void f_and_p(const DifferentialGeometry& geometry, const Vector3f V, const Vector3f L, Vector3f& f, float& p, const SphericalMeasure measure = kProjectedSolidAngle) const
100  {
101  const Vector3f N = geometry.normal_s;
102 
103  const float NoL = dot(N, L);
104  const float NoV = dot(N, V);
105 
106  f = NoL * NoV > 0.0f ? color : Vector3f(0.0f);
107  p = NoL * NoV > 0.0f ? 1.0f / M_PIf : 0.0f;
108 
109  if (measure == kSolidAngle)
110  p *= fabsf(NoL);
111  }
112 
115  CUGAR_FORCEINLINE CUGAR_HOST_DEVICE
116  float p(const DifferentialGeometry& geometry, const Vector3f V, const Vector3f L, const SphericalMeasure measure = kProjectedSolidAngle) const
117  {
118  const Vector3f N = geometry.normal_s;
119 
120  const float NoL = dot(N, L);
121  const float NoV = dot(N, V);
122 
123  const float p = NoL * NoV > 0.0f ? 1.0f / M_PIf : 0.0f;
124 
125  return (measure == kSolidAngle) ? p * fabsf(NoL) : p;
126  }
127 
130  CUGAR_FORCEINLINE CUGAR_HOST_DEVICE
131  void sample(
132  const Vector3f u,
133  const DifferentialGeometry& geometry,
134  const Vector3f V,
135  Vector3f& L,
136  Vector3f& g,
137  float& p,
138  float& p_proj) const
139  {
140  const Vector3f N = geometry.normal_s;
141 
142  Vector3f local_L = square_to_cosine_hemisphere(u.xy());
143  if (dot(V, N) < 0.0f)
144  local_L[2] = -local_L[2];
145 
146  L = local_L[0] * geometry.tangent +
147  local_L[1] * geometry.binormal +
148  local_L[2] * geometry.normal_s;
149 
150  g = color * M_PIf;
151  p = fabsf( local_L[2] ) / M_PIf;
152  p_proj = 1.0f / M_PIf;
153  }
154 
157  template <typename RandomGeneratorT>
158  CUGAR_FORCEINLINE CUGAR_HOST_DEVICE
159  bool invert(
160  const DifferentialGeometry& geometry,
161  const Vector3f V,
162  const Vector3f L,
163  RandomGeneratorT& random,
164  Vector3f& z,
165  float& p,
166  float& p_proj) const
167  {
168  const Vector3f N = geometry.normal_s;
169 
170  if (dot(V, N) * dot(L, N) < 0.0f)
171  return false;
172 
173  const Vector3f local_L(
174  dot(L, geometry.tangent ),
175  dot(L, geometry.binormal ),
176  fabsf(dot(L, geometry.normal_s )));
177 
178  p = M_PIf / cugar::max( local_L[2], 1.0e-8f );
179  p_proj = M_PIf;
180 
181  const Vector2f u = cosine_hemisphere_to_square( local_L );
182  z = Vector3f(u.x, u.y, random.next());
183  return true;
184  }
185 
188  CUGAR_FORCEINLINE CUGAR_HOST_DEVICE
190  const DifferentialGeometry& geometry,
191  const Vector3f V,
192  const Vector3f L,
193  const Vector3f u,
194  float& p,
195  float& p_proj) const
196  {
197  const Vector3f N = geometry.normal_s;
198 
199  if (dot(V, N) * dot(L, N) < 0.0f)
200  p = p_proj = 0.0f;
201  else
202  {
203  p = M_PIf / cugar::max(fabsf(dot(L, N)), 1.0e-8f);
204  p_proj = M_PIf;
205  }
206  }
207 
208 public:
209  Vector3f color;
210 };
211 
215 } // namespace cugar
SphericalMeasure
Definition: differential_geometry.h:50
CUGAR_FORCEINLINE CUGAR_HOST_DEVICE Vector3f f_over_p(const DifferentialGeometry &geometry, const Vector3f V, const Vector3f L) const
Definition: lambert.h:86
Defines various spherical mappings.
CUGAR_FORCEINLINE CUGAR_HOST_DEVICE void sample(const Vector3f u, const DifferentialGeometry &geometry, const Vector3f V, Vector3f &L, Vector3f &g, float &p, float &p_proj) const
Definition: lambert.h:131
Definition: differential_geometry.h:59
float random()
Definition: tiled_sampling.h:44
CUGAR_FORCEINLINE CUGAR_HOST_DEVICE bool invert(const DifferentialGeometry &geometry, const Vector3f V, const Vector3f L, RandomGeneratorT &random, Vector3f &z, float &p, float &p_proj) const
Definition: lambert.h:159
Define a vector_view POD type and plain_view() for std::vector.
Definition: diff.h:38
CUGAR_FORCEINLINE CUGAR_HOST_DEVICE Vector3f f(const DifferentialGeometry &geometry, const Vector3f V, const Vector3f L) const
Definition: lambert.h:73
CUGAR_FORCEINLINE CUGAR_HOST_DEVICE void f_and_p(const DifferentialGeometry &geometry, const Vector3f V, const Vector3f L, Vector3f &f, float &p, const SphericalMeasure measure=kProjectedSolidAngle) const
Definition: lambert.h:99
CUGAR_HOST CUGAR_DEVICE Vector3f square_to_cosine_hemisphere(const Vector2f &uv)
Definition: mappings_inline.h:119
CUGAR_HOST CUGAR_DEVICE Vector2f cosine_hemisphere_to_square(const Vector3f &dir)
Definition: mappings_inline.h:137
CUGAR_FORCEINLINE CUGAR_HOST_DEVICE float p(const DifferentialGeometry &geometry, const Vector3f V, const Vector3f L, const SphericalMeasure measure=kProjectedSolidAngle) const
Definition: lambert.h:116
CUGAR_FORCEINLINE CUGAR_HOST_DEVICE void inverse_pdf(const DifferentialGeometry &geometry, const Vector3f V, const Vector3f L, const Vector3f u, float &p, float &p_proj) const
Definition: lambert.h:189