36 #include <cugar/linalg/vector.h> 37 #include <cugar/basic/numbers.h> 38 #include <cugar/bsdf/differential_geometry.h> 47 CUGAR_FORCEINLINE CUGAR_HOST_DEVICE
52 Vector3f H = (dot(V, N)*dot(L, N) >= 0.0f) ?
69 CUGAR_FORCEINLINE CUGAR_HOST_DEVICE
72 Vector3f H = (dot(V, N)*dot(L, N) >= 0.0f) ?
77 if (dot(H,H) < 1.0e-12f)
91 CUGAR_FORCEINLINE CUGAR_HOST_DEVICE
93 const float2 &inv_alpha,
98 const float x = ht * inv_alpha.x;
99 const float y = hb * inv_alpha.y;
100 const float aniso = x * x + y * y;
108 const float f = aniso + nh * nh;
109 return (1.0f / M_PIf) * inv_alpha.x * inv_alpha.y / (f * f);
114 CUGAR_FORCEINLINE CUGAR_HOST_DEVICE
116 const float2 &samples,
117 const float inv_alpha)
120 const float phi = (float)(2.0 * M_PI) * samples.x;
122 cugar::sincosf(phi, &sp, &cp);
124 const float ia2 = inv_alpha * inv_alpha;
126 const float sp2 = cp;
127 const float cp2 = sp;
129 const float tantheta2 = samples.y / ((1.0f - samples.y) * ia2);
130 const float sintheta = ::sqrtf(tantheta2 / (1.0f + tantheta2));
135 cugar::rsqrtf(1.0f + tantheta2));
140 CUGAR_FORCEINLINE CUGAR_HOST_DEVICE
142 const float2 &samples,
143 const float2 &inv_alpha)
146 const float phi = (float)(2.0 * M_PI) * samples.x;
148 sincosf(phi, &sp, &cp);
150 const float iax2 = inv_alpha.x*inv_alpha.x;
151 const float iay2 = inv_alpha.y*inv_alpha.y;
153 const float is = rsqrtf(iax2 * cp*cp + iay2 * sp*sp);
155 const float sp2 = inv_alpha.x * cp*is;
156 const float cp2 = inv_alpha.y * sp*is;
158 const float tantheta2 = samples.y / ((1.0f - samples.y) * (cp2 * cp2 * iax2 + sp2 * sp2 * iay2));
159 const float sintheta = sqrtf(tantheta2 / (1.0f + tantheta2));
164 rsqrtf(1.0f + tantheta2));
169 CUGAR_FORCEINLINE CUGAR_HOST_DEVICE
170 Vector2f Fu(
const float u,
const float2 ia,
const float2 b)
172 const float iax2 = ia.x*ia.x;
173 const float iay2 = ia.y*ia.y;
175 const float2 p = make_float2(sinf(u), cosf(u));
178 sqrtf(iax2 * p.y*p.y + iay2 * p.x*p.x) * b.x - p.y,
179 sqrtf(iax2 * p.y*p.y + iay2 * p.x*p.x) * b.y - p.x);
182 CUGAR_FORCEINLINE CUGAR_HOST_DEVICE
183 Vector2f Ju(
const float u,
const float2 ia,
const float2 b)
185 const float iax2 = ia.x*ia.x;
186 const float iay2 = ia.y*ia.y;
188 const float2 p = make_float2(sinf(u), cosf(u));
191 r.x = (-2.0f * iax2 * p.y * p.x + 2.0f * iay2 * p.x * p.y) * b.x * 0.5f / (iax2 * p.y*p.y + iay2 * p.x*p.x) + p.x;
192 r.y = (-2.0f * iax2 * p.y * p.x + 2.0f * iay2 * p.x * p.y) * b.x * 0.5f / (iax2 * p.y*p.y + iay2 * p.x*p.x) - p.y;
196 CUGAR_FORCEINLINE CUGAR_HOST_DEVICE
197 bool refine_solution(
float& u,
const float2 ia,
const float2 b)
200 for (uint32 i = 0; i < 100; ++i)
203 if (fabsf(f.x) < 1.0e-5f &&
204 fabsf(f.y) < 1.0e-5f)
209 const Vector2f inv_J = J / dot(J, J);
211 u = u - dot(inv_J, f);
219 CUGAR_FORCEINLINE CUGAR_HOST_DEVICE
220 bool invert(
float& u,
const float2 ia,
const float2 b)
223 const float cp = b.x;
224 const float sp = b.y;
227 const float phi = atan2f( sp, cp );
228 u = phi < 0.0f ? phi + 2.0f*float(M_PI) : phi;
237 CUGAR_FORCEINLINE CUGAR_HOST_DEVICE
240 const float2 inv_alpha)
242 const float tantheta2 = 1.0f / (H.z * H.z) - 1.0f;
243 const float sintheta = sqrtf(tantheta2 / (1.0f + tantheta2));
244 const float cp2 = H.x / sintheta;
245 const float sp2 = H.y / sintheta;
247 const float iax2 = inv_alpha.x*inv_alpha.x;
248 const float iay2 = inv_alpha.y*inv_alpha.y;
250 const float v = tantheta2 * (cp2 * cp2 * iax2 + sp2 * sp2 * iay2) / (1.0f + tantheta2 * (cp2 * cp2 * iax2 + sp2 * sp2 * iay2));
254 ggx::invert(u, inv_alpha, make_float2(sp2 / inv_alpha.x, cp2 / inv_alpha.y));
258 return make_float2(u, v);
264 CUGAR_FORCEINLINE CUGAR_HOST_DEVICE
266 const float2 samples,
278 float a = 1.0f / (1.0f + V.z);
279 float r = sqrtf(samples.x);
280 float phi = (samples.y < a) ? samples.y / a * M_PIf : M_PIf + (samples.y - a) / (1.0f - a) * M_PIf;
281 float P1 = r*cosf(phi);
282 float P2 = r*sinf(phi) * ((samples.y < a) ? 1.0f : V.z);
285 Vector3f N = P1*T1 + P2*T2 + sqrtf(max(0.0f, 1.0f - P1*P1 - P2*P2))*V;
288 N = normalize(
Vector3f(alpha.x*N.x, alpha.y*N.y, max(0.0f, N.z)));
295 CUGAR_FORCEINLINE CUGAR_HOST_DEVICE
339 const float P1 = dot( N, T1 );
340 const float P2 = dot( N, T2 );
342 const float a = 1.0f / (1.0f + V.z);
353 const float r2 = min( P1*P1 + P2*P2, 1.0f );
354 const float r = sqrtf(r2);
356 float phi = r > 1.0e-6f ? atan2f( P2 / r, P1 / r ) : 0.0f;
364 samples.y = phi * a / M_PIf;
367 assert(is_finite(samples.x) && is_finite(samples.y));
368 assert(samples.y >= 0.0f && samples.y <= 1.0f);
375 const float r2 = min( P1*P1 + P2*P2 / (V.z*V.z), 1.0f );
376 const float r = sqrtf(r2);
378 float phi = r > 1.0e-6f && V.z > 1.0e-6f ? atan2f( P2 / (r * V.z), P1 / r ) : 0.0f;
388 samples.y = (phi - M_PIf) * (1.0f - a) / M_PIf + a;
389 assert(is_finite(samples.x) && is_finite(samples.y));
390 assert(samples.y >= 0.0f && samples.y <= 1.0f);
CUGAR_FORCEINLINE CUGAR_HOST_DEVICE float3 hvd_ggx_sample(const float2 &samples, const float inv_alpha)
Definition: ggx_common.h:115
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 Vector3f vndf_microfacet(const Vector3f V, const Vector3f L, const Vector3f N, const float inv_eta)
Definition: ggx_common.h:70
CUGAR_FORCEINLINE CUGAR_HOST_DEVICE float2 vndf_ggx_smith_invert(const Vector3f _N, const float2 alpha, const Vector3f _V)
Definition: ggx_common.h:296
CUGAR_FORCEINLINE CUGAR_HOST_DEVICE Vector3f microfacet(const Vector3f V, const Vector3f L, const Vector3f N, const float inv_eta)
Definition: ggx_common.h:50
CUGAR_FORCEINLINE CUGAR_HOST_DEVICE float3 vndf_ggx_smith_sample(const float2 samples, const float2 alpha, const Vector3f _V)
Definition: ggx_common.h:265
Define a vector_view POD type and plain_view() for std::vector.
Definition: diff.h:38
CUGAR_FORCEINLINE CUGAR_HOST_DEVICE float2 hvd_ggx_invert(const float3 H, const float2 inv_alpha)
Definition: ggx_common.h:238