コード例 #1
0
        private WorkingMaterial CreateBakedMaterial(string name, Bounds bounds, bool useHighMaterial)
        {
            int    matInstanceID = useHighMaterial ? m_terrainMaterialInstanceId : m_terrainMaterialLowInstanceId;
            string matName       = useHighMaterial ? m_terrainMaterialName : m_terrainMaterialLowName;

            WorkingMaterial material = new WorkingMaterial(Allocator.Persistent, matInstanceID, matName);

            material.Name = name + "_Material";

            m_queue.EnqueueJob(() =>
            {
                WorkingTexture albedo = BakeAlbedo(name, bounds, m_hlod.TextureSize);
                material.AddTexture(m_hlod.AlbedoPropertyName, albedo);
            });

            if (m_hlod.UseNormal)
            {
                m_queue.EnqueueJob(() =>
                {
                    WorkingTexture normal = BakeNormal(name, bounds, m_hlod.TextureSize);
                    material.AddTexture(m_hlod.NormalPropertyName, normal);
                });
            }

            if (m_hlod.UseMask)
            {
                m_queue.EnqueueJob(() =>
                {
                    WorkingTexture mask = BakeMask(name, bounds, m_hlod.TextureSize);
                    material.AddTexture(m_hlod.MaskPropertyName, mask);
                });
            }

            return(material);
        }
コード例 #2
0
            private WorkingTexture GenerateMipmap(WorkingTexture source)
            {
                int sx = Mathf.Max(source.Width >> 1, 1);
                int sy = Mathf.Max(source.Height >> 1, 1);

                WorkingTexture mipmap = new WorkingTexture(Allocator.Persistent, source.Format, sx, sy, source.Linear);

                mipmap.Name = source.Name;

                for (int y = 0; y < sy; ++y)
                {
                    for (int x = 0; x < sx; ++x)
                    {
                        Color color = new Color();

                        int x1 = Mathf.Min(x * 2 + 0, source.Width - 1);
                        int x2 = Mathf.Min(x * 2 + 1, source.Width - 1);
                        int y1 = Mathf.Min(y * 2 + 0, source.Height - 1);
                        int y2 = Mathf.Min(y * 2 + 1, source.Height - 1);

                        color += source.GetPixel(x1, y1);
                        color += source.GetPixel(x1, y2);
                        color += source.GetPixel(x2, y1);
                        color += source.GetPixel(x2, y2);

                        color /= 4;

                        mipmap.SetPixel(x, y, color);
                    }
                }

                return(mipmap);
            }
コード例 #3
0
 private void RemapTexture(WorkingTexture source, Color min, Color max)
 {
     for (int y = 0; y < source.Height; ++y)
     {
         for (int x = 0; x < source.Width; ++x)
         {
             var color = source.GetPixel(x, y);
             color = color * max + min;
             source.SetPixel(x, y, color);
         }
     }
 }
コード例 #4
0
        static private WorkingTexture CreateEmptyTexture(int width, int height, Color color, bool linear)
        {
            WorkingTexture texture = new WorkingTexture(Allocator.Persistent, TextureFormat.RGB24, width, height, linear);

            for (int y = 0; y < height; ++y)
            {
                for (int x = 0; x < width; ++x)
                {
                    texture.SetPixel(x, y, color);
                }
            }

            return(texture);
        }
コード例 #5
0
            private void ApplyTintColor(WorkingTexture texture, Color tintColor)
            {
                for (int ty = 0; ty < texture.Height; ++ty)
                {
                    for (int tx = 0; tx < texture.Width; ++tx)
                    {
                        Color c = texture.GetPixel(tx, ty);

                        c.r = c.r * tintColor.r;
                        c.g = c.g * tintColor.g;
                        c.b = c.b * tintColor.b;
                        c.a = c.a * tintColor.a;

                        texture.SetPixel(tx, ty, c);
                    }
                }
            }
コード例 #6
0
        private WorkingTexture BakeMask(string name, Bounds bounds, int resolution)
        {
            WorkingTexture maskTexture = new WorkingTexture(Allocator.Persistent, TextureFormat.ARGB32, resolution, resolution, false);

            maskTexture.Name     = name + "_Mask";
            maskTexture.WrapMode = TextureWrapMode.Clamp;

            EnqueueBlendTextureJob(maskTexture, bounds, resolution, (layer, wx, wz, sx, sz, linear) =>
            {
                Color c = m_layers[layer].GetMaskByWorld(wx, wz, sx, sz);
                if (!linear)
                {
                    c = c.linear;
                }
                return(c);
            });

            return(maskTexture);
        }
