24/03/22
1교시
주제 : Geometry Shader 완성하기
작업 내용 : Geometry Shader 완성, Billboard 기능 구현
Geometry Shader 를 통해 얻을 수 있는 장점 :
- 비활성화 처리한 파티클에 대한 렌더링 파이프라인에 대한 작업을 GS 단계에서 중단 가능 -> 반복문의 continue 기능
- Point Mesh -> Rect Mesh : 중심점에 해당하는 Point Mesh의 좌표를 기준으로 View Space에서 정점(Vertex)을 확장시켜 자연스럽게 Billboard 처리가 되도록 함
Vertex Shader의 존재 이유 :
GS에서 좌표 변환 작업을 전부 해줌으로 VS에선 input 값으로 들어온 Vertex 정보를 output으로 GS에 전달해주는 역할만 한다.
VS가 딱히 하는 작업이 없어졌기에 없애도 되지 않겠냐는 생각을 할 수 있지만 그럴 수 없다.
렌더링 파이프라인 단계는 VS 없이 호출 될 수 없기에 GS로 단순히 데이터를 전달하는 기능이라도 구현해서 세팅해줘야한다.
VS는 정점연산의 시작이라는 상징적인 의미가 있다.
GS의 반환값 :
GS 연산에 사용될 함수를 작성할 때,
Point Mesh로 들어온 정점하나를 4개의 정점으로 분할하여 OutStream에 넣어줄 예정이다.
때문에 길이 4짜리 GS_OUT(GS의 반환 타입) 배열을 만들고 여기에 정점들을 넣어서 관리한다.
또한 GS의 경우 반환값을 함수에서 직접 반환하지 않고 인자로 들어온 Stream에 넣어주는 형태로 반환한다.
Append() : 버퍼의 끝에 값을 추가하는 기능
void Append(
in T value
);
RestartStrip() : 기본 스트립을 종료하고 새 스트립을 시작한다. 현재 스트립에 기본 토폴로지를 채우기 위해 내보내는 꼭짓점이 충분하지 않으면 불완전한 기본 형식이 삭제된다.
스트립..?
GS의 파라미터로 TriangleStream 을 받았는데
삼각형을 이루기 위해선 3개의 꼭짓점이 필요하고 Stream 에 꼭짓점에 대한 정보를 넣어줄때 삼각형을 이루는 한 그룹의 꼭짓점들을 스트립으로 부르는것 같다.
즉, Stream 으로 설정한 모양을 이루기 위한 꼭짓점들의 그룹 단위
Triangle의 Strip : 3개의 꼭짓점
Line의 Strip : 2개의 꼭짓점
참고로, Stream에 정점정보를 넣을때, Input Assembler 단계에서 Index Buffer를 넣어주던것과 같이 Rect Mesh를 이룰 두개의 삼각형을 그려주는 정점을 순서대로 넣어줘야한다.
0 - 1
| \ |
3 - 2
삼각형1 : 0 -> 1 -> 2
삼각형2 : 0 -> 2 -> 3
GS의 연산 :
VS에서 전달받은 Point Mesh의 정점에 대해 GS에서 World,View,Projection 변환을 수행한다.
변환작업을 수행하기전에 해당 Particle이 활성화 상태인지 확인하고 비활성화 상태이면 GS를 종료한다.
1. World 변환
World 변환의 경우 파티클의 타입인 tParticle 의 멤버로 들어있는 vWorldPos 의 값을 가져오는것으로 대체한다.
2. View 변환
카메라 시점기준에대한 변환으로 Point Mesh의 정점은 1개 이기에 간단하다.
View 변환된 정점을 중심좌표로 해서 RectMesh를 이룰 4개의 정점으로 분할한다.
이렇게 되면 별도의 과정을 거치지 않고도 자연스럽게 Billboard 기능을 구현할 수 있다.
3. Projection 변환
View 변환을 거친 4개의 정점들을 대상으로 연산해준다.
2교시
주제 : GS로 생성한 Rect Mesh에 이미지 출력해보기
작업 내용 : Particle 에 이미지 출력
ParticleSystem 수정사항 :
ParticleSystem Render Component에 출력할 Texture 데이터 저장할 멤버(m_ParticleTex) 추가
ParticleSystem::render() 과정에서 재질 리소스의 Texture 컨테이너(CMaterial::m_arrTex)에 파티클 이미지 저장
SetTexParam() 함수를 호출하여 컨테이너의 0번 Texture 공간에 이미지 저장
Texture 데이터 Binding 과정 :
Binding 과정은 m_arrTex 컨테이너의 각 원소 공간에 들어있는 데이터가 있다면 PS에 ShaderResourceView를 설정해준다. 추가적으로 재질 상수버퍼에 해당하는 원소에 이미지 데이터가 있다는 표시도 해준다. (m_Const.btex[i] = true)
void PSSetShaderResources(
[in] UINT StartSlot, // 설정할 처음 슬롯번호
[in] UINT NumViews, // 설정할 셰이더 리소스뷰 개수
[in, optional] ID3D11ShaderResourceView * const *ppShaderResourceViews // 설정할 셰이더 리소스 배열
);
만약 m_arrTex[i]의 데이터가 비어있다면 해당 SRV를 비워준다.
Particle Texture 출력 :
재질 상수버퍼의 g_btex_0에 이미지가 들어있다는 체크가 되어 있다면
g_tex_0에 들어있는 이미지 데이터를 샘플링하여 출력한다.
만약 PS 단계까지 넘어왔는데 이미지 파일이 들어있지 않다면 마젠타 색상의 Rect 가 출력되도록 분기처리 함
PS 에서의 분기처리 :
이미지 유무에 따른 분기처리시 사용가능한 방법중 하나는 GetDimensions() 함수를 사용하는거다.
Texture2D 에 사용할수 있는 함수로 인자로 들어온 변수들로 이미지의 너비와 높이값을 전달해준다.
하지만, Pixel Shader는 화면상 모든 Pixel들이 호출하는 작업으로 모든 픽셀이 해당 함수를 호출하는건 연산효율이 너무 좋지 않다.
때문에 우린 재질 상수를 통해 이미지 유무를 받아와 해당 값으로 분기처리를 해주는 방식을 채택했다.
Next Note
'DirectX11 > AR' 카테고리의 다른 글
AR50_ClassNote_6 (0) | 2024.03.28 |
---|---|
AR50_ClassNote_5 (0) | 2024.03.26 |
AR50_ClassNote_4 (0) | 2024.03.26 |
AR50_ClassNote_2 (0) | 2024.03.22 |
AR50_ClassNote_1 (0) | 2024.03.21 |