Get FSceneView for Inactive Camera

There is a lot of code in github that uses this way of grabbing the FSceneView of the viewport:

FSceneViewFamilyContext ViewFamily(FSceneViewFamily::ConstructionValues(
		LocalPlayer->ViewportClient->Viewport,
		GetWorld()->Scene,
		LocalPlayer->ViewportClient->EngineShowFlags)
		.SetRealtimeUpdate(true));

	FVector ViewLocation;
	FRotator ViewRotation;
	FSceneView* sceneView = LocalPlayer->CalcSceneView(&ViewFamily, /*out*/ ViewLocation, /*out*/ ViewRotation, LocalPlayer->ViewportClient->Viewport);

I have the need to get the FSceneView for an inactive camera so that I can perform projections on it. However I can’t find anyway to get render targets from my camera. Is this possible? All I need is to project from world space to the local camera space and also the ViewRect of the camera view.

Hi! did you get that one solved? similar issue here so would be glad to hear how you do that!

Even if this question is old, I will post a solution I used, for anyone who might be interested in future. :wink:

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 USceneCaptureComponent2Ds 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);

}