티스토리 툴바



0. 오늘부턴 이론 좀 배워봅시다.

5강동안 잘 따라오셨는지요? 어렵진 않으셨는지요?

... 쉬웠지요?
솔직해 말해봐. 쉬웠잖아....

괜찮아괜찮아 쫄지말고 솔직히 말해봐.. 응? 친한척해 친한척해 그동안 너무 쉽다고 댓글도 안달리고 관심도 적었던거 다 알고 있어 ...






5강까지는 일단 '휘리릭' 하고 큰 줄기를 훑어 보았습니다. 이론이고 뭐고 대충 대충 넘어갔지요.
기본적으로 '이 정도는 뭐 쉽네... ' 라고 생각하시면서 지나오셨다면 정상입니다.
굳이 따라해보지 않고 눈으로 봐도 그냥그냥 따라 올 수 있을만큼이었지요.



... 노린거니까요.



그래서 여태까지를 1부라고 생각하도록 해 보겠습니다.
한마디로 유저를 낚기위한 낚시였달까.

월척이구나




그럼 이제 맛을 들였으니까, 조금 레벨을 올려보도록 해 볼까요?
이제 다음으로 계획되고 있는건 다음과 같습니다. 대충 이렇게 생각하고 있긴 한데, 뭐 상황에 따라 변할 수도 있겠..

2부
일단 실무에서 바로 사용하기 좋게, 몇 가지 함수와 이론를 이용한 예제로 응용작품 만들기 튜터리얼을 해 보겠습니다. 이것으로 일단 급한대로 실무에서도 사용가능!

3부
5강에서 휘리릭 넘어갔던 라이팅 이론을 '처음부터 구현해 봅시다' 노말맵도 그냥 있는거 쓰는게 아니라, 원리를 깨닫고 사용하고 응용하는 것 까지 해 봅시다. 기본적으로 Diffuse 라이트와 Specular 정도는 그냥 dot이랑 pow 써가면서 짜버릴 수 있게 .. 그러면서 프로그래머들이 잘난체하듯 어렵게 써놓은 쉐이더 코드들을 아주 쉽게 풀어서 쉐이더 FX로 짜 볼까요. (이건 과연 할 수 있을 것인가...)



대충 이렇게 생각해 봤는데요. 오늘부터 2부라고 할 수 있겠지요. 예정된 것도 아닙니다. 그냥 하다보니 이 정도에서는 해야겠다는 생각이 들었어요. 글도 손가는대로 막 쓰는 겁니다. 이 무개념에 무계획 같으니라고...

자아, 그래서 오늘은 뭘 해 볼까요...
아무 생각없이 쓸 수 있는 기본 조작은 끝났으니까...

오늘부터는 이제 실제로 이론도 약간 필요한 기본 조작들을 해 보도록 하지요.
오늘 해볼 건 UV 조절입니다.





1. UV? UV가 뭐지?


UV는 천재뮤지션 유세윤과 뮤지 2인으로 이루어진 가수를 의미합니다.
개인적으로 이태원 프리덤이라는 노래를 가장 좋아하지요.

출처 : 네이버 인물정보


.... 내 이럴 줄 알았어라면서 피식 웃은거 알아요.
이것은 당신의 얼굴. 당신 비웃는다 나를.

이 자식이 상평통보 시절 개그를...






이런 뻔한 낚시에 낚이지 않으실 거라는거 다 알고 있었습니다.
네, 사실대로 말씀드리지요. UV는 사실 (Ultraviolet: 자외선) 을 의미하는 말이었지요. 다 아시잖아요?
우리 눈에는 보이지 않지만, 화학작용과 살균작용이 강하고 피부암 등을 발생시킬 수도 있는 전자파입니다.
썬크림 바르는 이유가 이 빛을 차단하기 위해서인거 다 알고 계시지요?






... 죄송합니다. 이것도 개드립입니다. 사실대로 말씀드리겠습니다.

컴퓨터 그래픽스에서 UV는 , 3D 모델에 2D 텍스쳐를 입힐 때 사용하는 좌표입니다.[각주:1]

http://en.wikipedia.org/wiki/UV_mapping



그리고 UV는 이렇게 0~1 사이의 float 값으로 표현됩니다. 그림이 아무리 넓어도 , 정사각형이 아니더라도 말이죠.
.... 0~1 사이의 flaot 값이라? 우리가 이전에 RGBA 칼라의 채널 얘기할 때 하던 말 아닙니까? 흐음...
여기서 눈치가 빠르신 분들은 뭔가 눈치를 채 주셔야 합니다 후후후.
일반적으로 이렇게 표현하는데요,

http://wiki.modsrepository.com/index.php/Call_of_Duty:_Font_System


3D max에서 이걸 보시려면 Unwrap UVW 모디파이어에서 Edit 버튼을 누르시면 이런 그림을 보실 수 있습니다 .
광활한 가운데 파랑색으로 좀 진한 박스가 하나 그려져 있지요.
이 박스가 바로 UV의 0~1 까지를 나타내는 영역이며, 이렇게 생각하시면 됩니다. [각주:2]





자, 예를 들어 이런 물체에 이런 텍스쳐가 입혀진다고 해 봅시다.



그럼 이렇게 입혀지도록 UV를 조절하셨겠죠.



맥스에서 보면, 이렇게 말이죠. 이렇게 만드시잖아요.
저기 있는 Edit UVWs 안에 그려진 '좀 굵은 사각형' 안에 텍스쳐를 채워 넣으라고 배웠잖아요. 이유는 모른채.
그랬잖아요. 그렇게 살아왔잖아요.
조금 아시는 분은 저 칸 넘어가도 동일한 그림이 나온다는걸 알고 그걸 이용하시기도 하고...


그래서 실제 복잡한 작업 하실 때에는 저 영역에서 가능한한 낭비없이 만드시려고 애쓰시곤 합니다. 이렇게도 배치해 보고 , 저렇게도 배치해 보고 말이죠. 여기까지가 그래픽 디자이너 분들의 생각.


그래서 그렇게 해서 UV를 맞추고 나면,

그 UV 위치값은 "vertex" 에 저장되게 됩니다.

vertex가 이런 정보를 가지고 있는 거지요

"나 1번 버텍스(vertex)는 [grass.dds] 텍스쳐 파일을 (0.0 , 0.0) 이라는 좌표로 가지고 있습니다"

이렇게 vertex에는, 다른 많은 정보와 함께 UV 정보도 float2로, 0.0~1.0 사이의 값으로 가지고 있게 되는 것입니다.[각주:3]
아래 그림에서처럼 말이지요.


이것이 UV 정보입니다. 텍스쳐가 입혀진 오브젝트라면 반드시 버텍스에 UV 좌표 정보가 들어가 있습니다.

그러므로, 정리해 보면 3D 오브젝트에 텍스쳐가 입혀지려면 두 가지 중요한 정보가 필요하다는 것을 알 수 있습니다.

바로

1. 어떤 텍스쳐를 입힐 것이냐
(Sampling 이라고 합니다.말그대로 텍스쳐에서 칼라값을 추출하는 기능이죠)


2. 어느 좌표에 입힐 것이냐
(UV 좌표. UV coordinate 라고 합니다. )


이 두 가지 정보 말입니다.








2. ShaderFX에서 제대로 된 방법으로 만들어 봅시다.

자... 그럼 shader FX 에서 , 위 그림과 똑같은걸 한 번 만들어 봤습니다.
이제 이건 뭐 눈감고도 하시겠지요 허허허. 아니, 진짜 눈감고는 하지 마세요.


그런데, 위 단원에서 분명 이렇게 말했습니다.
"텍스쳐가 오브젝트에 입혀지려면 반드시 텍스쳐 정보 (샘플러)와 UV 좌표가 있어야 한다"
라고 말이죠.




그런데 우리는 그런 정보 입력한 적 없거든요?

네가 나몰래 넣었냐?






뭔가 이상합니다. 뭐 우리 그래픽 디자이너들은 원래 탁하면 척하고 잘 알아서 붙는 프로그램에 익숙해져 있다 보니 이런 일이 생겨도 의문을 가지지 않던게 보통이었습니다.

그렇지만 이젠 그렇게 에이 몰라 하고 넘어가면 안되지유.
어쨌건 이건 뭔가 이상합니다. 아무것도 없는데 그림이 나오다니 !!! 텍스쳐는 넣었다 쳐도 '샘플러'라는 것은, 'UV'는 어디서 와서 어디로 간건가!!

그렇게 생각하고 다시 찬찬히 shaderFX를 보니 뭔가 이상한게 보입니다.


으응?

너무도 당당하게 샘플러(Sampler)랑 UV Coords(UV Coordinate : UV좌표) 라고 씌여 있습니다.
보통 shaderFX는 오른쪽에서 입력받아서 왼쪽으로 출력하는 방식이니...
보니까 이 두 값을 입력받아야 하는데 비어 있습니다 !!!! 값이 없는데 작동하고 있어요!!!
심장이 없는데 움직이는 좀비처럼 말이죠!!!

으아아아아아아악

잠깐 심호흡을 하시고 진정하세요. 아직 심장마비에 걸리시지 않아도 좋습니다.
다행히도 shaderFX에는 좀비가 살고 있지 않으며, 정상으로 동작하고 있는 것입니다.

shaderFX는 그래픽 디자이너들이 쉽게 쉽게 쉐이더를 짤 수 있게끔, 이 값을 넣지 않으면 자동으로 처리해 주는 기능을 가지고 있습니다. 즉, 넣지 않아도 자동으로 적절한 값을 넣어 준다는 말이지요. 특별이 이 값을 만질 이유가 없다면, 그냥 두셔도 상관 없습니다.

그렇지만 이번 시간엔 이 값을 만져볼 생각이므로, 이 값을 넣어보도록 하겠습니다.
샘플러랑 UV coords 노드를 만들어 보겠습니다.


샘플러는 TextureSampler란 이름으로 Maps 아래에 있습니다. [각주:4]

UV coords는 vertex에서 입력받는거라 Input에 있습니다.

이 둘을 만들고, 각각 맞는 곳에 연결해 줍니다.
이렇게 되면, 정말 정식 방법으로 완성되는 것이지요. [각주:5]

단, 아주 약간 귀찮은 것이 있습니다. 이제 더이상 Texture를 TextureMap 노드에서 불러오지 않습니다. 기존에 불러온건 무시됩니다. 이제 Texture는 TextureSampler에서 불러와야만 합니다. (저는 혼동을 피하기 위해, 아예 TextureMap 노드를 지웠다가 다시 만들었습니다 ) 이론적으로 이게 당연하겠지요? 샘플러가 텍스쳐를 불러오는 것이 정석이니까요.



그림으로 보면 아래 그림처럼 되겠지요. 더 이상 TextureMap 노드에 넣었던 그림은 사용되지 않습니다.

모양은 똑같지만. "이게 정석입니다" 프로그래머들이 이해하는 개념과 같은 모양이지요.



3. UV를 움직여 봅시다.

자 이렇게 만들었으니, UV 를 좀 써먹어 봐야 서운하지 않겠지요.
기존에 그냥 텍스쳐만 넣는 것 만으로는 안되었던 것. 그런 것을 해봅시다.
어떻게 쓸 수 있을까요?

