当前位置:网站首页>UE5如何将屏幕坐标转为世界坐标和世界方向
UE5如何将屏幕坐标转为世界坐标和世界方向
2022-06-10 13:57:00 【人宅】
哈喽,大家好,一起分享一下关于UE5如何将屏幕坐标转为世界坐标的方法。

屏幕坐标转为世界坐标
在PlayerControoler下找到这个函数: DeprojectScreenPositionToWorld
bool APlayerController::DeprojectScreenPositionToWorld(float ScreenX, float ScreenY, FVector& WorldLocation, FVector& WorldDirection) const;
只要将屏幕位置传进去就可以获取的基于屏幕位置的世界位置和方向。
那它是怎么实现的呢?
bool UGameplayStatics::DeprojectScreenToWorld(APlayerController const* Player, const FVector2D& ScreenPosition, FVector& WorldPosition, FVector& WorldDirection)
{
ULocalPlayer* const LP = Player ? Player->GetLocalPlayer() : nullptr;
if (LP && LP->ViewportClient)
{
// get the projection data
FSceneViewProjectionData ProjectionData;
if (LP->GetProjectionData(LP->ViewportClient->Viewport, eSSP_FULL, /*out*/ ProjectionData))
{
//开始求逆
FMatrix const InvViewProjMatrix = ProjectionData.ComputeViewProjectionMatrix().InverseFast();
FSceneView::DeprojectScreenToWorld(ScreenPosition, ProjectionData.GetConstrainedViewRect(), InvViewProjMatrix, /*out*/ WorldPosition, /*out*/ WorldDirection);
return true;
}
}
// something went wrong, zero things and return false
WorldPosition = FVector::ZeroVector;
WorldDirection = FVector::ZeroVector;
return false;
}
其中的FSceneViewProjectionData是一个关于场景视口的数据描述
// Projection data for a FSceneView
struct FSceneViewProjectionData
{
/** The view origin. */
FVector ViewOrigin;
/** Rotation matrix transforming from world space to view space. */
FMatrix ViewRotationMatrix;
/** UE4 projection matrix projects such that clip space Z=1 is the near plane, and Z=0 is the infinite far plane. */
FMatrix ProjectionMatrix;
protected:
//The unconstrained (no aspect ratio bars applied) view rectangle (also unscaled)
FIntRect ViewRect;
// The constrained view rectangle (identical to UnconstrainedUnscaledViewRect if aspect ratio is not constrained)
FIntRect ConstrainedViewRect;
};
ViewOrigin:是视口的原点
ViewRotationMatrix:是一个旋转矩阵 可以理解为ViewMatrix 只是不包含平移矩阵
ProjectionMatrix:投影矩阵
需要区分的是 ViewMatrix 是把世界点的物体转为视口下的局部坐标,而WorldMatrix是把局部坐标转为世界的坐标。
其中对 VP 进行求逆 希望可以将视口下的点通过这个求逆来转为世界坐标
FMatrix ComputeViewProjectionMatrix() const
{
return FTranslationMatrix(-ViewOrigin) * ViewRotationMatrix * ProjectionMatrix;
}
FMatrix const InvViewProjMatrix = ProjectionData.ComputeViewProjectionMatrix().InverseFast();
当获取了 FSceneViewProjectionData 结构的数据,接下来我们看看 DeprojectScreenToWorld
我们知道射线的公式是

