浏览代码

[Shader Graph]

Add preview for main node
Allow overriding of preview size per node
Fix issue with preview generation happening before active nodes were recached
Allow 'preview' generation to generate surface shaders
Fix bug in function3 nodes
/main
Tim Cooper 9 年前
当前提交
e1a0768f
共有 12 个文件被更改,包括 127 次插入57 次删除
  1. 6
      UnityProject/Assets/UnityShaderEditor/Editor/Source/BaseMaterialGraph.cs
  2. 2
      UnityProject/Assets/UnityShaderEditor/Editor/Source/Light/BaseLightFunction.cs
  3. 28
      UnityProject/Assets/UnityShaderEditor/Editor/Source/MaterialGraph.cs
  4. 5
      UnityProject/Assets/UnityShaderEditor/Editor/Source/MaterialGraphGUI.cs
  5. 7
      UnityProject/Assets/UnityShaderEditor/Editor/Source/MaterialSubGraph.cs
  6. 26
      UnityProject/Assets/UnityShaderEditor/Editor/Source/Nodes/BaseMaterialNode.cs
  7. 2
      UnityProject/Assets/UnityShaderEditor/Editor/Source/Nodes/Function3Input.cs
  8. 4
      UnityProject/Assets/UnityShaderEditor/Editor/Source/Nodes/PerlinNode.cs
  9. 35
      UnityProject/Assets/UnityShaderEditor/Editor/Source/Nodes/PixelShaderNode.cs
  10. 48
      UnityProject/Assets/UnityShaderEditor/Editor/Source/PixelGraph.cs
  11. 17
      UnityProject/Assets/UnityShaderEditor/Editor/Source/Util/ShaderGenerator.cs
  12. 4
      UnityProject/UnityProject.sln.DotSettings

6
UnityProject/Assets/UnityShaderEditor/Editor/Source/BaseMaterialGraph.cs


{
get { return isAwake && nodes.Any(x => x is IRequiresTime); }
}
protected abstract void RecacheActiveNodes();
public override void RemoveEdge(Edge e)
{

if (toNode == null)
return;
RecacheActiveNodes();
toNode.RegeneratePreviewShaders();
}

if (fromNode == null || toNode == null)
return edge;
RecacheActiveNodes();
toNode.RegeneratePreviewShaders();
fromNode.CollectChildNodesByExecutionOrder().ToList().ForEach(s => s.UpdatePreviewProperties());

2
UnityProject/Assets/UnityShaderEditor/Editor/Source/Light/BaseLightFunction.cs


using System;
using UnityEngine;
namespace UnityEditor.Graphs.Material
{

28
UnityProject/Assets/UnityShaderEditor/Editor/Source/MaterialGraph.cs


public int GetShaderInstanceID()
{
Debug.Log("Returning: " + m_Shader.GetInstanceID());
return m_Shader.GetInstanceID();
}

public void UpdateShaderSource(string src, Dictionary<string, Texture> defaultTexutres)
{
UnityEditor.ShaderUtil.UpdateShaderAsset(m_Shader, src);
ShaderUtil.UpdateShaderAsset(m_Shader, src);
EditorMaterialUtility.SetShaderDefaults(m_Shader, defaultTexutres.Keys.ToArray(), defaultTexutres.Values.ToArray());
}

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 }" +
" }" +
"}" +
"}";
"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 = UnityEditor.ShaderUtil.CreateShaderAsset(shaderSource);
m_Shader = ShaderUtil.CreateShaderAsset(shaderSource);
m_PixelGraph.AddMasterNodeToAsset();
}
}
}

5
UnityProject/Assets/UnityShaderEditor/Editor/Source/MaterialGraphGUI.cs


using System.Collections.Generic;
using System.IO;
using UnityEngine;
using System.Linq;

GUILayout.FlexibleSpace();
if (GUILayout.Button("Output Shader :)"))
{
ShaderGenerator.GenerateSurfaceShader(graph);
Dictionary<string, Texture> defaultTextures;
var shader = ShaderGenerator.GenerateSurfaceShader(graph, graph.name, false, out defaultTextures);
graph.UpdateShaderSource(shader, defaultTextures);
}
GUILayout.EndArea();
}

7
UnityProject/Assets/UnityShaderEditor/Editor/Source/MaterialSubGraph.cs


using System;
using System.Collections.Generic;
using System.Collections.Generic;
using UnityEngine;
namespace UnityEditor.Graphs.Material

public SubGraphOutputsNode outputsNode { get { return m_OutputsNode; } }
public override BaseMaterialNode masterNode { get { return outputsNode; } }
protected override void RecacheActiveNodes()
{
}
public new void OnEnable()
{

26
UnityProject/Assets/UnityShaderEditor/Editor/Source/Nodes/BaseMaterialNode.cs


using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using UnityEditorInternal;
using UnityEngine;

}
private static Shader m_DefaultPreviewShader;
private static Shader defaultPreviewShader
protected static Shader defaultPreviewShader
{
get
{

}
}
private UnityEngine.Material previewMaterial
protected UnityEngine.Material previewMaterial
{
get
{

}
}
private PreviewMode m_GeneratedShaderMode = PreviewMode.Preview2D;
protected PreviewMode m_GeneratedShaderMode = PreviewMode.Preview2D;
protected virtual int previewWidth
{
get { return kPreviewWidth; }
}
protected virtual int previewHeight
{
get { return kPreviewHeight; }
}
#endregion
public virtual void Init()

if (!ShaderUtil.hardwareSupportsRectRenderTexture)
return;
GUILayout.BeginHorizontal(GUILayout.MinWidth(kPreviewWidth + 10), GUILayout.MinWidth(kPreviewHeight + 10));
GUILayout.BeginHorizontal(GUILayout.MinWidth(previewWidth + 10), GUILayout.MinWidth(previewHeight + 10));
var rect = GUILayoutUtility.GetRect(kPreviewWidth, kPreviewHeight, GUILayout.ExpandWidth(false));
var rect = GUILayoutUtility.GetRect(previewWidth, previewHeight, GUILayout.ExpandWidth(false));
var preview = RenderPreview(rect);
GUILayout.FlexibleSpace();
GUILayout.EndHorizontal();

{
MaterialWindow.DebugMaterialGraph("RecreateShaderAndMaterial : " + name + "_" + GetInstanceID());
var resultShader = ShaderGenerator.GeneratePreviewShader(this, out m_GeneratedShaderMode);
MaterialWindow.DebugMaterialGraph(resultShader);

previewMaterial.shader = UnityEditor.ShaderUtil.CreateShaderAsset(resultShader);
previewMaterial.shader = ShaderUtil.CreateShaderAsset(resultShader);
previewMaterial.shader.hideFlags = HideFlags.DontSave;
return true;
}

2
UnityProject/Assets/UnityShaderEditor/Editor/Source/Nodes/Function3Input.cs


string input1Value = GetSlotValue(inputSlot1, generationMode);
string input2Value = GetSlotValue(inputSlot2, generationMode);
string input3Value = GetSlotValue(inputSlot2, generationMode);
string input3Value = GetSlotValue(inputSlot3, generationMode);
visitor.AddShaderChunk(precision + "4 " + GetOutputVariableNameForSlot(outputSlot, generationMode) + " = " + GetFunctionCallBody(input1Value, input2Value, input3Value) + ";", true);
}

4
UnityProject/Assets/UnityShaderEditor/Editor/Source/Nodes/PerlinNode.cs


using System;
using System.Linq;
using UnityEngine;
namespace UnityEditor.Graphs.Material