일단, 샘플러는 그대로 두고, UV에다가 우리가 알고 있던 사칙연산을 써 봅시다.

여기다가 뭔가 해 봅시다.


이미 기초 조작법 시간에 충분히 했으므로, 사칙연산을 하는 법은 굳이 다시 설명하지 않겠습니다.

MathOperator 로, Constant(상수)에 더해보도록 합시다.
간편하게 1을 더하고 싶으나, UV에서는 1을 더하면 원하지 않는 결과가 나오니 0.2 정도를 더하는 것으로 하겠습니다.
아래 그림처럼 만들어 보세요.

못하겠으면 1강부터 다시 보고 와

자, 0.2를 UV 값에 더했습니다.
무슨 일이 일어났습니까?


으음? 그림이 살짝 옮겨졌습니다. 약간 왼쪽 위로 올라간 것 처럼 보이는군요.
덕분에 윗부분의 그림과 왼쪽 부분의 그림이 짤렸습니다.

근데 웃긴건, 그 짤린 이미지가 아래쪽과 오른쪽에 나타났다는 것이지요.
이게 뭔 일일까요?

이상하니, 상수의 값을 0.4로 올려 보겠습니다.
뭔가 이상할 때, Hybrid아저씨처럼 수학적 증명에 재주가 없을 때에는 조금씩 값을 변화시켜 보면서 규칙을 찾아 보는 것은 좋은 방법입니다. :)


그랬더니 응?
그림이 더 올라갔습니다.
마치 지금 화살표 방향으로 올라가는 것 처럼 말이지요.

그 이유를 한 번 생각해 보지요.
뭐 간단합니다. 벌써 아시는 분들도 326분쯤 계시군요.

그림은 여기에서부터 시작합니다. vertex는 구석에 있는 4 개만 일단 보지요.


아까 버텍스가 UV좌표를 가지고 있다고 했었지요?



여기에 각각의 vertex에다가 0.2를 더했으니까요.
이렇게 되었다는 겁니다. [각주:6]



0.4를 더한다면 이렇게 되는 거겠지요.


자, 이제 좀 이해가 되시겠지요? UV가 움직이는 이론도, 사실 아주 간단한 이론입니다.



그럼, 이번엔 곱하기는? 곱하기를 하면 어떻게 될까요?

자 숙제입니다.

아래 그림에 1.5를 곱해 보세요.

그리고 2도 곱해보세요.


미리 답보기 금지.















자, 푸셨나요?




정답 공개입니다. 아래와 같이 되겠지요?

엇 ...? 뭔가? 늘어났...?


2를 곱해보면 그럼 어떻게 되는 것일까요?

어엇? 2를 곱했더니, 풀 그림이 4개가 나왔습니다!

그도 그럴 것이, 곱하기는 0에다가 뭘 곱해도 0이고... 1을 곱하면 그대로고... 2를 곱하면 2배인 습성을 가진 아주 특이한 녀석이니까요. 게다가 소숫점을 곱하면 오히려 더 작은 숫자가 나오기까지 합니다. 이 나이 먹어서 곱하기에 감동을 하다니


자아, 그럼 우리 그래픽 디자이너 여러분, 특히 3D 그래픽 디자이너 여러분.
뭔가 깨닫는게 있지 않으신가요?

UV의 덧셈 (혹은 뺄셈) 은
여러분이 자주 쓰던 UV의 이동 (Offset) 과 같은 것이고,


UV의 곱셈 (혹은 잘 안쓰지만 나눗셈) 은
UV의 타일링 (Tiling)과 같은 것입니다.


자, 이해가 잘 가셨는지요?
정말 쉽지 않습니까?
정말 별거 아니지 않습니까?

멋지죠?


자 그럼 이 때쯤 되면 이제...

내 짤방은 내가 그린다,jpg







이 때쯤 되면 이런 질문을 하실 타이밍인것 맞습니다만...
확실히 지금은 float2에다가 그냥 한번에 숫자를 더하다 보니 동시에 움직이는게 맞지요. 그러다보니 대각선으로밖에 못 움직이고, 대각선으로 커지거나 작게 되는 수 밖에 없습니다.

이걸 따로따로 계산하려면, float2를 각 float 별로 따로따로 떼내어야 합니다.
이건 좀 귀찮으니까 나중에 하도록 하지요. 절대 제가 게으른게 아닙니다 .




4. 샘플러(Sampler)의 세계

이번엔 약간 간단한 겁니다.
위에서 본 그림에서 ....



요 그림을 보고 좀 이상하게 생각될 만한 거 있으셨나요?

아니, 이상하진 않겠구나... 늘 이렇게 봐 왔으니까요.

그럼, 그냥 곰곰히 생각해 봤을 때 "생각해 보니 뭐 이래?" 라는거 없었나요?



저는 저걸 봤을 때, "뭐야 UV가 1.0 넘어가니까 왜 또 그림이 반복되는건데?" 라고 생각했었습니다.
그리고 그게 나중에서야 샘플러 옵션에 그런게 있다는 것을 알게 되었지요.

바로 여기에요.

이렇게 , 샘플러를 선택하면 오른쪽에 옵션이 좌아악 펼쳐지게 됩니다.[각주:7]

일단 Mip Filter , Min Filter, Mag Filter 라고 하는 3가지 옵션이 있는데요.



이건 쉽게 말해서 '텍스쳐가 (화면에서 멀어져서 )줄어들거나 (화면에 가까이 다가와서 )커질때 각 텍스쳐의 이미지를 어떤 공식으로 크게 혹은 작게 다시 만들어주냐' 라는 옵션입니다.