コード例 #7
0
            private void AddToCache(WorkingMaterial material)
            {
                string         inputName = m_textureInfoList[0].InputName;
                WorkingTexture texture   = material.GetTexture(inputName);

                if (texture == null)
                {
                    texture = m_defaultTextures[m_textureInfoList[0].Type];
                }

                TexturePacker.MaterialTexture materialTexture = new TexturePacker.MaterialTexture();

                if (m_enableTintColor)
                {
                    Color tintColor = material.GetColor(m_tintColorName);

                    texture = texture.Clone();
                    ApplyTintColor(texture, tintColor);
                    materialTexture.Add(texture);
                    texture.Dispose();
                }
                else
                {
                    materialTexture.Add(texture);
                }


                for (int ti = 1; ti < m_textureInfoList.Count; ++ti)
                {
                    string         input = m_textureInfoList[ti].InputName;
                    WorkingTexture tex   = material.GetTexture(input);

                    if (tex == null)
                    {
                        tex = m_defaultTextures[m_textureInfoList[ti].Type];
                    }

                    materialTexture.Add(tex);
                }

                m_textureCache.Add(material.Guid, materialTexture);
            }
コード例 #8
0
        private WorkingTexture BakeAlbedo(string name, Bounds bounds, int resolution)
        {
            WorkingTexture albedoTexture = new WorkingTexture(Allocator.Persistent, TextureFormat.RGB24, resolution, resolution, false);

            albedoTexture.Name     = name + "_Albedo";
            albedoTexture.WrapMode = TextureWrapMode.Clamp;

            EnqueueBlendTextureJob(albedoTexture, bounds, resolution, (layer, wx, wz, sx, sz, linear) =>
            {
                Color c = m_layers[layer].GetColorByWorld(wx, wz, sx, sz);
                if (!linear)
                {
                    c = c.linear;
                }
                return(c);
            });


            return(albedoTexture);
        }
コード例 #9
0
        private WorkingTexture BakeNormal(string name, Bounds bounds, int resolution)
        {
            WorkingTexture normalTexture = new WorkingTexture(Allocator.Persistent, TextureFormat.RGB24, resolution, resolution, true);

            normalTexture.Name     = name + "_Normal";
            normalTexture.WrapMode = TextureWrapMode.Clamp;

            EnqueueBlendTextureJob(normalTexture, bounds, resolution, (layer, wx, wz, sx, sz, linear) =>
            {
                Color c = m_layers[layer].GetNormalByWorld(wx, wz, sx, sz);
                c       = UnPackNormal(c, m_layers[layer].NormalScale);
                return(c);
            }, (c) =>
            {
                Vector3 n = new Vector3(c.r, c.g, c.b);
                n.Normalize();
                c = new Color(n.x, n.y, n.z);
                return(PackNormal(c));
            });

            return(normalTexture);
        }
コード例 #10
0
            private DisposableList <MaterialTexture> CreateResizedTextures(int newWidth, int newHeight)
            {
                DisposableList <MaterialTexture> resized = new DisposableList <MaterialTexture>();

                for (int i = 0; i < m_textures.Count; ++i)
                {
                    MaterialTexture newMT = new MaterialTexture();

                    for (int k = 0; k < m_textures[i].Count; ++k)
                    {
                        int            targetWidth    = Mathf.Min(newWidth, m_textures[i][k].Width);
                        int            targetHeight   = Mathf.Min(newHeight, m_textures[i][k].Height);
                        WorkingTexture resizedTexture =
                            m_textures[i][k].Resize(Allocator.Persistent, targetWidth, targetHeight);
                        newMT.Add(resizedTexture);
                        resizedTexture.Dispose();
                    }

                    resized.Add(newMT);
                }

                return(resized);
            }
