草庐IT

openGL ES 教程(二):渲染管线

康小曹 2023-03-28 原文

首先,GPU 的渲染流程就是一个程序,该程序是由多个着色器组成。着色器本身也是一个程序,所以需要先进行编写、编译,然后再链接到渲染程序中,多个着色器链接之后生成最终的渲染程序。

GPU 本身是高并发设计,在渲染管线进行时,各个小的着色器可以并发执行。比如在顶点输入阶段,输入了 10 个顶点,可能就有 10 个着色器程序同时执行并输出结果。

至于在同一个渲染管线内,不同阶段之间是否能够并发,这个取决于 GPU 是 Tiled Based Render 还是 ???比如,顶点着色器运行阶段,第十个顶点还没有输出时,第一个顶点的输出有没有可能已经进入到了片段着色器阶段?如果是 TBR,因为只会渲染一次,所以需要等到每个 Tile 对应的顶点都输出完成之后才能传递到下一个阶段?这么理解对不对???

一般的渲染管线包括如下着色器:

渲染管线

这里需要几点需要说明:

  • 可编程着色器

上图中,在 OpenGL 加入可编程着色器功能之后,顶点着色器、几何着色器、片段着色器是可编程的。但是系统有提供默认几何着色器的,所以要生成一个渲染程序,开发者至少需要提供两个着色器:顶点着色器 + 片段着色器;

  • 输入和输出

上述着色器中,每个着色器的输出都会作为输入传递给下一个着色器。顶点着色器因为是第一个着色器,所以直接接受外部浮点类型数组作为输入。

Rendering Pipline 步骤如下:

1.顶点输入

float 类型的数组作为顶点输入到顶点着色器,其格式一般是这样的:

顶点数组

因为是在 2D 框架中,所以这个的 Z 值一般直接写 1 即可。

2. 顶点着色器处理

这个着色器是可编程着色器,可以对输入的顶点进行一些自定义的处理,后面的文章会详细讲;

另外,如何对顶点数据做解析,后面的文章也会讲到。总之,顶点着色器就是对输入的顶点做一些自定义的处理并输出给图元装配着色器;

3. 图元装配

图形装配着色器接收到顶点着色器的输出之后,按照图元参数对输入的顶点做一些处理,包含裁剪、透视分割和视口变换等,最终装配成指定的图元。

比如裁剪,如果给入的顶点超过了可视范围,那么图形装配之后生成的顶点就不一定是原来的顶点了,而是处理过后的顶点。

即:将输入的顶点处理成符合当前上下文的顶点;

图元的位置、形状等信息在计算机中仍然是通过顶点 + 图元类型来表示的,所以,这一步的输出形式依然是顶点数组。而图元的类型有点、线段、三角形,这个参数的传递是贯穿整个 pipline 的,在 draw calls 中传入,比如 drawArray 方法;

4. 图元的概念

说说自己对图元和图元枚举的概念的理解。

首先是 draw call 中的图元枚举:

图元枚举

这个枚举是告诉着色器,需要按照怎样的方式处理数据。比如装配阶段,如果输入是 3 个顶点且有一个顶点超出坐标系,绘制图元的类型是线段和三角形时,最终生成的顶点就会有区别:

  1. 线段时,仍然输出 3 个顶点;
  2. 三角形时,输出 4 或 5 个顶点;

图元的概念:图元其实就是一个可视化的概念,目的是方便理解 pipline,对于计算机而言,图元本质上仍然是由(顶点数据 + 图元类型)组成;

比如提供三个点绘制三角形,且有一个点超出范围时,图元装配阶段需要进行裁剪。图形装配之后,假如输出输出 5 个点:

图元装配

最终其实是生成了 3 个三角形的图元,但是这三个图元本质上是由 5 个顶点 + Triangle 这个枚举来标识;

