29 TEXT(
"carla.RTLens.SyncModeBlockingReadback"),
31 TEXT(
"In synchronous mode, deliver the rt_lens image captured on the same tick.\n")
32 TEXT(
" 0: always use the asynchronous, one-tick-late, droppable readback.\n")
33 TEXT(
" 1: capture then read back through the per-tick batched GPU sync (default)."),
42 TEXT(
"carla.RTLens.SyncModeBlockingPipelineCreation"),
44 TEXT(
"In synchronous mode, wait for the ray tracing material pipeline before rendering.\n")
45 TEXT(
" 0: leave r.RayTracing.NonBlockingPipelineCreation as configured (new actors may render with the fallback hit shader for a few ticks).\n")
46 TEXT(
" 1: set r.RayTracing.NonBlockingPipelineCreation 0 while synchronous, restore it when asynchronous (default)."),
53 TEXT(
"carla.RTLens.MaxAutoExposureEV"),
55 TEXT(
"Upper limit (EV100) of the rt_lens auto exposure range; the lower limit is the camera profile's."),
67 static const FString Lookup[] =
70 TEXT(
"stereographic"),
74 TEXT(
"kannala_brandt"),
75 TEXT(
"brown_conrady"),
80 using I = std::underlying_type_t<ECameraModel>;
83 sizeof(Lookup) /
sizeof(Lookup[0]) == (I)ECameraModel::MaxEnum,
84 "camera_model string lookup size mismatch.");
86 for (I i = 0; i != (I)ECameraModel::MaxEnum; ++i)
88 if (Name == Lookup[i])
92 UE_LOG(LogCarla, Warning,
93 TEXT(
"ASceneCaptureCamera_RayTracedLens: unknown camera_model '%s', defaulting to perspective."),
105 TArrayView<const float> Coeffs)
111 return FMath::Tan(FMath::Min(Theta, FMath::DegreesToRadians(89.5f)));
113 return 2.0f * FMath::Tan(Theta * 0.5f);
117 return 2.0f * FMath::Sin(Theta * 0.5f);
119 return FMath::Sin(FMath::Min(Theta, PI * 0.5f));
125 return FMath::Tan(FMath::Min(Theta, FMath::DegreesToRadians(89.5f)));
131 TArray<float> Result;
134 TArray<FString> Parts;
135 CSV.ParseIntoArray(Parts, TEXT(
","),
true);
136 Result.Reserve(Parts.Num());
137 for (
const auto &Part : Parts)
138 Result.Add(FCString::Atof(*Part));
150 constexpr bool bEnableModifyingPostProcessEffects =
true;
153 bEnableModifyingPostProcessEffects);
157 : Super(ObjectInitializer)
165 PostProcessSettings.bOverride_PathTracingSamplesPerPixel =
true;
166 PostProcessSettings.bOverride_PathTracingEnableDenoiser =
true;
181 if (!PostProcessSettings.bOverride_AutoExposureMaxBrightness ||
182 PostProcessSettings.AutoExposureMaxBrightness > MaxEV)
184 PostProcessSettings.bOverride_AutoExposureMaxBrightness =
true;
185 PostProcessSettings.AutoExposureMaxBrightness = MaxEV;
187 if (PostProcessSettings.bOverride_AutoExposureMinBrightness &&
188 PostProcessSettings.AutoExposureMinBrightness > MaxEV)
190 PostProcessSettings.AutoExposureMinBrightness = MaxEV;
199 Super::Set(Description);
203 const auto &Variations = Description.
Variations;
210 "camera_model", Variations, TEXT(
"perspective")));
213 "distortion_coeffs", Variations, TEXT(
"")));
216 "lut", Variations, TEXT(
"")));
218 "fx", Variations, 0.0f);
220 "fy", Variations, 0.0f);
222 "cx", Variations, 0.5f);
224 "cy", Variations, 0.5f);
233 "fov", Variations, 90.0f);
234 const float FOVDeg = FMath::Clamp(FOVDegRequested, 1.0f, 170.0f);
235 if (FOVDegRequested > 170.0f)
237 UE_LOG(LogCarla, Warning,
238 TEXT(
"ASceneCaptureCamera_RayTracedLens: fov=%.1f clamped to 170 (known shader limitation beyond 170 degrees)."),
241 const float ThetaHalf = FMath::DegreesToRadians(FOVDeg) * 0.5f;
246 UE_LOG(LogCarla, Warning,
247 TEXT(
"ASceneCaptureCamera_RayTracedLens: camera_model=lut/ftheta needs an explicit fx (1/width for pixel-unit coefficients); using fx=1."));
260 const float AspectRatio =
268 "theta_max_deg", Variations, 0.0f);
269 if (ThetaMaxDeg > 0.0f)
275 const float Width = FMath::Max((
float)
GetImageWidth(), 1.0f);
277 const float CornerScale = FMath::Sqrt(1.0f + FMath::Square(Height / Width));
278 LensModel.
ThetaMax = FMath::Min(ThetaHalf * CornerScale, FMath::DegreesToRadians(89.0f));
281 "ca_shift_r", Variations, 1.0f);
283 "ca_shift_b", Variations, 1.0f);
290 "aperture_fstop", Variations, 0.0f);
294 "focus_distance_m", Variations, 1000.0f)
299 "samples_per_pixel", Variations, 16);
301 "enable_denoiser", Variations,
true);
307 if (
const IConsoleVariable* MaxPassCountVar =
308 IConsoleManager::Get().FindConsoleVariable(TEXT(
"r.PathTracing.MaxFramePassCount")))
310 const int32 MaxPassCount = FMath::Max(MaxPassCountVar->GetInt(), 1);
313 UE_LOG(LogCarla, Warning,
314 TEXT(
"rt_lens: samples_per_pixel %d exceeds r.PathTracing.MaxFramePassCount %d; "
315 "clamping so every frame converges and denoises within the tick"),
337 "exposure_mode", Variations, TEXT(
"auto"));
339 if (ExposureMode == TEXT(
"manual"))
341 PPS.bOverride_AutoExposureMethod =
true;
342 PPS.AutoExposureMethod = AEM_Manual;
344 const float ProfileBias = PPS.bOverride_AutoExposureBias ? PPS.AutoExposureBias : 0.0f;
345 PPS.bOverride_AutoExposureBias =
true;
347 "exposure_compensation", Variations, 0.0f);
353 Super::UpdatePostProcessConfig(InOutPostProcessConfig);
371 Super::EndPlay(EndPlayReason);
411 if (RenderTarget ==
nullptr)
418 TArrayView<const FColor> Pixels,
419 FIntPoint Size) ->
bool
461 if (bSynchronousMode &&
472 EnqueueReadback(
false, Context);
506 if (bWillCaptureThisFrame)
static TAutoConsoleVariable< int32 > CVarRTLensSyncBlockingReadback(TEXT("carla.RTLens.SyncModeBlockingReadback"), 1, TEXT(" 1: capture then read back through the per-tick batched GPU sync (default)."), ECVF_Default)
static constexpr float GPinholeApertureFstop
static TAutoConsoleVariable< float > CVarRTLensMaxAutoExposureEV(TEXT("carla.RTLens.MaxAutoExposureEV"), 12.0f, TEXT("Upper limit (EV100) of the rt_lens auto exposure range; the lower limit is the camera profile's."), ECVF_Default)
static TAutoConsoleVariable< int32 > CVarRTLensSyncBlockingPipelineCreation(TEXT("carla.RTLens.SyncModeBlockingPipelineCreation"), 1, TEXT(" 1: set r.RayTracing.NonBlockingPipelineCreation 0 while synchronous, restore it when asynchronous (default)."), ECVF_Default)
ASceneCaptureCamera_RayTracedLens(const FObjectInitializer &ObjectInitializer)
virtual void OnLastClientDisconnected() override
void UpdatePostProcessConfig(FPostProcessConfig &InOutPostProcessConfig) override
Forces path-tracing view mode for this sensor's capture.
void EndPlay(const EEndPlayReason::Type EndPlayReason) override
Restores r.RayTracing.NonBlockingPipelineCreation if this sensor left it at 0 (synchronous mode,...
void PostPhysTick(UWorld *World, ELevelTick TickType, float DeltaSeconds) override
FLensModelDescriptor LensModel
Resolved lens-model parameters, rebuilt in Set() from the camera_model / distortion_coeffs / lut / fx...
int32 SamplesPerPixel
Path-tracer quality knobs.
FSensorCaptureContext PendingReadbackContext
Capture metadata for what is currently in the render target (see TickCaptureAndReadback).
static FActorDefinition GetSensorDefinition()
virtual void OnFirstClientConnected() override
bool bHasPendingReadbackContext
void Set(const FActorDescription &ActorDescription) override
void TickCaptureAndReadback(UWorld *World, ELevelTick TickType, float DeltaSeconds, TFunctionRef< void(bool bNonBlocking, const FSensorCaptureContext &Context)> EnqueueReadback)
Runs this tick's capture and this tick's readback in the order the world's synchronization mode requi...
void SetRayTracedLensExposure()
Pins the capture's auto exposure to the daylight histogram window (EV100 10-12, same as the viewport)...
bool ShouldCaptureThisFrame()
Aggregate gate: main stream or any GBuffer stream has listeners, or CVarCarlaCameraForceAllGBuffers f...
UTextureRenderTarget2D * GetCaptureRenderTarget()
TObjectPtr< USceneCaptureComponent2D_CARLA > CaptureComponent2D
Scene capture component.
void SetUseRayTracing(bool Enable)
void SetAperture(float Aperture)
void SetFocalDistance(float Distance)
uint32 GetImageHeight() const
uint32 GetImageWidth() const
FRHIGPUReadbackPoolPtr GetReadbackPool() const
Per-sensor pool of recyclable RHI readback objects.
virtual void PostPhysTick(UWorld *World, ELevelTick TickType, float DeltaTime) override
static void SendDataToClient(SensorType &&Sensor, TArrayView< ElementType > SensorData, const FSensorCaptureContext &CaptureContext)
static FSensorCaptureContext MakeCaptureContext(const ASensor &Sensor)
Call on the game thread right after CaptureScene().
bool AreClientsListening()
const UCarlaEpisode & GetEpisode() const
FEngineShowFlags EngineShowFlags
static int32 RetrieveActorAttributeToInt(const FString &Id, const TMap< FString, FActorAttribute > &Attributes, int32 Default)
static FActorDefinition MakeRayTracedLensCameraDefinition(const FString &Id, bool bEnableModifyingPostProcessEffects=false)
static FString RetrieveActorAttributeToString(const FString &Id, const TMap< FString, FActorAttribute > &Attributes, const FString &Default)
static float RetrieveActorAttributeToFloat(const FString &Id, const TMap< FString, FActorAttribute > &Attributes, float Default)
static bool RetrieveActorAttributeToBool(const FString &Id, const TMap< FString, FActorAttribute > &Attributes, bool Default)
const FEpisodeSettings & GetSettings() const
float SolveRadius(float Theta, TArrayView< const float > Coefficients, int32 Iterations)
float ComputeCameraPolynomial(float Theta, TArrayView< const float > Coefficients)
bool ReadImageDataAsyncFColor(UTextureRenderTarget2D &RenderTarget, ReadImageDataAsyncCallbackFColor &&Callback, bool bNonBlocking, FRHIGPUReadbackPoolPtr Pool)
void SetBlockingRayTracingPipelineCreation(bool bBlocking)
void ApplyLensModel(FPostProcessSettings &PostProcessSettings, const FLensModelDescriptor &Descriptor)
static float RadialAtTheta(ECameraModel Model, float Theta, TArrayView< const float > Coeffs)
static ECameraModel ParseCameraModelName(const FString &Name)
static TArray< float > ParseFloatCSV(const FString &CSV)
A definition of a Carla Actor with all the variation and attributes.
A description of a Carla Actor with all its variation.
TMap< FString, FActorAttribute > Variations
User selected variations of the actor.
Sensor frame metadata snapshotted at capture time, carried by value through async delivery instead of...