浏览代码

Modify SwizzleNode such that it is possible to change channels without shader generation in preview mode

/main
Peter Bay Bastian 7 年前
当前提交
ce482316
共有 1 个文件被更改,包括 70 次插入29 次删除
  1. 99
      MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/Nodes/Channel/SwizzleNode.cs

99
MaterialGraphProject/Assets/UnityShaderEditor/Editor/Data/Nodes/Channel/SwizzleNode.cs


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

get { return true; }
}
string GetFunctionName()
{
return "Unity_Swizzle_" + precision + "_" + GuidEncoder.Encode(guid);
}
public sealed override void UpdateNodeAfterDeserialization()
{
AddSlot(new DynamicVectorMaterialSlot(InputSlotId, kInputSlotName, kInputSlotName, SlotType.Input, Vector4.zero));

static Dictionary<TextureChannel, string> m_ComponentList = new Dictionary<TextureChannel, string>
static Dictionary<TextureChannel, string> s_ComponentList = new Dictionary<TextureChannel, string>
{TextureChannel.Red, ".r" },
{TextureChannel.Green, ".g" },
{TextureChannel.Blue, ".b" },
{TextureChannel.Alpha, ".a" },
{TextureChannel.Red, "r" },
{TextureChannel.Green, "g" },
{TextureChannel.Blue, "b" },
{TextureChannel.Alpha, "a" },
private TextureChannel m_RedChannel;
TextureChannel m_RedChannel;
[ChannelEnumControl("Red Out")]
public TextureChannel redChannel

m_RedChannel = value;
if (onModified != null)
{
onModified(this, ModificationScope.Graph);
onModified(this, ModificationScope.Node);
private TextureChannel m_GreenChannel;
TextureChannel m_GreenChannel;
[ChannelEnumControl("Green Out")]
public TextureChannel greenChannel

m_GreenChannel = value;
if (onModified != null)
{
onModified(this, ModificationScope.Graph);
onModified(this, ModificationScope.Node);
private TextureChannel m_BlueChannel;
TextureChannel m_BlueChannel;
[ChannelEnumControl("Blue Out")]
public TextureChannel blueChannel

m_BlueChannel = value;
if (onModified != null)
{
onModified(this, ModificationScope.Graph);
onModified(this, ModificationScope.Node);
private TextureChannel m_AlphaChannel;
TextureChannel m_AlphaChannel;
[ChannelEnumControl("Alpha Out")]
public TextureChannel alphaChannel

m_AlphaChannel = value;
if (onModified != null)
{
onModified(this, ModificationScope.Graph);
onModified(this, ModificationScope.Node);
}
}
}

int channelCount = (int)SlotValueHelper.GetChannelCount(FindInputSlot<MaterialSlot>(InputSlotId).concreteValueType);
var channelCount = (int)SlotValueHelper.GetChannelCount(FindInputSlot<MaterialSlot>(InputSlotId).concreteValueType);
if ((int)redChannel >= channelCount)
redChannel = TextureChannel.Red;
if ((int)greenChannel >= channelCount)

public void GenerateNodeCode(ShaderGenerator visitor, GenerationMode generationMode)
{
ValidateChannelCount();
string inputValue = GetSlotValue(InputSlotId, generationMode);
string outputValue = GetSlotValue(OutputSlotId, generationMode);
visitor.AddShaderChunk(string.Format("{0} {1};", FindOutputSlot<MaterialSlot>(OutputSlotId).concreteValueType.ToString(precision), GetVariableNameForSlot(OutputSlotId)), false);
visitor.AddShaderChunk(GetFunctionCallBody(inputValue, outputValue), false);
var outputSlotType = FindOutputSlot<MaterialSlot>(OutputSlotId).concreteValueType.ToString(precision);
var outputName = GetVariableNameForSlot(OutputSlotId);
var inputValue = GetSlotValue(InputSlotId, generationMode);
var inputValueType = FindInputSlot<MaterialSlot>(InputSlotId).concreteValueType;
if (generationMode == GenerationMode.ForReals)
visitor.AddShaderChunk(string.Format("{0} {1} = {2}.{3}{4}{5}{6};", outputSlotType, outputName, inputValue, s_ComponentList[m_RedChannel], s_ComponentList[m_GreenChannel], s_ComponentList[m_BlueChannel], s_ComponentList[m_AlphaChannel]), false);
else
visitor.AddShaderChunk(string.Format("{0} {1} = {0}(Unity_Swizzle_Select_{4}({3}, {2}, 0), Unity_Swizzle_Select_{4}({3}, {2}, 1), Unity_Swizzle_Select_{4}({3}, {2}, 2), Unity_Swizzle_Select_{4}({3}, {2}, 3));",
outputSlotType,
outputName,
GetVariableNameForNode(),
inputValue,
inputValueType.ToString(precision)), false);
}
public override void CollectShaderProperties(PropertyCollector properties, GenerationMode generationMode)
{
base.CollectShaderProperties(properties, generationMode);
if (generationMode != GenerationMode.Preview)
return;
properties.AddShaderProperty(new FloatShaderProperty
{
overrideReferenceName = GetVariableNameForNode(),
generatePropertyBlock = false
});
string GetFunctionCallBody(string inputValue, string outputValue)
public override void CollectPreviewMaterialProperties(List<PreviewProperty> properties)
return GetFunctionName() + " (" + inputValue + ", " + outputValue + ");";
base.CollectPreviewMaterialProperties(properties);
var value = ((int)redChannel) | ((int)greenChannel << 2) | ((int)blueChannel << 4) | ((int)alphaChannel << 6);
properties.Add(new PreviewProperty
{
name = GetVariableNameForNode(),
propType = PropertyType.Float,
floatValue = value
});
ValidateChannelCount();
if (generationMode != GenerationMode.Preview)
return;
sb.AppendLine("void {0} ({1} In, out {2} Out)", GetFunctionName(), FindInputSlot<MaterialSlot>(InputSlotId).concreteValueType.ToString(precision), FindOutputSlot<MaterialSlot>(OutputSlotId).concreteValueType.ToString(precision));
var valueType = FindInputSlot<MaterialSlot>(InputSlotId).concreteValueType;
sb.AppendLine("float Unity_Swizzle_Select_{0}({0} Value, int Swizzle, int Channel)", valueType.ToString(precision));
sb.AppendLine("Out = {0}({1}{2}, {1}{3}, {1}{4}, {1}{5});", FindOutputSlot<MaterialSlot>(OutputSlotId).concreteValueType.ToString(precision), kInputSlotName, m_ComponentList[m_RedChannel], m_ComponentList[m_GreenChannel], m_ComponentList[m_BlueChannel], m_ComponentList[m_AlphaChannel]);
if (valueType == ConcreteSlotValueType.Vector1)
{
sb.AppendLine("return Value;");
}
else
{
sb.AppendLine("int index = (Swizzle >> (2 * Channel)) & 3;");
sb.AppendLine("if (index == 0) return Value.r;");
if (valueType == ConcreteSlotValueType.Vector2 || valueType == ConcreteSlotValueType.Vector3 || valueType == ConcreteSlotValueType.Vector4)
sb.AppendLine("if (index == 1) return Value.g;");
if (valueType == ConcreteSlotValueType.Vector3 || valueType == ConcreteSlotValueType.Vector4)
sb.AppendLine("if (index == 2) return Value.b;");
if (valueType == ConcreteSlotValueType.Vector4)
sb.AppendLine("if (index == 3) return Value.a;");
sb.AppendLine("return 0;");
}
visitor.AddShaderChunk(sb.ToString(), true);
}
}
正在加载...
取消
保存