コード例 #11
0
        private WorkingMaterial CreateBakedMaterial(string name, Bounds bounds)
        {
            WorkingMaterial material = new WorkingMaterial(Allocator.Persistent, m_terrainMaterialInstanceId, m_terrainMaterialName);

            material.Name = name + "_Material";

            m_queue.EnqueueJob(() =>
            {
                WorkingTexture albedo = BakeAlbedo(name, bounds, m_hlod.TextureSize);
                material.AddTexture(m_hlod.AlbedoPropertyName, albedo);
            });

            if (m_hlod.UseNormal)
            {
                m_queue.EnqueueJob(() =>
                {
                    WorkingTexture normal = BakeNormal(name, bounds, m_hlod.TextureSize);
                    material.AddTexture(m_hlod.NormalPropertyName, normal);
                });
            }

            return(material);
        }
コード例 #12
0
        private WorkingTexture BakeNormal(string name, Bounds bounds, int resolution)
        {
            WorkingTexture normalTexture = new WorkingTexture(Allocator.Persistent, TextureFormat.RGB24, resolution, resolution, true);

            normalTexture.Name     = name + "_Normal";
            normalTexture.WrapMode = TextureWrapMode.Clamp;

            m_queue.EnqueueJob(() =>
            {
                float ustart = (bounds.min.x) / m_size.x;
                float vstart = (bounds.min.z) / m_size.z;
                float usize  = (bounds.max.x - bounds.min.x) / m_size.x;
                float vsize  = (bounds.max.z - bounds.min.z) / m_size.z;

                for (int y = 0; y < resolution; ++y)
                {
                    for (int x = 0; x < resolution; ++x)
                    {
                        float u = (float)x / (float)resolution * usize + ustart;
                        float v = (float)y / (float)resolution * vsize + vstart;

                        Vector3 normal = m_heightmap.GetInterpolatedNormal(u, v);

                        Color color = new Color(0.0f, 0.0f, 0.0f, 0.0f);
                        color.r     = normal.x * 0.5f + 0.5f;
                        color.g     = -normal.z * 0.5f + 0.5f;
                        color.b     = normal.y * 0.5f + 0.5f;

                        color.a = 1.0f;
                        normalTexture.SetPixel(x, y, color);
                    }
                }
            });


            return(normalTexture);
        }
コード例 #13
0
        private WorkingTexture BakeAlbedo(string name, Bounds bounds, int resolution)
        {
            WorkingTexture albedoTexture = new WorkingTexture(Allocator.Persistent, TextureFormat.RGB24, resolution, resolution, false);

            albedoTexture.Name     = name + "_Albedo";
            albedoTexture.WrapMode = TextureWrapMode.Clamp;

            m_queue.EnqueueJob(() =>
            {
                float ustart = (bounds.min.x) / m_size.x;
                float vstart = (bounds.min.z) / m_size.z;
                float usize  = (bounds.max.x - bounds.min.x) / m_size.x;
                float vsize  = (bounds.max.z - bounds.min.z) / m_size.z;

                for (int y = 0; y < resolution; ++y)
                {
                    for (int x = 0; x < resolution; ++x)
                    {
                        float u = (float)x / (float)resolution * usize + ustart;
                        float v = (float)y / (float)resolution * vsize + vstart;

                        Color color = new Color(0.0f, 0.0f, 0.0f, 0.0f);

                        for (int li = 0; li < m_layers.Count; ++li)
                        {
                            float weight = 0.0f;
                            switch (li % 4)
                            {
                            case 0:
                                weight = m_alphamaps[li / 4].GetPixel(u, v).r;
                                break;

                            case 1:
                                weight = m_alphamaps[li / 4].GetPixel(u, v).g;
                                break;

                            case 2:
                                weight = m_alphamaps[li / 4].GetPixel(u, v).b;
                                break;

                            case 3:
                                weight = m_alphamaps[li / 4].GetPixel(u, v).a;
                                break;
                            }

                            //optimize to skip not effect pixels.
                            if (weight < 0.01f)
                            {
                                continue;
                            }

                            float wx = (float)x / (float)resolution * bounds.size.x + bounds.min.x;
                            float wy = (float)y / (float)resolution * bounds.size.z + bounds.min.z;

                            Color c = m_layers[li].GetColorByWorld(wx, wy, bounds.size.x, bounds.size.z);

                            color.r += Mathf.Pow(c.r, 2.2f) * weight;
                            color.g += Mathf.Pow(c.g, 2.2f) * weight;
                            color.b += Mathf.Pow(c.b, 2.2f) * weight;
                        }

                        color.r = Mathf.Pow(color.r, 0.454545f);
                        color.g = Mathf.Pow(color.g, 0.454545f);
                        color.b = Mathf.Pow(color.b, 0.454545f);
                        color.a = 1.0f;
                        albedoTexture.SetPixel(x, y, color);
                    }
                }
            });


            return(albedoTexture);
        }
