3D角色遮挡住UI的实现,关于Stencil Buffer,描边,以及其他

来源:互联网 发布:手机淘宝如何退货退款 编辑:程序博客网 时间:2024/06/06 09:31

3D角色遮挡住UI的实现,关于Stencil Buffer,描边,以及其他

我这么懒的人能会写这篇博客,主因是这个需求对我造成的大量伤害~~~

起因

最近服务器AI的工作刚刚阶段性完成,马上被策划拉过去做一个渲染的效果,需求是这样的:在游戏中被选中敌人是有一个红色描边的,同时会有一个感知箭头(一个UI提示图表),现在这两个都会显示在主角上面。现象如下

前面的这个怪物X假设为主角(原谅我只能拿以前项目的资源了,那公司黄了应该不会来找我吧~~),更远处的那个是怪物,白色格子是一个UI 图片,现在均可以渲染在主角上面,影响视觉感受。希望主角可以挡住描边以及特定UI。

这里要先提前说一下描边的实现,目前主要的描边实现方式有几种

(1)有的是渲染在角色上的,即对角色模型根据法线方向或者offset进行外扩,实现描边

(2) 类似于posteffect的方式,用一个摄像机单独渲染需要描边角色,然后对得到的rendertexture进行模糊放大,再cut off掉原图进而得到描边的rendertexture,然后合并到场景摄像机上面渲染即可。

(3) 根据模型法线方向以及view 方向进行计算,叠加颜色实现边缘光的效果。

项目现在的是第二种方法,后面代码部分会有展示,另外几种方式大家如果感兴趣可以自行google下,相关的帖子很多。

坑坑坑,biu 

于是乎~~这需求就是要某个3D角色可以盖住UI以及这个描边图呗。其实在最初的需求中是没有挡住描边的,所以我的第一个想法是利用Stencil Buffer。订制主角和UI的Shader,主角会写入特定的stencilValue,UI在这个值下不会通过stencil test,代码如下:

UI部分

Stencil{<span style="white-space:pre"></span>Ref [_StencilValue]Comp NotEqual//Pass [_StencilOp] //ReadMask [_StencilReadMask]//WriteMask [_StencilWriteMask]}

主角部分

Stencil{Ref[_StencilValue]Comp AlwaysPass replace}

这样就应该是OK了!!(这里推荐一篇Stencil Buffer相关的博客:)在测试场景中,角色成功挡住了UI图标。然而,,在运行时,,并没有效果。。。Orz。。

经过测试,涉及stencil buffer的代码并没有问题。那么,只有一个可能是模板缓存被清掉。

谁偷走了我的Stencil Buffer?

上面提到过,我们的描边实现是posteffect的方式做的,在OnRenderImage中做了很多处理。在OnRenderImage中实现功能必然会使用到Graphics.Blits这个方法,类似代码:

void OnRenderImage(RenderTexture src, RenderTexture dest ){Graphics.Blits(src,dest);}

经过排查发现,注释掉上面代码之后效果恢复正常。

这是为什么呢!!!让我们看看官方的解释:



真是悲剧!描边兄给我挖了一个小坑。

解决方案

后续过程中,我把描边输出的RenderTexture输出到了Ugui中的一个Raw Image单独渲染,而不是在主摄像机中使用OnRenderImage方法把这张图渲染在摄像机中。这个描边图片同样使用UI订制的那个材质球,这样就会被主角挡住了。
下面会分享一个展示项目,包含了所有细节。
后续应该会优化描边中的blur shader,现在锯齿效果有点严重,可能会考虑下使用描边中第一种实现方式,那样效率应该会高上不少。
第一次分享博客哈,感觉写的丑的话大家就点赞鼓励下吧!

项目下载:http://pan.baidu.com/s/1bpiaqWv


0 0
原创粉丝点击