Add Games File

This commit is contained in:
Ivan Anikin
2026-05-19 13:42:41 +07:00
parent 7908479e0c
commit 12e7e22c1a
3672 changed files with 125922 additions and 0 deletions
@@ -0,0 +1,357 @@
#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
@@ -0,0 +1,80 @@
#pragma once
#include "CoreMinimal.h"
#include "Modules/ModuleManager.h"
#include "Engine/TextureRenderTarget2D.h"
#include "RendererInterface.h"
//#include "VRMImporterModule.h"
//DECLARE_LOG_CATEGORY_EXTERN(LogVRM4URender, Verbose, All);
//#define SPRITER_IMPORT_ERROR(FormatString, ...) \
// if (!bSilent) { UE_LOG(LogVRM4URender, Warning, FormatString, __VA_ARGS__); }
//#define SPRITER_IMPORT_WARNING(FormatString, ...) \
// if (!bSilent) { UE_LOG(LogVRM4URender, Warning, FormatString, __VA_ARGS__); }
UENUM()
enum EVRM4U_CaptureSource : int
{
ColorTexturePostOpaque,
ColorTextureOverlay,
ColorTexturePreTonemap,
ColorTexturePostTonemap,
ColorTextureLastPass,
DepthTexture,
NormalTexture,
VelocityTexture,
//SmallDepthTexture,
SceneColorTexturePostOpaque,
SceneColorTextureOverlay,
SceneDepthTexture,
//ScenePartialDepthTexture,
// GBuffer
GBufferATexture,
GBufferBTexture,
GBufferCTexture,
GBufferDTexture,
GBufferETexture,
GBufferFTexture,
GBufferVelocityTexture,
// SSAO
ScreenSpaceAOTexture,
// Custom Depth / Stencil
CustomDepthTexture,
//CaptureSource_MAX,
};
class FVRM4URenderModule : public FDefaultModuleImpl
{
FDelegateHandle HandleTearDown;
bool bIsPlay = false;
public:
TMap<TObjectPtr<UTextureRenderTarget2D>, TEnumAsByte<EVRM4U_CaptureSource> > CaptureList;
virtual void StartupModule() override;
virtual void ShutdownModule() override;
void OnPostOpaque(FPostOpaqueRenderParameters& Parameters);
void OnOverlay(FPostOpaqueRenderParameters& Parameters);
#if WITH_EDITOR
void OnMapChange(UWorld* World, EMapChangeType ChangeType);
void OnPIEEvent(bool bPIEBegin, bool bPIEEnd);
#endif
static void AddCopyPass(FRDGBuilder& GraphBuilder, FIntPoint ViewRectSize, FRDGTextureRef SrcRDGTex, TObjectPtr<UTextureRenderTarget2D> RenderTarget);
static bool isCaptureTarget(const FSceneView* View);
};
@@ -0,0 +1,13 @@
#pragma once
#include "CoreMinimal.h"
DECLARE_LOG_CATEGORY_EXTERN(LogVRM4URender, Verbose, All);
//#define SPRITER_IMPORT_ERROR(FormatString, ...) \
// if (!bSilent) { UE_LOG(LogVRM4UMIsc, Warning, FormatString, __VA_ARGS__); }
//#define SPRITER_IMPORT_WARNING(FormatString, ...) \
// if (!bSilent) { UE_LOG(LogVRM4UMIsc, Warning, FormatString, __VA_ARGS__); }
@@ -0,0 +1,176 @@
// Fill out your copyright notice in the Description page of Project Settings.
#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"
#if UE_VERSION_OLDER_THAN(5,4,0)
#include "Runtime/Renderer/Private/SceneTextures.h"
#endif
#if WITH_EDITOR
#include "LevelEditor.h"
#endif
void UVRM4U_RenderSubsystem::Initialize(FSubsystemCollectionBase& Collection) {
Super::Initialize(Collection);
// generate
SceneViewExtension = FSceneViewExtensions::NewExtension<FVrmSceneViewExtension>();
}
void UVRM4U_RenderSubsystem::Deinitialize() {
{
FScopeLock lock(&cs_rim);
RimFilterData.Empty();
}
Super::Deinitialize();
}
void UVRM4U_RenderSubsystem::OnResolvedSceneColor_RenderThread(FRDGBuilder& GraphBuilder, const FSceneTextures& SceneTextures) {
}
#if WITH_EDITOR
void UVRM4U_RenderSubsystem::OnMapChange(UWorld* World, EMapChangeType ChangeType) {
FVRM4URenderModule* m = FModuleManager::GetModulePtr<FVRM4URenderModule>("VRM4URender");
if (m != nullptr) {
m->OnMapChange(World, ChangeType);
}
}
void UVRM4U_RenderSubsystem::OnPIEEvent(bool bPIEBegin, bool bPIEEnd) {
FVRM4URenderModule* m = FModuleManager::GetModulePtr<FVRM4URenderModule>("VRM4URender");
if (m != nullptr) {
m->OnPIEEvent(bPIEBegin, bPIEEnd);
}
}
#endif
void UVRM4U_RenderSubsystem::RenderPre(FRDGBuilder& GraphBuilder) {
}
void UVRM4U_RenderSubsystem::RenderPost(FRDGBuilder& GraphBuilder) {
}
void UVRM4U_RenderSubsystem::AddCaptureTexture(UTextureRenderTarget2D* Texture, EVRM4U_CaptureSource CaptureSource) {
if (Texture == nullptr) return;
FVRM4URenderModule* m = FModuleManager::GetModulePtr<FVRM4URenderModule>("VRM4URender");
if (m != nullptr){
m->CaptureList.FindOrAdd(Texture) = CaptureSource;
}
#if WITH_EDITOR
if (HandleTearDown.IsValid() == false){
if (FModuleManager::Get().IsModuleLoaded("LevelEditor"))
{
FLevelEditorModule& LevelEditor = FModuleManager::GetModuleChecked<FLevelEditorModule>("LevelEditor");
HandleTearDown = LevelEditor.OnMapChanged().AddUObject(this, &UVRM4U_RenderSubsystem::OnMapChange);
/*
HandleTearDown = LevelEditor.OnMapChanged().AddLambda([&](UWorld* World, EMapChangeType ChangeType)
{
if (ChangeType == EMapChangeType::TearDownWorld)
{
CaptureList.Empty();
}
});
*/
}
}
if (bInitPIE == false) {
bInitPIE = true;
FEditorDelegates::BeginPIE.AddLambda([&](const bool bIsSimulating) {
this->OnPIEEvent(true, false);
});
FEditorDelegates::EndPIE.AddLambda([&](const bool bIsSimulating) {
this->OnPIEEvent(false, true);
});
}
#endif
}
void UVRM4U_RenderSubsystem::RemoveCaptureTexture(UTextureRenderTarget2D* Texture) {
FVRM4URenderModule* m = FModuleManager::GetModulePtr<FVRM4URenderModule>("VRM4URender");
if (m != nullptr) {
m->CaptureList.Remove(Texture);
}
}
void UVRM4U_RenderSubsystem::RemoveAllCaptureTexture() {
FVRM4URenderModule* m = FModuleManager::GetModulePtr<FVRM4URenderModule>("VRM4URender");
if (m != nullptr) {
m->CaptureList.Empty();
}
}
void UVRM4U_RenderSubsystem::ResetSceneTextureExtentHistory() {
::ResetSceneTextureExtentHistory();
}
void UVRM4U_RenderSubsystem::SetViewExtension(bool bEnable) {
}
void UVRM4U_RenderSubsystem::AddRimFilterData(class UVrmExtensionRimFilterData* FilterData) {
FScopeLock lock(&cs_rim);
RimFilterData.AddUnique(FilterData);
}
void UVRM4U_RenderSubsystem::RemoveRimFilterData(class UVrmExtensionRimFilterData* FilterData) {
FScopeLock lock(&cs_rim);
RimFilterData.Remove(FilterData);
}
void UVRM4U_RenderSubsystem::RemoveRimFilterDataByPriority(int Priority) {
FScopeLock lock(&cs_rim);
if (Priority < 0) {
RimFilterData.Empty();
return;
}
RimFilterData.RemoveAll([&Priority](const TWeakObjectPtr<UVrmExtensionRimFilterData>& Item) {
if (Item.IsValid() == false) return true;
return Item->Priority == Priority;
});
}
TArray<UVrmExtensionRimFilterData::FFilterData> UVRM4U_RenderSubsystem::GenerateFilterData() {
FScopeLock lock(&cs_rim);
RimFilterData.RemoveAll([](const TWeakObjectPtr<UVrmExtensionRimFilterData>& Item) {
return !Item.IsValid();
});
RimFilterData.Sort([](const TWeakObjectPtr<UVrmExtensionRimFilterData>& A, const TWeakObjectPtr<UVrmExtensionRimFilterData>& B)
{
return A->Priority < B->Priority;
});
TArray<UVrmExtensionRimFilterData::FFilterData> f;
for (auto& a : RimFilterData) {
auto d = a->GetFilterData();
if (d.bUseFilter == false) continue;
f.Add(MoveTemp(d));
}
return MoveTemp(f);
}
@@ -0,0 +1,62 @@
// Fill out your copyright notice in the Description page of Project Settings.
#include "VrmExtensionRimFilterData.h"
#include "VRM4U_RenderSubsystem.h"
#include "Engine/World.h"
// Sets default values
UVrmExtensionRimFilterData::UVrmExtensionRimFilterData(const FObjectInitializer& ObjectInitializer)
:Super(ObjectInitializer)
{
// Set this actor to call Tick() every frame. You can turn this off to improve performance if you don't need it.
//PrimaryActorTick.bCanEverTick = false;
}
/*
void UVrmExtensionRimFilterData::BeginDestroy() {
UVRM4U_RenderSubsystem* s = GEngine->GetEngineSubsystem<UVRM4U_RenderSubsystem>();
if (s == nullptr) return;
s->RemoveRimFilterData(this);
Super::BeginDestroy();
}
*/
void UVrmExtensionRimFilterData::PostInitProperties() {
Super::PostInitProperties();
if (GEngine == nullptr) return;
if (!HasAnyFlags(RF_ClassDefaultObject)) {
// インスタンスの場合
UVRM4U_RenderSubsystem* s = GEngine->GetEngineSubsystem<UVRM4U_RenderSubsystem>();
if (s == nullptr) return;
s->AddRimFilterData(this);
}
}
// Called every frame
//void UVrmExtensionRimFilterData::Tick(float DeltaTime)
//{
// Super::Tick(DeltaTime);
//}
/*
void UVrmExtensionRimFilterData::OnConstruction(const FTransform& Transform) {
Super::OnConstruction(Transform);
//UVRM4U_RenderSubsystem* s = UWorld::GetSubsystem<UVRM4U_RenderSubsystem>(GetWorld());
UVRM4U_RenderSubsystem* s = GEngine->GetEngineSubsystem<UVRM4U_RenderSubsystem>();
if (s == nullptr) return;
s->bUsePostRenderBasePass = bUseExtension;
}
*/
@@ -0,0 +1,167 @@
// VRM4U Copyright (c) 2021-2024 Haruyoshi Yamamoto. This software is released under the MIT License.
#include "VrmSceneCaptureComponent.h"
#include "SceneViewExtension.h"
#include "Runtime/Engine/Public/SceneView.h"
#include "Engine/TextureRenderTarget2D.h"
#include "ScreenPass.h"
#include "Kismet/GameplayStatics.h"
#include "VRM4URender.h"
#include "VrmBPFunctionLibrary.h"
#include "Misc/EngineVersionComparison.h"
#if UE_VERSION_OLDER_THAN(5,3,0)
#include "PostProcess/PostProcessing.h"
#include "PostProcess/PostProcessMaterial.h"
#else
#include "PostProcess/PostProcessMaterialInputs.h"
#endif
class FVrmSceneCaptureSceneViewExtension : public ISceneViewExtension, public TSharedFromThis<FVrmSceneCaptureSceneViewExtension, ESPMode::ThreadSafe>
{
public:
FVrmSceneCaptureSceneViewExtension(const FAutoRegister& AutoRegister)
{ }
virtual ~FVrmSceneCaptureSceneViewExtension() = default;
virtual void BeginRenderViewFamily(FSceneViewFamily& InViewFamily) override {};
virtual void SetupViewFamily(FSceneViewFamily& InViewFamily) override {};
virtual void SetupView(FSceneViewFamily& InViewFamily, FSceneView& InView) override
{
}
virtual void PostRenderBasePassDeferred_RenderThread(FRDGBuilder& GraphBuilder, FSceneView& InView, const FRenderTargetBindingSlots& RenderTargets, TRDGUniformBufferRef<FSceneTextureUniformParameters> SceneTextures)
{
if (InView.bIsSceneCapture == false) return;
FRDGTextureRef DstRDGTex = nullptr;
FRDGTextureRef SrcRDGTex = nullptr;
if (CaptureComponentWeak.IsValid() == false) return;
if (CaptureComponentWeak->RenderTargetA == nullptr) return;
if (CaptureComponentWeak->RenderTargetB == nullptr) return;
//DstRDGTex = RegisterExternalTexture(GraphBuilder, CaptureComponentWeak->RenderTargetA->GetRenderTargetResource()->GetTexture2DRHI(), TEXT("VRM4U_CopyDst"));
for (auto &a : RenderTargets.Output) {
if (a.GetTexture() == nullptr) continue;
FString s = a.GetTexture()->Name;
if (s.Contains("BufferC")) {
SrcRDGTex = a.GetTexture();
}
}
if (SrcRDGTex) {
FVRM4URenderModule::AddCopyPass(GraphBuilder, FIntPoint(InView.UnscaledViewRect.Width(), InView.UnscaledViewRect.Height()), SrcRDGTex, CaptureComponentWeak->RenderTargetA);
}
SrcRDGTex = nullptr;
//DstRDGTex = RegisterExternalTexture(GraphBuilder, CaptureComponentWeak->RenderTargetA->GetRenderTargetResource()->GetTexture2DRHI(), TEXT("VRM4U_CopyDst"));
for (auto& a : RenderTargets.Output) {
if (a.GetTexture() == nullptr) continue;
FString s = a.GetTexture()->Name;
if (s.Contains("BufferA")) {
SrcRDGTex = a.GetTexture();
}
}
if (SrcRDGTex) {
FVRM4URenderModule::AddCopyPass(GraphBuilder, FIntPoint(InView.UnscaledViewRect.Width(), InView.UnscaledViewRect.Height()), SrcRDGTex, CaptureComponentWeak->RenderTargetB);
}
}
virtual void SubscribeToPostProcessingPass(EPostProcessingPass PassId, const FSceneView& View, FAfterPassCallbackDelegateArray& InOutPassCallbacks, bool bIsPassEnabled)
{
if (PassId == EPostProcessingPass::Tonemap)
{
//InOutPassCallbacks.Add(FAfterPassCallbackDelegate::CreateRaw(this, &FVrmSceneCaptureSceneViewExtension::PostProcessPassAfterTonemap_RenderThread));
}
}
FScreenPassTexture PostProcessPassAfterTonemap_RenderThread(FRDGBuilder& GraphBuilder, const FSceneView& InView, const FPostProcessMaterialInputs& InOutInputs)
{
#if UE_VERSION_OLDER_THAN(5,4,0)
FScreenPassTexture SceneTexture = const_cast<FScreenPassTexture&>(InOutInputs.Textures[(uint32)EPostProcessMaterialInput::SceneColor]);
return SceneTexture;
#else
return InOutInputs.ReturnUntouchedSceneColorForPostProcessing(GraphBuilder);
#endif
}
public:
TWeakObjectPtr<UVrmSceneCaptureComponent2D> CaptureComponentWeak;
};
UVrmSceneCaptureComponent2D::UVrmSceneCaptureComponent2D(const FObjectInitializer& ObjectInitializer)
: Super(ObjectInitializer)
{
}
void UVrmSceneCaptureComponent2D::OnRegister()
{
Super::OnRegister();
#if WITH_EDITORONLY_DATA
if (ProxyMeshComponent)
{
ProxyMeshComponent->DestroyComponent();
ProxyMeshComponent = nullptr;
}
#endif
if (!SceneViewExtension.IsValid())
{
SceneViewExtension = FSceneViewExtensions::NewExtension<FVrmSceneCaptureSceneViewExtension>();
SceneViewExtension->CaptureComponentWeak = this;
}
}
void UVrmSceneCaptureComponent2D::OnUnregister()
{
Super::OnUnregister();
if (SceneViewExtension.IsValid())
{
SceneViewExtensions.Remove(SceneViewExtension);
SceneViewExtension.Reset();
}
//CineCameraComponent = nullptr;
}
void UVrmSceneCaptureComponent2D::OnAttachmentChanged()
{
}
void UVrmSceneCaptureComponent2D::TickComponent(float DeltaTime, ELevelTick TickType, FActorComponentTickFunction* ThisTickFunction)
{
Super::TickComponent(DeltaTime, TickType, ThisTickFunction);
FTransform transform;
float fovDegree;
UVrmBPFunctionLibrary::VRMGetCameraTransform(this, 0, false, transform, fovDegree);
float fov = fovDegree;
{
bool b1, b2, b3;
UVrmBPFunctionLibrary::VRMGetPlayMode(b1, b2, b3);
if (b1 == true && b2 == false) {
auto* c = UGameplayStatics::GetPlayerCameraManager(this, 0);
float ar_current = (float)RenderTargetA->SizeX / RenderTargetA->SizeY;
float HalfX_game = FMath::DegreesToRadians(fovDegree / 2);
float HalfY = FMath::Atan(FMath::Tan(HalfX_game) / c->ViewTarget.POV.AspectRatio);
float HalfX_new = FMath::Atan(ar_current * FMath::Tan(HalfY));
fov = 2.f * FMath::RadiansToDegrees(HalfX_new);
}
}
this->FOVAngle = fov;
}
@@ -0,0 +1,609 @@
// VRM4U Copyright (c) 2021-2024 Haruyoshi Yamamoto. This software is released under the MIT License.
#include "VrmSceneViewExtension.h"
#include "VrmExtensionRimFilterData.h"
#include "Misc/EngineVersionComparison.h"
#include "Runtime/Renderer/Private/SceneRendering.h"
#include "TextureResource.h"
#include "VRM4U_RenderSubsystem.h"
#if UE_VERSION_OLDER_THAN(5,2,0)
#else
#include "DataDrivenShaderPlatformInfo.h"
#include "SystemTextures.h"
#endif
#if UE_VERSION_OLDER_THAN(5,3,0)
#include "PostProcess/PostProcessing.h"
#include "PostProcess/PostProcessMaterial.h"
#else
#include "PostProcess/PostProcessMaterialInputs.h"
#endif
#if UE_VERSION_OLDER_THAN(5,4,0)
#include "Runtime/Renderer/Private/SceneTextures.h"
#endif
#include "ScreenPass.h"
#include "ShaderParameterUtils.h"
#include "GlobalShader.h"
#include "ShaderParameterStruct.h"
#include "RenderGraphEvent.h"
#include "RenderGraphBuilder.h"
#include "ProfilingDebugging/CpuProfilerTrace.h"
#include "Stats/Stats.h"
#include "DynamicRHI.h"
DECLARE_GPU_STAT(VRM4U);
class FMyComputeShader : public FGlobalShader
{
DECLARE_GLOBAL_SHADER(FMyComputeShader);
SHADER_USE_PARAMETER_STRUCT(FMyComputeShader, FGlobalShader);
BEGIN_SHADER_PARAMETER_STRUCT(FParameters, )
SHADER_PARAMETER_RDG_TEXTURE_UAV(RWTexture2D<float4>, SceneColorTexture)
SHADER_PARAMETER_RDG_TEXTURE_UAV(RWTexture2D<float4>, BaseColorTexture)
SHADER_PARAMETER_RDG_TEXTURE_SRV(Texture2D, NormalTexture)
SHADER_PARAMETER_RDG_TEXTURE_SRV(Texture2D<float>, SceneDepthTexture)
//SHADER_PARAMETER_RDG_TEXTURE(Texture2D, CustomDepthTexture)
SHADER_PARAMETER_RDG_TEXTURE_SRV(Texture2D<float4>, CustomDepthTexture)
SHADER_PARAMETER_RDG_TEXTURE_SRV(Texture2D<uint2>, CustomStencilTexture)
//SHADER_PARAMETER_RDG_UNIFORM_BUFFER(FSceneTextureUniformParameters, SceneTextures)
//SHADER_PARAMETER_RDG_TEXTURE(Texture2D, SceneDepthTexture) // 深度
//SHADER_PARAMETER_SAMPLER(SamplerState, DepthSampler)
//SHADER_PARAMETER_RDG_TEXTURE(Texture2D, SceneColorTexture) // カラー
//SHADER_PARAMETER_SAMPLER(SamplerState, ColorSampler)
SHADER_PARAMETER_STRUCT_REF(FViewUniformShaderParameters, View)
SHADER_PARAMETER(FVector3f, CameraPosition)
SHADER_PARAMETER(FVector3f, CameraForwardVector)
SHADER_PARAMETER(float, UseCustomLightPosition)
SHADER_PARAMETER(float, UseCustomLightColor)
SHADER_PARAMETER(FVector3f, LightPosition)
SHADER_PARAMETER(FVector3f, LightDirection)
SHADER_PARAMETER(FVector3f, LightColor)
SHADER_PARAMETER(float, LightScale)
SHADER_PARAMETER(float, RimEdgeFade)
SHADER_PARAMETER(float, UseBinaryEdge)
SHADER_PARAMETER(float, RimEdgeBinaryRange)
SHADER_PARAMETER(float, SampleScreenScale)
SHADER_PARAMETER(float, SampleScale)
SHADER_PARAMETER(int, CustomStencilMask)
//RENDER_TARGET_BINDING_SLOTS()
END_SHADER_PARAMETER_STRUCT()
public:
static bool ShouldCompilePermutation(const FGlobalShaderPermutationParameters& Parameters)
{
return IsFeatureLevelSupported(Parameters.Platform, ERHIFeatureLevel::SM5);
}
};
/*
BEGIN_SHADER_PARAMETER_STRUCT(FMyComputeShaderParameters, )
SHADER_PARAMETER_RDG_TEXTURE_UAV(RWTexture2D<float4>, SceneColorTexture)
//RENDER_TARGET_BINDING_SLOTS()
END_SHADER_PARAMETER_STRUCT()
*/
#if UE_VERSION_OLDER_THAN(5,2,0)
#else
IMPLEMENT_GLOBAL_SHADER(FMyComputeShader, "/VRM4UShaders/private/BaseColorCS.usf", "MainCS", SF_Compute);
#endif
static bool LocalCSEnable()
{
static const auto CVarCustomDepth = IConsoleManager::Get().FindTConsoleVariableDataInt(TEXT("r.CustomDepth"));
const int32 EnabledWithStencil = 3;// CustomDepthMode::EnabledWithStencil ではダメ。
if (CVarCustomDepth) {
if (CVarCustomDepth->GetValueOnAnyThread() != EnabledWithStencil) {
return false;
}
}
if (GMaxRHIFeatureLevel >= ERHIFeatureLevel::SM6) {
return true;
}
return false;
}
static void LocalCopyFilter(FRDGBuilder& GraphBuilder, FSceneView& InView, const FRenderTargetBindingSlots& RenderTargets, TRDGUniformBufferRef<FSceneTextureUniformParameters>& SceneTextures) {
#if UE_VERSION_OLDER_THAN(5,4,0)
#else
FScreenPassViewInfo ViewInfo(InView);
#endif
// copy枚数
const int copyNum = 4;
FRDGTextureDesc CopyDesc[copyNum] = {};
FRDGTextureRef CopyTexture[copyNum] = {};
FRDGTextureRef CopyTextureDepth[copyNum] = {};
{
#if UE_VERSION_OLDER_THAN(5,5,0)
#else
{
// depth copy
RDG_EVENT_SCOPE_STAT(GraphBuilder, VRM4U, "VRM4U::Copy2");
FRDGTextureRef SourceTexture = SceneTextures->GetParameters()->SceneDepthTexture;
if (!SourceTexture) return;
for (int i = 0; i < copyNum; ++i) {
CopyDesc[i] = SourceTexture->Desc;
if (i == 0) {
}
else {
CopyDesc[i].Extent = CopyDesc[i - 1].Extent / 2;
}
CopyDesc[i].Flags |= TexCreate_RenderTargetable | TexCreate_UAV;
FString name = TEXT("CopiedGBuffer2") + FString::FromInt(i);
CopyTextureDepth[i] = GraphBuilder.CreateTexture(
CopyDesc[i],
*name
);
// テクスチャをコピー
if (i == 0) {
AddCopyTexturePass(
GraphBuilder,
SourceTexture,
CopyTextureDepth[i]
);
}
else {
AddDrawTexturePass(
GraphBuilder,
ViewInfo,
//SourceTexture,
CopyTextureDepth[i - 1],
CopyTextureDepth[i],
FIntPoint(0, 0), CopyDesc[i - 1].Extent,
FIntPoint(0, 0), CopyDesc[i].Extent
);
}
}
}
#endif
#if UE_VERSION_OLDER_THAN(5,5,0)
#else
RDG_EVENT_SCOPE_STAT(GraphBuilder, VRM4U, "VRM4U::Copy");
#endif
RDG_GPU_STAT_SCOPE(GraphBuilder, VRM4U);
SCOPED_NAMED_EVENT(VRM4U, FColor::Emerald);
// RenderTargets の0番目を取得
const FRenderTargetBinding& FirstTarget = RenderTargets[0];
FRDGTextureRef SourceTexture = FirstTarget.GetTexture();
if (!SourceTexture) return;
for (int i = 0; i < copyNum; ++i) {
CopyDesc[i] = SourceTexture->Desc;
if (i == 0) {
}
else {
CopyDesc[i].Extent = CopyDesc[i - 1].Extent / 2;
}
CopyDesc[i].Flags |= TexCreate_RenderTargetable | TexCreate_UAV;
FString name = TEXT("CopiedGBuffer") + FString::FromInt(i);
CopyTexture[i] = GraphBuilder.CreateTexture(
CopyDesc[i],
*name
);
// テクスチャをコピー
if (i == 0) {
AddCopyTexturePass(
GraphBuilder,
SourceTexture,
CopyTexture[i]
);
}
else {
#if UE_VERSION_OLDER_THAN(5,4,0)
#elif UE_VERSION_OLDER_THAN(5,5,0)
AddDrawTexturePass(
GraphBuilder,
InView,
//SourceTexture,
CopyTexture[i - 1],
CopyTexture[i],
FIntPoint(0, 0), CopyDesc[0].Extent,
FIntPoint(0, 0), CopyDesc[i - 1].Extent
);
#else
AddDrawTexturePass(
GraphBuilder,
ViewInfo,
//SourceTexture,
CopyTexture[i - 1],
CopyTexture[i],
FIntPoint(0, 0), CopyDesc[i - 1].Extent,
FIntPoint(0, 0), CopyDesc[i].Extent
);
#endif
// AddCopyTexturePass(
// GraphBuilder,
// CopyTexture[i-1],
// CopyTexture[i]
// );
}
}
//RenderTargets.DepthStencil.GetTexture();
// SRV(読み込み用)を作成
//FRDGTextureSRVRef InputSRV = GraphBuilder.CreateSRV(CopyTexture[0]);
}
}
static void LocalRimFilter(FRDGBuilder& GraphBuilder, FSceneView& InView, const FRenderTargetBindingSlots& RenderTargets, TRDGUniformBufferRef<FSceneTextureUniformParameters> &SceneTextures) {
#if UE_VERSION_OLDER_THAN(5,2,0)
#else
UVRM4U_RenderSubsystem* s = GEngine->GetEngineSubsystem<UVRM4U_RenderSubsystem>();
if (s == nullptr) return;
auto data = s->GenerateFilterData();
for (int dataIndex = 0; dataIndex < data.Num(); ++dataIndex){
const auto& d = data[dataIndex];
if (RenderTargets[0].GetTexture() == nullptr) continue;
if (RenderTargets[1].GetTexture() == nullptr) continue;
if (RenderTargets[2].GetTexture() == nullptr) continue;
if (RenderTargets[3].GetTexture() == nullptr) continue;
// RenderTargets
// 0 SceneColor
// 1 A normal
// 2 B MRS
// 3 C basecolor
// 4 D subsurface
const FRDGSystemTextures& SystemTextures = FRDGSystemTextures::Get(GraphBuilder);
//const FCustomDepthTextures& CustomDepthTextures = SceneTextures->CustomDepth;
//bool bCustomDepthProduced = HasBeenProduced(CustomDepthTextures.Depth);
FMyComputeShader::FParameters* Parameters = GraphBuilder.AllocParameters<FMyComputeShader::FParameters>();
{
// SceneColorTexture
const FRenderTargetBinding& FirstTarget = RenderTargets[0];
FRDGTextureRef TargetTexture = FirstTarget.GetTexture();
FRDGTextureUAVRef GBufferUAV = GraphBuilder.CreateUAV(TargetTexture);
Parameters->SceneColorTexture = GBufferUAV;
}
{
// BaseColorTexture
//const FRenderTargetBinding& FirstTarget = RenderTargets[3];
//FRDGTextureRef TargetTexture = FirstTarget.GetTexture();
//FRDGTextureUAVRef GBufferUAV = GraphBuilder.CreateUAV(TargetTexture);
//Parameters->BaseColorTexture = GBufferUAV;
}
//Parameters->NormalTexture = GraphBuilder.CreateSRV(SceneTextures->GetParameters()->GBufferATexture);
Parameters->NormalTexture = GraphBuilder.CreateSRV(RenderTargets[1].GetTexture());
Parameters->SceneDepthTexture = GraphBuilder.CreateSRV(SceneTextures->GetParameters()->SceneDepthTexture);
Parameters->CustomDepthTexture = GraphBuilder.CreateSRV(SceneTextures->GetParameters()->CustomDepthTexture);
//Parameters->CustomDepthTexture = SceneTextures->GetParameters()->CustomDepthTexture;
Parameters->CustomStencilTexture = (SceneTextures->GetParameters()->CustomStencilTexture);
//Parameters->CustomStencilTexture = bCustomDepthProduced ? CustomDepthTextures.Stencil : SystemTextures.StencilDummySRV;
//Parameters->InputTexture = GraphBuilder.CreateSRV(CopyTexture[1]);
//Parameters->SceneDepthTexture = SceneTextures->GetParameters()->SceneDepthTexture;
//Parameters->SceneDepthTexture = SceneTextures->GetParameters()->GBufferBTexture;
//check(DepthTexture);
//Parameters->DepthSampler = TStaticSamplerState<SF_Point>::GetRHI();
Parameters->View = InView.ViewUniformBuffer;
//Parameters->SceneTextures = SceneTextures;
//Parameters->RenderTargets[0] = Output.GetRenderTargetBinding();
//PassParameters->SceneColorTexture = GraphBuilder.CreateUAV(FRDGTextureUAVDesc(SceneColorTexture));
Parameters->CameraPosition = FVector3f(InView.ViewMatrices.GetViewOrigin());
Parameters->CameraForwardVector = FVector3f(InView.ViewRotation.RotateVector(FVector(1, 0, 0)));
Parameters->UseCustomLightPosition = d.bUseCustomLighPosition;
Parameters->LightPosition = FVector3f(d.LightPosition);
Parameters->LightDirection = FVector3f(d.LightDirection);
Parameters->UseCustomLightColor = d.bUseCustomLighColor;
Parameters->LightColor = FVector3f(d.LightColor);
Parameters->LightScale = d.LightScale;
Parameters->RimEdgeFade = d.RimEdgeFade;
Parameters->UseBinaryEdge = d.bUseBinaryEdge;
Parameters->RimEdgeBinaryRange = d.RimEdgeBinaryRange;
Parameters->SampleScreenScale = d.SampleScreenScale;
Parameters->SampleScale = d.SampleScale;
Parameters->CustomStencilMask = d.CustomStencilMask;
int Width = RenderTargets[0].GetTexture()->Desc.Extent.X;
int Height = RenderTargets[0].GetTexture()->Desc.Extent.Y;
TShaderMapRef<FMyComputeShader> ComputeShader(GetGlobalShaderMap(GMaxRHIFeatureLevel));
FComputeShaderUtils::AddPass(
GraphBuilder,
RDG_EVENT_NAME("VRM4U_CustomGBufferWrite %d", dataIndex),
ComputeShader,
Parameters,
FIntVector(Width / 8, Height / 8, 1)
);
/*
//FRDGBuilder GraphBuilder(FRHICommandListExecutor::GetImmediateCommandList());
//RenderTargets.
// Render TargetをRDGリソースに変換
FRDGTextureRef SceneColorTexture = GraphBuilder.RegisterExternalTexture(CreateRenderTarget(RenderTarget->GameThread_GetRenderTargetResource(), TEXT("SceneColorTexture")));
FRDGTextureUAVRef OutputUAV = GraphBuilder.CreateUAV(SceneColorTexture);
// パラメータを設定
FMyComputeShader::FParameters* Parameters = GraphBuilder.AllocParameters<FMyComputeShader::FParameters>();
Parameters->SceneColorTexture = OutputUAV;
// Shaderを追加してディスパッチ
TShaderMapRef<FMyComputeShader> ComputeShader(GetGlobalShaderMap(GMaxRHIFeatureLevel));
FComputeShaderUtils::AddPass(
GraphBuilder,
RDG_EVENT_NAME("MyComputeShader"),
ComputeShader,
Parameters,
FIntVector(RenderTarget->SizeX / 8, RenderTarget->SizeY / 8, 1) // スレッドグループ数
);
GraphBuilder.Execute();
*/
}
#endif
}
///////////////////////
FVrmSceneViewExtension::FVrmSceneViewExtension(const FAutoRegister& AutoRegister) : FSceneViewExtensionBase(AutoRegister) {
}
void FVrmSceneViewExtension::PostRenderBasePassDeferred_RenderThread(FRDGBuilder& GraphBuilder, FSceneView& InView, const FRenderTargetBindingSlots& RenderTargets, TRDGUniformBufferRef<FSceneTextureUniformParameters> SceneTextures) {
if (LocalCSEnable() == false) return;
const auto FeatureLevel = InView.GetFeatureLevel();
if (FeatureLevel <= ERHIFeatureLevel::SM5) return;
{
bool bActive = false;
//bool bCapture = InView.bIsSceneCapture;
auto t = InView.Family->Scene->GetWorld()->WorldType;
switch (t) {
case EWorldType::Editor:
case EWorldType::Game:
case EWorldType::PIE:
bActive = true;
break;
}
if (bActive == false) {
return;
}
}
//check(InView.bIsViewInfo);
//auto ViewInfo = static_cast<const FViewInfo*>(&InView);
//decltype(auto) View = InView;
//check(View.bIsViewInfo);
//const FSceneTextures& st = static_cast<const FViewInfo&>(View).GetSceneTextures();
// GBuffer の BaseColor を取得(例: GBufferA に格納されていると仮定)
//FRDGTextureRef GBufferBaseColorTexture = SceneTextures.GBufferA;
//FRDGTextureRef GBufferBaseColorTexture = GraphBuilder.RegisterExternalTexture(
// InView.Scene->SceneTexturesUniformBuffer->GetRDGTexture("GBufferATexture"), // 仮の取得方法
// TEXT("GBufferBaseColor")
//);
//PassTextures.Depth = SceneTextures.Depth;
//PassTextures.Color = SceneTextures.Color.Target;
//PassTextures.GBufferA = (*SceneTextures.UniformBuffer)->GBufferATexture;
//PassTextures.GBufferB = (*SceneTextures.UniformBuffer)->GBufferBTexture;
//PassTextures.GBufferC = (*SceneTextures.UniformBuffer)->GBufferCTexture;
//PassTextures.GBufferE = (*SceneTextures.UniformBuffer)->GBufferETexture;
//PassTextures.DBufferTextures = DBufferTextures;
//FRDGTextureRef GBufferBaseColorTexture = (*SceneTextures.UniformBuffer)->GBufferATexture;
//FScreenPassTexture ScreenPassTex(SceneTextures->GetParameters()->GBufferATexture);
//RDG_EVENT_SCOPE(GraphBuilder, "Naga_PostRenderBasePassDeferred %dx%d", ScreenPassTex.ViewRect.Width(), ScreenPassTex.ViewRect.Height());
// FRDGTextureUAVRef GBufferUAV = GraphBuilder.CreateUAV(ScreenPassTex.Texture);
///// filter
#if UE_VERSION_OLDER_THAN(5,2,0)
#else
bool bUseRimFilter = false;
{
LocalRimFilter(GraphBuilder, InView, RenderTargets, SceneTextures);
}
#endif
}
void FVrmSceneViewExtension::PrePostProcessPass_RenderThread(FRDGBuilder& GraphBuilder, const FSceneView& View, const FPostProcessingInputs& Inputs) {
//const FSceneView& View = Views[0];
//check(View.bIsViewInfo);
//const FMinimalSceneTextures& SceneTextures = static_cast<const FViewInfo&>(View).GetSceneTextures();
}
#if UE_VERSION_OLDER_THAN(5,6,0)
void FVrmSceneViewExtension::SubscribeToPostProcessingPass(EPostProcessingPass Pass, FAfterPassCallbackDelegateArray& InOutPassCallbacks, bool bIsPassEnabled) {
if (Pass == EPostProcessingPass::FXAA)
{
//InOutPassCallbacks.Add(
// FAfterPassCallbackDelegate::CreateRaw(this, &FVrmSceneViewExtension::AfterTonemap_RenderThread));
}
}
#else
void FVrmSceneViewExtension::SubscribeToPostProcessingPass(EPostProcessingPass Pass, const FSceneView& InView, FPostProcessingPassDelegateArray& InOutPassCallbacks, bool bIsPassEnabled) {
if ((int)Pass == (int)EPostProcessingPass::Tonemap-1)
{
InOutPassCallbacks.Add(
FAfterPassCallbackDelegate::CreateRaw(this, &FVrmSceneViewExtension::PreTonemap_RenderThread));
}
if (Pass == EPostProcessingPass::Tonemap)
{
InOutPassCallbacks.Add(
FAfterPassCallbackDelegate::CreateRaw(this, &FVrmSceneViewExtension::AfterTonemap_RenderThread));
}
if ((int)Pass == (int)EPostProcessingPass::MAX-1)
{
InOutPassCallbacks.Add(
FAfterPassCallbackDelegate::CreateRaw(this, &FVrmSceneViewExtension::LastPass_RenderThread));
}
}
#endif
bool FVrmSceneViewExtension::IsActiveThisFrame_Internal(const FSceneViewExtensionContext& Context) const {
return FSceneViewExtensionBase::IsActiveThisFrame_Internal(Context);
}
FScreenPassTexture FVrmSceneViewExtension::PreTonemap_RenderThread(FRDGBuilder& GraphBuilder, const FSceneView& InView, const FPostProcessMaterialInputs& InOutInputs) {
return Pass_RenderThread(GraphBuilder, InView, InOutInputs, ECapturePass::PreTonemap);
}
FScreenPassTexture FVrmSceneViewExtension::AfterTonemap_RenderThread(FRDGBuilder& GraphBuilder, const FSceneView& InView, const FPostProcessMaterialInputs& InOutInputs) {
return Pass_RenderThread(GraphBuilder, InView, InOutInputs, ECapturePass::PostTonemap);
}
FScreenPassTexture FVrmSceneViewExtension::LastPass_RenderThread(FRDGBuilder& GraphBuilder, const FSceneView& InView, const FPostProcessMaterialInputs& InOutInputs) {
return Pass_RenderThread(GraphBuilder, InView, InOutInputs, ECapturePass::LastPass);
}
FScreenPassTexture FVrmSceneViewExtension::Pass_RenderThread(FRDGBuilder & GraphBuilder, const FSceneView & InView, const FPostProcessMaterialInputs & InOutInputs, ECapturePass Pass){
auto GetReturnTexture = [&InOutInputs, &GraphBuilder]() {
#if UE_VERSION_OLDER_THAN(5,4,0)
/** We don't want to modify scene texture in any way. We just want it to be passed back onto the next stage. */
FScreenPassTexture SceneTexture = const_cast<FScreenPassTexture&>(InOutInputs.Textures[(uint32)EPostProcessMaterialInput::SceneColor]);
return SceneTexture;
#else
return InOutInputs.ReturnUntouchedSceneColorForPostProcessing(GraphBuilder);
#endif
};
FVRM4URenderModule* m = FModuleManager::GetModulePtr<FVRM4URenderModule>("VRM4URender");
if (m == nullptr) {
return GetReturnTexture();
}
if (FVRM4URenderModule::isCaptureTarget(&InView) == false) {
return GetReturnTexture();
}
bool bOverride = false;
if (m->CaptureList.Num()) {
#if UE_VERSION_OLDER_THAN(5,3,0)
decltype(auto) View = static_cast<const FViewInfo&>(InView);
#else
decltype(auto) View = InView;
#endif
TObjectPtr<UTextureRenderTarget2D> dst;
//FScreenPassTextureSlice src;
auto src = InOutInputs.Textures[(uint32)EPostProcessMaterialInput::SceneColor];
for (auto c : m->CaptureList) {
if (c.Key == nullptr) continue;
if (c.Key->GetRenderTargetResource() == nullptr) continue;
switch (c.Value) {
case EVRM4U_CaptureSource::ColorTexturePostOpaque:
if (Pass == ECapturePass::PreTonemap) {
dst = c.Key;
}
break;
case EVRM4U_CaptureSource::ColorTexturePostTonemap:
if (Pass == ECapturePass::PostTonemap) {
dst = c.Key;
}
break;
case EVRM4U_CaptureSource::ColorTextureLastPass:
if (Pass == ECapturePass::LastPass) {
dst = c.Key;
}
break;
default:
break;
}
}
if (src.IsValid() && dst.Get()) {
#if UE_VERSION_OLDER_THAN(5,4,0)
FVRM4URenderModule::AddCopyPass(GraphBuilder, FIntPoint(View.UnscaledViewRect.Width(), View.UnscaledViewRect.Height()), src.Texture, dst);
bOverride = true;
#else
FVRM4URenderModule::AddCopyPass(GraphBuilder, FIntPoint(View.UnscaledViewRect.Width(), View.UnscaledViewRect.Height()), src.TextureSRV->GetParent(), dst);
bOverride = true;
#endif
}
}
if (bOverride && InOutInputs.OverrideOutput.IsValid())
{
return InOutInputs.OverrideOutput;
} else {
return GetReturnTexture();
}
}
@@ -0,0 +1,52 @@
// VRM4U Copyright (c) 2021-2024 Haruyoshi Yamamoto. This software is released under the MIT License.
#pragma once
#include "CoreMinimal.h"
#include "Misc/EngineVersionComparison.h"
#include "SceneViewExtension.h"
class FVrmSceneViewExtension : public FSceneViewExtensionBase
{
enum ECapturePass{
PreTonemap,
PostTonemap,
LastPass,
};
public:
FVrmSceneViewExtension(const FAutoRegister& AutoRegister);
virtual void SetupViewFamily(FSceneViewFamily& InViewFamily) override {}
virtual void SetupView(FSceneViewFamily& InViewFamily, FSceneView& InView) override {}
virtual void BeginRenderViewFamily(FSceneViewFamily& InViewFamily) override {}
virtual void PreRenderViewFamily_RenderThread(FRDGBuilder& RHICmdList, FSceneViewFamily& InViewFamily) override {}
virtual void PreRenderView_RenderThread(FRDGBuilder& RHICmdList, FSceneView& InView) override {}
virtual void PreInitViews_RenderThread(FRDGBuilder& GraphBuilder) override {}
virtual void PostRenderBasePassDeferred_RenderThread(FRDGBuilder& GraphBuilder, FSceneView& InView, const FRenderTargetBindingSlots& RenderTargets, TRDGUniformBufferRef<FSceneTextureUniformParameters> SceneTextures) override;
//virtual void PostRenderBasePassMobile_RenderThread(FRHICommandList& RHICmdList, FSceneView& InView) override {};
virtual void PrePostProcessPass_RenderThread(FRDGBuilder& GraphBuilder, const FSceneView& View, const FPostProcessingInputs& Inputs) override;
#if UE_VERSION_OLDER_THAN(5,6,0)
virtual void SubscribeToPostProcessingPass(EPostProcessingPass Pass, FAfterPassCallbackDelegateArray& InOutPassCallbacks, bool bIsPassEnabled) override;
#else
virtual void SubscribeToPostProcessingPass(EPostProcessingPass Pass, const FSceneView& InView, FPostProcessingPassDelegateArray& InOutPassCallbacks, bool bIsPassEnabled);
#endif
//virtual void PostRenderViewFamily_RenderThread(FRDGBuilder& GraphBuilder, FSceneViewFamily& InViewFamily) override {}
//virtual void PostRenderView_RenderThread(FRDGBuilder& GraphBuilder, FSceneView& InView) override;
virtual int32 GetPriority() const override { return 100; }
virtual bool IsActiveThisFrame_Internal(const FSceneViewExtensionContext& Context) const override;
FScreenPassTexture PreTonemap_RenderThread(FRDGBuilder& GraphBuilder, const FSceneView& View, const FPostProcessMaterialInputs& InOutInputs);
FScreenPassTexture AfterTonemap_RenderThread(FRDGBuilder& GraphBuilder, const FSceneView& View, const FPostProcessMaterialInputs& InOutInputs);
FScreenPassTexture LastPass_RenderThread(FRDGBuilder& GraphBuilder, const FSceneView& View, const FPostProcessMaterialInputs& InOutInputs);
FScreenPassTexture Pass_RenderThread(FRDGBuilder& GraphBuilder, const FSceneView& View, const FPostProcessMaterialInputs& InOutInputs, ECapturePass Pass);
};
@@ -0,0 +1,33 @@
// Fill out your copyright notice in the Description page of Project Settings.
#include "VrmSceneViewExtensionSettings.h"
#include "VRM4U_RenderSubsystem.h"
#include "Engine/World.h"
// Sets default values
AVrmSceneViewExtensionSettings::AVrmSceneViewExtensionSettings()
{
// Set this actor to call Tick() every frame. You can turn this off to improve performance if you don't need it.
PrimaryActorTick.bCanEverTick = false;
}
// Called when the game starts or when spawned
void AVrmSceneViewExtensionSettings::BeginPlay()
{
Super::BeginPlay();
}
// Called every frame
void AVrmSceneViewExtensionSettings::Tick(float DeltaTime)
{
Super::Tick(DeltaTime);
}
void AVrmSceneViewExtensionSettings::OnConstruction(const FTransform& Transform) {
Super::OnConstruction(Transform);
}
@@ -0,0 +1,91 @@
// Fill out your copyright notice in the Description page of Project Settings.
#pragma once
#include "CoreMinimal.h"
#include "Subsystems/EngineSubsystem.h"
#include "Misc/EngineVersionComparison.h"
#include "VrmSceneViewExtension.h"
#include "VrmExtensionRimFilterData.h"
#include "VRM4URender.h"
#if WITH_EDITOR
#include "UnrealEdMisc.h"
#endif
#include "VRM4U_RenderSubsystem.generated.h"
#if UE_VERSION_OLDER_THAN(4,22,0)
//Couldn't find parent type for 'VRM4U_AnimSubsystem' named 'UEngineSubsystem'
#error "please remove VRM4U_AnimSubsystem.h/cpp for <=UE4.21"
#endif
UCLASS()
class VRM4URENDER_API UVRM4U_RenderSubsystem : public UEngineSubsystem
{
GENERATED_BODY()
FDelegateHandle HandleTearDown;
bool bInitPIE = false;
public:
//// rim filter
FCriticalSection cs_rim;
TArray< TWeakObjectPtr<class UVrmExtensionRimFilterData> > RimFilterData;
UFUNCTION(BlueprintCallable, Category = "VRM4U")
void AddRimFilterData(class UVrmExtensionRimFilterData *FilterData);
UFUNCTION(BlueprintCallable, Category = "VRM4U")
void RemoveRimFilterData(class UVrmExtensionRimFilterData* FilterData);
UFUNCTION(BlueprintCallable, Category = "VRM4U")
void RemoveRimFilterDataByPriority(int Priotiry = -1);
TArray<struct UVrmExtensionRimFilterData::FFilterData> GenerateFilterData();
////
virtual void Initialize(FSubsystemCollectionBase& Collection) override;
virtual void Deinitialize() override;
void RenderPre(FRDGBuilder& GraphBuilder);
void RenderPost(FRDGBuilder& GraphBuilder);
void OnPostOpaque(FPostOpaqueRenderParameters& Parameters);
void OnOverlay(FPostOpaqueRenderParameters& Parameters);
void OnResolvedSceneColor_RenderThread(FRDGBuilder& GraphBuilder, const FSceneTextures& SceneTextures);
#if WITH_EDITOR
void OnMapChange(UWorld* World, EMapChangeType ChangeType);
void OnPIEEvent(bool bPIEBegin, bool bPIEEnd);
#endif
// keep class
TSharedPtr<class FVrmSceneViewExtension, ESPMode::ThreadSafe> SceneViewExtension;
UFUNCTION(BlueprintCallable, Category = "VRM4U")
void AddCaptureTexture(UTextureRenderTarget2D *Texture, EVRM4U_CaptureSource CaptureSource = EVRM4U_CaptureSource::ColorTextureOverlay);
UFUNCTION(BlueprintCallable, Category = "VRM4U")
void RemoveCaptureTexture(UTextureRenderTarget2D* Texture);
UFUNCTION(BlueprintCallable, Category = "VRM4U")
void RemoveAllCaptureTexture();
UFUNCTION(BlueprintCallable, Category = "VRM4U")
void ResetSceneTextureExtentHistory();
//
UFUNCTION(BlueprintCallable, Category = "VRM4U")
void SetViewExtension(bool bEnable);
};
@@ -0,0 +1,125 @@
// Fill out your copyright notice in the Description page of Project Settings.
#pragma once
#include "CoreMinimal.h"
#include "GameFramework/Actor.h"
#include "VrmExtensionRimFilterData.generated.h"
UCLASS(BlueprintType)
class VRM4URENDER_API UVrmExtensionRimFilterData : public UObject
{
GENERATED_UCLASS_BODY()
struct FFilterData {
bool bUseFilter = false;
int Priority = 0;
bool bUseCustomLighPosition = false;
FVector LightPosition;
FVector LightDirection;
bool bUseCustomLighColor = false;
FLinearColor LightColor;
float LightScale = 100.f;
float RimEdgeFade = 1.f;
bool bUseBinaryEdge = false;
float RimEdgeBinaryRange = 0.2f;
float SampleScreenScale = 0.25f;
float SampleScale = 1.5;
int CustomStencilMask = 0xFFFF;
};
public:
// Sets default values for this actor's properties
//UVrmExtensionRimFilterData();
protected:
// Called when the game starts or when spawned
//virtual void BeginPlay() override;
public:
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "VRM4U")
bool bUseFilter = false;
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "VRM4U")
int Priority = 0;
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "VRM4U")
bool bUseCustomLighPosition = false;
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "VRM4U")
FVector LightPosition;
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "VRM4U")
FVector LightDirection;
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "VRM4U")
float LightScale = 1.f;
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "VRM4U")
float RimEdgeFade = 1.f;
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "VRM4U")
bool bUseBinaryEdge = false;
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "VRM4U")
float RimEdgeBinaryRange = 0.2f;
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "VRM4U")
bool bUseCustomLighColor = false;
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "VRM4U")
FLinearColor LightColor;
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "VRM4U")
float SampleScreenScale = 0.5f;
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "VRM4U")
float SampleScale = 1.0;
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "VRM4U")
int CustomStencilMask = 0xFFFF;
// Called every frame
//virtual void Tick(float DeltaTime) override;
//UObject::UObject(const FObjectInitializer& ObjectInitializer)
// virtual void OnConstruction(const FTransform& Transform) override;
//virtual void BeginDestroy() override;
virtual void PostInitProperties() override;
FFilterData GetFilterData() {
FFilterData d;
d.bUseFilter = bUseFilter;
d.Priority = Priority;
d.bUseCustomLighPosition = bUseCustomLighPosition;
d.LightPosition = LightPosition;
d.LightDirection = LightDirection;
d.bUseCustomLighColor = bUseCustomLighColor;
d.LightColor = LightColor;
d.LightScale = LightScale;
d.RimEdgeFade = RimEdgeFade;
d.bUseBinaryEdge = bUseBinaryEdge;
d.RimEdgeBinaryRange = RimEdgeBinaryRange;
d.SampleScreenScale = SampleScreenScale;
d.SampleScale = SampleScale;
d.CustomStencilMask = CustomStencilMask;
return d;
}
};
@@ -0,0 +1,47 @@
// VRM4U Copyright (c) 2021-2024 Haruyoshi Yamamoto. This software is released under the MIT License.
#pragma once
#include "Components/SceneCaptureComponent2D.h"
#include "VrmSceneCaptureComponent.generated.h"
//DECLARE_LOG_CATEGORY_EXTERN(LogCineCapture, Log, All);
class FVrmSceneCaptureSceneViewExtension;
class UCineCameraComponent;
/**
* Cine Capture Component extends Scene Capture to allow users to render Cine Camera Component into a render target.
* Cine Capture has a few modifiable properties, but most of the properties are controlled by Cine Camera Component.
* Cine Capture Component is required to be parented to Cine Camera Component or a class that extends it.
*
*/
UCLASS(meta = (BlueprintSpawnableComponent))
//UCLASS(hidecategories = (Transform, Collision, Object, Physics, SceneComponent, PostProcessVolume, Projection, Rendering, PlanarReflection), ClassGroup = Rendering, editinlinenew, meta = (BlueprintSpawnableComponent))
class VRM4URENDER_API UVrmSceneCaptureComponent2D : public USceneCaptureComponent2D
{
GENERATED_UCLASS_BODY()
public:
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Capture Settings")
TObjectPtr<UTextureRenderTarget2D> RenderTargetA;
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Capture Settings")
TObjectPtr<UTextureRenderTarget2D> RenderTargetB;
public:
virtual void OnRegister() override;
virtual void OnUnregister() override;
/** Used for validation of this componet's attachment to Cine Camera Component. */
virtual void OnAttachmentChanged() override;
virtual void TickComponent(float DeltaTime, enum ELevelTick TickType, FActorComponentTickFunction* ThisTickFunction) override;
private:
private:
/** This scene view extension is used to get ahold of views during the setup process. */
TSharedPtr<FVrmSceneCaptureSceneViewExtension, ESPMode::ThreadSafe> SceneViewExtension;
//TSharedPtr<class FVrmSceneViewExtension, ESPMode::ThreadSafe> SceneViewExtension;
};
@@ -0,0 +1,32 @@
// Fill out your copyright notice in the Description page of Project Settings.
#pragma once
#include "CoreMinimal.h"
#include "GameFramework/Actor.h"
#include "VrmSceneViewExtensionSettings.generated.h"
UCLASS()
class VRM4URENDER_API AVrmSceneViewExtensionSettings : public AActor
{
GENERATED_BODY()
public:
// Sets default values for this actor's properties
AVrmSceneViewExtensionSettings();
protected:
// Called when the game starts or when spawned
virtual void BeginPlay() override;
public:
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "VRM4U")
bool bUseExtension = false;
// Called every frame
virtual void Tick(float DeltaTime) override;
virtual void OnConstruction(const FTransform& Transform) override;
};
@@ -0,0 +1,36 @@
using UnrealBuildTool;
public class VRM4URender : ModuleRules
{
public VRM4URender(ReadOnlyTargetRules Target) : base(Target)
{
PCHUsage = ModuleRules.PCHUsageMode.UseExplicitOrSharedPCHs;
PrivateIncludePaths.AddRange(
new string[] {
System.IO.Path.Combine(GetModuleDirectory("Renderer"), "Private"), //required for FPostProcessMaterialInputs
System.IO.Path.Combine(GetModuleDirectory("Renderer"), "Internal"), //required for FPostProcessMaterialInputs
});
PrivateDependencyModuleNames.AddRange(
new string[] {
"Core",
"CoreUObject",
"Engine",
"Projects",
"RenderCore",
"RHI",
//"ShaderCore",
"Renderer",
"VRM4U",
});
if (Target.bBuildEditor)
{
PrivateDependencyModuleNames.Add("UnrealEd");
}
}
}