Even if this question is old, I will post a solution I used, for anyone who might be interested in future. 
I used a USceneCaptureComponent2D
. If you want to place an camera actor in unreal, you can use the Scene Capture 2D, which has this component as a public variable.
Even if, to my knowledge, you cant create an FSceneView
directly from this class, you can use the static methods from the FSceneView
class for projection and deprojection.
The main issue with this is getting the right View Projection Matrix in both cases. There is some strange code in the LocalPlayer
class, which is only understandable, if the camera projection is using another coordinate system than the usual unreal one.
So let´s get to the solution I found:
- Create a
FMinimalViewInfo
using your USceneCaptureComponent2D
s attributes.
- Create a
FSceneViewProjectionData
and fill it with attributes. There you also have to apply the conversion to another coordinate system.
- Use the
ComputeViewProjectionMatrix()
method to get the Projection Matrix
- I´m currently not quit shure which matrix you have to invert, to get the InvViewProjMatrix used in
FSceneView::DeprojectWorldToScreen
Here is a code snippet which encapsulates the projection, at least for perspective mode:
bool UMyFunctionLibrary::ProjectWorldToScreen(USceneCaptureComponent2D * RenderComponent, FVector PointIn, FVector2D& PixelOut)
{
UTextureRenderTarget2D* RenderTexture = RenderComponent->TextureTarget;
// initialise Viewinfo for projection matrix
FMinimalViewInfo Info;
Info.Location = RenderComponent->GetComponentTransform().GetLocation();
Info.Rotation = RenderComponent->GetComponentTransform().GetRotation().Rotator();
Info.FOV = RenderComponent->FOVAngle;
Info.ProjectionMode = RenderComponent->ProjectionType;
Info.AspectRatio = float(RenderTexture->SizeX) / float(RenderTexture->SizeY);
Info.OrthoNearClipPlane = 1; // not quit shure where to get this...
Info.OrthoFarClipPlane = 1000;
Info.bConstrainAspectRatio = true;
FIntRect ScreenRect(0, 0, RenderTexture->SizeX, RenderTexture->SizeY);
// initialize projection data for sceneview
FSceneViewProjectionData ProjectionData;
ProjectionData.ViewOrigin = Info.Location;
// do some voodoo rotation that is somehow mandatory
ProjectionData.ViewRotationMatrix = FInverseRotationMatrix(Info.Rotation) * FMatrix(
FPlane(0, 0, 1, 0),
FPlane(1, 0, 0, 0),
FPlane(0, 1, 0, 0),
FPlane(0, 0, 0, 1));
if (RenderComponent->bUseCustomProjectionMatrix == true) {
ProjectionData.ProjectionMatrix = RenderComponent->CustomProjectionMatrix;
}
else {
ProjectionData.ProjectionMatrix = Info.CalculateProjectionMatrix();
}
ProjectionData.SetConstrainedViewRectangle(ScreenRect);
// Project Points to pixels
return FSceneView::ProjectWorldToScreen(PointIn, ScreenRect, ProjectionData.ComputeViewProjectionMatrix(), PixelOut);
}