Skip to content

Instantly share code, notes, and snippets.

@JSandusky
Created February 5, 2018 10:01
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save JSandusky/19e2f4b29024b961899802c080fa5d20 to your computer and use it in GitHub Desktop.
Save JSandusky/19e2f4b29024b961899802c080fa5d20 to your computer and use it in GitHub Desktop.
Graph helpers
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace SprueKit.Data.ShaderGen
{
public static class CodeGen
{
public static string GenerateCode(string[] lines)
{
StringBuilder ret = new StringBuilder();
ret.AppendLine("namespace SprueKit.Data.ShaderGen {");
for (int i = 0; i < lines.Length; ++i)
{
if (!string.IsNullOrWhiteSpace(lines[i]))
{
string overrideName = null;
if (lines[i].StartsWith("//"))
continue;
else if (lines[i].StartsWith("#"))
{
overrideName = lines[i].Substring(1);
++i;
}
string funcDef = lines[i];
string headerCode = null;
//WARNING!!! Template based code CANNOT use vmath, scalar, or vector keywords
if (lines[i].Trim().EndsWith("{"))
{
StringBuilder funcCode = new StringBuilder();
do
{
funcCode.Append("compiler.WriteRaw(\"");
funcCode.Append(lines[i]);
funcCode.AppendLine("\\r\\n\");");
++i;
} while (!lines[i].StartsWith("}"));
funcCode.AppendLine("compiler.WriteRaw(\"}\\r\\n\");");
headerCode = funcCode.ToString();
}
FunctionInfo info = new FunctionInfo(funcDef);
ret.AppendFormat(ClassTemplate,
string.Format("{0}", FirstToUpper(info.name)), //class name, {0}
info.GetSocketBuild(), // addinput {1}
info.GetEmitCode(), // emit {2}
info.GetCode(), // getcode {3}
info.name, // assured function name {4}
overrideName != null ? overrideName : FirstToUpper(info.name), // override name {5}
headerCode != null ? headerCode : "", // header code {6}
info.GetExecCode(),
info.GetAltExecCode()); // execute {7}
}
}
ret.AppendLine("}");
return ret.ToString();
}
static string FirstToUpper(string ret)
{
return ret.First().ToString().ToUpper() + ret.Substring(1);
}
class FunctionInfo
{
public string name;
public string outputType;
public string[] param;
public bool isFirstMatchStyle;
static readonly char[] splitKeys = new char[] { ' ', '(', ',', ')', ';' };
public FunctionInfo(string line)
{
string[] terms = line.Split(splitKeys, StringSplitOptions.RemoveEmptyEntries);
outputType = terms[0];
name = terms[1];
param = new string[terms.Length - 2];
for (int i = 0; i < param.Length; ++i)
param[i] = terms[i + 2];
isFirstMatchStyle = param[0].Equals("scalar") || param[0].Equals("vector") || param[0].Equals("matrix") || param[0].Equals("vmath");
}
public string GetExecCode()
{
if (isFirstMatchStyle)
return "OutputSockets[0].StoreSocketInfo(val.Key, GetSocketName(OutputSockets[0], CompilerStage.PixelShader));";
return "OutputSockets[0].StoreSocketInfo(OutputSockets[0].TypeID, GetSocketName(OutputSockets[0], CompilerStage.PixelShader));";
}
public string GetAltExecCode()
{
if (isFirstMatchStyle)
return "OutputSockets[0].StoreSocketInfo(OutputSockets[0].TypeID, GetCode());";
return "OutputSockets[0].StoreSocketInfo(val.Key, GetCode());";
}
public string GetEmitCode()
{
StringBuilder sb = new StringBuilder();
if (isFirstMatchStyle)
sb.Append("compiler.WriteFormat(\"{0} {1} = ({2});\", Tables.inst().IDMapping[firstVal.Key], GetSocketName(OutputSockets[0], CompilerStage.PixelShader), GetCode());");
else
sb.Append("compiler.WriteFormat(\"{0} {1} = ({2});\", Tables.inst().IDMapping[OutputSockets[0].TypeID], GetSocketName(OutputSockets[0], CompilerStage.PixelShader), GetCode());");
return sb.ToString();
}
public string GetCode()
{
StringBuilder sb = new StringBuilder();
// grab all of our socket info
for (int i = 0; i < param.Length/2; ++i)
sb.AppendLine(string.Format("var val{0} = InputSockets[{0}].GetSocketInfo();", i));
sb.Append("return string.Format(\"");
sb.Append("{0}(");
for (int i = 0; i < param.Length / 2; ++i)
{
if (i > 0)
sb.Append(", ");
sb.Append("{" + (i+1).ToString() + "}");
}
sb.Append(")\", funcName_, ");
for (int i = 0; i < param.Length/2; ++i)
{
if (i > 0)
sb.Append(", ");
sb.AppendFormat("val{0}.Value", i);
}
sb.Append(");");
return sb.ToString();
}
public string GetSocketBuild()
{
bool hasTables= Tables.inst().InverseIDMapping.ContainsKey("test");
StringBuilder sb = new StringBuilder();
for (int i = 0; i < param.Length; i += 2)
sb.AppendLine(string.Format("AddInput(\"{1}\", {0});", Tables.inst().ToCodeMapping[param[0]], param[1]));
sb.AppendLine(string.Format("AddOutput(\"Out\", {0});", Tables.inst().ToCodeMapping[outputType]));
return sb.ToString();
}
}
static readonly string ClassTemplate =
@"public partial class {0}Node : FunctionNode {{
string funcName_;
public {0}Node() {{ funcName_ = ""{4}""; }}
public override void Construct() {{
base.Construct();
Name = ""{5}"";
{1}
}}
public override void Execute(object param) {{
for (int i = 0; i < InputSockets.Count; ++i)
if (!InputSockets[i].HasConnections()) {{ IsValid = false; return; }}
var val = InputSockets[0].GetSocketInfo();
if (EmitsCode())
{7}
else
{8}
}}
public override void EmitCode(ShaderCompiler compiler) {{
for (int i = 0; i < InputSockets.Count; ++i)
if (!InputSockets[i].HasConnections()) return;
var firstVal = InputSockets[0].GetSocketInfo();
{2}
}}
string GetCode() {{
{3}
}}
public override void EmitHeaderBlock(ShaderCompiler compiler)
{{
{6}
}}
}}";
}
}
// vmath = float, vector, matrix
// matrix = float3x3 or float4x4
// scalar = float, vector
// vector = float2, float3, float4
// any = int, float, float2, float3, float4, matrix, bool, object
//======================================================
// basic math
//======================================================
vmath radians(vmath value);
vmath degrees(vmath value);
//======================================================
// Trig
//======================================================
@Cosine
vmath cos(vmath value);
@ArcCosine
vmath acos(vmath value);
@Sine
vmath sin(vmath value);
@ArcSine
vmath asin(vmath value);
@Tang
vmath tan(vmath value);
@ArcTan
vmath atan(vmath value);
@ArcTan2
vmath atan2(vmath y, vmath x);
@Hyperbolic Cosine
vmath cosh(vmath value);
@Hypberbolic Sine
vmath sinh(vmath value);
@Hypberbolic Tan
vmath tanh(vmath value);
vmath pow(vmath x, fmath y);
vmath exp(vmath x);
vmath exp2(vmath x);
vmath log(vmath x);
vmath log2(vmath x);
vmath sqrt(vmath x);
vmath rsqrt(vmath x);
vmath abs(vmath x);
vmath sign(vmath x);
vmath floor(vmath x);
vmath ceil(vmath x);
vmath frac(vmath x);
vmath fmod(vmath x, vmath y);
vmath round(vmath x);
vmath min(vmath x, vmath y);
vmath max(vmath x, vmath y);
vmath clamp(vmath val, vmath min, vmath max);
vmath lerp(vmath a, vmath b, float t);
vmath step(vmath a, vmath b);
vmath smoothstep(vmath edgeA, vmath edgeB, vmath x);
@Truncate
vector trunc(vector v);
float length(vmath x);
float distance(vmath p0, vmath p1);
vector dst(vector a, vector b);
float dot(scalar x, scalar y);
float3 cross(float3 x, float3 y);
vector normalize(vector v);
float determinant(matrix m);
matrix transpose(matrix m);
@Face Forward
scalar faceforward(scalar N, scalar, I, scalar nRef);
scalar reflect(scalar I, scalar N);
scalar refract(scalar I, scalar N, float eta);
//void clip(scalar below);
float ddx(scalar coord);
float ddy(scalar coord);
@Is Infinite
bool isinfinite(scalar value);
@Is Not a Number
bool isnan(scalar value);
scalar saturate(scalar value);
float3 GetSpecularIBL(float3 val, float3 oVal) {
return val * oVal + distance(val, oVal);
}
//float4 tex1D(sampler1D, float);
//float4 tex2D(sampler2D, float2);
//float4 tex3D(sampler3D, float3);
//float4 texCUBE(samplerCUBE, float3);
//float4 tex1Dbias(sampler1D, float4);
//float4 tex2Dbias(sampler2D, float4);
//float4 tex3Dbias(sampler3D, float4);
//float4 texCUBEbias(samplerCUBE, float4);
//float4 tex1Dgrad(sampler1D, float, float ddx, float ddy);
//float4 tex2Dgrad(sampler2D, float2, float ddx, float ddy);
//float4 tex3Dgrad(sampler3D, float3, float ddx, float ddy);
//float4 texCUBEgrad(samplerCUBE, float2, float ddx, float ddy);
//float4 tex1Dlod(sampler1D, float4);
//float4 tex2Dlod(sampler2D, float4);
//float4 tex3Dlod(sampler3D, float4);
//float4 texCUBElod(samplerCUBE, float4);
//float4 tex1Dproj(sampler1D, float4);
//float4 tex2Dproj(sampler2D, float4);
//float4 tex3Dproj(sampler3D, float4);
//float4 texCUBEproj(samplerCUBE, float4);
<graph name="Material" candebug="false">
<!--
<in /> = designates an input socket
<out /> = designates an output socket
<metadata></metadata> = can be attached to sockets or nodes themselves
List of Metadata: [NAME], [valid targets] = [purpose/effect]
Variadics (XXX, XXX_glsl, XXX_dx9, XXX_dx11, XXX_hlsl)
uniform, node = contents will be written during the uniform generation stage
inline, node|socket = code is not emitted contents of the inline are placed as written (constants, etc)
emit, node = body of code to be emitted
Definitions
ifdef, socket = socket will only be traversed if the contents of the <ifdef></ifdef> are found in the generators
#defines list
ifnotdef, socket = opposite of the above, socket will only be traversed if the given #define is not found
attachdef, socket = only valid on final OUTPUT or INPUT nodes
if the socket has any connections then the given #define will be added to the list
semantic_dx11, socket = DX11 vertex data semantic to use when emitting the vertex data structures
semantic_dx9, socket = DX9 vertex data semantic to use when emitting the vertex data structures
vsout_always, socket = contents will be written with VS_OUTPUT data
vsout_semantic_dx11, socket = ???
vsout_semantic_dx9, socket = ???
Special
include, node = the contents will be written during the #include generation step
use .hlsl for shader includes, when generating GLSL all instances of "hlsl" will be replaced "glsl"
error_notdef, node = contents are #define that will be checked for
if this define is not in the list #defines for shader generation than it is an error
for graph traversal to hit this node
-->
<category name="Textures" desc="Built in texture slots">
<node name="Diffuse">
<out type="Texture" />
</node>
<node name="Normal Map">
<out type="Texture" />
</node>
<node name="Specular">
<out type="Texture" />
</node>
<node name="Environment Map">
<out type="Texture" />
</node>
<node name="Custom #1">
<out type="Texture" />
</node>
<node name="Custom #2">
<out type="Texture" />
</node>
<node name="Zone Map">
<out type="Texture" />
</node>
</category>
<category name="Texture Sampling" desc="Reading textures" type="pure" color="cornflowerblue">
<node name="Texture 2D">
<in type="String" noconnect="true" />
<out type="Texture" />
<metadata>
<uniform_glsl>sampler2D {0};</uniform_glsl>
<uniform_hlsl>Texture2D t{0}; SamplerState s{0};</uniform_hlsl>
<inline>s{0}</inline>
</metadata>
</node>
<node name="Texture 3D">
<in type="String" noconnect="true" />
<out type="Texture" />
<metadata>
<uniform_glsl>sampler3D {0};</uniform_glsl>
<uniform_hlsl>Texture3D t{0};\r\nSamplerState s{0};</uniform_hlsl>
<inline>s{0}</inline>
</metadata>
</node>
<node name="Texture Cube">
<in type="String" noconnect="true" />
<out type="Texture" />
<metadata>
<uniform_glsl>samplerCube {0};</uniform_glsl>
<uniform_hlsl>TextureCube t{0};\r\nSamplerState s{0};</uniform_hlsl>
<inline>s{0}</inline>
</metadata>
</node>
<node name="Zone Environment">
<out type="Texture"/>
<metadata>
<inline>sZoneCubeMap</inline>
</metadata>
</node>
<node name="Shadow Map">
<out type="Texture"/>
<metadata>
<inline>sShadowMap</inline>
</metadata>
</node>
<node name="Sample 2D" type="blueprint" tip="Regular texture sampling">
<in type="Texture" />
<in name="UV" type="Vector" editable="false"/>
<out type="Vector" />
<metadata>
<emit>Sample2D({0},{1})</emit>
</metadata>
</node>
<node name="Sample 2D Normal" type="blueprint" tip="Samples a tangent space normal map">
<in type="Texture" />
<in type="Vector" editable="false"/>
<in name="RG Packed" type="Bool" />
<out type="Vector" />
</node>
<node name="Sample Cube" type="blueprint" tip="Samples an environment cube">
<in type="Texture" />
<in type="Vector" editable="false"/>
<out type="Vector" />
</node>
<node name="Sample Point Shadow" type="blueprint" tip="Samples a shadow-cube">
<in type="Texture" />
<in name="Pos" type="Vector" editable="false"/>
<out type="Bool" />
</node>
<node name="Sample Spot Shadow" type="blueprint" tip="Performs CSSM sampling">
<in type="Texture" />
<in name="Pos" type="Vector" editable="false"/>
<out type="Bool" />
</node>
<node name="Sample Directional Shadow" type="blueprint" tip="Samples the spot shadow texture">
<in type="Texture" />
<in name="Pos" type="Vector" editable="false"/>
<out type="Bool" />
</node>
<node name="Triplanar" type="blueprint" tip="Gets a triplanar mapping for the given input coordinates">
<in type="Texture" />
<in name="Pos" type="Vector" editable="false"/>
<in name="Nor" type="Vector" editable="false"/>
<in name="Scale" type="Vector" />
<out type="Vector" />
<metadata>
<include>#include "GRAPH_SamplerSupport.hlsl"</include>
<emit>TriplanarSample({0}, {1}, {2}, {3})</emit>
</metadata>
</node>
<node name="RGBA Splat">
<in name="Splat" type="Texture" />
<in name="Default" type="Texture" />
<in name="R" type="Texture" />
<in name="G" type="Texture" />
<in name="B" type="Texture" />
<in name="A" type="Texture" />
<in name="Scale" type="Vector" />
<out type="Vector" />
</node>
<node name="Dot-Prod Detailmap">
<in name="Splat" type="Texture" />
<in name="Details" type="Texture" />
<in name="Scale" type="Vector" />
<out type="Vector" />
<metadata>
<include>#include "GRAPH_SamplerSupport.hlsl"</include>
<emit>DotProdDetail({0}, {1}, {2})</emit>
</metadata>
</node>
<node name="Color Correct">
<in type="Texture" />
<in type="Vector" />
<out type="Vector" />
</node>
<node name="Gradient Map">
<in type="Texture" />
<in name="T" type="Float" />
<out type="Vector" />
</node>
<node name="Texel Fetch" tip="Sample a 2d texture with exact integer coordinates">
<in type="Texture" />
<in name="Coord" type="Vector" />
<out type="Vector" />
<metadata>
<emit>SampleExplicit({0}, {1}.xy)</emit>
</metadata>
</node>
</category>
<category name="Constants" desc="Uniform and non-varying values" color="dodgerblue" type="pure">
<node name="PI">
<out type="Float">
<metadata><inline>PI</inline></metadata>
</out>
<metadata>
<include>#define PI 3.141596</include>
</metadata>
</node>
<node name="Phi">
<out type="Float"><metadata><inline>PHI</inline></metadata></out>
<metadata>
<include>#define PHI 1.618</include>
</metadata>
</node>
<node name="Tau">
<out type="Float"><metadata><inline>TAU</inline></metadata></out>
<metadata>
<include>#define TAU 6.283192</include>
</metadata>
</node>
<node name="Root2">
<out type="Float"><metadata><inline>ROOT2</inline></metadata></out>
<metadata>
<include>#define ROOT2 1.41421</include>
</metadata>
</node>
<node name="Euler's">
<out type="Float"><metadata><inline>EULER</inline></metadata></out>
<metadata>
<include>#define EULER 2.71828182845</include>
</metadata>
</node>
<node name="Uniform Float" tip="A value that can be edited in the material">
<in type="String" noconnect="true" />
<out type="Float" />
<metadata>
<uniform>uniform float {0};</uniform>
<emit>{0}</emit>
</metadata>
</node>
<node name="Uniform Vector" tip="A value that can be edited in the material">
<in type="String" noconnect="true" />
<out type="Vector" />
<metadata>
<uniform_glsl>uniform vec4 {0};</uniform_glsl>
<uniform_hlsl>uniform float4 {0};</uniform_hlsl>
<emit>{0}</emit>
</metadata>
</node>
<node name="Constant Float" tip="An explicit constant value">
<out type="Float" editable="true" />
</node>
<node name="Constant Vector" tip="An explicit constant value">
<out type="Vector" editable="true" />
</node>
<node name="Time">
<out type="Float"><metadata><inline>cTime</inline></metadata></out>
</node>
</category>
<category name="Basic Math" desc="" color="" type="pure">
<node name="ADD">
<in type="AnyKey" />
<in type="AnySource" />
<out type="AnySource" />
<metadata>
<emit>({0} + {1})</emit>
</metadata>
</node>
<node name="SUBTRACT">
<in type="AnyKey" />
<in type="AnySource" />
<out type="AnySource" />
<metadata>
<emit>({0} - {1})</emit>
</metadata>
</node>
<node name="MULTIPLY">
<in type="AnyKey" />
<in type="AnySource" />
<out type="AnySource" />
<metadata>
<emit>({0} * {1})</emit>
</metadata>
</node>
<node name="DIVIDE">
<in type="AnyKey" />
<in type="AnySource" />
<out type="AnySource" />
<metadata>
<emit>({0} / {1})</emit>
</metadata>
</node>
<node name="Negate" tip="Unary minus">
<in type="AnyKey" />
<out type="AnySource" />
<metadata>
<emit>(-{0})</emit>
</metadata>
</node>
</category>
<category name="Trigonometry" color="cyan" type="pure" desc="SohCahToa and friends">
<node name="Sine">
<in type="AnyKey" />
<out type="AnySource" />
<metadata><emit>sin({0})</emit></metadata>
</node>
<node name="Cos">
<in type="AnyKey" />
<out type="AnySource" />
<metadata><emit>cos({0})</emit></metadata>
</node>
<node name="Tan">
<in type="AnyKey" />
<out type="AnySource" />
<metadata><emit>tan({0})</emit></metadata>
</node>
<node name="Asine">
<in type="AnyKey" />
<out type="AnySource" />
<metadata><emit>asin({0})</emit></metadata>
</node>
<node name="Acos">
<in type="AnyKey" />
<out type="AnySource" />
<metadata><emit>acos({0})</emit></metadata>
</node>
<node name="Atan">
<in type="AnyKey" />
<out type="AnySource" />
<metadata><emit>atan({0})</emit></metadata>
</node>
<node name="Atan2">
<in type="AnyKey" />
<in type="Float" />
<out type="AnySource" />
<metadata><emit>atan2({0}, {1})</emit></metadata>
</node>
</category>
<category name="Extended Math" color="violet" type="pure" desc="More math routines">
<node name="Sqrt" tip="Square root">
<in type="AnyKey" />
<out type="AnySource" />
<metadata><emit>sqrt({0})</emit></metadata>
</node>
<node name="Recip Sqrt" tip="Reciprocal square root">
<in type="AnyKey" />
<out type="AnySource" />
<metadata><emit>rsqrt({0})</emit></metadata>
</node>
<node name="Pow" tip="Raise the input to a power">
<in type="AnyKey" />
<in type="Float" />
<out type="AnySource" />
<metadata><emit>pow({0}, {1})</emit></metadata>
</node>
<node name="Log">
<in type="AnyKey" />
<out type="AnySource" />
<metadata><emit>log({0})</emit></metadata>
</node>
<node name="Log2">
<in type="AnyKey" />
<out type="AnySource" />
<metadata><emit>log2({0})</emit></metadata>
</node>
<node name="Exp">
<in type="AnyKey" />
<out type="AnySource" />
<metadata><emit>exp({0})</emit></metadata>
</node>
<node name="Exp2">
<in type="AnyKey" />
<out type="AnySource" />
<metadata><emit>exp2({0})</emit></metadata>
</node>
<node name="Abs">
<in type="AnyKey" />
<out type="AnySource" />
<metadata><emit>abs({0})</emit></metadata>
</node>
<node name="Sign">
<in type="AnyKey" />
<out type="AnySource" />
<metadata><emit>sign({0})</emit></metadata>
</node>
<node name="Floor">
<in type="AnyKey" />
<out type="AnySource" />
<metadata><emit>floor({0})</emit></metadata>
</node>
<node name="Ceil">
<in type="AnyKey" />
<out type="AnySource" />
<metadata><emit>ceil({0})</emit></metadata>
</node>
<node name="Frac">
<in type="AnyKey" />
<out type="AnySource" />
<metadata><emit>frac({0})</emit></metadata>
</node>
<node name="FMod">
<in type="AnyKey" />
<out type="AnySource" />
<metadata><emit>fmod({0}, {1})</emit></metadata>
</node>
</category>
<category name="Ranges" color="magenta" type="pure" desc="Multivalued functions">
<node name="Round" tip="Round floating points to the nearest integer value">
<in type="AnyKey" />
<out type="AnySource" />
<metadata><emit>round({0})</emit></metadata>
</node>
<node name="Min" tip="Take the minimum of two values">
<in type="AnyKey" />
<int type="AnySource" />
<out type="AnySource" />
<metadata><emit>min({0}, {1})</emit></metadata>
</node>
<node name="Max" tip="Take the maximum of two values">
<in type="AnyKey" />
<in type="AnySource" />
<out type="AnySource" />
<metadata><emit>max({0}, {1})</emit></metadata>
</node>
<node name="Clamp" tip="Bound a value between a lower and upper bound">
<in type="AnyKey" />
<in name="Min" type="AnySource" />
<in name="Max" type="AnySource" />
<out type="AnySource" />
<metadata><emit>clamp({0}, {1}, {2})</emit></metadata>
</node>
<node name="Lerp" tip="Interpolate or extrapolate between two values">
<in type="AnyKey" />
<in type="AnySource" />
<in type="Float" />
<out type="AnySource" />
<metadata><emit>lerp({0}, {1}, {2})</emit></metadata>
</node>
<node name="Step" tip="Returns 1.0 if B &gt; A, otherwise 0.0">
<in name="A" type="AnyKey" />
<in name="B" type="AnySource" />
<out type="AnySource" />
<metadata><emit>step({0}, {1})</emit></metadata>
</node>
<node name="Smoothstep" tip="Interpolates between two values using a sigmoid curved. Clamped as well.">
<in name="A" type="AnyKey" />
<in name="B" type="AnySource" />
<in name="T" type="AnySource" />
<out type="AnySource" />
<metadata><emit>smoothstep({0}, {1}, {2})</emit></metadata>
</node>
<node name="Deg to Rad" tip="Convert degrees to radians">
<in type="AnyKey" />
<out type="AnySource" />
<metadata><emit>radians({0})</emit></metadata>
</node>
<node name="Rad To Deg" tip="Convert radians to degrees">
<in type="AnyKey" />
<out type="AnySource" />
<metadata><emit>degrees({0})</emit></metadata>
</node>
</category>
<category name="Vectors" color="yellow" type="pure" desc="Dots, crosses, and mirrors">
<node name="Dot" tip="Outputs the dot-product of two vectors">
<in type="Vector" />
<in type="Vector" />
<out type="Float" />
<metadata>
<emit>dot({0}, {1})</emit>
</metadata>
</node>
<node name="Normalize" tip="Normalizes the input vector">
<in type="Vector" />
<out type="Vector" />
<metadata>
<emit>normalize({0})</emit>
</metadata>
</node>
<node name="Length" tip="Outputs the length of the vector">
<in type="Vector" />
<out type="Float" />
<metadata>
<emit>length({0})</emit>
</metadata>
</node>
<node name="Distance" tip="Distance between two points">
<in type="Vector" />
<in type="Vector" />
<out type="Float" />
<metadata>
<emit>distance({0}, {1})</emit>
</metadata>
</node>
<node name="Cross" tip="Output the vector to the right of the plane formed">
<in type="Vector" />
<in type="Vector" />
<out type="Vector" />
<metadata>
<emit>cross({0}, {1})</emit>
</metadata>
</node>
<node name="Reflect" tip="Reflects the source about the relative vector">
<in name="Src" type="Vector" />
<in name="Rel To" type="Vector" />
<out type="Vector" />
<metadata>
<emit>reflect({0}, {1})</emit>
</metadata>
</node>
<node name="Face Forward" tip="Outputs the forward facing vector based on the 3 frame vectors">
<in name="Nor" type="Vector" />
<in name="Incident" type="Vector" />
<in name="Ref" type="Vector" />
<out type="Vector" />
<metadata>
<emit>faceforward({0}, {1}, {2})</emit>
</metadata>
</node>
<node name="Compose Vector" tip="Constructs a vector out of individual floats">
<in name="X" type="Float" />
<in name="Y" type="Float" />
<in name="Z" type="Float" />
<in name="W" type="Float" />
<out type="Vector">
<metadata>
<emit_hlsl>float4({0}, {1}, {2}, {3})</emit_hlsl>
<emit_glsl>vec4({0}, {1}, {2}, {3})</emit_glsl>
</metadata>
</out>
</node>
<node name="Decompose Vector" tip="Breaks apart a vector into specific components">
<in type="Vector" />
<out name="X" type="Float"><metadata><emit>{0}.x</emit></metadata></out>
<out name="Y" type="Float"><metadata><emit>{0}.y</emit></metadata></out>
<out name="Z" type="Float"><metadata><emit>{0}.z</emit></metadata></out>
<out name="W" type="Float"><metadata><emit>{0}.w</emit></metadata></out>
</node>
</category>
<category name="Matrices" desc="Transforms" color="gold" type="pure">
<node name="Constant Matrix" tip="Constructs a matrix from explicit values">
<out type="Matrix" editable="true" />
</node>
<node name="Compose Matrix" tip="Composes a matrix out of multiple vectors">
<in name="Row 1" type="Vector" editable="false"/>
<in name="Row 2" type="Vector" editable="false"/>
<in name="Row 3" type="Vector" editable="false"/>
<in name="Row 4" type="Vector" editable="false"/>
<out type="Matrix" />
<metadata>
<emit_hlsl>float4x4({0}, {1}, {2}, {3})</emit_hlsl>
<emit_glsl>mat4({0}, {1}, {2}, {3})</emit_glsl>
</metadata>
</node>
<node name="Transform" tip="Performs matrix multiplication to transform a vector">
<in type="Matrix" />
<in type="Vector" />
<out type="Vector" />
<metadata>
<emit_hlsl>mul({1}, {0})</emit_hlsl>
<emit_glsl>({1} * {0})</emit_glsl>
</metadata>
</node>
<node name="Rotate" tip="Rotation transform for normals">
<in type="Matrix" />
<in type="Vector" />
<out type="Vector" />
<metadata>
<emit_hlsl>float4(mul({1}.xyz, float3x3({0})))</emit_hlsl>
<emit_glsl>vec4(mat3({0}) * {1}.xyz)</emit_glsl>
</metadata>
</node>
<node name="Transpose" tip="Flips columns into rows">
<in type="Matrix" />
<out type="Matrix" />
<metadata><emit>transpose({0})</emit></metadata>
</node>
<node name="Get Skin Matrix" tip="Gets the skeletal animation skinning matrix">
<in name="Weights" type="Vector"/>
<in name="Indices" type="Vector"/>
<out type="Matrix" />
<metadata>
<error_notdef>SKINNED</error_notdef>
<inline>GetSkinMatrix({0}, {1})</inline>
</metadata>
</node>
<node name="Get Translation" tip="Extracts the translation component from a matrix">
<in type="Matrix" />
<out type="Vector" />
<metadata>
<emit_glsl>vec4({0}[0][3], {0}[1][3], {0}[2][3], 0.0)</emit_glsl>
<emit_hlsl>float4({0}[0][3], {0}[1][3], {0}[2][3], 0.0)</emit_hlsl>
</metadata>
</node>
</category>
<category name="Effects" desc="" color="coral" type="pure">
<node name="Normal w/o Tangents" tip="Uses a tangent space normal map without having tangents">
<in name="Vertex Nor" type="Vector" />
<in name="Tan Nor" type="Vector" />
<in name="View Dir" type="Vector" />
<out type="Vector" />
</node>
<node name="Perlin Noise" tip="Outputs 3d perlin noise">
<in type="Vector3" />
<out type="float" />
</node>
<node name="FBM" tip="Generates Fractal brownian noise">
<in type="Vector3" />
<in name="Octaves" type="Float" />
<out type="float" />
</node>
<node name="Roughness To MipLevel" tip="Determines a mip level to use based on roughness">
<in name="Roughness" type="Float"/>
<in name="Levels" type="Float"/>
<out name="" type="Float"/>
</node>
<node name="Noise" tip="Outputs pseudorandom noise">
<in name="Coord" type="Float" />
<out type="Float"><metadata><emit>NoiseFloat({0})</emit></metadata></out>
<out type="Vector"><metadata><emit>NoiseVector({0})</emit></metadata></out>
</node>
</category>
<category name="Lighting" desc="BRDFs and falloffs" color="limegreen" type="pure">
<node name="Half Vector" tip="Calculates the half vector of the light and view">
<in name="Light Dir" type="Vector" />
<in name="View Dir" type="Vector" />
<out type="Vector" />
<metadata>
<include>#include "GRAPH_LightingSupport.hlsl"</include>
<emit>normalize({0} + {1})</emit>
</metadata>
</node>
<node name="Schlick Fresnel" tip="Outputs the Fresnel function, useful for rim lighting">
<in name="Color" type="Vector"/>
<in name="vDotH" type="Float"/>
<out type="Vector"/>
<metadata>
<include>#include "GRAPH_LightingSupport.hlsl"</include>
<emit>SchlickFresnel({0}, {1})</emit>
</metadata>
</node>
<node name="Lambertian Diffuse" tip="Old fashioned Lambertian diffuse">
<in name="Vector" />
<in name="Vector" />
<out name="Vector" />
<metadata>
<include>#include "GRAPH_LightingSupport.hlsl"</include>
<emit>dot({0}, {1})</emit>
</metadata>
</node>
<node name="Burley Diffuse" tip="Lambertian diffuse">
<in name="Color" type="Vector" />
<in name="Roughness" type="float" />
<in name="nDotV" type="float" />
<in name="nDotL" type="float" />
<in name="vDotH" type="float" />
<out name="Vector" />
<metadata>
<include>#include "GRAPH_LightingSupport.hlsl"</include>
<emit>BurleyDiffuse({0}, {1}, {2}, {3}, {4})</emit>
</metadata>
</node>
<node name="Oren-Nayer" tip="Evaluates the Oren-Nayer shading model">
<in name="Nor" type="Vector" />
<in name="Light" type="Vector" />
<in name="View" type="Vector" />
<out type="Vector" />
<metadata>
<include>#include "GRAPH_LightingSupport.hlsl"</include>
<emit>OrenNayer({0}, {1}, {2})</emit>
</metadata>
</node>
<node name="PBR - Schlick/GGX/Smith" tip="A complete PBR light evaluation">
<in type="Vector" />
<in type="Vector" />
<in type="Vector" />
<out type="Vector" />
<metadata>
<include>#include "GRAPH_LightingSupport.hlsl"</include>
<emit>PBR_Schlick_GGS_Smith({0}, {1}, {2})</emit>
</metadata>
</node>
<node name="Image Based Lighting" tip="Uses cubemap mip-levels for environmental light">
<in name="Nor" type="Vector" />
<in name="View" type="Vector" />
<in name="Specular" type="Vector" />
<in name="Roughness" type="Float" />
<out type="Vector" />
<metadata>
<include>#include "GRAPH_LightingSupport.hlsl"</include>
<emit>ImageBasedLighting({0}, {1}, {2}, {3})</emit>
</metadata>
</node>
<node name="Gradient" tip="Interpolates an axial gradient">
<in name="A" type="Vector"/>
<in name="B" type="Vector"/>
<in name="Orient" type="Vector"/>
<in name="Lower" type="Float"/>
<in name="Upper" type="Float"/>
<out type="Vector" />
<metadata>
<include>#include "GRAPH_MiscSupport.hlsl"</include>
<emit>SpaceGradient({0}, {1}, {2}, {3}, {4})</emit>
</metadata>
</node>
</category>
<category name="Platform Targets" desc="Low/High spec" color="orange" type="blueprint">
<node name="Quality Switch" tip="Use cheaper BRDFs and approximations">
<in name="Low" type="AnyKey">
<metadata>
<ifdef>spec_low</ifdef>
</metadata>
</in>
<in name="Medium" type="AnySource">
<metadata>
<ifdef>spec_medium</ifdef>
</metadata>
</in>
<in name="High" type="AnySource">
<metadata>
<ifdef>spec_high</ifdef>
</metadata>
</in>
<out name="" type="AnySource" />
<metadata><passthrough /></metadata>
</node>
<node name="Mobile / PC" tip="Forks based on mobile vs PC configuration">
<in name="Mobile" type="AnyKey">
<metadata>
<ifdef>gles</ifdef>
</metadata>
</in>
<in name="PC" type="AnySource">
<metadata>
<ifdef>desktop</ifdef>
</metadata>
</in>
<out name="" type="AnySource" />
<metadata><passthrough /></metadata>
</node>
<node name="Is Shadow Pass?" tip="Forks if we're rendering a shadow map">
<in name="Yes" type="AnyKey">
<metadata><ifdef>SHADOW</ifdef></metadata>
</in>
<in name="No" type="AnySource">
<metadata><ifnotdef>SHADOW</ifnotdef></metadata>
</in>
<out type="AnySource" />
<metadata><passthrough /></metadata>
</node>
<node name="Is Ambient Pass?" tip="Forks if the current pass is the ambient pass">
<in name="Yes" type="AnyKey">
<metadata><ifdef>AMBIENT</ifdef></metadata>
</in>
<in name="No" type="AnySource">
<metadata><ifnotdef>AMBIENT</ifnotdef></metadata>
</in>
<out type="AnySource" />
<metadata><passthrough /></metadata>
</node>
<node name="Has Lightmap?" tip="Forks if a lightmap is attached to the material">
<in name="Yes" type="AnyKey">
<metadata><ifdef>LIGHTMAP</ifdef></metadata>
</in>
<in name="No" type="AnySource">
<metadata><ifnotdef>LIGHTMAP</ifnotdef></metadata>
</in>
<out type="AnySource" />
<metadata><passthrough /></metadata>
</node>
<node name="Has Environment Map?" tip="Forks if an environment map is attached to the material">
<in name="Yes" type="AnyKey">
<metadata><ifdef>ENVCUBEMAP</ifdef></metadata>
</in>
<in name="No" type="AnySource">
<metadata><ifnotdef>ENVCUBEMAP</ifnotdef></metadata>
</in>
<out type="AnySource" />
<metadata><passthrough /></metadata>
</node>
<node name="IS GL3?" tip="Forks based on whether OpenGL is GL3.3 or not">
<in name="Yes" type="AnyKey">
<metadata><ifdef>GL3</ifdef></metadata>
</in>
<in name="No" type="AnySource">
<metadata><ifnotdef>GL3</ifnotdef></metadata>
</in>
<out type="AnySource" />
<metadata><passthrough /></metadata>
</node>
<node name="Is GLES?" tip="Forks based on whether OpenGL is GLES2.0 or not">
<in name="Yes" type="AnyKey">
<metadata><ifdef>GL_ES</ifdef></metadata>
</in>
<in name="No" type="AnySource">
<metadata><ifnotdef>GL_ES</ifnotdef></metadata>
</in>
<out type="AnySource" />
<metadata><passthrough /></metadata>
</node>
</category>
<category name="Inputs" desc="" color="red" type="pure">
<node name="Trivial Inputs" type="blueprint" tip="Input data for trivial drawables, like lines and shapes">
<out name="World Pos" type="Vector" />
<out name="World Nor" type="Vector" />
<out name="UV Coord" type="Vector" />
<out name="Vertex Color" type="Vector" />
<seperator />
<out name="Model Pos" type="Vector" />
<out name="Model Nor" type="Vector" />
</node>
<node name="Static Inputs" type="blueprint" tip="Input data for non-animated meshes">
<out name="World Pos" type="Vector" />
<out name="World Nor" type="Vector" />
<out name="World Tan" type="Vector" />
<out name="World Bitan" type="Vector" />
<out name="UV Coord" type="Vector" />
<seperator />
<out name="Model Pos" type="Vector" />
<out name="Model Nor" type="Vector" />
<out name="Model Tan" type="Vector" />
<out name="Model Bitan" type="Vector" />
</node>
<node name="Animated Inputs" type="blueprint" tip="Input data for animated drawables">
<out name="World Pos" type="Vector"></out>
<out name="World Nor" type="Vector" />
<out name="World Tan" type="Vector" />
<out name="World Bitan" type="Vector" />
<out name="UV Coord" type="Vector" />
<out name="Vertex Color" type="Vector" />
<out name="Bone Weights" type="Vector" />
<out name="Bone Indices" type="Vector" />
<seperator />
<out name="Model Pos" type="Vector" />
<out name="Model Nor" type="Vector" />
<out name="Model Tan" type="Vector" />
<out name="Model Bitan" type="Vector" />
</node>
<node name="Model Matrix" tip="Matrix of the current drawable">
<out type="Matrix">
<metadata>
<inline>cModelMatrix</inline>
</metadata>
</out>
</node>
<node name="View Matrix" tip="Camera mode/view matrix">
<out type="Matrix">
<metadata>
<inline>cViewMatrix</inline>
</metadata>
</out>
</node>
<node name="Tangent Basis" tip="Composed tangent basis matrix">
<out type="Matrix">
<metadata>
<inline>tangentBasis</inline>
</metadata>
</out>
<metadata>
<attachdef>TANGENT_BASIS</attachdef>
</metadata>
</node>
<node name="Camera Position" tip="3d position of the camera">
<out type="Vector">
<metadata>
<inline>cViewPos</inline>
</metadata>
</out>
</node>
<node name="View Direction" tip="Direction the camera is looking towards">
<out type="Vector">
<inline>cViewDir</inline>
</out>
</node>
</category>
<category name="Outputs" desc="" color="red" type="pure">
<node name="Physically Based" root="true" type="blueprint" guid="daace728-59a0-4f4a-b041-abc67f7b881e" tip="Standard physically based shading outputs, not all values need to be used">
<in name="Albedo" type="Vector">
<metadata>
<ifdef>COMPILE_PS</ifdef>
</metadata>
</in>
<in name="Normal" type="Vector">
<metadata>
<ifdef>COMPILE_PS</ifdef>
</metadata>
</in>
<in name="Roughness" type="Float">
<metadata>
<ifdef>COMPILE_PS</ifdef>
</metadata>
</in>
<in name="Metalness" type="Float">
<metadata>
<ifdef>COMPILE_PS</ifdef>
</metadata>
</in>
<in name="Specular" type="Vector" default="0.5 0.5 0.5 0.5">
<metadata>
<ifdef>COMPILE_PS</ifdef>
</metadata>
</in>
<in name="Fresnel" type="Float" default="0.04">
<metadata>
<ifdef>COMPILE_PS</ifdef>
</metadata>
</in>
<in name="Transparency" type="Float" default="1.0">
<metadata>
<ifdef>COMPILE_PS</ifdef>
<attachdef>ALPHA</attachdef>
</metadata>
</in>
<seperator />
<in name="Emissive" type="Vector" default="0.0 0.0 0.0 0.0">
<metadata>
<ifdef>COMPILE_PS</ifdef>
<attachdef>EMISSIVE</attachdef>
</metadata>
</in>
<in name="Ambient Occlusion" type="Float" default="0.0">
<metadata>
<ifdef>COMPILE_PS</ifdef>
<attachdef>AMBIENT_OCCLUSION</attachdef>
</metadata>
</in>
<seperator />
<in name="Subsurface Depth" type="Float" default="0.0">
<metadata>
<ifdef>COMPILE_PS</ifdef>
<attachdef>SUBSURFACE</attachdef>
</metadata>
</in>
<in name="Subsurface Color" type="Vector" default="1.0 1.0 1.0 1.0">
<metadata>
<ifdef>COMPILE_PS</ifdef>
<attachdef>SUBSURFACE</attachdef>
</metadata>
</in>
<seperator />
<in name="Vertex Position" type="Vector">
<metadata>
<ifdef>COMPILE_VS</ifdef>
<semantic_dx11>SV_POSITION</semantic_dx11>
</metadata>
</in>>
<in name="Vertex Normal" type="Vector">
<metadata>
<ifdef>COMPILE_VS</ifdef>
<semantic_dx11>TEXCOORD0</semantic_dx11>
</metadata>
</in>
<seperator />
<in name="Displacement" type="Float" />
</node>
<node name="Legacy" root="true" type="blueprint" guid="387949fe-f749-43f4-9d54-1b98650e5010" tip="Legacy shader for non-PBR rendering, use as a base for other non-PBR purposes">
<in name="Color" type="Vector">
<metadata>
<ifdef>COMPILE_PS</ifdef>
<semantic_dx11>COLOR</semantic_dx11>
</metadata>
</in>
<in name="Specular Color" type="Vector">
<metadata>
<ifdef>COMPILE_PS</ifdef>
<semantic_dx11>TEXCOORD1</semantic_dx11>
</metadata>
</in>
<in name="Normal" type="Vector">
<metadata>
<ifdef>COMPILE_PS</ifdef>
<semantic_dx11>NORMAL</semantic_dx11>
</metadata>
</in>
<seperator />
<in name="Vertex Position" type="Vector">
<metadata>
<ifdef>COMPILE_VS</ifdef>
<vsout_always />
<vsout_semantic_dx11>SV_POSITION</vsout_semantic_dx11>
<vsout_semantic_dx9>POSITION</vsout_semantic_dx9>
<semantic_dx11>SV_Position</semantic_dx11>
</metadata>
</in>
<in name="Vertex Normal" type="Vector">
<metadata>
<ifdef>COMPILE_VS</ifdef>
<vsout_always />
<vsout_semantic_dx11>NORMAL</vsout_semantic_dx11>
<semantic_dx11>NORMAL</semantic_dx11>
</metadata>
</in>
</node>
</category>
<category name="Utility" desc="" color="aquamarine" type="pure">
<node name="DDX" tip="Space derivative for manual mip-mapping">
<in type="Float" />
<out type="Float" />
<metadata>
<emit_hlsl>ddx({0})</emit_hlsl>
<emit_glsl>dFdx({0})</emit_glsl>
</metadata>
</node>
<node name="DDY" tip="Space derivative for manual mip-mapping">
<in type="Float" />
<out type="Float" />
<metadata>
<emit_hlsl>ddy({0})</emit_hlsl>
<emit_glsl>dFdy({0})</emit_glsl>
</metadata>
</node>
<node name="Is Infinite" tip="Outputs 1 if the input is infinite or -infinite">
<in type="AnyKey" />
<out type="Float" />
<metadata>
<emit_hlsl>isinfinite({0})</emit_hlsl>
<emit_glsl>isinf({0})</emit_glsl>
</metadata>
</node>
<node name="Is NaN" tip="Outputs 1 if the input is not-a-number">
<in type="AnyKey" />
<out type="Float" />
<metadata>
<emit_hlsl>isnan({0})</emit_hlsl>
<emit_glsl>isnan({0})</emit_glsl>
</metadata>
</node>
<node name="Saturate" tip="Clips to the 0-1 bounds">
<in type="AnyKey" />
<out type="AnyKey" />
<metadata>
<emit_hlsl>saturate({0})</emit_hlsl>
<emit_glsl>clamp({0}, 0.0, 1.0)</emit_glsl>
</metadata>
</node>
<node name="From Gamma" tip="Convert from Gamma to Linear for calculations">
<in type="AnyKey" />
<out type="AnySource" />
<metadata>
<emit>pow({0}, 2.2)</emit>
</metadata>
</node>
<node name="To Gamma" tip="Convert to Gamma space for display">
<in type="AnyKey" />
<out type="AnySource" />
<metadata>
<emit>pow({0}, 1.0 / 2.2)</emit>
</metadata>
</node>
</category>
</graph
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment