Skip to content
GitLab
Menu
Projects
Groups
Snippets
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Menu
Open sidebar
alta
alta
Commits
1f0a995e
Commit
1f0a995e
authored
Oct 28, 2013
by
Laurent Belcour
Browse files
Adding nonlinear function retro Beckmann
parent
f6d79a1f
Changes
6
Hide whitespace changes
Inline
Side-by-side
sources/plugins/SConscript
View file @
1f0a995e
...
...
@@ -6,6 +6,7 @@ SConscript('rational_fitter_quadprog/SConscript')
# Building functions
SConscript
(
'nonlinear_function_diffuse/SConscript'
)
SConscript
(
'nonlinear_function_beckmann/SConscript'
)
SConscript
(
'nonlinear_function_retrobeckmann/SConscript'
)
SConscript
(
'nonlinear_function_blinn/SConscript'
)
SConscript
(
'nonlinear_function_retroblinn/SConscript'
)
SConscript
(
'rational_function_legendre/SConscript'
)
...
...
sources/plugins/nonlinear_function_retrobeckmann/SConscript
0 → 100644
View file @
1f0a995e
env
=
Environment
()
env
.
Append
(
CPPPATH
=
[
'../../../external/build/include'
,
'../../'
])
env
.
Append
(
LIBPATH
=
[
'../../../external/build/lib'
,
'../../build'
])
sources
=
[
'function.cpp'
]
libs
=
[
'-lcore'
]
env
.
SharedLibrary
(
'../../build/nonlinear_function_retrobeckmann'
,
sources
,
LIBS
=
libs
)
sources/plugins/nonlinear_function_retrobeckmann/function.cpp
0 → 100644
View file @
1f0a995e
#include "function.h"
#include <string>
#include <sstream>
#include <iostream>
#include <fstream>
#include <limits>
#include <algorithm>
#include <cmath>
#include <core/common.h>
ALTA_DLL_EXPORT
function
*
provide_function
()
{
return
new
beckmann_function
();
}
vec
beckmann_function
::
G
(
const
vec
&
x
)
const
{
vec
res
(
dimY
());
for
(
int
i
=
0
;
i
<
dimY
();
++
i
)
{
const
double
cl
=
x
[
2
]
/
(
_a
[
i
]
*
sqrt
(
1
-
x
[
2
]
*
x
[
2
]));
const
double
cv
=
x
[
5
]
/
(
_a
[
i
]
*
sqrt
(
1
-
x
[
5
]
*
x
[
5
]));
res
[
i
]
=
1.0
;
if
(
cl
<
1.6
)
{
res
[
i
]
*=
(
3.535
*
cl
+
2.181
*
cl
*
cl
)
/
(
1
+
2.276
*
cl
+
2.577
*
cl
*
cl
);
}
if
(
cv
<
1.6
)
{
res
[
i
]
*=
(
3.535
*
cv
+
2.181
*
cv
*
cv
)
/
(
1
+
2.276
*
cv
+
2.577
*
cv
*
cv
);
}
}
return
res
;
}
// Overload the function operator
vec
beckmann_function
::
operator
()(
const
vec
&
x
)
const
{
return
value
(
x
);
}
vec
beckmann_function
::
value
(
const
vec
&
x
)
const
{
double
h
[
3
];
params
::
convert
(
&
x
[
0
],
params
::
CARTESIAN
,
params
::
SCHLICK_VK
,
&
h
[
0
]);
// Compute the Shadow term to init res
vec
res
=
G
(
x
);
for
(
int
i
=
0
;
i
<
dimY
();
++
i
)
{
const
double
a
=
_a
[
i
];
const
double
a2
=
a
*
a
;
const
double
dh2
=
h
[
2
]
*
h
[
2
];
const
double
expo
=
exp
((
dh2
-
1.0
)
/
(
a2
*
dh2
));
if
(
h
[
2
]
>
0.0
&&
x
[
2
]
*
x
[
5
]
>
0.0
)
{
res
[
i
]
*=
_ks
[
i
]
/
(
4.0
*
x
[
2
]
*
x
[
5
]
*
M_PI
*
a2
*
dh2
*
dh2
)
*
expo
;
}
else
{
res
[
i
]
*=
0.0
;
}
}
return
res
;
}
// Reset the output dimension
void
beckmann_function
::
setDimY
(
int
nY
)
{
_nY
=
nY
;
// Update the length of the vectors
_a
.
resize
(
_nY
)
;
_ks
.
resize
(
_nY
)
;
}
//! Number of parameters to this non-linear function
int
beckmann_function
::
nbParameters
()
const
{
return
2
*
dimY
();
}
//! Get the vector of parameters for the function
vec
beckmann_function
::
parameters
()
const
{
vec
res
(
2
*
dimY
());
for
(
int
i
=
0
;
i
<
dimY
();
++
i
)
{
res
[
i
*
2
+
0
]
=
_ks
[
i
];
res
[
i
*
2
+
1
]
=
_a
[
i
];
}
return
res
;
}
//! \brief get the min values for the parameters
vec
beckmann_function
::
getParametersMin
()
const
{
vec
res
(
2
*
dimY
());
for
(
int
i
=
0
;
i
<
dimY
();
++
i
)
{
res
[
i
*
2
+
0
]
=
0.0
;
res
[
i
*
2
+
1
]
=
0.0
;
}
return
res
;
}
//! Update the vector of parameters for the function
void
beckmann_function
::
setParameters
(
const
vec
&
p
)
{
for
(
int
i
=
0
;
i
<
dimY
();
++
i
)
{
_ks
[
i
]
=
p
[
i
*
2
+
0
];
_a
[
i
]
=
p
[
i
*
2
+
1
];
}
}
//! Obtain the derivatives of the function with respect to the
//! parameters
//! \todo finish.
vec
beckmann_function
::
parametersJacobian
(
const
vec
&
x
)
const
{
double
h
[
3
];
params
::
convert
(
&
x
[
0
],
params
::
CARTESIAN
,
params
::
SCHLICK_VK
,
h
);
// Get the geometry term
vec
g
=
G
(
x
);
vec
jac
(
dimY
()
*
nbParameters
());
for
(
int
i
=
0
;
i
<
dimY
();
++
i
)
{
for
(
int
j
=
0
;
j
<
dimY
();
++
j
)
{
if
(
i
==
j
&&
h
[
2
]
>
0.0
&&
x
[
2
]
*
x
[
5
]
>
0.0
)
{
const
double
a
=
_a
[
i
];
const
double
a2
=
a
*
a
;
const
double
dh2
=
h
[
2
]
*
h
[
2
];
const
double
expo
=
exp
((
dh2
-
1.0
)
/
(
a2
*
dh2
));
const
double
fac
=
(
4.0
*
x
[
2
]
*
x
[
5
]
*
M_PI
*
a2
*
dh2
*
dh2
);
// df / dk_s
jac
[
i
*
nbParameters
()
+
j
*
2
+
0
]
=
g
[
i
]
*
expo
/
fac
;
// df / da_x
jac
[
i
*
nbParameters
()
+
j
*
2
+
1
]
=
-
g
[
i
]
*
_ks
[
i
]
*
(
expo
/
(
4.0
*
x
[
2
]
*
x
[
5
]))
*
((
2
*
a
*
h
[
2
])
/
(
M_PI
*
a2
*
a2
*
dh2
))
*
(
1
+
(
dh2
-
1.0
)
*
h
[
2
]
/
(
a2
*
dh2
*
h
[
2
]));
}
else
{
jac
[
i
*
nbParameters
()
+
j
*
2
+
0
]
=
0.0
;
jac
[
i
*
nbParameters
()
+
j
*
2
+
1
]
=
0.0
;
}
}
}
return
jac
;
}
void
beckmann_function
::
bootstrap
(
const
data
*
d
,
const
arguments
&
args
)
{
for
(
int
i
=
0
;
i
<
dimY
();
++
i
)
{
_ks
[
i
]
=
1.0
;
_a
[
i
]
=
1.0
;
}
}
//! Load function specific files
bool
beckmann_function
::
load
(
std
::
istream
&
in
)
{
// Parse line until the next comment
while
(
in
.
peek
()
!=
'#'
)
{
char
line
[
256
];
in
.
getline
(
line
,
256
);
// If we cross the end of the file, or the badbit is
// set, the file cannot be loaded
if
(
!
in
.
good
())
return
false
;
}
// Checking for the comment line #FUNC nonlinear_function_lafortune
std
::
string
token
;
in
>>
token
;
if
(
token
.
compare
(
"#FUNC"
)
!=
0
)
{
std
::
cerr
<<
"<<ERROR>> parsing the stream. The #FUNC is not the next line defined."
<<
std
::
endl
;
return
false
;
}
in
>>
token
;
if
(
token
.
compare
(
"nonlinear_function_retrobeckmann"
)
!=
0
)
{
std
::
cerr
<<
"<<ERROR>> parsing the stream. function name is not the next token."
<<
std
::
endl
;
return
false
;
}
// Parse the lobe
for
(
int
i
=
0
;
i
<
_nY
;
++
i
)
{
in
>>
token
>>
_ks
[
i
];
in
>>
token
>>
_a
[
i
];
}
return
true
;
}
void
beckmann_function
::
save_call
(
std
::
ostream
&
out
,
const
arguments
&
args
)
const
{
bool
is_alta
=
!
args
.
is_defined
(
"export"
)
||
args
[
"export"
]
==
"alta"
;
if
(
is_alta
)
{
out
<<
"#FUNC nonlinear_function_retrobeckmann"
<<
std
::
endl
;
for
(
int
i
=
0
;
i
<
_nY
;
++
i
)
{
out
<<
"Ks "
<<
_ks
[
i
]
<<
std
::
endl
;
out
<<
"a "
<<
_a
[
i
]
<<
std
::
endl
;
}
out
<<
std
::
endl
;
}
else
{
out
<<
"retrobeckmann(L, V, N, X, Y, vec3("
;
for
(
int
i
=
0
;
i
<
_nY
;
++
i
)
{
out
<<
_ks
[
i
];
if
(
i
<
_nY
-
1
)
{
out
<<
", "
;
}
}
out
<<
"), vec3("
;
for
(
int
i
=
0
;
i
<
_nY
;
++
i
)
{
out
<<
_a
[
i
];
if
(
i
<
_nY
-
1
)
{
out
<<
", "
;
}
}
out
<<
"))"
;
}
}
void
beckmann_function
::
save_body
(
std
::
ostream
&
out
,
const
arguments
&
args
)
const
{
bool
is_shader
=
args
[
"export"
]
==
"shader"
||
args
[
"export"
]
==
"explorer"
;
if
(
is_shader
)
{
out
<<
"vec3 g_beckmann(vec3 M, vec3 N, vec3 a)"
<<
std
::
endl
;
out
<<
"{"
<<
std
::
endl
;
out
<<
"
\t
float d = dot(M,N);"
<<
std
::
endl
;
out
<<
"
\t
vec3 c = d / (a * sqrt(1.0f-d));"
<<
std
::
endl
;
out
<<
"
\t
vec3 r;"
<<
std
::
endl
;
out
<<
"
\t
if(c.x < 1.6f) {"
<<
std
::
endl
;
out
<<
"
\t\t
r.x = (3.535*c.x + 2.181*c.x*c.x) / (1 + 2.276*c.x + 2.577*c.x*c.x);"
<<
std
::
endl
;
out
<<
"
\t
} else {"
<<
std
::
endl
;
out
<<
"
\t\t
r.x = 1.0f;"
<<
std
::
endl
;
out
<<
"
\t
}"
<<
std
::
endl
;
out
<<
"
\t
if(c.y < 1.6f) {"
<<
std
::
endl
;
out
<<
"
\t\t
r.y = (3.535*c.y + 2.181*c.y*c.y) / (1 + 2.276*c.y + 2.577*c.y*c.y);"
<<
std
::
endl
;
out
<<
"
\t
} else {"
<<
std
::
endl
;
out
<<
"
\t\t
r.y = 1.0f;"
<<
std
::
endl
;
out
<<
"
\t
}"
<<
std
::
endl
;
out
<<
"
\t
if(c.z < 1.6f) {"
<<
std
::
endl
;
out
<<
"
\t\t
r.z = (3.535*c.z + 2.181*c.z*c.z) / (1 + 2.276*c.z + 2.577*c.z*c.z);"
<<
std
::
endl
;
out
<<
"
\t
} else {"
<<
std
::
endl
;
out
<<
"
\t\t
r.z = 1.0f;"
<<
std
::
endl
;
out
<<
"
\t
}"
<<
std
::
endl
;
out
<<
"
\t
return r;"
<<
std
::
endl
;
out
<<
"}"
<<
std
::
endl
;
out
<<
std
::
endl
;
out
<<
"vec3 retrobeckmann(vec3 L, vec3 V, vec3 N, vec3 X, vec3 Y, vec3 ks, vec3 a)"
<<
std
::
endl
;
out
<<
"{"
<<
std
::
endl
;
out
<<
"
\t
vec3 R = 2*dot(V,N)*N - V;"
<<
std
::
endl
;
out
<<
"
\t
vec3 B = normalize(L + R);"
<<
std
::
endl
;
out
<<
"
\t
float bn = dot(B,N);"
<<
std
::
endl
;
out
<<
"
\t
float ln = dot(L,N);"
<<
std
::
endl
;
out
<<
"
\t
float vn = dot(V,N);"
<<
std
::
endl
;
out
<<
"
\t
"
<<
std
::
endl
;
out
<<
"
\t
return ks / (4 * "
<<
M_PI
<<
" * a*a * ln*vn) * exp((bn*bn - 1.0) / (a*a*bn*bn)) * g_beckmann(L,N,a) * g_beckmann(V,N,a);"
<<
std
::
endl
;
out
<<
"}"
<<
std
::
endl
;
}
}
sources/plugins/nonlinear_function_retrobeckmann/function.h
0 → 100644
View file @
1f0a995e
#pragma once
// Include STL
#include <vector>
#include <string>
// Interface
#include <core/function.h>
#include <core/data.h>
#include <core/fitter.h>
#include <core/args.h>
#include <core/common.h>
/*! \brief A Microfacet model using a Gaussian distribution for the
* micro-gemeotry distribution parametrized by the half-angle.
*
* \details
*
* <h3>Plugin parameters</h3>
*
*/
class
beckmann_function
:
public
nonlinear_function
{
public:
// methods
beckmann_function
()
{
setParametrization
(
params
::
CARTESIAN
);
setDimX
(
6
);
}
// Overload the function operator
virtual
vec
operator
()(
const
vec
&
x
)
const
;
virtual
vec
value
(
const
vec
&
x
)
const
;
// Geometrical term of the microfacets
virtual
vec
G
(
const
vec
&
x
)
const
;
//! \brief Load function specific files
virtual
bool
load
(
std
::
istream
&
in
)
;
//! \brief Export function
virtual
void
save_call
(
std
::
ostream
&
out
,
const
arguments
&
args
)
const
;
virtual
void
save_body
(
std
::
ostream
&
out
,
const
arguments
&
args
)
const
;
//! \brief Boostrap the function by defining the diffuse term
//!
//! \details
virtual
void
bootstrap
(
const
data
*
d
,
const
arguments
&
args
);
//! \brief Number of parameters to this non-linear function
virtual
int
nbParameters
()
const
;
//! \brief Get the vector of parameters for the function
virtual
vec
parameters
()
const
;
//! \brief get the min values for the parameters
virtual
vec
getParametersMin
()
const
;
//! \brief Update the vector of parameters for the function
virtual
void
setParameters
(
const
vec
&
p
)
;
//! \brief Obtain the derivatives of the function with respect to the
//! parameters.
virtual
vec
parametersJacobian
(
const
vec
&
x
)
const
;
//! \brief Provide the dimension of the input space of the function
virtual
int
dimX
()
const
{
return
6
;
}
//! \brief Set the number of output dimensions
void
setDimY
(
int
nY
);
private:
// data
vec
_ks
,
_a
;
// Lobes data
}
;
sources/plugins/nonlinear_function_retrobeckmann/nonlinear_function_retrobeckmann.pro
0 → 100644
View file @
1f0a995e
TEMPLATE
=
lib
CONFIG
*=
plugin
\
eigen
DESTDIR
=
..
/../
build
INCLUDEPATH
+=
..
/..
HEADERS
=
function
.
h
SOURCES
=
function
.
cpp
LIBS
+=
-
L
..
/../
build
\
-
lcore
sources/plugins/plugins.pro
View file @
1f0a995e
...
...
@@ -19,6 +19,7 @@ SUBDIRS = \
nonlinear_fresnel_retroschlick
\
nonlinear_function_diffuse
\
nonlinear_function_beckmann
\
nonlinear_function_retrobeckmann
\
nonlinear_function_blinn
\
nonlinear_function_retroblinn
\
nonlinear_function_ward
\
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment