首页 > 其他分享 >unityshader_01

unityshader_01

时间:2022-09-02 22:57:19浏览次数:59  
标签:01 渲染 着色器 unityshader GPU 流水线 顶点 CPU

第一章 渲染流水线

1.1渲染流水线

1.1.1现实中流水线
在工业上,流水线被广泛应用在装配线上。
假设,老王有一个生产洋娃娃的工厂,一个洋娃娃的生产流程可以分为4个步骤:
在流水线出现之前,只有在每个洋娃娃完成了所有这4个工序后才能开始制作下一个洋娃娃。
但后来人们发现了一个更加有效的方法,即使用流水线。
虽然制作一个洋娃娃仍然需要4个步骤,但不需要从头到尾完成全部步骤,
使用流水线的好处在于可以提高单位时间的生产量。
理想情况下,如果把一个非流水线系统分成n个流水线阶段,且每个阶段耗费时间相同的话,会使整个系统得到n倍的速度提升。 
总而言之:流水线可以优化工作效率

1.1.2渲染概念流水线的过程
渲染流水线主要分成三个阶段:
应用阶段 —— 几何阶段 —— 光栅化阶段
应用阶段:
1.准备场景数据
摄像机位置,视椎体,场景中包含了那些模型
2.粗颗粒剔除工作
将不可见的模型剔除
3.设置模型渲染状态
材质,纹理,shader
几何阶段
几何阶段用于处理所有和我们要绘制的几何相关的事情。
例如,决定需要绘制的图元是什么,怎样绘制它们,在哪里绘制它们。这一阶段通常在GPU上进行。
光栅化阶段
这一阶段将会使用上个阶段传递的数据来产生屏幕上的像素,并渲染出最终的图像。
这一阶段也是在GPU上运行。光栅化的任务主要是决定每个渲染图元中的哪些像素应该被绘制在屏幕上。
它需要对上一个阶段得到的逐顶点数据(例如纹理坐标、顶点颜色等)进行插值,然后再进行逐像素处理。
这里的流水线均是概念流水线,是我们为了给一个渲染流程进行基本的功能划分而提出来的。
下面要介绍的GPU流水线,则是硬件真正用于实现上述概念的流水线。

1.2 CPU与GPU之间的通讯
渲染流水线的起点是CPU,即应用阶段
数据加载到显存中 —— 设置渲染状态 —— 调用Draw Call

1.2.1把数据加载到显存中
所有渲染所需的数据都需要从硬盘(Hard Disk Drive,HDD)中加载到系统内存(RandomAccess Memory,RAM)中。
然后,网格和纹理等数据又被加载到显卡上的存储空间——显存(Video Random Access Memory,VRAM)中。
这是因为,显卡对于显存的访问速度更快,而且大多数显卡对于RAM没有直接的访问权利。
PS:真实渲染中需要加载到显存中的数据要复杂许多。例如,顶点的位置信息、法线方向、顶点颜色、纹理坐标等。

1.2.2设置渲染状态
什么是渲染状态呢?一个通俗的解释就是,这些状态定义了场景中的网格是怎样被渲染的。
例如,使用哪个顶点着色器(Vertex Shader)/片元着色器(Fragment Shader)、光源属性、材质等。
如果我们没有更改渲染状态,那么所有的网格都将使用同一种渲染状态。

1.2.3调用Draw Call
Draw Call本身的含义很简单,就是CPU调用图像编程接口,
如OpenGL中的glDrawElements命令或者DirectX中的DrawIndexedPrimitive命令,以命令GPU进行渲染的操作。
在Draw Call上面有三个内容
(1)CPU和GPU是如何实现并行工作
如果没有流水线化,那么CPU需要等到GPU完成上一个渲染任务才能再次发送渲染命令。
但这种方法显然会造成效率低下。我们需要让CPU和GPU可以并行工作。而解决方法就是使用一个命令缓冲区(Command Buffer)。
命令缓冲区包含了一个命令队列,
由CPU向其中队头添加命令,而由GPU从中队尾读取命令,
添加和读取的过程是互相独立的。命令缓冲区使得CPU和GPU可以相互独立工作。
当CPU需要渲染一些对象时,它可以向命令缓冲区中添加命令,
而当GPU完成了上一次的渲染任务后,它就可以从命令队列中再取出一个命令并执行它。
命令缓冲区中的命令有很多种类
而Draw Call是其中一种,其他命令还有改变渲染状态等(例如改变使用的着色器,使用不同的纹理等)。

