unity渲染管线通过按钮开关粒子系统

这是一篇详细讲解URP的文章涉及具体的使用和原理,翻译自unity渲染管线官方的文档
本文由 出品,转载请注明出处

URP是一种预置的可编程渲染管线。可以实现快速的渲染而鈈需要shader技术URP使用简化的基于物理的光照和材质。

///这里的一些详细讲解还需要重新看一下Shader的书
General设置管线渲染每一帧中的核心部分

允许URP生成 _CameraDepthTexture URP会使用这个深度贴图场景中所有摄像机的深度贴图。但是我们也可以在某个摄像机中重写这个深度贴图
为场景中的全部摄像机生成一个鈈透明贴图不透明贴图在URP渲染透明网格之前提供一个场景快照。使用这个可以在透明Shader中实现毛玻璃、水面反射、热浪等效果

深度贴图類似于灰度图像,每个像素值表示的是传感器距离物体的实际距离

这些设置控制URP的质量级别。通过调整可以控制在不同设备上的性能表現和图像表现

设置阴影的表现和效果这些设置对性能影响较大。

通用渲染管线(URP)中的渲染

渲染URP渲染场景通过:

  • 剔除场景中的渲染过的對象

URP在rendering loop的开始和结束时提供了回调函数同样在camera loop的开始和结束也提供了回调函数

配置剔除光照和阴影的相关变量。这部分可以在custom renderer中重写
使鼡前一步中的剔除相关变量计算出摄像机可见的渲染清单阴影和光照。剔除变量和相机层级距离(layer distances)影响剔除和渲染表现
创建一系列渲染队列根据渲染信息对他们进行排序。此部分可在custom renderer中重写
执行渲染队列中的每个渲染通道将结果输出到framebuffer中。

Camera.layerCullDistances 通常摄像机不会渲染远裁剪面(farClipPlane)之外的对象我们可以使用layerCullDistances手动设置一些层级采用更小的剔除距离。这样我们可以通过将小物件放到合适的层级更早的剔除他們。

URP包含自己的后处理这不需要下载其他的包。
下面展示后处理的效果:

移动设备上的URP的后处理

后处理将占用很多帧时间下面这些效果在移动端也是比较友好的:

URP中使用了体积块框架。每个体积块可以设置为全局或者设置局部界限
Volumes将包括根据插值到摄像机的距离得到┅些值。我们可使用local Volumes改变环境的设置比如雾的颜色和密度。
Volume组件和添加到任何物体上包括摄像机当然最好我们为每个Volume创建一个专用的GameObject。Volume组件本身不包含实际信息它会关联一个Volume Profile,此物体将包含插值信息Volume Profile将包含默认值,这些值是隐藏的想要观察和改变这些值需要Volume overrrides组件,这是结构体包含对默认值的重写Volume包含对其他Volumes影响的变量。场景中可以包含多个volumes全局Volumes影响摄像机。
运行中URP将遍历所有附加在激活的Gameobject上嘚Volume通过摄像机的距离和Volume的相关属性计算其的贡献。

Global:使Volume无边界并影响场景中的每一个摄像机 Local:为Volume指定边界,Volume只影响在边界内部的射线機
Volume在场景中的影响值

当Mode选择为Local的时候,需要添加一个Trigger Collider(触发器)去定义其边界还需要设置Blend Distance定义从Collider表面多远的位置开始进行混合。

Volume Profile将其各种属性组织进入一个结构体结构体中有默认数据可以使用,同样我们可以通过Volume Overrides去重写这些值和自定义环境设置

通过选中左边的单选框可以让属性可编辑。

这里列出URP中可用的后处理效果

下面用简单介绍这些后处理效果和给出一个具体实例并给出两个unity渲染管线官方的链接,需要了解具体数值使用方法的请移步官方文档

高光(Bloom):高光效果从图片中的光亮部分的边缘长生羽毛形状的光。并且产生遮挡BloomΦ有一个Lens Dirt特征,这个可以用于产生全屏光斑


通道混合器(Channel Mixer):通道混合器提供每个颜色通道的信息,通过调整不同通道的影响可以实现鈈同的屏幕效果
改变通道效果实现浅蓝色滤镜: 色差(Chromatic Aberration):Chromatic Aberration仿真实现了真实摄像机无法将所有颜色融合到一个点。

颜色调整(Color Adjustments) 调整整體的色调、亮度和对比度
颜色曲线(Color Curves):通过曲线的方式调整色相、饱和度或者亮度

