9#include <util/ue-header-guard-begin.h>
10#include "Engine/TextureRenderTargetCube.h"
11#include "Engine/TextureRenderTarget2D.h"
12#include "GlobalShader.h"
13#include "ShaderParameterUtils.h"
14#include "PipelineStateCache.h"
15#include "RHIStaticStates.h"
16#include "RenderGraphBuilder.h"
17#include "RenderGraphUtils.h"
18#include <util/ue-header-guard-end.h>
41 std::make_pair(TEXT(
"THREAD_GROUP_SIZE_X"),
SubgroupSize),
42 std::make_pair(TEXT(
"THREAD_GROUP_SIZE_Y"), 1U),
43 std::make_pair(TEXT(
"THREAD_GROUP_SIZE_Z"), 1U),
50template <ECameraModel>
53 BEGIN_SHADER_PARAMETER_STRUCT(FParameters, )
54 SHADER_PARAMETER_RDG_TEXTURE_UAV(RWTexture2D<float4>, OutImage)
55 SHADER_PARAMETER_RDG_TEXTURE_SRV(Texture2D, CubeFront)
56 SHADER_PARAMETER_RDG_TEXTURE_SRV(Texture2D, CubeBack)
57 SHADER_PARAMETER_RDG_TEXTURE_SRV(Texture2D, CubeRight)
58 SHADER_PARAMETER_RDG_TEXTURE_SRV(Texture2D, CubeLeft)
59 SHADER_PARAMETER_RDG_TEXTURE_SRV(Texture2D, CubeTop)
60 SHADER_PARAMETER_RDG_TEXTURE_SRV(Texture2D, CubeBottom)
61 SHADER_PARAMETER_SAMPLER(SamplerState, FaceSampler)
62 SHADER_PARAMETER(
float, YFOVAngle)
63 SHADER_PARAMETER(FVector4f, CameraParams)
64 SHADER_PARAMETER(uint32, Flags)
65 SHADER_PARAMETER(
float, LongitudeOffset)
66 SHADER_PARAMETER(
float, FOVFadeSize)
67 SHADER_PARAMETER(FVector4f, InvalidColor)
68 END_SHADER_PARAMETER_STRUCT()
74 BEGIN_SHADER_PARAMETER_STRUCT(FParameters, )
75 SHADER_PARAMETER_RDG_TEXTURE_UAV(RWTexture2D<float4>, OutImage)
76 SHADER_PARAMETER_RDG_TEXTURE_SRV(Texture2D, CubeFront)
77 SHADER_PARAMETER_RDG_TEXTURE_SRV(Texture2D, CubeBack)
78 SHADER_PARAMETER_RDG_TEXTURE_SRV(Texture2D, CubeRight)
79 SHADER_PARAMETER_RDG_TEXTURE_SRV(Texture2D, CubeLeft)
80 SHADER_PARAMETER_RDG_TEXTURE_SRV(Texture2D, CubeTop)
81 SHADER_PARAMETER_RDG_TEXTURE_SRV(Texture2D, CubeBottom)
82 SHADER_PARAMETER_SAMPLER(SamplerState, FaceSampler)
83 SHADER_PARAMETER(
float, YFOVAngle)
84 SHADER_PARAMETER(FVector4f, CameraParams)
85 SHADER_PARAMETER(uint32, Flags)
86 SHADER_PARAMETER(
float, LongitudeOffset)
87 SHADER_PARAMETER(
float, FOVFadeSize)
88 SHADER_PARAMETER(FVector4f, InvalidColor)
89 SHADER_PARAMETER_RDG_BUFFER_SRV(StructuredBuffer<float>, Coefficients)
90 SHADER_PARAMETER(uint32, CoefficientCount)
91 END_SHADER_PARAMETER_STRUCT()
98 BEGIN_SHADER_PARAMETER_STRUCT(FParameters, )
99 SHADER_PARAMETER_RDG_TEXTURE_UAV(RWTexture2D<float4>, OutImage)
100 SHADER_PARAMETER_RDG_TEXTURE_SRV(Texture2D, CubeFront)
101 SHADER_PARAMETER_RDG_TEXTURE_SRV(Texture2D, CubeBack)
102 SHADER_PARAMETER_RDG_TEXTURE_SRV(Texture2D, CubeRight)
103 SHADER_PARAMETER_RDG_TEXTURE_SRV(Texture2D, CubeLeft)
104 SHADER_PARAMETER_RDG_TEXTURE_SRV(Texture2D, CubeTop)
105 SHADER_PARAMETER_RDG_TEXTURE_SRV(Texture2D, CubeBottom)
106 SHADER_PARAMETER_SAMPLER(SamplerState, FaceSampler)
107 SHADER_PARAMETER(
float, YFOVAngle)
108 SHADER_PARAMETER(FVector4f, CameraParams)
109 SHADER_PARAMETER(uint32, Flags)
110 SHADER_PARAMETER(
float, LongitudeOffset)
111 SHADER_PARAMETER(
float, FOVFadeSize)
112 SHADER_PARAMETER(FVector4f, InvalidColor)
113 SHADER_PARAMETER_RDG_BUFFER_SRV(StructuredBuffer<float>, LensLUT)
114 SHADER_PARAMETER(uint32, LensLUTSize)
115 SHADER_PARAMETER(
float, LensThetaMax)
116 END_SHADER_PARAMETER_STRUCT()
121template <ECameraModel>
124 BEGIN_SHADER_PARAMETER_STRUCT(FParameters, )
125 SHADER_PARAMETER_RDG_TEXTURE_UAV(RWTexture2D<float4>, Destination)
126 SHADER_PARAMETER_RDG_TEXTURE_SRV(Texture2D, Source)
127 SHADER_PARAMETER_SAMPLER(SamplerState, SourceSampler)
128 SHADER_PARAMETER(FVector4f, DestinationCameraParams)
129 SHADER_PARAMETER(FVector4f, SourceCameraParams)
130 END_SHADER_PARAMETER_STRUCT()
136 BEGIN_SHADER_PARAMETER_STRUCT(FParameters, )
137 SHADER_PARAMETER_RDG_TEXTURE_UAV(RWTexture2D<float4>, Destination)
138 SHADER_PARAMETER_RDG_TEXTURE_SRV(Texture2D, Source)
139 SHADER_PARAMETER_SAMPLER(SamplerState, SourceSampler)
140 SHADER_PARAMETER(FVector4f, DestinationCameraParams)
141 SHADER_PARAMETER(FVector4f, SourceCameraParams)
142 SHADER_PARAMETER_RDG_BUFFER_SRV(StructuredBuffer<float>, Coefficients)
143 SHADER_PARAMETER(uint32, CoefficientCount)
144 END_SHADER_PARAMETER_STRUCT()
152#define DECLARE_WIDE_ANGLE_LENS_SHADER(NAME, CAMERA_MODEL) \
154 public FWideAngleLensShaderBase<CAMERA_MODEL>, \
155 public FGlobalShader \
159 DECLARE_GLOBAL_SHADER(NAME); \
160 SHADER_USE_PARAMETER_STRUCT(NAME, FGlobalShader); \
162 static bool ShouldCompilePermutation(const FGlobalShaderPermutationParameters& Parameters) \
167 static void ModifyCompilationEnvironment( \
168 const FGlobalShaderPermutationParameters& Parameters, \
169 FShaderCompilerEnvironment& OutEnvironment) \
171 for (auto Definition : CommonShaderDefinitions) \
172 OutEnvironment.SetDefine(Definition.first, Definition.second); \
173 OutEnvironment.SetDefine(TEXT("CAMERA_TYPE"), static_cast<uint32>(CAMERA_MODEL)); \
174 FGlobalShader::ModifyCompilationEnvironment(Parameters, OutEnvironment); \
180#define DECLARE_PERSPECTIVE_SHADER(NAME, CAMERA_MODEL) \
182 public FToPerspectiveShaderBase<CAMERA_MODEL>, \
183 public FGlobalShader \
187 DECLARE_GLOBAL_SHADER(NAME); \
188 SHADER_USE_PARAMETER_STRUCT(NAME, FGlobalShader); \
190 static bool ShouldCompilePermutation(const FGlobalShaderPermutationParameters& Parameters) \
195 static void ModifyCompilationEnvironment( \
196 const FGlobalShaderPermutationParameters& Parameters, \
197 FShaderCompilerEnvironment& OutEnvironment) \
199 for (auto Definition : CommonShaderDefinitions) \
200 OutEnvironment.SetDefine(Definition.first, Definition.second); \
201 OutEnvironment.SetDefine(TEXT("CAMERA_TYPE"), static_cast<uint32>(CAMERA_MODEL)); \
202 FGlobalShader::ModifyCompilationEnvironment(Parameters, OutEnvironment); \
223template <
typename FShaderType>
225 FRDGBuilder& GraphBuilder,
226 FRDGTextureRef Destination,
227 FRDGTextureRef CubeTextures[6],
228 FRHISamplerState* Sampler,
230 FVector4f CameraParams)
232 auto Parameters = GraphBuilder.AllocParameters<
typename FShaderType::FParameters>();
233 Parameters->OutImage = GraphBuilder.CreateUAV(Destination);
234 Parameters->CubeFront = GraphBuilder.CreateSRV(FRDGTextureSRVDesc::Create(CubeTextures[0]));
235 Parameters->CubeBack = GraphBuilder.CreateSRV(FRDGTextureSRVDesc::Create(CubeTextures[1]));
236 Parameters->CubeRight = GraphBuilder.CreateSRV(FRDGTextureSRVDesc::Create(CubeTextures[2]));
237 Parameters->CubeLeft = GraphBuilder.CreateSRV(FRDGTextureSRVDesc::Create(CubeTextures[3]));
238 Parameters->CubeTop = GraphBuilder.CreateSRV(FRDGTextureSRVDesc::Create(CubeTextures[4]));
239 Parameters->CubeBottom = GraphBuilder.CreateSRV(FRDGTextureSRVDesc::Create(CubeTextures[5]));
240 Parameters->FaceSampler = Sampler;
241 Parameters->CameraParams = CameraParams;
242 Parameters->YFOVAngle = Options.
YFOVAngle;
246 Parameters->Flags = 0;
254template <
typename FShaderType>
256 FRDGBuilder& GraphBuilder,
257 typename FShaderType::FParameters* Parameters,
260 GraphBuilder.AddPass(
261 RDG_EVENT_NAME(
"WideAngleLens-Dispatch"),
263 ERDGPassFlags::Compute,
264 [Parameters, Size](FRHICommandListImmediate& RHICmdList)
266 TShaderMapRef<FShaderType> ComputeShader(GetGlobalShaderMap(GMaxRHIFeatureLevel));
267 check(ComputeShader.IsValid());
269 FComputeShaderUtils::Dispatch(
273 FComputeShaderUtils::GetGroupCount(
274 FIntVector(Size.X, Size.Y, 1),
279template <
typename FShaderType>
281 FRDGBuilder& GraphBuilder,
282 FRDGTextureRef Destination,
283 FRDGTextureRef CubeTextures[6],
284 FRHISamplerState* Sampler,
287 FVector4f CameraParams)
289 auto Parameters = CreateDistortionParameters<FShaderType>(
290 GraphBuilder, Destination, CubeTextures, Sampler, Options, CameraParams);
291 DispatchDistortion<FShaderType>(GraphBuilder, Parameters, Size);
295 FRDGBuilder& GraphBuilder,
296 FRDGTextureRef Destination,
297 FRDGTextureRef CubeTextures[6],
298 FRHISamplerState* Sampler,
301 FVector4f CameraParams)
303 using FShaderType = FWideAngleLensShader_Custom;
305 auto Parameters = CreateDistortionParameters<FShaderType>(
306 GraphBuilder, Destination, CubeTextures, Sampler, Options, CameraParams);
309 auto CoefficientBuffer = CreateStructuredBuffer(
311 TEXT(
"CoefficientBuffer"),
314 Coefficients.GetData(),
315 Coefficients.Num() *
sizeof(
float),
316 ERDGInitialDataFlags::None);
318 Parameters->Coefficients = GraphBuilder.CreateSRV(FRDGBufferSRVDesc(CoefficientBuffer));
319 Parameters->CoefficientCount =
static_cast<uint32
>(Coefficients.Num());
320 DispatchDistortion<FShaderType>(GraphBuilder, Parameters, Size);
324 FRDGBuilder& GraphBuilder,
325 FRDGTextureRef Destination,
326 FRDGTextureRef CubeTextures[6],
327 FRHISamplerState* Sampler,
330 FVector4f CameraParams)
332 using FShaderType = FWideAngleLensShader_LUT1D;
334 auto Parameters = CreateDistortionParameters<FShaderType>(
335 GraphBuilder, Destination, CubeTextures, Sampler, Options, CameraParams);
340 static const float EmptyLUT[1] = { 0.0F };
341 const TArrayView<const float> LUT = Options.
LUT.Num() > 0
343 : TArrayView<const float>(EmptyLUT, 1);
345 auto LUTBuffer = CreateStructuredBuffer(
347 TEXT(
"LensLUTBuffer"),
351 LUT.Num() *
sizeof(
float),
352 ERDGInitialDataFlags::None);
354 Parameters->LensLUT = GraphBuilder.CreateSRV(FRDGBufferSRVDesc(LUTBuffer));
355 Parameters->LensLUTSize =
static_cast<uint32
>(LUT.Num());
356 Parameters->LensThetaMax = Options.
ThetaMax;
357 DispatchDistortion<FShaderType>(GraphBuilder, Parameters, Size);
360template <
typename FShaderType>
362 FRDGBuilder& GraphBuilder,
363 FRDGTextureRef Destination,
364 FRDGTextureRef Source,
365 FRHISamplerState* Sampler,
367 float DestinationFocalDistance,
368 float SourceFocalDistance,
371 const auto Center = Size / 2;
373 auto Parameters = GraphBuilder.AllocParameters<
typename FShaderType::FParameters>();
374 Parameters->Destination = GraphBuilder.CreateUAV(Destination);
375 Parameters->Source = GraphBuilder.CreateSRV(FRDGTextureSRVDesc::Create(Source));
376 Parameters->SourceSampler = Sampler;
377 Parameters->SourceCameraParams = FVector4f(SourceFocalDistance, SourceFocalDistance, Center.X, Center.Y);
378 Parameters->DestinationCameraParams = FVector4f(DestinationFocalDistance, DestinationFocalDistance, Center.X, Center.Y);
380 GraphBuilder.AddPass(
381 RDG_EVENT_NAME(
"ToPerspective-Dispatch"),
383 ERDGPassFlags::Compute,
384 [Parameters, Size](FRHICommandListImmediate& RHICmdList)
386 TShaderMapRef<FShaderType> ComputeShader(GetGlobalShaderMap(GMaxRHIFeatureLevel));
387 check(ComputeShader.IsValid());
389 FComputeShaderUtils::Dispatch(RHICmdList, ComputeShader, *Parameters,
390 FComputeShaderUtils::GetGroupCount(
391 FIntVector(Size.X, Size.Y, 1),
397 FRDGBuilder& GraphBuilder,
398 FRDGTextureRef Destination,
399 FRDGTextureRef Source,
400 FRHISamplerState* Sampler,
402 float DestinationFocalDistance,
403 float SourceFocalDistance,
405 TArrayView<const float> KannalaBrandtCoefficients)
407 using FShaderType = FToPerspectiveShader_Custom;
409 const auto Center = Size / 2;
411 auto CoefficientBuffer = CreateStructuredBuffer(
413 TEXT(
"CoefficientBuffer"),
415 KannalaBrandtCoefficients.Num(),
416 KannalaBrandtCoefficients.GetData(),
417 KannalaBrandtCoefficients.Num() *
sizeof(
float),
418 ERDGInitialDataFlags::None);
420 auto Parameters = GraphBuilder.AllocParameters<
typename FShaderType::FParameters>();
421 Parameters->Destination = GraphBuilder.CreateUAV(Destination);
422 Parameters->Source = GraphBuilder.CreateSRV(FRDGTextureSRVDesc::Create(Source));
423 Parameters->SourceSampler = Sampler;
424 Parameters->SourceCameraParams = FVector4f(SourceFocalDistance, SourceFocalDistance, Center.X, Center.Y);
425 Parameters->DestinationCameraParams = FVector4f(DestinationFocalDistance, DestinationFocalDistance, Center.X, Center.Y);
426 Parameters->Coefficients = GraphBuilder.CreateSRV(FRDGBufferSRVDesc(CoefficientBuffer));
427 Parameters->CoefficientCount =
static_cast<uint32
>(KannalaBrandtCoefficients.Num());
429 GraphBuilder.AddPass(
430 RDG_EVENT_NAME(
"ToPerspective-Dispatch"),
432 ERDGPassFlags::Compute,
433 [Parameters, Size](FRHICommandListImmediate& RHICmdList)
435 TShaderMapRef<FShaderType> ComputeShader(GetGlobalShaderMap(GMaxRHIFeatureLevel));
436 check(ComputeShader.IsValid());
438 FComputeShaderUtils::Dispatch(RHICmdList, ComputeShader, *Parameters,
439 FComputeShaderUtils::GetGroupCount(
440 FIntVector(Size.X, Size.Y, 1),
453 TArrayView<const float> Coefficients)
456 auto Theta2 = Theta * Theta;
459 for (
auto K : Coefficients)
462 Result += K * ThetaN;
465 return Result * Theta;
470 TArrayView<const float> Coefficients)
473 auto Theta2 = Theta * Theta;
474 auto ThetaN = Theta2;
477 for (
auto K : Coefficients)
479 Result += A * K * ThetaN;
492 TArrayView<const float> Coefficients)
497 return std::atan(Distance);
499 return std::atan(Distance * 0.5F) * 2;
503 return std::asin(FMath::Clamp(Distance * 0.5F, -1.0F, 1.0F)) * 2;
505 return std::asin(FMath::Clamp(Distance, -1.0F, 1.0F));
508 float Theta = Distance;
527 TArrayView<const float> Coefficients)
529 const auto H =
static_cast<float>(ImageHeight);
530 const auto R = H * 0.5F;
537 F =
R / std::tan(Angle);
540 F =
R / (std::tan(Angle * 0.5F) * 2);
546 F =
R / (std::sin(Angle * 0.5F) * 2);
549 F =
R / std::sin(Angle);
562 FRDGBuilder& GraphBuilder,
563 FRDGTexture* Destination,
564 FRDGTexture** CubeTextures,
565 FRHISamplerState* Sampler,
568 auto& DestinationDesc = Destination->Desc;
569 auto SizeVector = DestinationDesc.GetSize();
570 auto Size = FIntPoint(SizeVector.X, SizeVector.Y);
572 auto DistortedTexture =
573 GraphBuilder.CreateTexture(
574 FRDGTextureDesc::Create2D(
576 DestinationDesc.Format,
577 DestinationDesc.ClearValue,
578 TexCreate_ShaderResource | TexCreate_UAV),
579 TEXT(
"DistortedTexture"));
591 ApplyDistortion<FWideAngleLensShader_Perspective>(
592 GraphBuilder, DistortedTexture, CubeTextures, Sampler, Size, Options, CameraParams);
595 ApplyDistortion<FWideAngleLensShader_Stereographic>(
596 GraphBuilder, DistortedTexture, CubeTextures, Sampler, Size, Options, CameraParams);
599 ApplyDistortion<FWideAngleLensShader_Equidistance>(
600 GraphBuilder, DistortedTexture, CubeTextures, Sampler, Size, Options, CameraParams);
603 ApplyDistortion<FWideAngleLensShader_Equisolid>(
604 GraphBuilder, DistortedTexture, CubeTextures, Sampler, Size, Options, CameraParams);
607 ApplyDistortion<FWideAngleLensShader_Orthogonal>(
608 GraphBuilder, DistortedTexture, CubeTextures, Sampler, Size, Options, CameraParams);
612 GraphBuilder, DistortedTexture, CubeTextures, Sampler, Size, Options, CameraParams);
616 GraphBuilder, DistortedTexture, CubeTextures, Sampler, Size, Options, CameraParams);
622 const bool bCanRenderPerspective =
628 auto PerspectiveTexture =
629 GraphBuilder.CreateTexture(
630 FRDGTextureDesc::Create2D(
632 DestinationDesc.Format,
633 FClearValueBinding::Black,
634 TexCreate_ShaderResource | TexCreate_UAV),
635 TEXT(
"PerspectiveTexture"));
646 ToPerspective<FToPerspectiveShader_Perspective>(
653 FocalDistancePerspective,
657 ToPerspective<FToPerspectiveShader_Stereographic>(
664 FocalDistancePerspective,
668 ToPerspective<FToPerspectiveShader_Equidistance>(
675 FocalDistancePerspective,
679 ToPerspective<FToPerspectiveShader_Equisolid>(
686 FocalDistancePerspective,
690 ToPerspective<FToPerspectiveShader_Orthogonal>(
697 FocalDistancePerspective,
708 FocalDistancePerspective,
731 FRDGBuilder& GraphBuilder,
732 UTextureRenderTarget2D* Destination,
733 UTextureRenderTarget2D** CubeRenderTargets,
734 FRHISamplerState* Sampler,
737 FTextureRHIRef TextureRHIs[6] = {};
739 for (uint8 i = 0; i != 6; ++i)
741 TextureRHIs[i] = CubeRenderTargets[i]
742 ->GetRenderTargetResource()
743 ->GetTextureRenderTarget2DResource()
747 auto DestinationRHI = Destination
748 ->GetRenderTargetResource()
749 ->GetTextureRenderTarget2DResource()
752 TRefCountPtr<IPooledRenderTarget> PRTs[] =
754 CreateRenderTarget(TextureRHIs[0], TEXT(
"CubeTextures[0]")),
755 CreateRenderTarget(TextureRHIs[1], TEXT(
"CubeTextures[1]")),
756 CreateRenderTarget(TextureRHIs[2], TEXT(
"CubeTextures[2]")),
757 CreateRenderTarget(TextureRHIs[3], TEXT(
"CubeTextures[3]")),
758 CreateRenderTarget(TextureRHIs[4], TEXT(
"CubeTextures[4]")),
759 CreateRenderTarget(TextureRHIs[5], TEXT(
"CubeTextures[5]"))
762 auto CaptureRenderTargetTexture = GraphBuilder.RegisterExternalTexture(
763 CreateRenderTarget(DestinationRHI, TEXT(
"CaptureRenderTargetTexture")));
765 FRDGTextureRef CubeTextures[6] = { };
767 for (uint8 i = 0; i != 6; ++i)
769 CubeTextures[i] = GraphBuilder.RegisterExternalTexture(PRTs[i]);
774 CaptureRenderTargetTexture,
786 return TStaticSamplerState< SF_Point>::GetRHI();
788 return TStaticSamplerState< SF_Bilinear>::GetRHI();
790 return TStaticSamplerState< SF_Trilinear>::GetRHI();
791 case SF_AnisotropicPoint:
792 return TStaticSamplerState< SF_AnisotropicPoint>::GetRHI();
793 case SF_AnisotropicLinear:
794 return TStaticSamplerState< SF_AnisotropicLinear>::GetRHI();
814 TArrayView<const float> C,
819 const float K1 = C.Num() > 0 ? C[0] : 0.0F;
820 const float K2 = C.Num() > 1 ? C[1] : 0.0F;
821 const float K3 = C.Num() > 2 ? C[2] : 0.0F;
822 const float P1 = C.Num() > 3 ? C[3] : 0.0F;
823 const float P2 = C.Num() > 4 ? C[4] : 0.0F;
825 const float R2 = Xn * Xn + Yn * Yn;
826 const float R4 = R2 * R2;
827 const float Radial = 1.0F + K1 * R2 + K2 * R4 + K3 * R4 * R2;
828 const float DRadialDR2 = K1 + 2.0F * K2 * R2 + 3.0F * K3 * R4;
830 OutXd = Xn * Radial + 2.0F * P1 * Xn * Yn + P2 * (R2 + 2.0F * Xn * Xn);
831 OutYd = Yn * Radial + P1 * (R2 + 2.0F * Yn * Yn) + 2.0F * P2 * Xn * Yn;
833 const float DRadialDXn = 2.0F * Xn * DRadialDR2;
834 const float DRadialDYn = 2.0F * Yn * DRadialDR2;
836 OutJ[0] = Radial + Xn * DRadialDXn + 2.0F * P1 * Yn + 6.0F * P2 * Xn;
837 OutJ[1] = Xn * DRadialDYn + 2.0F * P1 * Xn + 2.0F * P2 * Yn;
838 OutJ[2] = Yn * DRadialDXn + 2.0F * P1 * Xn + 2.0F * P2 * Yn;
839 OutJ[3] = Radial + Yn * DRadialDYn + 6.0F * P1 * Yn + 2.0F * P2 * Xn;
845 TArrayView<const float> Coefficients)
849 return FVector2f(Xd, Yd);
855 TArrayView<const float> Coefficients,
858 float Xn = Xd, Yn = Yd;
859 for (int32 i = 0; i != Iterations; ++i)
866 const float Det = J[0] * J[3] - J[1] * J[2];
867 if (FMath::Abs(Det) < 1e-12F)
870 const float InvDet = 1.0F / Det;
871 const float DXn = InvDet * (J[3] * Fx - J[1] * Fy);
872 const float DYn = InvDet * (-J[2] * Fx + J[0] * Fy);
877 return FVector2f(Xn, Yn);
883 float Polynomial(
float Distance, TArrayView<const float> Coefficients)
885 float Result = 0.0F, RN = 1.0F;
886 const int32 N = FMath::Min(Coefficients.Num(), 8);
887 for (int32 i = 0; i < N; ++i) { Result += Coefficients[i] * RN; RN *= Distance; }
890 float SolveRadius(
float Theta, TArrayView<const float> Coefficients, int32 Iterations)
892 const int32 N = FMath::Min(Coefficients.Num(), 8);
893 const float C0 = N > 0 ? Coefficients[0] : 0.0F, C1 = N > 1 ? Coefficients[1] : 0.0F;
894 float R = FMath::Abs(C1) > 1e-12F ? (Theta - C0) / C1 : Theta;
895 for (int32 It = 0; It < Iterations; ++It)
897 float D = 0.0F, RN = 1.0F;
898 for (int32 i = 1; i < N; ++i) { D += float(i) * Coefficients[i] * RN; RN *=
R; }
899 if (FMath::Abs(D) < 1e-12F)
break;
902 return FMath::Max(
R, 0.0F);
910 TArrayView<const float> Samples,
913 const int32 Count = Samples.Num();
919 const float Clamped = FMath::Clamp(Theta, 0.0F, ThetaMax);
920 const float T = ThetaMax > 0.0F ? (Clamped / ThetaMax) *
static_cast<float>(Count - 1) : 0.0F;
921 const int32 I0 = FMath::Clamp(
static_cast<int32
>(FMath::FloorToFloat(T)), 0, Count - 1);
922 const int32 I1 = FMath::Min(I0 + 1, Count - 1);
923 const float Frac = T -
static_cast<float>(I0);
924 return FMath::Lerp(Samples[I0], Samples[I1], Frac);
929 TArrayView<const float> Samples,
932 const int32 Count = Samples.Num();
935 if (Distance <= Samples[0])
937 if (Distance >= Samples[Count - 1])
942 int32 Hi = Count - 1;
945 const int32 Mid = (Lo + Hi) / 2;
946 if (Samples[Mid] <= Distance)
952 const float R0 = Samples[Lo];
953 const float R1 = Samples[Hi];
954 const float Frac = R1 > R0 ? (Distance - R0) / (R1 - R0) : 0.0F;
955 const float IndexF =
static_cast<float>(Lo) + Frac;
956 return (IndexF /
static_cast<float>(Count - 1)) * ThetaMax;
964 TArrayView<const float> Coeffs,
965 TArrayView<const float> LUT,
971 return std::tan(Theta);
973 return std::tan(Theta * 0.5F) * 2.0F;
977 return std::sin(Theta * 0.5F) * 2.0F;
979 return std::sin(Theta);
996 TArrayView<const float> Coeffs,
997 TArrayView<const float> LUT,
1003 return std::atan(Distance);
1005 return std::atan(Distance * 0.5F) * 2.0F;
1009 return std::asin(FMath::Clamp(Distance * 0.5F, -1.0F, 1.0F)) * 2.0F;
1011 return std::asin(FMath::Clamp(Distance, -1.0F, 1.0F));
1014 float Theta = Distance;
1051 Direction = Direction.GetSafeNormal();
1052 if (Direction.IsNearlyZero())
1053 Direction = FVector(0, 0, 1);
1061 const float Z = FMath::Max(
static_cast<float>(Direction.Z), KINDA_SMALL_NUMBER);
1062 const float PinholeX =
static_cast<float>(Direction.X) / Z;
1063 const float PinholeY =
static_cast<float>(Direction.Y) / Z;
1070 const float Theta = std::acos(FMath::Clamp(
static_cast<float>(Direction.Z), -1.0F, 1.0F));
1071 const float Phi = std::atan2(
static_cast<float>(Direction.Y),
static_cast<float>(Direction.X));
1073 Xn =
R * std::cos(Phi);
1074 Yn =
R * std::sin(Phi);
1087 FVector2f ImagePoint,
1091 const float SafeCAScale = FMath::IsNearlyZero(CAScale) ? 1.0F : CAScale;
1093 const float Xn = (ImagePoint.X - Descriptor.
CenterX) / (Descriptor.
FocalX * SafeCAScale);
1094 const float Yn = (ImagePoint.Y - Descriptor.
CenterY) / (Descriptor.
FocalY * SafeCAScale);
1099 return FVector(Pinhole.X, Pinhole.Y, 1.0F).GetSafeNormal();
1102 const float R = std::sqrt(Xn * Xn + Yn * Yn);
1103 const float Phi = std::atan2(Yn, Xn);
1105 const float SinTheta = std::sin(Theta);
1107 SinTheta * std::cos(Phi),
1108 SinTheta * std::sin(Phi),
1115 return FVector(LensDir.Z, LensDir.X, -LensDir.Y);
1121 return FVector(UEDir.Y, -UEDir.Z, UEDir.X);
1129 FWideAngleLensShader_Perspective,
1130 TEXT(
"/Plugin/Carla/WideAngleLens.usf"),
1135 FWideAngleLensShader_Stereographic,
1136 TEXT(
"/Plugin/Carla/WideAngleLens.usf"),
1141 FWideAngleLensShader_Equidistance,
1142 TEXT(
"/Plugin/Carla/WideAngleLens.usf"),
1147 FWideAngleLensShader_Equisolid,
1148 TEXT(
"/Plugin/Carla/WideAngleLens.usf"),
1153 FWideAngleLensShader_Orthogonal,
1154 TEXT(
"/Plugin/Carla/WideAngleLens.usf"),
1159 FWideAngleLensShader_Custom,
1160 TEXT(
"/Plugin/Carla/WideAngleLens.usf"),
1165 FWideAngleLensShader_LUT1D,
1166 TEXT(
"/Plugin/Carla/WideAngleLens.usf"),
1173 FToPerspectiveShader_Perspective,
1174 TEXT(
"/Plugin/Carla/ToPerspective.usf"),
1179 FToPerspectiveShader_Stereographic,
1180 TEXT(
"/Plugin/Carla/ToPerspective.usf"),
1185 FToPerspectiveShader_Equidistance,
1186 TEXT(
"/Plugin/Carla/ToPerspective.usf"),
1191 FToPerspectiveShader_Equisolid,
1192 TEXT(
"/Plugin/Carla/ToPerspective.usf"),
1197 FToPerspectiveShader_Orthogonal,
1198 TEXT(
"/Plugin/Carla/ToPerspective.usf"),
1203 FToPerspectiveShader_Custom,
1204 TEXT(
"/Plugin/Carla/ToPerspective.usf"),
static void ApplyDistortionLUT1D(FRDGBuilder &GraphBuilder, FRDGTextureRef Destination, FRDGTextureRef CubeTextures[6], FRHISamplerState *Sampler, FIntPoint Size, const CameraModelUtil::FDistortCubemapToImageOptions &Options, FVector4f CameraParams)
static void DispatchDistortion(FRDGBuilder &GraphBuilder, typename FShaderType::FParameters *Parameters, FIntPoint Size)
@ WAL_SHADER_FLAGS_EQUIRECTANGULAR
@ WAL_SHADER_FLAGS_FOV_MASK
static constexpr std::pair< const TCHAR *, uint32 > CommonShaderDefinitions[]
static void ApplyDistortion(FRDGBuilder &GraphBuilder, FRDGTextureRef Destination, FRDGTextureRef CubeTextures[6], FRHISamplerState *Sampler, FIntPoint Size, const CameraModelUtil::FDistortCubemapToImageOptions &Options, FVector4f CameraParams)
static void ToPerspective(FRDGBuilder &GraphBuilder, FRDGTextureRef Destination, FRDGTextureRef Source, FRHISamplerState *Sampler, float YFOVAngle, float DestinationFocalDistance, float SourceFocalDistance, FIntPoint Size)
static void ApplyDistortionKannalaBrandt(FRDGBuilder &GraphBuilder, FRDGTextureRef Destination, FRDGTextureRef CubeTextures[6], FRHISamplerState *Sampler, FIntPoint Size, const CameraModelUtil::FDistortCubemapToImageOptions &Options, FVector4f CameraParams)
#define DECLARE_PERSPECTIVE_SHADER(NAME, CAMERA_MODEL)
#define DECLARE_WIDE_ANGLE_LENS_SHADER(NAME, CAMERA_MODEL)
static const auto KannalaBrandtSolverIterations
IMPLEMENT_SHADER_TYPE(, FWideAngleLensShader_Perspective, TEXT("/Plugin/Carla/WideAngleLens.usf"), TEXT("MainCS"), SF_Compute)
static auto CreateDistortionParameters(FRDGBuilder &GraphBuilder, FRDGTextureRef Destination, FRDGTextureRef CubeTextures[6], FRHISamplerState *Sampler, const CameraModelUtil::FDistortCubemapToImageOptions &Options, FVector4f CameraParams)
static const auto SubgroupSize
static const auto WorkPerInvocation
carla::rpc::Response< T > R
FVector2f Undistort(float Xd, float Yd, TArrayView< const float > Coefficients, int32 Iterations)
static void EvalWithJacobian(float Xn, float Yn, TArrayView< const float > C, float &OutXd, float &OutYd, float OutJ[4])
FVector2f Distort(float Xn, float Yn, TArrayView< const float > Coefficients)
float SolveRadius(float Theta, TArrayView< const float > Coefficients, int32 Iterations)
float Polynomial(float Distance, TArrayView< const float > Coefficients)
float ComputeCameraPolynomialDerivative(float Theta, TArrayView< const float > Coefficients)
float ComputeCameraPolynomial(float Theta, TArrayView< const float > Coefficients)
float SampleForward(float Theta, TArrayView< const float > Samples, float ThetaMax)
float SampleInverse(float Distance, TArrayView< const float > Samples, float ThetaMax)
static float RadialForward(ECameraModel Model, float Theta, TArrayView< const float > Coeffs, TArrayView< const float > LUT, float ThetaMax)
float ComputeAngle(ECameraModel CameraModel, float Distance, TArrayView< const float > Coefficients)
float ComputeDistance(ECameraModel CameraModel, float Angle, int32 ImageHeight, TArrayView< const float > Coefficients)
FVector LensDirToUE(FVector LensDir)
FRHISamplerState * GetSampler(ESamplerFilter Filter)
FVector UEDirToLens(FVector UEDir)
void DistortCubemapToImage(FRDGBuilder &GraphBuilder, FRDGTexture *Destination, FRDGTexture **CubeTextures, FRHISamplerState *Sampler, const FDistortCubemapToImageOptions &Options)
FVector ComputeLensRayDirection(const FLensModelDescriptor &Descriptor, FVector2f ImagePoint, ELensColorChannel Channel)
FVector2f ComputeLensImagePoint(const FLensModelDescriptor &Descriptor, FVector Direction, ELensColorChannel Channel)
static float SelectCAScale(const FLensModelDescriptor &Descriptor, ELensColorChannel Channel)
static float RadialInverse(ECameraModel Model, float Distance, TArrayView< const float > Coeffs, TArrayView< const float > LUT, float ThetaMax)
TArrayView< const float > LUT
bool bRenderEquirectangular
TArrayView< const float > KannalaBrandtCoefficients