You are on page 1of 8

Coefficients and colors from d 'Eon and Luebke skin scattering work ScatterCoeffs 0.0064, 0.0484, 0.187, 0.

567, 1.99, 7.41 Sqrt 2 ScatterColors 0.233, 0.455, 0.649 , 0.1, 0.336, 0.344 , 0.118, 0.198, 0 , 0.113, 0.007, 0.007 , 0.358, 0.004, 0 , 0.078, 0, 0 GaussianFn var_ , x_ : 1 Sqrt 2 Pi var Exp x x 2 var Skin scattering profile approximated a sum of multiple gaussians. We don't want to work with three dimensional RGB vectors so here one of the inputs selects which channel we want ScatterFn x_ , rgb_ : Apply Plus, Table GaussianFn var , x , var , ScatterCoeffs ScatterColors
Out[1]= Out[2]=

rgb

0.00905097, 0.0684479, 0.264458, 0.801859, 2.81428, 10.4793 0.233, 0.455, 0.649 , 0.1, 0.336, 0.344 , 0.118, 0.198, 0 , 0.113, 0.007, 0.007 , 0.358, 0.004, 0 , 0.078, 0, 0 This is the function defined with integrals, as in the paper DiffuseLight _ , r_ , rgb_ : NIntegrate Clip Cos x , 0, 1 ScatterFn Abs 2 r Sin x 2 , rgb , x , Pi, Pi DiffuseWeight r_ , rgb_ : NIntegrate ScatterFn Abs 2 r Sin x 2 , rgb , x , Pi, Pi DiffuseIntegral _ , r_ , rgb_ : DiffuseLight , r , rgb DiffuseWeight r , rgb This is a bit faster to evaluate, it's a translation of the code used to generate the lookup table DiffuseWeight2 r_ , rgb_ : NSum ScatterFn Abs 2 r Sin x 2 , rgb , x , Pi, Pi, 2 Pi 20 DiffuseLight2 _ , r_ , rgb_ : NSum Clip Cos x , 0, 1 ScatterFn Abs 2 r Sin x 2 , rgb , x , Pi, Pi, 2 Pi 20 DiffuseIntegral2 _ , r_ , rgb_ : DiffuseLight2 , r , rgb DiffuseWeight2 r , rgb

In[5]:=

In[11]:=

Let's theck that they are similar ... DiffuseIntegral 0.1, 8, 1 DiffuseIntegral2 0.1, 8, 1 DiffuseIntegral 0.1, 15, 1 DiffuseIntegral2 0.1, 15, 1 0.979266 0.990889 0.990641 0.994601 Let's generate a table of data to be used for the numerical fitting... channel 1; 1 red 2 green 3 blue dataThetaRVal Flatten Table , r , DiffuseIntegral , r , channel , , 0, Pi, 2 Pi 20 , r , 0.25, 6, 1 20 , 1 ;

Out[11]= Out[12]= Out[13]= Out[14]=

In[16]:=

EricPenner_SkinScattering1.nb

an extended range that we will use to check how the fit extrapolates dataIntervalExt Flatten Table , r , , 0, Pi, 2 Pi 20 , r , 0, 12, 1 20 LineInterp a_ ,b_ ,x_ ,x0_ ,x1_ : b Clip x x0, 0,1 a Clip 1 x x0 x1 x0 , 0,1 dataGraph ListPlot3D dataThetaRVal, InterpolationOrder 3 cosGraph ListPlot3D x First x , Last x , Clip Cos First x , 0, 1 Plotting against the simple lambert cos lighting model, of course that's not dependent on r ... Show dataGraph , cosGraph

,1 ;

dataIntervalExt ;

Out[18]=

Out[20]=

EricPenner_SkinScattering1.nb

In[24]:=

Ok, let's have a peek at our function to understand its shape... We'll plot a single slice, then a graph with three slices and the Lambert's clamped cos plotIn2d Plot DiffuseIntegral x , 5, 1 , x , 0, Pi Plot DiffuseIntegral x , 1, 1 , DiffuseIntegral x , 3, 1 , DiffuseIntegral x , 6, 1 , Max Cos x , 0 , x , 0, Pi

0.8

0.6
Out[24]=

0.4

0.2

0.5 1.0

1.0

1.5

2.0

2.5

3.0

0.8

0.6
Out[25]=

0.4

0.2

0.5

1.0

1.5

2.0

2.5

3.0

EricPenner_SkinScattering1.nb

In[26]:=

We have to find a function of cos which could look similar to the DiffuseIntegral Show Plot Max Cos x 0.5 0.5, 0 ^ 3, x , 0, Pi , plotIn2d
1.0

0.8

0.6
Out[26]=

0.4

0.2

0.5

1.0

1.5

2.0

2.5

3.0

EricPenner_SkinScattering1.nb

In[27]:=

Let's find the fit now , first we have to define a parametric function, the fitting process will optimize the parameters to minimize the error piecewise linear models... fitFunction _ ,r_ : Max Cos Min a0 r a1 ,1 Max fitFunction _ ,r_ : Max Max Cos Min a0 r a1 ,1 Max a2 r a3 ,0 ,0 , Max Cos Min a4 r a5 ,1 Max a6 r a7 ,0 ,0 nonlinear models... fitFunction _ ,r_ : Cos a0 r a1 a2 r a3 ^ 3 fitFunction _ , r_ : Cos a0 r a1 a2 r a3 ^ 3 Clip a4 r a5, 0, 1 Max Cos , 0 1 Clip a4 r a5, 0, 1 fitting NonlinearModelFit dataThetaRVal, fitFunction , r , a0, a1, a2, a3, a4, a5, a6, a7 , , r , Method NMinimize We need to use NMinimize for non smooth models fitParams fitting "BestFitParameters" Plus Abs fitting "FitResiduals" Print the sum of residuals We plot the fit function over dataIntervalExt to check that it extrapolates well dataFit x First x , Last x , fitFunction First x , Last x dataIntervalExt; fitGraph ListPlot3D dataFit, InterpolationOrder 3, ColorFunction "SouthwestColors", Mesh None ; Show fitGraph , cosGraph Show fitGraph , dataGraph
Out[28]=

a2 r a3 ,0 ,0

. fitParams

FittedModel a0 a3

Clip 0.817767

0.11103 r , 0, 1

Out[29]=

0.0605281, a1 0.689657, a4

0.0903942, a2 0.0210583, 0.11103, a5 0.817767, a6 7.15776, a7

5.89292

Out[30]=

12.4611

EricPenner_SkinScattering1.nb

Out[33]=

Out[34]=

EricPenner_SkinScattering1.nb

lightVector

Normalize

1, 2, 0

Lambert SphericalPlot3D 1, , 0, Pi , , 0, Pi , ColorFunctionScaling False, False, False, False, False, False , ColorFunction x , y , z, , , r Max x , y , z .lightVector , 0 Our function radius 3; SphericalPlot3D 1, , 0, Pi , , 0, Pi , ColorFunctionScaling False, False, False, False, False, False , ColorFunction x , y , z, , , r fitFunction ArcCos x , y , z .lightVector , radius . fitParams

Out[45]=

EricPenner_SkinScattering1.nb

Out[47]=

todo... Use NMinimize to find a fit with a custom error metric, i.e. perceptual, weighting more the darker areas or we can fit the log of the functions or we could use the Weights option of NonlinearModelFit Constraint fit i.e. zero at r 1, 2 Pi or better , equal to Cos for r going to Find artist tunable parameters and use Manipulate to validate them ...

You might also like