mirror of
https://github.com/Eragon-Brisingr/UShaderLab.git
synced 2026-09-15 14:54:36 +00:00
64 lines
3.2 KiB
C++
64 lines
3.2 KiB
C++
// Copyright FlecsProj. All Rights Reserved.
|
|
|
|
#pragma once
|
|
|
|
#include "CoreMinimal.h"
|
|
#include "MaterialValueType.h"
|
|
#include "Materials/MaterialExpressionCustomOutput.h"
|
|
#include "MaterialExpressionShaderLabParameterAnchor.generated.h"
|
|
|
|
/**
|
|
* Internal ShaderLab node with two jobs, both keeping workaround machinery off the user's body nodes:
|
|
*
|
|
* 1. Anchors parameters so the Material Instance editor lists them. StaticBool parameters are consumed
|
|
* only inside HLSL `#if`, so they would otherwise be unconnected; the instance editor's visibility
|
|
* walk only reaches parameters connected to a material output or a CustomOutput. This is a
|
|
* CustomOutput, so it is always traversed; each anchored parameter reaches one of its inputs (via
|
|
* its static-switch selector).
|
|
*
|
|
* 2. Injects per-permutation static-switch `#define`s with ZERO engine modifications. Each input is a
|
|
* StaticSwitch over two `#define <Switch> 1` / `#define <Switch> 0` Custom nodes. This node returns
|
|
* ShouldCompileBeforeAttributes()==true, so FHLSLMaterialTranslator compiles it BEFORE the material
|
|
* attributes (FrontMaterial / body). Its Compile() compiles each input, so the selected `#define`
|
|
* (only the taken StaticSwitch branch is compiled) is emitted ahead of every body's `#if`. The
|
|
* `#define` leaks forward (preprocessor is global) and the body's `#if <Switch>` sees the current
|
|
* permutation's value — including a Material Instance's static override.
|
|
*
|
|
* It only ever lives in the editor graph (never serialized into a cooked package).
|
|
*/
|
|
UCLASS(MinimalAPI, collapsecategories, hidecategories = Object)
|
|
class UMaterialExpressionShaderLabParameterAnchor : public UMaterialExpressionCustomOutput
|
|
{
|
|
GENERATED_UCLASS_BODY()
|
|
|
|
/** One input per static-switch selector (a StaticSwitch over two `#define`-emitting Custom nodes). */
|
|
UPROPERTY()
|
|
TArray<FExpressionInput> Inputs;
|
|
|
|
//~ Begin UMaterialExpressionCustomOutput Interface
|
|
// One output so the translator actually compiles us (a zero-output CustomOutput is skipped). The
|
|
// output value is unused; compiling us is purely to emit our inputs' `#define`s before attributes.
|
|
virtual int32 GetNumOutputs() const override { return 1; }
|
|
virtual FString GetFunctionName() const override { return TEXT("ShaderLabParameterAnchor"); }
|
|
#if WITH_EDITOR
|
|
virtual bool NeedsCustomOutputDefines() override { return false; } // don't emit NUM_MATERIAL_OUTPUTS_*
|
|
virtual bool ShouldCompileBeforeAttributes() override { return true; } // emit #defines ahead of body #if
|
|
#endif
|
|
//~ End UMaterialExpressionCustomOutput Interface
|
|
|
|
#if WITH_EDITOR
|
|
//~ Begin UMaterialExpression Interface
|
|
virtual TArrayView<FExpressionInput*> GetInputsView() override;
|
|
virtual FExpressionInput* GetInput(int32 InputIndex) override;
|
|
virtual FName GetInputName(int32 InputIndex) const override;
|
|
virtual EMaterialValueType GetInputValueType(int32 InputIndex) override { return MCT_Float1; }
|
|
virtual int32 Compile(class FMaterialCompiler* Compiler, int32 OutputIndex) override;
|
|
virtual void GetCaption(TArray<FString>& OutCaptions) const override;
|
|
//~ End UMaterialExpression Interface
|
|
#endif
|
|
|
|
private:
|
|
/** Scratch pointer view rebuilt by GetInputsView(). */
|
|
TArray<FExpressionInput*> CachedInputs;
|
|
};
|