遊戲中紋理壓縮格式之Texture壓縮紋理特殊處理

記載目錄

1.雜言雜語
2.壓縮紋理特殊處理
    RGBA16 + Dithering 處理
    ETC1的通道剝離
    ETC1的shader

雜言雜語

上一篇文章寫了Texture壓縮紋理,由於篇幅太長的原因沒有寫壓縮紋理特殊處理方式,這裏做一個補充。
進入正題先來碗雞湯吧 [你編程不厲害, 是因爲還不夠努力]http://www.cnblogs.com/aspwebchh/p/7567106.html
不說其它的了,進入正題。

壓縮紋理特殊處理

RGBA16 + Dithering 處理

RGBA16 爲什麼要進行抖動處理呢? 看效果圖

圖片抖動處理效果對比
抖動處理代碼:

        /// <summary>
        /// Floyd–Steinberg dithering
        /// 抖動處理,需要給圖片進行抖動處理
        /// 需要注意的是 需要進行抖動處理的是RGBA32的紋理進行抖動處理,再壓縮爲16位
        /// </summary>
       private static void SetTextureDither(string tex_path)
        {
            SetTextureReadable(tex_path, true);
            var texture = AssetDatabase.LoadAssetAtPath(tex_path, typeof(Texture2D)) as Texture2D;
            var texw = texture.width;
            var texh = texture.height;

            var pixels = texture.GetPixels ();
            var offs = 0;

            var k1Per15 = 1.0f / 15.0f;
            var k1Per16 = 1.0f / 16.0f;
            var k3Per16 = 3.0f / 16.0f;
            var k5Per16 = 5.0f / 16.0f;
            var k7Per16 = 7.0f / 16.0f;

            for (var y = 0; y < texh; y++) 
            {
                for (var x = 0; x < texw; x++) 
                {
                    float a = pixels [offs].a;
                    float r = pixels [offs].r;
                    float g = pixels [offs].g;
                    float b = pixels [offs].b;

                    var a2 = Mathf.Clamp01 (Mathf.Floor (a * 16) * k1Per15);
                    var r2 = Mathf.Clamp01 (Mathf.Floor (r * 16) * k1Per15);
                    var g2 = Mathf.Clamp01 (Mathf.Floor (g * 16) * k1Per15);
                    var b2 = Mathf.Clamp01 (Mathf.Floor (b * 16) * k1Per15);

                    var ae = a - a2;
                    var re = r - r2;
                    var ge = g - g2;
                    var be = b - b2;

                    pixels [offs].a = a2;
                    pixels [offs].r = r2;
                    pixels [offs].g = g2;
                    pixels [offs].b = b2;

                    var n1 = offs + 1;   // (x+1,y)
                    var n2 = offs + texw - 1; // (x-1 , y+1)
                    var n3 = offs + texw;  // (x, y+1)
                    var n4 = offs + texw + 1; // (x+1 , y+1)

                    if (x < texw - 1) 
                    {
                        pixels [n1].a += ae * k7Per16;
                        pixels [n1].r += re * k7Per16;
                        pixels [n1].g += ge * k7Per16;
                        pixels [n1].b += be * k7Per16;
                    }

                    if (y < texh - 1) 
                    {
                        pixels [n3].a += ae * k5Per16;
                        pixels [n3].r += re * k5Per16;
                        pixels [n3].g += ge * k5Per16;
                        pixels [n3].b += be * k5Per16;

                        if (x > 0) 
                        {
                            pixels [n2].a += ae * k3Per16;
                            pixels [n2].r += re * k3Per16;
                            pixels [n2].g += ge * k3Per16;
                            pixels [n2].b += be * k3Per16;
                        }

                        if (x < texw - 1) 
                        {
                            pixels [n4].a += ae * k1Per16;
                            pixels [n4].r += re * k1Per16;
                            pixels [n4].g += ge * k1Per16;
                            pixels [n4].b += be * k1Per16;
                        }
                    }

                    offs++;
                }
            }
            SetTextureReadable(tex_path, false);
            SaveTexture(tex_path, texture, pixels);
        }

