A game about forced loneliness, made by TACStudios
1using System;
2using System.Collections.Generic;
3using System.Linq;
4using UnityEngine;
5
6namespace UnityEditor.ShaderGraph.Internal
7{
8 [Serializable]
9 public struct ShaderGraphRequirements
10 {
11 [SerializeField] List<NeededTransform> m_RequiresTransforms;
12 [SerializeField] NeededCoordinateSpace m_RequiresNormal;
13 [SerializeField] NeededCoordinateSpace m_RequiresBitangent;
14 [SerializeField] NeededCoordinateSpace m_RequiresTangent;
15 [SerializeField] NeededCoordinateSpace m_RequiresViewDir;
16 [SerializeField] NeededCoordinateSpace m_RequiresPosition;
17 [SerializeField] NeededCoordinateSpace m_RequiresPositionPredisplacement;
18 [SerializeField] bool m_RequiresScreenPosition;
19 [SerializeField] bool m_RequiresNDCPosition;
20 [SerializeField] bool m_RequiresPixelPosition;
21 [SerializeField] bool m_RequiresVertexColor;
22 [SerializeField] bool m_RequiresFaceSign;
23 [SerializeField] List<UVChannel> m_RequiresMeshUVs;
24 [SerializeField] bool m_RequiresDepthTexture;
25 [SerializeField] bool m_RequiresCameraOpaqueTexture;
26 [SerializeField] bool m_RequiresTime;
27 [SerializeField] bool m_RequiresVertexSkinning;
28 [SerializeField] bool m_RequiresVertexID;
29 [SerializeField] bool m_RequiresInstanceID;
30 [SerializeField] List<UVChannel> m_RequiresMeshUVDerivatives;
31
32 internal static ShaderGraphRequirements none
33 {
34 get
35 {
36 return new ShaderGraphRequirements
37 {
38 m_RequiresTransforms = new List<NeededTransform>(),
39 m_RequiresMeshUVs = new List<UVChannel>(),
40 m_RequiresMeshUVDerivatives = new List<UVChannel>()
41 };
42 }
43 }
44
45 public List<NeededTransform> requiresTransforms
46 {
47 get { return m_RequiresTransforms; }
48 internal set { m_RequiresTransforms = value; }
49 }
50
51 public NeededCoordinateSpace requiresNormal
52 {
53 get { return m_RequiresNormal; }
54 internal set { m_RequiresNormal = value; }
55 }
56
57 public NeededCoordinateSpace requiresBitangent
58 {
59 get { return m_RequiresBitangent; }
60 internal set { m_RequiresBitangent = value; }
61 }
62
63 public NeededCoordinateSpace requiresTangent
64 {
65 get { return m_RequiresTangent; }
66 internal set { m_RequiresTangent = value; }
67 }
68
69 public NeededCoordinateSpace requiresViewDir
70 {
71 get { return m_RequiresViewDir; }
72 internal set { m_RequiresViewDir = value; }
73 }
74
75 public NeededCoordinateSpace requiresPosition
76 {
77 get { return m_RequiresPosition; }
78 internal set { m_RequiresPosition = value; }
79 }
80
81 public NeededCoordinateSpace requiresPositionPredisplacement
82 {
83 get { return m_RequiresPositionPredisplacement; }
84 internal set { m_RequiresPositionPredisplacement = value; }
85 }
86
87 public bool requiresScreenPosition
88 {
89 get { return m_RequiresScreenPosition; }
90 internal set { m_RequiresScreenPosition = value; }
91 }
92
93 public bool requiresNDCPosition
94 {
95 get { return m_RequiresNDCPosition; }
96 internal set { m_RequiresNDCPosition = value; }
97 }
98
99 public bool requiresPixelPosition
100 {
101 get { return m_RequiresPixelPosition; }
102 internal set { m_RequiresPixelPosition = value; }
103 }
104
105 public bool requiresVertexColor
106 {
107 get { return m_RequiresVertexColor; }
108 internal set { m_RequiresVertexColor = value; }
109 }
110
111 public bool requiresFaceSign
112 {
113 get { return m_RequiresFaceSign; }
114 internal set { m_RequiresFaceSign = value; }
115 }
116
117 public List<UVChannel> requiresMeshUVs
118 {
119 get { return m_RequiresMeshUVs; }
120 internal set { m_RequiresMeshUVs = value; }
121 }
122
123 public List<UVChannel> requiresMeshUVDerivatives
124 {
125 get { return m_RequiresMeshUVDerivatives; }
126 internal set { m_RequiresMeshUVDerivatives = value; }
127 }
128
129 public bool requiresDepthTexture
130 {
131 get { return m_RequiresDepthTexture; }
132 internal set { m_RequiresDepthTexture = value; }
133 }
134
135 public bool requiresCameraOpaqueTexture
136 {
137 get { return m_RequiresCameraOpaqueTexture; }
138 internal set { m_RequiresCameraOpaqueTexture = value; }
139 }
140
141 public bool requiresTime
142 {
143 get { return m_RequiresTime; }
144 internal set { m_RequiresTime = value; }
145 }
146
147 public bool requiresVertexSkinning
148 {
149 get { return m_RequiresVertexSkinning; }
150 internal set { m_RequiresVertexSkinning = value; }
151 }
152
153 public bool requiresVertexID
154 {
155 get { return m_RequiresVertexID; }
156 internal set { m_RequiresVertexID = value; }
157 }
158
159 public bool requiresInstanceID
160 {
161 get { return m_RequiresInstanceID; }
162 internal set { m_RequiresInstanceID = value; }
163 }
164
165 internal bool NeedsTangentSpace()
166 {
167 var compoundSpaces = m_RequiresBitangent | m_RequiresNormal | m_RequiresPosition
168 | m_RequiresTangent | m_RequiresViewDir | m_RequiresPosition
169 | m_RequiresNormal;
170
171 return (compoundSpaces & NeededCoordinateSpace.Tangent) > 0;
172 }
173
174 internal ShaderGraphRequirements Union(ShaderGraphRequirements other)
175 {
176 var newReqs = new ShaderGraphRequirements();
177 newReqs.m_RequiresNormal = other.m_RequiresNormal | m_RequiresNormal;
178 newReqs.m_RequiresTangent = other.m_RequiresTangent | m_RequiresTangent;
179 newReqs.m_RequiresBitangent = other.m_RequiresBitangent | m_RequiresBitangent;
180 newReqs.m_RequiresViewDir = other.m_RequiresViewDir | m_RequiresViewDir;
181 newReqs.m_RequiresPosition = other.m_RequiresPosition | m_RequiresPosition;
182 newReqs.m_RequiresPositionPredisplacement = other.m_RequiresPositionPredisplacement | m_RequiresPositionPredisplacement;
183 newReqs.m_RequiresScreenPosition = other.m_RequiresScreenPosition | m_RequiresScreenPosition;
184 newReqs.m_RequiresNDCPosition = other.m_RequiresNDCPosition | m_RequiresNDCPosition;
185 newReqs.m_RequiresPixelPosition = other.m_RequiresPixelPosition | m_RequiresPixelPosition;
186 newReqs.m_RequiresVertexColor = other.m_RequiresVertexColor | m_RequiresVertexColor;
187 newReqs.m_RequiresFaceSign = other.m_RequiresFaceSign | m_RequiresFaceSign;
188 newReqs.m_RequiresDepthTexture = other.m_RequiresDepthTexture | m_RequiresDepthTexture;
189 newReqs.m_RequiresCameraOpaqueTexture = other.m_RequiresCameraOpaqueTexture | m_RequiresCameraOpaqueTexture;
190 newReqs.m_RequiresTime = other.m_RequiresTime | m_RequiresTime;
191 newReqs.m_RequiresVertexSkinning = other.m_RequiresVertexSkinning | m_RequiresVertexSkinning;
192 newReqs.m_RequiresVertexID = other.m_RequiresVertexID | m_RequiresVertexID;
193 newReqs.m_RequiresInstanceID = other.m_RequiresInstanceID | m_RequiresInstanceID;
194
195 newReqs.m_RequiresMeshUVs = new List<UVChannel>();
196 if (m_RequiresMeshUVs != null)
197 newReqs.m_RequiresMeshUVs.AddRange(m_RequiresMeshUVs);
198 if (other.m_RequiresMeshUVs != null)
199 newReqs.m_RequiresMeshUVs.AddRange(other.m_RequiresMeshUVs);
200
201 newReqs.m_RequiresMeshUVDerivatives = new List<UVChannel>();
202 if (m_RequiresMeshUVDerivatives != null)
203 newReqs.m_RequiresMeshUVDerivatives.AddRange(m_RequiresMeshUVDerivatives);
204 if (other.m_RequiresMeshUVDerivatives != null)
205 newReqs.m_RequiresMeshUVDerivatives.AddRange(other.m_RequiresMeshUVDerivatives);
206
207 return newReqs;
208 }
209
210 internal static ShaderGraphRequirements FromNodes<T>(IEnumerable<T> nodes, ShaderStageCapability stageCapability = ShaderStageCapability.All, bool includeIntermediateSpaces = true, bool[] texCoordNeedsDerivs = null)
211 where T : AbstractMaterialNode
212 {
213 var reqs = new ShaderGraphRequirements();
214
215 reqs.m_RequiresTransforms = new List<NeededTransform>();
216 reqs.m_RequiresMeshUVs = new List<UVChannel>();
217 reqs.m_RequiresMeshUVDerivatives = new List<UVChannel>();
218
219 foreach (var node in nodes)
220 {
221 if (node is IMayRequireTransform a)
222 reqs.m_RequiresTransforms.AddRange(a.RequiresTransform());
223
224 if (node is IMayRequireNormal b)
225 reqs.m_RequiresNormal |= b.RequiresNormal(stageCapability);
226
227 if (node is IMayRequireBitangent c)
228 reqs.m_RequiresBitangent |= c.RequiresBitangent(stageCapability);
229
230 if (node is IMayRequireTangent d)
231 reqs.m_RequiresTangent |= d.RequiresTangent(stageCapability);
232
233 if (node is IMayRequireViewDirection e)
234 reqs.m_RequiresViewDir |= e.RequiresViewDirection(stageCapability);
235
236 if (node is IMayRequirePosition f)
237 reqs.m_RequiresPosition |= f.RequiresPosition(stageCapability);
238
239 if (node is IMayRequirePositionPredisplacement g)
240 reqs.m_RequiresPositionPredisplacement |= g.RequiresPositionPredisplacement(stageCapability);
241
242 if (!reqs.m_RequiresScreenPosition && node is IMayRequireScreenPosition h)
243 reqs.m_RequiresScreenPosition = h.RequiresScreenPosition(stageCapability);
244
245 if (!reqs.m_RequiresNDCPosition && node is IMayRequireNDCPosition i)
246 reqs.m_RequiresNDCPosition = i.RequiresNDCPosition(stageCapability);
247
248 if (!reqs.m_RequiresPixelPosition && node is IMayRequirePixelPosition j)
249 reqs.m_RequiresPixelPosition = j.RequiresPixelPosition(stageCapability);
250
251 if (!reqs.m_RequiresVertexColor && node is IMayRequireVertexColor k)
252 reqs.m_RequiresVertexColor = k.RequiresVertexColor(stageCapability);
253
254 if (!reqs.m_RequiresFaceSign && node is IMayRequireFaceSign l)
255 reqs.m_RequiresFaceSign = l.RequiresFaceSign(stageCapability);
256
257 if (!reqs.m_RequiresDepthTexture && node is IMayRequireDepthTexture m)
258 reqs.m_RequiresDepthTexture = m.RequiresDepthTexture(stageCapability);
259
260 if (!reqs.m_RequiresCameraOpaqueTexture && node is IMayRequireCameraOpaqueTexture n)
261 reqs.m_RequiresCameraOpaqueTexture = n.RequiresCameraOpaqueTexture(stageCapability);
262
263 if (!reqs.m_RequiresTime)
264 reqs.m_RequiresTime = node.RequiresTime();
265
266 if (!reqs.m_RequiresVertexSkinning && node is IMayRequireVertexSkinning o)
267 reqs.m_RequiresVertexSkinning = o.RequiresVertexSkinning(stageCapability);
268
269 if (!reqs.m_RequiresVertexID && node is IMayRequireVertexID p)
270 reqs.m_RequiresVertexID = p.RequiresVertexID(stageCapability);
271
272 if (node is IMayRequireMeshUV q)
273 {
274 for (int uvIndex = 0; uvIndex < ShaderGeneratorNames.UVCount; ++uvIndex)
275 {
276 var channel = (UVChannel)uvIndex;
277 if (q.RequiresMeshUV(channel))
278 {
279 reqs.m_RequiresMeshUVs.Add(channel);
280 if (texCoordNeedsDerivs is not null &&
281 uvIndex < texCoordNeedsDerivs.Length &&
282 texCoordNeedsDerivs[uvIndex])
283 {
284 reqs.m_RequiresMeshUVDerivatives.Add(channel);
285 }
286 }
287 }
288 }
289
290 if (!reqs.m_RequiresInstanceID && node is IMayRequireInstanceID r)
291 reqs.m_RequiresInstanceID = r.RequiresInstanceID(stageCapability);
292 }
293
294 reqs.m_RequiresTransforms = reqs.m_RequiresTransforms.Distinct().ToList();
295
296 // if anything needs tangentspace we have make
297 // sure to have our othonormal basis!
298 if (includeIntermediateSpaces)
299 {
300 var compoundSpaces = reqs.m_RequiresBitangent | reqs.m_RequiresNormal | reqs.m_RequiresPosition
301 | reqs.m_RequiresTangent | reqs.m_RequiresViewDir | reqs.m_RequiresPosition
302 | reqs.m_RequiresNormal;
303
304 var needsTangentSpace = (compoundSpaces & NeededCoordinateSpace.Tangent) > 0;
305 if (needsTangentSpace)
306 {
307 reqs.m_RequiresBitangent |= NeededCoordinateSpace.World;
308 reqs.m_RequiresNormal |= NeededCoordinateSpace.World;
309 reqs.m_RequiresTangent |= NeededCoordinateSpace.World;
310 }
311 }
312
313 return reqs;
314 }
315
316 internal static ShaderGraphRequirements FromUvDerivativeList(List<UVChannel> meshUVDerivatives)
317 {
318 var reqs = new ShaderGraphRequirements()
319 {
320 m_RequiresMeshUVDerivatives = meshUVDerivatives,
321 };
322
323 return reqs;
324 }
325 }
326}