从透视到正交投影
From perspective to orthographic projections
我正在尝试将相机投影从透视更改为正交。
目前我的代码在透视投影下工作正常
m_prespective = glm::perspective(70.0f, (float)DISPLAY_WIDTH / (float)DISPLAY_HEIGHT, 0.01f, 1000.0f);
m_position = glm::vec3(mesh.centre.x, mesh.centre.y, -mesh.radius);
m_forward = centre;
m_up = glm::vec3(0.0f, 1.0f, 0.0f);
return m_prespective * glm::lookAt(m_position, m_forward, m_up);
但是一旦我将其更改为正交投影,我就再也看不到我的网格了。
m_ortho = glm::ortho(0.0f, (float)DISPLAY_WIDTH, (float)DISPLAY_HEIGHT,5.0f, 0.01f, 1000.0f);
m_position = glm::vec3(mesh.centre.x, mesh.centre.y, -mesh.radius);
m_forward = centre;
m_up = glm::vec3(0.0f, 1.0f, 0.0f);
return m_ortho * glm::lookAt(m_position, m_forward, m_up);
我不明白我做错了什么。
在透视投影中,术语(float)DISPLAY_WIDTH / (float)DISPLAY_HEIGHT
评估图片的纵横比。这个数字将接近1。透视投影的近平面的左右裁剪平面距离为aspect * near_distance
。更有趣的是在观看距离左右的范围,在你的情况下是 abs(m_position.z)= abs(mesh.radius)
.
将此应用于正交投影,左、右、上和下裁剪平面距离应具有相同的数量级,因此鉴于纵横比接近 1,左、右、下和上的值应接近 abs(mesh.radius)
的值。除了纵横比之外,显示器的分辨率(以像素为单位)完全无关紧要。
此外,当使用透视投影时,near
的值应选择得尽可能大,以便所有所需的几何图形都可见。否则会浪费宝贵的深度缓冲区分辨率。
float const view_distance = mesh.radius + 1;
float const aspect = (float)DISPLAY_WIDTH / (float)DISPLAY_HEIGHT;
switch( typeof_projection ){
case perspective:
m_projection = glm::perspective(70.0f, aspect, 1.f, 1000.0f);
break;
case ortho:
m_projection = glm::ortho(
-aspect * view_distance,
aspect * view_distance,
view_distance,
view_distance,
-1000, 1000 );
break;
}
m_position = glm::vec3(mesh.centre.x, mesh.centre.y, -view_distance);
m_forward = centre;
m_up = glm::vec3(0.0f, 1.0f, 0.0f);
return m_projection * glm::lookAt(m_position, m_forward, m_up);
我正在尝试将相机投影从透视更改为正交。 目前我的代码在透视投影下工作正常
m_prespective = glm::perspective(70.0f, (float)DISPLAY_WIDTH / (float)DISPLAY_HEIGHT, 0.01f, 1000.0f);
m_position = glm::vec3(mesh.centre.x, mesh.centre.y, -mesh.radius);
m_forward = centre;
m_up = glm::vec3(0.0f, 1.0f, 0.0f);
return m_prespective * glm::lookAt(m_position, m_forward, m_up);
但是一旦我将其更改为正交投影,我就再也看不到我的网格了。
m_ortho = glm::ortho(0.0f, (float)DISPLAY_WIDTH, (float)DISPLAY_HEIGHT,5.0f, 0.01f, 1000.0f);
m_position = glm::vec3(mesh.centre.x, mesh.centre.y, -mesh.radius);
m_forward = centre;
m_up = glm::vec3(0.0f, 1.0f, 0.0f);
return m_ortho * glm::lookAt(m_position, m_forward, m_up);
我不明白我做错了什么。
在透视投影中,术语(float)DISPLAY_WIDTH / (float)DISPLAY_HEIGHT
评估图片的纵横比。这个数字将接近1。透视投影的近平面的左右裁剪平面距离为aspect * near_distance
。更有趣的是在观看距离左右的范围,在你的情况下是 abs(m_position.z)= abs(mesh.radius)
.
将此应用于正交投影,左、右、上和下裁剪平面距离应具有相同的数量级,因此鉴于纵横比接近 1,左、右、下和上的值应接近 abs(mesh.radius)
的值。除了纵横比之外,显示器的分辨率(以像素为单位)完全无关紧要。
此外,当使用透视投影时,near
的值应选择得尽可能大,以便所有所需的几何图形都可见。否则会浪费宝贵的深度缓冲区分辨率。
float const view_distance = mesh.radius + 1;
float const aspect = (float)DISPLAY_WIDTH / (float)DISPLAY_HEIGHT;
switch( typeof_projection ){
case perspective:
m_projection = glm::perspective(70.0f, aspect, 1.f, 1000.0f);
break;
case ortho:
m_projection = glm::ortho(
-aspect * view_distance,
aspect * view_distance,
view_distance,
view_distance,
-1000, 1000 );
break;
}
m_position = glm::vec3(mesh.centre.x, mesh.centre.y, -view_distance);
m_forward = centre;
m_up = glm::vec3(0.0f, 1.0f, 0.0f);
return m_projection * glm::lookAt(m_position, m_forward, m_up);