渲染流水线

渲染流程的3个阶段1.应用阶段:通常由CPU负责实现,这一阶段最重要的输出信息是渲染所需要的几何信息(即渲染图元,rendering primitives)。2.几何阶段:这个阶段通常在GPU上进行,把顶点坐标变换到屏幕空间中,再交给光棚器进行处理。3.光棚化阶段:将上一个阶段传递的数据来产生屏幕上的像素,并渲染出最终的图像。...
摘要由CSDN通过智能技术生成

渲染流程的3个阶段

在这里插入图片描述
1.应用阶段:通常由CPU负责实现,这一阶段最重要的输出信息是渲染所需要的几何信息(即渲染图元,rendering primitives)。
2.几何阶段:这个阶段通常在GPU上进行,把顶点坐标变换到屏幕空间中,再交给光棚器进行处理。
3.光棚化阶段:将上一个阶段传递的数据来产生屏幕上的像素,并渲染出最终的图像。

渲染流水线的起点是CPU,即应用阶段,而应用阶段大致可以分为下面3个阶段:
1)把数据加载到显存中。
2)设置渲染状态。
3)调用Draw Call。

在这里插入图片描述
2)
在这里插入图片描述
3)
Draw Call实际上就是一个命令,它的发起方是CPU接收方GPU,这个命令仅仅会指向一个需要被渲染的图元列表。
在这里插入图片描述

GPU流水线
几何阶段和光棚化阶段开发者无法拥有绝对的控制权,其实现的载体是GPU。GPU通过实现流水线化大大加快渲染速度。
GPU渲染流水线
GPU渲染流水线
顶点着色器(Vertex Shader)是完全可编程的,它的输入来自于CPU,通常用于实现顶点的空间变换、顶点着色
,主要工作有:坐标变换、逐顶点光照。
曲面细分着色器(Tessellation Shader)是一个可选着色器,用于细分图元。
几何着色器(Geometry Shader)是一个可选着色器,用于执行逐图元(Per-Primitive)的着色操作,或者被用于产生更多的图元。
裁剪(Clipping)将那些不在摄像机视野内的顶点裁剪掉,并剔除某些三角图元的面片。一个图元和摄像机有3种关系:完全在视野内、部分在视野内、完全在视野外。完全在视野内的图元就继续传递给下一个流水线阶段,完全在视野外的图元不会继续向下传递,因为他们不需要被渲染,而那些部分在视野内的图元需要进行处理,这就是裁剪。
屏幕映射(Screen Mapping)把每个图元的坐标转换到屏幕坐标,它不可配置和编程。

顶点着色器
顶点着色器
裁剪
屏幕映射

光棚化阶段有2个主要的目标:计算每个图元覆盖哪些像素,以及这些像素计算它们的颜色。

三角形设置(Triangle Setup)计算光棚化一个三角网格所需的信息。上一个阶段得到的是三角网格的顶点,如果我们要得到整个三角网格对像素的覆盖情况,我们就必须计算每条边上的像素坐标。为了能够计算边界像素的坐标信息,我们就需要得到三角形边界的表达方式。这样一个三角网格表示数据的过程就是三角形设置。
三角形遍历(Triangle Traversal)检查每个像素是否被一个三角网格覆盖。如果被覆盖就会生成一个片元(Scan Conversion),一个片元并不是真正意义上的像素而是包含了很多状态的集合,这些状态用于计算每个像素的最终颜色。
片元着色器(Fragment Shader)它是一个非常重要的可编程的着色器,它完成很多重要的渲染技术,其中最重要的技术之一技术纹理采集。虽然可以完成很多重要效果,但它仅可以影响单个片元。
逐片元操作(Per-Fragment Operations)这个阶段有几个主要任务:1)决定每个片元的可见性。2)如果一个片元通过了所有测试就把这个片元的颜色值和已经存储在颜色缓冲区中的颜色进行合并(或者说是混合)。逐片元操作阶段是高度可配置性的,我们可以设置每一步的操作细节。

三角形遍历
片元着色器
逐片元操作阶段

