准备好镜子和镜中世界的天空球和物体
找到URP正在使用的Universal Renderer Data
添加 一个Render Object,通过Layer指定为对镜子产生影响
在渲染最开始直接对镜子的范围内写入模板测试的值,这里用1标识镜子范围
事件时间发生在BeforRenderingPrePasses,也就是什么都还没开始渲染的时候,先把镜子的模板值写入供日后使用
Layer选择Mirror对应镜子模型的Layer
深度不要写入并且关闭深度测试,因为我们的目的只是写入模板值
模板Stencil值设置为1,通过条件设置为总是通过,且只对通过的位置做操作写入值,所以其他两项为Keep保持原值即可
现在模板值写上了,想要达到想要的效果必须由我们控制镜中模型的渲染,所以我们把镜子包括镜中世界的模型全部在Shader Grapgh中设置为不写入深度且从不通过深度测试
这样,这几个模型因为没有深度值,且无法通过测试就不会在不透明队列中渲染了,才能留给我们修改的空间,否则只能在不透明队列渲染完毕后进行操作,会出现无法被前方物体遮挡的情况,虽然也是一种效果,但是我们这里想要的不是它。
如果在不透明队列渲染完毕后进行操作,并把境内世界的天空球深度测试设为总是通过的话(设置为总是通过需要让天空球的渲染在前,否则最后全都会被天空球的深度覆盖),可以看到应该在长方体后面被遮挡的镜子变得可视了
回到正题,把所有物体的深度都关闭,在Shaded WireFrame视图上看是这样的
模型在那里却没有正常渲染,这就对了,因为接下来要帮他们渲染
先处理天空球
添加天空球的渲染,时间选在不透明物体渲染前,Layer标定对应模型,深度写入开启并设置靠前的通过深度测试,模板选择等于1的通过,通过的位置模板保持原值1,不通过的保持原值0,这样可以把范围限定在镜子内,通过测试即可把颜色送去,即变成现在这样
添加模型的渲染
时间选在不透明物体渲染前,Layer标定对应模型,深度写入开启并设置靠前的通过深度测试,模板选择等于1的通过,通过的位置模板保持原值1,不通过的保持原值0,这样效果就有了
但是这样是有缺点的,如果这面镜子后面没有镜中世界模型以外的模型就没问题,一旦包含现实世界的物体,则现实世界中的物体也会影响镜中映射出的画面,因为我们是在不透明物体绘制前绘制完成了镜中世界,在这之后绘制的现实世界物体会写入新的深度,盖住原本的画面,目前我还没找到特别好的解决办法,感觉只能从代码处理Render Queue,让所有镜靠后的现实物体先渲染,然后渲染镜中世界用天空球的深度always全覆盖,然后渲染靠前的物体,才能让他不受现实世界物体影响。