Last active
March 28, 2020 14:15
-
-
Save AlvarBer/14b4721ca7015d2e10ab7b9d5721fd48 to your computer and use it in GitHub Desktop.
Toon lit & unlit "uber" shader
This file contains 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
// TODO: Do fresnel the ronja way | |
Shader "HCF/3D/Toon Lit" { | |
Properties { | |
_MainTex("Albedo (RGB)", 2D) = "white" {} | |
_Tint("Tint", Color) = (1, 1, 1, 1) | |
[Header(Lighting)] | |
[Toggle] | |
_UseRampText("Use Ramp Texture", Float) = 0 | |
[NoScaleOffset] | |
_RampTex("Ramp Texture (Greyscale)", 2D) = "white" {} | |
[IntRange] | |
_StepAmount("Shadow Steps (if no ramp tex)", Range(1, 16)) = 2 | |
_StepWidth("Step Size (if no ramp tex)", Range(0.05, 1)) = 0.25 | |
[Toggle] | |
_VertexColors("Display vertex colors", Float) = 0 | |
[Toggle] | |
_MaterialShadowColor("Shadow Color From Material", Float) = 1 | |
[HDR] | |
_ShadowTint("Shadow Color", Color) = (0, 0, 0, 1) | |
[Header(Specular)] | |
[Toggle] | |
_Specular("Enable Specular", Float) = 1 | |
_SpecularSize("Specular Size", Range(0, 1)) = 0.1 | |
_SpecularFalloff("Specular Falloff", Range(0, 2)) = 1 | |
_SpecularColor("Specular Color", Color) = (1, 1, 1, 1) | |
[Header(Rim Light)] | |
[Toggle] | |
_RimLight("Enable Rim Light", Float) = 0 | |
_RimColor("Rim color", Color) = (1, 1, 1, 1) | |
_RimAmount("Rim Amount", Range(0, 1)) = 0.716 | |
_RimExp("Rim Exponent", Range(0, 1)) = 0.1 | |
} | |
SubShader { | |
Tags { | |
"RenderType" = "Opaque" | |
"Queue" = "Geometry" | |
} | |
LOD 200 | |
CGPROGRAM | |
// fullforwardshadows makes sure unity adds the shadow passes the shader might need | |
#pragma surface surf ToonStep fullforwardshadows | |
#pragma target 3.0 | |
#pragma shader_feature_local _USERAMPTEXT_ON | |
#pragma shader_feature_local _VERTEXCOLORS_ON | |
#pragma shader_feature_local _MATERIALSHADOWCOLOR_ON | |
#pragma shader_feature_local _SPECULAR_ON | |
#pragma shader_feature_local _RIMLIGHT_ON | |
sampler2D _MainTex; | |
struct Input { | |
float2 uv_MainTex; | |
#if defined(_VERTEXCOLORS_ON) | |
float4 color : COLOR; | |
#endif | |
}; | |
struct ToonSurfaceOutput{ | |
fixed3 Albedo; | |
half3 Emission; | |
#if defined(_SPECULAR_ON) | |
fixed3 Specular; | |
#endif | |
fixed Alpha; | |
fixed3 Normal; | |
}; | |
fixed4 _Tint; | |
#if defined(_MATERIALSHADOWCOLOR_ON) | |
float3 _ShadowTint; | |
#endif | |
#if defined(_SPECULAR_ON) | |
fixed3 _SpecularColor; | |
#endif | |
void surf(Input IN, inout ToonSurfaceOutput o) { | |
fixed4 col = tex2D(_MainTex, IN.uv_MainTex) * _Tint; | |
#if defined(_VERTEXCOLORS_ON) | |
col *= IN.color; | |
#endif | |
o.Albedo = col.rgb; | |
#if defined(_MATERIALSHADOWCOLOR_ON) | |
o.Emission = col.rgb * _ShadowTint; | |
#else | |
o.Emission = col.rgb * UNITY_LIGHTMODEL_AMBIENT; | |
#endif | |
#if defined(_SPECULAR_ON) | |
o.Specular = _SpecularColor; | |
#endif | |
} | |
#if defined(_USERAMPTEXT_ON) | |
sampler2D _RampTex; | |
#else | |
int _StepAmount; | |
float _StepWidth; | |
#endif | |
#if defined(_SPECULAR_ON) | |
float _SpecularSize, _SpecularFalloff; | |
#endif | |
#if defined(_RIMLIGHT_ON) | |
float4 _RimColor; | |
float _RimAmount, _RimExp; | |
#endif | |
float4 LightingToonStep(ToonSurfaceOutput s, float3 lightDir, half3 viewDir, float shadowAttenuation) { | |
// Copied from toonlit standard shader | |
#ifndef USING_DIRECTIONAL_LIGHT | |
lightDir = normalize(lightDir); | |
#endif | |
float nDotL = dot(s.Normal, lightDir); | |
#if defined(_USERAMPTEXT_ON) | |
nDotL = nDotL * 0.5 + 0.5; | |
float intensity = tex2D(_RampTex, float2(nDotL, nDotL)).r; | |
#else | |
// strech values so each whole value is one step | |
nDotL /= _StepWidth; | |
// make steps harder | |
float intensity = floor(nDotL); | |
// fwidth computes difference over quad-pixels | |
// This gives a bit of smoother lines as it lerps over single pixel | |
// It's fine that intensity goes lower than 0, since that's just shadow | |
float nDotLDelta = fwidth(nDotL); | |
// calculate smoothing in first pixels of the steps and add smoothing to step, raising it by one step | |
// (that's fine because we used floor previously and we want everything to be the value above the floor value, | |
// for example 0 to 1 should be 1, 1 to 2 should be 2 etc...) | |
float smoothing = smoothstep(0, nDotLDelta, frac(nDotL)); | |
intensity += smoothing; | |
// bring the light intensity back into a range where we can use it for color | |
// and clamp it so it doesn't do weird stuff below 0 / above one | |
intensity /= _StepAmount; | |
intensity = saturate(intensity); | |
#endif | |
#if defined(USING_DIRECTIONAL_LIGHT) | |
float attenuationDelta = fwidth(shadowAttenuation) * 0.5; | |
float shadow = smoothstep(0.5 - attenuationDelta, 0.5 + attenuationDelta, shadowAttenuation); | |
#else | |
float attenuationDelta = fwidth(shadowAttenuation); | |
float shadow = smoothstep(0, attenuationDelta, shadowAttenuation); | |
#endif | |
intensity *= shadow; | |
float3 lightCol = intensity * _LightColor0.rgb; | |
#if defined(_SPECULAR_ON) | |
// calculate how much the surface points points towards the reflection direction | |
float3 reflectionDirection = reflect(lightDir, s.Normal); | |
float specular = dot(viewDir, -reflectionDirection); | |
// make specular highlight all off towards outside of model | |
float specularFalloff = dot(viewDir, s.Normal); | |
specularFalloff = pow(specularFalloff, _SpecularFalloff); | |
specular *= specularFalloff; | |
// make specular intensity with a hard corner | |
float specularDelta = fwidth(specular); | |
float specularIntensity = smoothstep(1 - _SpecularSize, 1 - _SpecularSize + specularDelta, specular); | |
// factor inshadows | |
specularIntensity *= shadow; | |
#endif | |
#if defined(_RIMLIGHT_ON) | |
float rimDot = 1 - dot(viewDir, s.Normal); | |
float rimIntensity = rimDot * pow(nDotL, _RimExp); | |
rimIntensity = smoothstep(_RimAmount - 0.01, _RimAmount + 0.01, rimIntensity); | |
float4 rim = rimIntensity * _RimColor; | |
lightCol += rim; | |
#endif | |
float4 color; | |
color.rgb = s.Albedo * lightCol; | |
#if defined(_SPECULAR_ON) | |
color.rgb = lerp(color.rgb, s.Specular, saturate(specularIntensity)); | |
#endif | |
color.a = s.Alpha; | |
return color; | |
} | |
ENDCG | |
} | |
FallBack "Standard" | |
} |
This file contains 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 "HCF/3D/Toon Unlit" { | |
Properties { | |
_MainTex ("Texture", 2D) = "white" {} | |
_Tint("Tint", Color) = (0.462745, 0.462745, 0.462745, 1) | |
[Header(Lighting)] | |
[NoScaleOffset] | |
_ShadingCube("Lightning cupemap(RGB)", Cube) = "" {} | |
} | |
SubShader { | |
Tags { | |
"RenderType" = "Opaque" | |
"Queue" = "Geometry" | |
} | |
LOD 100 | |
Pass { | |
Name "BASE" | |
Tags { | |
"LightMode" = "Always" // No Lighting | |
"PassFlags" = "OnlyDirectional" // Don't pass vertex/SH9 light | |
} | |
CGPROGRAM | |
#pragma vertex vert | |
#pragma fragment frag | |
#pragma multi_compile_fog | |
#include "UnityCG.cginc" | |
struct appdata { | |
float4 vertex : POSITION; | |
float2 uv : TEXCOORD0; | |
float3 normal : NORMAL; | |
}; | |
struct v2f { | |
float4 vertex : SV_POSITION; | |
float2 uv : TEXCOORD0; | |
float3 cubeNormal : TEXCOORD1; | |
UNITY_FOG_COORDS(2) | |
}; | |
sampler2D _MainTex; | |
float4 _MainTex_ST; | |
v2f vert(appdata v) { | |
v2f o; | |
o.vertex = UnityObjectToClipPos(v.vertex); | |
o.uv = TRANSFORM_TEX(v.uv, _MainTex); | |
// Dunno how to get rid of the warning. Or what exactly UNITY_MV is | |
o.cubeNormal = mul (UNITY_MATRIX_MV, float4(v.normal,0)); | |
UNITY_TRANSFER_FOG(o, o.vertex); | |
return o; | |
} | |
samplerCUBE _ShadingCube; | |
fixed4 _Tint; | |
fixed4 frag (v2f i) : SV_Target { | |
fixed4 col = tex2D(_MainTex, i.uv) * _Tint; | |
// Get lightning info from cubemap using the normals | |
// Multiply by 2 because cubemap is a detail map | |
fixed4 cube = texCUBE(_ShadingCube, i.cubeNormal); | |
// fixed4 cube = texCUBE(_ShadingCube, i.cubeNormal) * unity_ColorSpaceDouble; | |
col.rgb *= cube.rgb; | |
UNITY_APPLY_FOG(i.fogCoord, col); | |
return col; | |
} | |
ENDCG | |
} | |
} | |
FallBack "Standard" | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment