Author Topic: Alternative to Solidify (Premultiply Alpha)  (Read 7906 times)

FizzPow

  • Jr. Member
  • **
  • Thank You
  • -Given: 0
  • -Receive: 0
  • Posts: 83
    • View Profile
    • FizzPow Games
Alternative to Solidify (Premultiply Alpha)
« on: December 27, 2012, 03:50:30 PM »
So I was not happy with the 'Solidify' photoshop filter approach to cleaning up interior sprite edges and found another solution for anyone interested.  This involves using Texture Packer to create your textures with "Premultiply Alpha" checked and then using this shader:

  1. // unlit, vertex colour, premultiplied alpha blend
  2.  
  3. Shader "PremulVertexColor"
  4. {
  5.         Properties
  6.         {
  7.                 _MainTex ("Base (RGB) Trans (A)", 2D) = "white" {}
  8.         }
  9.  
  10.         SubShader
  11.         {
  12.                 Tags {"Queue"="Transparent" "IgnoreProjector"="True" "RenderType"="Transparent"}
  13.                 ZWrite Off Lighting Off Cull Off Fog { Mode Off } Blend One OneMinusSrcAlpha
  14.                 LOD 110
  15.                
  16.                 Pass
  17.                 {
  18.                         CGPROGRAM
  19.                         #pragma vertex vert_vct
  20.                         #pragma fragment frag_mult
  21.                         #pragma fragmentoption ARB_precision_hint_fastest
  22.                         #include "UnityCG.cginc"
  23.  
  24.                         sampler2D _MainTex;
  25.                         float4 _MainTex_ST;
  26.  
  27.                         struct vin_vct
  28.                         {
  29.                                 float4 vertex : POSITION;
  30.                                 float4 color : COLOR;
  31.                                 float2 texcoord : TEXCOORD0;
  32.                         };
  33.  
  34.                         struct v2f_vct
  35.                         {
  36.                                 float4 vertex : POSITION;
  37.                                 fixed4 color : COLOR;
  38.                                 half2 texcoord : TEXCOORD0;
  39.                         };
  40.  
  41.                         v2f_vct vert_vct(vin_vct v)
  42.                         {
  43.                                 v2f_vct o;
  44.                                 o.vertex = mul(UNITY_MATRIX_MVP, v.vertex);
  45.                                 o.color = v.color;
  46.                                 o.texcoord = v.texcoord;
  47.                                 return o;
  48.                         }
  49.  
  50.                         fixed4 frag_mult(v2f_vct i) : COLOR
  51.                         {
  52.                                 fixed4 col = tex2D(_MainTex, i.texcoord) * i.color;
  53.                                 return col;
  54.                         }
  55.                
  56.                         ENDCG
  57.                 }
  58.         }
  59.  
  60.         SubShader
  61.         {
  62.                 Tags {"Queue"="Transparent" "IgnoreProjector"="True" "RenderType"="Transparent"}
  63.                 ZWrite Off Blend One OneMinusSrcAlpha Cull Off Fog { Mode Off }
  64.                 LOD 100
  65.                
  66.                 BindChannels
  67.                 {
  68.                         Bind "Vertex", vertex
  69.                         Bind "TexCoord", texcoord
  70.                         Bind "Color", color
  71.                 }
  72.  
  73.                 Pass
  74.                 {
  75.                         Lighting Off
  76.                         SetTexture [_MainTex] { combine texture * primary }
  77.                 }
  78.         }
  79. }
  80.  

This works fantastic, but I would love to see this functionality native to NGUI at some point.

FizzPow

  • Jr. Member
  • **
  • Thank You
  • -Given: 0
  • -Receive: 0
  • Posts: 83
    • View Profile
    • FizzPow Games
Re: Alternative to Solidify (Premultiply Alpha)
« Reply #1 on: December 27, 2012, 05:04:18 PM »
Interesting aside using this process, to adjust alpha on a sprite, you have to adjust all 4 RGBA to match what you want alpha to be.  So instead of just Alpha to 100, have to set RGB to 100 as well, or it looks quite wrong =)

jeldrez

  • Sr. Member
  • ****
  • Thank You
  • -Given: 8
  • -Receive: 4
  • Posts: 352
    • View Profile
Re: Alternative to Solidify (Premultiply Alpha)
« Reply #2 on: June 11, 2013, 09:03:33 AM »
Sorry for the bump, but somebody test this script? it could be more useful than applying Solidify A to all the assets.

FizzPow

  • Jr. Member
  • **
  • Thank You
  • -Given: 0
  • -Receive: 0
  • Posts: 83
    • View Profile
    • FizzPow Games
Re: Alternative to Solidify (Premultiply Alpha)
« Reply #3 on: June 11, 2013, 12:12:13 PM »
I can only tell you it works great for us.  I have two apps live in store using this approach (See JamTok Spanish and Japanese).  My understanding is the latest versions of NGUI natively support a pre-multiply alpha option now in atlas creation, but I prefer the workflow of using Texture Packer right now, and how I can set it to auto-create for all 3 resolutions.

ArenMook

  • Administrator
  • Hero Member
  • *****
  • Thank You
  • -Given: 337
  • -Receive: 1171
  • Posts: 22,128
  • Toronto, Canada
    • View Profile
Re: Alternative to Solidify (Premultiply Alpha)
« Reply #4 on: June 11, 2013, 01:15:22 PM »
Pre-multiplied alpha approach doesn't exhibit the same issues as alpha-based, and is supposedly also faster on some mobile devices. I used it in Starlink just to be safe, which is why I added the option to the atlas maker.

To use the pre multiplied alpha, simply select the "Unlit/Premultiplied Colored" shader instead of "Unlit/Transparent Colored".

jeldrez

  • Sr. Member
  • ****
  • Thank You
  • -Given: 8
  • -Receive: 4
  • Posts: 352
    • View Profile
Re: Alternative to Solidify (Premultiply Alpha)
« Reply #5 on: June 11, 2013, 03:58:05 PM »
Thanks Aren!

YourUncleBob

  • Newbie
  • *
  • Thank You
  • -Given: 0
  • -Receive: 0
  • Posts: 4
    • View Profile
Re: Alternative to Solidify (Premultiply Alpha)
« Reply #6 on: July 08, 2013, 07:01:34 PM »
>>
>> which is why I added the option to the atlas maker.
>>
Does the atlas maker have any sort of premultiply support? All the widgets support adjusting their colors to correctly work with a premultiplied shader, but as far as I can see the atlas maker doesn't do anything different when a premultiply shader is used.

We added support for this to our local copy of NGUI and I think it would be worth adding as an option to the real version. We changed the atlas maker and texture packer to perform a premultiply on textures when adding them to the atlas. To better support this we also export the atlas as a TGA file rather than a PNG (I've seen different PNG readers/writers do weird things to the foreground color of pixels with 0 alpha, where everything seems to leave TGA files alone). We also fudge in something so that any texture with _Add in its name will be treated as additive (all its alphas will be 0).

It's an easy addition and saves artists from having to figure out how to create premultiplied art.

ArenMook

  • Administrator
  • Hero Member
  • *****
  • Thank You
  • -Given: 337
  • -Receive: 1171
  • Posts: 22,128
  • Toronto, Canada
    • View Profile
Re: Alternative to Solidify (Premultiply Alpha)
« Reply #7 on: July 08, 2013, 11:22:56 PM »
"Use PMA shader" is an option in atlas maker. It automatically multiplies RGB by alpha when adding sprites. If you don't see it, then your NGUI is out of date.