Camera FOV

Problems building or running the engine, queries about how to use features etc.
ART_Adventures
Goblin
Posts: 217
Joined: Sat Apr 16, 2005 4:47 pm

Camera FOV

Post by ART_Adventures »

Hello People,

Presently, I've modelled a scene in max and exported it over to Ogre without hassle. Right now, I'm aiming to position my camera in Ogre to be at the same position and orientation as it was in max so my scene is viewed from the same angle in Ogre. This too works fine. However, the one small issue is related to FOV. In max, my camera has an FOV of 45 degrees, but this does not seem to correspond to the same value in Ogre. It seems to be more like 34.6 for an Ogre camera, but this is only a guess based upon trial and error. Does anybody know a clean, calculated method of what this value should be in relation to the camera FOV from MAX?

Thanks.
User avatar
DWORD
OGRE Retired Moderator
OGRE Retired Moderator
Posts: 1365
Joined: Tue Sep 07, 2004 12:43 pm
Location: Aalborg, Denmark

Post by DWORD »

I'm not entierly sure on this, but it sounds like Max and Ogre define FOV using different axes (x and y). If you assume Max uses the x-axis, you can calculate the FOV necessary in Ogre by using something like:

arctan(tan(45°/2)*0.75)*2 = 34.5°

Where 45° is the FOV in Max, and 0.75 is the aspect ratio of the Ogre viewport.

Edit: Fixed calculation.
User avatar
c_dd2
Halfling
Posts: 79
Joined: Sun Jul 10, 2005 11:40 am
Location: Belgium

Post by c_dd2 »

Sorry to hijack a little bit this post :?

@DWORD:
Does this work also for Blender? I mean, for Z-axis-based FOV to Y-axis-based FOV?

Knowing that Blender uses Z-axis as up vector and Y-axis as depth vector...

Blender:

Code: Select all

Z Y
|/
+-- X

OGRE:

Code: Select all

  Y
  |
  +-- X
 /
Z
Also, in Blender the "Lens" (supposed to be the FOV?) is defined as 35° and in OGRE, for the moment, I use 60° and it seems to be just fine, but I'm not entirely sure...

I've had tried 90° like in Quake 3 but it was awful, lol.
"Who's the maddest of two? The mad or the one that's following him?"
Quote from Obi-Wan Kenobi (Alec Guinness), Star Wars Episode 4.
User avatar
c_dd2
Halfling
Posts: 79
Joined: Sun Jul 10, 2005 11:40 am
Location: Belgium

Post by c_dd2 »

I've computed your formula with 35° and it gives me 55.4°... It seems very near to 60°...

So, it seems to work for Blender :arrow: OGRE also? Cool, lol.

I've also tested the new FOV and it changes a little bit the way it's rendered (it's normal, lol) but I can't decide if it's really better ;)
Last edited by c_dd2 on Sun Oct 23, 2005 1:41 pm, edited 1 time in total.
"Who's the maddest of two? The mad or the one that's following him?"
Quote from Obi-Wan Kenobi (Alec Guinness), Star Wars Episode 4.
ART_Adventures
Goblin
Posts: 217
Joined: Sat Apr 16, 2005 4:47 pm

Post by ART_Adventures »

Hmmmmm. Not sure I've got this right.

I tried your formula like this:

Code: Select all

float R = atan(tan((float)45/2)*g_Camera->getAspectRatio())*2;
g_Camera->setFOVy(Radian(R));
Not sure that's correct. If it is, it doesn't seem to work. But perhaps MAX is a different axis.

Right now, in order to take a position from max and convert it to an ogre position I do the following:

-Keep X the same
- Swap Y and Z axis
- Invert Z axis

Not sure if that gives someone any insight as to how I convert the FOV.

:? [/code]
fantastico
Halfling
Posts: 46
Joined: Sat Oct 02, 2004 12:32 pm

Post by fantastico »

Ogre's camera FOV is vertical, where as 3ds max's is horizontal. I think I did somthing like this to get from one to the other

3dsmaxFOV / aspect_ratio = ogreFOV

Sadly, I've not got access to the MAXScript I had for doing this...

fantastico
User avatar
c_dd2
Halfling
Posts: 79
Joined: Sun Jul 10, 2005 11:40 am
Location: Belgium

Post by c_dd2 »

ART_Adventures wrote:-Keep X the same
- Swap Y and Z axis
- Invert Z axis
Oppose Z axis? No? I do the same to convert from Blender to OGRE :)

- Same X
- Swap Y and Z
- Z = -Z
"Who's the maddest of two? The mad or the one that's following him?"
Quote from Obi-Wan Kenobi (Alec Guinness), Star Wars Episode 4.
User avatar
DWORD
OGRE Retired Moderator
OGRE Retired Moderator
Posts: 1365
Joined: Tue Sep 07, 2004 12:43 pm
Location: Aalborg, Denmark

Post by DWORD »

ART_Adventures wrote:I tried your formula like this:

Code: Select all

float R = atan(tan((float)45/2)*g_Camera->getAspectRatio())*2;
g_Camera->setFOVy(Radian(R));
Oops, I think I swapped the aspect ratio - I used height/width=0.75, but Ogre uses width/height=1.33. And I think you mix up radians and degrees above.

Try this instead (not tested):

Code: Select all

Radian R = Math::ATan(Math::Tan(Degree((float)45/2))/g_Camera->getAspectRatio())*2;
g_Camera->setFOVy(R);
This should do it, I hope. :)
User avatar
c_dd2
Halfling
Posts: 79
Joined: Sun Jul 10, 2005 11:40 am
Location: Belgium

Post by c_dd2 »

