Editor/ShaderGraphPlus/Nodes/Effects/BumpOffsetNode.cs
namespace ShaderGraphPlus.Nodes;
[Title( "Bump Offset" ), Category( "Effects" ), Icon( "water" )]
public sealed class BumpOffsetNode : ShaderNodePlus
{
[JsonIgnore, Hide, Browsable( false )]
public override Color NodeTitleColor => ShaderGraphPlusTheme.NodeHeaderColors.FunctionNode;
[JsonIgnore, Hide, Browsable( false )]
private const float HeightScale = 0.1f;
[Hide]
public static string BumpOffset => $@"
float2 BumpOffset( float flHeightMap, float flDepthScale, float flReferencePlane, float2 vTextureCoords, float3 vTangentViewVector )
{{
float flHeight = flReferencePlane - flHeightMap;
float2 vUVOffset = vTangentViewVector.xy * float2( flHeight, flHeight ) * float2( flDepthScale, flDepthScale ) * float2( {HeightScale}f, {HeightScale}f );
float2 vDistortedUV = vTextureCoords.xy + vUVOffset;
return vDistortedUV;
}}
";
[Input( typeof( float ) )]
[Title( "Height" )]
[Hide]
public NodeInput InputHeight { get; set; }
[Input( typeof( float ) )]
[Title( "Depth Scale" )]
[Hide, NodeValueEditor( nameof( DefaultDepthScale ) )]
public NodeInput InputDepthScale { get; set; }
[Input( typeof( float ) )]
[Title( "Reference Plane" )]
[Hide, NodeValueEditor( nameof( DefaultReferencePlane ) )]
public NodeInput InputReferencePlane { get; set; }
[Input( typeof( Vector2 ) )]
[Title( "Coords" )]
[Hide]
public NodeInput InputCoords { get; set; }
[Title( "Height" )]
public float DefaultHeight { get; set; } = 0.0f;
[Title( "Depth Scale" )]
[Sandbox.Range( 0.0f, 1.0f )]
public float DefaultDepthScale { get; set; } = 0.125f;
[Title( "Reference Plane" )]
[Sandbox.Range( 0.0f, 1.0f )]
public float DefaultReferencePlane { get; set; } = 0.42f;
[Output( typeof( Vector2 ) )]
[Hide]
public NodeResult.Func Result => ( GraphCompiler compiler ) =>
{
var worldPosition = $"i.vPositionWithOffsetWs.xyz + g_vHighPrecisionLightingOffsetWs.xyz";
var tangentViewVector = compiler.ResultHLSLFunction( "GetTangentViewVector", $"{worldPosition}, i.vNormalWs, i.vTangentUWs, i.vTangentVWs" );
var inputHeight = compiler.ResultOrDefault( InputHeight, DefaultHeight );
var inputDepthScale = compiler.ResultOrDefault( InputDepthScale, DefaultDepthScale );
var inputReferencePlane = compiler.ResultOrDefault( InputReferencePlane, DefaultReferencePlane );
var inputCoords = compiler.Result( InputCoords );
string func = compiler.RegisterHLSLFunction( BumpOffset, "BumpOffset" );
string funcCall = compiler.ResultHLSLFunction( func,
$"{inputHeight}, " +
$"{inputDepthScale}, " +
$"{inputReferencePlane}, " +
$"{(inputCoords.IsValid ? $"{inputCoords.Cast( 2 )}" : "i.vTextureCoords.xy")}, " +
$"{tangentViewVector}"
);
return new NodeResult( ResultType.Vector2, funcCall );
};
}