Files
Brandyn / Techy fcc1b09210 init
2026-04-04 15:40:51 -05:00

261 lines
8.0 KiB
C++

// Copyright Epic Games, Inc. All Rights Reserved.
#include "JumpFloodComponent2D.h"
#include "Materials/MaterialInstanceDynamic.h"
#include "Kismet/KismetRenderingLibrary.h"
#include "WaterEditorModule.h"
#include "WaterUtils.h"
#include UE_INLINE_GENERATED_CPP_BY_NAME(JumpFloodComponent2D)
UJumpFloodComponent2D::UJumpFloodComponent2D(const FObjectInitializer& ObjectInitializer)
: Super(ObjectInitializer)
, BlurPasses(1)
, CompletedBlurPasses(0)
{
bCanEverAffectNavigation = false;
}
bool UJumpFloodComponent2D::ValidateJumpFloodRenderTargets()
{
if ((RTA == nullptr)
|| (RTB == nullptr)
|| (RTA->GetFormat() != RTB->GetFormat())
|| (RTA->SizeX != RTB->SizeX)
|| (RTA->SizeY != RTB->SizeY))
{
UE_LOG(LogWaterEditor, Error, TEXT("Invalid Render Target used in Jump Flood Component 2D."));
return false;
}
return true;
}
bool UJumpFloodComponent2D::ValidateJumpFloodRequirements()
{
if (JumpStepMID == nullptr)
{
UE_LOG(LogWaterEditor, Error, TEXT("Invalid Jump Step material used in Jump Flood Component 2D."));
return false;
}
if (UseBlur && (BlurEdgesMID == nullptr))
{
UE_LOG(LogWaterEditor, Error, TEXT("Invalid Blur Edges material used in Jump Flood Component 2D."));
return false;
}
if (FindEdgesMID == nullptr)
{
UE_LOG(LogWaterEditor, Error, TEXT("Invalid Find Edges material used in Jump Flood Component 2D."));
return false;
}
return ValidateJumpFloodRenderTargets();
}
void UJumpFloodComponent2D::JumpFlood(UTextureRenderTarget2D* SeedRT, float SceneCaptureZ, FLinearColor Curl, bool UseDepth, float ZLocationT)
{
CreateMIDs();
if (!ValidateJumpFloodRequirements())
{
UE_LOG(LogWaterEditor, Error, TEXT("Invalid setup for Jump Flood Component 2D. Aborting JumpFlood."));
return;
}
check(JumpStepMID != nullptr);
FindEdges(SeedRT, SceneCaptureZ, Curl, UseDepth, ZLocationT);
// Edge Blur
if (UseBlur)
{
for(int32 BlurPassIndex = 0, NumBlurPasses = FMath::Min(BlurPasses, 9) ; BlurPassIndex < NumBlurPasses; ++BlurPassIndex)
{
SingleBlurStep();
}
}
JumpStepMID->SetVectorParameterValue(FName(TEXT("TextureSize")), FLinearColor((float)RTA->SizeX, (float)RTA->SizeY, 0.0f, 0.0f));
CompletedPasses = 0;
RequiredPasses = FMath::CeilToInt(FMath::Loge((float)FMath::Max(RTA->SizeX, RTA->SizeY)) / FMath::Loge(2.0f));
while (CompletedPasses < RequiredPasses)
{
SingleJumpStep();
}
}
bool UJumpFloodComponent2D::CreateMIDs()
{
JumpStepMID = FWaterUtils::GetOrCreateTransientMID(JumpStepMID, TEXT("JumpStepMID"), JumpStepMaterial);
BlurEdgesMID = FWaterUtils::GetOrCreateTransientMID(BlurEdgesMID, TEXT("BlurEdgesMID"), BlurEdgesMaterial);
FindEdgesMID = FWaterUtils::GetOrCreateTransientMID(FindEdgesMID, TEXT("FindEdgesMID"), FindEdgesMaterial);
if ((JumpStepMID == nullptr) || (BlurEdgesMID == nullptr) || (FindEdgesMID == nullptr))
{
UE_LOG(LogWaterEditor, Error, TEXT("Invalid JumpFlood materials."));
return false;
}
return true;
}
void UJumpFloodComponent2D::AssignRenderTargets(UTextureRenderTarget2D* InRTA, UTextureRenderTarget2D* InRTB)
{
RTA = InRTA;
RTB = InRTB;
}
UTextureRenderTarget2D* UJumpFloodComponent2D::SingleJumpStep()
{
if (JumpStepMID == nullptr)
{
UE_LOG(LogWaterEditor, Error, TEXT("Invalid Jump Step material for Jump Flood Component 2D. Aborting SingleJumpStep."));
return nullptr;
}
if (!ValidateJumpFloodRenderTargets())
{
UE_LOG(LogWaterEditor, Error, TEXT("Invalid Render Targetfor Jump Flood Component 2D. Aborting SingleJumpStep."));
return nullptr;
}
check(JumpStepMID)
JumpStepMID->SetScalarParameterValue(FName(TEXT("Index")), float(CompletedPasses+1));
const int32 Offset = CompletedBlurPasses % 2;
JumpStepMID->SetTextureParameterValue(FName(TEXT("RT")), PingPongSource(Offset));
UTextureRenderTarget2D* RenderTarget = PingPongTarget(Offset);
UKismetRenderingLibrary::ClearRenderTarget2D(this, RenderTarget, FLinearColor::Black);
UKismetRenderingLibrary::DrawMaterialToRenderTarget(this, RenderTarget, JumpStepMID);
++CompletedPasses;
return PingPongSource(Offset);
}
UTextureRenderTarget2D* UJumpFloodComponent2D::FindEdges(UTextureRenderTarget2D* InSeed, float InCaptureZ, FLinearColor InCurl, bool InUseDepth, float InZLocation)
{
if (FindEdgesMID == nullptr)
{
UE_LOG(LogWaterEditor, Error, TEXT("Invalid Find Edges material for Jump Flood Component 2D. Aborting FindEdges."));
return nullptr;
}
if (!ValidateJumpFloodRenderTargets())
{
UE_LOG(LogWaterEditor, Error, TEXT("Invalid Render Targetfor Jump Flood Component 2D. Aborting FindEdges."));
return nullptr;
}
check(FindEdgesMID);
CompletedBlurPasses = 0;
CompletedPasses = 0;
FindEdgesMID->SetVectorParameterValue(FName(TEXT("TextureSize")), FLinearColor((float)InSeed->SizeX, (float)InSeed->SizeY, 0.0f, 0.0f));
FindEdgesMID->SetTextureParameterValue(FName(TEXT("SeedEdgesRT")), InSeed);
FindEdgesMID->SetVectorParameterValue(FName(TEXT("Curl")), InCurl);
FindEdgesMID->SetScalarParameterValue(FName(TEXT("SceneCaptureZ")), InCaptureZ);
FindEdgesMID->SetScalarParameterValue(FName(TEXT("UsesDepth")), InUseDepth ? 1.0f : 0.0f);
FindEdgesMID->SetScalarParameterValue(FName(TEXT("Z")), InZLocation);
UKismetRenderingLibrary::ClearRenderTarget2D(this, RTA, FLinearColor::Black);
UKismetRenderingLibrary::ClearRenderTarget2D(this, RTB, FLinearColor::Black);
UKismetRenderingLibrary::DrawMaterialToRenderTarget(this, RTA, FindEdgesMID);
return PingPongSource(0);
}
void UJumpFloodComponent2D::FindEdges_Debug(UTextureRenderTarget2D* InSeed, float InCaptureZ, FLinearColor InCurl, UTextureRenderTarget2D* inDest, float InZOffset)
{
if (FindEdgesMID == nullptr)
{
UE_LOG(LogWaterEditor, Error, TEXT("Invalid Find Edges material for Jump Flood Component 2D. Aborting FindEdges_Debug."));
return;
}
if (!ValidateJumpFloodRenderTargets())
{
UE_LOG(LogWaterEditor, Error, TEXT("Invalid Render Targetfor Jump Flood Component 2D. Aborting FindEdges_Debug."));
return;
}
check(FindEdgesMID);
CompletedPasses = 0;
FindEdgesMID->SetVectorParameterValue(FName(TEXT("TextureSize")), FLinearColor((float)InSeed->SizeX, (float)InSeed->SizeY, 0.0f, 0.0f));
FindEdgesMID->SetTextureParameterValue(FName(TEXT("SeedEdgesRT")), InSeed);
FindEdgesMID->SetVectorParameterValue(FName(TEXT("Curl")), InCurl);
FindEdgesMID->SetScalarParameterValue(FName(TEXT("SceneCaptureZ")), InCaptureZ);
FindEdgesMID->SetScalarParameterValue(FName(TEXT("UsesDepth")), FMath::IsNearlyEqual(InCaptureZ, 0.0f) ? 0.0f : 1.0f);
FindEdgesMID->SetScalarParameterValue(FName(TEXT("Z")), InZOffset);
UKismetRenderingLibrary::ClearRenderTarget2D(this, inDest, FLinearColor::Black);
UKismetRenderingLibrary::DrawMaterialToRenderTarget(this, inDest, FindEdgesMID);
}
UTextureRenderTarget2D* UJumpFloodComponent2D::SingleBlurStep()
{
if (BlurEdgesMID == nullptr)
{
UE_LOG(LogWaterEditor, Error, TEXT("Invalid Blur Edges material for Jump Flood Component 2D. Aborting SingleBlurStep."));
return nullptr;
}
if (!ValidateJumpFloodRenderTargets())
{
UE_LOG(LogWaterEditor, Error, TEXT("Invalid Render Targetfor Jump Flood Component 2D. Aborting SingleBlurStep."));
return nullptr;
}
check(BlurEdgesMID);
UTextureRenderTarget2D* Source = PingPongSource(0);
check(Source != nullptr);
UTextureRenderTarget2D* Target = PingPongTarget(0);
check(Target != nullptr);
FVector2D TextureSize((float)Source->SizeX, (float)Source->SizeY);
BlurEdgesMID->SetVectorParameterValue(FName(TEXT("TextureResolution")), FLinearColor(TextureSize.X, TextureSize.Y, 0.0f, 0.0f));
BlurEdgesMID->SetTextureParameterValue(FName(TEXT("SeedEdgesRT")), Source);
UKismetRenderingLibrary::ClearRenderTarget2D(this, Target, FLinearColor::Black);
UKismetRenderingLibrary::DrawMaterialToRenderTarget(this, Target, BlurEdgesMID);
++CompletedPasses;
++CompletedBlurPasses;
return Source;
}
UTextureRenderTarget2D* UJumpFloodComponent2D::PingPongSource(int32 Offset) const
{
if ((Offset + CompletedPasses) % 2)
{
return RTB;
}
else
{
return RTA;
}
}
UTextureRenderTarget2D* UJumpFloodComponent2D::PingPongTarget(int32 Offset) const
{
if ((Offset + CompletedPasses + 1) % 2)
{
return RTB;
}
else
{
return RTA;
}
}