使用的unitychan的模型进行练习脸部/眼睛/头发渲染

使用的unitychan的模型进行练习脸部/眼睛/头发渲染

使用unitychan的模型来练习

人脸/眼睛/头发渲染比较繁琐,每种材质都很特殊地图场景,实现中有很多细节,所以暂时使用原来的材质

基本的卡通风格渲染由几个主要部分组成

漫反射/高光/边缘/描边

finalColor = diffuse + specular + rimLight

基本质地

漫反射

普通漫反射是

环境光的颜色 * 法线和光的夹角
diffuse = diffuseColor * dot(N, L);

漫反射

卡通渲染的漫反射一般都有清晰的颜色边界unity卡通模型 带动作,形成不同颜色的波段

一般采用渐变或条状渐变纹理进行采样,通常称为RampTexture

颜色比较深,看起来不是很明显

强调

blinn-phone模型的亮点是

H = normalize(viewDir + lightDir);
specular = _SpecularColor * dot(N, H);

高光部分的处理是为了减弱过度,增加对比度

_SpecularEdge 为高光范围
float specular = step(_SpecularEdge, pow(NdotH, _Specular));
float3 specularColor = specular * _SpecularColor;

强调

轮廓光

轮廓光容易营造气氛,表现人物线条unity卡通模型 带动作,卡通渲染必不可少

一般采用菲涅尔反射计算在模型边缘产生轮廓光

fresnelPower 为菲涅尔反射强度
float fresnel = step(_FresnelEdge, pow(1 - NdotV, _Fresnel));
float3 rimLight = _FresnelColor * fresnel;

轮廓光

中风

主要是为了区分人物和背景

笔划的方式有很多种,最简单的方式就是用一个pass画字符3D动画,用一个额外的pass来画笔划

stroke的传递主要在裁剪空间进行

v2f vert(a2v v)
{
    v2f o;
    o.pos = UnityObjectToClipPos(v.vertex);
    float3 normal = normalize(mul((float3x3)UNITY_MATRIX_IT_MV, v.normal));
    float2 normalCS = mul((float3x3)UNITY_MATRIX_P, normal.xy);
    o.pos.xy += normalCS.xy * o.pos.z * _OutlineWidth;
    return o;
}
fixed4 frag(v2f i) : SV_Target 
{
    return _OutlineColor;
}

添加描边

最终整体效果

与unitychan的实现相比,normal有很多特殊的实现