コード例 #14
0
        private void EnqueueBlendTextureJob(WorkingTexture texture, Bounds bounds, int resolution, System.Func <int, float, float, float, float, bool, Color> getColor, System.Func <Color, Color> packColor = null)
        {
            bool linear = texture.Linear;

            m_queue.EnqueueJob(() =>
            {
                float ustart = (bounds.min.x) / m_size.x;
                float vstart = (bounds.min.z) / m_size.z;
                float usize  = (bounds.max.x - bounds.min.x) / m_size.x;
                float vsize  = (bounds.max.z - bounds.min.z) / m_size.z;

                for (int y = 0; y < resolution; ++y)
                {
                    for (int x = 0; x < resolution; ++x)
                    {
                        float u = (float)x / (float)resolution * usize + ustart;
                        float v = (float)y / (float)resolution * vsize + vstart;

                        Color color = new Color(0.0f, 0.0f, 0.0f, 0.0f);

                        for (int li = 0; li < m_layers.Count; ++li)
                        {
                            float weight = 0.0f;
                            switch (li % 4)
                            {
                            case 0:
                                weight = m_alphamaps[li / 4].GetPixel(u, v).r;
                                break;

                            case 1:
                                weight = m_alphamaps[li / 4].GetPixel(u, v).g;
                                break;

                            case 2:
                                weight = m_alphamaps[li / 4].GetPixel(u, v).b;
                                break;

                            case 3:
                                weight = m_alphamaps[li / 4].GetPixel(u, v).a;
                                break;
                            }

                            //optimize to skip not effect pixels.
                            if (weight < 0.01f)
                            {
                                continue;
                            }

                            float wx = (float)x / (float)resolution * bounds.size.x + bounds.min.x;
                            float wy = (float)y / (float)resolution * bounds.size.z + bounds.min.z;

                            Color c = getColor(li, wx, wy, bounds.size.x, bounds.size.z, linear);

                            // blend in linear space.
                            color.r += c.r * weight;
                            color.g += c.g * weight;
                            color.b += c.b * weight;
                            color.a += c.a * weight;
                        }

                        if (packColor != null)
                        {
                            color = packColor(color);
                        }

                        if (!linear)
                        {
                            color = color.gamma;
                        }

                        texture.SetPixel(x, y, color);
                    }
                }
            });
        }
コード例 #15
0
 public TextureCombiner(Allocator allocator, TextureFormat format, int width, int height, bool linear)
 {
     m_texture = new WorkingTexture(allocator, format, width, height, linear);
 }
コード例 #16
0
 public void SetTexture(WorkingTexture source, int x, int y)
 {
     m_texture.Blit(source, x, y);
 }
コード例 #17
0
        private void PackingTexture(TexturePacker packer, DisposableList <HLODBuildInfo> targets, dynamic options, Action <float> onProgress)
        {
            List <TextureInfo> textureInfoList = options.TextureInfoList;

            using (MaterialTextureCache cache = new MaterialTextureCache(options))
            {
                for (int i = 0; i < targets.Count; ++i)
                {
                    var workingObjects = targets[i].WorkingObjects;
                    Dictionary <Guid, TexturePacker.MaterialTexture> textures =
                        new Dictionary <Guid, TexturePacker.MaterialTexture>();

                    for (int oi = 0; oi < workingObjects.Count; ++oi)
                    {
                        var materials = workingObjects[oi].Materials;

                        for (int m = 0; m < materials.Count; ++m)
                        {
                            var materialTextures = cache.GetMaterialTextures(materials[m]);
                            if (materialTextures == null)
                            {
                                continue;
                            }

                            if (textures.ContainsKey(materialTextures[0].GetGUID()) == true)
                            {
                                continue;
                            }

                            textures.Add(materialTextures[0].GetGUID(), materialTextures);
                        }
                    }


                    packer.AddTextureGroup(targets[i], textures.Values.ToList());


                    if (onProgress != null)
                    {
                        onProgress(((float)i / targets.Count) * 0.1f);
                    }
                }
            }

            packer.Pack(TextureFormat.RGBA32, options.PackTextureSize, options.LimitTextureSize, false);
            if (onProgress != null)
            {
                onProgress(0.3f);
            }

            int index   = 1;
            var atlases = packer.GetAllAtlases();

            foreach (var atlas in atlases)
            {
                Dictionary <string, WorkingTexture> textures = new Dictionary <string, WorkingTexture>();
                for (int i = 0; i < atlas.Textures.Count; ++i)
                {
                    WorkingTexture wt = atlas.Textures[i];
                    wt.Name = "CombinedTexture " + index + "_" + i;
                    if (textureInfoList[i].Type == PackingType.Normal)
                    {
                        wt.Linear = true;
                    }

                    textures.Add(textureInfoList[i].OutputName, wt);
                }

                WorkingMaterial mat = CreateMaterial(options.MaterialGUID, textures);
                mat.Name = "CombinedMaterial " + index;
                m_createdMaterials.Add(atlas, mat);
                index += 1;
            }
        }
