[CG] Lookat矩阵
Lookat矩阵
在三维游戏引擎中,需要摄像机看向某个点,或者需要物体看向某个点,此时需要对物体的变换,以调整到我们需要的姿态。以Unity为例,Unity的坐标系是左手系,朝上的轴是y轴(up,绿色),朝前的轴是z轴(foward,蓝色),朝右的轴是x轴(right,红色)。现在我们想让foward看像某个点,需要对物体进行位姿的变换,那应该怎么做呢?
我们需要提供两个变量,target目标点,up可以理解为世界坐标下的朝上的方向,一般为(0,1,0)
- foward:用target - position并归一化。
- right:用 up 和求得的 foward 叉乘,cross(up,foward)
- up:用求得的 foward 和 求得的 right 叉乘,cross(foward, right)
为了验证正确性,用自己实现的函数和Unity提供的Lookat函数比较。
注意:这里为了方便,认为物体的局部坐标就是世界坐标(物体没有父节点),没有考虑缩放,认为缩放系数都为1.
//物体的位置, 目标点,朝上的方向
Matrix4x4 m_lookat(Vector3 pos,Vector3 target, Vector3 up)
{
Vector3 foward = (target - pos).normalized;
//注意叉乘的顺序,左手系满足左手定理,来判断向量的朝向
Vector3 right = Vector3.Cross(up, foward).normalized;
Vector3 newUp = Vector3.Cross(foward, right).normalized;
Matrix4x4 lookat = Matrix4x4.identity;
//将结果拷贝的新的矩阵上
lookat.SetColumn(0, new Vector4(right.x,right.y, right.z,0));
lookat.SetColumn(1, new Vector4(newUp.x, newUp.y, newUp.z, 0));
lookat.SetColumn(2, new Vector4(foward.x, foward.y, foward.z, 0));
lookat.SetColumn(3, new Vector4(pos.x, pos.y, pos.z, 1));
return lookat;
}
可以获取unity的物体的transofrm的localToWorldMatrix,得到物体的世界矩阵,因为物体没有父节点,所以local和world相等。然后再利用自定义的函数手动计算lookat矩阵,判断是否相等,结果证明相等(在无缩放和父节点的前提下)。
作者:芒果和小猫
出处:https://www.cnblogs.com/WAoyu/p/14715529.html
版权:本作品采用「署名-非商业性使用-相同方式共享 4.0 国际」许可协议进行许可。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 单元测试从入门到精通
· 上周热点回顾(3.3-3.9)
· winform 绘制太阳,地球,月球 运作规律