Film aperture in MM

Started by WAS, April 20, 2022, 01:12:17 AM

Previous topic - Next topic

WAS

Ok... forget that last topic, I got lost in questions... and I think I have solved them. I have created my own functions for getting the Vertical FOV and Horizontal FOV, since the Three.JS camera only have one FOV, which is defaulted to vertical. I am not sure if they are giving me the right results though.

effectiveVerticalFOV = ( 2 * Math.atan( (camera.getFilmHeight()/2) / camera.getFocalLength()) * 180 / Math.PI ),
 effectiveHorizontalFOV = ( 2 * Math.atan( (camera.getFilmWidth()/2) / camera.getFocalLength()) * 180 / Math.PI ),

But my real issue is I don't understand the values for film aperture in mm. Is the second value the vertical film gauge (value of 24 in default tg scene)? If so, how is it calculated? I only have one film gauge value.

WAS

#1
Is... is it really just Film Gauge / Film Width? That gives me a value of 24.694444~ from filmGauge = 35mm / filmWidth = 1.4173228346456692 (I think filmWidth is the Horizontal FOV?)

Additionally, in another annoying discovery; I found out that they derive the film gauge from the aperture width and height (in inches) and depending on the aperture mode, use FOV, or focal length. I'm not sure what formula they are using for FOV or focal length, and if it's VFOV and HFOV for horizontal or vertical modes. Here is some docu on it:

http://docs.autodesk.com/FBX/2014/ENU/FBX-SDK-Documentation/index.html?url=cpp_ref/class_fbx_camera.html,topicNumber=cpp_ref_class_fbx_camera_htmld363a59a-a768-4ab3-b3a6-d806f23a2f8b,hash=a10cf7a193e6be067d21992964f436b2d

http://docs.autodesk.com/FBX/2014/ENU/FBX-SDK-Documentation/index.html?url=cpp_ref/_camera_2main_8cxx-example.html,topicNumber=cpp_ref__camera_2main_8cxx_example_html00c9e922-0f70-4520-bff5-4fd83c5030aa

https://download.autodesk.com/us/fbx/sdkdocs/fbx_sdk_help/files/fbxsdkref/class_k_fbx_camera.html#434770d8c013ac8d55a4e67278972aff

pokoy

I think Film Gauge is the same Film/Sensor Width.

Have a look at the other thread, I have included an excel sheet with all the formulas you need to get a matching camera conversion.

WAS

#3
Well I discovered FBXLoader doesn't support gauge. It defaults to 35mm. And yeah gauge is the camera lense aperture. The other diameter is the diameter of the chevron shutter. That I can't seem to solve without user input as the FBX doesn't seem to come with f-stop in Three.JS. Three.JS seems to only be interpreting most the files but doesn't understand some of it so they just don't load parse it I guess.

Near and far planes is for DOF. In TG we only use the far plane I guess, as that's all the shader asks for. Blender defaults to 10.

So my real issue now is I need to use all the data I have a available, probably including resolution (1920x1080), focal length, FOV, etc, and somehow calculate the film gauge for horizontal and vertical. And I am not sure. That's what those links are I provided are about, how it gets the diameter mode. Just can't find the actual calculation.

I'll check out the excel sheet.

PS I just hard coded f-stop for now with a factor of 8, which is closest to TGs 5 based on 35mm.

PPS I do have filmWidth and filmHeight which is supposedly lense width and height in inches. I am sure this could be used to derive both horizontal and vertical camera lens diameter.

pokoy

If Near/Far planes are really related to f-stop in FBX, then target/focus point would have to be located 1/3 of the way between far and near - that's how physical DOF works. But I'm really not sure they are, the near point seems really like distance culling and is probably set up the way it is in order to avoid z-fighting, with most FBX importers just ignoring far plane or even both, it's probably a left-over from way back in the day when the FBX spec was created. If it is related to DOF then it would probably be possible to compute f-stop from these, but this would seem like a really convoluted way to express what one parameter could do.

All you need is focal length and film/sensor width. And actually, all you need is FOV in order to get a matching image, because FOV is a product of these two.

Read the other thread I posted in and the linked wikipedia stuff. There's way more info and variables with real world lenses, but for CG, only the pinhole model counts, and additional features like DOF/Bokeh/Tilt-Shift are done on top of the pinhole model.

WAS

#5
According to the documentation, it is for DOF. It's even used for DOF in Blender. It's set to 10, compared to TGs 100 because of the unit scaling I believe (similar to having to divide Blender/FBX position units by 100 for meters). I don't know why it wouldn't be part of DOF honestly.

WAS

Thanks for the links too, but they don't seem top help with my specific issues. I already have aspect ratio from the resolution, and I can't derive a f-stop from data I have, so it would have to be an input for every camera before exporting, then I could get the pinhole diameter. The main issue I am having is all I have is sensor width and height in inches, and I need lense diameter for vertical/horizontal to set these correct camera lens mm, as Three.JS defaults to 35mm and doesn't use the data provided by FBX to get its actual camera lens type, this independent of the pinhole diameter, which I can derive if I have a f-stop input.

WAS

#7
Here is how I derived a value of 24mm using the film width (trying to match whatever TG did and has)