コード例 #18
0
 public void Add(WorkingTexture texture)
 {
     m_textures.Add(texture.Clone());
 }
コード例 #19
0
            public Layer(TerrainLayer layer)
            {
                var texture = layer.diffuseTexture;

                bool linear = !GraphicsFormatUtility.IsSRGBFormat(texture.graphicsFormat);

                m_diffuseTexstures = new DisposableList <WorkingTexture>();

                m_offset = layer.tileOffset;
                m_size   = layer.tileSize;
                var diffuseRemapMin = layer.diffuseRemapMin;
                var diffuseRemapMax = layer.diffuseRemapMax;

                diffuseRemapMin.x = Mathf.Pow(diffuseRemapMin.x, 0.45f);
                diffuseRemapMin.y = Mathf.Pow(diffuseRemapMin.y, 0.45f);
                diffuseRemapMin.z = Mathf.Pow(diffuseRemapMin.z, 0.45f);

                diffuseRemapMax.x = Mathf.Pow(diffuseRemapMax.x, 0.45f);
                diffuseRemapMax.y = Mathf.Pow(diffuseRemapMax.y, 0.45f);
                diffuseRemapMax.z = Mathf.Pow(diffuseRemapMax.z, 0.45f);


                //make to texture readable.
                var assetImporter        = AssetImporter.GetAtPath(AssetDatabase.GetAssetPath(texture));
                var textureImporter      = assetImporter as TextureImporter;
                TextureImporterType type = TextureImporterType.Default;

                if (textureImporter)
                {
                    type = textureImporter.textureType;
                    textureImporter.isReadable  = true;
                    textureImporter.textureType = TextureImporterType.Default;
                    textureImporter.SaveAndReimport();
                }

                try
                {
                    for (int i = 0; i < texture.mipmapCount; ++i)
                    {
                        int            width          = texture.width >> i;
                        int            height         = texture.height >> i;
                        WorkingTexture workingTexture = new WorkingTexture(Allocator.Persistent, texture.format, width, height, linear);
                        Color[]        colors         = texture.GetPixels(i);
                        for (int y = 0; y < height; ++y)
                        {
                            for (int x = 0; x < width; ++x)
                            {
                                workingTexture.SetPixel(x, y, colors[y * width + x]);
                            }
                        }

                        RemapTexture(workingTexture, diffuseRemapMin, diffuseRemapMax);
                        m_diffuseTexstures.Add(workingTexture);
                    }
                }
                finally
                {
                    if (textureImporter)
                    {
                        textureImporter.isReadable  = false;
                        textureImporter.textureType = type;
                        textureImporter.SaveAndReimport();
                    }
                }
            }
