游戏中纹理压缩格式之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  
                }  
            }  
        }  
    }  

猜你喜欢

转载自blog.csdn.net/biospc/article/details/78076833
今日推荐