[Suggest] Let SceneCaptureComponent2D has Alpha Channel

because Alpha channel Save in GBufferD’s R channel

so we Add ScreenPixelAlphaShder.usf to write alpha channel


#include "Common.usf"

Texture2D InTexture;
SamplerState InTextureSampler;

Texture2D InAlphaTexture;
SamplerState InAlphaTextureSampler;

void Main(FScreenVertexOutput Input,
	out float4 OutColor : SV_Target0)
{
	OutColor = Texture2DSample(InTexture, InTextureSampler, Input.UV);
	OutColor.a = Texture2DSample(InAlphaTexture, InAlphaTextureSampler, Input.UV).r;
}

Add FScreenAlphaPS class in ScreenRendering.h


class FScreenAlphaPS : public FGlobalShader
{
	DECLARE_EXPORTED_SHADER_TYPE(FScreenPS, Global, ENGINE_API);
public:

	static bool ShouldCache(EShaderPlatform Platform) { return true; }

	FScreenAlphaPS(const ShaderMetaType::CompiledShaderInitializerType& Initializer) :
		FGlobalShader(Initializer)
	{
		InTexture.Bind(Initializer.ParameterMap, TEXT("InTexture"), SPF_Mandatory);
		InTextureSampler.Bind(Initializer.ParameterMap, TEXT("InTextureSampler"));
		InAlphaTexture.Bind(Initializer.ParameterMap, TEXT("InAlphaTexture"), SPF_Mandatory);
		InAlphaTextureSampler.Bind(Initializer.ParameterMap, TEXT("InAlphaTextureSampler"));
	}
	FScreenAlphaPS() {}

	void SetParameters(FRHICommandList& RHICmdList, const FTexture* Texture)
	{
		SetTextureParameter(RHICmdList, GetPixelShader(), InTexture, InTextureSampler, Texture);
	}

	void SetParameters(FRHICommandList& RHICmdList, FSamplerStateRHIParamRef SamplerStateRHI, FTextureRHIParamRef TextureRHI)
	{
		SetTextureParameter(RHICmdList, GetPixelShader(), InTexture, InTextureSampler, SamplerStateRHI, TextureRHI);
	}

	void SetAlphaParameters(FRHICommandList& RHICmdList, const FTexture* Texture)
	{
		SetTextureParameter(RHICmdList, GetPixelShader(), InAlphaTexture, InAlphaTextureSampler, Texture);
	}

	void SetAlphaParameters(FRHICommandList& RHICmdList, FSamplerStateRHIParamRef SamplerStateRHI, FTextureRHIParamRef TextureRHI)
	{
		SetTextureParameter(RHICmdList, GetPixelShader(), InAlphaTexture, InAlphaTextureSampler, SamplerStateRHI, TextureRHI);
	}

	virtual bool Serialize(FArchive& Ar) override
	{
		bool bShaderHasOutdatedParameters = FGlobalShader::Serialize(Ar);
		Ar << InTexture;
		Ar << InTextureSampler;
		Ar << InAlphaTexture;
		Ar << InAlphaTextureSampler;
		return bShaderHasOutdatedParameters;
	}

private:
	FShaderResourceParameter InTexture;
	FShaderResourceParameter InTextureSampler;

	FShaderResourceParameter InAlphaTexture;
	FShaderResourceParameter InAlphaTextureSampler;
};


Add FScreenAlphaPS Implement in ScreenRendering.cpp


IMPLEMENT_SHADER_TYPE(, FScreenAlphaPS, TEXT("ScreenPixelAlphaShader"), TEXT("Main"), SF_Pixel);

We Add SceneCaputureModify.h


#pragma once

class USceneCaptureComponent2D;
class FSceneRenderer;
class USceneCaptureComponent;
class UTextureRenderTarget;
class FRHICommandListImmediate;

class RENDERER_API FSceneCaptureModify
{
public:
	static void UpdateSceneCaptureContents(
		USceneCaptureComponent2D* CaptureComponent, 
		FMatrix const& ProjectionMatrix, 
		bool bDrawHiddenOnly);
private:
	static void FSceneRenderer* CreateSceneRenderer(
		USceneCaptureComponent* SceneCaptureComponent, 
		UTextureRenderTarget* TextureTarget, 
		const FMatrix& ViewRotationMatrix, 
		const FVector& ViewLocation, 
		const FMatrix& ProjectionMatrix, 
		float MaxViewDistance, 
		bool bCaptureSceneColour, 
		FPostProcessSettings* PostProcessSettings, 
		float PostProcessBlendWeight
		bool bDrawHiddenOnly);

	static void UpdateSceneCaptureContent_RenderThread(
		FRHICommandListImmediate& RHICmdList, FSceneRenderer* SceneRenderer, 
		FTextureRenderTargetResource* TextureRenderTarget, 
		const FName OwnerName, 
		const FResolveParams& ResolveParams, 
		bool bUseSceneColorTexture)
};





then modify SceneCaptureRendering Add CopyCaptureToTargetWithAlpha