コード例 #20
0
        public IEnumerator CreateImpl()
        {
            try
            {
                using (m_queue = new JobQueue(8))
                {
                    Stopwatch sw = new Stopwatch();

                    AssetDatabase.Refresh();
                    AssetDatabase.SaveAssets();

                    sw.Reset();
                    sw.Start();

                    EditorUtility.DisplayProgressBar("Bake HLOD", "Initialize Bake", 0.0f);


                    TerrainData data = m_hlod.TerrainData;

                    m_size = data.size;

                    m_heightmap = new Heightmap(data.heightmapResolution, data.heightmapResolution, data.size,
                                                data.GetHeights(0, 0, data.heightmapResolution, data.heightmapResolution));

                    string materialPath = AssetDatabase.GUIDToAssetPath(m_hlod.MaterialGUID);
                    m_terrainMaterial = AssetDatabase.LoadAssetAtPath <Material>(materialPath);
                    if (m_terrainMaterial == null)
                    {
                        m_terrainMaterial = new Material(Shader.Find("Standard"));
                    }

                    m_terrainMaterialInstanceId = m_terrainMaterial.GetInstanceID();
                    m_terrainMaterialName       = m_terrainMaterial.name;

                    using (m_alphamaps = new DisposableList <WorkingTexture>())
                        using (m_layers = new DisposableList <Layer>())
                        {
                            for (int i = 0; i < data.alphamapTextures.Length; ++i)
                            {
                                m_alphamaps.Add(new WorkingTexture(Allocator.Persistent, data.alphamapTextures[i]));
                            }

                            for (int i = 0; i < data.terrainLayers.Length; ++i)
                            {
                                m_layers.Add(new Layer(data.terrainLayers[i]));
                            }


                            QuadTreeSpaceSplitter splitter =
                                new QuadTreeSpaceSplitter(0.0f);

                            SpaceNode rootNode = splitter.CreateSpaceTree(m_hlod.GetBounds(), m_hlod.ChunkSize * 2.0f,
                                                                          m_hlod.transform.position, null, progress => { });

                            EditorUtility.DisplayProgressBar("Bake HLOD", "Create mesh", 0.0f);

                            using (DisposableList <HLODBuildInfo> buildInfos = CreateBuildInfo(data, rootNode))
                            {
                                yield return(m_queue.WaitFinish());

                                //Write material & textures

                                for (int i = 0; i < buildInfos.Count; ++i)
                                {
                                    int curIndex = i;
                                    m_queue.EnqueueJob(() =>
                                    {
                                        ISimplifier simplifier = (ISimplifier)Activator.CreateInstance(m_hlod.SimplifierType,
                                                                                                       new object[] { m_hlod.SimplifierOptions });
                                        simplifier.SimplifyImmidiate(buildInfos[curIndex]);
                                    });
                                }

                                EditorUtility.DisplayProgressBar("Bake HLOD", "Simplify meshes", 0.0f);
                                yield return(m_queue.WaitFinish());

                                Debug.Log("[TerrainHLOD] Simplify: " + sw.Elapsed.ToString("g"));
                                sw.Reset();
                                sw.Start();
                                EditorUtility.DisplayProgressBar("Bake HLOD", "Make border", 0.0f);

                                for (int i = 0; i < buildInfos.Count; ++i)
                                {
                                    HLODBuildInfo info = buildInfos[i];
                                    m_queue.EnqueueJob(() =>
                                    {
                                        for (int oi = 0; oi < info.WorkingObjects.Count; ++oi)
                                        {
                                            WorkingObject o       = info.WorkingObjects[oi];
                                            int borderVertexCount = m_hlod.BorderVertexCount * Mathf.RoundToInt(Mathf.Pow(2.0f, (float)info.Distances[oi]));
                                            using (WorkingMesh m = MakeBorder(o.Mesh, info.Heightmap, borderVertexCount))
                                            {
                                                ReampUV(m, info.Heightmap);
                                                o.SetMesh(MakeFillHoleMesh(m));
                                            }
                                        }
                                    });
                                }
                                yield return(m_queue.WaitFinish());

                                Debug.Log("[TerrainHLOD] Make Border: " + sw.Elapsed.ToString("g"));
                                sw.Reset();
                                sw.Start();


                                for (int i = 0; i < buildInfos.Count; ++i)
                                {
                                    SpaceNode     node = buildInfos[i].Target;
                                    HLODBuildInfo info = buildInfos[i];
                                    if (node.HasChild() == false)
                                    {
                                        SpaceNode parent = node.ParentNode;
                                        node.ParentNode = null;

                                        GameObject go = new GameObject(buildInfos[i].Name);

                                        for (int wi = 0; wi < info.WorkingObjects.Count; ++wi)
                                        {
                                            WorkingObject wo       = info.WorkingObjects[wi];
                                            GameObject    targetGO = null;
                                            if (wi == 0)
                                            {
                                                targetGO = go;
                                            }
                                            else
                                            {
                                                targetGO = new GameObject(wi.ToString());
                                                targetGO.transform.SetParent(go.transform, false);
                                            }

                                            List <Material> materials = new List <Material>();
                                            for (int mi = 0; mi < wo.Materials.Count; ++mi)
                                            {
                                                WorkingMaterial wm = wo.Materials[mi];
                                                if (wm.NeedWrite() == false)
                                                {
                                                    materials.Add(wm.ToMaterial());
                                                    continue;
                                                }

                                                Material mat          = new Material(wm.ToMaterial());
                                                string[] textureNames = wm.GetTextureNames();
                                                for (int ti = 0; ti < textureNames.Length; ++ti)
                                                {
                                                    WorkingTexture wt  = wm.GetTexture(textureNames[ti]);
                                                    Texture2D      tex = wt.ToTexture();
                                                    tex.wrapMode = wt.WrapMode;
                                                    mat.name     = targetGO.name + "_Mat";
                                                    mat.SetTexture(textureNames[ti], tex);
                                                }
                                                mat.EnableKeyword("_NORMALMAP");
                                                materials.Add(mat);
                                            }

                                            targetGO.AddComponent <MeshFilter>().sharedMesh        = wo.Mesh.ToMesh();
                                            targetGO.AddComponent <MeshRenderer>().sharedMaterials = materials.ToArray();
                                        }

                                        go.transform.SetParent(m_hlod.transform, false);
                                        m_hlod.AddGeneratedResource(go);

                                        parent.Objects.Add(go);
                                        buildInfos.RemoveAt(i);
                                        i -= 1;
                                    }
                                }

                                //controller
                                IStreamingBuilder builder =
                                    (IStreamingBuilder)Activator.CreateInstance(m_hlod.StreamingType,
                                                                                new object[] { m_hlod, m_hlod.StreamingOptions });

                                builder.Build(rootNode, buildInfos, m_hlod.gameObject, m_hlod.CullDistance, m_hlod.LODDistance, true, false,
                                              progress =>
                                {
                                    EditorUtility.DisplayProgressBar("Bake HLOD", "Storing results.",
                                                                     0.75f + progress * 0.25f);
                                });

                                Debug.Log("[TerrainHLOD] Build: " + sw.Elapsed.ToString("g"));
                            }
                        }

                    EditorUtility.SetDirty(m_hlod.gameObject);
                }
            }
            finally
            {
                EditorUtility.ClearProgressBar();
                GC.Collect();
            }
        }
