相机计算坐标公式_定制相机解算公式

本文探讨了相机解算的理论与实践,重点介绍了如何利用数学模型和计算公式来定制相机坐标。通过分析Cinemachine的屏幕空间计算方案,提出在特定场景下,直接正向求解的思路,简化了复杂镜头的实现。文章提供了相应的代码示例,展示了如何计算相机位置和旋转,以满足特定的屏幕空间布局需求。
摘要由CSDN通过智能技术生成

这两周抽空看了下Cinemachine的屏幕空间计算方案。顺便看到了几篇关于相机解算的论文,对问题的观察角度和量化思路都非常有意思。Camera Motion Graphs​diglib.eg.org

在工业环境下,Cinemachine用的那套基于变化插值和阻尼調整的屏幕空间计算确实是银弹。算法思路本质上不依附于任何对相机需求的数学模型和变量设置,只要需求的目标是连续性且有方向性的,就可以通过逐帧检查和趋近最终求解画面。阻尼设置可以在拟合速度和拟合精度上做调整取舍,理论如此,但相机画面的动态性,或者说大多数需求对手持感并不算是能敏锐感知到的错误,就算出现了一时一刻,甚至是稳定的计算错误,其实也不会引起太多非难,这可是银弹。

只要需求是有方向性的,函数连续性没有太多的极值变化,校验配置就直接按需求写。Cinemachine自带的模块就是标准的死区-缓冲区模型,还带解算偏移,已经比大部分项目程序员死死盯着Transform的方案要标准许多,那等价于数值全为0的死区模型。

既然有银弹方案,自然也有定死需求的方案,当然我说的不是那些连数学模型都不建,只是写LookAt的代码。去年在复读育碧和巫师3的CinematicDialogue方案的时候,就特别说过参数化的相机,不过他们解算变量的方式是如Cinemachine这样还是定解算公式,我不得而知。最近所有思考都只是我闭门造车的内容,这块东西比起时下热门,在国内随处可见的各种图程模板方案,真的是不算好找。

大概模板还是巫师3和ACO,其实他俩的思路都是一样的,半身特写,道具特写,越肩特写。

控制变量稍微多一点的越肩特写,其实也不是特别完美(我在项目落地失败后才发现的),像下图所示的这个镜头,为了达到1.白狼在画面左侧边缘,2.对方在画面黄金比位置,3.白狼越肩,4.对方半身像,fov已经压的过小,地面的植被完全压到镜头背景上。

当你为这个画面需求建立一个解算视锥空间的数学模型的时候,能很清楚的发现,对方的半身高度和白狼的肩头高度差和双方的距离,约束了视锥空间的张角大小;距离越远,fov越小,这个数值范围甚至在双方距离1米的时候,已经要求fov在20左右的范围。

这种被两个屏幕空间计算约束的画面,完全不能顾及物理相机的经验配置;如果要考虑视距光圈等物理配置,需要放弃前景或者背景角色的一个维度的约束。对此我尝试过几种参数化方案,虽然各有利弊,不过模型和计算公式都没有多少变化区别。

设计得比较好的量化方案,不需要过多拆分变量等式,直接用配置变量一步步带入计算即可。效果如下(fov32)。

这个就是基本放弃背景角色屏幕空间计算的版本,公式可以写的非常简单。话虽这么说,其实也是我蒙了好久等式计算才发现可以直接正向求解的,公式和对应的图解如下。

void Calculate(Camera c)

{

var hf = c.fieldOfView / 2;

// Hf = dce var tanHf = Mathf.Tan(hf * Mathf.Deg2Rad);

// R = acb var tanR = tanHf * c.aspect * (compositionX * 2 - 1);

var ec = positionY / tanHf;

var ae = ec * tanR;

var ab = Vector3.Distance(ft, bt);

var be = Mathf.Sqrt(ab * ab - ae * ae);

var abc = Mathf.Atan(ae / be) * Mathf.Rad2Deg;

var lookCenter = bt + Quaternion.Euler(0, abc, 0) * (ft - bt).normalized * (be + ec);

c.transform.position = lookCenter;

c.transform.rotation = Quaternion.LookRotation(bt - lookCenter);

}

比起代码,貌似有人更愿意看文字胡诌,在家里闲的没事干更新一下。这块正向求解的思路基本都是初中构建三角形平面解析几何的知识,理解起来非常简单,讲起来就比较枯燥。

如上图所示,

是相机,

是抽象前景角色而来的焦点,在屏幕纵向中割线上,同理

是抽象背景角色而来的焦点,在屏幕纵向中割线上。过点

垂线得垂足

向正下方做线段和相机视锥空间交得

在正向求解的公式里,我们开放配置相机fov,即

,点

坐标,线段

的长度,

和相机在E点深度上的横向宽度比(

),由此求点

的坐标。这里用了一次三角函数。

是屏幕长宽比,Unity的fov是纵向角度需要乘,Unreal是横向的就不需要。

是输入变量

在直角三角形

,勾股定理用

会有不满足建模的情况,这里要有一定的容错缓冲手段。

这里用了一次反三角函数

向量

归一化,旋转

再放大

长度,得向量

,加点

即得点

。这里用的空间矩阵计算

因为三点确定一个平面,所以这里有个潜规则是C在BA的水平方向上

的旋转偷懒用Unity现成的接口

因为是直接正向求解,所以相机的旋转并没有多花心思做解算,需要复杂效果的时候,通过修改真实角色位置和A,B的屏幕空间位置关系再代入计算也能满足需求。不过效果复杂了,约束条件的冲突情况也会更多。

如果是项目级别的开发还是强烈推荐直接用Cinemachine的配置方案,程序员不需要承受表现层开发的心智负担,安心搬砖即可,对应的,整个项目的负担也小。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值