Supplemental Material

The SGGX Microflake Distribution
Supplemental Material
Eric Heitz1,2
1
Jonathan Dupuy3
Karlsruhe Institute of Technology
Cyril Crassin2
2
NVIDIA
3
Carsten Dachsbacher1
Univ. Montr´eal; LIRIS, Univ. Lyon 1
In this document we provide additional mathematical derivations, results and our C implementation of
the SGGX operators.
Contents
1 Definitions and Derivations
1.1 The SGGX Matrix . . . . . . . . . . . .
1.2 The Ellipsoid . . . . . . . . . . . . . . .
1.3 The Projected Area . . . . . . . . . . .
1.4 The Distribution of Normals . . . . . . .
1.5 Importance Sampling the Distribution of
1.6 Importance Sampling Algorithm . . . .
. . . . . . . . . .
. . . . . . . . . .
. . . . . . . . . .
. . . . . . . . . .
Visible Normals
. . . . . . . . . .
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
2
2
3
5
7
9
11
2 Implementation
2.1 The Projected Area . . . . . . . . . . .
2.2 The Distribution of Normals . . . . . . .
2.3 Importance Sampling the Distribution of
2.4 The Specular Microflake Phase Function
2.5 The Diffuse Microflake Phase Function .
. . . . . . . . . .
. . . . . . . . . .
Visible Normals
. . . . . . . . . .
. . . . . . . . . .
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
13
13
13
14
15
16
3 Parameter Estimation Results
18
4 LOD Results
20
4.1 Filtering Specular Microflakes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 20
4.2 Filtering Diffuse Microflakes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 22
4.3 Filtering Mixed Microflakes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 24
1
1
1.1
Definitions and Derivations
The SGGX Matrix
The SGGX Matrix is defined by

Sxx
S = Sxy
Sxz
Sxy
Syy
Syz

Sxz
Syz  .
Szz
It is symmetric positive definite, which means that it can be defined as


S11
0
0
0  (ω 1 , ω 2 , ω 3 )T ,
S = (ω 1 , ω 2 , ω 3 )  0 S22
0
0 S33
(1)
(2)
where S11 , S22 and S33 are positive eigenvalues that correspond to the squared projected areas of the ellipsoid
in the directions given by the orthonormal eigenvectors, which are respectively ω 1 , ω 2 and ω 3 , as shown in
Figure 1. The eigenvectors are the principal axes of the associated ellipsoid.
Figure 1: Eigenvectors and eigenvalues of the matrix S. The projected areas (the area of the green surfaces)
are the squared roots of the matrix eigenvalues.
2
1.2
The Ellipsoid
The Surface Note that our definition differs from Neyret’s [Ney95] where the surface of the ellipsoid was
defined as the set of points P such that P T Q P = 1, where Q is also a 3 × 3 symmetric positive definite
matrix. With our
√ definition based on the projected area, the surface is the set of points P = (x, y, z) such
that P T S P =
|S|
π
p
P T SP =
and S =
|S|
,
π
(3)
π2
|Q| Q.
The Points of the Surface If PΩ is a point on the unit sphere such that PΩT PΩ = 1, then a point PS of
the ellipsoid associated to S can be constructed by applying the transformation
PS = R T PΩ
(4)
R = (ω 1 , ω 2 , ω 3 )
(5)
where R is a rotation matrix
and T is a scaling matrix
q
4
1
T =√
π




S22 S33
S11
0
0
q
4
0
0
S11 S33
S22
0
0
q
4
S11 S22
S33





