SHARE
TWEET

Simple Double-sided Diffuse Rimlight Shader

Coguelin Oct 21st, 2013 126 Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. Shader "FX/DoubleSidediffuseRimlight"
  2. {
  3.         // These are the fields that will appear for this Material in the Inspector - see Unity doc at http://docs.unity3d.com/Documentation/Components/SL-Properties.html
  4.         // The first part is the property's variable, eg. "_MainTex" - Naming your main texture "_MainTex" signals to Unity that this Shader should be included in Lightmap calculations
  5.         // Using the standard Unity property names also lets Unity apply a fallback Shader if the user's hardware can't handle this one
  6.         // The second part in brackets is the name of the property in the Inspector, eg. "Main Texture" - This can be anything you like.
  7.         // The third part in brackets is the variable type, eg. "2D" declares it to be a texture file -
  8.         // The fourth part is the property's default value, eg. "white {}" - Textures are generally given default values of white, gray or black
  9.         Properties
  10.         {
  11.                 _MainTex ("Main Texture", 2D) = "white" {} // This is the material's Texture property and we want it to be included in Lightmap calculations (especially LightProbes)
  12.                 _RimColor ("Rim Color", Color) = (0.26, 0.19, 0.16, 0.0) // This is the material's RimLight Color
  13.                 _RimPower ("Rim Power", float) = 3.0 // This is the material's RimLight strength.  0 will be maximum rimlighting... Rim power is generally exposed as a Range property type
  14.         }
  15.        
  16.         // The SubShader is where the Shader calculations actually happen
  17.         // IMPORTANT : Normally, surface shaders cannot include two passes, but we're going to use a sneaky trick to use two passes into this one
  18.         SubShader
  19.         {
  20.        
  21.                 // This allows Unity to intelligently substitute this Shader when needed
  22.                 Tags { "RenderType"="Opaque" }
  23.                 LOD 200
  24.                
  25.                 // This lets Unity know it doesn't need to worry about the back of our object right now, because we can't see it
  26.                 Cull Back
  27.                
  28.                 // The syntax that was use after "pragma" tells Unity what kind of shader this is and how it should be applied, eg.
  29.                 // This shader is a surface Shader of type Lambert, and we want Unity to approximate view direction to speed up calculations
  30.                 CGPROGRAM
  31.                 #pragma surface surf Lambert approxview
  32.  
  33.                 //These match the shader properties
  34.                 uniform sampler2D _MainTex;
  35.                 uniform fixed4 _Color, _RimColor;
  36.                 uniform fixed _RimPower;
  37.  
  38.         // This contains the inputs to the surface function
  39.                 // Valid fields are listed at: http://docs.unity3d.com/Documentation/Components/SL-SurfaceShaders.html
  40.                 struct Input
  41.                 {
  42.                         float2 uv_MainTex;
  43.                         float3 viewDir; // Since this is a RimLight Shader, we need to account for the Camera View Direction.  This value accesses Unity's internal calculations
  44.                         float3 worldNormal; // Since this is a Mobile Shader, we want to try to avoid complex calculations.  This value uses the Unity's world normals instead of the object normals
  45.                 };
  46.  
  47.                 // This is where we prepare the surcace for lighting by propagating a SurfaceOutput structure
  48.                 void surf (Input IN, inout SurfaceOutput o)
  49.                 {
  50.                         fixed4 c = tex2D (_MainTex, IN.uv_MainTex); // Samples the texture
  51.                         o.Albedo = c.rgb; // Modulate by main colour
  52.                         o.Alpha = 1.0; // No alpha in this shader
  53.                        
  54.                         fixed rim = 1.0 - saturate(dot(normalize(IN.viewDir), IN.worldNormal)); // We calculate the dot product of the vertex and our view direction, and use it to calculate our rim light
  55.                        
  56.                         o.Emission = _RimColor.rgb * pow (rim, _RimPower); // We apply our rim light and place it in the Material's emmission value
  57.                 }
  58.                 ENDCG
  59.        
  60.                 // This lets Unity know that we'll need the back of theobject now, but it can ignore the front... it we wanted, we could also say "off" and have it paint everything
  61.                 Cull Front
  62.                
  63.                
  64.                 // IMPORTANT : This is where this shader starts getting sneaky and weird
  65.                 // The "vertex" syntax at the end of the "pragma" line tells the shader we want to do some vertex calculations before we paint the texture, and that we'll put them in a function called "vert"
  66.                 CGPROGRAM
  67.                 #pragma surface surf Lambert approxview vertex:vert
  68.  
  69.                 uniform sampler2D _MainTex;
  70.                 uniform fixed4 _Color, _RimColor;
  71.                 uniform fixed _RimPower;
  72.  
  73.                 struct Input
  74.                 {
  75.                         float2 uv_MainTex;
  76.                         float3 viewDir;
  77.                         float3 worldNormal;
  78.                 };
  79.                
  80.                 // This is our vertex function, I'm going to break it down so you know what's happening
  81.                 // "inout" tells Unity we want to hijack a value.  We're going to take it in, do something to it, and push it back out
  82.                 // "appdata_full" is the output of Unity's standard vertex calculations, if this wasn't a Surface Shader, we would have to do those ourselves
  83.                 // "out" tells Unity that we'll also be producing another value (this is actually pretty normal c syntax)
  84.                 // "Input" is the value structure we defined just above
  85.                 // We're calling it "o"
  86.                 void vert (inout appdata_full v, out Input o)
  87.                 {
  88.                         // Since Unity wouldn't normally worry about our Input structure before the surf function below, we ask Unity to prepare it for us now so we can access the vertex info
  89.                         UNITY_INITIALIZE_OUTPUT(Input, o);
  90.                
  91.                         // Here, we simply switch the normals of the entire object, this will let Unity paint a texture on the back side of the planes (which are now front sides)
  92.                         v.normal = -v.normal;
  93.                 }
  94.  
  95.                 void surf (Input IN, inout SurfaceOutput o)
  96.                 {
  97.                         fixed4 c = tex2D (_MainTex, IN.uv_MainTex);
  98.                         o.Albedo = c.rgb;
  99.                         o.Alpha = 1.0;
  100.                         fixed rim = 1.0 - saturate(dot(normalize(IN.viewDir), IN.worldNormal));
  101.                         o.Emission = _RimColor.rgb * pow (rim, _RimPower);
  102.                 }
  103.                 ENDCG
  104.         }
  105.         FallBack "Mobile/Diffuse"
  106. }
RAW Paste Data
We use cookies for various purposes including analytics. By continuing to use Pastebin, you agree to our use of cookies as described in the Cookies Policy. OK, I Understand
 
Top