Post Lists

2019년 1월 15일 화요일

DirectX 11 Braynzar Soft Tutorials - 04. Begin Drawing!

https://www.braynzarsoft.net/viewtutorial/q16390-4-begin-drawing

쉐에더 파이프라인..

Programmable Graphics Rendering Pipeline
만약 너가 Direct3D 10 경험이 있고, 그 파이프라인을 이해한다면, 너는 이러한 파이프라인 섹션의 대부분을 생략할 수 있다. 왜냐하면 Direct3D는 기본적으로 Direct3D 10의 확장이기 때문이다. 거기에서 그것은 같은 pipeline을 상요하지만, 몇 가지 추가 단계들이 있따. Direct3D 11은 그 프로그래밍 가능한 그래픽스 파이프라인에 3 개의 새로운 단계들을 추가했다. 그 뿐만 아니라, 그것은 또한 또 다른 별개의 그렇지만 느슨하게 연결된 파이프라인을 지원한다. 그것은 compute shader pipeline라고 불려진다. 그래픽스 렌더링 파이프라인(일명 draw pipeline)에서 그 세 개의 새로운 단계들은 Hull, Tesselator, and Domain shaders들이다. 그것들은 tesselation과 관련이 있는데, 그것은 기본적으로 한 오브젝트에 좀 더 많은 detail을 추가하는 것이다, 아주 많은 디테일을. 그것이 예제로 하는 것은 model로 부터 한 간단한 삼각형을 받아서, 더 많은 삼각형을 만들기 위해 좀 더 많은 정점들을 추가할지도 모르고, 그러고나서 그 삼각형이 좀 더 detailed해지도록 정점들을 재배치 한다. 그것은 simple low polygon model을 취해서 스크린에 보일 때 즈음엔 그것을 매우 디테일한 high poly model로 바꿀 수있다. 그것은 이 모든 것을 매우 빠르고 효율적으로 한다. 이것은 우리가 이 강의에서 구현하는 것을 배우지 않을 고급 주제이다.

그 compute shader(일명 Dispatch Pipeline)은 GPU를 일종의 병렬 프로세서의 종류로 사용하여 CPU의 연산력을 확장하여 매우 빠른 연산을 하기 위해 사용된다. 이것은 그래픽스와 관ㄹ녀이 있는 어떤 것을 가질 필요가 없다. 예를들어, 너는 매우 성능이 비싼 연산을 할 수 있다, compute shader pipeline을 사용해서 정확한 충돌 탐지 같은, gpu에서. 그 compute shader는 이 강의에서 이야기 되지 않을 것이다.

그 렌더링 파이프라인은 가상 카메라가 보는 것을 기반으로 2d image를 생성하기 위해 direct3d가 사용하는 단계들의 집합이다. 그것은 Direct3D 10에서 사용된 7개의 스테이지들과, Direct3D 11에 수반되는 3 개의 새로운 단계들이 있다. 그리고 다음과 같다:

1. Input Assembler (IA) Stage
2. Vertex Shader (VS) Stage
3. Hull SHader(HS) Stage
4. Tesselator Shader (TS) Stage
5. Domain Shader (DS) Stage
6. Geometry Shader (GS) Stage
7. Stream Output (SO) Stage
8. Rasterizer(RS) Stage
9. Pixel Shader (PS) Stage
10. Output Merger (OM) Stage

또 다른 것은 우리가 이제 각 쉐이더를 컴파일 해야만 하는 것이다. 이것은 그 쉐이더가 에러가 없도록 해야한다. 또한, effect file의 한 technique을 active technique으로 (shaders들의 연속) 설정하는 것 대신에, 우리는 우리가 코드에서 원할 때 마다 개별 쉐이더들을 설정할 수 있다. 나는 이것이 좀 더 dynamic approach라고 믿는다. 그것이 우리에게 그 active shaders들을 바꿀 더 많은 자유를 주기 때문이다. 동시에 다른 것들을 active shaders로 유지하면서. 예를들어, 우리는 final pixel color를 결정하는 lighting calculations을 상요하는 pixel shader를 lighting equations을 사용하지 않는 pixel shader로 바꿀 수 있다. 동시에 그 같은 vertex shader를 여전히 active하게 유지하면서.

그 둥그런 스테이지들이 "프로그래밍 가능한" 단계들이다. 거기에서 우리는 그것들을 생성할 수 있다. 그 square stages는 우리가 프로그램 하지 않는 것들이지만, 우리는 direct3d 11 device context를 사용해서 그것의 설정을 바꿀 수 있다.

Input Assembler (IA) Stage
너가 볼 수 있는 첫 번째 단계는 Input Assembler(IA)이다. 그 IA는 fixed function stage이고, 이것은 우리가 그것을 구현하는 프로그래밍을 할 수 없다는 것을 의미한다. 그 IA는 geometric data, vertices and indices를 읽는다. 그러고나서 그것은 삼각형, squares, lines, 그리고 점들 같은 geometric primitives를 생성하기 위해 그 데이터를 사용한다. 그 데이터는 다른 단계로 넘겨지거나 사용될 것이다. Indices는 그 primitives가 정점들로 어떻게 함께 모여야 하는지를 정의한다. 우리는 나중의 강의에서 indices를 이야기할 것이다.