Mip Filter 는 '밉맵[각주:8]을 처리할 때의 필터링 옵션' 이고,
Min Filter 는 '오브젝트가 화면에서 멀어져서, 작아보이게 되었을 때 텍스쳐의 처리방법' 이며
Mag Filter 는 '오브젝트가 화면에서 가까워져서, 커보이게 되었을 때 텍스쳐의 처리방법' 입니다.


필터의 옵션에는


대충 저런 것들이 있습니다.
물론 실제 사용되는건 저게 다가 아니예요. 좀 더 있습니다만..
일단 shaderFX 적용해도 실제로 맥스화면에서 볼 수가 없는게 문제입니다. (shaderFX가 3Dmax의 렌더링 엔진까지 건드리지는 않기 때문이지요 ) 그러므로 이걸로 제작해서, 나중에 게임 엔진에 넘겨서 봐야 볼 수 있다는게 문제지요.

그러므로 여기서는 이론만 공부하고 넘어가는 것으로 하겠습니다. 이게 눈에 들어오실 레벨이 된다면 그때 사용하셔도 상관없어요. (아 무책임하다...)

위에 얘기했듯 3Dmax에서는 볼 수가 없기 때문에, 이번에는 Unity 엔진을 켜고 엔진에서 간단하게 보도록 하겠습니다.


자 아래 그림을 보겠습니다.
원래 격자 텍스쳐가 2D 이미지로 존재하고 있던 것을, 3D 에 입힌 거지요.
그리고 그 3D 이미지가 기울어졌습니다. 졸지에 2D 이미지도 기울어지게 된 거지요.

이렇게 FOV가 있는 카메라에서 기울어지니까, 가까이 있는 부분의 격자는 원래의 격자보다 크게 보입니다.
그리고 멀리 있는 부분의 격자 그림은, 원래의 격자 그림보다 작게 보이게 될 것입니다. 뭐 당연하겠지요?

그렇다면 우리의 그래픽 카드는, 이 격자 그림을 '기울여서, 작게 혹은 크게' 보여주어야 할 타이밍입니다.
화면 가까운데 있으면 크게 보여줘야 겠고, 화면에서 멀리 있으면 작게 보여줘야 할겁니다.

이런 이미지의 각 '픽셀(Pixel)' 을 텍스쳐에 입히면, 구별하기 위해서 '텍셀(Texel)' 이라고 부른답니다.
벡셀(Bexel) 건전지와는 관계가 없어요


이게 Point 옵션을 사용했을때의 모습입니다. 멀리 있는 격자 텍셀들을 보세요. 안티알리아싱이 없는 것처럼 자글자글대지요?
이게 Point의 특징입니다. 이미지를 축소하거나 확대할 때, 그냥 옆 픽셀의 색 상관없이 무식하게 선택해 버려요. -_-;;
때문에 저렇게 타협없는 이미지가 나오게 됩니다 .


이게 리니어 (Linear) 혹은 바이리니어(Bilinear) 라고 불리는 옵션입니다.
이건 좀 바로 옆 텍셀이랑 타협한 티가 나지요? Point보단 살짝 부드럽습니다.

요건 필터링 옵션이 아니라... 밉멥(Mipmap) 을 사용하였을때 나오는 모습을 보여드리고 싶어서 만들어 봤습니다. 사실 이정도까지 구리게 나오지 않는데, 세부 옵션들을 무식하게 만져서 잘 보이도록 만들어 봤어요.
저 화살표 라인정도를 기점으로, 뒤에 있는 이미지는 뭔가 흐립니다. 저게 '작은 텍스쳐' 가 나타나는 기점이예요.
물론 잘 블렌딩 하고, 샘플링 (여기까지 되면 Trilinear 라고 합니다..) 되면 저건 더 자연스럽게 되지요. 단 , 좀 흐려지는건 어쩔 수 없뜸.


그래서 나온 궁극의 샘플링이 애니소트로픽(Anisotropic:비등방성 필터링) 샘플링 기법입니다. 이건 좀 쉽게 말하자면, 위치나 기울기까지 인식해서 주변의 텍셀 색을 샘플링해서 만들기 때문에, 기울어졌을때 아주 강력한 효과를 나타내며, 가장 정확하고 가장 무거운 샘플링 방법입니다.[각주:9]




그 다음에 볼 수 있는 AdressU와 AdressV ..

요건 딸랑 두 개 밖에 없네요? Clamp와 Wrap이라니...
여기서 Warp이 우리가 늘 봐 왔던 그것입니다. UV가 계속 , 영원히 타일링 되는 거지요.

*5 한 번 해봤뜸.




그에 반해 Clamp는, 이렇게 됩니다.
AdressU와 V를 모두 Clamp로 해 보았습니다.


호오... 마지막 텍셀의 색이 주욱 늘어나는군요?
네, 뭐 이런 것입니다. 이 외에도 Border나 Mirror 등의 옵션이 있습니다만,
개인적으로Mirror 외엔 써본적이 없어서 어디에 써야 할지 잘 모르겠군요 .[각주:10]
일반적으로는 wrap으로 사용되는 것이 보통이니, 그게 당연하다라고 생각하고 계셔도 큰 문제 없겠습니다. 단 , 수정 가능하다는 것 정도만 알아두세요.


이것이 Sampler의 옵션입니다. 사실 일반적으로 많이 쓰이는 옵션들은 아니고, ShaderFX 배우시는 동안에는 잊으셔도 상관 없는 옵션이라고 할 수 있겠습니다. 무엇보다 3Dmax 화면에서는 안보이거든요!!! [각주:11]

그러므로 사실 이 샘플러 부분은 그냥 이론 시간이라고 생각하시면 되겠습니다. 앞으로 강의 동안에는 사용하지 않겠습니다.

보이지도 않는걸 공부했다고 울고 불고 짜도 소용없습니다.


너무 억울해 하지 마세요.
그래도 Number of Mip Maps(밉맵의 갯수) 랑 Linear Gamma (감마 보정 옵션) 에 대해 설명 안한게 어디예요... [각주:12]



자, 이렇게 해서 조금 어려워진 '이론이 약간 가미된 shader FX 2부 강의의 첫 시간' 을 끝마치도록 하겠습니다.
다음 시간에 뭘 할까요...? 천천히 생각해 볼께요. 아유 힘들어 ...

아우 이론 나오니까 내가 힘들다.


다음 시간에는 UV를 한 방향으로 움직여 볼까...
그리고 UV를 칼라로 보기 해 볼까... (잊어버릴까봐 적어놓기)
  1. 3차원 텍스쳐라고 해서, UVW를 입히는 기술도 있습니다만 여기서 설명하지는 않겠습니다. 그리고... 왜 굳이 UVW라는 이름을 붙였냐면. XYZ와 헷갈리지 않게 하기 위해서 붙인 이름일 뿐입니다. -_- 사실은 XYZ랑 똑같은 겁니다. [본문으로]
  2. 다이렉트 X 에서는 지금 그림이 맞습니다 . 즉 게임에서는 지금 그림처럼 인식된다고 생각하시면 되지요. 하지만 OpenGL 등에서는 좀 다르게 UV를 정해놨는데요, 거기서는 지금 그림의 왼쪽 아래 점인 (0.0,1.0) 지점부터 시작합니다. 그리고 지금 그림을 보면, MAX도 그렇게 시작하는 것으로 보입니다. 물론 게임으로 넘길때 Exporter들이 알아서 컨버팅 해주니까 일반적으로는 크게 신경쓰시진 않아도 됩니다. [본문으로]
  3. 1.0 이상의 값이나 0.0 이하의 값은 없냐구요? 있지요 물론. 대신 그럴땐, 그 넘어가는 텍스쳐의 처리 옵션을 wrap이냐 clamp냐 등으로 처리해 놓은 것에 따라 다릅니다. 일반적으로는, 반복됩니다. 즉 2.0 도 1.0 으로 처리되는 거지요.(2.0, 2.0) = (1.0, 1.0) 뭐, 이건 나중에 또 얘기합시다. [본문으로]
  4. 빈 화면에서 오른쪽 클릭. 잊으셨습니까? [본문으로]
  5. 두 값을 모두 넣는 것이 정석이지만, 둘 중 하나만 넣어도 shaderFX에서는 알아서 자동으로 처리해 줍니다. [본문으로]
  6. 아! 그렇구나! 하시면서 3Dmax에서 Unwrap UVW를 열어보셔도, 저렇게 안되어 있습니다. 이건 맥스에서 고친게 아니라 shader에서 고친것이기 때문이지요 :) 즉 내부적으로만 '저런 모양으로 돌아간다' 라는걸 알려 드리도록 쓴 글이고, 실제 '맥스를 움직여 버리는' 것은 아닙니다. 맥스를 움직이는건 맥스 스크립트지요. :) [본문으로]
  7. 굳이 샘플러를 만들지 않아도, 원래 만들었던 Texture Map 옵션에도 동일한 옵션이 있습니다. 그러므로 샘플러 조작을 뭔가 계산해서 특이하게 만들 생각이 아니고 옵션만 조절해도 될 정도라면, 굳이 샘플러를 만들지 않아도 shaderFX에서는 충분합니다. [본문으로]
  8. Mipmap. dds 파일 포멧의 옵션에는, 텍스쳐가 입혀진 오브젝트가 멀리 떨어졌을때 작은 이미지의 텍스쳐로 전환하는 기능이 들어 있습니다. 이것을 밉맵(Mipmap) 이라고 합니다. [본문으로]
  9. http://gtgames.egloos.com/4777075 [본문으로]
  10. http://cafe.naver.com/tgedev.cafe?iframe_url=/ArticleRead.nhn%3Farticleid=471&연결이 안된다면 네이버에서 "6. [Shader Study, HLSL 기본문법] 변수의 선언과 사용: Type -2" 을 검색. [본문으로]
  11. 제가 Filtering을 썼던 기억은... 이펙트를 날카롭게 보일 수 있도록 하기 위해서 이펙트 텍스쳐는 강제로 point로 조절되게 만들었었던 기억 뿐입니다. :) [본문으로]
  12. 감마 코렉션은 제가 예전에 트위터에서 질문 한 번 했다가 프로그래머 분들의 시간을 잔뜩 허비하게 만든 적이 있었던 바로 그 주제.. http://chulin28ho.egloos.com/5626565 [본문으로]
Posted by 캬오 대마왕J

삼국지를 품다는 포워드 렌더러로 돌고 있습니다. 유니티 엔진은 디퍼드 렌더링도 가능하지만, 디퍼드 렌더링 쓴다고 무조건 좋아지는거 아닙니다 -_-; 기본적으로는 포워드 렌더링이 가볍게 만들기 좋지요.

근데 문제가 여기서 SSAO를 사용하면 원거리에서 좀 문제가 생긴단 말이지요.
특히 포그 있는데서.

일단 잘보이게 좀 강하게 처리해 봤습니다.


저렇게 먼거리에서 검댕이가 생깁니다.

지금이야 좀  과장한 거라고 하지만, 과장 안해도 멀리 포그가 짙은 곳에서 검뎅이가 왔다갔다 하는건 좀 거시기 하지요잉. 눈에도 은근히 잘떠서 스트레스.