Lol, DWORD, you were right it was 0.75 because 0.75 = 3/4 which is the ratio with use with our every day computer displays (640x480, 800x600, 1024x768, etc...) :)

It's always width/height, not the contrary except if you want to use resolutions like 600x800 or 768x1024 lol :)
"Who's the maddest of two? The mad or the one that's following him?"
Quote from Obi-Wan Kenobi (Alec Guinness), Star Wars Episode 4.
ART_Adventures
Goblin
Posts: 217
Joined: Sat Apr 16, 2005 4:47 pm

Post by ART_Adventures »

Thanks, People.

This seems to be correct. So, for the benefit of others:

To convert a MAX Camera to Ogre:

Swap Y and Z coordinates
Invert Z

And use DWORD's forumla to compute the FOV :)
reimpell
OGRE Contributor
OGRE Contributor
Posts: 570
Joined: Mon Mar 01, 2004 10:35 am
Location: Hamburg, Germany

Post by reimpell »

c_dd2 wrote:Does this work also for Blender?
See the Blender dotScene Exporter for the correct formula:

Code: Select all

if (camera.getType()==0):
			# perspective projection
			# FOV calculation
			#    .
			#   /|
			#  / |v = 16
			# /a |
			#.---'
			#  u = lens
			#
			# => FOV = 2*a = 2*arctan(v/u)
			#
			# Blender's v is in direction of the larger image dimension.
			# Ogre's FOV is definied in y direction. Therefore if 
			# SizeX*AspX > SizeY*AspY the corresponding v in y direction is
			# v_y = v*(SizeY*AspY)/(SizeX*AspX).
			fovY = 0.0
			if (sizeX*aspX > sizeY*aspY):
				fovY = 2*math.atan(sizeY*aspY*16.0/(camera.getLens()*sizeX*aspX))
			else:
				fovY = 2*math.atan(16.0/camera.getLens())
			# fov in degree
			fovY = fovY*180.0/math.pi
			# write fov
			fileObject.write("fov="%f"" % fovY)
			fileObject.write(" projectionType="perspective">\n")
		else:
			# orthographic projection
			# FOV calculation 
			# 
			# In Blender, the displayed area is scale wide in the larger image direction,
			# where scale is a ortho camera attribute.
			#
			# Ogre calculates the with and height of the displayed area from the
			# FOVy and the near clipping plane.
			#    .
			#   /|
			#  / |y
			# /a |
			#.---'
			#  n
			# Here n = near clipping plane and a = FOVy/2.
			#
			# Hence y = scale/2 and FOVy = 2*atan(scale/(2*n)).
			fovY = 0.0
			if (sizeX*aspX > sizeY*aspY):
				# tan(FOVx/2.0) = x/n = y*a/n,
				# where a is the aspect ratio.
				# It follows that s/(n*a) = y/n = tan(FOVy/2.0).
				fovY = 2.0*math.atan(sizeY*aspY*camera.getScale()/(2.0*camera.getClipStart()*sizeX*aspX))
			else:
				fovY = 2.0*math.atan(camera.getScale()/(2.0*camera.getClipStart()))
			# fov in degree
			fovY = fovY*180.0/math.pi
			# write fov
			fileObject.write("fov="%f"" % fovY)
			fileObject.write(" projectionType="orthographic">\n")
		# normal
		# Blender's camera normal always points in -z direction locally.
		fileObject.write(self._indent(indent + 1) + \
			"<normal x="0.0" y="0.0" z="-1.0"/>\n")
		# default clipping
		fileObject.write(self._indent(indent + 1) + \
			"<clipping near="%f" far="%f"/>\n" % (camera.getClipStart(), camera.getClipEnd()))
User avatar
c_dd2
Halfling
Posts: 79
Joined: Sun Jul 10, 2005 11:40 am
Location: Belgium

Post by c_dd2 »

Thank you very much reimpell. I didn't remember seeing this in your excellent exporter. Thank you to remind it to me :)
"Who's the maddest of two? The mad or the one that's following him?"
Quote from Obi-Wan Kenobi (Alec Guinness), Star Wars Episode 4.
dlannan
Gnoblar
Posts: 3
Joined: Tue May 13, 2008 3:12 am

Re: Camera FOV

Post by dlannan »

Sorry to bump this thread, but we have found there is a serious FOV problem in Ogre as posted by the original poster.
We are building simulators, and projecting the output of Ogre onto large multi-channel curved screens. While recently trying to setup the blending regions and the warping for such screens we found a discrepancy in the FOV settings between the actual and Ogre FOV rendering expected. We have a grid that indicates our blend regions and camera projection FOV's. When rendered in 3DSMax with camera horizontal FOV of 65.4478 (this is required for a 180 degree 3 channel view) we get a mathematically correct view - the blend regions exactly match either side of the view. When the exact same data is rendered in Ogre, we lose approximately 3.3 degrees of FOV (horizontal). Thus leaving about 20% of the blending region missing from the view. Below are two screenshots. Both done in 3DSMax to show the effect is directly an Ogre issue:
1. Screenshot of the 3DSMax render from the Camera
Image
2. Screenshot of the exact same view but with Ofusion Camera view. (this is exactly what we get in all of our Ogre images).
Image

I think what is happening, is that the Frustum being built may well be slightly smaller than the clip region? This used to be an old technique in rendering to mitigate some clipping artifacts - this is currently just a guess, I haven't yet had time to dig up the frustum code and figure out the missing FOV. Have been busy just trying to find out why our blending zones were not working in the first place.

So, two questions.
1. Does anyone know whether the frustum is for some reason shrunken slightly? If so, why?
2. Is there a fix, or a remedy that doesnt involve 'faking' the FOV - faking is very bad for multi-channel setups when on large screens it needs to be very accurate.

Cheers,
Dave