平民程序 - linghuye's blog

天下风云出我辈,一入江湖岁月催。皇图霸业谈笑中,不胜人生一场醉。提剑跨骑挥鬼雨,白骨如山鸟惊飞。尘事如潮人如水,只笑江湖几人回。

随笔 - 221, 文章 - 0, 评论 - 680, 引用 - 0
数据加载中……

Billboard思想和实现整理

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

posted on 2007-02-07 23:11 linghuye 阅读(4761) 评论(1)  编辑 收藏 引用 所属分类: 3D图形学研究

评论

# re: Billboard思想和实现整理  回复  更多评论   

我想做一个公告板太阳,而且太阳会沿着天空穹运动,写了代码如下:

D3DXMATRIX matView, matWorld;
D3DXMatrixTranspose(&matWorld, &matView);
matWorld._41 = sunpos.x
matWorld._42 = sunpos.y
matWorld._43 = sunpos.z
matWorld._44 =1;

g_pD3DDevice->SetTransform(D3DTS_WORLD, &matWorld);
虽然太阳一直朝向我,但当我的镜头上下俯仰或左右旋转,却发现太阳自己的位置却变了,我的sunpos是固定的,为什么会这样?请lingyue指教一下我。。
2007-04-20 16:37 | wl
只有注册用户登录后才能发表评论。