베개발

01. 색상 표현 기본원리, 색 연산 기초 본문

대학교 공부

01. 색상 표현 기본원리, 색 연산 기초

rusal0204 2021. 3. 15. 06:43

안녕하세요. 셰이더 스터디를 하게되어 관련 내용을 정리해보았습니다.

 

이번 글에서는 셰이더를 공부하기에 앞서, 색상 표현의 기본원리와 색 연산 기초에 대해 공부해보겠습니다.

 

[목차]

1. 모니터의 색상표현

1-1. bit

1-2. 픽셀 당 1bit 이상 사용하기

1-3. 디더링

1-4. 인덱스 컬러

1-5. 팔레트 애니메이션

1-6. 16비트, 그리고 RGB의 등장

1-7. 24비트, 32비트...

1-8. 게임 텍스쳐 포맷 (DDS)

1-9. 모바일 게임 텍스쳐 포맷 (ETC, ETC2, ASTC 계열)

 

2. 색의 연산

2-1. float

2-2. float 연산

2-3. 유니티 셰이더그래프

 

 

 

1. 모니터의 색상표현

1-1. bit

 

혹시 이런 걸 보신 적이 있으신가요?

 

위 사진의 주인공은 '천공테이프' 입니다.

저 테이프를 컴퓨터에 인식시켜서 데이터를 읽는 방식입니다.

해당 테이프의 '뚫린 부분'과, '뚫리지 않은 부분'을 컴퓨터가 읽어내는 식으로 작동합니다.

프로그래밍 초창기 때에 쓰였던 것이라고 하네요.

 

요즘에도 천공테이프와 비슷한 방식을 이용하곤 합니다.

쉬운 예시로는 OMR카드가 있습니다.

 

(오회말이 아닙니다. OMR입니다.)

 

OMR카드도 위에 보여드렸던 천공테이프와 비슷하게, '표시된 부분'과 '표시되지 않은 부분' 을 컴퓨터가 인식해서 읽어내는 식으로 작동합니다.

 

컴퓨터는 이런 두 가지 상태를 기반으로 작동하게 됩니다.

바로 '0'과 '1' 말이죠.

 

 

모니터도 이와 같은 원리입니다.

여기 우리를 위한 가상의 3*3픽셀 모니터가 있습니다.

이 모니터에는 총 9개의 픽셀이 존재합니다.

 

이제 여기에 '0'은 검정색인 상태, '1'은 흰색으로 불이 켜진 상태라고 정의를 하면,

(*반대로 0이 흰색, 1이 검정색이라고 정의해둘 수도 있습니다. 0과 1은 상태를 나타낼 숫자일 뿐이고 상태에 따라 색이 어떻게 나올지는 만드는 사람 마음이기 때문입니다.)

 

위 이미지는 픽셀이 전부 검정색이니,

0,0,0

0,0,0

0,0,0

인 상태라고 말 할 수 있습니다.

 

좀 더 예시를 들어보자면 아래 이미지와 같이 됩니다.

 

 

이런 식으로 모니터의 각 픽셀에 상태값을 줄 수 있게 되었습니다.

저 작은 픽셀들이 점점 더 많이 모여서, 현대의 모니터가 된 것입니다.

 

초기의 모니터도 이런 방식을 사용했습니다.

 

 

IBM PC/XT

 

 

사진의 모니터를 보면 픽셀당 검정색/초록색 이렇게 두가지 상태만 나타나있는 것을 볼 수 있습니다.

 

위와 같이 기본적으로 0 혹은 1의 상태를 지정할 수 있는 하나의 무언가를 '비트' 라고 부르고,

픽셀 하나당 하나의 비트만 사용하는 색상 표현을 우리는 픽셀 당 1bit 를 사용한다고 표현합니다.

 

 

1-2. 픽셀 당 1bit 이상 사용하기

 

지금까지는 하나의 비트만 사용해서 색을 표현했지만,

