【问题标题】:Unity3d, Focus Cam in a rect using project matrix.Unity3d,使用项目矩阵的矩形焦点凸轮。
【发布时间】:2017-06-13 09:16:18
【问题描述】:

所以我正在做这个项目,这需要我的相机查看并且只查看一个矩形区域。因此,无论相机如何移动,用户都无法看到盒子外面。我在下面附上了这张图片来解释我的话。 我浏览了 Unity Camera API,但没有发现任何有用的东西,任何建议都将不胜感激。

编辑: 原来使用投影矩阵的矩形对焦相机是一种物理上更准确的方法,但我不知道如何。

【问题讨论】:

  • "所以不管相机怎么移动,用户永远看不到盒子外面" 除非你在相机移动的时候改变投影参数,你问的基本上是不可能的,如果你改变投影参数只显示指定区域,它会扭曲视图,我认为这不是你想要的......
  • 当然,除非您创建一个非常大的盒子并将相机放在盒子内。
  • 这不是“不可能”。您需要做的就是改变焦距。随着相机移开,增加 FL,产生远摄效果。当你搬进来时,减少 FL。如果您真的很担心,请创建剪切平面
  • 您希望您的相机始终注视框的中心,无论相机位置如何
  • 这可能会有所帮助:wiki.unity3d.com/index.php/MirrorReflection3(尤其是倒数第二个函数)

标签: c# unity3d camera


【解决方案1】:

感谢 Samy Bencherif 提供资源。

这里的代码有一个类似的功能应该可以完成这项工作,一旦有时间,我会做更多的研究并发布更完整的解决方案。

http://wiki.unity3d.com/index.php/MirrorReflection4

编辑

我在这里找到了我的解决方案。作者:hpJohn 在 Unity 论坛中:

public Transform[] Corners;
public Transform lookTarget;
public bool drawNearCone, drawFrustum;

Camera theCam;

void Start () {
    theCam = camera;
}

void Update () {
    Vector3 pa, pb, pc, pd;
    pa = Corners[0].position; //Bottom-Left
    pb = Corners[1].position; //Bottom-Right
    pc = Corners[2].position; //Top-Left
    pd = Corners[3].position; //Top-Right

    Vector3 pe = theCam.transform.position;// eye position

    Vector3 vr = ( pb - pa ).normalized; // right axis of screen
    Vector3 vu = ( pc - pa ).normalized; // up axis of screen
    Vector3 vn = Vector3.Cross( vr, vu ).normalized; // normal vector of screen

    Vector3 va = pa - pe; // from pe to pa
    Vector3 vb = pb - pe; // from pe to pb
    Vector3 vc = pc - pe; // from pe to pc
    Vector3 vd = pd - pe; // from pe to pd

    float n = -lookTarget.InverseTransformPoint( theCam.transform.position ).z; // distance to the near clip plane (screen)
    float f = theCam.farClipPlane; // distance of far clipping plane
    float d = Vector3.Dot( va, vn ); // distance from eye to screen
    float l = Vector3.Dot( vr, va ) * n / d; // distance to left screen edge from the 'center'
    float r = Vector3.Dot( vr, vb ) * n / d; // distance to right screen edge from 'center'
    float b = Vector3.Dot( vu, va ) * n / d; // distance to bottom screen edge from 'center'
    float t = Vector3.Dot( vu, vc ) * n / d; // distance to top screen edge from 'center'

    Matrix4x4 p = new Matrix4x4(); // Projection matrix
    p[0, 0] = 2.0f * n / ( r - l );
    p[0, 2] = ( r + l ) / ( r - l );
    p[1, 1] = 2.0f * n / ( t - b );
    p[1, 2] = ( t + b ) / ( t - b );
    p[2, 2] = ( f + n ) / ( n - f );
    p[2, 3] = 2.0f * f * n / ( n - f );
    p[3, 2] = -1.0f;

    theCam.projectionMatrix = p; // Assign matrix to camera

    if ( drawNearCone ) { //Draw lines from the camera to the corners f the screen
        Debug.DrawRay( theCam.transform.position, va, Color.blue );
        Debug.DrawRay( theCam.transform.position, vb, Color.blue );
        Debug.DrawRay( theCam.transform.position, vc, Color.blue );
        Debug.DrawRay( theCam.transform.position, vd, Color.blue );
    }

    if ( drawFrustum ) DrawFrustum( theCam ); //Draw actual camera frustum

}

Vector3 ThreePlaneIntersection ( Plane p1, Plane p2, Plane p3 ) { //get the intersection point of 3 planes
    return ( ( -p1.distance * Vector3.Cross( p2.normal, p3.normal ) ) +
            ( -p2.distance * Vector3.Cross( p3.normal, p1.normal ) ) +
            ( -p3.distance * Vector3.Cross( p1.normal, p2.normal ) ) ) /
        ( Vector3.Dot( p1.normal, Vector3.Cross( p2.normal, p3.normal ) ) );
}

void DrawFrustum ( Camera cam ) {
    Vector3[] nearCorners = new Vector3[4]; //Approx'd nearplane corners
    Vector3[] farCorners = new Vector3[4]; //Approx'd farplane corners
    Plane[] camPlanes = GeometryUtility.CalculateFrustumPlanes( cam ); //get planes from matrix
    Plane temp = camPlanes[1]; camPlanes[1] = camPlanes[2]; camPlanes[2] = temp; //swap [1] and [2] so the order is better for the loop

    for ( int i = 0; i < 4; i++ ) {
        nearCorners[i] = ThreePlaneIntersection( camPlanes[4], camPlanes[i], camPlanes[( i + 1 ) % 4] ); //near corners on the created projection matrix
        farCorners[i] = ThreePlaneIntersection( camPlanes[5], camPlanes[i], camPlanes[( i + 1 ) % 4] ); //far corners on the created projection matrix
    }

    for ( int i = 0; i < 4; i++ ) {
        Debug.DrawLine( nearCorners[i], nearCorners[( i + 1 ) % 4], Color.red, Time.deltaTime, false ); //near corners on the created projection matrix
        Debug.DrawLine( farCorners[i], farCorners[( i + 1 ) % 4], Color.red, Time.deltaTime, false ); //far corners on the created projection matrix
        Debug.DrawLine( nearCorners[i], farCorners[i], Color.red, Time.deltaTime, false ); //sides of the created projection matrix
    }
}

【讨论】:

    猜你喜欢
    • 2020-03-10
    • 2014-05-04
    • 1970-01-01
    • 2019-05-16
    • 1970-01-01
    • 1970-01-01
    • 2020-12-05
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多