static void CopyCaptureToTargetWithAlpha(
	FRHICommandListImmediate& RHICmdList, 
	const FRenderTarget* Target, const FIntPoint& TargetSize, FViewInfo& View, const FIntRect& ViewRect, 
	FTextureRHIParamRef SourceTextureRHI,
	FTextureRHIParamRef AlphaTextureRHI, 
	bool bNeedsFlippedRenderTarget)
{
	SetRenderTarget(RHICmdList, Target->GetRenderTargetTexture(), NULL);

	RHICmdList.SetRasterizerState(TStaticRasterizerState<FM_Solid, CM_None>::GetRHI());
	RHICmdList.SetDepthStencilState(TStaticDepthStencilState<false, CF_Always>::GetRHI());
	RHICmdList.SetBlendState(TStaticBlendState<>::GetRHI());

	TShaderMapRef<FScreenVS> VertexShader(View.ShaderMap);
	TShaderMapRef<FScreenAlphaPS> PixelShader(View.ShaderMap);
	static FGlobalBoundShaderState BoundShaderState;
	SetGlobalBoundShaderState(RHICmdList, View.GetFeatureLevel(), BoundShaderState, GFilterVertexDeclaration.VertexDeclarationRHI, *VertexShader, *PixelShader);

	FRenderingCompositePassContext Context(RHICmdList, View);

	VertexShader->SetParameters(RHICmdList, View);
	PixelShader->SetParameters(RHICmdList, TStaticSamplerState<SF_Point>::GetRHI(), SourceTextureRHI);
	PixelShader->SetAlphaParameters(RHICmdList, TStaticSamplerState<SF_Point>::GetRHI(), AlphaTextureRHI);

	if (bNeedsFlippedRenderTarget)
	{
		DrawRectangle(
			RHICmdList,
			ViewRect.Min.X, ViewRect.Min.Y,
			ViewRect.Width(), ViewRect.Height(),
			ViewRect.Min.X, ViewRect.Height() - ViewRect.Min.Y,
			ViewRect.Width(), -ViewRect.Height(),
			TargetSize,
			TargetSize,
			*VertexShader,
			EDRF_UseTriangleOptimization);
	}
	else
	{
		DrawRectangle(
			RHICmdList,
			ViewRect.Min.X, ViewRect.Min.Y,
			ViewRect.Width(), ViewRect.Height(),
			ViewRect.Min.X, ViewRect.Min.Y,
			ViewRect.Width(), ViewRect.Height(),
			TargetSize,
			FSceneRenderTargets::Get(RHICmdList).GetBufferSizeXY(),
			*VertexShader,
			EDRF_UseTriangleOptimization);
	}
}


