Wayback Machinekoobas.hobune.stream
May JUN Jul
Previous capture 13 Next capture
2021 2022 2023
2 captures
13 Jun 22 - 14 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
0
Question by koobazaur · Mar 16, 2015 at 08:22 AM · shaderlightmapcartoon

Shader - different passes depending on Lightmap being set or not

I'm trying to implement custom cartoon shading but it needs to work differently for Lightmapped objects and non-lightmapped (i.e. apply ramp to lightmap texture vs. apply ramp to light itself).

How can I choose which pass gets used depending on whether the object has a lightmap set or not? I tried all the different tags (Tags { "RenderType" = "VertexLM" }) but they don't seem to work. I know I could just use 2 different shaders but I'd rather keep everything unified if possible (and I may want to might Lightmap + RT lighting as well).

I tried two approaches:

Here approach #1, using two different surface shaders (only one works at a time; I tried combining them into one but only one model works at a time due to the #pragma surface surf directive)


 Shader "K/Cartoon Lightmap2" 
 {
 Properties {
             _MainTex ("Texture", 2D) = "white" {}
             _Ramp("Ramp", 2D) = "white" {}   
         }
         SubShader {
             CGPROGRAM
 
             #pragma surface surf Standard
             sampler2D _Ramp;
 
             half4 LightingStandard (SurfaceOutput s, half3 lightDir, half atten) {
                 half NdotL = dot (s.Normal, lightDir);
                 half4 c; c.rgb = s.Albedo * _LightColor0.rgb * (NdotL * atten * 2);
                 c.a = s.Alpha;
                 
                 return c;
             }
 
             inline fixed4 LightingStandard_SingleLightmap (SurfaceOutput s, fixed4 color) {
                 half3 lm = DecodeLightmap (color);
                 //return fixed4(lm, 0);        
                  float lightmapAvg = (lm.r + lm.g + lm.b)/3.0;
                  
                   fixed4 ramp = tex2D(_Ramp, float2(lightmapAvg, 0));                
                 return ramp;        
                 
             }
 
             inline fixed4 LightingStandard_DualLightmap (SurfaceOutput s, fixed4 totalColor, fixed4 indirectOnlyColor, half indirectFade) {
                 half3 lm = lerp (DecodeLightmap (indirectOnlyColor), DecodeLightmap (totalColor), indirectFade);
                 return fixed4(lm, 0);
             }
 
             inline fixed4 LightingStandard_StandardLightmap (SurfaceOutput s, fixed4 color, fixed4 scale, bool surfFuncWritesNormal) {
                 UNITY_DIRBASIS
 
                 half3 lm = DecodeLightmap (color);
                 half3 scalePerBasisVector = DecodeLightmap (scale);
 
                 if (surfFuncWritesNormal)
                 {
                     half3 normalInRnmBasis = saturate (mul (unity_DirBasis, s.Normal));
                     lm *= dot (normalInRnmBasis, scalePerBasisVector);
                 }
 
                 return fixed4(lm, 0);
             }
 
             struct Input {
                 float2 uv_MainTex;
             };
             
             sampler2D _MainTex;
             
             void surf (Input IN, inout SurfaceOutput o) 
             {
                 o.Albedo = tex2D (_MainTex, IN.uv_MainTex).rgb;
             }
             ENDCG
             }
             
             
         SubShader {
             CGPROGRAM
             
             #pragma surface surf Ramp
             sampler2D _Ramp;
 
          half4 LightingRamp (SurfaceOutput s, half3 lightDir, half atten) {
                 half NdotL = dot (s.Normal, lightDir);
                 half diff = NdotL * 0.5 + 0.5;
                 half3 ramp = tex2D (_Ramp, float2(diff)).rgb;
                 half4 c;
                 c.rgb = s.Albedo * _LightColor0.rgb * ramp * (atten * 2);
                 c.a = s.Alpha;
                 
                 return c;
             }            
             
 
             struct Input {
                 float2 uv_MainTex;
             };
             
             sampler2D _MainTex;
             
             void surf (Input IN, inout SurfaceOutput o) 
             {
                 o.Albedo = tex2D (_MainTex, IN.uv_MainTex).rgb;
             }
             ENDCG
             }            
         Fallback "Diffuse"
 }



