【博物纳新】专栏是UWA旨在为开发者举荐新鲜、易用、乏味的开源我的项目,帮忙大家在我的项目研发之余发现世界上的热门我的项目、前沿技术或者令人惊叹的视觉效果,并摸索将其利用到本人我的项目的可行性。很多时候,咱们并不知道本人想要什么,直到某一天咱们遇到了它。


随着越来越多的我的项目应用URP管线,以及更多的我的项目的特效压力越来越大,因而本篇文章基于GitHub上的一个我的项目将其从Builtin管线下移植到URP修改版,给大家提供了URP管线下升高特效GPU压力的做法,以供大家参考。

GitHub我的项目:OffScreenParticleRendering
https://github.com/slipster21...

这个库做的工作是将粒子系统或者半透明的渲染对象独自渲染到RenderTexture中,而后再将RenderTexture与不通明的渲染进行混合。独自渲染到RenderTexture的益处是能够通过升高RenderTexture的分辨率从而缩小GPU的渲染压力。

Builtin管线下最终交融成果


Builtin管线下RenderTexture的渲染成果

为了能将此性能移植到URP下,咱们先阐明一下原始我的项目中Builtin管线下性能实现的关键点,具体细节在原GitHub我的项目的阐明文档中有阐明,次要步骤如下图1,2,3,4。

#1 主相机中渲染不通明对象,且因为渲染半透明时须要做深度比拟,因而主相机的depthTextureMode须要设置为DepthTextureMode.Depth。

#2 在OnRenderImage中将_CameraDepthTexture进行DownSample。

#3 在OnRenderImage中从主相机复制一个相机,此相机渲染到RenderTexture,且RenderTexture能够调整分辨率,在此相机中独自渲染粒子系统和其余半透明对象。调用拷贝的离线渲染相机的Camera.Render,这样能够保障离线相机的渲染程序是在主相机之后渲染的,否则设置了RenderTarget的相机会优先比没有设置RenderTarget的相机先渲染。半透明的对象的Shader须要做非凡解决,须要将半透明对象和渲染场景生成的深度进行比拟,比不通明对象离相机更近的像素才会被“绘制”到RenderTexture上。

PS:在原始我的项目中渲染Particle的Shader中少了“COMPUTE_EYEDEPTH(o.projPos.z);”,所以成果看上去不太对,在vert函数中增加上这句就OK了。

#4 在OnRenderImage的最初通过OffScreenParticle_Upsample Shader将Particle等半透明的RenderTexture交融到不通明场景中。此Shader中将RenderTexture的色彩通过Blend SrcAlpha OneMinusSrcAlpha的形式进行原色混合,从而和主场景进行混合。

以上就是原始Builtin管线下的实现思路,转到URP下,有几个问题须要思考:

  1. OnRenderImage在URP下是不反对的。
  2. 是否还须要额定的相机来实现半透明对象的渲染。
  3. 如何解决最初的交融操作。

在URP下,对于第一个问题,有专门的RenderFeature能够对应OnRenderImage的操作;第二个问题,并不需要额定的相机来渲染半透明对象,只须要模拟URP自带的CopyColor来实现渲染另外RenderTexture的操作即可,只是BlitCopy应用的材质球不一样;第三个问题,同样用另外一个RenderFeature来实现即可。

URP下的实现成果:

URP下RenderTexture中渲染OffScreen Particle的成果如下:

在此工程中,次要的点如下:
1、移除额定的Camera,勾销了OffScreenParticleCamera脚本的作用。主相机须要开启Copy Depth。额定加了一个Particle的Layer,粒子特效的层改成Particle了。

2、新增了两个RenderFeature,OffScreenParticleFeature和OffScreenMergeFeature。后面的是用来绘制Particle的,前面的是用来做主场景和Particle交融的。在OffScreenParticleFeature中增加了2个Pass,一个绘制Particle到_ParticleRT,一个对Depth进行降采样,绘制到_CameraDepthLowRes,OffScreenMergeFeature中有一个Pass,应用MergeShader进行交融。

3、OffScreenMergeFeature用到的Shader是MergeShader,依据原工程中OffScreenParticle_Upsample Shader进行批改的。

4、为了让Particle层只在OffScreenParticleFeature中进行渲染,须要将两个Shader的LightMode更改为一个自定义的字符串,并且在OffScreenParticleFeature中将这个“OffScreenParticle”退出到ShaderTagList中,ShaderTagList的值是由Pass中的Tags外面的LightMode的值决定的。

最终在FrameDebugger中确定好渲染队列:

  1. 渲染场景中不通明物体;
  2. Copy Depth到_CameraDepthTexture中;
  3. 应用OffScreenParticlePass进行Particle层对象的渲染,能够通过DownSample来调整RT的大小,原始大小或者1/2或者1/4;
  4. 对Depth进行降采样,渲染最终Merge中用到的_CameraDepthLowRes;
  5. 应用MergePass进行最终的Merge,应用的是MergeShader。

Unity Demo下载链接:
https://pan.baidu.com/s/1Zi1a...
明码:bksb