浏览代码

Merge pull request #85 from Unity-Technologies/node-channel

Node Channel
/main
GitHub 7 年前
当前提交
9ddf9039
共有 6 个文件被更改,包括 455 次插入94 次删除
  1. 7
      MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/Nodes/Channel/SplitNode.cs
  2. 254
      MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/Nodes/Channel/SwizzleNode.cs
  3. 188
      MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/Nodes/Channel/FlipNode.cs
  4. 11
      MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/Nodes/Channel/FlipNode.cs.meta
  5. 86
      MaterialGraphProject/Assets/UnityShaderEditor/Editor/Drawing/Controls/ToggleControl.cs
  6. 3
      MaterialGraphProject/Assets/UnityShaderEditor/Editor/Drawing/Controls/ToggleControl.cs.meta

7
MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/Nodes/Channel/SplitNode.cs


AddSlot(new Vector1MaterialSlot(OutputSlotGId, kOutputSlotGName, kOutputSlotGName, SlotType.Output, 0));
AddSlot(new Vector1MaterialSlot(OutputSlotBId, kOutputSlotBName, kOutputSlotBName, SlotType.Output, 0));
AddSlot(new Vector1MaterialSlot(OutputSlotAId, kOutputSlotAName, kOutputSlotAName, SlotType.Output, 0));
RemoveSlotsNameNotMatching(s_ValidSlots);
RemoveSlotsNameNotMatching(new int[] { InputSlotId, OutputSlotRId, OutputSlotGId, OutputSlotBId, OutputSlotAId });
static int[] s_ValidSlots = { InputSlotId, OutputSlotRId, OutputSlotGId, OutputSlotBId, OutputSlotAId };
NodeUtils.SlotConfigurationExceptionIfBadConfiguration(this, new[] { InputSlotId }, new[] { OutputSlotRId, OutputSlotGId, OutputSlotBId });
var inputValue = GetSlotValue(InputSlotId, generationMode);
var inputSlot = FindInputSlot<MaterialSlot>(InputSlotId);

for (var i = 0; i < 4; i++)
{
var outputValue = i >= numInputChannels ? "1.0" : string.Format("{0}[{1}]", inputValue, i);
var outputFormat = numInputChannels == 1 ? inputValue : string.Format("{0}[{1}]", inputValue, i);
var outputValue = i >= numInputChannels ? "0" : outputFormat;
visitor.AddShaderChunk(string.Format("{0} {1} = {2};", precision, GetVariableNameForSlot(s_OutputSlots[i]), outputValue), true);
}
}

254
MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/Nodes/Channel/SwizzleNode.cs


