혼합(2) - 혼합 상태

WanJu Kim·2022년 12월 31일

Direct3D

목록 보기
27/29

지금까지 혼합 연산자와 혼합 계수를 알아보았다. 응용 프로그램에서 이를 설정하려면 어떻게 해야 할까? 이와 같은 절차를 따르면 된다.

  1. 생성할 혼합 상태를 서술하는 D3D11_BLEND_DESC 구조체를 채운다.
  2. ID3D11Device::CreateBlendState 메서드를 호출해 ID3D11BlendState 객체를 생성한다.
  3. ID3D11DevicContext::OMSetBlendState 메서드를 통해 출력 병합기 단계에 묶는다.

D3D11_BLEND_DESC 구조체는 다음과 같다.

typedef struct D3D11_BLEND_DESC
    {
    BOOL AlphaToCoverageEnable;
    BOOL IndependentBlendEnable;
    D3D11_RENDER_TARGET_BLEND_DESC RenderTarget[ 8 ];
    } 	D3D11_BLEND_DESC;
  1. AlphaToCoverageEnable : true로 설정하면 나뭇잎이나 창살문 텍스처의 렌더링에 유용한 다중표본화 기법인 알파-포괄도(alpha-to-coverage) 변환이 활성화된다. 알파-포괄도 변환을 위해서는 다중표본화를 활성화해야 한다.
  2. IndependentBlendEnable : Direct3D 11에서는 장면을 최대 8개까지 렌더 대상들에 동시에 랜더링 할 수 있다. 이 플래그를 TRUE 설정하면 각 렌더 대상마다 혼합을 개별적으로 수행할 수 있다. FALSE 하면 모든 렌더 대상의 혼합 연산이, 배열의 첫 원소에 있는 설정으로 수행된다. 고급 기술이다.
  3. RenderTarget : D3D11_RENDER_TARGET_BLEND_DESC 원소 여덟 개짜리 배열로, 이 배열의 i번째 원소는 다중 렌더 대상의 i번째 렌더 대상에 적용할 혼합 섲렁을 담은 구조체이다. IndependentBlendEnable가 false이면 모든 렌더 대상은 RenderTarget[0]을 사용한다.

위의 제3 매개변수의 자료형인 D3D11_RENDER_TARGET_BLEND_DESC 구조체의 정의는 다음과 같다.

typedef struct D3D11_RENDER_TARGET_BLEND_DESC
    {
    BOOL BlendEnable;	// 기본값 : FALSE.
    D3D11_BLEND SrcBlend;	// 기본값 : D3D11_BLEND_ONE.
    D3D11_BLEND DestBlend;	// 기본값 : D3D11_BLEND_ZERO.
    D3D11_BLEND_OP BlendOp;	// 기본값 : D3D11_BLEND_OP_ADD.
    D3D11_BLEND SrcBlendAlpha;	// 기본값 : D3D11_BLEND_ONE.
    D3D11_BLEND DestBlendAlpha;	// 기본값 : D3D11_BLEND_ZERO.
    D3D11_BLEND_OP BlendOpAlpha;	// 기본값 : D3D11_BLEND_OP_ADD.
    UINT8 RenderTargetWriteMask;	// 기본값 : D3D11_COLOR_WRITE_ENABLE_ALL.
    } 	D3D11_RENDER_TARGET_BLEND_DESC;
  1. BlendEnable : 혼합을 활성화하려면 TRUE를, 비활성화하려면 FALSE를 지정한다.
  2. SrcBlend : RGB 성분 혼합의 원본 혼합 계수 Fsrc를 뜻한다. D3D11_BLEND의 열거형의 한 멤버를 지정해야 한다.
  3. DestBlend : RGB 성분 혼합의 원본 혼합 계수 Fdst를 뜻한다. D3D11_BLEND의 열거형의 한 멤버를 지정해야 한다.
  4. BlendOp : RGB 성분 혼합 연산자를 뜻한다. D3D11_BLEND_OP 열거형의 한 멤버를 지정해야 한다.
  5. SrcBlendAlpha : 알파 성분 혼합의 원본 혼합 계수 Fsrc를 뜻한다. D3D11_BLEND 열거형의 한 멤버를 지정해야 한다.
  6. DestBlendAlpha : 알파 성분 혼합의 원본 혼합 계수 Fdst를 뜻한다. D3D11_BLEND 열거형의 한 멤버를 지정해야 한다.
  7. BlendOpAlpha : 알파 성분 혼합 연산자를 뜻한다. D3D11_BLEND_OP 열거형의 한 멤버를 지정해야 한다.
  8. RenderTargetWriteMask : 렌더 대상 쓰기 마스크(write mask)로, 다음 플래그들을 하나 이상 조합해서 지정할 수 있다.
