我正在开发一个由2个阶段组成的游戏,其中一个具有正投影,另一个阶段具有透视投影。
目前,当我们进入模式之间时,我们会淡入黑色,然后再回到新的相机模式。
我如何在两者之间顺利过渡?
答案 0 :(得分:5)
可能有一些方法可以实现这一点,我发现这两种方式看起来似乎是最好的:
将所有矩阵元素从一个矩阵转换为另一个矩阵。显然,这一切都很好地考虑了所有事情。不过,我不认为这种转变会呈线性。您可以尝试给它一个缓动函数,而不是线性插值
透视矩阵上的dolly zoom来自/接近0视野。您可以从正交矩阵弹出到近0透视矩阵,并将fov渲染到目标,并可能在您去的时候大量调整近/远平面。反过来你会翻到0,然后弹出到正交矩阵。这背后的想法是,事物看起来更平坦,fov越低,0的fov本质上是正交投影。这更复杂,但也可以进行更多调整。
答案 1 :(得分:1)
我设法在没有明确使用矩阵的情况下完成了这项工作。我使用Java所以语法不同但可比较。我使用的一件事就是这个mix()函数。它在value1
为1时返回factor
,在value2
为0时返回factor
,并为其间的每个值都返回线性转换。
private double mix(double value1, double value2, double factor)
{
return (value1 * factor) + (value2 * (1 - factor));
}
当我调用此函数时,我使用value1作为perspective,使用value2作为正交,如下所示:mix(focalLength/voxel.z, orthoZoom, factor)
确定焦距和正交变焦系数时,了解远离相机距离focalLength/orthoZoom
的任何内容在整个过渡过程中都会投射到同一点是有帮助的。
希望这会有所帮助。您可以下载我的程序,了解它在https://github.com/npetrangelo/3rd-Dimension/releases的显示方式。
答案 2 :(得分:1)
如果您可以访问可编程管线(也称为着色器),则可以在顶点着色器中进行过渡。我发现这很好用,并且不会引入工件。这是GLSL代码段:
#version 150
uniform mat4 uModelMatrix;
uniform mat4 uViewMatrix;
uniform mat4 uProjectionMatrix;
uniform float uNearClipPlane = 1.0;
uniform vec2 uPerspToOrtho = vec2( 0.0 );
in vec4 inPosition;
void main( void )
{
// Calculate view space position.
vec4 view = uViewMatrix * uModelMatrix * inPosition;
// Scale x&y to 'undo' perspective projection.
view.x = mix( view.x, view.x * ( -view.z / uNearClipPlane ), uPerspToOrtho.x );
view.y = mix( view.y, view.y * ( -view.z / uNearClipPlane ), uPerspToOrtho.y );
// Output clip space coordinate.
gl_Position = uProjectionMatrix * view;
}
在代码中,uPerspToOrtho
是vec2
(例如float2
),其中包含[0..1]范围内的值。设置为0时,坐标将使用透视投影(假设投影矩阵是透视图)。设置为1时,坐标的行为就像正投影投影矩阵一样。您可以分别为X轴和Y轴执行此操作。
'uNearClipPlane'是近平面距离,这是您用来创建透视投影矩阵的值。
将其转换为HLSL时,您可能需要使用view.z
而不是-view.z
,但是我可能是错的。
我希望您觉得这有用。
编辑:您也可以从投影矩阵中提取它,而不用传递接近剪辑平面的距离。对于OpenGL,这是这样的:
float zNear = 2.0 * uProjectionMatrix[3][2] / ( 2.0 * uProjectionMatrix[2][2] - 2.0 );
编辑2:您可以通过同时缩放x和y来优化代码:
view.xy = mix( view.xy, view.xy * ( -view.z / uNearClipPlane ), uPerspToOrtho.xy );
要摆脱除法,可以乘以反近平面距离:
uniform float uInvNearClipPlane; // = 1.0 / zNear