2016-07-26 35 views
0

我製作了粒子系統,但我想使其效率。 所以現在我想製作實例化的粒子,但是我遇到了問題。 它看起來像所有的粒子同時在相同的軌道上移動。如何渲染實例粒子

如何它看起來像現在:

How it looks like now

所以我試圖讓他們分開,但我不明白這一點。

這就是我的粒子現在的工作方式。

GLfloat m_vertex_buffer_data[] = 
{ 
//  X  Y  Z  U  V 
    -.5f, -.5f, 0.f, 0.f, 0.f, 
    -.5f, .5f, 0.f, 0.f, 1.f, 
     .5f, .5f, 0.f, 1.f, 1.f, 
     .5f, -.5f, 0.f, 1.f, 0.f 
}; 

void Scene::DrawParticle(Emitter* emitter) 
{  
    for (auto it = emitter->GetParticleContainer().begin(); 
    it != emitter->GetParticleContainer().end(); ++it) 
    { 
    glBlendFunc(GL_SRC_ALPHA, GL_ONE); 

    // Update pipeline 
    Pipeline(*it); 
    vec4 sptColor = (*it)->GetColor(); 

    glUniformMatrix4fv(m_GSM->GetGLManager()->GetUnifrom(TRANSFORM), 1, GL_FALSE, &m_mvp.m_member[0][0]); 
    glUniformMatrix4fv(m_GSM->GetGLManager()->GetUnifrom(UV), 1, GL_FALSE, &m_animation.m_member[0][0]); 
    glUniform4f(m_GSM->GetGLManager()->GetUnifrom(COLOR), sptColor.x, sptColor.y, sptColor.z, (*it)->m_life); 

    emitter->Update((*it)); 
    } 

    //Refresh the buffer data 
    glBufferData(GL_ARRAY_BUFFER, emitter->GetNumOfParticle() * sizeof(m_vertex_buffer_data), NULL, GL_STREAM_DRAW); 
    glBufferSubData(GL_ARRAY_BUFFER, 0, emitter->GetNumOfParticle() * sizeof(m_vertex_buffer_data), m_vertex_buffer_data); 

    // Bind our texture in Texture Unit 0 
    glBindTexture(GL_TEXTURE_2D, emitter->GetTexture()->GetTexId()); 

    // Draw quads 
    glDrawArraysInstanced(GL_QUADS, 0, 4, emitter->GetNumOfParticle()); 

} 

以下是我的vs和fs。 vs;

#version 330 core 

// Input vertex data, different for all executions of this shader. 
layout(location = 0) in vec3 vertexPosition_modelspace; 
layout(location = 1) in vec2 vertTexCoord; 

// Values that stay constant for the whole mesh. 
uniform vec4 Color ; 
uniform mat4 MVP; 
uniform mat4 Animation; 

//Output data 
out vec4 fragmentColor; 
out vec2 fragTexCoord; 

void main(){ 

// Set model vertex 
gl_Position = MVP * vec4(vertexPosition_modelspace, 1); 

// Set Color 
fragmentColor = Color; 

// Set texture coordinate 
vec4 newTexCoord = Animation * vec4(vertTexCoord, 0, 1); 

fragTexCoord = vec2(newTexCoord.x, -newTexCoord.y); 
} 

fs;

#version 330 core 

// interpolated valuse form the vertex shaders 
in vec4 fragmentColor; 
in vec2 fragTexCoord; 

//Texture ID 
uniform sampler2D Texture; 

// Ouput data 
out vec4 finalColor; 

void main() 
{ 

finalColor = fragmentColor * texture(Texture, fragTexCoord); 

} 
+1

「*我製作了粒子系統,但我想讓它高效。所以現在我想製作實例化的粒子*」爲什麼你認爲實例化會提高你的性能? –

+0

我完全同意@NicolBolas。對於小批量的頂點,「頂點數組」比「VBO」快。如果您使用的是NVIDIA®(英偉達™)卡,您可以使用NVIDIA Bindless Extensions,特別是Vertex Buffer Unified Memory,將速度提高約7倍。如果你有興趣,這裏是一個鏈接到PDF http://developer.download.nvidia.com/opengl/tutorials/bindless_graphics.pdf – Harish

回答

1

您的MVP矩陣對於每個粒子都是不變的,所以它們都將被渲染到屏幕上的相同位置。

我相信你有每個粒子有一個不同的頂點位置之前,並試圖快速改變使用單個精靈並繪製它的多個實例,每個粒子一個。請注意,您需要讓每個粒子的變換矩陣反映粒子的運動(變換)。

可以說你的粒子系統有一個MVP矩陣,它包括整個粒子系統的任何轉換。每個粒子應該有它自己的變換矩陣[T]。

所以你爲MVP線應該是

glUniformMatrix4fv(m_GSM->GetGLManager()->GetUnifrom(TRANSFORM), 1, GL_FALSE, &MVP_Particle[0][0]); 

其中 [MVP_Particle] = [MVP]×[T]。

使用一些庫來增加矩陣並上傳最終矩陣。這應該是這個樣子

[MVP_Particle] = [Projection] * [View/Camera] * [SystemTransformMatrix] * [ParticleTransformMatrix] 

現在,當你發送相同的VBO與不同MVP_Particle着色器,它們將在不同的地方根據[ParticleTransformMatrix]繪製。

希望這會有所幫助。