[翻译完毕]饮水思源:学习计算机图形技术和编程

原文:https://miketuritzin.com/post/how-to-learn-computer-graphics-techniques-and-programming/

饮水思源:学习计算机图形技术和编程

  计算机图形学作为一个领域是广泛、深入、复杂和令人生畏的。半个多世纪以来,在学术研究和工业实践的推动下,它取得了快速的进展。部分内容深入到物理学、数学、信号处理、系统编程(以及更多)。而且,性能总是很重要的,所以简单直接的技术往往是不可能的,高级别的编程抽象也是不能用的。

  尽管这样,或者也许是因为这样,在图形方面做得更好是非常有意义的。作为一个孩子,吸引我加入图形学(和游戏编程)的原因是,只要在计算机内存中翻转比特,就能按照我的确切规格,从无到有地创造出庞大、美丽、动态、互动的世界。

  除了创意方面,通过学习如何模拟物理世界并在某种意义上重建物理世界,建立与物理世界更深层次的联系也是一种美。仅仅知道你能用你的双手和键盘做出神奇的东西,就非常令人满意。(注意:可能还需要大型、昂贵的GPU)。

  许多图形专家表示,他们喜欢这个领域将艺术与技术和科学相结合的趋势。在图形学中,很少有一个 "正确 "的答案,而是在正确性、性能和美学之间进行成千上万的权衡。随着该领域的发展--硬件的改进,以及新技术在旧技术之上的建立和取代,这些权衡不断变化。

  因此,图形是伟大的,但也是困难的。让我们再谈一谈这个问题。

我是谁,这篇文章是为谁写的

  我最近经历了深入研究图形的过程--特别是实时图形--所以我处在一个很好的位置,可以向其他正在这个旅程中的人提供建议。大约六个月前,我发布了一个VR应用(PARTICULATE),它是我在几年时间里在一个自定义引擎上建立的。
  我并不是从零开始的,我已经编程了几十年,在大学里作为学士和硕士生做了大量的图形工作(包括与人合作撰写SIGGRAPH 2004论文)。但我确实花了很多年时间离开图形学去做其他事情,当我回来的时候,我已经错过了大量的进展,所以我有大量的东西需要学习。(当然,这并不是说我早先就知道了一切--哈!)。
  我写这篇文章主要是为了那些已经开始了他们的图形之旅的人。如果你是一个绝对的初学者--这也很好!--这篇文章可能会是一个有趣的读物,但我建议在花太多时间迷失在更广泛的图形世界之前,先从一两本初学者书籍或教程系列开始。
  如果你已经在增长你的图形知识的道路上,你可能会觉得你已经咬了超过你能嚼的东西。这很正常。潜心研究一个新的图形子领域,却被一堆冗长而密集的书籍、期刊文章、PPT演示文稿和博士论文所困扰,这是很常见的。(也许你想快速浏览一下这本432页充满公式的关于路径追踪的开创性著作?或者在下午阅读一些关于Frostbite引擎中基于物理的渲染的文章(122页))。

  我写这篇文章是为了提供我在过去几年中发现的有用的技巧和建议。我专注于一般的原则,而不是具体的资源(书籍、教程等),但我会在最后提到其中一些。(因为如果没有一堆过时或是失效的参考资料和链接,那么这篇关于学习图形的文章将是什么呢?) )

  让我们开始吧。