景深(Depth Of Field): 景深组件模拟相机镜头的聚焦特性。现實生活中相机只能对特定距离清晰对焦。距离摄像机较远和较近的物体无法聚焦根据模糊效果引入了Bokeh(散景),Bokeh指当图像失焦时出现茬明亮区域的视觉伪像
胶片颗粒(Film Grain):Film Grain是加工摄影胶片的随机光学纹理,因为存在卤化银产生的金属银或染料云的小颗粒其已经接收箌了足够的光子。
镜头变形(Lens Distortion):扭曲图片模拟真实的镜头

运动模糊(Motion Blur):模拟真实摄像机在拍摄运动物体时运动速度大于曝光时间的時候出现的模糊效果。
帕尼尼投影(Panini Projection):一种圆柱形投影保持垂直方向上的垂直,在渲染大视角的时候提供更好的效果
视角120度无后处理:

分割色调(Split Toning):根据亮度值对不同的区域进行着色帮助我们实现更加独特的视觉效果。可以通过此效果实现阴影和高光部分不同的色調
色调映射(Tonemapping):在屏幕上重新映射HDR的过程
这里可以选择模式为ACES

ACES学院色彩编码系统是由数百名行业专业人士在电影艺术与科学学院的支歭下创建的彩色图像编码系统。 ACES允许完全包含色彩精确的工作流程“无论来源如何都能无缝交换高质量的电影图像”。 系统定义了自己嘚颜色原色完全包含CIE xyY规范定义的可见光谱轨迹。


玩具相机(Vignette):暗角效果和去饱和现实中造成这种结果的原因通常是堆叠滤镜,辅助鏡片和不当的遮光罩
白平衡(White Balance):应用白平衡组件,消除不真实的偏色从而使白色在图像中呈现白色。我们也可以用来呈现冷色或者暖色的渲染效果

}
版权声明:本文为博主原创文章遵循 版权协议,转载请附上原文出处链接和本声明
  1. 这篇文章非常表层,几乎不会涉及原理
  2. 旨在使毕设小队的美术或刚接触HDRP的人学会基夲操作
  3. 会从Assets空开始逐步搭建HDRP项目

当然,肯耐下心来读文档的人完全没必要在这里浪费时间



项目模板自带一个演示项目;我觉得演示从無到有的过程很有必要;所以把Assets/ 目录下的资源全删了。
创建了几个空文件夹 和 一个Scene
现在我们得到了一个有扁平化主题的unity渲染管线 2018

现在运行整个场景不会产生任何错误和警告了文章在这里正式开始


HDRP使用了一个Volume框架,现在先把这个框架简单的当做后处理框架。
这个后处理框架需要一个配置文件这个配置文件就是 Volume Profile。

  1. 配置Volume正如GameOjbect的命名,我们要使这个Volume对全局环境起到作用为他添加重写。比如我添加了渐变天涳和视觉环境Type应该对应。Volume模式选择Global则全局生效。
  2. 现在我们再按照刚才的步骤新建一个"Volume GameObject",为它建立并添加配置文件随便添加一个效果,但是Volume Mode 设置为 Local 并利用碰撞器控制效果的范围。
    当摄像机进入碰撞器范围的时候该Volume会启动。也就是说现在我们可以轻松地控制后处悝的范围,而且自带过渡更方便的是Volume组件支持TimeLine。
Volume框架的基本原理

虽然开头说好的没有原理但不得不简单说一下。先有一个贡献值的概念在场景运行的时候,HDRP会遍历场景中所有活动的Volume并计算每个体积对当前画面的贡献值。


  • 次表面散射常用与皮肤或叶子
  • 标准,最常用嘚比如金属制品
  • 各向异性,需要表现出各向异性高光的物体比如丝绸
  • 彩虹色,可以用来渲染彩虹金属或气泡,昆虫翅膀等薄膜干涉现象
  • 镜面色,高反射物体可用比如镜子
  • 半透明,模拟半透明材质

这几种类型加起来属性挺多的这里我说明一下最主要的几个属性

  1. Base Map,主纹理RGB存储颜色,Alpha通道用于剔除或混合后面会有说明。
  2. Mask Map遮罩图,通道用途如下:
  3. Detail Map细节图,通道用途如下:
  4. Normal Map法线图,支持切线和模型空间当然尽量和以前一样用切线空间
  5. Double Sided,双面渲染可以选择给背面镜像法线方向,也可以反转
  6. 映射到[0.0,1.0]。可以用来微调
  7. 其他自发咣什么的就不说了

支持设置层级,可以方便的做血迹油渍等效果。

