본문 바로가기
Directx12 3D 프로그래밍 입문/10. 혼합

10.1 ~4 혼합 공식, 연산, 계수, 상태

by ftftgop3 2023. 10. 21.

혼합 : 현재 레스터화 하는 픽셀 (원본 픽셀)을 후면 버퍼에 이미 래스터화 되어 있는 (대상 픽셀) 섞는 기법 

현재 픽셀과 나중 픽셀을 섞어서 새로운 색을 만드는 기법 ( 반투명 수면 과  나무 상자 렌더링 시 발생)

 

혼합 공식

$ C= C_{src}\bigotimes F_{src}\bigoplus C_{dst} \bigotimes F_{dis}$

$ A= A_{src}\bigotimes F_{src}\bigoplus A_{dst} \bigotimes F_{dis}$

중간의 연산자는 여러 이항 연산자 중 하나 이며, +, -, min, max 로 사용 된다

C , A 독립적으로 동작 할 수 있고 다양한 연산을 할 수 있다

 

논리 이용자를 이용해서 섞는을 수도 있지만 위의 연산자를 사용하거나 논리 연산자를 혼합으로 

사용은 불가능( 동시 적용은 안된다)

픽셀의 형식은 반드시 부호 없는 정수 형식으로 나타 난다

 

혼합 계수

$ F_{src} , F_{dis}$ : 혼합 계수라고 부르며 각 혼합 계수들은 아래의 함수로 직접 설정 및 설된 값을 불러올 수 있다

GraphicsCommandList::OMSetBlendFactor 매서드의 두 번째 매개변수로 설정 

$ F_{src} , F_{dis}$  순으로 나타낸다

 

D3D_BLEND_ZERO : F = (0, 0, 0), F =0

D3D_BLEND_INV_BLEND_FACTOR : F = (1-r, 1-g, 1-b), F =1-a 등으로 설정 할 수 있다

지정된 색상은 혼합 상태를 변경 하기 전까지 유지 

RGB 혼합 공식에는 혼합 계수를 모두 사용 가능 하지만 알파 혼합 공식의 경우 _COLOR 로 끝나는 계수는 사용 못한다

 

혼합 상태

혼합 설정을 담은 혼합 상태는 PSO ( 파이프라인 상태 객체)에서 다룬다

//기존의 예제 코드에 적용 했던 방식
void BlendApp::BuildPSO()
{
 	D3D12_GRAPHICS_PIPELINE_STATE_DESC opaquePsoDesc;
    ZeroMemory(&opaquePsoDesc, sizeof(D3D12_GRAPHICS_PIPELINE_STATE_DESC));
    //PSO 상태 지정
    opaquePsoDesc.BlendState = CD3DX12_BLEND_DESC(D3D12_DEFAULT);
}



typedef struct D3D12_BLEND_DESC
    {
    // 알파 포고괄도 변환, 창살 텍스처, 군엽에 렌더링에 유용( 다중 표본화가 활성화 필수)
    BOOL AlphaToCoverageEnable; 
    
    //렌더 대상 마다 혼합 설정, 다중 렌더 대상에도 적용 가능 
    BOOL IndependentBlendEnable;
    //배열의 i번째 원소는 장면을 동시에 여러 렌더 대상에 렌더싱 시 i 번째 렌더 대상과 혼합 성정 구조체
    D3D12_RENDER_TARGET_BLEND_DESC RenderTarget[ 8 ];
    } 	D3D12_BLEND_DESC;
    
    typedef struct D3D12_RENDER_TARGET_BLEND_DESC
    {
    //혼합 활성화 
    BOOL BlendEnable;
    //논리 연산자 활성화( 일반 혼합과 논리 연산자 는 같이 사용 불가능) 
    BOOL LogicOpEnable;
    D3D12_BLEND SrcBlend; //RGB Fsrc
    D3D12_BLEND DestBlend; //RGB Fdst
    D3D12_BLEND_OP BlendOp; //RGB 혼합 연산자
    D3D12_BLEND SrcBlendAlpha; // A Fsrc
    D3D12_BLEND DestBlendAlpha; //A Fdst
    D3D12_BLEND_OP BlendOpAlpha; //A 혼합 연산자
    D3D12_LOGIC_OP LogicOp; // 논리 연산자에 사용할 연산자
    UINT8 RenderTargetWriteMask; //렌더 대상 마스크
    } 	D3D12_RENDER_TARGET_BLEND_DESC;

위의 플래그를 사용 해 결과 값을 후면 버퍼 채널에 적용,

마스크 에 따라 RGB 채널에는 기록되지 않고 A 값만 기록 하는 하게 사용 할수 있다

 

void BlendApp::BuildPSOs()
{
	//혼합 상태 생성 및 설정 방법
    //다른 PSO 마찬가지로 응용 프로그램 초기화 시점에 모두 미리 생성
	D3D12_GRAPHICS_PIPELINE_STATE_DESC transparentPsoDesc = opaquePsoDesc;

	D3D12_RENDER_TARGET_BLEND_DESC transparencyBlendDesc;
	transparencyBlendDesc.BlendEnable = true;
	transparencyBlendDesc.LogicOpEnable = false;
	transparencyBlendDesc.SrcBlend = D3D12_BLEND_SRC_ALPHA;
	transparencyBlendDesc.DestBlend = D3D12_BLEND_INV_SRC_ALPHA;
	transparencyBlendDesc.BlendOp = D3D12_BLEND_OP_ADD;
	transparencyBlendDesc.SrcBlendAlpha = D3D12_BLEND_ONE;
	transparencyBlendDesc.DestBlendAlpha = D3D12_BLEND_ZERO;
	transparencyBlendDesc.BlendOpAlpha = D3D12_BLEND_OP_ADD;
	transparencyBlendDesc.LogicOp = D3D12_LOGIC_OP_NOOP;
	transparencyBlendDesc.RenderTargetWriteMask = D3D12_COLOR_WRITE_ENABLE_ALL;

	transparentPsoDesc.BlendState.RenderTarget[0] = transparencyBlendDesc;
    ThrowIfFailed(md3dDevice->CreateGraphicsPipelineState(&transparentPsoDesc,
    IID_PPV_ARGS(&mPSOs["transparent"])));
}

'Directx12 3D 프로그래밍 입문 > 10. 혼합' 카테고리의 다른 글

10.9 요약 및 연습 문제  (1) 2023.11.02
10.8 안개  (1) 2023.10.28
10.5 혼합 연산자의 조합 예제  (0) 2023.10.26