![]() |
SUBSIM: The Web's #1 resource for all submarine & naval simulations since 1997 |
![]() |
#1 |
Helmsman
![]() Join Date: Jun 2011
Posts: 105
Downloads: 181
Uploads: 0
|
![]()
I don't know if this was posted before, at least I saw many threads for SH3/SH5 concerning calibration of scopes for different resolutions, but in all these threads only trial and error approach was proposed (i.e. draw a line and see if it is at proper bearing, etc.). In light of latest FOV thread I made a slight detour from my touchpads exploits into camera area. Here's what I came up with:
- AngularAngle is camera's horizontal FOV at 1x zoom. This means that in order to properly calibrate periscope, you need to determine what FOV your scope camera should have at 1x zoom. Disambiguation: this does not mean your scope's low power zoom should be set to 1. It just means that in order to get correct FOV for the scope at given zoom, you need to set AngularAngle for 1x zoom. - Stock graticules (SH3/SH5) tell the truth (in degrees). They are calculated for actual camera FOV, and are resized accordingly when zoom changes. - You can't make scopes with FOV that is non-multiple at different zoom levels (i.e French scopes), since you can only specify one FOV - formulas to calculate AngularAngle for given periscope ocular: For SH3 (with no resolution patch): AngularAngle = 2 * atan( ZoomAtThisFOV * w * N * tan( PeriscopeFOV / 2 ) ) For SH4/SH5: AngularAngle = 2 * atan( ZoomAtThisFOV * N * tan( PeriscopeFOV / 2 ) ) where: - PeriscopeFOV is actual periscope field of view (i.e. 38 for German scopes, 32 for US scopes) - ZoomAtThisFOV: zoom at which PeriscopeFOV is achieved (i.e. 1.5 for German/US scopes) - w (in SH3 formula) is viewport width. I.e. CameraParams.Viewport.Right-CameraParams.Viewport.Left - N is Resolution / OcularPixels (see below) It is convenient to set ZoomAtThisFOV to scope's low-power zoom (i.e. 1.5) and PeriscopeFOV to scope's low-power FOV (i.e. 38 for German scopes, 32 for US scopes in SH4). About N: you need to determine how many pixels your ocular's diameter would take at given resolution. This may vary depending on how you set up your periscope screen in .ini files, thus it is beyond the scope of this post. Then you divide your camera's horizontal resolution by this value. Why I say "camera's" here is because for SH3 it may differ from actual screen resolution. Below is some math and illustrations on how I came up with these formulas. Here we go. Let's start with finding out full FOV for camera when we only have our scope FOV. ![]() Here A is our monitor, B is our ocular, C is the distance between camera and view plane, FOVscope is periscope FOV, FOVcamera is camera FOV. What we know: A (horizontal resolution), B (ocular size), FOVscope (obviously). Let's do some math: 1) tan(FOVscope/2) = B/(2*C) 2) tan(FOVcamera/2) = A/(2*C) From (1) C = B / (2 * tan(FOVscope/2)). Putting that into (2) gives us tan(FOVcamera/2) = (A/B) * tan(FOVscope/2) From here, we could calculate FOVcamera, but we don't need to just yet. For now, let's just rename A/B as N: tan(FOVcamera/2) = N * tan(FOVscope/2) So far so good, but all this is for the scope low-power zoom, which is not necessary 1. And we need AngularAngle at 1x zoom. Let's take a look at another image: ![]() Looks exactly like the previous one, except some names are different. The game implements zoom by reducing FOV so that viewed objects appear larger. So here FOVcamera is AngularAngle (i.e. field of view at 1x zoom), FOVzoom is camera FOV after zoom is applied, B is some object that totally fills the view when zoom is applied. Now, when zoom is applied, FOV is reduced so that object appears larger. If put in other words, total viewed "width" is reduced by our zoom factor. So here, A/B = zoom. Using the same math as above, we get: tan(FOVcamera/2) = A/B * tan(FOVzoom/2) and FOVcamera = 2 * atan( A/B * tan(FOVzoom/2) ) Now, this FOVcamera is AngularAngle and A/B = zoom: AngularAngle = 2 * atan( zoom * tan(FOVzoom/2) ) What's the FOVzoom then? It's the FOVcamera from previous step, i.e. full field of view for our periscope camera at low-power zoom level: tan(FOVzoom/2) = N * tan(FOVscope/2) Let's put that in: AngularAngle = 2 * atan( zoom * N * tan(FOVscope/2) ) This is it. I hope that's clear enough ![]() Also I think clever minds should be able to translate it from resolution-tied calculations to aspect-ratio tied ones (basically the same thing, only ocular diameter should be properly scaled). I just didn't bother ![]() Example: suppose you have a 760x760 ocular image for 38-degree scope with minimal zoom of 1.5. Suppose you want the ocular to take as much space as possible, but still appear in full (i.e. full circle on screen). Let's calculate AngularAngle for 4:3 resolution, taking 1024x768 as reference. At this resolution, your ocular would be 768x768 pixels. Resolution = 1024 ZoomAtThisFOV = 1.5 PeriscopeFOV = 38 OcularPixels = 768 AngularAngle = 2 * atan( 1.5 * (1024 / 768) * tan( 38 / 2 ) ) = 69.106888959867263457785057221729 ~= 69.10689 This value should hold for any 4:3 resolution. Now, let's make our resolution 1680x1050 (16:10 or 8:5) and replace the ocular image with another one: a 1920x1920 image, but actual ocular is only 1900x1900 (some "black" space is present). At 1680x1050, the whole image would be rescaled to 1050x1050. This means that actual ocular size would be ((1900/1920)*1050) = 1039.0625 pixels. Resolution = 1680 ZoomAtThisFOV = 1.5 PeriscopeFOV = 38 OcularPixels = 1039.0625 AngularAngle = 2 * atan( 1.5 * (1680 / 1039.0625) * tan( 38 / 2 ) ) = 79.729506598014914131775270825077 ~= 79.72951 Again, for such image, this AngularAngle should be the same for any 16:10 (8:5) resolution. That's it. You get as much precision as fits into Single (or at least into S3D edit field), and no more time loss on manual search for appropriate FOV. EDIT: slight off-topic. It turns out that SH5 does not use viewport parameters for cameras (at least I haven't noticed any effect: it still uses entire screen to render), neither does SH4. But SH3 does. This brings additional coefficient to this formula for SH3: AngularAngle = 2 * atan( zoom * w * N * tan ( FOVscope/2 ) ) Here w is viewport width calculated as Viewport.Right - Viewport.Left. Reason it's here is that SH3 actually uses viewport parameters in CameraParams. Viewport.Left and Viewport.Right are "normalized device coordinates" in the range [0,1] that show where on the screen camera viewport starts/ends. So, actual camera render area may be less than entire screen. If you remember that N is Resolution / OcularPixels, where Resolution is horizontal size of screen, you can now see why we need to multiply by w: the actual camera's horizontal resolution may be less than Resolution. This is for SH3 without any widescreen patches (i.e. A is always 1024). This may be useful for people still interested in modding SH3. Don't forget to properly convert angles if your calculator expects radians instead of degrees ![]() PS. Of course, this is also applicable to binoculars/UZO/TBT AngularAngles. Just use the correct OcularPixels, especially if your ocular is not round (as is popular for binoculars): take full ocular width in pixels as it would appear at given resolution. Last edited by radcapricorn; 06-28-12 at 10:52 AM. Reason: Added correct SH3 formula |
![]() |
![]() |
![]() |
#2 |
Helmsman
![]() Join Date: Jun 2011
Posts: 105
Downloads: 181
Uploads: 0
|
![]()
Added correct formula for SH3 (is there a cross-game modding forum here?
![]() |
![]() |
![]() |
![]() |
#3 |
Eternal Patrol
![]() |
![]()
One thing to remember is that no real periscope ever had 1x zoom. They were all 1.5x and 6x.
__________________
“Never do anything you can't take back.” —Rocky Russo |
![]() |
![]() |
![]() |
#4 |
Helmsman
![]() Join Date: Jun 2011
Posts: 105
Downloads: 181
Uploads: 0
|
![]()
I think there's a bit of misunderstanding here
![]() I'm not proposing to use 1x zoom. It's just that this AngularAngle controls horizontal FOV for the camera that acts as periscope at 1x zoom. It is the initial value from which the game calculates FOV when zoom is applied. In other words, we have to "zoom out" our desired FOV to 1x if we want to have proper FOV at 1.5x in game. Using the formula we get the AngularAngle that needs to be set in cameras.cam in order that given scope low power zoom (1.5) and ocular size we would get correct field of view (i.e. 38 degrees). No 1x zoom involved ![]() |
![]() |
![]() |
![]() |
#5 |
Eternal Patrol
![]() |
![]()
Wouldn't surprise me. Half the time I misunderstand myself.
I wasn't sure, and just thought I'd mention it. What you're doing here is a good thing. ![]()
__________________
“Never do anything you can't take back.” —Rocky Russo |
![]() |
![]() |
![]() |
#6 |
Lieutenant
![]() Join Date: Jan 2012
Posts: 252
Downloads: 66
Uploads: 0
|
![]() ![]()
__________________
Robert Schmidt, LTJG U-43 |
![]() |
![]() |
![]() |
#7 |
Helmsman
![]() Join Date: Jun 2011
Posts: 105
Downloads: 181
Uploads: 0
|
![]()
Hmmm, where are these numbers from?
|
![]() |
![]() |
![]() |
#8 |
Helmsman
![]() Join Date: Jun 2011
Posts: 105
Downloads: 181
Uploads: 0
|
![]()
I have been able to run some tests on SH4 also. Post #1 updated accordingly.
|
![]() |
![]() |
![]() |
|
|