【3D技术宅公社】XR数字艺术论坛  XR技术讨论 XR互动电影 定格动画

 找回密码
 立即注册

QQ登录

只需一步,快速开始

调查问卷
论坛即将给大家带来全新的技术服务,面向三围图形学、游戏、动画的全新服务论坛升级为UTF8版本后,中文用户名和用户密码中有中文的都无法登陆,请发邮件到324007255(at)QQ.com联系手动修改密码

3D技术论坛将以计算机图形学为核心,面向教育 推出国内的三维教育引擎该项目在持续研发当中,感谢大家的关注。

查看: 1945|回复: 0

葵花朝太阳的BILLBOARD算法

[复制链接]
发表于 2009-5-12 16:09:38 | 显示全部楼层 |阅读模式
  一、             BILLBOARD介绍

BILLBOARD,译为“公告牌”,“公告板”。原本是美国唱片业的音乐排行榜的一个名词,所以如果在互联网检索这个名词得到和3D无关的内容,大家也不要惊讶。BILLBOARD是一种3D变换算法,主要作用是使一个3D物件始终朝向摄象机的方向,好比3D物件是个向日葵,摄象机是太阳,不管摄象机在哪里,物件都会把他的正面对着摄象机。

在实际应用中,BILLBOARD可以使一个片元(一般是一个矩形面)始终朝向摄象机,加上透明,镂空的处理,能够使4个顶点组成的2维片元感觉象是一个很多顶点组成的3维物体。BILLBOARD在3D粒子系统中有大量的应用,每一个火花都用一个片元组成,利用BILLBOARD,可以描绘出大群火焰粒子的真实效果。

BILLBORAD在游戏的实际应用中有两种,一种是Y轴BILLBOARD, DX8.0 SDK中有这个例子,这个算法仅会使片元绕Y轴转动使其面向摄象机的一方——好比向日葵会以自己的杆向东南西北旋转——但却不能上下抬头。这个方法适用于摄象机在Y轴上不会变化太大的情况(比如第一人称的游戏摄象机的Y坐标(高度)往往变化不大)。在DX8.0 SDK的BILLBOARD这个例子中,所有的树木都是以一个片元(一张图片)代替,无论摄象机如何移动,所有的片元绕自身Y轴旋转,确保都面向摄象机。

但如果摄象机移动到这些树木的上方,向下俯视,会发现这些树木只剩下一条线——因为片元无法抬头,所以我们只能看见图片的上边沿。所以在一些需要在任何方向上都看到片元正面的情况下(比如前面提到的火焰的粒子效果),需要一种完全的BILLBOARD算法,在任意方向上片元都会正面面对摄象机。下面,我们先看看Y轴BILLBOARD,再介绍完全BILLBOARD的实现方法。

二、             Y轴BILLBOARD
我认为BILLBOARD的关键在于,首先必须确定初始片元的“正面”到底在哪里。比如,如果设定 在一个左手坐标系中,一个正方形BILLBOARD,宽度为width, 且与坐标系XY平面平行,法线与Z轴负方向相同,并设定在坐标系原点的位置。那么四个顶点的位置分别为
((-width/2, width/2, 0), (width/2, width/2, 0), (width/2, -width/2, 0), (-width/2, -width/2, 0))
那么只有摄象机落在Z轴的负半轴上,视点沿Z轴正半轴,看到的才是BILLBOARD的正面。
当摄象机旋转后,BILLBOARD势必要跟随摄象机向相同的方向旋转,由于我们求的是Y轴BILLBOARD,所以只需关心BILLBOARD在XZ平面下的旋转角度。在这个思路下,我们可以写出Y轴BILLBOARD的算法。而这个算法,仅仅只需初中的三角几何知识便可得到。






图一:初始BILLBORAD和摄象机位置。




    图二:这是摄象机顺时针旋转a角度以后BILLBORAD的位置。
我们可以得出图一到图二摄象机旋转了D3DX_PI/2-atanf(z/x)的角度(z,x分别是摄象机在Z轴和X轴上的坐标),因此BILLBOARD也应该绕Y轴旋转D3DX_PI/2-atanf(z/x)。而当摄象机的X坐标为正时,摄象机会旋转-(D3DX_PI/2+atanf(z/ x))。
代码如下:
              MY_MATRIX rotatemattixY;
              rotatemattixY.Identity();

              if( vDir.x < 0.0f )
                     D3DXMatrixRotationY( &rotatemattixY, D3DX_PI/2-atanf(vDir.z/ vDir.x));
              else
                     D3DXMatrixRotationY(&rotatemattixY,-(D3DX_PI/2+atanf(vDir.z/ vDir.x)));


注意大多数情况下BILLBORAD的位置并不在坐标系原点处,这时应该以摄象机位置减去视点位置,得到BILLBOARD处于相对坐标系原点时摄象机的位置(即上例代码中的vDir)。


三、             完全BILLBOARD

完全BILLBOARD,也许有人会认为这是Y轴BILLBOARD,X轴BILLBORAD,Z轴BILLBOARD的集合。需要在三个轴上同样的做一次上述操作,这样的做法肯定也能成功,但是太费周折。
对于片元这种元素的物体,很容易想到另一种算法,在绘制BILLBOARD片元前,先得到当前摄象机的上向量(up),右向量(right),然后在片元的当前位置生成与上向量和右向量平行的片元面。这种算法,BILLBOARD不是先创建再变换,而是根据需要的变换生成的。
但下面我将会介绍一种算法,能够先创建物体,然后用一个简单的方法得到完全BILLBOARD。
摄象机旋转一个角度以后,在绘制物件之前,我们会对物件做一次视变换,即乘以一个视变换矩阵。这样我们会看到物件的不同角度。完全BILLBOARD会随着摄象机的位置调整旋转角度,把摄象机转过的角度再转回来。即乘以一个旋转矩阵。问题在于,我们如何求得BILLBOARD的旋转矩阵?
这里我们要引出逆矩阵的概念。矩阵和他的逆矩阵的乘积为一个单位矩阵,因此,一个旋转矩阵的逆矩阵可以将一个经过旋转的点映射回旋转前的位置。
同样,我们可以取得视矩阵的逆矩阵,将它作为完全BILLBOARD的旋转矩阵,这样产生的效果就是摄象机没有变换过!因此完全BILLBOARD会始终面对摄象机,然后再乘以位移矩阵,就可得到完全BILLBOARD的世界变换矩阵。

代码如下:
D3DXMatrixInverse(&OutMatrix, NULL, &matView); // matView是视矩阵
              OutMatrix.SetPosition(0.0f,0.0f,0.0f);

仅仅上述代码,就可得到完全BILLBOARD的旋转矩阵,非常方便。


 
 本文发表于<程序员-游戏创造>2005年9月
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|3D数字艺术论坛 ( 沪ICP备14023054号 )

GMT+8, 2025-2-6 09:51

Powered by Discuz! X3.4

Copyright © 2001-2020, Tencent Cloud.

快速回复 返回顶部 返回列表