D3D12엔진개발 – ID3D12PipelineState폭발…

D3D12에선 온갖 렌더링 스테이트를 묶어서 ID3D12PipelineState객체 하나로 만들어둠. 렌더링하면서 렌더 스테이트를 중간에 바꿀수 있는 API가 아예 존재하지 않음. 오직 ID3D12PipelineState객체만 바꿔가면서 렌더링 할 수 있음. 이게 쉐이더 폭발보다 더 무서움. [ 알파블랜딩 경우의 수 x 쉐이더 조합의 경우의 수 x 기타(양면 렌더링 여부, Depth Enable, Depth Write여부 등등) ] 변수가 더 있을텐데 이 정도만 해도 … More D3D12엔진개발 – ID3D12PipelineState폭발…

D3D12엔진 개발 – D3D11엔진과의 성능비교

  이 날을 기다렸다. 실제로 정말 더 빠른지를 테스트해보고 싶었다. 일단 데스크탑의 경우 최대 프레임이 D3D12버전보다 D3D11쪽이 두배 정도 나왔다. 이건 상당히 아쉬운 부분인데 그냥 화면 클리어만 해도 D3D11보단 무조건 느리다. 데스크탑에서 D3D11버전이 1400프레임 정도 나올때 D3D12버전은 800프레임 정도다. 뭔가 드라이버쪽에서 개선해줄 필요가 있을것 같다. 노트북GPU에선 일단 D3D12쪽이 빠르다. GTX980M이 장착된 에일리언웨어 노트북에서 테스트했을때 D3D12버전쪽이 … More D3D12엔진 개발 – D3D11엔진과의 성능비교

D3D12엔진 개발 – Dynamic VertexBuffer 사용

Voxel Horizon데모를 D3D12엔진으로 돌아가게 만들었다. 데모에서 바닥과 블럭 렌더링은 Dynamic VertexBuffer를 사용한다. D3D11에선 Map(), Unmap()을 사용해서 하나의 VertexBuffer에 Update하고 Draw..(), 또 Update하고 Draw..()하면 되었다. D3D11이라고 해서 Draw..()한다고 즉시 렌더링이 이루어지진 않는데 Resource Renaming이란 방법으로 해결하고 있다. D3D12에선 이런거 없다. 게다가 CommandList를 이욯하기 때문에 Execute()하는 시점까진 Draw…()에 사용될 VertexBuffer의 내용이 그대로 유지되어야한다. 우선 Vertex Buffer는 다음과 … More D3D12엔진 개발 – Dynamic VertexBuffer 사용

D3D12엔진 개발 – ID3D12RootSignature 생성시 ref count에 주의할것

D3D12에서는 draw를 위한 각종 파라미터를 Descriptor Table로 전달한다. 그리고 이 Descriptor Table의 형식을 정의하는 것이 ID3D12RootSignature 오브젝트이다. ID3D12Device::CreateRootSignature()함수로 ID3D12RootSignature 객체를 생성한다. 그런데 여기서 주의할 점이 있다. ID3D12RootSignature* pRootSignature = NULL; HRESULT hr = m_pD3DDevice->CreateRootSignature(nodeMask,pBlobWithRootSignature,blobLengthInBytes,IID_PPV_ARGS(&pRootSignature)); 이와같이 ID3D12RootSignature 객체를 생성했을때 pRootSignature의 ref count는 1일거라고 생각하는 것이 일반적이다. 그런데 1보다 큰 숫자일 수 있다. 이 경우 pRootSignature의 어드레스를 확인해보면 이전에 생성했던 ID3D12RootSignature객체이다. 즉 D3D내부에서 … More D3D12엔진 개발 – ID3D12RootSignature 생성시 ref count에 주의할것

D3D12엔진개발- Render Target의 Post Processing

가로 세로 7샘플씩, x축으로 한번, y축으로 한번씩 blur를 먹이는 blur filter를 구현했다. laplacian filter를 적용해서 outline을 검출하는 필터도 구현했다. D3D9나 D3D11에선 별것도 아닌 기능이지만 D3D12에서 구현하는건 그리 간단하지는 않았다. 예를 들어 BLUR를 보자. Original Image -> Resize -> Blur X -> Blur Y 이 순서로 가야하는데 D3D12이전에는 Original Image ->  Resize – (wait for complete) ->  Blur X … More D3D12엔진개발- Render Target의 Post Processing

D3D12엔진개발-CommandList 사용 실수

밖이 워낙 추우니 일단 집밖으로 나가기 싫은지라 추운 방에서 떨면서 작업을 했다. 현재 Post-effect를 적용하진 않았지만 준비는 다 끝났다. 아웃라인을 처리하기 위한 Normal과 Depth, 오브젝트 타입별 ID를 저장하는 별도의 렌더타겟 버퍼들을 만들고 렌더링하고 직접 눈으로 볼 수 있도록 했다. 그 외에 glow와 dof를 적용하기 위한 준비도 끝냈다. 그 와중에 너무 잘 돌아가는게 이상하다 싶어 Graphics Debugging을 … More D3D12엔진개발-CommandList 사용 실수

D3D12엔진개발 – Shadow Map등 멀티패스 렌더링의 효율적인 처리

CommandList와 CommandQueue를 이용한 Batch Processing은 멋지다. D3D12는 모든 작업을 CommandList에 기록하고 나중에 CommandQueue에서 여러개의 CommandList를 한번에 execute한다. 그림자 처리를 예로 들면 ShadowMap생성을 위한 Caster Object렌더링과 그림자를 받는 Receiver Object의 렌더링 사이에 wait가 필요없다. 이런식으로 그 모든 작업을 한방에 처리. 게다가 어플리케이션은 execute()결과가 완료될때까지 딴짓을 해도 된다. // Execute the command list. UINT CommandListCount = 0; … More D3D12엔진개발 – Shadow Map등 멀티패스 렌더링의 효율적인 처리

D3D12엔진개발-Cascade Shadow Map

뷰포인트 기준으로 거리에 따라 4단계의 Cascade Shadow Map을 적용했다. 이전 포스팅에서 언급했던것처럼 Shadow Map으로부터 SRV를 설정한 descriptor handle을 미리 준비해둔다. 오브젝트 렌더링시에 shadow적용을 받는 경우 오브젝트의 Descriptor Table의 Shadow Map영역에 Shadow Map의 descriptor을 CopyDescriptorsSimple()함수로 카피한다. shadow적용을 받지 않는 경우는 1×1사이즈의 white텍스쳐의 Descriptor를 카피한다. Shadow Map생성을 위해 shadow caster오브젝트들을 렌더링할땐 별도의 ID3D12GraphicsCommandList를 사용하므로 반사처리라든가 등등 pre-rendering하는 … More D3D12엔진개발-Cascade Shadow Map

D3D12엔진 개발 – 디버깅을 위한 Depth buffer 렌더링

요 몇 일간 Toon-Table Texture를 적용해서 아웃라인을 제외한 Toon Shading을 가능하도록 했다. 이제 그림자를 처리하려고 한다.그림자 처리를 위해 Shadow Map에 씬을 렌더링 해야한다. 그 전에 할 일이 있다. Render Target으로 사용한 텍스쳐를 화면에 렌더링 할 수 있도록 해야한다. 디버깅을 위해서 이 기능은 필수다. Shadow Map은 물론 snow처리나 Mirror효과, Out-line, Glow등의 Post Processing을 구현할때도 Render Target을 화면에 출력하는 기능이 꼭 … More D3D12엔진 개발 – 디버깅을 위한 Depth buffer 렌더링