Wayback Machinekoobas.hobune.stream
May JUN Jul
Previous capture 12 Next capture
2021 2022 2023
1 capture
12 Jun 22 - 12 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 /
  • Help Room /
avatar image
1
Question by Simon-Silva · Jun 09, 2019 at 10:13 PM · shadertoonshadingcel shading

Help with adding alpha cutout to toon shader.

so, I've recently gotten a project in university to make a game, in my group I'm the 3d artist, so im making all of the 3d models, textures, animations etc.. but i'm also responsible in making the shader for the game, i followed a pretty nice tutorial to this point, but as someone who really doesn't know what he's doing i need some help in adding a alpha cut out to my shader, we have a lot of foliage and assets using alphas so any help is appreciated !

the tutorial I'm following : https://roystan.net/articles/toon-shader.html

I'm using unity version 2018.3.14f1

 Shader "Test/Toon"
 {
     Properties
     {
         _Color("Color", Color) = (1,1,1,1)
         _MainTex("Main Texture", 2D) = "white" {}
     
     [HDR]
     _AmbientColor("Ambient Color", Color) = (0.4,0.4,0.4,1)
         [HDR]
     _SpecularColor("Specular Color", Color) = (0.9,0.9,0.9,1)
         
         _Glossiness("Glossiness", Float) = 32
         [HDR]
     _RimColor("Rim Color", Color) = (1,1,1,1)
         _RimAmount("Rim Amount", Range(0, 1)) = 0.716
         
         _RimThreshold("Rim Threshold", Range(0, 1)) = 0.1
     }
         SubShader
     {
         Pass
     {
     
         Tags
     {
         "LightMode" = "ForwardBase"
         "PassFlags" = "OnlyDirectional"
     }
 
         CGPROGRAM
 #pragma vertex vert
 #pragma fragment frag
         
 #pragma multi_compile_fwdbase
 
 #include "UnityCG.cginc"
 
 #include "Lighting.cginc"
 #include "AutoLight.cginc"
 
         struct appdata
     {
         float4 vertex : POSITION;
         float4 uv : TEXCOORD0;
         float3 normal : NORMAL;
     };
 
     struct v2f
     {
         float4 pos : SV_POSITION;
         float3 worldNormal : NORMAL;
         float2 uv : TEXCOORD0;
         float3 viewDir : TEXCOORD1;
     
         SHADOW_COORDS(2)
     };
 
     sampler2D _MainTex;
     float4 _MainTex_ST;
 
     v2f vert(appdata v)
     {
         v2f o;
         o.pos = UnityObjectToClipPos(v.vertex);
         o.worldNormal = UnityObjectToWorldNormal(v.normal);
         o.viewDir = WorldSpaceViewDir(v.vertex);
         o.uv = TRANSFORM_TEX(v.uv, _MainTex);
 
         TRANSFER_SHADOW(o)
             return o;
     }
 
     float4 _Color;
 
     float4 _AmbientColor;
 
     float4 _SpecularColor;
     float _Glossiness;
 
     float4 _RimColor;
     float _RimAmount;
     float _RimThreshold;
 
     float4 frag(v2f i) : SV_Target
     {
         float3 normal = normalize(i.worldNormal);
         float3 viewDir = normalize(i.viewDir);
 
         float NdotL = dot(_WorldSpaceLightPos0, normal);
 
         float shadow = SHADOW_ATTENUATION(i);
     
         float lightIntensity = smoothstep(0, 0.01, NdotL * shadow);
         
         float4 light = lightIntensity * _LightColor0;
 
         float3 halfVector = normalize(_WorldSpaceLightPos0 + viewDir);
         float NdotH = dot(normal, halfVector);
         
         float specularIntensity = pow(NdotH * lightIntensity, _Glossiness * _Glossiness);
         float specularIntensitySmooth = smoothstep(0.005, 0.01, specularIntensity);
         float4 specular = specularIntensitySmooth * _SpecularColor;
 
 
         float rimDot = 1 - dot(viewDir, normal);
 
         float rimIntensity = rimDot * pow(NdotL, _RimThreshold);
         rimIntensity = smoothstep(_RimAmount - 0.01, _RimAmount + 0.01, rimIntensity);
         float4 rim = rimIntensity * _RimColor;
 
         float4 sample = tex2D(_MainTex, i.uv);
 
         return (light + _AmbientColor + specular + rim) * _Color * sample;
     }
         ENDCG
     }
 

         UsePass "Legacy Shaders/VertexLit/SHADOWCASTER"
     }
 }

Also how could i add double facing to this shader ? since most of these assets are 1 polygon only....

Thank you for the help in advance!

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

1 Reply

· Add your reply
  • Sort: 
avatar image
3

Answer by Namey5 · Jun 16, 2019 at 11:41 AM

