描边在卡通渲染中经常会用到,最常见的做法是法线外扩,这种方式有一个问题是如果顶点的两个边的法线变化不连续或者说变化比较大,则会出现分叉,入正方体的法线外扩就会有这个问题。
其他解决方式:?
然后有一些做法可以解决这种问题,比如顶点放大,然后后处理把中间角色的颜色剔除来模拟描边。这种的问题就在于有一个全屏后处理的消耗,对于手机带宽有一定的影响。
当然还有卷积处理等等都会增加一定的带宽消耗。
而之前有尝试过一种解决方式,能够类似多一个pass描边来解决问题而不需要其他多余的消耗。
本方案核心思路:
主要的做法是堆模型的顶点做预处理。首先说下我们在顶点着色器是用顶点的法线外扩来实现最基础的描边的,而其实顶点他本身是没有法线这个概念的,他的法线来源于他的面,而一个顶点会相连三个面,如果我们只用一个面的信息,那么他当然是不连续的跳跃的过渡的。而我们想让他连续的话,就需要离线将三个面的法线拿到然后取平均。这个给到顶点颜色上,然后这个顶点颜色就是平均法线了,然后这个法线在描边的pass中做外扩就能得到连续的描边了。
核心代码:
离线处理上核心是法线取平均让他顶点间的法线连续:
for (int i = 0; i < mMesh.vertices.Length; i++)
{
var key = mMesh.vertices[i];
if (mRealNormals.ContainsKey(key))
{
mRealNormals[key] += mMesh.normals[i] / 3;
}
else
{
mRealNormals[key] = mMesh.normals[i] / 3;
}
}
shader中拿颜色信息外扩:
input.positionOS.xyz += input.color * _Outline;
最终效果:
?
?
|