第一人称相机奇怪的行为在移动眼睛 [英] First person camera weird behaviour on moving the eye

查看:257
本文介绍了第一人称相机奇怪的行为在移动眼睛的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图用Java / LWJGL制作游戏/演示,并且遇到第一人称相机的麻烦:



我使用 W A S D 移动 eye




  • 当我将眼睛移开或移动到我时,

  • 当我将眼睛移动到我的右边或左边时,然后将眼睛移动到我的右边或左边。


  • 我实现了鼠标移动(环顾四周)成功,相关的部分现在的代码:



    注意:Matrix4f类按列主要顺序工作)

      Matrix4f viewMatrix = new Matrix4f(); 

    private void checkKeys(){
    if(isKeyCurrentlyDown(Keyboard.KEY_W)){
    eye.updateTranslate(1.0f,0.0f,0.0f)
    updateView();
    }
    else if(isKeyCurrentlyDown(Keyboard.KEY_S)){
    eye.updateTranslate(-1.0f,0.0f,0.0f);
    updateView();
    }
    else if(isKeyCurrentlyDown(Keyboard.KEY_A)){
    eye.updateTranslate(0.0f,-1.0f,0.0f);
    updateView();
    }
    else if(isKeyCurrentlyDown(Keyboard.KEY_D)){
    eye.updateTranslate(0.0f,1.0f,0.0f);
    updateView();
    }
    }

    private void updateView(){
    System.out.println(eye =+ eye);
    viewMatrix.identity()。viewFPS(eye,roll,yaw,pitch);
    System.out.println(viewMatrix =+ viewMatrix);
    Uniforms.setUniformMatrix4(UNIFORM_VIEW_MATRIX,false,viewMatrix);
    }

    @Override
    protected void render(final double msDelta){
    super.render(msDelta);

    glClearColor(0.0f,0.25f,0.0f,1.0f);
    glClearDepthf(1f);
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    program.use();

    for(int i = 0; i <24; i ++){
    float fVar = i + currentTime / 1000f * 0.3f;
    modelviewMatrix.identity()
    .translate(0.0f,0.0f,-8.0f)
    .rotate(currentTime / 1000f * 45.0f,0.0f,1.0f,0.0f)
    .rotate(currentTime / 1000f * 21.0f,1.0f,0.0f,0.0f)
    .translate(
    (float)Math.sin(2.1f * fVar)* 2.0f,
    (float)Math.cos(1.7f * fVar)* 2.0f,
    (float)Math.sin(1.3f * fVar)* f
    );
    Uniforms.setUniformMatrix4(UNIFORM_MODEL_MATRIX,false,modelviewMatrix.writeToFloatBuffer(modelViewMatrixBuffer));
    program.drawElements(GL_TRIANGLES,36,GL_UNSIGNED_INT,0);
    }
    }






      #version 440核心

    布局(位置= 0)在vec4位置;

    out VS_OUT {
    vec4 color;
    } vs_out;

    layout(location = 0)uniform mat4 model_matrix;
    layout(location = 1)uniform mat4 view_matrix;
    layout(location = 2)uniform mat4 proj_matrix;

    void main(){
    gl_Position = proj_matrix * view_matrix * model_matrix * position;
    vs_out.color = position * 2.0 + vec4(0.5,0.5,0.5,0.0);
    }






      public enum UniformLocation {
    UNIFORM_MODEL_MATRIX(0),
    UNIFORM_VIEW_MATRIX(1),
    UNIFORM_PROJECTION_MATRIX(2)
    ;

    private final int location;

    private UniformLocation(final int location){
    this.location = location;
    }

    public int getLocation(){
    return this.location;
    }
    }






      //列主命令

    public Matrix4f viewFPS(final Vector3f eye,final float rollAngle,final float yawAngle,final float pitchAngle){
    // roll =滚动你的头,Q& E
    // yaw =向左/向右看,mouseY
    // pitch =向上/向下,mouseX
    float sinRoll = (MathAtoRadians(rollAngle));
    float cosRoll =(float)Math.cos(Math.toRadians(rollAngle));
    float sinYaw =(float)Math.sin(Math.toRadians(yawAngle));
    float cosYaw =(float)Math.cos(Math.toRadians(yawAngle));
    float sinPitch =(float)Math.sin(Math.toRadians(pitchAngle));
    float cosPitch =(float)Math.cos(Math.toRadians(pitchAngle));

    Vector3f xAxis = new Vector3f(
    cosYaw * cosPitch,
    sinYaw * cosPitch,
    -sinPitch
    );
    Vector3f yAxis = new Vector3f(
    cosYaw * sinPitch * sinRoll - sinYaw * cosRoll,
    sinYaw * sinPitch * sinRoll + cosYaw * cosRoll,
    cosPitch * sinRoll
    ) ;
    Vector3f zAxis = new Vector3f(
    cosYaw * sinPitch * cosRoll + sinYaw * sinRoll,
    sinYaw * sinPitch * cosRoll - cosYaw * sinRoll,
    cosPitch * cosRoll
    ) ;
    return multiply(
    xAxis.getX(),xAxis.getY(),xAxis.getZ(),-xAxis.dot(eye),// X column
    yAxis.getX ,yAxis.getY(),yAxis.getZ(),-yAxis.dot(eye),// Y column
    zAxis.getX(),zAxis.getY(),zAxis.getZ(),-zAxis。 dot(eye),// Z column
    0.0f,0.0f,0.0f,1.0f // W column
    );
    }



    我真的没有线索为什么相机表现如此奇怪,甚至意味着?

    如何使图片的某些部分突然变得不可见?



    更新:使用 viewFPS()方法,因为翻译看起来有点奇怪,有人可以确认吗?

    解决方案

    注意到在 viewFPS 中,您在一个矩阵乘法中结合旋转和平移。



    我不熟悉你建立矩阵的方式,但我可以告诉你对我有用。




    • 创建3个矩阵,一个用于X旋转,Y旋转和Z旋转值。

    • 按所需顺序乘以这些矩阵。 (我使用Z,Y然后X)

    • 将结果与您的翻译矩阵相乘。 (即眼睛的位置)

    • 结果矩阵是您的视图矩阵。



    可能比您使用的方法效率较低,但它是伟大的让它工作,然后从那里优化?



    旋转矩阵我使用:









    其中,(phi)和(psi)是绕X,Y和Z轴的旋转( http://www.fastgraph.com/ makegames / 3drotation /


    I am trying to make a game/demo with Java/LWJGL and having troubles with the first person camera:

    I use the WASD to move the eye vector around, however strange things are happening:

    • When I move the eye away or to me, the right resp. left parts of the view get blocked for my view.
    • When I move the eye to the right or left of me, then the top resp. bottom parts of the view get blocked for my view.

    I have implemented mouse movement (to look around) with success, the relevant pieces of code now:

    (Note: The Matrix4f class works in column-major order)

    Matrix4f viewMatrix = new Matrix4f();
    
    private void checkKeys() {
        if (isKeyCurrentlyDown(Keyboard.KEY_W)) {
            eye.updateTranslate(1.0f, 0.0f, 0.0f);
            updateView();
        }
        else if (isKeyCurrentlyDown(Keyboard.KEY_S)) {
            eye.updateTranslate(-1.0f, 0.0f, 0.0f);
            updateView();
        }
        else if (isKeyCurrentlyDown(Keyboard.KEY_A)) {
            eye.updateTranslate(0.0f, -1.0f, 0.0f);
            updateView();
        }
        else if (isKeyCurrentlyDown(Keyboard.KEY_D)) {
            eye.updateTranslate(0.0f, 1.0f, 0.0f);
            updateView();
        }
    }
    
    private void updateView() {
        System.out.println("eye = " + eye);
        viewMatrix.identity().viewFPS(eye, roll, yaw, pitch);
        System.out.println("viewMatrix = " + viewMatrix);
        Uniforms.setUniformMatrix4(UNIFORM_VIEW_MATRIX, false, viewMatrix);
    }
    
    @Override
    protected void render(final double msDelta) {
        super.render(msDelta);
    
        glClearColor(0.0f, 0.25f, 0.0f, 1.0f);
        glClearDepthf(1f);
        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
        program.use();
    
        for (int i = 0; i < 24; i++) {
            float fVar = i + currentTime / 1000f * 0.3f;
            modelviewMatrix.identity()
                    .translate(0.0f, 0.0f, -8.0f)
                    .rotate(currentTime / 1000f * 45.0f, 0.0f, 1.0f, 0.0f)
                    .rotate(currentTime / 1000f * 21.0f, 1.0f, 0.0f, 0.0f)
                    .translate(
                        (float)Math.sin(2.1f * fVar) * 2.0f,
                        (float)Math.cos(1.7f * fVar) * 2.0f,
                        (float)Math.sin(1.3f * fVar) * (float)Math.cos(1.5f * fVar) * 2.0f
                    );
            Uniforms.setUniformMatrix4(UNIFORM_MODEL_MATRIX, false, modelviewMatrix.writeToFloatBuffer(modelViewMatrixBuffer));
            program.drawElements(GL_TRIANGLES, 36, GL_UNSIGNED_INT, 0);
        }
    }
    


    #version 440 core
    
    layout(location = 0) in vec4 position;
    
    out VS_OUT {
        vec4 color;
    } vs_out;
    
    layout(location = 0) uniform mat4 model_matrix;
    layout(location = 1) uniform mat4 view_matrix;
    layout(location = 2) uniform mat4 proj_matrix;
    
    void main() {
        gl_Position = proj_matrix * view_matrix * model_matrix * position;
        vs_out.color = position * 2.0 + vec4(0.5, 0.5, 0.5, 0.0);
    }
    


    public enum UniformLocation {
        UNIFORM_MODEL_MATRIX(0),
        UNIFORM_VIEW_MATRIX(1),
        UNIFORM_PROJECTION_MATRIX(2)
        ;
    
        private final int location;
    
        private UniformLocation(final int location) {
            this.location = location;
        }
    
        public int getLocation() {
            return this.location;
        }
    }
    


    //Column-major order
    
    public Matrix4f viewFPS(final Vector3f eye, final float rollAngle, final float yawAngle, final float pitchAngle) {
        //roll = rolling your head, Q&E
        //yaw = looking left/right, mouseY
        //pitch = looking up/down, mouseX
        float sinRoll = (float)Math.sin(Math.toRadians(rollAngle));
        float cosRoll = (float)Math.cos(Math.toRadians(rollAngle));
        float sinYaw = (float)Math.sin(Math.toRadians(yawAngle));
        float cosYaw = (float)Math.cos(Math.toRadians(yawAngle));
        float sinPitch = (float)Math.sin(Math.toRadians(pitchAngle));
        float cosPitch = (float)Math.cos(Math.toRadians(pitchAngle));
    
        Vector3f xAxis = new Vector3f(
            cosYaw * cosPitch,
            sinYaw * cosPitch,
            -sinPitch
        );
        Vector3f yAxis = new Vector3f(
            cosYaw * sinPitch * sinRoll - sinYaw * cosRoll,
            sinYaw * sinPitch * sinRoll + cosYaw * cosRoll,
            cosPitch * sinRoll
        );
        Vector3f zAxis = new Vector3f(
            cosYaw * sinPitch * cosRoll + sinYaw * sinRoll,
            sinYaw * sinPitch * cosRoll - cosYaw * sinRoll,
            cosPitch * cosRoll
        );
        return multiply(
            xAxis.getX(),   xAxis.getY(),   xAxis.getZ(),   -xAxis.dot(eye),    //X column
            yAxis.getX(),   yAxis.getY(),   yAxis.getZ(),   -yAxis.dot(eye),    //Y column  
            zAxis.getX(),   zAxis.getY(),   zAxis.getZ(),   -zAxis.dot(eye),    //Z column
            0.0f,           0.0f,           0.0f,           1.0f                //W column
        );
    }
    

    I really have no clue why the camera is behaving so weirdly, and what it even means?
    How can parts of the picture suddenly become not visible anymore?

    Update: It might have to do with the viewFPS() method, as the translations look slightly odd there, could someone confirm?

    解决方案

    Noticed that in viewFPS you combine rotation and translation in one matrix multiplication.

    I am not familiar with the way you build the matrix, but I can tell you what works for me.

    • Create 3 matrices, one for X rotation, Y rotation and Z rotation values.
    • Multiply those matrices in the order you want. (I use Z, Y then X)
    • Multiply the result with your translation matrix. (i.e Position of your eye)
    • The resulting matrix is your view matrix.

    This might be less efficient than the method you are using, but it's great to get it working then optimize from there? Splitting up the rotation axies also gives the benefit of being able to debug 1 axis at a time.

    Rotation matrices I use:

    Where , (phi), and (psi) are the rotations around the X, Y and Z axes.(http://www.fastgraph.com/makegames/3drotation/)

    这篇关于第一人称相机奇怪的行为在移动眼睛的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