Files
UnrealEngine/Engine/Plugins/TextureGraph/Source/TextureGraphEngine/FxMat/RenderMaterial_FX_MinMax.cpp
2025-05-18 13:04:45 +08:00

113 lines
2.9 KiB
C++

// Copyright Epic Games, Inc. All Rights Reserved.
#include "RenderMaterial_FX_MinMax.h"
#include "FxMat/FxMaterial.h"
#include "Job/JobArgs.h"
#include "Job/Job.h"
#include "Transform/BlobTransform.h"
#include "Device/FX/DeviceBuffer_FX.h"
#include "Device/FX/Device_FX.h"
#include "2D/Tex.h"
#include <TextureResource.h>
DEFINE_LOG_CATEGORY(LogRenderMaterial_FX_MinMax);
RenderMaterial_FX_MinMax::RenderMaterial_FX_MinMax(FString InName, FxMaterialPtr InMaterial, FxMaterialPtr InSecondPassMaterial) : RenderMaterial_FX(InName, InMaterial)
{
SecondPassMaterial = InSecondPassMaterial;
}
RenderMaterial_FX_MinMax::~RenderMaterial_FX_MinMax()
{
}
AsyncPrepareResult RenderMaterial_FX_MinMax::PrepareResources(const TransformArgs& Args)
{
int Width = SourceDesc.Width;
int Height = SourceDesc.Height;
std::vector<std::decay_t<AsyncTexPtr>, std::allocator<std::decay_t<AsyncTexPtr>>> Promises;
while (Width > 1 && Height > 1)
{
Width = FMath::Max(Width >> 1, 1);
Height = FMath::Max(Height >> 1, 1);
if (Width > 1 && Height > 1)
{
BufferDescriptor Desc;
Desc.Width = Width;
Desc.Height = Height;
Desc.Format = SourceDesc.Format;
Desc.ItemsPerPoint = SourceDesc.ItemsPerPoint;
Desc.bIsSRGB = SourceDesc.bIsSRGB;
DownsampledResultTargets.Add(Device_FX::Get()->AllocateRenderTarget(Desc));
}
}
return cti::make_ready_continuable(0);
}
AsyncTransformResultPtr RenderMaterial_FX_MinMax::Exec(const TransformArgs& Args)
{
check(IsInRenderingThread());
TexPtr Source; // Source Texture
TexPtr Target;
int Width = SourceDesc.Width;
int Height = SourceDesc.Height;
for (int PassIndex = 0; PassIndex < DownsampledResultTargets.Num() + 1; PassIndex++)
{
Width = FMath::Max(Width >> 1, 1);
Height = FMath::Max(Height >> 1, 1);
if (Width == 1 && Height == 1)
{
BlobPtr TargetBlob = Args.Target.lock();
check(TargetBlob);
DeviceBuffer_FX* TargetBuffer = dynamic_cast<DeviceBuffer_FX*>(TargetBlob->GetBufferRef().get());
check(TargetBuffer);
Target = TargetBuffer->GetTexture();
check(Target.get());
}
else
{
Target = DownsampledResultTargets[PassIndex];
}
FTextureRenderTarget2DResource* RTRes = (FTextureRenderTarget2DResource*)Target->GetRenderTarget()->GetRenderTargetResource();
check(RTRes != nullptr);
if (PassIndex > 0)
{
FXMaterial = SecondPassMaterial;
SetSourceTexture(*Source.get());
SetFloat("DX", 1 / (float)Source->GetWidth());
SetFloat("DY", 1 / (float)Source->GetHeight());
}
auto& RHI = Device_FX::Get()->RHI();
FTextureRHIRef TextureRHI = RTRes->GetTextureRHI();
check(TextureRHI);
TextureRHI->SetName(FName(Target->GetRenderTarget()->GetName()));
FXMaterial->Blit(RHI, TextureRHI, Args.Mesh, Args.TargetId);
Source = Target;
}
TransformResultPtr Result = std::make_shared<TransformResult>();
Result->Target = Args.JobObj->GetResultRef();
return cti::make_ready_continuable(Result);
}