五、阴影
阴影是渲染一个真实场景的重要组成部分,它可以给场景中的物体提供更加真实的感觉,同时还可以帮助用户更好的了解对象间的空间关系。
启用阴影:
缺省情况下,阴影是关闭的,开启方式如下:
1、建立场景时就设置阴影技术有效 -- mSceneMgr->setShadowTechnique(SHADOWTYPE_STENCIL_ADDITIVE);
2、创建一个或者多个光源
3、关闭那些不需要投射阴影的物体,可以用物体的aetCastShadows(false)来实现。
4、设置投影的最远距离,通过SceneManager::setShadowFarDistance来限制投影的最远距离。
5、关闭那些不需要接受阴影的材质,透过Material::setReceiveShadows关闭阴影的接收。
选择阴影:
缺省情况下Ogre认为所有的不透明物体都可以投射和接收阴影。关闭方式如下:
1、关闭光源的投影功能,调用Light::setCastShadows(false),这个光源不会使任何物体产生阴影。
2、关闭材的阴影接收,调用Mateial::setReceiveShadows(false),可以使任何使用这种材质的物体不再接收阴影。
3、关闭独立物体的阴影,调用MovableObject::setCastsShadows(false),可以关闭具体物体的阴影功能。
4、关闭整个渲染队列的阴影,RenderQueueGroup::setShadowsEnabled(false)可以关闭整个渲染队列的投影和接收功能。
模板阴影:
模板阴影是一种通过硬件的模板缓存来"标记"屏幕中区域的方法。在系统中通过SceneManager::setShadowTechnique方法来打开模板阴影技术,并传入参数SHADOWTYPE_STENCIL_ADDITIVE或者是SHADOWTYPE_STENCIL_MODULATIVE。
弊端:场景中所有的阴影使用僵硬的边缘,并且无法对使用了shader的物体进行阴影操作。
纹理阴影:
纹理阴影是通过以光源作为”招眼点“把投影体渲染到纹理上来得到,然后再把这个纹理投射到接受阴影的表面上来得到最终的结果。
阴影的基础其实就是一张纹理图,它拥有一个固定的像素数量,当纹理被拉长之后这些像素就变得很明显和突兀,这里有一些方法来改善这个缺点:
1、选择一个”投影基础“
Uniform --- 最简单的投射方法
Uniform Focussed --- 仍然采用了标准的摄像机投影,只不过是摄像机聚焦到主观察摄像机所观察的区域
LiSPSM --- Light Space Perspective Shadow Mapping - 同时基于主观察摄像机聚焦并扭曲阴影的视截体
PlanOptimal --- 对一个独立的接收平面寻找最优的投影保真度
2、过滤
通过多次采样的方法来改善阴影的糅合度以及平滑边缘
3、使用更大一点的纹理
采用更加巨大的纹理来进行阴影处理,但是必须以硬件为基础。
光源选择:
有向光光源---采用更加巨大的纹理来进行阴影处理。
聚光灯光源----向着某一方向扩散光源
点光源 --- 可能会产生抖动,不建议使用点光源对纹理进行渲染。
配置纹理阴影:
1、阴影纹理的最大数量 --- SceneManager::setShadowTextureCount
2、阴影纹理的尺寸 --- SceneManager::setShadowTextureSize
3、阴影纹理的最大距离 --- 决定阴影结束的距离
4、阴影纹理的偏移量(针对有向光光源)
5、阴影淡出设置---阴影在远距离进行了淡出的处理来保证不会让阴影边缘过于生硬。
相对于模板阴影来说,纹理阴影有一个主要的优势——这些数据可以被标准的着色器引用并处理。
调制阴影:
调制阴影的工作方式是暗化已经渲染完场景的颜色。过程为:
1、场景会正常的渲染所有接受阴影的物体,
2、对每一个光源执行调制过程,把场景变暗,
3、渲染那些不接收阴影的物体。
六、动画
1、骨骼动画 ---- 运用骨骼结构来定义网格数据。
骨骼动画是根据网格数据中的骨骼信息来产生动画效果,一般是根据顶点上绑定的骨骼信息轮询确定模式的顶点。骨骼动画一般是通过3d建模工具完成的。骨骼和动画信息被保存在以.skeleton结尾的文件中,可以通过OGRE的exporters导出。
ogre3d支持的骨骼动画:
1 每个网格可以定义一个独立骨骼动画。
2 每个骨骼动画可以支持无限的骨骼。
3 作用于骨骼上的反向动力。
4 每个骨骼集可以定义多个名称的动画。
5 每个骨骼动画可以有多个关键帧。
6 关键帧之间的线性或者是样条插值。
7 一个顶点可以关联多个骨骼,并且可以被赋予权重,用来做融合。
8 通过权值融合,多个动画可以在同一时刻被作用于一个网格数据。
2、顶点动画 ----- 保存顶点的快照来决定网格数据如何改变。
顶点动画直接利用顶点的运动信息来产生动画。每个轨迹对应于一个VertexData的实例。顶点动画的数据存储于.mesh文件中。又分为两种:
变形动画:它根据动画的关键帧时间线插入相应的网格数据。
姿态动画:根据不同的权重和对顶点数据的偏移融合不同的姿态,来产生最后的结果。在面部动画中,姿态动画应用比较广泛。
3、场景节点动画 ----- 根据预先定义的路径来操作场景节点上挂接的实体的运动产生动画效果。
4、数值动画 ---- Ogre提供扩展的类来根据任何值产生动画效果。、
5、动画控制
通常的情况下,Ogre有两种不同的操作动画对象的方法,一种是通过关键帧,另外一种是通过控制器。
Ogre支持下面几种动画轨迹类型(在同一轨迹中的所有关键帧必须使用相同类型)。
数字动画轨迹(NumericAnimationTrack):与数字关键帧(NumericKeyFrame)对应,每个关键帧中都保存了相应的数字数据。这里使用了AnyNumeric数据类型来保存这些数值。在Ogre自身有一种特殊的数据结构被称为Any,它很类似动态语言中的可变类型,可以用来储存各种C++类型的数据。AnyNumeric是Any的子类,负责储存各种数值类型,比如实数和整形。
节点动画轨迹(NodeAnimationTrack):与变换关键帧(TransformKeyFrame)对应,每个关键帧都包含了两个三元向量和一个四元数,分别用来表现节点在当前帧的位置、缩放以及方向。
顶点动画轨迹(VertexAnimationTrack):同时对应于顶点变形关键帧(VertexMorphKeyFrame)和顶点姿态关键帧(VertexPoseKeyFrame),每个关键帧都保存了特定时间的顶点位置数据,在姿态动画(Pose)中还保存了顶点混合权重。
6、动画状态
长度:以秒为单位,获得动画片段的长度。
当前位置:得到或者设置当前播放的位置,换句话说是从动画片段(而不是整个动画)开始到当前位置所流逝的时间(秒)。
动画名称:尽管你可以通过物体本身得到所有的动画列表,这里仍然提供只读属性的动画名称用来在不知道动画名字情况下调用。
循环:设置或者得到在动画片段结束后是否循环播放。
启用:设置或者得到这个动画是否启用。
权重:动画可以被混合。
终于看完了,现在脑袋里晕晕乎乎的,东西太多了,看来只能慢慢消化了。