[Direct3D] Point sprite and sprite animation with shader(HLSL)

포인트 스프라이트는 주어진 Position과 Size를 가지고
하나의 텍스쳐를 맵핑해서 점 대신 텍스쳐 이미지를 출력해주는 기능입니다.
포인트 스프라이트는 Position의 리스트를 던져주고 다수의 파티클을 한번에 그리기때문에 매우 유용합니다.
같은 처리를 빌보드를 이용해서 한다면 개별 파티클마다 렌더링 해 줘야 하는 불편함이 있죠.

고정파이프라인 하에서의 포인트 스프라이트에 대한 자세한 내용은
"DirectX9를 이용한 3D Game 프로그래밍 입문"(용책)을 비롯해서 많은 서적을 참고하면 됩니다.

고정파이프라인을 사용한 포인트 스프라이트의 문제은 텍스쳐좌표가 0.0~1.0으로 자동매핑된다는 것입니다.
텍스처를 통째로 사용하기 때문에 일반적인 스프라이트 이미지를 사용할 수 없습니다.
그래서 플랫 애니메이션을 구현할려면 복수의 텍스쳐가 필요하며 텍스쳐마다 렌더링이 필요해지므로
포인트 스프레이트의 장점이 퇴색되게 됩니다.

포인트 스프라이트에서 일반적인 스프라이트 이미지를 사용이 가능해지면 플랫 애니메이션도 가능하지죠.
이를 해결하기 위해서 셰이더를 통한 포인트 스프라이트 처리를 해야 합니다.



우선 포인트 스프라이트 관련한 파이프라인만 간추려 보면 다음과 같습니다.
...-> Vertex Shader -> Generate Texture Coord -> Pixel Shader -> ...


렌더링 하기 전에 우선 D3DRS_POINTSPRITEENABLE를 켜줍니다.


우선 Vertex Shader에서는 일반적인 메쉬과 동일하게 정점 관련 처리를 해줍니다.
중요한 것은 포인트 사이즈를 반드시 출력해 주어야 합니다. (PSIZE)
그 외 Pixel Shader에 넘겨주고 싶은 값이 있다면 TexCoord0을 제외한 곳에 넣어 줍니다.
 
Vertex Shader구현에 주의해야 할 점은 고정파이프라인에서 해주었던 연산을 직접해야 하는 것입니다.
고정파이프라인 연산에서 사용하던 PointScaleEnable/PointSize/PointSize_Min/
PointSizeMax/PointScale_A/PointScale_B/PointScale_C등은 셰이더에서 적용되지 않습니다.
그리고 PSIZE는 스크린 좌표계 상의 크기를 넣어줘야 하므로 적절한 계산하여 값을 넣어줘야 합니다.
DirectX Point Sprite에서 쓰는 공식을 넣어도 좋고, 간략화한 공식을 써도 상관 없습니다.
(보통 A,B,C를 0, 0, 1로 넣기때문에 카메라와 거리로 나누어 주기만 해도 좋습니다. )


이렇게 넘겨준 PSize는 Pixel Shader에 가기 전에 DirectX(혹은 그래픽 하드웨어)에 의해
중점으로 부터 크기에 맞게 픽셀들이 생성되고 텍스쳐좌표가 설정되게 됩니다.
변환된 텍스쳐 좌표는 TexCoord0에 적제되기 때문에, Vertex Shader에서 TexCoord0를 사용할 수 없습니다.
만약 D3DRS_POINTSPRITEENABLE가 활성화되어 있지 않다면 이 변환은 무시됩니다.
그리고 PSIZE가 없어도 변환은 무시되는 듯 합니다. 그러나 불필요한 옵션은 꺼 놓는 것이 좋겠죠.


드디어 변환된 각 픽셀이 Pixel Shader에 전해지게 됩니다.
PSIZE에 의해 변환된 0~1로 맵핑된 텍스쳐 좌표가 TexCoord0에 들어있습니다.
일반적인 픽셀쉐이더와 같은 처리를 해주면 되는데, 스프라이트를 위해 TexCoord0의 값을 변형해야 합니다.
스프라이트 이미지에 맞춰 좌표를 축소하고 그리고 원하는 스프라이트가 선택되도록
오프셋을 계산하여 축소된 텍스쳐 좌표에 더해주면 완료입니다.



마침 HLSL를 사용한 파티클코드를 발견해서 만들고 있는 것에 넣기 전에 테스트용으로
스프라이트 이미지를 쓸 수 있게 개조해 테스트해 봤습니다.


그냥 테스트를 위해 대충 만든 스프라이트 이미지입니다...

랜덤으로 4가지 텍스쳐 중 하나를 선택하여 출력하고 있습니다.
프로그램에선 별도의 PSIZE처리를 하지는 않았습니다.



이제 스프라이트 이미지의 사용이 가능해졌으니 이를 바탕으로 프래임에 따라 적절한 스프라이트만
선택해주면 플랫 애니메이션이 가능해 집니다... 이를 위해서 Vertex Shader에서 관련 값을 출력해야겠죠.
그 외에도 사용되는 모든 파티클 이미지를 하나의 텍스쳐에 몰아 놓고 텍스처 설정을 크게 줄일수 있습니다.


프로그램 발췌
http://eldeann7.chez-alice.fr/HLSL_particles/index.htm

참고
http://groups.google.com/group/microsoft.public.win32.programmer.directx.graphics.shaders/browse_thread/thread/13862ec6bd382f91






by hellz | 2011/06/11 23:03 | Programming | 트랙백 | 덧글(1)

트랙백 주소 : http://hellzblog.egloos.com/tb/3182725
☞ 내 이글루에 이 글과 관련된 글 쓰기 (트랙백 보내기) [도움말]
Commented at 2014/01/13 21:31
비공개 덧글입니다.

:         :

:

비공개 덧글

◀ 이전 페이지          다음 페이지 ▶