Last active
August 17, 2018 11:48
-
-
Save johans2/422ef1d9e70a514772ac4a53efc9dc0a to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Shader "Custom/SvenssonToonLighting" | |
{ | |
Properties | |
{ | |
[Header(Diffuse)] | |
_MainTex ("Main Texture", 2D) = "white" {} | |
_Color ("Albedo", color) = (1., 1., 1., 1.) | |
_ToonRamp("Toon ramp", 2D) = "white" {} | |
_ShadowColor ("Shadow color", color) = (1., 1., 1., 1.) | |
[Header(Specular)] | |
[Toggle(ENABLE_SPEC)] _SpecEnabled ("Enabled", Float) = 0 | |
_Shininess ("Shininess", Range(0.1, 10)) = 1. | |
_SpecIntensity ("Specular intensity", Range(0.0, 2)) = 0.1 | |
_SpecColor ("Specular color", color) = (1., 1., 1., 1.) | |
_SpecRamp("Specular ramp", 2D) = "white" {} | |
[Header(Rim light)] | |
[Toggle(ENABLE_RIM)] _RimEnabled ("Enabled", Float) = 0 | |
_RimColor ("Rim color", color) = (1., 1., 1., 1.) | |
_RimPower ("Rim power", Range(0.1, 10)) = 3. | |
[Header(Recieve shadows)] | |
[Toggle(ENABLE_ADVANCED_SHADOWS)] _AdvancedShadowsEnabled ("Enabled", Float) = 0 | |
_ShadowRamp("Shadow ramp", 2D) = "white" {} | |
} | |
SubShader | |
{ | |
Cull back | |
Pass | |
{ | |
Tags { "RenderType"="Opaque" "LightMode"="ForwardBase" "Pass" = "OnlyDirectional"} | |
CGPROGRAM | |
#pragma vertex vert | |
#pragma fragment frag | |
#pragma multi_compile_fwdbase | |
#pragma shader_feature ENABLE_SPEC | |
#pragma shader_feature ENABLE_RIM | |
#pragma shader_feature ENABLE_ADVANCED_SHADOWS | |
#pragma shader_feature ENABLE_CUTOUT_ALPHA | |
#include "UnityCG.cginc" | |
#include "AutoLight.cginc" | |
struct v2f { | |
float4 pos : SV_POSITION; | |
float2 uv : TEXCOORD0; | |
float3 worldPos : TEXCOORD1; | |
float3 worldNormal : NORMAL; | |
#if ENABLE_ADVANCED_SHADOWS | |
LIGHTING_COORDS(2, 3) | |
#endif | |
}; | |
v2f vert(appdata_base v) | |
{ | |
v2f o; | |
// World position | |
o.worldPos = mul(unity_ObjectToWorld, v.vertex); | |
// Clip position | |
o.pos = mul(UNITY_MATRIX_VP, float4(o.worldPos, 1.)); | |
// Normal in WorldSpace | |
o.worldNormal = normalize(mul(v.normal, (float3x3)unity_WorldToObject)); | |
o.uv = v.texcoord; | |
#if ENABLE_ADVANCED_SHADOWS | |
TRANSFER_VERTEX_TO_FRAGMENT(o); | |
#endif | |
return o; | |
} | |
// Diffuse | |
sampler2D _MainTex; | |
sampler2D _ToonRamp; | |
fixed4 _LightColor0; | |
fixed4 _Color; | |
fixed4 _ShadowColor; | |
//Specular | |
fixed _Shininess; | |
fixed _SpecIntensity; | |
fixed4 _SpecColor; | |
sampler2D _SpecRamp; | |
// Rim | |
fixed4 _RimColor; | |
float _RimPower; | |
// Advanced shadows | |
sampler2D _ShadowRamp; | |
fixed4 frag(v2f i) : SV_Target | |
{ | |
fixed4 c = tex2D(_MainTex, i.uv); | |
float3 light = {0.0,0.0,0.0}; | |
// Light direction | |
half3 lightDir = normalize(_WorldSpaceLightPos0.xyz); | |
// Camera direction | |
half3 viewDir = normalize(_WorldSpaceCameraPos.xyz - i.worldPos.xyz); | |
// -------------------- DIFFUSE LIGHT ---------------------- | |
// This will be light added to all parts of the obejct, including dark ones. | |
half3 indirectDiffuse = unity_AmbientSky; | |
// Compute the diffuse lighting | |
half NdotL = max(0., dot(i.worldNormal, lightDir)); | |
// Sample the lut texture, float2(<the light value [0...1]>, 0). Creating the cell shading. | |
half toonRamp = tex2D(_ToonRamp, float2(NdotL, 0)); | |
// Diffuse based on light source | |
half3 directDiffuse = toonRamp * _LightColor0; | |
// Light = direct + indirect; | |
half3 diffuse = indirectDiffuse + directDiffuse; | |
// Add shadow color. | |
diffuse += (_ShadowColor * (1.0 - toonRamp)); | |
// -------------------- SPECULAR LIGHT ---------------------- | |
#if ENABLE_SPEC | |
// Get the light reflection across the normal. | |
half3 refl = normalize(reflect(-lightDir, i.worldNormal)); | |
// Calculate dot product between the reflection diretion and the view direction [0...1] | |
half RdotV = max(0., dot(refl, viewDir)); | |
// Make large values really large and small values really small. | |
half specPow = pow(RdotV, _Shininess); | |
// Sample the ramp texture for a smooth falloff. | |
half3 specRamp = tex2D(_SpecRamp , float2(specPow, 0)); | |
// Multiply by NdotL to make non lit areas not get spec (kinda works). | |
half3 spec = specRamp * toonRamp * _LightColor0 * _SpecColor * pow(_SpecIntensity,2); | |
#endif | |
// ----------------------- RIM LIGHT ------------------------ | |
#if ENABLE_RIM | |
// Light based only on view direction and normal | |
half rimAmount = 1 - saturate(dot(normalize(viewDir), i.worldNormal)); | |
half3 rim = _RimColor * pow(rimAmount, _RimPower); | |
#endif | |
// ------------------- RECIEVE SHADOWS --------------------- | |
#if ENABLE_ADVANCED_SHADOWS | |
// Get the light attenuation | |
half attenuation = LIGHT_ATTENUATION(i); | |
// Get the ramped shadow from the _ShadowRamp texture based on attenuation | |
half shadowRamp = tex2D(_ShadowRamp , float2(attenuation, 0)).r; | |
// Modify existing light based on the ramped shadow | |
diffuse = indirectDiffuse + (directDiffuse * shadowRamp); | |
// Add Shadow color | |
diffuse += (_ShadowColor * (1.0 - min(shadowRamp, toonRamp))); | |
#if ENABLE_SPEC | |
spec *= shadowRamp; | |
#endif | |
#endif | |
// --------------------- FINAL LIGHT ------------------------ | |
light += diffuse; | |
#if ENABLE_RIM | |
light += rim; | |
#endif | |
#if ENABLE_SPEC | |
light += spec; | |
#endif | |
c.rbg *= _Color; | |
c.rgb *= light.rgb; | |
// ------------------- ALPHA CLIPPING ---------------------- | |
clip(c.a - 0.1); | |
return c; | |
} | |
ENDCG | |
} | |
} | |
// This fallback makes the shader cast shadows | |
Fallback "Transparent/Cutout/Diffuse" | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment