irricht阴影体实现笔记

阴影体是一种动态阴影技术。

仔细一看,这玩意儿其实很简单。


利用的模拟缓冲的功能,把阴影体画进模板缓冲即可。

这要求计算出物体对着光线的轮廓。


本来觉得,怎么样高效地求出这个轮廓,发现irricht实现得非常简单,同时也意味着不够优化(笔者看的irricht版本是1.7的,可能最新的版本优化了)

irricht直接取面对光线的那些多边形,然后利用这些多边形构造阴影体。(可以想像,阴影体是背对光线延伸至无穷远,irricht的"无穷远"是1000)


irricht的阴影体定义成一个对象CShadowVolumeSceneNode

这个对象会做为CAnimatedMeshSceneNode的子节点,进入场影管理,

并在OnRegister时,进入场影的shadow list

CShadowVolumeSceneNode 会去取CAnimatedMeshSceneNode当前帧对应的mesh,并计算阴影体


irricht首先渲染所有的物体,例如CAnimatedMeshSceneNode

然后才渲染阴影体。


把阴影体画进模板,然后再画一个矩形,把整个渲染遮住,在画这个矩形时,会做模板测试,

只有模板缓存中的阴影体会被渲染,在视觉就形成了阴影。


这样就可以了?

这里还需要做一个简单的处理。


接下来的东西说起来拗口,但一画图就非常简单了。


图中的矩形是物体,因为光源而产生的阴影,物体1和物体3处于阴影中,而物体2显然不处于阴影当中。

如果不做处理,根据模板缓存里画出的阴影体直接渲染,则会错误地把物体2也画成处于阴影的状态。



irricht的处理如下:


CShadowVolumeSceneNode::render --> COpenGLDriver::drawStencilShadowVolume

这个函数中有这么一段代码


glStencilOp(GL_KEEP, incr, GL_KEEP);
glCullFace(GL_FRONT);
glDrawArrays(GL_TRIANGLES,0,count);


glStencilOp(GL_KEEP, decr, GL_KEEP);
glCullFace(GL_BACK);
glDrawArrays(GL_TRIANGLES,0,count);

会画两次,多边形可以认为有两个面(front back),

打开深度缓存,做比较,类似出栈入栈,在物体之后的阴影体多边的,遇到背面+1, 遇到正面-1,

最终,如果为0,表示该点不同阴影体之内,如果不为0,就需要加入阴影效果。


这样就可以正确把阴影效果表现出来。


相关的理论,有更详细的文章,请参考

http://blog.csdn.net/kongbu0622/article/details/1838317







求得阴影体后往模板里画就可以了?

这里还需要做一个简单的处理。


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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值