浏览代码

Added Channel Mixer Node

/main
Matt Dean 7 年前
当前提交
711f81fa
共有 4 个文件被更改,包括 290 次插入0 次删除
  1. 150
      MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/Nodes/Artistic/Adjustment/ChannelMixerNode.cs
  2. 11
      MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/Nodes/Artistic/Adjustment/ChannelMixerNode.cs.meta
  3. 118
      MaterialGraphProject/Assets/UnityShaderEditor/Editor/Drawing/Controls/ChannelMixerControl.cs
  4. 11
      MaterialGraphProject/Assets/UnityShaderEditor/Editor/Drawing/Controls/ChannelMixerControl.cs.meta

150
MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/Nodes/Artistic/Adjustment/ChannelMixerNode.cs


using System;
using UnityEditor.Graphing;
using UnityEditor.ShaderGraph.Drawing.Controls;
using UnityEngine;
namespace UnityEditor.ShaderGraph
{
[Title("Artistic/Adjustment/Channel Mixer")]
public class ChannelMixerNode : AbstractMaterialNode, IGeneratesBodyCode, IGeneratesFunction
{
public ChannelMixerNode()
{
name = "Channel Mixer";
UpdateNodeAfterDeserialization();
}
private const int InputSlotId = 0;
private const int OutputSlotId = 1;
private const string kInputSlotName = "In";
private const string kOutputSlotName = "Out";
public override bool hasPreview
{
get { return true; }
}
protected string GetFunctionName()
{
return "Unity_ChannelMixer_" + precision;
}
public sealed override void UpdateNodeAfterDeserialization()
{
AddSlot(GetInputSlot());
AddSlot(GetOutputSlot());
RemoveSlotsNameNotMatching(validSlots);
}
protected int[] validSlots
{
get { return new[] { InputSlotId, OutputSlotId }; }
}
protected virtual MaterialSlot GetInputSlot()
{
return new Vector3MaterialSlot(InputSlotId, kInputSlotName, kInputSlotName, SlotType.Input, Vector3.zero);
}
protected virtual MaterialSlot GetOutputSlot()
{
return new Vector3MaterialSlot(OutputSlotId, kOutputSlotName, kOutputSlotName, SlotType.Output, Vector3.zero);
}
[Serializable]
public class ChannelMixer
{
public OutChannel[] outChannels;
public ChannelMixer(OutChannel[] c)
{
outChannels = c;
}
}
[Serializable]
public class OutChannel
{
public float[] inChannels;
public OutChannel(float[] c)
{
inChannels = c;
}
}
[SerializeField]
private ChannelMixer m_ChannelMixer;
[ChannelMixerControl("")]
public ChannelMixer channelMixer
{
get
{
if(m_ChannelMixer == null)
{
m_ChannelMixer = new ChannelMixer(
new OutChannel[3]
{
new OutChannel( new float[3] { 1, 0, 0 } ),
new OutChannel( new float[3] { 0, 1, 0 } ),
new OutChannel( new float[3] { 0, 0, 1 } )
});
}
return m_ChannelMixer;
}
set
{
/*if (m_ChannelMixer == value) // This is always true with nested arrays in a class
return;*/
m_ChannelMixer = value;
if (onModified != null)
{
onModified(this, ModificationScope.Graph);
}
}
}
protected string GetFunctionPrototype(string arg1Name, string arg2Name)
{
return string.Format("void {0} ({1} {2}, out {3} {4})", GetFunctionName(), ConvertConcreteSlotValueTypeToString(precision, FindInputSlot<MaterialSlot>(InputSlotId).concreteValueType), arg1Name, ConvertConcreteSlotValueTypeToString(precision, FindOutputSlot<MaterialSlot>(OutputSlotId).concreteValueType), arg2Name);
}
public void GenerateNodeCode(ShaderGenerator visitor, GenerationMode generationMode)
{
NodeUtils.SlotConfigurationExceptionIfBadConfiguration(this, new[] { InputSlotId }, new[] { OutputSlotId });
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);
}
protected string GetFunctionCallBody(string inputValue, string outputValue)
{
return GetFunctionName() + " (" + inputValue + ", " + outputValue + ");";
}
public void GenerateNodeFunction(ShaderGenerator visitor, GenerationMode generationMode)
{
var outputString = new ShaderGenerator();
outputString.AddShaderChunk(GetFunctionPrototype("In", "Out"), false);
outputString.AddShaderChunk("{", false);
outputString.Indent();
outputString.AddShaderChunk(string.Format("{0}3 red = {0}3 ({1}, {2}, {3});",
precision, channelMixer.outChannels[0].inChannels[0], channelMixer.outChannels[0].inChannels[1], channelMixer.outChannels[0].inChannels[2]), true);
outputString.AddShaderChunk(string.Format("{0}3 green = {0}3 ({1}, {2}, {3});",
precision, channelMixer.outChannels[1].inChannels[0], channelMixer.outChannels[1].inChannels[1], channelMixer.outChannels[1].inChannels[2]), true);
outputString.AddShaderChunk(string.Format("{0}3 blue = {0}3 ({1}, {2}, {3});",
precision, channelMixer.outChannels[2].inChannels[0], channelMixer.outChannels[2].inChannels[1], channelMixer.outChannels[2].inChannels[2]), true);
outputString.AddShaderChunk(string.Format("Out = {0} {1};",
ConvertConcreteSlotValueTypeToString(precision, FindOutputSlot<MaterialSlot>(OutputSlotId).concreteValueType),
"(dot(In, red), dot(In, green), dot(In, blue))"), true);
outputString.Deindent();
outputString.AddShaderChunk("}", false);
visitor.AddShaderChunk(outputString.GetShaderString(0), true);
}
}
}