return value;
}
public override void NodeUI(Graphs.GraphGUI host)
public override void NodeUI(GraphGUI host)
{
base.NodeUI(host);

35
UnityProject/Assets/UnityShaderEditor/Editor/Source/Nodes/PixelShaderNode.cs


private static List<BaseLightFunction> s_LightFunctions;
protected override int previewWidth
{
get { return 300; }
}
protected override int previewHeight
{
get { return 300; }
}
public override void Init()
{
name = "PixelMaster";

return GetOutputVariableNameForNode();
}
public override void NodeUI(Graphs.GraphGUI host)
public override void NodeUI(GraphGUI host)
{
base.NodeUI(host);
var lightFunctions = GetLightFunctions();

if (lightFunction != null)
lightFuncIndex = lightFunctions.IndexOf(lightFunction);
EditorGUI.BeginChangeCheck();
if (EditorGUI.EndChangeCheck())
RegeneratePreviewShaders();
}
public override bool hasPreview
{
get { return true; }
}
public override bool UpdatePreviewMaterial()
{
Dictionary<string, Texture> defaultTextures;
var shaderName = "Hidden/PreviewShader/" + name + "_" + Math.Abs(GetInstanceID());;
var resultShader = ShaderGenerator.GenerateSurfaceShader(pixelGraph.owner, shaderName, true, out defaultTextures);
m_GeneratedShaderMode = PreviewMode.Preview3D;
if (previewMaterial.shader != defaultPreviewShader)
DestroyImmediate(previewMaterial.shader, true);
previewMaterial.shader = ShaderUtil.CreateShaderAsset(resultShader);
EditorMaterialUtility.SetShaderDefaults(previewMaterial.shader, defaultTextures.Keys.ToArray(), defaultTextures.Values.ToArray());
previewMaterial.shader.hideFlags = HideFlags.DontSave;
return true;
}
}
}

48
UnityProject/Assets/UnityShaderEditor/Editor/Source/PixelGraph.cs


using System;
using System.Collections.Generic;
using System.Linq;
using UnityEngine;

get { return pixelMasterNode; }
}
public override void OnEnable()
{
base.OnEnable();
if (m_PixelMasterNode == null)
m_PixelMasterNode = nodes.FirstOrDefault(x => x.GetType() == typeof (PixelShaderNode)) as PixelShaderNode;
if (m_PixelMasterNode == null)
{
m_PixelMasterNode = CreateInstance<PixelShaderNode>();
m_PixelMasterNode.hideFlags = HideFlags.HideInHierarchy;
m_PixelMasterNode.Init();
m_PixelMasterNode.position = new Rect(700, m_PixelMasterNode.position.y, m_PixelMasterNode.position.width, m_PixelMasterNode.position.height);
AddMasterNodeNoAddToAsset(m_PixelMasterNode);
}
}
public PixelShaderNode pixelMasterNode
{
get

{
get
{
if (m_ActiveNodes == null)
if (m_ActiveNodes == null)
m_ActiveNodes = pixelMasterNode.CollectChildNodesByExecutionOrder();
return m_ActiveNodes;
}

ShaderGenerator nodeFunction,
PropertyGenerator shaderProperties,
ShaderGenerator propertyUsages,
ShaderGenerator vertexShader)
ShaderGenerator vertexShader,
bool isPreview)
owner.materialProperties.GenerateSharedProperties(shaderProperties, propertyUsages, GenerationMode.SurfaceShader);
var genMode = isPreview ? GenerationMode.Preview3D : GenerationMode.SurfaceShader;
owner.materialProperties.GenerateSharedProperties(shaderProperties, propertyUsages, genMode);
if (node is IGeneratesFunction) (node as IGeneratesFunction).GenerateNodeFunction(nodeFunction, GenerationMode.SurfaceShader);
if (node is IGeneratesVertexToFragmentBlock) (node as IGeneratesVertexToFragmentBlock).GenerateVertexToFragmentBlock(inputStruct, GenerationMode.SurfaceShader);
if (node is IGeneratesVertexShaderBlock) (node as IGeneratesVertexShaderBlock).GenerateVertexShaderBlock(vertexShader, GenerationMode.SurfaceShader);
if (node is IGeneratesFunction) (node as IGeneratesFunction).GenerateNodeFunction(nodeFunction, genMode);
if (node is IGeneratesVertexToFragmentBlock) (node as IGeneratesVertexToFragmentBlock).GenerateVertexToFragmentBlock(inputStruct, genMode);
if (node is IGeneratesVertexShaderBlock) (node as IGeneratesVertexShaderBlock).GenerateVertexShaderBlock(vertexShader, genMode);
(node as IGenerateProperties).GeneratePropertyBlock(shaderProperties, GenerationMode.SurfaceShader);
(node as IGenerateProperties).GeneratePropertyUsages(propertyUsages, GenerationMode.SurfaceShader);
(node as IGenerateProperties).GeneratePropertyBlock(shaderProperties, genMode);
(node as IGenerateProperties).GeneratePropertyUsages(propertyUsages, genMode);
pixelMasterNode.GenerateNodeCode(shaderBody, GenerationMode.SurfaceShader);
pixelMasterNode.GenerateNodeCode(shaderBody, genMode);
public override void RemoveEdge(Edge e)
public void AddMasterNodeToAsset()
base.RemoveEdge(e);
m_ActiveNodes = pixelMasterNode.CollectChildNodesByExecutionOrder();
AssetDatabase.AddObjectToAsset(pixelMasterNode, this);
public override Edge Connect(Slot fromSlot, Slot toSlot)
protected override void RecacheActiveNodes()
var ret = base.Connect(fromSlot, toSlot);
return ret;
}
}
}