어쨌건 간단하게 말하면
SSAO 데이터를 뽑은것에다가


Z 버퍼값을 조금 모디파이한 녀석을 준비해요.





그리고 이 둘을 더하면
이렇게 되겠지요.

물론 거리는 조절가능. 기본은 0.5로 해놨는데 아마 충분할 겁니다.




그러면 먼 거리는 SSAO가 안먹어요잉.




수치조절은 맵마다 할 수 있어요.
여기 SSAO Attenuation 조절자를 만들어 놨거든요.


근데 여기까지 건드리니까 나 레알 프로그래머 같애...


'회사 내부용 자료' 카테고리의 다른 글

삼국지를 품다 SSAO 거리 조절하기  (0) 2012/02/15
Posted by 캬오 대마왕J
1. ShaderFX 메터리얼


자... 지금까지 배운 것들을 잠깐 정리해 보겠습니다.

a. 칼라 노드를 만들 수 있게
되었습니다.




원하는 칼라가 출력되는 노드를 만들 수 있게 되었습니다.








b. 텍스쳐 노드를 만들 수
있게 되었습니다.

사실 정식으로 쉐이더 코드를 짜려면, 텍스쳐 샘플러를 선언하고, UV 를 버텍스 쉐이더에서부터 받아서 픽셀 쉐이더로 넘겨오는 과정부터 거쳐야 하지만, 맨 첫 강의때 말했듯 이건 그래픽 디자이너를 위한 강의이므로 '일단 간지나게 만들고 공부는 나중에 한다' 라는 구조로 진행합니다 후후후
그러므로 여러분은 텍스쳐 노드를 만들 수 있게 되었습니다.



c. 텍스쳐 노드의 채널을 따로 따로 다룰 수 있게 되었습니다.



RGBA로 이루어진 텍스쳐 채널 구조를 배우게 되었습니다. 각각은 float으로 이루어진 상수이고, 이것들이 모여서 칼라와 투명도를 정합니다. 그리고 따로 사용할 수도 있습니다.







d.상수를 만들 수 있게 되었습니다. 



상수, 별 거 아닙니다. 그냥 숫자입니다. 1+1 같은 공식에서 1이 상수란 말입니다. 여기서는 float 이라고 해도 문제 없겠지요. 어차피 보통 소숫점을 쓰니까요. 











e. 연산자를 만들 수 있게 되었습니다. 



사칙연산이 가능하게 되었습니다. 이것도 별 거 아니죠. 1+1 에서 +를 만들 수 있게 되었다는 건데... 물론 곱하기나 빼기 등도 만들 수 있게 되었습니다. 거의 사용하지는 않지만 나누기 부호도 만들 수 있게 되었구요.










f. 이 출력물들을 연결할 수 있게
되었습니다 .



이 출력물 노드들을 이리 얽히고 저리 얽히게 만들어서 출력할 수 있게 되었습니다. 그리고 Ambient Color에 연결할 수 있게 되었습니다. (여태까지 Ambient Color에만 연결하신 분은 없으시겠지만)










생각보다 꽤 많은 것을 했네요!







지겨우셨을지도 모르지만, 사실 위 내용은 ShaderFX를 다루기 위한 기본 조작 같은 것입니다. 이제 여기에 함수가 추가되면 재미있는 기능이 발현되게 되지요. 그 때부터는 본격적 실습입니다 실습 !




그러기 위해서 오늘은 ... 배운것을 총 정리하는 겸 해서
ShaderFX 메터리얼을 배워보도록 합시다!
별 거 아닙니다. 이 왼쪽에 있는 진짜 루트 노드 말예요 이거.

여기에 연결하는거 배워보도록 하자는 거지요.
겸해서 라이팅에 대한 기본적인 지식을 쬐끔 배워보는 시간을 가지도록 하겠습니다.

제대로 배우시고 싶다고요? 제대로 배우려면 하나당 한 번의 강의로 해야 해요.
그러니 그건 나중에 , 라이팅을 직접 만들 때가 옵니다. 그 때 알려 드릴께요 .
그전에 실버치매님이 알려주시겠지





오늘 강의를 따라하면 드디어 이런 이미지를 만들 수 있게 됩니다.
그런대로 볼만하지요?

 




2. Diffuse Color 연결하기

Diffuse Color는, 확산광 (擴散光) 이라고도 불리며[각주:1] , 복잡하게 설명하면 어려워지지만, 간단하게 이렇게 생각하면 일단 편합니다.

"빛 때문에 밝고 어두워지는 색깔"

나중에 자세히 말하겠지만, Diffuse Color에서 가장 밝은 부분은 1이고, 가장 어두운 부분은 0입니다. 당연하게도 중간쯤 밝은 부분은 0.5겠지요.[각주:2]
그리고 이 값이 텍스쳐에 곱셈 연산이 됩니다. 즉 가장 밝은 부분은 텍스쳐의 고유한 색상이 되고, 가장 어두운 부분은 검은색이 되는 거지요.


그러므로, 아래 그림처럼 텍스쳐 노드를 만들고, RGB 채널을 Diffuse Color에 연결해 주면 그것으로 끝입니다.
빛의 밝고 어두움에 따라 음영이 지는 주전자를 볼 수 있습니다.
D_cobblestone.dds 를 적용하였습니다. [각주:3]





2. Ambient Color 만들어 연결하기

지금 당장 책상 아래를 보세요. 빛이 전혀 닿지 않는 곳임에도 불구하고 새카맣지 않고, 어스름히 보입니다.
그렇지 않습니까? 이것은 무엇 때문일까요?

