1
votes
Vector3d nearC(0,0,0 -w);
Vector3d farC(0,0,0-x);
double width = y/2;
double height = z/2;
double angleOfHeight = atan(height/w);
double angleOfWidth = atan(width/w);
double adjustedHeight = tan(angleOfHeight) * x;
double adjustedWidth = tan(angleOfWidth) * x;

nearC[0] - width, nearC[1] - height, nearC[2]
nearC[0] - width, nearC[1] + height, nearC[2]
nearC[0] + width, nearC[1] + height, nearC[2]
nearC[0] + width, nearC[1] - height, nearC[2]
farC[0] - adjustedWidth, farC[1] - adjustedHeight, farC[2]
farC[0] - adjustedWidth, farC[1] + adjustedHeight, farC[2]
farC[0] + adjustedWidth, farC[1] + adjustedHeight, farC[2]
farC[0] + adjustedWidth, farC[1] - adjustedHeight, farC[2]

Above is my frustum in view coordinates. View Matrix is:

 0   0  -1   0
 0   1   0  -1
 1   0   0 -10
 0   0   0   1

All of it is right, we have a sheet.

I can't for the life of me figure how to get that frustum in canonical viewing volume. I've run through every perspective projection I could find. Current is this:

        s,        0,                      0,                     0,
        0,        s,                      0,                     0,
        0,        0,             -(f+ne)/(f-ne),            2*f*ne/(f-ne),
        0,        0,                      1,                     0;

double s = 1/tan(angleOfView * 0.5 * M_PI / 180);

I'm missing a step or something, right? Or a few steps?

Sorry to sound so hopeless now, been spinning wheels a while on this.

Any help appreciated.

1
its unclear what you want to achieve.... and where the problem is try to describe your problem a bit moreSpektre
I'm trying to achieve something like this: scratchapixel.com/lessons/3d-basic-rendering/… Mapping a viewing frustum to that -1,1 canonical view. But I just can't manage it haha.Sean
what exactly is known? your first code/table is a mess.Spektre
I have the translation from world coordinates to viewing coordinates. That's from the first block, which gives the 8 corners of the frustum. The matrix beneath that is the translation from world coordinates to viewing coordinates. Now I'm trying to get those 8 corners of the frustum into a -1,1 box. w is the distance to the far pane. x is the distance to the near pane. Calculations beneath all that are trig to get the frustum. **Sorry x is far, w is near.Sean
Basically I've managed the trig and the first translation from world coordinates to viewing coordinates but every other matrix has eluded me. Can't work the orthogonal, can't work the canonical viewing volume.Sean

1 Answers

2
votes

Lest start with the perspective projection. The common way in old GL is to use gluPerspective.

for that we need znear,zfar,FOV and aspect ratio of view. For more info see:

  • Calculating the perspective projection matrix according to the view plane

    I am used to use FOVx (viewing angle in x axis). To compute that you need to look at your frustrum from above looking at xz plane (in camera space):

    frustrum XY plane

    so:

    tan(FOVx/2) = znear_width / 2*focal_length
    FOVx = 2*atan(znear_width / 2*focal_length)
    

    the focal length can be computed by computing the intersection of frustrum edge lines. Or by using triangle similarity. The second is easier to write:

    zfar_width/2*(|zfar-znear|+focal_length) = znear_width/2*(focal_length)
    zfar_width/(|zfar-znear|+focal_length) = znear_width/(focal_length)
    focal_length = (|zfar-znear|+focal_length)*znear_width/zfar_width
    focal_length - focal_length*znear_width/zfar_width = |zfar-znear|*znear_width/zfar_width 
    focal_length*(1-(znear_width/zfar_width)) = |zfar-znear|*znear_width/zfar_width 
    focal_length = (|zfar-znear|*znear_width/zfar_width) / (1-(znear_width/zfar_width))
    

    and that is all we need so:

    focal_length = (|zfar-znear|*znear_width/zfar_width) / (1-(znear_width/zfar_width))
    FOVx = 2*atan(znear_width / 2*focal_length)        
    FOVx*=180.0/M_PI; // convert to degrees
    aspect=znear_width/znear_height;
    gluPerspective(FOVx/aspect,aspect,znear,zfar);
    

    just be aware of that |zfar-znear| is perpendicular distance between the planes !!! So if you do not have axis aligned ones then you need to compute that using dot product and normal ...