using UnityEditor.Graphing;
using System.Linq;
using UnityEditor.Graphing;
using UnityEditor.ShaderGraph.Drawing.Controls;
using UnityEngine;
/* [Title("Channel/Swizzle")]
public class SwizzleNode : Function1Input
{
public enum SwizzleChannel
{
R = 0,
G = 1,
B = 2,
A = 3,
}
[Title("Channel/Swizzle")]
public class SwizzleNode : AbstractMaterialNode, IGeneratesBodyCode, IGeneratesFunction
{
public SwizzleNode()
{
name = "Swizzle";
UpdateNodeAfterDeserialization();
}
[SerializeField]
private SwizzleChannel[] m_SwizzleChannels = new SwizzleChannel[4] { SwizzleChannel.R, SwizzleChannel.G, SwizzleChannel.B, SwizzleChannel.A };
const int InputSlotId = 0;
const int OutputSlotId = 1;
const string kInputSlotName = "In";
const string kOutputSlotName = "Out";
public SwizzleChannel[] swizzleChannels
{
get { return m_SwizzleChannels; }
set
{
if (m_SwizzleChannels == value)
return;
public override bool hasPreview
{
get { return true; }
}
m_SwizzleChannels = value;
if (onModified != null)
{
onModified(this, ModificationScope.Graph);
}
}
}
string GetFunctionName()
{
return "Unity_Swizzle_" + precision + "_" + GuidEncoder.Encode(guid);
}
public SwizzleNode()
{
name = "Swizzle";
}
public sealed override void UpdateNodeAfterDeserialization()
{
AddSlot(new DynamicVectorMaterialSlot(InputSlotId, kInputSlotName, kInputSlotName, SlotType.Input, Vector4.zero));
AddSlot(new Vector4MaterialSlot(OutputSlotId, kOutputSlotName, kOutputSlotName, SlotType.Output, Vector4.zero));
RemoveSlotsNameNotMatching(new[] { InputSlotId, OutputSlotId });
}
protected override string GetFunctionName()
{
return "";
}
static Dictionary<TextureChannel, string> m_ComponentList = new Dictionary<TextureChannel, string>
{
{TextureChannel.Red, ".r" },
{TextureChannel.Green, ".g" },
{TextureChannel.Blue, ".b" },
{TextureChannel.Alpha, ".a" },
};
protected override string GetFunctionCallBody(string inputValue)
{
string[] channelNames = { "r", "g", "b", "a" };
var inputSlot = FindInputSlot<MaterialSlot>(InputSlotId);
var outputSlot = FindOutputSlot<MaterialSlot>(OutputSlotId);
[SerializeField]
private TextureChannel m_RedChannel;
if (inputSlot == null)
return "1.0";
if (outputSlot == null)
return "1.0";
[ChannelEnumControl("Red Out")]
public TextureChannel redChannel
{
get { return m_RedChannel; }
set
{
if (m_RedChannel == value)
return;
int numInputChannels = (int)SlotValueHelper.GetChannelCount(inputSlot.concreteValueType);
int numOutputChannels = (int)SlotValueHelper.GetChannelCount(outputSlot.concreteValueType);
m_RedChannel = value;
if (onModified != null)
{
onModified(this, ModificationScope.Graph);
}
}
}
//int numInputChannels = (int)inputSlot.concreteValueType;
int numOutputChannels = (int)outputSlot.concreteValueType;
if (owner.GetEdges(inputSlot.slotReference).ToList().Count() == 0)
numInputChannels = 0;
if (owner.GetEdges(outputSlot.slotReference).ToList().Count() == 0)
numOutputChannels = 0;
[SerializeField]
private TextureChannel m_GreenChannel;
if (numOutputChannels == 0)
{
return "1.0";
}
[ChannelEnumControl("Green Out")]
public TextureChannel greenChannel
{
get { return m_GreenChannel; }
set
{
if (m_GreenChannel == value)
return;
string outputString = precision + "4(";
//float4(1.0,1.0,1.0,1.0)
if (numInputChannels == 0)
{
outputString += "1.0, 1.0, 1.0, 1.0).";
}
else
{
//float4(arg1.
outputString += inputValue + ".";
m_GreenChannel = value;
if (onModified != null)
{
onModified(this, ModificationScope.Graph);
}
}
}
[SerializeField]
private TextureChannel m_BlueChannel;
[ChannelEnumControl("Blue Out")]
public TextureChannel blueChannel
{
get { return m_BlueChannel; }
set
{
if (m_BlueChannel == value)
return;
m_BlueChannel = value;
if (onModified != null)
{
onModified(this, ModificationScope.Graph);
}
}
}
[SerializeField]
private TextureChannel m_AlphaChannel;
[ChannelEnumControl("Alpha Out")]
public TextureChannel alphaChannel
{
get { return m_AlphaChannel; }
set
{
if (m_AlphaChannel == value)
return;
m_AlphaChannel = value;
if (onModified != null)
{
onModified(this, ModificationScope.Graph);
}
}
}
void ValidateChannelCount()
{
int channelCount = (int)SlotValueHelper.GetChannelCount(FindInputSlot<MaterialSlot>(InputSlotId).concreteValueType);
if ((int)redChannel >= channelCount)
redChannel = TextureChannel.Red;
if ((int)greenChannel >= channelCount)
greenChannel = TextureChannel.Red;
if ((int)blueChannel >= channelCount)
blueChannel = TextureChannel.Red;
if ((int)alphaChannel >= channelCount)
alphaChannel = TextureChannel.Red;
}
string GetFunctionPrototype(string inArg, string outArg)
{
return string.Format("void {0} ({1} {2}, out {3} {4})", GetFunctionName(),
ConvertConcreteSlotValueTypeToString(precision, FindInputSlot<MaterialSlot>(InputSlotId).concreteValueType), inArg,
ConvertConcreteSlotValueTypeToString(precision, FindOutputSlot<MaterialSlot>(OutputSlotId).concreteValueType), outArg);
}
//float4(arg1.xy
int i = 0;
for (; i < numInputChannels; ++i)
{
int channel = (int)m_SwizzleChannels[i];
outputString += channelNames[channel];
}
public void GenerateNodeCode(ShaderGenerator visitor, GenerationMode generationMode)
{
ValidateChannelCount();
string inputValue = GetSlotValue(InputSlotId, generationMode);
string outputValue = GetSlotValue(OutputSlotId, generationMode);
visitor.AddShaderChunk(string.Format("{0} {1};", ConvertConcreteSlotValueTypeToString(precision, FindOutputSlot<MaterialSlot>(OutputSlotId).concreteValueType), GetVariableNameForSlot(OutputSlotId)), true);
visitor.AddShaderChunk(GetFunctionCallBody(inputValue, outputValue), true);
}
string GetFunctionCallBody(string inputValue, string outputValue)
{
return GetFunctionName() + " (" + inputValue + ", " + outputValue + ");";
}
public void GenerateNodeFunction(ShaderGenerator visitor, GenerationMode generationMode)
{
ValidateChannelCount();
var outputString = new ShaderGenerator();
outputString.AddShaderChunk(GetFunctionPrototype("In", "Out"), true);
outputString.AddShaderChunk("{", true);
outputString.Indent();
outputString.AddShaderChunk(string.Format("Out = {0} ({1}, {2}, {3}, {4});",
ConvertConcreteSlotValueTypeToString(precision, FindOutputSlot<MaterialSlot>(OutputSlotId).concreteValueType),
kInputSlotName + m_ComponentList[m_RedChannel],
kInputSlotName + m_ComponentList[m_GreenChannel],
kInputSlotName + m_ComponentList[m_BlueChannel],
kInputSlotName + m_ComponentList[m_AlphaChannel]), true);
//float4(arg1.xy, 1.0, 1.0)
for (; i < 4; i++)
{
outputString += ", 1.0";
}
outputString += ").";
}
outputString.Deindent();
outputString.AddShaderChunk("}", true);
//float4(arg1.xy, 1.0, 1.0).rg
for (int j = 0; j < numOutputChannels; ++j)
{
outputString += channelNames[j];
}
return outputString;
}
}*/
}
visitor.AddShaderChunk(outputString.GetShaderString(0), true);
}
}
}