コード例 #21
0
            void MakeTexture(TerrainLayer layer, Texture2D texture, Vector4 min, Vector4 max, DisposableList <WorkingTexture> results)
            {
                bool linear = !GraphicsFormatUtility.IsSRGBFormat(texture.graphicsFormat);

                var offset = layer.tileOffset;
                var size   = layer.tileSize;

                if (!linear)
                {
                    min.x = Mathf.Pow(min.x, 0.45f);
                    min.y = Mathf.Pow(min.y, 0.45f);
                    min.z = Mathf.Pow(min.z, 0.45f);

                    max.x = Mathf.Pow(max.x, 0.45f);
                    max.y = Mathf.Pow(max.y, 0.45f);
                    max.z = Mathf.Pow(max.z, 0.45f);
                }


                //make to texture readable.
                var assetImporter        = AssetImporter.GetAtPath(AssetDatabase.GetAssetPath(texture));
                var textureImporter      = assetImporter as TextureImporter;
                TextureImporterType type = TextureImporterType.Default;

                if (textureImporter)
                {
                    type = textureImporter.textureType;
                    textureImporter.isReadable  = true;
                    textureImporter.textureType = TextureImporterType.Default;
                    textureImporter.SaveAndReimport();
                }

                try
                {
                    for (int i = 0; i < texture.mipmapCount; ++i)
                    {
                        int            width          = texture.width >> i;
                        int            height         = texture.height >> i;
                        WorkingTexture workingTexture = new WorkingTexture(Allocator.Persistent, texture.format, width, height, linear);
                        Color[]        colors         = texture.GetPixels(i);
                        for (int y = 0; y < height; ++y)
                        {
                            for (int x = 0; x < width; ++x)
                            {
                                workingTexture.SetPixel(x, y, colors[y * width + x]);
                            }
                        }

                        RemapTexture(workingTexture, min, max);
                        results.Add(workingTexture);
                    }
                }
                finally
                {
                    if (textureImporter)
                    {
                        textureImporter.isReadable  = false;
                        textureImporter.textureType = type;
                        textureImporter.SaveAndReimport();
                    }
                }
            }