Unity描边的几种方式(包括UGUI文字描边)

参考:在shader中实现五种描边方法

从描边方式上来讲,大体可分为两种,一种是对着原模型往外扩大挤出,然后通过某种方式裁剪掉与原模型重合的地方,来实现描边。另一种则是通过算法算出一张图片里,

那些地方是边缘。

注:以下用到双通道的方式,如果是在新版Unity里,开启了URP(自定义渲染管线,默认只支持Shader单通道) ,需要在Shader里为两个通道都加上Tag,否则默认只允许第一个LWRP(URP)学习笔记二多PASS的使用

参考:URP多Pass解决方案

Pass1加入:Tags { "LightMode"="SRPDefaultUnlit" }

Pass2加入:Tags { "LightMode"="UniversalForward" }

 

1.背面渲染法

需要2个渲染通道:

其实就是把下面的模板测试换成了剔除操作。正常渲染的时候剔除背面渲染正面,第二次顶点扩张之后剔除正面渲染背面,这样渲染背面时由于顶点外扩的那一部分就将被我们所看见,而原来的部分则由于是背面且不透明所以不会被看见,形成轮廓线渲染原理。因此从原理上也能看出,这里得到的轮廓线不单单是外轮廓线。

 

2.模板测试法

参考:unity-shader模板测试-描边

参考:unity 描边之stencil篇

需要2个渲染通道:

第一个渲染通道,正常渲染,同时开启模板测试,把每个片元的参考值 Ref 都设置为1,Comp Always 总是通过模板测试, 并且 Pass Replace (不写的话默认是 Pass Keep),即把当前对象所渲染区域的所有像素都用Ref值写入模板缓冲。

Stencil
            {
                Ref 1
                Comp Always
                Pass Replace
            }       

第二个通道,把模型往顶点法线方向往外扩一定距离(描边的宽度),在这个Pass中,我们同样把每个片元的参考值 Ref 都设置为1,Comp NotEqual 即只有当前参考值 Ref 和当前模板缓冲区的值不相等的时候才去渲染片元。也就是说,最终只会渲染出模型挤出后并裁剪掉原来模型的部分。即Pass2的渲染区域与Pass1渲染区域的一个补集。

Stencil
            {
                Ref 1
                Comp NotEqual
            }       

 

3.1.边缘检测法

这种方法其实是用屏幕后处理效果去实现的(也就是基于图像处理)。

屏幕后处理,通常指的是在渲染完整个场景得到屏幕图像后再对这个图像进行一系列操作实现各种特效。这里实现的原理其实是使用特定的材质去渲染一个可以刚好填充整个屏幕的四边形面片。

而边缘检测的原理其实就是用一个特定的卷积核去对一张图像卷积,得到梯度值,再根据梯度值的大小去判断是否为边界。

可以理解为对整张图片逐个像素进行判断,判断每个像素周围的像素,如果符合条件,那就说明该像素是处于边缘的像素

缺点:因为是对整张图片进行处理的,没有深度信息,所以没办法区分物体的边缘,图片上所有的明暗分明的地方都会被勾勒出来,例如影子,纹理上的条纹等。

 3.1.边缘检测法

在上面的算法优化下,同样的整张图片后处理,但是加入了深度纹理(深度纹理与法线纹理 - JeasonBoy - 博客园 (cnblogs.com),有了场景里物体的深度信息,所以能实现区分真正的物体边缘

缺点:由于是整张图片处理,所以只能处理场景的全部信息,不能对某一个物体单独描边。

 

4.基于观察角度表面法线法

 

5.SDF法

 

6.UGUI文字描边法

Unity里默认的Text描边方式很简单粗暴,就是复制4个一样的文字,分别放在当前文字的底下四周,如果文字描边比较细的话,效果还不错,但如果描边比较粗,就会造成看起来断裂了一样

当然也有解决方案,就是多复制几分,来达到圆滑边缘的目的,参考:n-yoda/unity-vertex-effects: Beautiful text outline for Unity UI. (github.com),但是这样大代价是文字量越多,造成的性能损耗会非常大,

因为,一个文字需要6个顶点,N个文字,复制M份,那就是 n*(m+1)*6个顶点,数量非常爆炸。

 

于是只能通过Shader方式来实现描边优化

参考:【Unity】UGUI描边的优化实现  

原理大致是:这个实现就是在C#代码中对UI顶点根据描边宽度进行外扩,然后在Shader的像素着色器中对像素的一周以描边宽度为半径采N个样,最后将颜色叠加起来。通常需要描边的元素尺寸都不大,故多重采样带来的性能影响几乎是可以忽略的。

有点类似上面的边缘坚持描边法

 
posted @ 2022-11-09 17:49  JeasonBoy  阅读(4209)  评论(0编辑  收藏  举报