OpenGL延迟着色法详解(上)
发表于2018-03-02
原文链接:https://learnopengl-cn.github.io/05%20Advanced%20Lighting/08%20Deferred%20Shading/
本篇文章只是学习延迟着色法的心得,系统学习请参考原文。
之前看Unity的文档的时候,经常看到正向渲染和延迟渲染这样高大上的名词,然后看了一下文档,依旧保持一脸懵逼的状态。
直到我学习了这篇之后,才真正理解了延迟渲染的意义和存在价值。
Q1:正向渲染的缺陷是什么?
大部分片段着色器输出,都会被之后的输出覆盖,浪费了大量资源。而且场景越复杂,光源越多,这种浪费越严重。
Q2:延迟着色延迟的是那一部分?
延迟的是复杂的光照部分。也就是片段着色器的部分。
Q3:延迟着色发的原理是什么?
把几何处理阶段的数据,存到G-Buffer中去,然后像类似后期处理一样的方式,去利用G-Buffer中的数据去计算光照
OpenGL并没有限制我们往颜色缓存里面存放什么数据,这是延迟着色法得以实现的大前提。
Q4:延迟着色发算是后期处理的一种吗?
原则上不是。
虽然有相似之处,比如,想把数据写入到Buffer中去,然后在一张Quad(四个顶点组成的平面)上计算最终结果。
但是,延迟渲染中的G-Buffer中的数据,并不是最终结果,他只是整个渲染过程的一部分,只有加上延迟着色的那部分,才算完成了一个完整的渲染过程。
Q5:延迟着色法有哪些缺点?
需要消耗大量缓存。
不能处理颜色混合。
迫使你对大部分场景使用相同的光照算法,虽然可以通过包含跟多关于材质的数据来减缓这一缺陷,但是也意味着会消耗更多的显存。
Q6:延迟着色为什么会消耗大量缓存?
因为我们要把大量数据存放到G-Buffer中,比如:顶点数据,法线向量数据,颜色数据,镜面反射系数数据等等。
初次之外,还要传入观察点位置和光源数据,当然,这些是可以忽略不计的。
Q7:延迟着色法为什么不支持颜色混合。
因为G缓冲中所有的数据都是从一个单独的片段中来的,也就是最前面的片段,而混合需要依赖当前片段和之前的片段进行计算操作(注意:在处理G缓冲的时候,实质上的片段操作还木有开始,下图中的G-Buffer.fs本质上是填充G-Buffer的过程,而不是在计算片段。)
下图是我对延迟着色发的过程的理解,这张图不包含通过前向着色法结合延迟着色法进行统一渲染的流程,那将是另一篇心得的内容。
第一组Shader,用来填充G-Buffer。
第二组Shader,用来通过G-Buffer中的数据来计算复杂的光照
第三组Shader,用来渲染光源,因为光源通常不参与光照计算,所以要单独提取出来渲染。
结合原文对应的例子代码,看这张图效果会更好!