이 세상에는 많은 물체가 있고, 그 물체들은 태양으로부터 나온 빛을 받아 반사하거나 , 흡수하고 있습니다. 때문에 빛이 직접 닿지 않는 곳이라 하더라도 새카맣게 보이는 경우는 없지요.

이 계산을  실제로 한다면 엄청나게 복잡할 수 밖에 없습니다 .때문에 이런 '환경 반사광' 을 직접 계산하지 않고, 단순히 칼라를 더해 (+) 줌으로써 이를 흉내내 주곤 하지요. 이것이 환경광 (Ambient light) 입니다.

이 빛은 방향성도 없고, 그냥 전체 화면에 일정 색을 더해주는 것 뿐입니다. 이것은 어떤 환경이냐 따라 다양한 색을 가지는데요. 쉽게 말해서 석양이 질 때는 붉은 계열 색을, 맑은 날에는 푸른 계열의 색을 쓰는 것이 일반적입니다.

아주 맑은 날은 건물의 어두운 부분이 하늘색입니다. 이것이 Ambient light.
 자, 이렇게 Ambient Color에는 그냥 단색 칼라를 연결해 주도록 합시다.[각주:4]

잘 보이게 하기 위해서 조금 강하게 넣었습니다. 조금만 밝아도 화면 전체가 밝아지니, 아주 어두운 색을 조심스럽게 쓰는 것이 요령입니다. 칼라를 조절하고 Set 버튼 누르는 것을 잊지마세요.



3. Specular Color 만들어 연결하기
Specular Color는 정반사 (正反射 : Specular Reflection) 의 색상을 의미합니다. 이것은 광원으로부터 나온 빛이 바로 반사하여 시야에 들어오는 '하이라이트' 를 의미하는데요. 
자세한 내용은 실버치매님의 글 http://gamedevforever.com/17 을 읽어보시면 되겠습니다. [각주:5] 

여기서는 그냥 색을 넣어주기만 하면 가동됩니다.
일반적으로 아무 생각 없을 때에는 흰 색을 넣는데요. 실버치매님의 글을 읽어보시면 사실 이렇게 간단한게 아니라는걸 아실 수 있으실 겁니다 .

그래도 우리는 초보니까 흰 색을 넣지요 헤헷.

간단하게 Specular 라이팅이 활성화 되면서, 칼라도 들어갔습니다. 물론 흰색은 좀 이상하지요. 원하시는 색으로 바꾸셔도 무방합니다. 정렬의 빨강색이라던가  
심지어, float3가 들어가니까 RGB텍스쳐를 따로 만들어 적용하는 것도 가능합니다.[각주:6]




4. Specular Level 연결하여 조정하기

이제 그 아래 있는 Specular level입니다. 이것은 스페큘러의 강도 같은 것을 결정하는건데요, float 하나가 들어간다는 것을 알 수 있습니다. 즉 0~1 사이의 값으로 강도를 조절한다는 거지요.
물론 상수를 하나 만들어서 저기다 연결해도 잘 작동합니다만...

자, 지금 더 돌 재질을 잘 보세요. 무슨 느낌인가요? 마치 덕수궁 돌벽같은 느낌이 아닌가요? 돌이 튀어나와있고 돌들 사이에 시멘트로 매워진 벽 느낌이요.
여기서는 그래서 돌 재질이 있는 부분만 반짝이고, 경계선 부분은 반짝이지 않게 하려면 어떻게 해야 할까요?
뭔가... 마스킹이 있어야 하겠지요? 돌 부분은 살리고 경계선은 죽이는.. 그런 이미지가 필요할겁니다.
그리고 그 마스킹 이미지가 이미 있습니다.

Diffuse Texture 로 사용했던 이미지의 Display Alpha 옵션을 켜보세요. 이건 이 이미지의 알파 채널이 있다면, 그 알파 채널이 어떻게 생겼나 보여주는 겁니다.

그걸 켜 보니까 이미지가 바뀝니다! 흑백의 알파 채널 이미지가 나옵니다.
네, 이 이미지는 알파 채널을 가지고 있었던 겁니다. 그것도 저런 모양으로.
마스킹으로 쓰기에 딱 좋은 이미지로 보입니다.

이전에도 누차 말씀드렸지만, 알파 채널에 그림이 있다고 전부 투명도는 아닙니다. 그 채널을 'Opacity' 에 연결했을때 투명도가 되는거지, 아무 짓도 하지 않으면 어떤 채널에 있는 이미지건 그냥 float 덩어리일 뿐이란 말씀입니다. 

이 오브젝트는 투명도가 필요 없습니다. 즉 이미지의 알파 채널은 어차피 쓰지 않는단 말이지요.
그래서 우리는 이 알파 채널을 Spacular level로 쓰기로 결심하였습니다. 이어줍시다.[각주:7]

연결했습니다 . Specular 영역이 잘 보이도록 Specular Color를 빨강으로 바꿔 보았습니다. 어떻게 보입니까?
돌이 있는 부분은 Specular 가 강하게 들어갔고, 돌이 없는 사이의 부분은 매우 약하게 들어갔다는 것을 볼 수 있습니다.
마스킹 이미지도 보시면, 밝은 부분이 아주 흰 색이 아니고 어두운 부분이 아주 검은 색도 아닙니다.
그래서 이렇게 적절한 강도로 들어간 것입니다. 위에 소개한 실버치매님의 글을 읽어 보신분은 아시겠지만, 완전히 Specular가 없는 물체는 없는 법이니까요. 오히려 이게 더 자연스럽다고 할 수 있겠습니다.




5. Glossiness 연결하여 조정하기
Glossiness는 Specular의 퍼짐 정도를 조절하는 메뉴입니다. 둔탁한 오브젝트일수록 Specular가 퍼질 것이고, 유리나 잘 닦은 당구공처럼 매끄러운 오브젝트일수록 Specular가 강하고 얇게 맺힐 것입니다. 이걸 조절하는 겁니다.

