36 #include <cugar/linalg/vector.h> 37 #include <cugar/basic/numbers.h> 38 #include <cugar/bsdf/differential_geometry.h> 48 struct GGXVCavityMicrofacetDistribution
56 CUGAR_FORCEINLINE CUGAR_HOST_DEVICE
57 GGXVCavityMicrofacetDistribution(
const float _roughness) :
58 roughness(_roughness),
59 inv_roughness(1.0f / _roughness) {}
63 CUGAR_FORCEINLINE CUGAR_HOST_DEVICE
66 const float2 inv_alpha = make_float2(inv_roughness, inv_roughness);
68 const Vector3f N = geometry.normal_s;
70 const float VoH = fabsf( dot(V, H) );
71 const float NoV = fabsf( dot(N, V) );
72 const float NoH = fabsf( dot(N, H) );
74 const float G1 = fminf(1, 2 * NoH * NoV / VoH);
76 const float D =
hvd_ggx_eval(inv_alpha, NoH, dot(geometry.tangent, H), dot(geometry.binormal, H));
77 float p = D * G1 * VoH / NoV;
82 return (!isfinite(p) || isnan(p)) ? 1.0e8f :
p;
87 CUGAR_FORCEINLINE CUGAR_HOST_DEVICE
96 const float inv_alpha = inv_roughness;
98 const Vector3f N = geometry.normal_s;
103 H[0] * geometry.tangent +
104 H[1] * geometry.binormal +
105 H[2] * geometry.normal_s;
107 const Vector3f H_prime = reflect(H, N);
109 float VoH = dot(V, H);
110 float VoH_prime = dot(V, H_prime);
112 if (u[2] < VoH_prime / (VoH + VoH_prime))
118 p = this->
p(geometry, V, H);
134 CUGAR_FORCEINLINE CUGAR_HOST_DEVICE
135 GGXBsdf(
const float _roughness) :
136 roughness(_roughness),
137 inv_roughness(1.0f / _roughness) {}
141 CUGAR_FORCEINLINE CUGAR_HOST_DEVICE
144 const float2 inv_alpha = make_float2(inv_roughness, inv_roughness);
146 const Vector3f H = cugar::normalize(V + L);
147 const Vector3f N = geometry.normal_s;
149 if (dot(N,L)*dot(N,V) <= 0.0f)
152 const float VoH = dot(V, H);
153 const float NoL = dot(N, L);
154 const float NoV = dot(N, V);
155 const float NoH = dot(N, H);
157 if (NoL * NoV <= 0.0f || NoH == 0.0f)
160 const float D =
hvd_ggx_eval(inv_alpha, NoH, dot(geometry.tangent, H), dot(geometry.binormal, H));
161 const float G2 = fminf(1, fminf(2 * NoH * NoV / VoH, 2 * NoH * NoL / VoH));
162 const float denom = (4 * NoV * NoL );
163 const float p = D * G2 / denom;
165 return (!isfinite(p) || isnan(p)) ? 1.0e8f : p;
170 CUGAR_FORCEINLINE CUGAR_HOST_DEVICE
173 const Vector3f H = cugar::normalize(V + L);
174 const Vector3f N = geometry.normal_s;
176 if (dot(N, L)*dot(N, V) <= 0.0f)
179 const float VoH = dot(V, H);
180 const float NoL = dot(N, L);
181 const float NoV = dot(N, V);
182 const float NoH = dot(N, H);
184 const float G2 = fminf(1, fminf(2 * NoH * NoV / VoH, 2 * NoH * NoL / VoH));
185 const float G1 = fminf(1, 2 * NoH * NoV / VoH);
192 CUGAR_FORCEINLINE CUGAR_HOST_DEVICE
195 const float2 inv_alpha = make_float2(inv_roughness, inv_roughness);
197 const Vector3f H = cugar::normalize(V + L);
198 const Vector3f N = geometry.normal_s;
200 const float VoH = dot(V, H);
201 const float NoL = dot(N, L);
202 const float NoV = dot(N, V);
203 const float NoH = dot(N, H);
205 const float D =
hvd_ggx_eval(inv_alpha, NoH, dot(geometry.tangent, H), dot(geometry.binormal, H));
206 const float G2 = fminf(1, fminf(2 * NoH * NoV / VoH, 2 * NoH * NoL / VoH));
207 const float G1 = fminf(1, 2 * NoH * NoV / VoH);
208 const float denom = (4 * NoV * NoL );
211 p = (!isfinite(p) || isnan(p)) ? 1.0e8f : p;
213 float f_s = D * G2 / denom;
214 f_s = (!isfinite(f_s) || isnan(f_s)) ? 1.0e8f : f_s;
218 if (measure == kSolidAngle)
224 CUGAR_FORCEINLINE CUGAR_HOST_DEVICE
227 const float2 inv_alpha = make_float2(inv_roughness, inv_roughness);
229 const Vector3f H = cugar::normalize(V + L);
230 const Vector3f N = geometry.normal_s;
232 const float VoH = dot(V, H);
233 const float NoL = dot(N, L);
234 const float NoV = dot(N, V);
235 const float NoH = dot(N, H);
237 const float D =
hvd_ggx_eval(inv_alpha, NoH, dot(geometry.tangent, H), dot(geometry.binormal, H));
238 const float G1 = fminf(1, 2 * NoH * NoV / VoH);
239 const float denom = (4 * NoV * NoL );
240 float p = D * G1 / denom;
242 if (measure == kSolidAngle)
245 return (!isfinite(p) || isnan(p)) ? 1.0e8f :
p;
250 CUGAR_FORCEINLINE CUGAR_HOST_DEVICE
261 const float inv_alpha = inv_roughness;
263 const Vector3f N = geometry.normal_s;
268 H[0] * geometry.tangent +
269 H[1] * geometry.binormal +
270 H[2] * geometry.normal_s;
272 const Vector3f H_prime = reflect(H, N);
274 float VoH = dot(V, H);
275 float VoH_prime = dot(V, H_prime);
277 if (u[2] < VoH_prime / (VoH + VoH_prime))
283 L = 2 * dot(V, H) * H - V;
285 const float NoL = dot(N, L);
286 const float NoV = dot(N, V);
287 const float NoH = dot(N, H);
289 const float D =
hvd_ggx_eval(make_float2(inv_alpha,inv_alpha), NoH, dot(geometry.tangent, H), dot(geometry.binormal, H));
290 const float G2 = fminf(1, fminf(2 * NoH * NoV / VoH, 2 * NoH * NoL / VoH));
291 const float G1 = fminf(1, 2 * NoH * NoV / VoH);
292 const float denom = (4 * NoV * NoL );
294 g =
cugar::Vector3f(1.0f) * (dot(L,N)*dot(V,N) > 0.0f ? (G2 / G1) : 0.0f);
295 p_proj = D * G1 / denom;
296 p = p_proj * fabsf(dot(N, L));
298 if (!isfinite(p) || isnan(p)) p = 1.0e8f;
299 if (!isfinite(p_proj) || isnan(p_proj)) p_proj = 1.0e8f;
304 template <
typename RandomGeneratorT>
305 CUGAR_FORCEINLINE CUGAR_HOST_DEVICE
315 const float2 inv_alpha = make_float2(inv_roughness, inv_roughness);
317 const Vector3f N = geometry.normal_s;
322 const Vector3f H = cugar::normalize(V + L);
323 const Vector3f H_alt = reflect(H, N);
337 float VoH = dot(V, H);
338 float VoH_alt = dot(V, H_alt);
342 const float NoH = dot(H, N);
346 const float2 H_prob = NoH > 0.0f ?
347 make_float2( fmaxf( 0.0f, fminf( 1.0f, VoH_alt / (VoH_alt + VoH) ) ), 1.0f ) :
348 make_float2( 0.0f, fmaxf( 0.0f, fminf( 1.0f, VoH / (VoH_alt + VoH) ) ) );
351 dot(H_orig, geometry.tangent),
352 dot(H_orig, geometry.binormal),
353 dot(H_orig, geometry.normal_s));
360 p_proj = 1.0f / cugar::max(this->
p(geometry, V, L, kProjectedSolidAngle), 1.0e-8f);
361 p = p_proj / cugar::max(fabsf(dot(L, N)), 1.0e-8f);
363 z =
Vector3f( u.x, u.y, H_prob.x + random.next() * (H_prob.y - H_prob.x) );
364 return H_prob.y - H_prob.x > 0.0f ? true :
false;
369 CUGAR_FORCEINLINE CUGAR_HOST_DEVICE
378 const Vector3f N = geometry.normal_s;
380 p_proj = 1.0f / cugar::max(this->
p(geometry, V, L, kProjectedSolidAngle), 1.0e-8f);
381 p = p_proj / cugar::max(fabsf(dot(L, N)), 1.0e-8f);
CUGAR_FORCEINLINE CUGAR_HOST_DEVICE float3 hvd_ggx_sample(const float2 &samples, const float inv_alpha)
Definition: ggx_common.h:115
SphericalMeasure
Definition: differential_geometry.h:50
CUGAR_FORCEINLINE CUGAR_HOST_DEVICE float p(const DifferentialGeometry &geometry, const Vector3f V, const Vector3f L, const SphericalMeasure measure=kProjectedSolidAngle) const
Definition: ggx.h:225
CUGAR_FORCEINLINE CUGAR_HOST_DEVICE float hvd_ggx_eval(const float2 &inv_alpha, const float nh, const float ht, const float hb)
Definition: ggx_common.h:92
CUGAR_FORCEINLINE CUGAR_HOST_DEVICE void sample(const Vector3f u, const DifferentialGeometry &geometry, const Vector3f V, Vector3f &H, float &p) const
Definition: ggx.h:88
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: ggx.h:370
CUGAR_FORCEINLINE CUGAR_HOST_DEVICE float p(const DifferentialGeometry &geometry, const Vector3f V, const Vector3f H) const
Definition: ggx.h:64
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 sample(const Vector3f u, const DifferentialGeometry &geometry, const Vector3f V, Vector3f &L, Vector3f &g, float &p, float &p_proj) const
Definition: ggx.h:251
CUGAR_FORCEINLINE CUGAR_HOST_DEVICE Vector3f f_over_p(const DifferentialGeometry &geometry, const Vector3f V, const Vector3f L) const
Definition: ggx.h:171
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: ggx.h:193
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: ggx.h:306
CUGAR_FORCEINLINE CUGAR_HOST_DEVICE float2 hvd_ggx_invert(const float3 H, const float2 inv_alpha)
Definition: ggx_common.h:238
CUGAR_FORCEINLINE CUGAR_HOST_DEVICE Vector3f f(const DifferentialGeometry &geometry, const Vector3f V, const Vector3f L) const
Definition: ggx.h:142