# 1.4分支

``````//分支声明
#pragma shader_feature __  _SHADERENUM_BASE _SHADERENUM_FACE _SHADERENUM_HAIR``````

# 1.5采样ramp贴图方法

``````            //ramptexture 采样函数
float3 NPR_Ramp(float NdotL) {

float halfLambertRamp = smoothstep(0.0, 0.5, NdotL * 0.5 + 0.5);

if(_InNight > 0.0){
float3 var_rampTex = tex2D(_RampTex, float2(halfLambertRamp, _RampMapYRange));
return var_rampTex;
}
else {
float3 var_rampTex = tex2D(_RampTex, float2(halfLambertRamp, _RampMapYRange + 0.5));
return var_rampTex;
}

}``````

# 1.6采样高光贴图方法

``````            //specular
float NPR_Specular(float HdotN, float4 var_ParamTex, float3 baseCol) {

//不同分支用不同的高光贴图
#if defined(_SHADERENUM_HAIR)
float specularPow = pow(HdotN, var_ParamTex.a * _SpecularPow);
#else
float specularPow = pow(HdotN, var_ParamTex.r * _SpecularPow);
#endif

float3 specularCol = var_ParamTex.b * baseCol;  //主颜色乘阴影

#if defined(_SHADERENUM_HAIR)
float specular = smoothstep(0.4, 0.5, specularPow) * lerp(_SpecularInt, 1.0, var_ParamTex.b) * specularCol ;
return specular;
#else
float specular = smoothstep(0.4, 0.5, specularPow) * var_ParamTex.b * specularCol;
return specular;
#endif
}``````

# 1.7采样金属贴图方法

``````            //metal
float3 NPR_Metal(float3 nDirVS, float4 var_ParamTex, float3 baseCol) {
float2 mapUV = nDirVS.rg * 0.5 + 0.5;
float3 var_matcap = tex2D(_Matcap, mapUV);

#if defined(_SHADERENUM_HAIR)
float3 metalCol = var_matcap * baseCol * var_ParamTex.a;
return metalCol;
#else
float3 metalCol = var_matcap * baseCol * var_ParamTex.r;
return metalCol;
#endif
}``````

# 1.8边缘光方法

``````            //边缘光,用菲尼尔
float3 NPR_Rim(float3 VdotN, float3 NdotL, float3 baseCol) {
float3 light = 1 - (NdotL * 0.5 + 0.5);
float3 rim = (1.0 - smoothstep(_RimPow, _RimPow + 0.03, VdotN) * _RinInt * light) * baseCol ;
return rim;
}``````

# 1.9自发光方法

``````            //自发光
float3 NPR_emissionCol(float emissionTex, float3 baseCol) {
float3 emission = emissionTex * _EmissionInt * baseCol * abs((frac(_Time.y * 0.5) - 0.5) * _EmissionSpeed);
return emission;
}``````

## 1.10面部阴影方法

``````            //脸部
float3 NRF_FaceShadow(float ndotl, float3 baseCol, float var_FaceShadowTex, float3 lDir) {
float3 Up = float3(0.0, 1.0, 0.0);
float3 Front = unity_ObjectToWorld._12_22_32;
float3 Right = cross(Up, Front);
float2 rightXZ = normalize(Right.xz);
float2 lDirXZ = normalize(lDir.xz);
float switchShadow = dot(rightXZ, lDirXZ) * 0.5 + 0.5 < 0.5;
float FaceShadow = lerp(var_FaceShadowTex, 1- var_FaceShadowTex, switchShadow) ;
float frontXZ = normalize(Front.xz);
float FaceShadowRange = dot(frontXZ, lDirXZ);
float lightAttenuation = 1 - smoothstep(FaceShadowRange - _FaceShadowRangeSmooth, FaceShadowRange + _FaceShadowRangeSmooth, FaceShadow);
float3 rampCol = NPR_Ramp(lightAttenuation *(ndotl * 5), _RampMapYRange)+0.35;
float3 faceCol = rampCol * baseCol + ndotl * 0.1;

return faceCol;
}``````

# 2.1控制全局光照参数脚本

``````using System.Collections.Generic;
using System.IO;
using System.Linq;
using UnityEditor;
using UnityEngine;
using UnityEngine.Rendering;

