浏览代码

Merge pull request #82 from Unity-Technologies/node-artistic-adjustment

Node artistic adjustment
/main
GitHub 7 年前
当前提交
d8578f92
共有 9 个文件被更改,包括 468 次插入10 次删除
  1. 17
      MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/Nodes/Artistic/Adjustment/ContrastNode.cs
  2. 166
      MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/Nodes/Artistic/Adjustment/ChannelMixerNode.cs
  3. 11
      MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/Nodes/Artistic/Adjustment/ChannelMixerNode.cs.meta
  4. 38
      MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/Nodes/Artistic/Adjustment/ReplaceColorNode.cs
  5. 12
      MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/Nodes/Artistic/Adjustment/ReplaceColorNode.cs.meta
  6. 71
      MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/Nodes/Artistic/Adjustment/WhiteBalanceNode.cs
  7. 11
      MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/Nodes/Artistic/Adjustment/WhiteBalanceNode.cs.meta
  8. 141
      MaterialGraphProject/Assets/UnityShaderEditor/Editor/Drawing/Controls/ChannelMixerControl.cs
  9. 11
      MaterialGraphProject/Assets/UnityShaderEditor/Editor/Drawing/Controls/ChannelMixerControl.cs.meta

17
MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/Nodes/Artistic/Adjustment/ContrastNode.cs


namespace UnityEditor.ShaderGraph
{
[Title("Art/Adjustments/Contrast")]
[Title("Artistic/Adjustment/Contrast")]
public class ContrastNode : CodeFunctionNode
{
public ContrastNode()

}
static string Unity_Contrast(
[Slot(0, Binding.None)] Vector3 input,
[Slot(1, Binding.None)] Vector1 contrast,
[Slot(2, Binding.None)] Vector1 midPoint,
[Slot(3, Binding.None)] out Vector3 result)
[Slot(0, Binding.None)] Vector3 In,
[Slot(1, Binding.None, 1, 1, 1, 1)] Vector1 Contrast,
[Slot(2, Binding.None)] out Vector3 Out)
result = Vector2.zero;
Out = Vector2.zero;
// Contrast (reacts better when applied in log)
// Optimal range: [0.0, 2.0]]
// From PostProcessing
result = (input - midPoint) * contrast + midPoint;
{precision} midpoint = pow(0.5, 2.2);
Out = (In - midpoint) * Contrast + midpoint;
}";
}
}

166
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;
namespace UnityEditor.ShaderGraph
{
[Title("Artistic/Adjustment/Channel Mixer")]
public class ChannelMixerNode : AbstractMaterialNode, IGeneratesBodyCode, IGeneratesFunction
{
public ChannelMixerNode()
{
name = "Channel Mixer";
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_ChannelMixer_" + precision;
}
public sealed override void UpdateNodeAfterDeserialization()
{
AddSlot(new Vector3MaterialSlot(InputSlotId, kInputSlotName, kInputSlotName, SlotType.Input, Vector3.zero));
AddSlot(new Vector3MaterialSlot(OutputSlotId, kOutputSlotName, kOutputSlotName, SlotType.Output, Vector3.zero));
RemoveSlotsNameNotMatching(new[] { InputSlotId, OutputSlotId });
}
[SerializeField]
ChannelMixer m_ChannelMixer = new ChannelMixer( new Vector3(1, 0, 0), new Vector3(0, 1, 0), new Vector3(0, 0, 1));
[Serializable]
public struct ChannelMixer
{
public Vector3 outRed;
public Vector3 outGreen;
public Vector3 outBlue;
public ChannelMixer(Vector3 red, Vector3 green, Vector3 blue)
{
outRed = red;
outGreen = green;
outBlue = blue;
}
}
[ChannelMixerControl("")]
public ChannelMixer channelMixer
{
get { return m_ChannelMixer; }
set
{
if ((value.outRed == m_ChannelMixer.outRed) && (value.outGreen == m_ChannelMixer.outGreen) && (value.outBlue == m_ChannelMixer.outBlue))
return;
m_ChannelMixer = value;
if (onModified != null)
onModified(this, ModificationScope.Node);
}
}
string GetFunctionPrototype(string argIn, string argRed, string argGreen, string argBlue, string argOut)
{
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);
}
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, FindInputSlot<MaterialSlot>(InputSlotId).concreteValueType), GetVariableNameForSlot(OutputSlotId)), 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
});
}
public override void CollectShaderProperties(PropertyCollector properties, GenerationMode generationMode)
{
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
});
}
public void GenerateNodeFunction(ShaderGenerator visitor, GenerationMode generationMode)
{
visitor.AddShaderChunk(GetFunctionPrototype("In", "Red", "Green", "Blue", "Out"), false);
visitor.AddShaderChunk("{", false);
visitor.Indent();
visitor.AddShaderChunk(string.Format("Out = {0} (dot(In, Red), dot(In, Green), dot(In, Blue));",
ConvertConcreteSlotValueTypeToString(precision, FindOutputSlot<MaterialSlot>(OutputSlotId).concreteValueType)), true);
visitor.Deindent();
visitor.AddShaderChunk("}", false);
}
}
}

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:

38
MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/Nodes/Artistic/Adjustment/ReplaceColorNode.cs


using System.Reflection;
using UnityEngine;
namespace UnityEditor.ShaderGraph
{
[Title("Artistic/Adjustment/Replace Color")]
public class ReplaceColorNode : CodeFunctionNode
{
public ReplaceColorNode()
{
name = "Replace Color";
}
protected override MethodInfo GetFunctionToConvert()
{
return GetType().GetMethod("Unity_ReplaceColor", BindingFlags.Static | BindingFlags.NonPublic);
}
static string Unity_ReplaceColor(
[Slot(0, Binding.None)] Vector3 In,
[Slot(1, Binding.None)] Color From,
[Slot(2, Binding.None)] Color To,
[Slot(3, Binding.None)] Vector1 Range,
[Slot(4, Binding.None)] out Vector3 Out)
{
Out = Vector2.zero;
return
@"
{
{precision}3 col = In;
{precision} Distance = distance(From, In);
if(Distance <= Range)
col = To;
Out = col;
}";
}
}
}

12
MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/Nodes/Artistic/Adjustment/ReplaceColorNode.cs.meta


fileFormatVersion: 2
guid: a60be5fb80fbbdb449fcc95fa2256cc5
timeCreated: 1444218016
licenseType: Pro
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

71
MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/Nodes/Artistic/Adjustment/WhiteBalanceNode.cs


