// Copyright UShaderLab. All Rights Reserved. // // View / camera / screen intrinsics. #include "ShaderLabIntrinsics.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" #include "Materials/MaterialExpressionMainDirectionalLight.h" #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(M); }); AddSimple(Registry, TEXT("CameraPositionWS"), EFreq::Any, TEXT("float3"), [](UMaterial& M) { return MakeSimple(M); }); AddSimple(Registry, TEXT("CameraVectorWS"), EFreq::Any, TEXT("float3"), [](UMaterial& M) { return MakeSimple(M); }); AddSimple(Registry, TEXT("LightVector"), EFreq::Any, TEXT("float3"), [](UMaterial& M) { return MakeSimple(M); }); AddSimple(Registry, TEXT("PixelDepth"), EFreq::PixelOnly, TEXT("float"), [](UMaterial& M) { return MakeSimple(M); }); AddSimple(Registry, TEXT("ScreenPosition"), EFreq::PixelOnly, TEXT("float2"), [](UMaterial& M) { return MakeSimple(M); }); AddSimple(Registry, TEXT("ReflectionVectorWS"), EFreq::PixelOnly, TEXT("float3"), [](UMaterial& M) { return MakeSimple(M); }); AddSimple(Registry, TEXT("ViewSize"), EFreq::Any, TEXT("float2"), [](UMaterial& M) { return MakeSimple(M); }); AddSimple(Registry, TEXT("SceneTexelSize"), EFreq::Any, TEXT("float2"), [](UMaterial& M) { return MakeSimple(M); }); AddSimple(Registry, TEXT("IsOrthographic"), EFreq::Any, TEXT("float"), [](UMaterial& M) { return MakeSimple(M); }); AddSimple(Registry, TEXT("EyeAdaptation"), EFreq::PixelOnly, TEXT("float"), [](UMaterial& M) { return MakeSimple(M); }); AddSimple(Registry, TEXT("IsFirstPerson"), EFreq::Any, TEXT("float"), [](UMaterial& M) { return MakeSimple(M); }); // MainDirectionalLight is multi-output (Illuminance, Direction) — one intrinsic per output pin. AddSimple(Registry, TEXT("MainDirectionalLightIlluminance"), EFreq::PixelOnly, TEXT("float3"), [](UMaterial& M) { return MakeSimple(M); }, 0); AddSimple(Registry, TEXT("MainDirectionalLightDirection"), EFreq::PixelOnly, TEXT("float3"), [](UMaterial& M) { return MakeSimple(M); }, 1); // 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(); check(PropertyParam.Enum); Desc.Params = { MoveTemp(PropertyParam) }; Desc.MakeNode = [](UMaterial& M, const TArray& Args, FString& OutError) -> UMaterialExpression* { UMaterialExpressionViewProperty* E = NewObject(&M); if (Args.Num() >= 1) { UEnum* Enum = StaticEnum(); 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(Value); } M.GetExpressionCollection().AddExpression(E); return E; }; Registry.Register(MoveTemp(Desc)); } }