danielepanozzo / cg-old

43 stars 16 forks source link

moving OVV with camera #45

Closed jw3877 closed 7 years ago

jw3877 commented 7 years ago

I'm having some trouble manually calculating the required matrices now that the camera is movable. As shown in Figure 7.7 in the book, it appears the orthographic view volume (OVV) moves with the camera.

Assume we want to set the values of l, b, n, r, t, f and we have the vectors e, v, u, and w (which are the same vectors used in matrix M_cam).

For setting the n,f values, do we begin by calculating: e + t(-w); // t = 0 represents distance between camera and near side of OVV e + length(-w); // length = length of OVV cube

Then we will have rays pointing to our desired n and f values which will be in front of the camera.

For the l, r values: e + halfWidth(u) //half width of OVV cube e + halfWidth(-u)

Then we will have rays pointing to our desired l and r values, which will be on the left and right side of the camera.

(e is the position of the camera and -w is the gaze direction, which is a ray starting at e pointing to the origin (0, 0, 0).)

Is this the right way to go about this? If not, could you give some more detail on how calculate l, b, n, r, t, f in a way that works with a moving camera?

danielepanozzo commented 7 years ago

I suggest to not try to explicitly compute a OVV box that is not axis aligned, it is possible to do (and what you are doing is correct) but it is a lot harder than following what I explained in the class.

The complete explanation is also in the book, at page 145 (below Figure 7.7). Instead of building the box explicitly, you first build a transformation (the camera transformation) to modify the OVV so that it becomes aligned with the canonical axis. This transformation depends on e,u,v,w,e (Equation 7.4 in the book). After this is done, building the orthographic transformation is straightforward since your u,v,w correspond to the canonical axis and you can use the matrix in Equation 7.3 directly.

jw3877 commented 7 years ago

I've been stuck on this for a bit and can't make much progress until I get this right. I'm not sure if this is correct, but first I'm building the OVV assuming the camera is located @ (0, 0, 0):

l = -halfWidth;
r = halfWidth;

t = halfHeight;
b = -halfHeight;

n = 0;
f = -length;

Then, I multiply M_cam (7.4) by the points:

Eigen::Matrix4f cam = GetViewMatrix(); // (7.4)

Eigen::Vector4f t_lbn(l, b, n, 1);
Eigen::Vector4f t_rtf(r, t, f, 1);

t_lbn = cam * t_lbn;
t_rtf = cam * t_rtf;

Now the points of the OVV will be relative to camera space, right? Where am I going wrong?

jw3877 commented 7 years ago

My camera matrix was build this way:

Eigen::Vector3f t(0, 1, 0);

Eigen::Vector3f w = -1 * (origin - e).normalized();
Eigen::Vector3f u = t.cross(w).normalized();
Eigen::Vector3f v = w.cross(u);

Eigen::Matrix4f cam;

cam <<
u[0], v[0], w[0], e[0],
u[1], v[1], w[1], e[1],
u[2], v[2], w[2], e[2],
0, 0, 0, 1;

return cam.inverse();

I am getting strange behavior, so something is clearly wrong between the two matrices.

danielepanozzo commented 7 years ago

I don't understand why you are using the camera matrix to transform the points of the OVV. It should be used only to transform the vertices of your primitives. If you are trying to render a scene with a moving camera, this is not needed. Could you explain why you want to transform the OVV? As I wrote in the previous answer, it is hard to construct an OVV that is not axis-aligned and I suggest to avoid it if there isn't a strong reason to do it.

The camera matrix will transform the points of the objects that you will render, so that the u,v,w axes will become the canonical axes. At this point you can construct the orthographic projection matrix as usual (without transforming l, b, n, r, t, f). There is no need (and it is wrong) to use "cam" to transform the points of the OVV before building the orthographic matrix using Equation 7.3.