void FSceneCaptureModify::UpdateSceneCaptureContent_RenderThread(
		FRHICommandListImmediate& RHICmdList, 
		FSceneRenderer* SceneRenderer, 
		FTextureRenderTargetResource* TextureRenderTarget, 
		const FName OwnerName, 
		const FResolveParams& ResolveParams, 
		bool bUseSceneColorTexture)
{
	FMemMark MemStackMark(FMemStack::Get());

	// update any resources that needed a deferred update
	FDeferredUpdateResource::UpdateResources(RHICmdList);

	{
#if WANTS_DRAW_MESH_EVENTS
		FString EventName;
		OwnerName.ToString(EventName);
		SCOPED_DRAW_EVENTF(RHICmdList, SceneCapture, TEXT("SceneCapture %s"), *EventName);
#else
		SCOPED_DRAW_EVENT(RHICmdList, UpdateSceneCaptureContent_RenderThread);
#endif

		const bool bIsMobileHDR = IsMobileHDR();
		const bool bRHINeedsFlip = RHINeedsToSwitchVerticalAxis(GMaxRHIShaderPlatform);
		const bool bNeedsFlippedRenderTarget = !bIsMobileHDR && bRHINeedsFlip;

		// Intermediate render target that will need to be flipped (needed on !IsMobileHDR())
		TRefCountPtr<IPooledRenderTarget> FlippedPooledRenderTarget;

		const FRenderTarget* Target = SceneRenderer->ViewFamily.RenderTarget;
		if (bNeedsFlippedRenderTarget)
		{
			// We need to use an intermediate render target since the result will be flipped
			auto& RenderTarget = Target->GetRenderTargetTexture();
			FPooledRenderTargetDesc Desc(FPooledRenderTargetDesc::Create2DDesc(Target->GetSizeXY(),
				RenderTarget.GetReference()->GetFormat(),
				FClearValueBinding::None,
				TexCreate_None,
				TexCreate_RenderTargetable,
				false));
			GRenderTargetPool.FindFreeElement(Desc, FlippedPooledRenderTarget, TEXT("SceneCaptureFlipped"));
		}

		// Helper class to allow setting render target
		struct FRenderTargetOverride : public FRenderTarget
		{
			FRenderTargetOverride(FRHITexture2D* In)
			{
				RenderTargetTextureRHI = In;
			}

			virtual FIntPoint GetSizeXY() const { return FIntPoint(RenderTargetTextureRHI->GetSizeX(), RenderTargetTextureRHI->GetSizeY()); }

			FTexture2DRHIRef GetTextureParamRef() { return RenderTargetTextureRHI; }
		} FlippedRenderTarget(
			FlippedPooledRenderTarget.GetReference()
			? FlippedPooledRenderTarget.GetReference()->GetRenderTargetItem().TargetableTexture->GetTexture2D()
			: nullptr);
		FViewInfo& View = SceneRenderer->Views[0];
		FIntRect ViewRect = View.ViewRect;
		FIntRect UnconstrainedViewRect = View.UnconstrainedViewRect;
		SetRenderTarget(RHICmdList, Target->GetRenderTargetTexture(), NULL);
		RHICmdList.Clear(true, FLinearColor::Black, false, (float)ERHIZBuffer::FarPlane, false, 0, ViewRect);

		// Render the scene normally
		{
			SCOPED_DRAW_EVENT(RHICmdList, RenderScene);

			if (bNeedsFlippedRenderTarget)
			{
				// Hijack the render target
				SceneRenderer->ViewFamily.RenderTarget = &FlippedRenderTarget; //-V506
			}
			SceneRenderer->Render(RHICmdList);
			if (bNeedsFlippedRenderTarget)
			{
				// And restore it
				SceneRenderer->ViewFamily.RenderTarget = Target;
			}
		}

		const FIntPoint TargetSize(UnconstrainedViewRect.Width(), UnconstrainedViewRect.Height());
		if (bNeedsFlippedRenderTarget)
		{
			// We need to flip this texture upside down (since we depended on tonemapping to fix this on the hdr path)
			SCOPED_DRAW_EVENT(RHICmdList, FlipCapture);

			
			CopyCaptureToTarget(RHICmdList, Target, TargetSize, View, ViewRect, FlippedRenderTarget.GetTextureParamRef(), true);
		}
		else if (bUseSceneColorTexture && (bIsMobileHDR || SceneRenderer->FeatureLevel >= ERHIFeatureLevel::SM4))
		{
			// Copy the captured scene into the destination texture (only required on HDR or deferred as that implies post-processing)
			SCOPED_DRAW_EVENT(RHICmdList, CaptureSceneColor);

			FSceneRenderTargets::Get_Todo_PassContent().AdjustGBufferRefCount(1);

			CopyCaptureToTargetWithAlpha(RHICmdList, Target, TargetSize, View, ViewRect, 
				FSceneRenderTargets::Get(RHICmdList).GetSceneColorTexture(),
				FSceneRenderTargets::Get(RHICmdList).GBufferD->GetRenderTargetItem().TargetableTexture, false);

			FSceneRenderTargets::Get_Todo_PassContent().AdjustGBufferRefCount(-1);
		}

		RHICmdList.CopyToResolveTarget(TextureRenderTarget->GetRenderTargetTexture(), TextureRenderTarget->TextureRHI, false, ResolveParams);
	}
	FSceneRenderer::WaitForTasksClearSnapshotsAndDeleteSceneRenderer(RHICmdList, SceneRenderer);
}

void FSceneCaptureModify::UpdateSceneCaptureContents(
	USceneCaptureComponent2D* CaptureComponent,
	FMatrix const& ProjectionMatrix,
	bool bDrawHiddenOnly)
{
	check(CaptureComponent);

	if (CaptureComponent->TextureTarget)
	{
		FTransform Transform = CaptureComponent->GetComponentToWorld();
		FVector ViewLocation = Transform.GetTranslation();

		// Remove the translation from Transform because we only need rotation.
		Transform.SetTranslation(FVector::ZeroVector);
		FMatrix ViewRotationMatrix = Transform.ToInverseMatrixWithScale();

		// swap axis st. x=z,y=x,z=y (unreal coord space) so that z is up
		ViewRotationMatrix = ViewRotationMatrix * FMatrix(
			FPlane(0, 0, 1, 0),
			FPlane(1, 0, 0, 0),
			FPlane(0, 1, 0, 0),
			FPlane(0, 0, 0, 1));
		
		const bool bUseSceneColorTexture = CaptureComponent->CaptureSource == SCS_SceneColorHDR;
		FSceneRenderer* SceneRenderer = CreateSceneRenderer(
			CaptureComponent, CaptureComponent->TextureTarget, ViewRotationMatrix, ViewLocation, 
			ProjectionMatrix, CaptureComponent->MaxViewDistanceOverride, 
			bUseSceneColorTexture, 
			&CaptureComponent->PostProcessSettings, CaptureComponent->PostProcessBlendWeight, bDrawHiddenOnly);

		FTextureRenderTargetResource* TextureRenderTarget = CaptureComponent->TextureTarget->GameThread_GetRenderTargetResource();
		const FName OwnerName = CaptureComponent->GetOwner() ? CaptureComponent->GetOwner()->GetFName() : NAME_None;

		ENQUEUE_UNIQUE_RENDER_COMMAND_FOURPARAMETER(
			CaptureCommand,
			FSceneRenderer*, SceneRenderer, SceneRenderer,
			FTextureRenderTargetResource*, TextureRenderTarget, TextureRenderTarget,
			FName, OwnerName, OwnerName,
			bool, bUseSceneColorTexture, bUseSceneColorTexture,
			{
				UpdateSceneCaptureContent_RenderThread(RHICmdList, SceneRenderer, TextureRenderTarget, OwnerName, FResolveParams(), bUseSceneColorTexture);
			});
	}
}