IA에 어떤 것을 보내기전에, 우리는 처음에 두 가지 것을 할 필요가 있다. 한 버퍼를 생성하고, Primitive Topology, Input layout, and active buffers를 설정하는 것이다.

우선, 우리는 한 버퍼를 생성한다. IA에 의해 사용되는 두 개의 버퍼들은 vertex and index buffers이다. 이 강의에서 우리는 아직 index buffer에 걱정하지 않을 것이다. 그 버퍼를 생성하기 위해서, 우리는 D3D11_BUFFER_DESC 구조체를 채울 것이다.

버퍼 또는 버퍼들을 생성한 후에, 우리는 input-layout object를 생성할 필요가 있다. 이것이 하는 것은 direct3d에게 우리의 vertex 구조체가 어떻게 구성되는지를 말하고, 우리의 vertex 구조체에서 각 컴포넌트로 무엇을 할지를 말하는 것이다. 우리는 direct3d에게 D3D11_INPUT_ELEMENT_DESC elements로 정보를 제공한다. D3D11_INPUT_ELEMENT_DESC 배열에 있는 각 element는 vertex structure에 있는 한 원소를 설명한다. 만약 너의 Vertex structure가 position element, and a color element를 가지고 있따면, 그러면 너의 D3D10_INPUT_ELEMENT_DESC 배열은 그 포지션과 컬러에 대해 한 원소씩 가지고 있을 것이다. 여기에 예시가 있다:

~~

Vertex Shader (VS) Stage
VS는 첫 번째 프로그래밍 가능한 쉐이더이고, 우리가 그것을 코딩해야하는 것을 의미한다. VS Stage는 primitives가 AI에서 조립되고난 후에 모든 정점들이 거치는 곳이다. 모든 그려지는 vertex는 VS를 통해 넣어질 것이다. VS로, 너는 transformation, scaling, lighting, 텍스쳐를 위한 displacement mapping과 같은 것을 할 수 있다. vs는 항상 작동하는 파이프라인을 위해 구현되어야 한다, 비록 그 프로그램에 있는 정점들이 수정될 필요가 없을지라도. 그 파이프라인에 있는 쉐이더들은 HLSL 언어로 쓰여진다. 그 언어는 C++ 문장과 유사하고, 그래서 배우기에 어렵지 않다. 나는 우리가 그것을 바꾸는 각 레슨마다 그 effects file을 설명할 것이고, 나중에 우리는 HLSL만 보는 강의를 가질 것이다. 이 강의에 대해, 우리의 Vertex Shader는 어떠한 것도 하지 않는다. 그래서 우리는 그것을 수정하지 않고 각 vertex의 position을 반환한다. 그것은 이것처럼 보인다:

~~

Hull Shader (HS) Stage
HS는 direct3d 11 그래픽스 렌더링 파이프라인에 추가된 세 개의 새로운 부가 단계들 중 하나이다. 그 세 개의 새로운 단계들인 Hull Shader Stage, Tessellator Stage, Domain Shader Stage는 모두 tesselation이라고 불려지는 것을 구현하기 위해 작동한다. tesselation이 하는 것은 삼각형 또는 직선같은 primitive object를 취하고, 모델들의 세부사항을 증가시키기 위해 그것을 많은 작은 부분들로 빠르게 나눈다. 그것은 스크린에 넣어지기전에 GPU에서 모든 이러한 새로운 primitives를 생성하고, 그것들은 메모리에 저장되지 않는다. 그래서 이것은 CPU와 메모리에서 그것들을 생성하는 것보다 시간을 더 절약한다. 너는 간단한 low poly model을 가져와서 그것을 tessellation을 사용해서 매우 높은 디테일의 poly로 바꿀 수 있다.

그래서 Hull Shader로 돌아와서. 이것은 또 다른 프로그래밍 가능한 단계이다. 나는 상세히 들어가지 않을 것이지만, 이 스테이지가 하는 것은 한 primitive를 더 상세하게 만들기 위해 새로운 정점들을 어떻게 그리고 어디에 추가 할 지를 계산하는 것이다. 그것은 그러고나서 이 데이터를 Tessellator Stage와 Domain Shader Stage로 보낸다.

Tessellator (TS) Stage
그 tessellator stage는 tessellation process에서 두 번째 단계이다. 이것은 Fixed Function stage이다. 이 스테이지가 하는 것은 Hull Shader로부터 입력을 취하고, 실제로 그 primitive를 나누기를 한다. 그것은 그러고나서 그 데이터를 Domain Shader로 전달한다.

