[Unity URP]原神 Shader渲染还原 Part1 面部阴影


声明
本文章的代码仅作为学习交流使用

//面部阴影 half3 faceShadow; #if FACESHADOW_ON float3 Front = mul(unity_ObjectToWorld, half3(0,0,1)); //人物正面朝向 float3 Right = mul(unity_ObjectToWorld, half3(1,0,0)); //人物右侧朝向 //对LightMap进行采样,1是光照到左半边脸,2是光照到右半边脸 float2 flipUV = float2(1 - i.uv0.x, i.uv0.y);//反向采样用的uv half4 LightMap1 = SAMPLE_TEXTURE2D(_LightMap, sampler_LightMap, i.uv0); half4 LightMap2 = SAMPLE_TEXTURE2D(_LightMap, sampler_LightMap, flipUV); //计算光和人右侧/光和人正面的夹角 float RightL = dot(normalize(Right.xz), normalize(lDirWS.xz)); float FrontL = dot(normalize(Front.xz), normalize(lDirWS.xz)); //判断采用哪张采样图 //half4 Rroad = cross(Front, lDirWS).y > 0 ? LightMap1 : LightMap2; half4 Rroad = lerp(LightMap2, LightMap1, step(RightL,0)); //RightL大于0,说明右侧光,用反采样图(2号) //角度angle利用RightL的反余弦计算光和右侧夹角(此时范围为0-PI),之后变换区间(0-2),判断大于还是小于1,得到角度值(范围为0-1) float LR = -(acos(RightL)/3.14159265 - 0.5)*2; float angle = lerp(LR, -LR, step(LR,0)); //判断光照在脸上还是后面,后面就全黑(FrontL<0) half3 lightforward = step(0, FrontL); //如果角度值比采样图的值大则说明被光照到 half lighton = step(angle,Rroad.r);//如果R通道小于angle,返回0,R通道大于angle,返回1 //依据lightforward和lighton光照情况对阴影色和基础色进行插值 return half4(lerp(ShadowRamp1*baseCol, baseCol.rgb, lightforward*lighton),1.0);
         #endif
 

参考文章:

[卡通渲染]二、原神角色渲染还原 - Diffuse-1 - 知乎 (zhihu.com)

从零开始的原神角色渲染 - 知乎 (zhihu.com)

面部还原主要参考:

BV15w411f7f9

头发平滑法线 参考文章:

Blender中通过修改法线获得圆滑头发阴影 - 菜鸟少侠 - 博客园 (cnblogs.com)

blender最好是默认路径安装,不然插件会出问题(懒人懒得调),这里版本用的3.2,abnormal插件要下最新版

其他问题存档:

1.视角拉远出现模糊方块,线条,视角拉近没有

解决:ramp 纹理mipmap关闭!!

2.只有diffuse贴图需要勾选SRGB,其余都不需要,法线贴图把type改成normal,sdf图关闭压缩

posted @ 2023-02-14 23:23  LOFU  阅读(463)  评论(0编辑  收藏  举报