Billboard 理解与实现

 

Billboard是一项使用非常普遍的技术,很多一些绚丽的特效可以使用它来实现,当然公告板、姓名板等是它较早的用途。

Billboard 的主要思想是在 XY 平面上建立一个绘图区域,在此区域上渲染一张贴图的一个区域,并且此平面要一直面向摄像机。

Billboard的主要实现:

1. Billboard的绘制区域是建立在自身坐标系的XY平面上,绘制区域的正面朝向为自身坐标系的Z轴的方向。由于Billboard需要朝向摄像机,所以Billboard在构造渲染顶点数据的时候需要将原始的Billboard绘制区域的左右对调后再填充定点数据(即原来的区域left与 right)。

2. Billboard朝向问题:

Billboard需要一直朝向摄像机,即通过Yaw\Picth\roll(由于旋转是相对于Billboard自身坐标系,所以Yaw\Picth\roll分别对应Y\X\Z)三次旋转后达到billboard永远朝向摄像机的目的。一般程序实现分两种,固定Yaw轴(Billboard的上方向不变)与不固定Yaw轴。

固定Yaw轴的Billboard旋转的时候要使Yaw轴保持固定所以不能进行Picth和Roll旋转,只需要沿Yaw轴旋转。

固定Yaw轴的Billboard需要三次旋转

Billboard旋转D3D代码:

//由于Billboard的旋转是按自身坐标系旋转,所以up/right/foward分别对应Y/X/Z轴

//首先得到billboard应该被设置成的朝向向量即摄像机的朝向向量的反方向

D3DXVECTOR3 lookAt(0.0f, 0.0f, 1.0f);

lookAt = -pCam->GetDirection();

//再得到lookAt投影到XZ平面上的向量,用于计算Pitch值(相当于沿X方向旋转的角度)

D3DXVECTOR3 adjustLookAt = lookAt;

adjustLookAt.y = 0.0f;

//必须要将向量变为单位向量

D3DXVec3Normalize(&lookAt, &lookAt);

D3DXVec3Normalize(&adjustLookAt, &adjustLookAt);

D3DXMATRIX rm_x;//沿X轴的旋转矩阵

D3DXMATRIX rm_z;//沿Y轴的旋转矩阵

D3DXMatrixIdentity(&rm_z);

//如果摄像机的上方向的Y值小于0则需要将Billboard的up方向向反方向调换一下

if (pCam && pCam->GetUp().y < 0.0f)

D3DXMatrixRotationAxis(&rm_z, &D3DXVECTOR3(0.0f, 0.0f, 1.0f), D3DX_PI);

//Billboard朝向与XZ平面的夹角

dot = D3DXVec3Dot(&adjustLookAt, &lookAt);

//如果Billboard朝向是沿Y轴向下则绕X轴正向旋转,否则沿X轴反向旋转,

//左手坐标系下的旋转符合左手定则,比划一下就能知道为什么

if (lookAt.y <= 0)

D3DXMatrixRotationAxis(&rm_x, &D3DXVECTOR3(1.0f, 0.0f, 0.0f), acos(dot));

else

D3DXMatrixRotationAxis(&rm_x, &D3DXVECTOR3(-1.0f, 0.0f, 0.0f), acos(dot));

rm_x = rm_z * rm_x;

D3DXMATRIX rm_y;//绕Y轴旋转的矩阵

//旋转的角度为Billboard朝向与Billboard原始朝向的夹角

dot = D3DXVec3Dot(&D3DXVECTOR3(0.0f, 0.0f, 1.0f), &adjustLookAt);

//根据Billboard朝向方向是偏X轴的正方向还是反方向决定绕Y轴的正方向或反方向

//同样用左手比划一下就知道为什么

if (adjustLookAt.x <= 0)

D3DXMatrixRotationAxis(&rm_y, &D3DXVECTOR3(0.0f, -1.0f, 0.0f), acos(dot));

else

D3DXMatrixRotationAxis(&rm_y, &D3DXVECTOR3(0.0f, 1.0f, 0.0f), acos(dot));

3. Billboard渲染时需要根据使用情况决定是否需要开启灯光渲染。

你可能感兴趣的:(Billboard 理解与实现)