Ogre2.1不是采用现在大部分引擎所用的延迟渲染,而是采用一种前向渲染的改进技术,理论基本来自于Forward+,见如下。
http://www.ogre3d.org/2015/03/05/ogre-progress-report-february-2015
第一个链接是Forward+技术的原理,第二个是讲Ogre2.x的Forward3D实现,和正规的Forward+不同之处,以及没有默认采用延迟渲染的原因,顺便也指出,一样可以采用延迟渲染,并且还能使用Forward3D生成的数据,实现Tiled-based Deferred Shading,相比Ogre1.x中的延迟渲染例子,现ogre2.1中实现更方便与高效,大致看下Ogre2.1的渲染流程(更高效的多线程,统一Cull,SOA,SMID)就能明白。
为了巩固对延迟渲染的理解,解释下Ogre1.x中延迟渲染例子,对于这个例子我自认为是Ogre1.x中的比较有难度的一个例子,因为关联的东东太多,如渲染流程以及事件在流程中的位置,合成器技术,自定义合成器渲染的实现,RTT,MRT等等,原来一直想单独用一篇来说明Ogre1.x中的延迟渲染例子,在Ogre2.1出来后,这个想法也就没了,简单说下这个例子,在这不讲理论,理论大家自己查找下,只讲Ogre1.x中的这个例子实现过程。
Ogre1.9的延迟渲染例子
1 生成GBuffer。使用合成器第一阶段DeferredShading/GBuffer,设置当前材质方案为GBuffer,截获(10至79)渲染通道,一般来说,Ogre1.x中,10之前的通道用来渲染背景如天空盒之类的,90之后的用来渲染UI这些,正常模型不设置默认为50,在这灯的包装模型设置渲染通道为80,所以GBuffer里没有包含灯的模型。
在渲染时,因为当前材质方案为GBuffer,Ogre就会去查找相应的MaterialManager::Listener,在这GBufferSchemeHandler调用GBufferMaterialGenerator根据Pass属性生成对应着色器代码,这里有点像Ogre2.1中的高级材质系统HLMS,在这把如点位置,顶点颜色,法线,纹理坐标等写入到GBuffer中,也就是纹理中,这里只用到二张,第一张保存颜色与暴光系数,第二张法线与深度,如果有法线贴图,法线是经过片断法线贴图转化了的,还有可能有人要问,顶点位置昨没了,这个在下面会提到。
2 使用GBuffer信息,还原顶点位置,法线,结合灯光生成最终颜色。使用合成器第二阶段DeferredShading/ShowLit,采用自定义的合成器渲染DeferredLight渲染场景全局颜色与灯光,此处可见DeferredLightRenderOperation::execute,把场景全局颜色包装成AmbientLight,灯光包装成DLight进行渲染。相应着色器代码的目录在DeferredShading/post,其中,AmbientLight与DLight都采用相同的顶点着色器vs.glsl,其中AmbientLight片断着色器是Ambient_ps.glsl,DLight根据灯光类型设置编译条件,LightMaterial_ps.glsl生成不同片断。
在这感觉有必要说下如何得到顶点位置,感觉这个思路还是很赞的。注意,GBuffer里存的深度是在视图坐标系下的,视图坐标系也是这个思路的重点。下面是vs.glsl的代码.
#version 150 in vec4 vertex; out vec2 oUv0; out vec3 oRay; uniform vec3 farCorner; uniform float flip; void main() { // Clean up inaccuracies vec2 Pos = sign(vertex.xy); // Image-space oUv0 = (vec2(Pos.x, -Pos.y) + 1.0) * 0.5; // This ray will be interpolated and will be the ray from the camera // to the far clip plane, per pixel oRay = farCorner * vec3(Pos, 1); gl_Position = vec4(Pos, 0, 1); gl_Position.y *= flip; }