3
\$\begingroup\$

I'm using three.js to make an animation of a box moving around the screen in 3 dimensions.

It is moving pseudo-randomly, according to a noise function. So, I want to place an invisible wall just outside of view, so the box tends to stay in the screen.

I have accomplished this. However, it only works correctly when the box's z coordinate is 0.

I need a function that calculates the boundaries based on the z coordinate of the box. Right now, if z is negative (farther away) the boundary is too small and if z is positive the boundary gets too big.

I am not sure how to go about this. This is how I am creating the camera, I am new to three.js and this part I just copied from a tutorial:

var camera = new THREE.PerspectiveCamera(45, window.innerWidth/window.innerHeight, 1, 10000);
camera.position.z=1000;

This is the function signature from the docs:

PerspectiveCamera( fov, aspect, near, far )

  • fov: Camera frustum vertical field of view.
  • aspect: Camera frustum aspect ratio.
  • near: Camera frustum near plane.
  • far: Camera frustum far plane.

I'm not really sure what FOV does but I think it may be the key here.... If FOV allows me to get a relevant angle than I can probably use basic trig to find my offset value.

\$\endgroup\$
4
  • \$\begingroup\$ you want to calculate the camera frustum boundarys? \$\endgroup\$ Mar 15, 2015 at 13:13
  • \$\begingroup\$ does this help? stackoverflow.com/questions/12018710/… \$\endgroup\$ Mar 15, 2015 at 13:14
  • \$\begingroup\$ @LukeP, did any of the answers help you with your problem? I need to award the bounty. \$\endgroup\$
    – House
    Mar 22, 2015 at 14:52
  • \$\begingroup\$ Great, glad you could find your answer here. \$\endgroup\$
    – House
    Mar 22, 2015 at 16:20

1 Answer 1

4
+150
\$\begingroup\$

FOV is field of view. Everyone likes to say that there is no camera in OpenGL, but to me that's a silly notion to hold on to even if it might be technically true. When you use the perspectiveCamera function you are essentially creating a camera. So think of the FOV as the type of lens. Is it a wide angle lens or more of a zoom lens?

The FOV is given as an angle. If it's a smaller number things that are farther away will appear larger. If it's a larger number things that are farther away will appear smaller. This is exactly like a real lens. In a way, smaller FOV's sort of compress the distance.

The way a lens works is that the visible plane at any farther distance is bigger than the visible plane at a shorter distance. Looking through a lens you can see the width of an entire city in the distance but only the width of a park bench in the foreground. The value you're trying to fix is this: What is the size of the visible X at a given Z. Then the Y height can be calculated using aspect ratio math.

I don't know three.js or even java. But that's not important because this is a pure math problem that you can translate into any programming language. I have a couple of links here.

First is when I tried to work this out originally. A question (and answer) that I wrote here on SE. It's fairly generic to which library you're using. It's mostly just the matrix math: In 3D camera math, calculate what Z depth is pixel unity for a given FOV

Second is a video I did on how to do it in Unity3D. That one shows the code and an example of altering the FOV and seeing an object slide to stay at a specific x/y size. It's using the same type of math. You can find it on my blog here: http://gameweasel.com/pixel-perfect-sprites-in-unity3d/

Last I'll give you the actual formula to do what you're wanting. The size of the frustum at any distance can be easily calculated:

frustumHeight = 2.0 * distance * tan(fov * 0.5 * (pi/180));

That calculates the total hight of the frustum at any distance from the camera. If the center of your screen is 0,0 then the Y bounds of your frustum are (+ and -) 1/2 that amount. So just remove the 2.0 * part of the formula and then that will be the Y bounds in both the positive and negative directions.

That distance value in my formula might just be the z coordinate if your camera is at zero. Where your camera is in 3d space is determined by your View Matrix or your lookAt matrix. If it's not at 0 it's going to be an offset amount from your camera, or the distance from the camera. It's obviously in the bounds between your near and far values that you used.

Then to get the X bounds you'll take your aspect and the height result of the above formula and do:

frustumWidth = frustumHeight * aspect;

That will give you either the total width if you included the 2.0 * or the X bounds if you didn't.

\$\endgroup\$
3
  • \$\begingroup\$ The link to the gameweasel page is broken, perhaps you could quote it here? \$\endgroup\$
    – Tyhja
    May 6, 2016 at 5:42
  • \$\begingroup\$ Thanks for letting me know. I'm not sure why that is. Looking in to it. \$\endgroup\$
    – badweasel
    May 6, 2016 at 5:44
  • \$\begingroup\$ Link is fixed. It's working now. Wordpress theme updated and messed up my permalinks. \$\endgroup\$
    – badweasel
    May 6, 2016 at 5:46

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .