Files
2025-05-18 13:04:45 +08:00

168 lines
8.3 KiB
C++

// Copyright Epic Games, Inc. All Rights Reserved.
#pragma once
#include "Dataflow/DataflowEngine.h"
#include "Dataflow/DataflowSelection.h"
#include "Dataflow/DataflowImage.h"
#include "GeometryCollection/ManagedArrayCollection.h"
#include "FractureAutoUV.h"
#include "Image/ImageBuilder.h"
#include "Engine/Texture2D.h"
#include "GeometryCollectionTextureNodes.generated.h"
UENUM()
enum class ECollectionBakeTextureAttribute: int32
{
// no attribute selected
None = (int32)UE::PlanarCut::EBakeAttributes::None,
// Phi value : distance to the closest face
DistanceToExternal = (int32)UE::PlanarCut::EBakeAttributes::DistanceToExternal,
// Ambient occlusion
AmbientOcclusion = (int32)UE::PlanarCut::EBakeAttributes::AmbientOcclusion,
// surface smoothed curvature
Curvature = (int32)UE::PlanarCut::EBakeAttributes::Curvature,
// Normal X coordinate ( object space )
NormalX = (int32)UE::PlanarCut::EBakeAttributes::NormalX,
// Normal Y coordinate ( object space )
NormalY = (int32)UE::PlanarCut::EBakeAttributes::NormalY,
// Normal Z coordinate ( object space )
NormalZ = (int32)UE::PlanarCut::EBakeAttributes::NormalZ,
// Position X coordinate ( relative to object local bounds )
PositionX = (int32)UE::PlanarCut::EBakeAttributes::PositionX,
// Position Y coordinate ( relative to object local bounds )
PositionY = (int32)UE::PlanarCut::EBakeAttributes::PositionY,
// Position Z coordinate ( relative to object local bounds )
PositionZ = (int32)UE::PlanarCut::EBakeAttributes::PositionZ,
};
/*
* Bake a texture from a geometry collection
* Output to a 4 channels Image object ( RGBA )
*/
USTRUCT()
struct FBakeTextureFromCollectionDataflowNode : public FDataflowNode
{
GENERATED_USTRUCT_BODY()
DATAFLOW_NODE_DEFINE_INTERNAL(FBakeTextureFromCollectionDataflowNode, "BakeTextureFromCollection", "GeometryCollection|Texture", "")
DATAFLOW_NODE_RENDER_TYPE("SurfaceRender", FGeometryCollection::StaticType(), "Collection", "UVChannel")
private:
/** Target Collection */
UPROPERTY(meta = (DataflowInput, DataflowOutput, DataflowPassthrough = "Collection", DataflowIntrinsic))
FManagedArrayCollection Collection;
/** Output image with the bake attributes */
UPROPERTY(meta = (DataflowOutput))
FDataflowImage Image;
/** selection of faces to bake : if not connected, all faces will be used */
UPROPERTY(meta = (DataflowInput))
FDataflowFaceSelection FaceSelection;
/** resolution of the image to bake */
UPROPERTY(EditAnywhere, Category = ImageOptions, meta = (DataflowInput))
EDataflowImageResolution Resolution = EDataflowImageResolution::Resolution512;
/** Approximate space to leave between UV islands, measured in texels */
UPROPERTY(EditAnywhere, Category = ChannelOptions, meta = (DataflowInput, ClampMin = 1, UIMin = 1))
int32 GutterSize = 1;
/** Index of the added UV channel */
UPROPERTY(EditAnywhere, Category = ChannelOptions, meta = (DataflowInput, DataflowOutput, DataflowPassthrough = "UVChannel", ClampMin = 0, ClampMax = 7, UIMin = 0, UIMax = 7))
int32 UVChannel = 0;
/** Attribute to bake in the red channel */
UPROPERTY(EditAnywhere, Category = ChannelOptions)
ECollectionBakeTextureAttribute RedChannel = ECollectionBakeTextureAttribute::DistanceToExternal;
/** Attribute to bake in the green channel */
UPROPERTY(EditAnywhere, Category = ChannelOptions)
ECollectionBakeTextureAttribute GreenChannel = ECollectionBakeTextureAttribute::AmbientOcclusion;
/** Attribute to bake in the blue channel */
UPROPERTY(EditAnywhere, Category = ChannelOptions)
ECollectionBakeTextureAttribute BlueChannel = ECollectionBakeTextureAttribute::Curvature;
/** Attribute to bake in the alpha channel */
UPROPERTY(EditAnywhere, Category = ChannelOptions)
ECollectionBakeTextureAttribute AlphaChannel = ECollectionBakeTextureAttribute::None;
/** Max distance to search for the outer mesh surface */
UPROPERTY(EditAnywhere, Category = DistToOuterSettings, meta = (
DataflowInput,
EditCondition = "RedChannel == ECollectionBakeTextureAttribute::DistanceToExternal || GreenChannel == ECollectionBakeTextureAttribute::DistanceToExternal || BlueChannel == ECollectionBakeTextureAttribute::DistanceToExternal || AlphaChannel == ECollectionBakeTextureAttribute::DistanceToExternal",
UIMin = "1", UIMax = "100", ClampMin = ".01", ClampMax = "1000"))
float MaxDistance = 100;
/** Number of occlusion rays */
UPROPERTY(EditAnywhere, Category = AmbientOcclusionSettings, meta = (
DataflowInput,
EditCondition = "RedChannel == ECollectionBakeTextureAttribute::AmbientOcclusion || GreenChannel == ECollectionBakeTextureAttribute::AmbientOcclusion || BlueChannel == ECollectionBakeTextureAttribute::AmbientOcclusion || AlphaChannel == ECollectionBakeTextureAttribute::AmbientOcclusion",
UIMin = "1", UIMax = "1024", ClampMin = "0", ClampMax = "50000"))
int32 OcclusionRays = 16;
/** Pixel Radius of Gaussian Blur Kernel applied to AO map (0 will apply no blur) */
UPROPERTY(EditAnywhere, Category = AmbientOcclusionSettings, meta = (
DataflowInput,
EditCondition = "RedChannel == ECollectionBakeTextureAttribute::AmbientOcclusion || GreenChannel == ECollectionBakeTextureAttribute::AmbientOcclusion || BlueChannel == ECollectionBakeTextureAttribute::AmbientOcclusion || AlphaChannel == ECollectionBakeTextureAttribute::AmbientOcclusion",
UIMin = "0", UIMax = "10.0", ClampMin = "0", ClampMax = "100.0"))
float OcclusionBlurRadius = 2.25;
/** Pixel Radius of Gaussian Blur Kernel applied to Curvature map (0 will apply no blur) */
UPROPERTY(EditAnywhere, Category = SmoothedCurvatureSettings, meta = (
DataflowInput,
EditCondition = "RedChannel == ECollectionBakeTextureAttribute::Curvature || GreenChannel == ECollectionBakeTextureAttribute::Curvature || BlueChannel == ECollectionBakeTextureAttribute::Curvature || AlphaChannel == ECollectionBakeTextureAttribute::Curvature",
UIMin = "0", UIMax = "10.0", ClampMin = "0", ClampMax = "100.0"))
float CurvatureBlurRadius = 2.25;
/** Voxel resolution of smoothed shape representation */
UPROPERTY(EditAnywhere, Category = SmoothedCurvatureSettings, meta = (
DataflowInput,
EditCondition = "RedChannel == ECollectionBakeTextureAttribute::Curvature || GreenChannel == ECollectionBakeTextureAttribute::Curvature || BlueChannel == ECollectionBakeTextureAttribute::Curvature || AlphaChannel == ECollectionBakeTextureAttribute::Curvature",
UIMin = "8", UIMax = "512", ClampMin = "4", ClampMax = "1024"))
int32 VoxelResolution = 128;
/** Amount of smoothing iterations to apply before computing curvature */
UPROPERTY(EditAnywhere, Category = SmoothedCurvatureSettings, meta = (
DataflowInput,
EditCondition = "RedChannel == ECollectionBakeTextureAttribute::Curvature || GreenChannel == ECollectionBakeTextureAttribute::Curvature || BlueChannel == ECollectionBakeTextureAttribute::Curvature || AlphaChannel == ECollectionBakeTextureAttribute::Curvature",
UIMin = "2", UIMax = "100", ClampMin = "2", ClampMax = "1000"))
int32 SmoothingIterations = 10;
/** Distance to search for correspondence between fractured shape and smoothed shape, as factor of voxel size */
UPROPERTY(EditAnywhere, Category = SmoothedCurvatureSettings, meta = (
DataflowInput,
EditCondition = "RedChannel == ECollectionBakeTextureAttribute::Curvature || GreenChannel == ECollectionBakeTextureAttribute::Curvature || BlueChannel == ECollectionBakeTextureAttribute::Curvature || AlphaChannel == ECollectionBakeTextureAttribute::Curvature",
UIMin = "2", UIMax = "10.0", ClampMin = "1", ClampMax = "100.0"))
float ThicknessFactor = 4;
/** Curvatures in the range [-MaxCurvature, MaxCurvature] will be mapped from [0,1]. Values outside that range will be clamped */
UPROPERTY(EditAnywhere, Category = SmoothedCurvatureSettings, meta = (
DataflowInput,
EditCondition = "RedChannel == ECollectionBakeTextureAttribute::Curvature || GreenChannel == ECollectionBakeTextureAttribute::Curvature || BlueChannel == ECollectionBakeTextureAttribute::Curvature || AlphaChannel == ECollectionBakeTextureAttribute::Curvature",
UIMin = ".01", UIMax = "1", ClampMin = ".0001", ClampMax = "10"))
float MaxCurvature = .1;
virtual void Evaluate(UE::Dataflow::FContext& Context, const FDataflowOutput* Out) const override;
public:
FBakeTextureFromCollectionDataflowNode(const UE::Dataflow::FNodeParameters& InParam, FGuid InGuid = FGuid::NewGuid());
};
namespace UE::Dataflow
{
void RegisterGeometryCollectionTextureNodes();
}