이건 단순하게 상수로 조절해 주도록 하겠습니다.
굳이 이젠 설명할 필요도 없겠지요. 직접 비교해 보세요.

1일때에는 넓게 퍼집니다.

10 정도 되니까 좀 줄어드는 군요.

100 정도 되니까 더 작아졌습니다.

물론 이것도 float이기 때문에 아까 Specular level에서 사용한 Alpha 채널을 마스킹으로 이용할 수 있겠습니다만, 그냥은 못쓰고 * 10 정도를 해 줘야 조금 쓸만할 겁니다. 그치만 여기서는 해도 잘 안보일것 같아서 넘어가도록 하지요. 다음에도 할 기회는 충분합니다.

자 이제 값을 20정도로 하고 Speculat Color도 다시 흰 색으로 만들었습니다.





6. Self - Illumination 만들어 연결하기
Self-illumination (자기 발광 自己光) 은 스스로 빛나는 효과 같은 것을 만들때 사용됩니다. 스스로 빛을 내는 발광체 표현을 할 때 주로 사용되지요. Diffuse Color의 음영값과 상관없이 자신의 칼라가 언제나 나타나게 되는 특징이 있습니다. [각주:8] 셰이더 프로그래밍에서는 Self-illumination이란 말을 거의 쓰지 않고, Emission 이라는 말을 주로 사용합니다


사실 이번엔 안 쓸 재질이지만, 특별히 시험삼아 잠시 텍스쳐를 넣어 보았습니다.
caustics_001.bmp 가 적절해 보이는군요. [각주:9]

뭔가 빛나는 것처럼 보입니다.

시험삼아 넣어본 것이니, 삭제하도록 하겠습니다.





7. Normal map 넣어보기
네에 Normalmap입니다. 뭔가 마법의 텍스쳐같은 Normal맵이죠. 분명 폴리곤이 없는데도 막 울퉁불퉁해지는!!!
그 이유 같은건 역시 나중에 알아보고, 일단 넣어보도록 해보겠습니다.

노말맵을 만들 때에는 일반 텍스쳐처럼 만들면 안됩니다.
빈 화면에서 오른쪽클릭을 하고 Maps/NormalMap을 선택합시다.
 
일반 텍스쳐를 선택하면 안됩니다. 노말맵은 -1.0~ 1.0 사이의 값이 필요해서, 그냥 텍스쳐 영역을 쓰면 안되거든요.[각주:10] 
 


그리고 여기에 N_cobblestone_ati.dds 를 넣어주겠습니다.
잘 나옵니다



 

...Opacity는 안넣겠습니다. 뭐 다 알잖아요?


 


 

오늘은 이렇게 메터리얼에 값 넣는 것을 해 보았습니다. 중간에 연산자 같은거 넣고 막 이러면... 복잡하게 할 수 있어 보이죠? 앞으로 하다보면 다 하게 됩니다. 힘내세요! 

다음 시간에는 뭘 할까요? 이런걸 생각하고 있긴 한데.. 
- Lerp로 텍스쳐 섞기
- 큐브맵 사용해 보기 


 

  1. 난반사광 이라고도 불리며, 산광이라고 불리는 등, 여러 가지 용어로 불리우고 있습니다. 그냥 Diffuse light 라고 부르는 것이 나을 것 같습니다. [본문으로]
  2. 추후에 이 계산을 직접 수식으로 만들어 보게 됩니다. 그 때 더 자세히 알아보도록 하지요. [본문으로]
  3. 빛을 직접 설치하고 싶으신 분은, Directional light 하나를 설치해 보십시오. 여러 개도 가능하지만, 현재 설정으로는 한 개의 Directional light 밖에 적용되지 않습니다. [본문으로]
  4. 물론, IBL 이나 Ambient Cube 등의 발전된 기법들도 사용됩니다만 아직도 많은 게임들은 단순한 Ambient Color를 쓰는 경우가 많으므로 우리도 그렇게 하는 것이 아무런 문제가 되지 않을것입니다. [본문으로]
  5. 저는 이거보다 더 잘 쓸 자신이 없어서요. [본문으로]
  6. 텍스쳐가 한 장 더 필요하게 되므로 리소스도 사용하게 되고 만들기도 귀찮은 작업이 되지만, 최신 게임에서는 실제로 이렇게 만들어서 적용하고 있습니다. 당장 여러분의 다음 프로젝트에서도 쓸 지도 모르지요! 아니면 이미 쓰고 있다던가!!! [본문으로]
  7. 실무에서도 엄청나게 많이 쓰이는 요령입니다. 텍스쳐는 무조건 아껴야 하거든요. 남는 채널이 있으면 무언가의 마스크로 꼭 쓰도록 합시다. [본문으로]
  8. 뭔가 거창해 보입니다만, 사실은 Ambient와 다른게 하나도 없는 녀석입니다. Self - illumination에 넣지 않고 Ambient Color에 넣어도 완전히 똑같이 작동합니다. [본문으로]
  9. 앗! 노드들이 어떻게 저렇게 작은 사이즈로 변했지요? 라고 생각하신다면, 노드를 더블클릭 해 보세요. :) [본문으로]
  10. 뭐 지금부터 알 필요는 없지만.... 0.0~1.0 사이에 있는 값을 -1.0~1.0 으로 확장하는 법은 *2-1 을 해주면 됩니다. 이런 놀라운 (?) 공식을 '매직 넘버' 라고 합니다 :) [본문으로]
Posted by 캬오 대마왕J