261 lines
8.0 KiB
C++
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;
|
|
}
|
|
}
|
|
|