(6)
as shown in Figure 2.
Figure 2: Mapping the unit sphere to the ellipsoid.
The Normals of the Surface The normals at the surface of the ellipsoid are given by the gradient of
the quadratic form
∂P T S P
= 2SP.
∂P
(7)
By normalizing this expression, we get the normal ω m at point P
ωm =
SP
,
||SP ||
as shown in Figure 3.
3
(8)
Figure 3: Computing a normal at the surface of the ellipsoid.
4
1.3
The Projected Area
In this section we give a proof of the formula of the projected area
q
σ(ω i ) = ω Ti S ω i .
(9)
To compute the projected area of the ellipsoid, we use the linear transformation R T that maps the unit
sphere to the ellipsoid, as shown in Figure 4.
Figure 4: Computing the projected area of the ellipsoid.
We start from an ellipsoid configuration (on the left) and we apply the inverse transformation to get a
unit sphere configuration (on the right). The incident direction in the unit sphere configuration is obtained
by applying the inverse transform and normalizing
ω 0i =
T −1 R−1 ω i
.
||T −1 R−1 ω i ||
(10)
We define an orthonormal basis (ω 0i , ω 0j , ω 0k ) around this direction
ω 0i = ω 0j × ω 0k .
(11)
We first notice that the projected area of the unit sphere onto direction ω 0i is π, as it is for any direction.
However, the transformation R T does not preserve orthonormality,
ω j = R T ω 0j
(12)
ω 0k
(13)
ωk = R T
ω i 6= ω j × ω k .
(14)
and the projected area in the ellipsoid configuration is not the projected area (π) modified by the transformation (the red area in the figure). The projected area σ(ω i ) of the ellipsoid in direction ω i is the projected
5
area of the transformed projected area of the unit sphere (in the figure it is the projection of the red area
onto ω i ) which is the projection of the vector π ω j × ω k onto ω i
σ(ω i ) = hω i , π ω j × ω k i
(15)
After the transformation the cross product is
ω j × ω k = (R T ω 0j ) × (R T ω 0k )
= |R T | (R T )−T (ω 0j × ω 0k )
= |T | R T −1 (ω 0j × ω 0k )
= |T | R T −1 ω 0i
= |T | R T −1
T −1 R−1 ω i
,
||T −1 R−1 ω i ||
(16)
where we used the following properties
• for any matrix M and vectors ω 1 and ω 2 we have (M ω 1 ) × (M ω 2 ) = |M | M −T (A × B),
• the inverse transpose are T −T = T −1 and R−T = R,
• the determinant of R is 1 because it is a rotation matrix, and
• ω 0i =
T −1 R−1 ω i
||T −1 R−1 ω i || .
Finally, by injecting the result of Equation (16) in Equation (15) we get
σ(ω i ) = hω i , π ω j × ω k i
−1 −1
R ωi
−1 T
= π ω i , |T | R T
||T −1 R−1 ω i ||
|T |
ω i , R T −1 T −1 R−1 ω i
=π
−1
−1
||T R ω i ||
|T |
=π
(R T −1 )T ω i , T −1 R−1 ω i
||T −1 R−1 ω i ||
−1 −1
|T |
=π
T R ω i , T −1 R−1 ω i
||T −1 R−1 ω i ||
||T −1 R−1 ω i ||2
= π −1
|T | ||T −1 R−1 ω i ||
||T −1 R−1 ω i ||
=π
|T −1 |
p
= hω i , ω 1 i2 S11 + hω i , ω 2 i2 S22 + hω i , ω 3 i2 S33
q
= ω Ti S ω i ,
which is the result of Equation (9).
6
(17)
1.4
The Distribution of Normals
In this section we propose two derivations of the formula of the distributions of normals
1
D(ω m ) =
From Neyret’s Definition
π
p
2.
(18)
|S| (ω Tm S −1 ω m )
Neyret [Ney95] defines the ellipsoid with the quadratic form
P T Q P = 1,
(19)
which is the equivalent of Equation 3. The relation between Q and S is then
π2
Q,
|Q|
π
S.
Q= p
|S|
S=
(20)
(21)
According to Neyret, the distribution of normals of the ellipsoid is
D(ω m ) =
|Q−1 |
2.
(22)
(ω Tm Q−1 ω m )
By replacing with the expression of S we get the form of Equation (18)
−1 √π
S
|S|
D(ω m ) =
!2
−1
ω Tm √π S
ωm
|S|
=
1
p
2.
T
π |S| (ω m S −1 ω m )
(23)
From the Anisotropic GGX Definition The eigenspace of the ellipsoid is R = (ω 1 , ω 2 , ω 3 ). The
anisotropic GGX distribution, is defined by two roughness coefficient α1 and α2 in the respective directions
ω 1 and ω 2 . A normal ω m = (xm , ym , zm ) is projected in this orthonormal basis by
T
ω 123
m = (m1 , m2 , m3 ) = R ω m .
(24)
Then, the distribution of normals for anisotropic GGX [Hei14] evaluates to
χ(hω 3 , ω m i)
D(ω m ) =
π α1 α2 cos4 θm
tan2 θm cos2 φm
α21
+
tan2 θm sin2 φm
α22
+1
2
(25)
First, we remove the χ(hω 3 , ω m i) to define the distribution on the entire sphere rather than only on the
hemisphere, like illustrated in Figure 5.
7
GGX D(ω m )
SGGX D(ω m )
Figure 5: The SGGX distribution is a symmetrized GGX, i.e. the distribution of normals of the surface of
an ellipsoid on the entire sphere.
Then, by replacing
cos4 θm = m43 ,
tan2 θm cos2 φm =
tan2 θm sin2 φm =
(26)
m21
,
m23
m22
,
m23
(27)
(28)
we get
1
D(ω m ) =
π α1 α2 m43
+
2
1 m2
α22 m23
+1
2
1
=
π α1 α2 1 +
=
2
1 m1
α21 m23
m21
α21
+
m22
α22
1
π
p
|S|
(ω Tm
S −1 ω m )
+
2
zm
1
2
2,
which is the form of Equation (18) where the eigenvalues are given by


S11 = α12
0
0
0
S22 = α22
0  RT .
S=R
0
0
S33 = 1
(29)
(30)
Note that it is not surprising that S33 = 1 because the distribution of normals used in microfacet based
BRDFs satisfy the normalization equation
Z
p
S33 = hω z , ω m i D(ω m ) dω m = 1.
(31)
Ω
8
1.5
Importance Sampling the Distribution of Visible Normals
Proof We demonstrate what is illustrated in Figure 6, i.e. that importance sampling the distribution of
visible normals can be done by casting rays on the ellipsoid.
1. We sample a 2D point (x, y) uniformly in the ellipse given by the projected of the ellipsoid in the plane
orthogonal to ω i . The area of the ellipse is the projected area σ(ω i ) and the PDF of the uniformly
1
.
sampled point is PDF(x, y) = σ(ω
i)
2. We project the 2D point (x, y) on the surface of the ellipsoid to get a 3D point (x, y, z). The PDF of
(x, y, z) is the PDF of (x, y) multiplied by the Jacobian of the orthogonal projection ∂(u,v)
= hω i , ω m i,
∂P
1
which gives PDF(x, y, z) = hω i , ω m i σ(ω
.
i)
3. We evaluate the normal ω m of the point P. The PDF of the generated normal is
PDF(ω m ) =
∂P
PDF(x, y, z)
∂ω m
= D(ω m ) hω i , ω m i
= Dωi (ω m )
1
σ(ω i )
(32)
(33)
(34)
where the distribution of normals is the Jacobian of the point to normal transformation D(ω m ) =
∂P
∂ω m [Hei14]. The normal ω m has been sampled with a PDF equals to the distribution of visible
normals.
4. We apply a specular (a) of a diffuse (b) reflection with ω m to get an outgoing direction ω o from the
phase function.
9
Operations
1. Sample the projected 2D ellipse
Samples and PDFs
A 2D point in the uniform
distribution within the
1
ellipse f (x, y) = σ(ω
i)
2. Project on the ellipsoid
A 3D point from the spatial PDF
1
PDF(x, y, z) = hω i , ω m i σ(ω
i)
3. Evaluate its normal ω m
A normal from the distribution
of visible normals Dωi (ω m )
1
= D(ω m ) hω i , ω m i σ(ω
i)
4.a. Specular reflection with ω m
An outgoing direction ω o
in the phase function
fpspec (ω i → ω o )
4.b. Diffuse reflection with ω m
An outgoing direction ω o
in the phase function
fpdiff (ω i → ω o )
Figure 6: Illustration of our importance sampling algorithm.
10
1.6
Importance Sampling Algorithm
We provide more details about our derivation of our VNDF sampling algorithm.
Algorithm 1 Importance sampling the VNDF with SGGX
1: function sampleVNDF(ω i , S, U1 , U2 )
2: compute an orthonormal basis (ω k , ω j , ω i ) around ω i
3: project S 
in this basis  

