本人水平有限,不正之處還往大拿狂噴!
看到這個標題,有人估計會質疑,這不蛋疼,好好的png干嘛要分拆成兩個啊!
倘若你有如此質疑,如此憤青的言論,恭喜你來對地方了,同時也小小鄙視你一下,水平太菜了。哈哈 言歸正傳!
為什么要這么做?
1、主要目的為了減小包大小,同時圖片質量損失小。手游大家都知道,包越小轉化率越高(可玩性相同的前提下)
實現細節:把一張帶alpha通道的導入ps,在ps里面新建一張大小跟原圖一樣,格式為位圖(為什么要位圖,alpha值在標記透明的時候 其實就是非黑及白 也就是 0 1),復制原圖的alpha通道到新建的圖層,保存為png,保存原圖為JPG 這樣mask和jpg制作好了(這塊用的bmp原圖遭吐槽了,補充一份png的圖)
前后大小比較:
實現原理:
在渲染過程中,把這兩個重新還原回來,緩沖區的rgb為jpg紋理的rgb,a為mask紋理的r或g或b(為什么是 r/g/b 保存的mask時三個值是一樣的 不信你試試 反正我試了 好使)
shader源碼:
Shader "MaskTest" { Properties { _MainTex ("Base (RGB)", 2D) = "" {} _MainMask ("Base (RGB)", 2D) = "" {} } SubShader { Pass { Blend SrcAlpha OneMinusSrcAlpha //一定不要忘了這個 CGPROGRAM #pragma vertex vert #pragma fragment frag #include "UnityCG.cginc" struct vert_Input { fixed4 vertex : POSITION; fixed2 texcoord : TEXCOORD0; }; struct vert_Output { fixed4 pos : SV_POSITION; fixed2 texcoord : TEXCOORD0; }; uniform sampler2D _MainTex; uniform sampler2D _MainMask; vert_Output vert(vert_Input i) { vert_Output o; o.pos = mul(UNITY_MATRIX_MVP,i.vertex); o.texcoord = i.texcoord; return o; } fixed4 frag(vert_Output o):COLOR { fixed4 color1 = tex2D(_MainTex,o.texcoord); fixed4 mask = tex2D(_MainMask,o.texcoord); color1.a = mask.r; return color1; } ENDCG } } }
實現效果:
使用紋理:
這樣基本實現了功能,但是有點麻煩 還的每次計算兩個紋理,效率有點低,也不夠高大尚
參考別人的說法,是在加載紋理的時候,實現紋理合並,在內存中一次生成一個texture,避免在shader中的運算。實現原理就是jpg的rgb拷貝到texture的rgb,把png的r/b/g拷貝到texture的a中
核心代碼如下:
for(int i = 0; i < len; i++)
{
dest = pngData[srcIndex];//得到第一個
outPic[outIndex] = jpgData[srcIndex];
outPic[outIndex + 1] = jpgData[srcIndex + 1];
outPic[outIndex + 2] = jpgData[srcIndex+2];
outPic[outIndex + 3] = dest;
srcIndex += 3;
outIndex += 4;
}