Smooth Mouse Movement

Started by Firen, March 04, 2012, 15:48:14

Previous topic - Next topic

Firen

Hey,

I am programming a 3D first person game and I have a problem with rotating the camera:

Since the mouse position can only be read in whole pixel, my rotating looks kind of rough (Every time the mouse position snaps to the next pixel, the camera rotation snaps a few degrees).

Is there a way to make this smoother? I thought about increasing the mouse speed so that it moves more pixels per actual mouse movement, and then reduce the rotation amount per pixel movement, but that would be kind of sucky because I would have to increase and reset the mouse speed every time I start and end the game. Does anyone know how other first person games do this?

Thanks for any replies

Firen

Bump. I really need some help, I have looked all over the internet and have not found any solution yet.

CodeBunny

I'm pretty sure that direct mouse-rotation correlation (basically, moving the camera x degrees per pixel the mouse moves) is the way to go. Every FPS I've played seems to use that method.

However, there are three ways to improve the experience:

1: Allow the user to set the mouse sensitivity (probably with some sort of slider). This allows them to get a level of responsiveness that they like.

2: Some games have some sort of visual effect in them that makes fast rotation seem more natural. In an third-person shooter, the character may twist their shoulders before the rest of their body follows the rotation. Visual queues like this help smooth out the look of the transition.

3: Motion blur. This will make the scene appear less choppy when every moves quickly.

A fourth, potential improvement you could make (this is just a hypothetical) could be to use some sort of exponential rotation. If the mouse is only moving a small amount, only rotate the camera a small amount. However, if the mouse is moving a lot, increase the rate at which the mouse rotates.

Firen

Thanks! Ill try the motion blur, that sounds like what I was looking for!

CodeBunny

Please note that motion blur is the most graphics-intensive option; you may want to experiment with the other two first. I ranked them in order of complexity: 1 is the easiest to implement, then 2, then 3.

Firen

Well, the first one only solves the problem by slowing down mouse sensitivity, then there is less rotation per pixel and it looks smoother, but you also rotate very slowly.

CodeBunny

I have to admit, I'm a little unsure of what you mean when you say "it looks choppy."

For example, Minecraft uses per-pixel rotation, but I'm fairly sure most people are fine with the smoothness of turning.

From what I'm hearing, it sounds like you are probably doing something with your rotation, that is causing it to be more jerky than it needs to be. It should be perfectly possible for you to get smooth rotation with straight mouse movement.

What's your FPS? What's the code you use to rotate the view?

Firen

The important code is:
Vertex2 tMouseDelta = new Vertex2(Mouse.getDX(), Mouse.getDY());
getLocalPlayer().rotate(tMouseDelta);

GL11.glRotatef(-ActiveCamera.getRotation().getX(), 1.0f, 0.0f, 0.0f);
GL11.glRotatef(-ActiveCamera.getRotation().getY(), 0.0f, 1.0f, 0.0f);


The Camera is attached to the local player and rotates as much as the player does, everything but the jumping of rotation works fine actually: The player rotates a specific angle per pixel, but not as in Minecraft. I guess it has to do something with mouse acceleration since in MC you can rotate slowly and it still is smooth.

I just wonder what  5600 dpi mouses are for if i can only see changes in pixel, cant I access them directly somehow?

EDIT: FPS is set to about 60.


CodeBunny

What is the code for this:

getLocalPlayer().rotate(tMouseDelta);


I'd like to see how you modify the rotational values of the active camera.

geekygenius

I'm no expert, but you could do some kind of interpolation where you average the last few vectors of the mouse, and the current frame's to get a smoother affect. I don't know though, I've never done it, but it would be the first thing I try.

Firen

Its quite easy:

public void rotate(Vertex2 pRotate)
{
    mRotation = mRotation.add(pRotate);
}


And then before I render, I call glLoadIdentity() and glRotate() as posted in the previous post (I forgot to post loadidentity).

And Im not actually that into interpolation (and motion blur as well.. after i thought about it) since it would cause quite a lag. I dont know any game where there is some kind of lag with the mouse movement.

CodeBunny

Is rotations in radians or degrees? It looks like you could simply be applying way too much rotation per pixel of mouse movement.

Motion blur should not cause noticeable slowdown. Even if you render every frame at 33% opacity, in 5 frames you render an image at 87.5% opacity. 1/12th of a second lag is nothing, especially when the player expects it and adjusts accordingly.

Play Alan Wake, Halo, Mass Effect. I'm pretty sure they all use motion blur. Alan Wake is especially heavy-handed, but it doesn't detract from the gameplay at all.

Epicbo

Sorry for going off-topic but i'm interested in implementing motionblur. How do I render every frame at non-100% opacity?

CodeBunny

Using render to texture is an easy and fast method.

Have one texture that shows the final view. Let's call this one FINAL.
Now, render the scene (without any motion blur, so normal rendering) to a separate texture. Let's call this texture SCENE.
Render SCENE over the contents of FINAL at a given level of opacity (say, 0.5).
To finish, render the final view onto the display.

The secret of motion blur is to not make it "predictive." Don't try to blur objects in the direction of their movement, but simply blur multiple frames together. The downside of this is that the player feels like their vision is slightly lagging, but you have to be using REALLY heavy motion blur for that to be a problem.

Epicbo

Alright, thanks. I kind of see the theory behind it now. Too bad im not good enough at OpenGL to actually implement it :P