enum D3D11_COLOR_WRITE_ENABLE
    {
        D3D11_COLOR_WRITE_ENABLE_RED	= 1,
        D3D11_COLOR_WRITE_ENABLE_GREEN	= 2,
        D3D11_COLOR_WRITE_ENABLE_BLUE	= 4,
        D3D11_COLOR_WRITE_ENABLE_ALPHA	= 8,
        D3D11_COLOR_WRITE_ENABLE_ALL	= ( ( ( D3D11_COLOR_WRITE_ENABLE_RED | D3D11_COLOR_WRITE_ENABLE_GREEN )  | D3D11_COLOR_WRITE_ENABLE_BLUE )  | D3D11_COLOR_WRITE_ENABLE_ALPHA ) 
    } 	D3D11_COLOR_WRITE_ENABLE;

이 플래그들은 혼합의 결과를 후면 버퍼의 어떤 색상 채널들에 기록할 것인지를 결정한다. 예를 들어 D3D11_COLOR_WRITE_ENABLE_ALPHA를 지정하면 결과가 RGB 채널들에는 기록되지 않고 알파 채널에만 기록된다. 비활성화한 경우에는 픽셀 셰이더가 돌려준 색상에 그 어떤 쓰기 마스크도 적용되지 않는다. 고급 기술이다.

D3D11_BLEND_DESC를 지정하였으면, ID3D11Device::CreateBlendState 메서드를 호출한다.

HRESULT ID3D11Device::CreateBlendState(
	const D3D11_BLEND_DESC *pBlendStateDesc,
    ID3D11BlendState **ppBlendState);
  1. pBlendStateDesc : 위의 D3D11_BLEND_DESC 구조체를 가리키는 포인터.
  2. ppBlendState : 생성된 혼합 상태 인터페이스를 가리키는 포인터를 돌려준다.

이를 통해 ID3D11BlendState 객체를 생성하였으면, 출력 병합기 단계에 묶어야 한다.

void ID3D11DeviceContext::OMSetBlendState(
	ID3D11BlendState *pBlendState,
    const FLOAT BlendFactor,
    UINT SampleMask);
  1. pBlendState : 장치에 적용할 혼합 상태 객체를 가리키는 포인터.
  2. BlendFactor : 부동소수점 값 네 개의 배열을 가리키는 포인터로, 그 값들은 하나의 RGBA 색상 벡터를 정의한다. D3D11_BLEND_BLEND_FACTOR나 D3D11_BLEND_INV_BLEND_FACTOR를 지정했을 때 혼합 계수로 쓰인다.
  3. SampleMask : 다중표본화는 최대 32개의 표본을 취할 수 있다. 이 32비트 정수 값으로 그 표본들 각각을 활성화/비활성화할 수 있다. 예를 들어 다섯 번째 비트를 끈(0으로 설정) 정수를 이 매개변수에 지정하면 다섯 번째 표본이 추출되지 않는다. 일반적으로는 어떤 표본도 비활성화 하지 않는다는 뜻인 0xffffffff 기본값이 쓰인다.

만약 제1 매개변수에 널 값을 지정해서 호출하면 기본 혼합 상태가 적용된다.

다음은 혼합 설정 예이다.

D3D11_BLEND_DESC desc;
ZeroMemory(&desc, sizeof(D3D11_BLEND_DESC));
D3D11_COLOR_WRITE_ENABLE
desc.AlphaToCoverageEnable = false;
desc.RenderTarget[0].BlendEnable = true;
desc.RenderTarget[0].SrcBlend = D3D11_BLEND_SRC_ALPHA;
desc.RenderTarget[0].DestBlend = D3D11_BLEND_INV_SRC_ALPHA;	
desc.RenderTarget[0].BlendOp = D3D11_BLEND_OP_ADD;
desc.RenderTarget[0].SrcBlendAlpha = D3D11_BLEND_ONE;
desc.RenderTarget[0].DestBlendAlpha = D3D11_BLEND_ZERO;
desc.RenderTarget[0].BlendOpAlpha = D3D11_BLEND_OP_ADD;

desc.RenderTarget[0].RenderTargetWriteMask = D3D11_COLOR_WRITE_ENABLE_ALL;

HRESULT hr = md3dDevice->CreateBlendState(&desc, &blendState);
assert(SUCCEEDED(hr));

md3dImmediateContext->OMSetBlendState(blendState, nullptr, 0xffffffff);

profile
Question, Think, Select

0개의 댓글