188
MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/Nodes/Channel/FlipNode.cs


using System;
using System.Collections.Generic;
using UnityEditor.Graphing;
using UnityEditor.ShaderGraph.Drawing.Controls;
using UnityEngine;
namespace UnityEditor.ShaderGraph
{
[Title("Channel/Flip")]
public class FlipNode : AbstractMaterialNode, IGeneratesBodyCode, IGeneratesFunction
{
public FlipNode()
{
name = "Flip";
UpdateNodeAfterDeserialization();
}
const int InputSlotId = 0;
const int OutputSlotId = 1;
const string kInputSlotName = "In";
const string kOutputSlotName = "Out";
public override bool hasPreview
{
get { return true; }
}
string GetFunctionName()
{
return "Unity_Flip_" + ConvertConcreteSlotValueTypeToString(precision, FindOutputSlot<MaterialSlot>(OutputSlotId).concreteValueType);
}
public sealed override void UpdateNodeAfterDeserialization()
{
AddSlot(new DynamicVectorMaterialSlot(InputSlotId, kInputSlotName, kInputSlotName, SlotType.Input, Vector4.zero));
AddSlot(new DynamicVectorMaterialSlot(OutputSlotId, kOutputSlotName, kOutputSlotName, SlotType.Output, Vector4.zero));
RemoveSlotsNameNotMatching(new[] { InputSlotId, OutputSlotId });
}
int channelCount { get { return (int)SlotValueHelper.GetChannelCount(FindSlot<MaterialSlot>(InputSlotId).concreteValueType); } }
[SerializeField]
private bool m_RedChannel;
[ToggleControl("Red")]
public Toggle redChannel
{
get { return new Toggle(m_RedChannel, channelCount > 0); }
set
{
if (m_RedChannel == value.isOn)
return;
m_RedChannel = value.isOn;
if (onModified != null)
{
onModified(this, ModificationScope.Node);
}
}
}
[SerializeField]
private bool m_GreenChannel;
[ToggleControl("Green")]
public Toggle greenChannel
{
get { return new Toggle(m_GreenChannel, channelCount > 1); }
set
{
if (m_GreenChannel == value.isOn)
return;
m_GreenChannel = value.isOn;
if (onModified != null)
{
onModified(this, ModificationScope.Node);
}
}
}
[SerializeField]
private bool m_BlueChannel;
[ToggleControl("Blue")]
public Toggle blueChannel
{
get { return new Toggle(m_BlueChannel, channelCount > 2); }
set
{
if (m_BlueChannel == value.isOn)
return;
m_BlueChannel = value.isOn;
if (onModified != null)
{
onModified(this, ModificationScope.Node);
}
}
}
private bool m_AlphaChannel;
[ToggleControl("Alpha")]
public Toggle alphaChannel
{
get { return new Toggle(m_AlphaChannel, channelCount > 3); }
set
{
if (m_AlphaChannel == value.isOn)
return;
m_AlphaChannel = value.isOn;
if (onModified != null)
{
onModified(this, ModificationScope.Node);
}
}
}
string GetFunctionPrototype(string inArg, string flipArg, string outArg)
{
return string.Format("void {0} ({1} {2}, {3} {4}, out {5} {6})", GetFunctionName(),
ConvertConcreteSlotValueTypeToString(precision, FindInputSlot<MaterialSlot>(InputSlotId).concreteValueType), inArg,
ConvertConcreteSlotValueTypeToString(precision, FindInputSlot<MaterialSlot>(InputSlotId).concreteValueType), flipArg,
ConvertConcreteSlotValueTypeToString(precision, FindOutputSlot<MaterialSlot>(OutputSlotId).concreteValueType), outArg);
}
public void GenerateNodeCode(ShaderGenerator visitor, GenerationMode generationMode)
{
string inputValue = GetSlotValue(InputSlotId, generationMode);
string outputValue = GetSlotValue(OutputSlotId, generationMode);
visitor.AddShaderChunk(string.Format("{0} {1};", ConvertConcreteSlotValueTypeToString(precision, FindOutputSlot<MaterialSlot>(OutputSlotId).concreteValueType), GetVariableNameForSlot(OutputSlotId)), true);
if(!generationMode.IsPreview())
{
visitor.AddShaderChunk(string.Format("{0} _{1}_Flip = {0} ({2}{3}{4}{5});",
ConvertConcreteSlotValueTypeToString(precision, FindOutputSlot<MaterialSlot>(OutputSlotId).concreteValueType),
GetVariableNameForNode(),
Convert.ToInt32(m_RedChannel).ToString(),
channelCount > 1 ? string.Format(", {0}", (Convert.ToInt32(m_GreenChannel)).ToString()) : "",
channelCount > 2 ? string.Format(", {0}", (Convert.ToInt32(m_BlueChannel)).ToString()) : "",
channelCount > 3 ? string.Format(", {0}", (Convert.ToInt32(m_AlphaChannel)).ToString()) : ""), true);
}
visitor.AddShaderChunk(GetFunctionCallBody(inputValue, string.Format("_{0}_Flip", GetVariableNameForNode()), outputValue), true);
}
string GetFunctionCallBody(string inputValue, string flipValue, string outputValue)
{
return GetFunctionName() + " (" + inputValue + ", " + flipValue + ", " + outputValue + ");";
}
public override void CollectPreviewMaterialProperties(List<PreviewProperty> properties)
{
base.CollectPreviewMaterialProperties(properties);
properties.Add(new PreviewProperty()
{
m_Name = string.Format("_{0}_Flip", GetVariableNameForNode()),
m_PropType = PropertyType.Vector4,
m_Vector4 = new Vector4(Convert.ToInt32(m_RedChannel), Convert.ToInt32(m_GreenChannel), Convert.ToInt32(m_BlueChannel), Convert.ToInt32(m_AlphaChannel)),
});
}
public override void CollectShaderProperties(PropertyCollector properties, GenerationMode generationMode)
{
if (!generationMode.IsPreview())
return;
base.CollectShaderProperties(properties, generationMode);
properties.AddShaderProperty(new Vector4ShaderProperty
{
overrideReferenceName = string.Format("_{0}_Flip", GetVariableNameForNode()),
generatePropertyBlock = false
});
}
public void GenerateNodeFunction(ShaderGenerator visitor, GenerationMode generationMode)
{
var outputString = new ShaderGenerator();
outputString.AddShaderChunk(GetFunctionPrototype("In", "Flip", "Out"), true);
outputString.AddShaderChunk("{", true);
outputString.Indent();
outputString.AddShaderChunk("Out = abs(Flip - In);", true);
outputString.Deindent();
outputString.AddShaderChunk("}", true);
visitor.AddShaderChunk(outputString.GetShaderString(0), true);
}
}
}