Here's approach #2 : Surface + multiplicative Lightmap pass (messes up on non-LM objects)


 Shader "K/Cartoon Lightmap" 
 {
  
   Properties 
   {
       _Color ("Main Color", Color) = (1,1,1,1)
     _MainTex ("Texture 1", 2D) = "white" {}
     _Ramp("Ramp", 2D) = "white" {}    
 }
  
   SubShader 
   {
         LOD 200
         Tags { "RenderType" = "Opaque" }
         CGPROGRAM
         #pragma surface surf Lambert
         struct Input {
           float2 uv_MainTex;
           float2 uv2_LightMap;
         };
         sampler2D _MainTex;
         sampler2D _LightMap;
         fixed4 _Color;
         void surf (Input IN, inout SurfaceOutput o)
         {
           o.Albedo = tex2D (_MainTex, IN.uv_MainTex).rgb * _Color;
           
         }
         ENDCG
  
     Pass {
       // Disable lighting, we're only using the lightmap
       Lighting Off
 
       Blend DstColor Zero // Multiplicative
       CGPROGRAM
       // Must be a vert/frag shader, not a surface shader: the necessary variables
       // won't be defined yet for surface shaders.
       #pragma vertex vert
       #pragma fragment frag
       
  
       #include "UnityCG.cginc"
  
       struct v2f {
         float4 pos : SV_POSITION;
         float2 uv0 : TEXCOORD0;
         float2 uv1 : TEXCOORD1;
       };
  
       struct appdata_lightmap {          
         float4 vertex : POSITION;
         float2 texcoord : TEXCOORD0;
         float2 texcoord1 : TEXCOORD1;
       };
  
       // These are prepopulated by Unity
       sampler2D unity_Lightmap;
       float4 unity_LightmapST;
  
       sampler2D _MainTex;
       sampler2D _Ramp;
       float4 _MainTex_ST; // Define this since its expected by TRANSFORM_TEX; it is also pre-populated by Unity.
  
       v2f vert(appdata_lightmap i) {
         v2f o;
         o.pos = mul(UNITY_MATRIX_MVP, i.vertex);
  
         // UnityCG.cginc - Transforms 2D UV by scale/bias property
         // #define TRANSFORM_TEX(tex,name) (tex.xy * name##_ST.xy + name##_ST.zw)
         o.uv0 = TRANSFORM_TEX(i.texcoord, _MainTex);
  
         // Use `unity_LightmapST` NOT `unity_Lightmap_ST`
         o.uv1 = i.texcoord1.xy * unity_LightmapST.xy + unity_LightmapST.zw;
         return o;
       }
  
       half4 frag(v2f i) : COLOR {
         half4 main_color = tex2D(_MainTex, i.uv0);
  
         // Decodes lightmaps:
         // - doubleLDR encoded on GLES
         // - RGBM encoded with range [0;8] on other platforms using surface shaders
         // inline fixed3 DecodeLightmap(fixed4 color) {
         // #if defined(SHADER_API_GLES) && defined(SHADER_API_MOBILE)
           // return 2.0 * color.rgb;
         // #else
           // return (8.0 * color.a) * color.rgb;
         // #endif
         // }
  
          fixed3 lightmap = DecodeLightmap(tex2D(unity_Lightmap, i.uv1));
          
          float lightmapAvg = (lightmap.r + lightmap.g + lightmap.b)/3.0;
           fixed4 ramp = tex2D(_Ramp, float2(lightmapAvg, 0));
           
         main_color.rgb *= ramp.rgb;
         return ramp; 
         //return main_color;
       }
       ENDCG
     }
   }
 }
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

0 Replies

· Add your reply
  • Sort: 

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

2 People are following this question.

avatar image avatar image

Related Questions

Static+Real Time lighting in Angry Bots Demo 1 Answer

Unity 3 Problem: Legacy Lightmap Shaders don't seem to work. 1 Answer

Replacing lightmap shader pass 0 Answers

Is there a way to Separate the light contribution from the shadow? 0 Answers

Different materials using the same colours doesn't match. 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