当前位置:   article > 正文

Unity渲染管线概述 -- Shder入门精要学习(1)_渲染管线 《unity shader入门精要》

渲染管线 《unity shader入门精要》

1 应用阶段(CPU)

1.1 把数据加载到显存中

所有渲染所需要的数据需要从硬盘中加载到系统内存,然后网格和纹理等数据又被加载到显存中

如何获得渲染所需要的数据:进行剔除和排序

剔除:

  • 视锥体剔除Frustum Culling
  • 层级剔除Layer Culling Musk
  • 遮挡剔除Occulusion Culling

排序:

  • 渲染队列RenderQueue
  • 不透明队列(RenderQueue < 2500) 按摄像机距离从前到后排序
  • 半透明队列(RenderQueue > 2500) 按摄像机距离从后到前排序

1.2 设置渲染状态

渲染状态定义了场景中网格是如何被渲染的,使用哪个顶点着色器VertexShader/片元着色器FragmentShader、光源属性、材质等

打包数据:

  • 模型信息:顶点坐标,法线,UV,切线,顶点色,索引列表

  • 变换矩阵:世界变换矩阵,VP矩阵(根据摄像机位置和FOV等参数构建)

  • 灯光,材质参数:Shader,材质信息,灯光信息

1.3 调用DrawCall

绘制调用,DrawCall是一个命令,发起方是CPU,接收方是GPU

关于DrawCall的补充

DrawCall本身的含义:CPU调用图像编程接口

注意:DrawCall中造成性能问题的元凶是CPU而不是GPU

  1. CPU和GPU实现并行工作的方式:

利用命令缓冲区实现,当CPU需要渲染一些对象时,它可以向命令缓冲区中添加命令,而当GPU完成上一次的渲染任务后,它就可以从命令队列中取出一个命令并执行它,DrawCall就是这诸多命令中的一种

  1. DrawCall如何影响帧率:

每次调用DrawCall之前,CPU需要向GPU发送很多内容,如数据、状态、命令等。

然而GPU渲染能力很强,因此渲染速度往往取决于CPU提交命令的速度。

如果DrawCall数量太多,CPU就会把大量的时间花费在提交和准备DrawCall上,造成CPU过载

  1. 如何减少DrawCall

采用批处Batching的方法,例如将图集打包,将静态的物体合并等

  1. 如何减少DrawCall的开销
  • 避免使用大量很小的网格
  • 避免使用过多的材质,尽量在不同的网格中共用一个材质

2 几何阶段(GPU)

在这里插入图片描述

2.1 顶点着色器(Vertex Shader)

用于实现顶点的空间变换、顶点着色等功能

  • 坐标变换:通过MVP矩阵将顶点坐标从模型空间转换到齐次裁剪空间,也可以改变顶点位置模拟水面,布料等
  • 逐顶点光照

可以加入可选着色器:

  • 曲面细分着色器(Tessellation Shader):用于细分图元
  • 几何着色器(Geometry Shader):用于执行逐图元的着色操作,或被用于产生更多的图元

2.2 裁剪(Clipping)

将不在摄像机视野内的顶点裁剪掉,并剔除某些三角图元的面片

  • 完全在视野内的图元 - 传递给流水线下一阶段
  • 完全在视野外的图元 - 不继续传递
  • 部分在视野内的图元 - 进行裁剪

无法编程,为硬件上的固定操作

补充:转换到NDC标准坐标系之后即可进行背面剔除

2.3 屏幕映射(Screen Mapping)

  • 不可配置和编程,把每个图元的坐标转换到屏幕坐标中
  • 不会对输入的z坐标做任何处理
  • 屏幕坐标系和z坐标系一起构成了一个坐标系,叫做窗口坐标系Window Coordinates

3 光栅化阶段(GPU)

3.1 图元装配及光栅化

  1. 三角形设置(Triangle Setting)

固定函数阶段,计算光栅化以一个三角网格所需的信息(即进行生成图元,将上一个阶段获得的顶点装配成三角形图元)

  1. 三角形遍历(Triangle Traversal)

固定函数阶段,获取三角形三个顶点的颜色,并根据该顶点信息对覆盖区域的像素信息进行插值,即光栅化

3.2 片元着色器(Fragment Shader)

可编程的,实现逐片元的着色操作

输入是上一阶段对顶点信息插值得到的结果,输出为一个或多个颜色值,同时完成纹理采样,光照计算等操作

  1. 纹理技术
  • 纹理采样:给定一个数值去寻找纹素地址对应的像素的颜色值(例如通过UV坐标映射到纹素地址上)
  • 纹理过滤机制:对一些计算出来的像素结果四舍五入,同时利用双线性插值方法对于放大的图片进行插值
  • Mipmap:将大图像映射到小区域里时,针对原图生成一系列大小不同的图像,形成一组纹理链,根据映射区域的大小选择图片
  • 纹理寻址模式
  • 纹理压缩格式
  1. 光照计算

光照组成:直接光+间接光

光照模型:

  • Phong光照模型:Diffuse(漫反射)+Specular(镜面反射)+Ambient(环境光) = Phong Reflection
  • 基本框架:直接光漫反射+直接光镜面反射+间接光漫反射+间接光镜面反射

3.3 逐片元操作(Per-Fragment Operations)

执行很多重要操作,如修改颜色、深度缓冲、进行混合等,不可编程,具有很高可配置性

  • 决定每个片元的可见性
  • 如果一个片元通过了测试,就要把这个片元的颜色值和已经存储在颜色缓冲区中的颜色进行合并

逐片元操作具有高度可配置性,可以设置每一步的操作细节

在这里插入图片描述

  1. 模板测试:即颜色缓冲,深度缓冲
  2. 深度测试:将该片元的深度值和已经存在于深度缓冲区中的深度值进行比较
  3. 合并:对于不透明的物体,关闭混合操作,使其完全覆盖;对于半透明的物体,开启混合操作使物体看起来是透明的
  4. 混合:使用混合函数进行混合操作,根据透明通道的值进行相加、相减、相乘等。

Early-z技术:将深度测试提前到片元Shader之前,这样就可以早知道哪些片元是被舍弃的,对于这些片元就不需要再使用片元着色器计算其颜色了,同时提前这些测试有可能会与片元着色器发生冲突,现代CPU会判断这些冲突

4 补充

4.1 什么是OpenGL/DirectX

OpenGL/DirectX即图像应用编程接口,用于渲染一些二维或三维图形,架起了上层应用和底层CPU的沟通桥梁

应用程序运行在CPU上,通过调用OpenGL或DirectX的图形接口将渲染所需的数据存储在显存中的特定区域,随后开发者通过图像编程接口发出渲染命令DrawCall,他们将会被显卡驱动翻译成GPU理解的代码,进行真正的绘制

4.2 什么是HLSL,GLSL,CG

着色语言有DirectX的HLSL,OpenGL的GLSL,NAVIDIA的CG

  1. HLSL:由微软控制着色器的编译,平台相对有限,基本是微软自己的产品
  2. GLSL:由于OpenGL没有提供着色器编译器,而是由显卡驱动来完成着色器的编译工作,取决于硬件供应商,所以有很强的跨平台性
  3. CG:真正意义上的跨平台,会根据平台的不同,编译成相应的中间语言

Unity中,可以选择使用”CG/HLSL“或者”GLSL“

参考:
UnityShader入门精要
技术美术入门:渲染管线概述

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/Gausst松鼠会/article/detail/116382
推荐阅读
相关标签
  

闽ICP备14008679号