public override double GetValue(double x, double y)
        {
            // pStr:
            double str = SourceModule2.GetValue(x, y);

            double mapX = MapX;
            double mapY = MapY;

            // Read the surrounding heights:
            double tl = SourceModule1.GetValue(x - mapX, y + mapY);
            double t  = SourceModule1.GetValue(x, y + mapY);
            double tr = SourceModule1.GetValue(x + mapX, y + mapY);
            double r  = SourceModule1.GetValue(x + mapX, y);
            double br = SourceModule1.GetValue(x + mapX, y - mapY);
            double b  = SourceModule1.GetValue(x, y - mapY);
            double bl = SourceModule1.GetValue(x - mapX, y - mapY);
            double l  = SourceModule1.GetValue(x - mapX, y);

            // sobel filter
            double dX = ((tr + 2.0 * r + br) - (tl + 2.0 * l + bl));
            double dY = ((bl + 2.0 * b + br) - (tl + 2.0 * t + tr));
            double dZ = 1.0 / str;

            // Normalise:
            double length = System.Math.Sqrt(dX * dX + dY * dY + dZ * dZ);

            return(dZ / length);
        }
Example #2
0
        public override double GetValue(double t)
        {
            double a = SourceModule1.GetValue(t);
            double b = SourceModule2.GetValue(t);

            return(a + ((b - a) * 0.5f));
        }
Example #3
0
        public override double GetValue(double x, double y, double z)
        {
            double v0 = SourceModule1.GetValue(x, y, z);
            double v1 = SourceModule2.GetValue(x, y, z);

            return(Math.Max(v0, v1));
        }
Example #4
0
        public override double GetWrapped(double x, double y, int wrap)
        {
            double a = SourceModule1.GetWrapped(x, y, wrap);
            double b = SourceModule2.GetWrapped(x, y, wrap);

            return(a + ((b - a) * 0.5f));
        }
Example #5
0
        public override double GetValue(double x, double y, double z)
        {
            double a = SourceModule1.GetValue(x, y, z);
            double b = SourceModule2.GetValue(x, y, z);

            return(a + ((b - a) * 0.5f));
        }
Example #6
0
        public override double GetValue(double t)
        {
            // Read the values:
            double min = LowerBound.GetValue(t);
            double max = UpperBound.GetValue(t);
            double value;

            if (min > max)
            {
                // Flip, using value as temp storage:
                value = min;
                min   = max;
                max   = value;
            }

            // Source:
            value = SourceModule1.GetValue(t);

            if (value > max)
            {
                return(max);
            }
            else if (value < min)
            {
                return(min);
            }

            return(value);
        }
        public override UnityEngine.Color GetColour(double x, double y)
        {
            // Read colour:
            UnityEngine.Color col1 = SourceModule1.GetColour(x, y);

            // Read colour:
            UnityEngine.Color col2 = SourceModule2.GetColour(x, y);

            // Pick biggest:
            if (col2.r > col1.r)
            {
                col1.r = col2.r;
            }

            if (col2.g > col1.g)
            {
                col1.g = col2.g;
            }

            if (col2.b > col1.b)
            {
                col1.b = col2.b;
            }

            return(col1);
        }
        public override UnityEngine.Color GetColour(double x, double y)
        {
            // 1/pStr:
            float str = (float)SourceModule2.GetValue(x, y);

            double mapX = MapX;
            double mapY = MapY;

            // Read the surrounding heights:
            double tl = SourceModule1.GetValue(x - mapX, y + mapY);
            double t  = SourceModule1.GetValue(x, y + mapY);
            double tr = SourceModule1.GetValue(x + mapX, y + mapY);
            double r  = SourceModule1.GetValue(x + mapX, y);
            double br = SourceModule1.GetValue(x + mapX, y - mapY);
            double b  = SourceModule1.GetValue(x, y - mapY);
            double bl = SourceModule1.GetValue(x - mapX, y - mapY);
            double l  = SourceModule1.GetValue(x - mapX, y);

            // sobel filter
            float dX = (float)((tr + 2.0 * r + br) - (tl + 2.0 * l + bl));
            float dY = (float)((bl + 2.0 * b + br) - (tl + 2.0 * t + tr));
            float dZ = str;

            // Normalise:
            float length = (float)System.Math.Sqrt(dX * dX + dY * dY + dZ * dZ);

            dX /= length;
            dY /= length;
            dZ /= length;

            return(new Color(dX, dY, dZ, 1f));
        }
