Edit:
Revised version of the update. Works with deferred rendering!
void APortal::UpdatePortalView()
{
// Increase current frame count.
currentFrameCount++;
// Get cameras post-processing settings.
portalCapture->PostProcessSettings = portalPawn->camera->PostProcessSettings;
if (isInited == false) {
// Setup clip plane to cut out objects between the camera and the back of the portal.
portalCapture->bEnableClipPlane = true;
portalCapture->bOverride_CustomNearClippingPlane = true;
portalCapture->ClipPlaneNormal = pTargetPortal->portalMesh->GetForwardVector();
portalCapture->ClipPlaneBase = pTargetPortal->portalMesh->GetComponentLocation() - (portalCapture->ClipPlaneNormal * 1.0f);
// Get the Projection Matrix from the players camera view settings.
UPortalPlayer* portalPlayer = Cast<UPortalPlayer>(portalController->GetLocalPlayer());
CHECK_DESTROY(LogPortal, !portalPlayer, "UpdatePortalView: Portal player class couldn't be found in the portal %s.", *GetName());
portalCapture->bUseCustomProjectionMatrix = true;
portalCapture->CustomProjectionMatrix = portalPlayer->GetCameraProjectionMatrix();
portalCapture->bCaptureEveryFrame = false;
portalCapture->bCaptureOnMovement = false;
//portalCapture->bAlwaysPersistRenderingState = true;
isInited = true;
}
// Get reference to player camera.
UCameraComponent* playerCamera = portalPawn->camera;
// Get the position of the main camera transform to the target portal.
if (DotProductCull == true) {
FRotator lookRot = UKismetMathLibrary::FindLookAtRotation(GetActorLocation(), playerCamera->GetComponentLocation());
float dp = FVector::DotProduct(UKismetMathLibrary::Conv_RotatorToVector(lookRot), playerCamera->GetForwardVector());
if (dp > 0) {
//GEngine->AddOnScreenDebugMessage(-1, 1, FColor::Orange, "Skipping " + GetName());
return;
}
}
FVector newCameraLocation = ConvertLocationToPortal(playerCamera->GetComponentLocation(), this, pTargetPortal);
FRotator newCameraRotation = ConvertRotationToPortal(playerCamera->GetComponentRotation(), this, pTargetPortal);
FVector recursiveCamLoc;
FRotator recursiveCamRot;
recursiveCamLoc = newCameraLocation;
recursiveCamRot = newCameraRotation;
// Recurse backwards for the max number of recursions and render to the texture each time overlaying each portal view.
for (int i = recursionAmount; i >= 0; i--)
{
// Update location of the scene capture.
recursiveCamLoc = newCameraLocation;
recursiveCamRot = newCameraRotation;
for (int p = 0; p < i; p++)
{
recursiveCamLoc = ConvertLocationToPortal(recursiveCamLoc, this, pTargetPortal);
recursiveCamRot = ConvertRotationToPortal(recursiveCamRot, this, pTargetPortal);
}
portalCapture->SetWorldLocationAndRotation(recursiveCamLoc, recursiveCamRot);
// Use-full for debugging convert transform to target function on the camera.
if (debugCameraTransform) DrawDebugBox(GetWorld(), recursiveCamLoc, FVector(10.0f), recursiveCamRot.Quaternion(), FColor::Red, false, 0.05f, 0.0f, 2.0f);
// Set portal to not be rendered if its the first recursion event.
// NOTE: Caps off the end so theres no visual glitches.
if (i == recursionAmount) portalMesh->SetVisibility(false);
// Update the portal scene capture to render it to the RT.
//portalCapture->CaptureScene();
FSceneInterface* Scene = GetWorld()->Scene;
portalCapture->UpdateDeferredCaptures(Scene);
portalCapture->CaptureSceneDeferred();
// Set portal to be rendered for next recursion.
if (i == recursionAmount) {
GetWorld()->SendAllEndOfFrameUpdates();
portalMesh->SetVisibility(true);
}
}
}
in header added
UPROPERTY()
bool isInited = false;
The key was sending the update on the first pass so it gets registered !. No more black mirrors in the final (well first really) pass.