혼합(1) - 혼합 공식

WanJu Kim·2022년 12월 31일

Direct3D

목록 보기
26/29

물이나 유리같은 반투명한 물체를 어떻게 출력할 것인가? 이런 반투명한 물체 뒤로 또 다른 물체가 보여야 한다. 하지만 지금까지 배웠던 픽셀 출력 방법은 이런 게 불가능하다. 이를 가능하게 하려면 '혼합(blending)'을 이용해야 한다. 혼합 기법은 현재 래스터화하는 픽셀을 후면 버퍼에 이미 래스터화되어 있는 픽셀과 섞는 방법이다.

현재 래스터화 중인 ij번째 픽셀, 즉 원본(source) 픽셀에 대해 픽셀 셰이더가 출력한 색상이 Csrc라고 한다. 그리고 현재 후면 버퍼에 있는 ij번째 픽셀, 즉 대상(destination) 픽셀의 색상을 Cdst라 한다. 혼합을 사용하지 않으면 Csrc가 Cdst를 덮어쓴다. 그러나 혼합을 사용하면 둘을 일정 공식에 따라서 혼합해서 얻은 새로운 색상 C가 출력된다. 다음이 Direct3D가 쓰는 혼합 공식이다.

C = Csrc☒Fsrc⊕Cdst☒Fdst

처음 보는 사람 입장에서는 매우 난처하다. 하나씩 알아보자.


23.1.8에 깨달은 사실. 난 저 현재 후면 버퍼에 있는 픽셀, 대상 픽셀을 원본 픽셀과 똑같이 생각했다. 무슨 말이냐면, 예를 들어 달리고 있는 게임 캐릭터를 출력한다고 하자. 달리는 모션을 내기 위해서, 후면 버퍼에는 이제 출력할 원본 픽셀의 그 전 모션이 기록돼있을 거라고 생각했다. 이는 큰 착각이었다. 그럼 어떤 픽셀이 후면 버퍼에 존재하는가? → 후면 버퍼에 그리기 전에 항상 ID3D11DeviceContext::ClearRenderTargetView() 메서드로 후면 버퍼를 일정한 색깔로 지우는 작업을 했었던 것이다. 그러니 후면 버퍼에 있는 픽셀과 혼합한다는 것은, 위의 메서드로 지운 색깔과 혼합하는 것을 말하는 것이었다. 혹은 아직 배우지는 않았지만, '이미 그려놓은 픽셀'과 어떻게 혼합할 것인가를 생각할 때도 올 것 같다. 왜? 그래야 물이나 유리 뒤의 물체들을 반투명하게 그릴 수 있을테니 말이다.
혼합 예시


우선 새로 나온 Fsrc, Fdst는 뭔가? 이는 각각 원본 혼합 계수(blend factor)와 대상 혼합 계수로, 다음 벡터들 중 하나이다.
(html적용이 안돼서 그냥 적음.)

enum D3D11_BLEND
{
D3D11_BLEND_ZERO = 1, //F = (0,0,0).
D3D11_BLEND_ONE = 2, //F = (1,1,1).
D3D11_BLEND_SRC_COLOR = 3, //F=(rs,gs,bs).
D3D11_BLEND_INV_SRC_COLOR = 4, //F=(1 - rs,1 - gs,1 - bs).
D3D11_BLEND_SRC_ALPHA = 5, //F=(as,as,as).
D3D11_BLEND_INV_SRC_ALPHA = 6, //F=(1 - as,1 - as,1 - as).
D3D11_BLEND_DEST_ALPHA = 7, //F=(ad,ad,ad).
D3D11_BLEND_INV_DEST_ALPHA = 8, //F=(1 - ad,1 - ad,1 - ad).
D3D11_BLEND_DEST_COLOR = 9, //F=(rd,gd,bd).
D3D11_BLEND_INV_DEST_COLOR = 10, //F=(1 - rd,1 - gd,1 - bd).
D3D11_BLEND_SRC_ALPHA_SAT = 11, //F=(a's,a's,a's). a's = clamp(as,0.1).
D3D11_BLEND_BLEND_FACTOR = 14, //F = (r,g,b). 여기서 (r,g,b)는 ID3D11DeviceContext::OMSetBlendState 메서드의 제2 매개변수로 주어진 값.
D3D11_BLEND_INV_BLEND_FACTOR = 15, //F = (1 - r,1 - g,1 - b). 여기서 (r,g,b)는 ID3D11DeviceContext::OMSetBlendState 메서드의 제2 매개변수로 주어진 값.
} D3D11_BLEND;

다음으로 ☒는 벡터의 성분별 곱을 말한다. 예를 들어 다음과 같다.

(1,2,3)(4,5,6) = (1*4, 2*5, 3*6)

다음으로 ⊕는 다음 연산자 중 하나이다.

enum D3D11_BLEND_OP
{
D3D11_BLEND_OP_ADD = 1, //C = Csrc☒Fsrc + Cdst☒Fdst.
D3D11_BLEND_OP_SUBTRACT = 2, //C = Cdst☒Fdst - Csrc☒Fsrc.
D3D11_BLEND_OP_REV_SUBTRACT = 3, //C = Csrc☒Fsrc - Cdst☒Fdst.
D3D11_BLEND_OP_MIN = 4, //C = min(Csrc, Cdst).
D3D11_BLEND_OP_MAX = 5 //C = max(Csrc, Cdst).
} D3D11_BLEND_OP;

OP는 operator의 줄임말일 것이다.

위의 혼합 공식은 색상의 RGB 성분들에만 적용된다. 알파 성분에는 비슷하지만 구별되는 공식이 적용된다.

A = AsrcFsrc⊕AdstFdst

혼합 색상과 분리한 이유는 그 둘을 다른 방식으로 처리하기 위함이다.

profile
Question, Think, Select

0개의 댓글