Example #9
0
        public double GetValue(double x, double y, double z)
        {
            if (SourceModule1 == null || SourceModule2 == null)
            {
                throw new NullReferenceException("Source modules must be provided.");
            }

            return(Math.GetSmaller(SourceModule1.GetValue(x, y, z), SourceModule2.GetValue(x, y, z)));
        }
Example #10
0
        public override double GetValue(double x, double y, double z)
        {
            // Stretch out t by times to repeat:
            double rep    = SourceModule2.GetValue(x, y, z);
            bool   mirror = (SourceModule3.GetValue(x, y, z) > 0.5);

            x *= rep;
            y *= rep;
            z *= rep;

            // Get the current repetition:
            int baseRepetition = (int)x;

            // Shift:
            x -= baseRepetition;

            // X is now in the 0-1 range.

            if (mirror && (baseRepetition & 1) == 1)
            {
                // "odd" repetition - flip t:
                x = 1.0 - x;
            }

            // Get the current repetition:
            baseRepetition = (int)y;

            // Shift:
            y -= baseRepetition;

            // Y is now in the 0-1 range.

            if (mirror && (baseRepetition & 1) == 1)
            {
                // "odd" repetition - flip t:
                y = 1.0 - y;
            }

            // Get the current repetition:
            baseRepetition = (int)z;

            // Shift:
            z -= baseRepetition;

            // Z is now in the 0-1 range.

            if (mirror && (baseRepetition & 1) == 1)
            {
                // "odd" repetition - flip t:
                z = 1.0 - z;
            }

            // Read source:
            return(SourceModule1.GetValue(x, y, z));
        }
        public override double GetValue(double t)
        {
            // Read amplitude:
            double amp = Contrast.GetValue(t);

            // Origin:
            double origin = Origin.GetValue(t);

            // Sample at that point:
            return(((SourceModule1.GetValue(t) - origin) * amp) + origin);
        }
Example #12
0
        public override double GetValue(double x)
        {
            // Read params:
            double mu     = SourceModule1.GetValue(x);
            double sigma2 = SourceModule2.GetValue(x);

            double tMu = x - mu;

            // Amplitude of 1.
            return(System.Math.Exp((-tMu * tMu) / (2.0 * sigma2)));
        }
        public override double GetValue(double x, double y)
        {
            double a = SourceModule1.GetValue(x, y);
            double b = SourceModule2.GetValue(x, y);

            if (a > b)
            {
                return(a);
            }
            return(b);
        }
        public override double GetWrapped(double x, double y, int wrap)
        {
            double a = SourceModule1.GetWrapped(x, y, wrap);
            double b = SourceModule2.GetWrapped(x, y, wrap);

            if (a > b)
            {
                return(a);
            }
            return(b);
        }
Example #15
0
        /// <summary>
        /// Returns the result of blending the output of the two source modules using the
        /// output of the weight module as the blending weight.
        /// </summary>
        public double GetValue(double x, double y, double z)
        {
            if (SourceModule1 == null || SourceModule2 == null || WeightModule == null)
            {
                throw new NullReferenceException();
            }

            return(LinearInterpolate(SourceModule1.GetValue(x, y, z),
                                     SourceModule2.GetValue(x, y, z),
                                     (WeightModule.GetValue(x, y, z) + 1.0) / 2.0));
        }
Example #16
0
        public override double GetValue(double x, double y)
        {
            double a = SourceModule1.GetValue(x, y);
            double b = SourceModule2.GetValue(x, y);

            if (a != b)
            {
                return(IfTrue.GetValue(x, y));
            }

            return(IfFalse.GetValue(x, y));
        }
Example #17
0
        public override UnityEngine.Color GetColour(double x, double y)
        {
            // Read colour:
            UnityEngine.Color col1 = SourceModule1.GetColour(x, y);

            // Read colour:
            UnityEngine.Color col2 = SourceModule2.GetColour(x, y);

            // T:
            UnityEngine.Color t = IfTrue.GetColour(x, y);

            // False:
            UnityEngine.Color f = IfFalse.GetColour(x, y);

            // Pick:
            if (col1.r != col2.r)
            {
                col1.r = t.r;
            }
            else
            {
                col1.r = f.r;
            }

            if (col1.g != col2.g)
            {
                col1.g = t.g;
            }
            else
            {
                col1.g = f.g;
            }

            if (col1.b != col2.b)
            {
                col1.b = t.b;
            }
            else
            {
                col1.b = f.b;
            }

            if (col1.a != col2.a)
            {
                col1.a = t.a;
            }
            else
            {
                col1.a = f.a;
            }

            return(col1);
        }
