UE5 RenderTexture鼠标点选

发布时间 2023-11-14 15:57:05作者: 啊循

好久没有记录了,大家好,今天分享一个最近解决的UE方面的功能

情景:
把3维物体渲染到纹理,并在umg中使用Image控件显示纹理。此外还支持鼠标在Image上点击时,选中纹理上对应位置的物体。

思路理解:
在空间中某点某方向,以某视场角观察3维场景,并把画面渲染到纹理上。
在UMG的Image控件显示该纹理,Image以某位置、某尺寸摆放在屏幕上。(这暗示着RenderTexture和Image可能有不同的尺寸和宽高比,但是把它们规范化到0-1就能很好的对应起来)
当鼠标点击时,计算出鼠标位置相对于Image的位置,进而计算出在RenderTexture上的位置,进而计算出在世界坐标系的方向,然后就可以光线投射了。

涉及的技术点:
1、3维物体渲染到纹理。使用UE自带的 USceneCaptureComponent2D 可以做到,和Unity的摆放一个Camera然后设置RenderTexture类似。
2、坐标转换:鼠标在屏幕上的坐标->渲染相机的投影面坐标->世界空间坐标。
3、Trace,也叫Raycast。用上一步计算得到的鼠标点击位置在世界空间中的方向进行光线投射,获取命中的物体。

USceneCaptureComponent2D
这个是专门用来完成渲染到纹理的组件,我们可以创建RenderTarget资产,然后赋值给它的TextureTarget字段,就可以把画面渲染到我们指定的RenderTarget中。
它可以指定 Primitive Render Mode 为 PRM_UseShowOnlyList,这种模式只会渲染列表 ShowOnlyActors 中的Actor。
另外它有各种Show Flags可以控制是否渲染某些特性。
例如想渲染透明背景的话,需取消选择 Atmosphere \ Cloud \ Fog \ Landscape
还有一点值得说的是 Capture Source 属性,它控制写入RenderTarget中的数据的格式,如果是要渲染透明背景的话,选择 SceneColor (HDR) in RGB, Inv Opacity in A的模式,以拿到透明度数据。
提醒:有一个Actor类型叫ASceneCapture2D可以直接在关卡使用,它基本等于Actor + USceneCaptureComponent2D。为了后续使用现成的库函数,推荐直接用它。

Image
Image没有太多可说的,它既可以直接使用RenderTarget,也可以使用材质球。如果按上述的透明背景的设置的话,这时候就需要一个材质球把透明度反向处理一下,因为上面的 Inv Opacity in A,所以需要在材质中1-A才是正常的透明度。
例如:

坐标转换
这里方法是把鼠标位置和Image的矩形框都变换到UMG视口中进行计算。涉及到几个现成的函数:
GetMousePositionOnViewport 获取鼠标在UMG视口中的坐标
GetCachedGeometry 获取UMG Wedget的几何体
LocalToViewport 从Wedget几何体的局部坐标变换到UMG视口坐标中
DeprojectSceneCaptureToWorld 把RenderTarget的uv坐标反投影到世界坐标系中的点和方向。这个函数就需要ASceneCapture2D为参数,因此上面推荐直接用ASceneCapture2D。

光线投射
用Trace系列的函数就可以了,例如使用 LineTraceSingle 查找第一个碰到的Actor