从透视切换到正交保持模型和缩放的相同视图大小
Switching from perspective to orthogonal keeping the same view size of model and zooming
我有 fov
角度 = 60,width
= 640 和 height
= 480 的 window,near
= 0.01 和 far
= 100 个平面,我使用 glm::perspective()
得到投影矩阵
glm::perspective(glm::radians(fov),
width / height,
zNear,
zFar);
效果不错
然后我想将投影类型更改为正交,但我不知道如何正确计算 glm::ortho()
的输入参数。
我尝试了很多方法,但问题是在切换到模型对象的正交投影大小后变成另一个。
让我有一个中心在 (0.5, 0.5, 0.5) 和长度大小为 1 的立方体,相机的 mEye 在 (0.5, 0.5, 3),mTarget 在 (0.5, 0.5, 0.5) 和 mUp ( 0、1、0)。视图矩阵是 glm::lookAt(mEye, mTarget, mUp)
使用透视投影效果很好。 glm::ortho(-width, width, -height, height, zNear, zFar)
我的立方体变成了 window 中心的一个小像素。
我也试过实现这个变体
但结果(几乎)和以前一样。
所以,第一个问题是如何计算正交参数来保存相机object/position的原始视图大小?
此外,使用
进行缩放
auto distance = glm::length(mTarget - mEye)
mEye = mTarget - glm::normalize(mTarget - mEye) * distance;
对正交没有影响。 那么第二个问题就是在正投影的情况下如何实现缩放?
P.s。
我假设我理解正确。模型的比例不取决于深度,但我仍然可以决定相机的位置以正确设置模型的大小并使用缩放。我还认为这是简单而微不足道的任务,例如,在开发 3D-viewer/editor/etc 时。如果不是,请纠正我。
how to compute ortho parameters for saving original view size of object/position of camera?
在正交投影中,3 维场景平行投影到 2 维视口。
这意味着投影在视口上的对象始终具有相同的大小,与其深度(到相机的距离)无关。
透视投影描述了从针孔相机看到的世界中的 3D 点到视口的 2D 点的映射。
这意味着投影在视口上的对象会变小,按其深度。
如果将透视图切换为正交投影,则仅显示 1 个平面中的对象,该平面与 viepwort 平面(平行),并保持其深度。请注意,平面是二维的,没有“深度”。这导致 3 维对象在切换投影时永远不会“看起来”相同。但是二维广告牌可以保持它的大小。
透视投影的深度与尺寸的比例是线性的,可以计算。仅取决于视场角:
float ratio_size_per_depth = atan(glm::radians(fov / 2.0f) * 2.0f;
如果你想建立一个正交投影,它保持一定距离(深度)的大小,那么你必须先定义深度:
例如到目标点的距离:
auto distance = glm::length(mTarget - mEye);
投影可以这样设置:
float aspect = width / height
float size_y = ratio_size_per_depth * distance;
float size_x = ratio_size_per_depth * distance * aspect;
glm::mat4 orthProject = glm::ortho(-size_x, size_x, -size_y, size_y, 0.0f, 2.0f*distance);
how to implement zooming in case of ortho projection?
缩放正交投影的 XY 分量:
glm::mat4 orthProject = glm::ortho(-size_x, size_x, -size_y, size_y, 0.0f, 2.0f*distance);
float orthScale = 2.0f;
orthProject = glm::scale(orthProject, glm::vec3(orthScale, orthScale, 1.0f));
设置 orthScale
的值 > 1.0 用于放大,设置值 < 1.0 用于缩放出。
我有 fov
角度 = 60,width
= 640 和 height
= 480 的 window,near
= 0.01 和 far
= 100 个平面,我使用 glm::perspective()
glm::perspective(glm::radians(fov),
width / height,
zNear,
zFar);
效果不错
然后我想将投影类型更改为正交,但我不知道如何正确计算 glm::ortho()
的输入参数。
我尝试了很多方法,但问题是在切换到模型对象的正交投影大小后变成另一个。
让我有一个中心在 (0.5, 0.5, 0.5) 和长度大小为 1 的立方体,相机的 mEye 在 (0.5, 0.5, 3),mTarget 在 (0.5, 0.5, 0.5) 和 mUp ( 0、1、0)。视图矩阵是 glm::lookAt(mEye, mTarget, mUp)
使用透视投影效果很好。 glm::ortho(-width, width, -height, height, zNear, zFar)
我的立方体变成了 window 中心的一个小像素。
我也试过实现这个变体
所以,第一个问题是如何计算正交参数来保存相机object/position的原始视图大小?
此外,使用
进行缩放auto distance = glm::length(mTarget - mEye)
mEye = mTarget - glm::normalize(mTarget - mEye) * distance;
对正交没有影响。 那么第二个问题就是在正投影的情况下如何实现缩放?
P.s。 我假设我理解正确。模型的比例不取决于深度,但我仍然可以决定相机的位置以正确设置模型的大小并使用缩放。我还认为这是简单而微不足道的任务,例如,在开发 3D-viewer/editor/etc 时。如果不是,请纠正我。
how to compute ortho parameters for saving original view size of object/position of camera?
在正交投影中,3 维场景平行投影到 2 维视口。
这意味着投影在视口上的对象始终具有相同的大小,与其深度(到相机的距离)无关。
透视投影描述了从针孔相机看到的世界中的 3D 点到视口的 2D 点的映射。
这意味着投影在视口上的对象会变小,按其深度。
如果将透视图切换为正交投影,则仅显示 1 个平面中的对象,该平面与 viepwort 平面(平行),并保持其深度。请注意,平面是二维的,没有“深度”。这导致 3 维对象在切换投影时永远不会“看起来”相同。但是二维广告牌可以保持它的大小。
透视投影的深度与尺寸的比例是线性的,可以计算。仅取决于视场角:
float ratio_size_per_depth = atan(glm::radians(fov / 2.0f) * 2.0f;
如果你想建立一个正交投影,它保持一定距离(深度)的大小,那么你必须先定义深度:
例如到目标点的距离:
auto distance = glm::length(mTarget - mEye);
投影可以这样设置:
float aspect = width / height
float size_y = ratio_size_per_depth * distance;
float size_x = ratio_size_per_depth * distance * aspect;
glm::mat4 orthProject = glm::ortho(-size_x, size_x, -size_y, size_y, 0.0f, 2.0f*distance);
how to implement zooming in case of ortho projection?
缩放正交投影的 XY 分量:
glm::mat4 orthProject = glm::ortho(-size_x, size_x, -size_y, size_y, 0.0f, 2.0f*distance);
float orthScale = 2.0f;
orthProject = glm::scale(orthProject, glm::vec3(orthScale, orthScale, 1.0f));
设置 orthScale
的值 > 1.0 用于放大,设置值 < 1.0 用于缩放出。