ω Tk Sω k ω Tk Sω j ω Tk Sω i
Skk Skj Ski
S kji =  Skj Sjj Sji  =  ω Tk Sω j ω Tj Sω j ω Tj Sω i 
Ski Sji Sii
ω Tk Sω i ω Tj Sω i ω Ti Sω i

r
4:

compute vectors Mk = 

Mj =
√1
Sii
|S kji |
2 
Sjj Sii −Sji
0
0
 S Sji −S Sii 
ki
kj
−√
2
 q Sjj Sii −Sji 

2 , Mi =

 Sjj Sii − Sji
,

√1
Sii
 
Ski
 Sji 
Sii
0
generate
random
3D
point (u, v, w) on the visible sphere
√
u = √ U1 cos(2π U2 )
v = √U1 sin(2π U2 )
w = 1 − u2 − v 2
6: compute normal and rotate to world space
uMk +vMj +wMi
ω kji
m = ||uMk +vMj +wMi ||
ω m = (ω k ω j ω i ) ω kji
m
7: return ω m
8: end function
5:
Orthonormal Basis We compute an orthonormal basis aligned with the incident direction (ω 1 , ω 2 , ω 3 = ω i ).
In practice, we use Frisvad’s method [Fri12] to do this efficiently. Then, we rotate the SGGX matrix in this
basis


  T
ω k Sω k ω Tk Sω j ω Tk Sω i
Skk Skj Ski
(35)
S kji =  Skj Sjj Sji  =  ω Tk Sω j ω Tj Sω j ω Tj Sω i  .
Ski Sji Sii
ω Tk Sω i ω Tj Sω i ω Ti Sω i
Vectors Mk , Mj and Mi
The coefficient of the Cholesky decomposition of the matrix S are
p
p
p
σk = Skk , σj = Sjj , σi = Sii
Skj
Ski
Sji
rkj = p
, rki = √
, rji = p
Skk Sii
Skk Sjj
Sjj Sii
(36)
(37)
The distribution of visible normals is a PDF, i.e. it does not depend on the scale of the ellipsoid. To simplify
the derivations, we assume in this section that S = Q, i.e. that the points P on the surface of the ellipsoid
are such that P T SP = 1. With the Cholesky decomposition, we can warp a point (u, v, w) from the sphere
to match a point P kji on the surface of the ellipsoid (such that P T SP = 1)


0
 
  
 1 q 0
pk
σk 0 0 
 u
2
r
1
−
r
0


kj
(38)
P kji =  pj  =  0 σj 0   kj
 v 
r

2
r
−r
r
(r
−r
r
)
ji
ji
kj ki
kj ki
2
w
pi
0
0 σi
√
rki
1 − rki −
2
1−r 2
1−rkj
11
kj
Then, the normal at point P kji is given by (see Section 1.2 of the supplemental)
kji
ωm
=
S kji P kji
,
||S kji P kji ||
(39)
where


S kji P kji

1
q 0
2
1 − rkj
0

 
 u
0
 
 v
r
2
rji −rkj rki
(rji −rkj rki )  w
2
√ 2
1 − rki −
2
1−rkj
1−rkj






0
0
q
σk




0
1 − r 2 σj 
r

= u Skji rkj σj  + v Skji 
 r −r rkj  + w Skji 

2
(rji −rkj rki )
2
ji
kj ki
σi
1 − rki −
rki σi
√ 2 σi
1−r 2
σk
= Skji  0
0
0
σj
0
0 
r
0   kj
σi  rki
1−rkj
(40)
(41)
kj
= uMk + vMj + wMi
(42)
which simplifies to
r

Mk = 


S ∗Sji −Skj ∗Sii
 
√
− ki
2
Ski
 q Sjj Sii −Sji 
1
1
 , Mj = √

 , Mi = √
 Sji 
2

Sii  Sjj Sii − Sji 
Sii S
ii
0

|Skji |
2 
Sjj Sii −Sji
0
0

(43)
kji
of the ellipsoid to a point (u, v, w) of the unit sphere is
The transformation that associates a normal ωm
thus
kji
ωm
=
uM1 + vM2 + wM3
S kji P kji
=
,
||S kji P kji ||
||uM1 + vM2 + wM3 ||
Point on the Visible Sphere To account for visibility, we generate a point on the sphere with a
ability depending on the visibility. This is equivalent to cast a ray on a sphere, i.e. generating a 2D
(u, v) on the unit disk and computing its third coordinate w by orthogonal projection
p
p
(u, v) =
U1 cos(2π U2 ), U1 sin(2π U2 ) ,
p
w = 1 − u2 − v 2 .
(44)
probpoint
(45)
(46)
Rotation back to world space The computations so far have been done in the space (ω k , ω j , ω i ) and
we need to we rotate the normal back to world space (ω x , ω y , ω z )
ω m = (ω k ω j ω i ) ω kji
m .
12
(47)
2
Implementation
2.1
The Projected Area
Z
hω i , ω m i D(ω m ) dω m
σ(ω i ) =
(48)
Ω
q
ω Ti S ω i
q
= x2i Sxx + yi2 Syy + zi2 Szz + 2xi yi Sxy + 2xi zi Sxz + 2yi zi Syz
=
(49)
(50)
float sigma(vec3 wi,
float S_xx, float S_yy, float S_zz,
float S_xy, float S_xz, float S_yz)
{
const float sigma_squared = wi.x*wi.x*S_xx + wi.y*wi.y*S_yy
+ wi.z*wi.z*S_zz
+ 2.0f * (wi.x*wi.y*S_xy + wi.x*wi.z*S_xz + wi.y*wi.z*S_yz);
return (sigma_squared > 0.0f) ? sqrtf(sigma_squared) : 0.0f; // conditional to avoid numerical errors
}
2.2
The Distribution of Normals
D(ω m ) =
1
π
p
|S| (ω Tm
(51)
S −1 ω m )2
3
|S| 2
=
π(ω Tm adj(S) ω m )2
(52)
where the adjugate is defined as
2
Syy Szz − Syz
= Sxz Syz − Sxy Szz
Sxy Syz − Sxz Syy

adj(S) = |S| S −1
Sxz Syz − Sxy Szz
2
Sxx Szz − Sxz
Sxy Sxz − Syz Sxx