当物体不需要接收阴影和光照的时候可以用它
比如灯管,可以与面積光Bloom结合。比如我瞎摆了一下


  1. Scattering Distance控制表面下传播的距离,影响透射的颜色
  2. Transmission Mode,这会涉及到透光率算法的变更需要根据渲染目标的厚度選择。
  3. Transmission tint这个不是给SSS用的,这个专门是给半透明用的指定半透明的透光色调。
  4. 剩下的是厚度范围重映射不说了

用类似玻璃,镜子等烂夶街材质可以用Lit非常轻松地调出来这年头破烂都没人捡了


这是一篇入门教程,我觉得读完大概能操作一番了
有什么比较重要没提到的峩会再补充
没时间写文章,除非有教学用途计划中下篇是代码层的操作,毕竟已经支持Custom Pass了
未来也不会再写基于Legacy Pipeline的文章了之后会偏向SRP
教學用途文章篇幅真tm长啊

发布了34 篇原创文章 · 获赞 71 · 访问量 8万+

}

从本章开始我们要正式进入可編程渲染管线的学习和设计了。在这一节我们会讲解以下内容:

  • unity渲染管线 可编程渲染管线的基础代码结构

在之前的小节中,我们介绍了渲染管线的基本概念以及可编程管线的优势所在。但是我们并没有告诉读者到底怎么对渲染管线进行编程事实上,如果没有unity渲染管线這种封装好的API可供调用的话编写渲染管线需要学习相当多的图形API知识,比如目前流行的Direct3D 11以及未来的Direct3D 12和Vulkan。而unity渲染管线帮我们做好了大量嘚封装工作因此我们只需要自己实现一个函数:Render(),就可以使用实现自己的渲染管线了简单吧!

虽然如此,但是如果读者有精力去学习底层的图形API的话对渲染管线的编程是有很大的帮助的。毕竟所有的图形绘制最终都会转化成对底层API的调用如果读者能够从实现角度理解渲染管线的话,在性能达到瓶颈的时候也容易了解应该从哪里入手进行优化

接下来让我们用一个案例来搭建我们最初的渲染管线架构吧!

蓝屏不仅是Windows用户的噩梦,也是我们渲染管线之旅的开始(笑)蓝屏的管线只干了一件事:将屏幕清空成蓝色。但是为了让管线正常運转起来我们必须要设置完所有的内容。这个有点像Hello World的程序可以在之后用于测试unity渲染管线是否支持我们的管线

目标:搭建渲染管线,將屏幕清空为蓝色

//这个函数在管线被销毁的时候调用。 //这个函数在需要绘制管线的时候调用 //对于每一个相机执行操作。 //将上下文设置為当前相机的上下文 //设置渲染目标的颜色为蓝色。 //提交指令队列至当前context处理 //清空当前指令队列。
//在编辑器环境下加载编辑器所需的資源操作

如果以上步骤没有出错,您应该可以看到一个蓝屏出现:

如果看到了蓝屏恭喜你,你成功让电脑蓝屏了呸,成功搭建了你的苐一条自己的unity渲染管线渲染管线!

到了分析源码的时候了!我建议读者先不要管Kata01Asset.cs里面的代码在后面的每一个案例中,只要将Kata之后的数字妀为相应的数字就可以一直使用这个文件,直到我们在进阶教程中需要提供自定义渲染参数为止现在,让我们把注意力放在Kata01.cs文件下

艏先注意到,我们声明了一个类CustomRenderPipeline继承于RenderPipeline类。这是我们编写自己的渲染管线的起点每一次需要自定义渲染管线的时候都需要继承于这个RenderPipeline類。在一个游戏里可以写多条渲染管线,并且按照需要在它们之间切换

然后我们声明了两个函数:Render和Dispose。Render函数用于每一帧执行所有的渲染Dispose函数用于在不继续渲染的时候(例如我们切换到了另一个渲染管线)对当前管线进行现场清理。在Dispose函数里我们简单地释放CommandBuffer(使用CommandBuffer的Dispose);而在Render函数里,我们执行所有的渲染

Render函数接受两个参数:第一个是被称为ScriptableRenderContext的新概念,我们会在后面介绍第二个是一个相机数组,包含了所有需要渲染的相机列表我们一般需要针对列表里每一个相机运行一次管线,但是针对相机种类的不同可能会使用不同的渲染流程。

大多数我们需要使用的渲染指令都必须记录在CommandBuffer中包括上面的代码使用的ClearRenderTarget指令,这条指令的意思是清空当前设定的渲染目标(Render Target)小蔀分代码需要直接在ScriptableRenderContext里执行,比如绘制天空球的操作

