浏览代码
Merge pull request #82 from Unity-Technologies/node-artistic-adjustment
Merge pull request #82 from Unity-Technologies/node-artistic-adjustment
Node artistic adjustment/main
GitHub
7 年前
当前提交
d8578f92
共有 9 个文件被更改,包括 468 次插入 和 10 次删除
-
17MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/Nodes/Artistic/Adjustment/ContrastNode.cs
-
166MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/Nodes/Artistic/Adjustment/ChannelMixerNode.cs
-
11MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/Nodes/Artistic/Adjustment/ChannelMixerNode.cs.meta
-
38MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/Nodes/Artistic/Adjustment/ReplaceColorNode.cs
-
12MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/Nodes/Artistic/Adjustment/ReplaceColorNode.cs.meta
-
71MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/Nodes/Artistic/Adjustment/WhiteBalanceNode.cs
-
11MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/Nodes/Artistic/Adjustment/WhiteBalanceNode.cs.meta
-
141MaterialGraphProject/Assets/UnityShaderEditor/Editor/Drawing/Controls/ChannelMixerControl.cs
-
11MaterialGraphProject/Assets/UnityShaderEditor/Editor/Drawing/Controls/ChannelMixerControl.cs.meta
|
|||
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); |
|||
} |
|||
} |
|||
} |
|
|||
fileFormatVersion: 2 |
|||
guid: d8d3a2d8c96e5994696f30f658efebea |
|||
MonoImporter: |
|||
externalObjects: {} |
|||
serializedVersion: 2 |
|||
defaultReferences: [] |
|||
executionOrder: 0 |
|||
icon: {instanceID: 0} |
|||
userData: |
|||
assetBundleName: |
|||
assetBundleVariant: |
|
|||
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; |
|||
}";
|
|||
} |
|||
} |
|||
} |
|
|||
fileFormatVersion: 2 |
|||
guid: a60be5fb80fbbdb449fcc95fa2256cc5 |
|||
timeCreated: 1444218016 |
|||
licenseType: Pro |
|||
MonoImporter: |
|||
serializedVersion: 2 |
|||
defaultReferences: [] |
|||
executionOrder: 0 |
|||
icon: {instanceID: 0} |
|||
userData: |
|||
assetBundleName: |
|||
assetBundleVariant: |
|
|||
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); |
|||
} |
|||
";
|
|||
} |
|||
} |
|||
} |
|
|||
fileFormatVersion: 2 |
|||
guid: c09bf9b59c16e0d48b9a346376d28640 |
|||
MonoImporter: |
|||
externalObjects: {} |
|||
serializedVersion: 2 |
|||
defaultReferences: [] |
|||
executionOrder: 0 |
|||
icon: {instanceID: 0} |
|||
userData: |
|||
assetBundleName: |
|||
assetBundleVariant: |
|
|||
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; |
|||
} |
|||
} |
|||
} |
|||
} |
|
|||
fileFormatVersion: 2 |
|||
guid: 74a26e3294ebad94fa5d78ee95751556 |
|||
MonoImporter: |
|||
externalObjects: {} |
|||
serializedVersion: 2 |
|||
defaultReferences: [] |
|||
executionOrder: 0 |
|||
icon: {instanceID: 0} |
|||
userData: |
|||
assetBundleName: |
|||
assetBundleVariant: |
撰写
预览
正在加载...
取消
保存
Reference in new issue