FSceneRenderer* FSceneCaptureModify::CreateSceneRenderer(
	USceneCaptureComponent* SceneCaptureComponent, 
	UTextureRenderTarget* TextureTarget, 
	const FMatrix& ViewRotationMatrix, 
	const FVector& ViewLocation, 
	const FMatrix& ProjectionMatrix, 
	float MaxViewDistance, 
	bool bCaptureSceneColour, 
	FPostProcessSettings* PostProcessSettings, 
	float PostProcessBlendWeight,
	bool bDrawHiddenOnly)
{
	FSceneInterface* Scene = SceneCaptureComponent->GetWorld()->Scene;

	FIntPoint CaptureSize(TextureTarget->GetSurfaceWidth(), TextureTarget->GetSurfaceHeight());

	FTextureRenderTargetResource* Resource = TextureTarget->GameThread_GetRenderTargetResource();
	FSceneViewFamily::ConstructionValues ConstructionValues(
		Resource,
		Scene,
		SceneCaptureComponent->ShowFlags);
	ConstructionValues.SetResolveScene(!bCaptureSceneColour);

	FSceneViewFamilyContext ViewFamily(ConstructionValues);

	FSceneViewInitOptions ViewInitOptions;
	ViewInitOptions.SetViewRectangle(FIntRect(0, 0, CaptureSize.X, CaptureSize.Y));
	ViewInitOptions.ViewFamily = &ViewFamily;
	ViewInitOptions.ViewOrigin = ViewLocation;
	ViewInitOptions.ViewRotationMatrix = ViewRotationMatrix;
	ViewInitOptions.BackgroundColor = FLinearColor::Black;
	ViewInitOptions.OverrideFarClippingPlaneDistance = MaxViewDistance;
	ViewInitOptions.SceneViewStateInterface = SceneCaptureComponent->GetViewState();

	if (bCaptureSceneColour)
	{
		ViewFamily.EngineShowFlags.PostProcessing = 0;
		ViewInitOptions.OverlayColor = FLinearColor::Black;
	}

	ViewInitOptions.ProjectionMatrix = ProjectionMatrix;

	FSceneView* View = new FSceneView(ViewInitOptions);

	View->bIsSceneCapture = true;

	check(SceneCaptureComponent);
	if (bDrawHiddenOnly)
	{
		for (auto It = SceneCaptureComponent->HiddenComponents.CreateConstIterator(); It; ++It)
		{
			// If the primitive component was destroyed, the weak pointer will return NULL.
			UPrimitiveComponent* PrimitiveComponent = It->Get();
			if (PrimitiveComponent)
			{
				View->ShowPrimitives.Add(PrimitiveComponent->ComponentId);
			}
		}
	}
	else
	{
		for (auto It = SceneCaptureComponent->HiddenComponents.CreateConstIterator(); It; ++It)
		{
			// If the primitive component was destroyed, the weak pointer will return NULL.
			UPrimitiveComponent* PrimitiveComponent = It->Get();
			if (PrimitiveComponent)
			{
				View->HiddenPrimitives.Add(PrimitiveComponent->ComponentId);
			}
		}
	}

	ViewFamily.Views.Add(View);

	View->StartFinalPostprocessSettings(ViewLocation);
	View->OverridePostProcessSettings(*PostProcessSettings, PostProcessBlendWeight);
	View->EndFinalPostprocessSettings(ViewInitOptions);

	return FSceneRenderer::CreateSceneRenderer(&ViewFamily, NULL);
}

We Add ShowPrimitives in SceneView.h



/** The primitives which are show for this view **/
TSet<FPrimitiveComponentId> ShowPrimitives;

And Modify SceneVisbility.cpp

void FSceneRenderer::ComputeViewVisibility(FRHICommandListImmediate& RHICmdList)



// If any primitives are explicitly show, hide others.
if (View.ShowPrimitive.Num())
{
	for (FSceneSetBitIterator BitIt(View.PrimitiveVisibilityMap); BitIt; ++BitIt)
	{
		if (View.ShowPrimitives.Contains(Scene->PrimitiveComponentIds[BitIt.GetIndex()]))
		{
			View.PrimitiveVisibilityMap.AccessCorrespondingBit(BitIt) = true;
		}
		else
		{
			View.PrimitiveVisibilityMap.AccessCorrespondingBit(BitIt) = false;
		}
	}
}

// If any primitives are explicitly hidden, remove them now.
if (View.HiddenPrimitives.Num())
{
	for (FSceneSetBitIterator BitIt(View.PrimitiveVisibilityMap); BitIt; ++BitIt)
	{
		if (View.HiddenPrimitives.Contains(Scene->PrimitiveComponentIds[BitIt.GetIndex()]))
		{
			View.PrimitiveVisibilityMap.AccessCorrespondingBit(BitIt) = false;
		}
	}
}


now we can let SceneCaptureComponent2D has Alpha Channel

[=icemark_liang;462669]
because Alpha channel Save in GBufferD’s R channel