心态

  首先,冒着听起来很轻率的风险,我建议要有极强的动力来学习更多的图形知识。这听起来可能是不必要的(或者说是显而易见的),但这是一个重要的因素--你越有动力,你就会投入越多的时间,当事情变得困难时,你就越不可能放弃,而这是会发生的。

  做一些周末式的快速图形项目是可能的(比如用Peter Shirley的书写一个简单的光线跟踪器),但更严肃的项目将涉及大量的学习和磨练,以取得重大进展。如果事情不是这样就好了,但这是我的经验。

  对我来说,获得动力的最好方法是开始构建一个我计划最终发布的真正的产品(这就是我对PARTICULATE的做法)。有些人很乐意在多个小的 "玩具 "项目上工作,或者建立一个个人引擎来学习不同的技术。这些方法并没有错--采取这些方法甚至可能是尽快学习许多技术的最好方法。但是,当我有一个人们可以使用的成品的愿景时,我就会有最执着的动力。这个愿景有助于指导我学习和做下一步的工作(并在我感到灰心的时候激励我)。你的情况可能有所不同--找到有效的方法吧!

  第二,重要的是要培养一种对哑巴感觉的宽容。当你遇到大量的文章、替代方法、不熟悉的数学以及密集的PPT和PDF时,很容易让一个简单的目标(比如说,渲染文本)变得不堪重负。(以文本渲染为例--Eric Lengyel把他的高质量文本渲染库卖给那些已经雇用了渲染专家的公司是有原因的。文本渲染比它最初看起来要复杂得多)。

  如果你讨厌哑巴的感觉--我不能说我喜欢这种感觉,但我已经能更好地容忍它了--你就更有可能放弃并回到更熟悉的牧场。极为积极的态度也有助于坚持不懈地克服哑巴的痛苦 😃

  通常需要多次阅读同一材料才能完全理解它(甚至接近理解)。我喜欢阅读不同的资源,这样我可以吸收对同一概念的不同解释,因为每个作者都有自己的角度。此外,即使经过多次阅读,你可能仍然觉得自己没有完全理解一个新的主题。这是我必须适应的--作为一个经验丰富的程序员,我已经习惯了对计算机科学中的新概念感到相当快的适应。
image

阅读多位作者对同一主题的看法,就像从多个图像中重建一个三维模型--额外的角度有助于填补完整的形状。(图片来自这篇文章)。

  我建议不以完全理解为目标,而是在每次阅读新的资源时,对一个主题多一点理解。把它看作是剥开洋葱的一层。(我在Laura Reznikov关于学习图形的Twitter主题中提到了这个想法,其中包含了其他的好建议)。

  有时你需要实现一些你觉得自己还没有完全理解的东西。一个常见的例子是输入那些看起来还有点神秘的数学公式。这可能是一条危险的道路(因为它使调试极其困难,还有其他问题),但有时在这方面有点 "欠债 "是必要的,以保持事情的进展。

  把你已经实现的、你不完全了解的东西列一个清单,并在你继续前进的过程中争取了解更多的东西。(与此相关的是,这个Twitter主题包含了一些关于理解图形论文中使用的数学的有用提示)。

  在图形学中,接受他人的工作,这一点非常重要。在更普遍的编程中,通常可以在不做很多背景研究的情况下设计出自己的算法。当然也有例外--使用quicksort比自己重新发明bubble sort更好--但我发现在其他一些领域,凭自己的能力编程更容易。如果你在图形学中经常尝试这样做,你会浪费很多时间去想出不合格的解决方案。随着你的经验越来越丰富,你将能够自己开发新的技术,但即使如此,你还是会严重依赖以前的工作。

管理信息过载

  要深入学习图形学--特别是在你自己或在有限的监督下--你需要成为寻找资源的高手,迅速梳理它们,并吸收对同一问题的不同方法(甚至是对同一方法的不同看法)。预计你会阅读大量的文章、博客文章、课程笔记、会议论文、论坛帖子、Twitter帖子、PPT演示文稿、博士和硕士论文以及书籍(并观看大量的会议演讲视频)。

  翻阅神秘的PPT演示文稿--特别是那些没有演讲者注释的演示文稿--是一种特殊的 "乐趣",有时由于缺乏关于你所感兴趣的主题的视频和文章,这种乐趣是必要的。

image

