【图形学】09 UnityShader入门(一)

来源:《UNITY SHADER入门精要》

1、图形渲染管线

  《Render-Time Rendering,Third Edition》一书中将一个渲染流程分成3个阶段:应用阶段(Application Stage)、几何阶段(Geometry Stage)、光栅化阶段(Rasterizer Stage)。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-lUbak1iO-1658471434097)(assets/image-20220610111219150.png)]

①应用阶段(Application Stage)

  从名字我们可以看出,这个阶段是由我们的应用主导的,因此通常由CPU负责实现。换句话说,我们这些开发者具有这个阶段的绝对控制权。
  在这一阶段中,开发者有3个主要任务:首先,我们需要准备好场景数据,例如摄像机的位置、视锥体、场景中包含了哪些模型、使用了哪些光源等等;其次,为了提高渲染性能,我们往往需要做一个粗粒度剔除(culling)工作,以把那些不可见的物体剔除出去,这样就不需要再移交给几何阶段进行处理:最后,我们需要设置好每个模型的渲染状态。这些渲染状态包括但不限于它使用的材质(漫反射颜色、高光反射颜色)、使用的纹理、使用的Shader等。这一阶段最重要的输出是渲染所需的几何信息,即渲染图元(rendering primitives)。。通俗来讲,渲染图元可以是点、线、三角面等。这些渲染图元将会被传递给下一个阶段一几何阶段。

②几何阶段(Geometry Stage)

  几何阶段用于处理所有和我们要绘制的几何相关的事情。例如,决定需要绘制的图元是什么,怎样绘制它们,在哪里绘制它们。这一阶段通常在GPU上进行。
  几何阶段负责和每个渲染图元打交道,进行逐顶点、逐多边形的操作。这个阶段可以进一步分成更小的流水线阶段,这在下一章中会讲到。几何阶段的一个重要任务就是把顶点坐标变换到屏幕空间中,再交给光栅器进行处理。通过对输入的渲染图元进行多步处理后,这一阶段将会输出屏幕空间的二维顶点坐标、每个顶点对应的深度值、着色等相关信息,并传递给下一个阶段。

③光栅化阶段(Rasterizer Stage)

  这一阶段将会使用上个阶段传递的数据来产生屏幕上的像素,并渲染出最终的图像。这一阶段也是在GPU上运行。光栅化的任务主要是决定每个渲染图元中的哪些像素应该被绘制在屏幕上。它需要对上一个阶段得到的逐顶点数据(例如纹理坐标、顶点颜色等)进行插值,然后再进行逐像素处理。

2、Draw Call

  这一步就是CPU准备好数据以后,把数据加载到显存中,再由CPU给出 Draw Call 命令给GPU,然后GPU就会根据 存储的渲染状态 来进行渲染。这些数据的准备就是在
  每一次渲染多有可能使用不同的渲染状态 ,比如使用顶点着色器(Vertex Shader)/片元着色器(Fragment Shader),不同的光源属性、材质等等。

2、GPU的工作流程


[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-kqIQKqkZ-1658471434098)(assets/image-20220521144349086.png)]

  正如图中所展示的,绿色是可编程的,黄色是可调整参数的,蓝色是不可更改的。绿色+红色边框是可选编程的。

3、一些DirectX和OpenGL的不同

  ①摄像机的视景体,变换后的坐标,我们叫做:归一化的设备坐标(Normalized Device Coordinates)。

  图上给出的坐标范围是 OpenGL 同时也是 Unity 使用的 NDC,它的 z 分量范围在[-1, 1] 之间,而在 DirectX 中,NDC的 z 分量范围是 [0,1]。也就是只有半个立方体。

  ②屏幕坐标系的不同

4、片元着色器(Fragment Shader)

  在DriectX中,片元着色器 被称为 像素着色器(Pixel Shader)
  片元着色器的输入是上一阶段对定点信息插值得到的结果,是根据那些从顶点着色器中输出的数据插值得到的。它的输出是一个或者多个颜色值。也就是说上一步骤传出的只是三角形的三个定点及其颜色,这一步输出之后就是各个像素的颜色了。

5、逐片元操作(Per-Fragment Operations)

  逐片元操作(Pre-Fragment Operations),OpenGL是这么说的。DircetX叫做输出合并阶段(Output-Merger),这个过程的主要任务是:
  (1)决定每个片元的可见性。有许多测试工作决定,比如:深度测试、模板测试等。
  (2)如果一个片元通过了所有测试,就需要把这个片元的颜色只和已经存储在颜色缓存区的颜色进行混合。

①模板测试(Stecil Test)

  与之相关的是 模板缓冲(Stencil Buffer)。如果开启了模板测试,GPU首先读取模板缓冲区中该片元位置的模板值,然后将该值和读取到的参考值作比较,这个比较规则可以自定义的(比如:大于还是小于的时候才画,或者与或出某个结果的时候才画)。这个测试可以做出一些比如:渲染阴影、轮廓渲染等效果。

②深度测试(Depth Test)

  这个测试的规则函数也是可以高度配置的,一般情况是,会把片元中的深度值和已经在深度缓冲区的深度值比较,然后舍弃较大的片元。这个测试和透明效果密切相关。

③混合(Blend)

  当我们执行这次渲染的时候,我们的颜色缓冲区往往还存在着上次渲染之后的颜色结果,那么,我们是使用这次渲染得到的结果完全覆盖上一次,还是进行其他处理?这就是 混合 索要解决的问题了。
  对于不透明物体,我们可以选择关闭 混合操作,覆盖掉上次的渲染像素值就完事了。但是对于半透明物体,我们就需要使用 混合操作 了。

④提升技术

  如果GPU在 片元着色器阶段 花了很多力气计算了片元的颜色,但是最终没有通过测试,这一部分的性能就是一种浪费。在Unity中,给出的深度测试是在 片元着色器 之前,这种技术称为 Early-Z 技术。比如:

  不过,将这些片元测试前置的话,有可能会和片元着色器中的一些操作冲突。现代GPU会判断 片元着色器 中的操作是否会和 提前测试 发生冲突。若有冲突,则会金庸提前测试。

6、双重缓冲(Double Buffering)

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

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值