opengl3 PointSprite及在粒子系统中的使用

点精灵介绍

是指在绘制时一个精灵用一个点来表示,通常将一个点的size变大,就变成了矩形,然后将纹理映射到点上

初步使用
glPointSize(10.0f);
....
glDrawArrays(GL_POINTS,0,cnt);

vertex sader

uniform mat4 mvp;
layout(location = 0) in vec4 position;
void main()
{
    gl_Position = mvp * position;
}

fragment shader:

uniform sampler2D tex;
layout(location = 0) out vec4 color;
void main()
{
    color = texture(tex, gl_PointCoord);
}

在粒子系统中的使用

这里写图片描述

每个粒子绘制成圆

fragment shader:

#version 330 core
in vec3 Fcolor;
layout(location = 0)out vec4 glcolor;
void main()
{
    vec2 texCoord = gl_PointCoord*2 -vec2(1.0f);
    float r2 = dot(texCoord,texCoord);
    if(r2>1.0)
        discard;
    glcolor = vec4(Fcolor,1.0f);
}

这里写图片描述

把粒子渲染成球

需要求出法向量,加入光照,视觉上看起来像球,实际上还只是画了圆
fragment shader:

#version 330 core
in  vec3 Fcolor;
layout(location = 0)out vec4 glcolor;
void main()
{

    vec3 n;
    n.xy = gl_PointCoord*2 -vec2(1.0f);
    float r2 = dot(n.xy, n.xy);
    if(r2>1.0)
        discard;
    n.z = sqrt(1-r2);

    vec3 lightDir = vec3(0.0, 0.0, 3.0);
    vec3 viewPos = vec3(.0 ,.0, 5.0);
    vec3 half = normalize(lightDir + viewPos);
    float diffuse = max(0.0, dot(lightDir,n));
    float spec = pow(max(0,dot(half,n)),64);
    glcolor = vec4( (diffuse)*Fcolor,1.0f)+spec;
}

这里写图片描述

粒子球之间的相互挤压效果

在并不需要如上面类型的两个球交叉时,交叉部分只会显示一种颜色,
表示完全遮挡,而不能表现出球之间的相互作用。
如果需要相互作用效果,像分子结构一样,就需要修改深度值,使得深度值是距离圆中心的距离相关的值,那么在交叉部分,像素的颜色会为距离
球中心近的颜色,效果如下:
这里写图片描述
在上面的fragment shader中加入一句即可

gl_FragDepth = r2;
粒子大小随着距离相机的远近变化

在vertex shader中算得距离相机的远近,设置gl_PointSize,
需要在程序中设置
glEnable(GL_PROGRAM_POINT_SIZE);
vertex shader:

void main()
{
    Fcolor = color;
    vec4 eyePos = modelView * vec4(position, 1.0);
    vec4 projVoxel = proj * vec4(spriteSize, spriteSize, eyePos.z, eyePos.w);
    vec2 projSize = screenSize * projVoxel.xy / projVoxel.w;
    gl_PointSize = 0.25 * (projSize.x + projSize.y);
    gl_Position = proj * eyePos;

} 

这里写图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值