另外,OpenGL ES 是 OpenGL 的子版本,用于嵌入式设备,在各个方面进行了精简。OpenGL ES 中只有点、线、三角形,所有的图形最终会转换成三角形来进行处理,没有 OpenGL 中的矩形、多边形等概念;

5. 几何着色器处理

几何着色器阶段是对上一步的图元进行再加工,可能会生成新的顶点和图元。

最开始的 pipline 图中,一个三角形变成了两个,需要注意的是,这里变成两个三角形并不是某些渲染流程相关的潜规则,而是完全由几何着色器的代码决定的。

类似的还有很多,比如传入一个顶点数据,生成多个顶点从而生成多个基础图元,最终组装成一个小房子的形状:

输入一个顶点产生一个小房子

上图中,传入一个顶点,在几何着色器阶段生成了 5 个顶点并构成了 3 个三角形图元,最终组成了小房子的形状,代码如下:

几何着色器代码

因为几何着色器是可编程的,所以这里开发者可以编写几何着色器对图元进行多样化的处理的。

因此,各种各样的几何着色器可以理解成实现各种功能的 Api,也就是传入顶点数据之后自动生成对应的图元数据。比如上述小房子的几何着色器就是实现传入一个顶点,从而生成一个小房子图元的功能。

iOS 中的 Tiled Based Rendering 中,将较大的三角形处理成小的三角形是不是可以理解成类似于几何着色器的功能?还是说是图元装配的过程??另外,因为 Metal 已经是和 OpenGL 一个级别的框架了,所以 Metal 中的 pipline 并不一定遵循 OpenGL 中的 pipline,所以不要对号入座,最多只能借鉴和参考;

6. 光栅化

OpenGL 中的一个片段(Fragment)是 OpenGL 渲染一个像素所需的所有数据。

几何着色器的输出会被传入光栅化阶段(Rasterization Stage),光栅化阶段会把图元映射为最终屏幕上相应的像素,生成供片段着色器(Fragment Shader) 使用的片段(Fragment)。

这一步说白了就是图元到硬件(像素)的转换。

因为屏幕是由很多个像素点组成,一个图形要展示在屏幕上,就需要知道哪些像素点需要亮起来,且要用什么强度的信号来展现出怎样的颜色。光栅化这一步就是将上下文坐标系中的图元转化成硬件层面上真正要展示的像素点,即:光栅化就是计算出哪些像素需要展示。而像素具体需要展示成什么颜色则在下一步的片段着色器中计算;

光栅化阶段计算并生成像素点模型(容器),片段着色器阶段生成完整的像素点数据(向容器中填充数据)。所以,一个 Fragment 中包含该像素被渲染时所需要的所有的数据。

一种简单的划分就是根据中心点,如果像素的中心点在图元内部,那么这个像素就属于这个图元。如上图所示,深蓝色的线就是图元信息所构建出的三角形;而通过是否覆盖中心点,可以遍历出所有属于该图元的所有像素;

光栅化

如上图,浅蓝色部分就是光栅化计算出来需要展示的像素点;

之前的步骤都相当于美术中的构图,只不过电脑世界的构图是以三角形作为基本图形。而光栅化这一步就相当于美术中的素描,这一步完成后就意味着将形状画到纸上了。素描完成了,接下来就是上色了,也就是美术中的水彩等阶段。

另外,在片段着色器运行之前会执行裁切(Clipping)。裁切会丢弃超出你的视图以外的所有像素,用来提升执行效率。

7.片段着色器

片段着色器(Fragment Shader)也叫做像素着色器(Pixel Shader),这个阶段的目的是给每一个像素 Pixel 赋予正确的颜色。

计算像素点的颜色需要顶点 + 场景数据。顶点可以从前面的步骤中获取。通常,片段着色器包含 3D 场景的数据(比如光照、阴影、光的颜色等等),这些数据可以被用来计算最终像素的颜色由于需要处理纹理、光照等复杂信息,所以该阶段通常是整个系统的性能瓶颈。

片段着色器的输入是什么?工作方式是什么?多个像素点并发、单独使用一个片段着色器计算?

