我希望将物体永久保持在离相机一定距离的位置。我怎么能做到这一点?我试过这个:
vec3 obj_pos = -cam->Get_CameraPos() ;
obj_pos .z -= 10.0f ;
...
o_modelMatrix = glm::translate(o_modelMatrix, obj_pos);
但它不起作用;物体只是站在确定的位置而不是移动
完整的渲染代码:
void MasterRenderer::renderPlane() {
PlaneShader->useShaderProgram();
glm::mat4 o_modelMatrix;
glm::mat4 o_view = cam->Get_ViewMatrix();
glm::mat4 o_projection = glm::perspective(static_cast<GLfloat>(glm::radians(cam->Get_fov())),
static_cast<GLfloat>(WIDTH) / static_cast<GLfloat>(HEIGHT), 0.1f, 1000.0f);
glUniformMatrix4fv(glGetUniformLocation(PlaneShader->ShaderProgramID, "projection"), 1, GL_FALSE, glm::value_ptr(o_projection ));
glUniformMatrix4fv(glGetUniformLocation(PlaneShader->ShaderProgramID, "view"), 1, GL_FALSE, glm::value_ptr(o_view ));
vec3 eye_pos = vec3(o_view [3][0], o_view [3][1], o_view [3][2]); //or cam->getCameraPosition();
glm::vec3 losDirection = glm::normalize(vec3(0.0f, 0.0f, -1.0f) - eye_pos);
vec3 obj_pos = eye_pos + losDirection * 1.0f;
b_modelMatrix = scale(o_modelMatrix, vec3(20.0f));
b_modelMatrix = glm::translate(b_modelMatrix, obj_pos );
glUniformMatrix4fv(glGetUniformLocation(PlaneShader->ShaderProgramID,
"model"), 1, GL_FALSE, glm::value_ptr(o_modelMatrix));
...
/// draw
答案 0 :(得分:0)
也许这是从臀部拍摄的,但我想你设置了一个 lookat 矩阵,并且你的对象位置是用世界坐标定义的。
通常,相机由眼睛位置,目标(中心)位置和向上矢量定义。 相机的外观方向是视线,即从眼睛位置到目标位置的单位矢量。
计算视线:
glm::vec3 cameraPosition ...; // the eye position
glm::vec3 cameraTarget ...; // the traget (center) posiiton
glm::vec3 losDirection = glm::normalize( cameraTarget - cameraPosition );
可能相机类知道视线方向(视线),然后你可以跳过这个计算。
如果物体总是放在相机前面一定距离,物体的位置就是相机的位置加上视线方向的距离:
float distance = ...;
float objectPosition = cameraPosition + losDirection * distance;
glm::mat4 modelPosMat = glm::translate( glm::mat4(1.0f) , objectPosition );
glm::mat4 objectModelMat = ...; // initial model matrix of the object
o_modelMatrix = modelPosMat * objectModelMat;
注意,如果对象没有进一步的转换objectModelMat
,glm::mat4(1.0f)
是单位矩阵。
答案 1 :(得分:0)
所以你想用相机移动物体(而不是用相机跟随物体移动相机)。如果这仅适用于某些 GUI 内容,则可以使用不同的静态视图矩阵。但是如果你想以你建议的方式做到这一点,那就是这样:
<强>定义强>
首先,我们需要很少3D 4x4 homogenuous transform matrices(阅读链接以了解如何消除/构建您需要的内容)。因此,我们为此定义一些矩阵:
C
- 逆相机矩阵(无投影)M
- 直接对象矩阵R
- 直接对象旋转每个矩阵有4个向量X,Y,Z
是由它表示的坐标系的轴,O
是原点。直接矩阵表示矩阵直接表示坐标系,反函数表示它是这种矩阵的逆矩阵。
<强>数学强>
所以我们要构建M
,以便它在d
前面的某个距离C
处直接放置并且具有轮换R
。我假设您正在使用透视投影,而C
查看方向是-Z
轴。所以你需要做的是计算M
的位置。你很容易做到这一点:
iC = inverse(C); // get the direct matrix of camera
M = R; // set rotation of object
M.O = iC.O - d*iC.Z; // set position of object
M.O = (M[12],M[13],M[14])
和iC.Z = (iC.Z[8],iC.Z[9],iC.Z[10])
因此,如果您可以直接访问矩阵,则可以自行执行此操作,以防 GLM 无法提供元素访问。
请注意,所有这些都适用于标准的 OpenGL 矩阵约定和乘法顺序。如果您使用 DirectX 约定,则M,R
是反向的,而C
是直接矩阵,因此您需要相应地更改等式。抱歉,我不使用 GLM ,因此我无法为您生成任何代码。
如果您想在对象旋转上应用相机旋转,则需要将{
M = R
更改为M = R*iC
或M = iC*R
< br />取决于你想要达到的效果。
答案 2 :(得分:0)
没有乘法就可以正常工作,但是补充
obj_pos = glm::normalize(glm::cross(vec3(0.0f, 0.0f, -1.0f), vec3(0.0f, 1.0f, 0.0f)));
o_modelMatrix[3][0] = camera_pos.x;
o_modelMatrix[3][1] = camera_pos.y;
o_modelMatrix[3][2] = camera_pos.z + distance;
o_modelMatrix = glm::translate(o_modelMatrix, obj_pos);