软件:Unity 2022.3.51f1c1、vscode、Meta XR All in One SDK V72
硬件:Meta Quest3
仅针对urp管线
博主搞这个主要是想做现实里的人的变身功能,最后效果如下
可以看到虽然身体是半透明的,但是裙子依旧被完全遮挡了
原理是参考unity的官方urp示例,使用RendererFeature更换被遮挡物体的材质
Unity - Manual: Example of creating a custom rendering effect via the Render Objects Renderer Feature in URP
实现步骤:
一、使用BuildingBlocks设置透视环境
注意:透视有个坑是camera不能开postprocessing(后处理),开后处理会导致环境全黑
二、配置一个具有全身追踪的玩家物体,可参考这篇
【Quest开发】全身跟踪(一)_quest3如何识别跟踪脚部-CSDN博客
我为了绑定准确直接使用meta默认的全身追踪示例
三、材质设置
身体材质:身体材质的shader需要是透明但写入深度(DepthWrite)的,这里我直接复制了一份meta提供的oculusHand改了参数给到了Mesh里的材质
ps.不用默认透明lit shader的原因是这个shader只参与深度测试但是不写入深度(也就是它能被别的东西遮,但是不能遮别的东西)
衣服材质:我直接用的默认lit shader材质。要求是在Transparent队列里,即使衣服本身不透明(原因在配置RendererFeature里解释)
被遮挡时替换的材质:为了让被遮挡的衣服不可见,也就是达成遮挡的效果,应创建一个透明材质(我这里又复制了一个oculusHand调成了全透明,lit的透明材质应该也行)
四、修改物体层级
新建一个Layer:Clothes,给自己的衣服改成这个层级
五、配置RendererFeature
1、找到自己正在使用的渲染管线使用的renderer(渲染器)
2、点击Renderer Data后选中最下方的add Renderer Feature
选择Render Objects
3、配置如下
这个渲染器的意思就是,在所有物体渲染完后,再对Clothes这个层级的透明队列里的物体再次进行渲染处理,当深度测试发现该层级有物体顶点?片元?处于别的物体后面时(也就是自身深度值大于当前像素点存储的深度缓冲区值时)就会把被遮挡的那个片元替换为ClothesTransparent材质
这样就完成啦,编辑器里应该能看见效果了。
现在来解释为什么衣服需要在Transparent队列里
因为渲染时,opaque(不透明)队列和Transparent(透明)队列是分开渲染的,opaque队列比Transparent队列先渲染。而我们添加的RendererFeature是针对Transparent队列的,那么如果衣服位于opaque队列的话,显然没法检测到
我相信会有人想那给rendererFeature改成针对opaque队列,衣服就可以在opaque里了呗。不行哈,遮不住一点,会变成下面这样。我还没有想通为什么,我贫瘠的渲染知识理解到这已经是极限了,希望大佬评论区解答吧。
2025.4.28
注意,当衣服使用lit材质的transparent时,会发现衣服自身重叠部分渲染奇怪,这也是由于这个shader不写入深度的原因,有这种困扰的朋友们可以自己建个shadergraph把深度写入和深度测试都打开