DirectX는 GPU를 활용하는 API이다.
왜 GPU를 활용?>
코어수 GPU > CPU
간단한 역할은 GPU가 성능이 좋다.
DirectX에서는 GPU를 활용하기 위해 Rendering Pipeline 단계를 거친다.
단계 (Stage)
IA -> VS -> RS -> PS -> OM
단계
IA(Input Assembler 입력 조립기)
기초 데이터(Vertex Shader) 데이터를 만들어서 넣어야 한다.
그러나 사용자들의 니즈가 많아 이를 다 만들 수 없어서 스스로 커스터마이징해서 Vertex 자료형을 만들어야 한다.
정적 배열로 만든 정점, 컬러 혹은 UV 데이터를 GPU에 넘겨야 한다.
그런데 GPU는 아무 데이터 타입을 받지 않는다. 자원(버퍼형 자원이나, 텍스쳐형 자원)만을 받는다.
그래서 ID3D11Buffer 타입으로 만들어서 GPU에 넘겨준다.
문제 발생
1) 컴퓨터는 어디서 부터 어디가 어떤 데이터 인지(정점 데이터 인지, 컬러 데이터인지 혹은 UV데이터 인지 알 수 없다.)
-> ID3D11InputLayout 타입으로 만들어서 지정해준다.
2) 정점을 찍었지만 어떻게 연결하라고 알려주지 않았다. (연결성 정보 필요)
-> D3D11_PRIMITIVE_TOPOLOGY 플래그를 통해 연결성 정보를 넘겨준다.
정점의 중복 발생 -> 불필요한 메모리 낭비
1) 모든 도형들은 삼각형으로 이루어져 있다. 삼각형이면 3개의 정점으로 상관이 없지만 예를 들어 사각형은 6개의 정점이 필요하다. 그래서 중복된 정점을 제거해줘야 한다.
-> ID3D11Buffer IndexBuffer를 만들어 준다. (중복된 정점을 제거해주고 연결 정보를 넘겨준다.)
VS(Vertex Shader)
공간변환(Transform)을 담당
공간은 Local -> World -> View -> Projection -> Clip -> NDC -> Viewport
여기서는 Local -> World -> View -> Projection -> Clip을 담당
RS가 NDC -> Viewport를 담당한다.
Local(내가 입력한 정점 정보를 가진 것, 즉 사각형이라 한다면 가운데가 0, 0 좌표의 기준일 것이다, 자기 중심적인 좌표)
-> 이를 세계공간에 배치한다면 World 좌표가 된 것이다. -> 내가 보는 공간으로 변환(View) -> Projection(투영) 차원을 한차원 내리는 역할(화면은 2D로 나온다. 그래서 3D 데이터를 2D 데이터로 변환) 투영에는 직교 투영과 원근 투영이 있다. -> Cliping Space에서는 자르기 위해 정규화 과정을 거친다. (-1 ~ 1)
* Projection(투영)의 종류
- 직교 투영 -> 직사각형 모양 (near plane과 far plane 사이에 데이터 동일)
- 원근 투영 -> 절두체 모양(원근감이 있다.)
DirectX에서는 Projection과 Cliping Space 공간이 합쳐져 있다.
* 크기나 위치 회전을 설정할때
직접 값을 줘서 하는 방법도 있지만, 함수를 통해 줄수도 있다.
함수로 주게 되면 도형이 공간에 있다면 그 공간을 회전시키거나, 위치를 움직이거나, 크기를 조정등 처리를 한다.
rotation, translation, scale
RS(Rasterizer Stage, 레스터화기)
RS가 Viewport를 세팅한다.(->RSSetViewports())
NDC -> Viewport를 담당한다.
ClipingSpace로 안들어오는 공간을 Rasterizer가 Clip하고 이후 NDC가 정규화 과정(-1 ~ 1)을 거친다. -> 이를 Viewport가 크기에 맞게 늘려준다.
* NDC와 ClipingSpace의 차이점
- NDC는 유클리디안 공간 -> 동차공간이 정규화되어 있다.
- ClipingSpace는 호모지니어스 공간 -> 동차공간이 아직 정규화되어있지 않다.
RasterizerState를 통해 보여질 공간을 설정할 수 있다.(어떻게 그릴건지?)
어떤게 앞면인지 설정하고, 보이지 않는 면을 그리지 않을지 설정 가능, 채울지 말지 어떤식으로 채울지도 설정가능
front, CULLMode, FILLMode 활용
* Cliping과 Culling의 차이점
- Cliping -> 카메라가 정보를 통과한, 지나온것을 오려냄
- Culling -> 그리기 전에 아예 그리지 않음
Raseterizer는 PS로 넘어가기전 넘어온 색깔들에게 티켓(FLAGMENT)을 준다.
티켓을 받은 얘들만 PS로 넘어갈 수 있다.
PS(Pixel Shader)
티켓을 받은 픽셀들만 색을 칠하게 된다.
타켓에 그리게 된다.
타켓 설정은 OM에서 가능하다.
OM(Output Merger, 출력 병합기) : 어디다 출력할 것이고, 어떻게 출력할 것인지를 정한다.
Render Target, Blend State, DepthStencil View등 세팅 가능
BlendState -> 색깔 혼합 지정 가능(알파 블랜딩을 사용할 수 있다.)
Local, World, View, Projection을 쓰기위해 VS나 PS로 넘기기 위해 Constant Buffer(상수 버퍼) 사용
Constant Buffer와 Shader Resource View는 모든 Shader에 세팅가능하다.
이미지를 그리기 위해서는 Shader Resource View 필요
Resource View(자원 뷰)
1. 버퍼형 자원 -> ID3D11Buffer
2. 텍스쳐형 자원 -> ID3D11Texture1D, 2D, 3D.... -> 텍스쳐의 경우에는 용도가 명확치 않다.(그림을 그릴 이미지?, 그려진 이미지를 받아서 할건지?)
이를 해결하기 위해 자원뷰가 등장(용도 명확히 하기 위해)
-> RenderTargetView, Shader Resource View, Depth Stencil View, unordered Resource View
이미지에는 UV를 사용했다.
UV는 좌측 상단 0,0 우측 하단 1,1로 (0 ~ 1)로 정규화된 좌표
늘릴 수 있다. -> 조작 가능
1.0이 넘는 UV에서는 어떻게 처리할지(나머지 부분 어떻게 처리) -> Sampler State
나머지 부분을 어떻게 채울것인지(ADDRESS)
이미지가 확대(Max), 축소(Min), Mipmap등 되었을 때 어떻게 필터링을 줄 것인지(LINEAR, POINT)
'DirectX11 2D' 카테고리의 다른 글
| <DirectX11 2D 과제> 원 출력 (0) | 2021.09.06 |
|---|