Hello, I’m trying to get 3D View of a static mesh using 2D Scene Capture Component. I am making a 3D Object viewer in my widget blueprint. When i rendering in my widget i got some AA problem.
Thats how I figure out system. These are my settings. I use ScenceColorHDR in RGB, Inv Opacity in A. But somehow i never get exact result when im trying to get.
Render Targets don’t support Anti-Aliasing, so there’s nothing you can do about it unfortunately.
Daniel Wright (Engine Graphics Programmer) has mentioned in the past that this is actually a relatively easy fix, and that there might already be a fix for it in Master branch already. I haven’t tested to see if that’s the case though.
If you use the capture component to generate a static texture once (not every frame), you could write your own AA in C++. I did this for generating icons, I use a 1024*1024 render target and I downsample it using a kernel size of 8. This gives me very smooth anti aliased icons
TArray<FColor> UBbLevelMakerUtils::DownsampleTextureData(TArray<FColor>& Data, int32 Width, int32 Kernel)
{
int32 Len = Data.Num();
int32 W = Width;
TArray<FColor> Downsampled;
Downsampled.Init(FColor(), Len / (Kernel * Kernel));
int32 Row = 0;
for (int32 i = 0; i < Downsampled.Num(); i++)
{
TArray<FColor> KernelColors;
KernelColors.Init(FColor(0, 0, 0, 255), Kernel * Kernel);
int32 KernelIndex = i * Kernel;
if (KernelIndex % W == 0 && i != 0)
{
Row++;
}
KernelIndex += Row * W * (Kernel - 1);
for (int32 k = 0; k < Kernel; ++k)
{
for (int32 kr = 0; kr < Kernel; ++kr)
{
int32 c = KernelIndex + k + (W * kr);
if (c > 0 && c < Len)
{
KernelColors[k * Kernel + kr] = Data[c];
}
}
}
int32 AvR = 0;
int32 AvG = 0;
int32 AvB = 0;
int32 AvA = 0;
for (int32 j = 0; j < KernelColors.Num(); ++j)
{
AvR += KernelColors[j].R;
AvG += KernelColors[j].G;
AvB += KernelColors[j].B;
AvA += KernelColors[j].A;
}
FColor KernelAvarage;
KernelAvarage.R = (uint8)(AvR / KernelColors.Num());
KernelAvarage.G = (uint8)(AvG / KernelColors.Num());
KernelAvarage.B = (uint8)(AvB / KernelColors.Num());
KernelAvarage.A = (uint8)(AvA / KernelColors.Num());
Downsampled[i] = KernelAvarage;
}
return Downsampled;
}
Note that this is supersampling and it’s quite heavy so it’s not really a good solution if you want the texture to update every frame.
You could do sobel edge detection and use it as a mask for blur, with small kernel size this would be fast enough for real time and small enough to build entirely inside material editor
Hey guys, I have done some modify to enable TAA on scene capture 2D component on the engine side.
I am using a latest UT version which is 4.15.
You need to make sure the post process run correctly for AAM_TemporalAA, original source code is below:
if( AntiAliasingMethod == AAM_TemporalAA && ViewState)
{
if(VelocityInput.IsValid())
{
AddTemporalAA( Context, VelocityInput );
}
else
{
// black is how we clear the velocity buffer so this means no velocity
FRenderingCompositePass* NoVelocity = Context.Graph.RegisterPass(new(FMemStack::Get()) FRCPassPostProcessInput(GSystemTextures.BlackDummy));
FRenderingCompositeOutputRef NoVelocityRef(NoVelocity);
AddTemporalAA( Context, NoVelocityRef );
}
}
So, we need make sure AntiAliasingMethod and VelocityInput’s value is correct.
1.for AntiAliasingMethod, Unreal will automatically disable when screen capture 2D, so you should modify CreateSceneRendererForSceneCapture function’s bIsPlanarReflection to be ture.
2.for VelocityInput, see ShouldRenderVelocities function and change code to
bNeedsVelocity |= (bMotionBlur || bTemporalAA || bDistanceFieldAO || bSSRTemporal)/* && !View.bIsSceneCapture*/;
then is ok.
see the attachment for the result(one is printscreen, one is scene captureattachment )
Hey!
I’m using 4.26. There’s an “advanced show flags” option, and TAA is disabled by default and is using FXAA as a fallback, make sure to turn it on and also that "Final Color (HDR) in Linear sRGB gamut is enabled.