UE4关于RenderInDepthPass不起效问题及解决(半透明头发那些事)
半透明的物体一般不会写Depth,就会导致模型的内部和背面也被画出来,模型就会看起来像一个透视图。解决这个的方法是在第一个Pass中只写入Depth,不渲染任何像素(只作为Mask),然后在第二个Pass中把RenderState设为DepthLEqual,这样就可以用DepthTest过滤掉我们不希望渲染出来的内部和背部了。我在UE4.24中尝试用这个思路解决头发的半透明渲染乱序的问题,但是发现诸多问题。
第一个Pass中只写入Depth,最开始我用的方法是关闭模型选项Render In Main Pass,仅写入CustomDepth
问题1:mobile RenderInMainPass和CustomDepth冲突
表现:模型勾选Custom Depth则RenderInMainPass失效(无论是否启用模型都会渲染)
官方解决:
我参照官方Bug页面解决了这个显示问题,不过后来我发现CustomDepth并不对正常的深度测试有效,半透明还是会乱序,不过CustomDepth可以通过在半透明材质中去手动抠出来实现深度测试,具体做法可以参考网上的很多类似文章,我列举几个:
不过应用到移动端中也有问题,具体可以参考我的另一篇文章UE4 CustomDepth mobile es3.1不起效问题 - 知乎 (zhihu.com)。这里暂时搁置这个Bug。
下面还是讨论作为Mask的物体正常Depth写入。
问题2:Render in Depth pass模型选项无效
预期:关闭RenderInMainPass的情况下勾选Render in Depth pass渲染深度
实际:关闭RenderInMainPass,即使勾选Render in Depth pass仍然不渲染深度,无论PC还是Mobile ES3.1都无效(测试工具:RenderDoc)
类似问题:
经实测发现即使勾上Render In Depth,也不会渲染深度~
解决方案:
对于StaticMesh而言,找到其GetViewRelevance函数(其它每种Mesh都有对应的GetViewRelevance函数这里不列举了)
\Engine\Source\Runtime\Engine\Private\StaticMeshRender.cpp FStaticMeshSceneProxy::GetViewRelevance(...)
...
Result.bRenderInMainPass = ShouldRenderInMainPass();
在此处添加一行代码:
+ -> Result.bRenderInDepthPass = ShouldRenderInDepthPass(); (这就是为什么开启了Render In Depth Pass选项却没有渲染深度的原因,估计是程序员漏写了~)
...
ok, build ue4 project , 问题解决。
我们再来测试一下,关闭Opaque模型的RendeInMainPass并且打开RendeInDepth:
这里有点奇怪的是这么一整后头发变成黑色了,猜测一下原因应该是因为写入了头发深度,由于深度测试这里本该渲染头发,而我们又关闭了头发的MainPass渲染,所以就没有任何颜色写入,就是黑色了。
打开Buffer可视化看一下SceneDepth:
已经成功渲染到了SceneDepth。这样我们再叠加一层半透明上去,头发Alpha乱序完美解决:
RendeInDepth这个问题应该是引擎bug,并且一直到我所使用的UE4.24版本并没有解决
总结:
对于半透明头发基本是两种方案:
一. 用两个重叠模型,第一个仅写入CustomDepth作为深度Mask,半透明材质中通过PixelDepth与CustomDepth比较解决乱序
二. 改引擎,实现仅RenderInDepth(这个方法还是要搞两个重叠模型还要改引擎,不推荐)
或者是改引擎实现双Pass渲染,不过这个在UE4中改起来也是非常麻烦的。
如果大家有什么更好的解决方案欢迎留言告诉我~
欢迎大家来我的主页坐客:
欢迎大家加入UE4游戏开发爱好者交流群:1101298523
页:
[1]