Paradox Game Engine  v1.0.0 beta06
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Events Macros Pages
MaterialReductionUtils.cs
Go to the documentation of this file.
1 // Copyright (c) 2014 Silicon Studio Corp. (http://siliconstudio.co.jp)
2 // This file is distributed under GPL v3. See LICENSE.md for details.
3 using System;
4 using SiliconStudio.Core.Mathematics;
5 using SiliconStudio.Paradox.Assets.Materials.Nodes;
6 
7 namespace SiliconStudio.Paradox.Assets.Materials.Processor.Visitors
8 {
9  internal class MaterialReductionUtils
10  {
11  /// <summary>
12  /// Perform the operation between two floats on CPU
13  /// </summary>
14  /// <param name="leftValue">The value of the left child.</param>
15  /// <param name="rightValue">The value of the right child.</param>
16  /// <param name="operand">The operation between the two values.</param>
17  /// <returns>The new float</returns>
18  public static float MixFloat(float leftValue, float rightValue, MaterialBinaryOperand operand)
19  {
20  switch (operand)
21  {
22  case MaterialBinaryOperand.Add:
23  return leftValue + rightValue;
24  case MaterialBinaryOperand.Average:
25  return 0.5f * (leftValue + rightValue);
26  case MaterialBinaryOperand.Divide:
27  return leftValue / rightValue;
28  case MaterialBinaryOperand.Multiply:
29  return leftValue * rightValue;
30  case MaterialBinaryOperand.None:
31  case MaterialBinaryOperand.Opaque:
32  return leftValue;
33  case MaterialBinaryOperand.Subtract:
34  return leftValue - rightValue;
35  default:
36  throw new ArgumentOutOfRangeException("Operand not supported between two floats");
37  }
38  }
39 
40  /// <summary>
41  /// Perform the operation between two float4 on CPU
42  /// </summary>
43  /// <param name="leftValue">The value of the left child.</param>
44  /// <param name="rightValue">The value of the right child.</param>
45  /// <param name="operand">The operation between the two values.</param>
46  /// <returns>The new float4</returns>
47  public static Vector4 MixFloat4(Vector4 leftValue, Vector4 rightValue, MaterialBinaryOperand operand)
48  {
49  switch (operand)
50  {
51  case MaterialBinaryOperand.Add:
52  return Add(leftValue, rightValue);
53  case MaterialBinaryOperand.Average:
54  return Average(leftValue, rightValue);
55  case MaterialBinaryOperand.Color:
56  return Color(leftValue, rightValue);
57  case MaterialBinaryOperand.ColorBurn:
58  return ColorBurn(leftValue, rightValue);
59  case MaterialBinaryOperand.ColorDodge:
60  return ColorDodge(leftValue, rightValue);
61  case MaterialBinaryOperand.Darken:
62  return Darken(leftValue, rightValue);
63  case MaterialBinaryOperand.Desaturate:
64  return Desaturate(leftValue, rightValue);
65  case MaterialBinaryOperand.Difference:
66  return Difference(leftValue, rightValue);
67  case MaterialBinaryOperand.Divide:
68  return Divide(leftValue, rightValue);
69  case MaterialBinaryOperand.Exclusion:
70  return Exclusion(leftValue, rightValue);
71  case MaterialBinaryOperand.HardLight:
72  return HardLight(leftValue, rightValue);
73  case MaterialBinaryOperand.HardMix:
74  return HardMix(leftValue, rightValue);
75  case MaterialBinaryOperand.Hue:
76  return Hue(leftValue, rightValue);
77  case MaterialBinaryOperand.Illuminate:
78  return Illuminate(leftValue, rightValue);
79  case MaterialBinaryOperand.In:
80  return In(leftValue, rightValue);
81  case MaterialBinaryOperand.Lighten:
82  return Lighten(leftValue, rightValue);
83  case MaterialBinaryOperand.LinearBurn:
84  return LinearBurn(leftValue, rightValue);
85  case MaterialBinaryOperand.LinearDodge:
86  return LinearDodge(leftValue, rightValue);
87  case MaterialBinaryOperand.Mask:
88  return Mask(leftValue, rightValue);
89  case MaterialBinaryOperand.Multiply:
90  return Multiply(leftValue, rightValue);
91  case MaterialBinaryOperand.None:
92  return None(leftValue, rightValue);
93  case MaterialBinaryOperand.Opaque:
94  return Opaque(leftValue, rightValue);
95  case MaterialBinaryOperand.Out:
96  return Out(leftValue, rightValue);
97  case MaterialBinaryOperand.Over:
98  return Over(leftValue, rightValue);
99  case MaterialBinaryOperand.Overlay:
100  return Overlay(leftValue, rightValue);
101  case MaterialBinaryOperand.PinLight:
102  return PinLight(leftValue, rightValue);
103  case MaterialBinaryOperand.Saturate:
104  return Saturate(leftValue, rightValue);
105  case MaterialBinaryOperand.Saturation:
106  return Saturation(leftValue, rightValue);
107  case MaterialBinaryOperand.Screen:
108  return Screen(leftValue, rightValue);
109  case MaterialBinaryOperand.SoftLight:
110  return SoftLight(leftValue, rightValue);
111  case MaterialBinaryOperand.Subtract:
112  return Subtract(leftValue, rightValue);
113  case MaterialBinaryOperand.SubstituteAlpha:
114  return SubstituteAlpha(leftValue, rightValue);
115  default:
116  throw new ArgumentOutOfRangeException("operand");
117  }
118  }
119 
120  /// <summary>
121  /// Perform the operation between two colors on CPU
122  /// </summary>
123  /// <param name="leftValue">The value of the left child.</param>
124  /// <param name="rightValue">The value of the right child.</param>
125  /// <param name="operand">The operation between the two values.</param>
126  /// <returns>The new Color</returns>
127  public static Color4 MixColor(Color4 leftValue, Color4 rightValue, MaterialBinaryOperand operand)
128  {
129  Vector4 res = MixFloat4(leftValue.ToVector4(), rightValue.ToVector4(), operand);
130  return new Color4(res);
131  }
132 
133  ///////////////////////////////////////////////////////
134  //
135  // Blend functions utils
136  //
137  ///////////////////////////////////////////////////////
138 
139  private static Vector4 BasicColorBlend(Vector4 backColor, Vector4 frontColor, Vector4 interColor)
140  {
141  return frontColor.W * backColor.W * interColor + frontColor.W * (1.0f - backColor.W) * frontColor + (1.0f - frontColor.W) * backColor.W * backColor;
142  }
143 
144  private static float BasicAlphaBlend(float ba, float fa)
145  {
146  return fa * (1.0f - ba) + ba;
147  }
148 
149  private static Vector4 BasicBlend(Vector4 backColor, Vector4 frontColor, Vector4 interColor)
150  {
151  var temp = BasicColorBlend(backColor, frontColor, interColor);
152  temp.W = BasicAlphaBlend(backColor.W, frontColor.W);
153  return temp;
154  }
155 
156  private static float GetSaturation(Vector4 tex)
157  {
158  float max = Math.Max(Math.Max(tex.X, tex.Y), tex.Z);
159 
160  if (max < 1.0e-10)
161  return 0.0f;
162 
163  return 1.0f - Math.Min(Math.Min(tex.X, tex.Y), tex.Z) / max;
164  }
165 
166  private static float GetValue(Vector4 tex)
167  {
168  return Math.Max(Math.Max(tex.X, tex.Y), tex.Z);
169  }
170 
171  private static float GetHue(Vector4 tex)
172  {
173  float max = Math.Max(Math.Max(tex.X, tex.Y), tex.Z);
174  float delta = max - Math.Min(Math.Min(tex.X, tex.Y), tex.Z);
175 
176  if (delta < 1.0e-10)
177  return 0.0f;
178  if (max == tex.X)
179  return (tex.Y - tex.Z) / (6.0f * delta);
180  if (max == tex.Y)
181  return 1.0f / 3.0f + (tex.Z - tex.X) / (6.0f * delta);
182 
183  return 2.0f / 3.0f + (tex.X - tex.Y) / (6.0f * delta);
184  }
185 
186  private static Vector4 HSVToRGB(float hue, float saturation, float value)
187  {
188  var ti = (int)Math.Floor(1.0f - hue < 1.0e-10 ? 0.0f : hue * 6.0f);
189  var f = hue * 6.0f - ti;
190  var l = value * (1.0f - saturation);
191  var m = value * (1.0f - f * saturation);
192  var n = value * (1.0f - (1.0f - f) * saturation);
193 
194  switch (ti)
195  {
196  case 0:
197  return new Vector4(value, n, l, 0.0f);
198  case 1:
199  return new Vector4(m, value, l, 0.0f);
200  case 2:
201  return new Vector4(l, value, n, 0.0f);
202  case 3:
203  return new Vector4(l, m, value, 0.0f);
204  case 4:
205  return new Vector4(n, l, value, 0.0f);
206  case 5:
207  return new Vector4(value, l, m, 0.0f);
208  default:
209  throw new Exception("Unable to convert HSV to RGB");
210  }
211  }
212 
213  private static float ColorDivide(float t1, float t2)
214  {
215  if (t2 < 1.0e-10)
216  {
217  if (t1 < 1.0e-10)
218  return 0.0f;
219  return 1.0f;
220  }
221 
222  return t1 / t2;
223  }
224 
225  private static Vector4 TermMultiply(Vector4 v1, Vector4 v2)
226  {
227  return new Vector4(v1.X * v2.X, v1.Y * v2.Y, v1.Z * v2.Z, v1.W * v2.W);
228  }
229 
230  private static Vector4 TermDivide(Vector4 v1, Vector4 v2)
231  {
232  return new Vector4(
233  ColorDivide(v1.X, v2.X),
234  ColorDivide(v1.Y, v2.Y),
235  ColorDivide(v1.Z, v2.Z),
236  ColorDivide(v1.W, v2.W)
237  );
238  }
239 
240  private static Vector4 Lerp(Vector4 v1, Vector4 v2, float coeff)
241  {
242  return v1 + coeff * (v2 - v1);
243  }
244 
245  private static float Saturate(float a)
246  {
247  return Math.Max(0.0f, Math.Min(a, 1.0f));
248  }
249 
250  ///////////////////////////////////////////////////////
251  //
252  // Blend functions
253  //
254  ///////////////////////////////////////////////////////
255 
256 
257  private static Vector4 Add(Vector4 backColor, Vector4 frontColor)
258  {
259  // 3DS Max version
260  var interColor = backColor + frontColor;
261  return BasicBlend(backColor, frontColor, interColor);
262 
263  //// Maya version
264  //interColor = backColor + frontColor * frontColor.W;
265  //interColor.W = backColor.W;
266  //return interColor;
267  }
268 
269  private static Vector4 Average(Vector4 backColor, Vector4 frontColor)
270  {
271  var interColor = 0.5f * (backColor + frontColor);
272  return BasicBlend(backColor, frontColor, interColor);
273  }
274 
275  private static Vector4 Color(Vector4 backColor, Vector4 frontColor)
276  {
277  Vector4 interColor;
278  var frontSaturation = GetSaturation(frontColor);
279  if (frontSaturation < 1.0e-10)
280  {
281  interColor = GetValue(backColor) * Vector4.One;
282  }
283  else
284  {
285  interColor = HSVToRGB(GetHue(frontColor), GetSaturation(frontColor), GetValue(backColor));
286  }
287  interColor.W = BasicAlphaBlend(backColor.W, frontColor.W);
288  return interColor;
289  }
290 
291  private static Vector4 ColorBurn(Vector4 backColor, Vector4 frontColor)
292  {
293  return new Vector4(
294  1.0f - ColorDivide(1.0f - backColor.X, frontColor.X),
295  1.0f - ColorDivide(1.0f - backColor.Y, frontColor.Y),
296  1.0f - ColorDivide(1.0f - backColor.Z, frontColor.Z),
297  1.0f - ColorDivide(1.0f - backColor.W, frontColor.W)
298  );
299  }
300 
301  private static Vector4 ColorDodge(Vector4 backColor, Vector4 frontColor)
302  {
303  var frontColor3 = new Vector3(frontColor.X, frontColor.Y, frontColor.Z);
304  var interColor = new Vector4();
305  if (frontColor3 == Vector3.One)
306  {
307  interColor.X = backColor.X == 1.0f ? 1.0f : 0.0f;
308  interColor.Y = backColor.Y == 1.0f ? 1.0f : 0.0f;
309  interColor.Z = backColor.Z == 1.0f ? 1.0f : 0.0f;
310  }
311  else
312  {
313  interColor = TermDivide(backColor, Vector4.One - frontColor);
314  interColor.X = Saturate(interColor.X);
315  interColor.Y = Saturate(interColor.Y);
316  interColor.Z = Saturate(interColor.Z);
317  }
318  return BasicBlend(backColor, frontColor, interColor);
319  }
320 
321  private static Vector4 Darken(Vector4 backColor, Vector4 frontColor)
322  {
323  // 3DS Max version
324  var alphaBack = backColor.W * backColor;
325  var alphaFront = frontColor.W * frontColor;
326  var interColor0 = Lerp(alphaBack, frontColor, frontColor.W);
327  var interColor1 = Lerp(alphaFront, backColor, backColor.W);
328  return new Vector4(
329  Math.Min(interColor0.X, interColor1.X),
330  Math.Min(interColor0.Y, interColor1.Y),
331  Math.Min(interColor0.Z, interColor1.Z),
332  BasicAlphaBlend(backColor.W, frontColor.W)
333  );
334 
335  //// Maya version
336  //var min = new Vector4(
337  // Math.Min(frontColor.X, backColor.X),
338  // Math.Min(frontColor.Y, backColor.Y),
339  // Math.Min(frontColor.Z, backColor.Z),
340  // 0.0f
341  // );
342  //var interColor = Lerp(backColor, min, frontColor.W);
343  //interColor.W = backColor.W;
344  //return interColor;
345  }
346 
347  private static Vector4 Desaturate(Vector4 backColor, Vector4 frontColor)
348  {
349  var interColor = TermMultiply(backColor, Vector4.One - frontColor.W * frontColor);
350  interColor.W = backColor.W;
351  return interColor;
352  }
353 
354  private static Vector4 Difference(Vector4 backColor, Vector4 frontColor)
355  {
356  // 3DS Max version
357  var interColor = frontColor - backColor;
358  interColor.X = Math.Abs(interColor.X);
359  interColor.Y = Math.Abs(interColor.Y);
360  interColor.Z = Math.Abs(interColor.Z);
361 
362  return BasicBlend(backColor, frontColor, interColor);
363 
364  //// Maya version
365  //var diff = new Vector4(
366  // Math.Abs(frontColor.X - backColor.X),
367  // Math.Abs(frontColor.Y - backColor.Y),
368  // Math.Abs(frontColor.Z - backColor.Z),
369  // 0.0f
370  // );
371  //interColor = Lerp(backColor, diff, frontColor.W);
372  //interColor.W = backColor.W;
373  //return interColor;
374  }
375 
376  private static Vector4 Divide(Vector4 backColor, Vector4 frontColor)
377  {
378  var interColor = new Vector4(
379  ColorDivide(backColor.X, frontColor.X),
380  ColorDivide(backColor.Y, frontColor.Y),
381  ColorDivide(backColor.Z, frontColor.Z),
382  0.0f
383  );
384  interColor.W = BasicAlphaBlend(backColor.W, frontColor.W);
385  return interColor;
386  }
387 
388  private static Vector4 Exclusion(Vector4 backColor, Vector4 frontColor)
389  {
390  var interColor = backColor + frontColor - 2.0f * TermMultiply(backColor, frontColor);
391  return BasicBlend(backColor, frontColor, interColor);
392  }
393 
394  private static Vector4 HardLight(Vector4 backColor, Vector4 frontColor)
395  {
396  var step = new Vector4(
397  frontColor.X < 0.5f ? 0.0f : 1.0f,
398  frontColor.Y < 0.5f ? 0.0f : 1.0f,
399  frontColor.Z < 0.5f ? 0.0f : 1.0f,
400  0.0f
401  );
402  var v1 = 2.0f * TermMultiply(frontColor, backColor);
403  var v2 = Vector4.One - 2.0f * TermMultiply(Vector4.One - frontColor, Vector4.One - backColor);
404  var interColor = v1 - TermMultiply(step, v2 - v1);
405  return BasicBlend(backColor, frontColor, interColor);
406  }
407 
408  private static Vector4 HardMix(Vector4 backColor, Vector4 frontColor)
409  {
410  var step = new Vector4(
411  frontColor.X + backColor.X < 1.0f ? 0.0f : 1.0f,
412  frontColor.Y + backColor.Y < 1.0f ? 0.0f : 1.0f,
413  frontColor.Z + backColor.Z < 1.0f ? 0.0f : 1.0f,
414  1.0f
415  );
416  return BasicBlend(backColor, frontColor, Vector4.One - step);
417  }
418 
419  private static Vector4 Hue(Vector4 backColor, Vector4 frontColor)
420  {
421  Vector4 interColor;
422  if (GetSaturation(frontColor) < 1.0e-10)
423  {
424  interColor = GetValue(backColor) * Vector4.One;
425  }
426  else
427  {
428  interColor = HSVToRGB(GetHue(frontColor), GetSaturation(backColor), GetValue(backColor));
429  }
430  interColor.W = BasicAlphaBlend(backColor.W, frontColor.W);
431  return interColor;
432  }
433 
434  private static Vector4 Illuminate(Vector4 backColor, Vector4 frontColor)
435  {
436  var interColor = TermMultiply(backColor, 2.0f * frontColor.W * frontColor + (1.0f - frontColor.W) * Vector4.One);
437  interColor.W = backColor.W;
438  return interColor;
439  }
440 
441  private static Vector4 In(Vector4 backColor, Vector4 frontColor)
442  {
443  return backColor * frontColor.W;
444  }
445 
446  private static Vector4 Lighten(Vector4 backColor, Vector4 frontColor)
447  {
448  // 3DS Max version
449  var v1 = Lerp(backColor * backColor.W, frontColor, frontColor.W);
450  var v2 = Lerp(frontColor * frontColor.W, backColor, backColor.W);
451  return new Vector4(
452  Math.Max(v1.X, v2.X),
453  Math.Max(v1.Y, v2.Y),
454  Math.Max(v1.Z, v2.Z),
455  BasicAlphaBlend(backColor.W, frontColor.W)
456  );
457 
458  //// Maya version
459  //var maxColor = new Vector4(
460  // Math.Max(backColor.X, frontColor.X),
461  // Math.Max(backColor.Y, frontColor.Y),
462  // Math.Max(backColor.Z, frontColor.Z),
463  // 1.0f
464  // );
465  //var interColor = Lerp(backColor, maxColor, frontColor.W);
466  //interColor.W = backColor.W;
467  //return interColor;
468  }
469 
470  private static Vector4 LinearBurn(Vector4 backColor, Vector4 frontColor)
471  {
472  var sum = frontColor + backColor;
473  var interColor = new Vector4(
474  sum.X > 1.0f ? sum.X - 1.0f : 0.0f,
475  sum.Y > 1.0f ? sum.Y - 1.0f : 0.0f,
476  sum.Z > 1.0f ? sum.Z - 1.0f : 0.0f,
477  0.0f
478  );
479  return BasicBlend(backColor, frontColor, interColor);
480  }
481 
482  private static Vector4 LinearDodge(Vector4 backColor, Vector4 frontColor)
483  {
484  var interColor = new Vector4(
485  Saturate(backColor.X + frontColor.X),
486  Saturate(backColor.Y + frontColor.Y),
487  Saturate(backColor.Z + frontColor.Z),
488  1.0f
489  );
490  return BasicBlend(backColor, frontColor, interColor);
491  }
492 
493  private static Vector4 Mask(Vector4 backColor, Vector4 frontColor)
494  {
495  return new Vector4(backColor.X, backColor.Y, backColor.Z, backColor.W * (frontColor.X + frontColor.Y + frontColor.Z) / 3.0f);
496  }
497 
498  private static Vector4 Multiply(Vector4 backColor, Vector4 frontColor)
499  {
500  // 3DS Max version
501  var interColor = TermMultiply(backColor, frontColor);
502  return BasicBlend(backColor, frontColor, interColor);
503 
504  //// Maya version
505  //interColor = TermMultiply(backColor, Lerp(Vector4.One, frontColor, frontColor.W));
506  //interColor.W = backColor.W;
507  //return interColor;
508  }
509 
510  private static Vector4 None(Vector4 backColor, Vector4 frontColor)
511  {
512  return backColor;
513  }
514 
515  private static Vector4 Opaque(Vector4 backColor, Vector4 frontColor)
516  {
517  return new Vector4(backColor.X, backColor.Y, backColor.Z, 1.0f);
518  }
519 
520  private static Vector4 Out(Vector4 backColor, Vector4 frontColor)
521  {
522  return backColor * (1.0f - frontColor.W);
523  }
524 
525  private static Vector4 Over(Vector4 backColor, Vector4 frontColor)
526  {
527  // 3DS max version
528  return BasicBlend(backColor, frontColor, frontColor);
529 
530  //// Maya version
531  //var interColor = Lerp(backColor, frontColor, frontColor.W);
532  //interColor.W = BasicAlphaBlend(backColor.W, frontColor.W);
533  //return interColor;
534  }
535 
536  private static Vector4 Overlay(Vector4 backColor, Vector4 frontColor)
537  {
538  // 3DS Version
539  var lerp0 = 2.0f * TermMultiply(backColor, frontColor);
540  var lerp1 = Vector4.One - 2.0f * TermMultiply(Vector4.One - backColor, Vector4.One - frontColor);
541 
542  var stepX = frontColor.X < 0.5f ? 0.0f : 1.0f;
543  var stepY = frontColor.Y < 0.5f ? 0.0f : 1.0f;
544  var stepZ = frontColor.Z < 0.5f ? 0.0f : 1.0f;
545  var stepW = frontColor.W < 0.5f ? 0.0f : 1.0f;
546 
547  return new Vector4(
548  lerp0.X + stepX * (lerp1.X - lerp0.X),
549  lerp0.Y + stepY * (lerp1.Y - lerp0.Y),
550  lerp0.Z + stepZ * (lerp1.Z - lerp0.Z),
551  lerp0.W + stepW * (lerp1.W - lerp0.W)
552  );
553  }
554 
555  private static Vector4 PinLight(Vector4 backColor, Vector4 frontColor)
556  {
557  var v1 = 2.0f * frontColor;
558  var max = new Vector4(
559  Math.Max(backColor.X, v1.X - 1.0f),
560  Math.Max(backColor.Y, v1.Y - 1.0f),
561  Math.Max(backColor.Z, v1.Z - 1.0f),
562  0.0f
563  );
564  var min = new Vector4(
565  Math.Min(backColor.X, v1.X),
566  Math.Min(backColor.Y, v1.Y),
567  Math.Min(backColor.Z, v1.Z),
568  0.0f
569  );
570  var step = new Vector4(
571  frontColor.X < 0.5f ? 1.0f : 0.0f,
572  frontColor.Y < 0.5f ? 1.0f : 0.0f,
573  frontColor.Z < 0.5f ? 1.0f : 0.0f,
574  0.0f
575  );
576  var interColor = max + TermMultiply(step, min - max);
577  return BasicBlend(backColor, frontColor, interColor);
578  }
579 
580  private static Vector4 Saturate(Vector4 backColor, Vector4 frontColor)
581  {
582  var interColor = TermMultiply(backColor, Vector4.One + (frontColor * frontColor.W));
583  interColor.W = backColor.W;
584  return interColor;
585  }
586 
587  private static Vector4 Saturation(Vector4 backColor, Vector4 frontColor)
588  {
589  Vector4 interColor;
590  if (GetSaturation(backColor) < 1.0e-10)
591  {
592  interColor = GetValue(backColor) * Vector4.One;
593  }
594  else
595  {
596  interColor = HSVToRGB(GetHue(backColor), GetSaturation(frontColor), GetValue(backColor));
597  }
598  interColor.W = BasicAlphaBlend(backColor.W, frontColor.W);
599  return interColor;
600  }
601 
602  private static Vector4 Screen(Vector4 backColor, Vector4 frontColor)
603  {
604  var v1 = backColor.W * backColor;
605  var interColor = TermMultiply(frontColor * frontColor.W, Vector4.One - v1) + v1;
606  interColor.W = BasicAlphaBlend(backColor.W, frontColor.W);
607  return interColor;
608  }
609 
610  private static float SoftLightTest(float bc, float fc)
611  {
612  if (fc < 0.5f)
613  return bc * (1.0f + (1.0f - bc) * (2.0f * fc - 1.0f));
614  if (bc < 9.0f / 64.0f)
615  return bc * (bc * (9.0f - 18.0f * fc) + 5.76f * fc - 1.88f);
616  return bc + ((float)Math.Sqrt(bc) - bc) * (2.0f * fc - 1.0f);
617  }
618 
619  private static Vector4 SoftLight(Vector4 backColor, Vector4 frontColor)
620  {
621  return new Vector4(
622  SoftLightTest(backColor.X, frontColor.X),
623  SoftLightTest(backColor.Y, frontColor.Y),
624  SoftLightTest(backColor.Z, frontColor.Z),
625  BasicAlphaBlend(backColor.W, frontColor.W));
626  }
627 
628  private static Vector4 Subtract(Vector4 backColor, Vector4 frontColor)
629  {
630  // 3DS Max version
631  var interColor = backColor - frontColor;
632  return BasicBlend(backColor, frontColor, interColor);
633 
634  //// Maya version
635  //interColor = backColor - frontColor.W * frontColor;
636  //interColor.W = backColor.W;
637  //return interColor;
638  }
639 
640  private static Vector4 SubstituteAlpha(Vector4 backColor, Vector4 frontColor)
641  {
642  var interColor = backColor;
643  interColor.W = frontColor.W;
644  return interColor;
645  }
646 
647  private static Vector4 Value(Vector4 backColor, Vector4 frontColor)
648  {
649  Vector4 interColor;
650  if (GetSaturation(backColor) < 1.0e-10)
651  interColor = GetValue(backColor) * Vector4.One;
652  else
653  {
654  interColor = HSVToRGB(GetHue(backColor), GetValue(backColor), GetValue(frontColor));
655  }
656  interColor.W = BasicAlphaBlend(backColor.W, frontColor.W);
657  return interColor;
658  }
659  }
660 }
Hue effect from the two textures.
float W
The W component of the vector.
Definition: Vector4.cs:101
Screen effect from the two textures.
function a
Illuminate effect from the two textures.
float X
The X component of the vector.
Definition: Vector4.cs:83
Apply mask from second texture to the first one.
Over effect from the two textures.
Color burn effect from the two textures.
Represents a three dimensional mathematical vector.
Definition: Vector3.cs:42
Take color for the first texture but alpha from the second
static readonly Vector3 One
A SiliconStudio.Core.Mathematics.Vector3 with all of its components set to one.
Definition: Vector3.cs:72
Take color for the first texture and use alpha = 1
Represents a color in the form of rgba.
Definition: Color4.cs:42
Saturation effect from the two textures.
MaterialBinaryOperand
Operands of the MaterialNode.
Represents a four dimensional mathematical vector.
Definition: Vector4.cs:42
SiliconStudio.Core.Mathematics.Color Color
Definition: ColorPicker.cs:14
Search for out only dependencies.
Saturate effect from the two textures.
Exclusion effect from the two textures.
Vector4 ToVector4()
Converts the color into a four component vector.
Definition: Color4.cs:295
Overlay effect from the two textures.
Soft light effect from the two textures.
Hard light effect from the two textures.
Linear dodge effect from the two textures.
float Y
The Y component of the vector.
Definition: Vector4.cs:89
Desaturate effect from the two textures.
Linear burn effect from the two textures.
SiliconStudio.Core.Mathematics.Vector3 Vector3
Search for in only dependencies.
float Z
The Z component of the vector.
Definition: Vector4.cs:95
hard mix effect from the two textures.
Pin light effect from the two textures.
static readonly Vector4 One
A SiliconStudio.Core.Mathematics.Vector4 with all of its components set to one.
Definition: Vector4.cs:77
Color dodge effect from the two textures.
Darken effect from the two textures.
Lighten effect from the two textures.