using System.Reflection;
using UnityEngine;
namespace UnityEditor.ShaderGraph
{
[Title("Artistic/Adjustment/White Balance")]
public class WhiteBalanceNode : CodeFunctionNode
{
public WhiteBalanceNode()
{
name = "White Balance";
}
protected override MethodInfo GetFunctionToConvert()
{
return GetType().GetMethod("Unity_WhiteBalance", BindingFlags.Static | BindingFlags.NonPublic);
}
static string Unity_WhiteBalance(
[Slot(0, Binding.None)] Vector3 In,
[Slot(1, Binding.None)] Vector1 Temperature,
[Slot(2, Binding.None)] Vector1 Tint,
[Slot(3, Binding.None)] out Vector3 Out)
{
Out = Vector3.zero;
return @"
{
// Range ~[-1.67;1.67] works best
{precision} t1 = Temperature * 10 / 6;
{precision} t2 = Tint * 10 / 6;
// Get the CIE xy chromaticity of the reference white point.
// Note: 0.31271 = x value on the D65 white point
{precision} x = 0.31271 - t1 * (t1 < 0 ? 0.1 : 0.05);
{precision} standardIlluminantY = 2.87 * x - 3 * x * x - 0.27509507;
{precision} y = standardIlluminantY + t2 * 0.05;
// Calculate the coefficients in the LMS space.
{precision}3 w1 = {precision}3(0.949237, 1.03542, 1.08728); // D65 white point
// CIExyToLMS
{precision} Y = 1;
{precision} X = Y * x / y;
{precision} Z = Y * (1 - x - y) / y;
{precision} L = 0.7328 * X + 0.4296 * Y - 0.1624 * Z;
{precision} M = -0.7036 * X + 1.6975 * Y + 0.0061 * Z;
{precision} S = 0.0030 * X + 0.0136 * Y + 0.9834 * Z;
{precision}3 w2 = {precision}3(L, M, S);
{precision}3 balance = {precision}3(w1.x / w2.x, w1.y / w2.y, w1.z / w2.z);
{precision}3x3 LIN_2_LMS_MAT = {
3.90405e-1, 5.49941e-1, 8.92632e-3,
7.08416e-2, 9.63172e-1, 1.35775e-3,
2.31082e-2, 1.28021e-1, 9.36245e-1
};
{precision}3x3 LMS_2_LIN_MAT = {
2.85847e+0, -1.62879e+0, -2.48910e-2,
-2.10182e-1, 1.15820e+0, 3.24281e-4,
-4.18120e-2, -1.18169e-1, 1.06867e+0
};
{precision}3 lms = mul(LIN_2_LMS_MAT, In);
lms *= balance;
Out = mul(LMS_2_LIN_MAT, lms);
}
";
}
}
}

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


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

141
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;
ChannelMixerNode.ChannelMixer m_ChannelMixer;
int m_OutChannel;
Slider m_RedSlider;
Slider m_GreenSlider;
Slider m_BlueSlider;
float m_Minimum;
float m_Maximum;
bool m_Initialized;
public ChannelMixerControlView(string label, float minimum, float maximum, AbstractMaterialNode node, PropertyInfo propertyInfo)
{
m_Node = node;
m_PropertyInfo = propertyInfo;
m_ChannelMixer = (ChannelMixerNode.ChannelMixer)m_PropertyInfo.GetValue(m_Node, null);
m_OutChannel = 0;
m_Minimum = minimum;
m_Maximum = maximum;
if (propertyInfo.PropertyType != typeof(ChannelMixerNode.ChannelMixer))
throw new ArgumentException("Property must be of type ChannelMixer.", "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);
Add(new Label("Red"));
Action<float> changedRedIn = (s) => { OnChangeSlider(s, 0); };
m_RedSlider = new Slider(m_Minimum, m_Maximum, changedRedIn);
Add(m_RedSlider);
Add(new Label("Green"));
Action<float> changedGreenIn = (s) => { OnChangeSlider(s, 1); };
m_GreenSlider = new Slider(m_Minimum, m_Maximum, changedGreenIn);
Add(m_GreenSlider);
Add(new Label("Blue"));
Action<float> changedBlueIn = (s) => { OnChangeSlider(s, 2); };
m_BlueSlider = new Slider(m_Minimum, m_Maximum, changedBlueIn);
Add(m_BlueSlider);
m_Initialized = true;
ResetSliders();
}
void ResetSliders()
{
Vector3 outputChannel = GetOutputChannel();
m_RedSlider.value = outputChannel[0];
m_GreenSlider.value = outputChannel[1];
m_BlueSlider.value = outputChannel[2];
}
void OnChangeSlider(float value, int inChannel)
{
if (!m_Initialized)
return;
m_Node.owner.owner.RegisterCompleteObjectUndo("Slider Change");
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)
{
m_OutChannel = outChannel;
ResetSliders();
}
Vector3 GetOutputChannel()
{
switch (m_OutChannel)
{
case 1:
return m_ChannelMixer.outGreen;
case 2:
return m_ChannelMixer.outBlue;
default:
return m_ChannelMixer.outRed;
}
}
}
}

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:
正在加载...
取消
保存