opengl object vibrate after moving a distance

你。 提交于 2019-12-23 13:23:09

问题


I have an object which moves on a terrain and a third person camera follow it, after I move it for some distance in different directions it begin to shaking or vibrating even if it is not moving and the camera rotates around it, this is the moving code of the object

double& delta = engine.getDeltaTime();
GLfloat velocity = delta * movementSpeed;
glm::vec3 t(glm::vec3(0, 0, 1) * (velocity * 3.0f));
//translate the objet atri before rendering
matrix = glm::translate(matrix, t);
//get the forward vetor of the matrix
glm::vec3 f(matrix[2][0], matrix[2][1], matrix[2][2]);
f = glm::normalize(f);
f = f * (velocity * 3.0f);
f = -f;
camera.translate(f);

and the camera rotation is

void Camera::rotate(GLfloat xoffset, GLfloat yoffset, glm::vec3& c, double& delta, GLboolean constrainpitch) {
    xoffset *= (delta * this->rotSpeed);
    yoffset *= (delta * this->rotSpeed);
    pitch += yoffset;
    yaw += xoffset;
    if (constrainpitch) {
        if (pitch >= maxPitch) {
            pitch = maxPitch;
            yoffset = 0;
        }
        if (pitch <= minPitch) {
            pitch = minPitch;
            yoffset = 0;
        }
    }
    glm::quat Qx(glm::angleAxis(glm::radians(yoffset), glm::vec3(1.0f, 0.0f, 0.0f)));
    glm::quat Qy(glm::angleAxis(glm::radians(xoffset), glm::vec3(0.0f, 1.0f, 0.0f)));
    glm::mat4 rotX = glm::mat4_cast(Qx);
    glm::mat4 rotY = glm::mat4_cast(Qy);
    view = glm::translate(view, c);
    view = rotX * view;
    view = view * rotY;
    view = glm::translate(view, -c);
}

回答1:


  1. float is sometimes not enough.

    I use double precision matrices on CPU side to avoid such problems. But as you are on Android it might not be possible. For GPU use floats again as there are no 64bit interpolators yet.

  2. Big numbers are usually the problem

    If your world is big then you are passing big numbers into the equations multiplying any errors and only at the final stage the stuff is translated relative to camera position meaning the errors stay multiplied but the numbers got clamped so error/data ratio got big.

    To lower this problem before rendering convert all vertexes to coordinate system with origin at or near your camera. You can ignore rotations just offset the positions.

    This way you will got higher errors only far away from camera which is with perspective not visible anyway... For more info see:

    • ray and ellipsoid intersection accuracy improvement
  3. Use cumulative transform matrix instead of Euler angles

    for more info see Understanding 4x4 homogenous transform matrices and all the links at bottom of that answer.




回答2:


This sounds like a numerical effect to me. Even small offsets coming from your game object will influence the rotation of the following camera with small movements / rotations and it looks like a vibrating object / camera.

So what you can do is:

  • Check if the movement above a threshold value before calculating a new rotation for your camera
  • When you are above this threshold: do a linear interpolation between the old and the new rotation using the lerp-algorithm for the quaternion ( see this unity answer to get a better understanding how your code can look like: Unity lerp discussion )


来源:https://stackoverflow.com/questions/46566270/opengl-object-vibrate-after-moving-a-distance

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!