进击的 Vulkan 移动开发(二)之谈谈对渲染流程的理解

简介: 都说 OpenGL 、Vulkan 是用来绘制二维、三维图形的,那么这个绘制渲染的流程到底是怎么样的呢?这里,谈谈我自己对它的理解。

作者:星陨

从泥巴到工艺品

先来举一个 玩泥巴 的例子,也就是我国的传统工艺 —— 陶瓷工艺

以我国传统的陶瓷工艺为例,先看看伟大的工匠们是如何把泥巴变成了精美的艺术品。

上面是一张粗略的示意图,详细的陶瓷制作流程可以自行网上搜索,或者 参考这里

小时候大家肯定都玩过泥巴啦,沾一点水之后可以捏成各种各样的形状,没玩过的话,橡皮泥也行。

现假设我们要用泥巴做一个陶瓷的彩色方块。

那么首先就得从一堆稀泥里面捏出一个方方正正的小块,注意把小块的六个面都打磨均匀了。

然后再放在火窑经过高温烧制,七七四十九小时之后,就可以出炉了,此时小方块就已经变硬了,而且它的形状就是我们捏完后的样子。

待冷却之后就可以给它上色了,掏出画笔,涂上代表自己心情的颜色,这样就制作完成了一个陶瓷的彩色方块(是不是很简单呢(づ。◕‿‿◕。)づ)。

OpenGL 的渲染

OpenGL 的渲染流程和陶瓷工艺在某些地方是有着相同之处的。

首先,OpenGL 的渲染是讲究先有形后有色。也就是说用 OpenGL 去渲染绘制二维或三维的物体,你得先把物体给勾勒描绘出来。就好比上面提到的陶瓷小方块,在进行高温烧制之前,也是要先把物体的形状给捏出来的。

在 OpenGL 中提供了几种基本的绘制图形,比如点、线、三角形等,就是使用这几个基本图元去描绘这万千世界,比如绘制一个矩形,可以用两个三角形拼接起来。

在陶瓷小方块的例子中,捏完形状之后就可以高温烧制了,然后再涂色。在 OpenGL 中也有类似高温烧制的一步,叫做 光栅化

强调一下这只是类似的对比,因为这两者还是有差别的。

当我们在构建定义物体形状时,是在三维的坐标系里面,而显示的屏幕确实二维坐标系,这里还涉及到一个三维坐标到二维坐标的转换,待会再说。

假设现在已经执行完了坐标转换,物体的坐标转换成了二维的,那么就需要通过 光栅化 来映射到屏幕的二维坐标上。

以上图作为示例,先定义了三个顶点代表三角形基本图元,再把经过坐标转换之后的三角形映射到屏幕上。而屏幕是由一个一个像素点组成的,光栅化的过程就是要把三角形分解成许多个小的片段,再把这些片段映射到屏幕对应位置上,这样就可以让屏幕显示坐标转换后的物体了。

给三角形显示来个特写如下:

光栅化之后的三角形与屏幕显示的关系。实际上屏幕像素并不是小方格而是像素点,肯定不会有这么夸张的锯齿。

当光栅化操作之后,就可以对它进行着色了。这又回到了上面的例子,陶瓷小方块的涂色阶段,在这个阶段,数字图像处理学科开始发挥它巨大的作用了,各种各样的滤镜、图像效果都是在这个阶段进行的。

用上面的图总结一下目前的渲染流程,这个流程比较简化,理解起来就和上面的陶瓷制作相似,也比较形象的阐述了 OpenGL 渲染从 有形有色 的过程。

现在再来看看坐标转换,坐标转换是在光栅化之前的,如下图:

这里会经过几个坐标的转换,分别是局部坐标、世界坐标、观察坐标、裁剪坐标。最后才是显示到屏幕的坐标。

具体的详细分析可以参考之前写过的相关 博客文章

简单说就是我们有了一个立方体形状,那么我们在不同地方、不同角度看到的物体的不一样的,这是人相对于物体的移动变化。另外还有物体相对人的移动变化,物体移出了我们的视线、物体侧放着、物体反过来对着我们,得到的观察结果也是不一样的。

而坐标转换就是约定好观察者与被观察者之间的位置、角度,这样才能确定看到的结果是什么,对这个结果进行光栅化处理,再映射到屏幕上。

写到这,你以为你就懂了 OpenGL 的渲染流程了嘛?想要更好地发挥 OpenGL 的作用,还需要了解它的各种 测试 和 颜色混合

  • 裁剪测试(Scissor Test)

在经过光栅化和片段着色器处理之后,通过裁剪测试可以选择只在某一个矩形区域内进行绘制,不需要绘制整个屏幕范围。这样的话,就可以在同一屏内分别绘制不同的内容。

  • 模板测试(Stencil Test)

模板测试能够让我们预先定义一个任意模板范围,然后在指定的任意范围内绘制。相比裁剪测试只能在矩形范围内,模板测试更加灵活了。对于某些场合实现效果还是很有帮助的。

  • 深度测试(Depth Test)

深度测试是指在三维坐标里面,距离观察点较远的片段会被前面较近的片段挡住,因此就不需要绘制那些被遮挡看不到的内容了,优化绘制。如果只是绘制平面二维的内容,那么深度测试开不开都没太大影响。

  • 混合测试(Alpha Blending)

混合测试指定就是在原有颜色的基础上用另外的颜色绘制时,如何确定这两种颜色混合后的最终颜色。如果是做贴纸相关应用,要特别注意透明度的问题,看到过一些同学透明度没处理好导致贴纸效果不理想。

经过这些个步骤之后,绘制的内容就会映射到指定的大小范围内,也就是 视口(ViewPort) 的大小,一般都是通过代码来指定这个大小。

而装载绘制内容的就是 帧缓冲(FrameBuffer),绘制的结果就是输出到这了。通过绑定到不同的帧缓冲,可以将绘制结果输出到不同的帧缓冲里。而 OpenGL 中,屏幕就是那个默认的帧缓冲,所以一般就直接输出显示到屏幕上了。当然也可以自己创建一个帧缓冲,用来做离屏渲染等操作。

维基百科 上的图来做个总结:

这个流程图就和上文内容提到的大致相同了,如果你明白了渲染流程,那么看懂这个图应该也不是难事了~

以上就是关于 OpenGL 渲染流程的一个看法和理解,如果有什么不足之处欢迎指出~~

Vulkan 的渲染

接下来看看 Vulkan 的渲染。

先上一张 英伟达(NVIDIA) 公司给出的 Vulkan 组件图。

由于本篇只关注渲染流程,所以组件图中很多是现在不用太过关心的,比如 Image、Command-buffer 等,后面的文章会再做讲解。

看到图中有一个 Graphics pipeline 的组件,这个组件里面就包含 Vulkan 的渲染流程。

Pipeline 组件里面都有哪些操作?看下图~

看到图中中的左边内容是不是有似曾相识的感觉,就和 OpenGL 的渲染流程一样的,也是从顶点 -> 到光栅化 -> 到着色器 -> 到帧缓冲,再加上各种测试。

Vulkan 的 Pipeline 组件就是对应了 OpenGL 的渲染流程,或者说就是图形学里面的渲染流程,因为这个流程、这个原理是不会变的,Vulkan 也没有改变它,只是调用的逻辑结构发生了变化,但万变不离其宗,这也是为什么说要先学会 OpenGL 再来看 Vulkan 。

在 Vulkan 中,Pipeline 组件是可以复用的,通过绑定不同的资源而实现。可以预先创建几个 Pipeline ,在使用时选择对应的 Pipeline ,另外 Pipeline 还可以缓存起来,关于 Pipeline 的具体细节等到使用时再详细阐述。

渲染和 Vulkan 的调用是分开的。Vulkan 的调用很复杂,但是很多和图形学并没有关系,比如多线程、比如资源分配等。

只节选了组件图的一小部分来讲解,更多讲解敬请期待后续文章。

当然,这只是个人的学习经验,仅供参考,有讲的不对之处,欢迎指出,也可以加我微信一起交流学习: zh_ying_13 。

系列文章的代码地址:

https://github.com/glumes/vulkan_tutorial

参考

这里有一些不错的参考链接:
https://www.toutiao.com/a6457289342741119502/
https://zhuanlan.zhihu.com/p/20712354
https://zhuanlan.zhihu.com/p/49112352
https://www.khronos.org/opengl/wiki/Rendering_Pipeline_Overview

Vulkan 系列文章

「视频云技术」你最值得关注的音视频技术公众号,每周推送来自阿里云一线的实践技术文章,在这里与音视频领域一流工程师交流切磋。

阿里云社区.png

相关文章
|
移动开发 API Android开发
进击的 Vulkan 移动开发之 Instance & Device & Queue
针对每个组件进行学习讲解并配上相关的示例代码,首先是 Instance、Device 和 Queue 组件。
387 0
进击的 Vulkan 移动开发之 Instance & Device & Queue
|
移动开发 API 图形学
进击的 Vulkan 移动开发之 SwapChain
在之前的文章中,讲到了 Command-Buffer 提交给 Queue 去执行,也提到了 Vulkan 实现跨平台机制,是有一些拓展的,这里就讲讲 Vulkan 窗口系统的拓展(Vulkan Window System Integration WSI),如下图所示:
1059 0
进击的 Vulkan 移动开发之 SwapChain
|
移动开发 异构计算 索引
进击的 Vulkan 移动开发之 Command Buffer
此篇文章继续学习 Vulkan 中的组件:Command-Buffer 。
555 0
进击的 Vulkan 移动开发之 Command Buffer
|
2月前
|
开发框架 Dart Android开发
移动应用开发中的创新之路:探索跨平台解决方案
【9月更文挑战第21天】在移动应用的海洋中,开发者们面临着一个不断变化的挑战——如何在多个操作系统上提供无缝的用户体验。本文将探讨跨平台开发的魅力与挑战,并深入分析Flutter框架如何成为现代开发者的利器。我们将通过实际代码示例,揭示Flutter简化开发流程、提高生产效率的秘密。从Dart语言的基础到热重载的便捷性,本文旨在为读者提供一次全面而深刻的跨平台开发之旅。
|
1月前
|
开发框架 前端开发 Android开发
移动应用开发中的跨平台策略与实践
【9月更文挑战第34天】本文将深入探讨移动应用开发的跨平台策略,包括对React Native、Flutter和Xamarin等流行框架的比较。文章还将分享一些实用的跨平台开发技巧和最佳实践,帮助开发者在多个平台上高效地构建和维护应用。无论你是初学者还是有经验的开发者,这篇文章都会为你提供有价值的见解和指导。
|
21天前
|
Dart Android开发 开发者
掌握跨平台移动应用开发:Flutter 的崛起
【10月更文挑战第9天】本文介绍了Flutter,一个由Google支持的开源UI工具包,专注于跨平台移动应用开发。文章详细探讨了Flutter的核心优势,如原生性能、热重载、丰富的组件及高可定制性,并提供了实施开发的步骤指南。此外,还分享了Flutter在快速原型开发、高性能应用及跨平台维护中的应用实例和实战技巧,旨在帮助开发者高效利用Flutter构建高质量移动应用。
|
30天前
|
开发框架 Android开发 开发者
移动应用开发中的跨平台策略与系统优化
在移动应用开发的广阔舞台上,跨平台策略和系统优化是两大核心议题。本文将深入探讨如何通过技术手段提升应用的跨平台性能和用户体验,同时确保系统的高效运行。我们将从Flutter框架的应用、Android和iOS平台的差异化处理,到系统资源管理和性能监测等方面进行详细阐述。文章旨在为开发者提供实用的指导和建议,帮助他们在不断变化的移动应用市场中保持竞争力。
|
2月前
|
设计模式 前端开发 JavaScript
探索移动应用开发:从Android到iOS的跨平台之旅
【9月更文挑战第21天】在这篇文章中,我们将一同揭开移动应用开发的神秘面纱,从Android和iOS这两个主流平台出发,探讨如何利用现代技术栈实现跨平台开发。文章将通过具体的代码示例,带领读者理解不同平台间的差异与联系,以及如何运用React Native框架简化开发流程,实现一次编写,多平台运行的目标。无论你是刚入门的新手还是希望拓展技能的老手,这篇文章都将为你提供宝贵的知识和启示。
67 3
|
2月前
|
前端开发 JavaScript C#
移动应用开发中的跨平台框架解析
【9月更文挑战第5天】在移动应用开发领域,跨平台框架因其“一次编写,处处运行”的便利性而受到开发者的青睐。本文将深入探讨几种流行的跨平台框架,包括React Native、Flutter和Xamarin,并比较它们的优势与局限。我们将通过代码示例揭示这些框架如何简化移动应用的开发过程,同时保持高性能和良好的用户体验。无论你是新手还是有经验的开发者,这篇文章都将成为你了解和选择跨平台框架的宝贵资源。
62 19
|
2月前
|
人工智能 开发框架 搜索推荐
移动应用开发的未来:跨平台框架与AI的融合
在移动互联网飞速发展的今天,移动应用开发已成为技术革新的前沿阵地。本文将探讨跨平台框架的兴起,以及人工智能技术如何与移动应用开发相结合,从而引领行业走向更加智能化、高效化的未来。文章通过分析当前流行的跨平台开发工具和AI技术的应用实例,为读者提供对未来移动应用开发的独到见解和预测。
58 3

热门文章

最新文章