转载:OGRE一起学(十四) 阴影

第十四章 阴影

OGRE 中可以使用三种形式的阴影技术 (ShadowTechnique) ,这个在引擎评估专栏的《 OGRE (10) -- 投影》一节中已经有过简要的说明,这里进一步研究三种阴影技术的一些具体差异和细节控制。

示例代码中除了阴影技术的演示之外还包括了键盘输入的处理,按主键盘上的 [1] 、 [2] 、 [3] 、 [4] 可以在各种阴影技术之间切换: 
[1] SHADOWTYPE_NONE 
[2] SHADOWTYPE_STENCIL_MODULATIVE 
[3] SHADOWTYPE_STENCIL_ADDITIVE 
[4] SHADOWTYPE_TEXTURE_MODULATIVE 
键盘输入的处理留到下一节再具体讲解,这一章专讲阴影技术。 
Ogre:: ShadowTechnique 本身是一个枚举类型,在头文件 OgreCommon.h 中定义:

    enum ShadowTechnique     {         SHADOWTYPE_NONE,                      // 无阴影         SHADOWTYPE_STENCIL_MODULATIVE,        // 模版调制阴影         SHADOWTYPE_STENCIL_ADDITIVE,          // 模版叠加阴影         SHADOWTYPE_TEXTURE_MODULATIVE,        // 纹理调制阴影     };

下面我们通过截图比较一下后面三种阴影技术各自的不同,包括阴影的细节表现和场景的运行速度。 
场景中存在着两盏方向光,一盏是蓝色,一盏是黄色。 
你可以对源代码中的各个参数做一些修改,然后观察三个阴影技术彼此之间的具体不同。 
Ogre:: SceneManager 类中有一群阴影相关的方法,下面逐一列举并简单说明: 
设置/获取阴影技术
virtual void setShadowTechnique (ShadowTechnique technique) 
virtual ShadowTechnique getShadowTechnique (void) const 
设置/获取调试阴影显示状态 
至于什么是调试阴影 (Debug Shadows) ,你把它打开看看就知道了 
virtual void setShowDebugShadows (bool debug) 
virtual bool getShowDebugShadows (void) const 
设置/获取阴影颜色 
virtual void setShadowColour (const ColourValue &colour) 
virtual const ColourValue & getShadowColour (void) const 
设置/获取方向光阴影影响距离 
物体距灯光超过这个距离,就不再计算它的阴影以节省场景运算。 
virtual void setShadowDirectionalLightExtrusionDistance (Real dist) 
virtual Real getShadowDirectionalLightExtrusionDistance (void) const 
设置/获取阴影最大可见距离 
阴影距镜头超过这个距离,就不再在视野中显示。注意这个跟上面的方向光阴影影响距离不同,上面那个是指物体距灯光的最大距离,这个是指阴影本身距镜头的最大距离。 
virtual void setShadowFarDistance (Real distance) 
virtual Real getShadowFarDistance (void) const 
设置/获取阴影索引缓存大小 
为了计算物体的阴影, OGRE 在 GPU 中设置了一个缓存区用于保存物体的顶点索引,默认是 51,200 个,大约占用 100KB GPU ,足够渲染大约 17,000 个三角形。你可以修改这个索引缓存的大小,使之适合场景中物体的顶点总数,顶点总数大约等于三角形总数的 3 倍。 
virtual void setShadowIndexBufferSize (size_t size) 
virtual size_t getShadowIndexBufferSize (void) const 
设置/获取阴影纹理尺寸 
当你使用纹理调制阴影技术( SHADOWTYPE_TEXTURE_MODULATIVE )的时候, OGRE 需要先把物体的阴影渲染到一张纹理贴图上,然后再与地板或墙壁做调制运算。这张纹理贴图的尺寸越大,阴影看上去就越清晰;尺寸越小,阴影看上去就越粗糙。 
但是要注意,如果你使用 OpenGL 渲染系统,纹理贴图的边长不能超过 OGRE 渲染窗口的尺寸,一般设置为不大于 512 。 
virtual void setShadowTextureSize (unsigned short size) 
unsigned short getShadowTextureSize (void) const 
设置/获取阴影纹理数目
当你使用纹理调制阴影技术( SHADOWTYPE_TEXTURE_MODULATIVE )的时候,每张阴影纹理贴图只能渲染一盏灯光所产生的阴影,所以如果场景中存在多盏灯光,你可能需要把阴影纹理数目相应调大以使每盏灯光都可以投射阴影。 
virtual void setShadowTextureCount (unsigned short count) 
unsigned short getShadowTextureCount (void) const 
设置阴影纹理设定 
这个方法是上面两个方法的结合版,同时设置阴影纹理的尺寸和个数。 
virtual void setShadowTextureSettings (unsigned short size, unsigned short count) 
设置方向光阴影纹理偏移 
当你使用纹理调制阴影技术( SHADOWTYPE_TEXTURE_MODULATIVE )的时候, OGRE 首先对每盏方向光产生一张阴影纹理,具体做法就是,把这盏灯光作为一个镜头,把这个镜头中看到的投影物体渲染下来,不是真实的渲染,只是用单色渲染出来一个“影子”,影子的边缘之外都是透明的,然后把这张阴影纹理蒙到物体所投射到的表面。 
而这个方向光阴影纹理偏移,是控制在渲染这张阴影纹理的时候,纹理距离作为“镜头”的光源的远近。纹理距离“镜头”太近,会导致纹理贴图的大部分边缘区域超出了“镜头”的视野之外,所以我们使用这个纹理偏移,使这张纹理图远离作为“镜头”的光源中心,以最大限度地利用纹理贴图的空间。当场景很大的时候,这个纹理偏移很有用。 
打个比方,手电筒发射光束,打在远处的墙上形成一个大光圈,我们拿着一张报纸截断这束光,距离手电筒越近,光打在报纸上的光圈就越小,报纸上就有更多的边缘区域是黑暗的,对于阴影纹理来说,就是有更多的边缘区域没有被利用,浪费了。 
这个偏移值是一个从 0 到 1 的比率:从光源位置到 ShadowFarDistance * 2 。 
virtual void setShadowDirLightTextureOffset (Real offset) 
设置阴影纹理淡出起始距离/结束距离
这两个距离也是从 0 到 1 的比率:占 setShadowFarDistance 所指定的阴影最大可见距离的比率。它指定当阴影上的一点距离镜头超过起始距离之后,这一点上的阴影就开始变淡,直到达到结束距离就完全看不见了。效果可以参看下面的截图,可以看到近处的阴影颜色比远处的深一些。 
virtual void setShadowTextureFadeStart (Real fadeStart) 
virtual void setShadowTextureFadeEnd (Real fadeEnd)

 

设置是否使用阴影无限远截面
当阴影的投射距离超出镜头的远视距离之后,阴影的计算就会出毛病,导致场景变花。为了解决这个问题,我们对阴影使用一个无限远的投射平面,可以一定程度上防止阴影计算错误。 
virtual void setShadowUseInfiniteFarPlane (bool enable) 
具体的细节差异,修改一下源代码的各项参数观察一下。 
设置了阴影技术之后,还不算完,还需要打开各个物体的阴影属性包括光源的阴影属性,使用 setCastShadows 方法: 
void Ogre::MovableObject:: setCastShadows ( bool enabled ) [inline, inherited] 
在本节的例子中,关闭了地面模型的阴影属性,如果打开,投影计算会有问题,也没必要。 
最后要注意,纹理阴影相关的很多方法都只对方向光起作用,不支持点光源或锥形光。

转载于:https://www.cnblogs.com/wanghao111/archive/2009/06/08/1498651.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值