4 using SiliconStudio.Core.Mathematics;
 
    5 using SiliconStudio.Paradox.Assets.Materials.Nodes;
 
    7 namespace SiliconStudio.
Paradox.Assets.Materials.Processor.Visitors
 
    9     internal class MaterialReductionUtils
 
   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:
 
   33                 case MaterialBinaryOperand.Subtract:
 
   34                     return leftValue - rightValue;
 
   36                     throw new ArgumentOutOfRangeException(
"Operand not supported between two floats");
 
   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:
 
   59                 case MaterialBinaryOperand.ColorDodge:
 
   61                 case MaterialBinaryOperand.Darken:
 
   62                     return Darken(leftValue, rightValue);
 
   63                 case MaterialBinaryOperand.Desaturate:
 
   65                 case MaterialBinaryOperand.Difference:
 
   67                 case MaterialBinaryOperand.Divide:
 
   68                     return Divide(leftValue, rightValue);
 
   69                 case MaterialBinaryOperand.Exclusion:
 
   71                 case MaterialBinaryOperand.HardLight:
 
   73                 case MaterialBinaryOperand.HardMix:
 
   74                     return HardMix(leftValue, rightValue);
 
   75                 case MaterialBinaryOperand.Hue:
 
   76                     return Hue(leftValue, rightValue);
 
   77                 case MaterialBinaryOperand.Illuminate:
 
   79                 case MaterialBinaryOperand.In:
 
   80                     return In(leftValue, rightValue);
 
   81                 case MaterialBinaryOperand.Lighten:
 
   82                     return Lighten(leftValue, rightValue);
 
   83                 case MaterialBinaryOperand.LinearBurn:
 
   85                 case MaterialBinaryOperand.LinearDodge:
 
   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:
 
  107                 case MaterialBinaryOperand.Screen:
 
  108                     return Screen(leftValue, rightValue);
 
  109                 case MaterialBinaryOperand.SoftLight:
 
  111                 case MaterialBinaryOperand.Subtract:
 
  112                     return Subtract(leftValue, rightValue);
 
  113                 case MaterialBinaryOperand.SubstituteAlpha:
 
  116                     throw new ArgumentOutOfRangeException(
"operand");
 
  129             Vector4 res = MixFloat4(leftValue.
ToVector4(), rightValue.ToVector4(), operand);
 
  141             return frontColor.W * backColor.W * interColor + frontColor.W * (1.0f - backColor.W) * frontColor + (1.0f - frontColor.
W) * backColor.W * backColor;
 
  144         private static float BasicAlphaBlend(
float ba, 
float fa)
 
  146             return fa * (1.0f - ba) + ba;
 
  151             var temp = BasicColorBlend(backColor, frontColor, interColor);
 
  152             temp.W = BasicAlphaBlend(backColor.
W, frontColor.
W);
 
  156         private static float GetSaturation(
Vector4 tex)
 
  158             float max = Math.Max(Math.Max(tex.X, tex.Y), tex.
Z);
 
  163             return 1.0f - Math.Min(Math.Min(tex.X, tex.Y), tex.Z) / max;
 
  166         private static float GetValue(
Vector4 tex)
 
  168             return Math.Max(Math.Max(tex.X, tex.Y), tex.
Z);
 
  171         private static float GetHue(
Vector4 tex)
 
  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);
 
  179                 return (tex.Y - tex.Z) / (6.0f * delta);
 
  181                 return 1.0f / 3.0f + (tex.Z - tex.X) / (6.0f * delta);
 
  183             return 2.0f / 3.0f + (tex.X - tex.Y) / (6.0f * delta);
 
  186         private static Vector4 HSVToRGB(
float hue, 
float saturation, 
float value)
 
  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);
 
  197                     return new Vector4(value, n, l, 0.0f);
 
  199                     return new Vector4(m, value, l, 0.0f);
 
  201                     return new Vector4(l, value, n, 0.0f);
 
  203                     return new Vector4(l, m, value, 0.0f);
 
  205                     return new Vector4(n, l, value, 0.0f);
 
  207                     return new Vector4(value, l, m, 0.0f);
 
  209                     throw new Exception(
"Unable to convert HSV to RGB");
 
  213         private static float ColorDivide(
float t1, 
float t2)
 
  227             return new Vector4(v1.
X * v2.
X, v1.
Y * v2.
Y, v1.
Z * v2.
Z, v1.
W * v2.
W);
 
  233                 ColorDivide(v1.
X, v2.
X),
 
  234                 ColorDivide(v1.
Y, v2.
Y),
 
  235                 ColorDivide(v1.
Z, v2.
Z),
 
  236                 ColorDivide(v1.
W, v2.
W)
 
  242             return v1 + coeff * (v2 - v1);
 
  247             return Math.Max(0.0f, Math.Min(
a, 1.0f));
 
  260             var interColor = backColor + frontColor;
 
  261             return BasicBlend(backColor, frontColor, interColor);
 
  271             var interColor = 0.5f * (backColor + frontColor);
 
  272             return BasicBlend(backColor, frontColor, interColor);
 
  278             var frontSaturation = GetSaturation(frontColor);
 
  279             if (frontSaturation < 1.0e-10)
 
  281                 interColor = GetValue(backColor) * Vector4.One;
 
  285                 interColor = HSVToRGB(GetHue(frontColor), GetSaturation(frontColor), GetValue(backColor));
 
  287             interColor.W = BasicAlphaBlend(backColor.
W, frontColor.
W);
 
  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)
 
  303             var frontColor3 = 
new Vector3(frontColor.
X, frontColor.
Y, frontColor.
Z);
 
  304             var interColor = 
