Frei0r
Frei0r은 Natron이나 kdenlive같은 비디오 에디터에서 사용되는 composition,transition, merge 툴이다.
adobe의 트랙 매트 (track matte)효과를 kdenlive에서 어떻게 구현할지를 생각하다가 이것으로 구현할 수 있을 것 같아 찾다가, 너무 이름이 직관적이지 않아 쓸 때마다 헛갈릴 것 같아 정리를 해놓는다.
Mixer2
Mixer2는 8비트 unsigned int형의 자료를 사용하여 각 픽셀의 색상정보를 저장한다. Mixer3을 봐야 알겠지만, 더 큰 자료형을 사용하는 부분이 구현이 되어있지 않다면, frei0r은 사용하지 않는 것이 좋을 것이다.
코드 호출이 어떻게 되는지를 몰라서, 일단은 A를 윗 레이어, B를 아래 레이어로 생각하고 글을 쓴다. kdenlive에 넣어서 테스트 해보니, A가 아래 B가 위로였다. natron에서는 다를 수 있으므로 1번 2번으로 전부 다시 고쳤다.
더하기 효과는 간단하다. 윗 이미지와 아래 이미지의 rgb값을 더 한다. 최대 값은 255로 한다.
알파의 값은 두 알파의 최소 값으로 한다.
고로 항등 image에 해당하는 윗 이미지는 (0,0,0,255)로 이루어진 이미지이다.
2번 레이어의 알파는 min연산이다보니, 중간 값을 이용하기 보다는, 이진의 마스크 효과를 사용할 수 있고, 윗 레이어를 통해 닷지 효과처럼 사용한다.
그리고 중요한 점 중 하나는, 윗레이어(마스크)와 아래레이어(배경)의 교환 법칙이 성립한다는 것이다. 많은 효과들이 교환 법칙이 성립하지만, 아닌 것들도 많다. gimp의 이미지 합성 툴 가운데에도 그런 것이 있다.
그룹레이어를 사용하지 못하는 경우에 교환 법칙이 성립하는 것을 유용하게 사용할 수 있고, (서로는 순서가 상관 없지만 그 각각도 위아래가 따로 있으므로 )노드 방식의 이미지 에디터에서 연결순서가 바뀌어도 같은 경과가 나오기에 유용하다. 이제 아래부터는 그냥 교환법칙이 성립한다로 끝내도록 한다.
Addition_alpha는 대표적인 잘못이름지어진 콤포지션 효과이다.
이름만 들으면, 마스크의 알파 값이 더해질 것 같은 이름이지만 전혀 다른 효과를 가진다.
1번의 rgb에다가 pre-multiplied RGB(이하 pRGB) 값을 더하는 효과이며,
결과값은 완전 불투명이다.
마치 이미지 에디터에서의 더하기라고 생각하면 된다. 레이어를 투명하게도 하지만, 브러쉬 툴의 알파를 이용해서 여러번 덧칠한다거나 하는 느낌을 주지 않을까??
매우 복잡하다.
일단, 결과값의 알파는 2번의 알파와 같다.
결과의 알파가 0이라면, 리소스 낭비를 줄이기 위해 모든 결과값을 0으로 한다. 이후에도 알파값을 먼저 계산하면 다 그러해서 설명하지 않는다.
0이 아닐 때는, 다음과 같은 계산을 거친다.
w1 = alpha2
w2 = 255 - alpha1
rgb_dst = [(prgb1 * w1 ) + (prgb2*w2)]/ alpha_dst
rgb_dst = rgb1*alpha1 + rgb2* [(1-alpha1)]
직관적으로 이해하기 어렵다.
2번의 알파값이 그대로 작동하므로 알파마스크처럼 사용되며,
1번의 알파값에 따라, 1,2번의 색상의 rgb 사잇값을 사용한다.
결과값의 알파는 1,2번 알파의 곱이다.
결과값의 RGB는 1번의 RGB값을 결과값의 RGB값으로 하도록 되어 있다.
rgb_dst = (rgb1*alpha1/255) * alpha2 / alpha_dst
그렇다면 prgb_dst = rgb1*alpha1*alpha2가 될 것이다.
막상 약분이 된다고 하면,
rgb_dst = rgb1이다. 약간의 차이는 uint8 연산이다보니 여기저기서 계단 현상이 일어난다. 이것이 중요한 부분일지는 모르겠다.
어쨌든 대충 alpha_dst= alpha1*alpha2
rgb_dst ≃ rgb1
최신 깔끔한 구현에는 그냥 두번째 알파채널 또는, 레이어마스크 처럼 작동하지 않을까?
단순한 알파마스크로 색상은 아무변화를 주지 못하며, 흰색일수록 불투명하다.
- alphainjection (오래된 api라 1,2번이 다를 수 있음)
1번의 rgb값의 평균값을 결과값의 알파값으로, 2번의 rgb를 그대로 사용한다.
fill/key로 분리해서 전송하는것과 같다고 보면 된다.
물론 rgb의 평균값이 yuv채널의 y값과 다르기 때문에 생각한 것과는 다를 수 있다.
matte의 경우에는 루마 값을 알파값으로 사용한다. (kdenlive)
(matte는 frei0r이 아니다. mlt framework sse!! code)
alphainjection이 kdenlive에서는 없는 것처럼 보인다.
alphaout은 alphain과 거의 같으나, 알파 대신 (255-alpha) 값을 사용한다. 반대로 작동한다. 시작효과를 끝에다가 붙인다면, 시작과 끝이 맞아서 아름답지 않을까?
무언가 수식만 봐도 미친 것 처럼 보인다. 편의상 0-1의 실수형 색상이라고 할 때, 결과값 알파는 다음과 같다.
alpha_dst = alpha1*alpha1 + alpha2*alpha2*(1-alpha1)
alpha1과 alpha2의 제곱사이의 사잇값이다. 1번이 불투명할 때는, 약간의 변화를 2번의 알파가 주며, 알파2의 제곱이 알파1보다 작을 때는 오히려 더 투명하게 된다.
결과값 RGB는 다음과 같다.
rgb_dst= (rgb1 * alpha1 + pRGB2*(1-alpha1) )/ alpha_dst
이건 써봐야 알 것 같기는 한데, 같은 수식을 그대로 적용한다.
1번에 있는 투명한 부분이 매우 밝게 강조 된다. 나누기 연산이 있으면 일단, 뭔가 특별한 상황에서만 써야지 결과값이 맛이 많이 간다.
alpha간 xor연산을 할 것 같지만 아니다. 또는 구현을 내가 몰라서일 수도 있다. (뭐 근데 xor연산을 다른 방법으로 하는건 좀 이상하다. 미치지 않고서는)
결과값 alpha = alpha1*(1-alpha2)+ alpha2*(1-alpha1)
모두 투명하거나 불투명하다면, 불투명하게,
하나만 투명할 때 투명하게 결과가 나온다.
비트 단위의 xor이 아닌 불투명도라는 정도에 대한 xor이다.
색상은 다음과 같다.
rgb_dst= (pRGB1 * (1-alpha2) + pRGB2* (1-alpha1) )/ alpha_dst
pRGB에 대해 불투명한 레이어 쪽이 더 부각되도록 되어 있다.
교환 법칙이 성립한다.
댓글 없음:
댓글 쓰기