13#include <util/ue-header-guard-begin.h>
14#include "Engine/Engine.h"
15#include "RenderGraphBuilder.h"
16#include "RenderGraphUtils.h"
17#include "HAL/IConsoleManager.h"
18#include "Kismet/KismetSystemLibrary.h"
19#include <util/ue-header-guard-end.h>
27 TEXT(
"Carla.WideAngleLens.DumpAllFrames"),
29 TEXT(
"If enabled, saves all frames of all *_WideAngleLens sensors to disk.\n")
31 TEXT(
"1: Enabled\n"));
34 TEXT(
"Carla.WideAngleLens.DumpAllFramesPath"),
36 TEXT(
"Sets the destination path when saving frames via \"Carla.WideAngleLens.DumpAllFrames\".\n"));
39 TEXT(
"Carla.WideAngleLens.DumpAllFrames.Cubemap"),
41 TEXT(
"If enabled, saves each individual face of each *_WideAngleLens sensor.\n")
43 TEXT(
"1: Enabled\n"));
46 TEXT(
"Carla.WideAngleLens.SkipVFTR"),
48 TEXT(
"If enabled, *_WideAngleLens sensors do not toggle r.VolumetricFog.TemporalReprojection when rendering.\n")
50 TEXT(
"1: Enabled\n"));
70 Super(ObjectInitializer),
73 CaptureRenderTarget(),
78 KannalaBrandtCameraCoefficients
82 0.008587261043925865F,
83 0.0008542188930970716F
86 LensThetaMax(PI * 0.5F),
87 LensIntrinsics(0.0F, 0.0F, 0.5F, 0.5F),
89 XFOVAngle(VerticalToHorizontal(YFOVAngle)),
95 KannalaBrandtCameraCoefficients)),
100 bUseRayTracing(
true),
101 bEnablePostProcessingEffects(
true),
102 bEnable16BitFormat(
false),
103 bRenderPerspective(
false),
104 bRenderEquirectangular(
false),
105 bFOVMaskEnable(
false),
106 bExplicitIntrinsics(
false)
108 FaceCaptures.SetNum(6);
109 FaceRenderTargets.SetNum(6);
115 CubemapRenderMask = ComputeCubemapRenderMask();
117 PrimaryActorTick.bCanEverTick =
true;
118 PrimaryActorTick.TickGroup = TG_PrePhysics;
120 using ProjectionMatrixType = std::conditional_t<
121 (bool)ERHIZBuffer::IsInverted,
122 FReversedZPerspectiveMatrix,
125 constexpr auto Deg2Rad = (PI / 180.0F);
126 constexpr auto FOV = 90.0F * Deg2Rad;
127 constexpr auto HalfFOV = FOV * 0.5F;
130 const auto FaceIndexBase = SensorIndex * 6;
131 const auto ProjectionMatrix = ProjectionMatrixType(HalfFOV, 1.0F, 1.0F, GNearClippingPlane);
133 const FVector Forward[] =
135 FVector::ForwardVector,
136 -FVector::ForwardVector,
137 FVector::RightVector,
138 -FVector::RightVector,
143 const FVector
Right[] =
145 FVector::RightVector,
146 -FVector::RightVector,
147 -FVector::ForwardVector,
148 FVector::ForwardVector,
149 FVector::RightVector,
150 -FVector::RightVector,
153 CaptureRenderTarget = CreateDefaultSubobject<UTextureRenderTarget2D>(
154 FName(*FString::Printf(
155 TEXT(
"CaptureRenderTarget2D-WideLens-Final-d%d"),
158 CaptureRenderTarget->CompressionSettings = TextureCompressionSettings::TC_Default;
159 CaptureRenderTarget->SRGB =
false;
160 CaptureRenderTarget->bAutoGenerateMips =
false;
161 CaptureRenderTarget->bGPUSharedFlag =
true;
162 CaptureRenderTarget->AddressX = TextureAddress::TA_Clamp;
163 CaptureRenderTarget->AddressY = TextureAddress::TA_Clamp;
165 for (uint8 i = 0; i != 6; ++i)
167 const auto AbsIndex = FaceIndexBase + i;
169 auto& RenderTarget = FaceRenderTargets[i];
170 auto& FaceCapture = FaceCaptures[i];
172 RenderTarget = CreateDefaultSubobject<UTextureRenderTarget2D>(
173 FName(*FString::Printf(TEXT(
"CaptureRenderTarget2D-WideLens-Face-d%d"), AbsIndex)));
174 check(RenderTarget !=
nullptr);
175 RenderTarget->CompressionSettings = TextureCompressionSettings::TC_Default;
176 RenderTarget->SRGB =
false;
177 RenderTarget->bAutoGenerateMips =
false;
178 RenderTarget->bGPUSharedFlag =
true;
179 RenderTarget->AddressX = TextureAddress::TA_Clamp;
180 RenderTarget->AddressY = TextureAddress::TA_Clamp;
182 FaceCapture = CreateDefaultSubobject<USceneCaptureComponent2D_CARLA>(
183 FName(*FString::Printf(TEXT(
"USceneCaptureComponent2D_CARLA-%d"), AbsIndex)));
184 check(FaceCapture !=
nullptr);
185 FaceCapture->SetupAttachment(RootComponent);
186 FaceCapture->SetRelativeRotation(FRotationMatrix::MakeFromXY(Forward[i], Right[i]).ToQuat());
187 FaceCapture->ViewActor =
this;
188 FaceCapture->ProjectionType = ECameraProjectionMode::Perspective;
189 FaceCapture->PrimitiveRenderMode = ESceneCapturePrimitiveRenderMode::PRM_RenderScenePrimitives;
190 FaceCapture->bCaptureOnMovement =
false;
191 FaceCapture->bCaptureEveryFrame =
false;
192 FaceCapture->bAlwaysPersistRenderingState =
true;
193 FaceCapture->bUseCustomProjectionMatrix =
true;
194 FaceCapture->CustomProjectionMatrix = ProjectionMatrix;
203 Super::Set(Description);
214 if (UpdateRenderMask)
223 static_cast<uint32
>(FMath::Max(Width, 1)),
224 static_cast<uint32
>(FMath::Max(Height, 1)));
234 bool UpdateRenderMask = NewCameraModel !=
CameraModel;
238 if (UpdateRenderMask)
264 bool UpdateRenderMask = NewFOV !=
YFOVAngle;
280 if (UpdateRenderMask)
287 LensThetaMax = ThetaMaxRadians > 0.0F ? ThetaMaxRadians : PI * 0.5F;
314 if (UpdateRenderMask)
322 for (uint32 i = 0; i != (uint32)Coefficients.Num() && !UpdateRenderMask; ++i)
327 if (UpdateRenderMask)
362 if (UpdateRenderMask)
377 if (UpdateRenderMask)
392 if (UpdateRenderMask)
412 float NewLatitudeOffset)
422 if (FaceCapture !=
nullptr)
435 const float R = hypotf(UV.X, UV.Y);
449 const float HalfPi = PI / 2.0f;
450 const float Phi = HalfPi - Theta;
451 const float Rho = atan2f(UV.Y, UV.X);
458 FMath::SinCos(&PhiSin, &PhiCos, Phi);
459 FMath::SinCos(&RhoSin, &RhoCos, Rho);
461 auto Direction = FVector(PhiSin, PhiCos * RhoCos, -PhiCos * RhoSin);
462 Direction.Normalize();
464 auto DirectionAbs = Direction.GetAbs();
466 if (DirectionAbs.X >= DirectionAbs.Y && DirectionAbs.X >= DirectionAbs.Z)
467 return Direction.X < 0 ? 1U : 0U;
468 else if (DirectionAbs.Y >= DirectionAbs.X && DirectionAbs.Y >= DirectionAbs.Z)
469 return Direction.Y < 0 ? 3U : 2U;
471 return Direction.Z < 0 ? 5U : 4U;
479 return (1U << CubeFace_PosX) | (1U << CubeFace_NegX) |
480 (1U << CubeFace_PosY) | (1U << CubeFace_NegY) |
481 (1U << CubeFace_PosZ) | (1U << CubeFace_NegZ);
483 static const float Pi = PI;
484 static const float HalfPi = Pi / 2.0f;
485 static const float Sqrt2 = sqrtf(2.0f);
487 auto Mask = 1U << CubeFace_PosX;
499 Mask |= 1U << CubeFace_PosZ;
500 Mask |= 1U << CubeFace_NegZ;
505 Mask |= 1U << CubeFace_PosY;
506 Mask |= 1U << CubeFace_NegY;
509 if (FOV.X > Pi || FOV.Y > Pi)
511 Mask |= 1U << CubeFace_NegX;
526 IConsoleVariable* VolumetricFogTRVar =
nullptr;
527 int32 PreviousVolumetricFogTR = 1;
531 VolumetricFogTRVar = IConsoleManager::Get().FindConsoleVariable(
532 TEXT(
"r.VolumetricFog.TemporalReprojection"));
533 if (VolumetricFogTRVar !=
nullptr)
535 PreviousVolumetricFogTR = VolumetricFogTRVar->GetInt();
536 FlushRenderingCommands();
537 VolumetricFogTRVar->Set(TEXT(
"0"), ECVF_SetByCode);
547 if (FaceCapture !=
nullptr)
553 static IConsoleVariable* SpawnCameraCutsVar =
554 IConsoleManager::Get().FindConsoleVariable(TEXT(
"carla.Camera.SpawnCameraCuts"));
555 const bool bCameraCut = SpawnCameraCutsVar !=
nullptr &&
NumCaptures < SpawnCameraCutsVar->GetInt();
559 for (uint8 i = 0; i < 6; ++i)
572 TWeakObjectPtr<ASceneCaptureSensor_WideAngleLens> WeakSelf(
this);
573 UTextureRenderTarget2D* RenderTargetsSnapshot[] =
609 ENQUEUE_RENDER_COMMAND(WideAngleLensCommand)(
611 RenderTargetsSnapshot,
612 CaptureRenderTargetSnapshot,
613 CubemapSamplerSnapshot,
614 DistortedOptions](FRHICommandListImmediate& RHICmdList)
616 TRACE_CPUPROFILER_EVENT_SCOPE(WideAngleLensCommand);
618 if (!WeakSelf.IsValid())
621 FRDGBuilder GraphBuilder(RHICmdList);
623 UTextureRenderTarget2D* RenderTargets[] =
625 RenderTargetsSnapshot[0],
626 RenderTargetsSnapshot[1],
627 RenderTargetsSnapshot[2],
628 RenderTargetsSnapshot[3],
629 RenderTargetsSnapshot[4],
630 RenderTargetsSnapshot[5]
635 CaptureRenderTargetSnapshot,
637 CubemapSamplerSnapshot,
640 GraphBuilder.Execute();
647 const TCHAR* Names[(size_t)ECameraModel::MaxEnum] =
650 TEXT(
"Stereographic"),
653 TEXT(
"Orthographic"),
654 TEXT(
"KannalaBrandt"),
655 TEXT(
"BrownConrady"),
665 for (uint8 FaceIndex = 0; FaceIndex != 6; ++FaceIndex)
670 TEXT(
"%s/Frame-%s-%u-Face-%u.png"),
681 TEXT(
"%s/Frame-%s-%u-Final.png"),
689 if (VolumetricFogTRVar !=
nullptr)
691 FlushRenderingCommands();
692 VolumetricFogTRVar->Set(*FString::FromInt(PreviousVolumetricFogTR), ECVF_SetByCode);
709 bInForceLinearGamma);
713 FaceRenderTarget->InitCustomFormat(
716 bInForceLinearGamma);
726 for (uint8 i = 0; i != 6; ++i)
739 FaceCapture->PostProcessSettings,
740 FaceCapture->ShowFlags);
741 PostProcessConfig.UpdateFromSceneCaptureComponent2D(*FaceCapture);
743 FaceCapture->ShowFlags = PostProcessConfig.EngineShowFlags;
744 FaceCapture->PostProcessSettings = PostProcessConfig.PostProcessSettings;
751 FaceCapture->CaptureSource = ESceneCaptureSource::SCS_FinalColorLDR;
752 FaceCapture->UpdateContent();
753 FaceCapture->Activate();
762 UKismetSystemLibrary::ExecuteConsoleCommand(
764 FString(
"g.TimeoutForBlockOnRenderFence 300000"));
772 ReadbackPool = MakeShared<FRHIGPUReadbackPool, ESPMode::ThreadSafe>(
773 TEXT(
"WideAngleLensReadback"));
780 Super::PrePhysTick(DeltaSeconds);
788 const float HalfFOVTan = FMath::Tan(
789 0.5f * FMath::DegreesToRadians(CaptureComponents[0]->FOVAngle));
790 IStreamingManager::Get().AddViewInformation(
791 CaptureComponents[0]->GetComponentLocation(),
798 Super::PostPhysTick(World, TickType, DeltaTime);
803 Super::EndPlay(EndPlayReason);
808 FlushRenderingCommands();
816 if (FaceCapture ==
nullptr)
818 FaceCapture->Deactivate();
819 FaceCapture->TextureTarget =
nullptr;
820 FaceCapture->ReleaseViewStates();
824 if (FaceRenderTarget !=
nullptr)
825 FaceRenderTarget->ReleaseResource();
829 FlushRenderingCommands();
858 FPostProcessSettings& PostProcessSettings = CaptureComponent.PostProcessSettings;
859 PostProcessSettings.bOverride_VignetteIntensity =
true;
860 PostProcessSettings.VignetteIntensity = 0;
861 PostProcessSettings.bOverride_DepthOfFieldVignetteSize =
true;
862 PostProcessSettings.DepthOfFieldVignetteSize = 0;
865 PostProcessSettings.bOverride_AutoExposureMethod =
true;
866 PostProcessSettings.AutoExposureMethod = EAutoExposureMethod::AEM_Manual;
867 PostProcessSettings.bOverride_AutoExposureBias =
true;
868 PostProcessSettings.AutoExposureBias = 0.0f;
869 PostProcessSettings.bOverride_AutoExposureMinBrightness =
true;
870 PostProcessSettings.AutoExposureMinBrightness = 1.0f;
871 PostProcessSettings.bOverride_AutoExposureMaxBrightness =
true;
872 PostProcessSettings.AutoExposureMaxBrightness = 1.0f;
static TAutoConsoleVariable< FString > CVarWideAngleSensorDumpAllFramesPath(TEXT("Carla.WideAngleLens.DumpAllFramesPath"), TEXT(""), TEXT("Sets the destination path when saving frames via \"Carla.WideAngleLens.DumpAllFrames\".\n"))
static TAutoConsoleVariable< int32 > CVarWideAngleSensorDumpAllFrames(TEXT("Carla.WideAngleLens.DumpAllFrames"), 0, TEXT("1: Enabled\n"))
static TAutoConsoleVariable< int32 > CVarWideAngleSensorSkipVFTR(TEXT("Carla.WideAngleLens.SkipVFTR"), 0, TEXT("1: Enabled\n"))
static auto WIDE_ANGLE_LENS_SENSOR_COUNTER
static TAutoConsoleVariable< int32 > CVarWideAngleSensorDumpAllFramesCubemap(TEXT("Carla.WideAngleLens.DumpAllFrames.Cubemap"), 0, TEXT("1: Enabled\n"))
void SetTargetGamma(float Gamma)
virtual void PrePhysTick(float DeltaSeconds) override
const TArray< float > & GetCameraCoefficients() const
virtual void SetUpSceneCaptureComponents(TArrayView< USceneCaptureComponent2D_CARLA * > SceneCaptures)
uint8 FindFaceIndex(FVector2D UV) const
void SetCameraCoefficients(TArrayView< const float > Coefficients)
uint8 ComputeCubemapRenderMask() const
ASceneCaptureSensor_WideAngleLens(const FObjectInitializer &ObjectInitializer)
bool bRenderEquirectangular
void SetRenderPerspective(bool bEnable)
void CaptureSceneExtended()
float GetRenderEquirectangularLongitudeOffset() const
void SetImageSize(int32 Width, int32 Height)
bool GetRenderPerspective() const
void SetLensLUT(const TArray< float > &Samples, float ThetaMaxRadians)
LUT1D camera model: R(Theta) samples, uniformly spaced over [0, ThetaMaxRadians], monotonically non-d...
ECameraModel GetCameraModel() const
float GetFOVAngleX() const
void SetRenderEquirectangularLongitudeOffset(float Shift)
void Set(const FActorDescription &ActorDescription) override
void SetFOVFadeSize(float NewFOVFadeSize)
virtual void BeginPlay() override
uint32 GetImageHeight() const
FRHIGPUReadbackPoolPtr ReadbackPool
bool GetRenderEquirectangular() const
virtual void PostPhysTick(UWorld *World, ELevelTick TickType, float DeltaTime) override
TArray< USceneCaptureComponent2D_CARLA * > FaceCaptures
void SetUseRayTracing(bool Enable)
bool bEnablePostProcessingEffects
void SetFOVMaskEnable(bool bEnable)
uint32 GetImageWidth() const
TArray< float > KannalaBrandtCameraCoefficients
void SetFocalLength(float NewFocalLength)
float VerticalToHorizontal(float Value) const
TArray< UTextureRenderTarget2D * > FaceRenderTargets
virtual void EndPlay(const EEndPlayReason::Type EndPlayReason) override
virtual FLinearColor GetInvalidPixelColor() const
Colour written to pixels the lens maps no ray to (LUT1D beyond its last sample).
float GetFocalLength() const
UTextureRenderTarget2D * GetCaptureRenderTarget()
TArrayView< USceneCaptureComponent2D_CARLA * > GetCaptureComponents2D()
void EnqueueRenderSceneImmediate()
Immediate enqueues render commands of the scene at the current time.
void SetCameraModel(ECameraModel NewCameraModel)
float GetFOVFadeSize() const
int32 NumCaptures
Captures rendered as camera cuts since BeginPlay (carla.Camera.SpawnCameraCuts).
float GetFOVAngle() const
float GetTargetGamma() const
UTextureRenderTarget2D * CaptureRenderTarget
void SetLensIntrinsics(float Fx, float Fy, float Cx, float Cy)
Explicit intrinsics in normalized viewport units, the same convention as sensor.camera....
FRHISamplerState * CubemapSampler
void SetFOVAngle(float NewFOV)
bool GetFOVMaskEnable() const
void SetRenderEquirectangular(bool bEnable)
float GetFOVAngleY() const
FCarlaShowOnlyFilter ShowOnlyFilter
Show-only actor filter, applied to every face capture right before the faces are captured (see FCarla...
static bool ResolveCameraRayTracing(bool bSensorEnabled, bool bRequired)
Applies the carla.Camera.UseRayTracing tier policy to a camera's own ray-tracing preference.
const UCarlaEpisode & GetEpisode() const
void NotifyWeather(ASensor *Sensor=nullptr)
Notifing the weather to the blueprint's event.
static TFuture< bool > SavePixelsToDisk(UTextureRenderTarget2D &RenderTarget, const FString &FilePath)
Asynchronously save the pixels in RenderTarget to disk.
static void SetCamera(const FActorDescription &Description, ASceneCaptureSensor *Camera)
AWeather * GetWeather() const
float SampleInverse(float Distance, TArrayView< const float > Samples, float ThetaMax)
float ComputeAngle(ECameraModel CameraModel, float Distance, TArrayView< const float > Coefficients)
float ComputeDistance(ECameraModel CameraModel, float Angle, int32 ImageHeight, TArrayView< const float > Coefficients)
FRHISamplerState * GetSampler(ESamplerFilter Filter)
void DistortCubemapToImage(FRDGBuilder &GraphBuilder, FRDGTexture *Destination, FRDGTexture **CubeTextures, FRHISamplerState *Sampler, const FDistortCubemapToImageOptions &Options)
static void SetCameraDefaultOverrides(USceneCaptureComponent2D_CARLA &CaptureComponent)
TArrayView< const float > LUT
bool bRenderEquirectangular
TArrayView< const float > KannalaBrandtCoefficients
A description of a Carla Actor with all its variation.
void Refresh(UWorld *World, const UCarlaEpisode *Episode)
Rebuild the cached actor list if the world changed since the last call.
void ApplyTo(USceneCaptureComponent2D &Capture) const
Push the current list into Capture (or restore full-scene rendering when the filter is disabled).