358 lines
11 KiB
C++
358 lines
11 KiB
C++
|
|
#include "VRM4URender.h"
|
|
#include "CoreMinimal.h"
|
|
#include "VRM4URenderLog.h"
|
|
#include "Interfaces/IPluginManager.h"
|
|
#include "Modules/ModuleManager.h"
|
|
#include "Misc/Paths.h"
|
|
#include "ShaderCore.h"
|
|
#include "Internationalization/Internationalization.h"
|
|
|
|
|
|
#include "VrmBPFunctionLibrary.h"
|
|
#include "VRM4U_RenderSubsystem.h"
|
|
#include "VrmExtensionRimFilterData.h"
|
|
#include "RenderGraphBuilder.h"
|
|
#include "RenderGraphResources.h"
|
|
#include "RenderGraphUtils.h"
|
|
#include "EngineModule.h"
|
|
#include "Engine/TextureRenderTarget2D.h"
|
|
#include "TextureResource.h"
|
|
#include "Engine/SkeletalMesh.h"
|
|
#include "RendererInterface.h"
|
|
#include "ScreenPass.h"
|
|
#include "Runtime/Renderer/Private/SceneRendering.h"
|
|
#include "SceneRenderTargetParameters.h"
|
|
#include "Slate/SceneViewport.h"
|
|
#include "ScreenRendering.h"
|
|
#include "SceneView.h"
|
|
#include "SceneRendering.h"
|
|
|
|
|
|
#define LOCTEXT_NAMESPACE "VRM4URender"
|
|
|
|
DEFINE_LOG_CATEGORY(LogVRM4URender);
|
|
|
|
bool FVRM4URenderModule::isCaptureTarget(const FSceneView* View) {
|
|
|
|
bool bCapture = false;
|
|
|
|
bool bPlay = false;
|
|
bool bSIE = false;
|
|
bool bEditor = false;
|
|
UVrmBPFunctionLibrary::VRMGetPlayMode(bPlay, bSIE, bEditor);
|
|
|
|
UWorld* World = View->Family->Scene->GetWorld();
|
|
if (World) {
|
|
EWorldType::Type WorldType = World->WorldType;
|
|
|
|
if (bPlay) {
|
|
switch (WorldType) {
|
|
case EWorldType::Game:
|
|
case EWorldType::PIE:
|
|
bCapture = true;
|
|
break;
|
|
}
|
|
} else {
|
|
switch (WorldType) {
|
|
case EWorldType::Editor:
|
|
bCapture = true;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
if (View->bIsGameView) {
|
|
bCapture = true;
|
|
}
|
|
if (View->bIsOfflineRender) {
|
|
bCapture = true;
|
|
}
|
|
if (View->bIsSceneCapture) {
|
|
bCapture = false;
|
|
}
|
|
|
|
return bCapture;
|
|
}
|
|
|
|
void FVRM4URenderModule::AddCopyPass(FRDGBuilder &GraphBuilder, FIntPoint ViewRectSize, FRDGTextureRef SrcRDGTex, TObjectPtr<UTextureRenderTarget2D> RenderTarget) {
|
|
|
|
if (SrcRDGTex == nullptr) {
|
|
return;
|
|
}
|
|
if (RenderTarget == nullptr) {
|
|
return;
|
|
}
|
|
|
|
//FPostOpaqueRenderParameters& Parameters
|
|
//const FIntPoint ViewRectSize = FIntPoint(Parameters.ViewportRect.Width(), Parameters.ViewportRect.Height());
|
|
|
|
AddPass(GraphBuilder, RDG_EVENT_NAME("VRM4UAddCopyPass"), [ViewRectSize, SrcRDGTex, RenderTarget](FRHICommandListImmediate& RHICmdList)
|
|
{
|
|
if (SrcRDGTex == nullptr) return;
|
|
if (SrcRDGTex->GetRHI() == nullptr) return;
|
|
|
|
const FIntPoint TargetSize(RenderTarget->GetRenderTargetResource()->GetSizeX(), RenderTarget->GetRenderTargetResource()->GetSizeY());
|
|
|
|
FRHITexture* DestRenderTarget = RenderTarget->GetRenderTargetResource()->GetTextureRHI();
|
|
|
|
FRHIRenderPassInfo RPInfo(DestRenderTarget, ERenderTargetActions::Load_Store);
|
|
RHICmdList.BeginRenderPass(RPInfo, TEXT("VRM4U_Copy"));
|
|
{
|
|
RHICmdList.SetViewport(0, 0, 0.0f, TargetSize.X, TargetSize.Y, 1.0f);
|
|
|
|
const ERHIFeatureLevel::Type FeatureLevel = GMaxRHIFeatureLevel;
|
|
FGlobalShaderMap* ShaderMap = GetGlobalShaderMap(FeatureLevel);
|
|
TShaderMapRef<FScreenVS> VertexShader(ShaderMap);
|
|
TShaderMapRef<FScreenPS> PixelShader(ShaderMap);
|
|
|
|
FGraphicsPipelineStateInitializer GraphicsPSOInit;
|
|
RHICmdList.ApplyCachedRenderTargets(GraphicsPSOInit);
|
|
GraphicsPSOInit.BlendState = TStaticBlendState<>::GetRHI();
|
|
GraphicsPSOInit.RasterizerState = TStaticRasterizerState<>::GetRHI();
|
|
GraphicsPSOInit.DepthStencilState = TStaticDepthStencilState<false, CF_Always>::GetRHI();
|
|
GraphicsPSOInit.BoundShaderState.VertexDeclarationRHI = GFilterVertexDeclaration.VertexDeclarationRHI;
|
|
GraphicsPSOInit.BoundShaderState.VertexShaderRHI = static_cast<FRHIVertexShader*>(VertexShader.GetRHIShaderBase(SF_Vertex));
|
|
GraphicsPSOInit.BoundShaderState.PixelShaderRHI = static_cast<FRHIPixelShader*>(PixelShader.GetRHIShaderBase(SF_Pixel));
|
|
GraphicsPSOInit.PrimitiveType = PT_TriangleList;
|
|
SetGraphicsPipelineState(RHICmdList, GraphicsPSOInit, 0);
|
|
|
|
FRHITexture* SceneTexture = SrcRDGTex->GetRHI()->GetTexture2D();
|
|
|
|
#if UE_VERSION_OLDER_THAN(5,3,0)
|
|
PixelShader->SetParameters(RHICmdList, TStaticSamplerState<SF_Bilinear>::GetRHI(), SceneTexture);
|
|
#else
|
|
FRHIBatchedShaderParameters& BatchedParameters = RHICmdList.GetScratchShaderParameters();
|
|
PixelShader->SetParameters(BatchedParameters, TStaticSamplerState<SF_Bilinear>::GetRHI(), SceneTexture);
|
|
RHICmdList.SetBatchedShaderParameters(RHICmdList.GetBoundPixelShader(), BatchedParameters);
|
|
#endif
|
|
IRendererModule* RendererModule = &FModuleManager::GetModuleChecked<IRendererModule>(TEXT("Renderer"));
|
|
RendererModule->DrawRectangle(
|
|
RHICmdList,
|
|
0, 0, // Dest X, Y
|
|
TargetSize.X, TargetSize.Y, // Dest Width, Height
|
|
0, 0, // Source U, V
|
|
ViewRectSize.X, ViewRectSize.Y, // Source USize, VSize
|
|
TargetSize, // Target buffer size
|
|
FIntPoint(SceneTexture->GetSizeX(), SceneTexture->GetSizeY()), // Source texture size
|
|
VertexShader,
|
|
EDRF_Default);
|
|
}
|
|
RHICmdList.EndRenderPass();
|
|
});
|
|
}
|
|
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
// FSpriterImporterModule
|
|
|
|
#if WITH_EDITOR
|
|
void FVRM4URenderModule::OnMapChange(UWorld* World, EMapChangeType ChangeType) {
|
|
if (ChangeType == EMapChangeType::TearDownWorld)
|
|
{
|
|
CaptureList.Empty();
|
|
}
|
|
}
|
|
|
|
void FVRM4URenderModule::OnPIEEvent(bool bPIEBegin, bool bPIEEnd) {
|
|
bIsPlay = bPIEBegin;
|
|
}
|
|
#endif
|
|
|
|
|
|
void FVRM4URenderModule::StartupModule(){
|
|
FString PluginShaderDir = FPaths::Combine(IPluginManager::Get().FindPlugin(TEXT("VRM4U"))->GetBaseDir(), TEXT("Shaders"));
|
|
|
|
AddShaderSourceDirectoryMapping(TEXT("/VRM4UShaders"), PluginShaderDir);
|
|
|
|
GetRendererModule().RegisterPostOpaqueRenderDelegate(FPostOpaqueRenderDelegate::CreateRaw(this, &FVRM4URenderModule::OnPostOpaque));
|
|
GetRendererModule().RegisterOverlayRenderDelegate(FPostOpaqueRenderDelegate::CreateRaw(this, &FVRM4URenderModule::OnOverlay));
|
|
|
|
#if WITH_EDITOR
|
|
#else
|
|
bIsPlay = true;
|
|
#endif
|
|
}
|
|
|
|
void FVRM4URenderModule::ShutdownModule(){
|
|
}
|
|
|
|
void FVRM4URenderModule::OnPostOpaque(FPostOpaqueRenderParameters& Parameters) {
|
|
|
|
if (CaptureList.Num() == 0) return;
|
|
|
|
if (isCaptureTarget(Parameters.View) == false) {
|
|
return;
|
|
}
|
|
|
|
{
|
|
TArray<TObjectPtr<UTextureRenderTarget2D>> keys;
|
|
CaptureList.GetKeys(keys);
|
|
for (auto k : keys) {
|
|
if (IsValid(k) == false) {
|
|
CaptureList.Remove(k);
|
|
continue;
|
|
}
|
|
if (k->GetRenderTargetResource() == nullptr) {
|
|
CaptureList.Remove(k);
|
|
continue;
|
|
}
|
|
if (k->GetRenderTargetResource()->GetTexture2DRHI() == nullptr) {
|
|
CaptureList.Remove(k);
|
|
continue;
|
|
}
|
|
}
|
|
}
|
|
|
|
FRDGTextureRef DstRDGTex = nullptr;
|
|
FRDGTextureRef SrcRDGTex = nullptr;
|
|
|
|
for (auto c : CaptureList) {
|
|
if (c.Key == nullptr) {
|
|
continue;
|
|
}
|
|
if (c.Key->GetRenderTargetResource() == nullptr) {
|
|
continue;
|
|
}
|
|
|
|
DstRDGTex = RegisterExternalTexture(*(Parameters.GraphBuilder), c.Key->GetRenderTargetResource()->GetTexture2DRHI(), TEXT("VRM4U_CopyDst"));
|
|
switch (c.Value) {
|
|
case EVRM4U_CaptureSource::ColorTexturePostOpaque:
|
|
SrcRDGTex = Parameters.ColorTexture;
|
|
break;
|
|
case EVRM4U_CaptureSource::DepthTexture:
|
|
SrcRDGTex = Parameters.DepthTexture;
|
|
break;
|
|
case EVRM4U_CaptureSource::NormalTexture:
|
|
SrcRDGTex = Parameters.NormalTexture;
|
|
break;
|
|
case EVRM4U_CaptureSource::VelocityTexture:
|
|
SrcRDGTex = Parameters.VelocityTexture;
|
|
break;
|
|
//case EVRM4U_CaptureSource::SmallDepthTexture:
|
|
// SrcRDGTex = Parameters.SmallDepthTexture;
|
|
// break;
|
|
default:
|
|
break;
|
|
}
|
|
|
|
if (SrcRDGTex == nullptr && Parameters.SceneTexturesUniformParams == nullptr) continue;
|
|
switch (c.Value) {
|
|
case EVRM4U_CaptureSource::SceneColorTexturePostOpaque:
|
|
SrcRDGTex = Parameters.SceneTexturesUniformParams->GetParameters()->SceneColorTexture;
|
|
break;
|
|
case EVRM4U_CaptureSource::SceneDepthTexture:
|
|
SrcRDGTex = Parameters.SceneTexturesUniformParams->GetParameters()->SceneDepthTexture;
|
|
break;
|
|
//case EVRM4U_CaptureSource::ScenePartialDepthTexture:
|
|
// SrcRDGTex = Parameters.SceneTexturesUniformParams->GetParameters()->ScenePartialDepthTexture;
|
|
// break;
|
|
|
|
// GBuffer
|
|
case EVRM4U_CaptureSource::GBufferATexture:
|
|
SrcRDGTex = Parameters.SceneTexturesUniformParams->GetParameters()->GBufferATexture;
|
|
break;
|
|
case EVRM4U_CaptureSource::GBufferBTexture:
|
|
SrcRDGTex = Parameters.SceneTexturesUniformParams->GetParameters()->GBufferBTexture;
|
|
break;
|
|
case EVRM4U_CaptureSource::GBufferCTexture:
|
|
SrcRDGTex = Parameters.SceneTexturesUniformParams->GetParameters()->GBufferCTexture;
|
|
break;
|
|
case EVRM4U_CaptureSource::GBufferDTexture:
|
|
SrcRDGTex = Parameters.SceneTexturesUniformParams->GetParameters()->GBufferDTexture;
|
|
break;
|
|
case EVRM4U_CaptureSource::GBufferETexture:
|
|
SrcRDGTex = Parameters.SceneTexturesUniformParams->GetParameters()->GBufferETexture;
|
|
break;
|
|
case EVRM4U_CaptureSource::GBufferFTexture:
|
|
SrcRDGTex = Parameters.SceneTexturesUniformParams->GetParameters()->GBufferFTexture;
|
|
break;
|
|
case EVRM4U_CaptureSource::GBufferVelocityTexture:
|
|
SrcRDGTex = Parameters.SceneTexturesUniformParams->GetParameters()->GBufferVelocityTexture;
|
|
break;
|
|
case EVRM4U_CaptureSource::ScreenSpaceAOTexture:
|
|
SrcRDGTex = Parameters.SceneTexturesUniformParams->GetParameters()->ScreenSpaceAOTexture;
|
|
break;
|
|
case EVRM4U_CaptureSource::CustomDepthTexture:
|
|
SrcRDGTex = Parameters.SceneTexturesUniformParams->GetParameters()->CustomDepthTexture;
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
|
|
if (DstRDGTex && SrcRDGTex) {
|
|
/*
|
|
FScreenPassRenderTarget DstTex(DstRDGTex, ERenderTargetLoadAction::EClear);
|
|
FScreenPassTexture SrcTex(SrcRDGTex);
|
|
|
|
AddDrawTexturePass(
|
|
*(Parameters.GraphBuilder),
|
|
*Parameters.View,
|
|
SrcTex,
|
|
DstTex
|
|
);
|
|
*/
|
|
FVRM4URenderModule::AddCopyPass(*Parameters.GraphBuilder, FIntPoint(Parameters.ViewportRect.Width(), Parameters.ViewportRect.Height()), SrcRDGTex, c.Key);
|
|
}
|
|
}
|
|
}
|
|
void FVRM4URenderModule::OnOverlay(FPostOpaqueRenderParameters& Parameters) {
|
|
if (CaptureList.Num() == 0) return;
|
|
|
|
if (isCaptureTarget(Parameters.View) == false) {
|
|
return;
|
|
}
|
|
|
|
for (auto c : CaptureList) {
|
|
if (c.Key == nullptr) {
|
|
continue;
|
|
}
|
|
if (c.Key->GetRenderTargetResource() == nullptr) {
|
|
continue;
|
|
}
|
|
|
|
FRDGTextureRef DstRDGTex = nullptr;
|
|
FRDGTextureRef SrcRDGTex = nullptr;
|
|
|
|
DstRDGTex = RegisterExternalTexture(*(Parameters.GraphBuilder), c.Key->GetRenderTargetResource()->GetTexture2DRHI(), TEXT("VRM4U_CopyDst"));
|
|
switch (c.Value) {
|
|
case EVRM4U_CaptureSource::ColorTextureOverlay:
|
|
SrcRDGTex = Parameters.ColorTexture;
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
|
|
if (SrcRDGTex == nullptr && Parameters.SceneTexturesUniformParams == nullptr) continue;
|
|
switch (c.Value) {
|
|
case EVRM4U_CaptureSource::SceneColorTextureOverlay:
|
|
SrcRDGTex = Parameters.SceneTexturesUniformParams->GetParameters()->SceneColorTexture;
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
|
|
if (DstRDGTex && SrcRDGTex) {
|
|
/*
|
|
FScreenPassRenderTarget DstTex(DstRDGTex, ERenderTargetLoadAction::EClear);
|
|
FScreenPassTexture SrcTex(SrcRDGTex);
|
|
AddDrawTexturePass(
|
|
*(Parameters.GraphBuilder),
|
|
*Parameters.View,
|
|
SrcTex,
|
|
DstTex);
|
|
*/
|
|
|
|
FVRM4URenderModule::AddCopyPass(*Parameters.GraphBuilder, FIntPoint(Parameters.ViewportRect.Width(), Parameters.ViewportRect.Height()), SrcRDGTex, c.Key);
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
|
|
IMPLEMENT_MODULE(FVRM4URenderModule, VRM4URender);
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
|
|
#undef LOCTEXT_NAMESPACE
|