Domain Shader (DS) Stage
이것은 tessellation process에서 세 개의 스테이지들 중 세 번째이다. 이것은 프로그래밍 가능한 함수 스테이지이다. 이 스테이지가 하는 것은 Hull Shader STage로부터 새로운 정점들의 위치를 취하고, 좀 더 디테일을 만들기 위해 tessellator로부터 받은 정점들을 transform 한다. 삼각형 또는 직선의 중심에서 더 많은 정점을 추가하는 것은 어떤 방식으로든 그 디테일을 증가시키지 않을 것이기 때문이다. 그러고나서 그것은 geometry shader stage에 정점을 보낸다.

Geometry Shader (GS) Stage
이 쉐이더 스테이지는 선택적이다. 그것은 또한 또 다른 프로그래밍 가능한 함수 스테이지이다. 그것은 입력으로 삼각형을 위해 3개의 정점, 직선을 위해 2개, 점을 위해 한 개 같은 primitives를 받는다. 그것은 또한 입력으로 edge-adjacent primitives의 데이터를 취할 수 있다. 그것은 한 직선에 대해 추가적인 2개의 정점, 한 삼각형을 위해 세 개의 추가적인 정점과 같다. GS에 대한 이점은 그것이 primitives를 생성하고 파괴할 수 있따는 것이다. 거기에서 VS는 할 수 없는 것이다 (VS는 한 정점을 취하고 그것을 output한다). 우리는 한 점을 quad 또는 삼각형으로 이 단계와 함께 만들 수 있다. 우리는 GS에서 rasterizer 단계로 데이터를 넘길 수 있고, and/or Stream Output 를 통해서 메모리에 있는 vertex buffer로 보낼 수 있다. 우리는 나중의 강의에서 이 쉐이더 단계에 대해 좀 더 배울 것이다.

Stream Output (SO) Stage
이 단계는 파이프라인의 Vertex data를 얻기위해 사용된다. 특히 만약 GS가 없다면 Geometry Shader stage또는 Vertex Shader Stage로 부터. SO를 통해 메모리에 보내진 vertex data는 한 개 이상의 vertex buffers에 넣어진다. SO로부터 온 Vertex data output은 line lists or triangle lists와 같은 lists들로 항상 보내진다. 불완전한 primitives는 결코 보내지지 않는다. 그것들은 그냥 조용히 vertex와 geometry에서 처럼 버려진다. 불완전한 primitives는 오직 2개의 정점만 있는 삼각형 또는 한 개의 정점만 있는 직선과 같은 prmitives이다.

Rasterization Stage (RS) Stage
RS stage는 그것에 보내진 (shapes and primitives) 벡터 정보들을 취하고, 그것들을 각 primitive에 대해 per-vertex values들을 보간하여 픽셀들로 바꾼다. 그것은 또한 clipping을 다룬다. clipping은 기본적으로 screen view의 밖에 있는 primitives를 잘라내는 것을 말한다. 우리는 RS에서 다음을 사용해서 viewport를 설정한다.

Pixel Shader (PS) Stage
이 단계는 스크린에서 보일 각 픽셀을 계산하고 수정한다. 픽셀 단위 기반의 라이팅 같은. 그것은 또 다른 프로그래밍 가능한 함수 그리고 선택적인 단계이다. RS는 한 primitive에서 각 픽셀에 대해 한 번씩 pixel shader를 불러온다. 우리가 이전에 말했던 것 처럼, 한 primitive에서 각 정점의 값과 attributes는 RS에서 전체 PRIMITIVE를 가로질러 보간된다. 기본적으로 그것은 vertex shader와 비슷한데, 거기에서 vertex shader는 1:1 mapping을 가진다 (그것은 한 정점을 취하고 한 정점을 반환한다), 그 Pixel Shader는 또한 1:1 매핑을 가진다 (한 픽셀을 취하고 한 픽셀을 반환한다).

픽셀 쉐이더의 일은 각 픽셀 fragment의 최정 컬러를 계산하는 것이다. pixel fragment는 스크린에 그려진 각 잠재적 픽셀이다. 예를들어, solid circle 뒤에 있는 solid square가 있다. square에 있는 픽셀들은 pixel fragments이고, 원에 있는 픽셀들은 pixel fragments이다. ~~~

Output Merger (OM) Stage
 파이프라인에서 마지막 단계는 Output Mergetr Stage이다. 기본적으로 이 단계는 pixel fragments와 depth/stencil buffers를 취하고, 어떤 픽셀들이 실제로 render target에 쓰일지를 결정한다. 우리는 마지막 가으이에서 다음을 호출하여 render target을 설정한다.

우리는 이것에 대해 나중에 이야기할 수 있다.

OM stage이후에, 해야 할 남은 것은 우리의 backbuffer를 스크린에 보여주는 것이다. 우리는 다음을 호출하여 이것을 할 수 있다.






















댓글 없음:

댓글 쓰기