만약 한 픽셀을 표현하는 데 두 개 이상의 비트를 사용할 수 있다면..!

좀 더 넓은 범위의 색을 표현해낼 수 있지 않을까요?

 

그렇게 나온 것이 픽셀 당 2비트 색상 표현입니다.

 

아까의 1비트 색상표현이 (0),(1) 이렇게 두 가지 경우의 수를 만들어낼 수 있었다면,

2비트 색상표현은 두 개의 비트를 사용해서 (0,0),(1,0),(0,1),(1,1) 이렇게 네 가지 경우의 수가 나옵니다.

 

(*경우의 수를 쉽게 계산식으로 만든다면, n비트 색상표현은 2의 n제곱가지를 사용할 수 있습니다. 4비트 색상표현은 2의 4제곱 즉 16가지를 사용할 수 있습니다. )

 

아래는 바로 2비트 표현을 사용한 예시입니다.

게임보이 화면

게임보이에서 플레이 가능했던 '포켓몬스터 청'

 

 

두번째 이미지를 보시면,

흰색 / 회색 / 짙은회색 / 검정색

이렇게 총 4가지 색깔이 사용된 것을 확인할 수 있습니다.

 

 

1-3. 디더링

 

이때 당시에는 보시는것처럼 표현할 수 있는 색이 적었기 때문에,

디더링(혹은 병치 혼합) 이라는 기법을 이용해서 좀 더 많은 색을 사용하는 것처럼 표현하곤 했습니다.

위 사진에서 화분들 밑부분 표현이 바로 그 예시입니다.

 

이 부분..!

 

옆의 다른 바닥 타일보다 좀 더 촘촘하게 표현이 되어있는 걸 보실 수 있는데요.

위에서 사용했던 색들 중, 흰색과 회색을 촘촘하게 배치해서 '밝은 회색' 처럼 보이게 하는 방법입니다.

 

흑백보다 훨씬 잘 보이는 컬러 예시를 가져와봤습니다.

예시로 가져온 게임은 '프린세스메이커' 이며,

굉장히 많은 색을 쓴 것 같이 화려해 보이지만 픽셀 당 오직 4비트만 사용합니다.

즉, 총 16색만을 사용했다는 것이 됩니다.

(이 색들을 인덱스 컬러라고 하는데, 이에 대해서는 뒤에서 자세하게 다루겠습니다.)

프린세스메이커

 

 

이를 확대해보면 이렇게 색들이 점처럼 찍혀, 다른 색으로 보이는 것처럼 표현되고 있다는 것을 알 수 있습니다.

 

이런 디더링 방법을 사용하면 16가지라는 적은 색으로도 이렇게 다채로운 표현을 할 수 있게 되는 것입니다.

전통 미술 기법인 점묘법과 굉장히 유사한 방식이죠.

 

조르주 쇠라 - 그랑드자트섬의 오후

*점묘법 예시로 굉장히 유명한 작품입니다.

그림의 일부분을 확대해보면 이런식으로 점들이 모여

그림을 완성시키고 있는 것을 볼 수 있습니다.

 

 

 

1-4. 인덱스 컬러

 

프린세스메이커 스크린샷을 다시 잘 보면, 분홍색 옷에 들어간 명암의 색이 머리카락의 색과 같은 것을 볼 수 있습니다. 디더링 등의 기법을 잘 활용하는 것도 중요하지만, 그 것들을 이루고 있는 '색'을 계획적으로 써야 그림이 예쁘게 나올 수 있다는 말과도 같죠.

 

처음에 3*3짜리 픽셀들을 예로 들 때, '0은 '검정색', 1은 '흰색'으로 정의해놓고 들어가보자.' 라고 언급했었습니다.

 

만약, 4가지 색을 이용할 수 있게 되고, 그 4가지 상태들에 각각

빨간색/마젠타/파란색/시안을 정의하게 된다면 어떻게 보일까요?

 

바로 이렇게 됩니다.

