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
1
Question by Jacksmack · Jun 30, 2014 at 09:09 AM · shadersalphatoontransparancy

How can I get Transparency into the Unity Toon Lighted Outline Shader?

I have been trying to figure out how to work shaders and I'm stumped. Does anyone have a modified version of the Basic Toon Lighted Outline shader that I can fade out over time? I would even take a cutout shader.

Bonus points if you can tell me how to modify it myself, I do want to learn this but I've spent all day trying and failing on it.

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

2 Replies

· Add your reply
  • Sort: 
avatar image
3

Answer by CHPedersen · Jun 30, 2014 at 10:29 AM

This is, thankfully, pretty easy. But it's going to involve a lot of code to explain what's going on. :) Ready? Brace yourself, it's mostly copy-pasted.

First off, let's start from the basic toon outline shader's source code, which looks like this:

 Shader "Toon/Basic Outline" {
     Properties {
         _Color ("Main Color", Color) = (.5,.5,.5,1)
         _OutlineColor ("Outline Color", Color) = (0,0,0,1)
         _Outline ("Outline width", Range (.002, 0.03)) = .005
         _MainTex ("Base (RGB)", 2D) = "white" { }
         _ToonShade ("ToonShader Cubemap(RGB)", CUBE) = "" { Texgen CubeNormal }
     }
 
 CGINCLUDE
 #include "UnityCG.cginc"
 
 struct appdata {
     float4 vertex : POSITION;
     float3 normal : NORMAL;
 };

 struct v2f {
     float4 pos : POSITION;
     float4 color : COLOR;
 };
 
 uniform float _Outline;
 uniform float4 _OutlineColor;
 
 v2f vert(appdata v) {
     v2f o;
     o.pos = mul(UNITY_MATRIX_MVP, v.vertex);

     float3 norm   = mul ((float3x3)UNITY_MATRIX_IT_MV, v.normal);
     float2 offset = TransformViewToProjection(norm.xy);

     o.pos.xy += offset * o.pos.z * _Outline;
     o.color = _OutlineColor;
     return o;
 }
 ENDCG

 SubShader {
     Tags { "RenderType"="Opaque" }
     UsePass "Toon/Basic/BASE"
     Pass {
         Name "OUTLINE"
         Tags { "LightMode" = "Always" }
         Cull Front
         ZWrite On
         ColorMask RGB
         Blend SrcAlpha OneMinusSrcAlpha

         CGPROGRAM
         #pragma vertex vert
         #pragma fragment frag
         half4 frag(v2f i) :COLOR { return i.color; }
         ENDCG
     }
 }
 
 SubShader {
     Tags { "RenderType"="Opaque" }
     UsePass "Toon/Basic/BASE"
     Pass {
         Name "OUTLINE"
         Tags { "LightMode" = "Always" }
         Cull Front
         ZWrite On
         ColorMask RGB
         Blend SrcAlpha OneMinusSrcAlpha

         CGPROGRAM
         #pragma vertex vert
         #pragma exclude_renderers shaderonly
         ENDCG
         SetTexture [_MainTex] { combine primary }
     }
 }
 
 Fallback "Toon/Basic"

}

Now, you just want to make this transparent. There are several things you'll want to change, but they're all simple, and more a matter of configuring the shader than it's a matter of doing any kind of new calculation, actually.

The first thing is to observe that the shader contains two sub-shaders. It will choose between them at runtime based on the machine it's running on, so you'll need to configure both. Secondly, notice that both subshaders have a Tags block, which contains a RenderType. Leave the RenderType, it's only relevant for replacement shading. But you do need to add "Queue"="Transparent" to the tags in order to tell Unity to move the shader to the render order's Transparent queue. So both Tags blocks should be changed to:

Tags { "RenderType"="Opaque" "Queue"="Transparent" }

Now, the next crucial thing to observe is that the Toon/Basic Outline shader uses a pass from the regular basic toon shader. That's what this line means:

UsePass "Toon/Basic/BASE"

