Signed Distance Field(有向距离场)的应用十分广泛,这种方法的思路就是使用距离场记录光照数据,之后在根据光源方向取出对应的阴影形状,它的优势很明显可以完全自定义阴影形态,同时在不同形态之间拥有自然的过渡。
制作方式:
1.帧间插值法
我尝试在PS中绘制8张阴影图,画几个特定角度下阴影的覆盖情况,图片必须连续且后一张必须可以覆盖前一张
然后执行网上一位大佬制作的批处理工具,就能生成下面的最终混合图
可以修改这个批处理工具,如增加图片,修改名称等等
下面是8张阴影图与最终生成结果
如果将这张图拖入ps调节阈值,即可预览效果
2.等高线填充法
使用Clip Studio Paint软件在UV图上绘制等高线,然后修改等高线颜色,最后使用等高线填充工具填充颜色即可
Unity使用方式:
在shader中写入下面的函数
half ApplyFaceShaderMap(half _FaceShadowOffset, half3 light, half _FaceShadowMapPow, Texture2D _FaceShadowMap, sampler sampler_FaceShadowMap, half2 uv)
{
// 计算光照旋转偏移
float sinx = sin(_FaceShadowOffset);
float cosx = cos(_FaceShadowOffset);
float2x2 rotationOffset = float2x2(cosx, -sinx, sinx, cosx);
//旋转矩阵中,Y列和Z列的数值,旋转方向
float3 Front = unity_ObjectToWorld._12_22_32;
float3 Right = unity_ObjectToWorld._13_23_33;
float2 lightDir1 = mul(rotationOffset, light.xz);
//计算xz平面下的光照角度
float FrontL = dot(normalize(Front.xz), normalize(lightDir1));
float RightL = dot(normalize(Right.xz), normalize(lightDir1));
RightL = - (acos(RightL) / PI - 0.5) * 2;
//左右各采样一次FaceLightMap的阴影数据存于lightData
float2 lightData = float2(SAMPLE_TEXTURE2D(_FaceShadowMap, sampler_FaceShadowMap, float2(uv.x, uv.y)).r,
SAMPLE_TEXTURE2D(_FaceShadowMap, sampler_FaceShadowMap, float2(-uv.x, uv.y)).r);
//修改lightData的变化曲线,使中间大部分变化速度趋于平缓。
lightData = pow(abs(lightData), _FaceShadowMapPow);
//根据光照角度判断是否处于背光,使用正向还是反向的lightData。
float lightAttenuation = step(0, FrontL) * min(step(RightL, lightData.x), step(-RightL, lightData.y));
half FaceColor = saturate((lightAttenuation));
return FaceColor;
}
© 版权声明
文章版权归作者所有,未经允许请勿转载。
THE END
暂无评论内容