Wayback Machinekoobas.hobune.stream
May JUN Jul
Previous capture 13 Next capture
2021 2022 2023
1 capture
13 Jun 22 - 13 Jun 22
sparklines
Close Help
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
  • Asset Store
  • Get Unity

UNITY ACCOUNT

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account
  • Blog
  • Forums
  • Answers
  • Evangelists
  • User Groups
  • Beta Program
  • Advisory Panel

Navigation

  • Home
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
    • Blog
    • Forums
    • Answers
    • Evangelists
    • User Groups
    • Beta Program
    • Advisory Panel

Unity account

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account

Language

  • Chinese
  • Spanish
  • Japanese
  • Korean
  • Portuguese
  • Ask a question
  • Spaces
    • Default
    • Help Room
    • META
    • Moderators
    • Topics
    • Questions
    • Users
    • Badges
  • Home /
avatar image
6
Question by Braithy85 · Dec 02, 2014 at 02:46 PM · guishader4.6

Custom shader with Unity 4.6 UI Canvas Group Alpha problem

I'm currently using a custom shader on some UI elements in my game. I'm getting the results I want, however I'm using a Canvas Group component on the parent element whose Alpha value isn't affecting my material as I'd expect.

Is there anything special I should be doing to to let this happen?

Comment
Add comment
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users

4 Replies

· Add your reply
  • Sort: 
avatar image
8
Best Answer

Answer by Braithy85 · Dec 17, 2014 at 10:52 AM

After comparing it to their UI/Default shader I fixed it by sending the vertex colour through to the fragment shader. This alpha seems to be affected by the group canvas alpha

Comment
Add comment · Show 2 · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image menehune23 · Nov 22, 2015 at 10:38 PM 0
Share

Would you $$anonymous$$d posting some code for this? I'm hitting the same situation. Thanks!

avatar image mw_rgeorge · Mar 23, 2016 at 11:17 PM 1
Share

@menehune23: I posted a more detailed answer that is pending moderator approval. If it gets through, check it out!

avatar image
12

Answer by mw_rgeorge · Mar 23, 2016 at 11:45 PM

I'm going to go into detail on what @Braithy85 is talking about:

CanvasGroup dictates transparency using the alpha in the vertex color. What that means is that your shader needs to find and pass on the vertex color to the fragment shader, and the fragment shader should take the vertex color's alpha into account when figuring out the color.

Here's a shader I hacked together to fade all pixels in a texture to a certain tint (2D only, ignores lighting):

 Shader "Sprites/Flash (Preserve Alpha)"
 {
     Properties
     {
         [PerRendererData] _MainTex ("Sprite Texture", 2D) = "white" {}
         _FlashAmount ("Flash Amount",Range(0.0,1.0)) = 0.0
         _Color ("Tint", Color) = (1,1,1,1)
     }
 
     SubShader
     {
         Tags
         { 
             "Queue"="Transparent" 
             "IgnoreProjector"="True" 
             "RenderType"="Transparent" 
             "PreviewType"="Plane"
             "CanUseSpriteAtlas"="True"
         }
         Pass {
 
             Cull Off
             Lighting Off
             ZWrite Off
             ZTest [unity_GUIZTestMode]
             Fog { Mode Off }
             Blend SrcAlpha OneMinusSrcAlpha
 
             CGPROGRAM
     //        #pragma target 2.0              //Run this shader on at least Shader Model 2.0 hardware (e.g. Direct3D 9)
             #pragma vertex vert_img_cust    //The vertex shader is named 'vert'
             #pragma fragment frag           //The fragment shader is named 'frag'
             #include "UnityCG.cginc"        //Include Unity's predefined inputs and macros
 
             sampler2D _MainTex;
             fixed4 _Color;
             float _FlashAmount,_SelfIllum;
             
             struct v_in {
                 float4 vertex : POSITION;
                 half2 texcoord : TEXCOORD0;
                 float4 color : COLOR;
             };
             
             struct Input
             {
                 float2 uv_MainTex;
                 fixed4 color;
             };
             
             struct v2f_img_vert_color {
                 float4 pos : SV_POSITION;
                 half2 uv : TEXCOORD0;
                 float4 diff : COLOR0;
             };
             
             v2f_img_vert_color vert_img_cust( v_in v )
             {
                 v2f_img_vert_color o;
                 o.pos = mul (UNITY_MATRIX_MVP, v.vertex);
                 o.uv = v.texcoord;
                 o.diff =  v.color;
                 return o;
             }
 
             fixed4 frag(v2f_img_vert_color IN) : COLOR {
                 fixed4 c = tex2D(_MainTex, IN.uv);
                 float3 rgbLerped = lerp(c.rgb, _Color, _FlashAmount);
                 return (rgbLerped[0], rgbLerped[1], rgbLerped[2], IN.diff.a * c.a);
             }
             ENDCG
         }
     }
 }
 

Let's break down what's going on:

The most important part of the tags above for alpha is the

 Blend SrcAlpha OneMinusSrcAlpha

which takes the alpha value and treats it like you'd expect (more on that here).