我在试图解码一个缺乏发言者注释的PPT演示文稿时。

  有时,你会浪费很多时间去解读一个特定的资源,后来才发现,作者没有很好地解释事情。最终,你会发展出一种第六感,即当一个资源感觉过于晦涩难懂时(即使你还不了解这个主题)。一旦你发现了这一点,你就可以迅速转向同一主题的其他资源--希望这些资源是存在的--并减少浪费在破译不清楚的解释上的时间。

  预计会经常遇到这类情况。你有一个新的图形问题需要解决(为你正在进行的一个项目),你需要了解这个问题的情况,以确定如何进行。最先进的解决方案是什么?在质量、效率和易实施性之间的权衡是什么?

  仅仅回答这些问题就需要相当长的时间--网络上到处都是现在很少使用的老方法(模版阴影)和从未完全成功的实验性方法。然后在某些情况下,你会发现一种看起来很好但性能很差的方法(例如,许多关于顺序无关的透明性的方法)。

  事情之所以如此复杂,部分原因是随着图形硬件和API的发展以及新技术的出现,权衡因素也在不断变化。像延迟渲染这样的技术可能在一段时间内无处不在,但随着形势的变化,它开始失宠(新硬件改变了内存带宽和计算之间的权衡;新技术被证明难以与它的限制整合)。

  最好的情况是找到一篇专家写的 "综述 "式的文章--需要是最近写的!--涵盖了某一特定问题的主要解决方案,并对其中的权衡进行了描述。不幸的是,这样的文章并不总是可用的,但当你找到它们时,它们是非常宝贵的。Aras Pranckevičius的这篇关于文本渲染的文章就是一个很好的例子。

  另一个不错的选择是询问友好的专家,特别是那些曾经写过你感兴趣的问题的人。推特是一个做这个的好地方。看看图形中的其他人在关注谁,找到谁在那里。

  即使你从专家那里得到了完全最新的信息,你仍然要确定一项技术对你的具体情况(API、硬件平台、质量/性能需求等)的适用性。你最不想做的事情是花几周时间实施一个解决方案,却发现它不适合你的情况。

  为了帮助解决这个问题,我建议寻找一个我称之为 "存在证明 "的东西--一个在类似平台上运行的游戏/应用程序(与你的项目类似),以足够好的质量和性能解决了你的问题。一旦你找到这样的例子,试着找到开发者使用的具体技术。(通常他们会在文章或演讲中公开讨论,或者你可以直接问他们)。知道你正在实施一种可以在你的目标平台上取得良好效果的技术,这让人感到很欣慰。现在,实际复制这些结果是另一回事,但你知道它是可能的。)

