点精灵(Point Sprite)使用点精灵我们可以通过绘制一个3D点将一个2D纹理图像显示在任意位置上。
点精灵最常见的应用就是微粒系统。我们可以用点来表示在屏幕上移动的大量微粒,来产生一些视觉效果。但是把这些点表示为很小的重叠2D图像就是戏剧性流动着的细丝。
点精灵允许我们通过发送单个3D顶点,渲染一个完美对齐的纹理2D多边形。点精灵所需要的带宽只有为四边形发送四个顶点所用的带宽的四分之一,并且不需要客户端的矩阵逻辑来保持3D四边形和照相机的对齐。
(1)使用点
在客户端我们要做的只是简单绑定一个2D纹理,并且为纹理单元设置恰当的统一值。因为现在点精灵已经是默认的点光栅化模式。一种情况下例外:开启点平滑的时候。
我们不能使用点精灵和抗锯齿点。在片段程序中,有一个内建变量gl_PointCoord,这是一个分量向量,在顶点上对纹理坐标进行插值。
#version 130
out vec4 vFragColor;
in vec4 vStarColor;
uniform sampler2D starImage;
void main(void)
{
vFragColor = texture(starImage, gl_PointCoord) * vStarColor;
}
如上面的片段着色器代码,对于点精灵来说,不需要将纹理坐标作为属性进行传递。
一个点就是一个单独的顶点,那么我们就不能以任何其他方式在点表面上进行插值了。当然如果我们无论如何都要提供一个纹理坐标,或者以自定义的方法进行插值,那么也没什么。
(2)点的大小
两种方式可以设置点的大小。
//第一种方式:
void glPointSize(FLfloat size);
这个函数为锯齿点以及抗锯齿点设置点的直径,以像素为单位。我们也可以在顶点着色器中用程序设置点大小:
//第二种方式
//首先启用点大小模式:
glEnable(GL_PROGRAM_POINT_SIZE);
然后在我们的顶点程序中,可以设置一个内建变量gl_PointSize,这个变量确定了点的最终光栅化大小。这种方式的一种常见用途就是根据点的距离来确定点的大小。当我们使用glPointSize函数设置点的代销的时候,他们不受到透视除法的影响,而是将所有点设置为相同大小。无论他们有多远。
关于点距离变换如下公式:
d为从这个点到观察点的距离,而a,b,c是二次方程的参数。我们可以将他们存储为统一值,并且应用程序来对他们进行更新,或者我们已经想好了一组特定的参数,也可以在顶点着色器中将他们设置为常量。
比如:我们想设置一个常量大小值,那么就将a设置为非0值,而将b,c设置为0。
如果a,c为0,b非0,那么点大小将随着距离变化而线性变化。
如果a,b设置为0,而c设置为非0。那么点大小将随着距离变化而呈平方关系。
(3)飞跃星空代码分析
#pragma comment(lib,"GLTools.lib")
#include <GLTools.h> // OpenGL toolkit
#include <GLFrustum.h>
#include <StopWatch.h>
#include <math.h>
#include <stdlib.h>
#include <GL/glut.h>
//定义星星的数量
#define NUM_STARS 10000
GLFrustum viewFrustum;
GLBatch starsBatch;
GLuint starFieldShader; // The point sprite shader
GLint locMVP; // The location of the ModelViewProjection matrix uniform
GLint locTimeStamp; // The location of the time stamp
GLint locTexture; // The location of the texture uniform
GLuint starTexture; // The star texture texture object
// Load a TGA as a 2D Texture. Completely initialize the state
bool LoadTGATexture(const char *szFileName, GLenum minFilter, GLenum magFilter, GLenum wrapMode)
{
GLbyte *pBits;
int nWidth, nHeight, nComponents;
GLenum eFormat;
// Read the texture bits
pBits = gltReadTGABits(szFileName, &nWidth, &nHeight,