This question isn't the most complicated to answer, but seeing as it has multiple parts at various places throughout the shader, I figured I would go through and add them for you. I've left comments wherever I've added/modified things that also explain what the changes do. The shadowcaster pass was the most complicated, but that's simply because there's no documentation, so you can't really learn how they work without dissecting Unity's internal shaders (I did that liberty for you a while ago, so I already knew how they worked).

 Shader "Test/Toon"
 {
     Properties
     {
         _Color("Color", Color) = (1,1,1,1)
         _MainTex("Main Texture", 2D) = "white" {}
      
         [HDR]
         _AmbientColor("Ambient Color", Color) = (0.4,0.4,0.4,1)
         [HDR]
         _SpecularColor("Specular Color", Color) = (0.9,0.9,0.9,1)
          
         _Glossiness("Glossiness", Float) = 32
         [HDR]
         _RimColor("Rim Color", Color) = (1,1,1,1)
         _RimAmount("Rim Amount", Range(0, 1)) = 0.716
          
         _RimThreshold("Rim Threshold", Range(0, 1)) = 0.1
 
         //How far along we want to clip pixels
         _AlphaThreshold ("Alpha Cutoff", Range(0,1)) = 0.5
     }
     SubShader
     {
         Pass
         {
             Tags { "LightMode" = "ForwardBase" "PassFlags" = "OnlyDirectional" }
 
             //This makes the shader double sided, but we will need to make some 
             //vertex shader adjustments so that both sides look right
             Cull Off
  
             CGPROGRAM
             #pragma vertex vert
             #pragma fragment frag
          
             #pragma multi_compile_fwdbase
  
             #include "UnityCG.cginc"
  
             #include "Lighting.cginc"
             #include "AutoLight.cginc"
  
             struct appdata
             {
                 float4 vertex : POSITION;
                 float4 uv : TEXCOORD0;
                 float3 normal : NORMAL;
             };
  
             struct v2f
             {
                 float4 pos : SV_POSITION;
                 float3 worldNormal : NORMAL;
                 float2 uv : TEXCOORD0;
                 float3 viewDir : TEXCOORD1;
      
                 SHADOW_COORDS(2)
             };
  
             sampler2D _MainTex;
             float4 _MainTex_ST;
  
             v2f vert(appdata v)
             {
                 v2f o;
                 o.pos = UnityObjectToClipPos(v.vertex);
                 o.worldNormal = UnityObjectToWorldNormal(v.normal);
                 o.viewDir = WorldSpaceViewDir(v.vertex);
                 o.uv = TRANSFORM_TEX(v.uv, _MainTex);
                 
                 //This makes sure that the normals are facing the right way on both sides of the object
                 o.worldNormal *= lerp (1.0, -1.0, dot (o.viewDir, o.worldNormal) < 0.0);
 
                 TRANSFER_SHADOW(o)
                 return o;
             }
  
             float4 _Color;
  
             float4 _AmbientColor;
  
             float4 _SpecularColor;
             float _Glossiness;
  
             float4 _RimColor;
             float _RimAmount;
             float _RimThreshold;
 
             //Also declare down here
             half _AlphaThreshold;
  
             float4 frag(v2f i) : SV_Target
             {
                 //Move the texture sample up here
                 float4 sample = tex2D(_MainTex, i.uv);
 
                 //Check if our alpha is lower than the threshold;
                 //If it is, then discard this pixel and return early.
                 if (sample.a < _AlphaThreshold)
                 {
                     discard;
                     return 0;
                 }
 
                 float3 normal = normalize(i.worldNormal);
                 float3 viewDir = normalize(i.viewDir);
  
                 float NdotL = dot(_WorldSpaceLightPos0, normal);
  
                 float shadow = SHADOW_ATTENUATION(i);
      
                 float lightIntensity = smoothstep(0, 0.01, NdotL * shadow);
          
                 float4 light = lightIntensity * _LightColor0;
  
                 float3 halfVector = normalize(_WorldSpaceLightPos0 + viewDir);
                 float NdotH = dot(normal, halfVector);
         
                 float specularIntensity = pow(NdotH * lightIntensity, _Glossiness * _Glossiness);
                 float specularIntensitySmooth = smoothstep(0.005, 0.01, specularIntensity);
                 float4 specular = specularIntensitySmooth * _SpecularColor;
  
  
                 float rimDot = 1 - dot(viewDir, normal);
  
                 float rimIntensity = rimDot * pow(NdotL, _RimThreshold);
                 rimIntensity = smoothstep(_RimAmount - 0.01, _RimAmount + 0.01, rimIntensity);
                 float4 rim = rimIntensity * _RimColor;
  
                 return (light + _AmbientColor + specular + rim) * _Color * sample;
             }
             ENDCG
         }
 
         //We will have to use our own shadowcaster pass now that we are discarding pixels
         //UsePass "Legacy Shaders/VertexLit/SHADOWCASTER"
 
         //Don't worry too much about this pass; shadowcaster passes are completely undocumented in Unity, 
         //but it basically just renders the bare minimum so that the shadow functions can see the object as it is in the scene
         Pass
         {
             Name "ShadowCaster"
             Tags { "LightMode" = "ShadowCaster" }
 
             Cull Off
 
             CGPROGRAM
             #pragma vertex vert
             #pragma fragment frag
             #pragma target 2.0
             #pragma multi_compile_shadowcaster
             #pragma multi_compile_instancing // allow instanced shadow pass for most of the shaders
 
             struct appdata
             {
                 float4 vertex : POSITION;
                 float2 uv : TEXCOORD0;
             };
 
             struct v2f
             {
                 float4 pos : SV_POSITION;
                 float2 uv : TEXCOORD0;
             };
 
             sampler2D _MainTex;
             float4 _MainTex_ST;
 
             half _AlphaThreshold;
 
             v2f vert (appdata v)
             {
                 v2f o;
                 o.pos = UnityObjectToClipPos (v.vertex);
                 o.uv = (v.uv * _MainTex_ST.xy) + _MainTex_ST.zw;
                 return o;
             }
 
             float4 frag (v2f i) : SV_Target
             {
                 float a = tex2D (_MainTex, i.uv).a;
                 if (a < _AlphaThreshold)
                     discard;
 
                 return 0;
             }
             ENDCG
         }
     }
 }

Good luck with the project.

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

241 People are following this question.

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

Related Questions

Toon Shader rendering backfaces black instead of transparent 0 Answers

Does Unity Plus allow you to use shaders that unity gives (example, the toon shader), or full screen effects? 1 Answer

Is it possible cel shade an objects lighting through the shader graph? 0 Answers

How can I ToonLitOutline shader transparent? 0 Answers

i want to modify toon outline shader. 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