永远学习

  在编程中,霍夫斯塔特定律是一个东西。

  即使你考虑到霍夫斯塔特定律,它也总是比你预期的要长。- 霍夫斯塔特定律

  在像图形学这样密集而复杂的领域,这一点是加倍的。当开始一个项目或任务时,你还不知道你是否在打开一个潘多拉的盒子。需要的解决方案可能比你想象的要复杂得多,而且可能需要大量的背景阅读。出于这个原因,我建议预测你接下来要面对的几个问题,并在你遇到这些问题之前开始阅读/研究过程。

  确保这种情况发生的最好方法是什么?总是在学习。我建议不断扩大你的图形知识,超越你目前正在进行的工作。把你的学习网扩大是很好的,因为你永远不知道你将来会突然需要使用什么--不同领域的概念会以意想不到的方式结合起来。

  我采取了一种日常学习的做法,以确保我一直在推动我的知识前沿--每个工作日,我都会花第一个小时来阅读关于图形(以及一些非图形但与编程有关的主题)的文章(等等)。通过连续几年这样做,我已经吸收了大量的信息。

  我还花了一些业余时间阅读较长篇幅的书籍,观看会议演讲的视频等等。但我建议不要在空闲时间里尝试过度,因为这可能会导致倦怠。(由于这个原因,我在过去不得不把事情做得很低调)。

  当选择如何集中你的学习时间时,我建议花大量的时间在 "基本原理 "上--这些东西是许多技术的基础,往往会反复出现。基本原理的一些例子是:(
渲染API功能和最佳实践。

  • GPU硬件架构和硬件光栅化管线。
  • 线性代数和基本微积分。
  • 浮点的内部表示和错综复杂的问题。
  • 抗锯齿,mip地图和纹理过滤。
  • 面向数据的设计原则和技术。
    (这份清单的重点是实时渲染。)

  当你开始真正掌握像这样的基础知识时,你会发现你学习新技术的能力开始加快。(注意到这种趋势真的很令人满意)。

  我认为图形专家往往低估了学习处理新信息所需的背景所需的时间(因为作为专家,他们已经了解了图形景观的形状以及它的碎片如何组合在一起)。例如,要真正理解网状着色器的功能,以及为什么它们是一个进步,就必须了解大量的背景,而这些背景并不包含在关于网状着色器的文章中!我花了几年时间专注于网状着色器的研究。

  我花了几年的时间潜心学习,才真正感觉到我已经摸清了这个领域,并把所有的 "未知数 "变成了 "已知数"(在某些情况下是 "已知数" 😃 )。一旦我完成了这一映射--由于未知的兔子洞出奇地深,花费的时间比预期的要长--就更容易快速吸收新的信息(也知道去哪里找)。当仍有许多未知数的时候,你会觉得自己在黑暗中颠簸。

image

当仍有许多未知的不确定因素时的感觉。

  这就是我对如何学习图形的一般建议的结束。最后一句话--请记住,这个旅程将需要数年时间(而且永远不会结束)。一旦一切都开始了,这将是令人难以置信的满足感和力量。

资源

  如前所述,本文的重点不是具体的API、技术或资源,但我确实想列出一些最重要的资源,这些资源具有普遍意义。除了这个清单之外,还有一个非常长的资源尾巴(会议论文和演示文稿、博客文章等),你通常会通过谷歌找到这些资源来挖掘特定的主题。

书籍

我已经阅读并推荐了这些书。

  • Real-Time Rendering (Akenine-Möller et al) --实时技术的旋风式调查;在大多数情况下,你需要阅读进一步的参考资料来实现这些技术。
  • Physically Based Rendering (Pharr et al) - 实现现代(离线)路径跟踪器;其中许多内容也与实时渲染有关(现在可以在pbr-book.org上免费在线阅读)。
  • Game Engine Architecture (Gregory) - 对游戏引擎内部的高层次调查,并对一些主题进行了深入研究(对图形的讨论相当粗略)
  • Mathematics for 3D Game Programming and Computer Graphics (Lengyel)--与图形有关的数学速成课程
  • Foundations of Physically-Based Modeling and Animation (House和Keyser)--对物理运动(粒子、弹簧、刚体、流体)的数值模拟的精彩介绍
      特别是《Real-Time Rendering》和《Physically Based Rendering》是很密集的书,可能很难读懂,但非常值得--把它看成是一次塑造性格的经历,不要指望第一次读就能完全理解所有内容。

我没有读过这些书(还没有),但它们被强烈推荐。

还有一些关于更多小众主题的书(以及关于特定渲染API的书),但我将把清单留在这里。

视频

会议报告中有大量高质量的内容,不过你必须有所选择,以免你在接下来的十年里除了看视频什么都不做。

网络

这个列表只是触及了表面。我试图包括一些反复出现的经典参考资料(而且一年后不可能成为死链接,我希望!)。

  • Jendrik Illner’s Graphics Programming Weekly — incredibly valuable weekly review of new graphics-related web content; the best way to stay up-to-date without spending too much time on Twitter
  • Joey de Vries’s LearnOpenGL.com — though OpenGL-specific (shockingly), probably the best graphics tutorials on the web
  • Fabian Giesen’s A trip through the Graphics Pipeline 2011 — a very detailed description of the hardware rasterization pipeline as it’s commonly implemented
  • Shadertoy — a very deep rabbit hole of demoscene-style techniques that produce beautiful results (warning: a lot of the techniques used are feats of math of limited applicability to real-world projects)
  • Inigo Quilez’s articles and videos — Quilez is co-creator of Shadertoy and a master of his craft
  • Adrian Courrèges’s “graphics studies” — detailed analyses of the rendering in particular games
  • Fabien Sanglard’s game engine source code reviews — due to the age of the engines reviewed, these are mostly interesting from a historical perspective
  • Dmitry Sokolov’s tinyrenderer — tutorials / source for implementing “OpenGL” (hardware rasterization, roughly) in C++ as a learning exercise
  • Bartosz Ciechanowski’s articles — there aren’t many of them, but these articles are incredibly thoughtful and well-done (and in some cases interactive) (see, in particular, Lights and Shadows, Alpha Compositing, Color Spaces, and Exposing Floating Point)
  • Jendrik Illner的《图形编程周刊》--对新的图形相关的网络内容进行令人难以置信的有价值的每周回顾;这是保持最新而无需在Twitter上花费太多时间的最佳方式。
  • Joey de Vries的LearnOpenGL.com - 尽管是专门针对OpenGL的(令人震惊),但可能是网络上最好的图形教程。
  • Fabian Giesen的A trip through the Graphics Pipeline 2011 - 非常详细地描述了硬件光栅化管线,因为它通常被实现。
  • Shadertoy - 一个非常深的兔子洞,里面的演示技术产生了美丽的结果(警告:所使用的许多技术是数学上的壮举,对现实世界项目的适用性有限)。
  • Inigo Quilez的文章和视频 - Quilez是Shadertoy的共同创造者,也是他的工艺大师。
  • Adrian Courrèges的 "图形研究"--对特定游戏中的渲染进行详细分析
  • Fabien Sanglard的游戏引擎源代码评论--由于所评论的引擎年代久远,这些评论主要是从历史的角度来看的。
  • Dmitry Sokolov的tinyrenderer - 用C++实现 "OpenGL"(硬件光栅化,大致如此)的教程/源码,作为一种学习练习。
  • Bartosz Ciechanowski的文章--虽然数量不多,但这些文章都是经过深思熟虑的,而且做得很好(在某些情况下是互动的)(特别是见灯光和阴影、Alpha合成、色彩空间和暴露浮点)。

问问题的地方

Subreddits like /r/graphicsprogramming, /r/opengl, and /r/vulkan
Discords like Graphics Programming, DirectX, Vulkan Community, Shadertoy, and GameDev.net (#graphicsdev in particular)
Forums like gamedev.net (to the extent they’re still used these days)
Ask people directly on Twitter (or alternatively, spend years building up a following and then ask your legions of followers)

  • 像/r/graphicsprogramming、/r/opengl和/r/vulkan这样的subreddits
  • 像图形编程、DirectX、Vulkan社区、Shadertoy和GameDev.net(尤其是#graphicsdev)这样的讨论区
  • 像gamedev.net这样的论坛(现在还在使用的程度)。
  • 直接在Twitter上问人(或者,花几年时间建立一个粉丝群,然后问你的粉丝群)。
  • 不过说真的,如果你要深入研究图形学,我强烈建议你使用Twitter,因为它能让你接触到这个领域中最聪明、最有成就的人。只要努力保持警觉,躲开那些喷火器就可以了。

资源愿望清单

  我希望能看到一本关于现代实时渲染引擎架构的中高级书籍。我还没有找到任何例子--关于游戏引擎的书往往会忽略渲染方面的内容(因为还有很多其他的东西要讲),而关于渲染的书往往会关注具体的技术,而不是如何将所有的东西整合成一个复杂的相互联系的系统。目前的情况是,人们只能阅读关于这个主题的零散文章,并深入研究源代码(虚幻引擎Godot是两个合理的游戏引擎源码选择)。

  我还希望看到一个更活跃的集中的图形讨论论坛。似乎Twitter已经在很大程度上取代了更多传统的互联网论坛,但它的分散(和混乱)性质和混乱的线程使它缺乏一个完整的替代。在Twitter上也很难进行深入的讨论。(Discords是另一个不错的选择,但也有Twitter的一些问题)。

posted @ 2022-09-08 12:32  泥烟  阅读(75)  评论(0编辑  收藏  举报