Using vwright/rcalc to do -pj

In my toying around with pixel-wise depth-of-field blur, I am
encountering a need for pixel jitter. I want to run

vwrays -fd -vf tempvf -x 740 -y 480 | rcalc -id6
  -e `vwright i < tempvf`
  [expressions to modify $1..$6, the ray origin and direction]
  -od | rtrace -fdc -x 740 -y 480 @opts scene.oct > img.pic

but there is no facility to incorporate pixel jitter, as defined
in rpict(1), save the use of the variables returned by vwright:

···

------------
       Nt: view type ('v'==1,'l'==2,'a'==3,'h'==4,'c'==5)
       Npx: view point x value
       Npy: view point y value
       Npz: view point z value
       Ndx: view direction x value (normalized)
       Ndy: view direction y value (normalized)
       Ndz: view direction z value (normalized)
       Nux: view up vector x value (normalized)
       Nuy: view up vector y value (normalized)
       Nuz: view up vector z value (normalized)
       Nh: view horizontal size
       Nv: view vertical size
       Ns: view shift
       Nl: view lift
       No: view fore clipping distance
       Na: view aft clipping distance
       Nhx: derived horizontal image vector x value (normalized)
       Nhy: derived horizontal image vector y value (normalized)
       Nhz: derived horizontal image vector z value (normalized)
       Nhn: derived horizontal image vector multiplier
       Nvx: derived vertical image vector x value (normalized)
       Nvy: derived vertical image vector y value (normalized)
       Nvz: derived vertical image vector z value (normalized)
       Nvn: derived vertical image vector multiplier
------------

My question is: how do I use these variables to incorporate pixel
jitter into these renderings? I do not know how to scale the
Nhx,Nhy,Nhz and Nvx,Nvy,Nvz vectors to jitter over one pixel's
width. Do I multiply by Nh,Nv and divide by 740 and 480,
respectively? Or does it depend on the view type?

Mark

Hi Mark,

If you use the variable output of vwright, you actually don't need vwrays at all. Taking the code from the viewray() routine in src/common/image.c:

  case VT_PER: /* perspective view */
    direc[0] = v->vdir[0] + x*v->hvec[0] + y*v->vvec[0];
    direc[1] = v->vdir[1] + x*v->hvec[1] + y*v->vvec[1];
    direc[2] = v->vdir[2] + x*v->hvec[2] + y*v->vvec[2];
    orig[0] = v->vp[0] + v->vfore*direc[0];
    orig[1] = v->vp[1] + v->vfore*direc[1];
    orig[2] = v->vp[2] + v->vfore*direc[2];
    d = normalize(direc);

To reproduce this in an rcalc script, we use the variables output from vwright to compute the origin and direction (with jitter) for your view using the following file, which we'll call "persp.cal":

            { Compute horizontal & vertical position on image }
H = (x + rand(.3523*recno-20.2)*jitter)/xres - 0.5;
V = (y + rand(-.1873*recno+400.3)*jitter)/yres - 0.5;
            { Compute unnormalized view direction }
dirx = idx + ihn*ihx*H + ivn*ivx*V;
diry = idy + ihn*ihy*H + ivn*ivy*V;
dirz = idz + ihn*ihz*H + ivn*ivz*V;
            { Compute view origin, including fore clipping plane }
orgx = ipx + io*dirx;
orgy = ipy + io*diry;
orgz = ipz + io*dirz;

···

------------
Here's how you apply it using rcalc:

cnt 480 740 | rcalc -od -i 'x=$2;y=$1' -e 'xres:740;yres:480;jitter:0.6' \
  -e `vwright i < tempvf` -f persp.cal \
  -e '$1=orgx;$2=orgy;$3=orgz;$4=dirx;$5=diry;$6=dirz' \
  > rtrace -fdc -x 740 -y 480 @opts scene.oct > img.pic

Naturally, you could shorten your rcalc command by sticking the various extra settings into persp.cal, but I thought you might like to leave that file general. I arbitrarily chose 0.6 as the jitter amount -- I wasn't sure what you wanted for this. Also, I haven't tested this, so I probably screwed up or missed something, which hopefully you'll be able to sort out. Let us know if it works.

-Greg