버텍스 - 지오메트리 셰이더로부터 출력된 정점정보는 레스터라이저 스테이지에 보내진후 렌더링 될 픽셀로 변환된다.
Direct3D에서는 이러한 과정을 통틀어서 레스터라이제이션 이라고 부르고 고정 파이프라인 단계로 프로그래밍이 불가능하며 자체 알고리즘을 통해 동작한다.
레스터라이제이션은 다음과 같은 역할을 수행한다.
•
클리핑
•
원근 나눗셈(perspective division)
•
뒷면 제거(backface culling)
•
스캔변환(ndc Scan transform)
•
뷰포트 변환
래스터 라이저 스테이트 오브젝트를 만드려면 늘 하던 식의 D3D11_RASTERIZER_DESC 구조체를 만들고
ID3D11Device::CreateRasterizerState함수를 호출하여 생성한다.
// 래스터라이저 스테이트 오브젝트 생성
D3D11_RASTERIZER_DESC RSDesc;
RSDesc.FillMode = D3D11_FILL_SOLID; // 평범하게 렌더링
RSDesc.CullMode = D3D11_CULL_NONE; // 컬모드 하지 않음
RSDesc.FrontCounterClockwise = FALSE; // 시계방향이 뒷면임 CCW
RSDesc.DepthBias = 0; //깊이 바이어스 값 0
RSDesc.DepthBiasClamp = 0;
RSDesc.SlopeScaledDepthBias = 0;
RSDesc.DepthClipEnable = FALSE; // 깊이 클리핑 없음
RSDesc.ScissorEnable = FALSE; // 시저 테스트 하지 않음
RSDesc.MultisampleEnable = FALSE; // 멀티 샘플링 하지 않음
RSDesc.AntialiasedLineEnable = FALSE; // 라인 안티앨리어싱 없음
hr = g_pD3DDevice->CreateRasterizerState(&RSDesc, &g_pRasterizerState);
JavaScript
복사
그리고 생선된 오브젝트로 레스터라이저 스테이트에 묶어준다.
void GraphicDevice_DX11::BindRasterizerState(ID3D11RasterizerState* pRasterizerState)
{
mContext->RSSetState(pRasterizerState);
}
JavaScript
복사
Output merger
OuputMerger 에서 중요한것은 렌더타겟에서 계산된 픽셀 값을 사용하는 것이다.
OuputMerger는 동시에 8개의 렌더타겟과 1개의 깊이/스텐실 버퍼를 설정한다.
Blend State(블렌드 스테이트)
블렌드 스테이트는 픽셀 셰이더에서 출력된 값(Src)와 렌더타겟의 값(Dest)에 각각의 계수를 곱하고
그값에 대해 지정한 계산을 수행하고 레더타겟에 쓰여지는 값을 결정한다.
outputColor = 연산방법(SRC값 * SRC계수, DEST값 * DEST 계수)
D3D11_BLEND_DESC bsDesc = {};
bsDesc.AlphaToCoverageEnable = false; //멀티 샘플링에서 알파값 사용 유무
bsDesc.IndependentBlendEnable = false; // False -> 렌더타겟의 0번쨰만 사용 (1~7 번째는 무시)
// 0번 렌더타겟에 대한 블렌드 상태 설정 (0~7 번까지 설정 가능하다)
bsDesc.RenderTarget[0].BlendEnable = true;
bsDesc.RenderTarget[0].SrcBlend = D3D11_BLEND::D3D11_BLEND_SRC_ALPHA;
bsDesc.RenderTarget[0].DestBlend = D3D11_BLEND::D3D11_BLEND_INV_SRC_ALPHA;
bsDesc.RenderTarget[0].BlendOp = D3D11_BLEND_OP::D3D11_BLEND_OP_ADD;
bsDesc.RenderTarget[0].SrcBlendAlpha = D3D11_BLEND::D3D11_BLEND_ONE;
bsDesc.RenderTarget[0].DestBlendAlpha = D3D11_BLEND::D3D11_BLEND_ZERO;
bsDesc.RenderTarget[0].BlendOpAlpha = D3D11_BLEND_OP::D3D11_BLEND_OP_ADD;
bsDesc.RenderTarget[0].RenderTargetWriteMask = D3D11_COLOR_WRITE_ENABLE::D3D11_COLOR_WRITE_ENABLE_ALL;
GetDevice()->CreateBlendState(&bsDesc, blendStates[(UINT)eBlendState::AlphaBlend].GetAddressOf());
JavaScript
복사
각 옵션별 상용 방법은 MSDN Document를 참고 해보자.
만약 따로 설정하지 안는다면 디폴트 값으로 설정되는 상태는 다음과 같다.
그리고 Blend State를 렌더링 파이프라인에 묶어준다.
FLOAT blendFactor[4] = {0.f, 0.f, 0.f, 0.f};
g_pImmediateContext->OMSetBlendState(g_pBlendState, //설정할 오브젝트
blendFactor, //상수값(RGBA)
0xffffffff); //샘플용 마스크
JavaScript
복사
두번째필드 BlendFactor는 D3D11_BLEND_BLEND_FACTOR 에서 사용할 상수값을 RGBA별로 설정한 배열이며 세번째 필드 SampleMask는 멀티샘플 렌더타겟에서 어떤 샘플을 Enable로 할까(Masking할까)를 설정하는 값으로 멀티 샘플링의 설정과는 독립되어있으며 멀티샘플 렌더타겟을 사용하는가에 따라 다르다.
Depth/Stencil State( 깊이/스텐실 상태 )
뎁스 / 스텐실 스테이트의 흐름은 대략 다음과 같다.
DepthStencil오브젝트를 생성해보자.
ID3D11DepthStencilState* g_pDepthStencilState = NULL;
D3D11_DEPTH_STENCIL_DESC DepthStencilDesc;
DepthStencilDesc.DepthEnable = TRUE; //깊이 테스트 활성화
DepthStencilDesc.DepthWriteMask = D3D11_DEPTH_WRITE_MASK_ALL; //쓰기
DepthStencilDesc.DepthFunc = D3D11_COMPARISON_LESS; // 앞쪽물체를 렌더링
DepthStencilDesc.StencilEnable = FALSE; //스텐실 테스트 비활성화
DepthStencilDesc.StencilReadMask = D3D11_DEFAULT_STENCIL_READ_MASK; //스텐실 읽기 마스크
DepthStencilDesc.StencilWriteMask = D3D11_DEFAULT_STENCIL_WRITE_MASK; //스텐실 쓰기 마스크
// 면이 앞을 보고 있을 경우 스텐실 테스트 설정
DepthStencilDesc.FrontFace.StencilFailOp = D3D11_STENCIL_OP_KEEP; //유지
DepthStencilDesc.FrontFace.StencilDepthFailOp = D3D11_STENCIL_OP_KEEP; //유지
DepthStencilDesc.FrontFace.StencilPassOp = D3D11_STENCIL_OP_KEEP; //유지
DepthStencilDesc.FrontFace.StencilFunc = D3D11_COMPARISON_ALWAYS; //항상 성공
//면이 뒤를 보고 있을경우 스텐실 테스트 설정
DepthStencilDesc.BackFace.StencilFailOp = D3D11_STENCIL_OP_KEEP; //유지
DepthStencilDesc.BackFace.StencilDepthFailOp = D3D11_STENCIL_OP_KEEP; //유지
DepthStencilDesc.BackFace.StencilPassOp = D3D11_STENCIL_OP_KEEP; //유지
DepthStencilDesc.BackFace.StencilFunc = D3D11_COMPARISON_ALWAYS; //항상 성공
g_pd3dDevice->CreateDepthStencilState(&DepthStencilDesc,&g_pDepthStencilState);
JavaScript
복사
DepthStencil오브젝트도 따로 설정해주지 않으면 기본값은 아래와 같다.
DepthStencil 오브젝트를 설정 했으면 함수를 호출하여 OM 스테이지에 설정한다
g_pImmediateContext->OMSetDepthStencilState(g_pDepthStencilState, 0);
JavaScript
복사