Ogre参考手册(五)3.2 合成器
3.2 合成器Compositor
合成器框架是Ogre用于全屏后处理的API。你可以通过脚本而不是API定义合成器。你可以很容易为视口实例化合成器。
合成器基础
无论是要替换还是要与主渲染窗口混合,实现后处理效果首先是渲染场景到纹理。当场景渲染到纹理后,你可以将其渲染为全屏四边形从而将场景图像推送到片段着色器进行处理。后处理渲染目标可以为最终结果(渲染窗口),也可以是另一个渲染纹理,从而可以对图像实现多次转换。你可以在一对纹理之间多次转换,而不用为每个阶段采用单独的纹理。最后,你可以通过全屏四边形将结果输出。这一步可以替换整个渲染窗口(此时主渲染窗口不需要对场景进行渲染),或者进行混合。
定义
Compositor 合成器
定义一个用于视口的全屏效果。本节将详细介绍如何通过合成器脚本进行定义
Compositor Instance 合成器实例
针对某个视口的合成器实例。 通过合成器定义创建, 参考3.2.4应用合成器。
Compositor Chain合成器链
可以对单个视口实例化多个合成器,每一个合成器采用前一个的输出作为输入。关联了一个或以上合成器的视口将创建一个合成器链
Target 渲染目标(纹理或最终输出)
一系列渲染操作的结果,渲染目标可以是最终的输出(默认,不需要声明),或者作为中间渲染纹理(通过texure脚本行定义)。不作为输出目标的渲染目标可以设置大小和像素格式。
Output Target 输出目标
类似渲染目标,作为所有操作的最终结果。大小和像素格式由应用环境决定,不可以在脚本中设置,可以为输出目标声明目标通道
Target Pass目标通道
一个渲染目标可能需要渲染多次以实现某些合成效果。特别是,如果你在一对纹理间来回转换,每个渲染目标将包含多于一个目标通道。目标通道通过target()或者target_output行声明,最后一个目标通道是最终输出目标通道,每个渲染目标只有一个。
Pass 通道
一个目标通道可以包含多个通道实现各自的动作,比如渲染原始场景、获取前一合成器渲染结果、渲染一个全屏四边形或者清空一个或多个缓冲区。典型情况下,一个目标通道使用一个”render_scene’通道或者’render_quad’通道。 两种情况下都可以使用clear通道.
脚本加载
合成器脚本在资源组初始化时加载,Ogre通过资源位置下的’.compositor’文件解析合成器。可以通过CompositorSerializer::parseScript手动解析合成器脚本。
示例:
compositor B&W
{ technique {
// 定义渲染目标rt0(纹理)
texture rt0 target_width target_height PF_A8R8G8B8
target rt0 //目标通道, 渲染到渲染目标rt0(纹理)
{
input previous //从前一合成器或者场景输入数据
}
target_output //输出目标
{
input none //无输入(先清空输出)
pass render_quad //通道,渲染为全屏四边形
{
material Ogre/Compositor/BlackAndWhite //指定渲染采用的材质
input 0 rt0 //材质所用的第一纹理:rt0
}
}
}
}
合成器必须有名称,名称必须唯一,名称中可以含路径符’/’,该字符可以用来逻辑划分质,也有助于避免重复,引擎并不依据此按树结构处理。如果名称包含空格,需用双引号括起来。
3.2.1 Technique技术
合成器技术与材质类似,用于描述实现效果的一种方式。可以定义多个技术以便硬件不支持的时候退化处理。技术的硬件支持基于两个方面:
材质
渲染全屏四边形的通道需要使用材质,当材质不支持时,通道将退化
纹理格式
并不是所有请求的格式硬件都支持,特别是浮点格式。这种情况下,硬件典型的会降级请求格式为硬件支持的格式。在使用合成器时,你可能希望不同的方式。在评估技术时,合成器先检查原本的像素格式支持,如果不支持将跳到下一技术。没有匹配的技术时,将再次检查,此时将允许使用硬件降级的纹理格式。
和材质技术一样,先声明的技术优先使用
技术包含以下内嵌元素:
texture
声明渲染纹理,用于后续的目标通道
格式:texture <Name> <Width> <Height> <Pixel Format> [<MRT Pixel Format2>] [<MRT Pixel FormatN>] [pooled] [gamma] [no_fsaa] [depth_pool <poolId>] [<scope>]
name 纹理名,合成器内必须唯一。用于在目标通道渲染到该纹理时引用,或者在通道渲染全屏四边形时作为材质的输入
width/height 纹理大小,可以指定固定的大小或者基于合成器关联视口的物理大小。基于视口通过 'target_width', 'target_height', target_width_scaled <factor>' 和'target_height_scaled <factor>
factor为对应的缩放倍数
Pixel Forat 像素格式,决定内存使用数量、可用颜色通道、颜色通道精度。可用的格式包括: PF_A8R8G8B8, PF_R8G8B8A8, PF_R8G8B8, PF_FLOAT16_RGBA, PF_FLOAT16_RGB, PF_FLOAT16_R, PF_FLOAT32_RGBA, PF_FLOAT32_RGB, PF_FLOAT32_R.
pooled 如果提供,要求纹理在合成器示例间共享,可以节省内存
gamma 如果提供,要求写纹理时需要rgb gamma校正,你需要相应的在读取纹理材质中转换回去,比如渲染四边形时。当使用render_scene通道渲染到此纹理、同时关联的视口支持rgb写时,此选项自动有效。
no_fsaa 关闭反锯齿(anti-aliasing),当使用render_scene通道渲染到此纹理、同时关联的视口开启FASS时,可使用此选项覆盖默认值,禁用FSAA。
depth_pool 此参数用于设置深度缓冲区使用深度换冲池id(poold)。此指令和pooled指令没有关系。所有合成器的渲染纹理具有相同poodId时将共享同一深度缓冲区(如果渲染系统支持还包括渲染窗口),默认为1,为0时表示不使用深度缓冲区,将节省性能和内存。
scope 纹理访问范围,有三种:
local_scope 默认值,仅所在的合成器可以适应
chain_scope 同一合成器链的后续合成器可用
global_scope 整个应用程序可用
指令影响纹理的创建,global_scope纹理仅创建一次,不能和pooled指令合用,不能依赖视口大小
例:texture rt0 512 512 PF_R8G8B8A8
texture rt1 target_width target_height PF_FLOAT32_RGB
可以重复Pixcel Format,这么做纹理将成为MRT(多渲染目标,Multiple Render Target),用于GPU一次写入多个纹理。用着色器写入MRT时,需要写入所有目标,否则结果未定义。另外,虽然可以指定不同的像素格式,但需要相同的位深度,因为大多说图形卡不支持彼此无关的位深度。如果图形卡不支持你需要的MRT个数,技术将会跳过(退化)。 注:MRT典型用于Ogre延迟渲染的GBuffer(Geometry Buffer几何缓冲区)
texture_ref
声明纹理引用,用于在使用其它合成器中的纹理
格式:texture_ref <Local Name> <Reference Compositor> <Reference Texture Name>
需要确保被引用纹理的作用范围(chain/global_scope),同时被引用的合成器应位于当前合成器之前。
例:texture_ref GBuffer GBufferCompositor mrt_output
scheme
设置合成器方案,用于通过CompositorInstance::setScheme切换不同的技术。
格式:material_scheme <Name>
compositor_logic
建立合成器和代码间的关联管理。合成器创建时,将会通知合成器逻辑,以便做合成器准备工作(比如增加监听器)。可通过CompositorManager::registerCompositorLogic注册合成器逻辑
格式:compositor_logic <Name>
3.2.2 目标通道
目标通道是对目标的渲染,包括渲染纹理或者最终的输出。你可以通过使用多个目标通道对一个渲染纹理进行多次渲染,这对于在一对渲染纹理间来回渲染以实现复杂的效果时很有用,比如模糊.
有两种类型目标通道:
渲染到纹理 target <textureName> {}
渲染到最终输出 target_output {}
两种通道是相同的,区别在于target_output只能有一个
目标通道包含的属性值:
input
输入的内容
intput (none | previous), 默认none
none 无输入,表示通道产生内容。注:none只表示无输入,清空内容仍需要clear pass
previous 采用视口之前的内容,如果合成器是第一个则是原始场景,不是的话则是合成器链中上一个合成器的输出
only_initial
设置为on表示仅在初始化时执行一次。
格式:only_initial (on | off), 默认off
visibility_mask
设置可见性标志位,用于内部render_scene通道,映射到SceneManager::setVisibilityMask,需要设置为10进制数,不是十六进制
格式:visibility_mask <mask>
例:visibility_mask 4294967295
lod_bias
设置场景lod偏移,用于内部render_scene通道。默认值为1.0,小于意味低质量,大于意味高质量
格式:lod_bias <value>
shadows
设置是否渲染阴影,用于内部render_scene通道,默认on
material_scheme
设置内部render_scene通道的材质方案。
3.2.3 合成器通道
通道是目标通道中的一次渲染
格式:pass (render_quad | clear | stencil | render_scene | render_custom) [customName] { }
第一个参数为通道类型,包括:
clear 清除颜色、深度、模板缓冲区,设置为固定的内容
stencil 配置模板操作、比较函数、参考值
render_scene 执行常规的场景渲染,会使用所在目标通道的visibility_mask\lod_bias\material_scheme设置
render_quad 通过指定纹理在整个渲染目标上渲染四边形。毫无疑问,你会用来处理它通道的输出结果实现全屏效果
render_custom 用户自定义合成器通道代码回调接口(通过CompositorManager::registeCustomCompositionPass注册),需要使用customName参数。
通道属性:
material
用于render_quad类型通道,设置渲染四边形所用的纹理。你可能会在材质中使用着色器实现全屏效果,并通过input映射其它纹理目标用于材质纹理绑定, 例:
pass render_quad
{
// Renders a fullscreen quad with a material
material Ogre/Compositor/ASCII
input 0 rt0
}
input
用于render_quad类型通道,设置材质使用的纹理。
格式: input <samplerIndex> <Name> [<MRTIndex>]
samplerIndex 纹理索引,[0, OGRE_MAX_TEXTURE_LAYERS-1]
name 引用的渲染纹理目标名称
MRTIndex 当纹理目标是MRT时,用于标识MRT的表面
例:
input 0 mrt0 0
identifier
设置通道的标识号,用于注册合成器监听器(CompositorInstance::addListener)
格式: identifier <number>, 默认0
例: identifier 99945
last_render_queue
用于render_scene通道,设置最大的渲染队列id,默认为RENDER_QUEUE_SKIES_LATE/95
格式:last_render_queue <id>
material_scheme
设置通道使用的方案,可以覆盖目标通道的方案设置
clear类型
clear类型通道定义清除缓冲区参数,包括:
buffers
格式:buffers [colour] [depth] [stencil]
设置清空的缓冲区
colour_value
设置清除的颜色缓冲区值
格式:colour_value <red> <green> <blue> <alpha>, 默认0 0 0 0
depth_value
设置深度缓冲区值
格式:depth_value <depth>, 默认 1.0
stencil_value
清除后模板缓冲区值
格式:stencil_value <value>, 默认 0
Stencil Section
stencil类型通道设置
check
是否启用模板检查,格式:check (on | off)
comp_func
设置比较操作(ref_value & mask) comp_func (Stencil Buffer Value & mask)中的比较函数
格式:comp_func (always_fail | always_pass | less | less_equal | not_equal | greater_equal | greater)
默认always_pass
ref_value
设置参考值
格式:ref_value <value>, 默认0
mask
设置屏蔽位
格式:mask <value>, 默认4294967295
fail_op
设置模板测试失败时操作类型(模板失败后不会进行深度测试)
格式:fail_op (keep模板值不变| zero 清零| replace设为参考值| increment 模板值加1,裁剪到最大值| decrement -1,裁剪到0| increment_wrap +1,最大值循环为0| decrement_wrap -1,小于0循环为最大值| invert 取反)
默认keep
depth_fail_op
模板测试成功,深度测试失败进行的操作,同fail_op
默认keep
pass_op
模板\深度测试均通过后进行的操作,同fail_op
默认keep
two_sided
模板测试是否双面,on将操作用于背面多边形
默认off
3.2.4 应用合成器
为视口添加合成器实例:
CompositorManager::getSingleton().addCompositor(viewport, compositorName);
默认新增加的合成器处于无效状态,启用或禁用合成器通过:
CompositorManager::getSingleton().setCompositorEnabled(viewport, compositorName, enabledOrDisabled);