Fresnel

Cook-Torrance formulation of unpolarized Fresnel reflectance at cos θ = 1

(1/2)(((((g-c)/(g+c))))^2)(1+((((((g+c)c-1)/((g-c)c+1))))^2))/.g->(Sqrt[(n^2)+(c^2)-1])/.c->1

Can simplify if it knows n>0

Simplify[((((-1+(Sqrt[(n^2)])))^2)/(((1+(Sqrt[(n^2)])))^2)),n>0]

A few common ones from https://www.physlink.com/reference/indicesofrefraction.cfm

Ice

(((((n-1)/(n+1))))^2)/.n->1.31

Water

(((((n-1)/(n+1))))^2)/.n->1.33

Glass

(((((n-1)/(n+1))))^2)/.n->1.52

Diamond

(((((n-1)/(n+1))))^2)/.n->2.417

Solve for n in terms of F0

Simplify[Solve[f==((((-1+n))^2)/(((1+n))^2)),n]]

Which one of those is air into glass rather than glass into air?

{{n->((1+(Sqrt[f]))/(1-(Sqrt[f])))},{n->((1-(Sqrt[f]))/(1+(Sqrt[f])))}}/.f->0.04

Function form in terms of cosine and (Subscript[F, 0])

F[c_,f_]:=(1/2)(((((g-c)/(g+c))))^2)(1+((((((g+c)c-1)/((g-c)c+1))))^2))/.g->(Sqrt[(n^2)+(c^2)-1])/.n->((1+(Sqrt[f]))/(1-(Sqrt[f])))

Plot with slider for F0

Manipulate[Plot[F[c,f],{c,0,1},PlotRange->{0,1}],{{f,0.04},0,1}]

Rescale range to 0-1 in range from ice to diamond

Manipulate[Plot[((F[c,f]-f)/(1-f)),{c,0,1},PlotRange->Full],{{f,0.04},0.015,0.2}]

Generate Monte-Carlo table for different cos θ values, assuming F0 ≈ glass

FresnelData=ParallelTable[{c,F[c,0.04]}/.c->RandomReal[],{i,1,1000000}];

Schlick approximation

Schlick approximation to F

S[c_]:=(((1-c))^5)

Manipulate[Plot[{f+(1-f)S[c],F[c,f]},{c,0,1},PlotRange->{0,1}],{f,0,1}]

Is there a better non-integer exponent?

FindFit[FresnelData,f+(1-f)(((1-c))^p)/.f->0.04,p,c]

Compare errors in ice to diamond range

Manipulate[Plot[{f+(1-f)S[c]-F[c,f],f+(1-f)(((1-c))^p)-F[c,f]/.{p->5.134303923970539`}},{c,0,1},PlotRange->Full],{f,0.15,0.2}]

(2^(-b c)) approximation

How’s something in the (2^(-c)) form instead

Manipulate[Plot[{f+(1-f)(2^(-b c)),F[c,f]},{c,0,1},PlotRange->{0,1}],{{f,0.04},0,1},{b,0,10}]

Find the best actual fit exponent

FindFit[FresnelData,f+(1-f)(2^(-b c))/.f->0.04,b,c]

Plot error of Schlick and exponential for ice to diamond

Manipulate[Plot[{f+(1-f)S[c]-F[c,f],f+(1-f)(2^(-b c))-F[c,f]/.{b->8.47727396770898`}},{c,0,1},PlotRange->Full],{{f,0.04},0.015,0.2}]

Not 0 at u=1, add a rescaling to enforce that constraint

Manipulate[Plot[{(2^(-b c)),(((2^(-b c))-(2^(-b)))/(1-(2^(-b))))},{c,0,1},PlotRange->{0,1}],{{b,8.4},1,10}]

Revised function to fit

P[c_,b_]:=(((2^(-b c))-(2^(-b)))/(1-(2^(-b))))

FindFit[FresnelData,f+(1-f)P[c,b]/.f->0.04,b,c]

Update with fit result

P[c_]:=P[c,b]/.{b->8.40256341137208`}

Plot the error compared to Schlick

Manipulate[Plot[{f+(1-f)S[c]-F[c,f],f+(1-f)P[c]-F[c,f]},{c,0,1},PlotRange->Full],{{f,0.04},0.015,0.2}]

Error

Expected RMS error for the data

var=NIntegrate[((F[c,0.04])^2),{c,0,1}]-((NIntegrate[F[c,0.04],{c,0,1}])^2)

(Sqrt[(var/1000000)])

Max approximation error

NMaximize[{f+(1-f)P[c]-F[c,f],0≤c≤1,0.15≤f≤0.2},{c,f}]

Propagated error from b into result

NMaximize[{Abs[D[f+(1-f)P[c,b],b]]/.b->8.40256341137208`,0≤c≤1,0.15≤f≤0.2},{c,f}]

So (Subscript[e, F])≈0.04 (Subscript[e, b]). Allowable (Subscript[e, b]) that’s still an order of magnitude less than the approximation error

(0.006/0.04)

Seems like 8.4 would be close enough. Plot the error compared to Schlick, using 8.4 as the constant

Manipulate[Plot[{f+(1-f)S[c]-F[c,f],f+(1-f)P[c]-F[c,f],f+(1-f)P[c,8.4]-F[c,f]},{c,0,1},PlotRange->Full],{{f,0.04},0.015,0.2}]