11
MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/Nodes/Channel/FlipNode.cs.meta


fileFormatVersion: 2
guid: fa443691530c547418e195e22597f2af
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

86
MaterialGraphProject/Assets/UnityShaderEditor/Editor/Drawing/Controls/ToggleControl.cs


using System;
using System.Reflection;
using UnityEngine;
using UnityEditor.Graphing;
using UnityEngine.Experimental.UIElements;
namespace UnityEditor.ShaderGraph.Drawing.Controls
{
[Serializable]
public struct Toggle
{
public bool isOn;
public bool isEnabled;
public Toggle(bool on, bool enabled)
{
isOn = on;
isEnabled = enabled;
}
public Toggle(bool on)
{
isOn = on;
isEnabled = true;
}
}
[AttributeUsage(AttributeTargets.Property)]
public class ToggleControlAttribute : Attribute, IControlAttribute
{
string m_Label;
public ToggleControlAttribute(string label = null)
{
m_Label = label;
}
public VisualElement InstantiateControl(AbstractMaterialNode node, PropertyInfo propertyInfo)
{
return new ToggleControlView(m_Label, node, propertyInfo);
}
}
public class ToggleControlView : VisualElement, INodeModificationListener
{
GUIContent m_Label;
AbstractMaterialNode m_Node;
PropertyInfo m_PropertyInfo;
IMGUIContainer m_Container;
public ToggleControlView(string label, AbstractMaterialNode node, PropertyInfo propertyInfo)
{
m_Node = node;
m_PropertyInfo = propertyInfo;
if (propertyInfo.PropertyType != typeof(Toggle))
throw new ArgumentException("Property must be a Toggle.", "propertyInfo");
m_Label = new GUIContent(label ?? ObjectNames.NicifyVariableName(propertyInfo.Name));
m_Container = new IMGUIContainer(OnGUIHandler);
Add(m_Container);
}
public void OnNodeModified(ModificationScope scope)
{
if (scope == ModificationScope.Graph)
m_Container.Dirty(ChangeType.Repaint);
}
void OnGUIHandler()
{
var value = (Toggle) m_PropertyInfo.GetValue(m_Node, null);
using (var changeCheckScope = new EditorGUI.ChangeCheckScope())
{
m_Container.SetEnabled(value.isEnabled);
bool isOn = EditorGUILayout.Toggle(m_Label, value.isOn);
value = new Toggle(isOn, value.isEnabled);
if (changeCheckScope.changed)
{
m_Node.owner.owner.RegisterCompleteObjectUndo("Change " + m_Node.name);
m_PropertyInfo.SetValue(m_Node, value, null);
}
}
}
}
}

3
MaterialGraphProject/Assets/UnityShaderEditor/Editor/Drawing/Controls/ToggleControl.cs.meta


fileFormatVersion: 2
guid: 5e83ab8eb10c20c4fbed2700d4f4f11c
timeCreated: 1507817885
正在加载...
取消
保存