Sxy Syz − Sxz Syy
Sxy Sxz − Syz Sxx 
2
Sxx Syy − Sxy
(53)
float D(vec3 wm,
float S_xx, float S_yy, float S_zz,
float S_xy, float S_xz, float S_yz)
{
const float detS =
S_xx*S_yy*S_zz - S_xx*S_yz*S_yz - S_yy*S_xz*S_xz - S_zz*S_xy*S_xy + 2.0f*S_xy*S_xz*S_yz;
const float den = wm.x*wm.x*(S_yy*S_zz-S_yz*S_yz) + wm.y*wm.y*(S_xx*S_zz-S_xz*S_xz) + wm.z*wm.z*(S_xx*S_yy-S_xy*S_xy)
+ 2.0f*(wm.x*wm.y*(S_xz*S_yz-S_zz*S_xy) + wm.x*wm.z*(S_xy*S_yz-S_yy*S_xz) + wm.y*wm.z*(S_xy*S_xz-S_xx*S_yz));
const float D = powf(fabsf(detS), 1.5f) / (M_PI*den*den);
return D;
}
13
2.3
Importance Sampling the Distribution of Visible Normals
This function implements the importance sampling procedure of the distribution of visible normals.
vec3 sample_VNDF(const vec3 wi,
const float S_xx, const float S_yy, const float S_zz,
const float S_xy, const float S_xz, const float S_yz,
const float U1, const float U2)
{
// generate
const float
const float
const float
const float
const float
sample (u, v, w)
r = sqrtf(U1);
phi = 2.0f*M_PI*U2;
u = r*cosf(phi);
v= r*sinf(phi);
w = sqrtf(1.0f - u*u - v*v);
// build orthonormal basis
vec3 wk, wj;
buildOrthonormalBasis(wk, wj, wi);
// project S in this basis
const float S_kk = wk.x*wk.x*S_xx + wk.y*wk.y*S_yy + wk.z*wk.z*S_zz
+ 2.0f * (wk.x*wk.y*S_xy + wk.x*wk.z*S_xz + wk.y*wk.z*S_yz);
const float S_jj = wj.x*wj.x*S_xx + wj.y*wj.y*S_yy + wj.z*wj.z*S_zz
+ 2.0f * (wj.x*wj.y*S_xy + wj.x*wj.z*S_xz + wj.y*wj.z*S_yz);
const float S_ii = wi.x*wi.x*S_xx + wi.y*wi.y*S_yy + wi.z*wi.z*S_zz
+ 2.0f * (wi.x*wi.y*S_xy + wi.x*wi.z*S_xz + wi.y*wi.z*S_yz);
const float S_kj = wk.x*wj.x*S_xx + wk.y*wj.y*S_yy + wk.z*wj.z*S_zz
+ (wk.x*wj.y + wk.y*wj.x)*S_xy
+ (wk.x*wj.z + wk.z*wj.x)*S_xz
+ (wk.y*wj.z + wk.z*wj.y)*S_yz;
const float S_ki = wk.x*wi.x*S_xx + wk.y*wi.y*S_yy + wk.z*wi.z*S_zz
+ (wk.x*wi.y + wk.y*wi.x)*S_xy + (wk.x*wi.z + wk.z*wi.x)*S_xz + (wk.y*wi.z + wk.z*wi.y)*S_yz;
const float S_ji = wj.x*wi.x*S_xx + wj.y*wi.y*S_yy + wj.z*wi.z*S_zz
+ (wj.x*wi.y + wj.y*wi.x)*S_xy
+ (wj.x*wi.z + wj.z*wi.x)*S_xz
+ (wj.y*wi.z + wj.z*wi.y)*S_yz;
// compute normal
float sqrtDetSkji = sqrtf(fabsf(S_kk*S_jj*S_ii - S_kj*S_kj*S_ii - S_ki*S_ki*S_jj
float inv_sqrtS_ii = 1.0f / sqrtf(S_ii);
float tmp = sqrtf(S_jj*S_ii-S_ji*S_ji);
vec3 Mk(sqrtDetSkji/tmp, 0.0f, 0.0f);
vec3 Mj(-inv_sqrtS_ii*(S_ki*S_ji-S_kj*S_ii)/tmp , inv_sqrtS_ii*tmp, 0);
vec3 Mi(inv_sqrtS_ii*S_ki, inv_sqrtS_ii*S_ji, inv_sqrtS_ii*S_ii);
vec3 wm_kji = normalize(u*Mk+v*Mj+w*Mi);
- S_ji*S_ji*S_kk + 2.0f*S_kj*S_ki*S_ji));
// rotate back to world basis
return wm_kji.x * wk + wm_kji.y * wj + wm_kji.z * wi;
}
Helper: Orthonormal Basis Construction This function implements Frisvad’s algorithm [Fri12].
// build orthonormal basis (Building an Orthonormal Basis from a 3D Unit Vector Without Normalization, [Frisvad2012])
void buildOrthonormalBasis(vec3& omega_1, vec3& omega_2, const vec3& omega_3)
{
if(omega_3.z < -0.9999999f)
{
omega_1 = vec3 ( 0.0f , -1.0f , 0.0f );
omega_2 = vec3 ( -1.0f , 0.0f , 0.0f );
} else {
const float a = 1.0f /(1.0f + omega_3.z );
const float b = -omega_3.x*omega_3 .y*a ;
omega_1 = vec3 (1.0f - omega_3.x*omega_3. x*a , b , -omega_3.x );
omega_2 = vec3 (b , 1.0f - omega_3.y*omega_3.y*a , -omega_3.y );
}
}
14
2.4
The Specular Microflake Phase Function
Evaluation
This function implements the evaluation of the specular microflake phase function.
fpspec (ω i → ωo ) =
D(ωh )
4 σ(ω i )
(54)
float eval_specular(vec3 wi, vec3 wo,
const float S_xx, const float S_yy, const float S_zz,
const float S_xy, const float S_xz, const float S_yz)
{
vec3 wh = normalize(wi + wo);
return 0.25f * D(wh, S_xx, S_yy, S_zz, S_xy, S_xz, S_yz) / sigma(wi, S_xx, S_yy, S_zz, S_xy, S_xz, S_yz);
}
Importance Sampling This function implements the importance sampling procedure of the specular
microflake phase function.
vec3 sample_specular(const vec3 wi,
const float S_xx, const float S_yy, const float S_zz,
const float S_xy, const float S_xz, const float S_yz,
const float U1, const float U2)
{
// sample VNDF
const vec3 wm = sample_VNDF(wi, S_xx, S_yy, S_zz, S_xy, S_xz, S_yz, U1, U2);
// specular reflection
const vec3 wo = -wi + 2.0f * wm * dot(wm, wi);
return wo;
}
15
2.5
The Diffuse Microflake Phase Function
Evaluation
function.
This function implements the unbiased stochastic evaluation of the diffuse microflake phase
float eval_diffuse(vec3 wi, vec3 wo,
const float S_xx, const float S_yy, const float S_zz,
const float S_xy, const float S_xz, const float S_yz,
const float U1, const float U2)
{
// sample VNDF
const vec3 wm = sample_VNDF(wi, S_xx, S_yy, S_zz, S_xy, S_xz, S_yz, U1, U2);
// eval diffuse
return 1.0f / M_PI * max(0.0f, dot(wo, wm));
}
Importance Sampling
croflake phase function.
This function implements the importance sampling procedure of the diffuse mi
vec3 sample_diffuse(const vec3 wi,
const float S_xx, const float S_yy, const float S_zz,
const float S_xy, const float S_xz, const float S_yz,
const float U1, const float U2, const float U3, const float U4)
{
// sample VNDF
const vec3 wm = sample_VNDF(wi, S_xx, S_yy, S_zz, S_xy, S_xz, S_yz, U1, U2);
// sample diffuse reflection
vec3 w1, w2;
buildOrthonormalBasis(w1, w2, wm);
float r1 = 2.0f*U3 - 1.0f;
float r2 = 2.0f*U4 - 1.0f;
// concentric map code from
// http://psgraphics.blogspot.ch/2011/01/improved-code-for-concentric-map.html
float phi, r;
if (r1 == 0 && r2 == 0) {
r = phi = 0;
} else if (r1*r1 > r2*r2) {
r = r1;
phi = (M_PI/4.0f) * (r2/r1);
} else {
r = r2;
phi = (M_PI/2.0f) - (r1/r2) * (M_PI/4.0f);
}
float x = r*cosf(phi);
float y = r*sinf(phi);
float z = sqrtf(1.0f - x*x - y*y);
vec3 wo = x*w1 + y*w2 + z*wm;
return wo;
}
16
17
3
Parameter Estimation Results
Input
Parameter Estimation
SGGX
Linear Filtering
Neyret
SGGX
X
X
−1
1
1
Q
Sn
n
N
N
n=1..N
n=1..N


