support for up to ~10K particles

This commit is contained in:
devZoGok
2021-10-19 19:06:40 +03:00
parent 29cfd4ab4f
commit 088f1d6416
5 changed files with 49 additions and 14 deletions
+2
View File
@@ -43,6 +43,8 @@ namespace vb01{
c->update();
for(ParticleEmitter *p : emitters)
p->update();
/*
*/
}
}
+1 -1
View File
@@ -8,7 +8,7 @@ layout (location=0) out vec4 FragColor;
layout (location=1) out vec4 BrightColor;
uniform sampler2D tex;
uniform vec4 color[200];
uniform vec4 color[507];
void main(){
float alpha=texture(tex,texCoords).r;
+11 -4
View File
@@ -2,6 +2,7 @@
layout (location=0) in vec3 aPos;
layout (location=1) in vec2 aTexCoords;
layout (location=2) in mat4 aInstancedModel;
out vec2 texCoords;
@@ -9,17 +10,23 @@ flat out int id;
uniform mat4 proj;
uniform mat4 view;
uniform mat4 model[200];
uniform vec2 size[200];
//uniform mat4 model[4];
uniform vec3 trans[507];
uniform vec2 size[507];
void main(){
vec3 camLeft=vec3(view[0][0],view[1][0],view[2][0]);
vec3 camUp=vec3(view[0][1],view[1][1],view[2][1]);
id=gl_InstanceID;
vec2 s=size[gl_InstanceID];
vec3 v=camLeft*s.x*aPos.x+camUp*s.y*aPos.y;
gl_Position=proj*view*model[gl_InstanceID]*vec4(v,1);
mat4 model=aInstancedModel;
model[3][0]=trans[gl_InstanceID].x;
model[3][1]=trans[gl_InstanceID].y;
model[3][2]=trans[gl_InstanceID].z;
/*
*/
gl_Position=proj*view*model*vec4(v,1);
//gl_Position=proj*view*model[gl_InstanceID]*vec4(s.x*aPos.x,s.y*aPos.y,aPos.z,1);
texCoords=aTexCoords;
}
+33 -8
View File
@@ -42,14 +42,19 @@ namespace vb01{
ParticleEmitter::Vertex vertices[]={v1,v2,v3,v4,v5,v6};
unsigned int indices[]={0,1,2,3,4,5};
u32 MBO;
mat4 *matrices=new mat4[numParticles];
for(int i=0;i<numParticles;i++){
mat4 mat=translate(mat4(1.f),vec3(0,0,0));
Particle p;
p.mat=mat;
p.dir=direction;
particles[i]=p;
matrices[i]=mat;
}
glGenVertexArrays(1,&VAO);
glGenBuffers(1,&VBO);
glGenBuffers(1,&EBO);
@@ -62,6 +67,22 @@ namespace vb01{
glEnableVertexAttribArray(0);
glVertexAttribPointer(1,2,GL_FLOAT,GL_FALSE,sizeof(Vertex),(void*)(offsetof(Vertex,texCoords)));
glEnableVertexAttribArray(1);
glGenBuffers(1,&MBO);
glBindBuffer(GL_ARRAY_BUFFER,MBO);
glBufferData(GL_ARRAY_BUFFER,numParticles*sizeof(mat4),&matrices[0],GL_STATIC_DRAW);
glVertexAttribPointer(2,4,GL_FLOAT,GL_FALSE,sizeof(mat4),(void*)0);
glEnableVertexAttribArray(2);
glVertexAttribPointer(3,4,GL_FLOAT,GL_FALSE,sizeof(mat4),(void*)(1*sizeof(vec4)));
glEnableVertexAttribArray(3);
glVertexAttribPointer(4,4,GL_FLOAT,GL_FALSE,sizeof(mat4),(void*)(2*sizeof(vec4)));
glEnableVertexAttribArray(4);
glVertexAttribPointer(5,4,GL_FLOAT,GL_FALSE,sizeof(mat4),(void*)(3*sizeof(vec4)));
glEnableVertexAttribArray(5);
glVertexAttribDivisor(2,1);
glVertexAttribDivisor(3,1);
glVertexAttribDivisor(4,1);
glVertexAttribDivisor(5,1);
}
ParticleEmitter::~ParticleEmitter(){
@@ -100,10 +121,12 @@ namespace vb01{
float factor=(float)(rand()%100)/100;
float s1=float(rand()%(int)spread)/180*PI,s2=float(rand()%360)/180*PI;
Vector3 ra1=(Vector3(0,1,0).cross(dir)).norm(),ra2=dir.norm();
if(ra1==Vector3::VEC_ZERO) ra1=Vector3(1,0,0);
dir=Quaternion(s1,ra1)*dir;
dir=Quaternion(s2,ra2)*dir;
particles[i].timeToLive=s64(1000*((highLife-lowLife)*factor+lowLife));
particles[i].mat=translate(mat4(1.f),vec3(nodePos.x,nodePos.y,nodePos.z));
particles[i].trans=nodePos;
}
//dir=nodeLeft*dir.x+nodeUp*dir.y+nodeDir*dir.z;
particles[i].dir=dir.norm()*direction.getLengthSq()+gravity;
@@ -111,29 +134,31 @@ namespace vb01{
particles[i].color=startColor+(endColor-startColor)*lifePercentage;
particles[i].size=startSize+(endSize-startSize)*lifePercentage;
particles[i].mat=translate(particles[i].mat,vec3(dir.x,dir.y,dir.z));
particles[i].trans=particles[i].trans+dir;
shader->setVec3(particles[i].trans,"trans["+to_string(i)+"]");
shader->setVec4(particles[i].color,"color["+to_string(i)+"]");
shader->setVec2(particles[i].size,"size["+to_string(i)+"]");
}
/*
for(int i=0;i<numParticles;i++){
for(int j=0;j<numParticles-1;j++){
for(int j=i;j<numParticles-1;j++){
mat4 m1=particles[j].mat,m2=particles[j+1].mat;
Vector3 v1=Vector3(m1[3][0],m1[3][1],m1[3][2]);
Vector3 v2=Vector3(m2[3][0],m2[3][1],m2[3][2]);
float d1=cos(camDir.getAngleBetween((v1-camPos).norm()))*camPos.getDistanceFrom(v1);
float d2=cos(camDir.getAngleBetween((v2-camPos).norm()))*camPos.getDistanceFrom(v2);
if(d1<d2){
if(d1<d2)
swap(particles[j],particles[j+1]);
}
}
}
*/
glBindVertexArray(VAO);
glDrawElementsInstanced(GL_TRIANGLES,6,GL_UNSIGNED_INT,0,numParticles);
for(int i=0;i<numParticles;i++){
shader->setMat4(particles[i].mat,"model["+to_string(i)+"]");
shader->setVec4(particles[i].color,"color["+to_string(i)+"]");
shader->setVec2(particles[i].size,"size["+to_string(i)+"]");
}
//glDisable(GL_CULL_FACE);
glBindVertexArray(VAO);
glDrawElementsInstanced(GL_TRIANGLES,6,GL_UNSIGNED_INT,0,numParticles);
//glEnable(GL_CULL_FACE);
}
+2 -1
View File
@@ -34,10 +34,11 @@ namespace vb01{
Vector2 texCoords;
};
struct Particle{
int VAO;
glm::mat4 mat;
s64 time=0,timeToLive=0;
Vector4 color;
Vector3 dir;
Vector3 dir,trans;
Vector2 size;
};