Example #18
0
        public override double GetValue(double t)
        {
            // Read the values:
            double a = SourceModule1.GetValue(t);
            double b = SourceModule2.GetValue(t);

            // Blend factor:
            double blend = WeightModule.GetValue(t);

            // Blend now!
            return(a + ((b - a) * blend));
        }
Example #19
0
        public override double GetValue(double t)
        {
            double a = SourceModule1.GetValue(t);
            double b = SourceModule2.GetValue(t);

            if (a < b)
            {
                return(a);
            }

            return(b);
        }
Example #20
0
        public override double GetWrapped(double x, double y, int wrap)
        {
            double a = SourceModule1.GetWrapped(x, y, wrap);
            double b = SourceModule2.GetWrapped(x, y, wrap);

            if (a != b)
            {
                return(IfTrue.GetWrapped(x, y, wrap));
            }

            return(IfFalse.GetWrapped(x, y, wrap));
        }
Example #21
0
        public override UnityEngine.Color GetColour(double x, double y)
        {
            // Read colour:
            UnityEngine.Color col1 = SourceModule1.GetColour(x, y);

            // Read colour:
            UnityEngine.Color col2 = SourceModule2.GetColour(x, y);

            col1.r = (float)System.Math.Atan2(col1.r, col2.r);
            col1.g = (float)System.Math.Atan2(col1.g, col2.g);
            col1.b = (float)System.Math.Atan2(col1.b, col2.b);

            return(col1);
        }
Example #22
0
        public override UnityEngine.Color GetColour(double x, double y)
        {
            // Read colour:
            UnityEngine.Color col1 = SourceModule1.GetColour(x, y);

            // Read colour:
            UnityEngine.Color col2 = SourceModule2.GetColour(x, y);

            // Middle (ignoring alpha):
            col1.r = col1.r + ((col2.r - col1.r) * 0.5f);
            col1.g = col1.g + ((col2.g - col1.g) * 0.5f);
            col1.b = col1.b + ((col2.b - col1.b) * 0.5f);

            return(col1);
        }
Example #23
0
        public override UnityEngine.Color GetColour(double x, double y)
        {
            // Read colour:
            UnityEngine.Color col1 = SourceModule1.GetColour(x, y);

            // Read colour:
            UnityEngine.Color col2 = SourceModule2.GetColour(x, y);

            // Multiply away! Ignore alpha though - it comes from col1:
            col1.r *= col2.r;
            col1.g *= col2.g;
            col1.b *= col2.b;

            return(col1);
        }
Example #24
0
        public override double GetValue(double x, double y, double z)
        {
            double controlValue = ControlModule.GetValue(x, y, z);

            if (EdgeFalloff > 0.0)
            {
                if (controlValue < (LowerBound - EdgeFalloff))
                {
                    // The output value from the control module is below the selector
                    // threshold; return the output value from the first source module.
                    return(SourceModule1.GetValue(x, y, z));
                }
                if (controlValue < (LowerBound + EdgeFalloff))
                {
                    // The output value from the control module is near the lower end of the
                    // selector threshold and within the smooth curve. Interpolate between
                    // the output values from the first and second source modules.
                    double lowerCurve = (LowerBound - EdgeFalloff);
                    double upperCurve = (LowerBound + EdgeFalloff);
                    double alpha      = Interp.SCurve3((controlValue - lowerCurve) / (upperCurve - lowerCurve));
                    return(Interp.LinearInterp(SourceModule1.GetValue(x, y, z), SourceModule2.GetValue(x, y, z), alpha));
                }
                if (controlValue < (UpperBound - EdgeFalloff))
                {
                    // The output value from the control module is within the selector
                    // threshold; return the output value from the second source module.
                    return(SourceModule2.GetValue(x, y, z));
                }
                if (controlValue < (UpperBound + EdgeFalloff))
                {
                    // The output value from the control module is near the upper end of the
                    // selector threshold and within the smooth curve. Interpolate between
                    // the output values from the first and second source modules.
                    double lowerCurve = (UpperBound - EdgeFalloff);
                    double upperCurve = (UpperBound + EdgeFalloff);
                    double alpha      = Interp.SCurve3((controlValue - lowerCurve) / (upperCurve - lowerCurve));
                    return(Interp.LinearInterp(SourceModule2.GetValue(x, y, z), SourceModule1.GetValue(x, y, z), alpha));
                }
                // Output value from the control module is above the selector threshold;
                // return the output value from the first source module.
                return(SourceModule1.GetValue(x, y, z));
            }
            if (controlValue < LowerBound || controlValue > UpperBound)
            {
                return(SourceModule1.GetValue(x, y, z));
            }
            return(SourceModule2.GetValue(x, y, z));
        }
        public override double GetValue(double x)
        {
            // How many stairs?
            double count = SourceModule2.GetValue(x);

            // Map x into our current step:
            x *= count;

            // Get the base step:
            int baseStep = (int)x;

            // Read the curve at x-baseStep (0-1 inside the current step):
            double curve = SourceModule1.GetValue(x - baseStep);

            // Gotta now offset and compress it back:
            return(((double)baseStep + curve) / count);
        }
