URP Toon Lit 初见

Git Repository: timrockefeller/UnityURPToonLitShaderExample

Main Structure

  1. SurfaceColor pass

  2. Outline pass

  3. ShadowCaster pass

  4. DepthOnly pass

Features

核心特性

  • 面部法线修正⚠️

  • 光滑描边⚠️

  • FOV、LOD 描边变形修正⚠️

  • 面部头发投影 clip⚠️

  • 前发遮挡的眼部渲染

  • 各向异性头发渲染与“天使环”结合 UV 拉伸

  • 边缘光

  • PBR 镜面光照

  • 通过 HSV 控制阴影、描边颜色

  • 2D 嘴部渲染

  • stencil local hair shadow on face

  • 物理与风的模拟

  • 其他的特性材质如 AO、镜面、法线等

Spotlight Methods

Alpha Cliping

1
2
3
4
5
6
7
8
9
10
11
12
13
void DoClipTestToTargetAlphaValue(half alpha) 
{
// iOS上编译该shader出了点问题
/*
if(_UseAlphaClipping)
{
clip(alpha - _Cutoff);
}
*/

// 并非最佳方案,尽量使用GPU原生特性
clip(alpha - _Cutoff + (1.0001-_UseAlphaClipping));
}

Lighting Equaltion

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
// this function will be used by all direct lights (directional/point/spot)
half3 ShadeSingleLightDefaultMethod(SurfaceData surfaceData, LightingData lightingData, Light light)
{
half3 N = lightingData.normalWS;
half3 L = light.direction;
half3 V = lightingData.viewDirectionWS;
half3 H = normalize(L+V);

half NoL = dot(N,L);

half lightAttenuation = 1;

// light's shadow map. If you prefer hard shadow, you can smoothstep() light.shadowAttenuation to make it sharp.
lightAttenuation *= lerp(1,light.shadowAttenuation,_ReceiveShadowMappingAmount);

// light's distance & angle fade for point light & spot light (see GetAdditionalPerObjectLight() in Lighting.hlsl)
// Lighting.hlsl -> https://github.com/Unity-Technologies/Graphics/blob/master/com.unity.render-pipelines.universal/ShaderLibrary/Lighting.hlsl
lightAttenuation *= min(2,light.distanceAttenuation); //max intensity = 2, prevent over bright if light too close, can expose this float to editor if you wish to

// N dot L
// simplest 1 line cel shade, you can always replace this line by your own better method !
lightAttenuation *= smoothstep(_CelShadeMidPoint-_CelShadeSoftness,_CelShadeMidPoint+_CelShadeSoftness, NoL);

// don't want direct lighting becomes too bright for toon lit characters? set this value to a lower value
lightAttenuation *= _DirectLightMultiplier;

return surfaceData.albedo * light.color * lightAttenuation;
}
Share