浏览代码

first real working shader in the 'new' model.

/main
Tim Cooper 7 年前
当前提交
be067cc2
共有 26 个文件被更改,包括 719 次插入467 次删除
  1. 2
      MaterialGraphProject/Assets/NewNodes/Keep/LightProbeNode.cs
  2. 10
      MaterialGraphProject/Assets/NewNodes/Keep/ParallaxNode.cs
  3. 4
      MaterialGraphProject/Assets/NewNodes/Keep/ReflectionProbeNode.cs
  4. 6
      MaterialGraphProject/Assets/NewNodes/Keep/TangentToWorldNode.cs
  5. 12
      MaterialGraphProject/Assets/NewNodes/Keep/TransformNode.cs
  6. 6
      MaterialGraphProject/Assets/NewNodes/Kill/MultiLayerParallaxNode.cs
  7. 6
      MaterialGraphProject/Assets/NewNodes/Kill/POMNode.cs
  8. 2
      MaterialGraphProject/Assets/NewNodes/Kill/SphericalIndentationNode.cs
  9. 4
      MaterialGraphProject/Assets/UnityShaderEditor/Runtime/Graphs/AbstractMaterialGraph.cs
  10. 213
      MaterialGraphProject/Assets/UnityShaderEditor/Runtime/Graphs/MaterialGraph.cs
  11. 2
      MaterialGraphProject/Assets/UnityShaderEditor/Runtime/Interfaces/IMayRequireNormal.cs
  12. 156
      MaterialGraphProject/Assets/UnityShaderEditor/Runtime/Nodes/HLSLNode.cs
  13. 8
      MaterialGraphProject/Assets/UnityShaderEditor/Runtime/Nodes/Input/Geometry/WorldSpaceBitangentNode.cs
  14. 14
      MaterialGraphProject/Assets/UnityShaderEditor/Runtime/Nodes/Input/Geometry/WorldSpacePositionNode.cs
  15. 14
      MaterialGraphProject/Assets/UnityShaderEditor/Runtime/Nodes/Input/Geometry/WorldSpaceTangentNode.cs
  16. 175
      MaterialGraphProject/Assets/UnityShaderEditor/Runtime/Nodes/MasterNode.cs
  17. 60
      MaterialGraphProject/Assets/UnityShaderEditor/Runtime/SubGraph/SubGraphNode.cs
  18. 289
      MaterialGraphProject/Assets/UnityShaderEditor/Runtime/Util/ShaderGenerator.cs
  19. 14
      MaterialGraphProject/Assets/UnityShaderEditor/Runtime/Interfaces/NeededCoordinateSpace.cs
  20. 3
      MaterialGraphProject/Assets/UnityShaderEditor/Runtime/Interfaces/NeededCoordinateSpace.cs.meta
  21. 43
      MaterialGraphProject/Assets/UnityShaderEditor/Runtime/Nodes/Input/Geometry/NormalNode.cs
  22. 50
      MaterialGraphProject/Assets/UnityShaderEditor/Runtime/Nodes/Input/Geometry/ViewDirectionNode.cs
  23. 50
      MaterialGraphProject/Assets/UnityShaderEditor/Runtime/Nodes/Input/Geometry/WorldSpaceViewDirectionNode.cs
  24. 43
      MaterialGraphProject/Assets/UnityShaderEditor/Runtime/Nodes/Input/Geometry/WorldSpaceNormalNode.cs
  25. 0
      /MaterialGraphProject/Assets/UnityShaderEditor/Runtime/Nodes/Input/Geometry/NormalNode.cs.meta
  26. 0
      /MaterialGraphProject/Assets/UnityShaderEditor/Runtime/Nodes/Input/Geometry/ViewDirectionNode.cs.meta

2
MaterialGraphProject/Assets/NewNodes/Keep/LightProbeNode.cs


}
static string Unity_LightProbe(
[Slot(0, Binding.Normal)] Vector3 worldSpaceNormal,
[Slot(0, Binding.WorldSpaceNormal)] Vector3 worldSpaceNormal,
[Slot(1, Binding.None)] out Vector4 color)
{
color = Vector4.one;

10
MaterialGraphProject/Assets/NewNodes/Keep/ParallaxNode.cs


namespace UnityEngine.MaterialGraph
{
interface IMayRequireViewDirectionTangentSpace
{
bool RequiresViewDirectionTangentSpace();
}
public class ParallaxNode : AbstractMaterialNode, IGeneratesBodyCode, IGeneratesFunction, IMayRequireMeshUV, IMayRequireViewDirectionTangentSpace
public class ParallaxNode : AbstractMaterialNode, IGeneratesBodyCode, IGeneratesFunction, IMayRequireMeshUV, IMayRequireViewDirection
{
protected const string kInputSlot1ShaderName = "Depth";
protected const string kOutputSlotShaderName = "UV";

return channel == UVChannel.uv0;
}
public bool RequiresViewDirectionTangentSpace()
public NeededCoordinateSpace RequiresViewDirection()
return true;
return NeededCoordinateSpace.Tangent;
}
}
}

4
MaterialGraphProject/Assets/NewNodes/Keep/ReflectionProbeNode.cs


}
static string Unity_ReflectionProbe(
[Slot(0, Binding.ViewDirection)] Vector3 viewDirection,
[Slot(1, Binding.Normal)] Vector3 worldSpaceNormal,
[Slot(0, Binding.ObjectSpaceNormal)] Vector3 viewDirection,
[Slot(1, Binding.ObjectSpaceViewDirection)] Vector3 worldSpaceNormal,
[Slot(2, Binding.None)] Vector1 lod,
[Slot(3, Binding.None)] out Vector4 color)
{

6
MaterialGraphProject/Assets/NewNodes/Keep/TangentToWorldNode.cs


static string Unity_TangentToWorld(
[Slot(0, Binding.None)] Vector3 inVector,
[Slot(1, Binding.None)] out Vector3 result,
[Slot(2, Binding.Tangent)] Vector3 tangent,
[Slot(3, Binding.Bitangent)] Vector3 biTangent,
[Slot(4, Binding.Normal)] Vector3 normal)
[Slot(2, Binding.WorldSpaceTangent)] Vector3 tangent,
[Slot(3, Binding.WorldSpaceBitangent)] Vector3 biTangent,
[Slot(4, Binding.WorldSpaceNormal)] Vector3 normal)
{
result = Vector3.zero;
return

12
MaterialGraphProject/Assets/NewNodes/Keep/TransformNode.cs


get { return ConvertConcreteSlotValueTypeToString(FindInputSlot<MaterialSlot>(InputSlotId).concreteValueType); }
}
public bool RequiresTangent()
public NeededCoordinateSpace RequiresTangent()
return true;
return NeededCoordinateSpace.World;
public bool RequiresBitangent()
public NeededCoordinateSpace RequiresBitangent()
return true;
return NeededCoordinateSpace.World;
public bool RequiresNormal()
public NeededCoordinateSpace RequiresNormal()
return true;
return NeededCoordinateSpace.World;
}
}
}

6
MaterialGraphProject/Assets/NewNodes/Kill/MultiLayerParallaxNode.cs


namespace UnityEngine.MaterialGraph
{
[Title("UV/MultiLayerParallax")]
public class MultiLayerParallaxNode : AbstractMaterialNode, IGeneratesBodyCode, IGeneratesFunction, IMayRequireMeshUV, IMayRequireViewDirectionTangentSpace
public class MultiLayerParallaxNode : AbstractMaterialNode, IGeneratesBodyCode, IGeneratesFunction, IMayRequireMeshUV, IMayRequireViewDirection
{
protected const string kInputDepthShaderName = "Depth";
protected const string kInputFadeRateShaderName = "FadeRate";

return channel == UVChannel.uv0;
}
public bool RequiresViewDirectionTangentSpace()
public NeededCoordinateSpace RequiresViewDirection()
return true;
return NeededCoordinateSpace.Tangent;
}
}
}

6
MaterialGraphProject/Assets/NewNodes/Kill/POMNode.cs


[Slot(1, Binding.None)] Texture2D tex,
[Slot(2, Binding.None)] Vector1 heightScale,
[Slot(3, Binding.MeshUV0)] Vector2 UVs,
[Slot(4, Binding.ViewDirectionTangentSpace)] Vector3 viewTangentSpace,
[Slot(5, Binding.Normal)] Vector3 worldSpaceNormal,
[Slot(6, Binding.ViewDirection)] Vector3 worldSpaceViewDirection,
[Slot(4, Binding.TangentSpaceViewDirection)] Vector3 viewTangentSpace,
[Slot(5, Binding.WorldSpaceNormal)] Vector3 worldSpaceNormal,
[Slot(6, Binding.WorldSpaceViewDirection)] Vector3 worldSpaceViewDirection,
[Slot(7, Binding.None)] out Vector2 result)
{
result = Vector2.zero;

2
MaterialGraphProject/Assets/NewNodes/Kill/SphericalIndentationNode.cs


[Slot(3, Binding.None, 1f, 1f, 1f, 1f)] Vector1 radius,
[Slot(4, Binding.None)] out Vector3 resultUV,
[Slot(5, Binding.None)] out Vector3 resultNormal,
[Slot(6, Binding.ViewDirectionTangentSpace, true)] Vector3 tangentSpaceViewDirection)
[Slot(6, Binding.TangentSpaceViewDirection, true)] Vector3 tangentSpaceViewDirection)
{
resultUV = Vector3.zero;
resultNormal = Vector3.up;

4
MaterialGraphProject/Assets/UnityShaderEditor/Runtime/Graphs/AbstractMaterialGraph.cs


fullName = "UnityEngine.MaterialGraph.ViewDirectionNode",
assemblyName = "Assembly-CSharp"
};
result[viewNode] = SerializationHelper.GetTypeSerializableAsString(typeof(WorldSpaceViewDirectionNode));
result[viewNode] = SerializationHelper.GetTypeSerializableAsString(typeof(ViewDirectionNode));
var normalNode = new SerializationHelper.TypeSerializationInfo
{

result[normalNode] = SerializationHelper.GetTypeSerializableAsString(typeof(WorldSpaceNormalNode));
result[normalNode] = SerializationHelper.GetTypeSerializableAsString(typeof(NormalNode));
var worldPosNode = new SerializationHelper.TypeSerializationInfo
{

213
MaterialGraphProject/Assets/UnityShaderEditor/Runtime/Graphs/MaterialGraph.cs


get { return GetNodes<MasterNode>().FirstOrDefault(); }
}
public string GetFullShader(GenerationMode mode, string name, out List<PropertyCollector.TextureInfo> configuredTextures)
protected MasterNode.Requirements GetRequierments()
// figure out what kind of preview we want!
bool requiresBitangent = activeNodeList.OfType<IMayRequireBitangent>().Any(x => x.RequiresBitangent());
bool requiresTangent = activeNodeList.OfType<IMayRequireTangent>().Any(x => x.RequiresTangent());
bool requiresViewDirTangentSpace = activeNodeList.OfType<IMayRequireViewDirectionTangentSpace>().Any(x => x.RequiresViewDirectionTangentSpace());
bool requiresViewDir = activeNodeList.OfType<IMayRequireViewDirection>().Any(x => x.RequiresViewDirection());
bool requiresWorldPos = activeNodeList.OfType<IMayRequireWorldPosition>().Any(x => x.RequiresWorldPosition());
bool requiresNormal = activeNodeList.OfType<IMayRequireNormal>().Any(x => x.RequiresNormal());
NeededCoordinateSpace requiresNormal = activeNodeList.OfType<IMayRequireNormal>().Aggregate(NeededCoordinateSpace.None, (mask, node) => mask | node.RequiresNormal());
NeededCoordinateSpace requiresBitangent = activeNodeList.OfType<IMayRequireBitangent>().Aggregate(NeededCoordinateSpace.None, (mask, node) => mask | node.RequiresBitangent());
NeededCoordinateSpace requiresTangent = activeNodeList.OfType<IMayRequireTangent>().Aggregate(NeededCoordinateSpace.None, (mask, node) => mask | node.RequiresTangent());
NeededCoordinateSpace requiresViewDir = activeNodeList.OfType<IMayRequireViewDirection>().Aggregate(NeededCoordinateSpace.None, (mask, node) => mask | node.RequiresViewDirection());
NeededCoordinateSpace requiresPosition = activeNodeList.OfType<IMayRequirePosition>().Aggregate(NeededCoordinateSpace.None, (mask, node) => mask | node.RequiresPosition());
var shaderInterpolators = new ShaderGenerator();
// if anything needs tangentspace we have make
// sure to have our othonormal basis!
var compoundSpaces = requiresBitangent | requiresNormal | requiresPosition
| requiresTangent | requiresViewDir | requiresPosition
| requiresNormal;
var needsTangentSpace = (compoundSpaces & NeededCoordinateSpace.Tangent) > 0;
if (needsTangentSpace)
{
requiresBitangent |= NeededCoordinateSpace.Object;
requiresNormal |= NeededCoordinateSpace.Object;
requiresTangent |= NeededCoordinateSpace.Object;
}
var reqs = new MasterNode.Requirements()
{
requiresNormal = requiresNormal,
requiresBitangent = requiresBitangent,
requiresTangent = requiresTangent,
requiresViewDir = requiresViewDir,
requiresPosition = requiresPosition,
requiresScreenPosition = requiresScreenPosition,
requiresVertexColor = requiresVertexColor
};
ListPool<INode>.Release(activeNodeList);
return reqs;
}
private static void GenerateSpaceTranslation(
NeededCoordinateSpace neededSpaces,
ShaderGenerator surfaceInputs,
string objectSpaceName,
string viewSpaceName,
string worldSpaceName,
string tangentSpaceName)
{
if ((neededSpaces & NeededCoordinateSpace.Object) > 0)
surfaceInputs.AddShaderChunk(string.Format("float3 {0};", objectSpaceName), false);
if ((neededSpaces & NeededCoordinateSpace.World) > 0)
surfaceInputs.AddShaderChunk(string.Format("float3 {0};", worldSpaceName), false);
if ((neededSpaces & NeededCoordinateSpace.View) > 0)
surfaceInputs.AddShaderChunk(string.Format("float3 {0};", viewSpaceName), false);
if ((neededSpaces & NeededCoordinateSpace.Tangent) > 0)
surfaceInputs.AddShaderChunk(string.Format("float3 {0};", tangentSpaceName), false);
}
public string GetFullShader(GenerationMode mode, string name, out List<PropertyCollector.TextureInfo> configuredTextures)
{
var vertexShader = new ShaderGenerator();
var pixelShader = new ShaderGenerator();
var surfaceDescription = new ShaderGenerator();

// always add color because why not.
shaderInterpolators.AddShaderChunk(@"
var graphVertexInput = @"
struct GraphVertexInput
{
float4 vertex : POSITION;

float2 lightmapUV : TEXCOORD1;
UNITY_VERTEX_INPUT_INSTANCE_ID
};", false);
};";
shaderInterpolators.AddShaderChunk("struct GraphVertexOutput{", false);
shaderInterpolators.Indent();
shaderInterpolators.AddShaderChunk("float4 position : POSITION;", false);
surfaceInputs.AddShaderChunk("struct SurfaceInputs{", false);
surfaceInputs.Indent();
var requirements = GetRequierments();
GenerateSpaceTranslation(requirements.requiresNormal, surfaceInputs,
ShaderGeneratorNames.ObjectSpaceNormal, ShaderGeneratorNames.ViewSpaceNormal,
ShaderGeneratorNames.WorldSpaceNormal, ShaderGeneratorNames.TangentSpaceNormal);
vertexShader.AddShaderChunk("GraphVertexInput PopulateVertexData(GraphVertexInput v){", false);
vertexShader.Indent();
vertexShader.AddShaderChunk("return v;", false);
vertexShader.Deindent();
vertexShader.AddShaderChunk("}", false);
GenerateSpaceTranslation(requirements.requiresTangent, surfaceInputs,
ShaderGeneratorNames.ObjectSpaceTangent, ShaderGeneratorNames.ViewSpaceTangent,
ShaderGeneratorNames.WorldSpaceTangent, ShaderGeneratorNames.TangentSpaceTangent);
surfaceInputs.AddShaderChunk("struct SurfaceInputs{", false);
surfaceInputs.Indent();
GenerateSpaceTranslation(requirements.requiresBitangent, surfaceInputs,
ShaderGeneratorNames.ObjectSpaceBiTangent, ShaderGeneratorNames.ViewSpaceBiTangent,
ShaderGeneratorNames.WorldSpaceSpaceBiTangent, ShaderGeneratorNames.TangentSpaceBiTangent);
surfaceDescription.AddShaderChunk(@"struct SurfaceDescription{", false);
surfaceDescription.Indent();
foreach (var input in masterNode.GetInputSlots<MaterialSlot>())
{
surfaceDescription.AddShaderChunk(AbstractMaterialNode.ConvertConcreteSlotValueTypeToString(AbstractMaterialNode.OutputPrecision.@float, input.concreteValueType) + " " + input.shaderOutputName + ";", false);
}
surfaceDescription.Deindent();
surfaceDescription.AddShaderChunk("};", false);
GenerateSpaceTranslation(requirements.requiresViewDir, surfaceInputs,
ShaderGeneratorNames.ObjectSpaceViewDirection, ShaderGeneratorNames.ViewSpaceViewDirection,
ShaderGeneratorNames.WorldSpaceViewDirection, ShaderGeneratorNames.TangentSpaceViewDirection);
pixelShader.AddShaderChunk("SurfaceDescription PopulateSurfaceData(SurfaceInputs IN) {", false);
pixelShader.Indent();
GenerateSpaceTranslation(requirements.requiresPosition, surfaceInputs,
ShaderGeneratorNames.ObjectSpacePosition, ShaderGeneratorNames.ViewSpacePosition,
ShaderGeneratorNames.WorldSpacePosition, ShaderGeneratorNames.TangentSpacePosition);
// view directions calculated from world position
if (requiresWorldPos || requiresViewDir || requiresViewDirTangentSpace)
{
shaderInterpolators.AddShaderChunk(string.Format("float3 {0} : TEXCOORD0;", ShaderGeneratorNames.WorldSpacePosition), false);
surfaceInputs.AddShaderChunk(string.Format("float3 {0}", ShaderGeneratorNames.WorldSpacePosition), false);
if (requirements.requiresVertexColor)
surfaceInputs.AddShaderChunk(string.Format("float4 {0};", ShaderGeneratorNames.VertexColor), false);
//vertexShader.AddShaderChunk("o.worldPos = worldPos;", false);
}
if (requirements.requiresScreenPosition)
surfaceInputs.AddShaderChunk(string.Format("float4 {0};", ShaderGeneratorNames.ScreenPosition), false);
/* if (requiresBitangent || requiresNormal || requiresViewDirTangentSpace)
{
shaderInterpolators.AddShaderChunk("float3 worldNormal : TEXCOORD1;", false);
//vertexShader.AddShaderChunk("o.worldNormal = worldNormal;", false);
//pixelShader.AddShaderChunk("float3 " + ShaderGeneratorNames.WorldSpaceNormal + " = normalize(IN.worldNormal);", false);
}
var activeNodeList = ListPool<INode>.Get();
NodeUtils.DepthFirstCollectNodesFromNode(activeNodeList, masterNode);
{
shaderInterpolators.AddShaderChunk(string.Format("half4 meshUV{0} : TEXCOORD{1};", uvIndex, (uvIndex + 5)), false);
vertexShader.AddShaderChunk(string.Format("o.meshUV{0} = v.texcoord{1};", uvIndex, uvIndex == 0 ? "" : uvIndex.ToString()), false);
pixelShader.AddShaderChunk(string.Format("half4 {0} = IN.meshUV{1};", channel.GetUVName(), uvIndex), false);
}
surfaceInputs.AddShaderChunk(string.Format("half4 meshUV{0};", uvIndex), false);
if (requiresViewDir || requiresViewDirTangentSpace)
{
pixelShader.AddShaderChunk(
"float3 "
+ ShaderGeneratorNames.WorldSpaceViewDirection
+ " = normalize(UnityWorldSpaceViewDir("
+ ShaderGeneratorNames.WorldSpacePosition
+ "));", false);
}
if (requiresScreenPosition)
{
shaderInterpolators.AddShaderChunk("float4 screenPos : TEXCOORD3;", false);
vertexShader.AddShaderChunk("o.screenPos = screenPos;", false);
pixelShader.AddShaderChunk("half4 " + ShaderGeneratorNames.ScreenPosition + " = IN.screenPos;", false);
}
if (requiresBitangent || requiresViewDirTangentSpace || requiresTangent)
{
shaderInterpolators.AddShaderChunk("float4 worldTangent : TEXCOORD4;", false);
vertexShader.AddShaderChunk("o.worldTangent = float4(UnityObjectToWorldDir(v.tangent.xyz), v.tangent.w);", false);
pixelShader.AddShaderChunk("float3 " + ShaderGeneratorNames.WorldSpaceTangent + " = normalize(IN.worldTangent.xyz);", false);
}
surfaceInputs.Deindent();
surfaceInputs.AddShaderChunk("};", false);
if (requiresBitangent || requiresViewDirTangentSpace)
{
pixelShader.AddShaderChunk(string.Format("float3 {0} = cross({1}, {2}) * IN.worldTangent.w;", ShaderGeneratorNames.WorldSpaceBitangent, ShaderGeneratorNames.WorldSpaceNormal, ShaderGeneratorNames.WorldSpaceTangent), false);
}
vertexShader.AddShaderChunk("GraphVertexInput PopulateVertexData(GraphVertexInput v){", false);
vertexShader.Indent();
vertexShader.AddShaderChunk("return v;", false);
vertexShader.Deindent();
vertexShader.AddShaderChunk("}", false);
if (requiresViewDirTangentSpace)
surfaceDescription.AddShaderChunk("struct SurfaceDescription{", false);
surfaceDescription.Indent();
foreach (var input in masterNode.GetInputSlots<MaterialSlot>())
pixelShader.AddShaderChunk(
"float3 " + ShaderGeneratorNames.TangentSpaceViewDirection + ";", false);
pixelShader.AddShaderChunk(
ShaderGeneratorNames.TangentSpaceViewDirection + ".x = dot(" +
ShaderGeneratorNames.WorldSpaceViewDirection + "," +
ShaderGeneratorNames.WorldSpaceTangent + ");", false);
pixelShader.AddShaderChunk(
ShaderGeneratorNames.TangentSpaceViewDirection + ".y = dot(" +
ShaderGeneratorNames.WorldSpaceViewDirection + "," +
ShaderGeneratorNames.WorldSpaceBitangent + ");", false);
pixelShader.AddShaderChunk(
ShaderGeneratorNames.TangentSpaceViewDirection + ".z = dot(" +
ShaderGeneratorNames.WorldSpaceViewDirection + "," +
ShaderGeneratorNames.WorldSpaceNormal + ");", false);
surfaceDescription.AddShaderChunk(AbstractMaterialNode.ConvertConcreteSlotValueTypeToString(AbstractMaterialNode.OutputPrecision.@float, input.concreteValueType) + " " + input.shaderOutputName + ";", false);
if (requiresVertexColor)
{
vertexShader.AddShaderChunk("o.color = v.color;", false);
pixelShader.AddShaderChunk("float4 " + ShaderGeneratorNames.VertexColor + " = IN.color;", false);
}*/
surfaceDescription.Deindent();
surfaceDescription.AddShaderChunk("};", false);
shaderInterpolators.Deindent();
shaderInterpolators.AddShaderChunk("};", false);
pixelShader.AddShaderChunk("SurfaceDescription PopulateSurfaceData(SurfaceInputs IN) {", false);
pixelShader.Indent();
var generationMode = GenerationMode.ForReals;
var shaderProperties = new PropertyCollector();

pixelShader.AddShaderChunk("}", false);
ListPool<INode>.Release(activeNodeList);
surfaceInputs.Deindent();
surfaceInputs.AddShaderChunk("};", false);
var finalShader = new ShaderGenerator();
finalShader.AddShaderChunk(string.Format(@"Shader ""{0}""", name), false);
finalShader.AddShaderChunk("{", false);

finalShader.AddShaderChunk("CGINCLUDE", false);
finalShader.AddShaderChunk("#include \"UnityCG.cginc\"", false);
finalShader.AddShaderChunk(shaderFunctionVisitor.GetShaderString(2), false);
finalShader.AddShaderChunk(shaderProperties.GetPropertiesDeclaration(2), false);
finalShader.AddShaderChunk(shaderInterpolators.GetShaderString(2), false);
finalShader.AddShaderChunk(graphVertexInput, false);
finalShader.AddShaderChunk(shaderProperties.GetPropertiesDeclaration(2), false);
finalShader.AddShaderChunk(masterNode.GetSubShader(requiresNormal), false);
finalShader.AddShaderChunk(masterNode.GetSubShader(GetRequierments()), false);
finalShader.Deindent();
finalShader.AddShaderChunk("}", false);

2
MaterialGraphProject/Assets/UnityShaderEditor/Runtime/Interfaces/IMayRequireNormal.cs


{
public interface IMayRequireNormal
{
bool RequiresNormal();
NeededCoordinateSpace RequiresNormal();
}
}

156
MaterialGraphProject/Assets/UnityShaderEditor/Runtime/Nodes/HLSLNode.cs


, IMayRequireMeshUV
, IMayRequireScreenPosition
, IMayRequireViewDirection
, IMayRequireWorldPosition
, IMayRequirePosition
, IMayRequireViewDirectionTangentSpace
{
[NonSerialized]
private List<SlotAttribute> m_Slots = new List<SlotAttribute>();

protected enum Binding
{
None,
Normal,
Tangent,
Bitangent,
ObjectSpaceNormal,
ObjectSpaceTangent,
ObjectSpaceBitangent,
ObjectSpacePosition,
ViewSpaceNormal,
ViewSpaceTangent,
ViewSpaceBitangent,
ViewSpacePosition,
WorldSpaceNormal,
WorldSpaceTangent,
WorldSpaceBitangent,
WorldSpacePosition,
TangentSpaceNormal,
TangentSpaceTangent,
TangentSpaceBitangent,
TangentSpacePosition,
ViewDirection,
WorldPosition,
ObjectSpaceViewDirection,
ViewSpaceViewDirection,
WorldSpaceViewDirection,
TangentSpaceViewDirection,
ViewDirectionTangentSpace
}
private static string BindChannelToShaderName(Binding channel)

case Binding.None:
return "ERROR!";
case Binding.Normal:
case Binding.ObjectSpaceNormal:
return ShaderGeneratorNames.ObjectSpaceNormal;
case Binding.ObjectSpaceTangent:
return ShaderGeneratorNames.ObjectSpaceTangent;
case Binding.ObjectSpaceBitangent:
return ShaderGeneratorNames.ObjectSpaceBiTangent;
case Binding.ObjectSpacePosition:
return ShaderGeneratorNames.ObjectSpacePosition;
case Binding.ViewSpaceNormal:
return ShaderGeneratorNames.ViewSpaceNormal;
case Binding.ViewSpaceTangent:
return ShaderGeneratorNames.ViewSpaceTangent;
case Binding.ViewSpaceBitangent:
return ShaderGeneratorNames.ViewSpaceBiTangent;
case Binding.ViewSpacePosition:
return ShaderGeneratorNames.ViewSpacePosition;
case Binding.WorldSpaceNormal:
case Binding.Tangent:
case Binding.WorldSpaceTangent:
case Binding.Bitangent:
return ShaderGeneratorNames.WorldSpaceBitangent;
case Binding.WorldSpaceBitangent:
return ShaderGeneratorNames.WorldSpaceSpaceBiTangent;
case Binding.WorldSpacePosition:
return ShaderGeneratorNames.WorldSpacePosition;
case Binding.TangentSpaceNormal:
return ShaderGeneratorNames.TangentSpaceNormal;
case Binding.TangentSpaceTangent:
return ShaderGeneratorNames.TangentSpaceTangent;
case Binding.TangentSpaceBitangent:
return ShaderGeneratorNames.TangentSpaceBiTangent;
case Binding.TangentSpacePosition:
return ShaderGeneratorNames.TangentSpacePosition;
return ShaderGeneratorNames.GetUVName(UVChannel.uv0);
return UVChannel.uv0.GetUVName();
return ShaderGeneratorNames.GetUVName(UVChannel.uv1);
return UVChannel.uv1.GetUVName();
return ShaderGeneratorNames.GetUVName(UVChannel.uv2);
return UVChannel.uv2.GetUVName();
return ShaderGeneratorNames.GetUVName(UVChannel.uv3);
return UVChannel.uv3.GetUVName();
case Binding.ViewDirection:
case Binding.ObjectSpaceViewDirection:
return ShaderGeneratorNames.ObjectSpaceViewDirection;
case Binding.ViewSpaceViewDirection:
return ShaderGeneratorNames.ViewSpaceViewDirection;
case Binding.WorldSpaceViewDirection:
case Binding.WorldPosition:
return ShaderGeneratorNames.WorldSpacePosition;
case Binding.TangentSpaceViewDirection:
return ShaderGeneratorNames.TangentSpaceViewDirection;
case Binding.ViewDirectionTangentSpace:
return ShaderGeneratorNames.TangentSpaceViewDirection;
default:
throw new ArgumentOutOfRangeException("channel", channel, null);
}

return attrs.FirstOrDefault();
}
public bool RequiresNormal()
public NeededCoordinateSpace RequiresNormal()
return NodeRequiresBinding(Binding.Normal);
var binding = NeededCoordinateSpace.None;
if (NodeRequiresBinding(Binding.ObjectSpaceNormal))
binding |= NeededCoordinateSpace.Object;
if (NodeRequiresBinding(Binding.ViewSpaceNormal))
binding |= NeededCoordinateSpace.View;
if (NodeRequiresBinding(Binding.WorldSpaceNormal))
binding |= NeededCoordinateSpace.World;
if (NodeRequiresBinding(Binding.TangentSpaceNormal))
binding |= NeededCoordinateSpace.Tangent;
return binding;
}
public bool RequiresMeshUV(UVChannel channel)

return NodeRequiresBinding(Binding.ScreenPosition);
}
public bool RequiresViewDirection()
public NeededCoordinateSpace RequiresViewDirection()
return NodeRequiresBinding(Binding.ViewDirection);
var binding = NeededCoordinateSpace.None;
if (NodeRequiresBinding(Binding.ObjectSpaceViewDirection))
binding |= NeededCoordinateSpace.Object;
if (NodeRequiresBinding(Binding.ViewSpaceViewDirection))
binding |= NeededCoordinateSpace.View;
if (NodeRequiresBinding(Binding.WorldSpaceViewDirection))
binding |= NeededCoordinateSpace.World;
if (NodeRequiresBinding(Binding.TangentSpaceNormal))
binding |= NeededCoordinateSpace.Tangent;
return binding;
public bool RequiresViewDirectionTangentSpace()
public NeededCoordinateSpace RequiresPosition()
return NodeRequiresBinding(Binding.ViewDirectionTangentSpace);
}
var binding = NeededCoordinateSpace.None;
if (NodeRequiresBinding(Binding.ObjectSpacePosition))
binding |= NeededCoordinateSpace.Object;
if (NodeRequiresBinding(Binding.ViewSpacePosition))
binding |= NeededCoordinateSpace.View;
if (NodeRequiresBinding(Binding.WorldSpacePosition))
binding |= NeededCoordinateSpace.World;
if (NodeRequiresBinding(Binding.TangentSpacePosition))
binding |= NeededCoordinateSpace.Tangent;
public bool RequiresWorldPosition()
{
return NodeRequiresBinding(Binding.WorldPosition);
return binding;
public bool RequiresTangent()
public NeededCoordinateSpace RequiresTangent()
return NodeRequiresBinding(Binding.Tangent);
var binding = NeededCoordinateSpace.None;
if (NodeRequiresBinding(Binding.ObjectSpaceTangent))
binding |= NeededCoordinateSpace.Object;
if (NodeRequiresBinding(Binding.ViewSpaceTangent))
binding |= NeededCoordinateSpace.View;
if (NodeRequiresBinding(Binding.WorldSpaceTangent))
binding |= NeededCoordinateSpace.World;
if (NodeRequiresBinding(Binding.TangentSpaceTangent))
binding |= NeededCoordinateSpace.Tangent;
return binding;
public bool RequiresBitangent()
public NeededCoordinateSpace RequiresBitangent()
return NodeRequiresBinding(Binding.Bitangent);
var binding = NeededCoordinateSpace.None;
if (NodeRequiresBinding(Binding.ObjectSpaceBitangent))
binding |= NeededCoordinateSpace.Object;
if (NodeRequiresBinding(Binding.ViewSpaceBitangent))
binding |= NeededCoordinateSpace.View;
if (NodeRequiresBinding(Binding.WorldSpaceBitangent))
binding |= NeededCoordinateSpace.World;
if (NodeRequiresBinding(Binding.TangentSpaceBitangent))
binding |= NeededCoordinateSpace.Tangent;
return binding;
}
public bool RequiresVertexColor()

8
MaterialGraphProject/Assets/UnityShaderEditor/Runtime/Nodes/Input/Geometry/WorldSpaceBitangentNode.cs


{
public interface IMayRequireBitangent
{
bool RequiresBitangent();
NeededCoordinateSpace RequiresBitangent();
[Title("Input/Geometry/World Bitangent")]
/* [Title("Input/Geometry/World Bitangent")]
public class WorldSpaceBitangentNode : AbstractMaterialNode, IMayRequireBitangent
{
public const int kOutputSlotId = 0;

public override string GetVariableNameForSlot(int slotId)
{
return ShaderGeneratorNames.WorldSpaceBitangent;
return ShaderGeneratorNames.BiTangent;
}
public bool RequiresBitangent()

}
}*/
}

14
MaterialGraphProject/Assets/UnityShaderEditor/Runtime/Nodes/Input/Geometry/WorldSpacePositionNode.cs


namespace UnityEngine.MaterialGraph
{
interface IMayRequireWorldPosition
interface IMayRequirePosition
bool RequiresWorldPosition();
NeededCoordinateSpace RequiresPosition();
public class WorldSpacePositionNode : AbstractMaterialNode, IMayRequireWorldPosition
public class WorldSpacePositionNode : AbstractMaterialNode, IMayRequirePosition
{
private const int kOutputSlotId = 0;

public WorldSpacePositionNode()
{
name = "WorldSpacePosition";
name = "Position";
UpdateNodeAfterDeserialization();
}

public override string GetVariableNameForSlot(int slotId)
{
return ShaderGeneratorNames.WorldSpacePosition;
return "IN." + ShaderGeneratorNames.WorldSpacePosition;
public bool RequiresWorldPosition()
public NeededCoordinateSpace RequiresPosition()
return true;
return NeededCoordinateSpace.World;
}
}
}

14
MaterialGraphProject/Assets/UnityShaderEditor/Runtime/Nodes/Input/Geometry/WorldSpaceTangentNode.cs


{
public interface IMayRequireTangent
{
bool RequiresTangent();
NeededCoordinateSpace RequiresTangent();
public class WorldSpaceTangentNode : AbstractMaterialNode, IMayRequireTangent
public class TangentNode : AbstractMaterialNode, IMayRequireTangent
public WorldSpaceTangentNode()
public TangentNode()
name = "WorldTangent";
name = "Tangent";
UpdateNodeAfterDeserialization();
}

public override string GetVariableNameForSlot(int slotId)
{
return ShaderGeneratorNames.WorldSpaceTangent;
return ShaderGeneratorNames.ObjectSpaceTangent;
public bool RequiresTangent()
public NeededCoordinateSpace RequiresTangent()
return true;
return NeededCoordinateSpace.Object;
}
}
}

175
MaterialGraphProject/Assets/UnityShaderEditor/Runtime/Nodes/MasterNode.cs


using System;
using System.Collections.Generic;
using System.Linq;
using UnityEngine.Graphing;
namespace UnityEngine.MaterialGraph

CGPROGRAM
#pragma vertex vert
#pragma fragment frag
// make fog work
#pragma multi_compile_fog
struct GraphVertexOutput
{
float4 position : POSITION;
{0}
};
GraphVertexOutput vert (GraphVertexInput v)
{
v = PopulateVertexData(v);

{0}
{1}
return o;
}