new Vector4();
 
  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;
 
  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);
 
  318             return BasicBlend(backColor, frontColor, interColor);
 
  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);
 
  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)
 
  349             var interColor = TermMultiply(backColor, 
Vector4.
One - frontColor.
W * frontColor);
 
  350             interColor.W = backColor.W;
 
  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);
 
  362             return BasicBlend(backColor, frontColor, interColor);
 
  379                 ColorDivide(backColor.
X, frontColor.
X),
 
  380                 ColorDivide(backColor.
Y, frontColor.
Y),
 
  381                 ColorDivide(backColor.
Z, frontColor.
Z),
 
  384             interColor.W = BasicAlphaBlend(backColor.
W, frontColor.
W);
 
  390             var interColor = backColor + frontColor - 2.0f * TermMultiply(backColor, frontColor);
 
  391             return BasicBlend(backColor, frontColor, interColor);
 
  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,
 
  402             var v1 = 2.0f * TermMultiply(frontColor, backColor);
 
  404             var interColor = v1 - TermMultiply(step, v2 - v1);
 
  405             return BasicBlend(backColor, frontColor, interColor);
 
  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,
 
  416             return BasicBlend(backColor, frontColor, 
Vector4.
One - step);
 
  422             if (GetSaturation(frontColor) < 1.0e-10)
 
  424                 interColor = GetValue(backColor) * Vector4.One;
 
  428                 interColor = HSVToRGB(GetHue(frontColor), GetSaturation(backColor), GetValue(backColor));
 
  430             interColor.W = BasicAlphaBlend(backColor.
W, frontColor.
W);
 
  436             var interColor = TermMultiply(backColor, 2.0f * frontColor.
W * frontColor + (1.0f - frontColor.
W) * 
Vector4.
One);
 
  437             interColor.W = backColor.W;
 
  443             return backColor * frontColor.W;
 
  449             var v1 = Lerp(backColor * backColor.
W, frontColor, frontColor.
W);
 
  450             var v2 = Lerp(frontColor * frontColor.
W, backColor, backColor.
W);
 
  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)
 
  472             var sum = frontColor + backColor;
 
  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,
 
  479             return BasicBlend(backColor, frontColor, interColor);
 
  490             return BasicBlend(backColor, frontColor, interColor);
 
  495             return new Vector4(backColor.
X, backColor.
Y, backColor.
Z, backColor.
W * (frontColor.
X + frontColor.
Y + frontColor.
Z) / 3.0f);
 
  501             var interColor = TermMultiply(backColor, frontColor);
 
  502             return BasicBlend(backColor, frontColor, interColor);
 
  517             return new Vector4(backColor.
X, backColor.
Y, backColor.
Z, 1.0f);
 
  522             return backColor * (1.0f - frontColor.W);
 
  528             return BasicBlend(backColor, frontColor, frontColor);
 
  539             var lerp0 = 2.0f * TermMultiply(backColor, frontColor);
 
  540             var lerp1 = Vector4.One - 2.0f * TermMultiply(
Vector4.
One - backColor, 
Vector4.
One - frontColor);
 
  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;
 
  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)
 
  557             var v1 = 2.0f * frontColor;
 
  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),
 
  565                 Math.Min(backColor.
X, v1.X),
 
  566                 Math.Min(backColor.Y, v1.Y),
 
  567                 Math.Min(backColor.
Z, v1.Z),
 
  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,
 
  576             var interColor = max + TermMultiply(step, min - max);
 
  577             return BasicBlend(backColor, frontColor, interColor);
 
  582             var interColor = TermMultiply(backColor, 
Vector4.
One + (frontColor * frontColor.
W));
 
  583             interColor.W = backColor.W;
 
  590             if (GetSaturation(backColor) < 1.0e-10)
 
  592                 interColor = GetValue(backColor) * Vector4.One;
 
  596                 interColor = HSVToRGB(GetHue(backColor), GetSaturation(frontColor), GetValue(backColor));
 
  598             interColor.W = BasicAlphaBlend(backColor.
W, frontColor.
W);
 
  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);
 
  610         private static float SoftLightTest(
float bc, 
float fc)
 
  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);
 
  622                 SoftLightTest(backColor.
X, frontColor.
X),
 
  623                 SoftLightTest(backColor.
Y, frontColor.
Y),
 
  624                 SoftLightTest(backColor.
Z, frontColor.
Z),
 
  625                 BasicAlphaBlend(backColor.
W, frontColor.
W));
 
  631             var interColor = backColor - frontColor;
 
  632             return BasicBlend(backColor, frontColor, interColor);
 
  642             var interColor = backColor;
 
  643             interColor.W = frontColor.W;
 
  650             if (GetSaturation(backColor) < 1.0e-10)
 
  651                 interColor = GetValue(backColor) * Vector4.One;
 
  654                 interColor = HSVToRGB(GetHue(backColor), GetValue(backColor), GetValue(frontColor));
 
  656             interColor.W = BasicAlphaBlend(backColor.
W, frontColor.
W);
 
Hue effect from the two textures. 
float W
The W component of the vector. 
Screen effect from the two textures. 
Average of the two textures. 
Illuminate effect from the two textures. 
Subtract the two textures. 
float X
The X component of the vector. 
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. 
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. 
Take color for the first texture and use alpha = 1 
Represents a color in the form of rgba. 
Saturation effect from the two textures. 
MaterialBinaryOperand
Operands of the MaterialNode. 
Represents a four dimensional mathematical vector. 
SiliconStudio.Core.Mathematics.Color Color
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. 
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. 
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. 
Difference of the two textures. 
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. 
Color dodge effect from the two textures. 
Darken effect from the two textures. 
Lighten effect from the two textures.