public class lightingcontrollor : MonoBehaviour
{

public float _RampMapYRange = 0.3f;
public float _SpecularPow = 50.0f;
public float _SpecularInt = 2.0f;
public float _RimPow = 1.0f;
public float _RinInt = 1.0f;
public float _EmissionInt = 2.0f;
public float _EmissionSpeed = 2.0f;
public float _FaceShadowRangeSmooth = 0.1f;

public float _OutlineWidth = 0.0001f;
public Color _OutlineCol = Color.black;

private void OnEnable()
{
UpdateGlobalProperties();
}

public void UpdateGlobalProperties()
{
Shader.SetGlobalFloat("_RampMapYRange", _RampMapYRange);
Shader.SetGlobalFloat("_SpecularPow", _SpecularPow);
Shader.SetGlobalFloat("_SpecularInt", _SpecularInt);
Shader.SetGlobalFloat("_RimPow", _RimPow);
Shader.SetGlobalFloat("_RinInt", _RinInt);
Shader.SetGlobalFloat("_EmissionInt", _EmissionInt);
Shader.SetGlobalFloat("_EmissionSpeed", _EmissionSpeed);
Shader.SetGlobalFloat("_FaceShadowRangeSmooth", _FaceShadowRangeSmooth);
Shader.SetGlobalFloat("_OutlineWidth", _OutlineWidth);
Shader.SetGlobalColor("_OutlineCol", _OutlineCol);
}``````

# 3.1脚本GUI

``````using UnityEditor;
using UnityEngine;

[CustomEditor(typeof(lightingcontrollor))]
public class lightingcontrollorGUI : Editor
{
// 重载GUI绘制方法
public override void OnInspectorGUI()
{
// 获取控制器
var controller = target as lightingcontrollor;
// 判空
if (controller == null) return;

// 绘制参数面板区
DrawGlobalProperties(controller);
}

// 组开关变量
private bool _groupAToggle;
private bool _groupBToggle;

private void DrawGlobalProperties(lightingcontrollor controller)
{
EditorGUI.BeginChangeCheck();
{
// 参数组A: 光照参数配置
_groupAToggle = EditorGUILayout.BeginFoldoutHeaderGroup(_groupAToggle, "光照参数配置");
if (_groupAToggle)
{
controller._RampMapYRange = EditorGUILayout.Slider(
"RampTexture采样颜色",
controller._RampMapYRange,
0.0f, 0.5f);

controller._SpecularPow = EditorGUILayout.Slider(
"高光次幂",
controller._SpecularPow,
10.0f, 200.0f);

controller._SpecularInt = EditorGUILayout.Slider(
"高光强度",
controller._SpecularInt,
0.0f, 5.0f);

controller._RimPow = EditorGUILayout.Slider(
"边缘光幂",
controller._RimPow,
0.0f, 2.0f);

controller._RinInt = EditorGUILayout.Slider(
"边缘光强度",
controller._RinInt,
0.0f, 0.5f);

controller._EmissionInt = EditorGUILayout.Slider(
"自发光强度",
controller._EmissionInt,
1.0f, 5.0f);

controller._EmissionSpeed = EditorGUILayout.Slider(
"发光频率",
controller._EmissionSpeed,
1.0f, 4.0f);

controller._FaceShadowRangeSmooth = EditorGUILayout.Slider(
"面部阴影模糊程度",
controller._FaceShadowRangeSmooth,
0.1f, 1.0f);
}
EditorGUILayout.EndFoldoutHeaderGroup();

// 参数组B: 描边参数配置
_groupBToggle = EditorGUILayout.BeginFoldoutHeaderGroup(_groupBToggle, "描边参数配置");
if (_groupBToggle)
{
controller._OutlineCol = EditorGUILayout.ColorField(
"RampTexture采样颜色",
controller._OutlineCol);

controller._OutlineWidth = EditorGUILayout.Slider(
"轮廓线宽度",
controller._OutlineWidth,
0.0001f, 0.0003f);
}
EditorGUILayout.EndFoldoutHeaderGroup();
}

if (EditorGUI.EndChangeCheck())
{
controller.UpdateGlobalProperties();
EditorUtility.SetDirty(controller);
}
}

}``````

THE END