{1}
{2}
{2}
{3}
public string GetSubShader(bool requiresNormal)
public struct Requirements
public NeededCoordinateSpace requiresNormal;
public NeededCoordinateSpace requiresBitangent;
public NeededCoordinateSpace requiresTangent;
public NeededCoordinateSpace requiresViewDir;
public NeededCoordinateSpace requiresPosition;
public bool requiresScreenPosition;
public bool requiresVertexColor;
public bool NeedsTangentSpace()
{
var compoundSpaces = requiresBitangent | requiresNormal | requiresPosition
| requiresTangent | requiresViewDir | requiresPosition
| requiresNormal;
return (compoundSpaces & NeededCoordinateSpace.Tangent) > 0;
}
}
public string GetSubShader(Requirements requirements)
{
var activeNodeList = ListPool<INode>.Get();
NodeUtils.DepthFirstCollectNodesFromNode(activeNodeList, this);
var interpolators = new ShaderGenerator();
// var surfaceInputs = new ShaderGenerator();
vertexShader.AddShaderChunk("float3 worldPos = mul(unity_ObjectToWorld, v.vertex).xyz;", true);
vertexShader.AddShaderChunk("float3 viewDir = UnityWorldSpaceViewDir(worldPos);", true);
vertexShader.AddShaderChunk("float4 screenPos = ComputeScreenPos(UnityObjectToClipPos(v.vertex));", true);
vertexShader.AddShaderChunk("float3 worldNormal = UnityObjectToWorldNormal(v.normal);", true);
// bitangent needs normal for x product
if (requirements.requiresNormal > 0 || requirements.requiresBitangent > 0)
{
interpolators.AddShaderChunk(string.Format("float3 {0} : NORMAL;", ShaderGeneratorNames.ObjectSpaceNormal), false);
vertexShader.AddShaderChunk(string.Format("o.{0} = v.normal;", ShaderGeneratorNames.ObjectSpaceNormal), false);
pixelShader.AddShaderChunk(string.Format("float3 {0} = normalize(IN.{0});", ShaderGeneratorNames.ObjectSpaceNormal), false);
}
if (requirements.requiresTangent > 0 || requirements.requiresBitangent > 0)
{
interpolators.AddShaderChunk(string.Format("float4 {0} : TANGENT;", ShaderGeneratorNames.ObjectSpaceTangent), false);
vertexShader.AddShaderChunk(string.Format("o.{0} = v.tangent;", ShaderGeneratorNames.ObjectSpaceTangent), false);
pixelShader.AddShaderChunk(string.Format("float4 {0} = IN.{0};", ShaderGeneratorNames.ObjectSpaceTangent), false);
pixelShader.AddShaderChunk(string.Format("float4 {0} = normalize(cross(normalize(IN.{1}), normalize(IN.{2}.xyz)) * IN.{2}.w);",
ShaderGeneratorNames.ObjectSpaceBiTangent,
ShaderGeneratorNames.ObjectSpaceTangent,
ShaderGeneratorNames.ObjectSpaceNormal), false);
}
int interpolatorIndex = 0;
if (requirements.requiresViewDir > 0)
{
interpolators.AddShaderChunk(string.Format("float4 {0} : TEXCOORD{1};", ShaderGeneratorNames.ObjectSpaceViewDirection, interpolatorIndex), false);
vertexShader.AddShaderChunk(string.Format("o.{0} = ObjSpaceViewDir(v.vertex);", ShaderGeneratorNames.ObjectSpaceViewDirection), false);
pixelShader.AddShaderChunk(string.Format("float4 {0} = normalize(IN.{0});", ShaderGeneratorNames.ObjectSpaceViewDirection), false);
interpolatorIndex++;
}
if (requirements.requiresPosition > 0)
{
interpolators.AddShaderChunk(string.Format("float4 {0} : TEXCOORD{1};", ShaderGeneratorNames.ObjectSpacePosition, interpolatorIndex), false);
vertexShader.AddShaderChunk(string.Format("o.{0} = v.vertex;", ShaderGeneratorNames.ObjectSpacePosition), false);
pixelShader.AddShaderChunk(string.Format("float4 {0} = IN.{0};", ShaderGeneratorNames.ObjectSpacePosition), false);
interpolatorIndex++;
}
if (requirements.NeedsTangentSpace())
{
pixelShader.AddShaderChunk(string.Format("float3x3 tangentSpaceTransform = float3x3({0},{1},{2});",
ShaderGeneratorNames.ObjectSpaceTangent, ShaderGeneratorNames.ObjectSpaceBiTangent, ShaderGeneratorNames.ObjectSpaceNormal), false);
}
GenerateSpaceTranslation(requirements.requiresNormal, pixelShader,
ShaderGeneratorNames.ObjectSpaceNormal, ShaderGeneratorNames.ViewSpaceNormal,
ShaderGeneratorNames.WorldSpaceNormal, ShaderGeneratorNames.TangentSpaceNormal);
GenerateSpaceTranslation(requirements.requiresTangent, pixelShader,
ShaderGeneratorNames.ObjectSpaceTangent, ShaderGeneratorNames.ViewSpaceTangent,
ShaderGeneratorNames.WorldSpaceTangent, ShaderGeneratorNames.TangentSpaceTangent);
if (requiresNormal)
GenerateSpaceTranslation(requirements.requiresBitangent, pixelShader,
ShaderGeneratorNames.ObjectSpaceBiTangent, ShaderGeneratorNames.ViewSpaceBiTangent,
ShaderGeneratorNames.WorldSpaceSpaceBiTangent, ShaderGeneratorNames.TangentSpaceBiTangent);
GenerateSpaceTranslation(requirements.requiresViewDir, pixelShader,
ShaderGeneratorNames.ObjectSpaceViewDirection, ShaderGeneratorNames.ViewSpaceViewDirection,
ShaderGeneratorNames.WorldSpaceViewDirection, ShaderGeneratorNames.TangentSpaceViewDirection);
GenerateSpaceTranslation(requirements.requiresPosition, pixelShader,
ShaderGeneratorNames.ObjectSpacePosition, ShaderGeneratorNames.ViewSpacePosition,
ShaderGeneratorNames.WorldSpacePosition, ShaderGeneratorNames.TangentSpacePosition);
if (requirements.requiresVertexColor)
vertexShader.AddShaderChunk(string.Format("o.{0} = worldPos", ShaderGeneratorNames.WorldSpacePosition), false);
pixelShader.AddShaderChunk(string.Format("surfaceInput.{0} = IN.worldPos;", ShaderGeneratorNames.WorldSpacePosition), false);
interpolators.AddShaderChunk(string.Format("float4 {0} : COLOR;", ShaderGeneratorNames.VertexColor), false);
vertexShader.AddShaderChunk(string.Format("o.{0} = color", ShaderGeneratorNames.VertexColor), false);
pixelShader.AddShaderChunk(string.Format("surfaceInput.{0} = IN.{0};", ShaderGeneratorNames.VertexColor), false);
}
if (requirements.requiresScreenPosition)
{
interpolators.AddShaderChunk(string.Format("float4 {0} : TEXCOORD{1};;", ShaderGeneratorNames.ScreenPosition, interpolatorIndex), false);
vertexShader.AddShaderChunk(string.Format("o.{0} = ComputeScreenPos(UnityObjectToClipPos(v.vertex)", ShaderGeneratorNames.ScreenPosition), false);
pixelShader.AddShaderChunk(string.Format("surfaceInput.{0} = IN.{0};", ShaderGeneratorNames.ScreenPosition), false);
interpolatorIndex++;
}
for (int uvIndex = 0; uvIndex < ShaderGeneratorNames.UVCount; ++uvIndex)
{
var channel = (UVChannel)uvIndex;
if (activeNodeList.OfType<IMayRequireMeshUV>().Any(x => x.RequiresMeshUV(channel)))
{
interpolators.AddShaderChunk(string.Format("half4 meshUV{0} : TEXCOORD{1};", uvIndex, interpolatorIndex), false);
vertexShader.AddShaderChunk(string.Format("o.meshUV{0} = v.texcoord{1};", uvIndex, uvIndex == 0 ? "" : uvIndex.ToString()), false);
pixelShader.AddShaderChunk(string.Format("surfaceInput.{0} = IN.meshUV{1};", channel.GetUVName(), uvIndex), false);
interpolatorIndex++;
}
var res = subShaderTemplate.Replace("{0}", vertexShader.GetShaderString(0));
res = res.Replace("{1}", pixelShader.GetShaderString(0));
res = res.Replace("{2}", outputs.GetShaderString(0));
var res = subShaderTemplate.Replace("{0}", interpolators.GetShaderString(0));
res = res.Replace("{1}", vertexShader.GetShaderString(0));
res = res.Replace("{2}", pixelShader.GetShaderString(0));
res = res.Replace("{3}", outputs.GetShaderString(0));
}
private static void GenerateSpaceTranslation(
NeededCoordinateSpace neededSpaces,
ShaderGenerator pixelShader,
string objectSpaceName,
string viewSpaceName,
string worldSpaceName,
string tangentSpaceName,
bool isNormal = false)
{
if ((neededSpaces & NeededCoordinateSpace.Object) > 0)
{
pixelShader.AddShaderChunk(string.Format("surfaceInput.{0} = IN.{0};", objectSpaceName), false);
}
if ((neededSpaces & NeededCoordinateSpace.World) > 0)
{
if (isNormal)
pixelShader.AddShaderChunk(string.Format("surfaceInput.{0} = UnityObjectToWorldNormal(IN.{1});", worldSpaceName, objectSpaceName), false);
else
pixelShader.AddShaderChunk(string.Format("surfaceInput.{0} = UnityObjectToWorldDir(IN.{1});", worldSpaceName, objectSpaceName), false);
}
if ((neededSpaces & NeededCoordinateSpace.View) > 0)
{
pixelShader.AddShaderChunk(string.Format("surfaceInput.{0} = UnityObjectToViewPos(IN.{1});", viewSpaceName, objectSpaceName), false);
}
if ((neededSpaces & NeededCoordinateSpace.Tangent) > 0)
{
pixelShader.AddShaderChunk(string.Format("surfaceInput.{0} = mul(tangentSpaceTransform, IN.{1})", tangentSpaceName, objectSpaceName), false);
}
}
}
}

60
MaterialGraphProject/Assets/UnityShaderEditor/Runtime/SubGraph/SubGraphNode.cs


, IMayRequireMeshUV
, IMayRequireScreenPosition
, IMayRequireViewDirection
, IMayRequireWorldPosition
, IMayRequirePosition
, IMayRequireViewDirectionTangentSpace
, IMayRequireTime
{
[SerializeField]

subGraph.GenerateVertexToFragmentBlock(visitor, GenerationMode.ForReals);
}
public bool RequiresNormal()
public NeededCoordinateSpace RequiresNormal()
return false;
return NeededCoordinateSpace.None;
return subGraph.activeNodes.OfType<IMayRequireNormal>().Any(x => x.RequiresNormal());
return subGraph.activeNodes.OfType<IMayRequireNormal>().Aggregate(NeededCoordinateSpace.None, (mask, node) =>
{
mask |= node.RequiresNormal();
return mask;
});
}
public bool RequiresMeshUV(UVChannel channel)

return subGraph.activeNodes.OfType<IMayRequireScreenPosition>().Any(x => x.RequiresScreenPosition());
}
public bool RequiresViewDirection()
public NeededCoordinateSpace RequiresViewDirection()
return false;
return NeededCoordinateSpace.None;
return subGraph.activeNodes.OfType<IMayRequireViewDirection>().Any(x => x.RequiresViewDirection());
return subGraph.activeNodes.OfType<IMayRequireViewDirection>().Aggregate(NeededCoordinateSpace.None, (mask, node) =>
{
mask |= node.RequiresViewDirection();
return mask;
});
public bool RequiresViewDirectionTangentSpace()
{
if (subGraph == null)
return false;
return subGraph.activeNodes.OfType<IMayRequireViewDirectionTangentSpace>().Any(x => x.RequiresViewDirectionTangentSpace());
}
public bool RequiresWorldPosition()
public NeededCoordinateSpace RequiresPosition()
return false;
return NeededCoordinateSpace.None;
return subGraph.activeNodes.OfType<IMayRequireWorldPosition>().Any(x => x.RequiresWorldPosition());
return subGraph.activeNodes.OfType<IMayRequirePosition>().Aggregate(NeededCoordinateSpace.None, (mask, node) =>
{
mask |= node.RequiresPosition();
return mask;
});
public bool RequiresTangent()
public NeededCoordinateSpace RequiresTangent()
return false;
return NeededCoordinateSpace.None;
return subGraph.activeNodes.OfType<IMayRequireTangent>().Any(x => x.RequiresTangent());
return subGraph.activeNodes.OfType<IMayRequireTangent>().Aggregate(NeededCoordinateSpace.None, (mask, node) =>
{
mask |= node.RequiresTangent();
return mask;
});
}
public bool RequiresTime()

return subGraph.activeNodes.OfType<IMayRequireTime>().Any(x => x.RequiresTime());
}
public bool RequiresBitangent()
public NeededCoordinateSpace RequiresBitangent()
return false;
return NeededCoordinateSpace.None;
return subGraph.activeNodes.OfType<IMayRequireBitangent>().Any(x => x.RequiresBitangent());
return subGraph.activeNodes.OfType<IMayRequireBitangent>().Aggregate(NeededCoordinateSpace.None, (mask, node) =>
{
mask |= node.RequiresBitangent();
return mask;
});
}
public bool RequiresVertexColor()

289
MaterialGraphProject/Assets/UnityShaderEditor/Runtime/Util/ShaderGenerator.cs


private static string[] UV = {"uv0", "uv1", "uv2", "uv3"};
public static int UVCount = 4;
public const string ObjectSpaceNormal = "objectSpaceNormal";
public const string ViewSpaceNormal = "viewSpaceNormal";
public const string WorldSpaceBitangent = "worldSpaceBitangent";
public const string WorldSpaceTangent = "worldSpaceTangent";
public const string WorldSpacePosition = "worldPosition";
public const string TangentSpaceNormal = "tangentSpaceNormal";
public const string ObjectSpaceBiTangent = "objectSpaceBiTangent";
public const string ViewSpaceBiTangent = "viewSpaceBiTangent";
public const string WorldSpaceSpaceBiTangent = "worldSpaceSpaceBiTangent";
public const string TangentSpaceBiTangent = "TangentSpaceBitangent";
public const string ObjectSpaceTangent = "objectSpaceTangent";
public const string ViewSpaceTangent = "viewSpaceTangent";
public const string WorldSpaceTangent = "worldSpaceSpaceTangent";
public const string TangentSpaceTangent = "tangentSpaceSpaceTangent";
public const string ObjectSpaceViewDirection = "objectSpaceViewDirection";
public const string ViewSpaceViewDirection = "viewSpaceViewDirection";
public const string ObjectSpacePosition = "objectSpacePosition";
public const string ViewSpacePosition = "viewSpaceVPosition";
public const string WorldSpacePosition = "worldSpacePosition";
public const string TangentSpacePosition = "tangentSpacePosition";
public const string ScreenPosition = "screenPosition";
public const string VertexColor = "vertexColor";

