浏览代码

Fixes for PR

Also made function reusable for different node insatnces
/main
Matt Dean 7 年前
当前提交
c06cd050
共有 2 个文件被更改,包括 152 次插入99 次删除
  1. 175
      MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/Nodes/Artistic/Adjustment/ChannelMixerNode.cs
  2. 76
      MaterialGraphProject/Assets/UnityShaderEditor/Editor/Drawing/Controls/ChannelMixerControl.cs

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


using System;
using System.Collections.Generic;
using UnityEditor.Graphing;
using UnityEditor.ShaderGraph.Drawing.Controls;
using UnityEngine;

UpdateNodeAfterDeserialization();
}
private const int InputSlotId = 0;
private const int OutputSlotId = 1;
private const string kInputSlotName = "In";
private const string kOutputSlotName = "Out";
const int InputSlotId = 0;
const int OutputSlotId = 1;
const string kInputSlotName = "In";
const string kOutputSlotName = "Out";
public override bool hasPreview
{

protected string GetFunctionName()
string GetFunctionName()
{
return "Unity_ChannelMixer_" + precision;
}

AddSlot(GetInputSlot());
AddSlot(GetOutputSlot());
RemoveSlotsNameNotMatching(validSlots);
}
protected int[] validSlots
{
get { return new[] { InputSlotId, OutputSlotId }; }
AddSlot(new Vector3MaterialSlot(InputSlotId, kInputSlotName, kInputSlotName, SlotType.Input, Vector3.zero));
AddSlot(new Vector3MaterialSlot(OutputSlotId, kOutputSlotName, kOutputSlotName, SlotType.Output, Vector3.zero));
RemoveSlotsNameNotMatching(new[] { InputSlotId, OutputSlotId });
protected virtual MaterialSlot GetInputSlot()
{
return new Vector3MaterialSlot(InputSlotId, kInputSlotName, kInputSlotName, SlotType.Input, Vector3.zero);
}
[SerializeField]
ChannelMixer m_ChannelMixer = new ChannelMixer( new Vector3(1, 0, 0), new Vector3(0, 1, 0), new Vector3(0, 0, 1));
protected virtual MaterialSlot GetOutputSlot()
{
return new Vector3MaterialSlot(OutputSlotId, kOutputSlotName, kOutputSlotName, SlotType.Output, Vector3.zero);
}
public class ChannelMixer
public struct ChannelMixer
public OutChannel[] outChannels;
public ChannelMixer(OutChannel[] c)
{
outChannels = c;
}
}
public Vector3 outRed;
public Vector3 outGreen;
public Vector3 outBlue;
[Serializable]
public class OutChannel
{
public float[] inChannels;
public OutChannel(float[] c)
public ChannelMixer(Vector3 red, Vector3 green, Vector3 blue)
inChannels = c;
outRed = red;
outGreen = green;
outBlue = blue;
[SerializeField]
private ChannelMixer m_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;
}
get { return m_ChannelMixer; }
/*if (m_ChannelMixer == value) // This is always true with nested arrays in a class
return;*/
if (Equals(value))
return;
{
onModified(this, ModificationScope.Graph);
}
onModified(this, ModificationScope.Node);
protected string GetFunctionPrototype(string arg1Name, string arg2Name)
bool Equals(ChannelMixer c)
{
if (ReferenceEquals(c, null))
return false;
if (ReferenceEquals(c, m_ChannelMixer))
return true;
return (c.outRed == m_ChannelMixer.outRed) && (c.outGreen == m_ChannelMixer.outGreen) && (c.outBlue == m_ChannelMixer.outBlue);
}
string GetFunctionPrototype(string argIn, string argRed, string argGreen, string argBlue, string argOut)
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);
return string.Format("void {0} ({1} {2}, {3} {4}, {3} {5}, {3} {6}, out {7} {8})", GetFunctionName(),
ConvertConcreteSlotValueTypeToString(precision, FindInputSlot<MaterialSlot>(InputSlotId).concreteValueType), argIn,
precision+"3", argRed, argGreen, argBlue,
ConvertConcreteSlotValueTypeToString(precision, FindOutputSlot<MaterialSlot>(OutputSlotId).concreteValueType), argOut);
NodeUtils.SlotConfigurationExceptionIfBadConfiguration(this, new[] { InputSlotId }, new[] { OutputSlotId });
visitor.AddShaderChunk(GetFunctionCallBody(inputValue, outputValue), true);
if(!generationMode.IsPreview())
{
visitor.AddShaderChunk(string.Format("{0}3 _{1}_Red = {0}3 ({2}, {3}, {4});", precision, GetVariableNameForNode(), channelMixer.outRed[0], channelMixer.outRed[1], channelMixer.outRed[2]), true);
visitor.AddShaderChunk(string.Format("{0}3 _{1}_Green = {0}3 ({2}, {3}, {4});", precision, GetVariableNameForNode(), channelMixer.outGreen[0], channelMixer.outGreen[1], channelMixer.outGreen[2]), true);
visitor.AddShaderChunk(string.Format("{0}3 _{1}_Blue = {0}3 ({2}, {3}, {4});", precision, GetVariableNameForNode(), channelMixer.outBlue[0], channelMixer.outBlue[1], channelMixer.outBlue[2]), true);
}
visitor.AddShaderChunk(GetFunctionCallBody(inputValue, string.Format("_{0}_Red", GetVariableNameForNode()), string.Format("_{0}_Green", GetVariableNameForNode()), string.Format("_{0}_Blue", GetVariableNameForNode()), outputValue), true);
}
string GetFunctionCallBody(string inputValue, string red, string green, string blue, string outputValue)
{
return GetFunctionName() + " (" + inputValue + ", " + red + ", " + green + ", " + blue + ", " + outputValue + ");";
}
public override void CollectPreviewMaterialProperties(List<PreviewProperty> properties)
{
base.CollectPreviewMaterialProperties(properties);
properties.Add(new PreviewProperty()
{
m_Name = string.Format("_{0}_Red", GetVariableNameForNode()),
m_PropType = PropertyType.Vector3,
m_Vector4 = channelMixer.outRed
});
properties.Add(new PreviewProperty()
{
m_Name = string.Format("_{0}_Green", GetVariableNameForNode()),
m_PropType = PropertyType.Vector3,
m_Vector4 = channelMixer.outGreen
});
properties.Add(new PreviewProperty()
{
m_Name = string.Format("_{0}_Blue", GetVariableNameForNode()),
m_PropType = PropertyType.Vector3,
m_Vector4 = channelMixer.outBlue
});
protected string GetFunctionCallBody(string inputValue, string outputValue)
public override void CollectShaderProperties(PropertyCollector properties, GenerationMode generationMode)
return GetFunctionName() + " (" + inputValue + ", " + outputValue + ");";
if (!generationMode.IsPreview())
return;
base.CollectShaderProperties(properties, generationMode);
properties.AddShaderProperty(new Vector4ShaderProperty()
{
overrideReferenceName = string.Format("_{0}_Red", GetVariableNameForNode()),
generatePropertyBlock = false
});
properties.AddShaderProperty(new Vector4ShaderProperty()
{
overrideReferenceName = string.Format("_{0}_Green", GetVariableNameForNode()),
generatePropertyBlock = false
});
properties.AddShaderProperty(new Vector4ShaderProperty()
{
overrideReferenceName = string.Format("_{0}_Blue", GetVariableNameForNode()),
generatePropertyBlock = false
});
outputString.AddShaderChunk(GetFunctionPrototype("In", "Out"), false);
outputString.AddShaderChunk(GetFunctionPrototype("In", "Red", "Green", "Blue", "Out"), false);
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);
"(dot(In, red), dot(In, green), dot(In, blue))"), true);
"(dot(In, Red), dot(In, Green), dot(In, Blue))"), true);
outputString.Deindent();
outputString.AddShaderChunk("}", false);

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


