Fermat
blend.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 
48 template <
52  typename TBsdf1,
53  typename TBsdf2>
54 struct BlendBsdf
55 {
63  CUGAR_FORCEINLINE CUGAR_HOST_DEVICE
65  const float _w1 = 0.5f,
66  const float _w2 = 0.5f,
67  const TBsdf1 _bsdf1 = TBsdf1(),
68  const TBsdf2 _bsdf2 = TBsdf2()) :
69  w1(_w1),
70  w2(_w2),
71  bsdf1(_bsdf1),
72  bsdf2(_bsdf2)
73  {}
74 
77  CUGAR_FORCEINLINE CUGAR_HOST_DEVICE
78  Vector3f f(const DifferentialGeometry& geometry, const Vector3f V, const Vector3f L) const
79  {
80  return
81  w1 * bsdf1.f(geometry,V,L) +
82  w2 * bsdf2.f(geometry,V,L);
83  }
84 
87  CUGAR_FORCEINLINE CUGAR_HOST_DEVICE
88  Vector3f f_over_p(const DifferentialGeometry& geometry, const Vector3f V, const Vector3f L) const
89  {
90  return
91  w1 * bsdf1.f_over_p(geometry,V,L) +
92  w2 * bsdf2.f_over_p(geometry,V,L);
93  }
94 
97  CUGAR_FORCEINLINE CUGAR_HOST_DEVICE
98  void f_and_p(const DifferentialGeometry& geometry, const Vector3f V, const Vector3f L, Vector3f& f, float& p, const SphericalMeasure measure = kProjectedSolidAngle) const
99  {
100  Vector3f f1, f2;
101  float p1, p2;
102 
103  bsdf1.f_over_p( geometry, V, L, f1, p1, measure );
104  bsdf2.f_over_p( geometry, V, L, f2, p2, measure );
105 
106  f = w1 * f1 + w2 * f2;
107  p = w1 * p1 + w2 * p2;
108  }
109 
112  CUGAR_FORCEINLINE CUGAR_HOST_DEVICE
113  float p(const DifferentialGeometry& geometry, const Vector3f V, const Vector3f L, const SphericalMeasure measure = kProjectedSolidAngle) const
114  {
115  return
116  w1 * bsdf1.p(geometry,V,L) +
117  w2 * bsdf2.p(geometry,V,L);
118  }
119 
122  CUGAR_FORCEINLINE CUGAR_HOST_DEVICE
123  void sample(
124  const Vector3f u,
125  const DifferentialGeometry& geometry,
126  const Vector3f V,
127  Vector3f& L,
128  Vector3f& g,
129  float& p,
130  float& p_proj) const
131  {
132  if (u.z < w1)
133  {
134  // sample the first component
135  bsdf1.sample( Vector3f(u.x,u.y,u.z/w1), geometry, V, L, g, p, p_proj );
136 
137  g /= w1;
138  p *= w1;
139  p_proj *= w1;
140  }
141  else if (u.z < w1 + w2)
142  {
143  // sample the second component
144  bsdf2.sample( Vector3f(u.x,u.y,(u.z-w1)/w2), geometry, V, L, g, p, p_proj );
145 
146  g /= w2;
147  p *= w2;
148  p_proj *= w2;
149  }
150  else
151  {
152  // absorption
153  g = Vector3f(0.0f);
154  p = (1 - w1 - w2);
155  p_proj = (1 - w1 - w2);
156  }
157  }
158 
161  template <typename RandomGeneratorT>
162  CUGAR_FORCEINLINE CUGAR_HOST_DEVICE
163  bool invert(
164  const DifferentialGeometry& geometry,
165  const Vector3f V,
166  const Vector3f L,
167  RandomGeneratorT& random,
168  Vector3f& z,
169  float& p,
170  float& p_proj) const
171  {
172  // TODO
173  return false;
174  }
175 
178  CUGAR_FORCEINLINE CUGAR_HOST_DEVICE
180  const DifferentialGeometry& geometry,
181  const Vector3f V,
182  const Vector3f L,
183  const Vector3f u,
184  float& p,
185  float& p_proj) const
186  {
187  p_proj = 1.0f / this->p( geometry, V, L, u, kProjectedSolidAngle );
188  p = fabsf(dot(L, geometry.normal_s)) * p_proj;
189  }
190 
191 public:
192  float w1, w2;
193  TBsdf1 bsdf1;
194  TBsdf2 bsdf2;
195 };
196 
200 } // namespace cugar
SphericalMeasure
Definition: differential_geometry.h:50
CUGAR_FORCEINLINE CUGAR_HOST_DEVICE BlendBsdf(const float _w1=0.5f, const float _w2=0.5f, const TBsdf1 _bsdf1=TBsdf1(), const TBsdf2 _bsdf2=TBsdf2())
Definition: blend.h:64
Defines various spherical mappings.
CUGAR_FORCEINLINE CUGAR_HOST_DEVICE float p(const DifferentialGeometry &geometry, const Vector3f V, const Vector3f L, const SphericalMeasure measure=kProjectedSolidAngle) const
Definition: blend.h:113
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: blend.h:163
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: blend.h:123
CUGAR_FORCEINLINE CUGAR_HOST_DEVICE Vector3f f_over_p(const DifferentialGeometry &geometry, const Vector3f V, const Vector3f L) const
Definition: blend.h:88
Definition: blend.h:54
Definition: differential_geometry.h:59
float random()
Definition: tiled_sampling.h:44
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: blend.h:179
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: blend.h:98
CUGAR_FORCEINLINE CUGAR_HOST_DEVICE Vector3f f(const DifferentialGeometry &geometry, const Vector3f V, const Vector3f L) const
Definition: blend.h:78