Example #26
0
        public double GetValue(double x, double y, double z)
        {
            if (SourceModule1 == null || SourceModule2 == null)
            {
                throw new NullReferenceException("Source modules must be provided.");
            }

            double a = SourceModule1.GetValue(x, y, z);
            double b = SourceModule2.GetValue(x, y, z);

            if (b < 0)
            {
                return(a * 0);
            }


            return(a * b);
        }
Example #27
0
        public override UnityEngine.Color GetColour(double x, double y)
        {
            // Read colour:
            UnityEngine.Color col1 = SourceModule1.GetColour(x, y);

            // Read colour:
            UnityEngine.Color col2 = SourceModule2.GetColour(x, y);

            // Divide away! Ignore alpha though - it comes from col1:
            if (col2.r == 0f)
            {
                col1.r = 1f;
            }
            else
            {
                col1.r /= col2.r;
            }

            if (col2.g == 0f)
            {
                col1.g = 1f;
            }
            else
            {
                col1.g /= col2.g;
            }

            if (col2.b == 0f)
            {
                col1.b = 1f;
            }
            else
            {
                col1.b /= col2.b;
            }

            return(col1);
        }
Example #28
0
        public override double GetValue(double t)
        {
            // Stretch out t by times to repeat:
            t *= SourceModule2.GetValue(t);

            // Get the current repetition:
            int baseRepetition = (int)t;

            // Shift t:
            t -= baseRepetition;

            // T is now in the 0-1 range.
            bool mirror = (SourceModule3.GetValue(t) > 0.5);

            if (mirror && (baseRepetition & 1) == 1)
            {
                // "odd" repetition - flip t:
                t = 1.0 - t;
            }

            // Read source:
            return(SourceModule1.GetValue(t));
        }
        public override UnityEngine.Color GetColour(double x, double y)
        {
            float threshold  = (float)Threshold.GetValue(x, y);
            float nThreshold = -threshold;
            float a          = 4f * (float)Gain.GetValue(x, y);

            a += 1f;

            // Read the two colours:
            UnityEngine.Color pix2 = SourceModule1.GetColour(x, y);
            UnityEngine.Color pix1 = SourceModule2.GetColour(x, y);


            // Get deltas:
            float rDelta = pix1.r - pix2.r;
            float gDelta = pix1.g - pix2.g;
            float bDelta = pix1.b - pix2.b;

            // Threshold test:
            if (rDelta <= nThreshold || rDelta >= threshold)
            {
                pix1.r = (a * rDelta + pix2.r);
            }

            if (gDelta <= nThreshold || gDelta >= threshold)
            {
                pix1.g = (a * gDelta + pix2.g);
            }

            if (bDelta <= nThreshold || bDelta >= threshold)
            {
                pix1.b = (a * bDelta + pix2.b);
            }

            return(pix1);
        }