(2)为什么Draw Call多了会影响帧率
我们先来做一个实验:请创建10000个小文件,每个文件的大小为1KB,
然后把它们从一个文件夹复制到另一个文件夹。你会发现,尽管这些文件的空间总和不超过10MB,但要花费很长时间。
现在,我们再来创建一个单独的文件,它的大小是10MB,然后也把它从一个文件夹复制到另一个文件夹。而这次复制的时间却少很多!
这是为什么呢?明明它们所包含的内容大小是一样的。原因在于,每一个复制动作需要很多额外的操作,例如分配内存、创建各种元数据等。如你所见,这些操作将造成很多额外的性能开销,如果我们复制了很多小文件,那么这个开销将会很大。
渲染的过程虽然和上面的实验有很大不同,但从感性角度上是很类似的。
在每次调用DrawCall之前,CPU需要向GPU发送很多内容,包括数据、状态和命令等。
在这一阶段,CPU需要完成很多工作,例如检查渲染状态等。而一旦CPU完成了这些准备工作,GPU就可以开始本次的渲染。
GPU的渲染能力是很强的,渲染200个还是2000个三角网格通常没有什么区别,因此渲染速度往往快于CPU提交命令的速度。
如果Draw Call的数量太多,CPU就会把大量时间花费在提交Draw Call上,造成CPU的过载。

(3)问题三:如何减少Draw Call
尽管减少Draw Call的方法有很多,但我们这里仅讨论使用批处理(Batching)的方法。
提交大量很小的Draw Call会造成CPU的性能瓶颈,一个很显然的优化想法就是把很多小的DrawCall合并成一个大的Draw Call,这就是批处理的思想。
需要注意的是,由于我们需要在CPU的内存中合并网格,而合并的过程是需要消耗时间的。
因此,批处理技术更加适合于那些静态的物体,例如不会移动的大地、石头等,对于这些静态物体我们只需要合并一次即可。
当然,我们也可以对动态物体进行批处理。但是,由于这些物体是不断运动的,因此每一帧都需要重新进行合并然后再发送给GPU,这对空间和时间都会造成一定的影响。

1.3.1顶点着色器
顶点着色器(Vertex Shader)是流水线的第一个阶段,它的输入来自于CPU。
顶点着色器的处理单位是顶点,也就是说,输入进来的每个顶点都会调用一次顶点着色器。
顶点着色器本身不可以创建或者销毁任何顶点,而且无法得到顶点与顶点之间的关系。
顶点着色器需要完成的工作主要有:坐标变换和逐顶点光照。
除了这两个主要任务外,顶点着色器还可以输出后续阶段所需的数据。
PS: 坐标变换。顾名思义,就是对顶点的坐标(即位置)进行某种变换。
顶点着色器可以在这一步中改变顶点的位置,这在顶点动画中是非常有用的。
例如,我们可以通过改变顶点位置来模拟水面、布料等。
但需要注意的是,无论我们在顶点着色器中怎样改变顶点的位置,一个最基本的顶点着色器必须完成的一个工作是,把顶点坐标从模型空间转换到齐次裁剪空间。
想想看,我们在顶点着色器中是不是会看到类似下面的代码:
o. pos= mul(UNITY_MVP,v. position);
类似上面这句代码的功能,就是把顶点坐标转换到齐次裁剪坐标系下。

