Editor/ShaderGraphPlus/Nodes/PostProcessing/WarpNode.cs
namespace ShaderGraphPlus.Nodes;
/// <summary>
/// Takes in the Screen UV's and warps the edges, creating the spherized effect.
/// </summary>
[Title( "Warp" ), Category( "PostProcessing/Effects" ), Icon( "water" )]
public class WarpNode : ShaderNodePlus
{
[Hide]
public static string ScreenWarp => @"
float2 ScreenWarp( float2 vUV , float flWarpAmount )
{
float2 delta = vUV - 0.5f;
float delta2 = dot( delta.xy, delta.xy );
float delta4 = delta2 * delta2;
float deltaOffset = delta4 * flWarpAmount;
return vUV + delta * deltaOffset;
}
";
[Input( typeof( Vector2 ) ), Title( "Coords" )]
[Hide]
public NodeInput ScreenUVInput { get; set; }
[Input( typeof( float ) ), Title( "Warp Amount" )]
[Hide]
public NodeInput WarpAmountInput { get; set; }
[InputDefault( nameof( WarpAmountInput ) )]
[Title( "Warp Amount" )]
public float DefaultWarpAmount { get; set; } = 1.0f;
[Output( typeof( Vector2 ) )]
[Hide]
public NodeResult.Func Result => ( GraphCompiler compiler ) =>
{
if ( compiler.Graph.Domain != ShaderDomain.PostProcess )
{
return NodeResult.Error( $"'{DisplayInfo.Name}' node is only ment to be used in the '{ShaderDomain.PostProcess}' domain." );
}
var coords = compiler.Result( ScreenUVInput );
var warpamount = compiler.ResultOrDefault( WarpAmountInput, DefaultWarpAmount );
string func = compiler.RegisterHLSLFunction( ScreenWarp, "Warp" );
string funcCall = compiler.ResultHLSLFunction( func, $"{(coords.IsValid ? $"{coords.Cast( 2 )}" : "i.vPositionSs.xy / g_vRenderTargetSize")}, {warpamount}" );
return new NodeResult( ResultType.Vector2, funcCall );
};
}