广告版技术BillBoard 原理与实现
2016-04-10 19:12
357 查看
面向世界的广告板demo下载
广告板技术:
无论观察者处于什么位置观察任何图像,广告版都能提供一个朝向观众的面,这个面随着摄像机的改变而改变.BillBoard技术是计算机图形学领域中进行快速绘制的一种方法。在类似游戏这种对实时性要求较高的场景下采取BillBoard技术可以大大加快绘制的速度从而提高画面的流畅性。把3D的物体用2D来表示,然后让该物体始终朝向镜头。比如场景中的一棵树,对于整个场景来说不是主要物体,因此无需花费大量的时间去计算树的每一部分的细节。通常的做法是首先准备好一张树的照片,然后镜头运动的时候使得树始终正对着镜头,我们看到的始终是树的正面。
我们在渲染树木,灌木丛,云,烟等效果时都会用到.
先看一下图片,这颗树就是广告板技术生成的
原理:
问题的实质就是我们知道结果是物体面对摄像机,然后求物体的世界变换矩阵.我们看这张图,其中有两种坐标,一种是Camera,一种是Particle,其中Particle就是我们要讨论的广告板(BillBoard).
// 计算此物体的朝向矩阵,首先计算几个向量 float3 v3Look = normalize( + g_vEyePt.xyz - g_vLookAt.xyz ); float3 v3Right = normalize( cross( float3( 0.0f , 1.0f , 0.0f ) , v3Look )); float3 v3Up = cross( v3Look , v3Right );
这是其中三行确定广告版坐标的代码.
v3Look图中Particle 蓝色箭头的方向,意思是朝向Camera的方向,这个很容易由两个向量相减得到,然后规范化.
v3Right是图中Particle中深绿色的箭头.首先由Particle中的浅绿色箭头(float3( 0.0f , 1.0f , 0.0f )),也就是Camera中间的Y方向向量,然后和v3Look 叉乘,最后规范化,可以得到深绿色的v3Right向量.
v3Up是图中Particle 中是深红色的向量.可以由v3Look和v3Right叉乘得到.
float4x4 matLookAt ; matLookAt[ 0 ] = float4( v3Right.xyz , 0.0 );//将右向量作为矩阵的X变换分量 matLookAt[ 1 ] = float4( v3Up.xyz , 0.0 ); //将向上向量作为矩阵的Y变换分量 matLookAt[ 2 ] = float4( v3Look.xyz , 0.0 );//将向前向量作为矩阵的Z变换分量 matLookAt[ 3 ] = float4( g_vEyePt.xyz , 1.0 );//将观察位置作为矩阵的Z变化平移分量 float4x4 matLocal = mul( matLookAt , g_matWorld ); float4x4 matWorldView = mul( matLocal ,g_matView ); float4x4 matWorldViewProject = mul( matWorldView ,g_matProject ); Out.Position = mul( In.Position , matWorldViewProject );
这样子就能得到真实世界的坐标了.
广告版的种类:
1.面向世界的广告板,大小随远近调整,也称精灵技术2.某轴是巨鼎的,大小随远近变化
3.提示信息类,大小与远近距离无关
一.面向世界的广告板,大小随远近调整,也称精灵技术
VS_OUTPUT RenderSceneVS( VS_INPUT In )
{
VS_OUTPUT Out = ( VS_OUTPUT )0;
// 计算此物体的朝向矩阵,首先计算几个向量 float3 v3Look = normalize( + g_vEyePt.xyz - g_vLookAt.xyz ); float3 v3Right = normalize( cross( float3( 0.0f , 1.0f , 0.0f ) , v3Look )); float3 v3Up = cross( v3Look , v3Right );
// 通过几个向量建立矩阵
float4x4 matLookAt ;
matLookAt[ 0 ] = float4( v3Right.xyz , 0.0 );
matLookAt[ 1 ] = float4( v3Up.xyz , 0.0 );
matLookAt[ 2 ] = float4( v3Look.xyz , 0.0 );
matLookAt[ 3 ] = float4( g_vEyePt.xyz , 1.0 );
float4x4 matLocal = mul( matLookAt , g_matWorld );
float4x4 matWorldView = mul( matLocal ,g_matView );
float4x4 matWorldViewProject = mul( matWorldView ,g_matProject );
Out.Position = mul( In.Position , matWorldViewProject );
Out.TextureUV = In.TextureUV;
return Out;
}
三个变量建立起了matLookAt矩阵,再使用此矩阵与世界矩阵相乘后到世界位置.
二.某轴是巨鼎的,大小随远近变化
比如上面的树木的效果,模型只会随Y轴变化而转动.要建立起轴向固定的布告栏变化矩阵,需要以下几个变量,观察者的位置,向上方向,和被观察的位置.实际上,观察方向在Y轴上的投影为0,所以Y轴不参与变换,即观察变量v3Look = float3(v3Look.x,0.0,v3Look.z),同时 float3 v3Up = float3( 0.0f , 1.0f , 0.0f ),即v3Up向量也要变为向Y轴的.
VS_OUTPUT RenderSceneVS( VS_INPUT In ) { VS_OUTPUT Out = ( VS_OUTPUT )0; // 计算此物体的朝向矩阵,首先计算几个向量 float3 v3Look = normalize( + g_vEyePt.xyz - g_vLookAt.xyz ); v3Look = float3( v3Look.x , 0.0 , v3Look.z );//重点是这行 float3 v3Right = normalize( cross( float3( 0.0f , 1.0f , 0.0f ) , v3Look )); float3 v3Up = float3( 0.0f , 1.0f , 0.0f );//cross( v3Look , v3Right ); // 通过几个向量建立矩阵 float4x4 matLookAt ; matLookAt[ 0 ] = float4( v3Right.xyz , 0.0 ); matLookAt[ 1 ] = float4( v3Up.xyz , 0.0 ); matLookAt[ 2 ] = float4( v3Look.xyz , 0.0 ); matLookAt[ 3 ] = float4( g_vEyePt.xyz , 1.0 ); float4x4 matLocal = mul( matLookAt , g_matWorld ); float4x4 matWorldView = mul( matLocal ,g_matView ); float4x4 matWorldViewProject = mul( matWorldView ,g_matProject ); Out.Position = mul( In.Position , matWorldViewProject ); Out.TextureUV = In.TextureUV; return Out; }
三.提示信息类,大小与远近距离无关
有时候,需要某种提示信息的广告版技术,即广告板随物体运动,但是大小不会随远近而变换.这里,此广告板有一些特性,提示框与屏幕对齐,用于实现文字或图形信息.\
这说明广告板的坐标的X轴和Y轴是随着物体变化而变化的.所以广告版的X坐标就是物体X坐标,广告板Y坐标就是物体Y坐标.
面向世界的广告板demo下载
相关文章推荐
- Oracle VM + centos7.1+openstack kilo 多结点安装教程---基础环境配置(4)
- Qt网络与通信-UDP
- php的header函数之设置content-type
- Scala Actor通信
- Thinking in React(翻译)
- IntelliJ IDEA创建Web SpringMVC项目(二):添加springMVC框架
- inline hook
- 选择适合自己的Markdown编辑器
- C++ 模板特化
- MySQL的注释方式
- pjsip,webrtc音视频解决方案
- linux 项目打包发布(autoconf)
- android新浪客户端学习心得(一)
- error C4996 This function or variable may be unsafe
- ubuntu系统里用putty连接juniper时Backspace键不工作
- 【剑指offer系列】 从1到n中1出现的次数___32
- webstorm快捷键
- 微软 LUCKY STRING
- LeetCode OJ 223.Rectangle Area
- libev实现分析