σx = 1.30
σy = 1.14
σz = 1.20


1.30
1.13
1.19


1.36
1.33
1.37


1.36
1.16
1.23


σx = 1.84
σy = 1.69
σz = 4.22


1.84
1.72
4.23


2.43
2.00
4.30


1.85
1.98
4.26


σx = 0.68
σy = 0.72
σz = 1.63


0.69
0.77
1.64


0.98
0.90
1.68


0.69
0.89
1.65


σx = 0.41
σy = 1.22
σz = 1.48


0.41
1.27
1.52


0.84
1.32
1.55


0.41
1.32
1.55


σx = 1.30
σy = 0.61
σz = 1.25




1.40
0.64
1.34

1.32
0.60
1.23

1.40
1.10
1.40
Figure 7: Parameter estimation from abitrary distributions. The σ values are the projected areas onto the
canonical directions x, y and z.
18
Input
Parameter Estimation
SGGX
Linear Filtering
Neyret
SGGX
X
X
−1
1
1
Qn
Sn
N
N
n=1..N
n=1..N


σx = 0.81
σy = 1.27
σz = 1.31


0.83
1.29
1.33


0.89
1.13
1.35


0.87
1.34
1.38


σx = 0.16
σy = 0.59
σz = 0.63


0.16
0.59
0.62


