public static Texture2D BlendMono(Texture2D a, Texture2D b, int mode)
    {
        IntPairClass resA = new IntPairClass(a);
        IntPairClass resB = new IntPairClass(b);
        IntPairClass res = new IntPairClass();
        res.SetFromMinimum(resA, resB);

        Color[] originalColorsA = a.GetPixels(0, 0, res.value01, res.value02);
        Color[] originalColorsB = b.GetPixels(0, 0, res.value01, res.value02);
        Color[] resultColors = new Color[originalColorsA.Length];

        for (int i = 0; i < resultColors.Length; i++)
        {
            float aValue = originalColorsA[i].a;
            float bValue = originalColorsB[i].a;
            Color r = new Color();
            if (mode == 0 || mode == 1)
            {
                r = new Color(1f, 1f, 1f, aValue);
            }
            else if(mode == 2)
            {
                r = new Color(1f, 1f, 1f, aValue * bValue);
            }
            resultColors[i] = r;
        }

        Texture2D toReturn = new Texture2D(a.width, a.height, TextureFormat.Alpha8, true);
        toReturn.SetPixels(0, 0, a.width, a.height, resultColors);
        toReturn.Apply(true);
        return toReturn;
    }
    //0 - A over B, 1 - B over A, 2 - Multiply
    public static Texture2D Blend(Texture2D a, Texture2D b, int mode)
    {
        IntPairClass resA = new IntPairClass(a);
        IntPairClass resB = new IntPairClass(b);
        IntPairClass res = new IntPairClass();
        res.SetFromMinimum(resA, resB);

        Color[] originalColorsA = a.GetPixels(0, 0, res.value01, res.value02);
        Color[] originalColorsB = b.GetPixels(0, 0, res.value01, res.value02);
        Color[] resultColors = new Color[originalColorsA.Length];

        for(int i = 0; i < resultColors.Length; i++)
        {
            Color aColor = originalColorsA[i];
            Color bColor = originalColorsB[i];
            Color r = new Color();
            if(mode == 0 || mode == 1)
            {
                float restForB = GetMin(bColor.a, 1 - aColor.a);
                r = new Color(GetMiddleValue(aColor.r, bColor.r, aColor.a, restForB), GetMiddleValue(aColor.g, bColor.g, aColor.a, restForB), GetMiddleValue(aColor.b, bColor.b, aColor.a, restForB), aColor.a + restForB);
            }
            else if(mode == 2)
            {
                r = new Color(aColor.r * bColor.r, aColor.g * bColor.g, aColor.b * bColor.b, aColor.a * bColor.a);
            }
            resultColors[i] = r;
        }

        Texture2D toReturn = new Texture2D(a.width, a.height, TextureFormat.RGBA32, true);
        toReturn.SetPixels(0, 0, a.width, a.height, resultColors);
        toReturn.Apply(true);
        return toReturn;
    }
    public override bool Calculate()
    {
        if (Inputs[0].connection != null && Inputs[1].connection != null && Inputs[2].connection != null && Inputs[3].connection != null)
        {
            rInput = Inputs[0].connection.GetValue<Texture2D>();
            gInput = Inputs[1].connection.GetValue<Texture2D>();
            bInput = Inputs[2].connection.GetValue<Texture2D>();
            aInput = Inputs[3].connection.GetValue<Texture2D>();

            if (rInput != null && gInput != null && bInput != null && aInput != null)
            {
                IntPairClass rRes = new IntPairClass(rInput);
                IntPairClass gRes = new IntPairClass(gInput);
                IntPairClass bRes = new IntPairClass(bInput);
                IntPairClass aRes = new IntPairClass(aInput);

                IntPairClass resolution = new IntPairClass();
                resolution.SetFromMinimum(rRes, gRes, bRes, aRes);

                resTexture = new Texture2D(resolution.value01, resolution.value02, TextureFormat.RGBA32, true);
                Color[] rColors = rInput.GetPixels(0, 0, resolution.value01, resolution.value02);
                Color[] gColors = gInput.GetPixels(0, 0, resolution.value01, resolution.value02);
                Color[] bColors = bInput.GetPixels(0, 0, resolution.value01, resolution.value02);
                Color[] aColors = aInput.GetPixels(0, 0, resolution.value01, resolution.value02);

                Color[] resColors = new Color[rColors.Length];
                for (int i = 0; i < resColors.Length; i++)
                {
                    resColors[i] = new Color(rColors[i].a, gColors[i].a, bColors[i].a, aColors[i].a);
                }
                resTexture.SetPixels(0, 0, resolution.value01, resolution.value02, resColors);
                resTexture.Apply(true);
                Outputs[0].SetValue<Texture2D>(resTexture);

                prevImage = ImageHelperClass.MakePreviewImage(resTexture);
                prevStyle = ImageHelperClass.GetPreviewStyle();
            }
        }

        return true;
    }
    public static Texture2D MakeReplaceAlpha(Texture2D image, Texture2D alpha)
    {
        Color[] originalColors = image.GetPixels(0, 0, image.width, image.height);
        Color[] alphaColors = alpha.GetPixels(0, 0, alpha.width, alpha.height);
        IntPairClass originalResolution = new IntPairClass(image);
        IntPairClass alphaResolution = new IntPairClass(alpha);
        IntPairClass res = new IntPairClass();
        res.SetFromMinimum(originalResolution, alphaResolution);
        Color[] contrastedColors = new Color[res.GetProduct()];
        for (int i = 0; i < contrastedColors.Length; i++)
        {
            Color c = originalColors[i];
            contrastedColors[i] = new Color(c.r, c.g, c.b, alphaColors[i].a);
        }
        Texture2D toReturn = new Texture2D(res.value01, res.value02, TextureFormat.RGBA32, true);
        toReturn.SetPixels(0, 0, res.value01, res.value02, contrastedColors);
        toReturn.Apply(true);

        return toReturn;
    }