|
|
See thread 'Specular Lens Flares?' in p.general.
// Highlights on a Sphere
// written by Micha Riser, 2002
#macro evaluate(coef,pos)
// evaluate 4th-order polynom with coefficients coef at place pos
#local res=coef[0];
#local n=1;
#local pospow=pos;
#while(n<5)
#local res=res+coef[n]*pospow;
#local n=n+1;
#local pospow=pospow*pos;
#end
res
#end
#macro calc_n(l,a,px,py)
// calculate the vector poiting from origin to the point of highlight
#if ((abs(l-1)<0.00001)|(l<0))
// if (l<0) there is no reasonable solution
// if l==1 solution is simple and could be calculated
#debug "failure in calculation\n" <0,0,0>
#else
#local factor=(l-1)/(a*a*l*l-px*px-py*py);
factor*<a*l+px,py,0>
#end
#end
// macro to calculate position of highlight on a sphere
// camera: position <a,0,0>
// light_source: position <px,py,0>
// sphere: position <0,0,0>, radius 1
#macro highlight(a,px,py)
#local p=array[5] // holding coefficients of polynom
#local dp=array[5] // holding coefficients of derivation of p
// calculate coefficients of polynom
#local p_length=pow(px,2)+pow(py,2);
#local p[0]=pow(px,4)+pow(py,4)+2*px*px*py*py-p_length;
#local p[1]=2*(p_length-a*px);
#local p[2]=4*a*px-a*a-p_length*(1+2*a*a);
#local p[3]=2*a*(a-px);
#local p[4]=a*a*(a*a-1);
// derivate polynom
#local dp[0]=p[1];
#local dp[1]=2*p[2];
#local dp[2]=3*p[3];
#local dp[3]=4*p[4];
#local dp[4]=0;
// if both light source and camera is outside the sphere
// there has to be lmin <= l <= lmax
#local lmin=(sqrt(p_length)-1)/(abs(a)+1);
#local lmax=(sqrt(p_length)+1)/(abs(a)-1);
// use some very quick'n dirty newton algorithm to calculate
// roots of the polynom (uses lmin and lmax as starting points).
// needs to be reimplemented to find all four roots
#local i=0;
#local sol=lmin;
#while(i<20)
#local sol=sol-(evaluate(p,sol)/evaluate(dp,sol));
#debug str(sol,3,10)
#debug "\n"
#local i=i+1;
#end
#declare sol1=sol;
#local i=0;
#local sol=lmax;
#while(i<20)
#local sol=sol-(evaluate(p,sol)/evaluate(dp,sol));
#debug str(sol,3,10)
#debug "\n"
#local i=i+1;
#end
#declare sol2=sol;
// place sphere at the calculated position to mark the center
// of the highlight (one should place the lens flare there instead)
sphere{calc_n(sol1,a,px,py),0.05 pigment{rgb <1,0,0>} finish{ambient 0.8}
no_shadow}
sphere{calc_n(sol2,a,px,py),0.05 pigment{rgb <1,0,0>} finish{ambient 0.8}
no_shadow}
camera{
location <a,0,0>
look_at 0
}
light_source {
<px,py,0>
color 1
}
#end
/////////////////////////////////////////////////////////////////
// Test scene
#declare animation=3; // choses among there different animations
#declare Transmit=0; // sphere's transmit value
// transmit allows to see hidden highlights
#if (animation=1)
// animate camera
#declare a_anim=10-clock*9;
#declare px_anim=0;
#declare py_anim=4;
#end
#if (animation=2)
// animate lightsource from -x to +x
#declare a_anim=4;
#declare px_anim=-6+clock*15;
#declare py_anim=4;
#end
#if (animation=3)
// animate lightsource from -y to +y
#declare a_anim=4;
#declare px_anim=1.5;
#declare py_anim=-5+clock*10;
#end
highlight(a_anim,px_anim,py_anim)
sphere{0,1 pigment{rgb 1 transmit Transmit} finish{specular 1 roughness
.01}}
Post a reply to this message
|
|