diff --git a/AssetGenerator/Source/AssetGenerator/Private/Toolkit/AssetTypeGenerator/MaterialGenerator.cpp b/AssetGenerator/Source/AssetGenerator/Private/Toolkit/AssetTypeGenerator/MaterialGenerator.cpp index 91a6cef..264c24e 100644 --- a/AssetGenerator/Source/AssetGenerator/Private/Toolkit/AssetTypeGenerator/MaterialGenerator.cpp +++ b/AssetGenerator/Source/AssetGenerator/Private/Toolkit/AssetTypeGenerator/MaterialGenerator.cpp @@ -4,6 +4,7 @@ #include "Engine/Texture.h" #include "Engine/Texture2DArray.h" #include "Kismet2/BlueprintEditorUtils.h" +#include "MaterialDomain.h" #include "MaterialEditor/Public/MaterialEditingLibrary.h" #include "MaterialGraph/MaterialGraphNode_Comment.h" #include "Materials/Material.h" @@ -15,6 +16,7 @@ #include "Materials/MaterialExpressionLandscapeGrassOutput.h" #include "Materials/MaterialExpressionMultiply.h" #include "Materials/MaterialExpressionQualitySwitch.h" +#include "Materials/MaterialExpressionReflectionVectorWS.h" #include "Materials/MaterialExpressionRuntimeVirtualTextureSampleParameter.h" #include "Materials/MaterialExpressionScalarParameter.h" #include "Materials/MaterialExpressionStaticSwitchParameter.h" @@ -297,6 +299,10 @@ UClass* GetTextureSampleParameterClassForTexture(UTexture* Texture) { return NULL; } +FORCEINLINE static bool DoesTextureSamplerRequireUVW(UClass* ExpressionClass) { + return ExpressionClass->IsChildOf() || ExpressionClass->IsChildOf(); +} + void UMaterialGenerator::ApplyOtherLayoutChanges(UMaterial* Material, FMaterialLayoutChangeInfo& LayoutChangeInfo) { //Add Parameter Collection parameter nodes for (UMaterialParameterCollection* NewCollection : LayoutChangeInfo.NewReferencedParameterCollections) { @@ -481,6 +487,12 @@ void UMaterialGenerator::SpawnNewMaterialParameterNodes(UMaterial* Material, FMa Expression->SetParameterName(NewTextureParameter.ParameterInfo.Name); Expression->Texture = NewTextureParameter.ParameterValue.Get(); Expression->AutoSetSampleType(); + + if (DoesTextureSamplerRequireUVW(ExpressionClass)) { + const FVector2D NodePos = FVector2D(Expression->MaterialExpressionEditorX - 256, Expression->MaterialExpressionEditorY); + UMaterialExpressionReflectionVectorWS* ReflectionVector = SpawnMaterialExpression(Material, NodePos); + Expression->Coordinates.Connect(0, ReflectionVector); + } } } @@ -670,20 +682,47 @@ void DisconnectIfExpressionMissing(FExpressionInput& Input, UMaterial* Material) } } +static bool PreferEmissiveColor(EMaterialDomain Domain) { + return Domain == EMaterialDomain::MD_PostProcess || Domain == EMaterialDomain::MD_UI; +} + void UMaterialGenerator::TryConnectBasicMaterialPins(UMaterial* Material) { FExpressionInput& BaseColorInput = Material->GetEditorOnlyData()->BaseColor; FExpressionInput& NormalInput = Material->GetEditorOnlyData()->Normal; + FExpressionInput& EmissiveColorInput = Material->GetEditorOnlyData()->EmissiveColor; DisconnectIfExpressionMissing(BaseColorInput, Material); DisconnectIfExpressionMissing(NormalInput, Material); + DisconnectIfExpressionMissing(EmissiveColorInput, Material); + + if (Material->MaterialDomain == EMaterialDomain::MD_PostProcess) { + const FVector2D NodePos = FVector2D(Material->EditorX - 384, Material->EditorY); + // This terribleness is necessary because UMaterialExpressionSceneTexture + // is not exported at all, so there is no way to use the type directly... + UPackage* EngineScriptPackage = FindPackage(NULL, UMaterialExpressionSceneTexture::StaticPackage()); + TSubclassOf SceneTextureExpressionClass = FindObjectChecked(EngineScriptPackage, TEXT("MaterialExpressionSceneTexture")); + UMaterialExpressionSceneTexture* SceneTextureExpression = static_cast(SpawnMaterialExpression(Material, NodePos, SceneTextureExpressionClass)); + SceneTextureExpression->SceneTextureId = PPI_PostProcessInput0; + EmissiveColorInput.Connect(0, SceneTextureExpression); + return; + } + + FExpressionInput& ColorInput = PreferEmissiveColor(Material->MaterialDomain) ? EmissiveColorInput : BaseColorInput; for (UMaterialExpression* Expression : Material->GetExpressions()) { if (UMaterialExpressionTextureSample* TextureSample = Cast(Expression)) { - if ((TextureSample->SamplerType == SAMPLERTYPE_Color || TextureSample->SamplerType == SAMPLERTYPE_LinearColor) && !BaseColorInput.IsConnected()) { - BaseColorInput.Connect(0, TextureSample); - } - else if (TextureSample->SamplerType == SAMPLERTYPE_Normal && !NormalInput.IsConnected()) { - NormalInput.Connect(0, TextureSample); + switch (TextureSample->SamplerType) { + case SAMPLERTYPE_Color: + case SAMPLERTYPE_LinearColor: + if (!ColorInput.IsConnected()) { + ColorInput.Connect(0, TextureSample); + } + break; + case SAMPLERTYPE_Normal: + if (!NormalInput.IsConnected()) { + NormalInput.Connect(0, TextureSample); + } + break; } } } diff --git a/AssetGenerator/Source/AssetGenerator/Public/Toolkit/AssetTypeGenerator/MaterialGenerator.h b/AssetGenerator/Source/AssetGenerator/Public/Toolkit/AssetTypeGenerator/MaterialGenerator.h index 4161f15..57eaca8 100644 --- a/AssetGenerator/Source/AssetGenerator/Public/Toolkit/AssetTypeGenerator/MaterialGenerator.h +++ b/AssetGenerator/Source/AssetGenerator/Public/Toolkit/AssetTypeGenerator/MaterialGenerator.h @@ -149,15 +149,21 @@ class UMaterialGenerator : public UAssetTypeGenerator { static FVector2D GetGoodPlaceForNewMaterialExpression(UMaterial* Material); static void ForceMaterialCompilation(UMaterial* Material); static void ConnectBasicParameterPinsIfPossible(UMaterial* Material, const FString& ErrorMessage); - + template - FORCEINLINE static T* SpawnMaterialExpression(UMaterial* Material, UClass* ExpressionClass = T::StaticClass()) { - const FVector2D NodePos = GetGoodPlaceForNewMaterialExpression(Material); - T* NewMaterialExpression = CastChecked(UMaterialEditingLibrary::CreateMaterialExpressionEx(Material, NULL, ExpressionClass, NULL, NodePos.X, NodePos.Y)); + FORCEINLINE static T* SpawnMaterialExpression(UMaterial* Material, const FVector2D NodePos, UClass* ExpressionClass = T::StaticClass()) + { + T* NewMaterialExpression = CastChecked(UMaterialEditingLibrary::CreateMaterialExpressionEx(Material, NULL, ExpressionClass, NULL, NodePos.X, NodePos.Y)); if (Material->MaterialGraph) { Material->MaterialGraph->AddExpression(NewMaterialExpression, false); } return NewMaterialExpression; } + + template + FORCEINLINE static T* SpawnMaterialExpression(UMaterial* Material, UClass* ExpressionClass = T::StaticClass()) + { + return SpawnMaterialExpression(Material, GetGoodPlaceForNewMaterialExpression(Material), ExpressionClass); + } };