Mouse movement


(SRS-Kap) #21

Hi all,

For those of you experiencing these issues, I would be very interested to hear your feedback if you try the following command in the console:

RawInputUpdateTest true

For those of you that try this, please reply even if it is just to say that this makes no difference (or even if it makes things worse!).

You can also disable this test behavior so you can compare having it enabled or disabled using:

RawInputUpdateTest false

Thanks for your help!


(Bangtastic) #22

Have it on for now, but imo there is no difference. Still thx for your efforts :slight_smile: But never had rly issues, only experience mouse issues when I have low fps like on my laptop.


(SRS-Kap) #23

If you never really had issues previously or if you are running at a high framerate, it is unlikely you will notice any difference with this test :slight_smile:


(Mustang) #24

Can you explain what it does behind the scenes?


(SRS-Kap) #25

It is some test code to capture the latest raw input from the system just before beginning the rendering of the frame. The idea essentially being that what is rendered is “closer” to your latest input commands.


(BomBaKlaK) #26

I feel a better continuity in the mouse tracking, sometimes it feels a bit laggy but it feels better than without a this moment.
I will give a try a bit more then re-test without. But for the moment it’s a good feeling.


(Mustang) #27

So in real terms it’s a sub-millisecond reduction to input latency, call me skeptical but I’m rather dubious as to the improvement this will result in, isn’t it more likely a hiccup in the rendering pipeline. But hey, if it works then awesome!


(PixelTwitch) #28

When I type it in the console it says the command is not recognised :S

ok so it actually works in game…
but this is certainly still not rawinput…


(SRS-Kap) #29

Thought it might be useful to provide a high level overview for those interested.

Under Windows, the raw input API essentially allows a windows application to receive input from your devices before windows applies any modifications (such as ballistics).
Essentially there are 3 main ways to capture input in windows applications:

  1. WM_MOUSEMOVE windows messages. Game’s don’t tend to use this as this is limited by screen resolution. Essentially, you only receive these notifications when your mouse moves at least “a pixel”. If you have an awesome high DPI mouse, you would not benefit under this method.
  2. Raw Input. This is captured via the WM_INPUT windows message.
  3. Direct Input (part of DirectX). With regards to mouse input, this is essentially built on top of Raw Input, and acts as more of a wrapper.

We use Raw Input directly to capture mouse input, hence there should be absolutely no mouse acceleration etc… coming from the system at the lowest level.
Any features that would affect/alter these input commands will be in game features (for example mouse smoothing, which should be disabled by default).

The main thing to pay attention to here is the time between the mouse being moved and actually seeing the visual change on screen. In most modern game engines and even in modern hardware, there are various factors that influence this time.

To summarise, we do use raw-input and we are focused on making this game the best FPS experience available. This is definitely a hot-topic for us and we will be doing our up most to ensure that the mouse input feels great.

As mentioned in my previous post, please leave feedback as it is of great help to us!


(PixelTwitch) #30

[QUOTE=SRS-Kap;495987]Thought it might be useful to provide a high level overview for those interested.

Under Windows, the raw input API essentially allows a windows application to receive input from your devices before windows applies any modifications (such as ballistics).
Essentially there are 3 main ways to capture input in windows applications:

  1. WM_MOUSEMOVE windows messages. Game’s don’t tend to use this as this is limited by screen resolution. Essentially, you only receive these notifications when your mouse moves at least “a pixel”. If you have an awesome high DPI mouse, you would not benefit under this method.
  2. Raw Input. This is captured via the WM_INPUT windows message.
  3. Direct Input (part of DirectX). With regards to mouse input, this is essentially built on top of Raw Input, and acts as more of a wrapper.

We use Raw Input directly to capture mouse input, hence there should be absolutely no mouse acceleration etc… coming from the system at the lowest level.
Any features that would affect/alter these input commands will be in game features (for example mouse smoothing, which should be disabled by default).

The main thing to pay attention to here is the time between the mouse being moved and actually seeing the visual change on screen. In most modern game engines and even in modern hardware, there are various factors that influence this time.

To summarise, we do use raw-input and we are focused on making this game the best FPS experience available. This is definitely a hot-topic for us and we will be doing our up most to ensure that the mouse input feels great.