so we Add ScreenPixelAlphaShder.usf to write alpha channel


#include "Common.usf"

Texture2D InTexture;
SamplerState InTextureSampler;

Texture2D InAlphaTexture;
SamplerState InAlphaTextureSampler;

void Main(FScreenVertexOutput Input,
    out float4 OutColor : SV_Target0)
{
    OutColor = Texture2DSample(InTexture, InTextureSampler, Input.UV);
    OutColor.a = Texture2DSample(InAlphaTexture, InAlphaTextureSampler, Input.UV).r;
}

Add FScreenAlphaPS class in ScreenRendering.h


class FScreenAlphaPS : public FGlobalShader
{
    DECLARE_EXPORTED_SHADER_TYPE(FScreenPS, Global, ENGINE_API);
public:

    static bool ShouldCache(EShaderPlatform Platform) { return true; }

    FScreenAlphaPS(const ShaderMetaType::CompiledShaderInitializerType& Initializer) :
        FGlobalShader(Initializer)
    {
        InTexture.Bind(Initializer.ParameterMap, TEXT("InTexture"), SPF_Mandatory);
        InTextureSampler.Bind(Initializer.ParameterMap, TEXT("InTextureSampler"));
        InAlphaTexture.Bind(Initializer.ParameterMap, TEXT("InAlphaTexture"), SPF_Mandatory);
        InAlphaTextureSampler.Bind(Initializer.ParameterMap, TEXT("InAlphaTextureSampler"));
    }
    FScreenAlphaPS() {}

    void SetParameters(FRHICommandList& RHICmdList, const FTexture* Texture)
    {
        SetTextureParameter(RHICmdList, GetPixelShader(), InTexture, InTextureSampler, Texture);
    }

    void SetParameters(FRHICommandList& RHICmdList, FSamplerStateRHIParamRef SamplerStateRHI, FTextureRHIParamRef TextureRHI)
    {
        SetTextureParameter(RHICmdList, GetPixelShader(), InTexture, InTextureSampler, SamplerStateRHI, TextureRHI);
    }

    void SetAlphaParameters(FRHICommandList& RHICmdList, const FTexture* Texture)
    {
        SetTextureParameter(RHICmdList, GetPixelShader(), InAlphaTexture, InAlphaTextureSampler, Texture);
    }

    void SetAlphaParameters(FRHICommandList& RHICmdList, FSamplerStateRHIParamRef SamplerStateRHI, FTextureRHIParamRef TextureRHI)
    {
        SetTextureParameter(RHICmdList, GetPixelShader(), InAlphaTexture, InAlphaTextureSampler, SamplerStateRHI, TextureRHI);
    }

    virtual bool Serialize(FArchive& Ar) override
    {
        bool bShaderHasOutdatedParameters = FGlobalShader::Serialize(Ar);
        Ar << InTexture;
        Ar << InTextureSampler;
        Ar << InAlphaTexture;
        Ar << InAlphaTextureSampler;
        return bShaderHasOutdatedParameters;
    }

private:
    FShaderResourceParameter InTexture;
    FShaderResourceParameter InTextureSampler;

    FShaderResourceParameter InAlphaTexture;
    FShaderResourceParameter InAlphaTextureSampler;
};


Add FScreenAlphaPS Implement in ScreenRendering.cpp


IMPLEMENT_SHADER_TYPE(, FScreenAlphaPS, TEXT("ScreenPixelAlphaShader"), TEXT("Main"), SF_Pixel);

We Add SceneCaputureModify.h


#pragma once

class USceneCaptureComponent2D;
class FSceneRenderer;
class USceneCaptureComponent;
class UTextureRenderTarget;
class FRHICommandListImmediate;

class RENDERER_API FSceneCaptureModify
{
public:
    static void UpdateSceneCaptureContents(
        USceneCaptureComponent2D* CaptureComponent, 
        FMatrix const& ProjectionMatrix, 
        bool bDrawHiddenOnly);
private:
    static void FSceneRenderer* CreateSceneRenderer(
        USceneCaptureComponent* SceneCaptureComponent, 
        UTextureRenderTarget* TextureTarget, 
        const FMatrix& ViewRotationMatrix, 
        const FVector& ViewLocation, 
        const FMatrix& ProjectionMatrix, 
        float MaxViewDistance, 
        bool bCaptureSceneColour, 
        FPostProcessSettings* PostProcessSettings, 
        float PostProcessBlendWeight
        bool bDrawHiddenOnly);

    static void UpdateSceneCaptureContent_RenderThread(
        FRHICommandListImmediate& RHICmdList, FSceneRenderer* SceneRenderer, 
        FTextureRenderTargetResource* TextureRenderTarget, 
        const FName OwnerName, 
        const FResolveParams& ResolveParams, 
        bool bUseSceneColorTexture)
};





then modify SceneCaptureRendering Add CopyCaptureToTargetWithAlpha