17
UnityProject/Assets/UnityShaderEditor/Editor/Source/Util/ShaderGenerator.cs


return template;
}
public static void GenerateSurfaceShader(MaterialGraph graph)
public static string GenerateSurfaceShader(MaterialGraph graph, string shaderName, bool isPreview, out Dictionary<string, Texture> defaultTextures)
return;
{
defaultTextures = new Dictionary<string, Texture>();
return string.Empty;
}
var templateText = File.ReadAllText(templateLocation);

shaderFunctionVisitor,
shaderPropertiesVisitor,
shaderPropertyUsagesVisitor,
vertexShaderBlock);
vertexShaderBlock,
isPreview);
if (shaderInputVisitor.numberOfChunks == 0)
{

options.GetDepthTest(zTestVisitor);
options.GetDepthWrite(zWriteVisitor);
var resultShader = templateText.Replace("${ShaderName}", graph.name);
var resultShader = templateText.Replace("${ShaderName}", shaderName);
resultShader = resultShader.Replace("${ShaderPropertiesHeader}", shaderPropertiesVisitor.GetShaderString(2));
resultShader = resultShader.Replace("${ShaderPropertyUsages}", shaderPropertyUsagesVisitor.GetShaderString(2));
resultShader = resultShader.Replace("${LightingFunctionName}", shaderLightFunctionVisitor.GetPragmaString());

resultShader = resultShader.Replace("${VertexShaderBody}", "");
}
//Build a map of default
graph.UpdateShaderSource(resultShader, shaderPropertiesVisitor.GetDefaultTexutres());
defaultTextures = shaderPropertiesVisitor.GetDefaultTexutres();
return resultShader;
}
public int numberOfChunks

4
UnityProject/UnityProject.sln.DotSettings


<s:String x:Key="/Default/CodeStyle/Naming/VBNaming/PredefinedNamingRules/=PublicFields/@EntryIndexedValue">&lt;Policy Inspect="True" Prefix="" Suffix="" Style="AaBb"&gt;&lt;ExtraRule Prefix="m_" Suffix="" Style="AaBb" /&gt;&lt;/Policy&gt;</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/VBNaming/PredefinedNamingRules/=StaticReadonly/@EntryIndexedValue">&lt;Policy Inspect="True" Prefix="s_" Suffix="" Style="AaBb" /&gt;</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/VBNaming/PredefinedNamingRules/=TypeParameters/@EntryIndexedValue">&lt;Policy Inspect="True" Prefix="T" Suffix="" Style="AaBb" /&gt;</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/VBNaming/PredefinedNamingRules/=TypesAndNamespaces/@EntryIndexedValue">&lt;Policy Inspect="True" Prefix="" Suffix="" Style="AaBb" /&gt;</s:String></wpf:ResourceDictionary>
<s:String x:Key="/Default/CodeStyle/Naming/VBNaming/PredefinedNamingRules/=TypesAndNamespaces/@EntryIndexedValue">&lt;Policy Inspect="True" Prefix="" Suffix="" Style="AaBb" /&gt;</s:String>
<s:Boolean x:Key="/Default/Environment/SettingsMigration/IsMigratorApplied/=JetBrains_002EReSharper_002EPsi_002ECSharp_002ECodeStyle_002ESettingsUpgrade_002EMigrateBlankLinesAroundFieldToBlankLinesAroundProperty/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/Environment/SettingsMigration/IsMigratorApplied/=JetBrains_002EReSharper_002EPsi_002ECSharp_002ECodeStyle_002ESettingsUpgrade_002EMigrateThisQualifierSettings/@EntryIndexedValue">True</s:Boolean></wpf:ResourceDictionary>
正在加载...
取消
保存