1.3.2裁剪
由于我们的场景可能会很大,而摄像机的视野范围很有可能不会覆盖所有的场景物体。
所以我们需要将那些不在摄像机视野范围的物体不需要被处理。
一个图元和摄像机视野的关系有3种:完全在视野内、部分在视野内、完全在视野外。
完全视野内的图元就继续传递给下一个流水线阶段,
完全在视野外的图元不会继续向下传递,因为们不需要被渲染。
部分在视野内的图元需要进行一个处理,这就是裁剪。
例如,一条线的一个顶点在视野内,而另一个顶点不在视野内,
那么在视野外部的顶点应该使用一个新的顶来代替,这个新的顶点位于这条线段和视野边界的交点处。

1.3.3屏幕映射

1.3.4三角形设置

1.3.5片元源着色器

 

标签:01,渲染,着色器,unityshader,GPU,流水线,顶点,CPU
From: https://www.cnblogs.com/0316F/p/16651583.html

相关文章

  • 2022-09-01 卢睿 学习心得
    目录1.AjaxJS原生的AjaxGET请求POST请求JQuery的Ajax发送GET请求发送POST请求完整写法Ajax(aixos)GET请求POST请求注意点:json1.Ajax异步刷新(局部刷新),前端技术——可以给后......
  • 1454. 异或和是质数的子集数 01背包
    题意给出n个互不相同的正整数。问存在多少个子集,使得子集中所有数的异或和是质数。由于答案可能很大,请你输出对109+7取模后的结果。分析题意就是指:从一堆元素中......
  • NC16886 [NOI2001]炮兵阵地
    题目链接题目题目描述司令部的将军们打算在N*M的网格地图上部署他们的炮兵部队。一个N*M的地图由N行M列组成,地图的每一格可能是山地(用"H"表示),也可能是平原(用"P"表示),如......
  • P4363 [九省联考 2018] 一双木棋 题解
    一道状压dp题,我写的记忆化搜索。注意到这道题已经下子的区域和未下子的区域有一条轮廓线分割,因此考虑右上到左下记纵向为1,横向为0,状压一下,然后顺着记忆化搜索(有点类似......
  • java学习笔记018 反射
    1.java.lang.Class获取Class对象的四种方式//1Classclazz1=Person.class;//2Personp=newPerson();Classclazz2=p.getClass();//3 用得多Classclazz3=......
  • SI3933/GC3933/PAN3501/AS179 125K低频唤醒芯片同类型芯片的优势对比
    关于125K低频唤醒芯片,现在市面上有太多太多,像PAN3501、GC3933还有SI3933,都是替换SKYWORKS的AS179-92,同类型芯片的优势在哪里呢?今天小编挑一款给大家浅浅分享一下SI3933:3D......
  • 2022牛客暑假多校01B[Spirit Circle Observation]
    2022牛客暑假多校01B[SpiritCircleObservation]大致题意给出一个长度为\(n\)的字符串\(s\),求有多少个子串对\((A,B)\),满足\(1.|A|=|B|\)\(2.\overline{A}+1=......
  • AcWing算法基础课---第三讲基础算法---01DFS和BFS
    DFSAcWing842.排列数字#include<iostream>usingnamespacestd;constintN=10;intn;intpath[N],st[N];voiddfs(intu){if(u==n){......
  • ICCV2019_Slimmable:(US-Nets)Universally Slimmable Networks and Improved Training
    Institute:UniversityofIllinoisatUrbana-ChampaignAuthor:JiahuiYu,ThomasHuangGitHub:https://github.com/JiahuiYu/slimmable_networksIntroduction最初......
  • 袋鼠云产品功能更新报告01期丨用诚心倾听您的需求
    作为一家以“客户第一”为价值观的公司,袋鼠云一直以来关注客户体验,专注提升产品品质,不断收集客户反馈,持续增加新功能并不断优化旧功能,为用户输出最佳产品使用体验。2022年......