DX12에서는 렌더링할 때 필요한 쉐이더, State들을 PSO(Pipeline State Object)에 담아서 관리한다.
DX11에서도 그 방식을 따라 구조를 변경해보도록 하자.
class GraphicsPSO {
public:
void operator=(const GraphicsPSO &pso);
void SetBlendFactor(const float blendFactor[4]);
public:
ComPtr<ID3D11VertexShader> m_vertexShader;
ComPtr<ID3D11PixelShader> m_pixelShader;
ComPtr<ID3D11HullShader> m_hullShader;
ComPtr<ID3D11DomainShader> m_domainShader;
ComPtr<ID3D11GeometryShader> m_geometryShader;
ComPtr<ID3D11InputLayout> m_inputLayout;
ComPtr<ID3D11BlendState> m_blendState;
ComPtr<ID3D11DepthStencilState> m_depthStencilState;
ComPtr<ID3D11RasterizerState> m_rasterizerState;
float m_blendFactor[4] = {0.0f, 0.0f, 0.0f, 1.0f};
UINT m_stencilRef = 0;
D3D11_PRIMITIVE_TOPOLOGY m_primitiveTopology =
D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST;
};
렌더링할 때 필요한 모든 쉐이더들, State들, primitiveTopology 들을 설정할 수 있다.
여러가지 GraphicsPSO들을 설정하기 위해서 필요한 부품들은 GraphicsCommon에 있다.
// Samplers
extern ComPtr<ID3D11SamplerState> linearWrapSS;
...
// Rasterizer States
extern ComPtr<ID3D11RasterizerState> solidRS;
...
// Depth Stencil States
extern ComPtr<ID3D11DepthStencilState> drawDSS; // 일반적으로 그리기
extern ComPtr<ID3D11DepthStencilState> maskDSS; // 스텐실버퍼에 표시
extern ComPtr<ID3D11DepthStencilState> drawMaskedDSS; // 스텐실 표시된 곳만
// Shaders
extern ComPtr<ID3D11VertexShader> basicVS;
...
// Input Layouts
extern ComPtr<ID3D11InputLayout> basicIL;
...
// Blend States
extern ComPtr<ID3D11BlendState> mirrorBS;
// Graphics Pipeline States
extern GraphicsPSO defaultSolidPSO;
PSO에 특정 상황마다 필요한 부품들, 그리고 마지막에 PSO가 선언되어 있다. 모든 변수들이 extern으로 설정되어
있으므로 cpp에서 정의를 한번 더 해줘야 한다. 이것들은 모두 Graphics namespace 안에 선언되어 있다.
void Graphics::InitCommonStates(ComPtr<ID3D11Device> &device) {
InitShaders(device);
InitSamplers(device);
InitRasterizerStates(device);
InitBlendStates(device);
InitDepthStencilStates(device);
InitPipelineStates(device);
}
void Graphics::InitSamplers(ComPtr<ID3D11Device> &device) {
D3D11_SAMPLER_DESC sampDesc;
ZeroMemory(&sampDesc, sizeof(sampDesc));
sampDesc.Filter = D3D11_FILTER_MIN_MAG_MIP_LINEAR;
sampDesc.AddressU = D3D11_TEXTURE_ADDRESS_WRAP;
sampDesc.AddressV = D3D11_TEXTURE_ADDRESS_WRAP;
sampDesc.AddressW = D3D11_TEXTURE_ADDRESS_WRAP;
sampDesc.ComparisonFunc = D3D11_COMPARISON_NEVER;
sampDesc.MinLOD = 0;
sampDesc.MaxLOD = D3D11_FLOAT32_MAX;
device->CreateSamplerState(&sampDesc, linearWrapSS.GetAddressOf());
sampDesc.AddressU = D3D11_TEXTURE_ADDRESS_CLAMP;
sampDesc.AddressV = D3D11_TEXTURE_ADDRESS_CLAMP;
sampDesc.AddressW = D3D11_TEXTURE_ADDRESS_CLAMP;
device->CreateSamplerState(&sampDesc, linearClampSS.GetAddressOf());
// 샘플러 순서가 "Common.hlsli"에서와 일관성 있어야 함
sampleStates.push_back(linearWrapSS.Get());
sampleStates.push_back(linearClampSS.Get());
}
GraphicsCommon.cpp에서 h에서 선언한 변수들을 다시 선언하고 Init 함수들로 초기화를 해준다.
sampleStates(list)에 샘플러들을 다 넣어주고 render할 때 쉐이더에 setsampler할 때 모든 sampler들을 넣어준다.
// 거울에 반사되면 삼각형의 Winding이 바뀌기 때문에 CCW로 그려야함
rastDesc.FrontCounterClockwise = true;
ThrowIfFailed(
device->CreateRasterizerState(&rastDesc, solidCCWRS.GetAddressOf()));
rastDesc.FillMode = D3D11_FILL_MODE::D3D11_FILL_WIREFRAME;
ThrowIfFailed(
device->CreateRasterizerState(&rastDesc, wireCCWRS.GetAddressOf()));
rastDesc.FrontCounterClockwise = false;
ThrowIfFailed(
device->CreateRasterizerState(&rastDesc, wireRS.GetAddressOf()));
rasterizeState도 설정에 따라 각각 다른 State에 넣어준다. 다른 State나 쉐이더도 이렇게 쭉 만들어준다.
// defaultSolidPSO;
defaultSolidPSO.m_vertexShader = basicVS;
defaultSolidPSO.m_inputLayout = basicIL;
defaultSolidPSO.m_pixelShader = basicPS;
defaultSolidPSO.m_rasterizerState = solidRS;
defaultSolidPSO.m_primitiveTopology = D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST;
// defaultWirePSO
defaultWirePSO = defaultSolidPSO;
defaultWirePSO.m_rasterizerState = wireRS;
// stencilMarkPSO;
stencilMaskPSO = defaultSolidPSO;
stencilMaskPSO.m_depthStencilState = maskDSS;
stencilMaskPSO.m_stencilRef = 1;
stencilMaskPSO.m_pixelShader = simplePS;
그리고 상태들을 조합해서 각각 다른 PSO들을 만들어서 넣어주면 된다.
'그래픽스' 카테고리의 다른 글
| [그래픽스] 그림자 (0) | 2023.07.23 |
|---|---|
| [그래픽스] Depth Map (0) | 2023.07.23 |
| [그래픽스] HDR 파이프라인 (0) | 2023.07.22 |
| [그래픽스] HDRI(High Dynamic Range Image) (0) | 2023.07.22 |
| [그래픽스] Height Map (0) | 2023.07.21 |