My vertex shader is exactly Unity's vert_img shader, but also passes down the vertex color.

             struct v_in {
                 float4 vertex : POSITION;
                 half2 texcoord : TEXCOORD0;
                 float4 color : COLOR;
             };
             
             v2f_img_vert_color vert_img_cust( v_in v )
             {
                 v2f_img_vert_color o;
                 o.pos = mul (UNITY_MATRIX_MVP, v.vertex);
                 o.uv = v.texcoord;
                 o.diff =  v.color;
                 return o;
             }

To see what I'm talking about, google "UnityCG.cginc source location" to see the code. All this shader does is get the position of the object (not used in my fragment shader), the texture coordinates, and grabs the vertex color from the input vertex struct (by instructing the input struct to get it it using the : COLOR0 semantic). If you're wondering what else you can grab from the vertex input, go here for a full specification (appdata specifies the app->vertex shader).

Finally, let's talk about the fragment shader:

             struct v2f_img_vert_color {
                 float4 pos : SV_POSITION;
                 half2 uv : TEXCOORD0;
                 float4 diff : COLOR0;
             };
 
             fixed4 frag(v2f_img_vert_color IN) : COLOR {
                 fixed4 c = tex2D(_MainTex, IN.uv);
                 float3 rgbLerped = lerp(c.rgb, _Color, _FlashAmount);
                 return (rgbLerped[0], rgbLerped[1], rgbLerped[2], IN.diff.a * c.a);
             }

The fragment shader takes in a v2f_img_vert_color struct (defined above), and spits out the fragment color. The important thing to notice here is the last member of the fixed4 being returned:

 return (rgbLerped[0], rgbLerped[1], rgbLerped[2], IN.diff.a * c.a);

This is just an RGBA value (what you'd expect a fragment shader to return). But there's now a calculation for the alpha component!

IN.diff.a x c.a is the multiplication of the vertex's alpha value with the texture pixel's original alpha value. Why do this? This preserves transparency in the texture while also applying the vertex's alpha to the color.

Think of it like this: You WANT the alpha in the original image to show through, but you also want to scale it relative to what the vertex's alpha currently is. So if the original image has an alpha value for a pixel of 50% opacity, but your vertex is at 25% opacity, the final opacity of that pixel should be 50% * 25% = 12.5%.

Comment
Add comment · Show 2 · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image Visuallization · May 27, 2018 at 01:44 PM 0
Share

nice thank you for the detailed explanation, worked like a charm. :)

avatar image Pookzob · Aug 26, 2018 at 07:23 PM 0
Share

It's rare to find gems like this. Extremely well written and broken down answer. I felt like I got a perfect ELI5 answer when I was expecting to find something much off topic to dig out a goodie from. Thank you immensely, sir!

I'd give rep if I had any.

avatar image
1

Answer by gabrieloc · Jul 25, 2021 at 01:08 AM

FYI For anyone trying to apply @Braithy85's solution to Shader Graph, there's a Vertex Color node you can split alpha from and multiply/send to the alpha of your master node.

Comment
Add comment · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image
0

Answer by ModernWestern · Feb 01, 2021 at 05:21 PM

5 years later @mw_rgeorge answer is still gold and easy to understand, even for the ones who use shader graph like me.

Comment
Add comment · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users

Your answer

Hint: You can notify a user about this post by typing @username

Up to 2 attachments (including images) can be used with a maximum of 524.3 kB each and 1.0 MB total.

Follow this Question

Answers Answers and Comments

8 People are following this question.

avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image

Related Questions

Unity 4.6B UI Scrollbar Usage 1 Answer

When I pause my game and enable canvas and then resume my keyboard starts controlling the menu... 1 Answer

New GUI - nomenclature of blueprint (b) vs Raw (R) 0 Answers

How to have no alignment 4.6 GUI 0 Answers

Pro Glow showing through GUI layer 0 Answers


Enterprise
Social Q&A

Social
Subscribe on YouTube social-youtube Follow on LinkedIn social-linkedin Follow on Twitter social-twitter Follow on Facebook social-facebook Follow on Instagram social-instagram

Footer

  • Purchase
    • Products
    • Subscription
    • Asset Store
    • Unity Gear
    • Resellers
  • Education
    • Students
    • Educators
    • Certification
    • Learn
    • Center of Excellence
  • Download
    • Unity
    • Beta Program
  • Unity Labs
    • Labs
    • Publications
  • Resources
    • Learn platform
    • Community
    • Documentation
    • Unity QA
    • FAQ
    • Services Status
    • Connect
  • About Unity
    • About Us
    • Blog
    • Events
    • Careers
    • Contact
    • Press
    • Partners
    • Affiliates
    • Security
Copyright © 2020 Unity Technologies
  • Legal
  • Privacy Policy
  • Cookies
  • Do Not Sell My Personal Information
  • Cookies Settings
"Unity", Unity logos, and other Unity trademarks are trademarks or registered trademarks of Unity Technologies or its affiliates in the U.S. and elsewhere (more info here). Other names or brands are trademarks of their respective owners.
  • Anonymous
  • Sign in
  • Create
  • Ask a question
  • Spaces
  • Default
  • Help Room
  • META
  • Moderators
  • Explore
  • Topics
  • Questions
  • Users
  • Badges