簡體   English   中英

如何將相機固定在播放器上,因此當播放器移動時,相機會跟隨

[英]How to fixate the camera on the player, so when the player moves the camera will follow

我正在嘗試用Java制作OpenGL游戲,其中您是一艘太空飛船,並且在3D空間中飛行,目的是消除該關卡中的所有敵方太空飛船。 但是,我似乎無法弄清楚如何使相機固定/跟隨播放器。 我想這樣做,以便我可以使用用戶輸入來移動播放器(又稱太空飛船),並且攝像機也會跟隨,以使播放器不會失明(屏幕外)。

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

(我將用通用代碼而不是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;
}

您可以在所有渲染周期中使用此相機矩陣,並將其傳遞給着色器,例如:

////// 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;

為了使攝像機固定在播放器上,您需要指定要對攝像機應用的偏航和俯仰(旋轉)以及距播放器的距離,然后您可以計算出它們的距離來平移攝像機,以便從那個角度看玩家。

這是一個關於您所要問的精妙教程: https : //youtu.be/PoxDDZmctnU

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM