Fermat
lambert_trans.h
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 
48 struct LambertTransBsdf
52 {
53  CUGAR_FORCEINLINE CUGAR_HOST_DEVICE
54  LambertTransBsdf(const Vector3f _color) :
55  color(_color) {}
56 
59  CUGAR_FORCEINLINE CUGAR_HOST_DEVICE
60  Vector3f f(const DifferentialGeometry& geometry, const Vector3f V, const Vector3f L) const
61  {
62  const Vector3f N = geometry.normal_s;
63 
64  const float NoL = dot(N,L);
65  const float NoV = dot(N,V);
66 
67  return NoL * NoV < 0.0f ? color : Vector3f(0.0f);
68  }
69 
72  CUGAR_FORCEINLINE CUGAR_HOST_DEVICE
73  Vector3f f_over_p(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 * M_PIf : Vector3f(0.0f);
81  }
82 
85  CUGAR_FORCEINLINE CUGAR_HOST_DEVICE
86  void f_and_p(const DifferentialGeometry& geometry, const Vector3f V, const Vector3f L, Vector3f& f, float& p, const SphericalMeasure measure = kProjectedSolidAngle) 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  f = NoL * NoV < 0.0f ? color : Vector3f(0.0f);
94  p = NoL * NoV < 0.0f ? 1.0f / M_PIf : 0.0f;
95 
96  if (measure == kSolidAngle)
97  p *= fabsf(NoL);
98  }
99 
102  CUGAR_FORCEINLINE CUGAR_HOST_DEVICE
103  float p(const DifferentialGeometry& geometry, const Vector3f V, const Vector3f L, const SphericalMeasure measure = kProjectedSolidAngle) const
104  {
105  const Vector3f N = geometry.normal_s;
106 
107  const float NoL = dot(N, L);
108  const float NoV = dot(N, V);
109 
110  const float p = NoL * NoV < 0.0f ? 1.0f / M_PIf : 0.0f;
111 
112  return (measure == kSolidAngle) ? p * fabsf(NoL) : p;
113  }
114 
117  CUGAR_FORCEINLINE CUGAR_HOST_DEVICE
118  void sample(
119  const Vector3f u,
120  const DifferentialGeometry& geometry,
121  const Vector3f V,
122  Vector3f& L,
123  Vector3f& g,
124  float& p,
125  float& p_proj) const
126  {
127  const Vector3f N = geometry.normal_s;
128 
129  Vector3f local_L = square_to_cosine_hemisphere(u.xy());
130  if (dot(V, N) > 0.0f)
131  local_L[2] = -local_L[2];
132 
133  L = local_L[0] * geometry.tangent +
134  local_L[1] * geometry.binormal +
135  local_L[2] * geometry.normal_s;
136 
137  g = color * M_PIf;
138  p = fabsf( local_L[2] ) / M_PIf;
139  p_proj = 1.0f / M_PIf;
140  }
141 
144  template <typename RandomGeneratorT>
145  CUGAR_FORCEINLINE CUGAR_HOST_DEVICE
146  bool invert(
147  const DifferentialGeometry& geometry,
148  const Vector3f V,
149  const Vector3f L,
150  RandomGeneratorT& random,
151  Vector3f& z,
152  float& p,
153  float& p_proj) const
154  {
155  const Vector3f N = geometry.normal_s;
156 
157  if (dot(V, N) * dot(L, N) > 0.0f)
158  return false;
159 
160  const Vector3f local_L(
161  dot(L, geometry.tangent ),
162  dot(L, geometry.binormal ),
163  fabsf(dot(L, geometry.normal_s )));
164 
165  p = M_PIf / cugar::max( local_L[2], 1.0e-8f );
166  p_proj = M_PIf;
167 
168  const Vector2f u = cosine_hemisphere_to_square( local_L );
169  z = Vector3f(u.x, u.y, random.next());
170  return true;
171  }
172 
175  CUGAR_FORCEINLINE CUGAR_HOST_DEVICE
177  const DifferentialGeometry& geometry,
178  const Vector3f V,
179  const Vector3f L,
180  const Vector3f u,
181  float& p,
182  float& p_proj) const
183  {
184  const Vector3f N = geometry.normal_s;
185 
186  const float NoL = dot(N, L);
187  const float NoV = dot(N, V);
188 
189  if (NoV * NoL > 0.0f)
190  p = p_proj = 0.0f;
191  else
192  {
193  p = M_PIf / cugar::max(fabsf(NoL), 1.0e-8f);
194  p_proj = M_PIf;
195  }
196  }
197 
198 public:
199  Vector3f color;
200 };
201 
205 } // namespace cugar
CUGAR_FORCEINLINE CUGAR_HOST_DEVICE float p(const DifferentialGeometry &geometry, const Vector3f V, const Vector3f L, const SphericalMeasure measure=kProjectedSolidAngle) const
Definition: lambert_trans.h:103
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_trans.h:118
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_trans.h:73
Defines various spherical mappings.
CUGAR_FORCEINLINE CUGAR_HOST_DEVICE Vector3f f(const DifferentialGeometry &geometry, const Vector3f V, const Vector3f L) const
Definition: lambert_trans.h:60
Definition: differential_geometry.h:59
float random()
Definition: tiled_sampling.h:44
Define a vector_view POD type and plain_view() for std::vector.
Definition: diff.h:38
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_trans.h:86
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 void inverse_pdf(const DifferentialGeometry &geometry, const Vector3f V, const Vector3f L, const Vector3f u, float &p, float &p_proj) const
Definition: lambert_trans.h:176
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_trans.h:146