8. 混合阶段

在所有对应颜色值确定以后,最终的对象将会被传到最后一个阶段,我们叫做Alpha测试和混合(Blending)阶段。这个阶段检测片段的对应的深度(和模板(Stencil))值(后面会讲),用它们来判断这个像素是其它物体的前面还是后面,决定是否应该丢弃。这个阶段也会检查alpha值(alpha值定义了一个物体的透明度)并对物体进行混合(Blend)。所以,即使在片段着色器中计算出来了一个像素输出的颜色,在渲染多个三角形的时候最后的像素颜色也可能完全不同。

另外,iOS 中的混合可能会相对简单,因为 iOS 是基于 TBR 方式计算了,如果没有离屏渲染,是不是混合都没有必要?或者说,混合是在 Tiler 生成之前就做完了?具体还得学习下 Metal;

有关openGL ES 教程(二):渲染管线的更多相关文章

  1. ruby-on-rails - 渲染另一个 Controller 的 View - 2

    我想要做的是有2个不同的Controller,client和test_client。客户端Controller已经构建,我想创建一个test_clientController,我可以使用它来玩弄客户端的UI并根据需要进行调整。我主要是想绕过我在客户端中内置的验证及其对加载数据的管理Controller的依赖。所以我希望test_clientController加载示例数据集,然后呈现客户端Controller的索引View,以便我可以调整客户端UI。就是这样。我在test_clients索引方法中试过这个:classTestClientdefindexrender:template=>

  2. ruby-on-rails - Rails HTML 请求渲染 JSON - 2

    在我的Controller中,我通过以下方式在我的index方法中支持HTML和JSON:respond_todo|format|format.htmlformat.json{renderjson:@user}end在浏览器中拉起它时,它会自然地以HTML呈现。但是,当我对/user资源进行内容类型为application/json的curl调用时(因为它是索引方法),我仍然将HTML作为响应。如何获取JSON作为响应?我还需要说明什么? 最佳答案 您应该将.json附加到请求的url,提供的格式在routes.rb的路径中定义。这

  3. 世界前沿3D开发引擎HOOPS全面讲解——集3D数据读取、3D图形渲染、3D数据发布于一体的全新3D应用开发工具 - 2

    无论您是想搭建桌面端、WEB端或者移动端APP应用,HOOPSPlatform组件都可以为您提供弹性的3D集成架构,同时,由工业领域3D技术专家组成的HOOPS技术团队也能为您提供技术支持服务。如果您的客户期望有一种在多个平台(桌面/WEB/APP,而且某些客户端是“瘦”客户端)快速、方便地将数据接入到3D应用系统的解决方案,并且当访问数据时,在各个平台上的性能和用户体验保持一致,HOOPSPlatform将帮助您完成。利用HOOPSPlatform,您可以开发在任何环境下的3D基础应用架构。HOOPSPlatform可以帮您打造3D创新型产品,HOOPSSDK包含的技术有:快速且准确的CAD

  4. postman接口测试工具-基础使用教程 - 2

    1.postman介绍Postman一款非常流行的API调试工具。其实,开发人员用的更多。因为测试人员做接口测试会有更多选择,例如Jmeter、soapUI等。不过,对于开发过程中去调试接口,Postman确实足够的简单方便,而且功能强大。2.下载安装官网地址:https://www.postman.com/下载完成后双击安装吧,安装过程极其简单,无需任何操作3.使用教程这里以百度为例,工具使用简单,填写URL地址即可发送请求,在下方查看响应结果和响应状态码常用方法都有支持请求方法:getpostputdeleteGet、Post、Put与Delete的作用get:请求方法一般是用于数据查询,

  5. 在VMware16虚拟机安装Ubuntu详细教程 - 2

    在VMware16.2.4安装Ubuntu一、安装VMware1.打开VMwareWorkstationPro官网,点击即可进入。2.进入后向下滑动找到Workstation16ProforWindows,点击立即下载。3.下载完成,文件大小615MB,如下图:4.鼠标右击,以管理员身份运行。5.点击下一步6.勾选条款,点击下一步7.先勾选,再点击下一步8.去掉勾选,点击下一步9.点击下一步10.点击安装11.点击许可证12.在百度上搜索VM16许可证,复制填入,然后点击输入即可,亲测有效。13.点击完成14.重启系统,点击是15.双击VMwareWorkstationPro图标,进入虚拟机主

  6. hadoop安装之保姆级教程(二)之YARN的配置 - 2

    1.1.1 YARN的介绍 为克服Hadoop1.0中HDFS和MapReduce存在的各种问题⽽提出的,针对Hadoop1.0中的MapReduce在扩展性和多框架⽀持⽅⾯的不⾜,提出了全新的资源管理框架YARN. ApacheYARN(YetanotherResourceNegotiator的缩写)是Hadoop集群的资源管理系统,负责为计算程序提供服务器计算资源,相当于⼀个分布式的操作系统平台,⽽MapReduce等计算程序则相当于运⾏于操作系统之上的应⽤程序。 YARN被引⼊Hadoop2,最初是为了改善MapReduce的实现,但是因为具有⾜够的通⽤性,同样可以⽀持其他的分布式计算模

  7. ruby-on-rails - Rails 渲染带有驼峰命名法的 json 对象 - 2

    我在一个简单的RailsAPI中有以下Controller代码:classApi::V1::AccountsControllerehead:not_foundendendend问题在于,生成的json具有以下格式:{id:2,name:'Simpleaccount',cash_flows:[{id:1,amount:34.3,description:'simpledescription'},{id:2,amount:1.12,description:'otherdescription'}]}我需要我生成的json是camelCase('cashFlows'而不是'cash_flows'

  8. ruby - 在 RUBY 上的 PADRINO 框架上使用 RSPEC 进行测试的教程 - 2

    我是Ruby新手,并被要求在我们的新项目中使用它。我们还被要求使用Padrino(Sinatra)作为后端/框架。我们被要求使用Rspec进行测试。我一直在寻找可以指导在Padrino上使用RspecforRuby的教程。我得到的主要是引用RoR。但是,我需要RubyonPadrino。请在任何入门/指南/引用/讨论等方面指导我。如有不妥之处请指正。可能是我没有针对我的问题搜索正确的词/短语组合。我正在使用Ruby1.9.3和Padrinov.0.10.6。注意:我还提到了SOquestion,但它没有帮助。 最佳答案 我没用过Pa

  9. ruby-on-rails - 使用 header 渲染 JSON - 2

    我想在我的Controller中使用以下corsheader呈现JSON:'Access-Control-Allow-Origin'='*'.我试过这个:defmy_actionrender(json:some_params)response.headers['Access-Control-Allow-Origin']='*'end但是我得到了一个AbstractController::DoubleRenderError。有没有办法使用header呈现JSON? 最佳答案 您不能在渲染后设置header,因为已发送响应。所以在没有意

  10. 区块链入门教程(6)--WeBASE-Front节点前置服务安装 - 2

    文章目录1.任务背景2.任务目标3.相关知识点4.任务实操4.1安装配置JDK4.2启动FISCOBCOS4.3下载解压WeBASE-Front4.4拷贝sdk证书文件4.5启动节点4.6访问节点4.7检查运行状态5.任务总结1.任务背景FISCOBCOS其实是有控制台管理工具,用来对区块链系统进行各种管理操作。但是对于初学者来说,还是可视化界面更友好,本节就来介绍WeBASE管理平台,这是一款微众银行开源的自研区块链中间件平台,可以降低区块链使用的门槛,大幅提高区块链应用的开发效率。微众银行是腾讯牵头设立的民营银行,在国内民营银行里还是比较出名的。微众银行参与FISCOBCOS生态建设,一定

随机推荐