|
|
|
|
|
|
namespace UnityEditor.ShaderGraph |
|
|
|
{ |
|
|
|
[Title("Channel", "Swizzle")] |
|
|
|
public class SwizzleNode : AbstractMaterialNode, IGeneratesBodyCode, IGeneratesFunction |
|
|
|
public class SwizzleNode : AbstractMaterialNode, IGeneratesBodyCode |
|
|
|
{ |
|
|
|
public SwizzleNode() |
|
|
|
{ |
|
|
|
|
|
|
var outputName = GetVariableNameForSlot(OutputSlotId); |
|
|
|
var inputValue = GetSlotValue(InputSlotId, generationMode); |
|
|
|
var inputValueType = FindInputSlot<MaterialSlot>(InputSlotId).concreteValueType; |
|
|
|
if (generationMode == GenerationMode.ForReals) |
|
|
|
if (inputValueType == ConcreteSlotValueType.Vector1) |
|
|
|
visitor.AddShaderChunk(string.Format("{0} {1} = {2};", outputSlotType, outputName, inputValue), false); |
|
|
|
else if (generationMode == GenerationMode.ForReals) |
|
|
|
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));", |
|
|
|
visitor.AddShaderChunk(string.Format("{0} {1} = {0}({3}[((int){2} >> 0) & 3], {3}[((int){2} >> 2) & 3], {3}[((int){2} >> 4) & 3], {3}[((int){2} >> 6) & 3]);", |
|
|
|
GetVariableNameForNode(), |
|
|
|
inputValue, |
|
|
|
inputValueType.ToString(precision)), false); |
|
|
|
GetVariableNameForNode(), // Name of the uniform we encode swizzle values into
|
|
|
|
inputValue), false); |
|
|
|
} |
|
|
|
|
|
|
|
public override void CollectShaderProperties(PropertyCollector properties, GenerationMode generationMode) |
|
|
|
|
|
|
public override void CollectPreviewMaterialProperties(List<PreviewProperty> properties) |
|
|
|
{ |
|
|
|
base.CollectPreviewMaterialProperties(properties); |
|
|
|
// Encode swizzle values into an integer
|
|
|
|
var value = ((int)redChannel) | ((int)greenChannel << 2) | ((int)blueChannel << 4) | ((int)alphaChannel << 6); |
|
|
|
properties.Add(new PreviewProperty |
|
|
|
{ |
|
|
|
|
|
|
}); |
|
|
|
} |
|
|
|
|
|
|
|
public void GenerateNodeFunction(ShaderGenerator visitor, GenerationMode generationMode) |
|
|
|
{ |
|
|
|
if (generationMode != GenerationMode.Preview) |
|
|
|
return; |
|
|
|
|
|
|
|
var sb = new ShaderStringBuilder(); |
|
|
|
var valueType = FindInputSlot<MaterialSlot>(InputSlotId).concreteValueType; |
|
|
|
sb.AppendLine("float Unity_Swizzle_Select_{0}({0} Value, int Swizzle, int Channel)", valueType.ToString(precision)); |
|
|
|
using (sb.BlockScope()) |
|
|
|
{ |
|
|
|
var channelCount = SlotValueHelper.GetChannelCount(valueType); |
|
|
|
if (channelCount == 1) |
|
|
|
{ |
|
|
|
sb.AppendLine("return Value;"); |
|
|
|
} |
|
|
|
else |
|
|
|
{ |
|
|
|
sb.AppendLine("int index = (Swizzle >> (2 * Channel)) & 3;"); |
|
|
|
sb.AppendLine("if (index == 0) return Value.r;"); |
|
|
|
if (channelCount >= 2) |
|
|
|
sb.AppendLine("if (index == 1) return Value.g;"); |
|
|
|
if (channelCount >= 3) |
|
|
|
sb.AppendLine("if (index == 2) return Value.b;"); |
|
|
|
if (channelCount == 4) |
|
|
|
sb.AppendLine("if (index == 3) return Value.a;"); |
|
|
|
sb.AppendLine("return 0;"); |
|
|
|
} |
|
|
|
} |
|
|
|
visitor.AddShaderChunk(sb.ToString(), true); |
|
|
|
} |
|
|
|
} |
|
|
|
} |