태그 보관물: graphics-programming

graphics-programming

간단한 입자 효과를 만드는 가장 빠른 방법 찾고 있습니다 … 기본적으로 내

게임에서 지옥처럼 스팸이 될 간단한 입자 효과를 만드는 가장 빠른 방법을 찾고 있습니다 …

기본적으로 내 게임은 대부분 라인으로 구성된 vectrex 게임처럼 보입니다 … 나는 아주 흔한 작은 폭발을 만들고 싶습니다.

GL_Point로 일부 점을 이동하고 렌더링하는 것보다 더 빠른 것이 있습니까?



답변

모든 파티클에 대한 메모리를 저장할 필요가 없으며 각 파티클을 개별적으로 애니메이션 할 필요가 없습니다. 고전적인 물리 방정식을 사용하여 그리기 중에 입자 위치를 재구성하여 절차 적으로 수행 할 수 있습니다. s = ut + 1 / 2.at ^ 2

입자의 지속적인 가속없이 간단한 예 :


void drawExplosion(ExplosionParameters& s)
{
  Random rng;
  rng.seed(s.startSeed);
  glBegin(GL_POINTS);
  for (int i = 0; i < s.numParticles; i++)
  {
    vec3 vel = rng.getRandomVector(-1.0f, 1.0f) * s.explosionSpeed;
    float timeBias = rng.getRandom(0, s.particleTimeBias);
    vec3 pos = s.explosionCentre + (vel * (s.timeElapsed + timeBias));
    glPoint3fv(&pos);
  }
  glEnd();
}

그런 다음 업데이트 루프가 반복 될 때마다 s.timeElapsed를 증가시킵니다.

또한 GPU에서 완벽하게 구현되므로 CPU가 작업을 수행하지 않아도됩니다. GPU 구현은 다음과 같습니다.

void drawExplosion(ExplosionParameters& s)
{
    //bind Vertex Shader If Not Already Bound();
    ...
    // bindVertexBuffer of Zeroes If Not AlreadyBound();
    glVertexPointer(...)
    //uploadShaderUniformsForExplosion(s);
    glUniform3f(...)
    ...
    glDrawArrays(GL_POINTS, 0, s.numParticles);
} 

그런 다음 GPU 버텍스 쉐이더는 물리학 방정식을 통해 입자 위치를 재구성하고 CPU 버전과 마찬가지로 유니폼 / 상수를 전달합니다.

약간의 차이를 추가하기 위해 약간 다른 매개 변수를 사용하여 색상 / 알파에 애니메이션을 적용하고 다른 시작 위치를 선택하여 더 많은 폭발을 동시에 사용할 수 있습니다. 기타


답변

몇 가지 테스트를했으며 가장 빠른 방법 (코드가 가장 빠른 방법은 아님)은 위치와 속도를 알고있는 GL_LINE으로 만든 입자였으며 렌더링 할 때의 점으로 사용했습니다. 느려질수록 포인트가됩니다).

그 효과는 정말 멋지다 (지오메트리 워즈 비디오를보고 그것을 보아라). 쿼크에서 쓰레기를 걷어차십시오 (특히 쿼드로 인해 두 배의 꼭지점을 계산해야하기 때문에)

또한 이미 완성 된 파티클 시스템을 사용하는 것보다 낫습니다. 구체적이고 빠른 효과를 원했기 때문에 파티클 시스템은 일반적으로 비례적인 양의 오버 헤드로 많은 기능을 지원합니다.


답변

일반적으로 파티클을 텍스처 매핑 된 쿼드로 할 것이라고 생각합니다. 기본적으로 2D 스프라이트로 취급하고 시간이 지남에 따라 희미 해져 보이지 않으면 파괴합니다. 더 좋은 방법은, 새로운 것을 만들 때 오래된 것들을 재사용하여 이러한 것들에 대한 기억을 방해하지 않도록하십시오.

아트에 미리 곱한 알파 를 사용 하면 한 가지 유형의 블렌딩 작업으로 조명, 불, 연기 등을 쉽게 지원할 수 있습니다.


답변

OpenGL ES 2.0, 확장이 포함 된 ES 1.X 및 OpenGL => 2.1을 사용하면 GL_POINT_SPRITES를 사용할 수 있습니다. GL_POINT_SPRITES는 항상 카메라 앞에있는 쿼드와 같습니다.

프래그먼트 셰이더에서 다음을 수행 할 수 있습니다.

  • 버텍스 쉐이더에서 gl_PointSize로 스프라이트 크기 정의
  • 프래그먼트 셰이더에서 gl_PointCoord (uv 좌표) 사용

알파로 텍스처를 사용하여 볼 스프라이트를 그릴 수 있습니다 …

포인트 스프라이트에 대한 튜토리얼


답변

내가 본 대부분의 입자 효과 시스템은 많은 수의 점을 그리는 대신 각 텍스처가 약간 폭발처럼 보이는 비교적 적은 수의 빌보드 텍스처를 그립니다. 당신의 예술 스타일이 실제로 막지 않는다면, 그 길을 따라가는 것이 더 행복 할 것입니다. 개별적으로 애니메이션을 적용하고 렌더링하는 데 필요한 입자의 양을 최소화하면서도 큰 시각적 효과를 제공합니다.


답변

파티클의 간단한 배열이 있다고 가정 할 때 파티클의 생성 / 삭제 / 업데이트를 처리 할 수있는 깔끔한 작은 방법-파티클 [MAX_PARTICLES] :

활성 입자 추적 (NumActiveParticles = 0으로 시작)

새로운 입자는 항상 배열의 끝에 추가됩니다 :

pNewParticle = &Particles[NumActiveParticles++];

영리한 비트- ‘죽은’파티클을 제거 할 때 마지막 활성 파티클과 바꾸고 NumActiveParticles를 줄입니다.

if ( DeadParticle < NumActiveParticles-1 )
{
  Particles[ DeadParticle ] = Particles[ NumActiveParticles-1 ];
}
NumActiveParticles--;

이렇게하면 스폰시 ‘사용하지 않은 파티클’을 검색하지 않으며 MAX_PARTICLES 배열을 사용하여 스캔하지 않아도됩니다.

파티클을 삭제하는이 방법은 배열을 재정렬하기 때문에 업데이트 / 렌더 순서가 중요하지 않은 경우에만 작동합니다 (추가 블렌딩을 사용하는 많은 파티클 효과의 경우와 마찬가지로).


답변

내가 생각하는 가장 빠른 방법은 입자 엔진을 찾아 효과에 사용하는 것입니다. 몇 가지가 있습니다 :