static void CopyCaptureToTargetWithAlpha(
    FRHICommandListImmediate& RHICmdList, 
    const FRenderTarget* Target, const FIntPoint& TargetSize, FViewInfo& View, const FIntRect& ViewRect, 
    FTextureRHIParamRef SourceTextureRHI,
    FTextureRHIParamRef AlphaTextureRHI, 
    bool bNeedsFlippedRenderTarget)
{
    SetRenderTarget(RHICmdList, Target->GetRenderTargetTexture(), NULL);

    RHICmdList.SetRasterizerState(TStaticRasterizerState<FM_Solid, CM_None>::GetRHI());
    RHICmdList.SetDepthStencilState(TStaticDepthStencilState<false, CF_Always>::GetRHI());
    RHICmdList.SetBlendState(TStaticBlendState<>::GetRHI());

    TShaderMapRef<FScreenVS> VertexShader(View.ShaderMap);
    TShaderMapRef<FScreenAlphaPS> PixelShader(View.ShaderMap);
    static FGlobalBoundShaderState BoundShaderState;
    SetGlobalBoundShaderState(RHICmdList, View.GetFeatureLevel(), BoundShaderState, GFilterVertexDeclaration.VertexDeclarationRHI, *VertexShader, *PixelShader);

    FRenderingCompositePassContext Context(RHICmdList, View);

    VertexShader->SetParameters(RHICmdList, View);
    PixelShader->SetParameters(RHICmdList, TStaticSamplerState<SF_Point>::GetRHI(), SourceTextureRHI);
    PixelShader->SetAlphaParameters(RHICmdList, TStaticSamplerState<SF_Point>::GetRHI(), AlphaTextureRHI);

    if (bNeedsFlippedRenderTarget)
    {
        DrawRectangle(
            RHICmdList,
            ViewRect.Min.X, ViewRect.Min.Y,
            ViewRect.Width(), ViewRect.Height(),
            ViewRect.Min.X, ViewRect.Height() - ViewRect.Min.Y,
            ViewRect.Width(), -ViewRect.Height(),
            TargetSize,
            TargetSize,
            *VertexShader,
            EDRF_UseTriangleOptimization);
    }
    else
    {
        DrawRectangle(
            RHICmdList,
            ViewRect.Min.X, ViewRect.Min.Y,
            ViewRect.Width(), ViewRect.Height(),
            ViewRect.Min.X, ViewRect.Min.Y,
            ViewRect.Width(), ViewRect.Height(),
            TargetSize,
            FSceneRenderTargets::Get(RHICmdList).GetBufferSizeXY(),
            *VertexShader,
            EDRF_UseTriangleOptimization);
    }
}