That pass is defined in the regular Toon Basic shader, and the source code of that shader looks like this:

 Shader "Toon/Basic" {
     Properties {
         _Color ("Main Color", Color) = (.5,.5,.5,1)
         _MainTex ("Base (RGB)", 2D) = "white" {}
         _ToonShade ("ToonShader Cubemap(RGB)", CUBE) = "" { Texgen CubeNormal }
     }
 
 
     SubShader {
         Tags { "RenderType"="Opaque" }
         Pass {
             Name "BASE"
             Cull Off
             
             CGPROGRAM
             #pragma vertex vert
             #pragma fragment frag
             #pragma fragmentoption ARB_precision_hint_fastest 
 
             #include "UnityCG.cginc"
 
             sampler2D _MainTex;
             samplerCUBE _ToonShade;
             float4 _MainTex_ST;
             float4 _Color;
 
             struct appdata {
                 float4 vertex : POSITION;
                 float2 texcoord : TEXCOORD0;
                 float3 normal : NORMAL;
             };
             
             struct v2f {
                 float4 pos : POSITION;
                 float2 texcoord : TEXCOORD0;
                 float3 cubenormal : TEXCOORD1;
             };
 
             v2f vert (appdata v)
             {
                 v2f o;
                 o.pos = mul (UNITY_MATRIX_MVP, v.vertex);
                 o.texcoord = TRANSFORM_TEX(v.texcoord, _MainTex);
                 o.cubenormal = mul (UNITY_MATRIX_MV, float4(v.normal,0));
                 return o;
             }
 
             float4 frag (v2f i) : COLOR
             {
                 float4 col = _Color * tex2D(_MainTex, i.texcoord);
                 float4 cube = texCUBE(_ToonShade, i.cubenormal);
                 return float4(2.0f * cube.rgb * col.rgb, col.a);
             }
             ENDCG            
         }
     } 
 
     SubShader {
         Tags { "RenderType"="Opaque" }
         Pass {
             Name "BASE"
             Cull Off
             SetTexture [_MainTex] {
                 constantColor [_Color]
                 Combine texture * constant
             } 
             SetTexture [_ToonShade] {
                 combine texture * previous DOUBLE, previous
             }
         }
     } 
     
     Fallback "VertexLit"
 }

It's defining the name of its pass using this line of code:

Name "BASE"

That's what enables its pass to be callable from within the outline version. So, this means we have to also modify the basic toon shader to be transparent, such that the pass used in the outline version will draw something transparent. So, add "Queue"="Transparent" to the basic toon shader, too. The basic toon shader does not have blending enabled, either, so you have to tell it to alphablend with the background. This line of code does that:

Blend SrcAlpha OneMinusSrcAlpha

That's it. In order to preserve the original Basic Toon shader and the original Basic Toon Outline, I created two new shaders by copy-pasting these two shaders' code in, and then did the modifications there, including slight renaming. As a result, this is the modified basic one:

 Shader "Toon/Basic-Alpha" {
     Properties {
         _Color ("Main Color", Color) = (.5,.5,.5,1)
         _MainTex ("Base (RGB)", 2D) = "white" {}
         _ToonShade ("ToonShader Cubemap(RGB)", CUBE) = "" { Texgen CubeNormal }
     }

 SubShader {
     Tags { "RenderType"="Opaque" "Queue"="Transparent" }
     Pass {
         Name "BASE"
         Blend SrcAlpha OneMinusSrcAlpha

         CGPROGRAM
         #pragma vertex vert
         #pragma fragment frag
         #pragma fragmentoption ARB_precision_hint_fastest 

         #include "UnityCG.cginc"

         sampler2D _MainTex;
         samplerCUBE _ToonShade;
         float4 _MainTex_ST;
         float4 _Color;

         struct appdata {
             float4 vertex : POSITION;
             float2 texcoord : TEXCOORD0;
             float3 normal : NORMAL;
         };
         
         struct v2f {
             float4 pos : POSITION;
             float2 texcoord : TEXCOORD0;
             float3 cubenormal : TEXCOORD1;
         };

         v2f vert (appdata v)
         {
             v2f o;
             o.pos = mul (UNITY_MATRIX_MVP, v.vertex);
             o.texcoord = TRANSFORM_TEX(v.texcoord, _MainTex);
             o.cubenormal = mul (UNITY_MATRIX_MV, float4(v.normal,0));
             return o;
         }

         float4 frag (v2f i) : COLOR
         {
             float4 col = _Color * tex2D(_MainTex, i.texcoord);
             float4 cube = texCUBE(_ToonShade, i.cubenormal);
             return float4(2.0f * cube.rgb * col.rgb, col.a);
         }
         ENDCG            
     }
 } 

 SubShader {
     Tags { "RenderType"="Opaque" "Queue"="Transparent"}
     Pass {
         Name "BASE"
         SetTexture [_MainTex] {
             constantColor [_Color]
             Combine texture * constant
         } 
         SetTexture [_ToonShade] {
             combine texture * previous DOUBLE, previous
         }
     }
 } 
 
 Fallback "VertexLit"

}

