如何将相机固定在播放器上,因此当播放器移动时,相机将跟随

时间:2016-08-05 17:47:01

标签: java opengl 3d lwjgl

我正在尝试在java中制作一个OpenGL游戏,你是一个宇宙飞船,你在3D空间飞行,目的是消除关卡中的所有敌人太空飞船。但是,我似乎无法弄清楚如何使相机固定/跟随播放器。我想这样做,以便我可以使用用户输入移动播放器(AKA:太空飞船),然后摄像机将跟随,这样玩家就不会离开视线(屏幕外)。

注意:我使用的是现代OpenGL。 (着色器......),而不是固定功能管道。

2 个答案:

答案 0 :(得分:2)

(我将在一般代码中解释,而不是Java,但语法很容易翻译) 假设您正在使用Matrix转换 场景中的所有对象都呈现为:

B * M * P,

,同时:

B = Base (or View/Camera) matrix
M = Model (or objects, like the enemies or the player spaceship) matrix
P = Projection matrix

在渲染周期之前的更新周期中,在您更新玩家的太空船模型矩阵之后,相应地更改基本矩阵,例如将摄像机置于太空船后面,首先找到太空船的航向矢量和宇宙飞船的载体:

Vector3 vHeading = shipMatrix * Vector3(0.0,0.0,1.0);
Vector3 vShipUp = shipMatrix * Vector3(0.0,1.0,0.0);

然后创建放置在宇宙飞船后面的相机矩阵,并使用LookAt计算查看宇宙飞船:

/// set the offsets between the camera and the spaceship            ///
float distCameraToShip = 2.0;
float cameraElevation = 2.0;
// find the ship position                                            ///
Vector3 vShipTranslation = shipMatrix.GetTranslation();
/// or Vector3 vShipTranslation = shipMatrix * Vector3(0.0,0.0,0.0); ///

/// calculate the camera transformation                              ///
Vector3 vCameraPos = vShipTranslation - vHeading * distCameraToShip + vShipUp * cameraElevation;

Matrix4x4 cameraMatrix = LookAt(vCameraPos, vShipTranslation, vShipUp);

LookAt实施:

CMatrix4x4 LookAt(Vector3 vEye, Vector3 vObject, Vector3 vUp)
{
Vector3 n = normalize(vEye - vObject);
        Vector3 u = cross(vUp , n);
        Vector3 v = cross(n , u);

        float m[16] = { u[0], v[0], n[0], 0.0f,
            u[1], v[1], n[1], 0.0f,
            u[2], v[2], n[2], 0.0f,
            (u * -1.0 * vEye) ,
            (v * -1.0 * vEye) ,
            (n * -1.0 * vEye),
            1.0f };

return m;
}

您将此相机矩阵用于所有渲染周期并将其传递到着色器ex:

////// Vertex shader ///

/// it is recommended to do the multiplication on the CPU and pass the ModelViewMatrix to the shader, here is just to example ///
uniform mat4 u_BaseMatrix;
uniform mat4 u_ModelMatrix;
uniform mat4 u_ProjectionMatrix;

in vec3 a_VerAttrib;

void main()
{
gl_Position = u_ProjectionMatrix * u_BaseMatrix * u_ModelMatrix * vec4(a_VertAttrib, 1.0);
}

现在你可以开始操作相机并给它各种很酷的插值,比如根据船的速度设置相机和船之间的距离:

float distCameraToShip = 2.0 + pow(shipSpeed,2.0) * 0.1;

你也可以使用时间平滑过滤器给它一个很酷的效果:

/// dt = time diff between updating cycles, or 1/FrameRate ///
float ct = 1.0 / (1.0 + dt);
cameraMatrix = cameraMatrix + (previousCameraMatrix - cameraMatrix) * ct;

答案 1 :(得分:0)

为了让相机固定在播放器上,您需要指定您想要应用于相机的偏航和俯仰(旋转)以及距离播放器一段距离的距离,然后您可以通过计算机将它们移动远距离以平移相机这样你就可以从那个角度看到玩家了。

这是一个精彩的教程,正是您所要求的: https://youtu.be/PoxDDZmctnU