{
AbstractMaterialNode m_Node;
PropertyInfo m_PropertyInfo;
ChannelMixerNode.ChannelMixer m_ChannelMixer;
Slider redSlider;
Slider greenSlider;
Slider blueSlider;
Slider m_RedSlider;
Slider m_GreenSlider;
Slider m_BlueSlider;
bool m_Initialized;
m_ChannelMixer = (ChannelMixerNode.ChannelMixer)m_PropertyInfo.GetValue(m_Node, null);
m_OutChannel = 0;
m_Minimum = minimum;

throw new ArgumentException("Property must be of type Channel Mixer.", "propertyInfo");
throw new ArgumentException("Property must be of type ChannelMixer.", "propertyInfo");
label = label ?? ObjectNames.NicifyVariableName(propertyInfo.Name);
if (!string.IsNullOrEmpty(label))

var outputButtonBlue = new Button(changedOutputBlue);
Add(outputButtonBlue);
ChannelMixerNode.ChannelMixer channelMixer = (ChannelMixerNode.ChannelMixer)m_PropertyInfo.GetValue(m_Node, null);
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);
Action<float> changedRedIn = (s) => { OnChangeSlider(s, 0); };
m_RedSlider = new Slider(m_Minimum, m_Maximum, changedRedIn);
Add(m_RedSlider);
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);
Action<float> changedGreenIn = (s) => { OnChangeSlider(s, 1); };
m_GreenSlider = new Slider(m_Minimum, m_Maximum, changedGreenIn);
Add(m_GreenSlider);
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);
Action<float> changedBlueIn = (s) => { OnChangeSlider(s, 2); };
m_BlueSlider = new Slider(m_Minimum, m_Maximum, changedBlueIn);
Add(m_BlueSlider);
m_Initialized = true;
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];
Vector3 outputChannel = GetOutputChannel();
m_RedSlider.value = outputChannel[0];
m_GreenSlider.value = outputChannel[1];
m_BlueSlider.value = outputChannel[2];
void OnChangeSlider(float value, int outChannel, int inChannel)
void OnChangeSlider(float value, int inChannel)
if (!m_Initialized)
return;
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);
switch (m_OutChannel)
{
case 1:
m_ChannelMixer.outGreen[inChannel] = value;
break;
case 2:
m_ChannelMixer.outBlue[inChannel] = value;
break;
default:
m_ChannelMixer.outRed[inChannel] = value;
break;
}
m_PropertyInfo.SetValue(m_Node, m_ChannelMixer, null);
}
void OnClickButton(int outChannel)

ResetSliders();
Dirty(ChangeType.Repaint);
}
Vector3 GetOutputChannel()
{
switch (m_OutChannel)
{
case 1:
return m_ChannelMixer.outGreen;
case 2:
return m_ChannelMixer.outBlue;
default:
return m_ChannelMixer.outRed;
}
}
}
}
正在加载...
取消
保存