D3D12엔진개발 – PipelineState 조합(폭발) 처리

D3D12렌더러 개발을 시작하면서 한번 언급했던 내용이다. PipelineState폭발.

D3D12에선 Render State의 각 항목들을 개별적으로 바꿀 방법이 없다.

무슨 소린고 하니 A라는 VertexShader를 사용해서 렌더링했다가 모든 Render State를 그대로 유지한 상태에서 B라는 VertexShader로 바꿔서 렌더링하고 싶다…이런거 불가능하다.

알파블랜딩 상태도 마찬가지이고 Z-Write를 끌지 켤지, Z-Test를 할지 말지도 마찬가지다.
이 모든 상태들은 ID3D12PipelineState객체 한개로 묶어서 처리된다.

D3D12_GRAPHICS_PIPELINE_STATE_DESC구조체 각 상태들을 설정해서 ID3D12PipelineState객체를 생성하고 렌더링할땐 SetPipelineState()로 한번에 상태를 지정한다.

안그래도 Shader 자체가 꽤 융통성이 없는 편이라 HLSL파일에 되도록 적은 수의 Shader함수를 작성하고 pre-processor를 이용해서 다양한 옵션을 주는 경우가 많다. 그런데 여기에 그 Shader들의 옵션 조합에 Blend상태, Z-Test상태들을 더 붙여야 하는 것이다.

다른데선 어떻게 처리하는지 모르겠다. 아직 D3D12로 개발하는 곳이 많지 않고 자료도 찾기 어렵다.
일단 내 경우는 단순하게 처리했다.

난 이런 코드 진짜 싫다. 현업에서 17년째 일하는 동안 4차원 배열은 처음 써본다.
그런데 이보다 더 속도가 빠르고 명료한 방법이 있는지는 모르겠다.

decl_pipeline_state

  • Depth Write Enable, Depth Test Enable을 조합하여 -> DEPTH_TYPE_NUM (4)
  • 불투명,1-alpha/alpha,Add 조합으로  -> BLEND_TYPE_NUM (3)
  • Per Vertex Lighting, Toon Shading, Per Pixel Lighting 조합으로 -> VL_SHADER_TYPE_NUM (3)
  • 감쇄라이트, 그림자 받음 여부, 라이트 프로브 사용 여부 등의 조합으로  -> SHADER_PARAMETER_COMBO_NUM (16)

이렇게 해서 괴랄한 ID3D12PipelineState포인터의 4차원 배열을 구성했다.
그리고 이런식으로 ID3D12PipelineState 객체를 생성.

create_pipeline_state

렌더링할때 입력된 파라미터와 오브젝트 속성에 따라서 포인터 4차원 배열에서 적당한 ID3D12PipelineState객체를 가져다가 SetPipelineState()로 설정한다.

코드가 별로 아름답진 않지만..하여간 잘 작동함.

dx12_level_editor_2016_0217


답글 남기기

댓글을 게시하려면 다음의 방법 중 하나를 사용하여 로그인 하세요:

WordPress.com 로고

WordPress.com의 계정을 사용하여 댓글을 남깁니다. 로그아웃 /  변경 )

Facebook 사진

Facebook의 계정을 사용하여 댓글을 남깁니다. 로그아웃 /  변경 )

%s에 연결하는 중