Example #30
0
        public override UnityEngine.Color GetColour(double x, double y)
        {
            // Read colour:
            UnityEngine.Color col1 = SourceModule1.GetColour(x, y);

            // Read colour:
            UnityEngine.Color col2 = SourceModule2.GetColour(x, y);

            // Blend factor is..
            float dstA = col1.a;
            float srcA = (float)WeightModule.GetColour(x, y).r *col2.a;

            switch (Mode)
            {
            case BlendingMode.Normal:

                // Do nothing here - we just alpha blend.

                break;

            case BlendingMode.Darken:

                // Pick the smallest of the two and set col2:
                if (col1.r < col2.r)
                {
                    col2.r = col1.r;
                }

                if (col1.g < col2.g)
                {
                    col2.g = col1.g;
                }

                if (col1.b < col2.b)
                {
                    col2.b = col1.b;
                }

                break;

            case BlendingMode.Multiply:

                col2.r *= col1.r;
                col2.g *= col1.g;
                col2.b *= col1.b;

                break;

            case BlendingMode.ColourBurn:

                col2.r = 1f - ((1f - col1.r) / col2.r);
                col2.g = 1f - ((1f - col1.g) / col2.g);
                col2.b = 1f - ((1f - col1.b) / col2.b);

                break;

            case BlendingMode.LinearBurn:

                col2.r += col1.r - 1f;
                col2.g += col1.g - 1f;
                col2.b += col1.b - 1f;

                break;

            case BlendingMode.Lighten:

                // Pick the biggest of the two and set col2:
                if (col1.r > col2.r)
                {
                    col2.r = col1.r;
                }

                if (col1.g > col2.g)
                {
                    col2.g = col1.g;
                }

                if (col1.b > col2.b)
                {
                    col2.b = col1.b;
                }

                break;

            case BlendingMode.Screen:

                col2.r = 1f - (1f - col1.r) * (1f - col2.r);
                col2.g = 1f - (1f - col1.g) * (1f - col2.g);
                col2.b = 1f - (1f - col1.b) * (1f - col2.b);

                break;

            case BlendingMode.ColourDodge:

                // Bottom layer / (inverted Top layer)
                if (col2.r != 1f)
                {
                    col2.r = col1.r / (1f - col2.r);
                }

                if (col2.g != 1f)
                {
                    col2.g = col1.g / (1f - col2.g);
                }

                if (col2.b != 1f)
                {
                    col2.b = col1.b / (1f - col2.b);
                }

                break;

            case BlendingMode.LinearDodge:

                // Sum the two layers:
                col2.r += col1.r;
                col2.g += col1.g;
                col2.b += col1.b;

                break;

            case BlendingMode.Overlay:

                if (col1.r < 0.5f)
                {
                    col2.r = 2f * col1.r * col2.r;
                }
                else
                {
                    col2.r = 1f - 2f * (1f - col1.r) * (1f - col2.r);
                }

                if (col1.g < 0.5f)
                {
                    col2.g = 2f * col1.g * col2.g;
                }
                else
                {
                    col2.g = 1f - 2f * (1f - col1.g) * (1f - col2.g);
                }

                if (col1.b < 0.5f)
                {
                    col2.b = 2f * col1.b * col2.b;
                }
                else
                {
                    col2.b = 1f - 2f * (1f - col1.b) * (1f - col2.b);
                }

                break;

            case BlendingMode.SoftLight:

                // W3C soft light blend here.
                float g;
                float a;
                float b;

                a = col1.r;
                b = col2.r;

                if (b <= 0.5f)
                {
                    col2.r = a - (1f - 2f * b) * a * (1f - a);
                }
                else
                {
                    if (a <= 0.25f)
                    {
                        g = ((16f * a - 12f) * a + 4f) * a;
                    }
                    else
                    {
                        g = (float)System.Math.Sqrt(a);
                    }

                    col2.r = a + (2f * b - 1f) * (g - a);
                }

                a = col1.g;
                b = col2.g;

                if (b <= 0.5f)
                {
                    col2.g = a - (1f - 2f * b) * a * (1f - a);
                }
                else
                {
                    if (a <= 0.25f)
                    {
                        g = ((16f * a - 12f) * a + 4f) * a;
                    }
                    else
                    {
                        g = (float)System.Math.Sqrt(a);
                    }

                    col2.g = a + (2f * b - 1f) * (g - a);
                }

                a = col1.b;
                b = col2.b;

                if (b <= 0.5f)
                {
                    col2.b = a - (1f - 2f * b) * a * (1f - a);
                }
                else
                {
                    if (a <= 0.25f)
                    {
                        g = ((16f * a - 12f) * a + 4f) * a;
                    }
                    else
                    {
                        g = (float)System.Math.Sqrt(a);
                    }

                    col2.b = a + (2f * b - 1f) * (g - a);
                }

                break;

            case BlendingMode.HardLight:

                if (col2.r < 0.5f)
                {
                    col2.r = 2f * col2.r * col1.r;
                }
                else
                {
                    col2.r = 1f - 2f * (1f - col2.r) * (1f - col1.r);
                }

                if (col2.g < 0.5f)
                {
                    col2.g = 2f * col2.g * col1.g;
                }
                else
                {
                    col2.g = 1f - 2f * (1f - col2.g) * (1f - col1.g);
                }

                if (col2.b < 0.5f)
                {
                    col2.b = 2f * col2.b * col1.b;
                }
                else
                {
                    col2.b = 1f - 2f * (1f - col2.b) * (1f - col1.b);
                }

                break;

            case BlendingMode.VividLight:

                if (col2.r < 0.5f)
                {
                    // Colour Burn
                    col2.r = 1f - ((1f - col1.r) / col2.r);
                }
                else
                {
                    // Colour Dodge
                    col2.r = col1.r / (1f - col2.r);
                }

                if (col2.g < 0.5f)
                {
                    // Colour Burn
                    col2.g = 1f - ((1f - col1.g) / col2.g);
                }
                else
                {
                    // Colour Dodge
                    col2.g = col1.g / (1f - col2.g);
                }

                if (col2.b < 0.5f)
                {
                    // Colour Burn
                    col2.b = 1f - ((1f - col1.b) / col2.b);
                }
                else
                {
                    // Colour Dodge
                    col2.b = col1.b / (1f - col2.b);
                }

                break;

            case BlendingMode.LinearLight:

                if (col2.r < 0.5f)
                {
                    // Linear Burn
                    col2.r += col1.r - 1f;
                }
                else
                {
                    // Linear Dodge
                    col2.r += col1.r;
                }

                if (col2.g < 0.5f)
                {
                    // Linear Burn
                    col2.g += col1.g - 1f;
                }
                else
                {
                    // Linear Dodge
                    col2.g += col1.g;
                }

                if (col2.b < 0.5f)
                {
                    // Linear Burn
                    col2.b += col1.b - 1f;
                }
                else
                {
                    // Linear Dodge
                    col2.b += col1.b;
                }

                break;

            case BlendingMode.Hue:

                // Top layers hue and the sat/lum from bottom layer.

                float s = col1.r;
                float l = col1.g;
                HsyRgb.ToSatLum(ref s, ref l, col1.b);

                // Top hue:
                float h = HsyRgb.Hue(col2.r, col2.g, col2.b);

                // Recombine to RGB.
                HsyRgb.ToRgb(ref h, ref s, ref l);

                // They're now RGB.
                col2.r = h;
                col2.g = s;
                col2.b = l;

                break;

            case BlendingMode.Saturation:

                // Top layers saturation and the hue/lum from bottom layer.

                h = col1.r;
                l = col1.g;
                HsyRgb.ToHueLum(ref h, ref l, col1.b);

                // Top saturation:
                s = HsyRgb.Saturation(col2.r, col2.g, col2.b);

                // Recombine to RGB.
                HsyRgb.ToRgb(ref h, ref s, ref l);

                // They're now RGB.
                col2.r = h;
                col2.g = s;
                col2.b = l;

                break;

            case BlendingMode.Colour:

                // Top layers hue/sat and the luminosity from bottom layer.

                h = col2.r;
                s = col2.g;
                HsyRgb.ToHueSat(ref h, ref s, col2.b);

                // Bottom luminosity:
                l = HsyRgb.Luminance(col1.r, col1.g, col1.b);

                // Recombine to RGB.
                HsyRgb.ToRgb(ref h, ref s, ref l);

                // They're now RGB.
                col2.r = h;
                col2.g = s;
                col2.b = l;

                break;

            case BlendingMode.Luminosity:

                // Top layers luminosity and the hue/sat from bottom layer.

                h = col1.r;
                s = col1.g;
                HsyRgb.ToHueSat(ref h, ref s, col1.b);

                // Top luminosity:
                l = HsyRgb.Luminance(col2.r, col2.g, col2.b);

                // Recombine to RGB.
                HsyRgb.ToRgb(ref h, ref s, ref l);

                // They're now RGB.
                col2.r = h;
                col2.g = s;
                col2.b = l;

                break;

            case BlendingMode.Divide:

                // Bottom layer / Top layer
                if (col2.r != 0f)
                {
                    col2.r = col1.r / col2.r;
                }

                if (col2.g != 0f)
                {
                    col2.g = col1.g / col2.g;
                }

                if (col2.b != 0f)
                {
                    col2.b = col1.b / col2.b;
                }

                break;

            case BlendingMode.Subtract:

                // Subtract:
                col2.r = (col1.r - col2.r);
                col2.g = (col1.g - col2.g);
                col2.b = (col1.b - col2.b);

                break;

            case BlendingMode.Difference:
            case BlendingMode.Exclusion:

                // Subtract:
                g = (col1.r - col2.r);

                if (g < 0f)
                {
                    col2.r = -g;
                }
                else
                {
                    col2.r = g;
                }

                g = (col1.g - col2.g);

                if (g < 0f)
                {
                    col2.g = -g;
                }
                else
                {
                    col2.g = g;
                }

                g = (col1.b - col2.b);

                if (g < 0f)
                {
                    col2.b = -g;
                }
                else
                {
                    col2.b = g;
                }

                break;

            case BlendingMode.HardMix:

                // Linear light first:

                if (col2.r < 0.5f)
                {
                    // Linear Burn
                    col2.r += col1.r - 1f;
                }
                else
                {
                    // Linear Dodge
                    col2.r += col1.r;
                }

                if (col2.g < 0.5f)
                {
                    // Linear Burn
                    col2.g += col1.g - 1f;
                }
                else
                {
                    // Linear Dodge
                    col2.g += col1.g;
                }

                if (col2.b < 0.5f)
                {
                    // Linear Burn
                    col2.b += col1.b - 1f;
                }
                else
                {
                    // Linear Dodge
                    col2.b += col1.b;
                }

                // Threshold:
                if (col2.r < 0.5f)
                {
                    col2.r = 0f;
                }
                else
                {
                    col2.r = 1f;
                }

                if (col2.g < 0.5f)
                {
                    col2.g = 0f;
                }
                else
                {
                    col2.g = 1f;
                }

                if (col2.b < 0.5f)
                {
                    col2.b = 0f;
                }
                else
                {
                    col2.b = 1f;
                }

                break;

            case BlendingMode.PinLight:

                if (col2.r < 0.5f)
                {
                    // Darken
                    if (col1.r < col2.r)
                    {
                        col2.r = col1.r;
                    }
                }
                else
                {
                    // Lighten
                    if (col1.r > col2.r)
                    {
                        col2.r = col1.r;
                    }
                }

                if (col2.g < 0.5f)
                {
                    // Darken
                    if (col1.g < col2.g)
                    {
                        col2.g = col1.g;
                    }
                }
                else
                {
                    // Lighten
                    if (col1.g > col2.g)
                    {
                        col2.g = col1.g;
                    }
                }

                if (col2.b < 0.5f)
                {
                    // Darken
                    if (col1.b < col2.b)
                    {
                        col2.b = col1.b;
                    }
                }
                else
                {
                    // Lighten
                    if (col1.b > col2.b)
                    {
                        col2.b = col1.b;
                    }
                }

                break;

            case BlendingMode.LighterColor:

                // Like lighten but applies to the composite channel.
                float total1 = col1.r + col1.g + col1.b;
                float total2 = col2.r + col2.g + col2.b;

                if (total1 > total2)
                {
                    // Blend will do nothing:
                    col1.a = srcA + dstA * (1f - srcA);
                    return(col1);
                }

                break;

            case BlendingMode.DarkerColor:

                // Like darken but applies to the composite channel.
                total1 = col1.r + col1.g + col1.b;
                total2 = col2.r + col2.g + col2.b;

                if (total1 < total2)
                {
                    // Blend will do nothing:
                    col1.a = srcA + dstA * (1f - srcA);
                    return(col1);
                }

                break;
            }

            // Time to alpha blend!

            if (srcA == 1f)
            {
                // Just foreground:

                col2.a = 1f;
                return(col2);
            }

            float dstAinvSrc = dstA * (1f - srcA);
            float outA       = srcA + dstAinvSrc;

            if (outA == 0f)
            {
                col1.r = 0f;
                col1.g = 0f;
                col1.b = 0f;
            }
            else
            {
                col1.r = ((col2.r * srcA) + (col1.r * dstAinvSrc)) / outA;
                col1.g = ((col2.g * srcA) + (col1.g * dstAinvSrc)) / outA;
                col1.b = ((col2.b * srcA) + (col1.b * dstAinvSrc)) / outA;
            }

            col1.a = outA;

            return(col1);
        }