Tim Cooper
12 年前
当前提交
2a039635
共有 187 个文件被更改,包括 3399 次插入 和 0 次删除
-
5UnityProject/Assets/Editor/Material.meta
-
104UnityProject/Assets/Editor/Material/BaseMaterialGraph.cs
-
8UnityProject/Assets/Editor/Material/BaseMaterialGraph.cs.meta
-
85UnityProject/Assets/Editor/Material/BaseMaterialGraphGUI.cs
-
8UnityProject/Assets/Editor/Material/BaseMaterialGraphGUI.cs.meta
-
5UnityProject/Assets/Editor/Material/Editors.meta
-
87UnityProject/Assets/Editor/Material/Editors/BaseMaterialNodeEditor.cs
-
8UnityProject/Assets/Editor/Material/Editors/BaseMaterialNodeEditor.cs.meta
-
34UnityProject/Assets/Editor/Material/Editors/PropertyNodeEditor.cs
-
8UnityProject/Assets/Editor/Material/Editors/PropertyNodeEditor.cs.meta
-
5UnityProject/Assets/Editor/Material/Interfaces.meta
-
5UnityProject/Assets/Editor/Material/Light.meta
-
21UnityProject/Assets/Editor/Material/Light/BaseLightFunction.cs
-
8UnityProject/Assets/Editor/Material/Light/BaseLightFunction.cs.meta
-
28UnityProject/Assets/Editor/Material/Light/SimpleSpecularFunction.cs
-
8UnityProject/Assets/Editor/Material/Light/SimpleSpecularFunction.cs.meta
-
27UnityProject/Assets/Editor/Material/Light/WrapLambertFunction.cs
-
8UnityProject/Assets/Editor/Material/Light/WrapLambertFunction.cs.meta
-
109UnityProject/Assets/Editor/Material/MaterialGraph.cs
-
8UnityProject/Assets/Editor/Material/MaterialGraph.cs.meta
-
64UnityProject/Assets/Editor/Material/MaterialGraphGUI.cs
-
8UnityProject/Assets/Editor/Material/MaterialGraphGUI.cs.meta
-
213UnityProject/Assets/Editor/Material/MaterialSubGraph.cs
-
8UnityProject/Assets/Editor/Material/MaterialSubGraph.cs.meta
-
34UnityProject/Assets/Editor/Material/MaterialSubGraphGUI.cs
-
8UnityProject/Assets/Editor/Material/MaterialSubGraphGUI.cs.meta
-
156UnityProject/Assets/Editor/Material/MaterialWindow.cs
-
8UnityProject/Assets/Editor/Material/MaterialWindow.cs.meta
-
5UnityProject/Assets/Editor/Material/Nodes.meta
-
30UnityProject/Assets/Editor/Material/Nodes/AbsoluteNode.cs
-
8UnityProject/Assets/Editor/Material/Nodes/AbsoluteNode.cs.meta
-
50UnityProject/Assets/Editor/Material/Nodes/AddNode.cs
-
8UnityProject/Assets/Editor/Material/Nodes/AddNode.cs.meta
-
486UnityProject/Assets/Editor/Material/Nodes/BaseMaterialNode.cs
-
8UnityProject/Assets/Editor/Material/Nodes/BaseMaterialNode.cs.meta
-
67UnityProject/Assets/Editor/Material/Nodes/BlendNode.cs
-
8UnityProject/Assets/Editor/Material/Nodes/BlendNode.cs.meta
-
30UnityProject/Assets/Editor/Material/Nodes/ClampNode.cs
-
8UnityProject/Assets/Editor/Material/Nodes/ClampNode.cs.meta
-
99UnityProject/Assets/Editor/Material/Nodes/ColorNode.cs
-
8UnityProject/Assets/Editor/Material/Nodes/ColorNode.cs.meta
-
72UnityProject/Assets/Editor/Material/Nodes/ColorizeNode.cs
-
8UnityProject/Assets/Editor/Material/Nodes/ColorizeNode.cs.meta
-
114UnityProject/Assets/Editor/Material/Nodes/CombineNode.cs
-
8UnityProject/Assets/Editor/Material/Nodes/CombineNode.cs.meta
-
30UnityProject/Assets/Editor/Material/Nodes/DivNode.cs
-
8UnityProject/Assets/Editor/Material/Nodes/DivNode.cs.meta
-
14UnityProject/Assets/Editor/Material/Nodes/DotNode.cs
-
8UnityProject/Assets/Editor/Material/Nodes/DotNode.cs.meta
-
47UnityProject/Assets/Editor/Material/Nodes/Extensions.cs
-
8UnityProject/Assets/Editor/Material/Nodes/Extensions.cs.meta
-
31UnityProject/Assets/Editor/Material/Nodes/FresnelNode.cs
-
8UnityProject/Assets/Editor/Material/Nodes/FresnelNode.cs.meta
-
57UnityProject/Assets/Editor/Material/Nodes/Function1Input.cs
-
8UnityProject/Assets/Editor/Material/Nodes/Function1Input.cs.meta
-
46UnityProject/Assets/Editor/Material/Nodes/Function2Input.cs
-
8UnityProject/Assets/Editor/Material/Nodes/Function2Input.cs.meta
-
51UnityProject/Assets/Editor/Material/Nodes/Function3Input.cs
-
8UnityProject/Assets/Editor/Material/Nodes/Function3Input.cs.meta
-
83UnityProject/Assets/Editor/Material/Nodes/FunctionMultiInput.cs
-
8UnityProject/Assets/Editor/Material/Nodes/FunctionMultiInput.cs.meta
-
95UnityProject/Assets/Editor/Material/Nodes/KaleidoscopeNode.cs
-
8UnityProject/Assets/Editor/Material/Nodes/KaleidoscopeNode.cs.meta
-
14UnityProject/Assets/Editor/Material/Nodes/LengthNode.cs
-
8UnityProject/Assets/Editor/Material/Nodes/LengthNode.cs.meta
-
95UnityProject/Assets/Editor/Material/Nodes/MandelbrotNode.cs
-
8UnityProject/Assets/Editor/Material/Nodes/MandelbrotNode.cs.meta
-
14UnityProject/Assets/Editor/Material/Nodes/MaxNode.cs
-
8UnityProject/Assets/Editor/Material/Nodes/MaxNode.cs.meta
-
14UnityProject/Assets/Editor/Material/Nodes/MinNode.cs
-
8UnityProject/Assets/Editor/Material/Nodes/MinNode.cs.meta
-
37UnityProject/Assets/Editor/Material/Nodes/MultiplyNode.cs
-
8UnityProject/Assets/Editor/Material/Nodes/MultiplyNode.cs.meta
-
30UnityProject/Assets/Editor/Material/Nodes/NormalNode.cs
-
8UnityProject/Assets/Editor/Material/Nodes/NormalNode.cs.meta
-
14UnityProject/Assets/Editor/Material/Nodes/NormalizeNode.cs
-
8UnityProject/Assets/Editor/Material/Nodes/NormalizeNode.cs.meta
-
101UnityProject/Assets/Editor/Material/Nodes/PerlinNode.cs
-
8UnityProject/Assets/Editor/Material/Nodes/PerlinNode.cs.meta
-
145UnityProject/Assets/Editor/Material/Nodes/PixelShaderNode.cs
-
8UnityProject/Assets/Editor/Material/Nodes/PixelShaderNode.cs.meta
-
16UnityProject/Assets/Editor/Material/Nodes/PowerNode.cs
-
8UnityProject/Assets/Editor/Material/Nodes/PowerNode.cs.meta
-
69UnityProject/Assets/Editor/Material/Nodes/PropertyNode.cs
-
8UnityProject/Assets/Editor/Material/Nodes/PropertyNode.cs.meta
-
30UnityProject/Assets/Editor/Material/Nodes/QuantizeNode.cs
-
8UnityProject/Assets/Editor/Material/Nodes/QuantizeNode.cs.meta
-
38UnityProject/Assets/Editor/Material/Nodes/ReflectNode.cs
-
8UnityProject/Assets/Editor/Material/Nodes/ReflectNode.cs.meta
-
27UnityProject/Assets/Editor/Material/Nodes/ScreenPosNode.cs
-
8UnityProject/Assets/Editor/Material/Nodes/ScreenPosNode.cs.meta
-
14UnityProject/Assets/Editor/Material/Nodes/SinNode.cs
-
8UnityProject/Assets/Editor/Material/Nodes/SinNode.cs.meta
|
|||
fileFormatVersion: 2 |
|||
guid: a48816fdf109ebf49adc559a855f3e42 |
|||
folderAsset: yes |
|||
DefaultImporter: |
|||
userData: |
|
|||
using System.Collections.Generic; |
|||
using System.Linq; |
|||
using UnityEngine; |
|||
|
|||
namespace UnityEditor.Graphs.Material |
|||
{ |
|||
|
|||
public interface IGenerateGraphProperties |
|||
{ |
|||
void GenerateSharedProperties (PropertyGenerator shaderProperties, ShaderGenerator propertyUsages, GenerationMode generationMode); |
|||
IEnumerable<ShaderProperty> GetPropertiesForPropertyType (PropertyType propertyType); |
|||
} |
|||
|
|||
public abstract class BaseMaterialGraph : Graph |
|||
{ |
|||
public abstract BaseMaterialNode masterNode { get; } |
|||
|
|||
private PreviewRenderUtility m_PreviewUtility; |
|||
|
|||
public PreviewRenderUtility previewUtility |
|||
{ |
|||
get |
|||
{ |
|||
if (m_PreviewUtility == null) |
|||
m_PreviewUtility = new PreviewRenderUtility (); |
|||
|
|||
return m_PreviewUtility; |
|||
} |
|||
} |
|||
|
|||
public bool requiresRepaint |
|||
{ |
|||
get { return m_ImAwake && nodes.Any (x => x is IRequiresTime); } |
|||
} |
|||
|
|||
public override void RemoveEdge (Edge e) |
|||
{ |
|||
base.RemoveEdge (e); |
|||
|
|||
var toNode = e.toSlot.node as BaseMaterialNode; |
|||
if (toNode == null) |
|||
return; |
|||
|
|||
toNode.RegeneratePreviewShaders (); |
|||
} |
|||
|
|||
public override Edge Connect(Slot fromSlot, Slot toSlot) |
|||
{ |
|||
var edge = base.Connect (fromSlot, toSlot); |
|||
var toNode = toSlot.node as BaseMaterialNode; |
|||
var fromNode = fromSlot.node as BaseMaterialNode; |
|||
|
|||
if (fromNode == null || toNode == null) |
|||
return edge; |
|||
|
|||
toNode.RegeneratePreviewShaders(); |
|||
fromNode.CollectChildNodesByExecutionOrder().ToList ().ForEach (s => s.UpdatePreviewProperties()); |
|||
|
|||
return edge; |
|||
} |
|||
|
|||
public override void AddNode(Node node) |
|||
{ |
|||
base.AddNode(node); |
|||
AssetDatabase.AddObjectToAsset (node, this); |
|||
|
|||
var bmn = node as BaseMaterialNode; |
|||
if (bmn != null && bmn.hasPreview ) |
|||
bmn.UpdatePreviewMaterial (); |
|||
} |
|||
|
|||
protected void AddMasterNodeNoAddToAsset (Node node) |
|||
{ |
|||
base.AddNode (node); |
|||
} |
|||
|
|||
public void GeneratePreviewShaders () |
|||
{ |
|||
MaterialWindow.DebugMaterialGraph ("Generating preview shaders on: " + name); |
|||
|
|||
// 2 passes...
|
|||
// 1 create the shaders
|
|||
foreach (var node in nodes) |
|||
{ |
|||
var bmn = node as BaseMaterialNode; |
|||
if (bmn != null && bmn.hasPreview) |
|||
{ |
|||
bmn.UpdatePreviewMaterial (); |
|||
} |
|||
} |
|||
|
|||
// 2 set the properties
|
|||
foreach (var node in nodes) |
|||
{ |
|||
var pNode = node as BaseMaterialNode; |
|||
if (pNode != null) |
|||
{ |
|||
MaterialWindow.DebugMaterialGraph ("Updating preview Properties on Node: " + pNode); |
|||
pNode.UpdatePreviewProperties (); |
|||
} |
|||
} |
|||
} |
|||
} |
|||
} |
|
|||
fileFormatVersion: 2 |
|||
guid: 6567c9f37c0aaa94e9083ffc63612ecf |
|||
MonoImporter: |
|||
serializedVersion: 2 |
|||
defaultReferences: [] |
|||
executionOrder: 0 |
|||
icon: {instanceID: 0} |
|||
userData: |
|
|||
using System; |
|||
using UnityEngine; |
|||
using System.Reflection; |
|||
|
|||
namespace UnityEditor.Graphs.Material |
|||
{ |
|||
abstract class BaseMaterialGraphGUI : GraphGUI |
|||
{ |
|||
internal const int kDefaultNodeWidth = 50; |
|||
internal const int kDefaultNodeHeight = 80; |
|||
|
|||
public override void OnGraphGUI() |
|||
{ |
|||
m_Host.BeginWindows(); |
|||
|
|||
// Process all nodes in the graph
|
|||
foreach (var n in graph.nodes) |
|||
{ |
|||
var n2 = n; |
|||
bool isSelected = selection.Contains(n2); |
|||
n.position = GUILayout.Window(n.GetInstanceID(), n.position, delegate { NodeGUI(n2); }, n.title, Styles.GetNodeStyle(n.style, n.color, isSelected), GUILayout.Width(kDefaultNodeWidth), GUILayout.Height(kDefaultNodeHeight)); |
|||
if (n2 is BaseMaterialNode) |
|||
((BaseMaterialNode)n2).isSelected = isSelected; |
|||
} |
|||
|
|||
m_Host.EndWindows(); |
|||
|
|||
edgeGUI.DoEdges(); |
|||
|
|||
edgeGUI.DoDraggedEdge (); |
|||
|
|||
DragSelection(new Rect(-5000, -5000, 10000, 10000)); |
|||
HandleMenuEvents (); |
|||
|
|||
Event evt = Event.current; |
|||
if (evt.type == EventType.MouseDown) |
|||
{ |
|||
if (evt.button == 1) |
|||
{ |
|||
DoAddNodeMenu(Event.current.mousePosition); |
|||
evt.Use(); |
|||
} |
|||
} |
|||
} |
|||
|
|||
private class AddNodeCreationObject : object |
|||
{ |
|||
public Vector2 m_Pos; |
|||
public readonly Type m_Type; |
|||
|
|||
public AddNodeCreationObject(Type t, Vector2 p) { m_Type = t; m_Pos = p; } |
|||
}; |
|||
|
|||
private void AddNode(object obj) |
|||
{ |
|||
var posObj = obj as AddNodeCreationObject; |
|||
if (posObj == null) |
|||
return; |
|||
|
|||
var node = (BaseMaterialNode)CreateInstance(posObj.m_Type); |
|||
node.Init (); |
|||
node.position = new Rect(posObj.m_Pos.x, posObj.m_Pos.y, node.position.width, node.position.height); |
|||
graph.AddNode(node); |
|||
} |
|||
|
|||
public virtual bool CanAddToNodeMenu(Type type) { return true; } |
|||
|
|||
protected void DoAddNodeMenu (Vector2 pos) |
|||
{ |
|||
var gm = new GenericMenu(); |
|||
foreach (Type type in Assembly.GetAssembly(typeof(BaseMaterialNode)).GetTypes()) |
|||
{ |
|||
if(type.IsClass && !type.IsAbstract && (type.IsSubclassOf(typeof(BaseMaterialNode)) || type.IsSubclassOf(typeof(PropertyNode)))) |
|||
{ |
|||
var attrs = type.GetCustomAttributes(typeof(TitleAttribute), false) as TitleAttribute[]; |
|||
if(attrs != null && attrs.Length > 0 && CanAddToNodeMenu(type)) |
|||
{ |
|||
gm.AddItem(new GUIContent(attrs[0].m_Title), false, AddNode, new AddNodeCreationObject(type, pos)); |
|||
} |
|||
} |
|||
} |
|||
gm.ShowAsContext (); |
|||
} |
|||
} |
|||
} |
|
|||
fileFormatVersion: 2 |
|||
guid: ac8e8db31ba040a479c767257822927a |
|||
MonoImporter: |
|||
serializedVersion: 2 |
|||
defaultReferences: [] |
|||
executionOrder: 0 |
|||
icon: {instanceID: 0} |
|||
userData: |
|
|||
fileFormatVersion: 2 |
|||
guid: 221d30ba302de9c4c8912141392f3afa |
|||
folderAsset: yes |
|||
DefaultImporter: |
|||
userData: |
|
|||
using System; |
|||
using UnityEngine; |
|||
|
|||
namespace UnityEditor.Graphs.Material |
|||
{ |
|||
[CustomEditor(typeof(BaseMaterialNode), true)] |
|||
class BaseMaterialNodeEditor : Editor |
|||
{ |
|||
public override void OnInspectorGUI() |
|||
{ |
|||
var node = target as BaseMaterialNode; |
|||
if (node == null) |
|||
return; |
|||
|
|||
var slots = node.slots.ToArray(); |
|||
|
|||
EditorGUILayout.LabelField ("Preview Mode: " + node.previewMode); |
|||
|
|||
foreach (var slot in slots) |
|||
DoSlotUI (node, slot); |
|||
} |
|||
|
|||
/*private bool DoDefaultInspectorUI () |
|||
{ |
|||
EditorGUIUtility.LookLikeInspector(); |
|||
|
|||
EditorGUI.BeginChangeCheck (); |
|||
serializedObject.Update(); |
|||
|
|||
bool materialSlotsFound = serializedObject.FindProperty("m_SlotDefaultValues") != null; |
|||
SerializedProperty property = serializedObject.GetIterator (); |
|||
bool expanded = true; |
|||
|
|||
while (property.NextVisible (expanded)) |
|||
{ |
|||
expanded = false; |
|||
if (materialSlotsFound && (property.type == "Slot" || property.name == "m_SlotPropertiesIndexes" || property.name == "m_SlotProperties")) |
|||
continue; |
|||
EditorGUILayout.PropertyField (property, true); |
|||
} |
|||
|
|||
serializedObject.ApplyModifiedProperties (); |
|||
EditorGUI.EndChangeCheck (); |
|||
|
|||
return materialSlotsFound; |
|||
} |
|||
*/ |
|||
private void DoSlotUI (BaseMaterialNode node, Slot slot) |
|||
{ |
|||
GUILayout.BeginHorizontal (EditorStyles.inspectorBig); |
|||
GUILayout.BeginVertical (); |
|||
GUILayout.BeginHorizontal (); |
|||
GUILayout.Label ("Slot " + slot.title, EditorStyles.largeLabel); |
|||
GUILayout.FlexibleSpace(); |
|||
GUILayout.EndHorizontal (); |
|||
GUILayout.EndVertical (); |
|||
GUILayout.EndHorizontal (); |
|||
|
|||
DoMaterialSlotUIBody (node, slot); |
|||
} |
|||
|
|||
private static void DoMaterialSlotUIBody(BaseMaterialNode node, Slot slot) |
|||
{ |
|||
SlotDefaultValue defaultValue = node.GetSlotDefaultValue (slot.name); |
|||
if (defaultValue == null) |
|||
return; |
|||
|
|||
if (defaultValue.editable) |
|||
slot.title = EditorGUILayout.TextField ("Title", slot.title); |
|||
|
|||
var def = node.GetSlotDefaultValue (slot.name); |
|||
if (def != null) |
|||
{ |
|||
if (def.OnGUI()) |
|||
{ |
|||
node.UpdatePreviewProperties (); |
|||
|
|||
} |
|||
} |
|||
} |
|||
|
|||
private static void RemoveSlot (BaseMaterialNode node, Slot slot) |
|||
{ |
|||
node.RemoveSlot (slot); |
|||
} |
|||
} |
|||
} |
|
|||
fileFormatVersion: 2 |
|||
guid: d1e060684b84ebf4aa8b96b424def1ab |
|||
MonoImporter: |
|||
serializedVersion: 2 |
|||
defaultReferences: [] |
|||
executionOrder: 0 |
|||
icon: {instanceID: 0} |
|||
userData: |
|
|||
using System.Collections.Generic; |
|||
using System.Linq; |
|||
|
|||
namespace UnityEditor.Graphs.Material |
|||
{ |
|||
[CustomEditor(typeof(PropertyNode), true)] |
|||
class PropertyNodeEditor : Editor |
|||
{ |
|||
public override void OnInspectorGUI() |
|||
{ |
|||
var propertyNode = target as PropertyNode; |
|||
if (propertyNode == null) |
|||
return; |
|||
|
|||
// find available properties
|
|||
var allowedBindings = propertyNode.FindValidPropertyBindings ().ToList (); |
|||
|
|||
var names = new List<string> {"none"}; |
|||
names.AddRange (allowedBindings.Select (x => x.name)); |
|||
var currentIndex = names.IndexOf (propertyNode.boundProperty == null ? "none" : propertyNode.boundProperty.name); |
|||
|
|||
EditorGUI.BeginChangeCheck (); |
|||
currentIndex = EditorGUILayout.Popup ("Bound Property", currentIndex, names.ToArray ()); |
|||
if (EditorGUI.EndChangeCheck()) |
|||
{ |
|||
ShaderProperty selected = null; |
|||
if (currentIndex > 0) |
|||
selected = allowedBindings[currentIndex - 1]; |
|||
|
|||
propertyNode.BindProperty (selected, true); |
|||
} |
|||
} |
|||
} |
|||
} |
|
|||
fileFormatVersion: 2 |
|||
guid: 30abe8c249112c9408f055b48acef7d8 |
|||
MonoImporter: |
|||
serializedVersion: 2 |
|||
defaultReferences: [] |
|||
executionOrder: 0 |
|||
icon: {instanceID: 0} |
|||
userData: |
|
|||
fileFormatVersion: 2 |
|||
guid: 40a7723163e258742885b9b645737dd6 |
|||
folderAsset: yes |
|||
DefaultImporter: |
|||
userData: |
|
|||
fileFormatVersion: 2 |
|||
guid: bd024cce897f5b5459ef6b8b08a31329 |
|||
folderAsset: yes |
|||
DefaultImporter: |
|||
userData: |
|
|||
using System; |
|||
using UnityEngine; |
|||
|
|||
namespace UnityEditor.Graphs.Material |
|||
{ |
|||
public abstract class BaseLightFunction |
|||
{ |
|||
public virtual string GetName () { return ""; } |
|||
public virtual void GenerateBody (ShaderGenerator visitor) {} |
|||
} |
|||
|
|||
class LambertLightFunction : BaseLightFunction |
|||
{ |
|||
public override string GetName () { return "Lambert"; } |
|||
} |
|||
|
|||
class BlinnPhongLightFunction : BaseLightFunction |
|||
{ |
|||
public override string GetName () { return "BlinnPhong"; } |
|||
} |
|||
} |
|
|||
fileFormatVersion: 2 |
|||
guid: 0981739b7ed42c34c9f238c36a1d63e0 |
|||
MonoImporter: |
|||
serializedVersion: 2 |
|||
defaultReferences: [] |
|||
executionOrder: 0 |
|||
icon: {instanceID: 0} |
|||
userData: |
|
|||
using System; |
|||
using UnityEngine; |
|||
|
|||
namespace UnityEditor.Graphs.Material |
|||
{ |
|||
class SimpleSpecularFunction : BaseLightFunction |
|||
{ |
|||
public override string GetName () { return "SimpleSpecular"; } |
|||
public override void GenerateBody(ShaderGenerator visitor) |
|||
{ |
|||
var outputString = new ShaderGenerator (); |
|||
outputString.AddShaderChunk ("half4 Lighting" + GetName () + " (SurfaceOutput s, half3 lightDir, half3 viewDir, half atten)", false); |
|||
outputString.AddShaderChunk ("{", false); |
|||
outputString.Indent (); |
|||
outputString.AddShaderChunk ("half3 h = normalize (lightDir + viewDir);", false); |
|||
outputString.AddShaderChunk ("half diff = max (0, dot (s.Normal, lightDir));", false); |
|||
outputString.AddShaderChunk ("half nh = max (0, dot (s.Normal, h));", false); |
|||
outputString.AddShaderChunk ("half spec = pow (nh, 48.0);", false); |
|||
outputString.AddShaderChunk ("half4 c; c.rgb = (s.Albedo * _LightColor0.rgb * diff + _LightColor0.rgb * spec) * (atten * 2);", false); |
|||
outputString.AddShaderChunk ("c.a = s.Alpha;", false); |
|||
outputString.AddShaderChunk ("return c;", false); |
|||
outputString.Deindent (); |
|||
outputString.AddShaderChunk ("}", false); |
|||
|
|||
visitor.AddShaderChunk (outputString.GetShaderString (0), true); |
|||
} |
|||
} |
|||
} |
|
|||
fileFormatVersion: 2 |
|||
guid: 241a90386f89a7f4da1ca187a0dd3eb2 |
|||
MonoImporter: |
|||
serializedVersion: 2 |
|||
defaultReferences: [] |
|||
executionOrder: 0 |
|||
icon: {instanceID: 0} |
|||
userData: |
|
|||
using System; |
|||
using UnityEngine; |
|||
|
|||
namespace UnityEditor.Graphs.Material |
|||
{ |
|||
class WrapLambertFunction : BaseLightFunction |
|||
{ |
|||
public override string GetName () { return "WrapLambert"; } |
|||
public override void GenerateBody(ShaderGenerator visitor) |
|||
{ |
|||
var outputString = new ShaderGenerator (); |
|||
outputString.AddShaderChunk ("half4 Lighting" + GetName () + " (SurfaceOutput s, half3 lightDir, half atten)", false); |
|||
outputString.AddShaderChunk ("{", false); |
|||
outputString.Indent (); |
|||
outputString.AddShaderChunk ("half NdotL = dot (s.Normal, lightDir);", false); |
|||
outputString.AddShaderChunk ("half diff = NdotL * 0.5 + 0.5;", false); |
|||
outputString.AddShaderChunk ("half4 c;", false); |
|||
outputString.AddShaderChunk ("c.rgb = s.Albedo * _LightColor0.rgb * (diff * atten * 2);", false); |
|||
outputString.AddShaderChunk ("c.a = s.Alpha;", false); |
|||
outputString.AddShaderChunk ("return c;", false); |
|||
outputString.Deindent (); |
|||
outputString.AddShaderChunk ("}", false); |
|||
|
|||
visitor.AddShaderChunk (outputString.GetShaderString (0), true); |
|||
} |
|||
} |
|||
} |
|
|||
fileFormatVersion: 2 |
|||
guid: 4ed268fcd50cca74489ba39307e33e63 |
|||
MonoImporter: |
|||
serializedVersion: 2 |
|||
defaultReferences: [] |
|||
executionOrder: 0 |
|||
icon: {instanceID: 0} |
|||
userData: |
|
|||
using System; |
|||
using System.Collections.Generic; |
|||
using System.Linq; |
|||
using UnityEngine; |
|||
|
|||
namespace UnityEditor.Graphs.Material |
|||
{ |
|||
public class MaterialGraph : ScriptableObject, IGenerateGraphProperties |
|||
{ |
|||
[SerializeField] |
|||
private MaterialProperties m_MaterialProperties; |
|||
|
|||
[SerializeField] |
|||
private MaterialOptions m_MaterialOptions; |
|||
|
|||
[SerializeField] |
|||
private PixelGraph m_PixelGraph; |
|||
|
|||
[SerializeField] |
|||
private Shader m_Shader; |
|||
|
|||
public MaterialProperties materialProperties { get { return m_MaterialProperties; } } |
|||
public MaterialOptions materialOptions { get { return m_MaterialOptions; } } |
|||
|
|||
public BaseMaterialGraph currentGraph { get { return m_PixelGraph; } } |
|||
|
|||
public void GenerateSharedProperties(PropertyGenerator shaderProperties, ShaderGenerator propertyUsages, GenerationMode generationMode) |
|||
{ |
|||
m_MaterialProperties.GenerateSharedProperties (shaderProperties, propertyUsages, generationMode); |
|||
} |
|||
|
|||
public IEnumerable<ShaderProperty> GetPropertiesForPropertyType (PropertyType propertyType) |
|||
{ |
|||
return m_MaterialProperties.GetPropertiesForPropertyType(propertyType); |
|||
} |
|||
|
|||
public void OnEnable () |
|||
{ |
|||
if (m_MaterialProperties == null) |
|||
{ |
|||
m_MaterialProperties = CreateInstance<MaterialProperties>(); |
|||
m_MaterialProperties.hideFlags = HideFlags.HideInHierarchy; |
|||
} |
|||
|
|||
if (m_MaterialOptions == null) |
|||
{ |
|||
m_MaterialOptions = CreateInstance<MaterialOptions> (); |
|||
m_MaterialOptions.Init (); |
|||
m_MaterialOptions.hideFlags = HideFlags.HideInHierarchy; |
|||
} |
|||
|
|||
if (m_PixelGraph == null) |
|||
{ |
|||
m_PixelGraph = CreateInstance<PixelGraph>(); |
|||
m_PixelGraph.hideFlags = HideFlags.HideInHierarchy; |
|||
m_PixelGraph.name = name; |
|||
} |
|||
|
|||
m_PixelGraph.owner = this; |
|||
} |
|||
|
|||
public void OnDisable () |
|||
{ |
|||
// if (m_MaterialProperties != null)
|
|||
// m_MaterialProperties.OnChangePreviewState -= OnChangePreviewState;
|
|||
} |
|||
|
|||
void OnChangePreviewState (object sender, EventArgs eventArgs) |
|||
{ |
|||
m_PixelGraph.previewState = (PreviewState)sender; |
|||
} |
|||
|
|||
public void UpdateShaderSource (string src, Dictionary<string, Texture> defaultTexutres) |
|||
{ |
|||
UnityEditorInternal.InternalEditorUtility.UpdateShaderAsset (m_Shader, src); |
|||
EditorMaterialUtility.SetShaderDefaults (m_Shader, defaultTexutres.Keys.ToArray (), defaultTexutres.Values.ToArray ()); |
|||
} |
|||
|
|||
public void CreateSubAssets () |
|||
{ |
|||
AssetDatabase.AddObjectToAsset (m_MaterialProperties, this); |
|||
AssetDatabase.AddObjectToAsset (m_MaterialOptions, this); |
|||
AssetDatabase.AddObjectToAsset (m_PixelGraph, this); |
|||
|
|||
if (m_Shader == null) |
|||
{ |
|||
const string shaderSource = "Shader \"Graphs/Dummy\" {" + |
|||
"Properties { _Color (\"Main Color\", Color) = (1,1,1,0) }" + |
|||
"SubShader {" + |
|||
" Tags { \"Queue\" = \"Transparent\" }" + |
|||
" Pass {" + |
|||
" Blend One One ZWrite Off ColorMask RGB" + |
|||
" Material { Diffuse [_Color] Ambient [_Color] }" + |
|||
" Lighting On" + |
|||
" SetTexture [_Dummy] { combine primary double, primary }" + |
|||
" }" + |
|||
"}" + |
|||
"}"; |
|||
|
|||
m_Shader = UnityEditorInternal.InternalEditorUtility.CreateShaderAsset(shaderSource); |
|||
m_Shader.name = name; |
|||
m_Shader.hideFlags = HideFlags.HideInHierarchy; |
|||
} |
|||
AssetDatabase.AddObjectToAsset (m_Shader, this); |
|||
|
|||
m_PixelGraph.AddMasterNodeToAsset (); |
|||
} |
|||
} |
|||
} |
|
|||
fileFormatVersion: 2 |
|||
guid: ef5b9f0785847b04983f907c7f016a36 |
|||
MonoImporter: |
|||
serializedVersion: 2 |
|||
defaultReferences: [] |
|||
executionOrder: 0 |
|||
icon: {instanceID: 0} |
|||
userData: |
|
|||
using System.IO; |
|||
using UnityEngine; |
|||
using System.Linq; |
|||
|
|||
namespace UnityEditor.Graphs.Material |
|||
{ |
|||
class MaterialGraphGUI : BaseMaterialGraphGUI |
|||
{ |
|||
enum SelectedOptions |
|||
{ |
|||
properties, |
|||
options |
|||
} |
|||
|
|||
private PixelGraph GetGraph() {return graph as PixelGraph;} |
|||
public MaterialGraph materialGraph; |
|||
|
|||
private SelectedOptions m_SelectedGUI = SelectedOptions.properties; |
|||
|
|||
private static void DrawSpacer() |
|||
{ |
|||
var spacerLine = GUILayoutUtility.GetRect(GUIContent.none, |
|||
GUIStyle.none, |
|||
GUILayout.ExpandWidth(true), |
|||
GUILayout.Height(1)); |
|||
var oldBgColor = GUI.backgroundColor; |
|||
if (EditorGUIUtility.isProSkin) |
|||
GUI.backgroundColor = oldBgColor * 0.7058f; |
|||
else |
|||
GUI.backgroundColor = Color.black; |
|||
|
|||
if (Event.current.type == EventType.Repaint) |
|||
EditorGUIUtility.whiteTextureStyle.Draw(spacerLine, GUIContent.none, false, false, false, false); |
|||
|
|||
GUI.backgroundColor = oldBgColor; |
|||
} |
|||
|
|||
public void RenderOptions (Rect rect, MaterialGraph graph) |
|||
{ |
|||
GUILayout.BeginArea (rect); |
|||
|
|||
m_SelectedGUI = (SelectedOptions)EditorGUILayout.EnumPopup ("Options?", m_SelectedGUI); |
|||
|
|||
DrawSpacer (); |
|||
|
|||
if (m_SelectedGUI == SelectedOptions.properties) |
|||
graph.materialProperties.DoGUI(GetGraph().nodes); |
|||
else if (m_SelectedGUI == SelectedOptions.options) |
|||
graph.materialOptions.DoGUI (); |
|||
|
|||
GUILayout.FlexibleSpace (); |
|||
if (GUILayout.Button ("Output Shader :)")) |
|||
{ |
|||
var templateLocation = Path.Combine( Application.dataPath, |
|||
Path.Combine ("MaterialGraph", |
|||
"Shader.template")); |
|||
|
|||
if (File.Exists(templateLocation)) |
|||
ShaderGenerator.GenerateSurfaceShader (graph); |
|||
} |
|||
GUILayout.EndArea (); |
|||
} |
|||
} |
|||
} |
|
|||
fileFormatVersion: 2 |
|||
guid: b8ed425deb1eed44fb9b594561203b1a |
|||
MonoImporter: |
|||
serializedVersion: 2 |
|||
defaultReferences: [] |
|||
executionOrder: 0 |
|||
icon: {instanceID: 0} |
|||
userData: |
|
|||
using System; |
|||
using System.Linq; |
|||
using System.Collections.Generic; |
|||
using UnityEngine; |
|||
|
|||
namespace UnityEditor.Graphs.Material |
|||
{ |
|||
public class MaterialSubGraph : BaseMaterialGraph, IGeneratesVertexToFragmentBlock, IGeneratesFunction, IGeneratesVertexShaderBlock, IGenerateProperties |
|||
{ |
|||
[SerializeField] |
|||
private SubGraphInputsNode m_InputsNode; |
|||
|
|||
public SubGraphNode processingOwner { get; set; } |
|||
|
|||
[SerializeField] |
|||
private SubGraphOutputsNode m_OutputsNode; |
|||
|
|||
public SubGraphInputsNode inputsNode { get { return m_InputsNode; } } |
|||
|
|||
public SubGraphOutputsNode outputsNode { get { return m_OutputsNode; } } |
|||
|
|||
public override BaseMaterialNode masterNode { get { return outputsNode; } } |
|||
|
|||
|
|||
public new void OnEnable() |
|||
{ |
|||
base.OnEnable (); |
|||
if (m_InputsNode == null) |
|||
{ |
|||
m_InputsNode = CreateInstance<SubGraphInputsNode> (); |
|||
m_InputsNode.hideFlags = HideFlags.HideInHierarchy; |
|||
m_InputsNode.Init (); |
|||
AddMasterNodeNoAddToAsset (m_InputsNode); |
|||
} |
|||
|
|||
if (m_OutputsNode == null) |
|||
{ |
|||
m_OutputsNode = CreateInstance<SubGraphOutputsNode> (); |
|||
m_OutputsNode.hideFlags = HideFlags.HideInHierarchy; |
|||
m_OutputsNode.Init (); |
|||
AddMasterNodeNoAddToAsset (m_OutputsNode); |
|||
} |
|||
} |
|||
|
|||
public void CreateSubAssets() |
|||
{ |
|||
AssetDatabase.AddObjectToAsset(m_InputsNode, this); |
|||
AssetDatabase.AddObjectToAsset(m_OutputsNode, this); |
|||
} |
|||
|
|||
// Return if the given input slot is wired all the way to an output slot
|
|||
// and if that output slot is connected on the SubGraphNode
|
|||
public bool InputInternallyWired(string slotName, SubGraphNode subGraphNode) |
|||
{ |
|||
var outputSlot = inputsNode.slots.FirstOrDefault (x => x.name == slotName); |
|||
|
|||
if (outputSlot == null || outputSlot.edges.Count == 0) |
|||
return false; |
|||
|
|||
var usedInputSlots = new List<Slot> (); |
|||
foreach (var edge in outputSlot.edges) |
|||
{ |
|||
if (edge.toSlot.node == outputsNode) |
|||
usedInputSlots.Add (edge.toSlot); |
|||
|
|||
FindValidInputsToNodeFromNode (outputsNode, edge.toSlot.node, usedInputSlots); |
|||
} |
|||
|
|||
//var inputWiredToSlots = new List<Slot> ();
|
|||
foreach (var foundUsedInputSlot in usedInputSlots) |
|||
{ |
|||
Slot slot = foundUsedInputSlot; |
|||
var onExternalNodeSlot = subGraphNode.outputSlots.FirstOrDefault (x => x.name == slot.name); |
|||
|
|||
if (onExternalNodeSlot != null && onExternalNodeSlot.edges.Count > 0) |
|||
return true; |
|||
//inputWiredToSlots.Add (onExternalNodeSlot);
|
|||
} |
|||
return false; |
|||
|
|||
//return inputWiredToSlots;
|
|||
} |
|||
|
|||
private static void FindValidInputsToNodeFromNode(Node toNode, Node currentNode, ICollection<Slot> foundUsedInputSlots) |
|||
{ |
|||
if (currentNode == null || toNode == null) |
|||
{ |
|||
Debug.LogError ("Recursing to find valid inputs on NULL node"); |
|||
return; |
|||
} |
|||
|
|||
foreach (var outputSlot in currentNode.outputSlots) |
|||
{ |
|||
foreach (var edge in outputSlot.edges) |
|||
{ |
|||
if (edge.toSlot.node == toNode && !foundUsedInputSlots.Contains(edge.toSlot)) |
|||
{ |
|||
var validInputSlotsAtTarget = (edge.toSlot.node as BaseMaterialNode).GetValidInputSlots (); |
|||
if (validInputSlotsAtTarget.Contains (edge.toSlot)) |
|||
foundUsedInputSlots.Add (edge.toSlot); |
|||
} |
|||
else |
|||
FindValidInputsToNodeFromNode(toNode, edge.toSlot.node, foundUsedInputSlots); |
|||
} |
|||
} |
|||
} |
|||
|
|||
public string GetInputVariableNameForSlotByName(string slotName, BaseMaterialNode usageNode, GenerationMode generationMode) |
|||
{ |
|||
var outputSlot = inputsNode.slots.FirstOrDefault (x => x.name == slotName); |
|||
if (outputSlot == null) |
|||
return "Could Not Find Slot"; |
|||
return inputsNode.GetOutputVariableNameForSlot(outputSlot, generationMode); |
|||
} |
|||
|
|||
public bool OutputInternallyWired (string slotName) |
|||
{ |
|||
var inputSlot = outputsNode.slots.FirstOrDefault(x => x.name == slotName); |
|||
|
|||
if (inputSlot == null) |
|||
return false; |
|||
|
|||
return inputSlot.edges.Count > 0; |
|||
} |
|||
|
|||
public string GetOutputVariableNameForSlotByName(string slotName, BaseMaterialNode usageNode, GenerationMode generationMode) |
|||
{ |
|||
var inputSlot = outputsNode.slots.FirstOrDefault (x => x.name == slotName); |
|||
if (inputSlot == null || inputSlot.edges.Count == 0) |
|||
return "Slot Error"; |
|||
|
|||
var bmn = inputSlot.edges[0].fromSlot.node as BaseMaterialNode; |
|||
return bmn == null ? "Slot Error" : bmn.GetOutputVariableNameForSlot (inputSlot.edges[0].fromSlot, generationMode); |
|||
} |
|||
|
|||
|
|||
private IEnumerable<BaseMaterialNode> GetCollectedNodes() |
|||
{ |
|||
return outputsNode.CollectChildNodesByExecutionOrder (); |
|||
} |
|||
|
|||
public void GenerateNodeCode (ShaderGenerator visitor, SubGraphNode generatingFor) |
|||
{ |
|||
// First find which outputs are connected externally
|
|||
var externallyConnected = new List<Slot> (); |
|||
foreach (var slot in outputsNode.inputSlots) |
|||
{ |
|||
var externalSlot = generatingFor.outputSlots.FirstOrDefault (x => x.name == slot.name); |
|||
if (externalSlot == null) |
|||
continue; |
|||
|
|||
if (externalSlot.edges.Count > 0) |
|||
externallyConnected.Add (slot); |
|||
} |
|||
|
|||
// then collect the valid nodes
|
|||
var collectedNodes = new List<BaseMaterialNode>(); |
|||
foreach (var s in externallyConnected) |
|||
outputsNode.CollectChildNodesByExecutionOrder (collectedNodes, s, false); |
|||
|
|||
// then generate code for the connected nodes
|
|||
foreach (var n in collectedNodes.OfType<IGeneratesBodyCode>()) |
|||
n.GenerateNodeCode(visitor, GenerationMode.SurfaceShader); |
|||
} |
|||
|
|||
public void GenerateVertexToFragmentBlock (ShaderGenerator visitor, GenerationMode generationMode) |
|||
{ |
|||
foreach (var n in GetCollectedNodes ().OfType<IGeneratesVertexToFragmentBlock> ()) |
|||
n.GenerateVertexToFragmentBlock(visitor, generationMode); |
|||
} |
|||
|
|||
public void GenerateNodeFunction (ShaderGenerator visitor, GenerationMode generationMode) |
|||
{ |
|||
foreach (var n in GetCollectedNodes ().OfType<IGeneratesFunction> ()) |
|||
n.GenerateNodeFunction(visitor, generationMode); |
|||
} |
|||
|
|||
public void GenerateVertexShaderBlock(ShaderGenerator visitor, GenerationMode generationMode) |
|||
{ |
|||
foreach (var n in GetCollectedNodes ().OfType<IGeneratesVertexShaderBlock> ()) |
|||
n.GenerateVertexShaderBlock (visitor, generationMode); |
|||
} |
|||
|
|||
public void GeneratePropertyBlock(PropertyGenerator visitor, GenerationMode generationMode) |
|||
{ |
|||
foreach (var n in GetCollectedNodes().OfType<IGenerateProperties>()) |
|||
n.GeneratePropertyBlock (visitor, generationMode); |
|||
} |
|||
|
|||
public void GeneratePropertyUsages(ShaderGenerator visitor, GenerationMode generationMode) |
|||
{ |
|||
foreach (var n in GetCollectedNodes ().OfType<IGenerateProperties> ()) |
|||
n.GeneratePropertyUsages (visitor, generationMode); |
|||
} |
|||
|
|||
// Returns a list of preview properties that need to be set
|
|||
public IEnumerable<PreviewProperty> GetPreviewProperties () |
|||
{ |
|||
var properties = new List<PreviewProperty> (); |
|||
foreach (var tnode in nodes.Where (x => x is TextureNode).Cast<TextureNode> ()) |
|||
{ |
|||
properties.Add (tnode.GetPreviewProperty ()); |
|||
} |
|||
|
|||
foreach (var subNode in nodes.Where (x=>x is SubGraphNode).Cast<SubGraphNode> ()) |
|||
{ |
|||
if (subNode.subGraphAsset != null) |
|||
properties.AddRange (subNode.subGraphAsset.GetPreviewProperties ()); |
|||
} |
|||
return properties.Distinct(); |
|||
} |
|||
} |
|||
} |
|
|||
fileFormatVersion: 2 |
|||
guid: 4b00854e54a3ed940813fa47dec62d38 |
|||
MonoImporter: |
|||
serializedVersion: 2 |
|||
defaultReferences: [] |
|||
executionOrder: 0 |
|||
icon: {instanceID: 0} |
|||
userData: |
|
|||
using System; |
|||
using System.Collections.Generic; |
|||
using System.IO; |
|||
using UnityEngine; |
|||
using System.Reflection; |
|||
|
|||
namespace UnityEditor.Graphs.Material |
|||
{ |
|||
class MaterialSubGraphGUI : BaseMaterialGraphGUI |
|||
{ |
|||
public override void NodeGUI(Node n) |
|||
{ |
|||
// Handle node selection
|
|||
SelectNode(n); |
|||
// Make node minimize, etc. buttons
|
|||
// Make default input slots
|
|||
foreach (Slot s in n.inputSlots) |
|||
LayoutSlot(s, s.title, false, true, false, Styles.varPinIn); |
|||
// Make custom node UI
|
|||
n.NodeUI(this); |
|||
// Make default output slots
|
|||
foreach (Slot s in n.outputSlots) |
|||
LayoutSlot(s, s.title, true, false, true, Styles.varPinOut); |
|||
|
|||
var subnode = n as SubGraphIOBaseNode; |
|||
if (subnode != null) |
|||
subnode.FooterUI (this); |
|||
|
|||
DragNodes(); |
|||
|
|||
} |
|||
|
|||
} |
|||
} |
|
|||
fileFormatVersion: 2 |
|||
guid: 996990fe8c018a74aa83cd7a1f90141e |
|||
MonoImporter: |
|||
serializedVersion: 2 |
|||
defaultReferences: [] |
|||
executionOrder: 0 |
|||
icon: {instanceID: 0} |
|||
userData: |
|
|||
#define DEBUG_MAT_GEN
|
|||
|
|||
using UnityEngine; |
|||
using System.IO; |
|||
|
|||
namespace UnityEditor.Graphs.Material |
|||
{ |
|||
class MaterialWindow : EditorWindow |
|||
{ |
|||
[MenuItem("Window/Material")] |
|||
public static void OpenMenu () |
|||
{ |
|||
GetWindow<MaterialWindow>(); |
|||
} |
|||
|
|||
[MenuItem("Assets/Create/Shader Graph", false, 208)] |
|||
public static void CreateMaterialGraph() |
|||
{ |
|||
ProjectWindowUtil.StartNameEditingIfProjectWindowExists(0, DoCreateShaderGraphAsset, "New Shader Graph.ShaderGraph", null, null); |
|||
} |
|||
|
|||
[MenuItem("Assets/Create/Shader Sub-Graph", false, 209)] |
|||
public static void CreateMaterialSubGraph() |
|||
{ |
|||
ProjectWindowUtil.StartNameEditingIfProjectWindowExists(0, DoCreateShaderSubGraphAsset, "New Shader SubGraph.ShaderSubGraph", null, null); |
|||
} |
|||
|
|||
private static void DoCreateShaderGraphAsset (int instanceId, string pathName, string resourceFile) |
|||
{ |
|||
var graph = CreateInstance<MaterialGraph>(); |
|||
graph.name = Path.GetFileName (pathName); |
|||
AssetDatabase.CreateAsset (graph, pathName); |
|||
graph.CreateSubAssets (); |
|||
} |
|||
|
|||
private static void DoCreateShaderSubGraphAsset(int instanceId, string pathName, string resourceFile) |
|||
{ |
|||
var graph = CreateInstance<MaterialSubGraph>(); |
|||
graph.name = Path.GetFileName(pathName); |
|||
AssetDatabase.CreateAsset(graph, pathName); |
|||
graph.CreateSubAssets(); |
|||
} |
|||
|
|||
private MaterialGraph m_MaterialGraph; |
|||
private MaterialGraphGUI m_MaterialGraphGUI; |
|||
private MaterialSubGraph m_MaterialSubGraph; |
|||
private MaterialSubGraphGUI m_MaterialSubGraphGUI; |
|||
|
|||
private BaseMaterialGraphGUI m_ActiveGUI; |
|||
private ScriptableObject m_ActiveGraph; |
|||
|
|||
private bool shouldRepaint |
|||
{ |
|||
get |
|||
{ |
|||
return m_MaterialGraph != null && m_MaterialGraph.currentGraph != null && m_MaterialGraph.currentGraph.requiresRepaint |
|||
|| m_MaterialSubGraph != null && m_MaterialSubGraph.requiresRepaint; |
|||
} |
|||
} |
|||
|
|||
void Update () |
|||
{ |
|||
if (shouldRepaint) |
|||
Repaint(); |
|||
} |
|||
|
|||
void OnSelectionChange() |
|||
{ |
|||
MaterialWindow.DebugMaterialGraph ( "Got OnSelection Change: " + Selection.activeObject); |
|||
|
|||
if (Selection.activeObject == null || !EditorUtility.IsPersistent(Selection.activeObject)) |
|||
return; |
|||
|
|||
if (Selection.activeObject is MaterialSubGraph) |
|||
{ |
|||
var selection = Selection.activeObject as MaterialSubGraph; |
|||
if (selection != m_MaterialSubGraph) |
|||
{ |
|||
m_MaterialSubGraph = selection; |
|||
m_MaterialSubGraphGUI = null; |
|||
m_MaterialGraph = null; |
|||
m_MaterialSubGraph.GeneratePreviewShaders (); |
|||
} |
|||
|
|||
if (m_MaterialSubGraphGUI == null) |
|||
{ |
|||
m_MaterialSubGraphGUI = CreateInstance<MaterialSubGraphGUI>(); |
|||
m_MaterialSubGraphGUI.hideFlags = HideFlags.HideAndDontSave; |
|||
m_MaterialSubGraphGUI.graph = m_MaterialSubGraph; |
|||
} |
|||
|
|||
m_ActiveGUI = m_MaterialSubGraphGUI; |
|||
m_ActiveGraph = m_MaterialSubGraph; |
|||
} |
|||
else if(Selection.activeObject is MaterialGraph) |
|||
{ |
|||
var selection = Selection.activeObject as MaterialGraph; |
|||
MaterialWindow.DebugMaterialGraph ("Selection: " + selection); |
|||
MaterialWindow.DebugMaterialGraph("Existing: " + m_MaterialGraph); |
|||
if (selection != m_MaterialGraph) |
|||
{ |
|||
m_MaterialGraph = selection; |
|||
m_MaterialSubGraph = null; |
|||
m_MaterialGraphGUI = null; |
|||
m_MaterialGraph.currentGraph.GeneratePreviewShaders(); |
|||
|
|||
} |
|||
|
|||
if (m_MaterialGraphGUI == null) |
|||
{ |
|||
m_MaterialGraphGUI = CreateInstance<MaterialGraphGUI>(); |
|||
m_MaterialGraphGUI.hideFlags = HideFlags.HideAndDontSave; |
|||
m_MaterialGraphGUI.graph = m_MaterialGraph.currentGraph; |
|||
m_MaterialGraphGUI.materialGraph = m_MaterialGraph; |
|||
} |
|||
|
|||
m_ActiveGUI = m_MaterialGraphGUI; |
|||
m_ActiveGraph = m_MaterialGraph; |
|||
} |
|||
|
|||
Repaint(); |
|||
} |
|||
|
|||
void OnGUI () |
|||
{ |
|||
if (m_ActiveGraph == null || m_ActiveGUI == null) |
|||
{ |
|||
GUILayout.Label("No Graph selected"); |
|||
return; |
|||
} |
|||
|
|||
if(m_ActiveGUI == m_MaterialGraphGUI) |
|||
{ |
|||
m_MaterialGraphGUI.graph = m_MaterialGraph.currentGraph; |
|||
m_MaterialGraphGUI.materialGraph = m_MaterialGraph; |
|||
} |
|||
else if(m_ActiveGUI == m_MaterialSubGraphGUI) |
|||
{ |
|||
m_MaterialSubGraphGUI.graph = m_MaterialSubGraph; |
|||
} |
|||
|
|||
m_ActiveGUI.BeginGraphGUI(this, new Rect(0, 0, position.width - 300, position.height)); |
|||
m_ActiveGUI.OnGraphGUI(); |
|||
m_ActiveGUI.EndGraphGUI(); |
|||
if (m_ActiveGUI == m_MaterialGraphGUI) |
|||
m_MaterialGraphGUI.RenderOptions(new Rect(position.width - 300, 0, 300, position.height), m_MaterialGraph); |
|||
} |
|||
|
|||
public static void DebugMaterialGraph(string s) |
|||
{ |
|||
#if DEBUG_MAT_GEN
|
|||
Debug.Log (s); |
|||
#endif
|
|||
} |
|||
} |
|||
} |
|
|||
fileFormatVersion: 2 |
|||
guid: efbdf650af539bf4f872f46d9af5d72e |
|||
MonoImporter: |
|||
serializedVersion: 2 |
|||
defaultReferences: [] |
|||
executionOrder: 0 |
|||
icon: {instanceID: 0} |
|||
userData: |
|
|||
fileFormatVersion: 2 |
|||
guid: 1722e198c31ecfd479a7a9841c53c1cc |
|||
folderAsset: yes |
|||
DefaultImporter: |
|||
userData: |
|
|||
namespace UnityEditor.Graphs.Material |
|||
{ |
|||
[Title("Math/Absolute Node")] |
|||
class AbsoluteNode : Function1Input, IGeneratesFunction |
|||
{ |
|||
public override void Init() |
|||
{ |
|||
name = "AbsoluteNode"; |
|||
base.Init(); |
|||
} |
|||
|
|||
protected override string GetFunctionName () {return "unity_absolute_"+precision;} |
|||
|
|||
public void GenerateNodeFunction(ShaderGenerator visitor, GenerationMode generationMode) |
|||
{ |
|||
var outputString = new ShaderGenerator (); |
|||
foreach (var precision in m_PrecisionNames) |
|||
{ |
|||
outputString.AddShaderChunk("inline " + precision + "4 unity_absolute_" + precision + " (" + precision + "4 arg1)", false); |
|||
outputString.AddShaderChunk("{", false); |
|||
outputString.Indent(); |
|||
outputString.AddShaderChunk("return abs(arg1);", false); |
|||
outputString.Deindent(); |
|||
outputString.AddShaderChunk("}", false); |
|||
} |
|||
|
|||
visitor.AddShaderChunk (outputString.GetShaderString (0), true); |
|||
} |
|||
} |
|||
} |
|
|||
fileFormatVersion: 2 |
|||
guid: 4b496ffd32c22d94bb525897d152da05 |
|||
MonoImporter: |
|||
serializedVersion: 2 |
|||
defaultReferences: [] |
|||
executionOrder: 0 |
|||
icon: {instanceID: 0} |
|||
userData: |
|
|||
using UnityEngine; |
|||
|
|||
namespace UnityEditor.Graphs.Material |
|||
{ |
|||
[Title("Math/Add Node")] |
|||
class AddNode : FunctionMultiInput, IGeneratesFunction |
|||
{ |
|||
[SerializeField] |
|||
private float m_DefaultValue = 0.0f; |
|||
|
|||
public override void Init() |
|||
{ |
|||
name = "AddNode"; |
|||
base.Init(); |
|||
} |
|||
|
|||
protected override string GetFunctionName () {return "unity_add_"+precision;} |
|||
|
|||
public void GenerateNodeFunction(ShaderGenerator visitor, GenerationMode generationMode) |
|||
{ |
|||
var outputString = new ShaderGenerator (); |
|||
foreach (var precision in m_PrecisionNames) |
|||
{ |
|||
outputString.AddShaderChunk("inline " + precision + "4 unity_add_" + precision + " (" + precision + "4 arg1, " + precision + "4 arg2)", false); |
|||
outputString.AddShaderChunk("{", false); |
|||
outputString.Indent(); |
|||
outputString.AddShaderChunk("return arg1 + arg2;", false); |
|||
outputString.Deindent(); |
|||
outputString.AddShaderChunk("}", false); |
|||
} |
|||
|
|||
visitor.AddShaderChunk (outputString.GetShaderString (0), true); |
|||
} |
|||
|
|||
public override Vector4 GetNewSlotDefaultValue () |
|||
{ |
|||
return Vector4.zero; |
|||
} |
|||
|
|||
public override void NodeUI (Graphs.GraphGUI host) |
|||
{ |
|||
base.NodeUI(host); |
|||
|
|||
EditorGUI.BeginChangeCheck (); |
|||
m_DefaultValue = EditorGUILayout.FloatField("", m_DefaultValue, GUILayout.Width(64)); |
|||
if (EditorGUI.EndChangeCheck ()) |
|||
RegeneratePreviewShaders (); |
|||
} |
|||
} |
|||
} |
|
|||
fileFormatVersion: 2 |
|||
guid: 357a15b35b0cd9e47a66e10c5b627fcd |
|||
MonoImporter: |
|||
serializedVersion: 2 |
|||
defaultReferences: [] |
|||
executionOrder: 0 |
|||
icon: {instanceID: 0} |
|||
userData: |
|
|||
using System; |
|||
using System.Collections.Generic; |
|||
using System.IO; |
|||
using System.Linq; |
|||
using UnityEditorInternal; |
|||
using UnityEngine; |
|||
|
|||
namespace UnityEditor.Graphs.Material |
|||
{ |
|||
[AttributeUsage(AttributeTargets.Field | AttributeTargets.Property | AttributeTargets.Method | AttributeTargets.Class | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue)] |
|||
public class TitleAttribute : Attribute |
|||
{ |
|||
public string m_Title; |
|||
public TitleAttribute(string title) { this.m_Title = title; } |
|||
} |
|||
|
|||
public enum Precision |
|||
{ |
|||
Default = 0, // half
|
|||
Full = 1, |
|||
Fixed = 2, |
|||
} |
|||
|
|||
public class PreviewProperty |
|||
{ |
|||
public string m_Name; |
|||
public PropertyType m_PropType; |
|||
|
|||
public Color m_Color; |
|||
public Texture2D m_Texture; |
|||
public Vector4 m_Vector4; |
|||
} |
|||
|
|||
public enum PreviewMode |
|||
{ |
|||
Preview2D, |
|||
Preview3D |
|||
} |
|||
|
|||
public abstract class BaseMaterialNode : Node, IGenerateProperties |
|||
{ |
|||
|
|||
#region Fields
|
|||
private const int kPreviewWidth = 64; |
|||
private const int kPreviewHeight = 64; |
|||
|
|||
private UnityEngine.Material m_Material; |
|||
|
|||
[SerializeField] |
|||
private List<SlotDefaultValue> m_SlotDefaultValues; |
|||
#endregion
|
|||
|
|||
#region Properties
|
|||
internal PixelGraph pixelGraph { get { return graph as PixelGraph; } } |
|||
public bool generated { get; set; } |
|||
|
|||
// Nodes that want to have a preview area can override this and return true
|
|||
public virtual bool hasPreview { get { return false; } } |
|||
public virtual PreviewMode previewMode { get { return PreviewMode.Preview2D; } } |
|||
|
|||
public bool isSelected { get; set; } |
|||
|
|||
// lookup custom slot properties
|
|||
public void SetSlotDefaultValue (string slotName, SlotDefaultValue defaultValue) |
|||
{ |
|||
var existingValue = m_SlotDefaultValues.FirstOrDefault (x => x.slotName == slotName); |
|||
|
|||
if (existingValue != null) |
|||
m_SlotDefaultValues.Remove (existingValue); |
|||
|
|||
if (defaultValue == null) |
|||
return; |
|||
|
|||
m_SlotDefaultValues.Add (defaultValue); |
|||
} |
|||
|
|||
public string precision |
|||
{ |
|||
get { return "half"; } |
|||
} |
|||
|
|||
public string[] m_PrecisionNames = {"half"}; |
|||
|
|||
public SlotDefaultValue GetSlotDefaultValue (string slotName) |
|||
{ |
|||
return m_SlotDefaultValues.FirstOrDefault (x => x.slotName == slotName); |
|||
} |
|||
|
|||
private UnityEngine.Material previewMaterial |
|||
{ |
|||
get |
|||
{ |
|||
if (m_Material == null) |
|||
m_Material = new UnityEngine.Material(Shader.Find("Diffuse")) { hideFlags = HideFlags.DontSave }; |
|||
|
|||
return m_Material; |
|||
} |
|||
} |
|||
private PreviewMode m_GeneratedShaderMode = PreviewMode.Preview2D; |
|||
|
|||
private bool needsUpdate |
|||
{ |
|||
get { return true; } |
|||
} |
|||
#endregion
|
|||
|
|||
public virtual void Init () |
|||
{ |
|||
hideFlags = HideFlags.HideInHierarchy; |
|||
} |
|||
|
|||
void OnEnable () |
|||
{ |
|||
if (m_SlotDefaultValues == null) { |
|||
m_SlotDefaultValues = new List<SlotDefaultValue>(); |
|||
} |
|||
} |
|||
|
|||
public override void NodeUI (GraphGUI host) |
|||
{ |
|||
base.NodeUI(host); |
|||
if (hasPreview) |
|||
OnPreviewGUI(); |
|||
} |
|||
|
|||
protected virtual void OnPreviewGUI () |
|||
{ |
|||
if (!ShaderUtil.hardwareSupportsRectRenderTexture) |
|||
return; |
|||
|
|||
GUILayout.BeginHorizontal(GUILayout.MinWidth (kPreviewWidth + 10), GUILayout.MinWidth (kPreviewHeight + 10)); |
|||
GUILayout.FlexibleSpace(); |
|||
var rect = GUILayoutUtility.GetRect(kPreviewWidth, kPreviewHeight, GUILayout.ExpandWidth(false)); |
|||
var preview = RenderPreview (rect); |
|||
GUILayout.FlexibleSpace(); |
|||
GUILayout.EndHorizontal(); |
|||
GUI.DrawTexture (rect, preview, ScaleMode.StretchToFill, false); |
|||
} |
|||
|
|||
#region Nodes
|
|||
// CollectDependentNodes looks at the current node and calculates
|
|||
// which nodes further up the tree (parents) would be effected if this node was changed
|
|||
// it also includes itself in this list
|
|||
public IEnumerable<BaseMaterialNode> CollectDependentNodes() |
|||
{ |
|||
var nodeList = new List<BaseMaterialNode>(); |
|||
NodeUtils.CollectDependentNodes(nodeList, this); |
|||
return nodeList; |
|||
} |
|||
|
|||
// CollectDependentNodes looks at the current node and calculates
|
|||
// which child nodes it depends on for it's calculation.
|
|||
// Results are returned depth first so by processing each node in
|
|||
// order you can generate a valid code block.
|
|||
public IEnumerable<BaseMaterialNode> CollectChildNodesByExecutionOrder(Slot slotToUse = null, bool includeSelf = true) |
|||
{ |
|||
var nodeList = new List<BaseMaterialNode>(); |
|||
CollectChildNodesByExecutionOrder (nodeList, slotToUse, includeSelf); |
|||
return nodeList; |
|||
} |
|||
|
|||
public IEnumerable<BaseMaterialNode> CollectChildNodesByExecutionOrder (List<BaseMaterialNode> nodeList, Slot slotToUse = null, bool includeSelf = true) |
|||
{ |
|||
if (slotToUse != null && !slots.Contains(slotToUse)) |
|||
{ |
|||
Debug.LogError("Attempting to collect nodes by execution order with an invalid slot on: " + name); |
|||
return nodeList; |
|||
} |
|||
|
|||
NodeUtils.CollectChildNodesByExecutionOrder (nodeList, this, slotToUse); |
|||
|
|||
if (!includeSelf) |
|||
nodeList.Remove (this); |
|||
|
|||
return nodeList; |
|||
} |
|||
|
|||
#endregion
|
|||
|
|||
#region Previews
|
|||
|
|||
protected virtual void SetEditorPreviewMaterialValues () |
|||
{ |
|||
if (!needsUpdate) |
|||
return; |
|||
|
|||
if (previewMaterial.HasProperty ("EDITOR_TIME")) |
|||
{ |
|||
var time = (float)EditorApplication.timeSinceStartup; |
|||
previewMaterial.SetVector("EDITOR_TIME", new Vector4(time / 20.0f, time, time * 2.0f, time*3)); |
|||
} |
|||
if (previewMaterial.HasProperty("EDITOR_SIN_TIME")) |
|||
{ |
|||
var time = (float)EditorApplication.timeSinceStartup; |
|||
previewMaterial.SetVector("EDITOR_SIN_TIME", |
|||
new Vector4( |
|||
Mathf.Sin(time / 8.0f), |
|||
Mathf.Sin(time / 4.0f), |
|||
Mathf.Sin(time / 2.0f), |
|||
Mathf.Sin(time))); |
|||
} |
|||
} |
|||
|
|||
public virtual bool UpdatePreviewMaterial () |
|||
{ |
|||
MaterialWindow.DebugMaterialGraph("RecreateShaderAndMaterial : " + name + "_" + GetInstanceID()); |
|||
|
|||
|
|||
var resultShader = ShaderGenerator.GeneratePreviewShader (this, out m_GeneratedShaderMode); |
|||
|
|||
MaterialWindow.DebugMaterialGraph (resultShader); |
|||
|
|||
if (previewMaterial.shader.name != "Diffuse") |
|||
DestroyImmediate(previewMaterial.shader, true); |
|||
previewMaterial.shader = UnityEditorInternal.InternalEditorUtility.CreateShaderAsset (resultShader); |
|||
previewMaterial.shader.hideFlags = HideFlags.DontSave; |
|||
return true; |
|||
} |
|||
|
|||
// this function looks at all the nodes that have a
|
|||
// dependency on this node. They will then have their
|
|||
// preview regenerated.
|
|||
public void RegeneratePreviewShaders() |
|||
{ |
|||
CollectDependentNodes() |
|||
.Where(x => x.hasPreview) |
|||
.All(s => s.UpdatePreviewMaterial ()); |
|||
} |
|||
|
|||
private static Mesh[] s_Meshes = { null, null, null, null }; |
|||
|
|||
|
|||
/// <summary>
|
|||
/// RenderPreview gets called in OnPreviewGUI. Nodes can override
|
|||
/// RenderPreview and do their own rendering to the render texture
|
|||
/// </summary>
|
|||
public Texture RenderPreview (Rect targetSize) |
|||
{ |
|||
if (s_Meshes[0] == null) |
|||
{ |
|||
GameObject handleGo = (GameObject)EditorGUIUtility.LoadRequired ("Previews/PreviewMaterials.fbx"); |
|||
// @TODO: temp workaround to make it not render in the scene
|
|||
handleGo.SetActive (false); |
|||
foreach (Transform t in handleGo.transform) |
|||
{ |
|||
switch (t.name) |
|||
{ |
|||
case "sphere": |
|||
s_Meshes[0] = ((MeshFilter)t.GetComponent ("MeshFilter")).sharedMesh; |
|||
break; |
|||
case "cube": |
|||
s_Meshes[1] = ((MeshFilter)t.GetComponent ("MeshFilter")).sharedMesh; |
|||
break; |
|||
case "cylinder": |
|||
s_Meshes[2] = ((MeshFilter)t.GetComponent ("MeshFilter")).sharedMesh; |
|||
break; |
|||
case "torus": |
|||
s_Meshes[3] = ((MeshFilter)t.GetComponent ("MeshFilter")).sharedMesh; |
|||
break; |
|||
default: |
|||
Debug.Log ("Something is wrong, weird object found: " + t.name); |
|||
break; |
|||
} |
|||
} |
|||
} |
|||
|
|||
var bmg = (graph as BaseMaterialGraph); |
|||
if (bmg == null) |
|||
return null; |
|||
|
|||
var previewUtil = bmg.previewUtility; |
|||
previewUtil.BeginPreview (targetSize, GUIStyle.none); |
|||
|
|||
// update the time in the preview material
|
|||
SetEditorPreviewMaterialValues (); |
|||
|
|||
if (m_GeneratedShaderMode == PreviewMode.Preview3D) |
|||
{ |
|||
previewUtil.m_Camera.transform.position = -Vector3.forward * 5; |
|||
previewUtil.m_Camera.transform.rotation = Quaternion.identity; |
|||
var amb = new Color(.2f, .2f, .2f, 0); |
|||
previewUtil.m_Light[0].intensity = .5f; |
|||
previewUtil.m_Light[0].transform.rotation = Quaternion.Euler(50f, 50f, 0); |
|||
previewUtil.m_Light[1].intensity = .5f; |
|||
|
|||
InternalEditorUtility.SetCustomLighting(previewUtil.m_Light, amb); |
|||
previewUtil.DrawMesh(s_Meshes[0], Vector3.zero, Quaternion.Euler(-20, 0, 0) * Quaternion.Euler(0, 0, 0), previewMaterial, 0); |
|||
bool oldFog = RenderSettings.fog; |
|||
Unsupported.SetRenderSettingsUseFogNoDirty (false); |
|||
previewUtil.m_Camera.Render(); |
|||
Unsupported.SetRenderSettingsUseFogNoDirty (oldFog); |
|||
InternalEditorUtility.RemoveCustomLighting (); |
|||
} |
|||
else |
|||
{ |
|||
Graphics.Blit(null, previewMaterial); |
|||
} |
|||
return previewUtil.EndPreview (); |
|||
} |
|||
|
|||
private void SetPreviewMaterialProperty(PreviewProperty previewProperty) |
|||
{ |
|||
switch (previewProperty.m_PropType) |
|||
{ |
|||
case PropertyType.Texture2D: |
|||
previewMaterial.SetTexture(previewProperty.m_Name, previewProperty.m_Texture); |
|||
break; |
|||
case PropertyType.Color: |
|||
previewMaterial.SetColor(previewProperty.m_Name, previewProperty.m_Color); |
|||
break; |
|||
case PropertyType.Vector4: |
|||
previewMaterial.SetVector(previewProperty.m_Name, previewProperty.m_Vector4); |
|||
break; |
|||
} |
|||
} |
|||
|
|||
protected void SetDependentPreviewMaterialProperty (PreviewProperty previewProperty) |
|||
{ |
|||
var dependentNodes = CollectDependentNodes (); |
|||
|
|||
foreach (var node in dependentNodes) |
|||
{ |
|||
if (node.hasPreview) |
|||
node.SetPreviewMaterialProperty (previewProperty); |
|||
} |
|||
} |
|||
|
|||
|
|||
public virtual void UpdatePreviewProperties() |
|||
{ |
|||
foreach (var s in inputSlots) |
|||
{ |
|||
if (s.edges.Count > 0) |
|||
continue; |
|||
|
|||
var defaultInput = GetSlotDefaultValue (s.name); |
|||
if (defaultInput == null) |
|||
continue; |
|||
|
|||
var pp = new PreviewProperty |
|||
{ |
|||
m_Name = defaultInput.inputName, |
|||
m_PropType = PropertyType.Vector4, |
|||
m_Vector4 = defaultInput.defaultValue |
|||
}; |
|||
SetDependentPreviewMaterialProperty (pp); |
|||
} |
|||
} |
|||
|
|||
#endregion
|
|||
|
|||
#region Slots
|
|||
|
|||
public virtual IEnumerable<Slot> GetValidInputSlots () |
|||
{ |
|||
return inputSlots; |
|||
} |
|||
|
|||
public virtual string GetOutputVariableNameForSlot (Slot s, GenerationMode generationMode) |
|||
{ |
|||
if (s.isInputSlot) Debug.LogError ("Attempting to use input slot (" + s + ") for output!"); |
|||
if (!slots.Contains(s)) Debug.LogError("Attempting to use slot (" + s + ") for output on a node that does not have this slot!"); |
|||
|
|||
return GetOutputVariableNameForNode () + "_" + s.name; |
|||
} |
|||
|
|||
public virtual string GetOutputVariableNameForNode () |
|||
{ |
|||
return name + "_" + Math.Abs(GetInstanceID()); |
|||
} |
|||
|
|||
public virtual Vector4 GetNewSlotDefaultValue () |
|||
{ |
|||
return Vector4.one; |
|||
} |
|||
|
|||
public new void AddSlot(Slot slot) |
|||
{ |
|||
AddSlot (slot, GetNewSlotDefaultValue ()); |
|||
} |
|||
|
|||
public void AddSlot(Slot slot, Vector4 defaultValue) |
|||
{ |
|||
base.AddSlot(slot); |
|||
|
|||
// slots are not serialzied but the default values are
|
|||
// because of this we need to see if the default has
|
|||
// already been set
|
|||
// if it has... do nothing.
|
|||
MaterialWindow.DebugMaterialGraph ("Node ID: " + GetInstanceID ()); |
|||
MaterialWindow.DebugMaterialGraph ("Node Name: " + GetOutputVariableNameForNode ()); |
|||
|
|||
if (GetSlotDefaultValue(slot.name) == null) |
|||
SetSlotDefaultValue(slot.name, new SlotDefaultValue(defaultValue, this, slot.name, true)); |
|||
|
|||
var slotthing = GetSlotDefaultValue (slot.name); |
|||
MaterialWindow.DebugMaterialGraph ("Slot Thing: " + slotthing.inputName); |
|||
} |
|||
|
|||
public override void RemoveSlot (Slot slot) |
|||
{ |
|||
SetSlotDefaultValue(slot.name, null); |
|||
base.RemoveSlot(slot); |
|||
} |
|||
|
|||
public string GenerateSlotName (SlotType type) |
|||
{ |
|||
var slotsToCheck = type == SlotType.InputSlot ? inputSlots.ToArray() : outputSlots.ToArray(); |
|||
string format = type == SlotType.InputSlot ? "I{0:00}" : "O{0:00}"; |
|||
int index = slotsToCheck.Length; |
|||
var name = string.Format (format, index); |
|||
if (slotsToCheck.All (x => x.name != name)) |
|||
return name; |
|||
index = 0; |
|||
do { |
|||
name = string.Format (format, index++); |
|||
} while (slotsToCheck.Any(x => x.name == name)); |
|||
|
|||
return name; |
|||
} |
|||
#endregion
|
|||
|
|||
public virtual void GeneratePropertyBlock(PropertyGenerator visitor, GenerationMode generationMode) |
|||
{ |
|||
if (!generationMode.IsPreview ()) |
|||
return; |
|||
|
|||
foreach (var inputSlot in inputSlots) |
|||
{ |
|||
if (inputSlot.edges.Count > 0) |
|||
continue; |
|||
|
|||
var defaultForSlot = GetSlotDefaultValue(inputSlot.name); |
|||
defaultForSlot.GeneratePropertyBlock(visitor, generationMode); |
|||
} |
|||
} |
|||
|
|||
public virtual void GeneratePropertyUsages(ShaderGenerator visitor, GenerationMode generationMode) |
|||
{ |
|||
if (!generationMode.IsPreview ()) |
|||
return; |
|||
|
|||
foreach (var inputSlot in inputSlots) |
|||
{ |
|||
if (inputSlot.edges.Count > 0) |
|||
continue; |
|||
|
|||
var defaultForSlot = GetSlotDefaultValue(inputSlot.name); |
|||
defaultForSlot.GeneratePropertyUsages(visitor, generationMode); |
|||
} |
|||
} |
|||
|
|||
public Slot FindInputSlot (string name) |
|||
{ |
|||
var slot = inputSlots.FirstOrDefault(x => x.name == name); |
|||
if (slot == null) |
|||
Debug.LogError("Input slot: " + name + " could be found on node " + GetOutputVariableNameForNode() ); |
|||
return slot; |
|||
} |
|||
|
|||
public Slot FindOutputSlot(string name) |
|||
{ |
|||
var slot = outputSlots.FirstOrDefault(x => x.name == name); |
|||
if (slot == null) |
|||
Debug.LogError("Output slot: " + name + " could be found on node " + GetOutputVariableNameForNode()); |
|||
return slot; |
|||
} |
|||
|
|||
protected string GetSlotValue (Slot inputSlot, GenerationMode generationMode) |
|||
{ |
|||
bool pointInputConnected = inputSlot.edges.Count > 0; |
|||
string inputValue; |
|||
if (pointInputConnected) |
|||
{ |
|||
var dataProvider = inputSlot.edges[0].fromSlot.node as BaseMaterialNode; |
|||
inputValue = dataProvider.GetOutputVariableNameForSlot(inputSlot.edges[0].fromSlot, generationMode); |
|||
} |
|||
else |
|||
{ |
|||
var defaultValue = GetSlotDefaultValue(inputSlot.name); |
|||
inputValue = defaultValue.GetDefaultValue(generationMode); |
|||
} |
|||
return inputValue; |
|||
} |
|||
} |
|||
} |
|
|||
fileFormatVersion: 2 |
|||
guid: a4da4d7c02dcbdd4f9ef2d3b1106879a |
|||
MonoImporter: |
|||
serializedVersion: 2 |
|||
defaultReferences: [] |
|||
executionOrder: 0 |
|||
icon: {instanceID: 0} |
|||
userData: |
|
|||
using UnityEngine; |
|||
|
|||
namespace UnityEditor.Graphs.Material |
|||
{ |
|||
[Title("Art/Blend Node")] |
|||
class BlendNode : Function2Input, IGeneratesFunction |
|||
{ |
|||
public override void Init() |
|||
{ |
|||
name = "BlendNode"; |
|||
base.Init(); |
|||
} |
|||
|
|||
public enum Operation { |
|||
Normal, |
|||
Additive, |
|||
} |
|||
|
|||
[SerializeField] |
|||
private Operation m_Operation; |
|||
[SerializeField] |
|||
private float m_Blend = 0.5f; |
|||
|
|||
private static readonly string[] kOpNames = new[] |
|||
{ |
|||
"normal", |
|||
"add" |
|||
}; |
|||
|
|||
protected override string GetFunctionName() { return "unity_blend_"+ kOpNames[(int)m_Operation] +"_"+precision; } |
|||
protected override string GetFunctionCallBody (string input1Value, string input2Value) |
|||
{ |
|||
return GetFunctionName() + "("+input1Value+", "+input2Value+", "+m_Blend+")"; |
|||
} |
|||
|
|||
protected void AddOperationBody (ShaderGenerator visitor, string name, string body, string precision) |
|||
{ |
|||
var outputString = new ShaderGenerator (); |
|||
outputString.AddShaderChunk("inline "+precision+"4 unity_blend_"+name+"_"+precision+" ("+precision+"4 arg1, "+precision+"4 arg2, "+precision+" blend)", false); |
|||
outputString.AddShaderChunk("{", false); outputString.Indent(); |
|||
outputString.AddShaderChunk(body, false); |
|||
outputString.Deindent(); outputString.AddShaderChunk("}", false); |
|||
|
|||
visitor.AddShaderChunk (outputString.GetShaderString (0), true); |
|||
} |
|||
|
|||
public override void NodeUI (Graphs.GraphGUI host) |
|||
{ |
|||
base.NodeUI(host); |
|||
|
|||
EditorGUI.BeginChangeCheck (); |
|||
m_Blend = GUILayout.HorizontalSlider(m_Blend, 0f, 1f, GUILayout.Width(64)); |
|||
m_Operation = (Operation)EditorGUILayout.EnumPopup (m_Operation); |
|||
if (EditorGUI.EndChangeCheck ()) |
|||
RegeneratePreviewShaders (); |
|||
} |
|||
|
|||
public void GenerateNodeFunction(ShaderGenerator visitor, GenerationMode generationMode) |
|||
{ |
|||
foreach (var precision in m_PrecisionNames) |
|||
{ |
|||
AddOperationBody (visitor, kOpNames[(int)Operation.Normal], "return lerp(arg1, arg2, blend);", precision); |
|||
AddOperationBody (visitor, kOpNames[(int)Operation.Additive], "return (arg1 + arg2) * blend;", precision); |
|||
} |
|||
} |
|||
} |
|||
} |
|
|||
fileFormatVersion: 2 |
|||
guid: 909ffbb62e82bfb4abbeeb93022c6e9b |
|||
MonoImporter: |
|||
serializedVersion: 2 |
|||
defaultReferences: [] |
|||
executionOrder: 0 |
|||
icon: {instanceID: 0} |
|||
userData: |
|
|||
namespace UnityEditor.Graphs.Material |
|||
{ |
|||
[Title("Math/Clamp Node")] |
|||
class ClampNode : Function3Input, IGeneratesFunction |
|||
{ |
|||
public override void Init() |
|||
{ |
|||
name = "ClampNode"; |
|||
base.Init(); |
|||
} |
|||
|
|||
protected override string GetFunctionName () {return "unity_clamp_"+precision;} |
|||
|
|||
public void GenerateNodeFunction(ShaderGenerator visitor, GenerationMode generationMode) |
|||
{ |
|||
var outputString = new ShaderGenerator (); |
|||
foreach (var precision in m_PrecisionNames) |
|||
{ |
|||
outputString.AddShaderChunk("inline " + precision + "4 unity_clamp_" + precision + " (" + precision + "4 arg1, " + precision + "4 minval, " + precision + "4 maxval)", false); |
|||
outputString.AddShaderChunk("{", false); |
|||
outputString.Indent(); |
|||
outputString.AddShaderChunk("return clamp(arg1, minval, maxval);", false); |
|||
outputString.Deindent(); |
|||
outputString.AddShaderChunk("}", false); |
|||
} |
|||
|
|||
visitor.AddShaderChunk (outputString.GetShaderString (0), true); |
|||
} |
|||
} |
|||
} |
|
|||
fileFormatVersion: 2 |
|||
guid: b58e88ce87f05b241b7dc5d9a31bac69 |
|||
MonoImporter: |
|||
serializedVersion: 2 |
|||
defaultReferences: [] |
|||
executionOrder: 0 |
|||
icon: {instanceID: 0} |
|||
userData: |
|
|||
using System; |
|||
using System.Linq; |
|||
using UnityEngine; |
|||
|
|||
namespace UnityEditor.Graphs.Material |
|||
{ |
|||
[Title("Generate/Color Node")] |
|||
class ColorNode : PropertyNode, IGeneratesBodyCode |
|||
{ |
|||
[SerializeField] |
|||
private Color m_Color; |
|||
|
|||
private const string kOutputSlotName = "Color"; |
|||
|
|||
public override void Init() |
|||
{ |
|||
base.Init (); |
|||
name = "ColorNode"; |
|||
AddSlot(new Slot(SlotType.OutputSlot, kOutputSlotName)); |
|||
} |
|||
|
|||
public override PropertyType propertyType |
|||
{ |
|||
get { return PropertyType.Color; } |
|||
} |
|||
|
|||
public override void GeneratePropertyBlock(PropertyGenerator visitor, GenerationMode generationMode) |
|||
{ |
|||
if (HasBoundProperty() || !generationMode.IsPreview ()) |
|||
return; |
|||
|
|||
visitor.AddShaderProperty (new ColorPropertyChunk (GetPropertyName (), GetPropertyName (), m_Color, true)); |
|||
} |
|||
|
|||
public override string GetOutputVariableNameForSlot(Slot s, GenerationMode generationMode) |
|||
{ |
|||
return GetPropertyName(); |
|||
} |
|||
|
|||
public override void GeneratePropertyUsages(ShaderGenerator visitor, GenerationMode generationMode) |
|||
{ |
|||
if (HasBoundProperty() || !generationMode.IsPreview ()) |
|||
return; |
|||
|
|||
visitor.AddShaderChunk("float4 " + GetPropertyName() + ";", true); |
|||
} |
|||
|
|||
public void GenerateNodeCode(ShaderGenerator visitor, GenerationMode generationMode) |
|||
{ |
|||
// we only need to generate node code if we are using a constant... otherwise we can just refer to the property :)
|
|||
if (HasBoundProperty() || generationMode.IsPreview ()) |
|||
return; |
|||
|
|||
visitor.AddShaderChunk (precision+"4 " + GetPropertyName () + " = "+precision+"4 (" + m_Color.r + ", " + m_Color.g + ", " + m_Color.b + ", " + m_Color.a + ");", true); |
|||
} |
|||
|
|||
public override void NodeUI (Graphs.GraphGUI host) |
|||
{ |
|||
base.NodeUI(host); |
|||
|
|||
EditorGUI.BeginChangeCheck (); |
|||
m_Color = EditorGUILayout.ColorField(m_Color); |
|||
if (EditorGUI.EndChangeCheck()) |
|||
{ |
|||
var boundProp = boundProperty as ColorProperty; |
|||
if (boundProp != null) |
|||
{ |
|||
boundProp.defaultColor = m_Color; |
|||
} |
|||
UpdatePreviewProperties (); |
|||
} |
|||
} |
|||
|
|||
public override void BindProperty(ShaderProperty property, bool rebuildShaders) |
|||
{ |
|||
base.BindProperty(property, rebuildShaders); |
|||
|
|||
var colorProp = property as ColorProperty; |
|||
if (colorProp) |
|||
{ |
|||
m_Color = colorProp.defaultColor; |
|||
} |
|||
|
|||
if (rebuildShaders) |
|||
RegeneratePreviewShaders(); |
|||
else |
|||
UpdatePreviewProperties(); |
|||
} |
|||
|
|||
public override PreviewProperty GetPreviewProperty () |
|||
{ |
|||
return new PreviewProperty { |
|||
m_Name = GetPropertyName (), |
|||
m_PropType = PropertyType.Color, |
|||
m_Color = m_Color |
|||
}; |
|||
} |
|||
} |
|||
} |
|
|||
fileFormatVersion: 2 |
|||
guid: 325c0e24c20746345a5f90dc201973f8 |
|||
MonoImporter: |
|||
serializedVersion: 2 |
|||
defaultReferences: [] |
|||
executionOrder: 0 |
|||
icon: {instanceID: 0} |
|||
userData: |
|
|||
using UnityEngine; |
|||
|
|||
namespace UnityEditor.Graphs.Material |
|||
{ |
|||
[Title("Art/Colorize Node")] |
|||
class ColorizeNode : Function1Input, IGeneratesFunction |
|||
{ |
|||
[SerializeField] |
|||
private Color m_Color = Color.blue; |
|||
[SerializeField] |
|||
private float m_Colorization = 0.0f; |
|||
[SerializeField] |
|||
private float m_Brightness = 1.0f; |
|||
[SerializeField] |
|||
private float m_Contrast = 1.0f; |
|||
|
|||
public override void Init() |
|||
{ |
|||
name = "ColorizeNode"; |
|||
base.Init(); |
|||
} |
|||
|
|||
protected override string GetFunctionName() {return ""; } |
|||
|
|||
protected override string GetFunctionCallBody (string inputValue) |
|||
{ |
|||
return "unity_colorize_"+precision+"("+inputValue+", "+precision+"4("+m_Color.r+", "+m_Color.g+", "+m_Color.b+", "+m_Color.a+"), "+m_Colorization+", "+m_Brightness+", "+m_Contrast+")"; |
|||
} |
|||
|
|||
public void GenerateNodeFunction(ShaderGenerator visitor, GenerationMode generationMode) |
|||
{ |
|||
var outputString = new ShaderGenerator (); |
|||
|
|||
foreach (var thePrecisision in m_PrecisionNames) |
|||
{ |
|||
outputString.AddShaderChunk ("inline " + thePrecisision + "4 unity_colorize_" + thePrecisision + " (" + thePrecisision + "4 arg1, " + thePrecisision + "4 color, " + thePrecisision + " amount, " + thePrecisision + " brightness, " + thePrecisision + " contrast)", false); |
|||
outputString.AddShaderChunk ("{", false); |
|||
outputString.Indent (); |
|||
outputString.AddShaderChunk (thePrecisision + "4 x = lerp(arg1, arg1 * color, amount);", false); |
|||
outputString.AddShaderChunk ("x *= brightness;", false); |
|||
outputString.AddShaderChunk ("x = pow(x, contrast);", false); |
|||
outputString.AddShaderChunk ("return x;", false); |
|||
outputString.Deindent (); |
|||
outputString.AddShaderChunk ("}", false); |
|||
} |
|||
|
|||
visitor.AddShaderChunk (outputString.GetShaderString (0), true); |
|||
} |
|||
|
|||
static float Slider (string title, float value, float from, float to) |
|||
{ |
|||
GUILayout.BeginHorizontal (); |
|||
GUILayout.Label (title); |
|||
value = GUILayout.HorizontalSlider(value, from, to, GUILayout.Width(64)); |
|||
GUILayout.EndHorizontal (); |
|||
return value; |
|||
} |
|||
|
|||
public override void NodeUI (Graphs.GraphGUI host) |
|||
{ |
|||
base.NodeUI(host); |
|||
|
|||
EditorGUI.BeginChangeCheck (); |
|||
m_Color = EditorGUILayout.ColorField("Tint", m_Color); |
|||
m_Colorization = Slider ("Colorization", m_Colorization, 0f, 1f); |
|||
m_Brightness = Slider ("Brightness", m_Brightness, 0f, 2f); |
|||
m_Contrast = Slider ("Contrast", m_Contrast, 0.3f, 4f); |
|||
if (EditorGUI.EndChangeCheck ()) |
|||
RegeneratePreviewShaders (); |
|||
} |
|||
} |
|||
} |
|
|||
fileFormatVersion: 2 |
|||
guid: eb2553e0542079a4b86f8abe5ad4045e |
|||
MonoImporter: |
|||
serializedVersion: 2 |
|||
defaultReferences: [] |
|||
executionOrder: 0 |
|||
icon: {instanceID: 0} |
|||
userData: |
|
|||
using UnityEngine; |
|||
|
|||
namespace UnityEditor.Graphs.Material |
|||
{ |
|||
[Title("Art/Combine Node")] |
|||
class CombineNode : Function2Input, IGeneratesFunction |
|||
{ |
|||
public override void Init() |
|||
{ |
|||
name = "CombineNode"; |
|||
base.Init(); |
|||
} |
|||
|
|||
// Based on information from:
|
|||
// http://photoblogstop.com/photoshop/photoshop-blend-modes-explained
|
|||
// http://www.venture-ware.com/kevin/coding/lets-learn-math-photoshop-blend-modes/
|
|||
// http://mouaif.wordpress.com/2009/01/05/photoshop-math-with-glsl-shaders/
|
|||
// http://dunnbypaul.net/blends/
|
|||
public enum Operation { |
|||
Darken, |
|||
Multiply, |
|||
ColorBurn, |
|||
LinearBurn, |
|||
// TODO: DarkerColor (Darken, but based on luminosity)
|
|||
Lighten, |
|||
Screen, |
|||
ColorDodge, |
|||
LinearDodge, |
|||
// TODO: LighterColor (Lighten, but based on luminosity)
|
|||
Overlay, |
|||
SoftLight, |
|||
HardLight, |
|||
VividLight, |
|||
LinearLight, |
|||
PinLight, |
|||
HardMix, |
|||
Difference, |
|||
Exclusion, |
|||
Subtract, |
|||
Divide, |
|||
} |
|||
|
|||
[SerializeField] |
|||
private Operation m_Operation; |
|||
|
|||
private static readonly string[] kOpNames = new string [] { |
|||
"darken", "mul", "cburn", "lburn", |
|||
"lighten", "screen", "cdodge", "ldodge", |
|||
"overlay", "softl", "hardl", "vividl", "linearl", "pinl", "hardmix", |
|||
"diff", "excl", "sub", "div" }; |
|||
|
|||
protected override string GetFunctionName() { return "unity_combine_"+ kOpNames[(int)m_Operation] +"_"+precision; } |
|||
|
|||
|
|||
protected void AddOperationBody(ShaderGenerator visitor, string combineName, string body, string combinePrecision) |
|||
{ |
|||
var outputString = new ShaderGenerator (); |
|||
outputString.AddShaderChunk ("inline " + combinePrecision + "4 unity_combine_" + combineName + "_" + combinePrecision + " (" + combinePrecision + "4 arg1, " + combinePrecision + "4 arg2)", false); |
|||
outputString.AddShaderChunk ("{", false); |
|||
outputString.Indent (); |
|||
outputString.AddShaderChunk (body, false); |
|||
outputString.Deindent (); |
|||
outputString.AddShaderChunk ("}", false); |
|||
|
|||
visitor.AddShaderChunk (outputString.GetShaderString (0), true); |
|||
} |
|||
|
|||
|
|||
public override void NodeUI (Graphs.GraphGUI host) |
|||
{ |
|||
base.NodeUI(host); |
|||
|
|||
EditorGUI.BeginChangeCheck (); |
|||
m_Operation = (Operation)EditorGUILayout.EnumPopup (m_Operation); |
|||
if (EditorGUI.EndChangeCheck ()) |
|||
RegeneratePreviewShaders (); |
|||
} |
|||
|
|||
public void GenerateNodeFunction(ShaderGenerator visitor, GenerationMode generationMode) |
|||
{ |
|||
foreach (var precision in m_PrecisionNames) |
|||
{ |
|||
// Darken group
|
|||
AddOperationBody (visitor, kOpNames[(int)Operation.Darken], "return min(arg1, arg2);", precision); |
|||
AddOperationBody (visitor, kOpNames[(int)Operation.Multiply], "return arg1 * arg2;", precision); |
|||
AddOperationBody (visitor, kOpNames[(int)Operation.ColorBurn], "return 1 - (1-arg1)/(arg2+1e-5);", precision); |
|||
AddOperationBody (visitor, kOpNames[(int)Operation.LinearBurn], "return arg1 + arg2 - 1;", precision); |
|||
|
|||
// Lighten group
|
|||
AddOperationBody (visitor, kOpNames[(int)Operation.Lighten], "return max(arg1, arg2);", precision); |
|||
AddOperationBody (visitor, kOpNames[(int)Operation.Screen], "return 1- (1-arg1) * (1-arg2);", precision); |
|||
AddOperationBody (visitor, kOpNames[(int)Operation.ColorDodge], "return arg1/(1-arg2+1e-5);", precision); |
|||
AddOperationBody (visitor, kOpNames[(int)Operation.LinearDodge], "return arg1 + arg2;", precision); |
|||
|
|||
// Contrast group
|
|||
AddOperationBody (visitor, kOpNames[(int)Operation.Overlay], "return (arg1 < 0.5)? arg1*arg2*2: 1-(1-arg1)*(1-arg2)*2;", precision); |
|||
AddOperationBody (visitor, kOpNames[(int)Operation.SoftLight], |
|||
"return (1-arg1)*arg1*arg2 + arg1*(1- (1-arg1)*(1-arg2));", precision); |
|||
AddOperationBody (visitor, kOpNames[(int)Operation.HardLight], "return (arg2 < 0.5)? arg1*arg2*2: 1-(1-arg1)*(1-arg2)*2;", precision); |
|||
AddOperationBody (visitor, kOpNames[(int)Operation.VividLight], |
|||
"return (arg2 < 0.5)? 1- (1-arg1)/(2*arg2+1e-5): arg1/(1-2*(arg2-0.5)+1e-5);", precision); |
|||
AddOperationBody (visitor, kOpNames[(int)Operation.LinearLight], "return (arg2 < 0.5)? arg1+(2*arg2)-1: arg1+2*(arg2-0.5);", precision); |
|||
AddOperationBody (visitor, kOpNames[(int)Operation.PinLight], "return (arg2 < 0.5)? min(arg1, 2*arg2): max(arg1, 2*(arg2-0.5));", precision); |
|||
AddOperationBody (visitor, kOpNames[(int)Operation.HardMix], "return (arg2 < 1-arg1)? "+precision+"(0):"+precision+"(1);", precision); |
|||
|
|||
// Inversion group
|
|||
AddOperationBody (visitor, kOpNames[(int)Operation.Difference], "return abs(arg2-arg1);", precision); |
|||
AddOperationBody (visitor, kOpNames[(int)Operation.Exclusion], "return arg1 + arg2 - arg1*arg2*2;", precision); |
|||
AddOperationBody (visitor, kOpNames[(int)Operation.Subtract], "return max(arg2-arg1, 0.0);", precision); |
|||
AddOperationBody (visitor, kOpNames[(int)Operation.Divide], "return arg1 / (arg2+1e-5);", precision); |
|||
} |
|||
} |
|||
} |
|||
} |
|
|||
fileFormatVersion: 2 |
|||
guid: 3738e97908dea1f4bbc5e5a7cf562ecc |
|||
MonoImporter: |
|||
serializedVersion: 2 |
|||
defaultReferences: [] |
|||
executionOrder: 0 |
|||
icon: {instanceID: 0} |
|||
userData: |
|
|||
namespace UnityEditor.Graphs.Material |
|||
{ |
|||
[Title("Math/Div Node")] |
|||
class DivNode : Function2Input, IGeneratesFunction |
|||
{ |
|||
public override void Init() |
|||
{ |
|||
name = "DivNode"; |
|||
base.Init(); |
|||
} |
|||
|
|||
protected override string GetFunctionName () {return "unity_div_"+precision;} |
|||
|
|||
public void GenerateNodeFunction(ShaderGenerator visitor, GenerationMode generationMode) |
|||
{ |
|||
var outputString = new ShaderGenerator (); |
|||
foreach (var precision in m_PrecisionNames) |
|||
{ |
|||
outputString.AddShaderChunk("inline " + precision + "4 unity_div_" + precision + " (" + precision + "4 arg1, " + precision + "4 arg2)", false); |
|||
outputString.AddShaderChunk("{", false); |
|||
outputString.Indent(); |
|||
outputString.AddShaderChunk("return arg1 / arg2;", false); |
|||
outputString.Deindent(); |
|||
outputString.AddShaderChunk("}", false); |
|||
} |
|||
|
|||
visitor.AddShaderChunk (outputString.GetShaderString (0), true); |
|||
} |
|||
} |
|||
} |
|
|||
fileFormatVersion: 2 |
|||
guid: 8e9d13e64300d6942ad51651d39f9ac6 |
|||
MonoImporter: |
|||
serializedVersion: 2 |
|||
defaultReferences: [] |
|||
executionOrder: 0 |
|||
icon: {instanceID: 0} |
|||
userData: |
|
|||
namespace UnityEditor.Graphs.Material |
|||
{ |
|||
[Title("Math/Dot Node")] |
|||
class DotNode : Function2Input |
|||
{ |
|||
public override void Init() |
|||
{ |
|||
name = "DotNode"; |
|||
base.Init(); |
|||
} |
|||
|
|||
protected override string GetFunctionName() { return "dot"; } |
|||
} |
|||
} |
|
|||
fileFormatVersion: 2 |
|||
guid: 97e1d998eea5d644095671979ecf2e54 |
|||
MonoImporter: |
|||
serializedVersion: 2 |
|||
defaultReferences: [] |
|||
executionOrder: 0 |
|||
icon: {instanceID: 0} |
|||
userData: |
|
|||
using System; |
|||
using System.Collections.Generic; |
|||
using System.Linq; |
|||
|
|||
namespace UnityEditor.Graphs.Material |
|||
{ |
|||
internal static class Extensions |
|||
{ |
|||
public static IEnumerable<TSource> Except<TSource>(this IEnumerable<TSource> first, |
|||
IEnumerable<TSource> second , Func<TSource, TSource, bool> comparer ) |
|||
{ |
|||
return first.Except(second, new LambdaComparer<TSource>(comparer)); |
|||
} |
|||
|
|||
public class LambdaComparer<T> : IEqualityComparer<T> |
|||
{ |
|||
private readonly Func<T, T, bool> _lambdaComparer; |
|||
private readonly Func<T, int> _lambdaHash; |
|||
|
|||
public LambdaComparer(Func<T, T, bool> lambdaComparer) : |
|||
this(lambdaComparer, o => 0) |
|||
{ |
|||
} |
|||
|
|||
public LambdaComparer(Func<T, T, bool> lambdaComparer, Func<T, int> lambdaHash) |
|||
{ |
|||
if (lambdaComparer == null) |
|||
throw new ArgumentNullException("lambdaComparer"); |
|||
if (lambdaHash == null) |
|||
throw new ArgumentNullException("lambdaHash"); |
|||
|
|||
_lambdaComparer = lambdaComparer; |
|||
_lambdaHash = lambdaHash; |
|||
} |
|||
|
|||
public bool Equals(T x, T y) |
|||
{ |
|||
return _lambdaComparer(x, y); |
|||
} |
|||
|
|||
public int GetHashCode(T obj) |
|||
{ |
|||
return _lambdaHash(obj); |
|||
} |
|||
} |
|||
} |
|||
} |
|
|||
fileFormatVersion: 2 |
|||
guid: adf5c8d21f606c848a855790481093b2 |
|||
MonoImporter: |
|||
serializedVersion: 2 |
|||
defaultReferences: [] |
|||
executionOrder: 0 |
|||
icon: {instanceID: 0} |
|||
userData: |
|
|||
namespace UnityEditor.Graphs.Material |
|||
{ |
|||
[Title("Math/Fresnel Node")] |
|||
class FresnelNode : Function2Input, IGeneratesFunction |
|||
{ |
|||
public override void Init() |
|||
{ |
|||
name = "FresnelNode"; |
|||
base.Init(); |
|||
} |
|||
|
|||
protected override string GetFunctionName() { return "unity_fresnel_" + precision; } |
|||
|
|||
public void GenerateNodeFunction(ShaderGenerator visitor, GenerationMode generationMode) |
|||
{ |
|||
var outputString = new ShaderGenerator(); |
|||
|
|||
foreach (var precision in m_PrecisionNames) |
|||
{ |
|||
outputString.AddShaderChunk("inline " + precision + "4 unity_fresnel_" + precision + " (" + precision + "4 arg1, " + precision + "4 arg2)", false); |
|||
outputString.AddShaderChunk("{", false); |
|||
outputString.Indent(); |
|||
outputString.AddShaderChunk("return (1.0 - dot (normalize (arg1.xyz), normalize (arg2.xyz))).xxxx;", false); |
|||
outputString.Deindent(); |
|||
outputString.AddShaderChunk("}", false); |
|||
} |
|||
|
|||
visitor.AddShaderChunk(outputString.GetShaderString(0), true); |
|||
} |
|||
} |
|||
} |
|
|||
fileFormatVersion: 2 |
|||
guid: 06ab35c1dfe05414787df3ea2772d507 |
|||
MonoImporter: |
|||
serializedVersion: 2 |
|||
defaultReferences: [] |
|||
executionOrder: 0 |
|||
icon: {instanceID: 0} |
|||
userData: |
|
|||
using UnityEngine; |
|||
|
|||
namespace UnityEditor.Graphs.Material |
|||
{ |
|||
abstract class Function1Input : BaseMaterialNode, IGeneratesBodyCode |
|||
{ |
|||
public override bool hasPreview |
|||
{ |
|||
get { return true; } |
|||
} |
|||
|
|||
public override void Init() |
|||
{ |
|||
base.Init (); |
|||
AddSlot (new Slot (SlotType.OutputSlot, GetOutputSlotName ())); |
|||
AddSlot (new Slot (SlotType.InputSlot, GetInputSlotName ())); |
|||
} |
|||
|
|||
protected virtual string GetInputSlotName() {return "Input";} |
|||
protected virtual string GetOutputSlotName () {return "Output";} |
|||
|
|||
protected abstract string GetFunctionName (); |
|||
|
|||
public void GenerateNodeCode(ShaderGenerator visitor, GenerationMode generationMode) |
|||
{ |
|||
var outputSlot = FindOutputSlot (GetOutputSlotName ()); |
|||
var inputSlot = FindInputSlot (GetInputSlotName ()); |
|||
|
|||
if (inputSlot == null || outputSlot == null) |
|||
{ |
|||
Debug.LogError ("Invalid slot configuration on node: " + name); |
|||
return; |
|||
} |
|||
|
|||
bool inputConnected = inputSlot.edges.Count > 0; |
|||
|
|||
string inputValue; |
|||
if (inputConnected) |
|||
{ |
|||
var inputDateProvider = inputSlot.edges[0].fromSlot.node as BaseMaterialNode; |
|||
inputValue = inputDateProvider.GetOutputVariableNameForSlot (inputSlot.edges[0].fromSlot, generationMode); |
|||
} |
|||
else |
|||
{ |
|||
var defaultValue = GetSlotDefaultValue(inputSlot.name); |
|||
inputValue = defaultValue.GetDefaultValue (generationMode); |
|||
} |
|||
|
|||
visitor.AddShaderChunk(precision + "4 " + GetOutputVariableNameForSlot(outputSlot, generationMode) + " = " + GetFunctionCallBody(inputValue) + ";", true); |
|||
} |
|||
|
|||
protected virtual string GetFunctionCallBody (string inputValue) |
|||
{ |
|||
return GetFunctionName() + " (" + inputValue + ")"; |
|||
} |
|||
} |
|||
} |
|
|||
fileFormatVersion: 2 |
|||
guid: 9e8ba3e80e4d9e947a9377e9e73fdca9 |
|||
MonoImporter: |
|||
serializedVersion: 2 |
|||
defaultReferences: [] |
|||
executionOrder: 0 |
|||
icon: {instanceID: 0} |
|||
userData: |
|
|||
using System.Linq; |
|||
using UnityEngine; |
|||
|
|||
namespace UnityEditor.Graphs.Material |
|||
{ |
|||
abstract class Function2Input : BaseMaterialNode, IGeneratesBodyCode |
|||
{ |
|||
public override bool hasPreview { get { return true; } } |
|||
|
|||
public override void Init() |
|||
{ |
|||
base.Init(); |
|||
AddSlot(new Slot(SlotType.OutputSlot, GetOutputSlotName ())); |
|||
AddSlot(new Slot(SlotType.InputSlot, GetInputSlot1Name ())); |
|||
AddSlot(new Slot(SlotType.InputSlot, GetInputSlot2Name ())); |
|||
} |
|||
|
|||
protected virtual string GetInputSlot1Name() {return "Input1";} |
|||
protected virtual string GetInputSlot2Name() {return "Input2";} |
|||
protected virtual string GetOutputSlotName() {return "Output";} |
|||
|
|||
protected abstract string GetFunctionName(); |
|||
|
|||
public void GenerateNodeCode(ShaderGenerator visitor, GenerationMode generationMode) |
|||
{ |
|||
var outputSlot = FindOutputSlot (GetOutputSlotName ()); |
|||
var inputSlot1 = FindInputSlot (GetInputSlot1Name ()); |
|||
var inputSlot2 = FindInputSlot (GetInputSlot2Name ()); |
|||
|
|||
if (inputSlot1 == null || inputSlot2 == null || outputSlot == null) |
|||
{ |
|||
Debug.LogError("Invalid slot configuration on node: " + name); |
|||
return; |
|||
} |
|||
|
|||
string input1Value = GetSlotValue (inputSlot1, generationMode); |
|||
string input2Value = GetSlotValue (inputSlot2, generationMode); |
|||
visitor.AddShaderChunk(precision + "4 " + GetOutputVariableNameForSlot(outputSlot, generationMode) + " = " + GetFunctionCallBody(input1Value, input2Value) + ";", true); |
|||
} |
|||
|
|||
protected virtual string GetFunctionCallBody (string input1Value, string input2Value) |
|||
{ |
|||
return GetFunctionName() + " (" + input1Value + ", " + input2Value +")"; |
|||
} |
|||
} |
|||
} |
|
|||
fileFormatVersion: 2 |
|||
guid: 892d91fa7ade87541bac6c322a97b1bb |
|||
MonoImporter: |
|||
serializedVersion: 2 |
|||
defaultReferences: [] |
|||
executionOrder: 0 |
|||
icon: {instanceID: 0} |
|||
userData: |
|
|||
using System.Linq; |
|||
using UnityEngine; |
|||
|
|||
namespace UnityEditor.Graphs.Material |
|||
{ |
|||
abstract class Function3Input : BaseMaterialNode, IGeneratesBodyCode |
|||
{ |
|||
public override bool hasPreview { get { return true; } } |
|||
|
|||
public override void Init() |
|||
{ |
|||
base.Init (); |
|||
AddSlot (new Slot (SlotType.OutputSlot, GetOutputSlotName ())); |
|||
AddSlot (new Slot (SlotType.InputSlot, GetInputSlot1Name ())); |
|||
AddSlot (new Slot (SlotType.InputSlot, GetInputSlot2Name ())); |
|||
AddSlot (new Slot (SlotType.InputSlot, GetInputSlot3Name ())); |
|||
} |
|||
|
|||
protected virtual string GetInputSlot1Name() { return "Input1"; } |
|||
protected virtual string GetInputSlot2Name() { return "Input2"; } |
|||
protected virtual string GetInputSlot3Name() { return "Input3"; } |
|||
protected virtual string GetOutputSlotName() { return "Output"; } |
|||
|
|||
protected abstract string GetFunctionName(); |
|||
|
|||
public void GenerateNodeCode(ShaderGenerator visitor, GenerationMode generationMode) |
|||
{ |
|||
var outputSlot = FindOutputSlot (GetOutputSlotName ()); |
|||
var inputSlot1 = FindInputSlot (GetInputSlot1Name ()); |
|||
var inputSlot2 = FindInputSlot (GetInputSlot2Name ()); |
|||
var inputSlot3 = FindInputSlot (GetInputSlot3Name ()); |
|||
|
|||
if (inputSlot1 == null || inputSlot2 == null || inputSlot3 == null || outputSlot == null) |
|||
{ |
|||
Debug.LogError("Invalid slot configuration on node: " + name); |
|||
return; |
|||
} |
|||
|
|||
string input1Value = GetSlotValue(inputSlot1, generationMode); |
|||
string input2Value = GetSlotValue(inputSlot2, generationMode); |
|||
string input3Value = GetSlotValue(inputSlot2, generationMode); |
|||
|
|||
visitor.AddShaderChunk(precision + "4 " + GetOutputVariableNameForSlot(outputSlot, generationMode) + " = " + GetFunctionCallBody(input1Value, input2Value, input3Value) + ";", true); |
|||
} |
|||
|
|||
protected virtual string GetFunctionCallBody(string inputValue1, string inputValue2, string inputValue3) |
|||
{ |
|||
return GetFunctionName() + " (" + inputValue1 + ", " + inputValue2 + ", " + inputValue3 + ")"; |
|||
} |
|||
} |
|||
} |
|
|||
fileFormatVersion: 2 |
|||
guid: e7d8fb926f570fb48b10d7d068d54123 |
|||
MonoImporter: |
|||
serializedVersion: 2 |
|||
defaultReferences: [] |
|||
executionOrder: 0 |
|||
icon: {instanceID: 0} |
|||
userData: |
|
|||
using System.Linq; |
|||
using UnityEngine; |
|||
using System.Collections.Generic; |
|||
|
|||
namespace UnityEditor.Graphs.Material |
|||
{ |
|||
abstract class FunctionMultiInput : BaseMaterialNode, IGeneratesBodyCode |
|||
{ |
|||
private const string kOutputSlotName = "Output"; |
|||
private const string kBaseInputSlotName = "Input"; |
|||
|
|||
public override bool hasPreview { get { return true; } } |
|||
|
|||
public override void Init() |
|||
{ |
|||
base.Init (); |
|||
AddSlot (new Slot (SlotType.OutputSlot, kOutputSlotName)); |
|||
|
|||
AddSlot (new Slot (SlotType.InputSlot, GetInputSlotName (0))); |
|||
AddSlot (new Slot (SlotType.InputSlot, GetInputSlotName (1))); |
|||
} |
|||
|
|||
protected bool IsInputSlotConnected (int index) |
|||
{ |
|||
var inputSlot = GetValidInputSlots ().FirstOrDefault(x => x.name == GetInputSlotName (index)); |
|||
if (inputSlot == null) |
|||
{ |
|||
Debug.LogError("Invalid slot configuration on node: " + name); |
|||
return false; |
|||
} |
|||
|
|||
return inputSlot.edges.Count > 0; |
|||
} |
|||
|
|||
private static string GetInputSlotName (int index) { return kBaseInputSlotName + (index); } |
|||
|
|||
public override void InputEdgeChanged(Edge e) |
|||
{ |
|||
base.InputEdgeChanged(e); |
|||
|
|||
int inputSlotCount = GetValidInputSlots().Count(); |
|||
|
|||
if (IsInputSlotConnected(inputSlotCount - 1)) |
|||
AddSlot(new Slot(SlotType.InputSlot, GetInputSlotName(inputSlotCount))); |
|||
else if (inputSlotCount > 2) |
|||
{ |
|||
var lastSlot = inputSlots.FirstOrDefault (x => x.name == GetInputSlotName (inputSlotCount - 1)); |
|||
if (lastSlot != null) |
|||
RemoveSlot (lastSlot); |
|||
} |
|||
} |
|||
|
|||
protected abstract string GetFunctionName(); |
|||
|
|||
public void GenerateNodeCode(ShaderGenerator visitor, GenerationMode generationMode) |
|||
{ |
|||
var outputSlot = outputSlots.FirstOrDefault (x => x.name == kOutputSlotName); |
|||
|
|||
if (outputSlot == null) |
|||
{ |
|||
Debug.LogError ("Invalid slot configuration on node: " + name); |
|||
return; |
|||
} |
|||
|
|||
var inputSlots = GetValidInputSlots (); |
|||
int inputSlotCount = inputSlots.Count (); |
|||
|
|||
// build up a list of the valid input connections
|
|||
var inputValues = new List<string> (inputSlotCount); |
|||
MaterialWindow.DebugMaterialGraph ("Generating On Node: " + GetOutputVariableNameForNode () + " - Preview is: " + generationMode); |
|||
inputValues.AddRange (inputSlots.Select (inputSlot => GetSlotValue (inputSlot, generationMode))); |
|||
visitor.AddShaderChunk (precision + "4 " + GetOutputVariableNameForSlot (outputSlot, generationMode) + " = " + GetFunctionCallBody (inputValues) + ";", true); |
|||
} |
|||
|
|||
protected virtual string GetFunctionCallBody(List<string> inputValues) |
|||
{ |
|||
string functionCall = inputValues[0]; |
|||
for (int q = 1; q < inputValues.Count; ++q) |
|||
functionCall = GetFunctionName () + " (" + functionCall + ", " + inputValues[q] + ")"; |
|||
return functionCall; |
|||
} |
|||
} |
|||
} |
|
|||
fileFormatVersion: 2 |
|||
guid: 323a0eb1930dff241b4547716c8eb21f |
|||
MonoImporter: |
|||
serializedVersion: 2 |
|||
defaultReferences: [] |
|||
executionOrder: 0 |
|||
icon: {instanceID: 0} |
|||
userData: |
|
|||
using System; |
|||
using System.Linq; |
|||
using UnityEngine; |
|||
|
|||
namespace UnityEditor.Graphs.Material |
|||
{ |
|||
[Title("Fractal/Kaleidoscope Node")] |
|||
class KaleidoscopeNode : BaseMaterialNode, IGeneratesFunction, IGeneratesBodyCode |
|||
{ |
|||
[SerializeField] |
|||
private int m_Iterations = 6; |
|||
|
|||
private const string kPointInputName = "Point"; |
|||
private const string kConstant1InputName = "Constant1"; |
|||
private const string kConstant2InputName = "Constant2"; |
|||
private const string kOutputSlotName = "Output"; |
|||
|
|||
public override bool hasPreview { get { return true; } } |
|||
|
|||
public override void Init() |
|||
{ |
|||
name = "KaleidoscopeNode"; |
|||
base.Init(); |
|||
AddSlot(new Slot(SlotType.InputSlot, kPointInputName)); |
|||
AddSlot(new Slot(SlotType.InputSlot, kConstant1InputName)); |
|||
AddSlot(new Slot(SlotType.InputSlot, kConstant2InputName)); |
|||
AddSlot(new Slot(SlotType.OutputSlot, kOutputSlotName)); |
|||
} |
|||
|
|||
public void GenerateNodeFunction(ShaderGenerator visitor, GenerationMode generationMode) |
|||
{ |
|||
var outputString = new ShaderGenerator(); |
|||
foreach (var precision in m_PrecisionNames) |
|||
{ |
|||
outputString.AddShaderChunk("inline " + precision + "4 unity_kaleidoscope_" + precision + " (" + precision + "2 p, " + precision + "4 c1, " + precision + "4 c2, int iterations)", false); |
|||
outputString.AddShaderChunk("{", false); |
|||
outputString.Indent(); |
|||
outputString.AddShaderChunk("c1 = c1 * 2 - 1;", false); |
|||
outputString.AddShaderChunk("c2 = c2 * 2 - 1;", false); |
|||
outputString.AddShaderChunk("for (int n = 0; n < iterations; n++)", false); |
|||
outputString.AddShaderChunk("{", false); |
|||
outputString.Indent(); |
|||
outputString.AddShaderChunk("p = c1.xy + p * c1.zw + " + precision + "2(dot(p, c2.xy), dot(p, c2.zw));", false); |
|||
outputString.AddShaderChunk("if(p.x < p.y) p.xy = -p.yx;", false); |
|||
outputString.Deindent(); |
|||
outputString.AddShaderChunk("}", false); |
|||
outputString.AddShaderChunk("return " + precision + "4(p, 1, 1);", false); |
|||
outputString.Deindent(); |
|||
outputString.AddShaderChunk("}", false); |
|||
} |
|||
|
|||
visitor.AddShaderChunk(outputString.GetShaderString(0), true); |
|||
} |
|||
|
|||
public void GenerateNodeCode(ShaderGenerator visitor, GenerationMode generationMode) |
|||
{ |
|||
var outputSlot = FindOutputSlot (kOutputSlotName); |
|||
var pointInput = FindInputSlot (kPointInputName); |
|||
var constant1Input = FindInputSlot (kConstant1InputName); |
|||
var constant2Input = FindInputSlot (kConstant2InputName); |
|||
|
|||
if (outputSlot == null || pointInput == null || constant1Input == null || constant2Input == null) |
|||
{ |
|||
Debug.LogError("Invalid slot configuration on node: " + name); |
|||
return; |
|||
} |
|||
|
|||
string pointInputValue = GetSlotValue (pointInput, generationMode); |
|||
string constant1InputValue = GetSlotValue (constant1Input, generationMode); |
|||
string constant2InputValue = GetSlotValue (constant2Input, generationMode); |
|||
|
|||
string outName = GetOutputVariableNameForSlot (outputSlot, generationMode); |
|||
visitor.AddShaderChunk (precision + "4 " + outName + " = unity_kaleidoscope_" + precision + "(" + pointInputValue + ".xy, " + constant1InputValue + ", " + constant2InputValue + ", " + m_Iterations + ");", false); |
|||
} |
|||
|
|||
static float Slider(string title, float value, float from, float to) |
|||
{ |
|||
GUILayout.BeginHorizontal(); |
|||
GUILayout.Label(title); |
|||
value = GUILayout.HorizontalSlider(value, from, to, GUILayout.Width(64)); |
|||
GUILayout.EndHorizontal(); |
|||
return value; |
|||
} |
|||
|
|||
public override void NodeUI(Graphs.GraphGUI host) |
|||
{ |
|||
base.NodeUI(host); |
|||
|
|||
EditorGUI.BeginChangeCheck(); |
|||
m_Iterations = (int)Slider("Iterations", (float)m_Iterations, 1, 50); |
|||
if (EditorGUI.EndChangeCheck()) |
|||
RegeneratePreviewShaders(); |
|||
} |
|||
} |
|||
} |
|
|||
fileFormatVersion: 2 |
|||
guid: dfc00afcda39bfa4fbd9bd6176f53477 |
|||
MonoImporter: |
|||
serializedVersion: 2 |
|||
defaultReferences: [] |
|||
executionOrder: 0 |
|||
icon: {instanceID: 0} |
|||
userData: |
|
|||
namespace UnityEditor.Graphs.Material |
|||
{ |
|||
[Title("Math/Length Node")] |
|||
class LengthNode : Function1Input |
|||
{ |
|||
public override void Init() |
|||
{ |
|||
name = "LengthNode"; |
|||
base.Init(); |
|||
} |
|||
|
|||
protected override string GetFunctionName() { return "length"; } |
|||
} |
|||
} |
|
|||
fileFormatVersion: 2 |
|||
guid: 52afae1b1271e864c9c6965dc738c2dd |
|||
MonoImporter: |
|||
serializedVersion: 2 |
|||
defaultReferences: [] |
|||
executionOrder: 0 |
|||
icon: {instanceID: 0} |
|||
userData: |
|
|||
using System; |
|||
using System.Linq; |
|||
using UnityEngine; |
|||
|
|||
namespace UnityEditor.Graphs.Material |
|||
{ |
|||
[Title("Fractal/Mandelbrot Node")] |
|||
class MandelbrotNode : BaseMaterialNode, IGeneratesFunction, IGeneratesBodyCode |
|||
{ |
|||
[SerializeField] |
|||
private int m_Iterations = 6; |
|||
|
|||
private const string kPointInputName = "Point"; |
|||
private const string kConstantInputName = "Constant"; |
|||
private const string kOutputSlotName = "Output"; |
|||
|
|||
public override bool hasPreview { get { return true; } } |
|||
|
|||
public override void Init() |
|||
{ |
|||
name = "MandelbrotNode"; |
|||
base.Init(); |
|||
AddSlot(new Slot(SlotType.InputSlot, kPointInputName)); |
|||
AddSlot(new Slot(SlotType.InputSlot, kConstantInputName)); |
|||
AddSlot(new Slot(SlotType.OutputSlot, kOutputSlotName)); |
|||
} |
|||
|
|||
public void GenerateNodeFunction(ShaderGenerator visitor, GenerationMode generationMode) |
|||
{ |
|||
var outputString = new ShaderGenerator(); |
|||
foreach (var precision in m_PrecisionNames) |
|||
{ |
|||
outputString.AddShaderChunk("inline " + precision + "4 unity_mandelbrot_" + precision + " (" + precision + "2 p, " + precision + "2 c, float limit, float scale, int iterations)", false); |
|||
outputString.AddShaderChunk("{", false); |
|||
outputString.Indent(); |
|||
outputString.AddShaderChunk(precision + " zr = p.x * 4 - 2, zi = p.y * 4 - 2, dzr = 1, dzi = 0, r = 0, len2;", false); |
|||
outputString.AddShaderChunk("for (int n = 0; n < iterations; n++)", false); |
|||
outputString.AddShaderChunk("{", false); |
|||
outputString.Indent(); |
|||
outputString.AddShaderChunk(precision + " tmp1 = 2 * zr * zi + c.y; zr = zr * zr - zi * zi + c.x; zi = tmp1;", false); |
|||
outputString.AddShaderChunk(precision + " tmp2 = 2 * (dzr * zi + dzi * zr); dzr = 2 * (dzr * zr - dzi * zi) + 1; dzi = tmp2;", false); |
|||
outputString.AddShaderChunk("len2 = zr * zr + zi * zi;", false); |
|||
outputString.AddShaderChunk("if (len2 > 1000000 * limit) { r = n; break; }", false); |
|||
outputString.Deindent(); |
|||
outputString.AddShaderChunk("}", false); |
|||
outputString.AddShaderChunk("return scale * sqrt(len2 / (dzr * dzr + dzi * dzi)) * log(len2);", false); |
|||
outputString.Deindent(); |
|||
outputString.AddShaderChunk("}", false); |
|||
} |
|||
|
|||
visitor.AddShaderChunk(outputString.GetShaderString(0), true); |
|||
} |
|||
|
|||
public void GenerateNodeCode(ShaderGenerator visitor, GenerationMode generationMode) |
|||
{ |
|||
var outputSlot = outputSlots.FirstOrDefault(x => x.name == kOutputSlotName); |
|||
var pointInput = GetValidInputSlots().FirstOrDefault(x => x.name == kPointInputName); |
|||
var constantInput = GetValidInputSlots().FirstOrDefault(x => x.name == kConstantInputName); |
|||
if (outputSlot == null || pointInput == null || constantInput == null) |
|||
{ |
|||
Debug.LogError("Invalid slot configuration on node: " + name); |
|||
return; |
|||
} |
|||
|
|||
//TODO: This will break if there is NO input connected, use default in that case
|
|||
var pointProvider = pointInput.edges[0].fromSlot.node as BaseMaterialNode; |
|||
var pointName = pointProvider.GetOutputVariableNameForSlot(pointInput.edges[0].fromSlot, generationMode); |
|||
|
|||
var constantProvider = constantInput.edges[0].fromSlot.node as BaseMaterialNode; |
|||
var constantName = constantProvider.GetOutputVariableNameForSlot(constantInput.edges[0].fromSlot, generationMode); |
|||
|
|||
string outName = GetOutputVariableNameForSlot(outputSlot, generationMode); |
|||
visitor.AddShaderChunk(precision + "4 " + outName + " = unity_mandelbrot_" + precision + "(" + pointName + ".xy, " + constantName + ".xy, " + constantName + ".z, " + constantName + ".w, " + m_Iterations + ");", false); |
|||
} |
|||
|
|||
static float Slider(string title, float value, float from, float to) |
|||
{ |
|||
GUILayout.BeginHorizontal(); |
|||
GUILayout.Label(title); |
|||
value = GUILayout.HorizontalSlider(value, from, to, GUILayout.Width(64)); |
|||
GUILayout.EndHorizontal(); |
|||
return value; |
|||
} |
|||
|
|||
public override void NodeUI(Graphs.GraphGUI host) |
|||
{ |
|||
base.NodeUI(host); |
|||
|
|||
EditorGUI.BeginChangeCheck(); |
|||
m_Iterations = (int)Slider("Iterations", (float)m_Iterations, 1, 50); |
|||
if (EditorGUI.EndChangeCheck()) |
|||
RegeneratePreviewShaders(); |
|||
} |
|||
} |
|||
} |
|
|||
fileFormatVersion: 2 |
|||
guid: 45896ba83118f8548bd9d2f9263bcde5 |
|||
MonoImporter: |
|||
serializedVersion: 2 |
|||
defaultReferences: [] |
|||
executionOrder: 0 |
|||
icon: {instanceID: 0} |
|||
userData: |
|
|||
namespace UnityEditor.Graphs.Material |
|||
{ |
|||
[Title("Math/Maximum Node")] |
|||
class MaximumNode : Function2Input |
|||
{ |
|||
public override void Init() |
|||
{ |
|||
name = "MaximumNode"; |
|||
base.Init(); |
|||
} |
|||
|
|||
protected override string GetFunctionName() { return "max"; } |
|||
} |
|||
} |
|
|||
fileFormatVersion: 2 |
|||
guid: 1de46e012f3608843978529b36704c2b |
|||
MonoImporter: |
|||
serializedVersion: 2 |
|||
defaultReferences: [] |
|||
executionOrder: 0 |
|||
icon: {instanceID: 0} |
|||
userData: |
|
|||
namespace UnityEditor.Graphs.Material |
|||
{ |
|||
[Title("Math/Minimum Node")] |
|||
class MinimumNode : Function2Input |
|||
{ |
|||
public override void Init() |
|||
{ |
|||
name = "MinimumNode"; |
|||
base.Init(); |
|||
} |
|||
|
|||
protected override string GetFunctionName() { return "min"; } |
|||
} |
|||
} |
|
|||
fileFormatVersion: 2 |
|||
guid: 79ffed9a70f191f4c966a6eb3ae10d07 |
|||
MonoImporter: |
|||
serializedVersion: 2 |
|||
defaultReferences: [] |
|||
executionOrder: 0 |
|||
icon: {instanceID: 0} |
|||
userData: |
|
|||
using UnityEngine; |
|||
|
|||
namespace UnityEditor.Graphs.Material |
|||
{ |
|||
[Title("Math/Multiply Node")] |
|||
class MultiplyNode : FunctionMultiInput, IGeneratesFunction |
|||
{ |
|||
public override void Init() |
|||
{ |
|||
name = "MultiplyNode"; |
|||
base.Init(); |
|||
} |
|||
|
|||
protected override string GetFunctionName() { return "unity_multiply_" + precision; } |
|||
|
|||
public override Vector4 GetNewSlotDefaultValue() |
|||
{ |
|||
return Vector4.one; |
|||
} |
|||
|
|||
public void GenerateNodeFunction(ShaderGenerator visitor, GenerationMode generationMode) |
|||
{ |
|||
var outputString = new ShaderGenerator(); |
|||
foreach (var precision in m_PrecisionNames) |
|||
{ |
|||
outputString.AddShaderChunk ("inline " + precision + "4 unity_multiply_" + precision + " (" + precision + "4 arg1, " + precision + "4 arg2)", false); |
|||
outputString.AddShaderChunk ("{", false); |
|||
outputString.Indent (); |
|||
outputString.AddShaderChunk ("return arg1 * arg2;", false); |
|||
outputString.Deindent (); |
|||
outputString.AddShaderChunk ("}", false); |
|||
} |
|||
|
|||
visitor.AddShaderChunk(outputString.GetShaderString(0), true); |
|||
} |
|||
} |
|||
} |
|
|||
fileFormatVersion: 2 |
|||
guid: 088fb5bde3ece0f4190136b3ab43f7c4 |
|||
MonoImporter: |
|||
serializedVersion: 2 |
|||
defaultReferences: [] |
|||
executionOrder: 0 |
|||
icon: {instanceID: 0} |
|||
userData: |
|
|||
using UnityEngine; |
|||
|
|||
namespace UnityEditor.Graphs.Material |
|||
{ |
|||
[Title("Input/Normal Node")] |
|||
public class NormalNode : BaseMaterialNode |
|||
{ |
|||
private const string kOutputSlotName = "Normal"; |
|||
|
|||
public override bool hasPreview { get { return true; } } |
|||
public override PreviewMode previewMode |
|||
{ |
|||
get { return PreviewMode.Preview3D; } } |
|||
|
|||
public override void Init () |
|||
{ |
|||
base.Init (); |
|||
name = "Normal"; |
|||
AddSlot (new Slot (SlotType.OutputSlot, kOutputSlotName)); |
|||
} |
|||
|
|||
public override string GetOutputVariableNameForSlot(Slot slot, GenerationMode generationMode) |
|||
{ |
|||
if (generationMode == GenerationMode.Preview2D) |
|||
Debug.LogError ("Trying to generate 2D preview on a node that does not support it!"); |
|||
|
|||
return generationMode.Is2DPreview () ? "half4 (IN.Normal, 1)" : "half4 (o.Normal, 1)"; |
|||
} |
|||
} |
|||
} |
|
|||
fileFormatVersion: 2 |
|||
guid: 5b34601661908b3499c4c5e2ecd61f75 |
|||
MonoImporter: |
|||
serializedVersion: 2 |
|||
defaultReferences: [] |
|||
executionOrder: 0 |
|||
icon: {instanceID: 0} |
|||
userData: |
|
|||
namespace UnityEditor.Graphs.Material |
|||
{ |
|||
[Title("Math/Normalize Node")] |
|||
class NormalizeNode : Function1Input |
|||
{ |
|||
public override void Init() |
|||
{ |
|||
name = "NormalizeNode"; |
|||
base.Init(); |
|||
} |
|||
|
|||
protected override string GetFunctionName() { return "normalize"; } |
|||
} |
|||
} |
|
|||
fileFormatVersion: 2 |
|||
guid: 7eb73d726827e2c41ae4d68018bc97e1 |
|||
MonoImporter: |
|||
serializedVersion: 2 |
|||
defaultReferences: [] |
|||
executionOrder: 0 |
|||
icon: {instanceID: 0} |
|||
userData: |
|
|||
using System; |
|||
using System.Linq; |
|||
using UnityEngine; |
|||
|
|||
namespace UnityEditor.Graphs.Material |
|||
{ |
|||
[Title("Fractal/Perlin Node")] |
|||
class PerlinNode : TextureNode, IGeneratesFunction, IGeneratesBodyCode |
|||
{ |
|||
public override bool hasPreview { get { return true; } } |
|||
|
|||
[SerializeField] |
|||
private int m_Iterations = 4; |
|||
|
|||
[SerializeField] |
|||
private float m_Decay = 0.5f; |
|||
|
|||
[SerializeField] |
|||
private float m_Frequency = 2.0f; |
|||
|
|||
public override void Init() |
|||
{ |
|||
name = "Perlin"; |
|||
base.Init (); |
|||
} |
|||
|
|||
public void GenerateNodeFunction(ShaderGenerator visitor, GenerationMode generationMode) |
|||
{ |
|||
var outputString = new ShaderGenerator(); |
|||
foreach (var precision in m_PrecisionNames) |
|||
{ |
|||
outputString.AddShaderChunk("inline " + precision + "4 unity_perlin_" + precision + " (" |
|||
+ "sampler2D textureID, " |
|||
+ "int iterations, " |
|||
+ precision + " decay, " |
|||
+ precision + " frequency, " |
|||
+ precision + "2 p" |
|||
+ ")", false); |
|||
outputString.AddShaderChunk("{", false); |
|||
outputString.Indent(); |
|||
outputString.AddShaderChunk(precision + "4 sum = " + precision + "4(0, 0, 0, 0);", false); |
|||
outputString.AddShaderChunk(precision + " amp = 0.5;", false); |
|||
outputString.AddShaderChunk("for(int n = 0; n < iterations; n++)", false); |
|||
outputString.AddShaderChunk("{", false); |
|||
outputString.Indent(); |
|||
outputString.AddShaderChunk("sum += amp * tex2D (textureID, p);", false); |
|||
outputString.AddShaderChunk("p *= frequency;", false); |
|||
outputString.AddShaderChunk("amp *= decay;", false); |
|||
outputString.Deindent(); |
|||
outputString.AddShaderChunk("}", false); |
|||
outputString.AddShaderChunk("return sum;", false); |
|||
outputString.Deindent(); |
|||
outputString.AddShaderChunk("}", false); |
|||
} |
|||
|
|||
visitor.AddShaderChunk(outputString.GetShaderString(0), true); |
|||
} |
|||
|
|||
public override void GenerateNodeCode(ShaderGenerator visitor, GenerationMode generationMode) |
|||
{ |
|||
var outputSlot = FindOutputSlot(kOutputSlotName); |
|||
if (outputSlot == null) |
|||
return; |
|||
|
|||
var uvSlot = FindInputSlot(kUVSlotName); |
|||
if (uvSlot == null) |
|||
return; |
|||
|
|||
var uvName = "IN.meshUV0"; |
|||
if (uvSlot.edges.Count > 0) |
|||
{ |
|||
var fromNode = uvSlot.edges[0].fromSlot.node as BaseMaterialNode; |
|||
uvName = fromNode.GetOutputVariableNameForSlot(uvSlot.edges[0].fromSlot, generationMode); |
|||
} |
|||
|
|||
string body = "unity_perlin_" + precision + "(" + GetPropertyName () + ", " + m_Iterations + ", " + m_Decay + ", " + m_Frequency + ", " + uvName + ".xy)"; |
|||
visitor.AddShaderChunk("float4 " + GetOutputVariableNameForSlot(outputSlot, generationMode) + " = " + body + ";", true); |
|||
} |
|||
|
|||
static float Slider(string title, float value, float from, float to) |
|||
{ |
|||
GUILayout.BeginHorizontal(); |
|||
GUILayout.Label(title); |
|||
value = GUILayout.HorizontalSlider(value, from, to, GUILayout.Width(64)); |
|||
GUILayout.EndHorizontal(); |
|||
return value; |
|||
} |
|||
|
|||
public override void NodeUI(Graphs.GraphGUI host) |
|||
{ |
|||
base.NodeUI(host); |
|||
|
|||
EditorGUI.BeginChangeCheck(); |
|||
m_Iterations = (int)Slider("Iterations", (float)m_Iterations, 1, 8); |
|||
m_Decay = Slider("Decay", m_Decay, -1f, 1f); |
|||
m_Frequency = Slider("Frequency", m_Frequency, 0f, 5f); |
|||
if (EditorGUI.EndChangeCheck()) |
|||
RegeneratePreviewShaders(); |
|||
} |
|||
} |
|||
} |
|
|||
fileFormatVersion: 2 |
|||
guid: 6388ec78711fae240b4d5c60bd70d36d |
|||
MonoImporter: |
|||
serializedVersion: 2 |
|||
defaultReferences: [] |
|||
executionOrder: 0 |
|||
icon: {instanceID: 0} |
|||
userData: |
|
|||
using System; |
|||
using UnityEngine; |
|||
using System.Linq; |
|||
using System.Collections.Generic; |
|||
using System.Reflection; |
|||
|
|||
namespace UnityEditor.Graphs.Material |
|||
{ |
|||
[Title("Output/Pixel Shader")] |
|||
class PixelShaderNode : BaseMaterialNode, IGeneratesBodyCode |
|||
{ |
|||
private const string kAlbedoSlotName = "Albedo"; |
|||
private const string kNormalSlotName = "Normal"; |
|||
private const string kEmissionSlotName = "Emission"; |
|||
private const string kSpecularSlotName = "Specular"; |
|||
private const string kGlossSlotName = "Gloss"; |
|||
private const string kAlphaSlotName = "Alpha"; |
|||
|
|||
[SerializeField] |
|||
private string m_LightFunction; |
|||
|
|||
private static List<BaseLightFunction> s_LightFunctions; |
|||
|
|||
public override void Init() |
|||
{ |
|||
name = "PixelMaster"; |
|||
base.Init (); |
|||
|
|||
AddSlot (new Slot(SlotType.InputSlot, kAlbedoSlotName)); |
|||
AddSlot (new Slot(SlotType.InputSlot, kNormalSlotName)); |
|||
AddSlot (new Slot(SlotType.InputSlot, kEmissionSlotName)); |
|||
AddSlot (new Slot(SlotType.InputSlot, kSpecularSlotName)); |
|||
AddSlot (new Slot(SlotType.InputSlot, kGlossSlotName)); |
|||
AddSlot (new Slot(SlotType.InputSlot, kAlphaSlotName)); |
|||
} |
|||
|
|||
private static List<BaseLightFunction> GetLightFunctions () |
|||
{ |
|||
if (s_LightFunctions == null) |
|||
{ |
|||
s_LightFunctions = new List<BaseLightFunction> (); |
|||
|
|||
foreach (Type type in Assembly.GetAssembly (typeof(BaseLightFunction)).GetTypes ()) |
|||
{ |
|||
if (type.IsClass && !type.IsAbstract && (type.IsSubclassOf (typeof(BaseLightFunction)))) |
|||
{ |
|||
var func = Activator.CreateInstance (type) as BaseLightFunction; |
|||
s_LightFunctions.Add (func); |
|||
} |
|||
} |
|||
} |
|||
return s_LightFunctions; |
|||
} |
|||
|
|||
public virtual void GenerateLightFunction (ShaderGenerator visitor) |
|||
{ |
|||
visitor.AddPragmaChunk (m_LightFunction); |
|||
|
|||
var lightFunction = GetLightFunctions().FirstOrDefault(x => x.GetName() == m_LightFunction); |
|||
int lightFuncIndex = 0; |
|||
if (lightFunction != null) |
|||
lightFuncIndex = GetLightFunctions ().IndexOf (lightFunction); |
|||
|
|||
if (lightFuncIndex < s_LightFunctions.Count) |
|||
{ |
|||
BaseLightFunction func = s_LightFunctions[lightFuncIndex]; |
|||
func.GenerateBody (visitor); |
|||
} |
|||
} |
|||
|
|||
public void GenerateNodeCode(ShaderGenerator shaderBody, GenerationMode generationMode) |
|||
{ |
|||
// do the normal slot first so that it can be used later in the shader :)
|
|||
var normal = FindInputSlot (kNormalSlotName); |
|||
var nodes = new List<BaseMaterialNode>(); |
|||
CollectChildNodesByExecutionOrder(nodes, normal, false); |
|||
|
|||
foreach (var node in nodes) |
|||
{ |
|||
if (node is IGeneratesBodyCode) |
|||
(node as IGeneratesBodyCode).GenerateNodeCode (shaderBody, generationMode); |
|||
} |
|||
|
|||
foreach (var edge in normal.edges) |
|||
{ |
|||
var node = edge.fromSlot.node as BaseMaterialNode; |
|||
shaderBody.AddShaderChunk("o." + normal.name + " = " + node.GetOutputVariableNameForSlot(edge.fromSlot, generationMode) + ";", true); |
|||
} |
|||
|
|||
// track the last index of nodes... they have already been processed :)
|
|||
int pass2StartIndex = nodes.Count; |
|||
|
|||
//Get the rest of the nodes for all the other slots
|
|||
CollectChildNodesByExecutionOrder(nodes, null, false); |
|||
for (var i = pass2StartIndex; i < nodes.Count; i++) |
|||
{ |
|||
var node = nodes[i]; |
|||
if (node is IGeneratesBodyCode) |
|||
(node as IGeneratesBodyCode).GenerateNodeCode(shaderBody, generationMode); |
|||
} |
|||
|
|||
foreach (var slot in slots) |
|||
{ |
|||
if (slot == normal) |
|||
continue; |
|||
|
|||
foreach (var edge in slot.edges) |
|||
{ |
|||
var node = edge.fromSlot.node as BaseMaterialNode; |
|||
shaderBody.AddShaderChunk("o." + slot.name + " = " + node.GetOutputVariableNameForSlot(edge.fromSlot, generationMode) + ";", true); |
|||
} |
|||
} |
|||
} |
|||
|
|||
public override string GetOutputVariableNameForSlot(Slot s, GenerationMode generationMode) |
|||
{ |
|||
return GetOutputVariableNameForNode(); |
|||
} |
|||
|
|||
public override void NodeUI (Graphs.GraphGUI host) |
|||
{ |
|||
base.NodeUI(host); |
|||
var lightFunction = GetLightFunctions ().FirstOrDefault (x => x.GetName () == m_LightFunction); |
|||
int lightFuncIndex = 0; |
|||
if (lightFunction != null) |
|||
lightFuncIndex = GetLightFunctions ().IndexOf (lightFunction); |
|||
lightFuncIndex = EditorGUILayout.Popup (lightFuncIndex, s_LightFunctions.Select(x => x.GetName ()).ToArray (), EditorStyles.popup); |
|||
m_LightFunction = GetLightFunctions ()[lightFuncIndex].GetName (); |
|||
} |
|||
|
|||
public bool IsSpecularConnected () |
|||
{ |
|||
var specSlot = FindInputSlot (kSpecularSlotName); |
|||
var glossSlot = FindInputSlot(kGlossSlotName); |
|||
|
|||
if (specSlot == null || glossSlot == null) |
|||
return false; |
|||
|
|||
if (specSlot.edges.Count > 0 || glossSlot.edges.Count > 0) |
|||
return true; |
|||
|
|||
return false; |
|||
} |
|||
} |
|||
} |
|
|||
fileFormatVersion: 2 |
|||
guid: 38072936174514040b3e08813a3ec4e7 |
|||
MonoImporter: |
|||
serializedVersion: 2 |
|||
defaultReferences: [] |
|||
executionOrder: 0 |
|||
icon: {instanceID: 0} |
|||
userData: |
|
|||
using UnityEngine; |
|||
|
|||
namespace UnityEditor.Graphs.Material |
|||
{ |
|||
[Title("Math/Power Node")] |
|||
class PowerNode : Function2Input |
|||
{ |
|||
public override void Init() |
|||
{ |
|||
name = "PowerNode"; |
|||
base.Init(); |
|||
} |
|||
|
|||
protected override string GetFunctionName() { return "pow"; } |
|||
} |
|||
} |
|
|||
fileFormatVersion: 2 |
|||
guid: b2957c4e08e061444a7444a1a03fb584 |
|||
MonoImporter: |
|||
serializedVersion: 2 |
|||
defaultReferences: [] |
|||
executionOrder: 0 |
|||
icon: {instanceID: 0} |
|||
userData: |
|
|||
using System; |
|||
using System.Collections.Generic; |
|||
using UnityEngine; |
|||
|
|||
namespace UnityEditor.Graphs.Material |
|||
{ |
|||
public abstract class PropertyNode : BaseMaterialNode, IGenerateProperties |
|||
{ |
|||
[SerializeField] |
|||
private ShaderProperty m_BoundProperty; |
|||
|
|||
public bool exposed |
|||
{ |
|||
get { return m_BoundProperty != null; } |
|||
} |
|||
|
|||
protected virtual bool HasBoundProperty() { return m_BoundProperty != null; } |
|||
public ShaderProperty boundProperty { get { return m_BoundProperty; } } |
|||
|
|||
public virtual void BindProperty(ShaderProperty property, bool rebuildShaders) |
|||
{ |
|||
m_BoundProperty = property; |
|||
} |
|||
|
|||
public virtual void RefreshBoundProperty (ShaderProperty toRefresh, bool rebuildShader) |
|||
{ |
|||
if (m_BoundProperty != null && m_BoundProperty == toRefresh) |
|||
{ |
|||
BindProperty (toRefresh, rebuildShader); |
|||
} |
|||
} |
|||
|
|||
public IEnumerable<ShaderProperty> FindValidPropertyBindings() |
|||
{ |
|||
if (graph is IGenerateGraphProperties) |
|||
return (graph as IGenerateGraphProperties).GetPropertiesForPropertyType(propertyType); |
|||
|
|||
return new ShaderProperty[0]; |
|||
} |
|||
|
|||
public virtual string GetPropertyName() |
|||
{ |
|||
if (m_BoundProperty == null) |
|||
return name + "_" + Math.Abs(GetInstanceID()); |
|||
|
|||
return m_BoundProperty.name; |
|||
} |
|||
|
|||
public abstract PropertyType propertyType { get; } |
|||
|
|||
public abstract PreviewProperty GetPreviewProperty (); |
|||
|
|||
public override void UpdatePreviewProperties ( ) |
|||
{ |
|||
base.UpdatePreviewProperties (); |
|||
MaterialWindow.DebugMaterialGraph ("In Property Node: " + this); |
|||
SetDependentPreviewMaterialProperty (GetPreviewProperty ()); |
|||
} |
|||
|
|||
public void UnbindProperty (ShaderProperty prop) |
|||
{ |
|||
if (m_BoundProperty != null && m_BoundProperty == prop) |
|||
{ |
|||
m_BoundProperty = null; |
|||
RegeneratePreviewShaders(); |
|||
} |
|||
} |
|||
} |
|||
} |
|
|||
fileFormatVersion: 2 |
|||
guid: 93d9190b7b5ceb44ca24874c991b8da9 |
|||
MonoImporter: |
|||
serializedVersion: 2 |
|||
defaultReferences: [] |
|||
executionOrder: 0 |
|||
icon: {instanceID: 0} |
|||
userData: |
|
|||
namespace UnityEditor.Graphs.Material |
|||
{ |
|||
[Title("Math/Quantize Node")] |
|||
class QuantizeNode : Function2Input, IGeneratesFunction |
|||
{ |
|||
public override void Init() |
|||
{ |
|||
name = "QuantizeNode"; |
|||
base.Init(); |
|||
} |
|||
|
|||
protected override string GetFunctionName () {return "unity_quantize_"+precision;} |
|||
|
|||
public void GenerateNodeFunction(ShaderGenerator visitor, GenerationMode generationMode) |
|||
{ |
|||
var outputString = new ShaderGenerator (); |
|||
foreach (var precision in m_PrecisionNames) |
|||
{ |
|||
outputString.AddShaderChunk("inline " + precision + "4 unity_quantize_" + precision + " (" + precision + "4 input, " + precision + "4 stepsize)", false); |
|||
outputString.AddShaderChunk("{", false); |
|||
outputString.Indent(); |
|||
outputString.AddShaderChunk("return floor(input / stepsize) * stepsize;", false); |
|||
outputString.Deindent(); |
|||
outputString.AddShaderChunk("}", false); |
|||
} |
|||
|
|||
visitor.AddShaderChunk (outputString.GetShaderString (0), true); |
|||
} |
|||
} |
|||
} |
|
|||
fileFormatVersion: 2 |
|||
guid: 4322ad8d0cd83df47afd741a6b97d57b |
|||
MonoImporter: |
|||
serializedVersion: 2 |
|||
defaultReferences: [] |
|||
executionOrder: 0 |
|||
icon: {instanceID: 0} |
|||
userData: |
|
|||
using System; |
|||
|
|||
namespace UnityEditor.Graphs.Material |
|||
{ |
|||
[Title("Math/Reflect Node")] |
|||
class ReflectNode : Function2Input, IGeneratesFunction |
|||
{ |
|||
public override void Init() |
|||
{ |
|||
name = "ReflectNode"; |
|||
base.Init(); |
|||
} |
|||
|
|||
protected override string GetInputSlot1Name() {return "Normal";} |
|||
protected override string GetInputSlot2Name() {return "Direction";} |
|||
protected override string GetOutputSlotName() {return "Reflection";} |
|||
|
|||
protected override string GetFunctionName () {return "unity_reflect_"+precision;} |
|||
|
|||
public void GenerateNodeFunction(ShaderGenerator visitor, GenerationMode generationMode) |
|||
{ |
|||
var outputString = new ShaderGenerator (); |
|||
foreach (var precision in m_PrecisionNames) |
|||
{ |
|||
outputString.AddShaderChunk("inline " + precision + "4 unity_reflect_" + precision + " (" + precision + "4 normal, " + precision + "4 direction)", false); |
|||
outputString.AddShaderChunk("{", false); |
|||
outputString.Indent(); |
|||
outputString.AddShaderChunk(precision + "3 vn = normalize(normal.xyz);", false); |
|||
outputString.AddShaderChunk(precision + "3 vd = normalize(direction.xyz);", false); |
|||
outputString.AddShaderChunk("return half4 (2 * dot(vn, vd) * vn - vd, 1.0);", false); |
|||
outputString.Deindent(); |
|||
outputString.AddShaderChunk("}", false); |
|||
} |
|||
|
|||
visitor.AddShaderChunk (outputString.GetShaderString (0), true); |
|||
} |
|||
} |
|||
} |
|
|||
fileFormatVersion: 2 |
|||
guid: 6af2205640e32994db6fd7de8aebf1de |
|||
MonoImporter: |
|||
serializedVersion: 2 |
|||
defaultReferences: [] |
|||
executionOrder: 0 |
|||
icon: {instanceID: 0} |
|||
userData: |
|
|||
namespace UnityEditor.Graphs.Material |
|||
{ |
|||
[Title("Input/Screen Pos Node")] |
|||
public class ScreenPosNode : BaseMaterialNode, IGeneratesVertexToFragmentBlock |
|||
{ |
|||
private const string kOutputSlotName = "ScreenPos"; |
|||
|
|||
public override bool hasPreview { get { return true; } } |
|||
|
|||
public override void Init() |
|||
{ |
|||
name = "ScreenPos"; |
|||
base.Init(); |
|||
AddSlot(new Slot(SlotType.OutputSlot, kOutputSlotName)); |
|||
} |
|||
|
|||
public override string GetOutputVariableNameForSlot(Slot slot, GenerationMode generationMode) |
|||
{ |
|||
return "IN.screenPos"; |
|||
} |
|||
|
|||
public void GenerateVertexToFragmentBlock(ShaderGenerator visitor, GenerationMode generationMode) |
|||
{ |
|||
visitor.AddShaderChunk(precision + "4 screenPos;", true); |
|||
} |
|||
} |
|||
} |
|
|||
fileFormatVersion: 2 |
|||
guid: e204c7999bfa0ee42a18d8a560a36244 |
|||
MonoImporter: |
|||
serializedVersion: 2 |
|||
defaultReferences: [] |
|||
executionOrder: 0 |
|||
icon: {instanceID: 0} |
|||
userData: |
|
|||
namespace UnityEditor.Graphs.Material |
|||
{ |
|||
[Title("Math/Sin Node")] |
|||
class SinNode : Function1Input |
|||
{ |
|||
public override void Init() |
|||
{ |
|||
name = "SinNode"; |
|||
base.Init(); |
|||
} |
|||
|
|||
protected override string GetFunctionName() {return "sin";} |
|||
} |
|||
} |
|
|||
fileFormatVersion: 2 |
|||
guid: 2b10d839969f5484cad9632519dc7324 |
|||
MonoImporter: |
|||
serializedVersion: 2 |
|||
defaultReferences: [] |
|||
executionOrder: 0 |
|||
icon: {instanceID: 0} |
|||
userData: |
部分文件因为文件数量过多而无法显示
撰写
预览
正在加载...
取消
保存
Reference in new issue