unity编辑器拓展十一——将两张RGB图合并成一张

        游戏角色shader,包含的东西比较多,还要做到动态合并,程序那边希望贴图经可能少,而我们美术用了两张图,一张图的RGB是高光、流光、自发光,另外一张图的RGB是不同区域的偏色,其实每个通道的一整张贴图只用了一部分,其他地方都是空的,于是就想到把两张图合并成一张图来使用。合并后的这张贴图的R通道:0到128 为高光 128到255为偏色区域,前提是偏色跟高光不要重合 所以这个偏色区域最好是皮肤类的,无明显高光类的。从美术的角度,让他们直接按照这样的色阶来画,肯定是很困难的,所以他们还是按照两张图来做,做是做到不交叉,然后我们用工具将两张图合并成一张图,将偏色从0到255改成128到255,将高光从0到255改成0到128,这样再把两个颜色合并到一起。其他通道也是如此。

如图:                                           

        

           偏色                                                    高光                                                     合并后

这样就是一个通道的合成,到shader里 ,贴图采样后,将0到128提取出来,变换成0到255当作高光贴图来用,将128到255提取出来,变换成0到255当作偏色来用

工具代码如下:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEditor;



public class TextureCombine : EditorWindow
{
    [MenuItem("Tools/角色工具/合并贴图")]

    static void window()
    {
        TextureCombine win = (TextureCombine)EditorWindow.GetWindow(typeof(TextureCombine), false, "合并贴图", false);
        win.Show();
    }

     Texture2D tex1;
     Texture2D tex2;
    Texture2D tex3;
    //第一张贴图的的像素组
    List<Color> color01 = new List<Color>();
    //第二张贴图的的像素组
    List<Color> color02 = new List<Color> ();
    //得出第三张贴图得像素组
    List<Color> color03 = new List<Color>();

    private void OnGUI()
    {
        tex1 = EditorGUILayout.ObjectField("偏色贴图", tex1, typeof(Texture), true) as Texture2D;
        tex2 = EditorGUILayout.ObjectField("高光贴图", tex2, typeof(Texture), true) as Texture2D;
        tex3 = EditorGUILayout.ObjectField("合并后效果", tex3, typeof(Texture), true) as Texture2D;

        if (GUI.Button(new Rect(100, 40, 50, 25), "合并"))
        {
            if (tex1!=null && tex2 != null)
            {
                color01.Clear();
                color02.Clear();
                color03.Clear();
                TextureCombin();
            }else
                this.ShowNotification(new GUIContent("没贴图你点个屁啊!!!"));



        }
           

    }



    void TextureCombin()
    {
        //取出第一张贴图的像素
        for (int i = 0; i < tex1.height; i++)
        {
           
            for (int j = 0; j < tex1.width; j++)
            {
                Color a = tex1.GetPixel(j, i);
                //将0到1转换成0.51-1 需要加判断  0值也会被加到0.51 就不是黑底了
              
                if (a.r>0)
                    a.r = a.r * 0.51f + 0.49f;
                if (a.g > 0)
                    a.g = a.g * 0.51f + 0.49f;
                if (a.b > 0)
                    a.b = a.b * 0.51f + 0.49f;
           
                color01.Add(a);
            }
          
 
        }

        //取出第二张贴图的像素
        for (int i = 0; i < tex1.height; i++)
        {
            
            for (int j = 0; j < tex1.width; j++)
            {
                Color a = tex2.GetPixel(j, i);
                //将0-1的值 转换为 0-0.49
                a.r *= 0.49f;
                a.g *= 0.49f;
                a.b *= 0.49f;


                color02.Add(a);
            }
           
        }

        //得出第一张加第二张贴图  
        for (int i = 0; i< color01.Count; i++)
        {
            Color color = new Color();
            if (color01[i].r != 0 && color02[i].r != 0)
            {

                this.ShowNotification(new GUIContent("R通道“偏色”跟“高光”交集哦!!!"));
                break;
            }

            else
                color.r = color01[i].r + color02[i].r;

            if (color01[i].r != 0 && color02[i].r != 0)
            {
                this.ShowNotification(new GUIContent("G通道“偏色”跟“流光”有交集哦!!!"));
                break;
            }

            else
                color.g = color01[i].g + color02[i].g;

            if (color01[i].b != 0 && color02[i].b != 0)
            {
                this.ShowNotification(new GUIContent("B通道“偏色”跟“自发光”有交集哦!!!"));
                break;
            }

            else
                color.b = color01[i].b + color02[i].b;

           

            color03.Add(color);  
        }

        //给第三张图赋值
        if (color03.Count == tex1.width * tex1.height)
        {
            tex3 = new Texture2D(tex1.width, tex1.height, TextureFormat.RGB24, true);
            for (int i = 0; i < tex1.height; i++)
            {
                for (int j = 0; j < tex1.width; j++)
                {

                    tex3.SetPixel(j, i, color03[j + tex1.width * i]);
                }
            }
            tex3.Apply();
            string a = AssetDatabase.GetAssetPath(tex1);//Assets/aa/F2_D001_Body_C 1.psd
            string[] sArray = a.Split('.'); //取“.”前面部分
            a = sArray[0];//取“.”前面部分

            byte[] bytes = tex3.EncodeToPNG();
            string filename = a+"_Combin.png";//将合并的贴图储存到第一张贴图的路径下
            System.IO.File.WriteAllBytes(filename, bytes);
            EditorApplication.ExecuteMenuItem("Assets/Refresh");
           
        }
            



    }


}

将两张贴图拖拽到相应位置,点击“合并”,然后新的贴图将保存到偏色贴图的位置,名称为偏色贴图的名称 + “_Combin”

合并后的贴图为png贴图,本来想存成TGA的,发现Texture2D类没有TGA的接口,没弄成功。记得T4m里的那张通道图好像是TGA的,有空去再去研究下。

猜你喜欢

转载自blog.csdn.net/baicaishisan/article/details/79351582
今日推荐