Files
UShaderLab/Source/UShaderLabBuilder/Private/ShaderLabIntrinsics_View.cpp
Eragon-Brisingr 49b04addb4 Support UE 5.7
2026-07-07 13:07:53 +08:00

87 lines
5.0 KiB
C++

// Copyright UShaderLab. All Rights Reserved.
//
// View / camera / screen intrinsics.
#include "ShaderLabIntrinsics.h"
#include "Misc/EngineVersionComparison.h"
#include "Materials/MaterialExpressionCameraPositionWS.h"
#include "Materials/MaterialExpressionCameraVectorWS.h"
#include "Materials/MaterialExpressionEyeAdaptation.h"
#include "Materials/MaterialExpressionIsFirstPerson.h"
#include "Materials/MaterialExpressionIsOrthographic.h"
#include "Materials/MaterialExpressionLightVector.h"
#if !UE_VERSION_OLDER_THAN(5, 8, 0)
#include "Materials/MaterialExpressionMainDirectionalLight.h" // 5.8+ only
#endif
#include "Materials/MaterialExpressionPixelDepth.h"
#include "Materials/MaterialExpressionReflectionVectorWS.h"
#include "Materials/MaterialExpressionSceneTexelSize.h"
#include "Materials/MaterialExpressionScreenPosition.h"
#include "Materials/MaterialExpressionViewProperty.h"
#include "Materials/MaterialExpressionViewSize.h"
#include "Materials/MaterialExpressionWorldPosition.h"
void RegisterViewIntrinsics(FShaderLabIntrinsicRegistry& Registry)
{
using namespace ShaderLabIntrinsic_Private;
using EFreq = EShaderLabIntrinsicFrequency;
AddSimple(Registry, TEXT("WorldPosition"), EFreq::Any, TEXT("float3"), [](UMaterial& M) { return MakeSimple<UMaterialExpressionWorldPosition>(M); });
AddSimple(Registry, TEXT("CameraPositionWS"), EFreq::Any, TEXT("float3"), [](UMaterial& M) { return MakeSimple<UMaterialExpressionCameraPositionWS>(M); });
AddSimple(Registry, TEXT("CameraVectorWS"), EFreq::Any, TEXT("float3"), [](UMaterial& M) { return MakeSimple<UMaterialExpressionCameraVectorWS>(M); });
AddSimple(Registry, TEXT("LightVector"), EFreq::Any, TEXT("float3"), [](UMaterial& M) { return MakeSimple<UMaterialExpressionLightVector>(M); });
AddSimple(Registry, TEXT("PixelDepth"), EFreq::PixelOnly, TEXT("float"), [](UMaterial& M) { return MakeSimple<UMaterialExpressionPixelDepth>(M); });
AddSimple(Registry, TEXT("ScreenPosition"), EFreq::PixelOnly, TEXT("float2"), [](UMaterial& M) { return MakeSimple<UMaterialExpressionScreenPosition>(M); });
AddSimple(Registry, TEXT("ReflectionVectorWS"), EFreq::PixelOnly, TEXT("float3"), [](UMaterial& M) { return MakeSimple<UMaterialExpressionReflectionVectorWS>(M); });
AddSimple(Registry, TEXT("ViewSize"), EFreq::Any, TEXT("float2"), [](UMaterial& M) { return MakeSimple<UMaterialExpressionViewSize>(M); });
AddSimple(Registry, TEXT("SceneTexelSize"), EFreq::Any, TEXT("float2"), [](UMaterial& M) { return MakeSimple<UMaterialExpressionSceneTexelSize>(M); });
AddSimple(Registry, TEXT("IsOrthographic"), EFreq::Any, TEXT("float"), [](UMaterial& M) { return MakeSimple<UMaterialExpressionIsOrthographic>(M); });
AddSimple(Registry, TEXT("EyeAdaptation"), EFreq::PixelOnly, TEXT("float"), [](UMaterial& M) { return MakeSimple<UMaterialExpressionEyeAdaptation>(M); });
AddSimple(Registry, TEXT("IsFirstPerson"), EFreq::Any, TEXT("float"), [](UMaterial& M) { return MakeSimple<UMaterialExpressionIsFirstPerson>(M); });
// MainDirectionalLight is multi-output (Illuminance, Direction) — one intrinsic per output pin.
// UMaterialExpressionMainDirectionalLight is 5.8+; the intrinsics are simply not registered on 5.7
// (a .usl using them fails the build with "unknown UE_ intrinsic", which is the correct contract).
#if !UE_VERSION_OLDER_THAN(5, 8, 0)
AddSimple(Registry, TEXT("MainDirectionalLightIlluminance"), EFreq::PixelOnly, TEXT("float3"), [](UMaterial& M) { return MakeSimple<UMaterialExpressionMainDirectionalLight>(M); }, 0);
AddSimple(Registry, TEXT("MainDirectionalLightDirection"), EFreq::PixelOnly, TEXT("float3"), [](UMaterial& M) { return MakeSimple<UMaterialExpressionMainDirectionalLight>(M); }, 1);
#endif
// ViewProperty(Property) — Property is an EMaterialExposedViewProperty token.
{
FShaderLabIntrinsicDesc Desc;
Desc.Name = FName(TEXT("ViewProperty"));
Desc.ReturnType = TEXT("float4");
Desc.Doc = TEXT("Property is an EMaterialExposedViewProperty token (e.g. MEVP_FieldOfView).");
FShaderLabIntrinsicParam PropertyParam;
PropertyParam.Name = TEXT("Property");
// Safe: UShaderLabEditor depends on Engine, whose reflected enums register before any editor
// code runs, and this executes lazily at first registry use (build/command/test time).
PropertyParam.Enum = StaticEnum<EMaterialExposedViewProperty>();
check(PropertyParam.Enum);
Desc.Params = { MoveTemp(PropertyParam) };
Desc.MakeNode = [](UMaterial& M, const TArray<FString>& Args, FString& OutError) -> UMaterialExpression*
{
UMaterialExpressionViewProperty* E = NewObject<UMaterialExpressionViewProperty>(&M);
if (Args.Num() >= 1)
{
UEnum* Enum = StaticEnum<EMaterialExposedViewProperty>();
check(Enum);
const int64 Value = Enum->GetValueByNameString(Args[0]);
if (Value == INDEX_NONE)
{
OutError = FString::Printf(TEXT("unknown view property '%s'"), *Args[0]);
return nullptr;
}
E->Property = static_cast<EMaterialExposedViewProperty>(Value);
}
M.GetExpressionCollection().AddExpression(E);
return E;
};
Registry.Register(MoveTemp(Desc));
}
}