ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [26] - Z-buffer
    Graphics 2021. 7. 31. 18:19

    코드 hw3d/hw3d at T19-End · planetchili/hw3d (github.com)

    강의 (26) C++ 3D DirectX Tutorial [3D Cube / Z-buffer] - YouTube

    지금껏 그린 것은 이차원 Mesh입니다. 삼차원 Mesh로 넘어가도록 합니다. 만들어 두었던 Vertex Structure에는 z axis가 반영되어 있지 않습니다. 또한, Projection Matrix등의 개념도 도입되어 있지 않습니다.

    그래서 문제를 하나씩 해결합니다. z축을 추가하고 Vertex를 큐브를 만들 수 있게 해줍니다. 그럼 Index의 값도 함께 바꿔주어야 합니다.

    그리고 PerspectiveLH 행렬을 끝에 곱해주면 될 것 같습니다. 그런데 회전을 z축으로만 하면 돌고 있는지 아닌지 알기가 어렵기 때문에 x축으로도 돌려보겠습니다.

     

    그 결과가 다음과 같습니다. 가장 먼저 알아차릴 수 있는 것은 애초에 입체가 아닙니다. 그럼 무언가 빠뜨렸다는 소리입니다. D3D에게 우리가 z축을 추가했다는 사실을 알려주어야 합니다.

    바로 이 Inpu Layout의 position의 정보를 바꾸어야 합니다. 이것 뿐만 아니라 Vertex Shader에도 z축이 추가되었음을 알려야 합니다.

     

    이제 삼차원 Mesh도 나옵니다. 이번에는 색을 조정하기로 합니다. Blend된 색 보다는 차라리 통일된 색이 더 보기 좋을 지도 모릅니다. 여러 가지 방법이 있지만 각 삼각형에 0부터 시작하는 index를 가진 고유한 ID를 주는 방법입니다. 원래는 Geometry Shader가 필요하지만 D3D에선 그렇게 하지 않아도 된다고 합니다. 가장 먼저 해야 하는 일은 Pixel Shader에 Bind될 상수 버퍼[Constant Buffer]를 만드는 일입니다. 이 버퍼는 색의 배열을 저장하게 될 것이고 index를 통해서 색에 접근하게 됩니다. 

    이렇게 상수 버퍼를 만들고 그 안에 배열을 만듭니다. 이렇게 하면 Index로 각 색에 접근할 수 있게 됩니다. 상수 버퍼의 생성과 Pixel Shader에 Bind하는 과정은 기존의 상수 버퍼의 과정과 똑같습니다.

    그러면 자연스럽게 Pixel Shader 측에도 변화가 있어야 합니다. 상수 버퍼의 어떤 구조체가 Input으로 오게 되었기 때문입니다.

    Pixel Shader 내에 상수 버퍼를 받을 구조체를 만듭니다

    pixel shader의 기존 Input은 float3 colour였습니다. 이제 이런 걸 받지 않기 때문에 지워주고 다음과 같이 대체합니다.

    TriangleID라는 뜻에서 tid를 선정했습니다. 그 tid의 System value는 SV_PrimitiveID입니다. 이 시스템 값이 파이프 라인에게 모든 삼각형을 위해서  PrimitiveID를 생성하라 지시합니다. 그렇게 되면 Pixel Shader는 이 UniqueID를 통해서 현재 작업하고 있는 삼각형이 어떤 것인지 알게 되고 색 배열을 참조할 것입니다. tid / 2인 까닭은 육면체의 한 면은 두 개의 삼각형으로 이루어져 있기 때문입니다. Vertex Shader를 손봐야 합니다. Vertex Shader에도 더 이상 색에 관한 정보가 들어가지 않습니다. 만들었던 구조체는 버리고 그냥 원래대로 float4값을 반환하면 됩니다.

    C++측에서도 변화가 필요합니다. 더 이상 rgba값은 필요가 없기 때문에 Vertex를 찍어주는 과정에서도 색을 표기할 필요가 없어졌습니다. Input Layout 역시 더 이상 Colour값을 주지 않아도 되기 때문에 Position만 남기면 됩니다.

    이대로 디버그를 돌리면 오류가 발생합니다.

    Pixel Shader의 Property에서 General탭에 가면 Level을 고를 수 있도록 되어 있습니다.

    4.0을 선택하면 잘 됩니다.

     

    색이 더 이상 Blend되어 있지 않고 면마다 확실히 다르게 나옵니다. 이번에는 두 개의 Mesh를 생성하고 어떤 현상을 관찰해보도록 합시다.

    두 개의 육면체 Mesh를 만들고 더 직관적인 비교를 위해서 크기를 줄이지 않았습니다. 그리고 마우스를 움직이면 z축으로 Mesh가 이동하게 되고 중앙에 놓은 Mesh와 움직이는 Mesh가 서로 겹치거나 어느 한 쪽이 뒤로 가는 순간이 찾아올 것입니다. 하지만 기대와는 다른 결과를 보여줍니다. 겹친 것도 아니고 넘어간 것도 아닌 애매한 이상한 모습을 보여줍니다. 

    Drawing의 순서에 따라서 먼저 온 Mesh가 나중에 온 Mesh에 의해 덮어씌어지는 현상을 목도하고 있습니다. 이런 자세한 현상은 따로 알아볼 기회가 있습니다. 일단은 Z-buffer를 만들고 파이프 라인에 Bind로 합니다. 기쁜 소식은 이렇게 한 번 Z-buffer를 설정하면 다시 건드려야 할 기회는 거의 없다는 점입니다. 이 Z-buffer를 구성하기 가장 좋은 곳은 Graphics의 생성자[Constructor]입니다.

    Depth-buffer는 일종의 Frame Buffer입니다. 다른 점이라면 실제 Frame buffer는 Colour를 저장하지만 Depth buffer는 Depth value를 저장합니다. Device와 SwapChain을 만들 때 이 Frame Buffer들도 자동으로 만들어집니다. 그러나 Depth buffer의 경우에는 Texture를 직접 만들어 주어야 합니다. 그리고 Output Merger에 Bind해야 합니다. 이를 위해서 가장 먼저 해야하는 일은 Depth Stencil의 Description을 만들어 주는 일입니다. 이 Depth Stencil이나 여타 개념은 따로 준비된 강의가 있는 모양입니다.

    실행 하기 이전에 Depth Stencil Buffer 역시 Clear 해야할 필요가 있기 때문에 다음과 같이 Buffer을 clear합니다. 

    다음에는 전체적인 구조를 바꾸게 될 것입니다. 지금은 배우는 족족 테스트 하기 위해서 한 함수에 모든 것을 만들었기 때문입니다. 실질적으로는 이렇게 동작하지도 않고 구성하지도 않을 것이 뻔합니다.

    'Graphics' 카테고리의 다른 글

    [28] - Bindable/Drawable System - 2  (0) 2021.08.02
    [27] - Bindable/Drawable System  (0) 2021.08.01
    [25] - DirectXMath  (0) 2021.07.31
    [24] - Constant Buffer  (0) 2021.07.30
    [23] - Pipeline experiments  (0) 2021.07.30
Designed by Tistory.