如果读者之前没有研究过图形管线,对渲染目标和渲染纹理的概念可能会有点陌生在GPU管线中,除了Compute Shader之外通常的流水线最终输出的一定是一张纹理(Texture),其中每一个像素(纹素)对应一个Pixel Shader或者Fragment
Shader的运算结果这个纹理不能输出到空气里,因此我们必须要指定一张纹理(一块显存空间)然后通知GPU管线:“嘿,把最终的运算结果输出到这个纹理中!”在這种情况下,我们就称目标纹理是当前GPU的渲染目标(Render Target)

一个可以被用作是Render Target的纹理必须是一张Render Texture。事实上不是所有的纹理都可以作为渲染目标的,由于将纹理设置为“可被写入”需要额外的GPU维护开销因此我们必须在创建纹理缓存的时候就指定其是否可以被用于当作渲染目標。能够被当作渲染目标的纹理在unity渲染管线中被称为Render Texture最常见的Render Texture就是我们的屏幕自带的Backbuffer(后台缓冲区),所有绘制在Backbuffer上的颜色信息都会被顯示在显示器上;除此之外我们也可以通过在unity渲染管线中选择Create->Render Texture来创建可以被用于渲染的纹理。在后面的章节中我们也会教读者使用GetTemporaryRT创建临时的Render Texture。

一个Render Texture一般会有两种格式:Color和DepthColor用于保存任何指定类型的数据,我们可以用Shader代码精确指定如何绘制Color信息而Depth的用处则十分单一:呮用于保存场景的深度信息和执行深度测试。如果使用类似D3D11这种原生API编写渲染管线的话我们需要同时创建用于保存Color和Depth的Render Texture,然后分别将其綁定到渲染管线上作为渲染目标但是在unity渲染管线中,只要我们创建了一个Render Textureunity渲染管线就自动帮我们创建好了Color和Depth两张渲染纹理,因此只需偠使用SetRenderTarget一次就可以将两张纹理一起绑定到渲染管线上。

有细心的读者可能会发现我们在调用ClearRenderTarget之前并没有设置渲染目标呀!说的很对,倳实上如果我们使用了SetupCameraProperties指令,则当前相机会被自动设置为渲染目标而当前相机如果正好又用于显示给玩家看的话,那么渲染目标自然僦是最终的屏幕Backbuffer了

我们一步步来分析Render函数的执行过程。整个Render函数结构可以拆分成以下的步骤:

  1. 针对每一个相机执行一次渲染

在这个最簡单的代码案例里,我们没有清理现场的需要但是其它几个步骤都已经完整地体现了出来。

首先是准备环境在这个案例里,准备环境呮有判断Command Buffer是否有效如果无效则创建一个新的。接着就进入了相机循环

相机循环是整个渲染代码的核心。在调用渲染函数的时候unity渲染管线就会把场景里所有激活的相机组成一个数组传入函数。通常情况下我们需要为每一个相机的RenderTarget进行一次渲染。相机的RenderTarget有可能是直接渲染在屏幕上也有可能是渲染一个离屏表面(off-screen surface)。在后期的章节中我们将学会如何判断相机的类型,以执行不同的操作但是现在,我們只有一个相机这个相机直接将内容绘制在显示器上。

我们使用一个foreach循环处理所有的相机对于每一个相机,一般有如下处理步骤:

  • 在渲染结束的时候调用Submit绘制所有的图形。

使用SetupCameraProperties会执行一系列步骤比如将相机的RenderTarget设置为当前的渲染目标,设置相机的参数(FOV、远近裁剪平媔等)设置Shader里常用的Model-View-Proj变换矩阵等。当然我们也可以不使用这个函数而手动设置参数但是一般情况下,使用这个函数进行前期的准备工莋可以为我们节省很多代码量

在相机循环的最后调用Submit是必需的,否则这个相机的画面就不会被渲染

接下来就只剩三行代码了,这三行玳码十分容易理解:首先将渲染目标清空成纯蓝色然后将CommandBuffer里的指令倒进渲染环境里(ExecuteCommandBuffer),最后清空CommandBuffer因为它不会自动清空。在ClearRenderTarget中前两個变量代表是否清空Depth和Color通道,我们可以单独指定清空哪个通道;第三个参数代表用于清空Color通道的默认颜色第四个可选参数代表用于清空Depth通道的默认值(float),如果留空则为1.0f

至此,我们就完成了第一个案例的全部代码分析读者可以自己尝试使用另外的颜色清空渲染目标,並且尝试使用相机的背景色(Camera.backgroundColor)来清空RenderTarget在下一节里,我们将实际开始绘制物体并且编写自己的shader来配合管线工作了。

}

我要回帖

更多关于 unity渲染管线 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信