0.44
1.37
0.30


0.22
0.60
0.63


σx = 0.38
σy = 0.57
σz = 0.55


0.37
0.57
0.54


3.32
6.88
4.31


0.40
0.57
0.56


σx = 0.38
σy = 0.56
σz = 0.57


0.36
0.55
0.57


3.79
4.84
5.97


0.39
0.57
0.57


σx = 0.69
σy = 0.80
σz = 0.71




0.89
0.10
0.93

0.70
0.79
0.73

0.85
1.06
0.80
Figure 8: Parameter estimation from abitrary distributions. The σ values are the projected areas onto the
canonical directions x, y and z.
19
4
4.1
LOD Results
Filtering Specular Microflakes
Figure 9: Close up. The scarf is made of specular microflakes.
Reference
SGGX LOD2
density LOD1
37MB
SGGX LOD2
density LOD0
187MB
SGGX LOD3
density LOD3
2MB
SGGX LOD3
density LOD2
5MB
SGGX LOD3
density LOD1
23MB
42 voxels/pixel
1228MB
SGGX LOD2
density LOD2
18MB
Reference
82 voxels/pixel
1228MB
Figure 10: Filtering.
20
Figure 11: Close up. The hair is made of specular microflakes.
Reference
SGGX LOD2
density LOD1
113MB
SGGX LOD2
density LOD0
782MB
42 voxels/pixel
1911MB
SGGX LOD2
density LOD2
29MB
SGGX LOD3, density LOD3 SGGX LOD3, density LOD2 SGGX LOD3, density LOD1
4MB
14MB
98MB
82 voxels/pixel
Reference
1911MB
Figure 12: Filtering.
21
4.2
Filtering Diffuse Microflakes
Figure 13: Close up. The scarf is made of diffuse microflakes.
Reference
SGGX LOD2
density LOD1
37MB
SGGX LOD2
density LOD0
187MB
SGGX LOD3
density LOD3
2MB
SGGX LOD3
density LOD2
5MB
SGGX LOD3
density LOD1
23MB
42 voxels/pixel
1228MB
SGGX LOD2
density LOD2
18MB
Reference
82 voxels/pixel
1228MB
Figure 14: Filtering.
22
Figure 15: Close up. The hair is made of diffuse microflakes.
Reference
SGGX LOD2
density LOD1
113MB
SGGX LOD2
density LOD0
782MB
SGGX LOD3
density LOD3
4MB
SGGX LOD3
density LOD2
14MB
SGGX LOD3
density LOD1
98MB
42 voxels/pixel
1911MB
SGGX LOD2
density LOD2
29MB
Reference
82 voxels/pixel
1911MB
Figure 16: Filtering.
23
4.3
Filtering Mixed Microflakes
Figure 17: Close up. The tree is made of 35% specular and 65% diffuse microflakes.
Reference
SGGX LOD2
density LOD1
118MB
SGGX LOD2
density LOD0
810MB
SGGX LOD3
density LOD3
4MB
SGGX LOD3
density LOD2
15MB
SGGX LOD3
density LOD1
101MB
42 voxels/pixel
1979MB
SGGX LOD2
density LOD2
32MB
Reference
82 voxels/pixel
1979MB
Figure 18: Filtering.
24
References
[Fri12] Jeppe Revall Frisvad. Building an orthonormal basis from a 3d unit vector without normalization.
Journal of Graphics Tools, 16(3):151–159, 2012. 1.6, 2.3
[Hei14] Eric Heitz. Understanding the masking-shadowing function in microfacet-based BRDFs. Journal of
Computer Graphics Techniques, 3(2):32–91, 2014. 1.4, 3
[Ney95] Fabrice Neyret. A general and multiscale model for volumetric textures. In Graphics Interface,
pages 83–91, 1995. 1.2, 1.4
25