Code
console.log('Film Guage: ' + camera.filmGauge + ' Film Width: ' + cameraAttribute.FilmWidth.value + ' Vertical Film Gauge: ' + Math.floor( ( camera.filmGauge / cameraAttribute.FilmWidth.value ) ) );Result:
Film Guage: 35 Film Width: 1.4173228346456692 Vertical Film Gauge: 24

If I convert FilmWidth from Inches to Millimeters I get 36 rounded up. If I floor that, I get 35mm. If I convert FilmHeight from Inches to Millimeters I get 23.999999999999996447, round that up it's 24mm. This by default pretty much matches TG. And the round up to 36 matches blenders 36mm.

I think these literally are the gauges, just in inches!!

PS I don't have Excel, so I can't use the formulas in it. Just can look at them. I can't even see what's behind the seens, can't righ click anything or do anything. Literally just view the end spreadsheet. 

pokoy

You can use any of the open source Excel clones, Open Office Or Libre Office to view it. Attaching an open document table file type now instead.

First things first - camera properties such as focal width and film/sensor dimensions are always defined in mm, you will never see inches used.

Looking at the three.js camera properties, film gauge is film/sensor width - it specifically says that:

.filmGauge : float
Film size used for the larger axis. Default is 35 (millimeters).

But it obviously defaults to 35mm, not 36mm.

There's also FilmHeight and FilmWidth but FilmGauge seems to have been introduced to handle the larger axis, no idea why. There's probably a portrait and landscape mode and FilmGauge might make it easier to work with these independent from mode.

Focus doesn't have any influence on the projection matrix unless you use DOF or stereoscopy. Just like for a CG pinhole model, it is not needed to construct the correct the FOV.

Near and Far are the camera frustrum - not related to DOF in any way, just the region that the camera will display, starting from camera's local origin.

Also, there's this:

.setFocalLength ( focalLength : Float ) : undefined
Sets the FOV by focal length in respect to the current .filmGauge.
By default, the focal length is specified for a 35mm (full frame) camera.

This defaults to 35mm - but please don't confuse it with FilmGauge - they are different parameters, and just happen to default to 35mm respectively! It's probably set to 35mm because there's the notion that humans perceive their environment similar to a 35mm lens (with a full frame 36mm film), and smaller values tend to distort too much and are perceived as unrealistic.

And it specifically states that you can set the FOV by specifying both FocalLength and FilmGauge (which is film width in landscape mode), which is exactly what I'm trying to say in my previous posts.

I might be getting it all totally wrong, maybe just ask some CG specialists.

WAS

Well, the FBX SDK Documentation is very clear. The FilmWidth and FilmHeight are in inches. Lol Remember, what makes sense on a physical camera, may not make sense in code, or be as optimized. Such as using mm which would be larger floats.

And yeah, as I mentioned, Three.js doesn't support FBX gauge, it defaults ot 35mm because it isn't doing anything from the FBX file. I had to do it myself. It's a missing feature of the FBXLoader.js (See: https://discourse.threejs.org/t/fbx-not-setting-filmgauge/37240/4).  So none of that is relevant here. This has to be derived from raw data from the FBX attributes.




WAS

#10
These issues are pretty much resolved. I may add a feature to define aperture (pinhole) in mm for each camera before export.

My only remaining issue seems to be rotation. Setting Y+ UP and Z+ Forward in the export, doesn't seem to be yielding the correct rotations.

The application is updated online at NWDA (https://nwdagroup.com/terragen-tools/fbxcam2terragen/) to current state. It now exports the TGC file with the cameras. Just trying to work out the rotation right now.

pokoy

You're right - inches... well then.

Rotation... maybe rotation order? Other than that, I've no idea.

WAS

#12
Looks like they are all arbitrarily rotated on Y and extra 90 degrees for some reason. Without knowing why, I am hesitant to compensate for it. I asked on Three.js and Stackoverflow.

Adding 90 to Y rotation in the rotations Y formula yields correct result, but unsure where 90 degrees is being lost -- additionally, if I tilt cameras and compare, they are not correct still.

// Camera Rotation in XYZ Degrees
 cameraRotation = ( Math.round( THREE.Math.radToDeg( camera.rotation.x ) % 360 ) ) + ' ' + ( ( Math.round( THREE.Math.radToDeg( camera.rotation.y ) ) + 90 ) % 360 )
+ ' ' + ( Math.round( THREE.Math.radToDeg( camera.rotation.z ) % 360 ) );

Found another formula, which yields the same result, so starting to think it's not the formula.

cameraRotation = ( Math.round( camera.rotation.x * ( 180 / Math.PI ) ) ) + ' '
+ ( Math.round( camera.rotation.y * ( 180 / Math.PI ) ) ) + ' '
+ ( Math.round( camera.rotation.z * ( 180 / Math.PI ) ) );

WAS

I feel the rotation issue is based on something I am missing. Between the coordinate systems. Or something. Maybe @Matt could chime in when he gets a chance. Could even be down to all these ridiculous settings to export a FBX and some combination therein.

Matt

If the rotation order needs to be changed, I don't think you can do this with a simple 90 rotation, it's more complex than that. Terragen's FBX and chan importers perform additional steps to convert between rotation orders. The algorithm we use is pretty specific to the tools we have in our codebase, but perhaps there's some source code online?
Just because milk is white doesn't mean that clouds are made of milk.