- Home /
 
CG Shader: Setting output alpha changes RGB too
I have a shader that very nearly works, except for the final alpha setting in the fragment func. I'm trying to use the colour from one texture+UV and the alpha from another texture+UV. It works perfectly if I take the modified alpha and stick it in one of the colour channels (ie. it modifies the colour channel in exactly the way I want to modify the alpha channel)...but if I actually apply it to the alpha channel, the shader reverts to using the complete RGBA from MainTex, instead of the RGB from PaperTex.
I'm guessing I have some alpha setting wrong which confuses the shader compiler? Thanks for any suggestions!
 Shader "Custom/Paper Shader" {
     Properties
     {
         _MainTex ("Base (RGBA)", 2D) = "white" {}
         _PaperTex ("Paper (RGB)", 2D) = "white" {}
     }
     
     SubShader
     {
         Tags {"Queue"="Transparent" "RenderType"="Transparent"}
         Blend SrcAlpha OneMinusSrcAlpha
         AlphaTest GEqual 0.1    
         Pass
         {
             CGPROGRAM
             #pragma exclude_renderers ps3 xbox360 flash
             #pragma fragmentoption ARB_precision_hint_fastest
             #pragma vertex vert
             #pragma fragment frag
                   
             // uniforms
             uniform sampler2D _MainTex;
             uniform sampler2D _PaperTex; 
             uniform float4 _MainTex_ST;  //texture name + ST is needed to get the tiling/offset
             uniform float4 _PaperTex_ST;
             
             struct vertexInput
             {
                 float4 vertex : POSITION; 
                 float4 texcoord : TEXCOORD0;
             };
          
             struct fragmentInput
             {
                 float4 pos : SV_POSITION;
                 half2 uv : TEXCOORD0;
                 half2 uv2 : TEXCOORD1;
             };
          
             fragmentInput vert( vertexInput i )
             {
                 fragmentInput o;
                 o.pos = mul( UNITY_MATRIX_MVP, i.vertex );
                   o.uv = i.texcoord;
                 o.uv2 =  i.vertex.xy * _PaperTex_ST.xy + _PaperTex_ST.zw;    // xy is tiling and zw is offset
                 return o;
             }
          
             half4 frag( fragmentInput i ) : COLOR
             {
                 half alpha = tex2D( _MainTex, i.uv ).a;
                 half4 colour = tex2D( _PaperTex, i.uv2 );
                 colour.r = alpha; // This has correct effect on the red channel
                 //colour.a = alpha; // This makes the shader use _MainTex for RGBA
                 return colour;
             }
          
             ENDCG
         }
     }
     
     FallBack "Diffuse"
 }
 
 
              Seconds after posting, I've fixed it:
             half4 frag( fragmentInput i ) : COLOR
             {
                 half4 main = tex2D( _$$anonymous$$ainTex, i.uv );
                 half4 colour = tex2D( _PaperTex, i.uv2 );
                 colour.rgb *= main.rgb;
                 colour.a = main.a;
                 return colour;
             }
 
                  I always planned to multiply the colours together, so I thought I'd try it and see what happened. Works perfectly now.
I'd still love to know why the simpler case fails though. Seems to be an overzealous optimisation I$$anonymous$$HO, but if it's something I should be aware of, then please enlighten me!
One last guess: I put the alpha into a lone half, so the alignment didn't match and screwed up the swizzling?
Oh, and the source texture for PaperTex has no alpha channel. That probably didn't help :)
Your answer
 
             Follow this Question
Related Questions
Shader that renders fragment behind 0 Answers
Need help with this Shader; camera Solid color is being rendered on skybox. 0 Answers
Getting the world position of the pixel in the fragment shader. 1 Answer
custom Standard Shader alpha issues. 1 Answer
Find out if an object is in front of a target in fragment shader? 0 Answers