Skip to content

Commit 9f1ad22

Browse files
Esmeralda SalamoneEvergreen
authored andcommitted
[Port] [6000.0] [ShaderGraph] force swizzle node to use fixed size
1 parent 3d8066a commit 9f1ad22

7 files changed

Lines changed: 91 additions & 28 deletions

File tree

Packages/com.unity.shadergraph/Documentation~/Swizzle-Node.md

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,11 @@ Creates a new [vector](https://docs.unity3d.com/Manual/VectorCookbook.html) from
77
To specify how input elements should be swizzled, enter a formatting string in the input mask.
88
To invert the order of the input elements, for example, use the string "wzyx" or "abgr".
99

10-
The length of the input mask determines the dimensions of the output vector. The error "Invalid Mask" indicates an input mask value which includes one or more channels that do not exist in the input vector.
10+
The length of the input mask determines the dimensions of the output vector, while the channels used by the input mask determine the dimensions of the input vector.
1111

12-
To output a vector3 with the x, y and z elements of the input vector, for example, use the input mask “xyz” or “rgb”.
12+
For example;
13+
* To output a vector4 that contains two copies of a vector2 input, set **Mask** to `xyxy`.
14+
* To output the alpha value from a vector4 input, set **Mask** to `a`.
1315

1416

1517

Packages/com.unity.shadergraph/Editor/Data/Graphs/DynamicVectorMaterialSlot.cs

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -128,9 +128,13 @@ public override void AddDefaultProperty(PropertyCollector properties, Generation
128128

129129
public override void CopyValuesFrom(MaterialSlot foundSlot)
130130
{
131-
var slot = foundSlot as DynamicVectorMaterialSlot;
132-
if (slot != null)
133-
value = slot.value;
131+
switch (foundSlot)
132+
{
133+
case IMaterialSlotHasValue<float> slot1: value = new Vector4(slot1.value, slot1.value, slot1.value, slot1.value); break;
134+
case IMaterialSlotHasValue<Vector2> slot2: value = new Vector4(slot2.value.x, slot2.value.y); break;
135+
case IMaterialSlotHasValue<Vector3> slot3: value = new Vector4(slot3.value.x, slot3.value.y, slot3.value.z); break;
136+
case IMaterialSlotHasValue<Vector4> slot4: value = slot4.value; break;
137+
}
134138
}
135139

136140
public override void CopyDefaultValue(MaterialSlot other)

Packages/com.unity.shadergraph/Editor/Data/Graphs/Vector1MaterialSlot.cs

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -105,9 +105,13 @@ public override void GetPreviewProperties(List<PreviewProperty> properties, stri
105105

106106
public override void CopyValuesFrom(MaterialSlot foundSlot)
107107
{
108-
var slot = foundSlot as Vector1MaterialSlot;
109-
if (slot != null)
110-
value = slot.value;
108+
switch(foundSlot)
109+
{
110+
case IMaterialSlotHasValue<float> slot1: value = slot1.value; break;
111+
case IMaterialSlotHasValue<Vector2> slot2: value = slot2.value.x; break;
112+
case IMaterialSlotHasValue<Vector3> slot3: value = slot3.value.x; break;
113+
case IMaterialSlotHasValue<Vector4> slot4: value = slot4.value.x; break;
114+
}
111115
}
112116

113117
public override void CopyDefaultValue(MaterialSlot other)

Packages/com.unity.shadergraph/Editor/Data/Graphs/Vector2MaterialSlot.cs

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -125,9 +125,13 @@ public override void GetPreviewProperties(List<PreviewProperty> properties, stri
125125

126126
public override void CopyValuesFrom(MaterialSlot foundSlot)
127127
{
128-
var slot = foundSlot as Vector2MaterialSlot;
129-
if (slot != null)
130-
value = slot.value;
128+
switch (foundSlot)
129+
{
130+
case IMaterialSlotHasValue<float> slot1: value = new Vector2(slot1.value, slot1.value); break;
131+
case IMaterialSlotHasValue<Vector2> slot2: value = slot2.value; break;
132+
case IMaterialSlotHasValue<Vector3> slot3: value = new Vector2(slot3.value.x, slot3.value.y); break;
133+
case IMaterialSlotHasValue<Vector4> slot4: value = new Vector2(slot4.value.x, slot4.value.y); break;
134+
}
131135
}
132136

133137
public override void CopyDefaultValue(MaterialSlot other)

Packages/com.unity.shadergraph/Editor/Data/Graphs/Vector3MaterialSlot.cs

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -117,9 +117,13 @@ public override void GetPreviewProperties(List<PreviewProperty> properties, stri
117117

118118
public override void CopyValuesFrom(MaterialSlot foundSlot)
119119
{
120-
var slot = foundSlot as Vector3MaterialSlot;
121-
if (slot != null)
122-
value = slot.value;
120+
switch (foundSlot)
121+
{
122+
case IMaterialSlotHasValue<float> slot1: value = new Vector3(slot1.value, slot1.value, slot1.value); break;
123+
case IMaterialSlotHasValue<Vector2> slot2: value = new Vector3(slot2.value.x, slot2.value.y); break;
124+
case IMaterialSlotHasValue<Vector3> slot3: value = slot3.value; break;
125+
case IMaterialSlotHasValue<Vector4> slot4: value = new Vector3(slot4.value.x, slot4.value.y, slot4.value.z); break;
126+
}
123127
}
124128

125129
public override void CopyDefaultValue(MaterialSlot other)

Packages/com.unity.shadergraph/Editor/Data/Graphs/Vector4MaterialSlot.cs

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -120,9 +120,13 @@ public override void GetPreviewProperties(List<PreviewProperty> properties, stri
120120

121121
public override void CopyValuesFrom(MaterialSlot foundSlot)
122122
{
123-
var slot = foundSlot as Vector4MaterialSlot;
124-
if (slot != null)
125-
value = slot.value;
123+
switch (foundSlot)
124+
{
125+
case IMaterialSlotHasValue<float> slot1: value = new Vector4(slot1.value, slot1.value, slot1.value, slot1.value); break;
126+
case IMaterialSlotHasValue<Vector2> slot2: value = new Vector4(slot2.value.x, slot2.value.y); break;
127+
case IMaterialSlotHasValue<Vector3> slot3: value = new Vector4(slot3.value.x, slot3.value.y, slot3.value.z); break;
128+
case IMaterialSlotHasValue<Vector4> slot4: value = slot4.value; break;
129+
}
126130
}
127131

128132
public override void CopyDefaultValue(MaterialSlot other)

Packages/com.unity.shadergraph/Editor/Data/Nodes/Channel/SwizzleNode.cs

Lines changed: 52 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -100,8 +100,36 @@ public sealed override void UpdateNodeAfterDeserialization()
100100
if (_maskInput == null)
101101
_maskInput = "xxxx";
102102

103-
AddSlot(new DynamicVectorMaterialSlot(InputSlotId, kInputSlotName, kInputSlotName, SlotType.Input, Vector4.zero));
104-
switch (_maskInput.Length)
103+
int outputLength = _maskInput.Length;
104+
int inputLength = 1;
105+
foreach(var c in _maskInput.ToLowerInvariant())
106+
{
107+
switch (c)
108+
{
109+
case 'g': case 'y': inputLength = Mathf.Max(2, inputLength); break;
110+
case 'b': case 'z': inputLength = Mathf.Max(3, inputLength); break;
111+
case 'a': case 'w': inputLength = Mathf.Max(4, inputLength); break;
112+
default: break;
113+
}
114+
}
115+
116+
switch (inputLength)
117+
{
118+
case 1:
119+
AddSlot(new Vector1MaterialSlot(InputSlotId, kInputSlotName, kInputSlotName, SlotType.Input, 0));
120+
break;
121+
case 2:
122+
AddSlot(new Vector2MaterialSlot(InputSlotId, kInputSlotName, kInputSlotName, SlotType.Input, Vector2.zero));
123+
break;
124+
case 3:
125+
AddSlot(new Vector3MaterialSlot(InputSlotId, kInputSlotName, kInputSlotName, SlotType.Input, Vector3.zero));
126+
break;
127+
default:
128+
AddSlot(new Vector4MaterialSlot(InputSlotId, kInputSlotName, kInputSlotName, SlotType.Input, Vector4.zero));
129+
break;
130+
}
131+
132+
switch (outputLength)
105133
{
106134
case 1:
107135
AddSlot(new Vector1MaterialSlot(OutputSlotId, kOutputSlotName, kOutputSlotName, SlotType.Output, 0));
@@ -131,12 +159,6 @@ public void GenerateNodeCode(ShaderStringBuilder sb, GenerationMode generationMo
131159
{
132160
sb.AppendLine(string.Format("{0} {1} = 0;", outputSlotType, outputName));
133161
}
134-
else if(!FindInputSlot<MaterialSlot>(InputSlotId).isConnected)
135-
{
136-
// cannot swizzle off of a float literal, so if there is no upstream connection, it means we have defaulted to a float,
137-
// and the node's initial base case will generate invalid code.
138-
sb.AppendLine("{0} {1} = $precision({2}).{3};", outputSlotType, outputName, inputValue, convertedMask);
139-
}
140162
else
141163
{
142164
sb.AppendLine("{0} {1} = {2}.{3};", outputSlotType, outputName, inputValue, convertedMask);
@@ -146,12 +168,17 @@ public void GenerateNodeCode(ShaderStringBuilder sb, GenerationMode generationMo
146168
public override void ValidateNode()
147169
{
148170
base.ValidateNode();
171+
var inputSlot = FindInputSlot<MaterialSlot>(InputSlotId);
172+
int InputValueSize = GetInputLength(inputSlot);
173+
int ExpectedInputSize = SlotValueHelper.GetChannelCount(inputSlot.concreteValueType);
149174

150-
var inputValueType = FindInputSlot<MaterialSlot>(InputSlotId).concreteValueType;
151-
var InputValueSize = SlotValueHelper.GetChannelCount(inputValueType);
152175
if (!ValidateMaskInput(InputValueSize))
153176
{
154-
owner.AddValidationError(objectId, "Invalid mask for a Vector" + InputValueSize + " input.", ShaderCompilerMessageSeverity.Error);
177+
owner.AddValidationError(objectId, "Invalid mask for a 'Vector" + InputValueSize + "' input.", ShaderCompilerMessageSeverity.Error);
178+
}
179+
else if ( InputValueSize < ExpectedInputSize)
180+
{
181+
owner.AddValidationError(objectId, $"Connected input 'Vector{InputValueSize}' is smaller than expected input 'Vector{ExpectedInputSize}'.", ShaderCompilerMessageSeverity.Warning);
155182
}
156183
}
157184

@@ -199,5 +226,19 @@ public static void LegacySwizzleChannel(string json, SwizzleNode node)
199226
node._maskInput = s_ComponentList[legacySwizzleChannelData.m_RedChannel] + s_ComponentList[legacySwizzleChannelData.m_GreenChannel] + s_ComponentList[legacySwizzleChannelData.m_BlueChannel] + s_ComponentList[legacySwizzleChannelData.m_AlphaChannel];
200227
}
201228
}
229+
230+
private static int GetInputLength(MaterialSlot slot)
231+
{
232+
if (!slot.isConnected)
233+
return SlotValueHelper.GetChannelCount(slot.concreteValueType);
234+
235+
var graph = slot.owner.owner; //slot.isConnected null checks this already;
236+
var edges = graph.GetEdges(slot.slotReference);
237+
foreach(var edge in edges)
238+
return SlotValueHelper.GetChannelCount(edge.outputSlot.slot.concreteValueType);
239+
240+
// this shouldn't be reached, but we fall back to the slot's original concrete length.
241+
return SlotValueHelper.GetChannelCount(slot.concreteValueType);
242+
}
202243
}
203244
}

0 commit comments

Comments
 (0)