Search Unity

Premultiplied alpha shader generates white background inside OnGUI

Discussion in 'Shaders' started by genail, Jun 6, 2013.

  1. genail

    genail

    Joined:
    Jul 2, 2012
    Posts:
    1,045
    Hello,

    I'm trying to write shader for blending textures with alpha channel inside OnGUI() using Graphics.DrawTexture() with material parameter. No matter how hard I try I cannot get rid of half-transparent white background:


    On the left you see texture painted by Graphics.DrawTexture(). On the right is plane with the same material attached. Texture have premultiplied alpha channel with color components. Shader code looks like this:

    Code (csharp):
    1. Shader "Custom/PreAlphaShader" {
    2.     Properties {
    3.         _MainTex ("Base (RGB)", 2D) = "white" {}
    4.         _Color ("Color (RGB)", Color) = (1, 1, 1, 1)
    5.     }
    6.     SubShader {
    7.         Tags { "Queue"="Transparent" }
    8.         Blend One OneMinusSrcAlpha
    9.        
    10.         CGPROGRAM
    11.         #pragma surface surf Lambert
    12.  
    13.         sampler2D _MainTex;
    14.         fixed4 _Color;
    15.  
    16.         struct Input {
    17.             float2 uv_MainTex;
    18.         };
    19.        
    20.         void surf (Input IN, inout SurfaceOutput o) {
    21.             fixed4 c = tex2D(_MainTex, IN.uv_MainTex);
    22.            
    23.             o.Albedo = c.rgb * (fixed3) _Color;
    24.             o.Alpha = c.a * _Color.a;
    25.         }
    26.         ENDCG
    27.     }
    28.     FallBack "Diffuse"
    29. }
    30.  
    Also I'm attaching unity package with this shader, texture, material, and scene.
    I've tried to verify how source and destination component looks like using Blend Zero One and Blend One Zero and everything looks fine. What am I missing here?
     

    Attached Files:

  2. genail

    genail

    Joined:
    Jul 2, 2012
    Posts:
    1,045
    Solved!

    The reason was Lambert lighting. How I fixed it:

    Step 1) Define new lighting function in my shader:
    Code (csharp):
    1.         half4 LightingNoLighting (SurfaceOutput s, half3 lightDir, half atten) {
    2.             half4 c;
    3.             c.rgb = s.Albedo;
    4.             c.a = s.Alpha;
    5.             return c;
    6.         }
    Step 2) Change lighting to this defined in step 1:

    Code (csharp):
    1. #pragma surface surf NoLighting