11
MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/Nodes/Artistic/Adjustment/ChannelMixerNode.cs.meta


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

118
MaterialGraphProject/Assets/UnityShaderEditor/Editor/Drawing/Controls/ChannelMixerControl.cs


using System;
using System.Reflection;
using UnityEditor.Experimental.UIElements;
using UnityEngine;
using UnityEngine.Experimental.UIElements;
using UnityEngine.Experimental.UIElements.StyleSheets;
using UnityEditor.ShaderGraph;
namespace UnityEditor.ShaderGraph.Drawing.Controls
{
[AttributeUsage(AttributeTargets.Property)]
public class ChannelMixerControlAttribute : Attribute, IControlAttribute
{
string m_Label;
float m_Minimum;
float m_Maximum;
public ChannelMixerControlAttribute(string label = null, float minimum = -2f, float maximum = 2f)
{
m_Label = label;
m_Minimum = minimum;
m_Maximum = maximum;
}
public VisualElement InstantiateControl(AbstractMaterialNode node, PropertyInfo propertyInfo)
{
return new ChannelMixerControlView(m_Label, m_Minimum, m_Maximum, node, propertyInfo);
}
}
public class ChannelMixerControlView : VisualElement
{
AbstractMaterialNode m_Node;
PropertyInfo m_PropertyInfo;
int m_OutChannel;
Slider redSlider;
Slider greenSlider;
Slider blueSlider;
float m_Minimum;
float m_Maximum;
public ChannelMixerControlView(string label, float minimum, float maximum, AbstractMaterialNode node, PropertyInfo propertyInfo)
{
m_Node = node;
m_PropertyInfo = propertyInfo;
m_OutChannel = 0;
m_Minimum = minimum;
m_Maximum = maximum;
if (propertyInfo.PropertyType != typeof(ChannelMixerNode.ChannelMixer))
throw new ArgumentException("Property must be of type Channel Mixer.", "propertyInfo");
label = label ?? ObjectNames.NicifyVariableName(propertyInfo.Name);
if (!string.IsNullOrEmpty(label))
Add(new Label(label));
Action changedOutputRed = () => OnClickButton(0);
var outputButtonRed = new Button(changedOutputRed);
Add(outputButtonRed);
Action changedOutputGreen = () => OnClickButton(1);
var outputButtonGreen = new Button(changedOutputGreen);
Add(outputButtonGreen);
Action changedOutputBlue = () => OnClickButton(2);
var outputButtonBlue = new Button(changedOutputBlue);
Add(outputButtonBlue);
ChannelMixerNode.ChannelMixer channelMixer = (ChannelMixerNode.ChannelMixer)m_PropertyInfo.GetValue(m_Node, null);
Add(new Label("Red"));
Action<float> changedRedIn = (s) => { OnChangeSlider(s, m_OutChannel, 0); };
redSlider = new Slider(m_Minimum, m_Maximum, changedRedIn) { value = channelMixer.outChannels[m_OutChannel].inChannels[0] };
redSlider.value = 1; // This refuses to initialize at its default value
Add(redSlider);
Add(new Label("Green"));
Action<float> changedGreenIn = (s) => { OnChangeSlider(s, m_OutChannel, 1); };
greenSlider = new Slider(m_Minimum, m_Maximum, changedGreenIn) { value = channelMixer.outChannels[m_OutChannel].inChannels[1] };
Add(greenSlider);
Add(new Label("Blue"));
Action<float> changedBlueIn = (s) => { OnChangeSlider(s, m_OutChannel, 2); };
blueSlider = new Slider(m_Minimum, m_Maximum, changedBlueIn) { value = channelMixer.outChannels[m_OutChannel].inChannels[2] };
Add(blueSlider);
ResetSliders();
}
void ResetSliders()
{
ChannelMixerNode.ChannelMixer channelMixer = (ChannelMixerNode.ChannelMixer)m_PropertyInfo.GetValue(m_Node, null);
redSlider.value = channelMixer.outChannels[m_OutChannel].inChannels[0];
greenSlider.value = channelMixer.outChannels[m_OutChannel].inChannels[1];
blueSlider.value = channelMixer.outChannels[m_OutChannel].inChannels[2];
}
void OnChangeSlider(float value, int outChannel, int inChannel)
{
m_Node.owner.owner.RegisterCompleteObjectUndo("Slider Change");
ChannelMixerNode.ChannelMixer channelMixer = (ChannelMixerNode.ChannelMixer)m_PropertyInfo.GetValue(m_Node, null);
channelMixer.outChannels[outChannel].inChannels[inChannel] = value;
m_PropertyInfo.SetValue(m_Node, channelMixer, null);
Dirty(ChangeType.Repaint);
}
void OnClickButton(int outChannel)
{
m_Node.owner.owner.RegisterCompleteObjectUndo("Button Change");
m_OutChannel = outChannel;
ResetSliders();
Dirty(ChangeType.Repaint);
}
}
}

11
MaterialGraphProject/Assets/UnityShaderEditor/Editor/Drawing/Controls/ChannelMixerControl.cs.meta


fileFormatVersion: 2
guid: 74a26e3294ebad94fa5d78ee95751556
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
正在加载...
取消
保存