이미지 출처: 위키피디아 (https://en.wikipedia.org/wiki/Indexed_color)

 

16가지 색만을 사용한 위의 프린세스메이커에서도, 이와 같이 첫번째 색부터 16번째 색까지 각각 무슨 색을 출력할지 미리 정해놓고 가게 됩니다.

 

이렇듯 16색을 구성하는 컬러들은 '미리 지정된 상태'로 모니터에 출력되게 되는데,

이때 이런 '색을 미리 지정하는 기법' 을 '팔레트 기법', 혹은 '인덱스 컬러(indexed color) 기법' 이라고 부릅니다.

 

 

그렇다면, 아까 보여드린 프린세스메이커 그림의 인덱스 컬러들을 포토샵에서 간단히 확인해볼까요. 위 그림은 포토샵으로 불러오면 바로 인덱스 컬러 모드로 불러와집니다.

포토샵의 이미지 탭 > 모드에 들어가서, 맨 밑의 컬러 테이블을 체크하시면 그림에 쓰인 16가지 색을 바로 확인할 수 있습니다.

 

 

 

이렇게 16가지 색들이 쓰였네요.

 

 

 

저 컬러 테이블에서 각각의 컬러들을 변경하면, 그림에도 바로 적용이 되는 것을 확인할 수 있습니다. 예시에서는 캐릭터의 머리색에 가까워 보이는 색을 변경하자, 다른 외곽선이나 명암부분도 전부 색이 바뀌는 것을 볼 수 있습니다. 같은 인덱스 컬러를 사용한 부분이기 때문입니다.

 

이 기법은 8비트 컬러, 즉 256가지 (2의 8제곱)컬러들을 사용할 때까지도 계속 쓰이게 됩니다.

 

 

+ 포토샵에서 사진을 인덱스 컬러 모드로 변경할 수도 있습니다. 여기서는 점묘화를 다시 디더링 시켜보도록 하겠습니다. (?)

 

원래 RGB 모드였던 것을 인덱스 컬러 모드로 변경하려고 하면 이런 창이 뜨는데,

컬러 부분을 16으로 바꿔주시면 총 16개의 인덱스 컬러가 사용된 이미지로 변경됩니다.

 

 

점묘화가 좀더 티 나는 점묘화가 되었습니다.

원본 그림의 일부를 확대한 뒤, 인덱스 컬러 모드로 변경한 것과 비교해 본 이미지입니다.

 

 

정리차 간단하게 위키피디아에 있던 좋은 예시 이미지를 가져와봤습니다.

 

앵무새를 각각 2비트/4비트/8비트로 나타낸 이미지, 원본 이미지,

그리고 잘못된 컬러팔레트를 적용했을 때의 이미지

 

 

1-5. 팔레트 애니메이션

 

인덱스 컬러 기법을 사용할 때 많이 사용되었던 애니메이팅 기법입니다. 팔레트에 할당되어 있는 색을 바꿔줌으로써, 움직이는 물체들을 다시 그릴 필요 없이 물체가 움직이는 것처럼 표현하는 방식입니다.

(출처: http://www.effectgames.com/effect/article-Old_School_Color_Cycling_with_HTML5.html)

 

예시에서는 물 부분이 팔레트 애니메이션을 사용했습니다. 오른쪽의 팔레트를 보시면 물에 사용한 색들이 빠르게 바뀌고 있는 것을 보실 수 있습니다.

 

 

 

이것 역시 팔레트 애니메이션을 이용하여 금속의 반짝임을 표현했습니다.

애니메이션이 진행됨에 따라서 각 구간별로 색이 달라지는 것을 쉽게 확인할 수 있습니다.

 

https://www.youtube.com/watch?v=LUbrzg21X9c

위 gif 파일의 출처는 해당 영상이며, 팔레트 애니메이션에 대해 자세하게 나와있으므로 궁금하신 분은 시청하시면 도움이 많이 될 것이라 생각합니다.

 

 

1-6. 16비트, 그리고 RGB의 등장

 

이전까지는 픽셀 당 8비트를 사용해서 256가지의 색밖에 사용하지 못했는데,

이제 픽셀 당 16비트를 사용하는 것이 가능해져서, 총 65536가지의 색을 사용할 수 있게 되었습니다.

 

여기서부터는 팔레트 방식을 사용하지 않고, RGB방식을 사용하게 됩니다.

 

모니터를 확대한 사진

(출처: https://javalab.org/lcd_display/ )

 

인간이 색을 인식할때는 세 종류의 원추세포가 색을 감지하여 인식하게 되는데, 이 원추세포는 각각 빨간색, 초록색, 파란색을 강하게 인식한다고 합니다. 그 외의 색은 세포 여러개가 동시에 반응해 뇌에 신호를 보내면, 뇌가 그 색을 가산 혼합을 하는 식으로 합성해서 받아들이게 되는 방식입니다.

 

이러한 원리를 사용해서 만든 것이 바로 현재까지 쓰이고 있는 RGB 방식의 색 표현입니다.

이에 따라 더는 인덱스 컬러 방식으로 색을 지정해두지 않고, R,G,B 각각의 세기를 조절해서 색을 합성해내는 방식으로 표현하기 시작합니다.

 

간단하게 예시를 보고 가겠습니다.

포토샵에서 R,G,B가 각각 어느 세기로 나오고 있는지를 쉽게 확인해볼 수 있습니다.

 

(출처: https://en.wikipedia.org/wiki/RGB_color_model)

 

여기 R,G,B 각각이 강하게 돋보이는 이미지가 있습니다. 가산혼합 과정도 잘 보이네요.

 

포토샵에서는 채널 탭에서 R채널, G채널, B채널을 각각 볼 수 있습니다.

 

 

 

보기 쉽게 정리하면 이렇게 됩니다.

 

 

 

포토샵의 r,g,b 채널 각각은, 각 채널에 해당하는 색상이 어느정도 세기로 출력되고 있는지를

검정색부터 흰색에 대응해서 시각적으로 나타내주는 것이었습니다.

 

예시에서도 R채널을 보시면 빨간색 빛이 가운데에서 가장 세고 화면 가장자리로 갈수록 점점 약해지는데 그러한 부분이 R채널에서 잘 확인됩니다. G(초록색),B(파란색) 색상의 빛은 R채널에서는 아예 보이지 않습니다. G와 B는 R을 하나도 포함하고 있지 않는 색상이기 때문입니다.

 

다른 채널들에서도 마찬가지로, G 혹은 B 각각이 어느정도 세기로 출력되고 있는지를 검정색부터 흰색까지의 그라데이션에 대응해서 시각적으로 보여주고 있습니다.

 

여기서 알아두셔야 할 것이 있습니다. 임의의 채널의 빛의 세기를 숫자로 표현했을 때, 아예 꺼져있는 것은 0 으로 표현되며 가장 강하게 출력되고 있는 것은 1로 표현됩니다. 그리고 그 사이의 희미한 세기들은 0부터 1 사이의 숫자들로 표현됩니다.

 

일종의 약속과 같습니다.

 

예를 들어, 빨간색과 초록색이 최대로 강하게 출력되고, 파란색은 출력되지 않는다면

r은 1, g는 1, b는 0 으로 표현할 수 있습니다.

글 후반에 중요하게 쓰일 개념이니 숙지해두시면 좋습니다.

 

 

이렇게 한 픽셀 당 부여되는 비트 수가 늘어남에 따라서 색상 표현도 더욱 디테일해졌습니다.

기존의 방식이 '하나의 상태 당 하나의 컬러를 미리 지정해서 내보내는 방식' 이라면, 이 rgb 방식은 'r,g,b 각각의 출력 세기를 조절해서 컬러를 조합해내는 방식' 이라고 할 수 있겠습니다.

 

단, 하나의 픽셀에 할당되는 비트 수는 16비트입니다.

위에서 말했듯 R,G,B 각각의 세기를 조절해야 하니, 이 16비트를 세 개로 나눠서 각각의 색에 할당시켜줍니다.

 

주로 R에 5비트, G에 6비트, B에 5비트를 할당하는 방식으로 사용합니다.

그렇다면 R과 B는 32단계, G는 64단계로 나눠서 세기를 조절할 수 있을 것이며,

R,G,B 각각의 경우의 수를 모두 곱한다면 총 65536가지 색의 표현이 가능하게 됩니다.

여기서 G채널에 1비트가 더 할당된 이유는, 초록색을 감지하는 신경이 다른 신경들보다 훨씬 민감하기 때문이라고 합니다.

 

이렇게 세 채널에 각각 5,6,5비트씩 할당되었기 때문에 이걸 565컬러라고 부르기도 합니다.

 

 

1-7. 24비트, 32비트...

 

 

그러나, 픽셀 당 16비트를 사용해도 사람 눈에는 아직 한참 미치지 못했기 때문에,

그래픽의 발전은 계속되어 픽셀 당 24비트, 32비트까지 사용할 수 있게 되었습니다.

 

픽셀 당 24비트는 총 2의 24승, 즉 16,777,216가지 색을 표현할 수 있으며, '트루 컬러(true color)' 라고도 불립니다. 앞의 픽셀 당 16비트에서는 R에 5비트, G에 6비트, B에 5비트를 할당해줬다면, 픽셀 당 24비트에서는 주로 R,G,B 전부 동일하게 8비트씩 할당해줍니다.

 

R,G,B 를 각각 256가지의 세기로 조절할 수 있게 된 것이죠.

565컬러와 비슷하게 888컬러라고도 불립니다.

 

흔히 포토샵에서 봐왔던 R 255, G 255, B 255가 바로 여기서 나온 것입니다.

채널당 8비트, 즉 표현할 수 있는 세기가 256단계이니 0부터 255까지 표현되고 있다는 의미입니다.

바로 포토샵에 들어가 확인해보면,

 

모드에서 RGB컬러 / 채널당 8비트 모드를 선택할 수 있고,

 

컬러 피커에서 흰색을 찍어보면 R, G, B가 각각 255로 설정되어 있는 것을 볼 수 있습니다.

(흰색은 RGB전부가 최대치로 출력되고 있는 색이기 때문입니다.)

 

 

 

 

32비트는 2의 32승, 즉 4,294,967,296가지 색을 표현할 수 있으며 이때는 알파채널이 추가되어 R,G,B,A(알파) 모두 동일하게 8비트씩 할당해주는 식으로 활용됩니다.

(https://www.quora.com/Is-a-16-bit-or-32-bit-color-better)

 

이렇게 비트수가 많은 형식의 파일들은 고급 정보가 필요한 파일에 주로 쓰입니다.

그 대표적인 예가 TIFF파일입니다.

 

(https://www.instructables.com/Converting-Map-Height-Data-Into-3D-Tiles/)

 

이 이미지는 게임 엔진에서 쓰이는 하이트맵(HeightMap)입니다. 이런 이미지의 경우 이미지에 담긴 정보가 정확해야 하므로, 파일 당 많은 비트수를 사용합니다.

이 외에도 Displacement Map(하이트맵과 비슷함)이나 라이트맵 등 고급 정보가 필요한 곳에 주로 사용됩니다. 비슷한 것으로는 HDR 이미지 등이 있습니다.

 

HDR이미지는 더 넓은 색상 범위를 표현하기 위한 파일 포맷이며 이를 위한 HDR 모니터도 있습니다.

 

 

1-8. 게임 텍스쳐 포맷 (DDS)

 

유니티에 png, jpg 등의 파일을 가져가면 자동으로 DDS라는 압축 포맷으로 변환됩니다. 이 포맷은 DX9를 사용하는 PC게임 대부분에서 사용할 수 있습니다.

DDS의 종류에는 대표적으로 DX1, DX2, DX3, DX4, DX5가 있으며 그 외의 다른 세부 포맷들도 존재합니다.

 

 

이 픽셀 포맷들은 888컬러 모드나 그 이상의 정보량이 높은 이미지들을 압축시켜서 게임이 좀더 원활하게 실행될 수 있도록 만들어줍니다.

텍스쳐를 제작할 때 256,512 등의 사이즈로 제작해야 한다는 것은, 텍스쳐가 DDS 포맷으로 압축이 될 때 2의n승의 픽셀씩 묶어서 처리되기 때문이었습니다. 4*4 블럭으로 묶어서 처리하는데, 그렇기 때문에 아티팩트가 많이 발생하기도 합니다.

대신 용량은 많이 줄어들게 됩니다. RGBA 32bit를 기준으로 했을 때, 아래에서 설명드릴 DXT1 RGB 포맷으로 압축하게 된다면 기존 용량 대비 8분의 1로 가벼워집니다.

 

자주 쓰이는 세부 포맷들 각각의 특징에 대해서 간략하게 정리해보자면 다음과 같습니다.

 

DXT1 RGB(No Alpha)

-이미지를 R5G6B5컬러로 압축합니다.

-즉, 만약 텍스쳐를 제작할 때 888컬러로 제작을 해도 DXT1 RGB 포맷으로 변환한다면 565컬러로 인게임에 적용되는 것입니다.

-이름에서 볼 수 있다시피 알파채널은 존재하지 않습니다.

-적은 정보량으로 알파를 활용하고 싶다면 DXT1 ARGB라는 포맷을 사용할 수 있으며 이때 알파채널은 1비트로 할당됩니다. 알파 테스트를 할 때 주로 사용된다고 합니다.

-Direct X 10 이상의 BC1과 같습니다.

 

DX5 ARGB (Interpolated)

- R5G6B5 칼라로 압축되는 것은 같으나, 알파채널이 8비트입니다.

- 때문에 TGA파일에서 알파채널이 열화되지 않습니다. (PNG의 경우 감마 이슈가 있다고 합니다.)

-Direct X 10 이상의 BC3과 같습니다.

 

유니티에서 직접 확인할 수도 있으며, 포맷을 변경할 수도 있습니다.

유니티 안에 기본으로 들어있는 텍스쳐를 확인해보았습니다.

 

DXT5로 설정되어 있네요.

 

상황에 따라 맞는 포맷을 활용해야 합니다. 예를 들어 UI같은 경우, 이미지가 압축되며 열화된것이 눈에 띄기 쉽기때문에 최대한 압축이 되지 않는 포맷을 사용해야 합니다.

 

만약 UI를 R8G8B8A8 TGA 파일로 만들었고, 전혀 압축되지 않은 형태로 인게임에 사용하고 싶다면 위 이미지에서 어떤 포맷을 사용해야 할까요?

답은 RGBA 32bit 포맷입니다. 원본과 같은 형태이기 때문입니다.

 

반대로 알파 채널도 없고, 열화되어도 잘 눈에 띄지 않는 텍스쳐의 경우에는 DXT1 RGB 등의 높은 압축률을 가진 포맷을 선택하는 게 좋겠죠.

 

Direct X 10 이상에서는 Block Compression 포맷, 줄여서 BC 포맷을 사용합니다. PC에서만 주로 쓰이는 고급 포맷입니다.

BC1부터 BC5까지는 Direct X 10에서 사용되었으며(BC1~BC3까지는 기존 DXT와 같다고 보시면 됩니다.),

BC6H과 BC7은 Direct X 11부터 사용됩니다.

 

 

1-8. 모바일 게임 텍스쳐 포맷 (ETC, ETC2, ASTC 계열)

 

위에서 설명해드렸던 DDS 파일 포맷은 DirectX에서만 이용이 가능하기 때문에 모바일에서는 다른 포맷을 사용합니다.

 

다만 모바일 기기에서 그래픽을 처리할 때 사용되는 칩셋들이 다르기 때문에 사용해야 하는 포맷들도 다릅니다. 대표적으로 ETC, ETC2, ASTC 계열이 있습니다.

 

칩셋의 종류가 다름에 따라 포맷을 변경해야 하는 문제는 유니티 내부에서 자동으로 변경해주기도 하나, 위에서 DDS 포맷을 직접 설정했던 것 처럼 직접 포맷을 변경할 수도 있습니다.

 

 

 

 

2. 색의 연산

 

2-1. float

 

우선 float란, 프로그래밍에서 계산할 때 사용되는 단위 중 하나이며, 소수점이 있는 숫자의 형태라고 생각하시면 쉽습니다. (소수점 아래 6자리까지 유효하며, 그 이상은 오차가 생깁니다.)

예를들어 3.4를 float로 표현한다고 하면 float1(3.4)와 같이 표현할 수 있습니다? (있나요?)

 

RGB 각각의 채널은 각각 n비트가 할당되어 있고, 그 비트를 이용해서 세기를 정한 뒤 RGB가 한번에 출력되며 가산 혼합되는 과정을 거쳐 색을 나타내게 된다고 앞에서 설명드렸습니다.

 

float를 이용해서 그 RGB 채널 각각의 값을 정해줄 수 있습니다.

 

RGB채널만 있을땐 float3이라는, float 3개를 한 번에 묶은 형태로 표현해줄 수 있고,

알파채널까지 포함될때는 float4라는, float 4개를 한 번에 묶은 형태로 표현해줄 수 있습니다.

 

 

이러한 표현을 유니티 내에서 셰이더를 만들 때 그대로 활용하게 됩니다.

 

2-2. float 연산

 

float를 연산할 때는 같은 자리에 있는 수끼리만 연산합니다.

즉, 첫 번째 자리에 있는 숫자들은 첫 번째 자리 숫자들끼리만, 두 번째 자리에 있는 숫자들은 두 번째 자리 숫자들끼리만 연산한다는 이야기입니다.

예시를 한번 볼까요.

 

 

 

여기 빨간색 - float3(1,0,0), 파란색 - float3(0,0,1) 이 있습니다.

이 두 숫자를 '더한다' 라고 한다면,

위에서 언급했다시피 같은 자리에 있는 수 끼리만 연산이 됩니다.

위 두 색상을 예로 들자면,

 

이렇게 각 채널끼리 연산되어서, float3(1,0,1) 이라는 결과값이 나옵니다.

 

float3(1,0,1)은 아까 위에 있던 이미지를 보면, 마젠타 색입니다.

 

결과적으로 빨간색 - float3(1,0,0)과 파란색 - float3(0,0,1) 을 더하면 마젠타 - float3(1,0,1) 가 된다는 것입니다.

 

포토샵에서 흔히 쓰던 add 등의 레이어 모드도 이런 계산식을 사용하고 있습니다.

 

위에서 계산해봤던 그대로, 빨간색 위에 파란색 레이어를 Add 모드로 변경하여 올린 결과입니다.

컬러 피커로 선택해보면 정확히 마젠타색이라고 뜨는 것을 확인할 수 있습니다. (R:255, G:0, B:255)

 

만약, multiply 모드를 적용하게 된다면?

float3(1*0,0*0,0*1) = float3(0,0,0), 즉 검정색이 될 것이라는 사실을 유추해 볼 수 있습니다.

 

 

 

물론 실제로도 곱하기 모드를 적용했을 때 검정색이 되는 것을 확인할 수 있습니다.

 

http://www.deepskycolors.com/archive/2010/04/21/formulas-for-Photoshop-blending-modes.html

포토샵의 계산식이 잘 정리되어 있는 사이트입니다. 참고해보셔도 좋을 것 같습니다.

 

 

 

2-3. 유니티 셰이더그래프

 

이제부터는 유니티 셰이더그래프에서 직접 계산 실습을 해보겠습니다.

 

먼저 우리가 작업할 기본 셰이더를 꺼내와야 하므로, 프로젝트 파일 탭에서 마우스를 우클릭한 뒤 Create > Shader > Unlit Graph 를 선택해 새 셰이더를 생성해줍니다.

(여기서 Unlit 은 빛의 영향을 받지 않는 것을 뜻하는데, 지금은 간단하게 색을 연산하는 것만 진행해 볼 예정이므로 Unlit 셰이더를 만들어주는 것입니다.)

 

float3 은 유니티 셰이더 내에서 vector3이라는 형태로 표현할 수 있습니다.

 

셰이더그래프 내에서 우클릭을 한 뒤, Create Node를 클릭하고 바로 숫자 3을 입력해주면 Vector3 노드를 바로 꺼내올 수 있습니다.

이 Vector3 노드의 X,Y,Z에 각각 R,G,B값을 넣어 보겠습니다.

임의로 노란색 - float3(1,1,0) 을 입력해봅시다. X와 Y에 1, Z에 0을 입력하면 됩니다.

그런 뒤 아래 그림같이 Unlit Master의 Color(3)으로 연결해주면,

 

float3(1,1,0) 과 같은 상태로, 노란색이 정상적으로 출력됩니다.

 

 

[Add 노드]

 

연산 노드도 추가할 수 있습니다. 아까 Vector3 노드를 만들었던것처럼, 우클릭을 한 뒤 Add를 입력해봅시다. Add 노드를 바로 추가할 수 있습니다.

 

그림처럼 연결해줍시다.

 

지금 이 상태를 식으로 표현하면 (1,1,0) + (0,0,0) 이 됩니다. 즉 아무것도 더하지 않은 (=검정색을 더한) 것과 같습니다. 결과적으로 그냥 노란색이 나왔습니다.

 

이제 여기에 파란색을 0.5만큼 더해줍시다. 벡터3 노드를 하나 더 추가해주고, (0,0,0.5)를 입력해준 뒤 Add 노드에 연결해주면 되겠죠.

 

 

0.5만큼의 파란색이 더해져 결과적으로 연노랑색이 나왔습니다.

포토샵에서 해봐도 결과는 같습니다.

 

 

아까 위에서 진행했던 빨간색+파란색의 과정을 직접 구현해보도록 하겠습니다.

 

(오류난 것처럼 보이지만) 정상적인 결과로 잘 나왔습니다.

 

 

[Multiply 노드]

 

곱하기도 같습니다. 곱하기의 경우 노드 이름은 multiply입니다.

포토샵에서 진행했을때와 같은 결과가 나오는 것을 볼 수 있습니다.

 

float3(0.2,0.2,0.2) 값을 가진 회색끼리 곱하면, float3(0.04,0.04,0.04) 가 되므로 더 어두운 회색이 됩니다.

 

 

[Split, Combine 노드]

 

Split과 Combine 노드는 하나의 Vector3 안에 들어있는 X,Y,Z 각각을 따로 분리해서 (Split), 합칠(Combine) 수 있는 기능의 노드입니다.

 

간단한 예시입니다.

 

그냥 '숫자 한개를 가져온다' 라고 생각하시면 편합니다.

 

 

+[반전 노드]

 

반전 기능 또한 간단하게 구현할 수 있습니다.

1-(타겟 컬러)가 바로 색을 반전시키는 수식입니다.

셰이더그래프에는 One Minus라는 노드로 이미 구현이 되어있기 때문에, 해당 노드를 꺼내와서 사용하면 됩니다.

 

빨간색(1,0,0) 을 반전한다면 이렇게 (0,1,1)이 됩니다.

포토샵에서 빨간색을 반전시켜도 같은 결과가 나옵니다.

 

 

이 외에도 많은 노드들이 존재하며, 앞으로 실습을 통해 하나씩 알아가보도록 하겠습니다.

 

 

1주차 스터디 내용은 여기서 마무리하겠습니다. 감사합니다!