And this is the modified outline one (notice the name changes):

 Shader "Toon/Basic Outline-Alpha" {
     Properties {
         _Color ("Main Color", Color) = (.5,.5,.5,1)
         _OutlineColor ("Outline Color", Color) = (0,0,0,1)
         _Outline ("Outline width", Range (.002, 0.03)) = .005
         _MainTex ("Base (RGB)", 2D) = "white" { }
         _ToonShade ("ToonShader Cubemap(RGB)", CUBE) = "" { Texgen CubeNormal }
     }
 
 CGINCLUDE
 #include "UnityCG.cginc"
 
 struct appdata {
     float4 vertex : POSITION;
     float3 normal : NORMAL;
 };

 struct v2f {
     float4 pos : POSITION;
     float4 color : COLOR;
 };
 
 uniform float _Outline;
 uniform float4 _OutlineColor;
 
 v2f vert(appdata v) {
     v2f o;
     o.pos = mul(UNITY_MATRIX_MVP, v.vertex);

     float3 norm   = mul ((float3x3)UNITY_MATRIX_IT_MV, v.normal);
     float2 offset = TransformViewToProjection(norm.xy);

     o.pos.xy += offset * o.pos.z * _Outline;
     o.color = _OutlineColor;
     return o;
 }
 ENDCG

 SubShader {
     Tags { "RenderType"="Opaque" "Queue"="Transparent" }
     UsePass "Toon/Basic-Alpha/BASE"
     Pass {
         Name "OUTLINE"
         Tags { "LightMode" = "Always" }
         Cull Front
         ZWrite On
         ColorMask RGB
         Blend SrcAlpha OneMinusSrcAlpha

         CGPROGRAM
         #pragma vertex vert
         #pragma fragment frag
         half4 frag(v2f i) :COLOR { return i.color; }
         ENDCG
     }
 }
 
 SubShader {
     Tags { "RenderType"="Opaque" "Queue"="Transparent"}
     UsePass "Toon/Basic-Alpha/BASE"
     Pass {
         Name "OUTLINE"
         Tags { "LightMode" = "Always" }
         Cull Front
         ZWrite On
         ColorMask RGB
         Blend SrcAlpha OneMinusSrcAlpha

         CGPROGRAM
         #pragma vertex vert
         #pragma exclude_renderers shaderonly
         ENDCG
         SetTexture [_MainTex] { combine primary }
     }
 }
 
 Fallback "Toon/Basic"

}

Together, they render something that looks like this:

Alpha toony

That should accomplish what you want. Notice that the alpha is defined by the alpha channel of the colors it's already using. So, since there's one color for the main color and another for the outline color, it's possible for those two to have two different levels of transparency.


alphatoony.png (16.1 kB)
Comment
Add comment · Show 5 · 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 CHPedersen · Jul 01, 2014 at 11:35 AM 0
Share

It just occurred to me that changing the Color$$anonymous$$ask to RGBA shouldn't be necessary anyway, because the blending operation I used doesn't use the destination alpha, so there's no reason to write it to the buffer. I've updated my reply to reflect that. :)

avatar image Jacksmack · Jul 03, 2014 at 05:00 AM 0
Share

Very nicely done! I've been stumped on this for a while now. Thank you for taking the time to explain it as well. Now I need to figure out how to get it to be lit. Shouldn't be to hard hopefully. I'm a complete noob at this stuff.

avatar image CHPedersen · Jul 08, 2014 at 12:02 PM 0
Share

That's going to be slightly more involved, because the pass that draws the toony part consists of an old school pair of vertex/fragment shaders, so it isn't just a matter of declaring lighting function like one would with a surface shader, or writing "Lighting On" or whatever they do with that high level shaderlab code.

But you can find plenty of examples on shaders in general here, and on Surface Shaders in particular here.

If you feel this answer helped you, please consider marking it correct. :)

avatar image zarzarkel · Aug 07, 2015 at 12:05 PM 0
Share

Thanks! You saved my day! ;).

avatar image AlfieBooth · Jul 02, 2016 at 06:12 AM 0
Share

I know this is from a good while ago, but I just wanted to let you know this helped me out A LOT. Thank you for the detailed description.

avatar image
0

Answer by PhaetonLT · Dec 05, 2018 at 12:56 PM

Same here, very thankful for the explanation

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

7 People are following this question.

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

Related Questions

Multiply Shader with Alpha 0 Answers

Shader Help? Need an Alpha Test, then a "set pixel" sort of command 1 Answer

How to adjust alpha color of particle system main module during runtime (shuriken)? 1 Answer

Shadows with Alpha, fade out shadow. 2 Answers

How to move alpha mask along the floor plane as the user (camera) moves 1 Answer


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