2016-07-26 2 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와 셰이더 같은 VBO를 보낼 때이 지금이

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

처럼 보일 것이다, 그들은 [ParticleTransformMatrix]에 따라 서로 다른 장소에서 그려집니다.

희망이 도움이됩니다.

관련 문제