10 July 2018

Bend the world with Unity's Shader Graph

Hurray! Unity 2018.2 is out and that means: vertex positions are now accessible in graph shaders!

This means that the world bend shader from this previous post can now be implemented as a node! The cool part is: I only added one .cs file containing a custom node and it works with the existing code.

Add the "World Bend" node into the graph, and define 3 properties "Horizon", "Spread" and "Attenuation" (check my previous post to see what they are for). Connect the output as input for the position of your Master Node. Do not expose the three properties, but give them these reference values respectively: "_HORIZON", "_SPREAD", "_ATTENUATE". That way they receive the global values set by the World Bender script on the camera. And that's it! There is only one extra file:

using System.Reflection;
using UnityEditor.ShaderGraph;
using UnityEngine;

[Title("Custom", "World Bend")]
public class BendNode : CodeFunctionNode
{
 public BendNode()
 {
  name = "World Bend";
 }

 protected override MethodInfo GetFunctionToConvert()
 {
  return GetType().GetMethod("Bend",
   BindingFlags.Static | BindingFlags.NonPublic);
 }

 static string Bend(
  [Slot(0, Binding.ObjectSpacePosition)] Vector3 v,
  [Slot(1, Binding.None)] Vector1 Horizon,
  [Slot(2, Binding.None)] Vector1 Spread,
  [Slot(3, Binding.None)] Vector1 Attenuate,
  [Slot(4, Binding.None)] out Vector3 Out)
 {
  Out = Vector3.zero;
  return @"
{
 Out = mul (unity_ObjectToWorld, v);
 float dist = max(0.0, abs(Horizon.x - Out.z) - Spread);
 Out.y -= dist * dist * Attenuate;
 Out = mul(unity_WorldToObject, Out);
}";
 }
}

As always, you can find a small demo on my unity toolset repo. I'm open for feedback!

3 comments:

Rick said...

Great post! Thank you for sharing this with the world.

Nix said...

Great post, thanks! Only one problem, BendNode.cs does not seem to work in latest unity versions, 2019+, throws lots of errors =\ It would be great to know how to fix them ^^

Alex Vanden Abeele said...

See this Unity Forums thread: https://forum.unity.com/threads/unable-to-create-custom-shader-graph-node-due-to-inaccessibility-of-customfunctionnode-class.586876/

Apparently custom nodes have been disabled in 2019 and no replacement has been made yet. I'll follow this up and post an update as soon as Unity has a fix.