ETC1的通道剝離

        /// <summary>
        /// 剝離alpha必須得從RGBA32或者RGBA24剝離
        /// 從RGBA32剝離alpha通道
        /// </summary>
        private static void ChangeTextureToAlphaTexture(string tex_path ,string alpha_tex_path)
        {
            SetTextureReadable(tex_path, true);
            Texture2D sourcetex = AssetDatabase.LoadAssetAtPath(tex_path, typeof(Texture2D)) as Texture2D;
            Color[] colors = sourcetex.GetPixels();
            SetTextureReadable(tex_path, false);


            // 格式化通道
            Texture2D tex_alpha = new Texture2D(sourcetex.width, sourcetex.height, UnityEngine.TextureFormat.RGB24, false);
            Color[] alpha_colors = new Color[colors.Length];
            for (int i = 0; i < colors.Length; ++i)
            {
                alpha_colors[i].r = colors[i].a;
                alpha_colors[i].g = colors[i].a;
                alpha_colors[i].b = colors[i].a;
            }

            SaveTexture(alpha_tex_path, tex_alpha, alpha_colors);
        }

ETC1的shader

    Shader "Unlit/Transparent Colored ETC1"  
    {  
        Properties  
        {  
            _MainTex ("Base (RGB)", 2D) = "black" {}  
            _MainTex_A ("Alpha (A)", 2D) = "white" {}  
        }  

        SubShader  
        {  
            LOD 200  

            Tags  
            {  
                "Queue" = "Transparent"  
                "IgnoreProjector" = "True"  
                "RenderType" = "Transparent"  
            }  

            Pass  
            {  
                Cull Off  
                Lighting Off  
                ZWrite Off  
                Fog { Mode Off }  
                Offset -1, -1  
                Blend SrcAlpha OneMinusSrcAlpha  

                CGPROGRAM  
                #pragma vertex vert  
                #pragma fragment frag             
                #include "UnityCG.cginc"  

                sampler2D _MainTex;  
                sampler2D _MainTex_A;  
                float4 _MainTex_ST;  

                struct appdata_t  
                {  
                    float4 vertex : POSITION;  
                    float2 texcoord : TEXCOORD0;  
                    fixed4 color : COLOR;  
                };  

                struct v2f  
                {  
                    float4 vertex : SV_POSITION;  
                    half2 texcoord : TEXCOORD0;  
                    fixed4 color : COLOR;  
                };  

                v2f o;  

                v2f vert (appdata_t v)  
                {  
                    o.vertex = mul(UNITY_MATRIX_MVP, v.vertex);  
                    o.texcoord = v.texcoord;  
                    o.color = v.color;  
                    return o;  
                }  

                fixed4 frag (v2f IN) : COLOR  
                {  
                    fixed4 col;  

                    col.rgb = tex2D(_MainTex, IN.texcoord).rgb;  
                    col.a = tex2D(_MainTex_A, IN.texcoord).b;  

                    if (IN.color.r < 0.001 && IN.color.g > 0.001 && IN.color.b > 0.001)    
                    {    
                        float grey = dot(col.rgb, float3(0.299, 0.587, 0.114));    
                        col.rgb = float3(grey, grey, grey);    
                    }    
                    else    
                        col = col * IN.color;  

                    return col;  
                }  
                ENDCG  
            }  
        }  

        SubShader  
        {  
            LOD 100  

            Tags  
            {  
                "Queue" = "Transparent"  
                "IgnoreProjector" = "True"  
                "RenderType" = "Transparent"  
            }  

            Pass  
            {  
                Cull Off  
                Lighting Off  
                ZWrite Off  
                Fog { Mode Off }  
                Offset -1, -1  
                ColorMask RGB  
                Blend SrcAlpha OneMinusSrcAlpha  
                ColorMaterial AmbientAndDiffuse  

                SetTexture [_MainTex]  
                {  
                    Combine Texture * Primary  
                }  
            }  
        }  
    }  
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章