渲染器开发笔记1-ECS框架实现

Tags:

目前进展:

  1. 已把项目改造使用ECS框架,顺眼很多

  2. 做了基本的一系列system设计和实现

  3. 正在弄Deferred Rendering框架

开发计划:

  1. 据某大牛说,不结合实际的游戏项目而去开发游戏引擎,就是扯淡。所以目前还不打算把这个renderer项目弄成引擎,而是当做一个纯粹的渲染器来做。focus在渲染这块,所以会忽略开发一些次要模块,如脚本引擎、音频播放器、控制器啥的,都不搞。不过渲染这个东西里面,还有很多问题得暂时忽略的,例如是否要嵌入一个物理引擎还是自己做一个简易版(当学习CD算法)、超大世界渲染是否要做、动画系统等。

  2. 基于第一点,目前打算实现的是:Deferred + Forward的框架。实现之后的下一个计划是PBR渲染和SSAO。其他就不管先了。

记录一些渲染的心得

单纯的Forward Rendering为什么不好?

正向渲染,每一个模型都得跑一遍shader(vs做mvp变换、fs做光照),那么就是说每一个通过depth test的fragment都得做光照,而光照计算一般是一个线性叠加的过程,有几个光源就做几遍lighting pass,所以:

大致的时间复杂度 = O(模型面片数量 * 光源数量)

(注意,这里的光源数量非常关键,多一个光源就等于多跑了一遍fs。)

正向渲染的不足之处在于有大量的做了光照计算的fragment被覆盖掉了,即光照白做了。例如我先draw一个10万面片的角色,然后又在这个角色前面draw了一堵墙,完全把这个角色挡住了,那么这个角色的光照计算就是白做的。

Deferred Rendering的正确做法和优点

延迟渲染的延迟指的是把光照计算延迟了,以刚刚的例子来说,先渲染一个10万面片的模型,再渲染一堵墙,不会再有光照计算的浪费。延迟渲染的GBuffer,不会有光照计算信息。光照计算延迟到geometry pass之后再做,和模型面片数量再无关系,而与frame buffer分辨率产生关系

大致的时间复杂度 = O(模型面片数量) + O(光源数量 * 分辨率)

从这条公式可以发现,即使模型再多面片再多,光照计算只会和分辨率有关系,从而理论上可以做到超多光源渲染。

但Deferred Rendering不是一种用来替代Forward Rendering的技术,而是一钟补充。延迟渲染的特性导致有一些技巧会不好使,例如半透明的混合渲染。正确的做法是先延迟后正向,两步渲染。

值得一提的是, O(光源数量 * 分辨率),这一步还得特别优化下才能实现超多光源渲染。优化原理是:剔除掉和目标fragment无关的光照计算。比如可以根据光源强度和距离,把足够远的光源排除掉,那么就可以省下很多计算量。

(未经授权禁止转载)
Written on September 18, 2017

博主将十分感谢对本文章的任意金额的打赏^_^