Open Masterkent opened 1 year ago
I'd also suggest to consider a possible removal of
if ( Abs(FOVAngle - DesiredFOV) <= 10 )
FOVAngle = DesiredFOV;
The transition would become more smooth without this code. Perhaps, it was added as a hack to prevent infinite changing FOVAngle back and forth - above and below DesiredFOV, since the math above did not clamp the resulting value by DesiredFOV.
Implemented it, seams to work fine.
Looks like this causes issues with interpolation where it makes screen very jittery if default fov does not match with interpolationpoint fov.
Just FYI, PHYS_Interpolation changes PlayerPawn.FovAngle value every physics update. Maybe not update FOVAngle in UpdateEyeHeight if interpolating?
I think that the given regression revealed some fundamental issues with InterpolationPoints themselves. When player's FOVAngle is altered by InterpolationPoints, it is assumed that the normal FOV is 90 degrees. This assumption could be reasonable in the era of 4:3 monitors, but nowadays it no longer works well.
In case of an ultra-widescreen resolution with aspect ratio of 21:9, horizontal FOV of 90 degrees corresponds to the ultra-low vertical FOV of just 46.40 degrees (while the normal vertical FOV we'd get with the aspect ratio of 4:3 would be 73.74 degrees).
In order to increase vertical FOV to "normal" 73.74 degrees with this aspect ratio, the user has to set horizontal FOV to 120.51 degrees. I think that InterpolationPoints should respect this adjustment instead of enforcing obsolete defaults.
Is it also unclear why FOV dictated by InterpolationPoints should take priority over player's DesiredFOV. F.e., if we use zoom of a sniper rifle which draws a specific overlay on our screen, then resetting FOV to some default may look weirdly.
I think, the overall fix should be rather complex:
1) InterpolationPoints should not alter player's FOVAngle when DefaultFOV != DesiredFOV.
2) When player's DefaultFOV == DesiredFOV and the player is affected by InterpolationPoints, the value of FOVAngle should be calculated as follows:
FOVAngle = 360.0/Pi Atan(Tan(Pi/4.0 FovModifier) Tan(Pi/360.0 DefaultFOV));
Note that FovModifier is a linear factor defined specifically for 90 degrees, and it would be a big mistake to just replace (FovModifier 90) with (FovModifier DefaultFOV), because the "equivalent" modifier for a changed base is different. 90 degrees multiplied by 1.5 give us only 135 degrees, but 120.51 degrees multiplied by 1.5 would give us over 180 degrees - we won't see anything with such a FOV.
Alternatively, the implementation could ignore user-defined DefaultFOV and take 90 * FovModifier degrees as the horizontal FOV of the largest 4:3 rectangle inside the full viewport with the same orientation (such a FOV is often referred to as 4:3 FOV) and evaluate full horizontal FOVAngle as follows:
FOVAngle = 360.0/Pi Atan(Tan(Pi/4.0 FovModifier) FMax(1.0, GetAspectRatio() 0.75));
where GetAspectRatio() is supposed to return the current viewport width divided by the maximum of 1 and the current viewport height. In case if the aspect ratio is equal to or less than 4:3 (f.e., 5:4 for 1280x1024), the largest inner 4:3 rectangle has the same width as the width of the viewport and the full horizontal FOV angle is equal to the horizontal 4:3 FOV angle.
3) When player's FOVAngle is affected by an InterpolationPoint, UpdateEyeHeight should not update FOVAngle.
4) The state function PlayerSwimming.UpdateEyeHeight should alter FOVAngle in the same way as the global function UpdateEyeHeight (this detail is overlooked in the current implementation).
Implemented that.
Implemented that.
I can confirm that one of four issues is solved; others are not.
Consider the following code in Engine.PlayerPawn.UpdateEyeHeight:
Here FMax(7, 0.9 DeltaTime (FOVAngle - DesiredFOV)) evaluates to 7 and does not depend on DeltaTime under normal circumstances. For instance, if our framerate is 60 fps, the difference between FOVAngle and DesiredFOV must be greater than 466 degrees in order to make the value of (0.9 DeltaTime (FOVAngle - DesiredFOV)) greater than 7. This is impossible under a common usage of FOVAngle and DesiredFOV - when both belong to the range between 0 and 180 degrees. Although we can assume that some rare mods may intentionally produce weird visual effects by making that difference so large.
In case if FOVAngle is changed by 7 degrees on every tick, the speed of how FOVAngle approaches DesiredFOV highly depends on the framerate. In particular, returning from Rifle's zooming mode to the normal view will happen much faster with 300 fps than with 60 fps.
Assuming that in general framerate should not noticeably alter game mechanics or visual effects, the way of updating FOVAngle should be changed to be dependent on DeltaTime:
Here 60 fps is taken the as the standard framerate.