public override Color[] GetPixels(TextureSetForCombinedMaps set, TextureMeta id)
        {
            if (pixels == null)
            {
                ExtractPixels(set.diffuse, id?.width ?? set.width, id?.height ?? set.height);
            }

            return(pixels);
        }
        public override Color[] GetPixels(TextureSetForCombinedMaps set, TextureMeta id)
        {
            var width  = id?.width ?? set.width;
            var height = id?.height ?? set.height;

            if (pixels == null)
            {
                ExtractPixels(set.ambient ? set.ambient : set.heightMap, width, height);
            }

            return(pixels);
        }
        public List <Color[]> GetMipPixels(TextureSetForCombinedMaps set, TextureMeta id)
        {
            if (mipLevels != null)
            {
                return(mipLevels);
            }

            var width  = id?.width ?? set.width;
            var height = id?.height ?? set.height;

            mipLevels = new List <Color[]>();

            var w = width;
            var h = height;

            while (w > 1 && h > 1)
            {
                w /= 2;
                h /= 2;

                var dest = new Color[w * h];

                var dx = width / w;
                var dy = height / h;

                float pixelsPerSector = dx * dy;

                for (var y = 0; y < h; y++)
                {
                    for (var x = 0; x < w; x++)
                    {
                        var col = new Color(0, 0, 0, 0);

                        var start = y * dy * width + x * dx;

                        for (var sy = 0; sy < dy; sy++)
                        {
                            for (var sx = 0; sx < dx; sx++)
                            {
                                col += pixels[start + sy * width + sx];
                            }
                        }

                        col /= pixelsPerSector;

                        dest[y * w + x] = col;
                    }
                }

                mipLevels.Add(dest);
            }
            return(mipLevels);
        }
        public override Color[] GetPixels(TextureSetForCombinedMaps set, TextureMeta id)
        {
            if (pixels != null)
            {
                return(pixels);
            }

            var width  = id?.width ?? set.width;
            var height = id?.height ?? set.height;

            ExtractPixels(set.reflectivity ? set.reflectivity : set.gloss, width, height);
            return(pixels);
        }
        public override Color[] GetPixels(TextureSetForCombinedMaps set, TextureMeta id)
        {
            if (id != null)
            {
                return(id.Pixels);
            }

            if (pixels == null)
            {
                ExtractPixels(set.lastProduct, set.width, set.height);
            }

            return(pixels);
        }
        public override Color[] GetPixels(TextureSetForCombinedMaps set, TextureMeta id)
        {
            if (pixels == null)
            {
                var width  = id?.width ?? set.width;
                var height = id?.height ?? set.height;
                ExtractPixels(set.normalMap, width, height);
            }

            #if UNITY_EDITOR
            _texture = set.normalMap;
            #endif
            return(pixels);
        }
        public override Color[] GetPixels(TextureSetForCombinedMaps set, TextureMeta id)
        {
            if (pixels != null)
            {
                return(pixels);
            }

            var width  = id?.width ?? set.width;
            var height = id?.height ?? set.height;

            ExtractPixels(set.gloss ? set.gloss : set.reflectivity, width, height);

            if (set.Profile.glossNoiseFromHeight && set.heightMap)
            {
                GlossMipmapsFromHeightNoise(set.heightMap, width, height, set.Profile.bumpNoiseInGlossFraction);
            }

            return(pixels);
        }
        public override Color[] GetPixels(TextureSetForCombinedMaps set, TextureMeta id)
        {
            if (pixels != null)
            {
                return(pixels);
            }

            _width  = id?.width ?? set.width;
            _height = id?.height ?? set.height;

            ExtractPixels(set.heightMap ? set.heightMap : set.ambient, _width, _height);

            var strength = set.Profile.bumpStrength;

            for (var bY = 0; bY < _height; bY++)
            {
                for (var bX = 0; bX < _width; bX++)
                {
                    var dstIndex = IndexFrom(bX, bY);

                    var col = pixels[dstIndex];

                    col.b = col.grayscale;

                    var xLeft  = pixels[IndexFrom(bX - 1, bY)].a;
                    var xRight = pixels[IndexFrom(bX + 1, bY)].a;
                    var yUp    = pixels[IndexFrom(bX, bY - 1)].a;
                    var yDown  = pixels[IndexFrom(bX, bY + 1)].a;

                    var xDelta = (-xRight + xLeft) * strength;

                    var yDelta = (-yDown + yUp) * strength;

                    col.r = Mathf.Clamp01(xDelta * Mathf.Abs(xDelta) + 0.5f);
                    col.g = Mathf.Clamp01(yDelta * Mathf.Abs(yDelta) + 0.5f);

                    pixels[dstIndex] = col;
                }
            }

            return(pixels);
        }
        public override Color[] GetPixels(TextureSetForCombinedMaps set, TextureMeta id)
        {
            if (pixels != null)
            {
                return(pixels);
            }

            var noID   = id == null;
            var width  = noID ? set.width : id.width;
            var height = noID ? set.height : id.height;

            var col  = set.Profile.fillColor;
            var size = width * height;

            pixels = new Color[size];
            for (var i = 0; i < size; i++)
            {
                pixels[i] = col;
            }

            return(pixels);
        }
        private void Combine(TextureSetForCombinedMaps set, PlaytimePainter p)
        {
            TextureRole.Clear();

            int size;
            var id = p?.TexMeta;

            Color[]   dst;
            Texture2D tex = null;

            if (id != null)
            {
                size = id.width * id.height;
                dst  = id.Pixels;
                tex  = id.texture2D;
            }
            else
            {
                size         = set.width * set.height;
                tex          = new Texture2D(set.width, set.height, TextureFormat.ARGB32, true, set.isColor);
                dst          = new Color[size];
                tex.wrapMode = TextureWrapMode.Repeat;
                tex.name     = set.name;
            }

            var mips = new List <Color[]>();

            for (var i = 1; i < tex.mipmapCount; i++)
            {
                mips.Add(tex.GetPixels(i));
            }

            for (var colChan = 0; colChan < 4; colChan++)
            {
                var c = _channel[colChan];
                if (!c.enabled)
                {
                    continue;
                }

                var ch  = c.sourceChannel;
                var col = c.Role.GetPixels(set, id);

                if (c.flip)
                {
                    for (var i = 0; i < size; i++)
                    {
                        dst[i][colChan] = 1 - col[i][ch];
                    }
                }
                else
                {
                    for (var i = 0; i < size; i++)
                    {
                        dst[i][colChan] = col[i][ch];
                    }
                }


                var newMips = c.Role.GetMipPixels(set, id);
                for (var m = 1; m < tex.mipmapCount; m++)
                {
                    var mLevel   = mips[m - 1];
                    var newLevel = newMips[m - 1];


                    if (c.flip)
                    {
                        for (var si = 0; si < mLevel.Length; si++)
                        {
                            mLevel[si][colChan] = 1 - newLevel[si][colChan];
                        }
                    }
                    else
                    {
                        for (var si = 0; si < mLevel.Length; si++)
                        {
                            mLevel[si][colChan] = newLevel[si][colChan];
                        }
                    }

                    mips[m - 1] = mLevel;
                }
            }


            for (var i = 1; i < tex.mipmapCount; i++)
            {
                tex.SetPixels(mips[i - 1], i);
            }

            if (id != null)
            {
                id.SetAndApply(false);
                set.lastProduct = tex;
            }
            else
            {
                tex.SetPixels(dst);
                tex.Apply(false, false);
                set.lastProduct = tex;

#if UNITY_EDITOR
                set.lastProduct = tex.SaveTextureAsAsset(TexMGMTdata.texturesFolderName, ref set.name, false);

                var importer = set.lastProduct.GetTextureImporter();

                var needReimport = importer.WasNotReadable();
                needReimport |= importer.WasWrongIsColor(_isColor);
                needReimport |= importer.WasClamped();

                if (needReimport)
                {
                    importer.SaveAndReimport();
                }
#endif
            }

            TextureRole.Clear();
        }
        public bool Inspect(TextureSetForCombinedMaps sets)
        {
            var p = InspectedPainter;

            pegi.nl();

            var changed = "Name".edit(80, ref _name);

            var path = Path.Combine(PainterCamera.Data.texturesFolderName, FolderName);

            if (icon.Save.Click("Will save to " + path).nl())
            {
                this.SaveToAssets(path, _name);
                QcUnity.RefreshAssetDatabase();
                (_name + " was saved to " + path).showNotificationIn3D_Views();
            }
            pegi.nl();

            changed |= "Color texture ".toggleIcon(ref _isColor).nl(ref changed);

            var usingBumpStrength  = false;
            var usingColorSelector = false;
            var usingGlossMap      = false;

            for (var c = 0; c < 4; c++)
            {
                var ch = _channel[c];
                changed |= ((ColorChanel)c).GetIcon().toggle(ref ch.enabled);

                if (ch.enabled)
                {
                    if ((ch.flip ? "inverted" : "+ 0").Click("Copy as is or invert (1-X)"))
                    {
                        ch.flip = !ch.flip;
                    }

                    changed |= ch.Nested_Inspect().nl();

                    usingBumpStrength  |= ch.Role.UsingBumpStrengthSlider(ch.sourceChannel);
                    usingColorSelector |= ch.Role.UsingColorSelector;
                    usingGlossMap      |= ch.Role.GetType() == typeof(TextureRole_Gloss);
                }

                pegi.nl();
            }

            if (usingBumpStrength)
            {
                "Bump Strength".edit(ref bumpStrength).nl(ref changed);
            }
            if (usingColorSelector)
            {
                "Color".edit(ref fillColor).nl(ref changed);
            }
            if (usingGlossMap)
            {
                if ((sets == null || sets.heightMap) &&
                    "Gloss Mip -= Height Noise".toggle(ref glossNoiseFromHeight).nl(ref changed))
                {
                    _glossNoiseFromBump = false;
                }



                if ((sets == null || sets.normalMap) &&
                    "Gloss Mip -= Normal Noise".toggle(ref _glossNoiseFromBump).nl(ref changed))
                {
                    glossNoiseFromHeight = false;
                }


                if (glossNoiseFromHeight || _glossNoiseFromBump)
                {
                    "Fraction".edit(ref bumpNoiseInGlossFraction, 0f, 40f).nl();
                }
            }


            if (sets != null)
            {
                if ("Combine".Click().nl(ref changed))
                {
                    Combine(sets, p);
                }

                if (p)
                {
                    "You will still need to press SAVE in Painter to update original texture.".writeHint();
                }
            }

            return(changed);
        }