浏览代码

Fix Channel Mask node

- Convert to Abstract derived
- Move channel validation check to node side
- Cleanup
/main
Matt Dean 7 年前
当前提交
2cc3b58e
共有 2 个文件被更改,包括 77 次插入63 次删除
  1. 115
      MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/Nodes/Artistic/Mask/ChannelMaskNode.cs
  2. 25
      MaterialGraphProject/Assets/UnityShaderEditor/Editor/Drawing/Controls/ChannelEnumControl.cs

115
MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/Nodes/Artistic/Mask/ChannelMaskNode.cs


}
[Title("Artistic/Mask/Channel Mask")]
public class ChannelMaskNode : CodeFunctionNode
public class ChannelMaskNode : AbstractMaterialNode, IGeneratesBodyCode, IGeneratesFunction
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 string.Format("Unity_ChannelMask_{0}_{1}", channel, precision);
}
public sealed override void UpdateNodeAfterDeserialization()
{
AddSlot(new DynamicVectorMaterialSlot(InputSlotId, kInputSlotName, kInputSlotName, SlotType.Input, Vector3.zero));
AddSlot(new DynamicVectorMaterialSlot(OutputSlotId, kOutputSlotName, kOutputSlotName, SlotType.Output, Vector3.zero));
RemoveSlotsNameNotMatching(new[] { InputSlotId, OutputSlotId });
}
[SerializeField]

}
}
protected override MethodInfo GetFunctionToConvert()
void ValidateChannelCount()
switch (m_Channel)
{
case TextureChannel.Green:
return GetType().GetMethod("Unity_ChannelMask_Green", BindingFlags.Static | BindingFlags.NonPublic);
case TextureChannel.Blue:
return GetType().GetMethod("Unity_ChannelMask_Blue", BindingFlags.Static | BindingFlags.NonPublic);
case TextureChannel.Alpha:
return GetType().GetMethod("Unity_ChannelMask_Alpha", BindingFlags.Static | BindingFlags.NonPublic);
default:
return GetType().GetMethod("Unity_ChannelMask_Red", BindingFlags.Static | BindingFlags.NonPublic);
}
int channelCount = (int)SlotValueHelper.GetChannelCount(FindSlot<MaterialSlot>(InputSlotId).concreteValueType);
if ((int)channel >= channelCount)
channel = TextureChannel.Red;
static string Unity_ChannelMask_Red(
[Slot(0, Binding.None)] DynamicDimensionVector In,
[Slot(1, Binding.None)] out Vector4 Out)
string GetFunctionPrototype(string argIn, string argOut)
Out = Vector4.zero;
return
@"
{
Out = In.xxxx;
}";
return string.Format("void {0} ({1} {2}, out {3} {4})", GetFunctionName(),
ConvertConcreteSlotValueTypeToString(precision, FindInputSlot<DynamicVectorMaterialSlot>(InputSlotId).concreteValueType), argIn,
ConvertConcreteSlotValueTypeToString(precision, FindOutputSlot<DynamicVectorMaterialSlot>(OutputSlotId).concreteValueType), argOut);
static string Unity_ChannelMask_Green(
[Slot(0, Binding.None)] DynamicDimensionVector In,
[Slot(1, Binding.None)] out Vector4 Out)
public void GenerateNodeCode(ShaderGenerator visitor, GenerationMode generationMode)
Out = Vector4.zero;
return
@"
{
Out = In.yyyy;
}";
ValidateChannelCount();
string inputValue = GetSlotValue(InputSlotId, generationMode);
string outputValue = GetSlotValue(OutputSlotId, generationMode);
visitor.AddShaderChunk(string.Format("{0} {1};", ConvertConcreteSlotValueTypeToString(precision, FindInputSlot<MaterialSlot>(InputSlotId).concreteValueType), GetVariableNameForSlot(OutputSlotId)), true);
visitor.AddShaderChunk(GetFunctionCallBody(inputValue, outputValue), true);
static string Unity_ChannelMask_Blue(
[Slot(0, Binding.None)] DynamicDimensionVector In,
[Slot(1, Binding.None)] out Vector4 Out)
string GetFunctionCallBody(string inputValue, string outputValue)
Out = Vector4.zero;
return
@"
{
Out = In.zzzz;
}";
return GetFunctionName() + " (" + inputValue + ", " + outputValue + ");";
static string Unity_ChannelMask_Alpha(
[Slot(0, Binding.None)] DynamicDimensionVector In,
[Slot(1, Binding.None)] out Vector4 Out)
public void GenerateNodeFunction(ShaderGenerator visitor, GenerationMode generationMode)
Out = Vector4.zero;
return
@"
{
Out = In.wwww;
}";
ValidateChannelCount();
var outputString = new ShaderGenerator();
outputString.AddShaderChunk(GetFunctionPrototype("In", "Out"), false);
outputString.AddShaderChunk("{", false);
outputString.Indent();
switch(channel)
{
case TextureChannel.Green:
outputString.AddShaderChunk("Out = In.yyyy;", false);
break;
case TextureChannel.Blue:
outputString.AddShaderChunk("Out = In.zzzz;", false);
break;
case TextureChannel.Alpha:
outputString.AddShaderChunk("Out = In.wwww;", false);
break;
default:
outputString.AddShaderChunk("Out = In.xxxx;", false);
break;
}
outputString.Deindent();
outputString.AddShaderChunk("}", false);
visitor.AddShaderChunk(outputString.GetShaderString(0), true);
}
}
}

