OpenGL12-shader(GLSL)着色语言4-广告版的实现
之前介绍了vertex shader的基本原理,现在我们来做一个简单的实践,在游戏中广告版(布告版)
随处可见,而且效率很高,现在我们就使用shader来实现这一过程,首先我们要知道布告版的原理
实际上就是一直对着摄像机,与摄像机的方向上是垂直的。如下图所示:
不管摄像机如何去动,那么广告版也跟随一起动(即旋转),那么在摄像机动的时候,就要重新计算
布告版的位置,为了做到这一点,我么要对摄像机的原理有所了解,看摄像机的几个重要的参数,
观看的方向:dir
向上的方向:up
向右的方向:right
及组成如下的坐标系(就是摄像机的局部坐标系了)
黑色的表示的是世界坐标系,蓝色的是摄像机的坐标系。为了让布告版与摄像机垂直,我们要实时的对布告版的位置
做调整,首先我们要先定义下布告版的位置。然后根据计算的几个方向,就可以计算出来新的布告版的位置。
假设有四个点:如下图所示
以A点为起点,根据摄像机的 up,right,dir,就可以计算出来,B,C,D几个点的新的位置(即不管如何旋转,变化,A点的世界坐标
是不变的,我们才可以根据A计算出来B,C,D三个点的新位置)
下面就是一些数学上的基本知识了。
B点的位置如果要用摄像机垂直,及B点的方向是与摄像机的Up点是一致的。那么我们就可以计算出来它的位置。
B = A + (Width) * right;
C = A + Up* height + Width * right
D = A + Up * height
如下图:
现在我们知道了原理,就可以进行编写代码了:
uniform float size; uniform vec3 camPos; void main() { vec3 vAt = camPos - gl_Vertex.xyz; vAt = normalize( vAt ); vec3 vRight = cross( vec3( 0.0, 1.0, 0.0 ), vAt ); vec3 vUp = cross( vAt, vRight ); vRight = normalize( vRight ); vUp = normalize( vUp ); vec2 s = gl_MultiTexCoord0.zw * vec2( size/2.0, size ); vec3 vR = s.xxx * vRight; vec3 vU = s.yyy * vUp; vec4 dir = vec4( vR + vU, 0.0 ); gl_Position = gl_ModelViewProjectionMatrix * (gl_Vertex + dir ); gl_TexCoord[0] = gl_MultiTexCoord0; }
上面的代码中有些细节给大家介绍下,为了把布告版的宽度信息与高度信息,传递给shader,我通过纹理参数来做这件事情。
我们知道纹理可以有四维(x,y,z,w),z,w就用来保存布告版的宽度与高度信息。这样就可以参与计算(而不需要在二外的
传递更多的信息).
当然,还有很多种实现方式方法,大家可以用自己的实现方式,实现更加高效的布告版技术。如果是例子系统,其实OpenGL
也已经有一种实现方案,那就是粒子精灵,效率非常的高,大家可以参考。
代码随后上传