zoukankan      html  css  js  c++  java
  • Deferred Shading

    本篇博客说一下学习延迟渲染中遇到的问题。


     学习延迟渲染的过程中主要给了我疑惑的是深度测试的问题,在Learn OpenGL的相关代码中,我并没有看到G-buffer有根据片段深度对片段进行消隐或者显示。这是我一直疑惑的地方。如果在fragment shader中不经过深度测试就将片段输出至G-buffer相对应的纹理附件上的话,我认为会出现一些问题(因为纹理附件是2D的,在纹理附件上的一点不可能产生2个RGB值,这就说明我们需要在fragment shader中进行深度测试)。

    言归正传,先来说说延迟渲染的概念。

    在讲解延迟渲染之前,我们首先要知道到目前为止用的渲染都是正向渲染(forward rendering或者forward shading),即对于一个有多个物体以及一个光源的场景,我们会一个物体一个物体(无序)地去渲染(计算光照)。对于一个光源来说这可能没什么问题(事实上之前的学习中用到的光源不超过10个),然而如果是多个光源的话,问题就大了:由于多个光源下要进行的计算量很大(要逐个片段计算光照,然后还得将各个光源的光照效果结合起来),如果我们还是一个物体一个物体地去渲染,那么就有可能因为片段遮挡(片段深度测试)的问题导致一些计算白白浪费掉;并且因为计算量大,帧率也会下降。

    于是乎就出现了延迟渲染(deferred shading),延迟渲染改掉了“先光照计算,再深度测试”的顺序,变成了“先深度测试,再进行光照计算”。伪码如下:

    Pass 1 {
        //第一个Pass不进行光照计算,仅存储光照计算所需信息到G缓冲中
        
        for (each primitive in this model) {
             for (each fragment covered by this primitive) {
                 if (failed in depth test) {
                     discard;//若没有通过深度测试,则该片元不可见
                 }
                 else {
                     //若该片元可见,则进行光照计算,则将相关信息存储到G缓冲中
                     writeBuffer(materialInfo, pos, normal, lightDir, viewDir);
                 }
             }
        }
    }
    Pass 2 {
    	//利用G缓冲中的信息进行真正的光照计算
    	
    	for (each pixel in the screen) {
    		if (the pixel is valid) {
            	//若该像素有效,则读取其G缓冲中的信息
            	readBuffer(pixel, materialInfo, pos, normal, lightDir, viewDir);
            	
            	//根据读取到的信息进行光照计算
            	float4 color = Shading(materialInfo, pos, normal, lightDir, viewDir);
            	//更新帧缓冲
            	writeFrameBuffer(pixel, color);
                    }
            }
    }

    这样子就能避免不必要的光照计算了。值得一提的是,当光源数目不多的时候,有可能正向渲染的开销要小于延迟渲染,并且延迟渲染不能使用MSAA和Blending

    延迟渲染的优点是可以在大量渲染光照的时候不消耗大量的内存,然而并不能认为这它可以无限制地渲染光照,更多情况下,(由于光线衰弱等原因)我们会计算光照的“作用半径”,也就是光能到达的范围,称之为光体积(light volumes),来从根本上节省光照计算的开销。

    具体如何操作这里就不写了,详情参照Learn OpenGL的相关章节即可。

    参考资料:

    [1]【《Real-Time Rendering 3rd》 提炼总结】(七) 第七章续 · 延迟渲染(Deferred Rendering)的前生今世

    [2] Deferred Rendering基础篇(一)

    以上

    原来人类的悲欢并不相通, 我只觉得他们吵闹。
  • 相关阅读:
    软件测试工程师linux十大场景命令使用
    用yum安装软件显示错误:cannot find a valid baseurl for repo: base
    Redis安装、启动与多端口配置
    Linux vi编辑器
    cookie 和session、三种保持登陆会话的方式
    服务器内存溢出问题
    selenium多窗口切换
    Turtle库的学习积累
    高频ES6
    事件冒泡和捕获的执行顺序
  • 原文地址:https://www.cnblogs.com/zhlabcd/p/11972694.html
Copyright © 2011-2022 走看看