25
MaterialGraphProject/Assets/UnityShaderEditor/Editor/Drawing/Controls/ChannelEnumControl.cs


GUIContent m_Label;
AbstractMaterialNode m_Node;
PropertyInfo m_PropertyInfo;
IMGUIContainer m_Container;
int m_SlotId;
public ChannelEnumControlView(string label, int slotId, AbstractMaterialNode node, PropertyInfo propertyInfo)

if (!propertyInfo.PropertyType.IsEnum)
throw new ArgumentException("Property must be an enum.", "propertyInfo");
m_Label = new GUIContent(label ?? ObjectNames.NicifyVariableName(propertyInfo.Name));
Add(new IMGUIContainer(OnGUIHandler));
m_Container = new IMGUIContainer(OnGUIHandler);
Add(m_Container);
}
void OnGUIHandler()

public void OnNodeModified(ModificationScope scope)
{
if(scope == ModificationScope.Graph)
UpdatePopup();
if (scope == ModificationScope.Graph)
m_Container.Dirty(ChangeType.Repaint);
}
private void UpdatePopup()

{
int count = (int)SlotValueHelper.GetChannelCount(m_Node.FindSlot<MaterialSlot>(m_SlotId).concreteValueType);
if (value >= count)
{
m_Node.owner.owner.RegisterCompleteObjectUndo("Change " + m_Node.name);
m_PropertyInfo.SetValue(m_Node, 0, null);
return;
}
var entries = (Enum)m_PropertyInfo.GetValue(m_Node, null);
string[] enumNames = Enum.GetNames(entries.GetType());
string[] popupEntries = new string[count];
int channelCount = (int)SlotValueHelper.GetChannelCount(m_Node.FindSlot<MaterialSlot>(m_SlotId).concreteValueType);
var enumEntryCount = (Enum)m_PropertyInfo.GetValue(m_Node, null);
string[] enumEntryNames = Enum.GetNames(enumEntryCount.GetType());
string[] popupEntries = new string[channelCount];
popupEntries[i] = enumNames[i];
popupEntries[i] = enumEntryNames[i];
if (changeCheckScope.changed)
{
m_Node.owner.owner.RegisterCompleteObjectUndo("Change " + m_Node.name);

正在加载...
取消
保存