测试的过程实际上是个比较复杂的过程,而且不同的图形接口的实现细节也不尽相同。
模板测试和深度测试简化流程
混合测试简化流程
模板测试(Stencil Test)与之相关的是模板缓冲(Stencil Buffer)。如果开启模板测试,GPU会首先读取(使用读取掩码)模板缓冲区中该片元位置的模板值,然后将该值和读取(使用读取掩码)到的参考值(reference value)进行比较,这个比较函数可以是由开发者指定的。模板测试通常用于限制渲染的区域,另外它还有更高级的用法(渲染阴影、轮廓渲染等)。
深度测试(Depth Test)如果一个片元通过模板测试,那么它就会进入深度测试,GPU会把该片元的深度值和已经存在于深度缓冲区中的深度值进行比较,这个比较函数开发者也是可以自己设置的。如果该片元没有通过测试就会被舍弃,而如果通过测试,开发者还可以指定是否要用该片元的深度值覆盖掉原有的深度值。
混合(Blend)对于不透明的物体可以关闭混合操作,这样片元着色器计算得到的颜色值就会直接覆盖掉颜色缓冲区中的像素值。开启混合GPU会取出源颜色和目标颜色将这2种颜色通过一个混合函数进行混合操作。这个混合函数通常和透明通道息息相关(根据透明通道的值进行相加、相减、相乘等)。

作为想越高性能的GPU,它会希望尽可能早知道哪些片元是会被舍弃的,对于这些片元就不需要再使用片元着色器计算它们的颜色。在Unity给出的渲染流水线中,我们也可以看到它给出的深度测试是在片元着色器之前。这种将深度测试提前执行的技术通常也称为Early-Z技术。
在这里插入图片描述

为了避免我们看到那些正在进行光棚化的图元,GPU会使用双重缓冲(Double Buffering)的策略。这意味着对场景的渲染是在幕后发生的,即在后置缓冲(Back Buffer)中。一旦场景已经被渲染到后置缓冲中,GPU就会交换后置缓冲区和前置缓冲(Front Buffer)中的内容,而前置缓冲区是之前显示在屏幕上的图像。由此,保证了我们看到的图像总是连续的。

在这里插入图片描述

什么是HLSL、GLSL、CG?

在可编程管线出现之前,为了编写着色器代码,开发者们学习汇编语言。为了给开发者通过方便就出现了更高级的着色语言(Shading Language)。而常见的着色语言就是DirectX的HLSL(High Level Shading Language)、OpenGL的GLSL(OpenGL Shading Language)和NVIDIA的CG(C for Graphic)。

什么是Draw Call?

Draw Call本身的含义很简单,就是CPU调用图像编程接口。
一个误区是Draw Call中造成性能问题的元凶是GPU,但真正的元凶其实是CPU。
在这里插入图片描述
如果没有流水线化,那么CPU需要等到GPU完成上一个渲染任务才能再次发送渲染命令,这种方法显然会造成效率低下。而解决方法就是使用一个命令缓冲区(Command Buffer)。命令缓冲区包含了一个命令队列,由CPU向其中添加命令,而由GPU从中读取命令,添加和读取的过程是相互独立的。命令缓冲区使得CPU和GPU可以相互独立工作。命令缓冲区中的命令有很多种类,而Draw Call是其中一种。
在这里插入图片描述
在每次调用Draw Call之前,CPU需要向GPU发送很多内容,包括数据、状态、命令等。这个阶段CPU需要完成很多工作,而GPU的渲染能力是很强的,渲染200个和渲染2000个三角网格通常没有什么区别,因此渲染速度往往快于CPU提交命令的速度。如果Draw Call的数量太多,CPU就会把大量时间花费在提交Draw Call上,造成CPU过载。

在这里插入图片描述
减少Draw Call的方法很多,通常使用的是批处理(Batching)的方法。批处理的思想是把很多小的Draw Call合并成一个大的Draw Call。
需要注意的是,合并过程中是需要消耗时间的,所以批处理技术适合于那些静态的物体
在游戏开发中,为了减少Draw Call的开销,有2个地方要注意
1)避免使用大量很小的网格,不可避免考虑是否可以合并它们。
2)避免使用过多的材质。尽量在不同的网格之间共用同一个材质。

什么是固定管线渲染?

固定函数的流水线(Fixed-Function Pipeline),也简称为固定管线,通常是指在较旧的GPU上实现的渲染流水线。这种流水线只给开发者提供一些配置操作,但开发者没有对流水线阶段的完全控制权。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值