public static string GeneratePreviewShader(AbstractMaterialNode node, out PreviewMode generatedShaderMode)
{
if (!node.GetOutputSlots<MaterialSlot>().Any())
{
generatedShaderMode = PreviewMode.Preview2D;
return string.Empty;
}
generatedShaderMode = PreviewMode.Preview2D;
return string.Empty;
}
// figure out what kind of preview we want!
var activeNodeList = ListPool<INode>.Get();
NodeUtils.DepthFirstCollectNodesFromNode(activeNodeList, node);
/*
if (!node.GetOutputSlots<MaterialSlot>().Any())
{
return string.Empty;
}
if (activeNodeList.OfType<AbstractMaterialNode>().Any(x => x.previewMode == PreviewMode.Preview3D))
generatedShaderMode = PreviewMode.Preview3D;
string templateLocation = GetTemplatePath("2DPreview.template");
if (!File.Exists(templateLocation))
return null;
string template = File.ReadAllText(templateLocation);
var shaderBodyVisitor = new ShaderGenerator();
var shaderFunctionVisitor = new ShaderGenerator();
var shaderPropertiesVisitor = new PropertyCollector();
var shaderName = "Hidden/PreviewShader/" + node.GetVariableNameForSlot(node.GetOutputSlots<MaterialSlot>().First().id);
// figure out what kind of preview we want!
var activeNodeList = ListPool<INode>.Get();
NodeUtils.DepthFirstCollectNodesFromNode(activeNodeList, node);
generatedShaderMode = PreviewMode.Preview2D;
var owner = node.owner as AbstractMaterialGraph;
if (owner != null)
owner.CollectShaderProperties(shaderPropertiesVisitor, GenerationMode.Preview);
if (activeNodeList.OfType<AbstractMaterialNode>().Any(x => x.previewMode == PreviewMode.Preview3D))
generatedShaderMode = PreviewMode.Preview3D;
var shaderInputVisitor = new ShaderGenerator();
var vertexShaderBlock = new ShaderGenerator();
string templateLocation = GetTemplatePath("2DPreview.template");
if (!File.Exists(templateLocation))
return null;
// always add color because why not.
shaderInputVisitor.AddShaderChunk("float4 color : COLOR;", true);
string template = File.ReadAllText(templateLocation);
vertexShaderBlock.AddShaderChunk("float3 worldPos = mul(unity_ObjectToWorld, v.vertex).xyz;", true);
vertexShaderBlock.AddShaderChunk("float3 viewDir = UnityWorldSpaceViewDir(worldPos);", true);
vertexShaderBlock.AddShaderChunk("float4 screenPos = ComputeScreenPos(UnityObjectToClipPos(v.vertex));", true);
vertexShaderBlock.AddShaderChunk("float3 worldNormal = UnityObjectToWorldNormal(v.normal);", true);
var shaderBodyVisitor = new ShaderGenerator();
var shaderFunctionVisitor = new ShaderGenerator();
var shaderPropertiesVisitor = new PropertyCollector();
bool requiresBitangent = activeNodeList.OfType<IMayRequireBitangent>().Any(x => x.RequiresBitangent());
bool requiresTangent = activeNodeList.OfType<IMayRequireTangent>().Any(x => x.RequiresTangent());
bool requiresViewDirTangentSpace = activeNodeList.OfType<IMayRequireViewDirectionTangentSpace>().Any(x => x.RequiresViewDirectionTangentSpace());
bool requiresViewDir = activeNodeList.OfType<IMayRequireViewDirection>().Any(x => x.RequiresViewDirection());
bool requiresWorldPos = activeNodeList.OfType<IMayRequireWorldPosition>().Any(x => x.RequiresWorldPosition());
bool requiresNormal = activeNodeList.OfType<IMayRequireNormal>().Any(x => x.RequiresNormal());
bool requiresScreenPosition = activeNodeList.OfType<IMayRequireScreenPosition>().Any(x => x.RequiresScreenPosition());
bool requiresVertexColor = activeNodeList.OfType<IMayRequireVertexColor>().Any(x => x.RequiresVertexColor());
var shaderName = "Hidden/PreviewShader/" + node.GetVariableNameForSlot(node.GetOutputSlots<MaterialSlot>().First().id);
// view directions calculated from world position
if (requiresWorldPos || requiresViewDir || requiresViewDirTangentSpace)
{
shaderInputVisitor.AddShaderChunk("float3 worldPos : TEXCOORD0;", true);
vertexShaderBlock.AddShaderChunk("o.worldPos = worldPos;", true);
shaderBodyVisitor.AddShaderChunk("float3 " + ShaderGeneratorNames.WorldSpacePosition + " = IN.worldPos;", true);
}
var owner = node.owner as AbstractMaterialGraph;
if (owner != null)
owner.CollectShaderProperties(shaderPropertiesVisitor, GenerationMode.Preview);
if (requiresBitangent || requiresNormal || requiresViewDirTangentSpace)
{
shaderInputVisitor.AddShaderChunk("float3 worldNormal : TEXCOORD1;", true);
vertexShaderBlock.AddShaderChunk("o.worldNormal = worldNormal;", true);
shaderBodyVisitor.AddShaderChunk("float3 " + ShaderGeneratorNames.WorldSpaceNormal + " = normalize(IN.worldNormal);", true);
}
var shaderInputVisitor = new ShaderGenerator();
var vertexShaderBlock = new ShaderGenerator();
for (int uvIndex = 0; uvIndex < ShaderGeneratorNames.UVCount; ++uvIndex)
{
var channel = (UVChannel)uvIndex;
if (activeNodeList.OfType<IMayRequireMeshUV>().Any(x => x.RequiresMeshUV(channel)))
{
shaderInputVisitor.AddShaderChunk(string.Format("half4 meshUV{0} : TEXCOORD{1};", uvIndex, (uvIndex + 5)), true);
vertexShaderBlock.AddShaderChunk(string.Format("o.meshUV{0} = v.texcoord{1};", uvIndex, uvIndex == 0 ? "" : uvIndex.ToString()), true);
shaderBodyVisitor.AddShaderChunk(string.Format("half4 {0} = IN.meshUV{1};", channel.GetUVName(), uvIndex), true);
}
}
// always add color because why not.
shaderInputVisitor.AddShaderChunk("float4 color : COLOR;", true);
if (requiresViewDir || requiresViewDirTangentSpace)
{
shaderBodyVisitor.AddShaderChunk(
"float3 "
+ ShaderGeneratorNames.WorldSpaceViewDirection
+ " = normalize(UnityWorldSpaceViewDir("
+ ShaderGeneratorNames.WorldSpacePosition
+ "));", true);
}
vertexShaderBlock.AddShaderChunk("float3 worldPos = mul(unity_ObjectToWorld, v.vertex).xyz;", true);
vertexShaderBlock.AddShaderChunk("float3 viewDir = UnityWorldSpaceViewDir(worldPos);", true);
vertexShaderBlock.AddShaderChunk("float4 screenPos = ComputeScreenPos(UnityObjectToClipPos(v.vertex));", true);
vertexShaderBlock.AddShaderChunk("float3 worldNormal = UnityObjectToWorldNormal(v.normal);", true);
if (requiresScreenPosition)
{
shaderInputVisitor.AddShaderChunk("float4 screenPos : TEXCOORD3;", true);
vertexShaderBlock.AddShaderChunk("o.screenPos = screenPos;", true);
shaderBodyVisitor.AddShaderChunk("half4 " + ShaderGeneratorNames.ScreenPosition + " = IN.screenPos;", true);
}
bool requiresBitangent = activeNodeList.OfType<IMayRequireBitangent>().Any(x => x.RequiresBitangent());
bool requiresTangent = activeNodeList.OfType<IMayRequireTangent>().Any(x => x.RequiresTangent());
bool requiresViewDirTangentSpace = activeNodeList.OfType<IMayRequireViewDirectionTangentSpace>().Any(x => x.RequiresViewDirectionTangentSpace());
bool requiresViewDir = activeNodeList.OfType<IMayRequireViewDirection>().Any(x => x.RequiresViewDirection());
bool requiresWorldPos = activeNodeList.OfType<IMayRequireWorldPosition>().Any(x => x.RequiresWorldPosition());
bool requiresNormal = activeNodeList.OfType<IMayRequireNormal>().Any(x => x.RequiresNormal());
bool requiresScreenPosition = activeNodeList.OfType<IMayRequireScreenPosition>().Any(x => x.RequiresScreenPosition());
bool requiresVertexColor = activeNodeList.OfType<IMayRequireVertexColor>().Any(x => x.RequiresVertexColor());
if (requiresBitangent || requiresViewDirTangentSpace || requiresTangent)
{
shaderInputVisitor.AddShaderChunk("float4 worldTangent : TEXCOORD4;", true);
vertexShaderBlock.AddShaderChunk("o.worldTangent = float4(UnityObjectToWorldDir(v.tangent.xyz), v.tangent.w);", true);
shaderBodyVisitor.AddShaderChunk("float3 " + ShaderGeneratorNames.WorldSpaceTangent + " = normalize(IN.worldTangent.xyz);", true);
}
// view directions calculated from world position
if (requiresWorldPos || requiresViewDir || requiresViewDirTangentSpace)
{
shaderInputVisitor.AddShaderChunk("float3 worldPos : TEXCOORD0;", true);
vertexShaderBlock.AddShaderChunk("o.worldPos = worldPos;", true);
shaderBodyVisitor.AddShaderChunk("float3 " + ShaderGeneratorNames.Position + " = IN.worldPos;", true);
}
/*
if (requiresBitangent || requiresNormal || requiresViewDirTangentSpace)
{
shaderInputVisitor.AddShaderChunk("float3 worldNormal : TEXCOORD1;", true);
vertexShaderBlock.AddShaderChunk("o.worldNormal = worldNormal;", true);
shaderBodyVisitor.AddShaderChunk("float3 " + ShaderGeneratorNames.Normal + " = normalize(IN.worldNormal);", true);
}*
if (requiresBitangent || requiresViewDirTangentSpace)
for (int uvIndex = 0; uvIndex < ShaderGeneratorNames.UVCount; ++uvIndex)
{
var channel = (UVChannel)uvIndex;
if (activeNodeList.OfType<IMayRequireMeshUV>().Any(x => x.RequiresMeshUV(channel)))
shaderBodyVisitor.AddShaderChunk(string.Format("float3 {0} = cross({1}, {2}) * IN.worldTangent.w;", ShaderGeneratorNames.WorldSpaceBitangent, ShaderGeneratorNames.WorldSpaceNormal, ShaderGeneratorNames.WorldSpaceTangent), true);
shaderInputVisitor.AddShaderChunk(string.Format("half4 meshUV{0} : TEXCOORD{1};", uvIndex, (uvIndex + 5)), true);
vertexShaderBlock.AddShaderChunk(string.Format("o.meshUV{0} = v.texcoord{1};", uvIndex, uvIndex == 0 ? "" : uvIndex.ToString()), true);
shaderBodyVisitor.AddShaderChunk(string.Format("half4 {0} = IN.meshUV{1};", channel.GetUVName(), uvIndex), true);
if (requiresViewDirTangentSpace)
{
shaderBodyVisitor.AddShaderChunk(
"float3 " + ShaderGeneratorNames.TangentSpaceViewDirection + ";", true);
}
shaderBodyVisitor.AddShaderChunk(
ShaderGeneratorNames.TangentSpaceViewDirection + ".x = dot(" +
ShaderGeneratorNames.WorldSpaceViewDirection + "," +
ShaderGeneratorNames.WorldSpaceTangent + ");", true);
if (requiresViewDir || requiresViewDirTangentSpace)
{
shaderBodyVisitor.AddShaderChunk(
"float3 "
+ ShaderGeneratorNames.WorldSpaceViewDirection
+ " = normalize(UnityWorldSpaceViewDir("
+ ShaderGeneratorNames.Position
+ "));", true);
}
shaderBodyVisitor.AddShaderChunk(
ShaderGeneratorNames.TangentSpaceViewDirection + ".y = dot(" +
ShaderGeneratorNames.WorldSpaceViewDirection + "," +
ShaderGeneratorNames.WorldSpaceBitangent + ");", true);
if (requiresScreenPosition)
{
shaderInputVisitor.AddShaderChunk("float4 screenPos : TEXCOORD3;", true);
vertexShaderBlock.AddShaderChunk("o.screenPos = screenPos;", true);
shaderBodyVisitor.AddShaderChunk("half4 " + ShaderGeneratorNames.ScreenPosition + " = IN.screenPos;", true);
}
shaderBodyVisitor.AddShaderChunk(
ShaderGeneratorNames.TangentSpaceViewDirection + ".z = dot(" +
ShaderGeneratorNames.WorldSpaceViewDirection + "," +
ShaderGeneratorNames.WorldSpaceNormal + ");", true);
}
/* if (requiresBitangent || requiresViewDirTangentSpace || requiresTangent)
{
shaderInputVisitor.AddShaderChunk("float4 worldTangent : TEXCOORD4;", true);
vertexShaderBlock.AddShaderChunk("o.worldTangent = float4(UnityObjectToWorldDir(v.tangent.xyz), v.tangent.w);", true);
shaderBodyVisitor.AddShaderChunk("float3 " + ShaderGeneratorNames.Tangent + " = normalize(IN.worldTangent.xyz);", true);
}*
if (requiresVertexColor)
{
vertexShaderBlock.AddShaderChunk("o.color = v.color;", true);
shaderBodyVisitor.AddShaderChunk("float4 " + ShaderGeneratorNames.VertexColor + " = IN.color;", true);
}
if (requiresBitangent || requiresViewDirTangentSpace)
{
shaderBodyVisitor.AddShaderChunk(string.Format("float3 {0} = cross({1}, {2}) * IN.worldTangent.w;", ShaderGeneratorNames.BiTangent, ShaderGeneratorNames.Normal, ShaderGeneratorNames.Tangent), true);
}
var generationMode = GenerationMode.Preview;
foreach (var activeNode in activeNodeList.OfType<AbstractMaterialNode>())
{
if (activeNode is IGeneratesFunction)
(activeNode as IGeneratesFunction).GenerateNodeFunction(shaderFunctionVisitor, generationMode);
if (activeNode is IGeneratesBodyCode)
(activeNode as IGeneratesBodyCode).GenerateNodeCode(shaderBodyVisitor, generationMode);
if (requiresVertexColor)
{
vertexShaderBlock.AddShaderChunk("o.color = v.color;", true);
shaderBodyVisitor.AddShaderChunk("float4 " + ShaderGeneratorNames.VertexColor + " = IN.color;", true);
}
activeNode.CollectShaderProperties(shaderPropertiesVisitor, generationMode);
}
var generationMode = GenerationMode.Preview;
foreach (var activeNode in activeNodeList.OfType<AbstractMaterialNode>())
{
if (activeNode is IGeneratesFunction)
(activeNode as IGeneratesFunction).GenerateNodeFunction(shaderFunctionVisitor, generationMode);
if (activeNode is IGeneratesBodyCode)
(activeNode as IGeneratesBodyCode).GenerateNodeCode(shaderBodyVisitor, generationMode);
activeNode.CollectShaderProperties(shaderPropertiesVisitor, generationMode);
}
shaderBodyVisitor.AddShaderChunk("return " + AdaptNodeOutputForPreview(node, node.GetOutputSlots<MaterialSlot>().First().id) + ";", true);
ListPool<INode>.Release(activeNodeList);
shaderBodyVisitor.AddShaderChunk("return " + AdaptNodeOutputForPreview(node, node.GetOutputSlots<MaterialSlot>().First().id) + ";", true);
template = template.Replace("${ShaderName}", shaderName);
template = template.Replace("${ShaderPropertiesHeader}", shaderPropertiesVisitor.GetPropertiesBlock(2));
template = template.Replace("${ShaderPropertyUsages}", shaderPropertiesVisitor.GetPropertiesDeclaration(3));
template = template.Replace("${ShaderInputs}", shaderInputVisitor.GetShaderString(4));
template = template.Replace("${ShaderFunctions}", shaderFunctionVisitor.GetShaderString(3));
template = template.Replace("${VertexShaderBody}", vertexShaderBlock.GetShaderString(4));
template = template.Replace("${PixelShaderBody}", shaderBodyVisitor.GetShaderString(4));
ListPool<INode>.Release(activeNodeList);
string vertexShaderBody = vertexShaderBlock.GetShaderString(4);
if (vertexShaderBody.Length > 0)
{
template = template.Replace("${VertexShaderDecl}", "vertex:vert");
template = template.Replace("${VertexShaderBody}", vertexShaderBody);
}
else
{
template = template.Replace("${VertexShaderDecl}", "");
template = template.Replace("${VertexShaderBody}", vertexShaderBody);
}
template = template.Replace("${ShaderName}", shaderName);
template = template.Replace("${ShaderPropertiesHeader}", shaderPropertiesVisitor.GetPropertiesBlock(2));
template = template.Replace("${ShaderPropertyUsages}", shaderPropertiesVisitor.GetPropertiesDeclaration(3));
template = template.Replace("${ShaderInputs}", shaderInputVisitor.GetShaderString(4));
template = template.Replace("${ShaderFunctions}", shaderFunctionVisitor.GetShaderString(3));
template = template.Replace("${VertexShaderBody}", vertexShaderBlock.GetShaderString(4));
template = template.Replace("${PixelShaderBody}", shaderBodyVisitor.GetShaderString(4));
return Regex.Replace(template, @"\r\n|\n\r|\n|\r", Environment.NewLine);
string vertexShaderBody = vertexShaderBlock.GetShaderString(4);
if (vertexShaderBody.Length > 0)
{
template = template.Replace("${VertexShaderDecl}", "vertex:vert");
template = template.Replace("${VertexShaderBody}", vertexShaderBody);
else
{
template = template.Replace("${VertexShaderDecl}", "");
template = template.Replace("${VertexShaderBody}", vertexShaderBody);
}
return Regex.Replace(template, @"\r\n|\n\r|\n|\r", Environment.NewLine);
}*/
}
}

