只要是实际做过卡渲的人,就会遇到斜线锯齿的问题。这是因为内描线在纹理里只占用了1到2个像素的大小,斜过来肯定会变成这样。
增加纹理的尺寸自然可以解决问题,但让大片低细节的纹理占用如此大的面积实在太浪费了。而内描线占用的区域又大,分UV2也解决不了问题。
目前常用的内描线精度解决方法有以下几种。
1.本村线
可以看到,纹理里的横线和竖线都不会出现上述的问题,因为它们本身就是平直的。所以可以通过调整UV让所有的线正好处于横线或者竖线的位置。
这种做法只需要调整UV,是GGXX所推行的方案,所以也被很多人认为的这个问题的正规解法。
但实际操作过就明白,这个方法本身是非常麻烦的,如果对已经做好的图修改则更加困难,而且遇到三角形,曲线的时候也不好处理,也不方便做UV的合理布局。
如果描线少还好,在内描线较多的家具、建筑等物体内,它实际上是一个无法完成的任务。你要和美术有仇就可以让他拉这个。
2.Mesh描线
我们可以在有描线的地方单独拉UV,然后指向贴图的一个纯色区域。
这也是一种比较常用的做法(因为也没啥别的办法了),但依然比较麻烦,而且对曲线不友好。同时它会产生比较多的多余顶点。
锯齿问题用几何反锯齿一并处理就好。
3.后处理描线
通过在顶点信息里记录区域信息,绘制到屏幕缓存上,就能利用后处理在区域边缘生成描线。可以和普通的后处理外描线一起处理。
后处理本来就容易生成一些backface无法生成成描线(鼻头等等),而且更符合画师的“思路”,也容易实现软边缘、粗描线、等宽描线,但问题就在于性能和可控性上。
通常不予考虑。
这次我们用的是SDF的做法,将内描边单独分层并生成SDF,然后用SDF的渲染方法显示。
为了避免瑕疵,原始的内描边图片精度要高。我用了PS的钢笔工具勾线,然后绘制到一张8192的贴图上。
然后用这个工具来生成SDF。
http://www.lonesock.net/files/SDFont.zip
(没有用户界面,把PNG拖到SDFont.exe里就行)
注意输出的SDF时要指定大小(我指定是的512,也就是原纹理大小),而且不要再进行缩放了,否则依然会有失真。
SDF图的局部:
然后用Shader把它显示出来就行了,主要代码如下
fixed4 frag (v2f i) : SV_Target
{
fixed4 col = tex2D(_MainTex, i.uv);
fixed r = 0.5 - tex2D(_LineTex, i.uv).a;
col.rgb = lerp(col.rgb, _LineColor, step(r,_LineWidth));
return col;
}
初步效果:
由于使用的是step,所以会有锯齿。虽然也可以用smoothstep来反锯齿,但这里用的是Cell光照里用的一种反锯齿方法,可以确保边缘不模糊,这样观感就能和外描线一致。
//用这个代替原本的step
half stepAntiAliasing(half y, half x)
{
half v = x - y;
return saturate(v / fwidth(v));
}
之前的方案,由于外描线通常会做成粗细不随距离变化而改变,导致内描线和外描线的表现在缩放后会完全不同。这个瑕疵其实很明显。
而使用SDF描线,利用SDF的性质就能实现内描线粗细的动态设置。和外描线一样处理,就能和外描线的粗细保持一致了。
fixed4 frag (v2f i) : SV_Target
{
fixed4 col = tex2D(_MainTex, i.uv);
fixed r = 0.5 - tex2D(_LineTex, i.uv).a;
half w = _LineWidth * i.vertex.w;//乘下Clip空间的w,缩放线宽
col.rgb = lerp(col.rgb, _LineColor, stepAntiAliasing(r,w));
return col;
}
但是由于SDF的精度有限,过细的线会导致锯齿再度出现。
而且线框不能超出允许范围,需要用参数约束实际粗细的范围。
fixed4 frag (v2f i) : SV_Target
{
fixed4 col = tex2D(_MainTex, i.uv);
fixed r = 0.5 - tex2D(_LineTex, i.uv).a;
half w = clamp(_LineWidth * i.vertex.w, _LineMinWidth, _LineMaxWidth);
col.rgb = lerp(col.rgb, _LineColor, stepAntiAliasing(r,w));
return col;
}
声明:发布此文是出于传递更多知识以供交流学习之目的。若有来源标注错误或侵犯了您的合法权益,请作者持权属证明与我们联系,我们将及时更正、删除,谢谢。
作者:flashyiyi
来源:https://zhuanlan.zhihu.com/p/113190695
More:【微信公众号】 u3dnotes