void FSceneCaptureModify::UpdateSceneCaptureContent_RenderThread(
        FRHICommandListImmediate& RHICmdList, 
        FSceneRenderer* SceneRenderer, 
        FTextureRenderTargetResource* TextureRenderTarget, 
        const FName OwnerName, 
        const FResolveParams& ResolveParams, 
        bool bUseSceneColorTexture)
{
    FMemMark MemStackMark(FMemStack::Get());

    // update any resources that needed a deferred update
    FDeferredUpdateResource::UpdateResources(RHICmdList);

    {
#if WANTS_DRAW_MESH_EVENTS
        FString EventName;
        OwnerName.ToString(EventName);
        SCOPED_DRAW_EVENTF(RHICmdList, SceneCapture, TEXT("SceneCapture %s"), *EventName);
#else
        SCOPED_DRAW_EVENT(RHICmdList, UpdateSceneCaptureContent_RenderThread);
#endif

        const bool bIsMobileHDR = IsMobileHDR();
        const bool bRHINeedsFlip = RHINeedsToSwitchVerticalAxis(GMaxRHIShaderPlatform);
        const bool bNeedsFlippedRenderTarget = !bIsMobileHDR && bRHINeedsFlip;

        // Intermediate render target that will need to be flipped (needed on !IsMobileHDR())
        TRefCountPtr<IPooledRenderTarget> FlippedPooledRenderTarget;

        const FRenderTarget* Target = SceneRenderer->ViewFamily.RenderTarget;
        if (bNeedsFlippedRenderTarget)
        {
            // We need to use an intermediate render target since the result will be flipped
            auto& RenderTarget = Target->GetRenderTargetTexture();
            FPooledRenderTargetDesc Desc(FPooledRenderTargetDesc::Create2DDesc(Target->GetSizeXY(),
                RenderTarget.GetReference()->GetFormat(),
                FClearValueBinding::None,
                TexCreate_None,
                TexCreate_RenderTargetable,
                false));
            GRenderTargetPool.FindFreeElement(Desc, FlippedPooledRenderTarget, TEXT("SceneCaptureFlipped"));
        }

        // Helper class to allow setting render target
        struct FRenderTargetOverride : public FRenderTarget
        {
            FRenderTargetOverride(FRHITexture2D* In)
            {
                RenderTargetTextureRHI = In;
            }

            virtual FIntPoint GetSizeXY() const { return FIntPoint(RenderTargetTextureRHI->GetSizeX(), RenderTargetTextureRHI->GetSizeY()); }

            FTexture2DRHIRef GetTextureParamRef() { return RenderTargetTextureRHI; }
        } FlippedRenderTarget(
            FlippedPooledRenderTarget.GetReference()
            ? FlippedPooledRenderTarget.GetReference()->GetRenderTargetItem().TargetableTexture->GetTexture2D()
            : nullptr);
        FViewInfo& View = SceneRenderer->Views[0];
        FIntRect ViewRect = View.ViewRect;
        FIntRect UnconstrainedViewRect = View.UnconstrainedViewRect;
        SetRenderTarget(RHICmdList, Target->GetRenderTargetTexture(), NULL);
        RHICmdList.Clear(true, FLinearColor::Black, false, (float)ERHIZBuffer::FarPlane, false, 0, ViewRect);

        // Render the scene normally
        {
            SCOPED_DRAW_EVENT(RHICmdList, RenderScene);

            if (bNeedsFlippedRenderTarget)
            {
                // Hijack the render target
                SceneRenderer->ViewFamily.RenderTarget = &FlippedRenderTarget; //-V506
            }
            SceneRenderer->Render(RHICmdList);
            if (bNeedsFlippedRenderTarget)
            {
                // And restore it
                SceneRenderer->ViewFamily.RenderTarget = Target;
            }
        }

        const FIntPoint TargetSize(UnconstrainedViewRect.Width(), UnconstrainedViewRect.Height());
        if (bNeedsFlippedRenderTarget)
        {
            // We need to flip this texture upside down (since we depended on tonemapping to fix this on the hdr path)
            SCOPED_DRAW_EVENT(RHICmdList, FlipCapture);

            
            CopyCaptureToTarget(RHICmdList, Target, TargetSize, View, ViewRect, FlippedRenderTarget.GetTextureParamRef(), true);
        }
        else if (bUseSceneColorTexture && (bIsMobileHDR || SceneRenderer->FeatureLevel >= ERHIFeatureLevel::SM4))
        {
            // Copy the captured scene into the destination texture (only required on HDR or deferred as that implies post-processing)
            SCOPED_DRAW_EVENT(RHICmdList, CaptureSceneColor);

            FSceneRenderTargets::Get_Todo_PassContent().AdjustGBufferRefCount(1);

            CopyCaptureToTargetWithAlpha(RHICmdList, Target, TargetSize, View, ViewRect, 
                FSceneRenderTargets::Get(RHICmdList).GetSceneColorTexture(),
                FSceneRenderTargets::Get(RHICmdList).GBufferD->GetRenderTargetItem().TargetableTexture, false);

            FSceneRenderTargets::Get_Todo_PassContent().AdjustGBufferRefCount(-1);
        }

        RHICmdList.CopyToResolveTarget(TextureRenderTarget->GetRenderTargetTexture(), TextureRenderTarget->TextureRHI, false, ResolveParams);
    }
    FSceneRenderer::WaitForTasksClearSnapshotsAndDeleteSceneRenderer(RHICmdList, SceneRenderer);
}

void FSceneCaptureModify::UpdateSceneCaptureContents(
    USceneCaptureComponent2D* CaptureComponent,
    FMatrix const& ProjectionMatrix,
    bool bDrawHiddenOnly)
{
    check(CaptureComponent);

    if (CaptureComponent->TextureTarget)
    {
        FTransform Transform = CaptureComponent->GetComponentToWorld();
        FVector ViewLocation = Transform.GetTranslation();

        // Remove the translation from Transform because we only need rotation.
        Transform.SetTranslation(FVector::ZeroVector);
        FMatrix ViewRotationMatrix = Transform.ToInverseMatrixWithScale();

        // swap axis st. x=z,y=x,z=y (unreal coord space) so that z is up
        ViewRotationMatrix = ViewRotationMatrix * FMatrix(
            FPlane(0, 0, 1, 0),
            FPlane(1, 0, 0, 0),
            FPlane(0, 1, 0, 0),
            FPlane(0, 0, 0, 1));
        
        const bool bUseSceneColorTexture = CaptureComponent->CaptureSource == SCS_SceneColorHDR;
        FSceneRenderer* SceneRenderer = CreateSceneRenderer(
            CaptureComponent, CaptureComponent->TextureTarget, ViewRotationMatrix, ViewLocation, 
            ProjectionMatrix, CaptureComponent->MaxViewDistanceOverride, 
            bUseSceneColorTexture, 
            &CaptureComponent->PostProcessSettings, CaptureComponent->PostProcessBlendWeight, bDrawHiddenOnly);

        FTextureRenderTargetResource* TextureRenderTarget = CaptureComponent->TextureTarget->GameThread_GetRenderTargetResource();
        const FName OwnerName = CaptureComponent->GetOwner() ? CaptureComponent->GetOwner()->GetFName() : NAME_None;

        ENQUEUE_UNIQUE_RENDER_COMMAND_FOURPARAMETER(
            CaptureCommand,
            FSceneRenderer*, SceneRenderer, SceneRenderer,
            FTextureRenderTargetResource*, TextureRenderTarget, TextureRenderTarget,
            FName, OwnerName, OwnerName,
            bool, bUseSceneColorTexture, bUseSceneColorTexture,
            {
                UpdateSceneCaptureContent_RenderThread(RHICmdList, SceneRenderer, TextureRenderTarget, OwnerName, FResolveParams(), bUseSceneColorTexture);
            });
    }
}

