1. EX App Program
1.1 Billboard
1.1.1 Tree System
- 나무를 나타내는 완전한 3차원 기하구조를 렌더링하는 대신, 3차원 나무의 모습을 담은 2차원 텍스처를 사용
- 멀리있는 나무의 경우 빌보드인지 구분하기 어렵지만 빌보드는 항상 카메라를 향하게 해야 함
- 빌보드의 점의 정점에 대한 구조체를 생성
struct TreePointSprite { XMFLOAT3 pos; XMFLOAT2 size; };
- 정점 구조체는 세계 공간에서 빌보드 중심 위치를 나타내는 점의 좌표를 담음
- 또한 빌보드의 크기, 즉 빌보드의 너비와 높이를 담아 기하 셰이더를 통해 사각형으로 확장
const D3D11_INPUT_ELEMENT_DESC InputLayoutDesc::TreePointSprite[2] =
{
{"POSITION", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0},
{"SIZE", 0, DXGI_FORMAT_R32G32_FLOAT, 0, 12, D3D11_INPUT_PER_VERTEX_DATA, 0}
};
1.1.2 Effect File - Geometry Shader
- 기하 셰이더의 공간으로 각 점을 사각형으로 확장하므로, 실행 당 최대 출력 정점의 개수는 4개로 설정
- 또한 Vertex Shader로 부터 점을 전달받은 값을 입력 매개변수로, 출력 매개변수는 삼각형 띠로 출력
[maxvertexcount(4)]
void GS(point VertexOut gin[1], uint primID : SV_PrimitiveID, inout TriangleStream<GeoOut> triStream);
- 위 코드에서 기하 셰이더에서 특별한 부호 없는 정수 매개변수 하나를 받음
- 이 의미소를 지정하면 입력 조립기 단계는 각 기본도형마다 자동으로 기본도형ID를 생성
- 한 번의 그리기 호출로 N개의 기본도형을 그린다고 할 때, 0 부터 N - 1까지 식별번호가 부여
- 기본도형 ID들은 오직 주어진 한 번의 그리기 호출에 대해서만 유효
uint primID : SV_PrimitiveID
- 빌보드가 y축에 정렬되어 시점을 향하도록하는 세계 공간을 기준으로 한 빌보드의 좌표계 계산
float3 up = float3(0.0f, 1.0f, 0.0f); float3 look = gEyePosW - gin[0].CenterW;
look.y = 0.0f; look = normalize(look);
float3 right = cross(up, look);
- 사각형을 이루는 삼각형 띠의 정점들의 세계 공간 위치를 계산
float halfWidth = 0.5f*gin[0].SizeW.x; float halfHeight = 0.5f*gin[0].SizeW.y;
float4 v[4];
v[0] = float4(gin[0].CenterW + halfWidth*right - halfHeight*up, 1.0f);
v[1] = float4(gin[0].CenterW + halfWidth*right + halfHeight*up, 1.0f);
v[2] = float4(gin[0].CenterW - halfWidth*right - halfHeight*up, 1.0f);
v[3] = float4(gin[0].CenterW - halfWidth*right + halfHeight*up, 1.0f);
- 사각형 정점들을 카메라로 보이는 공간, 즉 동차 절단 공간으로 변환하고 하나의 삼각형 띠로 출력
- 반복을 지원하지 않는 모델에서는 반복할 내용을 반복 회수만큼 전개해서 컴파일하는 unroll 이용
GeoOut gout;
[unroll]
for(int i = 0; i < 4; ++i)
{
gout.PosH = mul(v[i], gViewProj);
gout.PosW = v[i].xyz;
gout.NormalW = look;
gout.Tex = gTexC[i];
gout.PrimID = primID;
triStream.Append(gout);
}
1.1.3 Effect File - Pixel Shader
- Texture Array에서 표본을 밑의 코드를 사용하여 추출
- 2차원 Texture Array의 한 표본을 추출하려면 세 가지 좌표성분이 필요
- 처음 두가지는 통상적인 2차원 Texture 좌표에 해당, 마지막은 Texture Array의 한 Texture를 선택하는 Index
- 위에서 사용한 Texture는 원소가 네 개인 Texture Array를 사용, 원소들은 서로 다른 나무의 Texture
- 한 번의 그리기 호출에서 나무 빌보드를 네 개 이상 그리기에 기본도형 ID가 3보다 커질 수 있음
- 따라서 4를 나눈 나머지를 Texture Array Index로 사용
float3 uvw = float3(pin.Tex, pin.PrimID%4);
texColor = gTreeMapArray.Sample( samLinear, uvw );
- 나머지 코드는 이전 코드와 비슷하여 밑의 글을 통해 참조
'C++ Algorithm & Study > Game Math & DirectX 11' 카테고리의 다른 글
[Direct11] 27. Direct3D Compute Shader - I/O Resource (0) | 2023.06.21 |
---|---|
[Direct11] 26. Direct3D Compute Shader (0) | 2023.06.21 |
[Direct11] 24. Direct3D Geometry Shader (0) | 2023.06.20 |
[Direct11] 23. EX App Program - Mirror (0) | 2023.06.19 |
[Direct11] 22. Direct3D Stencil (0) | 2023.06.19 |