ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/cal/cal/fovsample.cal
Revision: 1.3
Committed: Fri Apr 5 23:49:59 2019 UTC (5 years, 1 month ago) by greg
Branch: MAIN
Changes since 1.2: +7 -12 lines
Log Message:
Simplified expression

File Contents

# User Rev Content
1 greg 1.3 { RCSid $Id: fovsample.cal,v 1.2 2019/04/05 17:17:53 greg Exp $ }
2 greg 1.1 {
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 greg 1.2 Preset constants:
9 greg 1.1 Cx, Cy, Cz : central view direction
10 greg 1.2 M : central FOV magnification factor
11 greg 1.1 D : field of view (full angle in degrees)
12    
13     Inputs:
14     iDx, iDy, iDz = uniformly generated sampling vector
15    
16     Outputs:
17     oDx, oDy, oDz = foveated sample direction (normalized)
18    
19     Other variables computed:
20     iTheta = original angle to center (radians)
21 greg 1.2 oTheta = new angle to center (radians)
22 greg 1.1 }
23 greg 1.2
24     r : PI/360 * D; { half-angle of foveal region in radians }
25     rp : M * r; { half-angle of mapped boundary }
26    
27 greg 1.1 len(x,y,z) : sqrt(x*x + y*y + z*z);
28 greg 1.3 sq(x) : x*x;
29 greg 1.2 { normalize central vector }
30 greg 1.1 Clen : len(Cx,Cy,Cz);
31     nCx : Cx/Clen;
32     nCy : Cy/Clen;
33     nCz : Cz/Clen;
34 greg 1.2 { normalize input direction }
35 greg 1.1 iDnf = 1/len(iDx,iDy,iDz);
36     niDx = iDx*iDnf;
37     niDy = iDy*iDnf;
38     niDz = iDz*iDnf;
39 greg 1.2 { check for degenerate case (center of fovea) }
40     iDot = nCx*niDx + nCy*niDy + nCz*niDz;
41     degen = iDot - cos(.05*PI/180);
42 greg 1.1
43     iTheta = acos(iDot);
44    
45 greg 1.3 gamma = 1 + sq((iTheta-rp)/(PI-rp)) * (log(M)/(log(PI/(PI-r)) - log(M)));
46 greg 1.1
47 greg 1.3 oTheta = if(rp-iTheta, iTheta/M, (PI-r)*(iTheta/(M*(PI-r)))^gamma);
48 greg 1.1
49 greg 1.2 { normalized "up" vector for rotation }
50     Unf = 1/sqrt(1 - iDot*iDot);
51 greg 1.1 nUx = (nCy*niDz - nCz*niDy)*Unf;
52     nUy = (nCz*niDx - nCx*niDz)*Unf;
53     nUz = (nCx*niDy - nCy*niDx)*Unf;
54 greg 1.2 { rotate central vector by oTheta to get new output }
55     rcos = cos(oTheta);
56     rsin = sqrt(1 - rcos*rcos);
57     { foveated sample direction }
58 greg 1.3 rDx = nCx*rcos + (nUy*nCz - nUz*nCy)*rsin;
59     rDy = nCy*rcos + (nUz*nCx - nUx*nCz)*rsin;
60     rDz = nCz*rcos + (nUx*nCy - nUy*nCx)*rsin;
61 greg 1.2 { substitute approximation in degenerate case }
62 greg 1.1 oDx = if(degen, nCx+(niDx-nCx)/M, rDx);
63     oDy = if(degen, nCy+(niDy-nCy)/M, rDy);
64     oDz = if(degen, nCz+(niDz-nCz)/M, rDz);