FSceneRenderer* FSceneCaptureModify::CreateSceneRenderer(
    USceneCaptureComponent* SceneCaptureComponent, 
    UTextureRenderTarget* TextureTarget, 
    const FMatrix& ViewRotationMatrix, 
    const FVector& ViewLocation, 
    const FMatrix& ProjectionMatrix, 
    float MaxViewDistance, 
    bool bCaptureSceneColour, 
    FPostProcessSettings* PostProcessSettings, 
    float PostProcessBlendWeight,
    bool bDrawHiddenOnly)
{
    FSceneInterface* Scene = SceneCaptureComponent->GetWorld()->Scene;

    FIntPoint CaptureSize(TextureTarget->GetSurfaceWidth(), TextureTarget->GetSurfaceHeight());

    FTextureRenderTargetResource* Resource = TextureTarget->GameThread_GetRenderTargetResource();
    FSceneViewFamily::ConstructionValues ConstructionValues(
        Resource,
        Scene,
        SceneCaptureComponent->ShowFlags);
    ConstructionValues.SetResolveScene(!bCaptureSceneColour);

    FSceneViewFamilyContext ViewFamily(ConstructionValues);

    FSceneViewInitOptions ViewInitOptions;
    ViewInitOptions.SetViewRectangle(FIntRect(0, 0, CaptureSize.X, CaptureSize.Y));
    ViewInitOptions.ViewFamily = &ViewFamily;
    ViewInitOptions.ViewOrigin = ViewLocation;
    ViewInitOptions.ViewRotationMatrix = ViewRotationMatrix;
    ViewInitOptions.BackgroundColor = FLinearColor::Black;
    ViewInitOptions.OverrideFarClippingPlaneDistance = MaxViewDistance;
    ViewInitOptions.SceneViewStateInterface = SceneCaptureComponent->GetViewState();

    if (bCaptureSceneColour)
    {
        ViewFamily.EngineShowFlags.PostProcessing = 0;
        ViewInitOptions.OverlayColor = FLinearColor::Black;
    }

    ViewInitOptions.ProjectionMatrix = ProjectionMatrix;

    FSceneView* View = new FSceneView(ViewInitOptions);

    View->bIsSceneCapture = true;

    check(SceneCaptureComponent);
    if (bDrawHiddenOnly)
    {
        for (auto It = SceneCaptureComponent->HiddenComponents.CreateConstIterator(); It; ++It)
        {
            // If the primitive component was destroyed, the weak pointer will return NULL.
            UPrimitiveComponent* PrimitiveComponent = It->Get();
            if (PrimitiveComponent)
            {
                View->ShowPrimitives.Add(PrimitiveComponent->ComponentId);
            }
        }
    }
    else
    {
        for (auto It = SceneCaptureComponent->HiddenComponents.CreateConstIterator(); It; ++It)
        {
            // If the primitive component was destroyed, the weak pointer will return NULL.
            UPrimitiveComponent* PrimitiveComponent = It->Get();
            if (PrimitiveComponent)
            {
                View->HiddenPrimitives.Add(PrimitiveComponent->ComponentId);
            }
        }
    }

    ViewFamily.Views.Add(View);

    View->StartFinalPostprocessSettings(ViewLocation);
    View->OverridePostProcessSettings(*PostProcessSettings, PostProcessBlendWeight);
    View->EndFinalPostprocessSettings(ViewInitOptions);

    return FSceneRenderer::CreateSceneRenderer(&ViewFamily, NULL);
}

We Add ShowPrimitives in SceneView.h



/** The primitives which are show for this view **/
TSet<FPrimitiveComponentId> ShowPrimitives;

And Modify SceneVisbility.cpp

void FSceneRenderer::ComputeViewVisibility(FRHICommandListImmediate& RHICmdList)



// If any primitives are explicitly show, hide others.
if (View.ShowPrimitive.Num())
{
    for (FSceneSetBitIterator BitIt(View.PrimitiveVisibilityMap); BitIt; ++BitIt)
    {
        if (View.ShowPrimitives.Contains(Scene->PrimitiveComponentIds[BitIt.GetIndex()]))
        {
            View.PrimitiveVisibilityMap.AccessCorrespondingBit(BitIt) = true;
        }
        else
        {
            View.PrimitiveVisibilityMap.AccessCorrespondingBit(BitIt) = false;
        }
    }
}

// If any primitives are explicitly hidden, remove them now.
if (View.HiddenPrimitives.Num())
{
    for (FSceneSetBitIterator BitIt(View.PrimitiveVisibilityMap); BitIt; ++BitIt)
    {
        if (View.HiddenPrimitives.Contains(Scene->PrimitiveComponentIds[BitIt.GetIndex()]))
        {
            View.PrimitiveVisibilityMap.AccessCorrespondingBit(BitIt) = false;
        }
    }
}


now we can let SceneCaptureComponent2D has Alpha Channel
[/]

Hi icemark_liang,

I would highly recommend making a pull request for this. To do so, follow the instructions found here:

https://help.github.com/articles/creating-a-pull-request/