我们现在来看看 DeprojectScreenToWorld 这个函数 里面都干了什么。
我们知道如果将一个局部的模型点从局部空间到屏幕空间,它经历了这些变化
a.通过worldmatrix把模型的局部点转为世界点
b.通过viewmatrix矩阵把点从世界位置转为视口下
c.通过projematrix投影矩阵把视口点转为近剪裁面上的点
d.通过投射除法映射到NDC空间[-1.1]
e.通过半兰伯特手法把[-1.1]映射到[0,1]
f.再和屏幕宽高相乘获得屏幕的位置
如果要实现拾取,那么它将是一个逆的过程,已经知道屏幕位置,怎么求这个屏幕位置对应的世界位置和方向?
这里复习一个矩阵的知识。
如果一个worldmatrix可以把点从局部空间转为世界空间,那么想把这个点从世界空间转为局部空间,只需要对这个worldmatrix求逆就可以了,可以理解逆运算是矩阵的除法。
比如 已知
,现在希望通过500求 100,只需要
就可以得到100。其中 就是5的逆,矩阵也是一样的。
我们来看看UE5是怎么做的:
1.先拿到屏幕坐标
float PixelX = FMath::TruncToFloat(ScreenPos.X);
float PixelY = FMath::TruncToFloat(ScreenPos.Y);
2.拿到坐标后把坐标映射到0-1范围
const float NormalizedX = (PixelX - ViewRect.Min.X) / ((float)ViewRect.Width());
const float NormalizedY = (PixelY - ViewRect.Min.Y) / ((float)ViewRect.Height());
3.将坐标映射到NDC空间[-1,1]
const float ScreenSpaceX = (NormalizedX - 0.5f) * 2.0f;
const float ScreenSpaceY = ((1.0f - NormalizedY) - 0.5f) * 2.0f;
4.射线在投影空间的开始和结尾,其中0.01是近剪裁面,1是远剪裁面
const FVector4 RayStartProjectionSpace = FVector4(ScreenSpaceX, ScreenSpaceY, 1.0f, 1.0f);
const FVector4 RayEndProjectionSpace = FVector4(ScreenSpaceX, ScreenSpaceY, 0.01f, 1.0f);
5.通过前面的VP的逆运算 将裁剪空间的点转为世界空间
const FVector4 HGRayStartWorldSpace = InvViewProjMatrix.TransformFVector4(RayStartProjectionSpace);
const FVector4 HGRayEndWorldSpace = InvViewProjMatrix.TransformFVector4(RayEndProjectionSpace);
FVector RayStartWorldSpace(HGRayStartWorldSpace.X, HGRayStartWorldSpace.Y, HGRayStartWorldSpace.Z);
FVector RayEndWorldSpace(HGRayEndWorldSpace.X, HGRayEndWorldSpace.Y, HGRayEndWorldSpace.Z);
6.将向量除以W以撤消任何投影并获得3-space坐标(可以理解归一到世界的近剪裁面)
if (HGRayStartWorldSpace.W != 0.0f)
{
RayStartWorldSpace /= HGRayStartWorldSpace.W;
}
if (HGRayEndWorldSpace.W != 0.0f)
{
RayEndWorldSpace /= HGRayEndWorldSpace.W;
}
7.拿到方向
const FVector RayDirWorldSpace = (RayEndWorldSpace - RayStartWorldSpace).GetSafeNormal();
8.最终拿到需要的值
out_WorldOrigin = RayStartWorldSpace;
out_WorldDirection = RayDirWorldSpace;
有机会我们再讨论一下射线
那我们现在将这个的思路运用在 自研小引擎中:

边栏推荐
- 【解决】每次加载已经训练好的模型,生成的向量会有不同
- [notes] notes on C language array pointer, structure + two-dimensional array pointer
- Win10 virtual machine download and installation process
- 【技术分析】探讨大世界游戏的制作流程及技术——前期流程篇
- Application analysis of key recording and playing of wt2003h4-16s voice chip
- 智慧校园安全通道及视频监控解决方案
- D:\setup Exe could not find the problem
- 互联网公司研发效能团队为啥必须独立?何时独立?
- Celery 异步调用方法改动记录
- 如何定位游戏发热问题
猜你喜欢

软件智能:aaas系统 度量衡及文法的形式规则
![[note] the environment for setting up get injectedthread script supplemented by shellcode in Windows Security III and its use](/img/b4/f7838a7e12379190e2bc9b869839f0.png)
[note] the environment for setting up get injectedthread script supplemented by shellcode in Windows Security III and its use
![[FAQ] résumé des problèmes courants et des solutions lors de l'utilisation de l'interface API rest du Service de santé sportive](/img/ff/96a0a77795b271bef3a8ade2d646c3.png)
[FAQ] résumé des problèmes courants et des solutions lors de l'utilisation de l'interface API rest du Service de santé sportive

《软件体系结构原理、方法与实践》第二版期末考试复习总结

智慧校园安全通道及视频监控解决方案

【解决】每次加载已经训练好的模型,生成的向量会有不同

【无标题】
![buuctf [PHP]CVE-2019-11043](/img/ba/d97fe48acfd20daa66d47f34d99cf1.png)
buuctf [PHP]CVE-2019-11043
![[untitled]](/img/40/8ce6b9fc0050c9ed5b8b1d05dc3c51.png)
[untitled]

The shortcomings of the "big model" and the strengths of the "knowledge map"
随机推荐
Flutter学习个人总结1
[technical analysis] discuss the production process and technology of big world games - preliminary process
Leetcode-57- insert interval
组装芯片难保竞争优势,痛定思痛的高通终于开始自研核心架构
Markdown sets the font to red
[operation tutorial] how to correctly use the Hikvision demo tool to configure the channel to go online?
2022大厂高频软件测试面试真题(附答案)
Leetcode 829. Sum of continuous integers
「大模型」之所短,「知识图谱」之所长
Microsoft Word 教程,如何在 Word 中更改页边距、创建新闻稿栏?
Flutter Wrap Button bottomNavigationBar学习总结4
SnackBar usage details
[note] the environment for setting up get injectedthread script supplemented by shellcode in Windows Security III and its use
What is the p value of a gene?
[notes] notes on C language array pointer, structure + two-dimensional array pointer
What does the multi cloud management platform CMP mean? Who can explain it clearly
Im instant messaging development: the underlying principle of process killed and app skills to deal with killed
技术分享| 快对讲,全球对讲
[Huang ah code] teacher, I want to choose software development related majors after the college entrance examination. Which direction do you think is better? How to fill in the college entrance examin
五角大楼首次承认资助46个乌生物设施 俄方曾曝只有3个安全