Change usl grammar same like as hlsl

This commit is contained in:
Eragon-Brisingr
2026-06-30 20:55:45 +08:00
parent f19bb1e750
commit 0845f71aea
7 changed files with 846 additions and 377 deletions

View File

@@ -63,6 +63,8 @@ void FShaderLabIntrinsicRegistry::Register(FShaderLabIntrinsicDesc Desc)
{
check(!Desc.Name.IsNone());
check(Desc.MakeNode);
// Contract: every intrinsic is IDE-describable so ShaderLab.IDE.Prepare can always emit a stub.
check(!Desc.ReturnType.IsEmpty());
Descs.Add(Desc.Name, MoveTemp(Desc));
}
@@ -71,35 +73,49 @@ const FShaderLabIntrinsicDesc* FShaderLabIntrinsicRegistry::Find(FName Name) con
return Descs.Find(Name);
}
void FShaderLabIntrinsicRegistry::ForEach(TFunctionRef<void(const FShaderLabIntrinsicDesc&)> Fn) const
{
for (const TPair<FName, FShaderLabIntrinsicDesc>& Pair : Descs)
{
Fn(Pair.Value);
}
}
void FShaderLabIntrinsicRegistry::RegisterBuiltins()
{
using namespace ShaderLabIntrinsic_Private;
using EFreq = EShaderLabIntrinsicFrequency;
// Helper for the common no-arg case.
auto AddSimple = [this](const TCHAR* Name, EFreq Freq, TFunction<UMaterialExpression*(UMaterial&)> Make)
// Helper for the common no-arg case (ReturnType drives the generated authoring stub).
auto AddSimple = [this](const TCHAR* Name, EFreq Freq, const TCHAR* ReturnType, TFunction<UMaterialExpression*(UMaterial&)> Make)
{
FShaderLabIntrinsicDesc Desc;
Desc.Name = FName(Name);
Desc.Frequency = Freq;
Desc.ReturnType = ReturnType;
Desc.MakeNode = [Make = MoveTemp(Make)](UMaterial& M, const TArray<FString>&, FString&) { return Make(M); };
Register(MoveTemp(Desc));
};
// --- A. Mesh / surface attributes ---
AddSimple(TEXT("VertexNormalWS"), EFreq::Any, [](UMaterial& M) { return MakeSimple<UMaterialExpressionVertexNormalWS>(M); });
AddSimple(TEXT("VertexTangentWS"), EFreq::Any, [](UMaterial& M) { return MakeSimple<UMaterialExpressionVertexTangentWS>(M); });
AddSimple(TEXT("PixelNormalWS"), EFreq::PixelOnly, [](UMaterial& M) { return MakeSimple<UMaterialExpressionPixelNormalWS>(M); });
AddSimple(TEXT("VertexColor"), EFreq::Any, [](UMaterial& M) { return MakeSimple<UMaterialExpressionVertexColor>(M); });
AddSimple(TEXT("TwoSidedSign"), EFreq::Any, [](UMaterial& M) { return MakeSimple<UMaterialExpressionTwoSidedSign>(M); });
AddSimple(TEXT("LightmapUVs"), EFreq::Any, [](UMaterial& M) { return MakeSimple<UMaterialExpressionLightmapUVs>(M); });
AddSimple(TEXT("PreSkinnedNormal"), EFreq::Any, [](UMaterial& M) { return MakeSimple<UMaterialExpressionPreSkinnedNormal>(M); });
AddSimple(TEXT("PreSkinnedPosition"), EFreq::Any, [](UMaterial& M) { return MakeSimple<UMaterialExpressionPreSkinnedPosition>(M); });
AddSimple(TEXT("VertexNormalWS"), EFreq::Any, TEXT("float3"), [](UMaterial& M) { return MakeSimple<UMaterialExpressionVertexNormalWS>(M); });
AddSimple(TEXT("VertexTangentWS"), EFreq::Any, TEXT("float3"), [](UMaterial& M) { return MakeSimple<UMaterialExpressionVertexTangentWS>(M); });
AddSimple(TEXT("PixelNormalWS"), EFreq::PixelOnly, TEXT("float3"), [](UMaterial& M) { return MakeSimple<UMaterialExpressionPixelNormalWS>(M); });
AddSimple(TEXT("VertexColor"), EFreq::Any, TEXT("float4"), [](UMaterial& M) { return MakeSimple<UMaterialExpressionVertexColor>(M); });
AddSimple(TEXT("TwoSidedSign"), EFreq::Any, TEXT("float"), [](UMaterial& M) { return MakeSimple<UMaterialExpressionTwoSidedSign>(M); });
AddSimple(TEXT("LightmapUVs"), EFreq::Any, TEXT("float2"), [](UMaterial& M) { return MakeSimple<UMaterialExpressionLightmapUVs>(M); });
AddSimple(TEXT("PreSkinnedNormal"), EFreq::Any, TEXT("float3"), [](UMaterial& M) { return MakeSimple<UMaterialExpressionPreSkinnedNormal>(M); });
AddSimple(TEXT("PreSkinnedPosition"), EFreq::Any, TEXT("float3"), [](UMaterial& M) { return MakeSimple<UMaterialExpressionPreSkinnedPosition>(M); });
// TextureCoordinate(Index[, UTiling, VTiling]) — const args configure the node (mechanism: scalar/int args).
{
FShaderLabIntrinsicDesc Desc;
Desc.Name = FName(TEXT("TextureCoordinate"));
Desc.ReturnType = TEXT("float2");
Desc.Params = { { TEXT("int"), TEXT("Index"), TEXT("") },
{ TEXT("float"), TEXT("UTiling"), TEXT("1") },
{ TEXT("float"), TEXT("VTiling"), TEXT("1") } };
Desc.Doc = TEXT("UV channel `Index`, optionally tiled.");
Desc.MakeNode = [](UMaterial& M, const TArray<FString>& Args, FString&) -> UMaterialExpression*
{
UMaterialExpressionTextureCoordinate* E = NewObject<UMaterialExpressionTextureCoordinate>(&M);
@@ -113,31 +129,34 @@ void FShaderLabIntrinsicRegistry::RegisterBuiltins()
}
// --- B. Positions / spaces ---
AddSimple(TEXT("WorldPosition"), EFreq::Any, [](UMaterial& M) { return MakeSimple<UMaterialExpressionWorldPosition>(M); });
AddSimple(TEXT("LocalPosition"), EFreq::Any, [](UMaterial& M) { return MakeSimple<UMaterialExpressionLocalPosition>(M); });
AddSimple(TEXT("ActorPositionWS"), EFreq::Any, [](UMaterial& M) { return MakeSimple<UMaterialExpressionActorPositionWS>(M); });
AddSimple(TEXT("ObjectPositionWS"), EFreq::Any, [](UMaterial& M) { return MakeSimple<UMaterialExpressionObjectPositionWS>(M); });
AddSimple(TEXT("CameraPositionWS"), EFreq::Any, [](UMaterial& M) { return MakeSimple<UMaterialExpressionCameraPositionWS>(M); });
AddSimple(TEXT("CameraVectorWS"), EFreq::Any, [](UMaterial& M) { return MakeSimple<UMaterialExpressionCameraVectorWS>(M); });
AddSimple(TEXT("LightVector"), EFreq::Any, [](UMaterial& M) { return MakeSimple<UMaterialExpressionLightVector>(M); });
AddSimple(TEXT("PixelDepth"), EFreq::PixelOnly, [](UMaterial& M) { return MakeSimple<UMaterialExpressionPixelDepth>(M); });
AddSimple(TEXT("ScreenPosition"), EFreq::PixelOnly, [](UMaterial& M) { return MakeSimple<UMaterialExpressionScreenPosition>(M); });
AddSimple(TEXT("WorldPosition"), EFreq::Any, TEXT("float3"), [](UMaterial& M) { return MakeSimple<UMaterialExpressionWorldPosition>(M); });
AddSimple(TEXT("LocalPosition"), EFreq::Any, TEXT("float3"), [](UMaterial& M) { return MakeSimple<UMaterialExpressionLocalPosition>(M); });
AddSimple(TEXT("ActorPositionWS"), EFreq::Any, TEXT("float3"), [](UMaterial& M) { return MakeSimple<UMaterialExpressionActorPositionWS>(M); });
AddSimple(TEXT("ObjectPositionWS"), EFreq::Any, TEXT("float3"), [](UMaterial& M) { return MakeSimple<UMaterialExpressionObjectPositionWS>(M); });
AddSimple(TEXT("CameraPositionWS"), EFreq::Any, TEXT("float3"), [](UMaterial& M) { return MakeSimple<UMaterialExpressionCameraPositionWS>(M); });
AddSimple(TEXT("CameraVectorWS"), EFreq::Any, TEXT("float3"), [](UMaterial& M) { return MakeSimple<UMaterialExpressionCameraVectorWS>(M); });
AddSimple(TEXT("LightVector"), EFreq::Any, TEXT("float3"), [](UMaterial& M) { return MakeSimple<UMaterialExpressionLightVector>(M); });
AddSimple(TEXT("PixelDepth"), EFreq::PixelOnly, TEXT("float"), [](UMaterial& M) { return MakeSimple<UMaterialExpressionPixelDepth>(M); });
AddSimple(TEXT("ScreenPosition"), EFreq::PixelOnly, TEXT("float2"), [](UMaterial& M) { return MakeSimple<UMaterialExpressionScreenPosition>(M); });
// --- C. Object / bounds (ObjectLocalBounds & PreSkinnedLocalBounds are multi-output; output 0) ---
AddSimple(TEXT("ObjectRadius"), EFreq::Any, [](UMaterial& M) { return MakeSimple<UMaterialExpressionObjectRadius>(M); });
AddSimple(TEXT("ObjectBounds"), EFreq::Any, [](UMaterial& M) { return MakeSimple<UMaterialExpressionObjectBounds>(M); });
AddSimple(TEXT("ObjectLocalBounds"), EFreq::Any, [](UMaterial& M) { return MakeSimple<UMaterialExpressionObjectLocalBounds>(M); });
AddSimple(TEXT("ObjectOrientation"), EFreq::Any, [](UMaterial& M) { return MakeSimple<UMaterialExpressionObjectOrientation>(M); });
AddSimple(TEXT("PreSkinnedLocalBounds"), EFreq::Any, [](UMaterial& M) { return MakeSimple<UMaterialExpressionPreSkinnedLocalBounds>(M); });
AddSimple(TEXT("ObjectRadius"), EFreq::Any, TEXT("float"), [](UMaterial& M) { return MakeSimple<UMaterialExpressionObjectRadius>(M); });
AddSimple(TEXT("ObjectBounds"), EFreq::Any, TEXT("float3"), [](UMaterial& M) { return MakeSimple<UMaterialExpressionObjectBounds>(M); });
AddSimple(TEXT("ObjectLocalBounds"), EFreq::Any, TEXT("float3"), [](UMaterial& M) { return MakeSimple<UMaterialExpressionObjectLocalBounds>(M); });
AddSimple(TEXT("ObjectOrientation"), EFreq::Any, TEXT("float3"), [](UMaterial& M) { return MakeSimple<UMaterialExpressionObjectOrientation>(M); });
AddSimple(TEXT("PreSkinnedLocalBounds"), EFreq::Any, TEXT("float3"), [](UMaterial& M) { return MakeSimple<UMaterialExpressionPreSkinnedLocalBounds>(M); });
// --- D. Instancing ---
AddSimple(TEXT("PerInstanceRandom"), EFreq::Any, [](UMaterial& M) { return MakeSimple<UMaterialExpressionPerInstanceRandom>(M); });
AddSimple(TEXT("PerInstanceFadeAmount"), EFreq::Any, [](UMaterial& M) { return MakeSimple<UMaterialExpressionPerInstanceFadeAmount>(M); });
AddSimple(TEXT("PerInstanceRandom"), EFreq::Any, TEXT("float"), [](UMaterial& M) { return MakeSimple<UMaterialExpressionPerInstanceRandom>(M); });
AddSimple(TEXT("PerInstanceFadeAmount"), EFreq::Any, TEXT("float"), [](UMaterial& M) { return MakeSimple<UMaterialExpressionPerInstanceFadeAmount>(M); });
// PerInstanceCustomData(DataIndex[, ConstDefaultValue]) — mechanism: const args + optional input pin left at default.
{
FShaderLabIntrinsicDesc Desc;
Desc.Name = FName(TEXT("PerInstanceCustomData"));
Desc.ReturnType = TEXT("float");
Desc.Params = { { TEXT("int"), TEXT("DataIndex"), TEXT("") },
{ TEXT("float"), TEXT("ConstDefaultValue"), TEXT("0") } };
Desc.MakeNode = [](UMaterial& M, const TArray<FString>& Args, FString&) -> UMaterialExpression*
{
UMaterialExpressionPerInstanceCustomData* E = NewObject<UMaterialExpressionPerInstanceCustomData>(&M);
@@ -150,13 +169,16 @@ void FShaderLabIntrinsicRegistry::RegisterBuiltins()
}
// --- Time ---
AddSimple(TEXT("Time"), EFreq::Any, [](UMaterial& M) { return MakeSimple<UMaterialExpressionTime>(M); });
AddSimple(TEXT("DeltaTime"), EFreq::Any, [](UMaterial& M) { return MakeSimple<UMaterialExpressionDeltaTime>(M); });
AddSimple(TEXT("Time"), EFreq::Any, TEXT("float"), [](UMaterial& M) { return MakeSimple<UMaterialExpressionTime>(M); });
AddSimple(TEXT("DeltaTime"), EFreq::Any, TEXT("float"), [](UMaterial& M) { return MakeSimple<UMaterialExpressionDeltaTime>(M); });
// ViewProperty(Property) — representative of the enum-by-name const-arg mechanism.
{
FShaderLabIntrinsicDesc Desc;
Desc.Name = FName(TEXT("ViewProperty"));
Desc.ReturnType = TEXT("float4");
Desc.Params = { { TEXT("int"), TEXT("Property"), TEXT("") } };
Desc.Doc = TEXT("Property is an EMaterialExposedViewProperty token (e.g. MEVP_FieldOfView).");
Desc.MakeNode = [](UMaterial& M, const TArray<FString>& Args, FString& OutError) -> UMaterialExpression*
{
UMaterialExpressionViewProperty* E = NewObject<UMaterialExpressionViewProperty>(&M);
@@ -183,6 +205,7 @@ void FShaderLabIntrinsicRegistry::RegisterBuiltins()
{
FShaderLabIntrinsicDesc Desc;
Desc.Name = FName(TEXT("ParticleColor"));
Desc.ReturnType = TEXT("float4");
Desc.MakeNode = [](UMaterial& M, const TArray<FString>&, FString&) { return MakeSimple<UMaterialExpressionParticleColor>(M); };
Register(MoveTemp(Desc));
}