【问题标题】:How to shift Camera view over the display boundry?如何在显示边界上移动相机视图?
【发布时间】:2021-07-10 03:23:38
【问题描述】:

我正在使用 Unity 2020.1.17f1 为 VR 制作简单的演示。

由于显示和光学组件(镜头)的错位问题,我想动态地分别移动左右相机视图而不改变形状。

所以,我尝试通过更改视口矩形的 x 和 y 值来尝试,但是当我尝试在显示上移动图像时它无法正常工作。

例如,如果我尝试将左侧摄像头视图移动到左侧,它会在水平方向上被挤压。同样,如果它试图在垂直方向移动相机视图,它会在垂直方向被挤压。

我预计放置在屏幕外的部分会被裁剪,最后会显示出来。

考虑显示大小为 100*50,每个摄像头视图的大小为 50 * 50。左摄像头视图将从 0、0 到 50,50 绘制,右摄像头视图将从 50,0 到 100 绘制, 50. 我想将左相机视图向左移动 10 个像素。然后,通过在左侧丢失 10 * 50 像素,将左摄像机视图从 0, 0 绘制到 40, 50。因此,将视口矩形的 x 值更改为 -0.2。 但是,左侧摄像头视图的左侧不会过度显示。并且左摄像头视图被压缩了 1o 个像素,使左右摄像头视图之间存在间隙。

介绍很长。

问题很简单。

如何在不改变其形状的情况下将相机视图转移到显示器上?

PS。我可以使用带偏移的 Surface 着色器吗?

PPS。我认为我的代码无法帮助您拯救我,但这是我的代码的一部分。

using System.Collections;
using System.Collections.Generic;
using UnityEngine;


public class CameraController : MonoBehaviour
{    

    public Camera LCam;    
    public Camera RCam;    

    // Start is called before the first frame update
    void Awake()
    {

        LCam = transform.Find("Camera_L").GetComponent<Camera>();
        RCam = transform.Find("Camera_R").GetComponent<Camera>();        

    }

    //variables that counting how much camera view has shifted.
    float L_x_Shift, L_y_Shift, R_x_Shift, R_y_Shift = 0;

    //x, y variables of each camera's viewport.
    public float L_ViewPortx = 0;
    public float L_ViewPorty = 0;
    public float R_ViewPortx = 0.5f;
    public float R_ViewPorty = 0;

    void Update()
    {
       
        // each of u,h,j,k shift left camera view in upward, left, downward, right. 
        if (Input.GetKeyDown(KeyCode.U))
        {
            L_y_Shift += 1;
        }
        else if (Input.GetKeyDown(KeyCode.J))
        {
            L_y_Shift -= 1;
        }
        else if (Input.GetKeyDown(KeyCode.H))
        {
            L_x_Shift -= 1;
        }
        else if (Input.GetKeyDown(KeyCode.K))
        {
            L_x_Shift += 1;
        }
        else { }

        // each numpad 8,4,5,6 shift right camera view in upward, left, downward, right.
        if (Input.GetKeyDown(KeyCode.Keypad8))
        {
            R_y_Shift += 1;
        }
        else if (Input.GetKeyDown(KeyCode.Keypad5))
        {
            R_y_Shift -= 1;
        }
        else if (Input.GetKeyDown(KeyCode.Keypad4))
        {
            R_x_Shift -= 1;
        }
        else if (Input.GetKeyDown(KeyCode.Keypad6))
        {
            R_x_Shift += 1;
        }
        else { }

        // reset left camera view
        if (Input.GetKey(KeyCode.LeftControl) && Input.GetKeyDown(KeyCode.Space))
        {
            L_x_Shift = 0;
            L_y_Shift = 0;
        }
        // reset right camera view.
        else if (Input.GetKey(KeyCode.LeftShift) && Input.GetKeyDown(KeyCode.Space))
        {
            R_x_Shift = 0.5f;
            R_y_Shift = 0;
        }
        else { }
        // Display resolution is 1920 * 2160
        L_ViewPortx = L_x_Shift / 1920;
        L_ViewPorty = L_y_Shift / 2160;
        R_ViewPortx = 0.5f + R_x_Shift / 1920;
        R_ViewPorty = R_y_Shift / 2160;
                
        LCam.rect = new Rect(L_ViewPortx, L_ViewPorty, 0.5f, 1);
        RCam.rect = new Rect(R_ViewPortx, R_ViewPorty, 0.5f, 1);


    }

     
}

【问题讨论】:

  • 怎么样而不是移动矩形而是稍微旋转相机例如5° ?
  • 感谢您的评论@derHugo。但是旋转相机不会有帮助,因为我想要的是移动相机视图显示的位置,而不是移动相机视图显示的位置。很容易,我想要的是当相机视图从显示器上的 10,10 绘制到 100,100 时,通过将相机视图向右移动 10 个像素,让它从显示器上的 20、10 到 110、100 绘制。
  • 所以为了正确理解,您不想移动此相机正在渲染的内容,但您想要的是移动屏幕上渲染输出的绘制位置?
  • 是的。对不起我的英语和表达不好。

标签: c# unity3d camera virtual-reality


【解决方案1】:

您正在寻找的是一个倾斜的相机平截头体,也就是修改相机投影矩阵。幸运的是,在 Unity 中有一种简单的方法:https://docs.unity3d.com/Manual/ObliqueFrustum.html

使用镜头移位设置平截头体倾斜度
启用相机的物理相机属性以显示镜头移位选项。您可以使用它们沿 X 轴和 Y 轴偏移相机的焦点中心,从而最大限度地减少渲染图像的失真。
移动镜头会减小与移动方向相反的一侧的截锥角。例如,当您向上移动镜头时,截锥体底部与相机中心线之间的角度会变小。

【讨论】:

  • 感谢您的评论。我希望它能工作并帮助我,但它没有。我认为这可能是因为我在相机上应用了着色器。我猜你推荐它是因为我提到了镜头显示未对准。如果我在普通相机之前将我的着色器应用到一些额外的滤镜上会非常有帮助(然后我可以移动滤镜,而不是相机视图屏幕。)。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多