ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/cal/cal/fovsample.cal
Revision: 1.4
Committed: Sun Apr 7 15:38:35 2019 UTC (5 years, 2 months ago) by greg
Branch: MAIN
Changes since 1.3: +18 -13 lines
Log Message:
Made function invertible and added inverse

File Contents

# Content
1 { RCSid $Id: fovsample.cal,v 1.3 2019/04/05 23:49:59 greg Exp $ }
2 {
3 Foveated sampling based on central direction vector,
4 magnification factor at center, and central field of view.
5
6 Greg Ward April 2019
7
8 Preset constants:
9 Cx, Cy, Cz : central view direction
10 M : central FOV magnification factor
11 D : field of view (full angle in degrees)
12
13 Inputs:
14 forward = 1 if forward conversion, -1 if reverse
15 iDx, iDy, iDz = input sampling vector
16
17 Outputs:
18 oDx, oDy, oDz = output sample direction (normalized)
19
20 Other variables computed:
21 iTheta = input angle to center (radians)
22 oTheta = output angle to center (radians)
23 }
24
25 r : PI/360 * D; { half-angle of foveal region in radians }
26 rp : M * r; { half-angle of mapped boundary }
27
28 len(x,y,z) : sqrt(x*x + y*y + z*z);
29 sq(x) : x*x;
30 { normalize central vector }
31 Clen : len(Cx,Cy,Cz);
32 nCx : Cx/Clen;
33 nCy : Cy/Clen;
34 nCz : Cz/Clen;
35 { normalize input direction }
36 iDnf = 1/len(iDx,iDy,iDz);
37 niDx = iDx*iDnf;
38 niDy = iDy*iDnf;
39 niDz = iDz*iDnf;
40 { check for degenerate case (center of fovea) }
41 iDot = nCx*niDx + nCy*niDy + nCz*niDz;
42 degen = iDot - cos(.05*PI/180);
43
44 iTheta = acos(iDot);
45 { quadratic function coefficients mate to linear ramp }
46 qa : (PI - PI/M)/sq(PI - rp);
47 qb : 1/M - 2*PI*r*(M - 1)/sq(PI - rp);
48 qc : (PI - PI/M)/sq(PI/rp - 1);
49
50 oTheta = if (forward,
51 if(rp-iTheta, iTheta/M, qa*iTheta*iTheta + qb*iTheta + qc),
52 if(r-iTheta, iTheta*M, (sqrt(qb*qb - 4*qa*(qc - iTheta)) - qb)/(2*qa))
53 );
54 { normalized "up" vector for rotation }
55 Unf = 1/sqrt(1 - iDot*iDot);
56 nUx = (nCy*niDz - nCz*niDy)*Unf;
57 nUy = (nCz*niDx - nCx*niDz)*Unf;
58 nUz = (nCx*niDy - nCy*niDx)*Unf;
59 { rotate central vector by oTheta to get new output }
60 rcos = cos(oTheta);
61 rsin = sqrt(1 - rcos*rcos);
62 { foveated sample direction }
63 rDx = nCx*rcos + (nUy*nCz - nUz*nCy)*rsin;
64 rDy = nCy*rcos + (nUz*nCx - nUx*nCz)*rsin;
65 rDz = nCz*rcos + (nUx*nCy - nUy*nCx)*rsin;
66 { substitute approximation in degenerate case }
67 oDx = if(degen, nCx+(niDx-nCx)*if(forward,1/M,M), rDx);
68 oDy = if(degen, nCy+(niDy-nCy)*if(forward,1/M,M), rDy);
69 oDz = if(degen, nCz+(niDz-nCz)*if(forward,1/M,M), rDz);