As mentioned in my previous post, please leave feedback as it is of great help to us![/QUOTE]

So far from testing I have figured out that mouse smoothing turns itself on at random (normally on a respawn)
the tighter the FOV adjustment from aiming down sights the worse the effect is.
Slight delay from movements showing on screen.
Mouse acceleration is present
Raw Input only really makes a noticeable difference when using One Thread Frame thing…
Diagonal movement lowers the amount of horizontal movement
Angle Snapping is present
Missed ticks do not process the mouse movement (meaning sweeping a mouse with a fluctuating framerate is horrible.)

There is not a single Unreal Engine 3 game on the market with great Mouse control… so… good luck.


(PixelTwitch) #31

THIS IS A POST I STOLE!

However after reading it multiple times I can assure you that this is the EXACT problem I am facing… I am a 3.6Sensitivity gamer at 800dpi

Quakes Method is as follows: (assuming no mouse acceleration)

Code:
θ = MouseInputX * Sensitivity * M_Yaw
M_Yaw is by default 0.022 degrees. So if in game sensitivity is 1, 1 inch of travel on an 1800dpi mouse to the right will rotate the player by 39.6 degrees.

UDK’s Method is similar:

Code:
θ = MouseInputX * Sensitivity * 0.00549316540360483
So if we want the same feel as in the Quake example we can set the sensitivity to around 4, giving us 39.6 degrees of movement on 1800 dpi mouse over 1 inch of horizontal travel.

So where is the problem then?
UDK stores most rotations in a “rotator” struct

Code:
struct immutable Rotator
{
var() int Pitch, Yaw, Roll;
};
Where “rotator units” of rotation are stored as euler angles across 3 integers.

Taking this into account, UDK’s actual mouse translation looks like this,

Code:
int UnrRot = (int)(MouseInputX * Sensitivity)
So for every “UnrRot” of movement there is an amount of rotation, in degrees, of (UnrRot * UnrRotToDeg ) Where UnrRotToDeg = 0.00549316540360483;

You cannot move .5 UnrRots! It is an integer, you must move by whole numbers only!
Every decimal movement of the mouse is converted (rounded) to an integer. And C++ by default truncates (rounds down). If I move 1 dot to the right and have a sensitivity of 0.9 there is no rotation whatsoever.

Example:
Suppose two players want 1 inch of mouse movement to be 15 degrees of rotation. Player one has a 400dpi mouse and Player two has an 1800 dpi mouse. Player one sets his sensitivity to 6.82, and Player two sets his to 1.51.

If both players move their mice slowly, over an inch, to where every frame their mouse moves only one dot (MouseInputX = 1) Player one moves 13.18 degrees and Player two moves 9.88 degrees. That’s an error of 13.8% and 66% respectively.
Now both players move their mice by an inch but quicker. Now at 2 dots per frame instead of one(MouseInputX = 2) Player one moves 14.28 degrees and Player two moves 14.83. Their errors are suddenly very different, 5% and 1.1%.

But if Player 2 wants to play at zoom level 2 at low sensitivity, his lowest choice of sensitivity is 1. If the sensitivity is any lower the amount of error will sky rocket. The only way to safely lower the amount of rotation per unit of mouse travel is to lower the mouse dpi.

Why does this affect High DPI players more? It doesn’t, It affects all people who have decimal sensitivities, with the most affected being lower sensitivity players as the error caused by rounding is greatest. It’s just that high dpi players tend to play at lower sensitivities.

How to alleviate this problem:

Set your sensitivity to whole numbers or slightly above whole numbers (ex: 10.0 or 10.01)
Either set “bEnableFOVScaling=False” in your input.ini or understand how fov affects sensitivity.*

If fov scale is on your sensitivity is multiplied by (fov * .01111)
I’m guessing that at zoom level one your fov is (fov - (fov - 40)/2) aka halfway between normal and 40. And zoom level two your fov is 40.
If you set fov scaling off you should look for a sensitivity macro. Most games set the sensitivity to the ratio between the two fov’s (90->45 = .5 sensitivity) If you want it to feel like default cs 1.6 you multiply the ratio by 1.2 (90->45 = 1.2
(.5 sensitivity))

How Hi-Rez should handle it:

Level 0: Do nothing
Level 1: Add 0.5 to the mouse movement so it rounds better as it gets casted to an int
Level 2: In addition to above, save the error from rounding and apply it next frame
Level 3: Virtual DPI cvar
Level 4: Use quaternions instead of rotators."


(Kl3ppy) #32

Mouse movement is ****. I complain about it since a year. I think it is an UE problem because I don’t experience this behavior in non UE games.
Good thing is, SD is aware of this issue, maybe they find a solution :slight_smile:


(BomBaKlaK) #33

or the moment I enjoy the “RawInputUpdateTest” it feel more fluid and consistent, but there is still something weird I can’t explain.


(SRS-Kap) #34

[QUOTE=PixelTwitch;496068]THIS IS A POST I STOLE!

However after reading it multiple times I can assure you that this is the EXACT problem I am facing… I am a 3.6Sensitivity gamer at 800dpi

Quakes Method is as follows: (assuming no mouse acceleration)

Code:
θ = MouseInputX * Sensitivity * M_Yaw
M_Yaw is by default 0.022 degrees. So if in game sensitivity is 1, 1 inch of travel on an 1800dpi mouse to the right will rotate the player by 39.6 degrees.

UDK’s Method is similar:

Code:
θ = MouseInputX * Sensitivity * 0.00549316540360483
So if we want the same feel as in the Quake example we can set the sensitivity to around 4, giving us 39.6 degrees of movement on 1800 dpi mouse over 1 inch of horizontal travel.

So where is the problem then?
UDK stores most rotations in a “rotator” struct

Code:
struct immutable Rotator
{
var() int Pitch, Yaw, Roll;
};
Where “rotator units” of rotation are stored as euler angles across 3 integers.

Taking this into account, UDK’s actual mouse translation looks like this,

Code:
int UnrRot = (int)(MouseInputX * Sensitivity)
So for every “UnrRot” of movement there is an amount of rotation, in degrees, of (UnrRot * UnrRotToDeg ) Where UnrRotToDeg = 0.00549316540360483;

You cannot move .5 UnrRots! It is an integer, you must move by whole numbers only!
Every decimal movement of the mouse is converted (rounded) to an integer. And C++ by default truncates (rounds down). If I move 1 dot to the right and have a sensitivity of 0.9 there is no rotation whatsoever.

Example:
Suppose two players want 1 inch of mouse movement to be 15 degrees of rotation. Player one has a 400dpi mouse and Player two has an 1800 dpi mouse. Player one sets his sensitivity to 6.82, and Player two sets his to 1.51.

If both players move their mice slowly, over an inch, to where every frame their mouse moves only one dot (MouseInputX = 1) Player one moves 13.18 degrees and Player two moves 9.88 degrees. That’s an error of 13.8% and 66% respectively.
Now both players move their mice by an inch but quicker. Now at 2 dots per frame instead of one(MouseInputX = 2) Player one moves 14.28 degrees and Player two moves 14.83. Their errors are suddenly very different, 5% and 1.1%.

But if Player 2 wants to play at zoom level 2 at low sensitivity, his lowest choice of sensitivity is 1. If the sensitivity is any lower the amount of error will sky rocket. The only way to safely lower the amount of rotation per unit of mouse travel is to lower the mouse dpi.

Why does this affect High DPI players more? It doesn’t, It affects all people who have decimal sensitivities, with the most affected being lower sensitivity players as the error caused by rounding is greatest. It’s just that high dpi players tend to play at lower sensitivities.

How to alleviate this problem:

Set your sensitivity to whole numbers or slightly above whole numbers (ex: 10.0 or 10.01)
Either set “bEnableFOVScaling=False” in your input.ini or understand how fov affects sensitivity.*

If fov scale is on your sensitivity is multiplied by (fov * .01111)
I’m guessing that at zoom level one your fov is (fov - (fov - 40)/2) aka halfway between normal and 40. And zoom level two your fov is 40.
If you set fov scaling off you should look for a sensitivity macro. Most games set the sensitivity to the ratio between the two fov’s (90->45 = .5 sensitivity) If you want it to feel like default cs 1.6 you multiply the ratio by 1.2 (90->45 = 1.2
(.5 sensitivity))

How Hi-Rez should handle it:

Level 0: Do nothing
Level 1: Add 0.5 to the mouse movement so it rounds better as it gets casted to an int
Level 2: In addition to above, save the error from rounding and apply it next frame
Level 3: Virtual DPI cvar
Level 4: Use quaternions instead of rotators."[/QUOTE]

Hi PixelTwitch,

The post you made above is indeed correct and is one of the factors contributing to the mouse input feeling less than perfect. This is a known issue that will require some time to fix properly so watch this space for updates.


(Smooth) #35

[QUOTE=SRS-Kap;496155]Hi PixelTwitch,

The post you made above is indeed correct and is one of the factors contributing to the mouse input feeling less than perfect. This is a known issue that will require some time to fix properly so watch this space for updates.[/QUOTE]

But yeah, SRS-Kap is the man with a plan :armadillochase:


(PixelTwitch) #36

So after looking around for many hours I have come up with these as the most responsive mouse settings… Not because they “FIX” the problems with UE3 when it comes to mouse movement but because it minimises the errors to do with rounding. The following should be changed in your ShooterInput.ini and BaseInput.ini

Obviously bEnableMouseSmoothing=false turns off mouse smoothing.
LookRightScale and LookUpScale should always be left as 0 to avoid issues later.
UnrealEngine really does not like sensitivities below 5.0 if this is too high you can lower your DPI or the “SPEED” in the later lines of code.

Also I have still got no idea if the “Control” “Shift” and “Alt” mean anything just a few of the configs I looked at had them so I stuck em in as well… ALWAYS keep AbsoluteAxies=0 for mouse commands as it effects other values. Speed can be modified to get more or less sensitivity, enabling you to have lower sensitivity then 5 while keeping the value at 5.

[Engine.PlayerInput]
MoveForwardSpeed=1200
MoveStrafeSpeed=1200
LookRightScale=0
LookUpScale=-0
MouseSensitivity=5.000000
DoubleClickTime=0.250000
bEnableMouseSmoothing=false

For turning left and right…

Bindings=(Name="TurnLeft",Command="Axis aBaseX Speed=+1 DeadZone=0 AbsoluteAxis=0",Control=False,Shift=False,Alt=False,bIgnoreCtrl=False,bIgnoreShift=False,bIgnoreAlt=False)
Bindings=(Name="TurnRight",Command="Axis aBaseX  Speed=-1 DeadZone=0 AbsoluteAxis=0",Control=False,Shift=False,Alt=False,bIgnoreCtrl=False,bIgnoreShift=False,bIgnoreAlt=False)

Look up and down…

Bindings=(Name="LookUp",Command="Axis aLookUp Speed=+1 DeadZone=0 AbsoluteAxis=0",Control=False,Shift=False,Alt=False,bIgnoreCtrl=False,bIgnoreShift=False,bIgnoreAlt=False)
Bindings=(Name="LookDown",Command="Axis aLookUp Speed=-1 DeadZone=0 AbsoluteAxis=0",Control=False,Shift=False,Alt=False,bIgnoreCtrl=False,bIgnoreShift=False,bIgnoreAlt=False)

General Mouse…

Bindings=(Name="MouseX",Command="Count bXAxis | Axis aMouseX Speed=0.5",Control=False,Shift=False,Alt=False,bIgnoreCtrl=False,bIgnoreShift=False,bIgnoreAlt=False)
Bindings=(Name="MouseY",Command="Count bYAxis | Axis aMouseY Speed=0.5",Control=False,Shift=False,Alt=False,bIgnoreCtrl=False,bIgnoreShift=False,bIgnoreAlt=False)

(Mustang) #37

They are modifiers so if set to True it means the bind will only trigger if the corresponding modifier is held down as well.

They are supposed to all default to False, meaning you don’t have to include them if don’t want, but IIRC there is/was a bug where one/some of them were set to True by default, so it’s best to include them and manually set them False just in-case.


(Scarhand) #38

Tried the raw input update thing. Nice, there is finally something in this game that doesn’t lag. Thanks for adding.


(INF3RN0) #39

Oh nice! I just found this thread and the cmd kap posted had a noticeable improvement :eek:


(slanir) #40

So we’re in for a world of hurt now… :frowning:

Curse you, developers!!!