OGRE学习记录-Dot3Bump例子

        这里主要是记录一下理解Examples/BumpMapping/MultiLight的过程。

        材质有1个technique,technique内有3个pass。这是一种叫做Additive light masking的技术,使用这种技术可以使光照更加真实,OGRE手册里面有关于它的介绍

        我一开始对这三个pass的作用并不清楚,所以分别查看了仅仅使用其中一个pass的渲染效果(就是把材质里面另外两个pass注释掉)。

        按顺序来说,pass ambient,这个pass中只用环境光的渲染物体,这个材质里面分别使用了Ogre/BasicVertexPrograms/AmbientOneTextureUnified和Ogre/BasicFragmentPrograms/PassthroughFP着色器,两个着色器的代码就像它的名字说的一样,很基本,功能很简单,顶点着色器内部坐了坐标变换,输出坐标,纹理坐标和一个颜色,像素着色器直接返回顶点着色器传递的颜色(没有光照处理)。材质定义中,顶点着色器里面有个参数ambient,值是ambient_light_colour,它在C++代码中被设置成黑色。所以这个pass的渲染结果就是纯黑色的物体,同时因为视口背景是黑的,所以什么都看不到(可以试着修改视口背景颜色查看效果)。另外还有一点,这个pass还写入了深度缓存(我第一次看的时候,因为没注意这个细节,导致后面查看pass perlight的时候碰到一个问题)。

        然后是pass perlight,在pass中,每个灯光单独为物体渲染(没有环境光),渲染结果会叠加。虽然只是写作一个pass perlight,实际上OGRE会把pass拆分成(灯光数量)个pass。在这个pass里,着色器程序用来实现Bump Mapping,分别说一下。

        顶点着色器:

        做了坐标变换,输出坐标和纹理坐标。接着计算光源方向,为什么后面会有一个position * lightPosition.w,有两种情况,一是光源是方向光,lightPosition.w为0(齐次坐标,w为0表示向量),所以lightPosition本身就是光源方向。二是,点光源或聚光灯,计算方向就是光源位置减顶点位置,但两个坐标的齐次坐标不一定相同,所以顶点坐标要乘以一个lightPosition.w(整个式子写成lightPosition.xyz / lightPosition.w - position应该也是可以的,可能乘法会快一些)。接着求副法线,因为切线,副法线和法线构成正切空间,所以副法线只需要用正切向量叉乘法线向量(切线向量和法线向量来自模型数据)。因为假设了正切向量和法线都是单位向量,所以叉乘结果也是单位向量。另外它里面有个TANGENTS_HAVE_PARTIY宏,我不太明白这个宏的含义。接着由三个向量构造世界空间到正切空间的旋转矩阵(至于为什么能这样构造,计算机图形学里面坐标系转换里面有介绍),最后把光源向量变换到正切空间,在像素着色器里面会说明原因。

        像素着色器:

        首先是把正切空间的光源向量单位化,然后从法线纹理中获取法线,因为纹理中的单个颜色区间是[0, 1],法线纹理的作用就是把纹理中的rgb当作法线的xyz,但法线xyz的范围是[-1, 1],所以需要expand函数把区间扩大。之后使用普通光照模型的公式求出像素点最终的颜色,再回答前面那个问题(为什么要把光源变换到正切空间),是因为法线纹理的法线是正切空间的向量。

        先考虑只有白色灯光的情况,这个pass得到的渲染结果是带有凹凸效果的物体,但是物体出现了透明效果,看下图。

        这个问题我想了很久,最后知道了原因,首先这个pass是带有scene_blend属性的,就是渲染的结果会和已有的场景进行叠加,我原以为它只会和未渲染物体前的场景叠加(这个例子中,我认为物体只和黑色背景叠加),但其实不是,物体自身也是会叠加的。图中箭头所指就是自身叠加的结果,因为远离摄像机的点(注意,并不一定是模型顶点)先绘制,靠近摄像机的点后绘制,导致后绘制的点会与先绘制的点叠加,出现这种透明效果。然而点的绘制顺序(可能和模型文件定义有关),应该是没有办法在代码里设置的。为什么加上pass ambient之后,就不再透明了呢,就因为写入了深度信息,所以在pass perlight中,远离摄像机的点会因为深度检测失败而跳过渲染,所以靠近摄像机的点自然不会和远离摄像机的点进行叠加。

        加入了红光后,物体多了些红色的部分,看下图和上面对比一下,其实就是在上面黑色部分叠加了红色光源效果。

         最后说pass decal,这个pass不需要光照,设置了纹理单元,顶点着色器传入白色。如果仅有这一个pass,那效果就是什么都看不到(因为之前的场景是黑色)。即使加上了前面两个pass,物体也并没有变化,因为在这个材质中纹理并没有起到作用,在像素着色器里面并没有采样,而是直接返回了顶点着色器传入的颜色。但如果把像素着色器注释掉,就可以看到纹理了,看下图,物体上多了铁锈。

        这个材质就是这样,它实现了物体的凹凸效果,但这只是视觉上的凹凸效果,实际上,凸点都是平的(和我原来想的凹凸纹理不同,我原以为是通过顶点着色器改变顶点的位置,使模型具有凹凸效果,通过学习也了解到这其实做不到,因为凸点并不一定是物体的顶点,顶点着色器只能对顶点进行操作,所以没办法对所有凸点进行偏移),这是一种以像素为单位进行的着色方式(我所想的那种是以顶点为单位)。

        最后再说一下Additive light masking技术,在看这个例子的时候,我一直想不明白为什么手动拆分为这三个pass,后来看手册上说如果使用了自定义的顶点着色器,就必须要手动拆分pass,OGRE不会自动拆分。在这里,Additive light masking的效果并没有完全展现出来,因为pass ambient的渲染结果是纯黑的物体,好像只起到写入深度缓存的作用,但pass ambient的颜色可以是阴影的颜色(光源照不到的地方只有环境光,也就是阴影颜色,在实现自阴影后才有体现)。

        其实一个星期前就已经看过这个例子了,不过一直拖着没写blog,现在把它补上了,过几天还要写一下实现depth shadow mapping的过程。

        如果说错的地方,欢迎指正。


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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值