合成器架构是OGRE API的一部分,它允许你轻松定义全屏的后加工处理效果。合成器脚本给你提供了在脚本里定义合成器效果的能力,并且它们可以重复使用而且容易更改,而不必使用API去定义它们。虽然你仍然要使用代码实例化一个针对可视视口的合成器,但是比起实际上定义合成器本身这已经是相当简单的过程了。
合成器基本原理
进行后处理效果通常包括最开始的用纹理渲染场景,其中有些是添加到主窗口的有些是替代主窗口的。一旦场景中有了纹理,你就可以将场景图像送入一个片断程序,并在片断程序中通过全屏范围渲染它。这一后处理渲染的目标可以是主结果,又或者是另一种渲染纹理,以至于在画面上形成多级回旋。你甚至可以在两个渲染纹理之间反复进行渲染,以达到需要多次循环的回旋效果,而不是每层使用一个单独的纹理。最终,你将得到一个全屏窗口的最终渲染输出结果。这将代替整个窗口(因此,主窗口不必渲染场景本身),或者是一个联合效果。
因此,我们可以讨论一下,如何有效地实现这些技术,需要如下一些定义:
-
合成器
- 一个可以被应用于用户视口的全屏效果定义。当你写合成器脚本时,这就是你在这部分要详细定义的东西。
-
合成器实例
- 一个被应用于单一视口的合成器实例。根据合成器定义创建这些实例。参看 3.2.4 合成器应用。
-
合成器链
- 在一个视口上同时打开不止一个合成器实例是可能的,即一个合成器将其前面一个合成器的结果作为自己的输入。这就是合成器链。每一个至少有一个合成器的视口都有一个合成器链。参看 3.2.4 合成器应用。
-
目标
- 就是渲染目标,一系列渲染操作的结果被送到此处。一个目标可能就是一个最后的输出结果(并且这是隐含的,即不必声明它),或者是脚本中用 texture行声明的中间渲染纹理。不是输出目标的其他目标都有确定的大小和你可以控制的像素格式。
-
输出目标
- 也是目标,但是它是所有操作的唯一最终结果。此目标的大小和像素格式不能由合成器控制,因为它是由使用它的应用环境决定的,因此你不能在你的脚本里声明它。但是,你确实可以为它声明一个目标通路。详见下面介绍。
-
目标通路
- 一个目标在一个合成效果过程中可以被多次渲染。个别情况下,如果在两个纹理之间反复回旋,每个目标你都会得到不只一个目标通路。目标通路在脚本中用target行或者target_output行声明,后者是只能有一个的最终输出目标通路。
-
通路
- 在一个目标通路里,有一个或多个单独的渲染通路,分别进行各自的渲染动作,例如渲染初始场景(或者从合成器链中的上一个合成器取结果),渲染全屏图像,或者清空一个或多个缓冲器。典型地,在一个单独的目标通路里,你将使用'render scene'通路或者'render quad'通路,二者选其一,不能同时用。清空两种类型都可以使用。
装载脚本
合成器脚本是在资源组被初始化时被装载的:OGRE在所有与组相关的资源位置(详见Root::addResourceLocation)搜索'.compositor'后缀的文件,并解析它。如果你想人工解析,使用CompositorSerializer::parseScript。
格式
多个合成器可能被定义在单独的一个脚本里。脚本格式是借用C++的,以大括号('{','}')为段分隔符,以'//'作为一行的开始表示注释这一行(注意,不允许嵌套注释)。一般格式见如下例子所示:
// This is a comment // Black and white effect compositor B&W { technique { // Temporary textures texture rt0 target_width target_height PF_A8R8G8B8 target rt0 { // Render output from previous compositor (or original scene) input previous } target_output { // Start with clear output input none // Draw a fullscreen quad with the black and white image pass render_quad { // Renders a fullscreen quad with a material materialOgre/Compositor/BlackAndWhite input 0 rt0 } } } }
脚本中每个合成器都必须给定一个名字,即最开始的大括号('{')前面的'compositor '行。这个名字必须是全局唯一的。它可以包括路径字符(如上例所示)以便逻辑上区分你的合成器,也为了避免重名,但是引擎并不将这个名字分级对待,而仅作为字符串处理。名字里也可以包含空格,但是如果这样的话,就必须用双引号括起来,如compositor "My Name"。