14
MaterialGraphProject/Assets/UnityShaderEditor/Runtime/Interfaces/NeededCoordinateSpace.cs


using System;
namespace UnityEngine.MaterialGraph
{
[Flags]
public enum NeededCoordinateSpace
{
None = 0,
Object = 1<<0,
View = 1<<1,
World = 1<<2,
Tangent = 1<<3
}
}

3
MaterialGraphProject/Assets/UnityShaderEditor/Runtime/Interfaces/NeededCoordinateSpace.cs.meta


fileFormatVersion: 2
guid: 8ad845bb8ef34e4589bcf630a8a8a31a
timeCreated: 1505627582

43
MaterialGraphProject/Assets/UnityShaderEditor/Runtime/Nodes/Input/Geometry/NormalNode.cs


using UnityEngine.Graphing;
namespace UnityEngine.MaterialGraph
{
[Title("Input/Geometry/World Normal")]
public class NormalNode : AbstractMaterialNode, IMayRequireNormal
{
public const int kOutputSlotId = 0;
public const string kOutputSlotName = "Normal";
public NormalNode()
{
name = "Normal";
UpdateNodeAfterDeserialization();
}
public sealed override void UpdateNodeAfterDeserialization()
{
AddSlot(new MaterialSlot(kOutputSlotId, kOutputSlotName, kOutputSlotName, SlotType.Output, SlotValueType.Vector3, new Vector4(0, 0, 1, 1)));
RemoveSlotsNameNotMatching(new[] { kOutputSlotId });
}
public override bool hasPreview
{
get { return true; }
}
public override PreviewMode previewMode
{
get { return PreviewMode.Preview3D; }
}
public override string GetVariableNameForSlot(int slotId)
{
return ShaderGeneratorNames.ObjectSpaceNormal;
}
public NeededCoordinateSpace RequiresNormal()
{
return NeededCoordinateSpace.Object;
}
}
}

50
MaterialGraphProject/Assets/UnityShaderEditor/Runtime/Nodes/Input/Geometry/ViewDirectionNode.cs


using System.ComponentModel;
using UnityEngine.Graphing;
namespace UnityEngine.MaterialGraph
{
interface IMayRequireViewDirection
{
NeededCoordinateSpace RequiresViewDirection();
}
[Title("Input/Geometry/View Direction")]
public class ViewDirectionNode : AbstractMaterialNode, IMayRequireViewDirection
{
private const int kOutputSlotId = 0;
public override bool hasPreview { get { return true; } }
public override PreviewMode previewMode
{
get { return PreviewMode.Preview3D; }
}
public ViewDirectionNode()
{
name = "ViewDirection";
UpdateNodeAfterDeserialization();
}
public sealed override void UpdateNodeAfterDeserialization()
{
AddSlot(new MaterialSlot(
kOutputSlotId,
ShaderGeneratorNames.WorldSpaceViewDirection,
ShaderGeneratorNames.WorldSpaceViewDirection,
SlotType.Output,
SlotValueType.Vector3,
Vector4.zero));
RemoveSlotsNameNotMatching(new[] { kOutputSlotId });
}
public override string GetVariableNameForSlot(int slotId)
{
return ShaderGeneratorNames.WorldSpaceViewDirection;
}
public NeededCoordinateSpace RequiresViewDirection()
{
return NeededCoordinateSpace.Object;
}
}
}

50
MaterialGraphProject/Assets/UnityShaderEditor/Runtime/Nodes/Input/Geometry/WorldSpaceViewDirectionNode.cs


using System.ComponentModel;
using UnityEngine.Graphing;
namespace UnityEngine.MaterialGraph
{
interface IMayRequireViewDirection
{
bool RequiresViewDirection();
}
[Title("Input/Geometry/World Space View Direction")]
public class WorldSpaceViewDirectionNode : AbstractMaterialNode, IMayRequireViewDirection
{
private const int kOutputSlotId = 0;
public override bool hasPreview { get { return true; } }
public override PreviewMode previewMode
{
get { return PreviewMode.Preview3D; }
}
public WorldSpaceViewDirectionNode()
{
name = "WorldSpaceViewDirection";
UpdateNodeAfterDeserialization();
}
public sealed override void UpdateNodeAfterDeserialization()
{
AddSlot(new MaterialSlot(
kOutputSlotId,
ShaderGeneratorNames.WorldSpaceViewDirection,
ShaderGeneratorNames.WorldSpaceViewDirection,
SlotType.Output,
SlotValueType.Vector3,
Vector4.zero));
RemoveSlotsNameNotMatching(new[] { kOutputSlotId });
}
public override string GetVariableNameForSlot(int slotId)
{
return ShaderGeneratorNames.WorldSpaceViewDirection;
}
public bool RequiresViewDirection()
{
return true;
}
}
}

43
MaterialGraphProject/Assets/UnityShaderEditor/Runtime/Nodes/Input/Geometry/WorldSpaceNormalNode.cs


using UnityEngine.Graphing;
namespace UnityEngine.MaterialGraph
{
[Title("Input/Geometry/World Normal")]
public class WorldSpaceNormalNode : AbstractMaterialNode, IMayRequireNormal
{
public const int kOutputSlotId = 0;
public const string kOutputSlotName = "Normal";
public WorldSpaceNormalNode()
{
name = "WorldNormal";
UpdateNodeAfterDeserialization();
}
public sealed override void UpdateNodeAfterDeserialization()
{
AddSlot(new MaterialSlot(kOutputSlotId, kOutputSlotName, kOutputSlotName, SlotType.Output, SlotValueType.Vector3, new Vector4(0, 0, 1, 1)));
RemoveSlotsNameNotMatching(new[] { kOutputSlotId });
}
public override bool hasPreview
{
get { return true; }
}
public override PreviewMode previewMode
{
get { return PreviewMode.Preview3D; }
}
public override string GetVariableNameForSlot(int slotId)
{
return ShaderGeneratorNames.WorldSpaceNormal;
}
public bool RequiresNormal()
{
return true;
}
}
}

/MaterialGraphProject/Assets/UnityShaderEditor/Runtime/Nodes/Input/Geometry/WorldSpaceNormalNode.cs.meta → /MaterialGraphProject/Assets/UnityShaderEditor/Runtime/Nodes/Input/Geometry/NormalNode.cs.meta

/MaterialGraphProject/Assets/UnityShaderEditor/Runtime/Nodes/Input/Geometry/WorldSpaceViewDirectionNode.cs.meta → /MaterialGraphProject/Assets/UnityShaderEditor/Runtime/Nodes/Input/Geometry/ViewDirectionNode.cs.meta

正在加载...
取消
保存