혼합 : 현재 레스터화 하는 픽셀 (원본 픽셀)을 후면 버퍼에 이미 래스터화 되어 있는 (대상 픽셀) 섞는 기법
현재 픽셀과 나중 픽셀을 섞어서 새로운 색을 만드는 기법 ( 반투명 수면 과 나무 상자 렌더링 시 발생)
혼합 공식
$ 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 |