广告牌技术(Billboard)
作用
在3D空间里创建一个面片,使其始终面向摄像机。不同于UI的一点,是因为它在3D空间里,会有近大远小的特点,而UI大小始终不变。由于需要渲染两个三角面,所以是一种常用的优化手段。普遍用于游戏中的粒子,当然有些骚操作还会用来替代模型(近处是模型,镜头拉远到一定程度就替换成图片)
缺点
因为细节比较少,并且有始终面向摄像机的特性,所以如果用来替代模型的话,其他镜头角度就会穿帮。
原理
其实很简单,就是把面片的4个顶点转到摄像机视角,可以有多种方式实现,但原理基本都一样,这里只介绍其中一种。
struct Vertex
{
float3 position;
float2 uv;
float2 offset;
}
我们先定义上面这样的顶点格式,position是Billboard的中心位置,uv就是uv坐标,offset是Billboard相对中心的偏移。我们一共需要构造4个顶点,它们的position因为都是中心位置,所以都是一样的,uv和offset才有区别。其中offset,假设是左上角顶点的话值是(-SizeX/2,-SizeY/2),右下角的话是(-SizeX/2,SizeY/2)。SizeX和SizeY分别是Billboard在X方向和Y方向的尺寸。这里其实还可以进一步拓展,如果Billboard带二维旋转的话,可以根据旋转矩阵计算offset,这样最终结果看Billboard也是有旋转效果的。
我们构造好4个顶点数据之后,需要传两个矩阵到GPU,一个是模型矩阵,用来将position转到世界坐标(上面的position是本地空间,当然也可以上面直接用世界坐标,然后省去这个模型矩阵)。另一个是旋转矩阵,这个旋转矩阵直接用相机的旋转矩阵即可
然后GPU针对每个顶点只要做如下操作,即可以将顶点转到世界空间,并且处于摄像机视角。接下来就只要继续做MVP中的VP操作转到屏幕空间就完事了。
(position * modelMatrix).xyz + vec3(offset.x, offset.y, 0.0) * cameraRotMatrix;
以上就是实现Billboard的具体做法,当然也可以有其他姿势,例如CPU里直接把这一步做了,然后GPU里直接做VP操作。这样顶点数据就不需要传offset,以及也不需要传相机矩阵坐为常量
拓展
面朝摄像机方向我们已经掌握了,那怎么面朝其他方向呢?很简单,上面我们传了摄像机矩阵进GPU,其实只要根据面朝方向构造一个矩阵就行了。例如它的表现是朝上的,那它其实相对摄像机是朝下的,那我们只要构造一个朝下的旋转矩阵即可。
上一篇: 微信私域裂变5大打法