Billboard似乎是比较简单的技术,实际动手才知道相当复杂,最后把自己绕晕了.基础不扎实,没应用到实际开发中的知识随时都会忘记.有些技巧则无法探求其本源,大部分人都知道如何按技巧公式作出一个公告板,而不知其所以然.
In each billboard techniche, a target surface normal and an up direction are found for orienting the polygon, usually a quadrilateral.
Then M = (r, u, n)(r is right vector, u is up vector, n is normal vector, three all are said as to the target billboard plane),is the matrix transform a quadrilateral in the xy plane with +y as pointing towards its top edge.
就是说公告板的原始顶点要用xy平面来定义,M = (r, u, n)才是其对应的公告板矩阵.所以几乎所有的公告板实现为什么都是[x-d, y-d] - [x+d, y+d],而不是[x-d, z-d] - [x+d, z+d].
Screen-Aligned billboard的n是镜头视平面法线的逆方向,u是镜头的up.
Axial Billboard的u是受限制的Axial, r = u * n,(n是镜头视平面法线的逆方向,或,视线方向的逆方向),最后再计算一次n' = r * u,即n'才是最后可行的代入M的n,表达了受限的概念.
World-oriented billboard就不能直接使用镜头的up做up,因为镜头roll了,并且所画的billboard原本是应该相对世界站立的,按Screen-Aligned的做法就会随镜头旋转,所以此时应该r = u * n(u是其在世界上的up,n是镜头视线方向的逆方向),最后再计算一次u = r * n,即u'才是最后的up,即非物体本身相对世界的up,亦非镜头的up.
在应用粒子系统时有个很流行的技巧,
http://www.lighthouse3d.com/opengl/billboarding/index.php?billCheat2
这种技巧是view plane oriented(视平面对齐),而非view oriented(视点对齐).
对于粒子系统而言,如果使用view oriented,由于每个粒子都有自己的position和vLooAt,有自身的billboard矩阵,需要作一次transform计算,消耗就很大.而对于粒子系统这种使用视平面对齐(就是与屏幕对齐)即可以达到效果的应用,使用这技巧可以避免对每个粒子作一次transform计算,既然所有粒子都面朝一个视平面,其billboard都是一致的.而技巧公式只是上述原理的简化推导.对于大物体Impostor,这种面向视平面的技巧并不适合.
所以公告板技术是一种非常复杂的技术,它的实现变种实在太多了.归其根本在于,
1.View Oriented / View plane oriented
2.Sphere / Axial
3.Camera up / World up
公告板的原始顶点要用xy平面来定义
原始顶点的含义应该是经过骨骼运动后的顶点,骨骼运动后的顶点才是真正要做billboard的顶点. 若经过骨骼运动后的面没有朝向XY面,应该立刻附加一个矩阵使其朝向XY面,之后才能做Billboard.
// Billboard矩阵的根本: 正面镜头旋转 + 中心位置
D3DXMATRIX matBillboard( vRight.x, vRight.y, vRight.z, 0.0f,
vUp.x, vUp.y, vUp.z, 0.0f,
vLookat.x, vLookat.y, vLookat.z, 0.0f,
matTransform._41, matTransform._42, matTransform._43, 1.0f);
前提是模型原始顶点或原始顶点预变换后,在乘以matBillboard之前,应该是在XY平面内的,且以原点为中心.
Reference:
http://www.lighthouse3d.com/opengl/billboarding/index.php?billCheat1
More OpenGL Game Programming
Realtime Rendering
http://www.cnitblog.com/linghuye/archive/2007/04/29/26402.html