渲染手法技术Techinique:
一个“渲染手法技术”就是一个单独的渲染物体的方法。多个技术的存在原因是为适用不同的显卡以及根据远近关系对一个物体进行不同的渲染。
Pass渲染通路:
再次强调一个概念:一个材质脚本,为了适应不同的显卡和LOD细节层次技术,我们允许有多个技术,为了加速充分的使用GPU,每个技术中同时又支持多通道的渲染,每个渲染通道内,同时又允许有多个纹理单元。
一个渲染通路就是几何问题里的一次渲染;一个带有一整套渲染属性的渲染API的一次调用。一个技术可以包含有1到16个渲染通路,当然,渲染通路用得越多,技术在渲染的时候开销越大。
为了清楚识别使用的到底是哪个渲染通路,渲染通路常常被起个名字,当然,也可以不起,名字并不是必需的。脚本中没有名字的渲染通路将会以渲染通路索引号为名。例如:在一个技术里,第一个渲染通路索引号是index 0,所以,如果脚本中没有对它命名,那么它的名字就是“0”。一个技术中的渲染通路的名字必须是唯一的,否则,最后一个渲染通路的结果就会是所有相同名字的渲染通路的效果的融合。如果发生这种事,一个警告消息就会发到Ogre.log中。而且,命名渲染通路还有助于复制材质和修改已经存在的渲染通路:(详见3.1.11 材质拷贝部分)
渲染通路有一套全局属性(如下所述),0或多个纹理单元入口,:(详见3.1.3 纹理单元部分),以及可选的对于顶点程序或片断程序的引用(详见3.1.9 在渲染通路中使用顶点程序和片断程序部分)。
下面介绍在.material脚本中“渲染通路”部分能够使用的一些属性:
ambient
diffuse
specular
emissive
scene_blend
depth_check
depth_write
depth_func
depth_bias
alpha_rejection
cull_hardware
cull_software
lighting
shading
polygon_mode
fog_override
colour_write
max_lights
start_light
iteration
point_size
point_sprites
point_size_attenuation
point_size_min
point_size_max
属性详解
ambient
设置此渲染通路中周围环境的反射系数。当asm,CG,HLSL(High Level Shader Language高级渲染语言)使用时,该属性无效。与GLSL()一起使用时,渲染器可以读OpenGL材质状态。
格式: ambient (<red> <green> <blue> [<alpha>]| vertexcolour)
数值的取值范围在0.0到1.0之间。
示例: ambient 0.0 0.8 0.0
渲染通路的基本颜色取决于各顶点红色,绿色和蓝色光的反射量。此属性决定了反射多少环境光(无目标的全局光)。也可以如在网格中定义的一样,通过使用关键字vertexcolour而不是使用颜色值,使环境反射系数跟踪顶点颜色。默认值是全白的,意思就是物体整个完全被照亮。如果你想要看见散射和镜面反射的效果,就要减少这个属性的相关数值,或者改变颜色的混合,使物体有一个不是白色的基础色。如果使用了'lighting off'属性将动态光照关闭了或者任何纹理层有'colour_op replace'属性,那么“ambient”这个属性无效。
默认: ambient 1.0 1.0 1.0 1.0
diffuse
设置此渲染通路中漫反射系数。当asm,CG,HLSL(High Level Shader Language,高级渲染语言)使用时,该属性无效。与GLSL(OpenGL's Shader Language,OpenGL的渲染语言)一起使用时,渲染器可以读OpenGL材质状态。
格式: diffuse (<red> <green> <blue> [<alpha>]| vertexcolour)
数值的取值范围在0.0到1.0之间。
示例: diffuse 1.0 0.5 0.5
渲染通路的基本颜色取决于各顶点红色,绿色和蓝色光的反射量。此属性决定了反射多少四散光(来自场景中光照类实例的光)。也可以像在网格里一样定义,用vertexcolour关键字而不是用颜色值,令四散反射系数追踪顶点颜色。默认值是全白,意思就是物体反射所能接收到的所有白光。如果使用了'lighting off'属性将动态光照被关闭了或者任何纹理层有'colour_op replace'属性,那么“ambient”这个属性无效。
Default: diffuse 1.0 1.0 1.0 1.0
specular
设置此渲染通路中镜面反射颜色的反射系数。当asm,CG,HLSL(High Level Shader Language,高级渲染语言)使用时,该属性无效。与GLSL(OpenGL's Shader Language,OpenGL的渲染语言)一起使用时,渲染器可以读OpenGL材质状态。
格式: specular (<red> <green> <blue> [<alpha>]| vertexcolour) <shininess>
数值的取值范围在0.0到1.0之间。闪耀值(shininess)可以是任意比0大的值。
示例: specular 1.0 1.0 1.0 12.5
渲染通路的基本颜色取决于各顶点红色,绿色和蓝色光的反射量。此属性决定了反射多少镜面光(来自场景中光照类实例的高光)。也可以像在网格里一样定义,用vertexcolour关键字而不是用颜色值,令镜面反射系数追踪顶点颜色。默认值没有镜面反光。镜面反射的这种高光取决于颜色参数,闪耀值的设置大小。闪耀值设置得越高,高光就越耀眼。闪耀值在0.0到1.0之间时,使用要小心,因为这会引起高光颜色会被应用到有使用这种高光属性材质的整个平面。这样的话,当对该平面的视角发生改变的时候,会发生特别恶心的闪烁。闪耀值在1到128之间时,在DirectX和OpenGL渲染器上都表现良好。如果使用了'lighting
off'属性将动态光照被关闭了或者任何纹理层有'colour_op replace'属性,那么“ambient”这个属性无效。
默认: specular 0.0 0.0 0.0 0.0 0.0
emissive
设置一个物体自发光的量。当asm,CG,HLSL(High Level Shader Language,高级渲染语言)使用时,该属性无效。与GLSL(OpenGL's Shader Language,OpenGL的渲染语言)一起使用时,渲染器可以读OpenGL材质状态。
格式: emissive (<red> <green> <blue> [<alpha>]| vertexcolour)
数值的取值范围在0.0到1.0之间。
示例: emissive 1.0 0.0 0.0
如果一个物体是自发光的,那么它就不需要外界的光去照亮它,无论是环境光还是其它的光,就好像有自己的环境光一样。然而,其实这个属性并不像名字所暗示的那样,这个物体对场景中的其他物体来说并不是一个光源(如果你想让它成为一个光源,你需要创建一个光源然后将光源放在这个物体的中心上)。也可以像在网格里一样定义,用vertexcolour关键字而不是用颜色值,令这样放射出来的颜色追踪顶点颜色。如果使用了'lighting off'属性将动态光照被关闭了或者任何纹理层有'colour_op replace'属性,那么“ambient”这个属性无效。
默认: emissive 0.0 0.0 0.0 0.0
scene_blend
设置此渲染通路与场景中现有的内容混合的方式。纹理单元入口所见的那个纹理混合操作被看作是纹理层之间的混合,而这个混合是将此渲染通路的输出结果与当前渲染目标的内容相结合。所以,这种混合就允许物体透明和其他特殊效果。有两种形式可供选择使用:一是使用预定义混合形式;二是使用自定义的办法,源因数和目标因数都有你自己DIY。
格式1: scene_blend <add|modulate|alpha_blend|colour_blend>
示例: scene_blend add
这是一个比较简单的形式,常用的混合形式由一个参数枚举出来,可用的混合形式参数如下:
add
渲染输出的颜色和亮度一起叠加到场景中,用在爆炸、闪光、闪电、鬼魂等地方效果很好。相当于“scene_blend one one”
modulate
另一种将渲染输出加到场景内容中,一般用于给场景着色和加深场景颜色。对于浓烟弥漫的玻璃,半透明的物体等,有很好的使用效果。相当于“scene_blend dest_colour zero”。
colour_blend
基于输入文件的亮度给场景着色,但是并不加深颜色。相当于“scene_blend src_colour one_minus_src_colour”。
alpha_blend
渲染输出的alpha值被用作遮罩。相当于“scene_blend src_alpha one_minus_src_alpha”
格式2: scene_blend <src_factor> <dest_factor>
示例: scene_blend one one_minus_dest_alpha
这种格式允许你通过设置源和目标因数,从而完全控制混合操作。最终被写入渲染目标的颜色结果是(texture * sourceFactor) + (scene_pixel * destFactor)。两个参数的可选值如下:
one
常数值1.0
zero
常数值0.0
dest_colour
已存在的像素颜色
src_colour
纹理像素颜色
one_minus_dest_colour
1 -(dest_colour)
one_minus_src_colour
1 -(src_colour)
dest_alpha
已存在的像素alpha值
src_alpha
纹理像素alpha值
one_minus_dest_alpha
1 -(dest_alpha)
one_minus_src_alpha
1 -(src_alpha)
默认: scene_blend one zero (这句意为不透明的)
depth_check
设置此渲染通路的深度缓冲检测的状态是打开状态还是关闭状态。
格式: depth_check <on|off>
如果深度缓冲检测处于打开状态,则无论何时一个像素要想写入画面缓冲,深度缓冲检测就检查这个像素是否比在那一点的其它像素都要靠前。如果不是,那么这个像素就不写入。如果深度缓冲检测关闭了,则无论之前渲染的结果,一律写入这个像素。更高级的配置还可参看depth_func
默认: depth_check on
depth_write
设置此渲染通路的深度缓冲写入的状态是打开状态还是关闭状态。
格式: depth_write <on|off>
如果深度缓冲写入处于打开状态,无论何时一个像素想要写入画面缓冲,深度缓冲都会更新那个像素的深度值,因此,如果将来的像素在这个像素的后面,就会影响将来的渲染操作。如果这一属性被关闭了,那么像素就不会更新深度缓冲。一般来说,这一属性是打开的,但是,当你渲染静态背景或者位于场景后部的一系列透明物体以便它们能够彼此正确地重叠时,也可以关闭。
默认: depth_write on
depth_func
当深度检测打开时,设置用于比较深度值的函数。
格式: depth_func <func>
如果深度检测处于打开状态(参看depth_check),那么将要写入的像素的深度值与缓冲区中现有内容的深度值会发生比较。一般来说,这种比较是小于等于,例如:将要写入的像素比现有内容距离我们更近(或相等)。可能的函数如下:
always_fail
永远不向渲染目标写入像素
always_pass
总是将像素写入渲染目标
less
如果将要写入的像素的深度小于现在缓冲区内容的深度,则写入
less_equal
如果将要写入的像素的深度小于等于现在缓冲区内容的深度,则写入
equal
如果将要写入的像素的深度等于现在缓冲区内容的深度,则写入
not_equal
如果将要写入的像素的深度不等于现在缓冲区内容的深度,则写入
greater_equal
如果将要写入的像素的深度大于等于现在缓冲区内容的深度,则写入
greater
如果将要写入的像素的深度大于现在缓冲区内容的深度,则写入
默认: depth_func less_equal
depth_bias
设置此渲染通路的深度值的偏向。可用于使共面的多边形中的一个位于其它之上。例如:印制花纹图案。
格式: depth_bias <constant_bias> [<slopescale_bias>]
深度偏向值最终由偏向常数(constant_bias)*最小可观察的深度(minObservableDepth)+最大坡度(maxSlope)*坡度偏向(slopescale_bias)共同决定。坡度偏向与多边形到镜头的角度有关,形成相应的偏向值,但是在一些时间比较早的硬件上,这被忽略了。偏向常数是形成最小深度值的一个因素,所以1的价值就在于一点一点地缓慢地推进深度。
alpha_rejection
设置此项,可以使用alpha作为一个阀值,令渲染通路拒绝来自管线的像素。
格式: alpha_rejection <function> <value>
示例: alpha_rejection greater_equal 128
如上例所示,拒绝所有来自管线的alpha值大于等于128的像素。 function参数可以选择在depth_function属性的参数列表中所列的参数。value参数理论上可以是0到255之间的任意数,但是考虑到硬件兼容性,最好限制在0到128之间。
默认: alpha_rejection always_pass
cull_hardware
设置此渲染通路的硬件裁剪模式。
格式: cull_hardware <clockwise|anticlockwise|none>
硬件渲染引擎裁剪三角形的典型方法是基于三角形顶点的环绕顺序。顶点环绕顺序又与渲染操作中顶点传送和编号的方向有关,从镜头中看到的有可能是顺时针的也可能是逆时针的。如果选择了'cull_hardware clockwise'设置,则所有从镜头看顺时针顺序的三角形被硬件剪裁掉。显然,'anticlockwise'设置裁剪掉逆时针顺序的三角形。'none'设置关闭硬件裁剪,即所有三角形都渲染(用于渲染双侧道路)。
默认: cull_hardware clockwise
默认值与OpenGL的默认值相同,与Direct3D的默认值相反(因为OGRE与OpenGL一样使用右手坐标系)。
cull_software
设置此渲染通路的软件裁剪模式。
格式: cull_software <back|front|none>
在某些情形下,引擎也会在将几何体送往硬件渲染前进行软件裁剪。此设置仅在场景管理器使用它时起效(因为最好用在大量平面的世界几何体,而不是移动的几何体,因为用于移动的物体上代价会很大),但是如果在送入硬件之前可以有效裁剪的话还是可以使用的。在这种情况下,裁剪就要基于面向镜头的是三角形的背面还是正面——这个定义是基于面法向的(即:垂直于多边形平面且标示出正面方向的向量)。因为OGRE期望平面的逆时针方向为正向,所以软件裁剪'cull_software back'相当于硬件裁剪'cull_hardware clockwise'设置,也是为什么这两个作为默认设置的原因。虽然反映裁剪方式的命名是不同的,但是由于多数时候面法向都是预先计算好的且不一定是OGRE期望的方式,因此如果你有使用你自定义的面法向的场景管理器,也可以设置'cull_hardware
none'然后完全基于你的面法向进行软件裁剪。
默认: cull_software back
lighting
设置动态光照是处于打开状态还是关闭状态。如果光照被关闭,那么所有使用此渲染通路的物体将被完全照亮。如果使用了顶点程序,则此属性无效。
格式: lighting <on|off>
关闭动态光照会使得任何环境光、漫反射光、镜面反射光、放射光和阴影属性都成为了多余的。当打开光照时,物体按照顶点的法向被照亮。
默认: lighting on
shading
设置此渲染通路中为表现动态光照而使用的各种阴影形式。
格式: shading <flat|gouraud|phong>
当动态光照打开时,效果就在每个顶点处生成颜色值。这些值是否全平面插入(如何插入)就依赖于这个属性设置。
flat
无插值参与。每个平面的阴影由平面上第一个顶点的颜色决定。
gouraud
平面上每个顶点的颜色采用线性插入。
phong
在全平面上插入顶点法线向量,被用于决定每个像素的颜色。能够得到更加自然的光照效果,但是代价也相应更高,在高级应用中表现更好。并不是所有硬件都支持此属性。
默认: shading gouraud
polygon_mode
设置多边形应该如何被栅格化。例如:它们应该是被填充后画出来,还是作为点(只有顶点)、线(只有外边框)画出来。
格式: polygon_mode <solid|wireframe|points>
solid
一般情况——填充多边形
wireframe
多边形只画外边框
points
只画每个多边形的点
默认: polygon_mode solid
fog_override
这个属性告诉渲染通路是否撤销场景的雾设置,而强制执行此渲染通路它自己的设置。当场景中其他的物体被雾遮挡,而你不想让雾影响某些物体时非常有用。当然反之亦然。注意这只影响固定功能雾——原来的场景雾参数仍然被送入渲染器,使用fog_params参数绑定(这就允许你关闭固定功能雾,转而在渲染器中计算;如果你想关闭阴影雾,你可以通过阴影参数关闭它。)
格式: fog_override <override?> [<type> <colour> <density> <start> <end>]
默认: fog_override false
如果你指定第一个参数为真,并给出了其余参数,就表明你要告诉渲染通路如果在使用这些雾设置和使用场景设置之间选择的话,优先选择使用这些雾设置。如果你指定第一个参数为真,但没给出其余参数,就表明你要告诉渲染通路不使用任何雾设置,无论场景如何设置。以下是参数的解释:
type
none = 没有雾,相当于使用'fog_override true'。
linear = 线性雾,从 <start> 开始到 <end> 结束的这一段距离有雾。
exp = 雾以几何方式增加(fog = 1/e^(distance * density)), 使用浓度 <density> 参数控制。
exp2 = 雾以几何的二次方增加,更加快速(fog = 1/e^(distance * density)^2),使用浓度 <density> 参数控制。
colour
3个0到1之间的符点数组成的序列,表示红色、绿色、蓝色的亮度。
density
用于'exp'或者'exp2'雾类型的浓度参数。虽不用于线性模式,但是也必须写上,作为占位符。
start
线性雾距离镜头的开始距离。在其它模式下,尽管不用这个参数,也必须写上,作为占位符。
end
线性雾距离镜头的结束距离。在其它模式下,尽管不用这个参数,也必须写上,作为占位符。
示例: fog_override true exp 1 1 1 0.002 100 10000
colour_write
设置此渲染通路的颜色写入是打开还是关闭的。
格式: colour_write <on|off>
如果颜色写入被关闭,那么此渲染通路中没有可见像素写入屏幕。你也许认为这没什么用,但是如果你关闭颜色写入并且合理利用其他一些小的渲染设置,你可以使用这个渲染通路在执行后续的填充颜色数据的渲染通路之前初始化深度缓冲区。这样可以极大地提升效果,尤其是当你使用复杂的片断程序的时候,因为如果深度检测失败了,片断程序根本就不会运行。
默认: colour_write on
start_light
设置此渲染通路使用的首个光源。
格式: start_light <number>
你可以使用这个属性设置此渲染通路的光源的开始位置。换句话说,如果你设置start_light为2,那么被处理的第一个光源就是实际列表中的第三个光源。例如,你可以利用这个选项,使用不同的渲染通路处理第一组的几个光源对第二组的几个光源,或者使用它与iteration选项协作,从列表的给定点开始迭代(例如,在第一个渲染通路里处理头两个光源,然后从此开始每次两个光源重复进行)
默认: start_light 0
max_lights
设置此渲染通路使用的光源的最大数量。
格式: max_lights <number>
光源的最大数量由渲染系统设定,通常为8,常用于渲染固定功能材质。当你要使用可编程管线(详见3.1.9 在渲染通路中使用顶点程序和片断程序部分),这个限制依赖于你要运行的程序。如果你使用'iteration once_per_light'(详见下面 iteration),则它的有效性仅限于你想使用的渲染通路的数量。但是,无论你使用哪种方法,都要应用max_lights限制。
默认: max_lights 8
iteration
设置此渲染通路是否被迭代,多次重复执行。
格式 1: iteration <once | once_per_light> [lightType]
格式 2: iteration <number> [<per_light> [lightType]]
格式 3: iteration <number> [<per_n_lights> <num_lights> [lightType]]
示例:
iteration once
渲染通路只执行一次,默认设置。
iteration once_per_light point
渲染通路每个光源点执行一次。
iteration 5
此渲染通路的渲染状态将被建立,并且绘图调用将执行5次。
iteration 5 per_light point
此渲染通路的渲染状态将被建立,并且绘图调用将每个光源点各执行5次。
iteration 1 per_n_lights 2 point
此渲染通路的渲染状态将被建立,并且绘图调用将每2个光源点执行5次。
依照默认设置,渲染通路只执行一次。但是,如果你使用可编程管线,或者你希望超出支持的光源数量限制,你或许想要使用once_per_light选项。在这种情况下,只有光源0被使用,每次使用不同的光源作为光源0,渲染通路执行多次。显然,这会使渲染通路的代价很高,但是,考虑1到n个光源的每像素光照效果,这可能是唯一达到这种效果的办法。
使用数字代替“once”表示建立渲染状态后渲染通路的一次以上的迭代执行。渲染状态在初始化建立后就不再改变,所以对于使用需要迭代多次相同渲染状态的可编程渲染,重复的绘图调用是非常快速和理想的。例如,皮毛、动作模糊、特殊滤镜等渲染。
如果你使用了once_per_light,你也应该在此渲染通路之前的技术里增加一个环境渲染通路,否则,当这个物体附近没有光源时,它就不会被渲染;即使你的场景里没有环境光时,这也是很重要的,因为原本你仍然是想要显示物体的轮廓的。
此属性的光源类型参数仅在你使用once_per_light、per_light或者per_n_light时应用,且还限制运行单一类型光源('点光源'、'方向光源'或'斑光源')的渲染通路。如下面的例子所示,这个渲染通路将会每个电光源执行一次。如果你能估计到将要处理的光源类型,这会是有用的,因为当你要写一个顶点/片断程序时,它会很容易。至少点光源和方向光源可以用一种方法处理。
默认: iteration once
示例:使用了一个在第二次渲染通路中包含10次迭代操作用以生成皮毛的简单的皮毛渲染材质脚本
// GLSL simple Fur
vertex_program GLSLDemo/FurVS glsl
{
source fur.vert
default_params
{
param_named_auto lightPosition light_position_object_space 0
param_named_auto eyePosition camera_position_object_space
param_named_auto passNumber pass_number
param_named_auto multiPassNumber pass_iteration_number
param_named furLength float 0.15
}
}
fragment_program GLSLDemo/FurFS glsl
{
source fur.frag
default_params
{
param_named Ka float 0.2
param_named Kd float 0.5
param_named Ks float 0.0
param_named furTU int 0
}
}
material Fur
{
technique GLSL
{
pass base_coat
{
ambient 0.7 0.7 0.7
diffuse 0.5 0.8 0.5
specular 1.0 1.0 1.0 1.5
vertex_program_ref GLSLDemo/FurVS
{
}
fragment_program_ref GLSLDemo/FurFS
{
}
texture_unit
{
texture Fur.tga
tex_coord_set 0
filtering trilinear
}
}
pass grow_fur
{
ambient 0.7 0.7 0.7
diffuse 0.8 1.0 0.8
specular 1.0 1.0 1.0 64
depth_write off
scene_blend src_alpha one
iteration 10
vertex_program_ref GLSLDemo/FurVS
{
}
fragment_program_ref GLSLDemo/FurFS
{
}
texture_unit
{
texture Fur.tga
tex_coord_set 0
filtering trilinear
}
}
}
}
注意:使用GPU程序自动参数pass_number和pass_iteration_number告诉顶点或片断程序渲染通路数量和迭代数。
point_size
此设置允许你在渲染一个点列或者一个point sprites列时改变点的大小。这个命令的插值依赖于point_size_attenuation选项——如果是关闭的(默认情况),点的大小是屏幕像素的大小;如果是打开的,表现为标准化屏幕坐标(屏幕高为1.0)。
注意:某些设备有其所支持的点的大小的上限——相同的显卡不同的应用程序接口可能不同!不要相信点的大小,因为那些屏幕上很大的点可能仅限于某些显卡。最高像素的范围从64像素到256像素。
格式: point_size <size>
默认: point_size 1.0
point_sprites
这个设置指定此渲染通路的硬件point sprites渲染是否打开。如果打开了,意味着一个点列被作为一个四元组列渲染而不是作为一列点渲染。如果你使用了公告板集并且只需要使用基于公告板的大小相同的点,使用这个选项是非常有用的。你也可以在任何其它点列渲染中使用这个属性。
格式: point_sprites <on|off>
默认: point_sprites off
point_size_attenuation
定义点的大小是否根据视觉空间距离增加而衰减,以及以何种方式衰减。当你使用point sprites时,这个选项特别有用,因为它定义了当远离镜头时,应如何减小尺寸。你也可以关闭这个选项,使point sprites成为一个常数的屏幕尺寸(像点一样),或者打开这个选项,使之随距离而改变。
如果你打开了这个选项,你只要提供最后3个参数。衰减方程为点的大小乘以1 / (constant + linear * dist + quadratic * d^2);因此关闭这个选项就相当于(constant = 1, linear = 0, quadratic = 0)且标准透视缩减是(constant = 0, linear = 1, quadratic = 0)。后者假设你指定打开这个选项但未给出后3个参数。
注意衰减的结果应限于点尺寸的最小和最大值之间(详见下面介绍)。
格式: point_size_attenuation <on|off> [constant linear quadratic]
默认: point_size_attenuation off
point_size_min
设置点衰减(详见上面point_size_attenuation)的最小值。细节详见上面point_size。
格式: point_size_min <size>
默认: point_size_min 0
point_size_max
设置点衰减(详见上面point_size_attenuation)的最大值。细节详见上面point_size。 0值意味着将最大值设置为当前显卡所支持的最大值。
格式: point_size_max <size>
默认: point_size_max 0